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. x_toolkit_position
  64. x_update_opaque_region
  65. x_gc_free_ext_data_private
  66. x_gc_get_ext_data
  67. x_extension_initialize
  68. xi_frame_selected_for
  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 
  1219 
  1220 /* Global state maintained during a drag-and-drop operation.  */
  1221 
  1222 /* Flag that indicates if a drag-and-drop operation is in progress.  */
  1223 bool x_dnd_in_progress;
  1224 
  1225 /* The frame where the drag-and-drop operation originated.  */
  1226 struct frame *x_dnd_frame;
  1227 
  1228 /* That frame, but set when x_dnd_waiting_for_finish is true.  Used to
  1229    prevent the frame from being deleted inside selection handlers and
  1230    other callbacks.  */
  1231 struct frame *x_dnd_finish_frame;
  1232 
  1233 /* Flag that indicates if a drag-and-drop operation is no longer in
  1234    progress, but the nested event loop should continue to run, because
  1235    handle_one_xevent is waiting for the drop target to return some
  1236    important information.  */
  1237 bool x_dnd_waiting_for_finish;
  1238 
  1239 /* Flag that means (when set in addition to
  1240    `x_dnd_waiting_for_finish') to run the unsupported drop function
  1241    with the given arguments.  */
  1242 static bool x_dnd_run_unsupported_drop_function;
  1243 
  1244 /* The "before"-time of the unsupported drop.  */
  1245 static Time x_dnd_unsupported_drop_time;
  1246 
  1247 /* The target window of the unsupported drop.  */
  1248 static Window x_dnd_unsupported_drop_window;
  1249 
  1250 /* The Lisp data associated with the unsupported drop function.  */
  1251 static Lisp_Object x_dnd_unsupported_drop_data;
  1252 
  1253 /* Whether or not to move the tooltip along with the mouse pointer
  1254    during drag-and-drop.  */
  1255 static bool x_dnd_update_tooltip;
  1256 
  1257 /* Monitor attribute list used for updating the tooltip position.  */
  1258 static Lisp_Object x_dnd_monitors;
  1259 
  1260 /* The display the drop target that is supposed to send information is
  1261    on.  */
  1262 static Display *x_dnd_finish_display;
  1263 
  1264 /* State of the Motif drop operation.
  1265 
  1266    0 means nothing has happened, i.e. the event loop should not wait
  1267    for the receiver to send any data.  1 means an XmDROP_START message
  1268    was sent to the target, but no response has yet been received.  2
  1269    means a response to our XmDROP_START message was received and the
  1270    target accepted the drop, so Emacs should start waiting for the
  1271    drop target to convert one of the special selections
  1272    XmTRANSFER_SUCCESS or XmTRANSFER_FAILURE.  */
  1273 static int x_dnd_waiting_for_motif_finish;
  1274 
  1275 /* The display the Motif drag receiver will send response data
  1276    from.  */
  1277 struct x_display_info *x_dnd_waiting_for_motif_finish_display;
  1278 
  1279 /* Whether or not F1 was pressed during the drag-and-drop operation.
  1280 
  1281    Motif programs rely on this to decide whether or not help
  1282    information about the drop site should be displayed.  */
  1283 static bool x_dnd_xm_use_help;
  1284 
  1285 /* Whether or not Motif drag initiator info was set up.  */
  1286 static bool x_dnd_motif_setup_p;
  1287 
  1288 /* The Motif drag atom used during the drag-and-drop operation.  */
  1289 static Atom x_dnd_motif_atom;
  1290 
  1291 /* The target window we are waiting for an XdndFinished message
  1292    from.  */
  1293 static Window x_dnd_pending_finish_target;
  1294 
  1295 /* The protocol version of that target window.  */
  1296 static int x_dnd_waiting_for_finish_proto;
  1297 
  1298 /* Whether or not it is OK for something to be dropped on the frame
  1299    where the drag-and-drop operation originated.  */
  1300 static bool x_dnd_allow_current_frame;
  1301 
  1302 /* Whether or not the `XdndTypeList' property has already been set on
  1303    the drag frame.  */
  1304 static bool x_dnd_init_type_lists;
  1305 
  1306 /* Whether or not to return a frame from `x_dnd_begin_drag_and_drop'.
  1307 
  1308    0 means to do nothing.  1 means to wait for the mouse to first exit
  1309    `x_dnd_frame'.  2 means to wait for the mouse to move onto a frame,
  1310    and 3 means to return `x_dnd_return_frame_object'.  */
  1311 static int x_dnd_return_frame;
  1312 
  1313 /* The frame that should be returned by
  1314    `x_dnd_begin_drag_and_drop'.  */
  1315 static struct frame *x_dnd_return_frame_object;
  1316 
  1317 /* The last drop target window the mouse pointer moved over.  This can
  1318    be different from `x_dnd_last_seen_toplevel' if that window had an
  1319    XdndProxy.  */
  1320 static Window x_dnd_last_seen_window;
  1321 
  1322 /* The last toplevel the mouse pointer moved over.  */
  1323 static Window x_dnd_last_seen_toplevel;
  1324 
  1325 /* The window where the drop happened.  Normally None, but it is set
  1326    when something is actually dropped.  */
  1327 static Window x_dnd_end_window;
  1328 
  1329 /* The XDND protocol version of `x_dnd_last_seen_window'.  -1 means it
  1330    did not support XDND.  */
  1331 static int x_dnd_last_protocol_version;
  1332 
  1333 /* Whether or not the last seen window is actually one of our
  1334    frames.  */
  1335 static bool x_dnd_last_window_is_frame;
  1336 
  1337 /* The Motif drag and drop protocol style of `x_dnd_last_seen_window'.
  1338    XM_DRAG_STYLE_NONE means the window does not support the Motif drag
  1339    or drop protocol.  XM_DRAG_STYLE_DROP_ONLY means the window does
  1340    not respond to any drag protocol messages, so only drops should be
  1341    sent.  Any other value means that the window supports both the drag
  1342    and drop protocols.  */
  1343 static int x_dnd_last_motif_style;
  1344 
  1345 /* The timestamp where Emacs last acquired ownership of the
  1346    `XdndSelection' selection.  */
  1347 static Time x_dnd_selection_timestamp;
  1348 
  1349 /* The drop target window to which the rectangle below applies.  */
  1350 static Window x_dnd_mouse_rect_target;
  1351 
  1352 /* A rectangle where XDND position messages should not be sent to the
  1353    drop target if the mouse pointer lies within.  */
  1354 static XRectangle x_dnd_mouse_rect;
  1355 
  1356 /* If not None, Emacs is waiting for an XdndStatus event from this
  1357    window.  */
  1358 static Window x_dnd_waiting_for_status_window;
  1359 
  1360 /* If .type != 0, an event that should be sent to .xclient.window
  1361    upon receiving an XdndStatus event from said window.  */
  1362 static XEvent x_dnd_pending_send_position;
  1363 
  1364 /* Whether or not that event corresponds to a button press.  */
  1365 static bool x_dnd_pending_send_position_button;
  1366 
  1367 /* The root-window position of that event.  */
  1368 static int x_dnd_pending_send_position_root_x;
  1369 
  1370 /* Likewise.  */
  1371 static int x_dnd_pending_send_position_root_y;
  1372 
  1373 /* If true, send a drop from `x_dnd_finish_frame' to the pending
  1374    status window after receiving all pending XdndStatus events.  */
  1375 static bool x_dnd_need_send_drop;
  1376 
  1377 /* The protocol version of any such drop.  */
  1378 static int x_dnd_send_drop_proto;
  1379 
  1380 /* The action the drop target actually chose to perform.
  1381 
  1382    Under XDND, this is set upon receiving the XdndFinished or
  1383    XdndStatus messages from the drop target.
  1384 
  1385    Under Motif, this is changed upon receiving a XmDROP_START message
  1386    in reply to our own.
  1387 
  1388    When dropping on a target that doesn't support any drag-and-drop
  1389    protocol, this is set to the atom XdndActionPrivate.  */
  1390 static Atom x_dnd_action;
  1391 
  1392 /* The symbol to return from `x-begin-drag' if non-nil.  Takes
  1393    precedence over `x_dnd_action`.  */
  1394 static Lisp_Object x_dnd_action_symbol;
  1395 
  1396 /* The action we want the drop target to perform.  The drop target may
  1397    elect to perform some different action, which is guaranteed to be
  1398    in `x_dnd_action' upon completion of a drop.  */
  1399 static Atom x_dnd_wanted_action;
  1400 
  1401 /* The set of optional actions available to a Motif drop target
  1402    computed at the start of the drag-and-drop operation.  */
  1403 static uint8_t x_dnd_motif_operations;
  1404 
  1405 /* The preferred optional action out of that set.  Only takes effect
  1406    if `x_dnd_action' is XdndAsk.  */
  1407 static uint8_t x_dnd_first_motif_operation;
  1408 
  1409 /* Array of selection targets available to the drop target.  */
  1410 static Atom *x_dnd_targets;
  1411 
  1412 /* The number of elements in that array.  */
  1413 static int x_dnd_n_targets;
  1414 
  1415 /* The old window attributes of the root window before the
  1416    drag-and-drop operation started.  It is used to keep the old event
  1417    mask around, since that should be restored after the operation
  1418    finishes.  */
  1419 static XWindowAttributes x_dnd_old_window_attrs;
  1420 
  1421 /* Whether or not `x_dnd_cleaup_drag_and_drop' should actually clean
  1422    up the drag and drop operation.  */
  1423 static bool x_dnd_unwind_flag;
  1424 
  1425 /* The frame for which `x-dnd-movement-function' should be called.  */
  1426 static struct frame *x_dnd_movement_frame;
  1427 
  1428 /* The coordinates which the movement function should be called
  1429    with.  */
  1430 static int x_dnd_movement_x, x_dnd_movement_y;
  1431 
  1432 /* The frame for which `x-dnd-wheel-function' should be called.  */
  1433 static struct frame *x_dnd_wheel_frame;
  1434 
  1435 /* The coordinates which the wheel function should be called with.  */
  1436 static int x_dnd_wheel_x, x_dnd_wheel_y;
  1437 
  1438 /* The button that was pressed.  */
  1439 static int x_dnd_wheel_button;
  1440 
  1441 /* The modifier state when the button was pressed.  */
  1442 static int x_dnd_wheel_state;
  1443 
  1444 /* When the button was pressed.  */
  1445 static Time x_dnd_wheel_time;
  1446 
  1447 #ifdef HAVE_XKB
  1448 /* The keyboard state during the drag-and-drop operation.  */
  1449 static unsigned int x_dnd_keyboard_state;
  1450 #endif
  1451 
  1452 /* jmp_buf that gets us out of the IO error handler if an error occurs
  1453    terminating DND as part of the display disconnect handler.  */
  1454 static sigjmp_buf x_dnd_disconnect_handler;
  1455 
  1456 /* Whether or not the current invocation of handle_one_xevent
  1457    happened inside the drag_and_drop event loop.  */
  1458 static bool x_dnd_inside_handle_one_xevent;
  1459 
  1460 /* The recursive edit depth when the drag-and-drop operation was
  1461    started.  */
  1462 static int x_dnd_recursion_depth;
  1463 
  1464 /* The cons cell containing the selection alias between the Motif drag
  1465    selection and `XdndSelection'.  The car and cdr are only set when
  1466    initiating Motif drag-and-drop for the first time.  */
  1467 static Lisp_Object x_dnd_selection_alias_cell;
  1468 
  1469 /* The last known position of the tooltip window.  */
  1470 static int x_dnd_last_tooltip_x, x_dnd_last_tooltip_y;
  1471 
  1472 /* Whether or not those values are actually known yet.  */
  1473 static bool x_dnd_last_tooltip_valid;
  1474 
  1475 #ifdef HAVE_XINPUT2
  1476 /* The master pointer device being used for the drag-and-drop
  1477    operation.  */
  1478 static int x_dnd_pointer_device;
  1479 
  1480 /* The keyboard device attached to that pointer device.  */
  1481 static int x_dnd_keyboard_device;
  1482 #endif
  1483 
  1484 /* Structure describing a single window that can be the target of
  1485    drag-and-drop operations.  */
  1486 struct x_client_list_window
  1487 {
  1488   /* The window itself.  */
  1489   Window window;
  1490 
  1491   /* The display that window is on.  */
  1492   Display *dpy;
  1493 
  1494   /* Its X and Y coordinates from the root window.  */
  1495   int x, y;
  1496 
  1497   /* The width and height of the window.  */
  1498   int width, height;
  1499 
  1500   /* A bitmask describing events Emacs was listening for from the
  1501      window before some extra events were added in
  1502      `x_dnd_compute_toplevels'.  */
  1503   long previous_event_mask;
  1504 
  1505   /* The window manager state of the window.  */
  1506   unsigned long wm_state;
  1507 
  1508   /* The next window in this list.  */
  1509   struct x_client_list_window *next;
  1510 
  1511   /* The extents of the frame window in each direction.  */
  1512   int frame_extents_left;
  1513   int frame_extents_right;
  1514   int frame_extents_top;
  1515   int frame_extents_bottom;
  1516 
  1517 #ifdef HAVE_XSHAPE
  1518   /* The border width of this window.  */
  1519   int border_width;
  1520 
  1521   /* The number of rectangles composing the input shape.  */
  1522   int n_input_rects;
  1523 
  1524   /* The rectangles making up the input shape.  */
  1525   XRectangle *input_rects;
  1526 
  1527   /* The rectangles making up the bounding shape.  */
  1528   XRectangle *bounding_rects;
  1529 
  1530   /* The number of rectangles composing the bounding shape.  */
  1531   int n_bounding_rects;
  1532 #endif
  1533 
  1534   /* The Motif protocol style of this window, if any.  */
  1535   uint8_t xm_protocol_style;
  1536 
  1537   /* Whether or not the window is mapped.  */
  1538   bool mapped_p;
  1539 };
  1540 
  1541 /* List of all toplevels in stacking order, from top to bottom.  */
  1542 static struct x_client_list_window *x_dnd_toplevels;
  1543 
  1544 /* Whether or not the window manager supports the required features
  1545    for `x_dnd_toplevels' to work.  */
  1546 static bool x_dnd_use_toplevels;
  1547 
  1548 
  1549 
  1550 /* Motif drag-and-drop protocol support.  */
  1551 
  1552 /* Pointer to a variable which stores whether or not an X error
  1553    occurred while trying to create the Motif drag window.  */
  1554 static volatile bool *xm_drag_window_error;
  1555 
  1556 typedef enum xm_byte_order
  1557   {
  1558     XM_BYTE_ORDER_LSB_FIRST = 'l',
  1559     XM_BYTE_ORDER_MSB_FIRST = 'B',
  1560 #ifndef WORDS_BIGENDIAN
  1561     XM_BYTE_ORDER_CUR_FIRST = 'l',
  1562 #else
  1563     XM_BYTE_ORDER_CUR_FIRST = 'B',
  1564 #endif
  1565   } xm_byte_order;
  1566 
  1567 #ifdef ENABLE_CHECKING
  1568 
  1569 #define SWAPCARD32(l)                           \
  1570   {                                             \
  1571     struct { unsigned t : 32; } bit32;          \
  1572     char n, *tp = (char *) &bit32;              \
  1573     bit32.t = l;                                \
  1574     n = tp[0]; tp[0] = tp[3]; tp[3] = n;        \
  1575     n = tp[1]; tp[1] = tp[2]; tp[2] = n;        \
  1576     l = bit32.t;                                \
  1577   }
  1578 
  1579 #define SWAPCARD16(s)                           \
  1580   {                                             \
  1581     struct { unsigned t : 16; } bit16;          \
  1582     char n, *tp = (char *) &bit16;              \
  1583     bit16.t = s;                                \
  1584     n = tp[0]; tp[0] = tp[1]; tp[1] = n;        \
  1585     s = bit16.t;                                \
  1586   }
  1587 
  1588 #else
  1589 #define SWAPCARD32(l)   ((l) = bswap_32 (l))
  1590 #define SWAPCARD16(l)   ((l) = bswap_16 (l))
  1591 #endif
  1592 
  1593 typedef struct xm_targets_table_header
  1594 {
  1595   /* BYTE   */ uint8_t byte_order;
  1596   /* BYTE   */ uint8_t protocol;
  1597 
  1598   /* CARD16 */ uint16_t target_list_count;
  1599   /* CARD32 */ uint32_t total_data_size;
  1600 } xm_targets_table_header;
  1601 
  1602 typedef struct xm_targets_table_rec
  1603 {
  1604   /* CARD16 */ uint16_t n_targets;
  1605   /* CARD32 */ uint32_t targets[FLEXIBLE_ARRAY_MEMBER];
  1606 } xm_targets_table_rec;
  1607 
  1608 typedef struct xm_drop_start_message
  1609 {
  1610   /* BYTE   */ uint8_t reason;
  1611   /* BYTE   */ uint8_t byte_order;
  1612 
  1613   /* CARD16 */ uint16_t side_effects;
  1614   /* CARD32 */ uint32_t timestamp;
  1615   /* CARD16 */ uint16_t x, y;
  1616   /* CARD32 */ uint32_t index_atom;
  1617   /* CARD32 */ uint32_t source_window;
  1618 } xm_drop_start_message;
  1619 
  1620 typedef struct xm_drop_start_reply
  1621 {
  1622   /* BYTE   */ uint8_t reason;
  1623   /* BYTE   */ uint8_t byte_order;
  1624 
  1625   /* CARD16 */ uint16_t side_effects;
  1626   /* CARD16 */ uint16_t better_x;
  1627   /* CARD16 */ uint16_t better_y;
  1628 } xm_drop_start_reply;
  1629 
  1630 typedef struct xm_drag_initiator_info
  1631 {
  1632   /* BYTE   */ uint8_t byteorder;
  1633   /* BYTE   */ uint8_t protocol;
  1634 
  1635   /* CARD16 */ uint16_t table_index;
  1636   /* CARD32 */ uint32_t selection;
  1637 } xm_drag_initiator_info;
  1638 
  1639 typedef struct xm_drag_receiver_info
  1640 {
  1641   /* BYTE   */ uint8_t byteorder;
  1642   /* BYTE   */ uint8_t protocol;
  1643 
  1644   /* BYTE   */ uint8_t protocol_style;
  1645   /* BYTE   */ uint8_t unspecified0;
  1646   /* CARD32 */ uint32_t unspecified1;
  1647   /* CARD32 */ uint32_t unspecified2;
  1648   /* CARD32 */ uint32_t unspecified3;
  1649 } xm_drag_receiver_info;
  1650 
  1651 typedef struct xm_top_level_enter_message
  1652 {
  1653   /* BYTE   */ uint8_t reason;
  1654   /* BYTE   */ uint8_t byteorder;
  1655 
  1656   /* CARD16 */ uint16_t zero;
  1657   /* CARD32 */ uint32_t timestamp;
  1658   /* CARD32 */ uint32_t source_window;
  1659   /* CARD32 */ uint32_t index_atom;
  1660 } xm_top_level_enter_message;
  1661 
  1662 typedef struct xm_drag_motion_message
  1663 {
  1664   /* BYTE   */ uint8_t reason;
  1665   /* BYTE   */ uint8_t byteorder;
  1666 
  1667   /* CARD16 */ uint16_t side_effects;
  1668   /* CARD32 */ uint32_t timestamp;
  1669   /* CARD16 */ uint16_t x, y;
  1670 } xm_drag_motion_message;
  1671 
  1672 typedef struct xm_drag_motion_reply
  1673 {
  1674   /* BYTE   */ uint8_t reason;
  1675   /* BYTE   */ uint8_t byte_order;
  1676 
  1677   /* CARD16 */ uint16_t side_effects;
  1678   /* CARD32 */ uint32_t timestamp;
  1679   /* CARD16 */ uint16_t better_x;
  1680   /* CARD16 */ uint16_t better_y;
  1681 } xm_drag_motion_reply;
  1682 
  1683 typedef struct xm_top_level_leave_message
  1684 {
  1685   /* BYTE   */ uint8_t reason;
  1686   /* BYTE   */ uint8_t byteorder;
  1687 
  1688   /* CARD16 */ uint16_t zero;
  1689   /* CARD32 */ uint32_t timestamp;
  1690   /* CARD32 */ uint32_t source_window;
  1691 } xm_top_level_leave_message;
  1692 
  1693 #define XM_DRAG_SIDE_EFFECT(op, site, ops, act)         \
  1694   ((op) | ((site) << 4) | ((ops) << 8) | ((act) << 12))
  1695 
  1696 /* Some of the macros below are temporarily unused.  */
  1697 
  1698 #define XM_DRAG_SIDE_EFFECT_OPERATION(effect)   ((effect) & 0xf)
  1699 #define XM_DRAG_SIDE_EFFECT_SITE_STATUS(effect) (((effect) & 0xf0) >> 4)
  1700 /* #define XM_DRAG_SIDE_EFFECT_OPERATIONS(effect)       (((effect) & 0xf00) >> 8) */
  1701 #define XM_DRAG_SIDE_EFFECT_DROP_ACTION(effect) (((effect) & 0xf000) >> 12)
  1702 
  1703 enum xm_drag_operation
  1704   {
  1705     XM_DRAG_NOOP     = 0,
  1706     XM_DRAG_MOVE     = (1L << 0),
  1707     XM_DRAG_COPY     = (1L << 1),
  1708     XM_DRAG_LINK     = (1L << 2),
  1709     XM_DRAG_LINK_REC = 3,
  1710   };
  1711 
  1712 #define XM_DRAG_OPERATION_IS_LINK(op)   ((op) == XM_DRAG_LINK           \
  1713                                          || (op) == XM_DRAG_LINK_REC)
  1714 
  1715 enum xm_drag_action
  1716   {
  1717     XM_DROP_ACTION_DROP        = 0,
  1718     XM_DROP_ACTION_DROP_HELP   = 1,
  1719     XM_DROP_ACTION_DROP_CANCEL = 2,
  1720   };
  1721 
  1722 #define XM_DRAG_REASON(originator, code)        ((code) | ((originator) << 7))
  1723 #define XM_DRAG_REASON_ORIGINATOR(reason)       (((reason) & 0x80) ? 1 : 0)
  1724 #define XM_DRAG_REASON_CODE(reason)             ((reason) & 0x7f)
  1725 
  1726 enum xm_drag_reason
  1727   {
  1728     XM_DRAG_REASON_DROP_START      = 5,
  1729     XM_DRAG_REASON_TOP_LEVEL_ENTER = 0,
  1730     XM_DRAG_REASON_TOP_LEVEL_LEAVE = 1,
  1731     XM_DRAG_REASON_DRAG_MOTION     = 2,
  1732   };
  1733 
  1734 enum xm_drag_originator
  1735   {
  1736     XM_DRAG_ORIGINATOR_INITIATOR = 0,
  1737     XM_DRAG_ORIGINATOR_RECEIVER  = 1,
  1738   };
  1739 
  1740 enum xm_drag_style
  1741   {
  1742     /* The values ending with _REC should be treated as equivalent to
  1743        the ones without in messages from the receiver.  */
  1744     XM_DRAG_STYLE_NONE          = 0,
  1745     XM_DRAG_STYLE_DROP_ONLY     = 1,
  1746     XM_DRAG_STYLE_DROP_ONLY_REC = 3,
  1747     XM_DRAG_STYLE_DYNAMIC       = 5,
  1748     XM_DRAG_STYLE_DYNAMIC_REC   = 2,
  1749     XM_DRAG_STYLE_DYNAMIC_REC1  = 4,
  1750   };
  1751 
  1752 #define XM_DRAG_STYLE_IS_DROP_ONLY(n)   ((n) == XM_DRAG_STYLE_DROP_ONLY \
  1753                                          || (n) == XM_DRAG_STYLE_DROP_ONLY_REC)
  1754 #define XM_DRAG_STYLE_IS_DYNAMIC(n)     ((n) == XM_DRAG_STYLE_DYNAMIC   \
  1755                                          || (n) == XM_DRAG_STYLE_DYNAMIC_REC \
  1756                                          || (n) == XM_DRAG_STYLE_DYNAMIC_REC1)
  1757 
  1758 enum xm_drop_site_status
  1759   {
  1760     XM_DROP_SITE_VALID   = 3,
  1761     XM_DROP_SITE_INVALID = 2,
  1762     XM_DROP_SITE_NONE    = 1,
  1763   };
  1764 
  1765 /* The version of the Motif drag-and-drop protocols that Emacs
  1766    supports.  */
  1767 #define XM_DRAG_PROTOCOL_VERSION        0
  1768 
  1769 static uint8_t
  1770 xm_side_effect_from_action (struct x_display_info *dpyinfo, Atom action)
  1771 {
  1772   if (action == dpyinfo->Xatom_XdndActionCopy)
  1773     return XM_DRAG_COPY;
  1774   else if (action == dpyinfo->Xatom_XdndActionMove)
  1775     return XM_DRAG_MOVE;
  1776   else if (action == dpyinfo->Xatom_XdndActionLink)
  1777     return XM_DRAG_LINK;
  1778   else if (action == dpyinfo->Xatom_XdndActionAsk)
  1779     return x_dnd_first_motif_operation;
  1780 
  1781   return XM_DRAG_NOOP;
  1782 }
  1783 
  1784 static uint8_t
  1785 xm_operations_from_actions (struct x_display_info *dpyinfo,
  1786                             Atom *ask_actions, int n_ask_actions)
  1787 {
  1788   int i;
  1789   uint8_t flags;
  1790 
  1791   flags = 0;
  1792 
  1793   for (i = 0; i < n_ask_actions; ++i)
  1794     {
  1795       if (ask_actions[i] == dpyinfo->Xatom_XdndActionCopy)
  1796         flags |= XM_DRAG_COPY;
  1797       else if (ask_actions[i] == dpyinfo->Xatom_XdndActionMove)
  1798         flags |= XM_DRAG_MOVE;
  1799       else if (ask_actions[i] == dpyinfo->Xatom_XdndActionLink)
  1800         flags |= XM_DRAG_LINK;
  1801     }
  1802 
  1803   return flags;
  1804 }
  1805 
  1806 static int
  1807 xm_read_targets_table_header (uint8_t *bytes, ptrdiff_t length,
  1808                               xm_targets_table_header *header_return,
  1809                               xm_byte_order *byteorder_return)
  1810 {
  1811   if (length < 8)
  1812     return -1;
  1813 
  1814   header_return->byte_order = *byteorder_return = *(bytes++);
  1815   header_return->protocol = *(bytes++);
  1816 
  1817   header_return->target_list_count = *(uint16_t *) bytes;
  1818   header_return->total_data_size = *(uint32_t *) (bytes + 2);
  1819 
  1820   if (header_return->byte_order != XM_BYTE_ORDER_CUR_FIRST)
  1821     {
  1822       SWAPCARD16 (header_return->target_list_count);
  1823       SWAPCARD32 (header_return->total_data_size);
  1824     }
  1825 
  1826   header_return->byte_order = XM_BYTE_ORDER_CUR_FIRST;
  1827 
  1828   return 8;
  1829 }
  1830 
  1831 static xm_targets_table_rec *
  1832 xm_read_targets_table_rec (uint8_t *bytes, ptrdiff_t length,
  1833                            xm_byte_order byteorder)
  1834 {
  1835   uint16_t nitems, i;
  1836   xm_targets_table_rec *rec;
  1837 
  1838   if (length < 2)
  1839     return NULL;
  1840 
  1841   nitems = *(uint16_t *) bytes;
  1842 
  1843   if (byteorder != XM_BYTE_ORDER_CUR_FIRST)
  1844     SWAPCARD16 (nitems);
  1845 
  1846   if (length < 2 + nitems * 4)
  1847     return NULL;
  1848 
  1849   rec = xmalloc (FLEXSIZEOF (struct xm_targets_table_rec,
  1850                              targets, nitems * 4));
  1851   rec->n_targets = nitems;
  1852 
  1853   for (i = 0; i < nitems; ++i)
  1854     {
  1855       rec->targets[i] = ((uint32_t *) (bytes + 2))[i];
  1856 
  1857       if (byteorder != XM_BYTE_ORDER_CUR_FIRST)
  1858         SWAPCARD32 (rec->targets[i]);
  1859     }
  1860 
  1861   return rec;
  1862 }
  1863 
  1864 static int
  1865 xm_find_targets_table_idx (xm_targets_table_header *header,
  1866                            xm_targets_table_rec **recs,
  1867                            Atom *sorted_targets, int ntargets)
  1868 {
  1869   int j;
  1870   uint16_t i;
  1871   uint32_t *targets;
  1872 
  1873   targets = alloca (sizeof *targets * ntargets);
  1874 
  1875   for (j = 0; j < ntargets; ++j)
  1876     targets[j] = sorted_targets[j];
  1877 
  1878   for (i = 0; i < header->target_list_count; ++i)
  1879     {
  1880       if (recs[i]->n_targets == ntargets
  1881           && !memcmp (&recs[i]->targets, targets,
  1882                       sizeof *targets * ntargets))
  1883         return i;
  1884     }
  1885 
  1886   return -1;
  1887 }
  1888 
  1889 static int
  1890 x_atoms_compare (const void *a, const void *b)
  1891 {
  1892   return *(Atom *) a - *(Atom *) b;
  1893 }
  1894 
  1895 static void
  1896 xm_write_targets_table (Display *dpy, Window wdesc,
  1897                         Atom targets_table_atom,
  1898                         xm_targets_table_header *header,
  1899                         xm_targets_table_rec **recs)
  1900 {
  1901   uint8_t *header_buffer, *ptr, *rec_buffer;
  1902   ptrdiff_t rec_buffer_size;
  1903   uint16_t i, j;
  1904 
  1905   header_buffer = alloca (8);
  1906   ptr = header_buffer;
  1907 
  1908   *(header_buffer++) = header->byte_order;
  1909   *(header_buffer++) = header->protocol;
  1910   *((uint16_t *) header_buffer) = header->target_list_count;
  1911   *((uint32_t *) (header_buffer + 2)) = header->total_data_size;
  1912 
  1913   rec_buffer = xmalloc (600);
  1914   rec_buffer_size = 600;
  1915 
  1916   XChangeProperty (dpy, wdesc, targets_table_atom,
  1917                    targets_table_atom, 8, PropModeReplace,
  1918                    (unsigned char *) ptr, 8);
  1919 
  1920   for (i = 0; i < header->target_list_count; ++i)
  1921     {
  1922       if (rec_buffer_size < 2 + recs[i]->n_targets * 4)
  1923         {
  1924           rec_buffer_size = 2 + recs[i]->n_targets * 4;
  1925           rec_buffer = xrealloc (rec_buffer, rec_buffer_size);
  1926         }
  1927 
  1928       *((uint16_t *) rec_buffer) = recs[i]->n_targets;
  1929 
  1930       for (j = 0; j < recs[i]->n_targets; ++j)
  1931         ((uint32_t *) (rec_buffer + 2))[j] = recs[i]->targets[j];
  1932 
  1933       XChangeProperty (dpy, wdesc, targets_table_atom,
  1934                        targets_table_atom, 8, PropModeAppend,
  1935                        (unsigned char *) rec_buffer,
  1936                        2 + recs[i]->n_targets * 4);
  1937     }
  1938 
  1939   xfree (rec_buffer);
  1940 }
  1941 
  1942 static void
  1943 xm_write_drag_initiator_info (Display *dpy, Window wdesc,
  1944                               Atom prop_name, Atom type_name,
  1945                               xm_drag_initiator_info *info)
  1946 {
  1947   uint8_t *buf;
  1948 
  1949   buf = alloca (8);
  1950   buf[0] = info->byteorder;
  1951   buf[1] = info->protocol;
  1952 
  1953   if (info->byteorder != XM_BYTE_ORDER_CUR_FIRST)
  1954     {
  1955       SWAPCARD16 (info->table_index);
  1956       SWAPCARD16 (info->selection);
  1957     }
  1958 
  1959   *((uint16_t *) (buf + 2)) = info->table_index;
  1960   *((uint32_t *) (buf + 4)) = info->selection;
  1961 
  1962   XChangeProperty (dpy, wdesc, prop_name, type_name, 8,
  1963                    PropModeReplace, (unsigned char *) buf, 8);
  1964 }
  1965 
  1966 static int
  1967 xm_drag_window_error_handler (Display *display, XErrorEvent *event)
  1968 {
  1969   if (xm_drag_window_error)
  1970     *xm_drag_window_error = true;
  1971 
  1972   return 0;
  1973 }
  1974 
  1975 static _Noreturn int
  1976 xm_drag_window_io_error_handler (Display *dpy)
  1977 {
  1978   /* DPY isn't created through GDK, so it doesn't matter if we don't
  1979      crash here.  */
  1980   siglongjmp (x_dnd_disconnect_handler, 1);
  1981 }
  1982 
  1983 /* Determine whether or not WINDOW exists on DPYINFO by selecting for
  1984    input from it.  */
  1985 static bool
  1986 x_special_window_exists_p (struct x_display_info *dpyinfo,
  1987                            Window window)
  1988 {
  1989   bool rc;
  1990 
  1991   x_catch_errors (dpyinfo->display);
  1992   XSelectInput (dpyinfo->display, window,
  1993                 StructureNotifyMask);
  1994   rc = !x_had_errors_p (dpyinfo->display);
  1995   x_uncatch_errors_after_check ();
  1996 
  1997   return rc;
  1998 }
  1999 
  2000 /* Drag window creation strategy (very tricky, but race-free):
  2001 
  2002    First look for _MOTIF_DRAG_WINDOW.  If it is already present,
  2003    return it immediately to avoid the overhead of new display
  2004    connections.
  2005 
  2006    Otherwise, create a new connection to the display. In that
  2007    connection, create a window, which will be the new drag window. Set
  2008    the client disconnect mode of the new connection to
  2009    RetainPermanent, and close it.
  2010 
  2011    Grab the current display.  Look up _MOTIF_DRAG_WINDOW, the current
  2012    drag window.  If it exists (which means _MOTIF_DRAG_WINDOW was
  2013    created between the first step and now), kill the client that
  2014    created the new drag window to free the client slot on the X
  2015    server.  Otherwise, set _MOTIF_DRAG_WINDOW to the new drag window.
  2016 
  2017    Ungrab the display and return whichever window is currently in
  2018    _MOTIF_DRAG_WINDOW.  */
  2019 
  2020 static Window
  2021 xm_get_drag_window_1 (struct x_display_info *dpyinfo)
  2022 {
  2023   Atom actual_type;
  2024   int rc, actual_format;
  2025   unsigned long nitems, bytes_remaining;
  2026   unsigned char *tmp_data = NULL;
  2027   Window drag_window;
  2028   XSetWindowAttributes attrs;
  2029   Display *temp_display;
  2030   Emacs_XErrorHandler old_handler;
  2031   Emacs_XIOErrorHandler old_io_handler;
  2032 
  2033   /* This is volatile because GCC mistakenly warns about them being
  2034      clobbered by longjmp.  */
  2035   volatile bool error;
  2036 
  2037   drag_window = None;
  2038   rc = XGetWindowProperty (dpyinfo->display, dpyinfo->root_window,
  2039                            dpyinfo->Xatom_MOTIF_DRAG_WINDOW,
  2040                            0, 1, False, XA_WINDOW, &actual_type,
  2041                            &actual_format, &nitems, &bytes_remaining,
  2042                            &tmp_data) == Success;
  2043 
  2044   if (rc && actual_type == XA_WINDOW
  2045       && actual_format == 32 && nitems == 1
  2046       && tmp_data)
  2047     {
  2048       drag_window = *(Window *) tmp_data;
  2049 
  2050       /* This has the side effect of selecting for
  2051          StructureNotifyMask, meaning that we will get notifications
  2052          once it is deleted.  */
  2053       rc = x_special_window_exists_p (dpyinfo, drag_window);
  2054 
  2055       if (!rc)
  2056         drag_window = None;
  2057     }
  2058 
  2059   if (tmp_data)
  2060     XFree (tmp_data);
  2061 
  2062   if (drag_window == None)
  2063     {
  2064       block_input ();
  2065       old_io_handler = XSetIOErrorHandler (xm_drag_window_io_error_handler);
  2066 
  2067       if (sigsetjmp (x_dnd_disconnect_handler, 1))
  2068         {
  2069           XSetIOErrorHandler (old_io_handler);
  2070           unblock_input ();
  2071 
  2072           return None;
  2073         }
  2074 
  2075       unrequest_sigio ();
  2076       temp_display = XOpenDisplay (XDisplayString (dpyinfo->display));
  2077       request_sigio ();
  2078 
  2079       if (!temp_display)
  2080         {
  2081           XSetIOErrorHandler (old_io_handler);
  2082           unblock_input ();
  2083 
  2084           return None;
  2085         }
  2086 
  2087       error = false;
  2088       xm_drag_window_error = &error;
  2089 
  2090       XSetCloseDownMode (temp_display, RetainPermanent);
  2091       old_handler = XSetErrorHandler (xm_drag_window_error_handler);
  2092 
  2093       attrs.override_redirect = True;
  2094       drag_window = XCreateWindow (temp_display, DefaultRootWindow (temp_display),
  2095                                    -1, -1, 1, 1, 0, CopyFromParent, InputOnly,
  2096                                    CopyFromParent, CWOverrideRedirect, &attrs);
  2097 
  2098       /* Handle all errors now.   */
  2099       XSync (temp_display, False);
  2100 
  2101       /* Some part of the drag window creation process failed, so
  2102          punt.  Release all resources too.  */
  2103       if (error)
  2104         {
  2105           XSetCloseDownMode (temp_display, DestroyAll);
  2106           drag_window = None;
  2107         }
  2108 
  2109       xm_drag_window_error = NULL;
  2110 
  2111       /* FIXME: why does XCloseDisplay hang if SIGIO arrives and there
  2112          are multiple displays? */
  2113       unrequest_sigio ();
  2114       XCloseDisplay (temp_display);
  2115       request_sigio ();
  2116 
  2117       XSetErrorHandler (old_handler);
  2118       XSetIOErrorHandler (old_io_handler);
  2119 
  2120       /* Make sure the drag window created is actually valid for the
  2121          current display, and the XOpenDisplay above didn't
  2122          accidentally connect to some other display.  */
  2123       if (!x_special_window_exists_p (dpyinfo, drag_window))
  2124         drag_window = None;
  2125       unblock_input ();
  2126 
  2127       if (drag_window != None)
  2128         {
  2129           XGrabServer (dpyinfo->display);
  2130 
  2131           x_catch_errors (dpyinfo->display);
  2132           tmp_data = NULL;
  2133 
  2134           rc = XGetWindowProperty (dpyinfo->display, dpyinfo->root_window,
  2135                                    dpyinfo->Xatom_MOTIF_DRAG_WINDOW,
  2136                                    0, 1, False, XA_WINDOW, &actual_type,
  2137                                    &actual_format, &nitems, &bytes_remaining,
  2138                                    &tmp_data) == Success;
  2139 
  2140           if (rc && actual_type == XA_WINDOW
  2141               && actual_format == 32 && nitems == 1
  2142               && tmp_data
  2143               && x_special_window_exists_p (dpyinfo,
  2144                                             *(Window *) tmp_data))
  2145             {
  2146               /* Kill the client now to avoid leaking a client slot,
  2147                  which is a limited resource.  */
  2148               XKillClient (dpyinfo->display, drag_window);
  2149               drag_window = *(Window *) tmp_data;
  2150             }
  2151           else
  2152             XChangeProperty (dpyinfo->display, dpyinfo->root_window,
  2153                              dpyinfo->Xatom_MOTIF_DRAG_WINDOW,
  2154                              XA_WINDOW, 32, PropModeReplace,
  2155                              (unsigned char *) &drag_window, 1);
  2156 
  2157           if (tmp_data)
  2158             XFree (tmp_data);
  2159 
  2160           if (x_had_errors_p (dpyinfo->display))
  2161             drag_window = None;
  2162           x_uncatch_errors ();
  2163 
  2164           XUngrabServer (dpyinfo->display);
  2165         }
  2166     }
  2167 
  2168   return drag_window;
  2169 }
  2170 
  2171 static Window
  2172 xm_get_drag_window (struct x_display_info *dpyinfo)
  2173 {
  2174   if (dpyinfo->motif_drag_window != None)
  2175     return dpyinfo->motif_drag_window;
  2176 
  2177   dpyinfo->motif_drag_window = xm_get_drag_window_1 (dpyinfo);
  2178   return dpyinfo->motif_drag_window;
  2179 }
  2180 
  2181 static int
  2182 xm_setup_dnd_targets (struct x_display_info *dpyinfo,
  2183                       Atom *targets, int ntargets)
  2184 {
  2185   Window drag_window;
  2186   Atom *targets_sorted, actual_type;
  2187   unsigned char *tmp_data = NULL;
  2188   unsigned long nitems, bytes_remaining;
  2189   int rc, actual_format, idx;
  2190   bool had_errors;
  2191   xm_targets_table_header header;
  2192   xm_targets_table_rec **recs UNINIT;
  2193   xm_byte_order byteorder;
  2194   uint8_t *data;
  2195   ptrdiff_t total_bytes, total_items, i;
  2196   uint32_t size, target_count;
  2197 
  2198  retry_drag_window:
  2199 
  2200   drag_window = xm_get_drag_window (dpyinfo);
  2201 
  2202   if (drag_window == None || ntargets > 64)
  2203     return -1;
  2204 
  2205   targets_sorted = xmalloc (sizeof *targets * ntargets);
  2206   memcpy (targets_sorted, targets,
  2207           sizeof *targets * ntargets);
  2208   qsort (targets_sorted, ntargets,
  2209          sizeof (Atom), x_atoms_compare);
  2210 
  2211   XGrabServer (dpyinfo->display);
  2212 
  2213   x_catch_errors (dpyinfo->display);
  2214   rc = XGetWindowProperty (dpyinfo->display, drag_window,
  2215                            dpyinfo->Xatom_MOTIF_DRAG_TARGETS,
  2216                            0L, LONG_MAX, False,
  2217                            dpyinfo->Xatom_MOTIF_DRAG_TARGETS,
  2218                            &actual_type, &actual_format, &nitems,
  2219                            &bytes_remaining, &tmp_data) == Success;
  2220   had_errors = x_had_errors_p (dpyinfo->display);
  2221   x_uncatch_errors_after_check ();
  2222 
  2223   /* The drag window is probably invalid, so remove our record of
  2224      it.  */
  2225   if (had_errors)
  2226     {
  2227       dpyinfo->motif_drag_window = None;
  2228       XUngrabServer (dpyinfo->display);
  2229 
  2230       goto retry_drag_window;
  2231     }
  2232 
  2233   if (rc && tmp_data && !bytes_remaining
  2234       && actual_type == dpyinfo->Xatom_MOTIF_DRAG_TARGETS
  2235       && actual_format == 8)
  2236     {
  2237       data = (uint8_t *) tmp_data;
  2238       if (xm_read_targets_table_header ((uint8_t *) tmp_data,
  2239                                         nitems, &header,
  2240                                         &byteorder) == 8)
  2241         {
  2242           data += 8;
  2243           nitems -= 8;
  2244           total_bytes = 0;
  2245           total_items = 0;
  2246 
  2247           /* The extra rec is used to store a new target list if a
  2248              preexisting one doesn't already exist.  */
  2249           recs = xmalloc ((header.target_list_count + 1)
  2250                           * sizeof *recs);
  2251 
  2252           while (total_items < header.target_list_count)
  2253             {
  2254               recs[total_items] = xm_read_targets_table_rec (data + total_bytes,
  2255                                                              nitems, byteorder);
  2256 
  2257               if (!recs[total_items])
  2258                 break;
  2259 
  2260               total_bytes += 2 + recs[total_items]->n_targets * 4;
  2261               nitems -= 2 + recs[total_items]->n_targets * 4;
  2262               total_items++;
  2263             }
  2264 
  2265           if (header.target_list_count != total_items
  2266               || header.total_data_size != 8 + total_bytes)
  2267             {
  2268               for (i = 0; i < total_items; ++i)
  2269                 {
  2270                   if (recs[i])
  2271                       xfree (recs[i]);
  2272                   else
  2273                     break;
  2274                 }
  2275 
  2276               xfree (recs);
  2277 
  2278               rc = false;
  2279             }
  2280         }
  2281       else
  2282         rc = false;
  2283     }
  2284   else
  2285     rc = false;
  2286 
  2287   if (tmp_data)
  2288     XFree (tmp_data);
  2289 
  2290   /* Now rc means whether or not the target lists weren't updated and
  2291      shouldn't be written to the drag window.  */
  2292 
  2293   if (!rc)
  2294     {
  2295       header.byte_order = XM_BYTE_ORDER_CUR_FIRST;
  2296       header.protocol = XM_DRAG_PROTOCOL_VERSION;
  2297       header.target_list_count = 1;
  2298       header.total_data_size = 8 + 2 + ntargets * 4;
  2299 
  2300       recs = xmalloc (sizeof *recs);
  2301       recs[0] = xmalloc (FLEXSIZEOF (struct xm_targets_table_rec,
  2302                                      targets, ntargets * 4));
  2303 
  2304       recs[0]->n_targets = ntargets;
  2305 
  2306       for (i = 0; i < ntargets; ++i)
  2307         recs[0]->targets[i] = targets_sorted[i];
  2308 
  2309       idx = 0;
  2310     }
  2311   else
  2312     {
  2313       idx = xm_find_targets_table_idx (&header, recs,
  2314                                        targets_sorted,
  2315                                        ntargets);
  2316 
  2317       if (idx == -1)
  2318         {
  2319           target_count = header.target_list_count;
  2320           rc = false;
  2321 
  2322           if (ckd_add (&header.target_list_count, header.target_list_count, 1)
  2323               || ckd_mul (&size, ntargets, 4)
  2324               || ckd_add (&header.total_data_size, header.total_data_size, size)
  2325               || ckd_add (&header.total_data_size, header.total_data_size, 2))
  2326             {
  2327               /* Overflow, remove every entry from the targets table
  2328                  and add one for our current targets list.  This
  2329                  confuses real Motif but not GTK 2.x, and there is no
  2330                  other choice.  */
  2331 
  2332               for (i = 0; i < target_count; ++i)
  2333                 xfree (recs[i]);
  2334 
  2335               xfree (recs);
  2336 
  2337               header.byte_order = XM_BYTE_ORDER_CUR_FIRST;
  2338               header.protocol = XM_DRAG_PROTOCOL_VERSION;
  2339               header.target_list_count = 1;
  2340               header.total_data_size = 8 + 2 + ntargets * 4;
  2341 
  2342               recs = xmalloc (sizeof *recs);
  2343               recs[0] = xmalloc (FLEXSIZEOF (struct xm_targets_table_rec,
  2344                                              targets, ntargets * 4));
  2345 
  2346               recs[0]->n_targets = ntargets;
  2347 
  2348               for (i = 0; i < ntargets; ++i)
  2349                 recs[0]->targets[i] = targets_sorted[i];
  2350 
  2351               idx = 0;
  2352             }
  2353           else
  2354             {
  2355               recs[header.target_list_count - 1]
  2356                 = xmalloc (FLEXSIZEOF (struct xm_targets_table_rec,
  2357                                        targets, ntargets * 4));
  2358               recs[header.target_list_count - 1]->n_targets = ntargets;
  2359 
  2360               for (i = 0; i < ntargets; ++i)
  2361                 recs[header.target_list_count - 1]->targets[i] = targets_sorted[i];
  2362 
  2363               idx = header.target_list_count - 1;
  2364             }
  2365         }
  2366     }
  2367 
  2368   if (!rc)
  2369     {
  2370       /* Some implementations of Motif DND set the protocol version of
  2371          just the targets table to 1 without actually changing the
  2372          data format.  To avoid confusing Motif when that happens, set
  2373          it back to 0.  There will probably be no more updates to the
  2374          protocol either.  */
  2375       header.protocol = XM_DRAG_PROTOCOL_VERSION;
  2376 
  2377       x_catch_errors (dpyinfo->display);
  2378       xm_write_targets_table (dpyinfo->display, drag_window,
  2379                               dpyinfo->Xatom_MOTIF_DRAG_TARGETS,
  2380                               &header, recs);
  2381       /* Presumably we got a BadAlloc upon writing the targets
  2382          table.  */
  2383       if (x_had_errors_p (dpyinfo->display))
  2384         idx = -1;
  2385       x_uncatch_errors_after_check ();
  2386     }
  2387 
  2388   XUngrabServer (dpyinfo->display);
  2389 
  2390   for (i = 0; i < header.target_list_count; ++i)
  2391     xfree (recs[i]);
  2392 
  2393   xfree (recs);
  2394   xfree (targets_sorted);
  2395 
  2396   return idx;
  2397 }
  2398 
  2399 /* Allocate an atom that will be used for the Motif selection during
  2400    the drag-and-drop operation.
  2401 
  2402    Grab the server, and then retrieve a list of atoms named
  2403    _EMACS_DRAG_ATOM from the root window.  Find the first atom that
  2404    has no selection owner, own it and return it.  If there is no such
  2405    atom, add a unique atom to the end of the list and return that
  2406    instead.  */
  2407 
  2408 static Atom
  2409 xm_get_drag_atom_1 (struct x_display_info *dpyinfo,
  2410                     struct frame *source_frame)
  2411 {
  2412   Atom actual_type, *atoms, atom;
  2413   unsigned long nitems, bytes_remaining;
  2414   unsigned char *tmp_data;
  2415   int rc, actual_format;
  2416   unsigned long i;
  2417   char *buffer;
  2418   Window owner;
  2419 
  2420   /* Make sure this operation is done atomically.  */
  2421   XGrabServer (dpyinfo->display);
  2422 
  2423   rc = XGetWindowProperty (dpyinfo->display, dpyinfo->root_window,
  2424                            dpyinfo->Xatom_EMACS_DRAG_ATOM,
  2425                            0, LONG_MAX, False, XA_ATOM, &actual_type,
  2426                            &actual_format, &nitems, &bytes_remaining,
  2427                            &tmp_data);
  2428   atom = None;
  2429   /* GCC thinks i is used uninitialized, but it's always initialized if
  2430      `atoms' exists at that particular spot.  */
  2431   i = 0;
  2432 
  2433   if (rc == Success
  2434       && actual_format == 32 && nitems
  2435       && actual_type == XA_ATOM)
  2436     {
  2437       atoms = (Atom *) tmp_data;
  2438 
  2439       x_catch_errors (dpyinfo->display);
  2440 
  2441       for (i = 0; i < nitems; ++i)
  2442         {
  2443           owner = XGetSelectionOwner (dpyinfo->display, atoms[i]);
  2444 
  2445           if (!x_had_errors_p (dpyinfo->display)
  2446               && (owner == None
  2447                   /* If we already own this selection (even if another
  2448                      frame owns it), use it.  There is no way of
  2449                      knowing when ownership was asserted, so it still
  2450                      has to be owned again.  */
  2451                   || x_window_to_frame (dpyinfo, owner)))
  2452             {
  2453               atom = atoms[i];
  2454 
  2455               break;
  2456             }
  2457         }
  2458 
  2459       x_uncatch_errors ();
  2460     }
  2461 
  2462   if (tmp_data)
  2463     XFree (tmp_data);
  2464 
  2465   buffer = dpyinfo->motif_drag_atom_name;
  2466 
  2467   if (atom)
  2468     {
  2469       sprintf (buffer, "_EMACS_ATOM_%lu", i + 1);
  2470       XSetSelectionOwner (dpyinfo->display, atom,
  2471                           FRAME_X_WINDOW (source_frame),
  2472                           dpyinfo->last_user_time);
  2473 
  2474       /* The selection's last-change time is newer than our
  2475          last_user_time, so create a new selection instead.  */
  2476       if (XGetSelectionOwner (dpyinfo->display, atom)
  2477           != FRAME_X_WINDOW (source_frame))
  2478         atom = None;
  2479     }
  2480 
  2481   while (!atom)
  2482     {
  2483       sprintf (buffer, "_EMACS_ATOM_%lu", nitems + 1);
  2484       atom = XInternAtom (dpyinfo->display, buffer, False);
  2485 
  2486       XSetSelectionOwner (dpyinfo->display, atom,
  2487                           FRAME_X_WINDOW (source_frame),
  2488                           dpyinfo->last_user_time);
  2489 
  2490       XChangeProperty (dpyinfo->display, dpyinfo->root_window,
  2491                        dpyinfo->Xatom_EMACS_DRAG_ATOM, XA_ATOM, 32,
  2492                        (rc != Success
  2493                         || (actual_format != 32
  2494                             || actual_type != XA_ATOM)
  2495                         ? PropModeReplace : PropModeAppend),
  2496                        (unsigned char *) &atom, 1);
  2497 
  2498       actual_format = 32;
  2499       actual_type = XA_ATOM;
  2500       rc = Success;
  2501       nitems += 1;
  2502 
  2503       /* The selection's last-change time is newer than our
  2504          last_user_time, so create a new selection (again).  */
  2505       if (XGetSelectionOwner (dpyinfo->display, atom)
  2506           != FRAME_X_WINDOW (source_frame))
  2507         atom = None;
  2508     }
  2509 
  2510   dpyinfo->motif_drag_atom_time = dpyinfo->last_user_time;
  2511   dpyinfo->motif_drag_atom_owner = source_frame;
  2512 
  2513   XUngrabServer (dpyinfo->display);
  2514   return atom;
  2515 }
  2516 
  2517 static Atom
  2518 xm_get_drag_atom (struct x_display_info *dpyinfo)
  2519 {
  2520   Atom atom;
  2521 
  2522   if (dpyinfo->motif_drag_atom != None)
  2523     atom = dpyinfo->motif_drag_atom;
  2524   else
  2525     atom = xm_get_drag_atom_1 (dpyinfo, x_dnd_frame);
  2526 
  2527   dpyinfo->motif_drag_atom = atom;
  2528   return atom;
  2529 }
  2530 
  2531 static void
  2532 xm_setup_drag_info (struct x_display_info *dpyinfo,
  2533                     struct frame *source_frame)
  2534 {
  2535   Atom atom;
  2536   xm_drag_initiator_info drag_initiator_info;
  2537   int idx;
  2538 
  2539   atom = xm_get_drag_atom (dpyinfo);
  2540 
  2541   if (atom == None)
  2542     return;
  2543 
  2544   XSETCAR (x_dnd_selection_alias_cell,
  2545            x_atom_to_symbol (dpyinfo, atom));
  2546   XSETCDR (x_dnd_selection_alias_cell, QXdndSelection);
  2547 
  2548   idx = xm_setup_dnd_targets (dpyinfo, x_dnd_targets,
  2549                               x_dnd_n_targets);
  2550 
  2551   if (idx != -1)
  2552     {
  2553       drag_initiator_info.byteorder = XM_BYTE_ORDER_CUR_FIRST;
  2554       drag_initiator_info.protocol = XM_DRAG_PROTOCOL_VERSION;
  2555       drag_initiator_info.table_index = idx;
  2556       drag_initiator_info.selection = atom;
  2557 
  2558       xm_write_drag_initiator_info (dpyinfo->display,
  2559                                     FRAME_X_WINDOW (source_frame), atom,
  2560                                     dpyinfo->Xatom_MOTIF_DRAG_INITIATOR_INFO,
  2561                                     &drag_initiator_info);
  2562 
  2563       x_dnd_motif_setup_p = true;
  2564       x_dnd_motif_atom = atom;
  2565     }
  2566 }
  2567 
  2568 static void
  2569 xm_send_drop_message (struct x_display_info *dpyinfo, Window source,
  2570                       Window target, xm_drop_start_message *dmsg)
  2571 {
  2572   XEvent msg;
  2573 
  2574   msg.xclient.type = ClientMessage;
  2575   msg.xclient.message_type
  2576     = dpyinfo->Xatom_MOTIF_DRAG_AND_DROP_MESSAGE;
  2577   msg.xclient.format = 8;
  2578   msg.xclient.window = target;
  2579   msg.xclient.data.b[0] = dmsg->reason;
  2580   msg.xclient.data.b[1] = dmsg->byte_order;
  2581   *((uint16_t *) &msg.xclient.data.b[2]) = dmsg->side_effects;
  2582   *((uint32_t *) &msg.xclient.data.b[4]) = dmsg->timestamp;
  2583   *((uint16_t *) &msg.xclient.data.b[8]) = dmsg->x;
  2584   *((uint16_t *) &msg.xclient.data.b[10]) = dmsg->y;
  2585   *((uint32_t *) &msg.xclient.data.b[12]) = dmsg->index_atom;
  2586   *((uint32_t *) &msg.xclient.data.b[16]) = dmsg->source_window;
  2587 
  2588   x_ignore_errors_for_next_request (dpyinfo, 0);
  2589   XSendEvent (dpyinfo->display, target, False, NoEventMask, &msg);
  2590   x_stop_ignoring_errors (dpyinfo);
  2591 }
  2592 
  2593 static void
  2594 xm_send_top_level_enter_message (struct x_display_info *dpyinfo, Window source,
  2595                                  Window target, xm_top_level_enter_message *dmsg)
  2596 {
  2597   XEvent msg;
  2598 
  2599   msg.xclient.type = ClientMessage;
  2600   msg.xclient.message_type
  2601     = dpyinfo->Xatom_MOTIF_DRAG_AND_DROP_MESSAGE;
  2602   msg.xclient.format = 8;
  2603   msg.xclient.window = target;
  2604   msg.xclient.data.b[0] = dmsg->reason;
  2605   msg.xclient.data.b[1] = dmsg->byteorder;
  2606   *((uint16_t *) &msg.xclient.data.b[2]) = dmsg->zero;
  2607   *((uint32_t *) &msg.xclient.data.b[4]) = dmsg->timestamp;
  2608   *((uint32_t *) &msg.xclient.data.b[8]) = dmsg->source_window;
  2609   *((uint32_t *) &msg.xclient.data.b[12]) = dmsg->index_atom;
  2610   msg.xclient.data.b[16] = 0;
  2611   msg.xclient.data.b[17] = 0;
  2612   msg.xclient.data.b[18] = 0;
  2613   msg.xclient.data.b[19] = 0;
  2614 
  2615   x_ignore_errors_for_next_request (dpyinfo, 0);
  2616   XSendEvent (dpyinfo->display, target, False, NoEventMask, &msg);
  2617   x_stop_ignoring_errors (dpyinfo);
  2618 }
  2619 
  2620 static void
  2621 xm_send_drag_motion_message (struct x_display_info *dpyinfo, Window source,
  2622                              Window target, xm_drag_motion_message *dmsg)
  2623 {
  2624   XEvent msg;
  2625 
  2626   msg.xclient.type = ClientMessage;
  2627   msg.xclient.message_type
  2628     = dpyinfo->Xatom_MOTIF_DRAG_AND_DROP_MESSAGE;
  2629   msg.xclient.format = 8;
  2630   msg.xclient.window = target;
  2631   msg.xclient.data.b[0] = dmsg->reason;
  2632   msg.xclient.data.b[1] = dmsg->byteorder;
  2633   *((uint16_t *) &msg.xclient.data.b[2]) = dmsg->side_effects;
  2634   *((uint32_t *) &msg.xclient.data.b[4]) = dmsg->timestamp;
  2635   *((uint16_t *) &msg.xclient.data.b[8]) = dmsg->x;
  2636   *((uint16_t *) &msg.xclient.data.b[10]) = dmsg->y;
  2637   msg.xclient.data.b[12] = 0;
  2638   msg.xclient.data.b[13] = 0;
  2639   msg.xclient.data.b[14] = 0;
  2640   msg.xclient.data.b[15] = 0;
  2641   msg.xclient.data.b[16] = 0;
  2642   msg.xclient.data.b[17] = 0;
  2643   msg.xclient.data.b[18] = 0;
  2644   msg.xclient.data.b[19] = 0;
  2645 
  2646   x_ignore_errors_for_next_request (dpyinfo, 0);
  2647   XSendEvent (dpyinfo->display, target, False, NoEventMask, &msg);
  2648   x_stop_ignoring_errors (dpyinfo);
  2649 }
  2650 
  2651 static void
  2652 xm_send_top_level_leave_message (struct x_display_info *dpyinfo, Window source,
  2653                                  Window target, xm_top_level_leave_message *dmsg)
  2654 {
  2655   XEvent msg;
  2656   xm_drag_motion_message mmsg;
  2657 
  2658   /* Motif support for TOP_LEVEL_LEAVE has bitrotted, since these days
  2659      it assumes every client supports the preregister protocol style,
  2660      but we only support drop-only and dynamic.  (Interestingly enough
  2661      LessTif works fine.)  Sending an event with impossible
  2662      coordinates serves to get rid of any active drop site that might
  2663      still be around in the target drag context.  */
  2664 
  2665   if (x_dnd_fix_motif_leave)
  2666     {
  2667       mmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
  2668                                     XM_DRAG_REASON_DRAG_MOTION);
  2669       mmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
  2670       mmsg.side_effects = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo,
  2671                                                                            x_dnd_wanted_action),
  2672                                                XM_DROP_SITE_NONE, x_dnd_motif_operations,
  2673                                                XM_DROP_ACTION_DROP_CANCEL);
  2674       mmsg.timestamp = dmsg->timestamp;
  2675 
  2676       /* Use X_SHRT_MAX instead of the max value of uint16_t since
  2677          that will be interpreted as a plausible position by Motif,
  2678          and as such breaks if the drop target is beneath that
  2679          position.  */
  2680       mmsg.x = X_SHRT_MAX;
  2681       mmsg.y = X_SHRT_MAX;
  2682 
  2683       xm_send_drag_motion_message (dpyinfo, source, target, &mmsg);
  2684     }
  2685 
  2686   msg.xclient.type = ClientMessage;
  2687   msg.xclient.message_type
  2688     = dpyinfo->Xatom_MOTIF_DRAG_AND_DROP_MESSAGE;
  2689   msg.xclient.format = 8;
  2690   msg.xclient.window = target;
  2691   msg.xclient.data.b[0] = dmsg->reason;
  2692   msg.xclient.data.b[1] = dmsg->byteorder;
  2693   *((uint16_t *) &msg.xclient.data.b[2]) = dmsg->zero;
  2694   *((uint32_t *) &msg.xclient.data.b[4]) = dmsg->timestamp;
  2695   *((uint32_t *) &msg.xclient.data.b[8]) = dmsg->source_window;
  2696   msg.xclient.data.b[12] = 0;
  2697   msg.xclient.data.b[13] = 0;
  2698   msg.xclient.data.b[14] = 0;
  2699   msg.xclient.data.b[15] = 0;
  2700   msg.xclient.data.b[16] = 0;
  2701   msg.xclient.data.b[17] = 0;
  2702   msg.xclient.data.b[18] = 0;
  2703   msg.xclient.data.b[19] = 0;
  2704 
  2705   x_ignore_errors_for_next_request (dpyinfo, 0);
  2706   XSendEvent (dpyinfo->display, target, False, NoEventMask, &msg);
  2707   x_stop_ignoring_errors (dpyinfo);
  2708 }
  2709 
  2710 static int
  2711 xm_read_drop_start_reply (const XEvent *msg, xm_drop_start_reply *reply)
  2712 {
  2713   const uint8_t *data;
  2714 
  2715   data = (const uint8_t *) &msg->xclient.data.b[0];
  2716 
  2717   if ((XM_DRAG_REASON_ORIGINATOR (data[0])
  2718        != XM_DRAG_ORIGINATOR_RECEIVER)
  2719       || (XM_DRAG_REASON_CODE (data[0])
  2720           != XM_DRAG_REASON_DROP_START))
  2721     return 1;
  2722 
  2723   reply->reason = *(data++);
  2724   reply->byte_order = *(data++);
  2725   reply->side_effects = *(uint16_t *) data;
  2726   reply->better_x = *(uint16_t *) (data + 2);
  2727   reply->better_y = *(uint16_t *) (data + 4);
  2728 
  2729   if (reply->byte_order != XM_BYTE_ORDER_CUR_FIRST)
  2730     {
  2731       SWAPCARD16 (reply->side_effects);
  2732       SWAPCARD16 (reply->better_x);
  2733       SWAPCARD16 (reply->better_y);
  2734     }
  2735 
  2736   reply->byte_order = XM_BYTE_ORDER_CUR_FIRST;
  2737 
  2738   return 0;
  2739 }
  2740 
  2741 static int
  2742 xm_read_drop_start_message (const XEvent *msg,
  2743                             xm_drop_start_message *dmsg)
  2744 {
  2745   const uint8_t *data;
  2746 
  2747   data = (const uint8_t *) &msg->xclient.data.b[0];
  2748 
  2749   if ((XM_DRAG_REASON_ORIGINATOR (data[0])
  2750        != XM_DRAG_ORIGINATOR_INITIATOR)
  2751       || (XM_DRAG_REASON_CODE (data[0])
  2752           != XM_DRAG_REASON_DROP_START))
  2753     return 1;
  2754 
  2755   dmsg->reason = *(data++);
  2756   dmsg->byte_order = *(data++);
  2757   dmsg->side_effects = *(uint16_t *) data;
  2758   dmsg->timestamp = *(uint32_t *) (data + 2);
  2759   dmsg->x = *(uint16_t *) (data + 6);
  2760   dmsg->y = *(uint16_t *) (data + 8);
  2761   dmsg->index_atom = *(uint32_t *) (data + 10);
  2762   dmsg->source_window = *(uint32_t *) (data + 14);
  2763 
  2764   if (dmsg->byte_order != XM_BYTE_ORDER_CUR_FIRST)
  2765     {
  2766       SWAPCARD16 (dmsg->side_effects);
  2767       SWAPCARD32 (dmsg->timestamp);
  2768       SWAPCARD16 (dmsg->x);
  2769       SWAPCARD16 (dmsg->y);
  2770       SWAPCARD32 (dmsg->index_atom);
  2771       SWAPCARD32 (dmsg->source_window);
  2772     }
  2773 
  2774   dmsg->byte_order = XM_BYTE_ORDER_CUR_FIRST;
  2775 
  2776   return 0;
  2777 }
  2778 
  2779 static int
  2780 xm_read_drag_receiver_info (struct x_display_info *dpyinfo,
  2781                             Window wdesc, xm_drag_receiver_info *rec)
  2782 {
  2783   Atom actual_type;
  2784   int rc, actual_format;
  2785   unsigned long nitems, bytes_remaining;
  2786   unsigned char *tmp_data = NULL;
  2787   uint8_t *data;
  2788 
  2789   x_catch_errors (dpyinfo->display);
  2790   rc = XGetWindowProperty (dpyinfo->display, wdesc,
  2791                            dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO,
  2792                            0, 4, False,
  2793                            dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO,
  2794                            &actual_type, &actual_format, &nitems,
  2795                            &bytes_remaining,
  2796                            &tmp_data) == Success;
  2797 
  2798   if (x_had_errors_p (dpyinfo->display)
  2799       || actual_format != 8 || nitems < 16 || !tmp_data
  2800       || actual_type != dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO)
  2801     rc = 0;
  2802   x_uncatch_errors_after_check ();
  2803 
  2804   if (rc)
  2805     {
  2806       data = (uint8_t *) tmp_data;
  2807 
  2808       if (data[1] > XM_DRAG_PROTOCOL_VERSION)
  2809         return 1;
  2810 
  2811       rec->byteorder = data[0];
  2812       rec->protocol = data[1];
  2813       rec->protocol_style = data[2];
  2814       rec->unspecified0 = data[3];
  2815       rec->unspecified1 = *(uint32_t *) &data[4];
  2816       rec->unspecified2 = *(uint32_t *) &data[8];
  2817       rec->unspecified3 = *(uint32_t *) &data[12];
  2818 
  2819       if (rec->byteorder != XM_BYTE_ORDER_CUR_FIRST)
  2820         {
  2821           SWAPCARD32 (rec->unspecified1);
  2822           SWAPCARD32 (rec->unspecified2);
  2823           SWAPCARD32 (rec->unspecified3);
  2824         }
  2825 
  2826       rec->byteorder = XM_BYTE_ORDER_CUR_FIRST;
  2827     }
  2828 
  2829   if (tmp_data)
  2830     XFree (tmp_data);
  2831 
  2832   return !rc;
  2833 }
  2834 
  2835 static int
  2836 xm_read_drag_motion_message (const XEvent *msg,
  2837                              xm_drag_motion_message *dmsg)
  2838 {
  2839   const uint8_t *data;
  2840 
  2841   data = (const uint8_t *) &msg->xclient.data.b[0];
  2842 
  2843   if ((XM_DRAG_REASON_CODE (data[0])
  2844        != XM_DRAG_REASON_DRAG_MOTION)
  2845       || (XM_DRAG_REASON_ORIGINATOR (data[0])
  2846           != XM_DRAG_ORIGINATOR_INITIATOR))
  2847     return 1;
  2848 
  2849   dmsg->reason = *(data++);
  2850   dmsg->byteorder = *(data++);
  2851   dmsg->side_effects = *(uint16_t *) data;
  2852   dmsg->timestamp = *(uint32_t *) (data + 2);
  2853   dmsg->x = *(uint16_t *) (data + 6);
  2854   dmsg->y = *(uint16_t *) (data + 8);
  2855 
  2856   if (dmsg->byteorder != XM_BYTE_ORDER_CUR_FIRST)
  2857     {
  2858       SWAPCARD16 (dmsg->side_effects);
  2859       SWAPCARD32 (dmsg->timestamp);
  2860       SWAPCARD16 (dmsg->x);
  2861       SWAPCARD16 (dmsg->y);
  2862     }
  2863 
  2864   dmsg->byteorder = XM_BYTE_ORDER_CUR_FIRST;
  2865 
  2866   return 0;
  2867 }
  2868 
  2869 static int
  2870 xm_read_drag_motion_reply (const XEvent *msg, xm_drag_motion_reply *reply)
  2871 {
  2872   const uint8_t *data;
  2873 
  2874   data = (const uint8_t *) &msg->xclient.data.b[0];
  2875 
  2876   if ((XM_DRAG_REASON_CODE (data[0])
  2877        != XM_DRAG_REASON_DRAG_MOTION)
  2878       || (XM_DRAG_REASON_ORIGINATOR (data[0])
  2879           != XM_DRAG_ORIGINATOR_RECEIVER))
  2880     return 1;
  2881 
  2882   reply->reason = *(data++);
  2883   reply->byte_order = *(data++);
  2884   reply->side_effects = *(uint16_t *) data;
  2885   reply->timestamp = *(uint32_t *) (data + 2);
  2886   reply->better_x = *(uint16_t *) (data + 6);
  2887   reply->better_y = *(uint16_t *) (data + 8);
  2888 
  2889   if (reply->byte_order != XM_BYTE_ORDER_CUR_FIRST)
  2890     {
  2891       SWAPCARD16 (reply->side_effects);
  2892       SWAPCARD32 (reply->timestamp);
  2893       SWAPCARD16 (reply->better_x);
  2894       SWAPCARD16 (reply->better_y);
  2895     }
  2896 
  2897   reply->byte_order = XM_BYTE_ORDER_CUR_FIRST;
  2898 
  2899   return 0;
  2900 }
  2901 
  2902 static void
  2903 x_dnd_send_xm_leave_for_drop (struct x_display_info *dpyinfo,
  2904                               struct frame *f, Window wdesc,
  2905                               Time timestamp)
  2906 {
  2907   xm_top_level_leave_message lmsg;
  2908 
  2909   lmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
  2910                                 XM_DRAG_REASON_TOP_LEVEL_LEAVE);
  2911   lmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
  2912   lmsg.zero = 0;
  2913   lmsg.timestamp = timestamp;
  2914   lmsg.source_window = FRAME_X_WINDOW (f);
  2915 
  2916   if (x_dnd_motif_setup_p)
  2917     xm_send_top_level_leave_message (dpyinfo, FRAME_X_WINDOW (f),
  2918                                      wdesc, &lmsg);
  2919 }
  2920 
  2921 
  2922 
  2923 /* Drag-and-drop and XDND protocol primitives employed by the event
  2924    loop.  */
  2925 
  2926 static void
  2927 x_dnd_free_toplevels (bool display_alive)
  2928 {
  2929   struct x_client_list_window *last;
  2930   struct x_client_list_window *tem = x_dnd_toplevels;
  2931   ptrdiff_t n_windows, i, buffer_size;
  2932   Window *destroy_windows UNINIT;
  2933   unsigned long *prev_masks UNINIT;
  2934   specpdl_ref count;
  2935   Display *dpy UNINIT;
  2936   struct x_display_info *dpyinfo;
  2937 
  2938   if (!x_dnd_toplevels)
  2939     /* Probably called inside an IO error handler.  */
  2940     return;
  2941 
  2942   if (display_alive)
  2943     {
  2944       buffer_size = 1024;
  2945       destroy_windows = xmalloc (sizeof *destroy_windows
  2946                                  * buffer_size);
  2947       prev_masks = xmalloc (sizeof *prev_masks *
  2948                             buffer_size);
  2949       n_windows = 0;
  2950     }
  2951 
  2952   block_input ();
  2953   while (tem)
  2954     {
  2955       last = tem;
  2956       tem = tem->next;
  2957 
  2958       if (display_alive)
  2959         {
  2960           if (++n_windows >= buffer_size)
  2961             {
  2962               buffer_size += 1024;
  2963               destroy_windows
  2964                 = xrealloc (destroy_windows, (sizeof *destroy_windows
  2965                                               * buffer_size));
  2966               prev_masks
  2967                 = xrealloc (prev_masks, (sizeof *prev_masks
  2968                                          * buffer_size));
  2969             }
  2970 
  2971           dpy = last->dpy;
  2972           prev_masks[n_windows - 1] = last->previous_event_mask;
  2973           destroy_windows[n_windows - 1] = last->window;
  2974         }
  2975 
  2976 #ifdef HAVE_XSHAPE
  2977       if (last->n_input_rects != -1)
  2978         xfree (last->input_rects);
  2979       if (last->n_bounding_rects != -1)
  2980         xfree (last->bounding_rects);
  2981 #endif
  2982 
  2983       xfree (last);
  2984     }
  2985 
  2986   x_dnd_toplevels = NULL;
  2987 
  2988   if (!display_alive)
  2989     {
  2990       unblock_input ();
  2991       return;
  2992     }
  2993 
  2994   count = SPECPDL_INDEX ();
  2995   record_unwind_protect_ptr (xfree, destroy_windows);
  2996   record_unwind_protect_ptr (xfree, prev_masks);
  2997 
  2998   if (display_alive)
  2999     {
  3000       dpyinfo = x_display_info_for_display (dpy);
  3001 
  3002       if (n_windows)
  3003         {
  3004           eassume (dpyinfo);
  3005           x_ignore_errors_for_next_request (dpyinfo, 0);
  3006 
  3007           for (i = 0; i < n_windows; ++i)
  3008             {
  3009               XSelectInput (dpy, destroy_windows[i], prev_masks[i]);
  3010 #ifdef HAVE_XSHAPE
  3011               XShapeSelectInput (dpy, destroy_windows[i], None);
  3012 #endif
  3013             }
  3014 
  3015           x_stop_ignoring_errors (dpyinfo);
  3016         }
  3017     }
  3018 
  3019   unbind_to (count, Qnil);
  3020   unblock_input ();
  3021 }
  3022 
  3023 static int
  3024 x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
  3025 {
  3026   Atom type;
  3027   Window *toplevels;
  3028   int format, rc;
  3029   unsigned long nitems, bytes_after;
  3030   unsigned long i, real_nitems;
  3031   unsigned char *data = NULL;
  3032   int frame_extents[4];
  3033 
  3034 #ifndef USE_XCB
  3035   int dest_x, dest_y;
  3036   unsigned long *wmstate;
  3037   unsigned long wmstate_items, extent_items;
  3038   unsigned char *wmstate_data = NULL, *extent_data = NULL;
  3039   XWindowAttributes attrs;
  3040   Window child;
  3041   xm_drag_receiver_info xm_info;
  3042 #else
  3043   uint32_t *wmstate, *fextents;
  3044   uint8_t *xmdata;
  3045   xcb_get_window_attributes_cookie_t *window_attribute_cookies;
  3046   xcb_translate_coordinates_cookie_t *translate_coordinate_cookies;
  3047   xcb_get_property_cookie_t *get_property_cookies;
  3048   xcb_get_property_cookie_t *xm_property_cookies;
  3049   xcb_get_property_cookie_t *extent_property_cookies;
  3050   xcb_get_geometry_cookie_t *get_geometry_cookies;
  3051   xcb_get_window_attributes_reply_t attrs, *attrs_reply;
  3052   xcb_translate_coordinates_reply_t *coordinates_reply;
  3053   xcb_get_property_reply_t *property_reply;
  3054   xcb_get_property_reply_t *xm_property_reply;
  3055   xcb_get_property_reply_t *extent_property_reply;
  3056   xcb_get_geometry_reply_t *geometry_reply;
  3057   xcb_generic_error_t *error;
  3058 #endif
  3059 
  3060 #ifdef HAVE_XCB_SHAPE
  3061   xcb_shape_get_rectangles_cookie_t *bounding_rect_cookies;
  3062   xcb_shape_get_rectangles_reply_t *bounding_rect_reply;
  3063   xcb_rectangle_iterator_t bounding_rect_iterator;
  3064 #endif
  3065 
  3066 #ifdef HAVE_XCB_SHAPE_INPUT_RECTS
  3067   xcb_shape_get_rectangles_cookie_t *input_rect_cookies;
  3068   xcb_shape_get_rectangles_reply_t *input_rect_reply;
  3069   xcb_rectangle_iterator_t input_rect_iterator;
  3070 #endif
  3071 
  3072   struct x_client_list_window *tem;
  3073 #if defined HAVE_XSHAPE && !defined HAVE_XCB_SHAPE_INPUT_RECTS
  3074   int count, ordering;
  3075   XRectangle *rects;
  3076 #endif
  3077 
  3078   rc = XGetWindowProperty (dpyinfo->display, dpyinfo->root_window,
  3079                            dpyinfo->Xatom_net_client_list_stacking,
  3080                            0, LONG_MAX, False, XA_WINDOW, &type,
  3081                            &format, &nitems, &bytes_after, &data);
  3082 
  3083   if (rc != Success)
  3084     return 1;
  3085 
  3086   if (format != 32 || type != XA_WINDOW)
  3087     {
  3088       XFree (data);
  3089       return 1;
  3090     }
  3091 
  3092   toplevels = (Window *) data;
  3093 
  3094   for (i = 0, real_nitems = 0; i < nitems; ++i)
  3095     {
  3096       /* Some window managers with built in compositors end up putting
  3097          tooltips in the client list, which is silly.  */
  3098       if (!x_tooltip_window_to_frame (dpyinfo, toplevels[i], NULL))
  3099         toplevels[real_nitems++] = toplevels[i];
  3100     }
  3101 
  3102   nitems = real_nitems;
  3103 
  3104 #ifdef USE_XCB
  3105   USE_SAFE_ALLOCA;
  3106 
  3107   window_attribute_cookies
  3108     = SAFE_ALLOCA (sizeof *window_attribute_cookies * nitems);
  3109   translate_coordinate_cookies
  3110     = SAFE_ALLOCA (sizeof *translate_coordinate_cookies * nitems);
  3111   get_property_cookies
  3112     = SAFE_ALLOCA (sizeof *get_property_cookies * nitems);
  3113   xm_property_cookies
  3114     = SAFE_ALLOCA (sizeof *xm_property_cookies * nitems);
  3115   extent_property_cookies
  3116     = SAFE_ALLOCA (sizeof *extent_property_cookies * nitems);
  3117   get_geometry_cookies
  3118     = SAFE_ALLOCA (sizeof *get_geometry_cookies * nitems);
  3119 
  3120 #ifdef HAVE_XCB_SHAPE
  3121   bounding_rect_cookies
  3122     = SAFE_ALLOCA (sizeof *bounding_rect_cookies * nitems);
  3123 #endif
  3124 
  3125 #ifdef HAVE_XCB_SHAPE_INPUT_RECTS
  3126   input_rect_cookies
  3127     = SAFE_ALLOCA (sizeof *input_rect_cookies * nitems);
  3128 #endif
  3129 
  3130   for (i = 0; i < nitems; ++i)
  3131     {
  3132       window_attribute_cookies[i]
  3133         = xcb_get_window_attributes (dpyinfo->xcb_connection,
  3134                                      (xcb_window_t) toplevels[i]);
  3135       translate_coordinate_cookies[i]
  3136         = xcb_translate_coordinates (dpyinfo->xcb_connection,
  3137                                      (xcb_window_t) toplevels[i],
  3138                                      (xcb_window_t) dpyinfo->root_window,
  3139                                      0, 0);
  3140       get_property_cookies[i]
  3141         = xcb_get_property (dpyinfo->xcb_connection, 0, (xcb_window_t) toplevels[i],
  3142                             (xcb_atom_t) dpyinfo->Xatom_wm_state, 0,
  3143                             0, 2);
  3144       xm_property_cookies[i]
  3145         = xcb_get_property (dpyinfo->xcb_connection, 0, (xcb_window_t) toplevels[i],
  3146                             (xcb_atom_t) dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO,
  3147                             (xcb_atom_t) dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO,
  3148                             0, 4);
  3149       extent_property_cookies[i]
  3150         = xcb_get_property (dpyinfo->xcb_connection, 0,
  3151                             (xcb_window_t) toplevels[i],
  3152                             (xcb_atom_t) dpyinfo->Xatom_net_frame_extents,
  3153                             XA_CARDINAL, 0, 4);
  3154       get_geometry_cookies[i]
  3155         = xcb_get_geometry (dpyinfo->xcb_connection, (xcb_window_t) toplevels[i]);
  3156 
  3157 #ifdef HAVE_XCB_SHAPE
  3158       bounding_rect_cookies[i]
  3159         = xcb_shape_get_rectangles (dpyinfo->xcb_connection,
  3160                                     (xcb_window_t) toplevels[i],
  3161                                     XCB_SHAPE_SK_BOUNDING);
  3162 #endif
  3163 
  3164 #ifdef HAVE_XCB_SHAPE_INPUT_RECTS
  3165       if (dpyinfo->xshape_major > 1
  3166           || (dpyinfo->xshape_major == 1
  3167               && dpyinfo->xshape_minor >= 1))
  3168         input_rect_cookies[i]
  3169           = xcb_shape_get_rectangles (dpyinfo->xcb_connection,
  3170                                       (xcb_window_t) toplevels[i],
  3171                                       XCB_SHAPE_SK_INPUT);
  3172 #endif
  3173     }
  3174 #endif
  3175 
  3176   /* Actually right because _NET_CLIENT_LIST_STACKING has bottom-up
  3177      order.  */
  3178   for (i = 0; i < nitems; ++i)
  3179     {
  3180       frame_extents[0] = 0;
  3181       frame_extents[1] = 0;
  3182       frame_extents[2] = 0;
  3183       frame_extents[3] = 0;
  3184 
  3185 #ifndef USE_XCB
  3186       x_catch_errors (dpyinfo->display);
  3187       rc = (XGetWindowAttributes (dpyinfo->display,
  3188                                   toplevels[i], &attrs)
  3189             && !x_had_errors_p (dpyinfo->display));
  3190 
  3191       if (rc)
  3192         rc = (XTranslateCoordinates (dpyinfo->display, toplevels[i],
  3193                                      attrs.root, -attrs.border_width,
  3194                                      -attrs.border_width, &dest_x,
  3195                                      &dest_y, &child)
  3196               && !x_had_errors_p (dpyinfo->display));
  3197       if (rc)
  3198         rc = ((XGetWindowProperty (dpyinfo->display,
  3199                                    toplevels[i],
  3200                                    dpyinfo->Xatom_wm_state,
  3201                                    0, 2, False, AnyPropertyType,
  3202                                    &type, &format, &wmstate_items,
  3203                                    &bytes_after, &wmstate_data)
  3204                == Success)
  3205               && !x_had_errors_p (dpyinfo->display)
  3206               && wmstate_data && wmstate_items == 2 && format == 32);
  3207 
  3208       if (XGetWindowProperty (dpyinfo->display, toplevels[i],
  3209                               dpyinfo->Xatom_net_frame_extents,
  3210                               0, 4, False, XA_CARDINAL, &type,
  3211                               &format, &extent_items, &bytes_after,
  3212                               &extent_data) == Success
  3213           && !x_had_errors_p (dpyinfo->display)
  3214           && extent_data && extent_items >= 4 && format == 32)
  3215         {
  3216           frame_extents[0] = ((unsigned long *) extent_data)[0];
  3217           frame_extents[1] = ((unsigned long *) extent_data)[1];
  3218           frame_extents[2] = ((unsigned long *) extent_data)[2];
  3219           frame_extents[3] = ((unsigned long *) extent_data)[3];
  3220         }
  3221 
  3222       if (extent_data)
  3223         XFree (extent_data);
  3224 
  3225       x_uncatch_errors ();
  3226 #else
  3227       rc = true;
  3228 
  3229       attrs_reply
  3230         = xcb_get_window_attributes_reply (dpyinfo->xcb_connection,
  3231                                            window_attribute_cookies[i],
  3232                                            &error);
  3233 
  3234       if (!attrs_reply)
  3235         {
  3236           rc = false;
  3237           free (error);
  3238         }
  3239 
  3240       coordinates_reply
  3241         = xcb_translate_coordinates_reply (dpyinfo->xcb_connection,
  3242                                            translate_coordinate_cookies[i],
  3243                                            &error);
  3244 
  3245       if (!coordinates_reply)
  3246         {
  3247           rc = false;
  3248           free (error);
  3249         }
  3250 
  3251       property_reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  3252                                                get_property_cookies[i],
  3253                                                &error);
  3254 
  3255       if (!property_reply)
  3256         {
  3257           rc = false;
  3258           free (error);
  3259         }
  3260 
  3261       /* These requests don't set rc on failure because they aren't
  3262          required.  */
  3263 
  3264       xm_property_reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  3265                                                   xm_property_cookies[i],
  3266                                                   &error);
  3267 
  3268       if (!xm_property_reply)
  3269         free (error);
  3270 
  3271       extent_property_reply
  3272         = xcb_get_property_reply (dpyinfo->xcb_connection,
  3273                                   extent_property_cookies[i],
  3274                                   &error);
  3275 
  3276       if (!extent_property_reply)
  3277         free (error);
  3278       else
  3279         {
  3280           if (xcb_get_property_value_length (extent_property_reply) == 16
  3281               && extent_property_reply->format == 32
  3282               && extent_property_reply->type == XA_CARDINAL)
  3283             {
  3284               fextents = xcb_get_property_value (extent_property_reply);
  3285               frame_extents[0] = fextents[0];
  3286               frame_extents[1] = fextents[1];
  3287               frame_extents[2] = fextents[2];
  3288               frame_extents[3] = fextents[3];
  3289             }
  3290 
  3291           free (extent_property_reply);
  3292         }
  3293 
  3294       if (property_reply
  3295           && (xcb_get_property_value_length (property_reply) != 8
  3296               || property_reply->format != 32))
  3297         rc = false;
  3298 
  3299       geometry_reply = xcb_get_geometry_reply (dpyinfo->xcb_connection,
  3300                                                get_geometry_cookies[i],
  3301                                                &error);
  3302 
  3303       if (!geometry_reply)
  3304         {
  3305           rc = false;
  3306           free (error);
  3307         }
  3308 #endif
  3309 
  3310       if (rc)
  3311         {
  3312 #ifdef USE_XCB
  3313           wmstate = (uint32_t *) xcb_get_property_value (property_reply);
  3314           attrs = *attrs_reply;
  3315 #else
  3316           wmstate = (unsigned long *) wmstate_data;
  3317 #endif
  3318 
  3319           tem = xmalloc (sizeof *tem);
  3320           tem->window = toplevels[i];
  3321           tem->dpy = dpyinfo->display;
  3322           tem->frame_extents_left = frame_extents[0];
  3323           tem->frame_extents_right = frame_extents[1];
  3324           tem->frame_extents_top = frame_extents[2];
  3325           tem->frame_extents_bottom = frame_extents[3];
  3326 
  3327 #ifndef USE_XCB
  3328           tem->x = dest_x;
  3329           tem->y = dest_y;
  3330           tem->width = attrs.width + attrs.border_width;
  3331           tem->height = attrs.height + attrs.border_width;
  3332           tem->mapped_p = (attrs.map_state != IsUnmapped);
  3333 #else
  3334           tem->x = (coordinates_reply->dst_x
  3335                     - geometry_reply->border_width);
  3336           tem->y = (coordinates_reply->dst_y
  3337                     - geometry_reply->border_width);
  3338           tem->width = (geometry_reply->width
  3339                         + geometry_reply->border_width);
  3340           tem->height = (geometry_reply->height
  3341                          + geometry_reply->border_width);
  3342           tem->mapped_p = (attrs.map_state != XCB_MAP_STATE_UNMAPPED);
  3343 #endif
  3344           tem->next = x_dnd_toplevels;
  3345           tem->previous_event_mask = attrs.your_event_mask;
  3346           tem->wm_state = wmstate[0];
  3347           tem->xm_protocol_style = XM_DRAG_STYLE_NONE;
  3348 
  3349 #ifndef USE_XCB
  3350           if (!xm_read_drag_receiver_info (dpyinfo, toplevels[i], &xm_info))
  3351             tem->xm_protocol_style = xm_info.protocol_style;
  3352 #else
  3353           if (xm_property_reply
  3354               && xm_property_reply->format == 8
  3355               && (xm_property_reply->type
  3356                   == dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO)
  3357               && xcb_get_property_value_length (xm_property_reply) >= 4)
  3358             {
  3359               xmdata = xcb_get_property_value (xm_property_reply);
  3360 
  3361               if (xmdata[1] <= XM_DRAG_PROTOCOL_VERSION)
  3362                 tem->xm_protocol_style = xmdata[2];
  3363             }
  3364 #endif
  3365 
  3366 #ifdef HAVE_XSHAPE
  3367 #ifndef USE_XCB
  3368           tem->border_width = attrs.border_width;
  3369 #else
  3370           tem->border_width = geometry_reply->border_width;
  3371 #endif
  3372           tem->n_bounding_rects = -1;
  3373           tem->n_input_rects = -1;
  3374 
  3375           if (dpyinfo->xshape_supported_p)
  3376             {
  3377               x_ignore_errors_for_next_request (dpyinfo, 0);
  3378               XShapeSelectInput (dpyinfo->display,
  3379                                  toplevels[i],
  3380                                  ShapeNotifyMask);
  3381               x_stop_ignoring_errors (dpyinfo);
  3382 
  3383 #ifndef HAVE_XCB_SHAPE
  3384               x_catch_errors (dpyinfo->display);
  3385               rects = XShapeGetRectangles (dpyinfo->display,
  3386                                            toplevels[i],
  3387                                            ShapeBounding,
  3388                                            &count, &ordering);
  3389               rc = x_had_errors_p (dpyinfo->display);
  3390               x_uncatch_errors_after_check ();
  3391 
  3392               /* Does XShapeGetRectangles allocate anything upon an
  3393                  error?  */
  3394               if (!rc)
  3395                 {
  3396                   tem->n_bounding_rects = count;
  3397                   tem->bounding_rects
  3398                     = xmalloc (sizeof *tem->bounding_rects * count);
  3399                   memcpy (tem->bounding_rects, rects,
  3400                           sizeof *tem->bounding_rects * count);
  3401 
  3402                   XFree (rects);
  3403                 }
  3404 #else
  3405               bounding_rect_reply
  3406                 = xcb_shape_get_rectangles_reply (dpyinfo->xcb_connection,
  3407                                                   bounding_rect_cookies[i],
  3408                                                   &error);
  3409 
  3410               if (bounding_rect_reply)
  3411                 {
  3412                   bounding_rect_iterator
  3413                     = xcb_shape_get_rectangles_rectangles_iterator (bounding_rect_reply);
  3414                   tem->n_bounding_rects = bounding_rect_iterator.rem + 1;
  3415                   tem->bounding_rects = xmalloc (tem->n_bounding_rects
  3416                                                  * sizeof *tem->bounding_rects);
  3417                   tem->n_bounding_rects = 0;
  3418 
  3419                   for (; bounding_rect_iterator.rem;
  3420                        xcb_rectangle_next (&bounding_rect_iterator))
  3421                     {
  3422                       tem->bounding_rects[tem->n_bounding_rects].x
  3423                         = bounding_rect_iterator.data->x;
  3424                       tem->bounding_rects[tem->n_bounding_rects].y
  3425                         = bounding_rect_iterator.data->y;
  3426                       tem->bounding_rects[tem->n_bounding_rects].width
  3427                         = bounding_rect_iterator.data->width;
  3428                       tem->bounding_rects[tem->n_bounding_rects].height
  3429                         = bounding_rect_iterator.data->height;
  3430 
  3431                       tem->n_bounding_rects++;
  3432                     }
  3433 
  3434                   free (bounding_rect_reply);
  3435                 }
  3436               else
  3437                 free (error);
  3438 #endif
  3439 
  3440 #ifdef HAVE_XCB_SHAPE_INPUT_RECTS
  3441               if (dpyinfo->xshape_major > 1
  3442                   || (dpyinfo->xshape_major == 1
  3443                       && dpyinfo->xshape_minor >= 1))
  3444                 {
  3445                   input_rect_reply
  3446                     = xcb_shape_get_rectangles_reply (dpyinfo->xcb_connection,
  3447                                                       input_rect_cookies[i],
  3448                                                       &error);
  3449 
  3450                   if (input_rect_reply)
  3451                     {
  3452                       input_rect_iterator
  3453                         = xcb_shape_get_rectangles_rectangles_iterator (input_rect_reply);
  3454                       tem->n_input_rects = input_rect_iterator.rem + 1;
  3455                       tem->input_rects = xmalloc (tem->n_input_rects
  3456                                                   * sizeof *tem->input_rects);
  3457                       tem->n_input_rects = 0;
  3458 
  3459                       for (; input_rect_iterator.rem;
  3460                            xcb_rectangle_next (&input_rect_iterator))
  3461                         {
  3462                           tem->input_rects[tem->n_input_rects].x
  3463                             = input_rect_iterator.data->x;
  3464                           tem->input_rects[tem->n_input_rects].y
  3465                             = input_rect_iterator.data->y;
  3466                           tem->input_rects[tem->n_input_rects].width
  3467                             = input_rect_iterator.data->width;
  3468                           tem->input_rects[tem->n_input_rects].height
  3469                             = input_rect_iterator.data->height;
  3470 
  3471                           tem->n_input_rects++;
  3472                         }
  3473 
  3474                       free (input_rect_reply);
  3475                     }
  3476                   else
  3477                     free (error);
  3478                 }
  3479 #else
  3480 #ifdef ShapeInput
  3481               if (dpyinfo->xshape_major > 1
  3482                   || (dpyinfo->xshape_major == 1
  3483                       && dpyinfo->xshape_minor >= 1))
  3484                 {
  3485                   x_catch_errors (dpyinfo->display);
  3486                   rects = XShapeGetRectangles (dpyinfo->display,
  3487                                                toplevels[i], ShapeInput,
  3488                                                &count, &ordering);
  3489                   rc = x_had_errors_p (dpyinfo->display);
  3490                   x_uncatch_errors_after_check ();
  3491 
  3492                   /* Does XShapeGetRectangles allocate anything upon
  3493                      an error?  */
  3494                   if (!rc)
  3495                     {
  3496                       tem->n_input_rects = count;
  3497                       tem->input_rects
  3498                         = xmalloc (sizeof *tem->input_rects * count);
  3499                       memcpy (tem->input_rects, rects,
  3500                               sizeof *tem->input_rects * count);
  3501 
  3502                       XFree (rects);
  3503                     }
  3504                 }
  3505 #endif
  3506 #endif
  3507             }
  3508 
  3509           /* Handle the common case where the input shape equals the
  3510              bounding shape.  */
  3511 
  3512           if (tem->n_input_rects != -1
  3513               && tem->n_bounding_rects == tem->n_input_rects
  3514               && !memcmp (tem->bounding_rects, tem->input_rects,
  3515                           tem->n_input_rects * sizeof *tem->input_rects))
  3516             {
  3517               xfree (tem->input_rects);
  3518               tem->n_input_rects = -1;
  3519             }
  3520 
  3521           /* And the common case where there is no input rect and the
  3522              bounding rect equals the window dimensions.  */
  3523 
  3524           if (tem->n_input_rects == -1
  3525               && tem->n_bounding_rects == 1
  3526 #ifdef USE_XCB
  3527               && (tem->bounding_rects[0].width
  3528                   == (geometry_reply->width
  3529                       + geometry_reply->border_width))
  3530               && (tem->bounding_rects[0].height
  3531                   == (geometry_reply->height
  3532                       + geometry_reply->border_width))
  3533               && (tem->bounding_rects[0].x
  3534                   == -geometry_reply->border_width)
  3535               && (tem->bounding_rects[0].y
  3536                   == -geometry_reply->border_width)
  3537 #else
  3538               && (tem->bounding_rects[0].width
  3539                   == attrs.width + attrs.border_width)
  3540               && (tem->bounding_rects[0].height
  3541                   == attrs.height + attrs.border_width)
  3542               && (tem->bounding_rects[0].x
  3543                   == -attrs.border_width)
  3544               && (tem->bounding_rects[0].y
  3545                   == -attrs.border_width)
  3546 #endif
  3547               )
  3548             {
  3549               xfree (tem->bounding_rects);
  3550               tem->n_bounding_rects = -1;
  3551             }
  3552 #endif
  3553 
  3554           x_ignore_errors_for_next_request (dpyinfo, 0);
  3555           XSelectInput (dpyinfo->display, toplevels[i],
  3556                         (attrs.your_event_mask
  3557                          | StructureNotifyMask
  3558                          | PropertyChangeMask));
  3559           x_stop_ignoring_errors (dpyinfo);
  3560 
  3561           x_dnd_toplevels = tem;
  3562         }
  3563       else
  3564         {
  3565 #ifdef HAVE_XCB_SHAPE
  3566           if (dpyinfo->xshape_supported_p)
  3567             {
  3568               bounding_rect_reply
  3569                 = xcb_shape_get_rectangles_reply (dpyinfo->xcb_connection,
  3570                                                   bounding_rect_cookies[i],
  3571                                                   &error);
  3572 
  3573               if (bounding_rect_reply)
  3574                 free (bounding_rect_reply);
  3575               else
  3576                 free (error);
  3577             }
  3578 #endif
  3579 
  3580 #ifdef HAVE_XCB_SHAPE_INPUT_RECTS
  3581           if (dpyinfo->xshape_supported_p
  3582               && (dpyinfo->xshape_major > 1
  3583                   || (dpyinfo->xshape_major == 1
  3584                       && dpyinfo->xshape_minor >= 1)))
  3585             {
  3586               input_rect_reply
  3587                 = xcb_shape_get_rectangles_reply (dpyinfo->xcb_connection,
  3588                                                   input_rect_cookies[i],
  3589                                                   &error);
  3590 
  3591               if (input_rect_reply)
  3592                 free (input_rect_reply);
  3593               else
  3594                 free (error);
  3595             }
  3596 #endif
  3597         }
  3598 
  3599 #ifdef USE_XCB
  3600       if (attrs_reply)
  3601         free (attrs_reply);
  3602 
  3603       if (coordinates_reply)
  3604         free (coordinates_reply);
  3605 
  3606       if (property_reply)
  3607         free (property_reply);
  3608 
  3609       if (xm_property_reply)
  3610         free (xm_property_reply);
  3611 
  3612       if (geometry_reply)
  3613         free (geometry_reply);
  3614 #endif
  3615 
  3616 #ifndef USE_XCB
  3617       if (wmstate_data)
  3618         {
  3619           XFree (wmstate_data);
  3620           wmstate_data = NULL;
  3621         }
  3622 #endif
  3623     }
  3624 
  3625 #ifdef USE_XCB
  3626   SAFE_FREE ();
  3627 #endif
  3628 
  3629   if (data)
  3630     XFree (data);
  3631 
  3632   return 0;
  3633 }
  3634 
  3635 static _Noreturn int
  3636 x_dnd_io_error_handler (Display *display)
  3637 {
  3638 #ifdef USE_GTK
  3639   emacs_abort ();
  3640 #else
  3641   siglongjmp (x_dnd_disconnect_handler, 1);
  3642 #endif
  3643 }
  3644 
  3645 #define X_DND_SUPPORTED_VERSION 5
  3646 
  3647 static int x_dnd_get_window_proto (struct x_display_info *, Window);
  3648 static Window x_dnd_get_window_proxy (struct x_display_info *, Window);
  3649 static void x_dnd_update_state (struct x_display_info *, Time);
  3650 
  3651 #ifdef USE_XCB
  3652 static void
  3653 x_dnd_get_proxy_proto (struct x_display_info *dpyinfo, Window wdesc,
  3654                        Window *proxy_out, int *proto_out)
  3655 {
  3656   xcb_get_property_cookie_t xdnd_proto_cookie;
  3657   xcb_get_property_cookie_t xdnd_proxy_cookie;
  3658   xcb_get_property_reply_t *reply;
  3659   xcb_generic_error_t *error;
  3660 
  3661   if (proxy_out)
  3662     *proxy_out = None;
  3663 
  3664   if (proto_out)
  3665     *proto_out = -1;
  3666 
  3667   if (proxy_out)
  3668     xdnd_proxy_cookie = xcb_get_property (dpyinfo->xcb_connection, 0,
  3669                                           (xcb_window_t) wdesc,
  3670                                           (xcb_atom_t) dpyinfo->Xatom_XdndProxy,
  3671                                           XA_WINDOW, 0, 1);
  3672 
  3673   if (proto_out)
  3674     xdnd_proto_cookie = xcb_get_property (dpyinfo->xcb_connection, 0,
  3675                                           (xcb_window_t) wdesc,
  3676                                           (xcb_atom_t) dpyinfo->Xatom_XdndAware,
  3677                                           XA_ATOM, 0, 1);
  3678 
  3679   if (proxy_out)
  3680     {
  3681       reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  3682                                       xdnd_proxy_cookie, &error);
  3683 
  3684       if (!reply)
  3685         free (error);
  3686       else
  3687         {
  3688           if (reply->format == 32
  3689               && reply->type == XA_WINDOW
  3690               && (xcb_get_property_value_length (reply) >= 4))
  3691             *proxy_out = *(xcb_window_t *) xcb_get_property_value (reply);
  3692 
  3693           free (reply);
  3694         }
  3695     }
  3696 
  3697   if (proto_out)
  3698     {
  3699       reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  3700                                       xdnd_proto_cookie, &error);
  3701 
  3702       if (!reply)
  3703         free (error);
  3704       else
  3705         {
  3706           if (reply->format == 32
  3707               && reply->type == XA_ATOM
  3708               && (xcb_get_property_value_length (reply) >= 4))
  3709             *proto_out = (int) *(xcb_atom_t *) xcb_get_property_value (reply);
  3710 
  3711           free (reply);
  3712         }
  3713     }
  3714 }
  3715 #endif
  3716 
  3717 #ifdef HAVE_XSHAPE
  3718 static bool
  3719 x_dnd_get_target_window_2 (XRectangle *rects, int nrects,
  3720                            int x, int y)
  3721 {
  3722   int i;
  3723   XRectangle *tem;
  3724 
  3725   for (i = 0; i < nrects; ++i)
  3726     {
  3727       tem = &rects[i];
  3728 
  3729       if (x >= tem->x && y >= tem->y
  3730           && x < tem->x + tem->width
  3731           && y < tem->y + tem->height)
  3732         return true;
  3733     }
  3734 
  3735   return false;
  3736 }
  3737 #endif
  3738 
  3739 static Window
  3740 x_dnd_get_target_window_1 (struct x_display_info *dpyinfo,
  3741                            int root_x, int root_y, int *motif_out,
  3742                            bool *extents_p)
  3743 {
  3744   struct x_client_list_window *tem, *chosen = NULL;
  3745 
  3746   /* Loop through x_dnd_toplevels until we find the toplevel where
  3747      root_x and root_y are.  */
  3748 
  3749   *motif_out = XM_DRAG_STYLE_NONE;
  3750 
  3751   for (tem = x_dnd_toplevels; tem; tem = tem->next)
  3752     {
  3753       if (!tem->mapped_p || tem->wm_state != NormalState)
  3754         continue;
  3755 
  3756       /* Test if the coordinates are inside the window's frame
  3757          extents, and return None in that case.  */
  3758 
  3759       *extents_p = true;
  3760       if (root_x > tem->x - tem->frame_extents_left
  3761           && root_x < tem->x
  3762           && root_y > tem->y - tem->frame_extents_top
  3763           && root_y < (tem->y + tem->height - 1
  3764                        + tem->frame_extents_bottom))
  3765         return None;
  3766 
  3767       if (root_x > tem->x + tem->width
  3768           && root_x < (tem->x + tem->width - 1
  3769                        + tem->frame_extents_right)
  3770           && root_y > tem->y - tem->frame_extents_top
  3771           && root_y < (tem->y + tem->height - 1
  3772                        + tem->frame_extents_bottom))
  3773         return None;
  3774 
  3775       if (root_y > tem->y - tem->frame_extents_top
  3776           && root_y < tem->y
  3777           && root_x > tem->x - tem->frame_extents_left
  3778           && root_x < (tem->x + tem->width - 1
  3779                        + tem->frame_extents_right))
  3780         return None;
  3781 
  3782       if (root_y > tem->y + tem->height
  3783           && root_y < (tem->y + tem->height - 1
  3784                        + tem->frame_extents_bottom)
  3785           && root_x >= tem->x - tem->frame_extents_left
  3786           && root_x < (tem->x + tem->width - 1
  3787                        + tem->frame_extents_right))
  3788         return None;
  3789       *extents_p = false;
  3790 
  3791       if (root_x >= tem->x && root_y >= tem->y
  3792           && root_x < tem->x + tem->width
  3793           && root_y < tem->y + tem->height)
  3794         {
  3795 #ifdef HAVE_XSHAPE
  3796           if (tem->n_bounding_rects == -1)
  3797 #endif
  3798             {
  3799               chosen = tem;
  3800               break;
  3801             }
  3802 
  3803 #ifdef HAVE_XSHAPE
  3804           if (x_dnd_get_target_window_2 (tem->bounding_rects,
  3805                                          tem->n_bounding_rects,
  3806                                          tem->border_width + root_x - tem->x,
  3807                                          tem->border_width + root_y - tem->y))
  3808             {
  3809               if (tem->n_input_rects == -1
  3810                   || x_dnd_get_target_window_2 (tem->input_rects,
  3811                                                 tem->n_input_rects,
  3812                                                 (tem->border_width
  3813                                                  + root_x - tem->x),
  3814                                                 (tem->border_width
  3815                                                  + root_y - tem->y)))
  3816                 {
  3817                   chosen = tem;
  3818                   break;
  3819                 }
  3820             }
  3821 #endif
  3822         }
  3823     }
  3824 
  3825   if (chosen)
  3826     {
  3827       *motif_out = (x_dnd_disable_motif_protocol
  3828                     ? XM_DRAG_STYLE_NONE
  3829                     : chosen->xm_protocol_style);
  3830       return chosen->window;
  3831     }
  3832   else
  3833     *motif_out = XM_DRAG_STYLE_NONE;
  3834 
  3835   return None;
  3836 }
  3837 
  3838 static int
  3839 x_dnd_get_wm_state_and_proto (struct x_display_info *dpyinfo,
  3840                               Window window, int *wmstate_out,
  3841                               int *proto_out, int *motif_out,
  3842                               Window *proxy_out)
  3843 {
  3844 #ifndef USE_XCB
  3845   Atom type;
  3846   int format;
  3847   unsigned long nitems, bytes_after;
  3848   unsigned char *data = NULL;
  3849   xm_drag_receiver_info xm_info;
  3850 #else
  3851   xcb_get_property_cookie_t wmstate_cookie;
  3852   xcb_get_property_cookie_t xdnd_proto_cookie;
  3853   xcb_get_property_cookie_t xdnd_proxy_cookie;
  3854   xcb_get_property_cookie_t xm_style_cookie;
  3855   xcb_get_property_reply_t *reply;
  3856   xcb_generic_error_t *error;
  3857   uint8_t *xmdata;
  3858 #endif
  3859   int rc;
  3860 
  3861 #ifndef USE_XCB
  3862   x_catch_errors (dpyinfo->display);
  3863   rc = ((XGetWindowProperty (dpyinfo->display, window,
  3864                              dpyinfo->Xatom_wm_state,
  3865                              0, 2, False, AnyPropertyType,
  3866                              &type, &format, &nitems,
  3867                              &bytes_after, &data)
  3868          == Success)
  3869         && !x_had_errors_p (dpyinfo->display)
  3870         && data && nitems == 2 && format == 32);
  3871   x_uncatch_errors ();
  3872 
  3873   if (rc)
  3874     *wmstate_out = *(unsigned long *) data;
  3875 
  3876   *proto_out = x_dnd_get_window_proto (dpyinfo, window);
  3877 
  3878   if (!xm_read_drag_receiver_info (dpyinfo, window, &xm_info))
  3879     *motif_out = xm_info.protocol_style;
  3880   else
  3881     *motif_out = XM_DRAG_STYLE_NONE;
  3882 
  3883   *proxy_out = x_dnd_get_window_proxy (dpyinfo, window);
  3884 
  3885   if (data)
  3886     XFree (data);
  3887 #else
  3888   rc = true;
  3889 
  3890   wmstate_cookie = xcb_get_property (dpyinfo->xcb_connection, 0,
  3891                                      (xcb_window_t) window,
  3892                                      (xcb_atom_t) dpyinfo->Xatom_wm_state,
  3893                                      0, 0, 2);
  3894   xdnd_proto_cookie = xcb_get_property (dpyinfo->xcb_connection, 0,
  3895                                         (xcb_window_t) window,
  3896                                         (xcb_atom_t) dpyinfo->Xatom_XdndAware,
  3897                                         XA_ATOM, 0, 1);
  3898   xdnd_proxy_cookie = xcb_get_property (dpyinfo->xcb_connection, 0,
  3899                                         (xcb_window_t) window,
  3900                                         (xcb_atom_t) dpyinfo->Xatom_XdndProxy,
  3901                                         XA_WINDOW, 0, 1);
  3902   xm_style_cookie
  3903     = xcb_get_property (dpyinfo->xcb_connection, 0,
  3904                         (xcb_window_t) window,
  3905                         (xcb_atom_t) dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO,
  3906                         (xcb_atom_t) dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO,
  3907                         0, 4);
  3908 
  3909   reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  3910                                   wmstate_cookie, &error);
  3911 
  3912   if (!reply)
  3913     free (error), rc = false;
  3914   else
  3915     {
  3916       if (reply->format != 32
  3917           || xcb_get_property_value_length (reply) != 8)
  3918         rc = false;
  3919       else
  3920         *wmstate_out = *(uint32_t *) xcb_get_property_value (reply);
  3921 
  3922       free (reply);
  3923     }
  3924 
  3925   reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  3926                                   xdnd_proto_cookie, &error);
  3927 
  3928   *proto_out = -1;
  3929   if (!reply)
  3930     free (error);
  3931   else
  3932     {
  3933       if (reply->format == 32
  3934           && xcb_get_property_value_length (reply) >= 4)
  3935         *proto_out = *(uint32_t *) xcb_get_property_value (reply);
  3936 
  3937       free (reply);
  3938     }
  3939 
  3940   *proxy_out = None;
  3941   reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  3942                                   xdnd_proxy_cookie, &error);
  3943 
  3944   if (!reply)
  3945     free (error);
  3946   else
  3947     {
  3948       if (reply->format == 32
  3949           && reply->type == XA_WINDOW
  3950           && (xcb_get_property_value_length (reply) >= 4))
  3951         *proxy_out = *(xcb_window_t *) xcb_get_property_value (reply);
  3952 
  3953       free (reply);
  3954     }
  3955 
  3956   *motif_out = XM_DRAG_STYLE_NONE;
  3957 
  3958   reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  3959                                   xm_style_cookie, &error);
  3960 
  3961   if (!reply)
  3962     free (error);
  3963  else
  3964    {
  3965      if (reply->format == 8
  3966          && reply->type == dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO
  3967          && xcb_get_property_value_length (reply) >= 4)
  3968        {
  3969          xmdata = xcb_get_property_value (reply);
  3970          *motif_out = xmdata[2];
  3971        }
  3972 
  3973      free (reply);
  3974    }
  3975 #endif
  3976 
  3977   return rc;
  3978 }
  3979 
  3980 /* From the XDND protocol specification:
  3981 
  3982    Dropping on windows that do not support XDND
  3983 
  3984    Since middle clicking is the universal shortcut for pasting
  3985    in X, one can drop data into a window that does not support
  3986    XDND by:
  3987 
  3988    1. After the mouse has been released to trigger the drop,
  3989    obtain ownership of XA_PRIMARY.
  3990 
  3991    2. Send a ButtonPress event and then a ButtonRelease event to
  3992    the deepest subwindow containing the mouse to simulate a
  3993    middle click.  The times for these events should be the time
  3994    of the actual button release +1 and +2, respectively.  These
  3995    values will not be used by anybody else, so one can
  3996    unambiguously recognize the resulting `XConvertSelection'
  3997    request.
  3998 
  3999    3. If a request for XA_PRIMARY arrives bearing the timestamp
  4000    of either the ButtonPress or the ButtonRelease event, treat
  4001    it as a request for XdndSelection.  Note that you must use
  4002    the X data types instead of the MIME types in this case.
  4003    (e.g. XA_STRING instead of text/plain).  */
  4004 void
  4005 x_dnd_do_unsupported_drop (struct x_display_info *dpyinfo,
  4006                            Lisp_Object frame, Lisp_Object value,
  4007                            Lisp_Object targets, Window target_window,
  4008                            int root_x, int root_y, Time before)
  4009 {
  4010   XEvent event;
  4011   int dest_x, dest_y;
  4012   Window child_return, child, owner;
  4013   Lisp_Object current_value;
  4014   struct frame *f;
  4015 
  4016   f = decode_window_system_frame (frame);
  4017 
  4018   if (NILP (value))
  4019     return;
  4020 
  4021   if (!x_dnd_use_unsupported_drop)
  4022     return;
  4023 
  4024   event.xbutton.serial = 0;
  4025   event.xbutton.send_event = True;
  4026   event.xbutton.display = dpyinfo->display;
  4027   event.xbutton.root = dpyinfo->root_window;
  4028   event.xbutton.x_root = root_x;
  4029   event.xbutton.y_root = root_y;
  4030 
  4031   x_catch_errors (dpyinfo->display);
  4032 
  4033   child = dpyinfo->root_window;
  4034   dest_x = root_x;
  4035   dest_y = root_y;
  4036 
  4037   while (XTranslateCoordinates (dpyinfo->display, dpyinfo->root_window,
  4038                                 child, root_x, root_y, &dest_x, &dest_y,
  4039                                 &child_return)
  4040          && child_return != None)
  4041     child = child_return;
  4042 
  4043   x_uncatch_errors ();
  4044 
  4045   if (!CONSP (value))
  4046     return;
  4047 
  4048   current_value = assq_no_quit (QPRIMARY,
  4049                                 dpyinfo->terminal->Vselection_alist);
  4050 
  4051   if (!NILP (current_value))
  4052     current_value = XCAR (XCDR (current_value));
  4053 
  4054   x_own_selection (QPRIMARY, current_value, frame,
  4055                    XCAR (XCDR (value)), before);
  4056 
  4057   owner = XGetSelectionOwner (dpyinfo->display, XA_PRIMARY);
  4058 
  4059   /* If we didn't successfully obtain selection ownership, refrain
  4060      from generating events that will insert something else.  */
  4061 
  4062   if (owner != FRAME_X_WINDOW (f))
  4063     return;
  4064 
  4065   /* mouse-drag-and-drop-region will immediately deactivate the mark
  4066      after this is set.  Make sure the primary selection is not
  4067      clobbered in that case by setting `deactivate-mark' to
  4068      Qdont_save.  */
  4069   Vdeactivate_mark = Qdont_save;
  4070 
  4071   event.xbutton.window = child;
  4072   event.xbutton.subwindow = None;
  4073   event.xbutton.x = dest_x;
  4074   event.xbutton.y = dest_y;
  4075   event.xbutton.state = 0;
  4076   event.xbutton.button = 2;
  4077   event.xbutton.same_screen = True;
  4078 
  4079   dpyinfo->pending_dnd_time = before;
  4080 
  4081   event.xbutton.type = ButtonPress;
  4082   event.xbutton.time = before + 1;
  4083 
  4084   x_ignore_errors_for_next_request (dpyinfo, 0);
  4085   XSendEvent (dpyinfo->display, child,
  4086               True, ButtonPressMask, &event);
  4087 
  4088   event.xbutton.type = ButtonRelease;
  4089   event.xbutton.time = before + 2;
  4090 
  4091   XSendEvent (dpyinfo->display, child,
  4092               True, ButtonReleaseMask, &event);
  4093   x_stop_ignoring_errors (dpyinfo);
  4094 
  4095   x_dnd_action_symbol = QXdndActionPrivate;
  4096 
  4097   return;
  4098 }
  4099 
  4100 static void
  4101 x_dnd_send_unsupported_drop (struct x_display_info *dpyinfo, Window target_window,
  4102                              int root_x, int root_y, Time before)
  4103 {
  4104   Lisp_Object targets, arg;
  4105   int i;
  4106   char **atom_names, *name;
  4107 
  4108   targets = Qnil;
  4109   atom_names = alloca (sizeof *atom_names * x_dnd_n_targets);
  4110 
  4111   if (!XGetAtomNames (dpyinfo->display, x_dnd_targets,
  4112                       x_dnd_n_targets, atom_names))
  4113       return;
  4114 
  4115   for (i = x_dnd_n_targets; i > 0; --i)
  4116     {
  4117       targets = Fcons (build_string (atom_names[i - 1]),
  4118                        targets);
  4119       XFree (atom_names[i - 1]);
  4120     }
  4121 
  4122   name = x_get_atom_name (dpyinfo, x_dnd_wanted_action,
  4123                           NULL);
  4124 
  4125   if (name)
  4126     {
  4127       arg = intern (name);
  4128       xfree (name);
  4129     }
  4130   else
  4131     arg = Qnil;
  4132 
  4133   x_dnd_run_unsupported_drop_function = true;
  4134   x_dnd_unsupported_drop_time = before;
  4135   x_dnd_unsupported_drop_window = target_window;
  4136   x_dnd_unsupported_drop_data
  4137     = listn (5, assq_no_quit (QXdndSelection,
  4138                               dpyinfo->terminal->Vselection_alist),
  4139              targets, arg, make_fixnum (root_x),
  4140              make_fixnum (root_y));
  4141 
  4142   x_dnd_waiting_for_finish = true;
  4143   x_dnd_finish_display = dpyinfo->display;
  4144 }
  4145 
  4146 static Window
  4147 x_dnd_fill_empty_target (int *proto_out, int *motif_out,
  4148                          Window *toplevel_out, bool *was_frame)
  4149 {
  4150   *proto_out = -1;
  4151   *motif_out = XM_DRAG_STYLE_NONE;
  4152   *toplevel_out = None;
  4153   *was_frame = false;
  4154 
  4155   return None;
  4156 }
  4157 
  4158 static Window
  4159 x_dnd_get_target_window (struct x_display_info *dpyinfo,
  4160                          int root_x, int root_y, int *proto_out,
  4161                          int *motif_out, Window *toplevel_out,
  4162                          bool *was_frame)
  4163 {
  4164   Window child_return, child, proxy;
  4165   int dest_x_return, dest_y_return, rc, proto, motif;
  4166   int parent_x, parent_y;
  4167   bool extents_p;
  4168 #if defined HAVE_XCOMPOSITE && (XCOMPOSITE_MAJOR > 0 || XCOMPOSITE_MINOR > 2)
  4169   Window overlay_window;
  4170   XWindowAttributes attrs;
  4171 #endif
  4172   int wmstate;
  4173   struct frame *tooltip, *f;
  4174   bool unrelated;
  4175 
  4176   child_return = dpyinfo->root_window;
  4177   dest_x_return = root_x;
  4178   dest_y_return = root_y;
  4179 
  4180   proto = -1;
  4181   *motif_out = XM_DRAG_STYLE_NONE;
  4182   *toplevel_out = None;
  4183   *was_frame = false;
  4184 
  4185   if (x_dnd_use_toplevels)
  4186     {
  4187       extents_p = false;
  4188       child = x_dnd_get_target_window_1 (dpyinfo, root_x,
  4189                                          root_y, motif_out,
  4190                                          &extents_p);
  4191 
  4192       if (!x_dnd_allow_current_frame
  4193           && FRAME_X_WINDOW (x_dnd_frame) == child)
  4194         *motif_out = XM_DRAG_STYLE_NONE;
  4195 
  4196       f = x_top_window_to_frame (dpyinfo, child);
  4197 
  4198       *toplevel_out = child;
  4199 
  4200       if (child != None)
  4201         {
  4202           if (f)
  4203             {
  4204               *was_frame = true;
  4205               *proto_out = -1;
  4206               *motif_out = XM_DRAG_STYLE_NONE;
  4207 
  4208               return child;
  4209             }
  4210 
  4211 #ifndef USE_XCB
  4212           proxy = x_dnd_get_window_proxy (dpyinfo, child);
  4213 #else
  4214           x_dnd_get_proxy_proto (dpyinfo, child, &proxy, proto_out);
  4215 #endif
  4216 
  4217           if (proxy != None)
  4218             {
  4219               proto = x_dnd_get_window_proto (dpyinfo, proxy);
  4220 
  4221               if (proto != -1)
  4222                 {
  4223                   *proto_out = proto;
  4224                   return proxy;
  4225                 }
  4226             }
  4227 
  4228 #ifndef USE_XCB
  4229           *proto_out = x_dnd_get_window_proto (dpyinfo, child);
  4230 #endif
  4231           return child;
  4232         }
  4233 
  4234       if (extents_p)
  4235         {
  4236           *proto_out = -1;
  4237           *motif_out = XM_DRAG_STYLE_NONE;
  4238           *toplevel_out = None;
  4239 
  4240           return None;
  4241         }
  4242 
  4243       /* Then look at the composite overlay window.  */
  4244 #if defined HAVE_XCOMPOSITE && (XCOMPOSITE_MAJOR > 0 || XCOMPOSITE_MINOR > 2)
  4245       if (dpyinfo->composite_supported_p
  4246           && (dpyinfo->composite_major > 0
  4247               || dpyinfo->composite_minor > 2))
  4248         {
  4249           if (XGetSelectionOwner (dpyinfo->display,
  4250                                   dpyinfo->Xatom_NET_WM_CM_Sn) != None)
  4251             {
  4252               x_catch_errors (dpyinfo->display);
  4253               XGrabServer (dpyinfo->display);
  4254               overlay_window = XCompositeGetOverlayWindow (dpyinfo->display,
  4255                                                            dpyinfo->root_window);
  4256               XCompositeReleaseOverlayWindow (dpyinfo->display,
  4257                                               dpyinfo->root_window);
  4258               XUngrabServer (dpyinfo->display);
  4259 
  4260               if (!x_had_errors_p (dpyinfo->display))
  4261                 {
  4262                   XGetWindowAttributes (dpyinfo->display, overlay_window, &attrs);
  4263 
  4264                   if (attrs.map_state == IsViewable)
  4265                     {
  4266                       proxy = x_dnd_get_window_proxy (dpyinfo, overlay_window);
  4267 
  4268                       if (proxy != None)
  4269                         {
  4270                           proto = x_dnd_get_window_proto (dpyinfo, proxy);
  4271 
  4272                           if (proto != -1)
  4273                             {
  4274                               *proto_out = proto;
  4275                               *toplevel_out = overlay_window;
  4276                               x_uncatch_errors_after_check ();
  4277 
  4278                               return proxy;
  4279                             }
  4280                         }
  4281                     }
  4282                 }
  4283               x_uncatch_errors_after_check ();
  4284             }
  4285         }
  4286 #endif
  4287 
  4288       /* Now look for an XdndProxy on the root window.  */
  4289 
  4290       proxy = x_dnd_get_window_proxy (dpyinfo, dpyinfo->root_window);
  4291 
  4292       if (proxy != None)
  4293         {
  4294           proto = x_dnd_get_window_proto (dpyinfo, dpyinfo->root_window);
  4295 
  4296           if (proto != -1)
  4297             {
  4298               *toplevel_out = dpyinfo->root_window;
  4299               *proto_out = proto;
  4300               return proxy;
  4301             }
  4302         }
  4303 
  4304       /* No toplevel was found and the overlay and root windows were
  4305          not proxies, so return None.  */
  4306       *proto_out = -1;
  4307       *toplevel_out = dpyinfo->root_window;
  4308       return None;
  4309     }
  4310 
  4311   /* Not strictly necessary, but satisfies GCC.  */
  4312   child = dpyinfo->root_window;
  4313 
  4314   while (child_return != None)
  4315     {
  4316       child = child_return;
  4317       parent_x = dest_x_return;
  4318       parent_y = dest_y_return;
  4319 
  4320       x_catch_errors (dpyinfo->display);
  4321       rc = XTranslateCoordinates (dpyinfo->display, dpyinfo->root_window,
  4322                                   child_return, root_x, root_y, &dest_x_return,
  4323                                   &dest_y_return, &child_return);
  4324 
  4325       if (x_had_errors_p (dpyinfo->display) || !rc)
  4326         {
  4327           x_uncatch_errors_after_check ();
  4328           break;
  4329         }
  4330 
  4331       if (child_return)
  4332         {
  4333           /* If child_return is a tooltip frame, look beneath it.  We
  4334              never want to drop anything onto a tooltip frame.  */
  4335 
  4336           tooltip = x_tooltip_window_to_frame (dpyinfo, child_return,
  4337                                                &unrelated);
  4338 
  4339           if (tooltip || unrelated)
  4340             child_return = x_get_window_below (dpyinfo->display, child_return,
  4341                                                parent_x, parent_y, &dest_x_return,
  4342                                                &dest_y_return);
  4343 
  4344           if (!child_return)
  4345             {
  4346               x_uncatch_errors ();
  4347               break;
  4348             }
  4349 
  4350           f = x_top_window_to_frame (dpyinfo, child_return);
  4351 
  4352           if (f)
  4353             {
  4354               *proto_out = -1;
  4355               *motif_out = XM_DRAG_STYLE_NONE;
  4356               *toplevel_out = child_return;
  4357               *was_frame = true;
  4358 
  4359               return child_return;
  4360             }
  4361 
  4362           if (x_dnd_get_wm_state_and_proto (dpyinfo, child_return,
  4363                                             &wmstate, &proto, &motif,
  4364                                             &proxy)
  4365               /* `proto' and `motif' are set by x_dnd_get_wm_state
  4366                  even if getting the wm state failed.  */
  4367               || proto != -1 || motif != XM_DRAG_STYLE_NONE)
  4368             {
  4369               *proto_out = proto;
  4370               *motif_out = (x_dnd_disable_motif_protocol
  4371                             ? XM_DRAG_STYLE_NONE : motif);
  4372               *toplevel_out = child_return;
  4373               x_uncatch_errors ();
  4374 
  4375               return child_return;
  4376             }
  4377 
  4378           if (proxy != None)
  4379             {
  4380               proto = x_dnd_get_window_proto (dpyinfo, proxy);
  4381 
  4382               if (proto != -1)
  4383                 {
  4384                   *proto_out = proto;
  4385                   *toplevel_out = child_return;
  4386 
  4387                   x_uncatch_errors ();
  4388                   return proxy;
  4389                 }
  4390             }
  4391         }
  4392 
  4393       x_uncatch_errors ();
  4394     }
  4395 
  4396 #if defined HAVE_XCOMPOSITE && (XCOMPOSITE_MAJOR > 0 || XCOMPOSITE_MINOR > 2)
  4397   if (child != dpyinfo->root_window)
  4398     {
  4399 #endif
  4400       if (child != None)
  4401         {
  4402           proxy = x_dnd_get_window_proxy (dpyinfo, child);
  4403 
  4404           if (proxy)
  4405             {
  4406               proto = x_dnd_get_window_proto (dpyinfo, proxy);
  4407 
  4408               if (proto != -1)
  4409                 {
  4410                   *proto_out = proto;
  4411                   *toplevel_out = child;
  4412                   return proxy;
  4413                 }
  4414             }
  4415         }
  4416 
  4417       *proto_out = x_dnd_get_window_proto (dpyinfo, child);
  4418       return child;
  4419 #if defined HAVE_XCOMPOSITE && (XCOMPOSITE_MAJOR > 0 || XCOMPOSITE_MINOR > 2)
  4420     }
  4421   else if (dpyinfo->composite_supported_p
  4422            && (dpyinfo->composite_major > 0
  4423                || dpyinfo->composite_minor > 2))
  4424     {
  4425       /* Only do this if a compositing manager is present.  */
  4426       if (XGetSelectionOwner (dpyinfo->display,
  4427                               dpyinfo->Xatom_NET_WM_CM_Sn) != None)
  4428         {
  4429           x_catch_errors (dpyinfo->display);
  4430           XGrabServer (dpyinfo->display);
  4431           overlay_window = XCompositeGetOverlayWindow (dpyinfo->display,
  4432                                                        dpyinfo->root_window);
  4433           XCompositeReleaseOverlayWindow (dpyinfo->display,
  4434                                           dpyinfo->root_window);
  4435           XUngrabServer (dpyinfo->display);
  4436 
  4437           if (!x_had_errors_p (dpyinfo->display))
  4438             {
  4439               XGetWindowAttributes (dpyinfo->display, overlay_window, &attrs);
  4440 
  4441               if (attrs.map_state == IsViewable)
  4442                 {
  4443                   proxy = x_dnd_get_window_proxy (dpyinfo, overlay_window);
  4444 
  4445                   if (proxy != None)
  4446                     {
  4447                       proto = x_dnd_get_window_proto (dpyinfo, proxy);
  4448 
  4449                       if (proto != -1)
  4450                         {
  4451                           *proto_out = proto;
  4452                           *toplevel_out = overlay_window;
  4453                           x_uncatch_errors_after_check ();
  4454 
  4455                           return proxy;
  4456                         }
  4457                     }
  4458                 }
  4459             }
  4460           x_uncatch_errors_after_check ();
  4461         }
  4462     }
  4463 
  4464   if (child != None)
  4465     {
  4466       proxy = x_dnd_get_window_proxy (dpyinfo, child);
  4467 
  4468       if (proxy)
  4469         {
  4470           proto = x_dnd_get_window_proto (dpyinfo, proxy);
  4471 
  4472           if (proto != -1)
  4473             {
  4474               *toplevel_out = child;
  4475               *proto_out = proto;
  4476               return proxy;
  4477             }
  4478         }
  4479     }
  4480 
  4481   *proto_out = x_dnd_get_window_proto (dpyinfo, child);
  4482   *toplevel_out = child;
  4483   return child;
  4484 #endif
  4485 }
  4486 
  4487 static Window
  4488 x_dnd_get_window_proxy (struct x_display_info *dpyinfo, Window wdesc)
  4489 {
  4490   int rc, actual_format;
  4491   unsigned long actual_size, bytes_remaining;
  4492   unsigned char *tmp_data = NULL;
  4493   XWindowAttributes attrs;
  4494   Atom actual_type;
  4495   Window proxy;
  4496 
  4497   proxy = None;
  4498   x_catch_errors (dpyinfo->display);
  4499   rc = XGetWindowProperty (dpyinfo->display, wdesc,
  4500                            dpyinfo->Xatom_XdndProxy,
  4501                            0, 1, False, XA_WINDOW,
  4502                            &actual_type, &actual_format,
  4503                            &actual_size, &bytes_remaining,
  4504                            &tmp_data);
  4505 
  4506   if (!x_had_errors_p (dpyinfo->display)
  4507       && rc == Success
  4508       && tmp_data
  4509       && actual_type == XA_WINDOW
  4510       && actual_format == 32
  4511       && actual_size == 1)
  4512     {
  4513       proxy = *(Window *) tmp_data;
  4514 
  4515       /* Verify the proxy window exists.  */
  4516       XGetWindowAttributes (dpyinfo->display, proxy, &attrs);
  4517 
  4518       if (x_had_errors_p (dpyinfo->display))
  4519         proxy = None;
  4520     }
  4521 
  4522   if (tmp_data)
  4523     XFree (tmp_data);
  4524   x_uncatch_errors_after_check ();
  4525 
  4526   return proxy;
  4527 }
  4528 
  4529 static int
  4530 x_dnd_get_window_proto (struct x_display_info *dpyinfo, Window wdesc)
  4531 {
  4532   Atom actual, value;
  4533   unsigned char *tmp_data = NULL;
  4534   int rc, format;
  4535   unsigned long n, left;
  4536   bool had_errors;
  4537 
  4538   if (wdesc == None || (!x_dnd_allow_current_frame
  4539                         && wdesc == FRAME_OUTER_WINDOW (x_dnd_frame)))
  4540     return -1;
  4541 
  4542   x_catch_errors (dpyinfo->display);
  4543   rc = XGetWindowProperty (dpyinfo->display, wdesc, dpyinfo->Xatom_XdndAware,
  4544                            0, 1, False, XA_ATOM, &actual, &format, &n, &left,
  4545                            &tmp_data);
  4546   had_errors = x_had_errors_p (dpyinfo->display);
  4547   x_uncatch_errors_after_check ();
  4548 
  4549   if (had_errors || rc != Success || actual != XA_ATOM || format != 32 || n < 1
  4550       || !tmp_data)
  4551     {
  4552       if (tmp_data)
  4553         XFree (tmp_data);
  4554       return -1;
  4555     }
  4556 
  4557   value = (int) *(Atom *) tmp_data;
  4558   XFree (tmp_data);
  4559 
  4560   return min (X_DND_SUPPORTED_VERSION, (int) value);
  4561 }
  4562 
  4563 static void
  4564 x_dnd_send_enter (struct frame *f, Window target, Window toplevel,
  4565                   int supported)
  4566 {
  4567   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  4568   int i;
  4569   XEvent msg;
  4570 
  4571   msg.xclient.type = ClientMessage;
  4572   msg.xclient.message_type = dpyinfo->Xatom_XdndEnter;
  4573   msg.xclient.format = 32;
  4574   msg.xclient.window = toplevel;
  4575   msg.xclient.data.l[0] = FRAME_X_WINDOW (f);
  4576   msg.xclient.data.l[1] = (((unsigned int) min (X_DND_SUPPORTED_VERSION,
  4577                                                 supported) << 24)
  4578                            | (x_dnd_n_targets > 3 ? 1 : 0));
  4579   msg.xclient.data.l[2] = 0;
  4580   msg.xclient.data.l[3] = 0;
  4581   msg.xclient.data.l[4] = 0;
  4582 
  4583   for (i = 0; i < min (3, x_dnd_n_targets); ++i)
  4584     msg.xclient.data.l[i + 2] = x_dnd_targets[i];
  4585 
  4586   if (x_dnd_n_targets > 3 && !x_dnd_init_type_lists)
  4587     XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
  4588                      dpyinfo->Xatom_XdndTypeList, XA_ATOM, 32,
  4589                      PropModeReplace, (unsigned char *) x_dnd_targets,
  4590                      x_dnd_n_targets);
  4591 
  4592   /* Now record that the type list has already been set (if required),
  4593      so we don't have to set it again.  */
  4594   x_dnd_init_type_lists = true;
  4595 
  4596   x_ignore_errors_for_next_request (dpyinfo, 0);
  4597   XSendEvent (FRAME_X_DISPLAY (f), target, False, NoEventMask, &msg);
  4598   x_stop_ignoring_errors (dpyinfo);
  4599 }
  4600 
  4601 static void
  4602 x_dnd_send_position (struct frame *f, Window target, Window toplevel,
  4603                      int supported, unsigned short root_x,
  4604                      unsigned short root_y, Time timestamp, Atom action,
  4605                      int button, unsigned state)
  4606 {
  4607   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  4608   XEvent msg;
  4609 
  4610   msg.xclient.type = ClientMessage;
  4611   msg.xclient.message_type = dpyinfo->Xatom_XdndPosition;
  4612   msg.xclient.format = 32;
  4613   msg.xclient.window = toplevel;
  4614   msg.xclient.data.l[0] = FRAME_X_WINDOW (f);
  4615   msg.xclient.data.l[1] = 0;
  4616 
  4617   /* This is problematic because it's not specified in the
  4618      freedesktop.org copy of the protocol specification, but the copy
  4619      maintained by the original author of the protocol specifies it
  4620      for all versions.  Since at least one program supports these
  4621      flags, but uses protocol v4 (and not v5), set them for all
  4622      protocol versions.  */
  4623   if (button >= 4 && button <= 7)
  4624     {
  4625       msg.xclient.data.l[1] |= (1 << 10);
  4626       msg.xclient.data.l[1] |= (button - 4) << 8;
  4627     }
  4628   else if (button)
  4629     return;
  4630 
  4631   msg.xclient.data.l[1] |= state & 0xff;
  4632 
  4633   msg.xclient.data.l[2] = (root_x << 16) | root_y;
  4634   msg.xclient.data.l[3] = 0;
  4635   msg.xclient.data.l[4] = 0;
  4636 
  4637   if (supported >= 3)
  4638     msg.xclient.data.l[3] = timestamp;
  4639 
  4640   if (supported >= 4)
  4641     msg.xclient.data.l[4] = action;
  4642 
  4643   if (x_dnd_waiting_for_status_window == target)
  4644     {
  4645       x_dnd_pending_send_position = msg;
  4646       x_dnd_pending_send_position_button = button;
  4647       x_dnd_pending_send_position_root_x = root_x;
  4648       x_dnd_pending_send_position_root_y = root_y;
  4649     }
  4650   else
  4651     {
  4652       if (target == x_dnd_mouse_rect_target
  4653           && x_dnd_mouse_rect.width
  4654           && x_dnd_mouse_rect.height
  4655           /* Ignore the mouse rectangle if we're supposed to be sending a
  4656              button press instead.  */
  4657           && !button)
  4658         {
  4659           if (root_x >= x_dnd_mouse_rect.x
  4660               && root_x < (x_dnd_mouse_rect.x
  4661                            + x_dnd_mouse_rect.width)
  4662               && root_y >= x_dnd_mouse_rect.y
  4663               && root_y < (x_dnd_mouse_rect.y
  4664                            + x_dnd_mouse_rect.height))
  4665             return;
  4666         }
  4667 
  4668       x_ignore_errors_for_next_request (dpyinfo, 0);
  4669       XSendEvent (FRAME_X_DISPLAY (f), target, False, NoEventMask, &msg);
  4670       x_stop_ignoring_errors (dpyinfo);
  4671 
  4672       x_dnd_waiting_for_status_window = target;
  4673     }
  4674 }
  4675 
  4676 static void
  4677 x_dnd_send_leave (struct frame *f, Window target, Window toplevel)
  4678 {
  4679   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  4680   XEvent msg;
  4681 
  4682   msg.xclient.type = ClientMessage;
  4683   msg.xclient.message_type = dpyinfo->Xatom_XdndLeave;
  4684   msg.xclient.format = 32;
  4685   msg.xclient.window = toplevel;
  4686   msg.xclient.data.l[0] = FRAME_X_WINDOW (f);
  4687   msg.xclient.data.l[1] = 0;
  4688   msg.xclient.data.l[2] = 0;
  4689   msg.xclient.data.l[3] = 0;
  4690   msg.xclient.data.l[4] = 0;
  4691 
  4692   x_dnd_waiting_for_status_window = None;
  4693   x_dnd_pending_send_position.type = 0;
  4694 
  4695   x_ignore_errors_for_next_request (dpyinfo, 0);
  4696   XSendEvent (FRAME_X_DISPLAY (f), target, False, NoEventMask, &msg);
  4697   x_stop_ignoring_errors (dpyinfo);
  4698 }
  4699 
  4700 static bool
  4701 x_dnd_send_drop (struct frame *f, Window target, Window toplevel,
  4702                  Time timestamp, int supported)
  4703 {
  4704   struct x_display_info *dpyinfo;
  4705   XEvent msg;
  4706 
  4707   if (x_dnd_action == None)
  4708     {
  4709       x_dnd_send_leave (f, target, toplevel);
  4710       return false;
  4711     }
  4712 
  4713   dpyinfo = FRAME_DISPLAY_INFO (f);
  4714 
  4715   msg.xclient.type = ClientMessage;
  4716   msg.xclient.message_type = dpyinfo->Xatom_XdndDrop;
  4717   msg.xclient.format = 32;
  4718   msg.xclient.window = toplevel;
  4719   msg.xclient.data.l[0] = FRAME_X_WINDOW (f);
  4720   msg.xclient.data.l[1] = 0;
  4721   msg.xclient.data.l[2] = 0;
  4722   msg.xclient.data.l[3] = 0;
  4723   msg.xclient.data.l[4] = 0;
  4724 
  4725   if (supported >= 1)
  4726     msg.xclient.data.l[2] = timestamp;
  4727 
  4728   x_ignore_errors_for_next_request (dpyinfo, 0);
  4729   XSendEvent (FRAME_X_DISPLAY (f), target, False, NoEventMask, &msg);
  4730   x_stop_ignoring_errors (dpyinfo);
  4731   return true;
  4732 }
  4733 
  4734 static bool
  4735 x_dnd_do_drop (Window target, Window toplevel, int supported)
  4736 {
  4737   if (x_dnd_waiting_for_status_window != target)
  4738     return x_dnd_send_drop (x_dnd_frame, target, toplevel,
  4739                             x_dnd_selection_timestamp, supported);
  4740 
  4741   x_dnd_need_send_drop = true;
  4742   x_dnd_send_drop_proto = supported;
  4743 
  4744   return true;
  4745 }
  4746 
  4747 static void
  4748 x_set_dnd_targets (Atom *targets, int ntargets)
  4749 {
  4750   if (x_dnd_targets)
  4751     xfree (x_dnd_targets);
  4752 
  4753   block_input ();
  4754   x_dnd_targets = xmalloc (sizeof *targets * ntargets);
  4755   x_dnd_n_targets = ntargets;
  4756 
  4757   memcpy (x_dnd_targets, targets,
  4758           sizeof *targets * ntargets);
  4759   unblock_input ();
  4760 }
  4761 
  4762 static void
  4763 x_free_dnd_targets (void)
  4764 {
  4765   if (!x_dnd_targets)
  4766     return;
  4767 
  4768   xfree (x_dnd_targets);
  4769   x_dnd_targets = NULL;
  4770   x_dnd_n_targets = 0;
  4771 }
  4772 
  4773 /* Clear some Lisp variables after the drop finishes, so they are
  4774    freed by the GC.  */
  4775 
  4776 static void
  4777 x_clear_dnd_variables (void)
  4778 {
  4779   x_dnd_monitors = Qnil;
  4780   x_dnd_unsupported_drop_data = Qnil;
  4781 }
  4782 
  4783 static void
  4784 x_free_dnd_toplevels (void)
  4785 {
  4786   if (!x_dnd_use_toplevels || !x_dnd_toplevels)
  4787     return;
  4788 
  4789   /* If the display is deleted, x_dnd_toplevels will already be
  4790      NULL, so we can always assume the display is alive here.  */
  4791 
  4792   x_dnd_free_toplevels (true);
  4793 }
  4794 
  4795 /* Restore event masks and window properties changed during a
  4796    drag-and-drop operation, after it finishes.  */
  4797 static void
  4798 x_restore_events_after_dnd (struct frame *f, XWindowAttributes *wa)
  4799 {
  4800   struct x_display_info *dpyinfo;
  4801 
  4802   dpyinfo = FRAME_DISPLAY_INFO (f);
  4803 
  4804   /* Restore the old event mask.  */
  4805   XSelectInput (dpyinfo->display, dpyinfo->root_window,
  4806                 wa->your_event_mask);
  4807 #ifdef HAVE_XKB
  4808   if (dpyinfo->supports_xkb)
  4809     XkbSelectEvents (dpyinfo->display, XkbUseCoreKbd,
  4810                      XkbStateNotifyMask, 0);
  4811 #endif
  4812   /* Delete the Motif drag initiator info if it was set up.  */
  4813   if (x_dnd_motif_setup_p)
  4814     XDeleteProperty (dpyinfo->display, FRAME_X_WINDOW (f),
  4815                      x_dnd_motif_atom);
  4816 
  4817   /* Remove any type list set as well.  */
  4818   if (x_dnd_init_type_lists && x_dnd_n_targets > 3)
  4819     XDeleteProperty (dpyinfo->display, FRAME_X_WINDOW (f),
  4820                      dpyinfo->Xatom_XdndTypeList);
  4821 }
  4822 
  4823 #ifdef HAVE_XINPUT2
  4824 
  4825 /* Cancel the current drag-and-drop operation, sending leave messages
  4826    to any relevant toplevels.  This is called from the event loop when
  4827    an event is received telling Emacs to gracefully cancel the
  4828    drag-and-drop operation.  */
  4829 
  4830 static void
  4831 x_dnd_cancel_dnd_early (void)
  4832 {
  4833   struct frame *f;
  4834   xm_drop_start_message dmsg;
  4835 
  4836   eassert (x_dnd_frame && x_dnd_in_progress);
  4837 
  4838   f = x_dnd_frame;
  4839 
  4840   if (x_dnd_last_seen_window != None
  4841       && x_dnd_last_protocol_version != -1)
  4842     x_dnd_send_leave (x_dnd_frame,
  4843                       x_dnd_last_seen_window,
  4844                       x_dnd_last_seen_toplevel);
  4845   else if (x_dnd_last_seen_window != None
  4846            && !XM_DRAG_STYLE_IS_DROP_ONLY (x_dnd_last_motif_style)
  4847            && x_dnd_last_motif_style != XM_DRAG_STYLE_NONE
  4848            && x_dnd_motif_setup_p)
  4849     {
  4850       dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
  4851                                     XM_DRAG_REASON_DROP_START);
  4852       dmsg.byte_order = XM_BYTE_ORDER_CUR_FIRST;
  4853       dmsg.timestamp = FRAME_DISPLAY_INFO (f)->last_user_time;
  4854       dmsg.side_effects
  4855         = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (FRAME_DISPLAY_INFO (f),
  4856                                                            x_dnd_wanted_action),
  4857                                XM_DROP_SITE_VALID, x_dnd_motif_operations,
  4858                                XM_DROP_ACTION_DROP_CANCEL);
  4859       dmsg.x = 0;
  4860       dmsg.y = 0;
  4861       dmsg.index_atom = x_dnd_motif_atom;
  4862       dmsg.source_window = FRAME_X_WINDOW (f);
  4863 
  4864       x_dnd_send_xm_leave_for_drop (FRAME_DISPLAY_INFO (f), f,
  4865                                     x_dnd_last_seen_window,
  4866                                     FRAME_DISPLAY_INFO (f)->last_user_time);
  4867       xm_send_drop_message (FRAME_DISPLAY_INFO (f), FRAME_X_WINDOW (f),
  4868                             x_dnd_last_seen_window, &dmsg);
  4869     }
  4870 
  4871   x_dnd_last_seen_window = None;
  4872   x_dnd_last_seen_toplevel = None;
  4873   x_dnd_in_progress = false;
  4874   x_dnd_waiting_for_finish = false;
  4875   x_dnd_return_frame_object = NULL;
  4876   x_dnd_movement_frame = NULL;
  4877   x_dnd_wheel_frame = NULL;
  4878   x_dnd_frame = NULL;
  4879   x_dnd_action = None;
  4880   x_dnd_action_symbol = Qnil;
  4881 }
  4882 
  4883 #endif
  4884 
  4885 static void
  4886 x_dnd_cleanup_drag_and_drop (void *frame)
  4887 {
  4888   struct frame *f = frame;
  4889   xm_drop_start_message dmsg;
  4890 
  4891   if (!x_dnd_unwind_flag)
  4892     return;
  4893 
  4894   if (x_dnd_in_progress)
  4895     {
  4896       eassert (x_dnd_frame);
  4897 
  4898       block_input ();
  4899       if (x_dnd_last_seen_window != None
  4900           && x_dnd_last_protocol_version != -1)
  4901         x_dnd_send_leave (x_dnd_frame,
  4902                           x_dnd_last_seen_window,
  4903                           x_dnd_last_seen_toplevel);
  4904       else if (x_dnd_last_seen_window != None
  4905                && !XM_DRAG_STYLE_IS_DROP_ONLY (x_dnd_last_motif_style)
  4906                && x_dnd_last_motif_style != XM_DRAG_STYLE_NONE
  4907                && x_dnd_motif_setup_p)
  4908         {
  4909           dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
  4910                                         XM_DRAG_REASON_DROP_START);
  4911           dmsg.byte_order = XM_BYTE_ORDER_CUR_FIRST;
  4912           dmsg.timestamp = FRAME_DISPLAY_INFO (f)->last_user_time;
  4913           dmsg.side_effects
  4914             = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (FRAME_DISPLAY_INFO (f),
  4915                                                                x_dnd_wanted_action),
  4916                                    XM_DROP_SITE_VALID, x_dnd_motif_operations,
  4917                                    XM_DROP_ACTION_DROP_CANCEL);
  4918           dmsg.x = 0;
  4919           dmsg.y = 0;
  4920           dmsg.index_atom = x_dnd_motif_atom;
  4921           dmsg.source_window = FRAME_X_WINDOW (f);
  4922 
  4923           x_dnd_send_xm_leave_for_drop (FRAME_DISPLAY_INFO (f), f,
  4924                                         x_dnd_last_seen_window,
  4925                                         FRAME_DISPLAY_INFO (f)->last_user_time);
  4926           xm_send_drop_message (FRAME_DISPLAY_INFO (f), FRAME_X_WINDOW (f),
  4927                                 x_dnd_last_seen_window, &dmsg);
  4928         }
  4929       unblock_input ();
  4930 
  4931       x_dnd_end_window = x_dnd_last_seen_window;
  4932       x_dnd_last_seen_window = None;
  4933       x_dnd_last_seen_toplevel = None;
  4934       x_dnd_in_progress = false;
  4935     }
  4936 
  4937   x_dnd_waiting_for_finish = false;
  4938 
  4939   FRAME_DISPLAY_INFO (f)->grabbed = 0;
  4940 #ifdef USE_GTK
  4941   current_hold_quit = NULL;
  4942 #endif
  4943   x_dnd_return_frame_object = NULL;
  4944   x_dnd_movement_frame = NULL;
  4945   x_dnd_wheel_frame = NULL;
  4946   x_dnd_frame = NULL;
  4947 
  4948   x_restore_events_after_dnd (f, &x_dnd_old_window_attrs);
  4949 }
  4950 
  4951 
  4952 
  4953 /* Primitives for simplified drag-and-drop tracking when items are
  4954    being dragged between frames comprising the same Emacs session.  */
  4955 
  4956 static void
  4957 x_dnd_note_self_position (struct x_display_info *dpyinfo, Window target,
  4958                           unsigned short root_x, unsigned short root_y)
  4959 {
  4960   struct frame *f;
  4961   int dest_x, dest_y;
  4962 
  4963   f = x_top_window_to_frame (dpyinfo, target);
  4964 
  4965   if (f)
  4966     {
  4967       x_translate_coordinates (f, root_x, root_y, &dest_x, &dest_y);
  4968 
  4969       x_dnd_movement_frame = f;
  4970       x_dnd_movement_x = dest_x;
  4971       x_dnd_movement_y = dest_y;
  4972 
  4973       return;
  4974     }
  4975 }
  4976 
  4977 static void
  4978 x_dnd_note_self_wheel (struct x_display_info *dpyinfo, Window target,
  4979                        unsigned short root_x, unsigned short root_y,
  4980                        int button, unsigned int state, Time time)
  4981 {
  4982   struct frame *f;
  4983   int dest_x, dest_y;
  4984 
  4985   if (button < 4 || button > 7)
  4986     return;
  4987 
  4988   f = x_top_window_to_frame (dpyinfo, target);
  4989 
  4990   if (f)
  4991     {
  4992       x_translate_coordinates (f, root_x, root_y, &dest_x, &dest_y);
  4993 
  4994       x_dnd_wheel_frame = f;
  4995       x_dnd_wheel_x = dest_x;
  4996       x_dnd_wheel_y = dest_y;
  4997       x_dnd_wheel_button = button;
  4998       x_dnd_wheel_state = state;
  4999       x_dnd_wheel_time = time;
  5000 
  5001       return;
  5002     }
  5003 }
  5004 
  5005 static void
  5006 x_dnd_note_self_drop (struct x_display_info *dpyinfo, Window target,
  5007                       unsigned short root_x, unsigned short root_y,
  5008                       Time timestamp)
  5009 {
  5010   struct input_event ie;
  5011   struct frame *f;
  5012   Lisp_Object lval;
  5013   char **atom_names;
  5014   char *name;
  5015   int win_x, win_y, i;
  5016 
  5017   if (!x_dnd_allow_current_frame
  5018       && (FRAME_OUTER_WINDOW (x_dnd_frame)
  5019           == target))
  5020     return;
  5021 
  5022   f = x_top_window_to_frame (dpyinfo, target);
  5023 
  5024   if (!f)
  5025     return;
  5026 
  5027   if (NILP (Vx_dnd_native_test_function))
  5028     return;
  5029 
  5030   x_translate_coordinates (f, root_x, root_y, &win_x, &win_y);
  5031 
  5032   /* Emacs can't respond to DND events inside the nested event loop,
  5033      so when dragging items to itself, call the test function
  5034      manually.  */
  5035 
  5036   XSETFRAME (lval, f);
  5037   x_dnd_action = None;
  5038   x_dnd_action_symbol
  5039     = safe_call2 (Vx_dnd_native_test_function,
  5040                   Fposn_at_x_y (make_fixnum (win_x),
  5041                                 make_fixnum (win_y),
  5042                                 lval, Qnil),
  5043                   x_atom_to_symbol (dpyinfo,
  5044                                     x_dnd_wanted_action));
  5045 
  5046   if (!SYMBOLP (x_dnd_action_symbol))
  5047     return;
  5048 
  5049   EVENT_INIT (ie);
  5050 
  5051   ie.kind = DRAG_N_DROP_EVENT;
  5052   XSETFRAME (ie.frame_or_window, f);
  5053 
  5054   lval = Qnil;
  5055   atom_names = alloca (x_dnd_n_targets * sizeof *atom_names);
  5056   name = x_get_atom_name (dpyinfo, x_dnd_wanted_action, NULL);
  5057 
  5058   if (!XGetAtomNames (dpyinfo->display, x_dnd_targets,
  5059                       x_dnd_n_targets, atom_names))
  5060     {
  5061       xfree (name);
  5062       return;
  5063     }
  5064 
  5065   for (i = x_dnd_n_targets; i != 0; --i)
  5066     {
  5067       lval = Fcons (intern (atom_names[i - 1]), lval);
  5068       XFree (atom_names[i - 1]);
  5069     }
  5070 
  5071   lval = Fcons (assq_no_quit (QXdndSelection,
  5072                               FRAME_TERMINAL (f)->Vselection_alist),
  5073                 lval);
  5074   lval = Fcons (intern (name), lval);
  5075   lval = Fcons (QXdndSelection, lval);
  5076   ie.arg = lval;
  5077   ie.timestamp = timestamp;
  5078 
  5079   XSETINT (ie.x, win_x);
  5080   XSETINT (ie.y, win_y);
  5081 
  5082   xfree (name);
  5083   kbd_buffer_store_event (&ie);
  5084 }
  5085 
  5086 
  5087 
  5088 /* Miscellaneous X event and graphics extension functions.  */
  5089 
  5090 /* Flush display of frame F.  */
  5091 
  5092 static void
  5093 x_flush (struct frame *f)
  5094 {
  5095   eassert (f && FRAME_X_P (f));
  5096   /* Don't call XFlush when it is not safe to redisplay; the X
  5097      connection may be broken.  */
  5098   if (!NILP (Vinhibit_redisplay))
  5099     return;
  5100 
  5101   block_input ();
  5102   XFlush (FRAME_X_DISPLAY (f));
  5103   unblock_input ();
  5104 }
  5105 
  5106 #ifdef HAVE_XDBE
  5107 static void
  5108 x_drop_xrender_surfaces (struct frame *f)
  5109 {
  5110   font_drop_xrender_surfaces (f);
  5111 
  5112 #ifdef HAVE_XRENDER
  5113   if (f && FRAME_X_DOUBLE_BUFFERED_P (f)
  5114       && FRAME_X_PICTURE (f) != None)
  5115     {
  5116       XRenderFreePicture (FRAME_X_DISPLAY (f),
  5117                           FRAME_X_PICTURE (f));
  5118       FRAME_X_PICTURE (f) = None;
  5119     }
  5120 #endif
  5121 }
  5122 #endif
  5123 
  5124 #ifdef HAVE_XRENDER
  5125 void
  5126 x_xr_ensure_picture (struct frame *f)
  5127 {
  5128   if (FRAME_X_PICTURE (f) == None && FRAME_X_PICTURE_FORMAT (f))
  5129     {
  5130       XRenderPictureAttributes attrs;
  5131       attrs.clip_mask = None;
  5132       XRenderPictFormat *fmt = FRAME_X_PICTURE_FORMAT (f);
  5133 
  5134       FRAME_X_PICTURE (f) = XRenderCreatePicture (FRAME_X_DISPLAY (f),
  5135                                                   FRAME_X_RAW_DRAWABLE (f),
  5136                                                   fmt, CPClipMask, &attrs);
  5137     }
  5138 }
  5139 #endif
  5140 
  5141 
  5142 /***********************************************************************
  5143                               Debugging
  5144  ***********************************************************************/
  5145 
  5146 #if false
  5147 
  5148 /* This is a function useful for recording debugging information about
  5149    the sequence of occurrences in this file.  */
  5150 
  5151 struct record
  5152 {
  5153   char *locus;
  5154   int type;
  5155 };
  5156 
  5157 struct record event_record[100];
  5158 
  5159 int event_record_index;
  5160 
  5161 void
  5162 record_event (char *locus, int type)
  5163 {
  5164   if (event_record_index == ARRAYELTS (event_record))
  5165     event_record_index = 0;
  5166 
  5167   event_record[event_record_index].locus = locus;
  5168   event_record[event_record_index].type = type;
  5169   event_record_index++;
  5170 }
  5171 
  5172 #endif
  5173 
  5174 
  5175 
  5176 /* Miscelaneous event handling functions.  */
  5177 
  5178 static void
  5179 x_toolkit_position (struct frame *f, int x, int y,
  5180                     bool *menu_bar_p, bool *tool_bar_p)
  5181 {
  5182 #ifdef USE_GTK
  5183   GdkRectangle test_rect;
  5184   int scale;
  5185 
  5186   y += (FRAME_MENUBAR_HEIGHT (f)
  5187         + FRAME_TOOLBAR_TOP_HEIGHT (f));
  5188   x += FRAME_TOOLBAR_LEFT_WIDTH (f);
  5189 
  5190   if (FRAME_EXTERNAL_MENU_BAR (f))
  5191     *menu_bar_p = (x >= 0 && x < FRAME_PIXEL_WIDTH (f)
  5192                    && y >= 0 && y < FRAME_MENUBAR_HEIGHT (f));
  5193 
  5194   if (FRAME_X_OUTPUT (f)->toolbar_widget)
  5195     {
  5196       scale = xg_get_scale (f);
  5197       test_rect.x = x / scale;
  5198       test_rect.y = y / scale;
  5199       test_rect.width = 1;
  5200       test_rect.height = 1;
  5201 
  5202       *tool_bar_p = gtk_widget_intersect (FRAME_X_OUTPUT (f)->toolbar_widget,
  5203                                           &test_rect, NULL);
  5204     }
  5205 #elif defined USE_X_TOOLKIT
  5206   *menu_bar_p = (x > 0 && x < FRAME_PIXEL_WIDTH (f)
  5207                  && (y < 0 && y >= -FRAME_MENUBAR_HEIGHT (f)));
  5208 #else
  5209   *menu_bar_p = (WINDOWP (f->menu_bar_window)
  5210                  && (x > 0 && x < FRAME_PIXEL_WIDTH (f)
  5211                      && (y > 0 && y < FRAME_MENU_BAR_HEIGHT (f))));
  5212 #endif
  5213 }
  5214 
  5215 static void
  5216 x_update_opaque_region (struct frame *f, XEvent *configure)
  5217 {
  5218   unsigned long opaque_region[] = {0, 0,
  5219                                    (configure
  5220                                     ? configure->xconfigure.width
  5221                                     : FRAME_PIXEL_WIDTH (f)),
  5222                                    (configure
  5223                                     ? configure->xconfigure.height
  5224                                     : FRAME_PIXEL_HEIGHT (f))};
  5225 #ifdef HAVE_GTK3
  5226   GObjectClass *object_class;
  5227   GtkWidgetClass *class;
  5228 #endif
  5229 
  5230   if (!FRAME_DISPLAY_INFO (f)->alpha_bits)
  5231     return;
  5232 
  5233   if (f->alpha_background < 1.0)
  5234     XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
  5235                      FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region,
  5236                      XA_CARDINAL, 32, PropModeReplace,
  5237                      NULL, 0);
  5238 #ifndef HAVE_GTK3
  5239   else
  5240     XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
  5241                      FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region,
  5242                      XA_CARDINAL, 32, PropModeReplace,
  5243                      (unsigned char *) &opaque_region, 4);
  5244 #else
  5245   else if (FRAME_TOOLTIP_P (f))
  5246     XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
  5247                      FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region,
  5248                      XA_CARDINAL, 32, PropModeReplace,
  5249                      (unsigned char *) &opaque_region, 4);
  5250   else
  5251     {
  5252       /* This causes child frames to not update correctly for an
  5253          unknown reason.  (bug#55779) */
  5254       if (!FRAME_PARENT_FRAME (f))
  5255         {
  5256           object_class = G_OBJECT_GET_CLASS (FRAME_GTK_OUTER_WIDGET (f));
  5257           class = GTK_WIDGET_CLASS (object_class);
  5258 
  5259           if (class->style_updated)
  5260             class->style_updated (FRAME_GTK_OUTER_WIDGET (f));
  5261         }
  5262     }
  5263 #endif
  5264 }
  5265 
  5266 
  5267 #if defined USE_CAIRO || defined HAVE_XRENDER
  5268 static int
  5269 x_gc_free_ext_data_private (XExtData *extension)
  5270 {
  5271   xfree (extension->private_data);
  5272 
  5273   return 0;
  5274 }
  5275 
  5276 static struct x_gc_ext_data *
  5277 x_gc_get_ext_data (struct frame *f, GC gc, int create_if_not_found_p)
  5278 {
  5279   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  5280   XEDataObject object;
  5281   XExtData **head, *ext_data;
  5282 
  5283   object.gc = gc;
  5284   head = XEHeadOfExtensionList (object);
  5285   ext_data = XFindOnExtensionList (head, dpyinfo->ext_codes->extension);
  5286   if (ext_data == NULL)
  5287     {
  5288       if (!create_if_not_found_p)
  5289         return NULL;
  5290       else
  5291         {
  5292           ext_data = xzalloc (sizeof (*ext_data));
  5293           ext_data->number = dpyinfo->ext_codes->extension;
  5294           ext_data->private_data = xzalloc (sizeof (struct x_gc_ext_data));
  5295           ext_data->free_private = x_gc_free_ext_data_private;
  5296           XAddToExtensionList (head, ext_data);
  5297         }
  5298     }
  5299   return (struct x_gc_ext_data *) ext_data->private_data;
  5300 }
  5301 
  5302 static void
  5303 x_extension_initialize (struct x_display_info *dpyinfo)
  5304 {
  5305   XExtCodes *ext_codes = XAddExtension (dpyinfo->display);
  5306 
  5307   dpyinfo->ext_codes = ext_codes;
  5308 }
  5309 #endif
  5310 
  5311 #ifdef USE_CAIRO
  5312 
  5313 #define FRAME_CR_CONTEXT(f)     ((f)->output_data.x->cr_context)
  5314 #define FRAME_CR_SURFACE_DESIRED_WIDTH(f) \
  5315   ((f)->output_data.x->cr_surface_desired_width)
  5316 #define FRAME_CR_SURFACE_DESIRED_HEIGHT(f) \
  5317   ((f)->output_data.x->cr_surface_desired_height)
  5318 
  5319 #endif /* HAVE_CAIRO */
  5320 
  5321 
  5322 
  5323 /* X input extension device and event mask management functions.  */
  5324 
  5325 #ifdef HAVE_XINPUT2
  5326 
  5327 bool
  5328 xi_frame_selected_for (struct frame *f, unsigned long event)
  5329 {
  5330   XIEventMask *masks;
  5331   int i;
  5332 
  5333   masks = FRAME_X_OUTPUT (f)->xi_masks;
  5334 
  5335   if (!masks)
  5336     return false;
  5337 
  5338   for (i = 0; i < FRAME_X_OUTPUT (f)->num_xi_masks; ++i)
  5339     {
  5340       if (masks[i].mask_len >= XIMaskLen (event)
  5341           && XIMaskIsSet (masks[i].mask, event))
  5342         return true;
  5343     }
  5344 
  5345   return false;
  5346 }
  5347 
  5348 /* Convert XI2 button state IN to a standard X button modifier
  5349    mask, and place it in OUT.  */
  5350 
  5351 static void
  5352 xi_convert_button_state (XIButtonState *in, unsigned int *out)
  5353 {
  5354   int i;
  5355 
  5356   if (in->mask_len)
  5357     {
  5358       for (i = 1; i <= 8; ++i)
  5359         {
  5360           if (XIMaskIsSet (in->mask, i))
  5361             *out |= (Button1Mask << (i - 1));
  5362         }
  5363     }
  5364 }
  5365 
  5366 /* Return the modifier state in XEV as a standard X modifier mask.
  5367    This should be used for non-keyboard events, where the group does
  5368    not matter.  */
  5369 
  5370 #ifdef USE_GTK
  5371 static
  5372 #endif /* USE_GTK */
  5373 unsigned int
  5374 xi_convert_event_state (XIDeviceEvent *xev)
  5375 {
  5376   unsigned int mods, buttons;
  5377 
  5378   mods = xev->mods.effective;
  5379   buttons = 0;
  5380 
  5381   xi_convert_button_state (&xev->buttons, &buttons);
  5382 
  5383   return mods | buttons;
  5384 }
  5385 
  5386 /* Like the above.  However, buttons are not converted, while the
  5387    group is.  This should be used for key events being passed to the
  5388    likes of input methods and Xt.  */
  5389 
  5390 static unsigned int
  5391 xi_convert_event_keyboard_state (XIDeviceEvent *xev)
  5392 {
  5393   return ((xev->mods.effective & ~(1 << 13 | 1 << 14))
  5394           | (xev->group.effective << 13));
  5395 }
  5396 
  5397 /* Free all XI2 devices on DPYINFO.  */
  5398 
  5399 static void
  5400 x_free_xi_devices (struct x_display_info *dpyinfo)
  5401 {
  5402 #ifdef HAVE_XINPUT2_2
  5403   struct xi_touch_point_t *tem, *last;
  5404 #endif /* HAVE_XINPUT2_2 */
  5405 
  5406   block_input ();
  5407 
  5408   if (dpyinfo->num_devices)
  5409     {
  5410       for (int i = 0; i < dpyinfo->num_devices; ++i)
  5411         {
  5412 #ifdef HAVE_XINPUT2_1
  5413           xfree (dpyinfo->devices[i].valuators);
  5414 #endif /* HAVE_XINPUT2_1 */
  5415 
  5416 #ifdef HAVE_XINPUT2_2
  5417           tem = dpyinfo->devices[i].touchpoints;
  5418           while (tem)
  5419             {
  5420               last = tem;
  5421               tem = tem->next;
  5422               xfree (last);
  5423             }
  5424 #endif /* HAVE_XINPUT2_2 */
  5425         }
  5426 
  5427       xfree (dpyinfo->devices);
  5428       dpyinfo->devices = NULL;
  5429       dpyinfo->num_devices = 0;
  5430     }
  5431 
  5432   unblock_input ();
  5433 }
  5434 
  5435 #ifdef HAVE_XINPUT2_1
  5436 
  5437 struct xi_known_valuator
  5438 {
  5439   /* The current value of this valuator.  */
  5440   double current_value;
  5441 
  5442   /* The number of the valuator.  */
  5443   int number;
  5444 
  5445   /* The next valuator whose value we already know.  */
  5446   struct xi_known_valuator *next;
  5447 };
  5448 
  5449 /* Populate the scroll valuator at INDEX in DEVICE with the scroll
  5450    valuator information provided in INFO.
  5451 
  5452    The information consists of:
  5453 
  5454      - whether or not the valuator is horizontal.
  5455 
  5456      - whether or not the valuator's value is currently unknown,
  5457        until the next XI_Motion event is received or the valuator's
  5458        value is restored by the caller upon encountering valuator
  5459        class data.
  5460 
  5461      - what the current value of the valuator is.  This is set to
  5462        DBL_MIN for debugging purposes, but can be any value, as
  5463        invalid_p is currently true.
  5464 
  5465      - the increment, which defines the amount of movement equal to a
  5466        single unit of scrolling.  For example, if the increment is
  5467        2.0, then a WHEEL_DOWN or WHEEL_UP event will be sent every
  5468        time the valuator value changes by 2.0, unless
  5469        mwheel-coalesce-scroll-events is nil.
  5470 
  5471      - the number used in XI_Motion events and elsewhere to identify
  5472        the valuator.  */
  5473 
  5474 static void
  5475 xi_populate_scroll_valuator (struct xi_device_t *device,
  5476                              int index, XIScrollClassInfo *info)
  5477 {
  5478   struct xi_scroll_valuator_t *valuator;
  5479 
  5480   valuator = &device->valuators[index];
  5481   valuator->horizontal
  5482     = (info->scroll_type == XIScrollTypeHorizontal);
  5483   valuator->invalid_p = true;
  5484   valuator->emacs_value = DBL_MIN;
  5485   valuator->increment = info->increment;
  5486   valuator->number = info->number;
  5487 }
  5488 
  5489 #endif /* HAVE_XINPUT2_1 */
  5490 
  5491 static void
  5492 xi_populate_device_from_info (struct x_display_info *dpyinfo,
  5493                               struct xi_device_t *xi_device,
  5494                               XIDeviceInfo *device)
  5495 {
  5496 #ifdef HAVE_XINPUT2_1
  5497   struct xi_known_valuator *values, *tem;
  5498   int actual_valuator_count, c;
  5499   XIScrollClassInfo *info;
  5500   XIValuatorClassInfo *valuator_info;
  5501 #endif /* HAVE_XINPUT2_1 */
  5502 #ifdef HAVE_XINPUT2_2
  5503   XITouchClassInfo *touch_info;
  5504 #endif /* HAVE_XINPUT2_2 */
  5505 
  5506 #ifdef HAVE_XINPUT2_1
  5507   USE_SAFE_ALLOCA;
  5508 #endif /* HAVE_XINPUT2_1 */
  5509 
  5510   /* Initialize generic information about the device: its ID, which
  5511      buttons are currently pressed and thus presumably actively
  5512      grabbing the device, what kind of device it is (master pointer,
  5513      master keyboard, slave pointer, slave keyboard, or floating
  5514      slave), and its attachment.
  5515 
  5516      Here is a brief description of what device uses and attachments
  5517      are.  Under XInput 2, user input from individual input devices is
  5518      multiplexed into specific seats before being delivered, with each
  5519      seat corresponding to a single on-screen mouse pointer and having
  5520      its own keyboard focus.  Each seat consists of two virtual
  5521      devices: the master keyboard and the master pointer, the first of
  5522      which is used to report all keyboard input, with the other used
  5523      to report all other input.
  5524 
  5525      Input from each physical device (mouse, trackpad or keyboard) is
  5526      then associated with that slave device's paired master device.
  5527      For example, moving the device "Logitech USB Optical Mouse",
  5528      enslaved by the master pointer device "Virtual core pointer",
  5529      will result in movement of the mouse pointer associated with that
  5530      master device's seat.  If the pointer moves over an Emacs frame,
  5531      then the frame will receive XI_Enter and XI_Motion events from
  5532      that master pointer.
  5533 
  5534      Likewise, keyboard input from the device "AT Translated Set 2
  5535      keyboard", enslaved by the master keyboard device "Virtual core
  5536      keyboard", will be reported to its seat's input focus window.
  5537 
  5538      The device use describes what the device is.  The meanings of
  5539      MasterPointer, MasterKeyboard, SlavePointer and SlaveKeyboard
  5540      should be obvious.  FloatingSlave means the device is a slave
  5541      device that is not associated with any seat, and thus generates
  5542      no input.
  5543 
  5544      The device attachment is a device ID whose meaning varies
  5545      depending on the device's use.  If a device is a master device,
  5546      then its attachment is the device ID of the other device in its
  5547      seat (the master keyboard for master pointer devices and vice
  5548      versa.)  Otherwise, it is the ID of the master device the slave
  5549      device is attached to.  For slave devices not attached to any
  5550      seat, its value is undefined.
  5551 
  5552      Emacs receives ordinary pointer and keyboard events from the
  5553      master devices associated with each seat, discarding events from
  5554      slave devices.  However, multiplexing events from touch devices
  5555      onto a master device poses problems: if both dependent and direct
  5556      touch devices are attached to the same master pointer device, the
  5557      coordinate space of touch events sent from that seat becomes
  5558      ambiguous.  In addition, the X server does not send TouchEnd
  5559      events to cancel ongoing touch sequences if the slave device that
  5560      is their source is detached.  As a result of these ambiguities,
  5561      touch events are processed from and recorded onto their slave
  5562      devices instead.  */
  5563 
  5564   xi_device->device_id = device->deviceid;
  5565   xi_device->grab = 0;
  5566   xi_device->use = device->use;
  5567   xi_device->name = build_string (device->name);
  5568   xi_device->attachment = device->attachment;
  5569 
  5570   /* Clear the list of active touch points on the device, which are
  5571      individual touches tracked by a touchscreen.  */
  5572 
  5573 #ifdef HAVE_XINPUT2_2
  5574   xi_device->touchpoints = NULL;
  5575   xi_device->direct_p = false;
  5576 #endif /* HAVE_XINPUT2_1 */
  5577 
  5578 #ifdef HAVE_XINPUT2_1
  5579   if (!dpyinfo->xi2_version)
  5580     {
  5581       /* Skip everything below as there are no classes of interest on
  5582          XI 2.0 servers.  */
  5583       xi_device->valuators = NULL;
  5584       xi_device->scroll_valuator_count = 0;
  5585 
  5586       SAFE_FREE ();
  5587       return;
  5588     }
  5589 
  5590   actual_valuator_count = 0;
  5591   xi_device->valuators = xnmalloc (device->num_classes,
  5592                                    sizeof *xi_device->valuators);
  5593   values = NULL;
  5594 
  5595   /* Initialize device info based on a list of "device classes".
  5596      Device classes are little pieces of information associated with a
  5597      device.  Emacs is interested in scroll valuator information and
  5598      touch handling information, which respectively describe the axes
  5599      (if any) along which the device's scroll wheel rotates, and how
  5600      the device reports touch input.  */
  5601 
  5602   for (c = 0; c < device->num_classes; ++c)
  5603     {
  5604       switch (device->classes[c]->type)
  5605         {
  5606         case XIScrollClass:
  5607           {
  5608             info = (XIScrollClassInfo *) device->classes[c];
  5609             xi_populate_scroll_valuator (xi_device, actual_valuator_count++,
  5610                                          info);
  5611             break;
  5612           }
  5613 
  5614         case XIValuatorClass:
  5615           {
  5616             valuator_info = (XIValuatorClassInfo *) device->classes[c];
  5617             tem = SAFE_ALLOCA (sizeof *tem);
  5618 
  5619             /* Avoid restoring bogus values if some driver
  5620                accidentally specifies relative values in scroll
  5621                valuator classes how the input extension spec says they
  5622                should be, but allow restoring values when a value is
  5623                set, which is how the input extension actually
  5624                behaves.  */
  5625 
  5626             if (valuator_info->value == 0.0
  5627                 && valuator_info->mode != XIModeAbsolute)
  5628               continue;
  5629 
  5630             tem->next = values;
  5631             tem->number = valuator_info->number;
  5632             tem->current_value = valuator_info->value;
  5633 
  5634             values = tem;
  5635             break;
  5636           }
  5637 
  5638 #ifdef HAVE_XINPUT2_2
  5639         case XITouchClass:
  5640           {
  5641             touch_info = (XITouchClassInfo *) device->classes[c];
  5642 
  5643             /* touch_info->mode indicates the coordinate space that
  5644                this device reports in its touch events.
  5645 
  5646                DirectTouch means that the device uses a coordinate
  5647                space that corresponds to locations on the screen.  It
  5648                is set by touch screen devices which are overlaid
  5649                over the raster itself.
  5650 
  5651                The other value (DependentTouch) means that the device
  5652                uses a separate abstract coordinate space corresponding
  5653                to its own surface.  Emacs ignores events from these
  5654                devices because it does not support recognizing touch
  5655                gestures from surfaces other than the screen.
  5656 
  5657                Master devices may report multiple touch classes for
  5658                attached slave devices, leaving the nature of touch
  5659                events they send ambiguous.  The problem of
  5660                discriminating between these events is bypassed
  5661                entirely through only processing touch events from the
  5662                slave devices where they originate.  */
  5663 
  5664             if (touch_info->mode == XIDirectTouch)
  5665               xi_device->direct_p = true;
  5666             else
  5667               xi_device->direct_p = false;
  5668           }
  5669 #endif /* HAVE_XINPUT2_2 */
  5670         default:
  5671           break;
  5672         }
  5673     }
  5674 
  5675   xi_device->scroll_valuator_count = actual_valuator_count;
  5676 
  5677   /* Now look through all the valuators whose values are already known
  5678      and populate our client-side records with their current
  5679      values.  */
  5680 
  5681   for (tem = values; values; values = values->next)
  5682     {
  5683       for (c = 0; c < xi_device->scroll_valuator_count; ++c)
  5684         {
  5685           if (xi_device->valuators[c].number == tem->number)
  5686             {
  5687               xi_device->valuators[c].invalid_p = false;
  5688               xi_device->valuators[c].current_value
  5689                 = tem->current_value;
  5690               xi_device->valuators[c].emacs_value = 0.0;
  5691             }
  5692         }
  5693     }
  5694 
  5695   SAFE_FREE ();
  5696 #endif /* HAVE_XINPUT2_1 */
  5697 }
  5698 
  5699 /* Populate our client-side record of all devices, which includes
  5700    basic information about the device and also touchscreen tracking
  5701    information and scroll valuators.
  5702 
  5703    Keeping track of scroll valuators is required in order to support
  5704    scroll wheels that report information in a fashion more detailed
  5705    than a single turn of a "step" in the wheel.
  5706 
  5707    When the input extension is being utilized, the states of the mouse
  5708    wheels on each axis are stored as absolute values inside
  5709    "valuators" attached to each mouse device.  To obtain the delta of
  5710    the scroll wheel from a motion event (which is used to report that
  5711    some valuator has changed), it is necessary to iterate over every
  5712    valuator that changed, and compare its previous value to the
  5713    current value of the valuator.
  5714 
  5715    Each individual valuator also has an "interval", which is the
  5716    amount you must divide that delta by in order to obtain a delta in
  5717    the terms of scroll units.
  5718 
  5719    This delta however is still intermediate, to make driver
  5720    implementations easier.  The XInput developers recommend (and most
  5721    programs use) the following algorithm to convert from scroll unit
  5722    deltas to pixel deltas by which the display must actually be
  5723    scrolled:
  5724 
  5725      pixels_scrolled = pow (window_height, 2.0 / 3.0) * delta;  */
  5726 
  5727 static void
  5728 x_cache_xi_devices (struct x_display_info *dpyinfo)
  5729 {
  5730   int ndevices, actual_devices, i;
  5731   XIDeviceInfo *infos;
  5732 
  5733   actual_devices = 0;
  5734   block_input ();
  5735   x_free_xi_devices (dpyinfo);
  5736   infos = XIQueryDevice (dpyinfo->display,
  5737                          XIAllDevices,
  5738                          &ndevices);
  5739 
  5740   if (!ndevices)
  5741     {
  5742       XIFreeDeviceInfo (infos);
  5743       unblock_input ();
  5744       return;
  5745     }
  5746 
  5747   dpyinfo->devices = xzalloc (sizeof *dpyinfo->devices * ndevices);
  5748 
  5749   for (i = 0; i < ndevices; ++i)
  5750     {
  5751       if (infos[i].enabled)
  5752         xi_populate_device_from_info (dpyinfo,
  5753                                       &dpyinfo->devices[actual_devices++],
  5754                                       &infos[i]);
  5755     }
  5756 
  5757   dpyinfo->num_devices = actual_devices;
  5758   XIFreeDeviceInfo (infos);
  5759   unblock_input ();
  5760 }
  5761 
  5762 #ifdef HAVE_XINPUT2_1
  5763 /* Return the delta of the scroll valuator VALUATOR_NUMBER under
  5764    DEVICE in the display DPYINFO with VALUE.  The valuator's valuator
  5765    will be set to VALUE afterwards.  In case no scroll valuator is
  5766    found, or if the valuator state is invalid (see the comment under
  5767    XI_Enter in handle_one_xevent).  Otherwise, the valuator is
  5768    returned in VALUATOR_RETURN.  */
  5769 static double
  5770 x_get_scroll_valuator_delta (struct x_display_info *dpyinfo,
  5771                              struct xi_device_t *device,
  5772                              int valuator_number, double value,
  5773                              struct xi_scroll_valuator_t **valuator_return)
  5774 {
  5775   struct xi_scroll_valuator_t *sv;
  5776   double delta;
  5777   int i;
  5778 
  5779   for (i = 0; i < device->scroll_valuator_count; ++i)
  5780     {
  5781       sv = &device->valuators[i];
  5782 
  5783       if (sv->number == valuator_number)
  5784         {
  5785           *valuator_return = sv;
  5786 
  5787           if (sv->increment == 0)
  5788             return DBL_MAX;
  5789 
  5790           if (sv->invalid_p)
  5791             {
  5792               sv->current_value = value;
  5793               sv->invalid_p = false;
  5794 
  5795               return DBL_MAX;
  5796             }
  5797           else
  5798             {
  5799               delta = (sv->current_value - value) / sv->increment;
  5800               sv->current_value = value;
  5801 
  5802               return delta;
  5803             }
  5804         }
  5805     }
  5806 
  5807   *valuator_return = NULL;
  5808   return DBL_MAX;
  5809 }
  5810 
  5811 #endif
  5812 
  5813 struct xi_device_t *
  5814 xi_device_from_id (struct x_display_info *dpyinfo, int deviceid)
  5815 {
  5816   for (int i = 0; i < dpyinfo->num_devices; ++i)
  5817     {
  5818       if (dpyinfo->devices[i].device_id == deviceid)
  5819         return &dpyinfo->devices[i];
  5820     }
  5821 
  5822   return NULL;
  5823 }
  5824 
  5825 #ifdef HAVE_XINPUT2_2
  5826 
  5827 /* Record a touch sequence with the identifier DETAIL from the given
  5828    FRAME on the specified DEVICE.  Round X and Y and record them as
  5829    its current position.  */
  5830 
  5831 static void
  5832 xi_link_touch_point (struct xi_device_t *device,
  5833                      int detail, double x, double y,
  5834                      struct frame *frame)
  5835 {
  5836   struct xi_touch_point_t *touchpoint;
  5837 
  5838   touchpoint = xmalloc (sizeof *touchpoint);
  5839   touchpoint->next = device->touchpoints;
  5840   touchpoint->x = lrint (x);
  5841   touchpoint->y = lrint (y);
  5842   touchpoint->number = detail;
  5843   touchpoint->frame = frame;
  5844   touchpoint->ownership = TOUCH_OWNERSHIP_NONE;
  5845 
  5846   device->touchpoints = touchpoint;
  5847 }
  5848 
  5849 /* Free and remove the touch sequence with the identifier DETAIL.
  5850    DEVICE is the device in which the touch sequence should be
  5851    recorded.
  5852 
  5853    Value is 0 if no touch sequence by that identifier exists inside
  5854    DEVICE, 1 if a touch sequence has been found but is not owned by
  5855    Emacs, and 2 otherwise.  */
  5856 
  5857 static int
  5858 xi_unlink_touch_point (int detail, struct xi_device_t *device)
  5859 {
  5860   struct xi_touch_point_t *last, *tem;
  5861   enum xi_touch_ownership ownership;
  5862 
  5863   for (last = NULL, tem = device->touchpoints; tem;
  5864        last = tem, tem = tem->next)
  5865     {
  5866       if (tem->number == detail)
  5867         {
  5868           if (!last)
  5869             device->touchpoints = tem->next;
  5870           else
  5871             last->next = tem->next;
  5872 
  5873           ownership = tem->ownership;
  5874           xfree (tem);
  5875 
  5876           if (ownership == TOUCH_OWNERSHIP_SELF)
  5877             return 2;
  5878 
  5879           return 1;
  5880         }
  5881     }
  5882 
  5883   return 0;
  5884 }
  5885 
  5886 /* Unlink all touch points associated with the frame F.
  5887    This is done upon unmapping or destroying F's window, because
  5888    touch point delivery after that point is undefined.  */
  5889 
  5890 static void
  5891 xi_unlink_touch_points (struct frame *f)
  5892 {
  5893   struct xi_device_t *device;
  5894   struct xi_touch_point_t **next, *last;
  5895   int i;
  5896 
  5897   for (i = 0; i < FRAME_DISPLAY_INFO (f)->num_devices; ++i)
  5898     {
  5899       device = &FRAME_DISPLAY_INFO (f)->devices[i];
  5900 
  5901       /* Now unlink all touch points on DEVICE matching F.  */
  5902 
  5903       for (next = &device->touchpoints; (last = *next);)
  5904         {
  5905           if (last->frame == f)
  5906             {
  5907               *next = last->next;
  5908               xfree (last);
  5909             }
  5910           else
  5911             next = &last->next;
  5912         }
  5913     }
  5914 }
  5915 
  5916 /* Return the data associated with a touch sequence DETAIL recorded by
  5917    `xi_link_touch_point' from DEVICE, or NULL if it can't be
  5918    found.  */
  5919 
  5920 static struct xi_touch_point_t *
  5921 xi_find_touch_point (struct xi_device_t *device, int detail)
  5922 {
  5923   struct xi_touch_point_t *point;
  5924 
  5925   for (point = device->touchpoints; point; point = point->next)
  5926     {
  5927       if (point->number == detail)
  5928         return point;
  5929     }
  5930 
  5931   return NULL;
  5932 }
  5933 
  5934 #endif /* HAVE_XINPUT2_2 */
  5935 
  5936 #ifdef HAVE_XINPUT2_1
  5937 
  5938 static void
  5939 xi_reset_scroll_valuators_for_device_id (struct x_display_info *dpyinfo,
  5940                                          int id)
  5941 {
  5942   struct xi_device_t *device;
  5943   struct xi_scroll_valuator_t *valuator;
  5944   int i;
  5945 
  5946   device = xi_device_from_id (dpyinfo, id);
  5947 
  5948   if (!device)
  5949     return;
  5950 
  5951   if (!device->scroll_valuator_count)
  5952     return;
  5953 
  5954   for (i = 0; i < device->scroll_valuator_count; ++i)
  5955     {
  5956       valuator = &device->valuators[i];
  5957       valuator->invalid_p = true;
  5958       valuator->emacs_value = 0.0;
  5959     }
  5960 
  5961   return;
  5962 }
  5963 
  5964 #endif /* HAVE_XINPUT2_1 */
  5965 #endif /* HAVE_XINPUT2 */
  5966 
  5967 
  5968 
  5969 /* Cairo context, X rendering extension, and GC auxiliary data
  5970    management functions.  */
  5971 
  5972 #ifdef USE_CAIRO
  5973 
  5974 void
  5975 x_cr_destroy_frame_context (struct frame *f)
  5976 {
  5977   if (FRAME_CR_CONTEXT (f))
  5978     {
  5979       cairo_destroy (FRAME_CR_CONTEXT (f));
  5980       FRAME_CR_CONTEXT (f) = NULL;
  5981     }
  5982 }
  5983 
  5984 void
  5985 x_cr_update_surface_desired_size (struct frame *f, int width, int height)
  5986 {
  5987   if (FRAME_CR_SURFACE_DESIRED_WIDTH (f) != width
  5988       || FRAME_CR_SURFACE_DESIRED_HEIGHT (f) != height)
  5989     {
  5990       x_cr_destroy_frame_context (f);
  5991       FRAME_CR_SURFACE_DESIRED_WIDTH (f) = width;
  5992       FRAME_CR_SURFACE_DESIRED_HEIGHT (f) = height;
  5993     }
  5994 }
  5995 
  5996 static void
  5997 x_cr_gc_clip (cairo_t *cr, struct frame *f, GC gc)
  5998 {
  5999   if (gc)
  6000     {
  6001       struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0);
  6002 
  6003       if (gc_ext && gc_ext->n_clip_rects)
  6004         {
  6005           for (int i = 0; i < gc_ext->n_clip_rects; i++)
  6006             cairo_rectangle (cr, gc_ext->clip_rects[i].x,
  6007                              gc_ext->clip_rects[i].y,
  6008                              gc_ext->clip_rects[i].width,
  6009                              gc_ext->clip_rects[i].height);
  6010           cairo_clip (cr);
  6011         }
  6012     }
  6013 }
  6014 
  6015 cairo_t *
  6016 x_begin_cr_clip (struct frame *f, GC gc)
  6017 {
  6018   cairo_t *cr = FRAME_CR_CONTEXT (f);
  6019 
  6020   if (!cr)
  6021     {
  6022       int width = FRAME_CR_SURFACE_DESIRED_WIDTH (f);
  6023       int height = FRAME_CR_SURFACE_DESIRED_HEIGHT (f);
  6024       cairo_surface_t *surface;
  6025 #ifdef USE_CAIRO_XCB_SURFACE
  6026       if (FRAME_DISPLAY_INFO (f)->xcb_visual)
  6027         surface = cairo_xcb_surface_create (FRAME_DISPLAY_INFO (f)->xcb_connection,
  6028                                             (xcb_drawable_t) FRAME_X_RAW_DRAWABLE (f),
  6029                                             FRAME_DISPLAY_INFO (f)->xcb_visual,
  6030                                             width, height);
  6031       else
  6032 #endif
  6033         surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
  6034                                              FRAME_X_RAW_DRAWABLE (f),
  6035                                              FRAME_X_VISUAL (f),
  6036                                              width, height);
  6037 
  6038       cr = FRAME_CR_CONTEXT (f) = cairo_create (surface);
  6039       cairo_surface_destroy (surface);
  6040     }
  6041   cairo_save (cr);
  6042   x_cr_gc_clip (cr, f, gc);
  6043 
  6044   return cr;
  6045 }
  6046 
  6047 void
  6048 x_end_cr_clip (struct frame *f)
  6049 {
  6050   cairo_restore (FRAME_CR_CONTEXT (f));
  6051 #ifdef HAVE_XDBE
  6052   if (FRAME_X_DOUBLE_BUFFERED_P (f))
  6053     x_mark_frame_dirty (f);
  6054 #endif
  6055 }
  6056 
  6057 void
  6058 x_set_cr_source_with_gc_foreground (struct frame *f, GC gc,
  6059                                     bool respect_alpha_background)
  6060 {
  6061   XGCValues xgcv;
  6062   XColor color;
  6063   unsigned int depth;
  6064 
  6065   XGetGCValues (FRAME_X_DISPLAY (f), gc, GCForeground, &xgcv);
  6066   color.pixel = xgcv.foreground;
  6067   x_query_colors (f, &color, 1);
  6068   depth = FRAME_DISPLAY_INFO (f)->n_planes;
  6069 
  6070   if (f->alpha_background < 1.0 && depth == 32
  6071       && respect_alpha_background)
  6072     {
  6073       cairo_set_source_rgba (FRAME_CR_CONTEXT (f), color.red / 65535.0,
  6074                              color.green / 65535.0, color.blue / 65535.0,
  6075                              f->alpha_background);
  6076 
  6077       cairo_set_operator (FRAME_CR_CONTEXT (f), CAIRO_OPERATOR_SOURCE);
  6078     }
  6079   else
  6080     {
  6081       cairo_set_source_rgb (FRAME_CR_CONTEXT (f), color.red / 65535.0,
  6082                             color.green / 65535.0, color.blue / 65535.0);
  6083       cairo_set_operator (FRAME_CR_CONTEXT (f), CAIRO_OPERATOR_OVER);
  6084     }
  6085 }
  6086 
  6087 void
  6088 x_set_cr_source_with_gc_background (struct frame *f, GC gc,
  6089                                     bool respect_alpha_background)
  6090 {
  6091   XGCValues xgcv;
  6092   XColor color;
  6093   unsigned int depth;
  6094 
  6095   XGetGCValues (FRAME_X_DISPLAY (f), gc, GCBackground, &xgcv);
  6096   color.pixel = xgcv.background;
  6097 
  6098   x_query_colors (f, &color, 1);
  6099 
  6100   depth = FRAME_DISPLAY_INFO (f)->n_planes;
  6101 
  6102   if (f->alpha_background < 1.0 && depth == 32
  6103       && respect_alpha_background)
  6104     {
  6105       cairo_set_source_rgba (FRAME_CR_CONTEXT (f), color.red / 65535.0,
  6106                              color.green / 65535.0, color.blue / 65535.0,
  6107                              f->alpha_background);
  6108 
  6109       cairo_set_operator (FRAME_CR_CONTEXT (f), CAIRO_OPERATOR_SOURCE);
  6110     }
  6111   else
  6112     {
  6113       cairo_set_source_rgb (FRAME_CR_CONTEXT (f), color.red / 65535.0,
  6114                             color.green / 65535.0, color.blue / 65535.0);
  6115       cairo_set_operator (FRAME_CR_CONTEXT (f), CAIRO_OPERATOR_OVER);
  6116     }
  6117 }
  6118 
  6119 static const cairo_user_data_key_t xlib_surface_key, saved_drawable_key;
  6120 
  6121 static void
  6122 x_cr_destroy_xlib_surface (cairo_surface_t *xlib_surface)
  6123 {
  6124   if (xlib_surface)
  6125     {
  6126       XFreePixmap (cairo_xlib_surface_get_display (xlib_surface),
  6127                    cairo_xlib_surface_get_drawable (xlib_surface));
  6128       cairo_surface_destroy (xlib_surface);
  6129     }
  6130 }
  6131 
  6132 static bool
  6133 x_try_cr_xlib_drawable (struct frame *f, GC gc)
  6134 {
  6135   cairo_t *cr = FRAME_CR_CONTEXT (f);
  6136   if (!cr)
  6137     return true;
  6138 
  6139   cairo_surface_t *surface = cairo_get_target (cr);
  6140   switch (cairo_surface_get_type (surface))
  6141     {
  6142     case CAIRO_SURFACE_TYPE_XLIB:
  6143 #ifdef USE_CAIRO_XCB_SURFACE
  6144     case CAIRO_SURFACE_TYPE_XCB:
  6145 #endif
  6146       cairo_surface_flush (surface);
  6147       return true;
  6148 
  6149     case CAIRO_SURFACE_TYPE_IMAGE:
  6150       break;
  6151 
  6152     default:
  6153       return false;
  6154     }
  6155 
  6156   /* FRAME_CR_CONTEXT (f) is an image surface we can not draw into
  6157      directly with Xlib.  Set up a Pixmap so we can copy back the
  6158      result later in x_end_cr_xlib_drawable.  */
  6159   cairo_surface_t *xlib_surface = cairo_get_user_data (cr, &xlib_surface_key);
  6160   int width = FRAME_CR_SURFACE_DESIRED_WIDTH (f);
  6161   int height = FRAME_CR_SURFACE_DESIRED_HEIGHT (f);
  6162   Pixmap pixmap;
  6163   if (xlib_surface
  6164       && cairo_xlib_surface_get_width (xlib_surface) == width
  6165       && cairo_xlib_surface_get_height (xlib_surface) == height)
  6166     pixmap = cairo_xlib_surface_get_drawable (xlib_surface);
  6167   else
  6168     {
  6169       pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_RAW_DRAWABLE (f),
  6170                               width, height,
  6171                               DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
  6172       xlib_surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
  6173                                                 pixmap, FRAME_X_VISUAL (f),
  6174                                                 width, height);
  6175       cairo_set_user_data (cr, &xlib_surface_key, xlib_surface,
  6176                            (cairo_destroy_func_t) x_cr_destroy_xlib_surface);
  6177     }
  6178 
  6179   cairo_t *buf = cairo_create (xlib_surface);
  6180   cairo_set_source_surface (buf, surface, 0, 0);
  6181   cairo_matrix_t matrix;
  6182   cairo_get_matrix (cr, &matrix);
  6183   cairo_pattern_set_matrix (cairo_get_source (cr), &matrix);
  6184   cairo_set_operator (buf, CAIRO_OPERATOR_SOURCE);
  6185   x_cr_gc_clip (buf, f, gc);
  6186   cairo_paint (buf);
  6187   cairo_destroy (buf);
  6188 
  6189   cairo_set_user_data (cr, &saved_drawable_key,
  6190                        (void *) (uintptr_t) FRAME_X_RAW_DRAWABLE (f), NULL);
  6191   FRAME_X_RAW_DRAWABLE (f) = pixmap;
  6192   cairo_surface_flush (xlib_surface);
  6193 
  6194   return true;
  6195 }
  6196 
  6197 static void
  6198 x_end_cr_xlib_drawable (struct frame *f, GC gc)
  6199 {
  6200   cairo_t *cr = FRAME_CR_CONTEXT (f);
  6201   if (!cr)
  6202     return;
  6203 
  6204   Drawable saved_drawable
  6205     = (uintptr_t) cairo_get_user_data (cr, &saved_drawable_key);
  6206   cairo_surface_t *surface = (saved_drawable
  6207                               ? cairo_get_user_data (cr, &xlib_surface_key)
  6208                               : cairo_get_target (cr));
  6209   struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0);
  6210   if (gc_ext && gc_ext->n_clip_rects)
  6211     for (int i = 0; i < gc_ext->n_clip_rects; i++)
  6212       cairo_surface_mark_dirty_rectangle (surface, gc_ext->clip_rects[i].x,
  6213                                           gc_ext->clip_rects[i].y,
  6214                                           gc_ext->clip_rects[i].width,
  6215                                           gc_ext->clip_rects[i].height);
  6216   else
  6217     cairo_surface_mark_dirty (surface);
  6218   if (!saved_drawable)
  6219     return;
  6220 
  6221   cairo_save (cr);
  6222   cairo_set_source_surface (cr, surface, 0, 0);
  6223   cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
  6224   x_cr_gc_clip (cr, f, gc);
  6225   cairo_paint (cr);
  6226   cairo_restore (cr);
  6227 
  6228   FRAME_X_RAW_DRAWABLE (f) = saved_drawable;
  6229   cairo_set_user_data (cr, &saved_drawable_key, NULL, NULL);
  6230 }
  6231 
  6232 /* Fringe bitmaps.  */
  6233 
  6234 static int max_fringe_bmp = 0;
  6235 static cairo_pattern_t **fringe_bmp = 0;
  6236 
  6237 static void
  6238 x_cr_define_fringe_bitmap (int which, unsigned short *bits, int h, int wd)
  6239 {
  6240   int i, stride;
  6241   cairo_surface_t *surface;
  6242   cairo_pattern_t *pattern;
  6243   unsigned char *data;
  6244 
  6245   if (which >= max_fringe_bmp)
  6246     {
  6247       i = max_fringe_bmp;
  6248       max_fringe_bmp = which + 20;
  6249       fringe_bmp = xrealloc (fringe_bmp, max_fringe_bmp * sizeof (*fringe_bmp));
  6250       while (i < max_fringe_bmp)
  6251         fringe_bmp[i++] = 0;
  6252     }
  6253 
  6254   block_input ();
  6255 
  6256   surface = cairo_image_surface_create (CAIRO_FORMAT_A1, wd, h);
  6257   stride = cairo_image_surface_get_stride (surface);
  6258   data = cairo_image_surface_get_data (surface);
  6259 
  6260   for (i = 0; i < h; i++)
  6261     {
  6262       *((unsigned short *) data) = bits[i];
  6263       data += stride;
  6264     }
  6265 
  6266   cairo_surface_mark_dirty (surface);
  6267   pattern = cairo_pattern_create_for_surface (surface);
  6268   cairo_surface_destroy (surface);
  6269 
  6270   unblock_input ();
  6271 
  6272   fringe_bmp[which] = pattern;
  6273 }
  6274 
  6275 static void
  6276 x_cr_destroy_fringe_bitmap (int which)
  6277 {
  6278   if (which >= max_fringe_bmp)
  6279     return;
  6280 
  6281   if (fringe_bmp[which])
  6282     {
  6283       block_input ();
  6284       cairo_pattern_destroy (fringe_bmp[which]);
  6285       unblock_input ();
  6286     }
  6287   fringe_bmp[which] = 0;
  6288 }
  6289 
  6290 static void
  6291 x_cr_draw_image (struct frame *f, GC gc, cairo_pattern_t *image,
  6292                  int src_x, int src_y, int width, int height,
  6293                  int dest_x, int dest_y, bool overlay_p)
  6294 {
  6295   cairo_t *cr = x_begin_cr_clip (f, gc);
  6296 
  6297   if (overlay_p)
  6298     cairo_rectangle (cr, dest_x, dest_y, width, height);
  6299   else
  6300     {
  6301       x_set_cr_source_with_gc_background (f, gc, false);
  6302       cairo_rectangle (cr, dest_x, dest_y, width, height);
  6303       cairo_fill_preserve (cr);
  6304     }
  6305 
  6306   cairo_translate (cr, dest_x - src_x, dest_y - src_y);
  6307 
  6308   cairo_surface_t *surface;
  6309   cairo_pattern_get_surface (image, &surface);
  6310   cairo_format_t format = cairo_image_surface_get_format (surface);
  6311   if (format != CAIRO_FORMAT_A8 && format != CAIRO_FORMAT_A1)
  6312     {
  6313       cairo_set_source (cr, image);
  6314       cairo_fill (cr);
  6315     }
  6316   else
  6317     {
  6318       x_set_cr_source_with_gc_foreground (f, gc, false);
  6319       cairo_clip (cr);
  6320       cairo_mask (cr, image);
  6321     }
  6322 
  6323   x_end_cr_clip (f);
  6324 }
  6325 
  6326 void
  6327 x_cr_draw_frame (cairo_t *cr, struct frame *f)
  6328 {
  6329   int width, height;
  6330 
  6331   width = FRAME_PIXEL_WIDTH (f);
  6332   height = FRAME_PIXEL_HEIGHT (f);
  6333 
  6334   cairo_t *saved_cr = FRAME_CR_CONTEXT (f);
  6335   FRAME_CR_CONTEXT (f) = cr;
  6336   x_clear_area (f, 0, 0, width, height);
  6337   expose_frame (f, 0, 0, width, height);
  6338   FRAME_CR_CONTEXT (f) = saved_cr;
  6339 }
  6340 
  6341 static cairo_status_t
  6342 x_cr_accumulate_data (void *closure, const unsigned char *data,
  6343                       unsigned int length)
  6344 {
  6345   Lisp_Object *acc = (Lisp_Object *) closure;
  6346 
  6347   *acc = Fcons (make_unibyte_string ((char const *) data, length), *acc);
  6348 
  6349   return CAIRO_STATUS_SUCCESS;
  6350 }
  6351 
  6352 static void
  6353 x_cr_destroy (void *cr)
  6354 {
  6355   block_input ();
  6356   cairo_destroy (cr);
  6357   unblock_input ();
  6358 }
  6359 
  6360 Lisp_Object
  6361 x_cr_export_frames (Lisp_Object frames, cairo_surface_type_t surface_type)
  6362 {
  6363   struct frame *f;
  6364   cairo_surface_t *surface;
  6365   cairo_t *cr;
  6366   int width, height;
  6367   void (*surface_set_size_func) (cairo_surface_t *, double, double) = NULL;
  6368   Lisp_Object acc = Qnil;
  6369   specpdl_ref count = SPECPDL_INDEX ();
  6370 
  6371   specbind (Qredisplay_dont_pause, Qt);
  6372   redisplay_preserve_echo_area (31);
  6373 
  6374   f = XFRAME (XCAR (frames));
  6375   frames = XCDR (frames);
  6376   width = FRAME_PIXEL_WIDTH (f);
  6377   height = FRAME_PIXEL_HEIGHT (f);
  6378 
  6379   block_input ();
  6380 #ifdef CAIRO_HAS_PDF_SURFACE
  6381   if (surface_type == CAIRO_SURFACE_TYPE_PDF)
  6382     {
  6383       surface = cairo_pdf_surface_create_for_stream (x_cr_accumulate_data, &acc,
  6384                                                      width, height);
  6385       surface_set_size_func = cairo_pdf_surface_set_size;
  6386     }
  6387   else
  6388 #endif
  6389 #ifdef CAIRO_HAS_PNG_FUNCTIONS
  6390   if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
  6391     surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
  6392   else
  6393 #endif
  6394 #ifdef CAIRO_HAS_PS_SURFACE
  6395   if (surface_type == CAIRO_SURFACE_TYPE_PS)
  6396     {
  6397       surface = cairo_ps_surface_create_for_stream (x_cr_accumulate_data, &acc,
  6398                                                     width, height);
  6399       surface_set_size_func = cairo_ps_surface_set_size;
  6400     }
  6401   else
  6402 #endif
  6403 #ifdef CAIRO_HAS_SVG_SURFACE
  6404   if (surface_type == CAIRO_SURFACE_TYPE_SVG)
  6405     surface = cairo_svg_surface_create_for_stream (x_cr_accumulate_data, &acc,
  6406                                                    width, height);
  6407   else
  6408 #endif
  6409     abort ();
  6410 
  6411   cr = cairo_create (surface);
  6412   cairo_surface_destroy (surface);
  6413   record_unwind_protect_ptr (x_cr_destroy, cr);
  6414 
  6415   while (1)
  6416     {
  6417       cairo_t *saved_cr = FRAME_CR_CONTEXT (f);
  6418       FRAME_CR_CONTEXT (f) = cr;
  6419       x_clear_area (f, 0, 0, width, height);
  6420       expose_frame (f, 0, 0, width, height);
  6421       FRAME_CR_CONTEXT (f) = saved_cr;
  6422 
  6423       if (NILP (frames))
  6424         break;
  6425 
  6426       cairo_surface_show_page (surface);
  6427       f = XFRAME (XCAR (frames));
  6428       frames = XCDR (frames);
  6429       width = FRAME_PIXEL_WIDTH (f);
  6430       height = FRAME_PIXEL_HEIGHT (f);
  6431       if (surface_set_size_func)
  6432         (*surface_set_size_func) (surface, width, height);
  6433 
  6434       unblock_input ();
  6435       maybe_quit ();
  6436       block_input ();
  6437     }
  6438 
  6439 #ifdef CAIRO_HAS_PNG_FUNCTIONS
  6440   if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
  6441     {
  6442       cairo_surface_flush (surface);
  6443       cairo_surface_write_to_png_stream (surface, x_cr_accumulate_data, &acc);
  6444     }
  6445 #endif
  6446   unblock_input ();
  6447 
  6448   unbind_to (count, Qnil);
  6449 
  6450   return CALLN (Fapply, Qconcat, Fnreverse (acc));
  6451 }
  6452 
  6453 #endif  /* USE_CAIRO */
  6454 
  6455 #if defined HAVE_XRENDER
  6456 
  6457 void
  6458 x_xr_apply_ext_clip (struct frame *f, GC gc)
  6459 {
  6460   eassert (FRAME_X_PICTURE (f) != None);
  6461 
  6462   struct x_gc_ext_data *data = x_gc_get_ext_data (f, gc, 1);
  6463 
  6464   if (data->n_clip_rects)
  6465     XRenderSetPictureClipRectangles (FRAME_X_DISPLAY (f),
  6466                                      FRAME_X_PICTURE (f),
  6467                                      0, 0, data->clip_rects,
  6468                                      data->n_clip_rects);
  6469 }
  6470 
  6471 void
  6472 x_xr_reset_ext_clip (struct frame *f)
  6473 {
  6474   XRenderPictureAttributes attrs = { .clip_mask = None };
  6475 
  6476   XRenderChangePicture (FRAME_X_DISPLAY (f),
  6477                         FRAME_X_PICTURE (f),
  6478                         CPClipMask, &attrs);
  6479 }
  6480 
  6481 #endif /* HAVE_XRENDER */
  6482 
  6483 static void
  6484 x_set_clip_rectangles (struct frame *f, GC gc, XRectangle *rectangles, int n)
  6485 {
  6486   XSetClipRectangles (FRAME_X_DISPLAY (f), gc, 0, 0, rectangles, n, Unsorted);
  6487 #if defined USE_CAIRO || defined HAVE_XRENDER
  6488   eassert (n >= 0 && n <= MAX_CLIP_RECTS);
  6489 
  6490   {
  6491     struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 1);
  6492 
  6493     gc_ext->n_clip_rects = n;
  6494     memcpy (gc_ext->clip_rects, rectangles, sizeof (XRectangle) * n);
  6495   }
  6496 #endif
  6497 }
  6498 
  6499 static void
  6500 x_reset_clip_rectangles (struct frame *f, GC gc)
  6501 {
  6502   XSetClipMask (FRAME_X_DISPLAY (f), gc, None);
  6503 #if defined USE_CAIRO || defined HAVE_XRENDER
  6504   {
  6505     struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0);
  6506 
  6507     if (gc_ext)
  6508       gc_ext->n_clip_rects = 0;
  6509   }
  6510 #endif
  6511 }
  6512 
  6513 #ifdef HAVE_XRENDER
  6514 # if !defined USE_CAIRO && (RENDER_MAJOR > 0 || RENDER_MINOR >= 2)
  6515 static void
  6516 x_xrender_color_from_gc_foreground (struct frame *f, GC gc, XRenderColor *color,
  6517                                     bool apply_alpha_background)
  6518 {
  6519   XGCValues xgcv;
  6520   XColor xc;
  6521 
  6522   XGetGCValues (FRAME_X_DISPLAY (f), gc, GCForeground, &xgcv);
  6523   xc.pixel = xgcv.foreground;
  6524   x_query_colors (f, &xc, 1);
  6525 
  6526   color->alpha = (apply_alpha_background
  6527                   ? 65535 * f->alpha_background
  6528                   : 65535);
  6529 
  6530   if (color->alpha == 65535)
  6531     {
  6532       color->red = xc.red;
  6533       color->blue = xc.blue;
  6534       color->green = xc.green;
  6535     }
  6536   else
  6537     {
  6538       color->red = (xc.red * color->alpha) / 65535;
  6539       color->blue = (xc.blue * color->alpha) / 65535;
  6540       color->green = (xc.green * color->alpha) / 65535;
  6541     }
  6542 }
  6543 # endif
  6544 
  6545 void
  6546 x_xrender_color_from_gc_background (struct frame *f, GC gc, XRenderColor *color,
  6547                                     bool apply_alpha_background)
  6548 {
  6549   XGCValues xgcv;
  6550   XColor xc;
  6551 
  6552   XGetGCValues (FRAME_X_DISPLAY (f), gc, GCBackground, &xgcv);
  6553   xc.pixel = xgcv.background;
  6554   x_query_colors (f, &xc, 1);
  6555 
  6556   color->alpha = (apply_alpha_background
  6557                   ? 65535 * f->alpha_background
  6558                   : 65535);
  6559 
  6560   if (color->alpha == 65535)
  6561     {
  6562       color->red = xc.red;
  6563       color->blue = xc.blue;
  6564       color->green = xc.green;
  6565     }
  6566   else
  6567     {
  6568       color->red = (xc.red * color->alpha) / 65535;
  6569       color->blue = (xc.blue * color->alpha) / 65535;
  6570       color->green = (xc.green * color->alpha) / 65535;
  6571     }
  6572 }
  6573 #endif
  6574 
  6575 static void
  6576 x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height,
  6577                   bool respect_alpha_background)
  6578 {
  6579 #ifdef USE_CAIRO
  6580   Display *dpy = FRAME_X_DISPLAY (f);
  6581   cairo_t *cr;
  6582   XGCValues xgcv;
  6583 
  6584   cr = x_begin_cr_clip (f, gc);
  6585   XGetGCValues (dpy, gc, GCFillStyle | GCStipple, &xgcv);
  6586   if (xgcv.fill_style == FillSolid
  6587       /* Invalid resource ID (one or more of the three most
  6588          significant bits set to 1) is obtained if the GCStipple
  6589          component has never been explicitly set.  It should be
  6590          regarded as Pixmap of unspecified size filled with ones.  */
  6591       || (xgcv.stipple & ((Pixmap) 7 << (sizeof (Pixmap) * CHAR_BIT - 3))))
  6592     {
  6593       x_set_cr_source_with_gc_foreground (f, gc, respect_alpha_background);
  6594       cairo_rectangle (cr, x, y, width, height);
  6595       cairo_fill (cr);
  6596     }
  6597   else
  6598     {
  6599       eassert (xgcv.fill_style == FillOpaqueStippled);
  6600       eassert (xgcv.stipple != None);
  6601       x_set_cr_source_with_gc_background (f, gc, respect_alpha_background);
  6602       cairo_rectangle (cr, x, y, width, height);
  6603       cairo_fill_preserve (cr);
  6604 
  6605       cairo_pattern_t *pattern = x_bitmap_stipple (f, xgcv.stipple);
  6606       if (pattern)
  6607         {
  6608           x_set_cr_source_with_gc_foreground (f, gc, respect_alpha_background);
  6609           cairo_clip (cr);
  6610           cairo_mask (cr, pattern);
  6611         }
  6612     }
  6613   x_end_cr_clip (f);
  6614 #else
  6615 #if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2))
  6616   if (respect_alpha_background
  6617       && f->alpha_background != 1.0
  6618       && FRAME_DISPLAY_INFO (f)->alpha_bits
  6619       && FRAME_CHECK_XR_VERSION (f, 0, 2))
  6620     {
  6621       x_xr_ensure_picture (f);
  6622 
  6623       if (FRAME_X_PICTURE (f) != None)
  6624         {
  6625           XRenderColor xc;
  6626 
  6627 #if RENDER_MAJOR > 0 || (RENDER_MINOR >= 10)
  6628           XGCValues xgcv;
  6629           XRenderPictureAttributes attrs;
  6630           XRenderColor alpha;
  6631           Picture stipple, fill;
  6632 #endif
  6633 
  6634           x_xr_apply_ext_clip (f, gc);
  6635 
  6636 #if RENDER_MAJOR > 0 || (RENDER_MINOR >= 10)
  6637           XGetGCValues (FRAME_X_DISPLAY (f),
  6638                         gc, GCFillStyle | GCStipple, &xgcv);
  6639 
  6640           if (xgcv.fill_style == FillOpaqueStippled
  6641               && FRAME_CHECK_XR_VERSION (f, 0, 10))
  6642             {
  6643               x_xrender_color_from_gc_background (f, gc, &alpha, true);
  6644               x_xrender_color_from_gc_foreground (f, gc, &xc, true);
  6645               attrs.repeat = RepeatNormal;
  6646 
  6647               stipple = XRenderCreatePicture (FRAME_X_DISPLAY (f),
  6648                                               xgcv.stipple,
  6649                                               XRenderFindStandardFormat (FRAME_X_DISPLAY (f),
  6650                                                                          PictStandardA1),
  6651                                               CPRepeat, &attrs);
  6652 
  6653               XRenderFillRectangle (FRAME_X_DISPLAY (f), PictOpSrc,
  6654                                     FRAME_X_PICTURE (f),
  6655                                     &alpha, x, y, width, height);
  6656 
  6657               fill = XRenderCreateSolidFill (FRAME_X_DISPLAY (f), &xc);
  6658 
  6659               XRenderComposite (FRAME_X_DISPLAY (f), PictOpOver, fill, stipple,
  6660                                 FRAME_X_PICTURE (f), 0, 0, x, y, x, y, width, height);
  6661 
  6662               XRenderFreePicture (FRAME_X_DISPLAY (f), stipple);
  6663               XRenderFreePicture (FRAME_X_DISPLAY (f), fill);
  6664             }
  6665           else
  6666 #endif
  6667             {
  6668               x_xrender_color_from_gc_foreground (f, gc, &xc, true);
  6669               XRenderFillRectangle (FRAME_X_DISPLAY (f),
  6670                                     PictOpSrc, FRAME_X_PICTURE (f),
  6671                                     &xc, x, y, width, height);
  6672             }
  6673           x_xr_reset_ext_clip (f);
  6674           x_mark_frame_dirty (f);
  6675 
  6676           return;
  6677         }
  6678     }
  6679 #endif
  6680   XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
  6681                   gc, x, y, width, height);
  6682 #endif
  6683 }
  6684 
  6685 
  6686 
  6687 /* Graphics primitives.  */
  6688 
  6689 static void
  6690 x_clear_rectangle (struct frame *f, GC gc, int x, int y, int width, int height,
  6691                    bool respect_alpha_background)
  6692 {
  6693 #ifdef USE_CAIRO
  6694   cairo_t *cr;
  6695 
  6696   cr = x_begin_cr_clip (f, gc);
  6697   x_set_cr_source_with_gc_background (f, gc, respect_alpha_background);
  6698   cairo_rectangle (cr, x, y, width, height);
  6699   cairo_fill (cr);
  6700   x_end_cr_clip (f);
  6701 #else
  6702 #if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2))
  6703   if (respect_alpha_background
  6704       && f->alpha_background != 1.0
  6705       && FRAME_DISPLAY_INFO (f)->alpha_bits
  6706       && FRAME_CHECK_XR_VERSION (f, 0, 2))
  6707     {
  6708       x_xr_ensure_picture (f);
  6709 
  6710       if (FRAME_X_PICTURE (f) != None)
  6711         {
  6712           XRenderColor xc;
  6713 
  6714           x_xr_apply_ext_clip (f, gc);
  6715           x_xrender_color_from_gc_background (f, gc, &xc, true);
  6716           XRenderFillRectangle (FRAME_X_DISPLAY (f),
  6717                                 PictOpSrc, FRAME_X_PICTURE (f),
  6718                                 &xc, x, y, width, height);
  6719           x_xr_reset_ext_clip (f);
  6720           x_mark_frame_dirty (f);
  6721 
  6722           return;
  6723         }
  6724     }
  6725 #endif
  6726 
  6727   XGCValues xgcv;
  6728   Display *dpy = FRAME_X_DISPLAY (f);
  6729   XGetGCValues (dpy, gc, GCBackground | GCForeground, &xgcv);
  6730   XSetForeground (dpy, gc, xgcv.background);
  6731   XFillRectangle (dpy, FRAME_X_DRAWABLE (f),
  6732                   gc, x, y, width, height);
  6733   XSetForeground (dpy, gc, xgcv.foreground);
  6734 #endif
  6735 }
  6736 
  6737 static void
  6738 x_draw_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
  6739 {
  6740 #ifdef USE_CAIRO
  6741   cairo_t *cr;
  6742 
  6743   cr = x_begin_cr_clip (f, gc);
  6744   x_set_cr_source_with_gc_foreground (f, gc, false);
  6745   cairo_rectangle (cr, x + 0.5, y + 0.5, width, height);
  6746   cairo_set_line_width (cr, 1);
  6747   cairo_stroke (cr);
  6748   x_end_cr_clip (f);
  6749 #else
  6750   XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
  6751                   gc, x, y, width, height);
  6752 #endif
  6753 }
  6754 
  6755 static void
  6756 x_clear_window (struct frame *f)
  6757 {
  6758 #ifdef USE_CAIRO
  6759   cairo_t *cr;
  6760 
  6761   cr = x_begin_cr_clip (f, NULL);
  6762   x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc, true);
  6763   cairo_paint (cr);
  6764   x_end_cr_clip (f);
  6765 #else
  6766 #ifndef USE_GTK
  6767   if (f->alpha_background != 1.0
  6768 #ifdef HAVE_XDBE
  6769       || FRAME_X_DOUBLE_BUFFERED_P (f)
  6770 #endif
  6771       )
  6772 #endif
  6773     x_clear_area (f, 0, 0, FRAME_PIXEL_WIDTH (f),
  6774                   FRAME_PIXEL_HEIGHT (f));
  6775 #ifndef USE_GTK
  6776   else
  6777     XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
  6778 #endif
  6779 #endif
  6780 }
  6781 
  6782 #ifdef USE_CAIRO
  6783 static void
  6784 x_fill_trapezoid_for_relief (struct frame *f, GC gc, int x, int y,
  6785                              int width, int height, int top_p)
  6786 {
  6787   cairo_t *cr;
  6788 
  6789   cr = x_begin_cr_clip (f, gc);
  6790   x_set_cr_source_with_gc_foreground (f, gc, false);
  6791   cairo_move_to (cr, top_p ? x : x + height, y);
  6792   cairo_line_to (cr, x, y + height);
  6793   cairo_line_to (cr, top_p ? x + width - height : x + width, y + height);
  6794   cairo_line_to (cr, x + width, y);
  6795   cairo_fill (cr);
  6796   x_end_cr_clip (f);
  6797 }
  6798 
  6799 enum corners
  6800   {
  6801     CORNER_BOTTOM_RIGHT,        /* 0 -> pi/2 */
  6802     CORNER_BOTTOM_LEFT,         /* pi/2 -> pi */
  6803     CORNER_TOP_LEFT,            /* pi -> 3pi/2 */
  6804     CORNER_TOP_RIGHT,           /* 3pi/2 -> 2pi */
  6805     CORNER_LAST
  6806   };
  6807 
  6808 static void
  6809 x_erase_corners_for_relief (struct frame *f, GC gc, int x, int y,
  6810                             int width, int height,
  6811                             double radius, double margin, int corners)
  6812 {
  6813   cairo_t *cr;
  6814   int i;
  6815 
  6816   cr = x_begin_cr_clip (f, gc);
  6817   x_set_cr_source_with_gc_background (f, gc, false);
  6818   for (i = 0; i < CORNER_LAST; i++)
  6819     if (corners & (1 << i))
  6820       {
  6821         double xm, ym, xc, yc;
  6822 
  6823         if (i == CORNER_TOP_LEFT || i == CORNER_BOTTOM_LEFT)
  6824           xm = x - margin, xc = xm + radius;
  6825         else
  6826           xm = x + width + margin, xc = xm - radius;
  6827         if (i == CORNER_TOP_LEFT || i == CORNER_TOP_RIGHT)
  6828           ym = y - margin, yc = ym + radius;
  6829         else
  6830           ym = y + height + margin, yc = ym - radius;
  6831 
  6832         cairo_move_to (cr, xm, ym);
  6833         cairo_arc (cr, xc, yc, radius, i * M_PI_2, (i + 1) * M_PI_2);
  6834       }
  6835   cairo_clip (cr);
  6836   cairo_rectangle (cr, x, y, width, height);
  6837   cairo_fill (cr);
  6838   x_end_cr_clip (f);
  6839 }
  6840 
  6841 static void
  6842 x_draw_horizontal_wave (struct frame *f, GC gc, int x, int y,
  6843                         int width, int height, int wave_length)
  6844 {
  6845   cairo_t *cr;
  6846   double dx = wave_length, dy = height - 1;
  6847   int xoffset, n;
  6848 
  6849   cr = x_begin_cr_clip (f, gc);
  6850   x_set_cr_source_with_gc_foreground (f, gc, false);
  6851   cairo_rectangle (cr, x, y, width, height);
  6852   cairo_clip (cr);
  6853 
  6854   if (x >= 0)
  6855     {
  6856       xoffset = x % (wave_length * 2);
  6857       if (xoffset == 0)
  6858         xoffset = wave_length * 2;
  6859     }
  6860   else
  6861     xoffset = x % (wave_length * 2) + wave_length * 2;
  6862   n = (width + xoffset) / wave_length + 1;
  6863   if (xoffset > wave_length)
  6864     {
  6865       xoffset -= wave_length;
  6866       --n;
  6867       y += height - 1;
  6868       dy = -dy;
  6869     }
  6870 
  6871   cairo_move_to (cr, x - xoffset + 0.5, y + 0.5);
  6872   while (--n >= 0)
  6873     {
  6874       cairo_rel_line_to (cr, dx, dy);
  6875       dy = -dy;
  6876     }
  6877   cairo_set_line_width (cr, 1);
  6878   cairo_stroke (cr);
  6879   x_end_cr_clip (f);
  6880 }
  6881 #endif
  6882 
  6883 
  6884 /* Return the struct x_display_info corresponding to DPY.  */
  6885 
  6886 struct x_display_info *
  6887 x_display_info_for_display (Display *dpy)
  6888 {
  6889   struct x_display_info *dpyinfo;
  6890 
  6891   for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
  6892     if (dpyinfo->display == dpy)
  6893       return dpyinfo;
  6894 
  6895   return 0;
  6896 }
  6897 
  6898 static Window
  6899 x_find_topmost_parent (struct frame *f)
  6900 {
  6901   struct x_output *x = f->output_data.x;
  6902   Window win = None, wi = x->parent_desc;
  6903   Display *dpy = FRAME_X_DISPLAY (f);
  6904 
  6905   while (wi != FRAME_DISPLAY_INFO (f)->root_window)
  6906     {
  6907       Window root;
  6908       Window *children;
  6909       unsigned int nchildren;
  6910 
  6911       win = wi;
  6912       if (XQueryTree (dpy, win, &root, &wi, &children, &nchildren))
  6913         XFree (children);
  6914       else
  6915         break;
  6916     }
  6917 
  6918   return win;
  6919 }
  6920 
  6921 #define OPAQUE  0xffffffff
  6922 
  6923 static void
  6924 x_set_frame_alpha (struct frame *f)
  6925 {
  6926   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  6927   Display *dpy = FRAME_X_DISPLAY (f);
  6928   Window win = FRAME_OUTER_WINDOW (f);
  6929   double alpha = 1.0;
  6930   double alpha_min = 1.0;
  6931   unsigned long opac;
  6932   Window parent;
  6933 
  6934   if (dpyinfo->highlight_frame == f)
  6935     alpha = f->alpha[0];
  6936   else
  6937     alpha = f->alpha[1];
  6938 
  6939   if (alpha < 0.0)
  6940     return;
  6941 
  6942   if (FLOATP (Vframe_alpha_lower_limit))
  6943     alpha_min = XFLOAT_DATA (Vframe_alpha_lower_limit);
  6944   else if (FIXNUMP (Vframe_alpha_lower_limit))
  6945     alpha_min = (XFIXNUM (Vframe_alpha_lower_limit)) / 100.0;
  6946 
  6947   if (alpha > 1.0)
  6948     alpha = 1.0;
  6949   else if (alpha < alpha_min && alpha_min <= 1.0)
  6950     alpha = alpha_min;
  6951 
  6952   opac = alpha * OPAQUE;
  6953 
  6954   /* If there is a parent from the window manager, put the property there
  6955      also, to work around broken window managers that fail to do that.
  6956      Do this unconditionally as this function is called on reparent when
  6957      alpha has not changed on the frame.  */
  6958 
  6959   x_ignore_errors_for_next_request (dpyinfo, 0);
  6960 
  6961   if (!FRAME_PARENT_FRAME (f))
  6962     {
  6963       parent = x_find_topmost_parent (f);
  6964 
  6965       if (parent != None)
  6966         {
  6967           XChangeProperty (dpy, parent,
  6968                            dpyinfo->Xatom_net_wm_window_opacity,
  6969                            XA_CARDINAL, 32, PropModeReplace,
  6970                            (unsigned char *) &opac, 1);
  6971         }
  6972     }
  6973 
  6974   XChangeProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity,
  6975                    XA_CARDINAL, 32, PropModeReplace,
  6976                    (unsigned char *) &opac, 1);
  6977   x_stop_ignoring_errors (dpyinfo);
  6978 }
  6979 
  6980 
  6981 
  6982 /***********************************************************************
  6983                     Starting and ending an update
  6984  ***********************************************************************/
  6985 
  6986 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
  6987 
  6988 /* Wait for an event matching PREDICATE to show up in the event
  6989    queue, or TIMEOUT to elapse.
  6990 
  6991    If TIMEOUT passes without an event being found, return 1.
  6992    Otherwise, return 0 and behave as XIfEvent would.  */
  6993 
  6994 static int
  6995 x_if_event (Display *dpy, XEvent *event_return,
  6996             Bool (*predicate) (Display *, XEvent *, XPointer),
  6997             XPointer arg, struct timespec timeout)
  6998 {
  6999   struct timespec current_time, target;
  7000   int fd;
  7001   fd_set fds;
  7002 
  7003   fd = ConnectionNumber (dpy);
  7004   current_time = current_timespec ();
  7005   target = timespec_add (current_time, timeout);
  7006 
  7007   /* Check if an event is already in the queue.  If it is, avoid
  7008      syncing.  */
  7009   if (XCheckIfEvent (dpy, event_return, predicate, arg))
  7010     return 0;
  7011 
  7012   while (true)
  7013     {
  7014       /* Get events into the queue.  */
  7015       XSync (dpy, False);
  7016 
  7017       /* Look for an event again.  */
  7018       if (XCheckIfEvent (dpy, event_return, predicate, arg))
  7019         return 0;
  7020 
  7021       /* Calculate the timeout.  */
  7022       current_time = current_timespec ();
  7023       timeout = timespec_sub (target, current_time);
  7024 
  7025       /* If not, wait for some input to show up on the X connection,
  7026          or for the timeout to elapse.  */
  7027       FD_ZERO (&fds);
  7028       FD_SET (fd, &fds);
  7029 
  7030       /* If this fails due to an IO error, XSync will call the IO
  7031          error handler.  */
  7032       pselect (fd + 1, &fds, NULL, NULL, &timeout, NULL);
  7033 
  7034       /* Timeout elapsed.  */
  7035       current_time = current_timespec ();
  7036       if (timespec_cmp (target, current_time) < 0)
  7037         return 1;
  7038     }
  7039 }
  7040 
  7041 /* Return the monotonic time corresponding to the high-resolution
  7042    server timestamp TIMESTAMP.  Return 0 if the necessary information
  7043    is not available.  */
  7044 
  7045 static uint_fast64_t
  7046 x_sync_get_monotonic_time (struct x_display_info *dpyinfo,
  7047                            uint_fast64_t timestamp)
  7048 {
  7049   if (dpyinfo->server_time_monotonic_p)
  7050     return timestamp;
  7051 
  7052   /* This means we haven't yet initialized the server time offset.  */
  7053   if (!dpyinfo->server_time_offset)
  7054     return 0;
  7055 
  7056   uint_fast64_t t;
  7057   return ckd_sub (&t, timestamp, dpyinfo->server_time_offset) ? 0 : t;
  7058 }
  7059 
  7060 # ifndef CLOCK_MONOTONIC
  7061 #  define CLOCK_MONOTONIC CLOCK_REALTIME
  7062 # endif
  7063 
  7064 /* Return the current monotonic time in the same format as a
  7065    high-resolution server timestamp, or 0 if not available.  */
  7066 
  7067 static uint_fast64_t
  7068 x_sync_current_monotonic_time (void)
  7069 {
  7070   struct timespec time;
  7071   uint_fast64_t t;
  7072   return (((clock_gettime (CLOCK_MONOTONIC, &time) != 0
  7073             && (CLOCK_MONOTONIC == CLOCK_REALTIME
  7074                 || clock_gettime (CLOCK_REALTIME, &time) != 0))
  7075            || ckd_mul (&t, time.tv_sec, 1000000)
  7076            || ckd_add (&t, t, time.tv_nsec / 1000))
  7077           ? 0 : t);
  7078 }
  7079 
  7080 /* Decode a _NET_WM_FRAME_DRAWN message and calculate the time it took
  7081    to draw the last frame.  */
  7082 
  7083 static void
  7084 x_sync_note_frame_times (struct x_display_info *dpyinfo,
  7085                          struct frame *f, XEvent *event)
  7086 {
  7087   uint_fast64_t low, high, time;
  7088   struct x_output *output;
  7089 
  7090   low = event->xclient.data.l[2];
  7091   high = event->xclient.data.l[3];
  7092   output = FRAME_X_OUTPUT (f);
  7093 
  7094   time = x_sync_get_monotonic_time (dpyinfo, low | (high << 32));
  7095 
  7096   if (!time || !output->temp_frame_time
  7097       || ckd_sub (&output->last_frame_time, time, output->temp_frame_time))
  7098     output->last_frame_time = 0;
  7099 
  7100 #ifdef FRAME_DEBUG
  7101   uint_fast64_t last_frame_ms = output->last_frame_time / 1000;
  7102   fprintf (stderr,
  7103            "Drawing the last frame took: %"PRIuFAST64" ms (%"PRIuFAST64")\n",
  7104            last_frame_ms, time);
  7105 #endif
  7106 }
  7107 
  7108 static Bool
  7109 x_sync_is_frame_drawn_event (Display *dpy, XEvent *event,
  7110                              XPointer user_data)
  7111 {
  7112   struct frame *f;
  7113   struct x_display_info *dpyinfo;
  7114 
  7115   f = (struct frame *) user_data;
  7116   dpyinfo = FRAME_DISPLAY_INFO (f);
  7117 
  7118   if (event->type == ClientMessage
  7119       && (event->xclient.message_type
  7120           == dpyinfo->Xatom_net_wm_frame_drawn)
  7121       && event->xclient.window == FRAME_OUTER_WINDOW (f))
  7122     return True;
  7123 
  7124   return False;
  7125 }
  7126 
  7127 /* Wait for the compositing manager to finish drawing the last frame.
  7128    If the compositing manager has already drawn everything, do
  7129    nothing.  */
  7130 
  7131 static void
  7132 x_sync_wait_for_frame_drawn_event (struct frame *f)
  7133 {
  7134   XEvent event;
  7135   struct x_display_info *dpyinfo;
  7136 
  7137   if (!FRAME_X_WAITING_FOR_DRAW (f)
  7138       /* The compositing manager can't draw a frame if it is
  7139          unmapped.  */
  7140       || !FRAME_VISIBLE_P (f))
  7141     return;
  7142 
  7143   dpyinfo = FRAME_DISPLAY_INFO (f);
  7144 
  7145   /* Wait for the frame drawn message to arrive.  */
  7146   if (x_if_event (FRAME_X_DISPLAY (f), &event,
  7147                   x_sync_is_frame_drawn_event, (XPointer) f,
  7148                   make_timespec (1, 0)))
  7149     {
  7150       /* The first time a draw hangs, treat it as a random fluctuation
  7151          on the part of the compositor.  If the next draw continues to
  7152          hang, disable frame synchronization.  */
  7153       if (FRAME_X_DRAW_JUST_HUNG (f))
  7154         {
  7155           fprintf (stderr, "Warning: compositing manager spent more than 1 "
  7156                    "second drawing a frame.  Frame synchronization has "
  7157                    "been disabled\n");
  7158           FRAME_X_OUTPUT (f)->use_vsync_p = false;
  7159 
  7160           /* Remove the compositor bypass property from the outer
  7161              window.  */
  7162           XDeleteProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
  7163                            dpyinfo->Xatom_net_wm_bypass_compositor);
  7164 
  7165           /* Also change the frame parameter to reflect the new
  7166              state.  */
  7167           store_frame_param (f, Quse_frame_synchronization, Qnil);
  7168         }
  7169       else
  7170         {
  7171           fprintf (stderr, "Warning: compositing manager spent more than 1 "
  7172                    "second drawing a frame.  Frame synchronization will be "
  7173                    "disabled if this happens again\n");
  7174           FRAME_X_DRAW_JUST_HUNG (f) = true;
  7175         }
  7176     }
  7177   else
  7178     x_sync_note_frame_times (dpyinfo, f, &event);
  7179 
  7180   FRAME_X_WAITING_FOR_DRAW (f) = false;
  7181 }
  7182 
  7183 /* Tell the compositing manager to postpone updates of F until a frame
  7184    has finished drawing.  */
  7185 
  7186 static void
  7187 x_sync_update_begin (struct frame *f)
  7188 {
  7189   XSyncValue value, add;
  7190   Bool overflow;
  7191 
  7192   if (FRAME_X_EXTENDED_COUNTER (f) == None)
  7193     return;
  7194 
  7195   value = FRAME_X_COUNTER_VALUE (f);
  7196 
  7197   if (FRAME_X_OUTPUT (f)->ext_sync_end_pending_p)
  7198     {
  7199       FRAME_X_COUNTER_VALUE (f)
  7200         = FRAME_X_OUTPUT (f)->resize_counter_value;
  7201 
  7202       value = FRAME_X_COUNTER_VALUE (f);
  7203 
  7204       if (XSyncValueLow32 (value) % 2)
  7205         {
  7206           XSyncIntToValue (&add, 1);
  7207           XSyncValueAdd (&value, value, add, &overflow);
  7208 
  7209           if (overflow)
  7210             XSyncIntToValue (&value, 0);
  7211         }
  7212 
  7213       FRAME_X_OUTPUT (f)->ext_sync_end_pending_p = false;
  7214     }
  7215 
  7216   /* Since a frame is already in progress, there is no point in
  7217      continuing.  */
  7218   if (XSyncValueLow32 (value) % 2)
  7219     return;
  7220 
  7221   /* Wait for the last frame to be drawn before drawing this one.  */
  7222   x_sync_wait_for_frame_drawn_event (f);
  7223 
  7224   /* Make a note of the time at which we started to draw this
  7225      frame.  */
  7226   FRAME_X_OUTPUT (f)->temp_frame_time = x_sync_current_monotonic_time ();
  7227 
  7228   /* Since Emacs needs a non-urgent redraw, ensure that value % 4 ==
  7229      1.  Later, add 3 to create the even counter value.  */
  7230   if (XSyncValueLow32 (value) % 4 == 2)
  7231     XSyncIntToValue (&add, 3);
  7232   else
  7233     XSyncIntToValue (&add, 1);
  7234 
  7235   XSyncValueAdd (&FRAME_X_COUNTER_VALUE (f),
  7236                  value, add, &overflow);
  7237 
  7238   if (overflow)
  7239     XSyncIntToValue (&FRAME_X_COUNTER_VALUE (f), 3);
  7240 
  7241   eassert (XSyncValueLow32 (FRAME_X_COUNTER_VALUE (f)) % 4 == 1);
  7242 
  7243   XSyncSetCounter (FRAME_X_DISPLAY (f),
  7244                    FRAME_X_EXTENDED_COUNTER (f),
  7245                    FRAME_X_COUNTER_VALUE (f));
  7246 }
  7247 
  7248 #ifdef HAVE_XSYNCTRIGGERFENCE
  7249 
  7250 /* Trigger the sync fence for counter VALUE immediately before a frame
  7251    finishes.  */
  7252 
  7253 static void
  7254 x_sync_trigger_fence (struct frame *f, XSyncValue value)
  7255 {
  7256   uint_fast64_t n, low, high, idx;
  7257 
  7258   /* Sync fences aren't supported by the X server.  */
  7259   if (FRAME_DISPLAY_INFO (f)->xsync_major < 3
  7260       || (FRAME_DISPLAY_INFO (f)->xsync_major == 3
  7261           && FRAME_DISPLAY_INFO (f)->xsync_minor < 1))
  7262     return;
  7263 
  7264   low = XSyncValueLow32 (value);
  7265   high = XSyncValueHigh32 (value);
  7266 
  7267   n = low | (high << 32);
  7268   idx = (n / 4) % 2;
  7269 
  7270 #ifdef FRAME_DEBUG
  7271   fprintf (stderr, "Triggering synchronization fence: %lu\n", idx);
  7272 #endif
  7273 
  7274   XSyncTriggerFence (FRAME_X_DISPLAY (f),
  7275                      FRAME_X_OUTPUT (f)->sync_fences[idx]);
  7276 }
  7277 
  7278 /* Initialize the sync fences on F.  */
  7279 
  7280 void
  7281 x_sync_init_fences (struct frame *f)
  7282 {
  7283   struct x_output *output;
  7284   struct x_display_info *dpyinfo;
  7285 
  7286   output = FRAME_X_OUTPUT (f);
  7287   dpyinfo = FRAME_DISPLAY_INFO (f);
  7288 
  7289   /* Sync fences aren't supported by the X server.  */
  7290   if (dpyinfo->xsync_major < 3
  7291       || (dpyinfo->xsync_major == 3
  7292           && dpyinfo->xsync_minor < 1))
  7293     return;
  7294 
  7295   output->sync_fences[0]
  7296     = XSyncCreateFence (FRAME_X_DISPLAY (f),
  7297                         /* The drawable given below is only used to
  7298                            determine the screen on which the fence is
  7299                            created.  */
  7300                         FRAME_X_WINDOW (f),
  7301                         False);
  7302   output->sync_fences[1]
  7303     = XSyncCreateFence (FRAME_X_DISPLAY (f),
  7304                         FRAME_X_WINDOW (f),
  7305                         False);
  7306 
  7307   XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
  7308                    dpyinfo->Xatom_net_wm_sync_fences, XA_CARDINAL,
  7309                    32, PropModeReplace,
  7310                    (unsigned char *) &output->sync_fences, 2);
  7311 }
  7312 
  7313 static void
  7314 x_sync_free_fences (struct frame *f)
  7315 {
  7316   if (FRAME_X_OUTPUT (f)->sync_fences[0] != None)
  7317     XSyncDestroyFence (FRAME_X_DISPLAY (f),
  7318                        FRAME_X_OUTPUT (f)->sync_fences[0]);
  7319 
  7320   if (FRAME_X_OUTPUT (f)->sync_fences[1] != None)
  7321     XSyncDestroyFence (FRAME_X_DISPLAY (f),
  7322                        FRAME_X_OUTPUT (f)->sync_fences[1]);
  7323 }
  7324 
  7325 #endif
  7326 
  7327 /* Tell the compositing manager that FRAME has been drawn and can be
  7328    updated.  */
  7329 
  7330 static void
  7331 x_sync_update_finish (struct frame *f)
  7332 {
  7333   XSyncValue value, add;
  7334   Bool overflow;
  7335 
  7336   if (FRAME_X_EXTENDED_COUNTER (f) == None)
  7337     return;
  7338 
  7339   value = FRAME_X_COUNTER_VALUE (f);
  7340 
  7341   if (!(XSyncValueLow32 (value) % 2))
  7342     return;
  7343 
  7344   if ((XSyncValueLow32 (value) % 4) == 1)
  7345     /* This means the frame is non-urgent and should be drawn at the
  7346        next redraw point.  */
  7347     XSyncIntToValue (&add, 3);
  7348   else
  7349     /* Otherwise, the frame is urgent and should be drawn as soon as
  7350        possible.  */
  7351     XSyncIntToValue (&add, 1);
  7352 
  7353   XSyncValueAdd (&FRAME_X_COUNTER_VALUE (f),
  7354                  value, add, &overflow);
  7355 
  7356   if (overflow)
  7357     XSyncIntToValue (&FRAME_X_COUNTER_VALUE (f), 0);
  7358 
  7359   /* Trigger any sync fences if necessary.  */
  7360 #ifdef HAVE_XSYNCTRIGGERFENCE
  7361   x_sync_trigger_fence (f, FRAME_X_COUNTER_VALUE (f));
  7362 #endif
  7363 
  7364   XSyncSetCounter (FRAME_X_DISPLAY (f),
  7365                    FRAME_X_EXTENDED_COUNTER (f),
  7366                    FRAME_X_COUNTER_VALUE (f));
  7367 
  7368   if (FRAME_OUTPUT_DATA (f)->use_vsync_p)
  7369     FRAME_X_WAITING_FOR_DRAW (f) = true;
  7370 }
  7371 
  7372 /* Handle a _NET_WM_FRAME_DRAWN message from the compositor.  */
  7373 
  7374 static void
  7375 x_sync_handle_frame_drawn (struct x_display_info *dpyinfo,
  7376                            XEvent *message, struct frame *f)
  7377 {
  7378   XSyncValue value, counter;
  7379 
  7380   if (FRAME_OUTER_WINDOW (f) == message->xclient.window)
  7381     {
  7382       counter = FRAME_X_COUNTER_VALUE (f);
  7383 
  7384       /* Check that the counter in the message is the same as the
  7385          counter in the frame.  */
  7386       XSyncIntsToValue (&value,
  7387                         message->xclient.data.l[0] & 0xffffffff,
  7388                         message->xclient.data.l[1] & 0xffffffff);
  7389 
  7390       if (XSyncValueEqual (value, counter))
  7391         FRAME_X_WAITING_FOR_DRAW (f) = false;
  7392 
  7393       /* As long as a _NET_WM_FRAME_DRAWN message arrives, we know
  7394          that the compositor is still sending events, so avoid timing
  7395          out.  */
  7396       FRAME_X_DRAW_JUST_HUNG (f) = false;
  7397     }
  7398 
  7399   x_sync_note_frame_times (dpyinfo, f, message);
  7400 }
  7401 #endif
  7402 
  7403 /* Start an update of frame F.  This function is installed as a hook
  7404    for update_begin, i.e. it is called when update_begin is called.
  7405    This function is called prior to calls to gui_update_window_begin for
  7406    each window being updated.  Currently, there is nothing to do here
  7407    because all interesting stuff is done on a window basis.  */
  7408 
  7409 static void
  7410 x_update_begin (struct frame *f)
  7411 {
  7412 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
  7413   /* If F is double-buffered, we can make the entire frame center
  7414      around XdbeSwapBuffers.  */
  7415 #ifdef HAVE_XDBE
  7416   if (!FRAME_X_DOUBLE_BUFFERED_P (f))
  7417 #endif
  7418     x_sync_update_begin (f);
  7419 #else
  7420   /* Nothing to do.  */
  7421 #endif
  7422 
  7423 #ifdef HAVE_XDBE
  7424   if (FRAME_X_DOUBLE_BUFFERED_P (f))
  7425     /* The frame is no longer complete, as it is in the midst of an
  7426        update.  */
  7427     FRAME_X_COMPLETE_P (f) = false;
  7428 #endif
  7429 }
  7430 
  7431 /* Draw a vertical window border from (x,y0) to (x,y1)  */
  7432 
  7433 static void
  7434 x_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
  7435 {
  7436   struct frame *f = XFRAME (WINDOW_FRAME (w));
  7437   struct face *face;
  7438 
  7439   face = FACE_FROM_ID_OR_NULL (f, VERTICAL_BORDER_FACE_ID);
  7440   if (face)
  7441     XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc,
  7442                     face->foreground);
  7443 
  7444 #ifdef USE_CAIRO
  7445   x_fill_rectangle (f, f->output_data.x->normal_gc, x, y0, 1, y1 - y0, false);
  7446 #else
  7447   XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
  7448              f->output_data.x->normal_gc, x, y0, x, y1);
  7449 #endif
  7450 }
  7451 
  7452 /* Draw a window divider from (x0,y0) to (x1,y1)  */
  7453 
  7454 static void
  7455 x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
  7456 {
  7457   struct frame *f = XFRAME (WINDOW_FRAME (w));
  7458   struct face *face = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FACE_ID);
  7459   struct face *face_first
  7460     = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID);
  7461   struct face *face_last
  7462     = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
  7463   unsigned long color = face ? face->foreground : FRAME_FOREGROUND_PIXEL (f);
  7464   unsigned long color_first = (face_first
  7465                                ? face_first->foreground
  7466                                : FRAME_FOREGROUND_PIXEL (f));
  7467   unsigned long color_last = (face_last
  7468                               ? face_last->foreground
  7469                               : FRAME_FOREGROUND_PIXEL (f));
  7470   Display *display = FRAME_X_DISPLAY (f);
  7471 
  7472   if ((y1 - y0 > x1 - x0) && (x1 - x0 >= 3))
  7473     /* A vertical divider, at least three pixels wide: Draw first and
  7474        last pixels differently.  */
  7475     {
  7476       XSetForeground (display, f->output_data.x->normal_gc, color_first);
  7477       x_fill_rectangle (f, f->output_data.x->normal_gc,
  7478                         x0, y0, 1, y1 - y0, false);
  7479       XSetForeground (display, f->output_data.x->normal_gc, color);
  7480       x_fill_rectangle (f, f->output_data.x->normal_gc,
  7481                         x0 + 1, y0, x1 - x0 - 2, y1 - y0, false);
  7482       XSetForeground (display, f->output_data.x->normal_gc, color_last);
  7483       x_fill_rectangle (f, f->output_data.x->normal_gc,
  7484                         x1 - 1, y0, 1, y1 - y0, false);
  7485     }
  7486   else if ((x1 - x0 > y1 - y0) && (y1 - y0 >= 3))
  7487     /* A horizontal divider, at least three pixels high: Draw first and
  7488        last pixels differently.  */
  7489     {
  7490       XSetForeground (display, f->output_data.x->normal_gc, color_first);
  7491       x_fill_rectangle (f, f->output_data.x->normal_gc,
  7492                         x0, y0, x1 - x0, 1, false);
  7493       XSetForeground (display, f->output_data.x->normal_gc, color);
  7494       x_fill_rectangle (f, f->output_data.x->normal_gc,
  7495                         x0, y0 + 1, x1 - x0, y1 - y0 - 2, false);
  7496       XSetForeground (display, f->output_data.x->normal_gc, color_last);
  7497       x_fill_rectangle (f, f->output_data.x->normal_gc,
  7498                         x0, y1 - 1, x1 - x0, 1, false);
  7499     }
  7500   else
  7501     {
  7502     /* In any other case do not draw the first and last pixels
  7503        differently.  */
  7504       XSetForeground (display, f->output_data.x->normal_gc, color);
  7505       x_fill_rectangle (f, f->output_data.x->normal_gc,
  7506                         x0, y0, x1 - x0, y1 - y0, false);
  7507     }
  7508 }
  7509 
  7510 #ifdef HAVE_XDBE
  7511 
  7512 /* Show the frame back buffer.  If frame is double-buffered,
  7513    atomically publish to the user's screen graphics updates made since
  7514    the last call to show_back_buffer.  */
  7515 
  7516 static void
  7517 show_back_buffer (struct frame *f)
  7518 {
  7519   XdbeSwapInfo swap_info;
  7520 #ifdef USE_CAIRO
  7521   cairo_t *cr;
  7522 #endif
  7523 
  7524   if (FRAME_X_DOUBLE_BUFFERED_P (f))
  7525     {
  7526 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
  7527       /* Wait for drawing of the previous frame to complete before
  7528          displaying this new frame.  */
  7529       x_sync_wait_for_frame_drawn_event (f);
  7530 
  7531       /* Begin a new frame.  */
  7532       x_sync_update_begin (f);
  7533 #endif
  7534 
  7535 #ifdef USE_CAIRO
  7536       cr = FRAME_CR_CONTEXT (f);
  7537       if (cr)
  7538         cairo_surface_flush (cairo_get_target (cr));
  7539 #endif
  7540       memset (&swap_info, 0, sizeof (swap_info));
  7541       swap_info.swap_window = FRAME_X_WINDOW (f);
  7542       swap_info.swap_action = XdbeCopied;
  7543       XdbeSwapBuffers (FRAME_X_DISPLAY (f), &swap_info, 1);
  7544 
  7545 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
  7546       /* Finish the frame here.  */
  7547       x_sync_update_finish (f);
  7548 #endif
  7549     }
  7550 
  7551   FRAME_X_NEED_BUFFER_FLIP (f) = false;
  7552 }
  7553 
  7554 #endif
  7555 
  7556 /* Updates back buffer and flushes changes to display.  Called from
  7557    minibuf read code.  Note that we display the back buffer even if
  7558    buffer flipping is blocked.  */
  7559 static void
  7560 x_flip_and_flush (struct frame *f)
  7561 {
  7562   /* Flipping buffers requires a working connection to the X server,
  7563      which isn't always present if `inhibit-redisplay' is t, since
  7564      this can be called from the IO error handler.  */
  7565   if (!NILP (Vinhibit_redisplay)
  7566       /* This has to work for tooltip frames, however, and redisplay
  7567          cannot happen when they are being flushed anyway.  (bug#55519) */
  7568       && !FRAME_TOOLTIP_P (f))
  7569     return;
  7570 
  7571   block_input ();
  7572 #ifdef HAVE_XDBE
  7573   if (FRAME_X_NEED_BUFFER_FLIP (f))
  7574     show_back_buffer (f);
  7575 
  7576   /* The frame is complete again as its contents were just
  7577      flushed.  */
  7578   FRAME_X_COMPLETE_P (f) = true;
  7579 #endif
  7580   x_flush (f);
  7581   unblock_input ();
  7582 }
  7583 
  7584 /* End update of frame F.  This function is installed as a hook in
  7585    update_end.  */
  7586 
  7587 static void
  7588 x_update_end (struct frame *f)
  7589 {
  7590   /* Mouse highlight may be displayed again.  */
  7591   MOUSE_HL_INFO (f)->mouse_face_defer = false;
  7592 
  7593 #ifdef USE_CAIRO
  7594 # ifdef HAVE_XDBE
  7595   if (!FRAME_X_DOUBLE_BUFFERED_P (f) && FRAME_CR_CONTEXT (f))
  7596     cairo_surface_flush (cairo_get_target (FRAME_CR_CONTEXT (f)));
  7597 # endif
  7598 #endif
  7599 
  7600   /* If double buffering is disabled, finish the update here.
  7601      Otherwise, finish the update when the back buffer is next
  7602      displayed.  */
  7603 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
  7604 #ifdef HAVE_XDBE
  7605   if (!FRAME_X_DOUBLE_BUFFERED_P (f))
  7606 #endif
  7607     x_sync_update_finish (f);
  7608 #endif
  7609 }
  7610 
  7611 /* This function is called from various places in xdisp.c
  7612    whenever a complete update has been performed.  */
  7613 
  7614 static void
  7615 XTframe_up_to_date (struct frame *f)
  7616 {
  7617 #if defined HAVE_XSYNC && defined HAVE_GTK3
  7618   GtkWidget *widget;
  7619   GdkWindow *window;
  7620   GdkFrameClock *clock;
  7621 #endif
  7622 
  7623   eassert (FRAME_X_P (f));
  7624   block_input ();
  7625   FRAME_MOUSE_UPDATE (f);
  7626 
  7627 #ifdef HAVE_XDBE
  7628   if (!buffer_flipping_blocked_p ()
  7629       && FRAME_X_NEED_BUFFER_FLIP (f))
  7630     show_back_buffer (f);
  7631 
  7632   /* The frame is now complete, as its contents have been drawn.  */
  7633   FRAME_X_COMPLETE_P (f) = true;
  7634 #endif
  7635 
  7636 #ifdef HAVE_XSYNC
  7637 #ifndef HAVE_GTK3
  7638   if (FRAME_X_OUTPUT (f)->sync_end_pending_p
  7639       && FRAME_X_BASIC_COUNTER (f) != None)
  7640     {
  7641       XSyncSetCounter (FRAME_X_DISPLAY (f),
  7642                        FRAME_X_BASIC_COUNTER (f),
  7643                        FRAME_X_OUTPUT (f)->pending_basic_counter_value);
  7644       FRAME_X_OUTPUT (f)->sync_end_pending_p = false;
  7645     }
  7646 #else
  7647   if (FRAME_X_OUTPUT (f)->xg_sync_end_pending_p)
  7648     {
  7649       widget = FRAME_GTK_OUTER_WIDGET (f);
  7650       window = gtk_widget_get_window (widget);
  7651       eassert (window);
  7652       clock = gdk_window_get_frame_clock (window);
  7653       eassert (clock);
  7654 
  7655       gdk_frame_clock_request_phase (clock,
  7656                                      GDK_FRAME_CLOCK_PHASE_AFTER_PAINT);
  7657       FRAME_X_OUTPUT (f)->xg_sync_end_pending_p = false;
  7658     }
  7659 #endif
  7660 #endif
  7661   unblock_input ();
  7662 }
  7663 
  7664 #ifdef HAVE_XDBE
  7665 static void
  7666 XTbuffer_flipping_unblocked_hook (struct frame *f)
  7667 {
  7668   block_input ();
  7669 
  7670   if (FRAME_X_NEED_BUFFER_FLIP (f))
  7671     show_back_buffer (f);
  7672 
  7673   unblock_input ();
  7674 }
  7675 #endif
  7676 
  7677 
  7678 
  7679 /**
  7680  * x_clear_under_internal_border:
  7681  *
  7682  * Clear area of frame F's internal border.  If the internal border face
  7683  * of F has been specified (is not null), fill the area with that face.
  7684  */
  7685 void
  7686 x_clear_under_internal_border (struct frame *f)
  7687 {
  7688   if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
  7689     {
  7690       int border = FRAME_INTERNAL_BORDER_WIDTH (f);
  7691       int width = FRAME_PIXEL_WIDTH (f);
  7692       int height = FRAME_PIXEL_HEIGHT (f);
  7693       int margin = FRAME_TOP_MARGIN_HEIGHT (f);
  7694       int bottom_margin = FRAME_BOTTOM_MARGIN_HEIGHT (f);
  7695       int face_id = (FRAME_PARENT_FRAME (f)
  7696                      ? (!NILP (Vface_remapping_alist)
  7697                         ? lookup_basic_face (NULL, f,
  7698                                              CHILD_FRAME_BORDER_FACE_ID)
  7699                         : CHILD_FRAME_BORDER_FACE_ID)
  7700                      : (!NILP (Vface_remapping_alist)
  7701                         ? lookup_basic_face (NULL, f,
  7702                                              INTERNAL_BORDER_FACE_ID)
  7703                         : INTERNAL_BORDER_FACE_ID));
  7704       struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
  7705 
  7706       if (face)
  7707         {
  7708           unsigned long color = face->background;
  7709           Display *display = FRAME_X_DISPLAY (f);
  7710           GC gc = f->output_data.x->normal_gc;
  7711 
  7712           XSetForeground (display, gc, color);
  7713           x_fill_rectangle (f, gc, 0, margin, width, border, false);
  7714           x_fill_rectangle (f, gc, 0, 0, border, height, false);
  7715           x_fill_rectangle (f, gc, width - border, 0, border, height, false);
  7716           x_fill_rectangle (f, gc, 0, height - bottom_margin - border,
  7717                             width, border, false);
  7718           XSetForeground (display, gc, FRAME_FOREGROUND_PIXEL (f));
  7719         }
  7720       else
  7721         {
  7722           x_clear_area (f, 0, 0, border, height);
  7723           x_clear_area (f, 0, margin, width, border);
  7724           x_clear_area (f, width - border, 0, border, height);
  7725           x_clear_area (f, 0, height - bottom_margin - border,
  7726                         width, border);
  7727         }
  7728     }
  7729 }
  7730 
  7731 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
  7732    arrow bitmaps, or clear the fringes if no bitmaps are required
  7733    before DESIRED_ROW is made current.  This function is called from
  7734    update_window_line only if it is known that there are differences
  7735    between bitmaps to be drawn between current row and DESIRED_ROW.  */
  7736 
  7737 static void
  7738 x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
  7739 {
  7740   eassert (w);
  7741 
  7742   if (!desired_row->mode_line_p && !w->pseudo_window_p)
  7743     desired_row->redraw_fringe_bitmaps_p = true;
  7744 
  7745 #ifdef USE_X_TOOLKIT
  7746   /* When a window has disappeared, make sure that no rest of
  7747      full-width rows stays visible in the internal border.  Could
  7748      check here if updated window is the leftmost/rightmost window,
  7749      but I guess it's not worth doing since vertically split windows
  7750      are almost never used, internal border is rarely set, and the
  7751      overhead is very small.  */
  7752   {
  7753     struct frame *f;
  7754     int width, height;
  7755 
  7756     if (windows_or_buffers_changed
  7757         && desired_row->full_width_p
  7758         && (f = XFRAME (w->frame),
  7759             width = FRAME_INTERNAL_BORDER_WIDTH (f),
  7760             width != 0)
  7761         && (height = desired_row->visible_height,
  7762             height > 0))
  7763       {
  7764         int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
  7765         int face_id =
  7766           (FRAME_PARENT_FRAME (f)
  7767            ? (!NILP (Vface_remapping_alist)
  7768               ? lookup_basic_face (NULL, f, CHILD_FRAME_BORDER_FACE_ID)
  7769               : CHILD_FRAME_BORDER_FACE_ID)
  7770            : (!NILP (Vface_remapping_alist)
  7771               ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
  7772               : INTERNAL_BORDER_FACE_ID));
  7773         struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
  7774 
  7775         if (face)
  7776           {
  7777             unsigned long color = face->background;
  7778             Display *display = FRAME_X_DISPLAY (f);
  7779             GC gc = f->output_data.x->normal_gc;
  7780 
  7781             XSetForeground (display, gc, color);
  7782             x_fill_rectangle (f, gc, 0, y, width, height, true);
  7783             x_fill_rectangle (f, gc, FRAME_PIXEL_WIDTH (f) - width, y,
  7784                               width, height, true);
  7785             XSetForeground (display, gc, FRAME_FOREGROUND_PIXEL (f));
  7786           }
  7787         else
  7788           {
  7789             x_clear_area (f, 0, y, width, height);
  7790             x_clear_area (f, FRAME_PIXEL_WIDTH (f) - width, y, width, height);
  7791           }
  7792       }
  7793   }
  7794 #endif
  7795 }
  7796 
  7797 /* Generate a premultiplied pixel value for COLOR with ALPHA applied
  7798    on the given display.  COLOR will be modified.  The display must
  7799    use a visual that supports an alpha channel.
  7800 
  7801    This is possibly dead code on builds which do not support
  7802    XRender.  */
  7803 
  7804 #ifndef USE_CAIRO
  7805 
  7806 static unsigned long
  7807 x_premultiply_pixel (struct x_display_info *dpyinfo,
  7808                      XColor *color, double alpha)
  7809 {
  7810   unsigned long pixel;
  7811 
  7812   eassert (dpyinfo->alpha_bits);
  7813 
  7814   /* Multiply the RGB channels.  */
  7815   color->red *= alpha;
  7816   color->green *= alpha;
  7817   color->blue *= alpha;
  7818 
  7819   /* First, allocate a fully opaque pixel.  */
  7820   pixel = x_make_truecolor_pixel (dpyinfo, color->red,
  7821                                   color->green,
  7822                                   color->blue);
  7823 
  7824   /* Next, erase the alpha component.  */
  7825   pixel &= ~dpyinfo->alpha_mask;
  7826 
  7827   /* And add an alpha channel.  */
  7828   pixel |= (((unsigned long) (alpha * 65535)
  7829              >> (16 - dpyinfo->alpha_bits))
  7830             << dpyinfo->alpha_offset);
  7831 
  7832   return pixel;
  7833 }
  7834 
  7835 #endif
  7836 
  7837 static void
  7838 x_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
  7839                       struct draw_fringe_bitmap_params *p)
  7840 {
  7841   struct frame *f = XFRAME (WINDOW_FRAME (w));
  7842   Display *display = FRAME_X_DISPLAY (f);
  7843   GC gc = f->output_data.x->normal_gc;
  7844   struct face *face = p->face;
  7845 
  7846   /* Must clip because of partially visible lines.  */
  7847   x_clip_to_row (w, row, ANY_AREA, gc);
  7848 
  7849   if (p->bx >= 0 && !p->overlay_p)
  7850     {
  7851       /* In case the same realized face is used for fringes and
  7852          for something displayed in the text (e.g. face `region' on
  7853          mono-displays, the fill style may have been changed to
  7854          FillSolid in x_draw_glyph_string_background.  */
  7855       if (face->stipple)
  7856         {
  7857           XSetFillStyle (display, face->gc, FillOpaqueStippled);
  7858           x_fill_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny,
  7859                             true);
  7860           XSetFillStyle (display, face->gc, FillSolid);
  7861 
  7862           row->stipple_p = true;
  7863         }
  7864       else
  7865         {
  7866           XSetBackground (display, face->gc, face->background);
  7867           x_clear_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny,
  7868                            true);
  7869           XSetForeground (display, face->gc, face->foreground);
  7870         }
  7871     }
  7872 
  7873 #ifdef USE_CAIRO
  7874   if (p->which
  7875       && p->which < max_fringe_bmp
  7876       && p->which < max_used_fringe_bitmap)
  7877     {
  7878       XGCValues gcv;
  7879 
  7880       XGetGCValues (display, gc, GCForeground | GCBackground, &gcv);
  7881       XSetForeground (display, gc, (p->cursor_p
  7882                                     ? (p->overlay_p ? face->background
  7883                                        : f->output_data.x->cursor_pixel)
  7884                                     : face->foreground));
  7885       XSetBackground (display, gc, face->background);
  7886       if (!fringe_bmp[p->which])
  7887         {
  7888           /* This fringe bitmap is known to fringe.c, but lacks the
  7889              cairo_pattern_t pattern which shadows that bitmap.  This
  7890              is typical to define-fringe-bitmap being called when the
  7891              selected frame was not a GUI frame, for example, when
  7892              packages that define fringe bitmaps are loaded by a
  7893              daemon Emacs.  Create the missing pattern now.  */
  7894           gui_define_fringe_bitmap (f, p->which);
  7895         }
  7896       x_cr_draw_image (f, gc, fringe_bmp[p->which], 0, p->dh,
  7897                        p->wd, p->h, p->x, p->y, p->overlay_p);
  7898       XSetForeground (display, gc, gcv.foreground);
  7899       XSetBackground (display, gc, gcv.background);
  7900     }
  7901 #else  /* not USE_CAIRO */
  7902   if (p->which)
  7903     {
  7904       Drawable drawable = FRAME_X_DRAWABLE (f);
  7905       char *bits;
  7906       Pixmap pixmap, clipmask = None;
  7907       int depth = FRAME_DISPLAY_INFO (f)->n_planes;
  7908       XGCValues gcv;
  7909       unsigned long background = face->background;
  7910       XColor bg;
  7911 #ifdef HAVE_XRENDER
  7912       Picture picture = None;
  7913       XRenderPictureAttributes attrs;
  7914 
  7915       memset (&attrs, 0, sizeof attrs);
  7916 #endif
  7917 
  7918       if (p->wd > 8)
  7919         bits = (char *) (p->bits + p->dh);
  7920       else
  7921         bits = (char *) p->bits + p->dh;
  7922 
  7923       if (FRAME_DISPLAY_INFO (f)->alpha_bits
  7924           && f->alpha_background < 1.0)
  7925         {
  7926           /* Extend the background color with an alpha channel
  7927              according to f->alpha_background.  */
  7928           bg.pixel = background;
  7929           x_query_colors (f, &bg, 1);
  7930 
  7931           background
  7932             = x_premultiply_pixel (FRAME_DISPLAY_INFO (f),
  7933                                    &bg,
  7934                                    f->alpha_background);
  7935         }
  7936 
  7937       /* Draw the bitmap.  I believe these small pixmaps can be cached
  7938          by the server.  */
  7939       pixmap = XCreatePixmapFromBitmapData (display, drawable, bits, p->wd, p->h,
  7940                                             (p->cursor_p
  7941                                              ? (p->overlay_p ? face->background
  7942                                                 : f->output_data.x->cursor_pixel)
  7943                                              : face->foreground),
  7944                                             background, depth);
  7945 
  7946 #ifdef HAVE_XRENDER
  7947       if (FRAME_X_PICTURE_FORMAT (f)
  7948           && (x_xr_ensure_picture (f), FRAME_X_PICTURE (f)))
  7949         picture = XRenderCreatePicture (display, pixmap,
  7950                                         FRAME_X_PICTURE_FORMAT (f),
  7951                                         0, &attrs);
  7952 #endif
  7953 
  7954       if (p->overlay_p)
  7955         {
  7956           clipmask = XCreatePixmapFromBitmapData (display,
  7957                                                   FRAME_DISPLAY_INFO (f)->root_window,
  7958                                                   bits, p->wd, p->h,
  7959                                                   1, 0, 1);
  7960 
  7961 #ifdef HAVE_XRENDER
  7962           if (picture != None)
  7963             {
  7964               attrs.clip_mask = clipmask;
  7965               attrs.clip_x_origin = p->x;
  7966               attrs.clip_y_origin = p->y;
  7967 
  7968               XRenderChangePicture (display, FRAME_X_PICTURE (f),
  7969                                     CPClipMask | CPClipXOrigin | CPClipYOrigin,
  7970                                     &attrs);
  7971             }
  7972           else
  7973 #endif
  7974             {
  7975               gcv.clip_mask = clipmask;
  7976               gcv.clip_x_origin = p->x;
  7977               gcv.clip_y_origin = p->y;
  7978               XChangeGC (display, gc, GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv);
  7979             }
  7980         }
  7981 
  7982 #ifdef HAVE_XRENDER
  7983       if (picture != None)
  7984         {
  7985           x_xr_apply_ext_clip (f, gc);
  7986           XRenderComposite (display, PictOpSrc, picture,
  7987                             None, FRAME_X_PICTURE (f),
  7988                             0, 0, 0, 0, p->x, p->y, p->wd, p->h);
  7989           x_xr_reset_ext_clip (f);
  7990 
  7991           XRenderFreePicture (display, picture);
  7992         }
  7993       else
  7994 #endif
  7995         XCopyArea (display, pixmap, drawable, gc, 0, 0,
  7996                    p->wd, p->h, p->x, p->y);
  7997       XFreePixmap (display, pixmap);
  7998 
  7999       if (p->overlay_p)
  8000         {
  8001           gcv.clip_mask = (Pixmap) 0;
  8002           XChangeGC (display, gc, GCClipMask, &gcv);
  8003           XFreePixmap (display, clipmask);
  8004         }
  8005     }
  8006 #endif  /* not USE_CAIRO */
  8007 
  8008   x_reset_clip_rectangles (f, gc);
  8009 }
  8010 
  8011 /***********************************************************************
  8012                             Glyph display
  8013  ***********************************************************************/
  8014 
  8015 static bool x_alloc_lighter_color (struct frame *, Display *, Colormap,
  8016                                    unsigned long *, double, int);
  8017 static void x_scroll_bar_clear (struct frame *);
  8018 
  8019 #ifdef GLYPH_DEBUG
  8020 static void x_check_font (struct frame *, struct font *);
  8021 #endif
  8022 
  8023 /* If SEND_EVENT, make sure that TIME is larger than the current last
  8024    user time.  We don't sanitize timestamps from events sent by the X
  8025    server itself because some Lisp might have set the user time to a
  8026    ridiculously large value, and this way a more reasonable timestamp
  8027    can be obtained upon the next event.
  8028 
  8029    Alternatively, the server time could've overflowed.
  8030 
  8031    SET_PROPERTY specifies whether or not to change the user time
  8032    property for the active frame.  The important thing is to not set
  8033    the last user time upon leave events; on Metacity and GNOME Shell,
  8034    mapping a new frame on top of the old frame potentially causes
  8035    crossing events to be sent to the old frame if it contains the
  8036    pointer, as the new frame will initially stack above the old frame.
  8037    If _NET_WM_USER_TIME is changed at that point, then GNOME may get
  8038    notified about the user time change on the old frame before it
  8039    tries to focus the new frame, which will make it consider the new
  8040    frame (whose user time property will not have been updated at that
  8041    point, due to not being focused) as having been mapped
  8042    out-of-order, and lower the new frame, which is typically not what
  8043    users want.  */
  8044 
  8045 static void
  8046 x_display_set_last_user_time (struct x_display_info *dpyinfo, Time time,
  8047                               bool send_event, bool set_property)
  8048 {
  8049 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
  8050   uint_fast64_t monotonic_time;
  8051   uint_fast64_t monotonic_ms;
  8052   int_fast64_t diff_ms;
  8053 #endif
  8054 #ifndef USE_GTK
  8055   struct frame *focus_frame;
  8056   Time old_time;
  8057 
  8058   focus_frame = dpyinfo->x_focus_frame;
  8059   old_time = dpyinfo->last_user_time;
  8060 #endif
  8061 
  8062 #ifdef ENABLE_CHECKING
  8063   eassert (time <= X_ULONG_MAX);
  8064 #endif
  8065 
  8066   if (!send_event || time > dpyinfo->last_user_time)
  8067     dpyinfo->last_user_time = time;
  8068 
  8069 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
  8070   if (!send_event)
  8071     {
  8072       /* See if the current CLOCK_MONOTONIC time is reasonably close
  8073          to the X server time.  */
  8074       monotonic_time = x_sync_current_monotonic_time ();
  8075       monotonic_ms = monotonic_time / 1000;
  8076 
  8077       dpyinfo->server_time_monotonic_p
  8078         = (monotonic_time != 0
  8079            && !ckd_sub (&diff_ms, time, monotonic_ms)
  8080            && -500 < diff_ms && diff_ms < 500);
  8081 
  8082       if (!dpyinfo->server_time_monotonic_p)
  8083         {
  8084           /* Compute an offset that can be subtracted from the server
  8085              time to estimate the monotonic time on the X server.  */
  8086 
  8087           if (!monotonic_time
  8088               || ckd_mul (&dpyinfo->server_time_offset, time, 1000)
  8089               || ckd_sub (&dpyinfo->server_time_offset,
  8090                           dpyinfo->server_time_offset, monotonic_time))
  8091             dpyinfo->server_time_offset = 0;
  8092 
  8093           /* If the server time is reasonably close to the monotonic
  8094              time after the latter is truncated to CARD32, simply make
  8095              the offset that between the server time in ms and the
  8096              actual time in ms.  */
  8097 
  8098           monotonic_ms = monotonic_ms & 0xffffffff;
  8099           if (!ckd_sub (&diff_ms, time, monotonic_ms)
  8100               && -500 < diff_ms && diff_ms < 500)
  8101             {
  8102               /* The server timestamp overflowed.  Make the time
  8103                  offset exactly how much it overflowed by.  */
  8104 
  8105               if (ckd_sub (&dpyinfo->server_time_offset,
  8106                            monotonic_time / 1000, monotonic_ms)
  8107                   || ckd_mul (&dpyinfo->server_time_offset,
  8108                               dpyinfo->server_time_offset, 1000)
  8109                   || ckd_sub (&dpyinfo->server_time_offset,
  8110                               0, dpyinfo->server_time_offset))
  8111                 dpyinfo->server_time_offset = 0;
  8112             }
  8113         }
  8114     }
  8115 #endif
  8116 
  8117 #ifndef USE_GTK
  8118   /* Don't waste bandwidth if the time hasn't actually changed.  */
  8119   if (focus_frame && old_time != dpyinfo->last_user_time
  8120       && set_property)
  8121     {
  8122       time = dpyinfo->last_user_time;
  8123 
  8124       while (FRAME_PARENT_FRAME (focus_frame))
  8125         focus_frame = FRAME_PARENT_FRAME (focus_frame);
  8126 
  8127       if (FRAME_X_OUTPUT (focus_frame)->user_time_window != None)
  8128         XChangeProperty (dpyinfo->display,
  8129                          FRAME_X_OUTPUT (focus_frame)->user_time_window,
  8130                          dpyinfo->Xatom_net_wm_user_time,
  8131                          XA_CARDINAL, 32, PropModeReplace,
  8132                          (unsigned char *) &time, 1);
  8133     }
  8134 #endif
  8135 }
  8136 
  8137 #ifdef USE_GTK
  8138 
  8139 static void
  8140 x_set_gtk_user_time (struct frame *f, Time time)
  8141 {
  8142   GtkWidget *widget;
  8143   GdkWindow *window;
  8144 
  8145   widget = FRAME_GTK_OUTER_WIDGET (f);
  8146   window = gtk_widget_get_window (widget);
  8147 
  8148   /* This widget isn't realized yet.  */
  8149   if (!window)
  8150     return;
  8151 
  8152   gdk_x11_window_set_user_time (window, time);
  8153 }
  8154 
  8155 #endif
  8156 
  8157 #if !defined USE_GTK || defined HAVE_XFIXES
  8158 
  8159 /* Create and return a special window for receiving events such as
  8160    selection notify events, and reporting user time.  The window is an
  8161    1x1 unmapped override-redirect InputOnly window at -1, -1 relative
  8162    to the parent, which should prevent it from doing anything.  */
  8163 
  8164 static Window
  8165 x_create_special_window (struct x_display_info *dpyinfo,
  8166                          Window parent_window)
  8167 {
  8168   XSetWindowAttributes attrs;
  8169 
  8170   attrs.override_redirect = True;
  8171 
  8172   return XCreateWindow (dpyinfo->display, parent_window,
  8173                         -1, -1, 1, 1, 0, CopyFromParent, InputOnly,
  8174                         CopyFromParent, CWOverrideRedirect, &attrs);
  8175 }
  8176 
  8177 #endif
  8178 
  8179 /* Not needed on GTK because GTK handles reporting the user time
  8180    itself.  */
  8181 
  8182 #ifndef USE_GTK
  8183 
  8184 static void
  8185 x_update_frame_user_time_window (struct frame *f)
  8186 {
  8187   struct x_output *output;
  8188   struct x_display_info *dpyinfo;
  8189 
  8190   output = FRAME_X_OUTPUT (f);
  8191   dpyinfo = FRAME_DISPLAY_INFO (f);
  8192 
  8193   if (!NILP (Vx_no_window_manager)
  8194       || !x_wm_supports (f, dpyinfo->Xatom_net_wm_user_time))
  8195     {
  8196       if (output->user_time_window != None
  8197           && output->user_time_window != FRAME_OUTER_WINDOW (f))
  8198         {
  8199           XDestroyWindow (dpyinfo->display, output->user_time_window);
  8200           XDeleteProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
  8201                            dpyinfo->Xatom_net_wm_user_time_window);
  8202         }
  8203       else
  8204         XDeleteProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
  8205                          dpyinfo->Xatom_net_wm_user_time);
  8206 
  8207       output->user_time_window = None;
  8208       return;
  8209     }
  8210 
  8211   if (!x_wm_supports (f, dpyinfo->Xatom_net_wm_user_time_window))
  8212     {
  8213       if (output->user_time_window == None)
  8214         output->user_time_window = FRAME_OUTER_WINDOW (f);
  8215       else if (output->user_time_window != FRAME_OUTER_WINDOW (f))
  8216         {
  8217           XDestroyWindow (dpyinfo->display,
  8218                           output->user_time_window);
  8219           XDeleteProperty (dpyinfo->display,
  8220                            FRAME_OUTER_WINDOW (f),
  8221                            dpyinfo->Xatom_net_wm_user_time_window);
  8222           output->user_time_window = FRAME_OUTER_WINDOW (f);
  8223         }
  8224     }
  8225   else
  8226     {
  8227       if (output->user_time_window == FRAME_OUTER_WINDOW (f)
  8228           || output->user_time_window == None)
  8229         {
  8230           /* Create a "user time" window that is used to report user
  8231              activity on a given frame.  This is used in preference to
  8232              _NET_WM_USER_TIME, as using a separate window allows the
  8233              window manager to express interest in other properties
  8234              while only reading the user time when necessary, thereby
  8235              improving battery life by not involving the window
  8236              manager in each key press.  */
  8237 
  8238           output->user_time_window
  8239             = x_create_special_window (dpyinfo, FRAME_X_WINDOW (f));
  8240 
  8241           XDeleteProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
  8242                            dpyinfo->Xatom_net_wm_user_time);
  8243           XChangeProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
  8244                            dpyinfo->Xatom_net_wm_user_time_window,
  8245                            XA_WINDOW, 32, PropModeReplace,
  8246                            (unsigned char *) &output->user_time_window, 1);
  8247         }
  8248     }
  8249 }
  8250 
  8251 #endif
  8252 
  8253 void
  8254 x_set_last_user_time_from_lisp (struct x_display_info *dpyinfo,
  8255                                 Time time)
  8256 {
  8257   x_display_set_last_user_time (dpyinfo, time, true, true);
  8258 }
  8259 
  8260 
  8261 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
  8262    face.  */
  8263 
  8264 static void
  8265 x_set_cursor_gc (struct glyph_string *s)
  8266 {
  8267   if (s->font == FRAME_FONT (s->f)
  8268       && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
  8269       && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
  8270       && !s->cmp)
  8271     s->gc = s->f->output_data.x->cursor_gc;
  8272   else
  8273     {
  8274       /* Cursor on non-default face: must merge.  */
  8275       XGCValues xgcv;
  8276       unsigned long mask;
  8277       Display *display = FRAME_X_DISPLAY (s->f);
  8278 
  8279       xgcv.background = s->f->output_data.x->cursor_pixel;
  8280       xgcv.foreground = s->face->background;
  8281 
  8282       /* If the glyph would be invisible, try a different foreground.  */
  8283       if (xgcv.foreground == xgcv.background)
  8284         xgcv.foreground = s->face->foreground;
  8285       if (xgcv.foreground == xgcv.background)
  8286         xgcv.foreground = s->f->output_data.x->cursor_foreground_pixel;
  8287       if (xgcv.foreground == xgcv.background)
  8288         xgcv.foreground = s->face->foreground;
  8289 
  8290       /* Make sure the cursor is distinct from text in this face.  */
  8291       if (xgcv.background == s->face->background
  8292           && xgcv.foreground == s->face->foreground)
  8293         {
  8294           xgcv.background = s->face->foreground;
  8295           xgcv.foreground = s->face->background;
  8296         }
  8297 
  8298       IF_DEBUG (x_check_font (s->f, s->font));
  8299       xgcv.graphics_exposures = False;
  8300       xgcv.line_width = 1;
  8301       mask = (GCForeground | GCBackground
  8302               | GCGraphicsExposures
  8303               | GCLineWidth);
  8304 
  8305       if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
  8306         XChangeGC (display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
  8307                    mask, &xgcv);
  8308       else
  8309         FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
  8310           = XCreateGC (display, FRAME_X_DRAWABLE (s->f), mask, &xgcv);
  8311 
  8312       s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
  8313     }
  8314 }
  8315 
  8316 
  8317 /* Set up S->gc of glyph string S for drawing text in mouse face.  */
  8318 
  8319 static void
  8320 x_set_mouse_face_gc (struct glyph_string *s)
  8321 {
  8322   if (s->font == s->face->font)
  8323     s->gc = s->face->gc;
  8324   else
  8325     {
  8326       /* Otherwise construct scratch_cursor_gc with values from FACE
  8327          except for FONT.  */
  8328       XGCValues xgcv;
  8329       unsigned long mask;
  8330       Display *display = FRAME_X_DISPLAY (s->f);
  8331 
  8332       xgcv.background = s->face->background;
  8333       xgcv.foreground = s->face->foreground;
  8334       xgcv.graphics_exposures = False;
  8335       xgcv.line_width = 1;
  8336 
  8337       mask = (GCForeground | GCBackground
  8338               | GCGraphicsExposures
  8339               | GCLineWidth);
  8340 
  8341       if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
  8342         XChangeGC (display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
  8343                    mask, &xgcv);
  8344       else
  8345         FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
  8346           = XCreateGC (display, FRAME_X_DRAWABLE (s->f), mask, &xgcv);
  8347 
  8348       s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
  8349 
  8350     }
  8351   eassert (s->gc != 0);
  8352 }
  8353 
  8354 
  8355 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
  8356    Faces to use in the mode line have already been computed when the
  8357    matrix was built, so there isn't much to do, here.  */
  8358 
  8359 static void
  8360 x_set_mode_line_face_gc (struct glyph_string *s)
  8361 {
  8362   s->gc = s->face->gc;
  8363 }
  8364 
  8365 
  8366 /* Set S->gc of glyph string S for drawing that glyph string.  Set
  8367    S->stippled_p to a non-zero value if the face of S has a stipple
  8368    pattern.  */
  8369 
  8370 static void
  8371 x_set_glyph_string_gc (struct glyph_string *s)
  8372 {
  8373   prepare_face_for_display (s->f, s->face);
  8374 
  8375   if (s->hl == DRAW_NORMAL_TEXT)
  8376     {
  8377       s->gc = s->face->gc;
  8378       s->stippled_p = s->face->stipple != 0;
  8379     }
  8380   else if (s->hl == DRAW_INVERSE_VIDEO)
  8381     {
  8382       x_set_mode_line_face_gc (s);
  8383       s->stippled_p = s->face->stipple != 0;
  8384     }
  8385   else if (s->hl == DRAW_CURSOR)
  8386     {
  8387       x_set_cursor_gc (s);
  8388       s->stippled_p = false;
  8389     }
  8390   else if (s->hl == DRAW_MOUSE_FACE)
  8391     {
  8392       x_set_mouse_face_gc (s);
  8393       s->stippled_p = s->face->stipple != 0;
  8394     }
  8395   else if (s->hl == DRAW_IMAGE_RAISED
  8396            || s->hl == DRAW_IMAGE_SUNKEN)
  8397     {
  8398       s->gc = s->face->gc;
  8399       s->stippled_p = s->face->stipple != 0;
  8400     }
  8401   else
  8402     emacs_abort ();
  8403 
  8404   /* GC must have been set.  */
  8405   eassert (s->gc != 0);
  8406 }
  8407 
  8408 
  8409 /* Set clipping for output of glyph string S.  S may be part of a mode
  8410    line or menu if we don't have X toolkit support.  */
  8411 
  8412 static void
  8413 x_set_glyph_string_clipping (struct glyph_string *s)
  8414 {
  8415   XRectangle *r = s->clip;
  8416   int n = get_glyph_string_clip_rects (s, r, 2);
  8417 
  8418   if (n > 0)
  8419     x_set_clip_rectangles (s->f, s->gc, r, n);
  8420   s->num_clips = n;
  8421 }
  8422 
  8423 
  8424 /* Set SRC's clipping for output of glyph string DST.  This is called
  8425    when we are drawing DST's left_overhang or right_overhang only in
  8426    the area of SRC.  */
  8427 
  8428 static void
  8429 x_set_glyph_string_clipping_exactly (struct glyph_string *src, struct glyph_string *dst)
  8430 {
  8431   XRectangle r;
  8432 
  8433   r.x = src->x;
  8434   r.width = src->width;
  8435   r.y = src->y;
  8436   r.height = src->height;
  8437   dst->clip[0] = r;
  8438   dst->num_clips = 1;
  8439   x_set_clip_rectangles (dst->f, dst->gc, &r, 1);
  8440 }
  8441 
  8442 
  8443 /* RIF:
  8444    Compute left and right overhang of glyph string S.  */
  8445 
  8446 static void
  8447 x_compute_glyph_string_overhangs (struct glyph_string *s)
  8448 {
  8449   if (s->cmp == NULL
  8450       && (s->first_glyph->type == CHAR_GLYPH
  8451           || s->first_glyph->type == COMPOSITE_GLYPH))
  8452     {
  8453       struct font_metrics metrics;
  8454 
  8455       if (s->first_glyph->type == CHAR_GLYPH)
  8456         {
  8457           struct font *font = s->font;
  8458           font->driver->text_extents (font, s->char2b, s->nchars, &metrics);
  8459         }
  8460       else
  8461         {
  8462           Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
  8463 
  8464           composition_gstring_width (gstring, s->cmp_from, s->cmp_to, &metrics);
  8465         }
  8466       s->right_overhang = (metrics.rbearing > metrics.width
  8467                            ? metrics.rbearing - metrics.width : 0);
  8468       s->left_overhang = metrics.lbearing < 0 ? - metrics.lbearing : 0;
  8469     }
  8470   else if (s->cmp)
  8471     {
  8472       s->right_overhang = s->cmp->rbearing - s->cmp->pixel_width;
  8473       s->left_overhang = - s->cmp->lbearing;
  8474     }
  8475 }
  8476 
  8477 
  8478 /* Fill rectangle X, Y, W, H with background color of glyph string S.  */
  8479 
  8480 static void
  8481 x_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h)
  8482 {
  8483   x_clear_rectangle (s->f, s->gc, x, y, w, h, s->hl != DRAW_CURSOR);
  8484 }
  8485 
  8486 #ifndef USE_CAIRO
  8487 
  8488 static void
  8489 x_clear_point (struct frame *f, GC gc, int x, int y,
  8490                bool respect_alpha_background)
  8491 {
  8492   XGCValues xgcv;
  8493   Display *dpy;
  8494 
  8495   dpy = FRAME_X_DISPLAY (f);
  8496 
  8497   if (f->alpha_background != 1.0
  8498       && respect_alpha_background)
  8499     {
  8500       x_clear_rectangle (f, gc, x, y, 1, 1, true);
  8501       return;
  8502     }
  8503 
  8504   XGetGCValues (dpy, gc, GCBackground | GCForeground, &xgcv);
  8505   XSetForeground (dpy, gc, xgcv.background);
  8506   XDrawPoint (dpy, FRAME_X_DRAWABLE (f), gc, x, y);
  8507   XSetForeground (dpy, gc, xgcv.foreground);
  8508 }
  8509 
  8510 #endif
  8511 
  8512 /* Draw the background of glyph_string S.  If S->background_filled_p
  8513    is non-zero don't draw it.  FORCE_P non-zero means draw the
  8514    background even if it wouldn't be drawn normally.  This is used
  8515    when a string preceding S draws into the background of S, or S
  8516    contains the first component of a composition.  */
  8517 
  8518 static void
  8519 x_draw_glyph_string_background (struct glyph_string *s, bool force_p)
  8520 {
  8521   /* Nothing to do if background has already been drawn or if it
  8522      shouldn't be drawn in the first place.  */
  8523   if (!s->background_filled_p)
  8524     {
  8525       int box_line_width = max (s->face->box_horizontal_line_width, 0);
  8526 
  8527       if (s->stippled_p)
  8528         {
  8529           Display *display = FRAME_X_DISPLAY (s->f);
  8530 
  8531           /* Fill background with a stipple pattern.  */
  8532           XSetFillStyle (display, s->gc, FillOpaqueStippled);
  8533           x_fill_rectangle (s->f, s->gc, s->x,
  8534                             s->y + box_line_width,
  8535                             s->background_width,
  8536                             s->height - 2 * box_line_width,
  8537                             s->hl != DRAW_CURSOR);
  8538           XSetFillStyle (display, s->gc, FillSolid);
  8539           s->background_filled_p = true;
  8540         }
  8541       else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
  8542                /* When xdisp.c ignores FONT_HEIGHT, we cannot trust
  8543                   font dimensions, since the actual glyphs might be
  8544                   much smaller.  So in that case we always clear the
  8545                   rectangle with background color.  */
  8546                || FONT_TOO_HIGH (s->font)
  8547                || s->font_not_found_p
  8548                || s->extends_to_end_of_line_p
  8549                || force_p)
  8550         {
  8551           x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
  8552                                      s->background_width,
  8553                                      s->height - 2 * box_line_width);
  8554           s->background_filled_p = true;
  8555         }
  8556     }
  8557 }
  8558 
  8559 
  8560 /* Draw the foreground of glyph string S.  */
  8561 
  8562 static void
  8563 x_draw_glyph_string_foreground (struct glyph_string *s)
  8564 {
  8565   int i, x;
  8566 
  8567   /* If first glyph of S has a left box line, start drawing the text
  8568      of S to the right of that box line.  */
  8569   if (s->face->box != FACE_NO_BOX
  8570       && s->first_glyph->left_box_line_p)
  8571     x = s->x + max (s->face->box_vertical_line_width, 0);
  8572   else
  8573     x = s->x;
  8574 
  8575   /* Draw characters of S as rectangles if S's font could not be
  8576      loaded.  */
  8577   if (s->font_not_found_p)
  8578     {
  8579       for (i = 0; i < s->nchars; ++i)
  8580         {
  8581           struct glyph *g = s->first_glyph + i;
  8582           x_draw_rectangle (s->f,
  8583                           s->gc, x, s->y, g->pixel_width - 1,
  8584                           s->height - 1);
  8585           x += g->pixel_width;
  8586         }
  8587     }
  8588   else
  8589     {
  8590       struct font *font = s->font;
  8591 #ifdef USE_CAIRO
  8592       if (!EQ (font->driver->type, Qx)
  8593           || x_try_cr_xlib_drawable (s->f, s->gc))
  8594         {
  8595 #endif  /* USE_CAIRO */
  8596           int boff = font->baseline_offset;
  8597           int y;
  8598 
  8599           if (font->vertical_centering)
  8600             boff = VCENTER_BASELINE_OFFSET (font, s->f) - boff;
  8601 
  8602           y = s->ybase - boff;
  8603           if (s->for_overlaps
  8604               || (s->background_filled_p && s->hl != DRAW_CURSOR))
  8605             font->driver->draw (s, 0, s->nchars, x, y, false);
  8606           else
  8607             font->driver->draw (s, 0, s->nchars, x, y, true);
  8608           if (s->face->overstrike)
  8609             font->driver->draw (s, 0, s->nchars, x + 1, y, false);
  8610 #ifdef USE_CAIRO
  8611           if (EQ (font->driver->type, Qx))
  8612             x_end_cr_xlib_drawable (s->f, s->gc);
  8613         }
  8614       else
  8615         {
  8616           /* Fallback for the case that no Xlib Drawable is available
  8617              for drawing text with X core fonts.  */
  8618           if (!(s->for_overlaps
  8619                 || (s->background_filled_p && s->hl != DRAW_CURSOR)))
  8620             {
  8621               int box_line_width = max (s->face->box_horizontal_line_width, 0);
  8622 
  8623               if (s->stippled_p)
  8624                 {
  8625                   Display *display = FRAME_X_DISPLAY (s->f);
  8626 
  8627                   /* Fill background with a stipple pattern.  */
  8628                   XSetFillStyle (display, s->gc, FillOpaqueStippled);
  8629                   x_fill_rectangle (s->f, s->gc, s->x,
  8630                                     s->y + box_line_width,
  8631                                     s->background_width,
  8632                                     s->height - 2 * box_line_width,
  8633                                     false);
  8634                   XSetFillStyle (display, s->gc, FillSolid);
  8635                 }
  8636               else
  8637                 x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
  8638                                            s->background_width,
  8639                                            s->height - 2 * box_line_width);
  8640             }
  8641           for (i = 0; i < s->nchars; ++i)
  8642             {
  8643               struct glyph *g = s->first_glyph + i;
  8644               x_draw_rectangle (s->f,
  8645                                 s->gc, x, s->y, g->pixel_width - 1,
  8646                                 s->height - 1);
  8647               x += g->pixel_width;
  8648             }
  8649         }
  8650 #endif  /* USE_CAIRO */
  8651     }
  8652 }
  8653 
  8654 /* Draw the foreground of composite glyph string S.  */
  8655 
  8656 static void
  8657 x_draw_composite_glyph_string_foreground (struct glyph_string *s)
  8658 {
  8659   int i, j, x;
  8660   struct font *font = s->font;
  8661 
  8662   /* If first glyph of S has a left box line, start drawing the text
  8663      of S to the right of that box line.  */
  8664   if (s->face && s->face->box != FACE_NO_BOX
  8665       && s->first_glyph->left_box_line_p)
  8666     x = s->x + max (s->face->box_vertical_line_width, 0);
  8667   else
  8668     x = s->x;
  8669 
  8670   /* S is a glyph string for a composition.  S->cmp_from is the index
  8671      of the first character drawn for glyphs of this composition.
  8672      S->cmp_from == 0 means we are drawing the very first character of
  8673      this composition.  */
  8674 
  8675   /* Draw a rectangle for the composition if the font for the very
  8676      first character of the composition could not be loaded.  */
  8677   if (s->font_not_found_p)
  8678     {
  8679       if (s->cmp_from == 0)
  8680         x_draw_rectangle (s->f, s->gc, x, s->y,
  8681                         s->width - 1, s->height - 1);
  8682     }
  8683   else
  8684 #ifdef USE_CAIRO
  8685     if (!EQ (font->driver->type, Qx)
  8686         || x_try_cr_xlib_drawable (s->f, s->gc))
  8687       {
  8688 #endif  /* USE_CAIRO */
  8689         if (! s->first_glyph->u.cmp.automatic)
  8690           {
  8691             int y = s->ybase;
  8692 
  8693             for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++)
  8694               /* TAB in a composition means display glyphs with
  8695                  padding space on the left or right.  */
  8696               if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
  8697                 {
  8698                   int xx = x + s->cmp->offsets[j * 2];
  8699                   int yy = y - s->cmp->offsets[j * 2 + 1];
  8700 
  8701                   font->driver->draw (s, j, j + 1, xx, yy, false);
  8702                   if (s->face->overstrike)
  8703                     font->driver->draw (s, j, j + 1, xx + 1, yy, false);
  8704                 }
  8705           }
  8706         else
  8707           {
  8708             Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
  8709             Lisp_Object glyph;
  8710             int y = s->ybase;
  8711             int width = 0;
  8712 
  8713             for (i = j = s->cmp_from; i < s->cmp_to; i++)
  8714               {
  8715                 glyph = LGSTRING_GLYPH (gstring, i);
  8716                 if (NILP (LGLYPH_ADJUSTMENT (glyph)))
  8717                   width += LGLYPH_WIDTH (glyph);
  8718                 else
  8719                   {
  8720                     int xoff, yoff, wadjust;
  8721 
  8722                     if (j < i)
  8723                       {
  8724                         font->driver->draw (s, j, i, x, y, false);
  8725                         if (s->face->overstrike)
  8726                           font->driver->draw (s, j, i, x + 1, y, false);
  8727                         x += width;
  8728                       }
  8729                     xoff = LGLYPH_XOFF (glyph);
  8730                     yoff = LGLYPH_YOFF (glyph);
  8731                     wadjust = LGLYPH_WADJUST (glyph);
  8732                     font->driver->draw (s, i, i + 1, x + xoff, y + yoff, false);
  8733                     if (s->face->overstrike)
  8734                       font->driver->draw (s, i, i + 1, x + xoff + 1, y + yoff,
  8735                                           false);
  8736                     x += wadjust;
  8737                     j = i + 1;
  8738                     width = 0;
  8739                   }
  8740               }
  8741             if (j < i)
  8742               {
  8743                 font->driver->draw (s, j, i, x, y, false);
  8744                 if (s->face->overstrike)
  8745                   font->driver->draw (s, j, i, x + 1, y, false);
  8746               }
  8747           }
  8748 #ifdef USE_CAIRO
  8749         if (EQ (font->driver->type, Qx))
  8750           x_end_cr_xlib_drawable (s->f, s->gc);
  8751       }
  8752     else
  8753       {
  8754         /* Fallback for the case that no Xlib Drawable is available
  8755            for drawing text with X core fonts.  */
  8756         if (s->cmp_from == 0)
  8757           x_draw_rectangle (s->f, s->gc, x, s->y,
  8758                             s->width - 1, s->height - 1);
  8759       }
  8760 #endif  /* USE_CAIRO */
  8761 }
  8762 
  8763 
  8764 /* Draw the foreground of glyph string S for glyphless characters.  */
  8765 
  8766 static void
  8767 x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
  8768 {
  8769   struct glyph *glyph = s->first_glyph;
  8770   unsigned char2b[8];
  8771   int x, i, j;
  8772 
  8773   /* If first glyph of S has a left box line, start drawing the text
  8774      of S to the right of that box line.  */
  8775   if (s->face && s->face->box != FACE_NO_BOX
  8776       && s->first_glyph->left_box_line_p)
  8777     x = s->x + max (s->face->box_vertical_line_width, 0);
  8778   else
  8779     x = s->x;
  8780 
  8781   s->char2b = char2b;
  8782 
  8783   for (i = 0; i < s->nchars; i++, glyph++)
  8784     {
  8785 #ifdef GCC_LINT
  8786       enum { PACIFY_GCC_BUG_81401 = 1 };
  8787 #else
  8788       enum { PACIFY_GCC_BUG_81401 = 0 };
  8789 #endif
  8790       char buf[7 + PACIFY_GCC_BUG_81401];
  8791       char *str = NULL;
  8792       int len = glyph->u.glyphless.len;
  8793 
  8794       if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM)
  8795         {
  8796           if (len > 0
  8797               && CHAR_TABLE_P (Vglyphless_char_display)
  8798               && (CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display))
  8799                   >= 1))
  8800             {
  8801               Lisp_Object acronym
  8802                 = (! glyph->u.glyphless.for_no_font
  8803                    ? CHAR_TABLE_REF (Vglyphless_char_display,
  8804                                      glyph->u.glyphless.ch)
  8805                    : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
  8806               if (CONSP (acronym))
  8807                 acronym = XCAR (acronym);
  8808               if (STRINGP (acronym))
  8809                 str = SSDATA (acronym);
  8810             }
  8811         }
  8812       else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE)
  8813         {
  8814           unsigned int ch = glyph->u.glyphless.ch;
  8815           eassume (ch <= MAX_CHAR);
  8816           sprintf (buf, "%0*X", ch < 0x10000 ? 4 : 6, ch);
  8817           str = buf;
  8818         }
  8819 
  8820       if (str)
  8821         {
  8822           int upper_len = (len + 1) / 2;
  8823 
  8824           /* It is assured that all LEN characters in STR is ASCII.  */
  8825           for (j = 0; j < len; j++)
  8826             char2b[j] = s->font->driver->encode_char (s->font, str[j]) & 0xFFFF;
  8827           s->font->driver->draw (s, 0, upper_len,
  8828                                  x + glyph->slice.glyphless.upper_xoff,
  8829                                  s->ybase + glyph->slice.glyphless.upper_yoff,
  8830                                  false);
  8831           s->font->driver->draw (s, upper_len, len,
  8832                                  x + glyph->slice.glyphless.lower_xoff,
  8833                                  s->ybase + glyph->slice.glyphless.lower_yoff,
  8834                                  false);
  8835         }
  8836       if (glyph->u.glyphless.method != GLYPHLESS_DISPLAY_THIN_SPACE)
  8837         x_draw_rectangle (s->f, s->gc,
  8838                         x, s->ybase - glyph->ascent,
  8839                         glyph->pixel_width - 1,
  8840                         glyph->ascent + glyph->descent - 1);
  8841       x += glyph->pixel_width;
  8842    }
  8843 
  8844   /* Defend against hypothetical bad code elsewhere that uses
  8845      s->char2b after this function returns.  */
  8846   s->char2b = NULL;
  8847 }
  8848 
  8849 #ifdef USE_X_TOOLKIT
  8850 
  8851 #ifdef USE_LUCID
  8852 
  8853 /* Return the frame on which widget WIDGET is used.. Abort if frame
  8854    cannot be determined.  */
  8855 
  8856 static struct frame *
  8857 x_frame_of_widget (Widget widget)
  8858 {
  8859   struct x_display_info *dpyinfo;
  8860   Lisp_Object tail, frame;
  8861   struct frame *f;
  8862 
  8863   dpyinfo = x_display_info_for_display (XtDisplay (widget));
  8864 
  8865   /* Find the top-level shell of the widget.  Note that this function
  8866      can be called when the widget is not yet realized, so XtWindow
  8867      (widget) == 0.  That's the reason we can't simply use
  8868      x_any_window_to_frame.  */
  8869   while (!XtIsTopLevelShell (widget))
  8870     widget = XtParent (widget);
  8871 
  8872   /* Look for a frame with that top-level widget.  Allocate the color
  8873      on that frame to get the right gamma correction value.  */
  8874   FOR_EACH_FRAME (tail, frame)
  8875     {
  8876       f = XFRAME (frame);
  8877       if (FRAME_X_P (f)
  8878           && FRAME_DISPLAY_INFO (f) == dpyinfo
  8879           && f->output_data.x->widget == widget)
  8880         return f;
  8881     }
  8882   emacs_abort ();
  8883 }
  8884 
  8885 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
  8886    or DELTA.  Try a color with RGB values multiplied by FACTOR first.
  8887    If this produces the same color as PIXEL, try a color where all RGB
  8888    values have DELTA added.  Return the allocated color in *PIXEL.
  8889    DISPLAY is the X display, CMAP is the colormap to operate on.
  8890    Value is true if successful.  */
  8891 
  8892 bool
  8893 x_alloc_lighter_color_for_widget (Widget widget, Display *display, Colormap cmap,
  8894                                   unsigned long *pixel, double factor, int delta)
  8895 {
  8896   struct frame *f = x_frame_of_widget (widget);
  8897   return x_alloc_lighter_color (f, display, cmap, pixel, factor, delta);
  8898 }
  8899 
  8900 #endif /* USE_LUCID */
  8901 
  8902 
  8903 /* Structure specifying which arguments should be passed by Xt to
  8904    cvt_string_to_pixel.  We want the widget's screen and colormap.  */
  8905 
  8906 static XtConvertArgRec cvt_string_to_pixel_args[] =
  8907   {
  8908     {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.screen),
  8909      sizeof (Screen *)},
  8910     {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.colormap),
  8911      sizeof (Colormap)}
  8912   };
  8913 
  8914 
  8915 /* The address of this variable is returned by
  8916    cvt_string_to_pixel.  */
  8917 
  8918 static Pixel cvt_string_to_pixel_value;
  8919 
  8920 
  8921 /* Convert a color name to a pixel color.
  8922 
  8923    DPY is the display we are working on.
  8924 
  8925    ARGS is an array of *NARGS XrmValue structures holding additional
  8926    information about the widget for which the conversion takes place.
  8927    The contents of this array are determined by the specification
  8928    in cvt_string_to_pixel_args.
  8929 
  8930    FROM is a pointer to an XrmValue which points to the color name to
  8931    convert.  TO is an XrmValue in which to return the pixel color.
  8932 
  8933    CLOSURE_RET is a pointer to user-data, in which we record if
  8934    we allocated the color or not.
  8935 
  8936    Value is True if successful, False otherwise.  */
  8937 
  8938 static Boolean
  8939 cvt_string_to_pixel (Display *dpy, XrmValue *args, Cardinal *nargs,
  8940                      XrmValue *from, XrmValue *to,
  8941                      XtPointer *closure_ret)
  8942 {
  8943   Screen *screen;
  8944   Colormap cmap;
  8945   Pixel pixel;
  8946   String color_name;
  8947   XColor color;
  8948 
  8949   if (*nargs != 2)
  8950     {
  8951       XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
  8952                        "wrongParameters", "cvt_string_to_pixel",
  8953                        "XtToolkitError",
  8954                        "Screen and colormap args required", NULL, NULL);
  8955       return False;
  8956     }
  8957 
  8958   screen = *(Screen **) args[0].addr;
  8959   cmap = *(Colormap *) args[1].addr;
  8960   color_name = (String) from->addr;
  8961 
  8962   if (strcmp (color_name, XtDefaultBackground) == 0)
  8963     {
  8964       *closure_ret = (XtPointer) False;
  8965       pixel = WhitePixelOfScreen (screen);
  8966     }
  8967   else if (strcmp (color_name, XtDefaultForeground) == 0)
  8968     {
  8969       *closure_ret = (XtPointer) False;
  8970       pixel = BlackPixelOfScreen (screen);
  8971     }
  8972   else if (XParseColor (dpy, cmap, color_name, &color)
  8973            && x_alloc_nearest_color_1 (dpy, cmap, &color))
  8974     {
  8975       pixel = color.pixel;
  8976       *closure_ret = (XtPointer) True;
  8977     }
  8978   else
  8979     {
  8980       String params[1];
  8981       Cardinal nparams = 1;
  8982 
  8983       params[0] = color_name;
  8984       XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
  8985                        "badValue", "cvt_string_to_pixel",
  8986                        "XtToolkitError", "Invalid color '%s'",
  8987                        params, &nparams);
  8988       return False;
  8989     }
  8990 
  8991   if (to->addr != NULL)
  8992     {
  8993       if (to->size < sizeof (Pixel))
  8994         {
  8995           to->size = sizeof (Pixel);
  8996           return False;
  8997         }
  8998 
  8999       *(Pixel *) to->addr = pixel;
  9000     }
  9001   else
  9002     {
  9003       cvt_string_to_pixel_value = pixel;
  9004       to->addr = (XtPointer) &cvt_string_to_pixel_value;
  9005     }
  9006 
  9007   to->size = sizeof (Pixel);
  9008   return True;
  9009 }
  9010 
  9011 
  9012 /* Free a pixel color which was previously allocated via
  9013    cvt_string_to_pixel.  This is registered as the destructor
  9014    for this type of resource via XtSetTypeConverter.
  9015 
  9016    APP is the application context in which we work.
  9017 
  9018    TO is a pointer to an XrmValue holding the color to free.
  9019    CLOSURE is the value we stored in CLOSURE_RET for this color
  9020    in cvt_string_to_pixel.
  9021 
  9022    ARGS and NARGS are like for cvt_string_to_pixel.  */
  9023 
  9024 static void
  9025 cvt_pixel_dtor (XtAppContext app, XrmValuePtr to, XtPointer closure, XrmValuePtr args,
  9026                 Cardinal *nargs)
  9027 {
  9028   if (*nargs != 2)
  9029     {
  9030       XtAppWarningMsg (app, "wrongParameters", "cvt_pixel_dtor",
  9031                        "XtToolkitError",
  9032                        "Screen and colormap arguments required",
  9033                        NULL, NULL);
  9034     }
  9035   else if (closure != NULL)
  9036     {
  9037       /* We did allocate the pixel, so free it.  */
  9038       Screen *screen = *(Screen **) args[0].addr;
  9039       Colormap cmap = *(Colormap *) args[1].addr;
  9040       x_free_dpy_colors (DisplayOfScreen (screen), screen, cmap,
  9041                          (Pixel *) to->addr, 1);
  9042     }
  9043 }
  9044 
  9045 
  9046 #endif /* USE_X_TOOLKIT */
  9047 
  9048 
  9049 /* Value is an array of XColor structures for the contents of the
  9050    color map of display DPY.  Set *NCELLS to the size of the array.
  9051    Note that this probably shouldn't be called for large color maps,
  9052    say a 24-bit TrueColor map.  */
  9053 
  9054 static const XColor *
  9055 x_color_cells (Display *dpy, int *ncells)
  9056 {
  9057   struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
  9058   eassume (dpyinfo);
  9059 
  9060   if (dpyinfo->color_cells == NULL)
  9061     {
  9062       int ncolor_cells = dpyinfo->visual_info.colormap_size;
  9063       int i;
  9064 
  9065       dpyinfo->color_cells = xnmalloc (ncolor_cells,
  9066                                        sizeof *dpyinfo->color_cells);
  9067       dpyinfo->ncolor_cells = ncolor_cells;
  9068 
  9069       for (i = 0; i < ncolor_cells; ++i)
  9070         dpyinfo->color_cells[i].pixel = i;
  9071 
  9072       XQueryColors (dpy, dpyinfo->cmap,
  9073                     dpyinfo->color_cells, ncolor_cells);
  9074     }
  9075 
  9076   *ncells = dpyinfo->ncolor_cells;
  9077   return dpyinfo->color_cells;
  9078 }
  9079 
  9080 
  9081 /* On frame F, translate pixel colors to RGB values for the NCOLORS
  9082    colors in COLORS.  Use cached information, if available.
  9083 
  9084    Pixel values are in unsigned normalized format, meaning that
  9085    extending missing bits is done straightforwardly without any
  9086    complex colorspace conversions.  */
  9087 
  9088 void
  9089 x_query_colors (struct frame *f, XColor *colors, int ncolors)
  9090 {
  9091   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  9092   int i;
  9093 
  9094   if (dpyinfo->red_bits > 0)
  9095     {
  9096       /* For TrueColor displays, we can decompose the RGB value
  9097          directly.  */
  9098       unsigned int rmult, gmult, bmult;
  9099       unsigned int rmask, gmask, bmask;
  9100 
  9101       rmask = (1 << dpyinfo->red_bits) - 1;
  9102       gmask = (1 << dpyinfo->green_bits) - 1;
  9103       bmask = (1 << dpyinfo->blue_bits) - 1;
  9104       /* If we're widening, for example, 8 bits in the pixel value to
  9105          16 bits for the separate-color representation, we want to
  9106          extrapolate the lower bits based on those bits available --
  9107          in other words, we'd like 0xff to become 0xffff instead of
  9108          the 0xff00 we'd get by just zero-filling the lower bits.
  9109 
  9110          We generate a 32-bit scaled-up value and shift it, in case
  9111          the bit count doesn't divide 16 evenly (e.g., when dealing
  9112          with a 3-3-2 bit RGB display), to get more of the lower bits
  9113          correct.
  9114 
  9115          Should we cache the multipliers in dpyinfo?  Maybe
  9116          special-case the 8-8-8 common case?  */
  9117       rmult = 0xffffffff / rmask;
  9118       gmult = 0xffffffff / gmask;
  9119       bmult = 0xffffffff / bmask;
  9120 
  9121       for (i = 0; i < ncolors; ++i)
  9122         {
  9123           unsigned int r, g, b;
  9124           unsigned long pixel = colors[i].pixel;
  9125 
  9126           r = (pixel >> dpyinfo->red_offset) & rmask;
  9127           g = (pixel >> dpyinfo->green_offset) & gmask;
  9128           b = (pixel >> dpyinfo->blue_offset) & bmask;
  9129 
  9130           colors[i].red = (r * rmult) >> 16;
  9131           colors[i].green = (g * gmult) >> 16;
  9132           colors[i].blue = (b * bmult) >> 16;
  9133         }
  9134 
  9135       return;
  9136     }
  9137 
  9138   if (dpyinfo->color_cells)
  9139     {
  9140       int i;
  9141       for (i = 0; i < ncolors; ++i)
  9142         {
  9143           unsigned long pixel = colors[i].pixel;
  9144           eassert (pixel < dpyinfo->ncolor_cells);
  9145           eassert (dpyinfo->color_cells[pixel].pixel == pixel);
  9146           colors[i] = dpyinfo->color_cells[pixel];
  9147         }
  9148       return;
  9149     }
  9150 
  9151   XQueryColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), colors, ncolors);
  9152 }
  9153 
  9154 /* Store F's real background color into *BGCOLOR.  */
  9155 
  9156 static void
  9157 x_query_frame_background_color (struct frame *f, XColor *bgcolor)
  9158 {
  9159   unsigned long background = FRAME_BACKGROUND_PIXEL (f);
  9160 #ifndef USE_CAIRO
  9161   XColor bg;
  9162 #endif
  9163 
  9164   if (FRAME_DISPLAY_INFO (f)->alpha_bits)
  9165     {
  9166 #ifdef USE_CAIRO
  9167       background = (background & ~FRAME_DISPLAY_INFO (f)->alpha_mask);
  9168       background |= (((unsigned long) (f->alpha_background * 0xffff)
  9169                       >> (16 - FRAME_DISPLAY_INFO (f)->alpha_bits))
  9170                      << FRAME_DISPLAY_INFO (f)->alpha_offset);
  9171 #else
  9172       if (FRAME_DISPLAY_INFO (f)->alpha_bits
  9173           && f->alpha_background < 1.0)
  9174         {
  9175           bg.pixel = background;
  9176           x_query_colors (f, &bg, 1);
  9177 
  9178           background
  9179             = x_premultiply_pixel (FRAME_DISPLAY_INFO (f),
  9180                                    &bg, f->alpha_background);
  9181         }
  9182 #endif
  9183     }
  9184 
  9185   bgcolor->pixel = background;
  9186 
  9187   x_query_colors (f, bgcolor, 1);
  9188 }
  9189 
  9190 static unsigned int
  9191 x_hash_string_ignore_case (const char *string)
  9192 {
  9193   unsigned int i;
  9194 
  9195   i = 3323198485ul;
  9196   for (; *string; ++string)
  9197     {
  9198       i ^= c_tolower (*string);
  9199       i *= 0x5bd1e995;
  9200       i ^= i >> 15;
  9201     }
  9202   return i;
  9203 }
  9204 
  9205 /* On frame F, translate the color name to RGB values.  Use cached
  9206    information, if possible.
  9207 
  9208    If too many entries are placed in the cache, the least recently
  9209    used entries are removed.  */
  9210 
  9211 Status
  9212 x_parse_color (struct frame *f, const char *color_name,
  9213                XColor *color)
  9214 {
  9215   unsigned short r, g, b;
  9216   Display *dpy;
  9217   Colormap cmap;
  9218   struct x_display_info *dpyinfo;
  9219   struct color_name_cache_entry *cache_entry, *last;
  9220   struct color_name_cache_entry *next, *color_entry;
  9221   unsigned int hash, idx;
  9222   int rc, i;
  9223 
  9224   /* Don't pass #RGB strings directly to XParseColor, because that
  9225      follows the X convention of zero-extending each channel
  9226      value: #f00 means #f00000.  We want the convention of scaling
  9227      channel values, so #f00 means #ff0000, just as it does for
  9228      HTML, SVG, and CSS.  */
  9229   if (parse_color_spec (color_name, &r, &g, &b))
  9230     {
  9231       color->red = r;
  9232       color->green = g;
  9233       color->blue = b;
  9234 
  9235       return 1;
  9236     }
  9237 
  9238   /* Some X servers send BadValue on empty color names.  */
  9239   if (!strlen (color_name))
  9240     return 0;
  9241 
  9242   cmap = FRAME_X_COLORMAP (f);
  9243   dpy = FRAME_X_DISPLAY (f);
  9244   dpyinfo = FRAME_DISPLAY_INFO (f);
  9245 
  9246   hash = x_hash_string_ignore_case (color_name);
  9247   idx = hash % dpyinfo->color_names_size;
  9248 
  9249   last = NULL;
  9250 
  9251   for (cache_entry = dpyinfo->color_names[idx];
  9252        cache_entry; cache_entry = cache_entry->next)
  9253     {
  9254       if (!xstrcasecmp (cache_entry->name, color_name))
  9255         {
  9256           /* Move recently used entries to the start of the color
  9257              cache.  */
  9258 
  9259           if (last)
  9260             {
  9261               last->next = cache_entry->next;
  9262               cache_entry->next = dpyinfo->color_names[idx];
  9263 
  9264               dpyinfo->color_names[idx] = cache_entry;
  9265             }
  9266 
  9267           if (cache_entry->valid)
  9268             *color = cache_entry->rgb;
  9269 
  9270           return cache_entry->valid;
  9271         }
  9272 
  9273       last = cache_entry;
  9274     }
  9275 
  9276   block_input ();
  9277   rc = XParseColor (dpy, cmap, color_name, color);
  9278   unblock_input ();
  9279 
  9280   cache_entry = xzalloc (sizeof *cache_entry);
  9281   dpyinfo->color_names_length[idx] += 1;
  9282 
  9283   if (rc)
  9284     cache_entry->rgb = *color;
  9285 
  9286   cache_entry->valid = rc;
  9287   cache_entry->name = xstrdup (color_name);
  9288   cache_entry->next = dpyinfo->color_names[idx];
  9289 
  9290   dpyinfo->color_names[idx] = cache_entry;
  9291 
  9292   /* Don't let the color cache become too big.  */
  9293   if (dpyinfo->color_names_length[idx] > (x_color_cache_bucket_size > 0
  9294                                           ? x_color_cache_bucket_size : 128))
  9295     {
  9296       i = 0;
  9297 
  9298       for (last = dpyinfo->color_names[idx]; last; last = last->next)
  9299         {
  9300           if (++i == (x_color_cache_bucket_size > 0
  9301                       ? x_color_cache_bucket_size : 128))
  9302             {
  9303               next = last->next;
  9304               last->next = NULL;
  9305 
  9306               for (color_entry = next; color_entry; color_entry = last)
  9307                 {
  9308                   last = color_entry->next;
  9309 
  9310                   xfree (color_entry->name);
  9311                   xfree (color_entry);
  9312 
  9313                   dpyinfo->color_names_length[idx] -= 1;
  9314                 }
  9315 
  9316               return rc;
  9317             }
  9318         }
  9319     }
  9320 
  9321   return rc;
  9322 }
  9323 
  9324 
  9325 /* Allocate the color COLOR->pixel on DISPLAY, colormap CMAP.  If an
  9326    exact match can't be allocated, try the nearest color available.
  9327    Value is true if successful.  Set *COLOR to the color
  9328    allocated.  */
  9329 
  9330 static bool
  9331 x_alloc_nearest_color_1 (Display *dpy, Colormap cmap, XColor *color)
  9332 {
  9333   struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
  9334   bool rc;
  9335 
  9336   eassume (dpyinfo);
  9337   rc = XAllocColor (dpy, cmap, color) != 0;
  9338 
  9339   if (dpyinfo->visual_info.class == DirectColor)
  9340     return rc;
  9341 
  9342   if (rc == 0)
  9343     {
  9344       /* If we got to this point, the colormap is full, so we're going
  9345          to try and get the next closest color.  The algorithm used is
  9346          a least-squares matching, which is what X uses for closest
  9347          color matching with StaticColor visuals.  */
  9348 
  9349       const XColor *cells;
  9350       int no_cells;
  9351       int nearest;
  9352       long nearest_delta, trial_delta;
  9353       int x;
  9354       Status status;
  9355       bool retry = false;
  9356       int ncolor_cells, i;
  9357       bool temp_allocated;
  9358       XColor temp;
  9359 
  9360     start:
  9361       cells = x_color_cells (dpy, &no_cells);
  9362       temp_allocated = false;
  9363 
  9364       nearest = 0;
  9365       /* I'm assuming CSE so I'm not going to condense this. */
  9366       nearest_delta = ((((color->red >> 8) - (cells[0].red >> 8))
  9367                         * ((color->red >> 8) - (cells[0].red >> 8)))
  9368                        + (((color->green >> 8) - (cells[0].green >> 8))
  9369                           * ((color->green >> 8) - (cells[0].green >> 8)))
  9370                        + (((color->blue >> 8) - (cells[0].blue >> 8))
  9371                           * ((color->blue >> 8) - (cells[0].blue >> 8))));
  9372       for (x = 1; x < no_cells; x++)
  9373         {
  9374           trial_delta = ((((color->red >> 8) - (cells[x].red >> 8))
  9375                           * ((color->red >> 8) - (cells[x].red >> 8)))
  9376                          + (((color->green >> 8) - (cells[x].green >> 8))
  9377                             * ((color->green >> 8) - (cells[x].green >> 8)))
  9378                          + (((color->blue >> 8) - (cells[x].blue >> 8))
  9379                             * ((color->blue >> 8) - (cells[x].blue >> 8))));
  9380           if (trial_delta < nearest_delta)
  9381             {
  9382               /* We didn't decide to use this color, so free it.  */
  9383               if (temp_allocated)
  9384                 {
  9385                   XFreeColors (dpy, cmap, &temp.pixel, 1, 0);
  9386                   temp_allocated = false;
  9387                 }
  9388 
  9389               temp.red = cells[x].red;
  9390               temp.green = cells[x].green;
  9391               temp.blue = cells[x].blue;
  9392               status = XAllocColor (dpy, cmap, &temp);
  9393 
  9394               if (status)
  9395                 {
  9396                   temp_allocated = true;
  9397                   nearest = x;
  9398                   nearest_delta = trial_delta;
  9399                 }
  9400             }
  9401         }
  9402       color->red = cells[nearest].red;
  9403       color->green = cells[nearest].green;
  9404       color->blue = cells[nearest].blue;
  9405 
  9406       if (!temp_allocated)
  9407         status = XAllocColor (dpy, cmap, color);
  9408       else
  9409         {
  9410           *color = temp;
  9411           status = 1;
  9412         }
  9413 
  9414       if (status == 0 && !retry)
  9415         {
  9416           /* Our private cache of color cells is probably out of date.
  9417              Refresh it here, and try to allocate the nearest color
  9418              from the new colormap.  */
  9419 
  9420           retry = true;
  9421           xfree (dpyinfo->color_cells);
  9422 
  9423           ncolor_cells = dpyinfo->visual_info.colormap_size;
  9424 
  9425           dpyinfo->color_cells = xnmalloc (ncolor_cells,
  9426                                            sizeof *dpyinfo->color_cells);
  9427           dpyinfo->ncolor_cells = ncolor_cells;
  9428 
  9429           for (i = 0; i < ncolor_cells; ++i)
  9430             dpyinfo->color_cells[i].pixel = i;
  9431 
  9432           XQueryColors (dpy, dpyinfo->cmap,
  9433                         dpyinfo->color_cells, ncolor_cells);
  9434 
  9435           goto start;
  9436         }
  9437 
  9438       rc = status != 0;
  9439     }
  9440   else
  9441     {
  9442       /* If allocation succeeded, and the allocated pixel color is not
  9443          equal to a cached pixel color recorded earlier, there was a
  9444          change in the colormap, so clear the color cache.  */
  9445       struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
  9446       eassume (dpyinfo);
  9447 
  9448       if (dpyinfo->color_cells)
  9449         {
  9450           XColor *cached_color = &dpyinfo->color_cells[color->pixel];
  9451           if (cached_color->red != color->red
  9452               || cached_color->blue != color->blue
  9453               || cached_color->green != color->green)
  9454             {
  9455               xfree (dpyinfo->color_cells);
  9456               dpyinfo->color_cells = NULL;
  9457               dpyinfo->ncolor_cells = 0;
  9458             }
  9459         }
  9460     }
  9461 
  9462 #ifdef DEBUG_X_COLORS
  9463   if (rc)
  9464     register_color (color->pixel);
  9465 #endif /* DEBUG_X_COLORS */
  9466 
  9467   return rc;
  9468 }
  9469 
  9470 
  9471 /* Allocate the color COLOR->pixel on frame F, colormap CMAP, after
  9472    gamma correction.  If an exact match can't be allocated, try the
  9473    nearest color available.  Value is true if successful.  Set *COLOR
  9474    to the color allocated.  */
  9475 
  9476 bool
  9477 x_alloc_nearest_color (struct frame *f, Colormap cmap, XColor *color)
  9478 {
  9479   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  9480 
  9481   gamma_correct (f, color);
  9482 
  9483   if (dpyinfo->red_bits > 0)
  9484     {
  9485       color->pixel = x_make_truecolor_pixel (dpyinfo,
  9486                                              color->red,
  9487                                              color->green,
  9488                                              color->blue);
  9489       return true;
  9490     }
  9491 
  9492   return x_alloc_nearest_color_1 (FRAME_X_DISPLAY (f), cmap, color);
  9493 }
  9494 
  9495 
  9496 /* Allocate color PIXEL on frame F.  PIXEL must already be allocated.
  9497    It's necessary to do this instead of just using PIXEL directly to
  9498    get color reference counts right.  */
  9499 
  9500 unsigned long
  9501 x_copy_color (struct frame *f, unsigned long pixel)
  9502 {
  9503   XColor color;
  9504 
  9505   /* If display has an immutable color map, freeing colors is not
  9506      necessary and some servers don't allow it.  Since we won't free a
  9507      color once we've allocated it, we don't need to re-allocate it to
  9508      maintain the server's reference count.  */
  9509   if (!x_mutable_colormap (FRAME_X_VISUAL_INFO (f)))
  9510     return pixel;
  9511 
  9512   color.pixel = pixel;
  9513   block_input ();
  9514   /* The color could still be found in the color_cells array.  */
  9515   x_query_colors (f, &color, 1);
  9516   XAllocColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &color);
  9517   unblock_input ();
  9518 #ifdef DEBUG_X_COLORS
  9519   register_color (pixel);
  9520 #endif
  9521   return color.pixel;
  9522 }
  9523 
  9524 
  9525 /* Brightness beyond which a color won't have its highlight brightness
  9526    boosted.
  9527 
  9528    Nominally, highlight colors for `3d' faces are calculated by
  9529    brightening an object's color by a constant scale factor, but this
  9530    doesn't yield good results for dark colors, so for colors who's
  9531    brightness is less than this value (on a scale of 0-65535) have an
  9532    use an additional additive factor.
  9533 
  9534    The value here is set so that the default menu-bar/mode-line color
  9535    (grey75) will not have its highlights changed at all.  */
  9536 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 48000
  9537 
  9538 
  9539 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
  9540    or DELTA.  Try a color with RGB values multiplied by FACTOR first.
  9541    If this produces the same color as PIXEL, try a color where all RGB
  9542    values have DELTA added.  Return the allocated color in *PIXEL.
  9543    DISPLAY is the X display, CMAP is the colormap to operate on.
  9544    Value is non-zero if successful.  */
  9545 
  9546 static bool
  9547 x_alloc_lighter_color (struct frame *f, Display *display, Colormap cmap,
  9548                        unsigned long *pixel, double factor, int delta)
  9549 {
  9550   XColor color, new;
  9551   long bright;
  9552   bool success_p;
  9553 
  9554   /* Get RGB color values.  */
  9555   color.pixel = *pixel;
  9556   x_query_colors (f, &color, 1);
  9557 
  9558   /* Change RGB values by specified FACTOR.  Avoid overflow!  */
  9559   eassert (factor >= 0);
  9560   new.red = min (0xffff, factor * color.red);
  9561   new.green = min (0xffff, factor * color.green);
  9562   new.blue = min (0xffff, factor * color.blue);
  9563 
  9564   /* Calculate brightness of COLOR.  */
  9565   bright = (2 * color.red + 3 * color.green + color.blue) / 6;
  9566 
  9567   /* We only boost colors that are darker than
  9568      HIGHLIGHT_COLOR_DARK_BOOST_LIMIT.  */
  9569   if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
  9570     /* Make an additive adjustment to NEW, because it's dark enough so
  9571        that scaling by FACTOR alone isn't enough.  */
  9572     {
  9573       /* How far below the limit this color is (0 - 1, 1 being darker).  */
  9574       double dimness = 1 - (double) bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
  9575       /* The additive adjustment.  */
  9576       int min_delta = delta * dimness * factor / 2;
  9577 
  9578       if (factor < 1)
  9579         {
  9580           new.red =   max (0, new.red -   min_delta);
  9581           new.green = max (0, new.green - min_delta);
  9582           new.blue =  max (0, new.blue -  min_delta);
  9583         }
  9584       else
  9585         {
  9586           new.red =   min (0xffff, min_delta + new.red);
  9587           new.green = min (0xffff, min_delta + new.green);
  9588           new.blue =  min (0xffff, min_delta + new.blue);
  9589         }
  9590     }
  9591 
  9592   /* Try to allocate the color.  */
  9593   success_p = x_alloc_nearest_color (f, cmap, &new);
  9594   if (success_p)
  9595     {
  9596       if (new.pixel == *pixel)
  9597         {
  9598           /* If we end up with the same color as before, try adding
  9599              delta to the RGB values.  */
  9600           x_free_colors (f, &new.pixel, 1);
  9601 
  9602           new.red = min (0xffff, delta + color.red);
  9603           new.green = min (0xffff, delta + color.green);
  9604           new.blue = min (0xffff, delta + color.blue);
  9605           success_p = x_alloc_nearest_color (f, cmap, &new);
  9606         }
  9607       else
  9608         success_p = true;
  9609       *pixel = new.pixel;
  9610     }
  9611 
  9612   return success_p;
  9613 }
  9614 
  9615 
  9616 /* Set up the foreground color for drawing relief lines of glyph
  9617    string S.  RELIEF is a pointer to a struct relief containing the GC
  9618    with which lines will be drawn.  Use a color that is FACTOR or
  9619    DELTA lighter or darker than the relief's background which is found
  9620    in S->f->output_data.x->relief_background.  If such a color cannot
  9621    be allocated, use DEFAULT_PIXEL, instead.  */
  9622 
  9623 static void
  9624 x_setup_relief_color (struct frame *f, struct relief *relief, double factor,
  9625                       int delta, unsigned long default_pixel)
  9626 {
  9627   XGCValues xgcv;
  9628   struct x_output *di = f->output_data.x;
  9629   unsigned long mask = GCForeground | GCLineWidth | GCGraphicsExposures;
  9630   unsigned long pixel;
  9631   unsigned long background = di->relief_background;
  9632   Colormap cmap = FRAME_X_COLORMAP (f);
  9633   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  9634   Display *dpy = FRAME_X_DISPLAY (f);
  9635 
  9636   xgcv.graphics_exposures = False;
  9637   xgcv.line_width = 1;
  9638 
  9639   /* Free previously allocated color.  The color cell will be reused
  9640      when it has been freed as many times as it was allocated, so this
  9641      doesn't affect faces using the same colors.  */
  9642   if (relief->gc && relief->pixel != -1)
  9643     {
  9644       x_free_colors (f, &relief->pixel, 1);
  9645       relief->pixel = -1;
  9646     }
  9647 
  9648   /* Allocate new color.  */
  9649   xgcv.foreground = default_pixel;
  9650   pixel = background;
  9651   if (dpyinfo->n_planes != 1
  9652       && x_alloc_lighter_color (f, dpy, cmap, &pixel, factor, delta))
  9653     xgcv.foreground = relief->pixel = pixel;
  9654 
  9655   if (relief->gc == 0)
  9656     {
  9657       xgcv.stipple = dpyinfo->gray;
  9658       mask |= GCStipple;
  9659       relief->gc = XCreateGC (dpy, FRAME_X_DRAWABLE (f), mask, &xgcv);
  9660     }
  9661   else
  9662     XChangeGC (dpy, relief->gc, mask, &xgcv);
  9663 }
  9664 
  9665 
  9666 /* Set up colors for the relief lines around glyph string S.  */
  9667 
  9668 static void
  9669 x_setup_relief_colors (struct glyph_string *s)
  9670 {
  9671   struct x_output *di = s->f->output_data.x;
  9672   unsigned long color;
  9673 
  9674   if (s->face->use_box_color_for_shadows_p)
  9675     color = s->face->box_color;
  9676   else if (s->first_glyph->type == IMAGE_GLYPH
  9677            && s->img->pixmap
  9678            && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
  9679     color = IMAGE_BACKGROUND (s->img, s->f, 0);
  9680   else
  9681     {
  9682       XGCValues xgcv;
  9683 
  9684       /* Get the background color of the face.  */
  9685       XGetGCValues (FRAME_X_DISPLAY (s->f), s->gc, GCBackground, &xgcv);
  9686       color = xgcv.background;
  9687     }
  9688 
  9689   if (di->white_relief.gc == 0
  9690       || color != di->relief_background)
  9691     {
  9692       di->relief_background = color;
  9693       x_setup_relief_color (s->f, &di->white_relief, 1.2, 0x8000,
  9694                             WHITE_PIX_DEFAULT (s->f));
  9695       x_setup_relief_color (s->f, &di->black_relief, 0.6, 0x4000,
  9696                             BLACK_PIX_DEFAULT (s->f));
  9697     }
  9698 }
  9699 
  9700 #ifndef USE_CAIRO
  9701 static void
  9702 x_fill_triangle (struct frame *f, GC gc, XPoint point1,
  9703                  XPoint point2, XPoint point3)
  9704 {
  9705   XPoint abc[3];
  9706 
  9707   abc[0] = point1;
  9708   abc[1] = point2;
  9709   abc[2] = point3;
  9710 
  9711   XFillPolygon (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
  9712                 gc, abc, 3, Convex, CoordModeOrigin);
  9713 }
  9714 
  9715 static XPoint
  9716 x_make_point (int x, int y)
  9717 {
  9718   XPoint pt;
  9719 
  9720   pt.x = x;
  9721   pt.y = y;
  9722 
  9723   return pt;
  9724 }
  9725 
  9726 static bool
  9727 x_inside_rect_p (XRectangle *rects, int nrects, int x, int y)
  9728 {
  9729   int i;
  9730 
  9731   for (i = 0; i < nrects; ++i)
  9732     {
  9733       if (x >= rects[i].x && y >= rects[i].y
  9734           && x < rects[i].x + rects[i].width
  9735           && y < rects[i].y + rects[i].height)
  9736         return true;
  9737     }
  9738 
  9739   return false;
  9740 }
  9741 #endif
  9742 
  9743 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
  9744    TOP_Y, RIGHT_X, and BOTTOM_Y.  VWIDTH and HWIDTH are respectively
  9745    the thickness of the vertical relief (left and right) and
  9746    horizontal relief (top and bottom) to draw, it must be >= 0.
  9747    RAISED_P means draw a raised relief.  LEFT_P means draw a relief on
  9748    the left side of the rectangle.  RIGHT_P means draw a relief on the
  9749    right side of the rectangle.  CLIP_RECT is the clipping rectangle
  9750    to use when drawing.  */
  9751 
  9752 static void
  9753 x_draw_relief_rect (struct frame *f, int left_x, int top_y, int right_x,
  9754                     int bottom_y, int hwidth, int vwidth, bool raised_p,
  9755                     bool top_p, bool bot_p, bool left_p, bool right_p,
  9756                     XRectangle *clip_rect)
  9757 {
  9758 #ifdef USE_CAIRO
  9759   GC top_left_gc, bottom_right_gc;
  9760   int corners = 0;
  9761 
  9762   if (raised_p)
  9763     {
  9764       top_left_gc = f->output_data.x->white_relief.gc;
  9765       bottom_right_gc = f->output_data.x->black_relief.gc;
  9766     }
  9767   else
  9768     {
  9769       top_left_gc = f->output_data.x->black_relief.gc;
  9770       bottom_right_gc = f->output_data.x->white_relief.gc;
  9771     }
  9772 
  9773   x_set_clip_rectangles (f, top_left_gc, clip_rect, 1);
  9774   x_set_clip_rectangles (f, bottom_right_gc, clip_rect, 1);
  9775 
  9776   if (left_p)
  9777     {
  9778       x_fill_rectangle (f, top_left_gc, left_x, top_y,
  9779                         vwidth, bottom_y + 1 - top_y, false);
  9780       if (top_p)
  9781         corners |= 1 << CORNER_TOP_LEFT;
  9782       if (bot_p)
  9783         corners |= 1 << CORNER_BOTTOM_LEFT;
  9784     }
  9785   if (right_p)
  9786     {
  9787       x_fill_rectangle (f, bottom_right_gc, right_x + 1 - vwidth, top_y,
  9788                         vwidth, bottom_y + 1 - top_y, false);
  9789       if (top_p)
  9790         corners |= 1 << CORNER_TOP_RIGHT;
  9791       if (bot_p)
  9792         corners |= 1 << CORNER_BOTTOM_RIGHT;
  9793     }
  9794   if (top_p)
  9795     {
  9796       if (!right_p)
  9797         x_fill_rectangle (f, top_left_gc, left_x, top_y,
  9798                           right_x + 1 - left_x, hwidth, false);
  9799       else
  9800         x_fill_trapezoid_for_relief (f, top_left_gc, left_x, top_y,
  9801                                      right_x + 1 - left_x, hwidth, 1);
  9802     }
  9803   if (bot_p)
  9804     {
  9805       if (!left_p)
  9806         x_fill_rectangle (f, bottom_right_gc, left_x, bottom_y + 1 - hwidth,
  9807                           right_x + 1 - left_x, hwidth, false);
  9808       else
  9809         x_fill_trapezoid_for_relief (f, bottom_right_gc,
  9810                                      left_x, bottom_y + 1 - hwidth,
  9811                                      right_x + 1 - left_x, hwidth, 0);
  9812     }
  9813   if (left_p && vwidth > 1)
  9814     x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
  9815                       1, bottom_y + 1 - top_y, false);
  9816   if (top_p && hwidth > 1)
  9817     x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
  9818                       right_x + 1 - left_x, 1, false);
  9819   if (corners)
  9820     {
  9821       XSetBackground (FRAME_X_DISPLAY (f), top_left_gc,
  9822                       FRAME_BACKGROUND_PIXEL (f));
  9823       x_erase_corners_for_relief (f, top_left_gc, left_x, top_y,
  9824                                   right_x - left_x + 1, bottom_y - top_y + 1,
  9825                                   6, 1, corners);
  9826     }
  9827 
  9828   x_reset_clip_rectangles (f, top_left_gc);
  9829   x_reset_clip_rectangles (f, bottom_right_gc);
  9830 #else
  9831   GC gc, white_gc, black_gc, normal_gc;
  9832   Drawable drawable;
  9833   Display *dpy;
  9834 
  9835   /* This code is more complicated than it has to be, because of two
  9836      minor hacks to make the boxes look nicer: (i) if width > 1, draw
  9837      the outermost line using the black relief.  (ii) Omit the four
  9838      corner pixels.  */
  9839 
  9840   white_gc = f->output_data.x->white_relief.gc;
  9841   black_gc = f->output_data.x->black_relief.gc;
  9842   normal_gc = f->output_data.x->normal_gc;
  9843 
  9844   drawable = FRAME_X_DRAWABLE (f);
  9845   dpy = FRAME_X_DISPLAY (f);
  9846 
  9847   x_set_clip_rectangles (f, white_gc, clip_rect, 1);
  9848   x_set_clip_rectangles (f, black_gc, clip_rect, 1);
  9849 
  9850   if (raised_p)
  9851     gc = white_gc;
  9852   else
  9853     gc = black_gc;
  9854 
  9855   /* Draw lines.  */
  9856 
  9857   if (top_p)
  9858     x_fill_rectangle (f, gc, left_x, top_y,
  9859                       right_x - left_x + 1, hwidth,
  9860                       false);
  9861 
  9862   if (left_p)
  9863     x_fill_rectangle (f, gc, left_x, top_y, vwidth,
  9864                       bottom_y - top_y + 1, false);
  9865 
  9866   if (raised_p)
  9867     gc = black_gc;
  9868   else
  9869     gc = white_gc;
  9870 
  9871   if (bot_p)
  9872     x_fill_rectangle (f, gc, left_x, bottom_y - hwidth + 1,
  9873                       right_x - left_x + 1, hwidth, false);
  9874 
  9875   if (right_p)
  9876     x_fill_rectangle (f, gc, right_x - vwidth + 1, top_y,
  9877                       vwidth, bottom_y - top_y + 1, false);
  9878 
  9879   /* Draw corners.  */
  9880 
  9881   if (bot_p && left_p)
  9882     x_fill_triangle (f, raised_p ? white_gc : black_gc,
  9883                      x_make_point (left_x, bottom_y - hwidth),
  9884                      x_make_point (left_x + vwidth, bottom_y - hwidth),
  9885                      x_make_point (left_x, bottom_y));
  9886 
  9887   if (top_p && right_p)
  9888     x_fill_triangle (f, raised_p ? white_gc : black_gc,
  9889                      x_make_point (right_x - vwidth, top_y),
  9890                      x_make_point (right_x, top_y),
  9891                      x_make_point (right_x - vwidth, top_y + hwidth));
  9892 
  9893   /* Draw outer line.  */
  9894 
  9895   if (top_p && left_p && bot_p && right_p
  9896       && hwidth > 1 && vwidth > 1)
  9897     x_draw_rectangle (f, black_gc, left_x, top_y,
  9898                       right_x - left_x, bottom_y - top_y);
  9899   else
  9900     {
  9901       if (top_p && hwidth > 1)
  9902         XDrawLine (dpy, drawable, black_gc, left_x, top_y,
  9903                    right_x + 1, top_y);
  9904 
  9905       if (bot_p && hwidth > 1)
  9906         XDrawLine (dpy, drawable, black_gc, left_x, bottom_y,
  9907                    right_x + 1, bottom_y);
  9908 
  9909       if (left_p && vwidth > 1)
  9910         XDrawLine (dpy, drawable, black_gc, left_x, top_y,
  9911                    left_x, bottom_y + 1);
  9912 
  9913       if (right_p && vwidth > 1)
  9914         XDrawLine (dpy, drawable, black_gc, right_x, top_y,
  9915                    right_x, bottom_y + 1);
  9916     }
  9917 
  9918   /* Erase corners.  */
  9919 
  9920   if (hwidth > 1 && vwidth > 1)
  9921     {
  9922       if (left_p && top_p && x_inside_rect_p (clip_rect, 1,
  9923                                               left_x, top_y))
  9924         /* This should respect `alpha-background' since it's being
  9925            cleared with the background color of the frame.  */
  9926         x_clear_point (f, normal_gc, left_x, top_y, true);
  9927 
  9928       if (left_p && bot_p && x_inside_rect_p (clip_rect, 1,
  9929                                               left_x, bottom_y))
  9930         x_clear_point (f, normal_gc, left_x, bottom_y, true);
  9931 
  9932       if (right_p && top_p && x_inside_rect_p (clip_rect, 1,
  9933                                                right_x, top_y))
  9934         x_clear_point (f, normal_gc, right_x, top_y, true);
  9935 
  9936       if (right_p && bot_p && x_inside_rect_p (clip_rect, 1,
  9937                                                right_x, bottom_y))
  9938         x_clear_point (f, normal_gc, right_x, bottom_y, true);
  9939     }
  9940 
  9941   x_reset_clip_rectangles (f, white_gc);
  9942   x_reset_clip_rectangles (f, black_gc);
  9943 #endif
  9944 }
  9945 
  9946 
  9947 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
  9948    RIGHT_X, and BOTTOM_Y.  WIDTH is the thickness of the lines to
  9949    draw, it must be >= 0.  LEFT_P means draw a line on the
  9950    left side of the rectangle.  RIGHT_P means draw a line
  9951    on the right side of the rectangle.  CLIP_RECT is the clipping
  9952    rectangle to use when drawing.  */
  9953 
  9954 static void
  9955 x_draw_box_rect (struct glyph_string *s,
  9956                  int left_x, int top_y, int right_x, int bottom_y, int hwidth,
  9957                  int vwidth, bool left_p, bool right_p, XRectangle *clip_rect)
  9958 {
  9959   Display *display = FRAME_X_DISPLAY (s->f);
  9960   XGCValues xgcv;
  9961 
  9962   XGetGCValues (display, s->gc, GCForeground, &xgcv);
  9963   XSetForeground (display, s->gc, s->face->box_color);
  9964   x_set_clip_rectangles (s->f, s->gc, clip_rect, 1);
  9965 
  9966   /* Top.  */
  9967   x_fill_rectangle (s->f, s->gc,
  9968                     left_x, top_y, right_x - left_x + 1, hwidth,
  9969                     false);
  9970 
  9971   /* Left.  */
  9972   if (left_p)
  9973     x_fill_rectangle (s->f, s->gc,
  9974                       left_x, top_y, vwidth, bottom_y - top_y + 1,
  9975                       false);
  9976 
  9977   /* Bottom.  */
  9978   x_fill_rectangle (s->f, s->gc,
  9979                     left_x, bottom_y - hwidth + 1, right_x - left_x + 1, hwidth,
  9980                     false);
  9981 
  9982   /* Right.  */
  9983   if (right_p)
  9984     x_fill_rectangle (s->f, s->gc,
  9985                       right_x - vwidth + 1, top_y, vwidth, bottom_y - top_y + 1,
  9986                       false);
  9987 
  9988   XSetForeground (display, s->gc, xgcv.foreground);
  9989   x_reset_clip_rectangles (s->f, s->gc);
  9990 }
  9991 
  9992 
  9993 /* Draw a box around glyph string S.  */
  9994 
  9995 static void
  9996 x_draw_glyph_string_box (struct glyph_string *s)
  9997 {
  9998   int hwidth, vwidth, left_x, right_x, top_y, bottom_y, last_x;
  9999   bool raised_p, left_p, right_p;
 10000   struct glyph *last_glyph;
 10001   XRectangle clip_rect;
 10002 
 10003   last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
 10004             ? WINDOW_RIGHT_EDGE_X (s->w)
 10005             : window_box_right (s->w, s->area));
 10006 
 10007   /* The glyph that may have a right box line.  For static
 10008      compositions and images, the right-box flag is on the first glyph
 10009      of the glyph string; for other types it's on the last glyph.  */
 10010   if (s->cmp || s->img)
 10011     last_glyph = s->first_glyph;
 10012   else if (s->first_glyph->type == COMPOSITE_GLYPH
 10013            && s->first_glyph->u.cmp.automatic)
 10014     {
 10015       /* For automatic compositions, we need to look up the last glyph
 10016          in the composition.  */
 10017         struct glyph *end = s->row->glyphs[s->area] + s->row->used[s->area];
 10018         struct glyph *g = s->first_glyph;
 10019         for (last_glyph = g++;
 10020              g < end && g->u.cmp.automatic && g->u.cmp.id == s->cmp_id
 10021                && g->slice.cmp.to < s->cmp_to;
 10022              last_glyph = g++)
 10023           ;
 10024     }
 10025   else
 10026     last_glyph = s->first_glyph + s->nchars - 1;
 10027 
 10028   vwidth = eabs (s->face->box_vertical_line_width);
 10029   hwidth = eabs (s->face->box_horizontal_line_width);
 10030   raised_p = s->face->box == FACE_RAISED_BOX;
 10031   left_x = s->x;
 10032   right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
 10033              ? last_x - 1
 10034              : min (last_x, s->x + s->background_width) - 1);
 10035   top_y = s->y;
 10036   bottom_y = top_y + s->height - 1;
 10037 
 10038   left_p = (s->first_glyph->left_box_line_p
 10039             || (s->hl == DRAW_MOUSE_FACE
 10040                 && (s->prev == NULL
 10041                     || s->prev->hl != s->hl)));
 10042   right_p = (last_glyph->right_box_line_p
 10043              || (s->hl == DRAW_MOUSE_FACE
 10044                  && (s->next == NULL
 10045                      || s->next->hl != s->hl)));
 10046 
 10047   get_glyph_string_clip_rect (s, &clip_rect);
 10048 
 10049   if (s->face->box == FACE_SIMPLE_BOX)
 10050     x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, hwidth,
 10051                      vwidth, left_p, right_p, &clip_rect);
 10052   else
 10053     {
 10054       x_setup_relief_colors (s);
 10055       x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y, hwidth,
 10056                           vwidth, raised_p, true, true, left_p, right_p,
 10057                           &clip_rect);
 10058     }
 10059 }
 10060 
 10061 
 10062 #ifndef USE_CAIRO
 10063 
 10064 static void
 10065 x_composite_image (struct glyph_string *s, Pixmap dest,
 10066 #ifdef HAVE_XRENDER
 10067                    Picture destination,
 10068 #endif
 10069                    int srcX, int srcY, int dstX, int dstY,
 10070                    int width, int height)
 10071 {
 10072   Display *display;
 10073 #ifdef HAVE_XRENDER
 10074   XRenderPictFormat *default_format;
 10075   XRenderPictureAttributes attr UNINIT;
 10076 #endif
 10077 
 10078   display = FRAME_X_DISPLAY (s->f);
 10079 
 10080 #ifdef HAVE_XRENDER
 10081   if (s->img->picture && FRAME_X_PICTURE_FORMAT (s->f))
 10082     {
 10083       if (destination == None)
 10084         {
 10085           /* The destination picture was not specified.  This means we
 10086              have to create a picture representing the */
 10087           default_format = FRAME_X_PICTURE_FORMAT (s->f);
 10088           destination = XRenderCreatePicture (display, dest,
 10089                                               default_format, 0, &attr);
 10090 
 10091           XRenderComposite (display, (s->img->mask_picture
 10092                                       ? PictOpOver : PictOpSrc),
 10093                             s->img->picture, s->img->mask_picture,
 10094                             destination, srcX, srcY, srcX, srcY,
 10095                             dstX, dstY, width, height);
 10096 
 10097           XRenderFreePicture (display, destination);
 10098         }
 10099       else
 10100         XRenderComposite (display, (s->img->mask_picture
 10101                                     ? PictOpOver : PictOpSrc),
 10102                           s->img->picture, s->img->mask_picture,
 10103                           destination, srcX, srcY, srcX, srcY,
 10104                           dstX, dstY, width, height);
 10105 
 10106       return;
 10107     }
 10108 #endif
 10109 
 10110   XCopyArea (display, s->img->pixmap,
 10111              dest, s->gc,
 10112              srcX, srcY,
 10113              width, height, dstX, dstY);
 10114 }
 10115 
 10116 #endif  /* !USE_CAIRO */
 10117 
 10118 
 10119 /* Draw foreground of image glyph string S.  */
 10120 
 10121 static void
 10122 x_draw_image_foreground (struct glyph_string *s)
 10123 {
 10124   int x = s->x;
 10125   int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
 10126 
 10127   /* If first glyph of S has a left box line, start drawing it to the
 10128      right of that line.  */
 10129   if (s->face->box != FACE_NO_BOX
 10130       && s->first_glyph->left_box_line_p
 10131       && s->slice.x == 0)
 10132     x += max (s->face->box_vertical_line_width, 0);
 10133 
 10134   /* If there is a margin around the image, adjust x- and y-position
 10135      by that margin.  */
 10136   if (s->slice.x == 0)
 10137     x += s->img->hmargin;
 10138   if (s->slice.y == 0)
 10139     y += s->img->vmargin;
 10140 
 10141 #ifdef USE_CAIRO
 10142   if (s->img->cr_data)
 10143     {
 10144       x_set_glyph_string_clipping (s);
 10145       x_cr_draw_image (s->f, s->gc, s->img->cr_data,
 10146                        s->slice.x, s->slice.y, s->slice.width, s->slice.height,
 10147                        x, y, true);
 10148       if (!s->img->mask)
 10149         {
 10150           /* When the image has a mask, we can expect that at
 10151              least part of a mouse highlight or a block cursor will
 10152              be visible.  If the image doesn't have a mask, make
 10153              a block cursor visible by drawing a rectangle around
 10154              the image.  I believe it's looking better if we do
 10155              nothing here for mouse-face.  */
 10156           if (s->hl == DRAW_CURSOR)
 10157             {
 10158               int relief = eabs (s->img->relief);
 10159               x_draw_rectangle (s->f, s->gc, x - relief, y - relief,
 10160                                 s->slice.width + relief*2 - 1,
 10161                                 s->slice.height + relief*2 - 1);
 10162             }
 10163         }
 10164     }
 10165 #else  /* ! USE_CAIRO */
 10166   if (s->img->pixmap)
 10167     {
 10168       if (s->img->mask)
 10169         {
 10170           /* We can't set both a clip mask and use XSetClipRectangles
 10171              because the latter also sets a clip mask.  We also can't
 10172              trust on the shape extension to be available
 10173              (XShapeCombineRegion).  So, compute the rectangle to draw
 10174              manually.  */
 10175           /* FIXME: Do we need to do this when using XRender compositing?  */
 10176           unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
 10177                                 | GCFunction);
 10178           XGCValues xgcv;
 10179           XRectangle clip_rect, image_rect, r;
 10180 
 10181           xgcv.clip_mask = s->img->mask;
 10182           xgcv.clip_x_origin = x;
 10183           xgcv.clip_y_origin = y;
 10184           xgcv.function = GXcopy;
 10185           XChangeGC (FRAME_X_DISPLAY (s->f), s->gc, mask, &xgcv);
 10186 
 10187           get_glyph_string_clip_rect (s, &clip_rect);
 10188           image_rect.x = x;
 10189           image_rect.y = y;
 10190           image_rect.width = s->slice.width;
 10191           image_rect.height = s->slice.height;
 10192           if (gui_intersect_rectangles (&clip_rect, &image_rect, &r))
 10193             x_composite_image (s, FRAME_X_DRAWABLE (s->f),
 10194 #ifdef HAVE_XRENDER
 10195                                FRAME_X_PICTURE (s->f),
 10196 #endif
 10197                                s->slice.x + r.x - x, s->slice.y + r.y - y,
 10198                                r.x, r.y, r.width, r.height);
 10199         }
 10200       else
 10201         {
 10202           XRectangle clip_rect, image_rect, r;
 10203 
 10204           get_glyph_string_clip_rect (s, &clip_rect);
 10205           image_rect.x = x;
 10206           image_rect.y = y;
 10207           image_rect.width = s->slice.width;
 10208           image_rect.height = s->slice.height;
 10209           if (gui_intersect_rectangles (&clip_rect, &image_rect, &r))
 10210             x_composite_image (s, FRAME_X_DRAWABLE (s->f),
 10211 #ifdef HAVE_XRENDER
 10212                                FRAME_X_PICTURE (s->f),
 10213 #endif
 10214                                s->slice.x + r.x - x,
 10215                                s->slice.y + r.y - y,
 10216                                r.x, r.y, r.width, r.height);
 10217 
 10218           /* When the image has a mask, we can expect that at
 10219              least part of a mouse highlight or a block cursor will
 10220              be visible.  If the image doesn't have a mask, make
 10221              a block cursor visible by drawing a rectangle around
 10222              the image.  I believe it's looking better if we do
 10223              nothing here for mouse-face.  */
 10224           if (s->hl == DRAW_CURSOR)
 10225             {
 10226               int relief = eabs (s->img->relief);
 10227               x_draw_rectangle (s->f, s->gc,
 10228                               x - relief, y - relief,
 10229                               s->slice.width + relief*2 - 1,
 10230                               s->slice.height + relief*2 - 1);
 10231             }
 10232         }
 10233     }
 10234 #endif  /* ! USE_CAIRO */
 10235   else
 10236     /* Draw a rectangle if image could not be loaded.  */
 10237     x_draw_rectangle (s->f, s->gc, x, y,
 10238                     s->slice.width - 1, s->slice.height - 1);
 10239 }
 10240 
 10241 
 10242 /* Draw a relief around the image glyph string S.  */
 10243 
 10244 static void
 10245 x_draw_image_relief (struct glyph_string *s)
 10246 {
 10247   int x1, y1, thick;
 10248   bool raised_p, top_p, bot_p, left_p, right_p;
 10249   int extra_x, extra_y;
 10250   XRectangle r;
 10251   int x = s->x;
 10252   int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
 10253 
 10254   /* If first glyph of S has a left box line, start drawing it to the
 10255      right of that line.  */
 10256   if (s->face->box != FACE_NO_BOX
 10257       && s->first_glyph->left_box_line_p
 10258       && s->slice.x == 0)
 10259     x += max (s->face->box_vertical_line_width, 0);
 10260 
 10261   /* If there is a margin around the image, adjust x- and y-position
 10262      by that margin.  */
 10263   if (s->slice.x == 0)
 10264     x += s->img->hmargin;
 10265   if (s->slice.y == 0)
 10266     y += s->img->vmargin;
 10267 
 10268   if (s->hl == DRAW_IMAGE_SUNKEN
 10269       || s->hl == DRAW_IMAGE_RAISED)
 10270     {
 10271       if (s->face->id == TAB_BAR_FACE_ID)
 10272         thick = (tab_bar_button_relief < 0
 10273                  ? DEFAULT_TAB_BAR_BUTTON_RELIEF
 10274                  : min (tab_bar_button_relief, 1000000));
 10275       else
 10276         thick = (tool_bar_button_relief < 0
 10277                  ? DEFAULT_TOOL_BAR_BUTTON_RELIEF
 10278                  : min (tool_bar_button_relief, 1000000));
 10279       raised_p = s->hl == DRAW_IMAGE_RAISED;
 10280     }
 10281   else
 10282     {
 10283       thick = eabs (s->img->relief);
 10284       raised_p = s->img->relief > 0;
 10285     }
 10286 
 10287   x1 = x + s->slice.width - 1;
 10288   y1 = y + s->slice.height - 1;
 10289 
 10290   extra_x = extra_y = 0;
 10291   if (s->face->id == TAB_BAR_FACE_ID)
 10292     {
 10293       if (CONSP (Vtab_bar_button_margin)
 10294           && FIXNUMP (XCAR (Vtab_bar_button_margin))
 10295           && FIXNUMP (XCDR (Vtab_bar_button_margin)))
 10296         {
 10297           extra_x = XFIXNUM (XCAR (Vtab_bar_button_margin)) - thick;
 10298           extra_y = XFIXNUM (XCDR (Vtab_bar_button_margin)) - thick;
 10299         }
 10300       else if (FIXNUMP (Vtab_bar_button_margin))
 10301         extra_x = extra_y = XFIXNUM (Vtab_bar_button_margin) - thick;
 10302     }
 10303 
 10304   if (s->face->id == TOOL_BAR_FACE_ID)
 10305     {
 10306       if (CONSP (Vtool_bar_button_margin)
 10307           && FIXNUMP (XCAR (Vtool_bar_button_margin))
 10308           && FIXNUMP (XCDR (Vtool_bar_button_margin)))
 10309         {
 10310           extra_x = XFIXNUM (XCAR (Vtool_bar_button_margin));
 10311           extra_y = XFIXNUM (XCDR (Vtool_bar_button_margin));
 10312         }
 10313       else if (FIXNUMP (Vtool_bar_button_margin))
 10314         extra_x = extra_y = XFIXNUM (Vtool_bar_button_margin);
 10315     }
 10316 
 10317   top_p = bot_p = left_p = right_p = false;
 10318 
 10319   if (s->slice.x == 0)
 10320     x -= thick + extra_x, left_p = true;
 10321   if (s->slice.y == 0)
 10322     y -= thick + extra_y, top_p = true;
 10323   if (s->slice.x + s->slice.width == s->img->width)
 10324     x1 += thick + extra_x, right_p = true;
 10325   if (s->slice.y + s->slice.height == s->img->height)
 10326     y1 += thick + extra_y, bot_p = true;
 10327 
 10328   x_setup_relief_colors (s);
 10329   get_glyph_string_clip_rect (s, &r);
 10330   x_draw_relief_rect (s->f, x, y, x1, y1, thick, thick, raised_p,
 10331                       top_p, bot_p, left_p, right_p, &r);
 10332 }
 10333 
 10334 
 10335 #ifndef USE_CAIRO
 10336 /* Draw the foreground of image glyph string S to PIXMAP.  */
 10337 
 10338 static void
 10339 x_draw_image_foreground_1 (struct glyph_string *s, Pixmap pixmap)
 10340 {
 10341   int x = 0;
 10342   int y = s->ybase - s->y - image_ascent (s->img, s->face, &s->slice);
 10343 
 10344   /* If first glyph of S has a left box line, start drawing it to the
 10345      right of that line.  */
 10346   if (s->face->box != FACE_NO_BOX
 10347       && s->first_glyph->left_box_line_p
 10348       && s->slice.x == 0)
 10349     x += max (s->face->box_vertical_line_width, 0);
 10350 
 10351   /* If there is a margin around the image, adjust x- and y-position
 10352      by that margin.  */
 10353   if (s->slice.x == 0)
 10354     x += s->img->hmargin;
 10355   if (s->slice.y == 0)
 10356     y += s->img->vmargin;
 10357 
 10358   if (s->img->pixmap)
 10359     {
 10360       Display *display = FRAME_X_DISPLAY (s->f);
 10361 
 10362       if (s->img->mask)
 10363         {
 10364           /* We can't set both a clip mask and use XSetClipRectangles
 10365              because the latter also sets a clip mask.  We also can't
 10366              trust on the shape extension to be available
 10367              (XShapeCombineRegion).  So, compute the rectangle to draw
 10368              manually.  */
 10369           /* FIXME: Do we need to do this when using XRender compositing?  */
 10370           unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
 10371                                 | GCFunction);
 10372           XGCValues xgcv;
 10373 
 10374           xgcv.clip_mask = s->img->mask;
 10375           xgcv.clip_x_origin = x - s->slice.x;
 10376           xgcv.clip_y_origin = y - s->slice.y;
 10377           xgcv.function = GXcopy;
 10378           XChangeGC (display, s->gc, mask, &xgcv);
 10379 
 10380           x_composite_image (s, pixmap,
 10381 #ifdef HAVE_XRENDER
 10382                              None,
 10383 #endif
 10384                              s->slice.x, s->slice.y, x, y,
 10385                              s->slice.width, s->slice.height);
 10386           XSetClipMask (display, s->gc, None);
 10387         }
 10388       else
 10389         {
 10390           XCopyArea (display, s->img->pixmap, pixmap, s->gc,
 10391                      s->slice.x, s->slice.y,
 10392                      s->slice.width, s->slice.height, x, y);
 10393 
 10394           /* When the image has a mask, we can expect that at
 10395              least part of a mouse highlight or a block cursor will
 10396              be visible.  If the image doesn't have a mask, make
 10397              a block cursor visible by drawing a rectangle around
 10398              the image.  I believe it's looking better if we do
 10399              nothing here for mouse-face.  */
 10400           if (s->hl == DRAW_CURSOR)
 10401             {
 10402               int r = eabs (s->img->relief);
 10403               x_draw_rectangle (s->f, s->gc, x - r, y - r,
 10404                               s->slice.width + r*2 - 1,
 10405                               s->slice.height + r*2 - 1);
 10406             }
 10407         }
 10408     }
 10409   else
 10410     /* Draw a rectangle if image could not be loaded.  */
 10411     x_draw_rectangle (s->f, s->gc, x, y,
 10412                     s->slice.width - 1, s->slice.height - 1);
 10413 }
 10414 #endif  /* ! USE_CAIRO */
 10415 
 10416 
 10417 /* Draw part of the background of glyph string S.  X, Y, W, and H
 10418    give the rectangle to draw.  */
 10419 
 10420 static void
 10421 x_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h)
 10422 {
 10423   if (s->stippled_p)
 10424     {
 10425       Display *display = FRAME_X_DISPLAY (s->f);
 10426 
 10427       /* Fill background with a stipple pattern.  */
 10428       XSetFillStyle (display, s->gc, FillOpaqueStippled);
 10429       x_fill_rectangle (s->f, s->gc, x, y, w, h, true);
 10430       XSetFillStyle (display, s->gc, FillSolid);
 10431     }
 10432   else
 10433     x_clear_glyph_string_rect (s, x, y, w, h);
 10434 }
 10435 
 10436 
 10437 /* Draw image glyph string S.
 10438 
 10439             s->y
 10440    s->x      +-------------------------
 10441              |   s->face->box
 10442              |
 10443              |     +-------------------------
 10444              |     |  s->img->margin
 10445              |     |
 10446              |     |       +-------------------
 10447              |     |       |  the image
 10448 
 10449  */
 10450 
 10451 static void
 10452 x_draw_image_glyph_string (struct glyph_string *s)
 10453 {
 10454   int box_line_hwidth = max (s->face->box_vertical_line_width, 0);
 10455   int box_line_vwidth = max (s->face->box_horizontal_line_width, 0);
 10456   int height;
 10457 #ifndef USE_CAIRO
 10458   Display *display = FRAME_X_DISPLAY (s->f);
 10459   Pixmap pixmap = None;
 10460 #endif
 10461 
 10462   height = s->height;
 10463   if (s->slice.y == 0)
 10464     height -= box_line_vwidth;
 10465   if (s->slice.y + s->slice.height >= s->img->height)
 10466     height -= box_line_vwidth;
 10467 
 10468   /* Fill background with face under the image.  Do it only if row is
 10469      taller than image or if image has a clip mask to reduce
 10470      flickering.  */
 10471   s->stippled_p = s->face->stipple != 0;
 10472   if (height > s->slice.height
 10473       || s->img->hmargin
 10474       || s->img->vmargin
 10475       || s->img->mask
 10476       || s->img->pixmap == 0
 10477       || s->width != s->background_width)
 10478     {
 10479       if (s->stippled_p)
 10480         s->row->stipple_p = true;
 10481 
 10482 #ifndef USE_CAIRO
 10483       if (s->img->mask)
 10484         {
 10485           /* Create a pixmap as large as the glyph string.  Fill it
 10486              with the background color.  Copy the image to it, using
 10487              its mask.  Copy the temporary pixmap to the display.  */
 10488           int depth = FRAME_DISPLAY_INFO (s->f)->n_planes;
 10489 
 10490           /* Create a pixmap as large as the glyph string.  */
 10491           pixmap = XCreatePixmap (display, FRAME_X_DRAWABLE (s->f),
 10492                                   s->background_width,
 10493                                   s->height, depth);
 10494 
 10495           /* Don't clip in the following because we're working on the
 10496              pixmap.  */
 10497           XSetClipMask (display, s->gc, None);
 10498 
 10499           /* Fill the pixmap with the background color/stipple.  */
 10500           if (s->stippled_p)
 10501             {
 10502               /* Fill background with a stipple pattern.  */
 10503               XSetFillStyle (display, s->gc, FillOpaqueStippled);
 10504               XSetTSOrigin (display, s->gc, - s->x, - s->y);
 10505               XFillRectangle (display, pixmap, s->gc,
 10506                               0, 0, s->background_width, s->height);
 10507               XSetFillStyle (display, s->gc, FillSolid);
 10508               XSetTSOrigin (display, s->gc, 0, 0);
 10509             }
 10510           else
 10511             {
 10512               XGCValues xgcv;
 10513 #if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2))
 10514               if (FRAME_DISPLAY_INFO (s->f)->alpha_bits
 10515                   && s->f->alpha_background != 1.0
 10516                   && FRAME_CHECK_XR_VERSION (s->f, 0, 2)
 10517                   && FRAME_X_PICTURE_FORMAT (s->f))
 10518                 {
 10519                   XRenderColor xc;
 10520                   XRenderPictureAttributes attrs;
 10521                   Picture pict;
 10522                   memset (&attrs, 0, sizeof attrs);
 10523 
 10524                   pict = XRenderCreatePicture (display, pixmap,
 10525                                                FRAME_X_PICTURE_FORMAT (s->f),
 10526                                                0, &attrs);
 10527                   x_xrender_color_from_gc_background (s->f, s->gc, &xc, true);
 10528                   XRenderFillRectangle (FRAME_X_DISPLAY (s->f), PictOpSrc, pict,
 10529                                         &xc, 0, 0, s->background_width, s->height);
 10530                   XRenderFreePicture (display, pict);
 10531                 }
 10532               else
 10533 #endif
 10534                 {
 10535                   XGetGCValues (display, s->gc, GCForeground | GCBackground,
 10536                                 &xgcv);
 10537                   XSetForeground (display, s->gc, xgcv.background);
 10538                   XFillRectangle (display, pixmap, s->gc,
 10539                                   0, 0, s->background_width, s->height);
 10540                   XSetForeground (display, s->gc, xgcv.foreground);
 10541                 }
 10542             }
 10543         }
 10544       else
 10545 #endif  /* ! USE_CAIRO */
 10546         {
 10547           int x = s->x;
 10548           int y = s->y;
 10549           int width = s->background_width;
 10550 
 10551           if (s->first_glyph->left_box_line_p
 10552               && s->slice.x == 0)
 10553             {
 10554               x += box_line_hwidth;
 10555               width -= box_line_hwidth;
 10556             }
 10557 
 10558           if (s->slice.y == 0)
 10559             y += box_line_vwidth;
 10560 
 10561           x_draw_glyph_string_bg_rect (s, x, y, width, height);
 10562         }
 10563 
 10564       s->background_filled_p = true;
 10565     }
 10566 
 10567   /* Draw the foreground.  */
 10568 #ifndef USE_CAIRO
 10569   if (pixmap != None)
 10570     {
 10571       x_draw_image_foreground_1 (s, pixmap);
 10572       x_set_glyph_string_clipping (s);
 10573       XCopyArea (display, pixmap, FRAME_X_DRAWABLE (s->f), s->gc,
 10574                  0, 0, s->background_width, s->height, s->x, s->y);
 10575       XFreePixmap (display, pixmap);
 10576     }
 10577   else
 10578 #endif  /* ! USE_CAIRO */
 10579     x_draw_image_foreground (s);
 10580 
 10581   /* If we must draw a relief around the image, do it.  */
 10582   if (s->img->relief
 10583       || s->hl == DRAW_IMAGE_RAISED
 10584       || s->hl == DRAW_IMAGE_SUNKEN)
 10585     x_draw_image_relief (s);
 10586 }
 10587 
 10588 
 10589 /* Draw stretch glyph string S.  */
 10590 
 10591 static void
 10592 x_draw_stretch_glyph_string (struct glyph_string *s)
 10593 {
 10594   eassert (s->first_glyph->type == STRETCH_GLYPH);
 10595 
 10596   if (s->hl == DRAW_CURSOR
 10597       && !x_stretch_cursor_p)
 10598     {
 10599       /* If `x-stretch-cursor' is nil, don't draw a block cursor as
 10600          wide as the stretch glyph.  */
 10601       int width, background_width = s->background_width;
 10602       int x = s->x;
 10603 
 10604       if (!s->row->reversed_p)
 10605         {
 10606           int left_x = window_box_left_offset (s->w, TEXT_AREA);
 10607 
 10608           if (x < left_x)
 10609             {
 10610               background_width -= left_x - x;
 10611               x = left_x;
 10612             }
 10613         }
 10614       else
 10615         {
 10616           /* In R2L rows, draw the cursor on the right edge of the
 10617              stretch glyph.  */
 10618           int right_x = window_box_right (s->w, TEXT_AREA);
 10619 
 10620           if (x + background_width > right_x)
 10621             background_width -= x - right_x;
 10622           x += background_width;
 10623         }
 10624       width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
 10625       if (s->row->reversed_p)
 10626         x -= width;
 10627 
 10628       /* Draw cursor.  */
 10629       x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
 10630 
 10631       /* Clear rest using the GC of the original non-cursor face.  */
 10632       if (width < background_width)
 10633         {
 10634           int y = s->y;
 10635           int w = background_width - width, h = s->height;
 10636           Display *display = FRAME_X_DISPLAY (s->f);
 10637           XRectangle r;
 10638           GC gc;
 10639 
 10640           if (!s->row->reversed_p)
 10641             x += width;
 10642           else
 10643             x = s->x;
 10644           if (s->row->mouse_face_p
 10645               && cursor_in_mouse_face_p (s->w))
 10646             {
 10647               x_set_mouse_face_gc (s);
 10648               gc = s->gc;
 10649             }
 10650           else
 10651             gc = s->face->gc;
 10652 
 10653           get_glyph_string_clip_rect (s, &r);
 10654           x_set_clip_rectangles (s->f, gc, &r, 1);
 10655 
 10656           if (s->face->stipple)
 10657             {
 10658               /* Fill background with a stipple pattern.  */
 10659               XSetFillStyle (display, gc, FillOpaqueStippled);
 10660               x_fill_rectangle (s->f, gc, x, y, w, h, true);
 10661               XSetFillStyle (display, gc, FillSolid);
 10662 
 10663               s->row->stipple_p = true;
 10664             }
 10665           else
 10666             {
 10667               XGCValues xgcv;
 10668               XGetGCValues (display, gc, GCForeground | GCBackground, &xgcv);
 10669               XSetForeground (display, gc, xgcv.background);
 10670               x_fill_rectangle (s->f, gc, x, y, w, h, true);
 10671               XSetForeground (display, gc, xgcv.foreground);
 10672             }
 10673 
 10674           x_reset_clip_rectangles (s->f, gc);
 10675         }
 10676     }
 10677   else if (!s->background_filled_p)
 10678     {
 10679       int background_width = s->background_width;
 10680       int x = s->x, text_left_x = window_box_left (s->w, TEXT_AREA);
 10681 
 10682       /* Don't draw into left fringe or scrollbar area except for
 10683          header line and mode line.  */
 10684       if (s->area == TEXT_AREA
 10685           && x < text_left_x && !s->row->mode_line_p)
 10686         {
 10687           background_width -= text_left_x - x;
 10688           x = text_left_x;
 10689         }
 10690 
 10691       if (!s->row->stipple_p)
 10692         s->row->stipple_p = s->stippled_p;
 10693 
 10694       if (background_width > 0)
 10695         x_draw_glyph_string_bg_rect (s, x, s->y,
 10696                                      background_width, s->height);
 10697     }
 10698 
 10699   s->background_filled_p = true;
 10700 }
 10701 
 10702 static void
 10703 x_get_scale_factor (Display *disp, int *scale_x, int *scale_y)
 10704 {
 10705   const int base_res = 96;
 10706   struct x_display_info * dpyinfo = x_display_info_for_display (disp);
 10707 
 10708   *scale_x = *scale_y = 1;
 10709 
 10710   if (dpyinfo)
 10711     {
 10712       if (dpyinfo->resx > base_res)
 10713         *scale_x = floor (dpyinfo->resx / base_res);
 10714       if (dpyinfo->resy > base_res)
 10715         *scale_y = floor (dpyinfo->resy / base_res);
 10716     }
 10717 }
 10718 
 10719 /*
 10720    Draw a wavy line under S. The wave fills wave_height pixels from y0.
 10721 
 10722                     x0         wave_length = 2
 10723                                  --
 10724                 y0   *   *   *   *   *
 10725                      |* * * * * * * * *
 10726     wave_height = 3  | *   *   *   *
 10727 
 10728 */
 10729 static void
 10730 x_draw_underwave (struct glyph_string *s, int decoration_width)
 10731 {
 10732   Display *display = FRAME_X_DISPLAY (s->f);
 10733 
 10734   /* Adjust for scale/HiDPI.  */
 10735   int scale_x, scale_y;
 10736 
 10737   x_get_scale_factor (display, &scale_x, &scale_y);
 10738 
 10739   int wave_height = 3 * scale_y, wave_length = 2 * scale_x;
 10740 
 10741 #ifdef USE_CAIRO
 10742   x_draw_horizontal_wave (s->f, s->gc, s->x, s->ybase - wave_height + 3,
 10743                           decoration_width, wave_height, wave_length);
 10744 #else  /* not USE_CAIRO */
 10745   int dx, dy, x0, y0, width, x1, y1, x2, y2, xmax, thickness = scale_y;;
 10746   bool odd;
 10747   XRectangle wave_clip, string_clip, final_clip;
 10748 
 10749   dx = wave_length;
 10750   dy = wave_height - 1;
 10751   x0 = s->x;
 10752   y0 = s->ybase + wave_height / 2 - scale_y;
 10753   width = decoration_width;
 10754   xmax = x0 + width;
 10755 
 10756   /* Find and set clipping rectangle */
 10757 
 10758   wave_clip.x = x0;
 10759   wave_clip.y = y0;
 10760   wave_clip.width = width;
 10761   wave_clip.height = wave_height;
 10762   get_glyph_string_clip_rect (s, &string_clip);
 10763 
 10764   if (!gui_intersect_rectangles (&wave_clip, &string_clip, &final_clip))
 10765     return;
 10766 
 10767   XSetClipRectangles (display, s->gc, 0, 0, &final_clip, 1, Unsorted);
 10768 
 10769   /* Draw the waves */
 10770 
 10771   x1 = x0 - (x0 % dx);
 10772   x2 = x1 + dx;
 10773   odd = (x1 / dx) & 1;
 10774   y1 = y2 = y0;
 10775 
 10776   if (odd)
 10777     y1 += dy;
 10778   else
 10779     y2 += dy;
 10780 
 10781   if (INT_MAX - dx < xmax)
 10782     emacs_abort ();
 10783 
 10784   while (x1 <= xmax)
 10785     {
 10786       XSetLineAttributes (display, s->gc, thickness, LineSolid, CapButt,
 10787                           JoinRound);
 10788       XDrawLine (display, FRAME_X_DRAWABLE (s->f), s->gc, x1, y1, x2, y2);
 10789       x1  = x2, y1 = y2;
 10790       x2 += dx, y2 = y0 + odd*dy;
 10791       odd = !odd;
 10792     }
 10793 
 10794   /* Restore previous clipping rectangle(s) */
 10795   XSetClipRectangles (display, s->gc, 0, 0, s->clip, s->num_clips, Unsorted);
 10796 #endif  /* not USE_CAIRO */
 10797 }
 10798 
 10799 
 10800 /* Draw glyph string S.  */
 10801 
 10802 static void
 10803 x_draw_glyph_string (struct glyph_string *s)
 10804 {
 10805   bool relief_drawn_p = false;
 10806 
 10807   /* If S draws into the background of its successors, draw the
 10808      background of the successors first so that S can draw into it.
 10809      This makes S->next use XDrawString instead of XDrawImageString.  */
 10810   if (s->next && s->right_overhang && !s->for_overlaps)
 10811     {
 10812       int width;
 10813       struct glyph_string *next;
 10814 
 10815       for (width = 0, next = s->next;
 10816            next && width < s->right_overhang;
 10817            width += next->width, next = next->next)
 10818         if (next->first_glyph->type != IMAGE_GLYPH)
 10819           {
 10820             x_set_glyph_string_gc (next);
 10821             x_set_glyph_string_clipping (next);
 10822             if (next->first_glyph->type == STRETCH_GLYPH)
 10823               x_draw_stretch_glyph_string (next);
 10824             else
 10825               x_draw_glyph_string_background (next, true);
 10826             next->num_clips = 0;
 10827           }
 10828     }
 10829 
 10830   /* Set up S->gc, set clipping and draw S.  */
 10831   x_set_glyph_string_gc (s);
 10832 
 10833   /* Draw relief (if any) in advance for char/composition so that the
 10834      glyph string can be drawn over it.  */
 10835   if (!s->for_overlaps
 10836       && s->face->box != FACE_NO_BOX
 10837       && (s->first_glyph->type == CHAR_GLYPH
 10838           || s->first_glyph->type == COMPOSITE_GLYPH))
 10839 
 10840     {
 10841       x_set_glyph_string_clipping (s);
 10842       x_draw_glyph_string_background (s, true);
 10843       x_draw_glyph_string_box (s);
 10844       x_set_glyph_string_clipping (s);
 10845       relief_drawn_p = true;
 10846     }
 10847   else if (!s->clip_head /* draw_glyphs didn't specify a clip mask. */
 10848            && !s->clip_tail
 10849            && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
 10850                || (s->next && s->next->hl != s->hl && s->right_overhang)))
 10851     /* We must clip just this glyph.  left_overhang part has already
 10852        drawn when s->prev was drawn, and right_overhang part will be
 10853        drawn later when s->next is drawn. */
 10854     x_set_glyph_string_clipping_exactly (s, s);
 10855   else
 10856     x_set_glyph_string_clipping (s);
 10857 
 10858   switch (s->first_glyph->type)
 10859     {
 10860     case IMAGE_GLYPH:
 10861       x_draw_image_glyph_string (s);
 10862       break;
 10863 
 10864     case XWIDGET_GLYPH:
 10865       x_draw_xwidget_glyph_string (s);
 10866       break;
 10867 
 10868     case STRETCH_GLYPH:
 10869       x_draw_stretch_glyph_string (s);
 10870       break;
 10871 
 10872     case CHAR_GLYPH:
 10873       if (s->for_overlaps)
 10874         s->background_filled_p = true;
 10875       else
 10876         x_draw_glyph_string_background (s, false);
 10877       x_draw_glyph_string_foreground (s);
 10878       break;
 10879 
 10880     case COMPOSITE_GLYPH:
 10881       if (s->for_overlaps || (s->cmp_from > 0
 10882                               && ! s->first_glyph->u.cmp.automatic))
 10883         s->background_filled_p = true;
 10884       else
 10885         x_draw_glyph_string_background (s, true);
 10886       x_draw_composite_glyph_string_foreground (s);
 10887       break;
 10888 
 10889     case GLYPHLESS_GLYPH:
 10890       if (s->for_overlaps)
 10891         s->background_filled_p = true;
 10892       else
 10893         x_draw_glyph_string_background (s, true);
 10894       x_draw_glyphless_glyph_string_foreground (s);
 10895       break;
 10896 
 10897     default:
 10898       emacs_abort ();
 10899     }
 10900 
 10901   if (!s->for_overlaps)
 10902     {
 10903       int area_x, area_y, area_width, area_height;
 10904       int area_max_x, decoration_width;
 10905 
 10906       /* Prevent the underline from overwriting surrounding areas
 10907          and the fringe.  */
 10908       window_box (s->w, s->area, &area_x, &area_y,
 10909                   &area_width, &area_height);
 10910       area_max_x = area_x + area_width - 1;
 10911 
 10912       decoration_width = s->width;
 10913       if (!s->row->mode_line_p
 10914           && !s->row->tab_line_p
 10915           && area_max_x < (s->x + decoration_width - 1))
 10916         decoration_width -= (s->x + decoration_width - 1) - area_max_x;
 10917 
 10918       /* Draw relief if not yet drawn.  */
 10919       if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
 10920         x_draw_glyph_string_box (s);
 10921 
 10922       /* Draw underline.  */
 10923       if (s->face->underline)
 10924         {
 10925           if (s->face->underline == FACE_UNDER_WAVE)
 10926             {
 10927               if (s->face->underline_defaulted_p)
 10928                 x_draw_underwave (s, decoration_width);
 10929               else
 10930                 {
 10931                   Display *display = FRAME_X_DISPLAY (s->f);
 10932                   XGCValues xgcv;
 10933                   XGetGCValues (display, s->gc, GCForeground, &xgcv);
 10934                   XSetForeground (display, s->gc, s->face->underline_color);
 10935                   x_draw_underwave (s, decoration_width);
 10936                   XSetForeground (display, s->gc, xgcv.foreground);
 10937                 }
 10938             }
 10939           else if (s->face->underline == FACE_UNDER_LINE)
 10940             {
 10941               unsigned long thickness, position;
 10942               int y;
 10943 
 10944               if (s->prev
 10945                   && s->prev->face->underline == FACE_UNDER_LINE
 10946                   && (s->prev->face->underline_at_descent_line_p
 10947                       == s->face->underline_at_descent_line_p)
 10948                   && (s->prev->face->underline_pixels_above_descent_line
 10949                       == s->face->underline_pixels_above_descent_line))
 10950                 {
 10951                   /* We use the same underline style as the previous one.  */
 10952                   thickness = s->prev->underline_thickness;
 10953                   position = s->prev->underline_position;
 10954                 }
 10955               else
 10956                 {
 10957                   struct font *font = font_for_underline_metrics (s);
 10958                   unsigned long minimum_offset;
 10959                   bool underline_at_descent_line;
 10960                   bool use_underline_position_properties;
 10961                   Lisp_Object val = (WINDOW_BUFFER_LOCAL_VALUE
 10962                                      (Qunderline_minimum_offset, s->w));
 10963 
 10964                   if (FIXNUMP (val))
 10965                     minimum_offset = max (0, XFIXNUM (val));
 10966                   else
 10967                     minimum_offset = 1;
 10968 
 10969                   val = (WINDOW_BUFFER_LOCAL_VALUE
 10970                          (Qx_underline_at_descent_line, s->w));
 10971                   underline_at_descent_line
 10972                     = (!(NILP (val) || BASE_EQ (val, Qunbound))
 10973                        || s->face->underline_at_descent_line_p);
 10974 
 10975                   val = (WINDOW_BUFFER_LOCAL_VALUE
 10976                          (Qx_use_underline_position_properties, s->w));
 10977                   use_underline_position_properties
 10978                     = !(NILP (val) || BASE_EQ (val, Qunbound));
 10979 
 10980                   /* Get the underline thickness.  Default is 1 pixel.  */
 10981                   if (font && font->underline_thickness > 0)
 10982                     thickness = font->underline_thickness;
 10983                   else
 10984                     thickness = 1;
 10985                   if (underline_at_descent_line)
 10986                     position = ((s->height - thickness)
 10987                                 - (s->ybase - s->y)
 10988                                 - s->face->underline_pixels_above_descent_line);
 10989                   else
 10990                     {
 10991                       /* Get the underline position.  This is the
 10992                          recommended vertical offset in pixels from
 10993                          the baseline to the top of the underline.
 10994                          This is a signed value according to the
 10995                          specs, and its default is
 10996 
 10997                          ROUND ((maximum descent) / 2), with
 10998                          ROUND(x) = floor (x + 0.5)  */
 10999 
 11000                       if (use_underline_position_properties
 11001                           && font && font->underline_position >= 0)
 11002                         position = font->underline_position;
 11003                       else if (font)
 11004                         position = (font->descent + 1) / 2;
 11005                       else
 11006                         position = minimum_offset;
 11007                     }
 11008 
 11009                   /* Ignore minimum_offset if the amount of pixels was
 11010                      explicitly specified.  */
 11011                   if (!s->face->underline_pixels_above_descent_line)
 11012                     position = max (position, minimum_offset);
 11013                 }
 11014               /* Check the sanity of thickness and position.  We should
 11015                  avoid drawing underline out of the current line area.  */
 11016               if (s->y + s->height <= s->ybase + position)
 11017                 position = (s->height - 1) - (s->ybase - s->y);
 11018               if (s->y + s->height < s->ybase + position + thickness)
 11019                 thickness = (s->y + s->height) - (s->ybase + position);
 11020               s->underline_thickness = thickness;
 11021               s->underline_position = position;
 11022               y = s->ybase + position;
 11023               if (s->face->underline_defaulted_p)
 11024                 x_fill_rectangle (s->f, s->gc,
 11025                                   s->x, y, decoration_width, thickness,
 11026                                   false);
 11027               else
 11028                 {
 11029                   Display *display = FRAME_X_DISPLAY (s->f);
 11030                   XGCValues xgcv;
 11031                   XGetGCValues (display, s->gc, GCForeground, &xgcv);
 11032                   XSetForeground (display, s->gc, s->face->underline_color);
 11033                   x_fill_rectangle (s->f, s->gc,
 11034                                     s->x, y, decoration_width, thickness,
 11035                                     false);
 11036                   XSetForeground (display, s->gc, xgcv.foreground);
 11037                 }
 11038             }
 11039         }
 11040       /* Draw overline.  */
 11041       if (s->face->overline_p)
 11042         {
 11043           unsigned long dy = 0, h = 1;
 11044 
 11045           if (s->face->overline_color_defaulted_p)
 11046             x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
 11047                               decoration_width, h, false);
 11048           else
 11049             {
 11050               Display *display = FRAME_X_DISPLAY (s->f);
 11051               XGCValues xgcv;
 11052               XGetGCValues (display, s->gc, GCForeground, &xgcv);
 11053               XSetForeground (display, s->gc, s->face->overline_color);
 11054               x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
 11055                                 decoration_width, h, false);
 11056               XSetForeground (display, s->gc, xgcv.foreground);
 11057             }
 11058         }
 11059 
 11060       /* Draw strike-through.  */
 11061       if (s->face->strike_through_p)
 11062         {
 11063           /* Y-coordinate and height of the glyph string's first
 11064              glyph.  We cannot use s->y and s->height because those
 11065              could be larger if there are taller display elements
 11066              (e.g., characters displayed with a larger font) in the
 11067              same glyph row.  */
 11068           int glyph_y = s->ybase - s->first_glyph->ascent;
 11069           int glyph_height = s->first_glyph->ascent + s->first_glyph->descent;
 11070           /* Strike-through width and offset from the glyph string's
 11071              top edge.  */
 11072           unsigned long h = 1;
 11073           unsigned long dy = (glyph_height - h) / 2;
 11074 
 11075           if (s->face->strike_through_color_defaulted_p)
 11076             x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy,
 11077                               s->width, h, false);
 11078           else
 11079             {
 11080               Display *display = FRAME_X_DISPLAY (s->f);
 11081               XGCValues xgcv;
 11082               XGetGCValues (display, s->gc, GCForeground, &xgcv);
 11083               XSetForeground (display, s->gc, s->face->strike_through_color);
 11084               x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy,
 11085                                 decoration_width, h, false);
 11086               XSetForeground (display, s->gc, xgcv.foreground);
 11087             }
 11088         }
 11089 
 11090       if (s->prev)
 11091         {
 11092           struct glyph_string *prev;
 11093 
 11094           for (prev = s->prev; prev; prev = prev->prev)
 11095             if (prev->hl != s->hl
 11096                 && prev->x + prev->width + prev->right_overhang > s->x)
 11097               {
 11098                 /* As prev was drawn while clipped to its own area, we
 11099                    must draw the right_overhang part using s->hl now.  */
 11100                 enum draw_glyphs_face save = prev->hl;
 11101 
 11102                 prev->hl = s->hl;
 11103                 x_set_glyph_string_gc (prev);
 11104                 x_set_glyph_string_clipping_exactly (s, prev);
 11105                 if (prev->first_glyph->type == CHAR_GLYPH)
 11106                   x_draw_glyph_string_foreground (prev);
 11107                 else
 11108                   x_draw_composite_glyph_string_foreground (prev);
 11109                 x_reset_clip_rectangles (prev->f, prev->gc);
 11110                 prev->hl = save;
 11111                 prev->num_clips = 0;
 11112               }
 11113         }
 11114 
 11115       if (s->next)
 11116         {
 11117           struct glyph_string *next;
 11118 
 11119           for (next = s->next; next; next = next->next)
 11120             if (next->hl != s->hl
 11121                 && next->x - next->left_overhang < s->x + s->width)
 11122               {
 11123                 /* As next will be drawn while clipped to its own area,
 11124                    we must draw the left_overhang part using s->hl now.  */
 11125                 enum draw_glyphs_face save = next->hl;
 11126 
 11127                 next->hl = s->hl;
 11128                 x_set_glyph_string_gc (next);
 11129                 x_set_glyph_string_clipping_exactly (s, next);
 11130                 if (next->first_glyph->type == CHAR_GLYPH)
 11131                   x_draw_glyph_string_foreground (next);
 11132                 else
 11133                   x_draw_composite_glyph_string_foreground (next);
 11134                 x_reset_clip_rectangles (next->f, next->gc);
 11135                 next->hl = save;
 11136                 next->num_clips = 0;
 11137                 next->clip_head = s->next;
 11138               }
 11139         }
 11140     }
 11141 
 11142   /* Reset clipping.  */
 11143   x_reset_clip_rectangles (s->f, s->gc);
 11144   s->num_clips = 0;
 11145 
 11146   /* Set the stippled flag that tells redisplay whether or not a
 11147      stipple was actually draw.  */
 11148 
 11149   if (s->first_glyph->type != STRETCH_GLYPH
 11150       && s->first_glyph->type != IMAGE_GLYPH
 11151       && !s->row->stipple_p)
 11152     s->row->stipple_p = s->stippled_p;
 11153 }
 11154 
 11155 /* Shift display to make room for inserted glyphs.   */
 11156 
 11157 static void
 11158 x_shift_glyphs_for_insert (struct frame *f, int x, int y, int width, int height, int shift_by)
 11159 {
 11160 /* Never called on a GUI frame, see
 11161    https://lists.gnu.org/r/emacs-devel/2015-05/msg00456.html
 11162 */
 11163   XCopyArea (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f),
 11164              f->output_data.x->normal_gc,
 11165              x, y, width, height,
 11166              x + shift_by, y);
 11167 }
 11168 
 11169 /* Delete N glyphs at the nominal cursor position.  Not implemented
 11170    for X frames.  */
 11171 
 11172 static void
 11173 x_delete_glyphs (struct frame *f, int n)
 11174 {
 11175   emacs_abort ();
 11176 }
 11177 
 11178 
 11179 /* Like XClearArea, but check that WIDTH and HEIGHT are reasonable.
 11180    If they are <= 0, this is probably an error.  */
 11181 
 11182 #if defined USE_GTK || !defined USE_CAIRO
 11183 static void
 11184 x_clear_area1 (Display *dpy, Window window,
 11185                int x, int y, int width, int height, int exposures)
 11186 {
 11187   eassert (width > 0 && height > 0);
 11188   XClearArea (dpy, window, x, y, width, height, exposures);
 11189 }
 11190 #endif
 11191 
 11192 void
 11193 x_clear_area (struct frame *f, int x, int y, int width, int height)
 11194 {
 11195 #ifdef USE_CAIRO
 11196   cairo_t *cr;
 11197 
 11198   eassert (width > 0 && height > 0);
 11199 
 11200   cr = x_begin_cr_clip (f, NULL);
 11201   x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc,
 11202                                       true);
 11203   cairo_rectangle (cr, x, y, width, height);
 11204   cairo_fill (cr);
 11205   x_end_cr_clip (f);
 11206 #else
 11207 #ifndef USE_GTK
 11208   if (f->alpha_background != 1.0
 11209 #ifdef HAVE_XDBE
 11210       || FRAME_X_DOUBLE_BUFFERED_P (f)
 11211 #endif
 11212       )
 11213 #endif
 11214     {
 11215 #if defined HAVE_XRENDER && \
 11216   (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2))
 11217       x_xr_ensure_picture (f);
 11218       if (FRAME_DISPLAY_INFO (f)->alpha_bits
 11219           && FRAME_X_PICTURE (f) != None
 11220           && f->alpha_background != 1.0
 11221           && FRAME_CHECK_XR_VERSION (f, 0, 2))
 11222         {
 11223           XRenderColor xc;
 11224           GC gc = f->output_data.x->normal_gc;
 11225 
 11226           x_xr_apply_ext_clip (f, gc);
 11227           x_xrender_color_from_gc_background (f, gc, &xc, true);
 11228           XRenderFillRectangle (FRAME_X_DISPLAY (f),
 11229                                 PictOpSrc, FRAME_X_PICTURE (f),
 11230                                 &xc, x, y, width, height);
 11231           x_xr_reset_ext_clip (f);
 11232           x_mark_frame_dirty (f);
 11233         }
 11234       else
 11235 #endif
 11236         XFillRectangle (FRAME_X_DISPLAY (f),
 11237                         FRAME_X_DRAWABLE (f),
 11238                         f->output_data.x->reverse_gc,
 11239                         x, y, width, height);
 11240     }
 11241 #ifndef USE_GTK
 11242   else
 11243     x_clear_area1 (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 11244                    x, y, width, height, False);
 11245 #endif
 11246 #endif
 11247 }
 11248 
 11249 
 11250 /* Clear an entire frame.  */
 11251 
 11252 static void
 11253 x_clear_frame (struct frame *f)
 11254 {
 11255   /* Clearing the frame will erase any cursor, so mark them all as no
 11256      longer visible.  */
 11257   mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
 11258 
 11259   block_input ();
 11260   font_drop_xrender_surfaces (f);
 11261   x_clear_window (f);
 11262 
 11263   /* We have to clear the scroll bars.  If we have changed colors or
 11264      something like that, then they should be notified.  */
 11265   x_scroll_bar_clear (f);
 11266 
 11267   unblock_input ();
 11268 }
 11269 
 11270 /* Send a message to frame F telling the event loop to track whether
 11271    or not an hourglass is being displayed.  This is required to ignore
 11272    the right events when the hourglass is mapped without callig XSync
 11273    after displaying or hiding the hourglass.  */
 11274 
 11275 static void
 11276 x_send_hourglass_message (struct frame *f, bool hourglass_enabled)
 11277 {
 11278   struct x_display_info *dpyinfo;
 11279   XEvent msg;
 11280 
 11281   dpyinfo = FRAME_DISPLAY_INFO (f);
 11282   memset (&msg, 0, sizeof msg);
 11283 
 11284   msg.xclient.type = ClientMessage;
 11285   msg.xclient.message_type
 11286     = dpyinfo->Xatom_EMACS_TMP;
 11287   msg.xclient.format = 8;
 11288   msg.xclient.window = FRAME_X_WINDOW (f);
 11289   msg.xclient.data.b[0] = hourglass_enabled ? 1 : 0;
 11290 
 11291   XSendEvent (dpyinfo->display, FRAME_X_WINDOW (f),
 11292               False, NoEventMask, &msg);
 11293 }
 11294 
 11295 /* RIF: Show hourglass cursor on frame F.  */
 11296 
 11297 static void
 11298 x_show_hourglass (struct frame *f)
 11299 {
 11300   Display *dpy = FRAME_X_DISPLAY (f);
 11301 
 11302   if (dpy)
 11303     {
 11304       struct x_output *x = FRAME_X_OUTPUT (f);
 11305 
 11306       /* If the hourglass window is mapped inside a popup menu, input
 11307          could be lost if the menu is popped down and the grab is
 11308          relinquished, but the hourglass window is still up.  Just
 11309          avoid displaying the hourglass at all while popups are
 11310          active.  */
 11311 
 11312       if (popup_activated ())
 11313         return;
 11314 
 11315       x_send_hourglass_message (f, true);
 11316 
 11317 #ifdef USE_X_TOOLKIT
 11318       if (x->widget)
 11319 #else
 11320       if (FRAME_OUTER_WINDOW (f))
 11321 #endif
 11322        {
 11323          if (!x->hourglass_window)
 11324            {
 11325 #ifndef USE_XCB
 11326              unsigned long mask = CWCursor;
 11327              XSetWindowAttributes attrs;
 11328 #ifdef USE_GTK
 11329              Window parent = FRAME_X_WINDOW (f);
 11330 #else
 11331              Window parent = FRAME_OUTER_WINDOW (f);
 11332 #endif
 11333              attrs.cursor = x->hourglass_cursor;
 11334 
 11335              x->hourglass_window = XCreateWindow
 11336                (dpy, parent, 0, 0, 32000, 32000, 0, 0,
 11337                 InputOnly, CopyFromParent, mask, &attrs);
 11338 #else
 11339              uint32_t cursor = (uint32_t) x->hourglass_cursor;
 11340 #ifdef USE_GTK
 11341              xcb_window_t parent = (xcb_window_t) FRAME_X_WINDOW (f);
 11342 #else
 11343              xcb_window_t parent = (xcb_window_t) FRAME_OUTER_WINDOW (f);
 11344 #endif
 11345              x->hourglass_window
 11346                = (Window) xcb_generate_id (FRAME_DISPLAY_INFO (f)->xcb_connection);
 11347 
 11348              xcb_create_window (FRAME_DISPLAY_INFO (f)->xcb_connection,
 11349                                 XCB_COPY_FROM_PARENT,
 11350                                 (xcb_window_t) x->hourglass_window,
 11351                                 parent, 0, 0, FRAME_PIXEL_WIDTH (f),
 11352                                 FRAME_PIXEL_HEIGHT (f), 0,
 11353                                 XCB_WINDOW_CLASS_INPUT_ONLY,
 11354                                 XCB_COPY_FROM_PARENT, XCB_CW_CURSOR,
 11355                                 &cursor);
 11356 #endif
 11357            }
 11358 
 11359 #ifndef USE_XCB
 11360          XMapRaised (dpy, x->hourglass_window);
 11361          /* Ensure that the spinning hourglass is shown.  */
 11362          flush_frame (f);
 11363 #else
 11364          uint32_t value = XCB_STACK_MODE_ABOVE;
 11365 
 11366          xcb_configure_window (FRAME_DISPLAY_INFO (f)->xcb_connection,
 11367                                (xcb_window_t) x->hourglass_window,
 11368                                XCB_CONFIG_WINDOW_STACK_MODE, &value);
 11369          xcb_map_window (FRAME_DISPLAY_INFO (f)->xcb_connection,
 11370                          (xcb_window_t) x->hourglass_window);
 11371          xcb_flush (FRAME_DISPLAY_INFO (f)->xcb_connection);
 11372 #endif
 11373        }
 11374     }
 11375 }
 11376 
 11377 /* RIF: Cancel hourglass cursor on frame F.  */
 11378 
 11379 static void
 11380 x_hide_hourglass (struct frame *f)
 11381 {
 11382   struct x_output *x = FRAME_X_OUTPUT (f);
 11383 
 11384   /* Watch out for newly created frames.  */
 11385   if (x->hourglass_window)
 11386     {
 11387 #ifndef USE_XCB
 11388       XUnmapWindow (FRAME_X_DISPLAY (f), x->hourglass_window);
 11389 #else
 11390       xcb_unmap_window (FRAME_DISPLAY_INFO (f)->xcb_connection,
 11391                         (xcb_window_t) x->hourglass_window);
 11392 #endif
 11393       x_send_hourglass_message (f, false);
 11394     }
 11395 }
 11396 
 11397 /* Invert the middle quarter of the frame for .15 sec.  */
 11398 
 11399 static void
 11400 XTflash (struct frame *f)
 11401 {
 11402   GC gc;
 11403   XGCValues values;
 11404   fd_set fds;
 11405   int fd, rc;
 11406 
 11407   block_input ();
 11408 
 11409   if (FRAME_X_VISUAL_INFO (f)->class == TrueColor)
 11410     {
 11411       values.function = GXxor;
 11412       values.foreground = (FRAME_FOREGROUND_PIXEL (f)
 11413                            ^ FRAME_BACKGROUND_PIXEL (f));
 11414 
 11415       gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 11416                       GCFunction | GCForeground, &values);
 11417     }
 11418   else
 11419     gc = FRAME_X_OUTPUT (f)->normal_gc;
 11420 
 11421 
 11422   /* Get the height not including a menu bar widget.  */
 11423   int height = FRAME_PIXEL_HEIGHT (f);
 11424   /* Height of each line to flash.  */
 11425   int flash_height = FRAME_LINE_HEIGHT (f);
 11426   /* These will be the left and right margins of the rectangles.  */
 11427   int flash_left = FRAME_INTERNAL_BORDER_WIDTH (f);
 11428   int flash_right = FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f);
 11429   int width = flash_right - flash_left;
 11430 
 11431   /* If window is tall, flash top and bottom line.  */
 11432   if (height > 3 * FRAME_LINE_HEIGHT (f))
 11433     {
 11434       XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
 11435                       flash_left,
 11436                       (FRAME_INTERNAL_BORDER_WIDTH (f)
 11437                        + FRAME_TOP_MARGIN_HEIGHT (f)),
 11438                       width, flash_height);
 11439       XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
 11440                       flash_left,
 11441                       (height - flash_height
 11442                        - FRAME_INTERNAL_BORDER_WIDTH (f)
 11443                        - FRAME_BOTTOM_MARGIN_HEIGHT (f)),
 11444                       width, flash_height);
 11445 
 11446     }
 11447   else
 11448     /* If it is short, flash it all.  */
 11449     XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
 11450                     flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
 11451                     width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
 11452 
 11453   x_flush (f);
 11454 
 11455   struct timespec delay = make_timespec (0, 150 * 1000 * 1000);
 11456   struct timespec wakeup = timespec_add (current_timespec (), delay);
 11457   fd = ConnectionNumber (FRAME_X_DISPLAY (f));
 11458 
 11459   /* Keep waiting until past the time wakeup or any input gets
 11460      available.  */
 11461   while (! detect_input_pending ())
 11462     {
 11463       struct timespec current = current_timespec ();
 11464       struct timespec timeout;
 11465 
 11466       /* Break if result would not be positive.  */
 11467       if (timespec_cmp (wakeup, current) <= 0)
 11468         break;
 11469 
 11470       /* How long `select' should wait.  */
 11471       timeout = make_timespec (0, 10 * 1000 * 1000);
 11472 
 11473       /* Wait for some input to become available on the X
 11474          connection.  */
 11475       FD_ZERO (&fds);
 11476       FD_SET (fd, &fds);
 11477 
 11478       /* Try to wait that long--but we might wake up sooner.  */
 11479       rc = pselect (fd + 1, &fds, NULL, NULL, &timeout, NULL);
 11480 
 11481       /* Some input is available, exit the visible bell.  */
 11482       if (rc >= 0 && FD_ISSET (fd, &fds))
 11483         break;
 11484     }
 11485 
 11486   /* If window is tall, flash top and bottom line.  */
 11487   if (height > 3 * FRAME_LINE_HEIGHT (f))
 11488     {
 11489       XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
 11490                       flash_left,
 11491                       (FRAME_INTERNAL_BORDER_WIDTH (f)
 11492                        + FRAME_TOP_MARGIN_HEIGHT (f)),
 11493                       width, flash_height);
 11494       XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
 11495                       flash_left,
 11496                       (height - flash_height
 11497                        - FRAME_INTERNAL_BORDER_WIDTH (f)
 11498                        - FRAME_BOTTOM_MARGIN_HEIGHT (f)),
 11499                       width, flash_height);
 11500     }
 11501   else
 11502     /* If it is short, flash it all.  */
 11503     XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
 11504                     flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
 11505                     width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
 11506 
 11507   if (FRAME_X_VISUAL_INFO (f)->class == TrueColor)
 11508     XFreeGC (FRAME_X_DISPLAY (f), gc);
 11509   x_flush (f);
 11510 
 11511   unblock_input ();
 11512 }
 11513 
 11514 /* Make audible bell.  */
 11515 
 11516 static void
 11517 XTring_bell (struct frame *f)
 11518 {
 11519   struct x_display_info *dpyinfo;
 11520 
 11521   if (!FRAME_X_DISPLAY (f))
 11522     return;
 11523 
 11524   dpyinfo = FRAME_DISPLAY_INFO (f);
 11525 
 11526   if (visible_bell)
 11527     XTflash (f);
 11528   else
 11529     {
 11530       /* When Emacs is untrusted, Bell requests sometimes generate
 11531          Access errors.  This is not in the security extension
 11532          specification but seems to be a bug in the X consortium XKB
 11533          implementation.  */
 11534 
 11535       block_input ();
 11536       x_ignore_errors_for_next_request (dpyinfo, 0);
 11537 #ifdef HAVE_XKB
 11538       XkbBell (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 0, None);
 11539 #else
 11540       XBell (FRAME_X_DISPLAY (f), 0);
 11541 #endif
 11542       XFlush (FRAME_X_DISPLAY (f));
 11543       x_stop_ignoring_errors (dpyinfo);
 11544       unblock_input ();
 11545     }
 11546 }
 11547 
 11548 /***********************************************************************
 11549                               Line Dance
 11550  ***********************************************************************/
 11551 
 11552 /* Perform an insert-lines or delete-lines operation, inserting N
 11553    lines or deleting -N lines at vertical position VPOS.  */
 11554 
 11555 static void
 11556 x_ins_del_lines (struct frame *f, int vpos, int n)
 11557 {
 11558   emacs_abort ();
 11559 }
 11560 
 11561 
 11562 /* Scroll part of the display as described by RUN.  */
 11563 
 11564 static void
 11565 x_scroll_run (struct window *w, struct run *run)
 11566 {
 11567   struct frame *f = XFRAME (w->frame);
 11568   int x, y, width, height, from_y, to_y, bottom_y;
 11569 
 11570   /* Get frame-relative bounding box of the text display area of W,
 11571      without mode lines.  Include in this box the left and right
 11572      fringe of W.  */
 11573   window_box (w, ANY_AREA, &x, &y, &width, &height);
 11574 
 11575   from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
 11576   to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
 11577   bottom_y = y + height;
 11578 
 11579   if (to_y < from_y)
 11580     {
 11581       /* Scrolling up.  Make sure we don't copy part of the mode
 11582          line at the bottom.  */
 11583       if (from_y + run->height > bottom_y)
 11584         height = bottom_y - from_y;
 11585       else
 11586         height = run->height;
 11587     }
 11588   else
 11589     {
 11590       /* Scrolling down.  Make sure we don't copy over the mode line.
 11591          at the bottom.  */
 11592       if (to_y + run->height > bottom_y)
 11593         height = bottom_y - to_y;
 11594       else
 11595         height = run->height;
 11596     }
 11597 
 11598   block_input ();
 11599 
 11600   /* Cursor off.  Will be switched on again in gui_update_window_end.  */
 11601   gui_clear_cursor (w);
 11602 
 11603 #ifdef HAVE_XWIDGETS
 11604   /* "Copy" xwidget windows in the area that will be scrolled.  */
 11605   Display *dpy = FRAME_X_DISPLAY (f);
 11606   Window window = FRAME_X_WINDOW (f);
 11607 
 11608   Window root, parent, *children;
 11609   unsigned int nchildren;
 11610 
 11611   if (XQueryTree (dpy, window, &root, &parent, &children, &nchildren))
 11612     {
 11613       /* Now find xwidget views situated between from_y and to_y, and
 11614          attached to w.  */
 11615       for (unsigned int i = 0; i < nchildren; ++i)
 11616         {
 11617           Window child = children[i];
 11618           struct xwidget_view *view = xwidget_view_from_window (child);
 11619 
 11620           if (view && !view->hidden)
 11621             {
 11622               int window_y = view->y + view->clip_top;
 11623               int window_height = view->clip_bottom - view->clip_top;
 11624 
 11625               Emacs_Rectangle r1, r2, result;
 11626               r1.x = w->pixel_left;
 11627               r1.y = from_y;
 11628               r1.width = w->pixel_width;
 11629               r1.height = height;
 11630               r2 = r1;
 11631               r2.y = window_y;
 11632               r2.height = window_height;
 11633 
 11634               /* The window is offscreen, just unmap it.  */
 11635               if (window_height == 0)
 11636                 {
 11637                   view->hidden = true;
 11638                   XUnmapWindow (dpy, child);
 11639                   continue;
 11640                 }
 11641 
 11642               bool intersects_p =
 11643                 gui_intersect_rectangles (&r1, &r2, &result);
 11644 
 11645               if (XWINDOW (view->w) == w && intersects_p)
 11646                 {
 11647                   int y = view->y + (to_y - from_y);
 11648                   int text_area_x, text_area_y, text_area_width, text_area_height;
 11649                   int clip_top, clip_bottom;
 11650 
 11651                   window_box (w, view->area, &text_area_x, &text_area_y,
 11652                               &text_area_width, &text_area_height);
 11653 
 11654                   view->y = y;
 11655 
 11656                   clip_top = 0;
 11657                   clip_bottom = XXWIDGET (view->model)->height;
 11658 
 11659                   if (y < text_area_y)
 11660                     clip_top = text_area_y - y;
 11661 
 11662                   if ((y + clip_bottom) > (text_area_y + text_area_height))
 11663                     {
 11664                       clip_bottom -= (y + clip_bottom) - (text_area_y + text_area_height);
 11665                     }
 11666 
 11667                   view->clip_top = clip_top;
 11668                   view->clip_bottom = clip_bottom;
 11669 
 11670                   /* This means the view has moved offscreen.  Unmap
 11671                      it and hide it here.  */
 11672                   if ((view->clip_bottom - view->clip_top) <= 0)
 11673                     {
 11674                       view->hidden = true;
 11675                       XUnmapWindow (dpy, child);
 11676                     }
 11677                   else
 11678                     {
 11679                       XMoveResizeWindow (dpy, child, view->x + view->clip_left,
 11680                                          view->y + view->clip_top,
 11681                                          view->clip_right - view->clip_left,
 11682                                          view->clip_bottom - view->clip_top);
 11683                       cairo_xlib_surface_set_size (view->cr_surface,
 11684                                                    view->clip_right - view->clip_left,
 11685                                                    view->clip_bottom - view->clip_top);
 11686                     }
 11687                   xwidget_expose (view);
 11688                 }
 11689             }
 11690         }
 11691       XFree (children);
 11692     }
 11693 #endif
 11694 
 11695 #ifdef USE_CAIRO_XCB_SURFACE
 11696   /* Some of the following code depends on `normal_gc' being
 11697      up-to-date on the X server, but doesn't call a routine that will
 11698      flush it first.  So do this ourselves instead.  */
 11699   XFlushGC (FRAME_X_DISPLAY (f),
 11700             f->output_data.x->normal_gc);
 11701 #endif
 11702 
 11703 #ifdef USE_CAIRO
 11704   if (FRAME_CR_CONTEXT (f))
 11705     {
 11706       cairo_surface_t *surface = cairo_get_target (FRAME_CR_CONTEXT (f));
 11707       if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_XLIB)
 11708         {
 11709           eassert (cairo_xlib_surface_get_display (surface)
 11710                    == FRAME_X_DISPLAY (f));
 11711           eassert (cairo_xlib_surface_get_drawable (surface)
 11712                    == FRAME_X_RAW_DRAWABLE (f));
 11713           cairo_surface_flush (surface);
 11714           XCopyArea (FRAME_X_DISPLAY (f),
 11715                      FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f),
 11716                      f->output_data.x->normal_gc,
 11717                      x, from_y,
 11718                      width, height,
 11719                      x, to_y);
 11720           cairo_surface_mark_dirty_rectangle (surface, x, to_y, width, height);
 11721         }
 11722 #ifdef USE_CAIRO_XCB_SURFACE
 11723       else if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_XCB)
 11724         {
 11725           cairo_surface_flush (surface);
 11726           xcb_copy_area (FRAME_DISPLAY_INFO (f)->xcb_connection,
 11727                          (xcb_drawable_t) FRAME_X_DRAWABLE (f),
 11728                          (xcb_drawable_t) FRAME_X_DRAWABLE (f),
 11729                          (xcb_gcontext_t) XGContextFromGC (f->output_data.x->normal_gc),
 11730                          x, from_y, x, to_y, width, height);
 11731           cairo_surface_mark_dirty_rectangle (surface, x, to_y, width, height);
 11732         }
 11733 #endif
 11734       else
 11735         {
 11736           cairo_surface_t *s
 11737             = cairo_surface_create_similar (surface,
 11738                                             cairo_surface_get_content (surface),
 11739                                             width, height);
 11740           cairo_t *cr = cairo_create (s);
 11741           cairo_set_source_surface (cr, surface, -x, -from_y);
 11742           cairo_paint (cr);
 11743           cairo_destroy (cr);
 11744 
 11745           cr = FRAME_CR_CONTEXT (f);
 11746           cairo_save (cr);
 11747           cairo_set_source_surface (cr, s, x, to_y);
 11748           cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
 11749           cairo_rectangle (cr, x, to_y, width, height);
 11750           cairo_fill (cr);
 11751           cairo_restore (cr);
 11752           cairo_surface_destroy (s);
 11753         }
 11754     }
 11755   else
 11756 #endif  /* USE_CAIRO */
 11757     XCopyArea (FRAME_X_DISPLAY (f),
 11758                FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f),
 11759                f->output_data.x->normal_gc,
 11760                x, from_y,
 11761                width, height,
 11762                x, to_y);
 11763 
 11764   unblock_input ();
 11765 }
 11766 
 11767 
 11768 
 11769 /***********************************************************************
 11770                            Exposure Events
 11771  ***********************************************************************/
 11772 
 11773 
 11774 static void
 11775 x_frame_highlight (struct frame *f)
 11776 {
 11777   struct x_display_info *dpyinfo;
 11778 
 11779   dpyinfo = FRAME_DISPLAY_INFO (f);
 11780 
 11781   /* We used to only do this if Vx_no_window_manager was non-nil, but
 11782      the ICCCM (section 4.1.6) says that the window's border pixmap
 11783      and border pixel are window attributes which are "private to the
 11784      client", so we can always change it to whatever we want.  */
 11785   block_input ();
 11786   /* I recently started to get errors in this XSetWindowBorder, depending on
 11787      the window-manager in use, tho something more is at play since I've been
 11788      using that same window-manager binary for ever.  Let's not crash just
 11789      because of this (bug#9310).  */
 11790   x_ignore_errors_for_next_request (dpyinfo, 0);
 11791   XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 11792                     f->output_data.x->border_pixel);
 11793   x_stop_ignoring_errors (dpyinfo);
 11794   unblock_input ();
 11795   gui_update_cursor (f, true);
 11796   x_set_frame_alpha (f);
 11797 }
 11798 
 11799 static void
 11800 x_frame_unhighlight (struct frame *f)
 11801 {
 11802   struct x_display_info *dpyinfo;
 11803 
 11804   dpyinfo = FRAME_DISPLAY_INFO (f);
 11805 
 11806   /* We used to only do this if Vx_no_window_manager was non-nil, but
 11807      the ICCCM (section 4.1.6) says that the window's border pixmap
 11808      and border pixel are window attributes which are "private to the
 11809      client", so we can always change it to whatever we want.  */
 11810 
 11811   block_input ();
 11812   /* Same as above for XSetWindowBorder (bug#9310).  */
 11813   x_ignore_errors_for_next_request (dpyinfo, 0);
 11814   XSetWindowBorderPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 11815                           f->output_data.x->border_tile);
 11816   x_stop_ignoring_errors (dpyinfo);
 11817   unblock_input ();
 11818 
 11819   gui_update_cursor (f, true);
 11820   x_set_frame_alpha (f);
 11821 }
 11822 
 11823 /* The focus has changed.  Update the frames as necessary to reflect
 11824    the new situation.  Note that we can't change the selected frame
 11825    here, because the Lisp code we are interrupting might become confused.
 11826    Each event gets marked with the frame in which it occurred, so the
 11827    Lisp code can tell when the switch took place by examining the events.  */
 11828 
 11829 static void
 11830 x_new_focus_frame (struct x_display_info *dpyinfo, struct frame *frame)
 11831 {
 11832   struct frame *old_focus = dpyinfo->x_focus_frame;
 11833 #if defined USE_GTK && !defined HAVE_GTK3 && defined HAVE_XINPUT2
 11834   XIEventMask mask;
 11835   ptrdiff_t l;
 11836 
 11837   if (dpyinfo->supports_xi2)
 11838     {
 11839       l = XIMaskLen (XI_LASTEVENT);
 11840       mask.mask = alloca (l);
 11841       mask.mask_len = l;
 11842       memset (mask.mask, 0, l);
 11843 
 11844       mask.deviceid = XIAllDevices;
 11845     }
 11846 #endif
 11847 
 11848   if (frame != dpyinfo->x_focus_frame)
 11849     {
 11850       /* Set this before calling other routines, so that they see
 11851          the correct value of x_focus_frame.  */
 11852       dpyinfo->x_focus_frame = frame;
 11853 
 11854       /* Once none of our frames are focused anymore, stop selecting
 11855          for raw input events from the root window.  */
 11856 
 11857 #if defined USE_GTK && !defined HAVE_GTK3 && defined HAVE_XINPUT2
 11858       if (frame && dpyinfo->supports_xi2)
 11859         XISetMask (mask.mask, XI_RawKeyPress);
 11860 
 11861       if (dpyinfo->supports_xi2)
 11862         XISelectEvents (dpyinfo->display, dpyinfo->root_window, &mask, 1);
 11863 #endif
 11864 
 11865       if (old_focus && old_focus->auto_lower)
 11866         x_lower_frame (old_focus);
 11867 
 11868       if (dpyinfo->x_focus_frame && dpyinfo->x_focus_frame->auto_raise)
 11869         dpyinfo->x_pending_autoraise_frame = dpyinfo->x_focus_frame;
 11870       else
 11871         dpyinfo->x_pending_autoraise_frame = NULL;
 11872     }
 11873 
 11874   x_frame_rehighlight (dpyinfo);
 11875 }
 11876 
 11877 #if defined HAVE_XFIXES && XFIXES_VERSION >= 40000
 11878 
 11879 /* True if the display in DPYINFO supports a version of Xfixes
 11880    sufficient for pointer blanking.  */
 11881 
 11882 static bool
 11883 x_fixes_pointer_blanking_supported (struct x_display_info *dpyinfo)
 11884 {
 11885   return (dpyinfo->xfixes_supported_p
 11886           && dpyinfo->xfixes_major >= 4);
 11887 }
 11888 
 11889 #endif /* HAVE_XFIXES && XFIXES_VERSION >= 40000 */
 11890 
 11891 /* Toggle mouse pointer visibility on frame F using the XFixes
 11892    extension.  */
 11893 #if defined HAVE_XFIXES && XFIXES_VERSION >= 40000
 11894 
 11895 static void
 11896 xfixes_toggle_visible_pointer (struct frame *f, bool invisible)
 11897 
 11898 {
 11899   if (invisible)
 11900     XFixesHideCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
 11901   else
 11902     XFixesShowCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
 11903   f->pointer_invisible = invisible;
 11904 }
 11905 
 11906 #endif /* HAVE_XFIXES */
 11907 
 11908 /* Create invisible cursor on the X display referred by DPYINFO.  */
 11909 static Cursor
 11910 make_invisible_cursor (struct x_display_info *dpyinfo)
 11911 {
 11912   Display *dpy = dpyinfo->display;
 11913   static char const no_data[] = { 0 };
 11914   Pixmap pix;
 11915   XColor col;
 11916   Cursor c;
 11917 
 11918   c = None;
 11919 
 11920   x_catch_errors (dpy);
 11921   pix = XCreateBitmapFromData (dpy, dpyinfo->root_window, no_data, 1, 1);
 11922   if (!x_had_errors_p (dpy) && pix != None)
 11923     {
 11924       Cursor pixc;
 11925       col.pixel = 0;
 11926       col.red = col.green = col.blue = 0;
 11927       col.flags = DoRed | DoGreen | DoBlue;
 11928       pixc = XCreatePixmapCursor (dpy, pix, pix, &col, &col, 0, 0);
 11929       if (! x_had_errors_p (dpy) && pixc != None)
 11930         c = pixc;
 11931       XFreePixmap (dpy, pix);
 11932     }
 11933 
 11934   x_uncatch_errors ();
 11935 
 11936   return c;
 11937 }
 11938 
 11939 /* Toggle mouse pointer visibility on frame F by using an invisible
 11940    cursor.  */
 11941 static void
 11942 x_toggle_visible_pointer (struct frame *f, bool invisible)
 11943 {
 11944   struct x_display_info *dpyinfo;
 11945 
 11946   dpyinfo = FRAME_DISPLAY_INFO (f);
 11947 
 11948   /* We could have gotten a BadAlloc error while creating the
 11949      invisible cursor.  Try to create it again, but if that fails,
 11950      just give up.  */
 11951   if (dpyinfo->invisible_cursor == None)
 11952     dpyinfo->invisible_cursor = make_invisible_cursor (dpyinfo);
 11953 
 11954 #if !defined HAVE_XFIXES || XFIXES_VERSION < 40000
 11955   if (dpyinfo->invisible_cursor == None)
 11956     invisible = false;
 11957 #else
 11958   /* But if Xfixes is available, try using it instead.  */
 11959   if (dpyinfo->invisible_cursor == None)
 11960     {
 11961       if (x_fixes_pointer_blanking_supported (dpyinfo))
 11962         {
 11963           dpyinfo->fixes_pointer_blanking = true;
 11964           xfixes_toggle_visible_pointer (f, invisible);
 11965 
 11966           return;
 11967         }
 11968       else
 11969         invisible = false;
 11970     }
 11971 #endif
 11972 
 11973   if (invisible)
 11974     XDefineCursor (dpyinfo->display, FRAME_X_WINDOW (f),
 11975                    dpyinfo->invisible_cursor);
 11976   else
 11977     XDefineCursor (dpyinfo->display, FRAME_X_WINDOW (f),
 11978                    f->output_data.x->current_cursor);
 11979 
 11980   f->pointer_invisible = invisible;
 11981 }
 11982 
 11983 static void
 11984 XTtoggle_invisible_pointer (struct frame *f, bool invisible)
 11985 {
 11986   block_input ();
 11987 #if defined HAVE_XFIXES && XFIXES_VERSION >= 40000
 11988   if (FRAME_DISPLAY_INFO (f)->fixes_pointer_blanking
 11989       && x_fixes_pointer_blanking_supported (FRAME_DISPLAY_INFO (f)))
 11990     xfixes_toggle_visible_pointer (f, invisible);
 11991   else
 11992 #endif
 11993     x_toggle_visible_pointer (f, invisible);
 11994   unblock_input ();
 11995 }
 11996 
 11997 /* Handle FocusIn and FocusOut state changes for FRAME.  If FRAME has
 11998    focus and there exists more than one frame, puts a FOCUS_IN_EVENT
 11999    into *BUFP.  Note that this code is not used to handle focus
 12000    changes on builds that can use the X Input extension for handling
 12001    input focus when it is available (currently the no toolkit and GTK
 12002    3 toolkits).  */
 12003 
 12004 static void
 12005 x_focus_changed (int type, int state, struct x_display_info *dpyinfo,
 12006                  struct frame *frame, struct input_event *bufp)
 12007 {
 12008   if (type == FocusIn)
 12009     {
 12010       if (dpyinfo->x_focus_event_frame != frame)
 12011         {
 12012           x_new_focus_frame (dpyinfo, frame);
 12013           dpyinfo->x_focus_event_frame = frame;
 12014           bufp->kind = FOCUS_IN_EVENT;
 12015           XSETFRAME (bufp->frame_or_window, frame);
 12016         }
 12017 
 12018       frame->output_data.x->focus_state |= state;
 12019 
 12020 #ifdef HAVE_X_I18N
 12021       if (FRAME_XIC (frame))
 12022         XSetICFocus (FRAME_XIC (frame));
 12023 #ifdef USE_GTK
 12024       GtkWidget *widget;
 12025 
 12026       if (x_gtk_use_native_input)
 12027         {
 12028           gtk_im_context_focus_in (FRAME_X_OUTPUT (frame)->im_context);
 12029           widget = FRAME_GTK_OUTER_WIDGET (frame);
 12030           gtk_im_context_set_client_window (FRAME_X_OUTPUT (frame)->im_context,
 12031                                             gtk_widget_get_window (widget));
 12032         }
 12033 #endif
 12034 #endif
 12035     }
 12036   else if (type == FocusOut)
 12037     {
 12038       frame->output_data.x->focus_state &= ~state;
 12039 
 12040       if (dpyinfo->x_focus_event_frame == frame)
 12041         {
 12042           dpyinfo->x_focus_event_frame = 0;
 12043           x_new_focus_frame (dpyinfo, 0);
 12044 
 12045           bufp->kind = FOCUS_OUT_EVENT;
 12046           XSETFRAME (bufp->frame_or_window, frame);
 12047         }
 12048 
 12049       if (!frame->output_data.x->focus_state)
 12050         {
 12051 #ifdef HAVE_X_I18N
 12052           if (FRAME_XIC (frame))
 12053             XUnsetICFocus (FRAME_XIC (frame));
 12054 #ifdef USE_GTK
 12055           if (x_gtk_use_native_input)
 12056             {
 12057               gtk_im_context_focus_out (FRAME_X_OUTPUT (frame)->im_context);
 12058               gtk_im_context_set_client_window (FRAME_X_OUTPUT (frame)->im_context, NULL);
 12059             }
 12060 #endif
 12061 #endif
 12062         }
 12063 
 12064       if (frame->pointer_invisible)
 12065         XTtoggle_invisible_pointer (frame, false);
 12066     }
 12067 }
 12068 
 12069 /* Return the Emacs frame-object corresponding to an X window.  It
 12070    could be the frame's main window, an icon window, or an xwidget
 12071    window.  */
 12072 
 12073 static struct frame *
 12074 x_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
 12075 {
 12076   Lisp_Object tail, frame;
 12077   struct frame *f;
 12078 
 12079   if (wdesc == None)
 12080     return NULL;
 12081 
 12082 #ifdef HAVE_XWIDGETS
 12083   struct xwidget_view *xvw = xwidget_view_from_window (wdesc);
 12084 
 12085   if (xvw && xvw->frame)
 12086     return xvw->frame;
 12087 #endif
 12088 
 12089   FOR_EACH_FRAME (tail, frame)
 12090     {
 12091       f = XFRAME (frame);
 12092       if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
 12093         continue;
 12094       if (f->output_data.x->hourglass_window == wdesc)
 12095         return f;
 12096 #ifdef USE_X_TOOLKIT
 12097       if ((f->output_data.x->edit_widget
 12098            && XtWindow (f->output_data.x->edit_widget) == wdesc)
 12099           /* A tooltip frame?  */
 12100           || (!f->output_data.x->edit_widget
 12101               && FRAME_X_WINDOW (f) == wdesc)
 12102           || f->output_data.x->icon_desc == wdesc)
 12103         return f;
 12104 #else /* not USE_X_TOOLKIT */
 12105 #ifdef USE_GTK
 12106       if (f->output_data.x->edit_widget)
 12107       {
 12108         GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
 12109         struct x_output *x = f->output_data.x;
 12110         if (gwdesc != 0 && gwdesc == x->edit_widget)
 12111           return f;
 12112       }
 12113 #endif /* USE_GTK */
 12114       if (FRAME_X_WINDOW (f) == wdesc
 12115           || f->output_data.x->icon_desc == wdesc)
 12116         return f;
 12117 #endif /* not USE_X_TOOLKIT */
 12118     }
 12119   return 0;
 12120 }
 12121 
 12122 /* Like x_any_window_to_frame but only try to find tooltip frames.
 12123 
 12124    If wdesc is a toolkit tooltip without an associated frame, set
 12125    UNRELATED_TOOLTIP_P to true.  Otherwise, set it to false.  */
 12126 static struct frame *
 12127 x_tooltip_window_to_frame (struct x_display_info *dpyinfo,
 12128                            Window wdesc, bool *unrelated_tooltip_p)
 12129 {
 12130   Lisp_Object tail, frame;
 12131   struct frame *f;
 12132 #ifdef USE_GTK
 12133   GtkWidget *widget;
 12134   GdkWindow *tooltip_window;
 12135 #endif
 12136 
 12137   if (unrelated_tooltip_p)
 12138     *unrelated_tooltip_p = false;
 12139 
 12140   FOR_EACH_FRAME (tail, frame)
 12141     {
 12142       f = XFRAME (frame);
 12143 
 12144       if (FRAME_X_P (f) && FRAME_TOOLTIP_P (f)
 12145           && FRAME_DISPLAY_INFO (f) == dpyinfo
 12146           && FRAME_X_WINDOW (f) == wdesc)
 12147         return f;
 12148 
 12149 #ifdef USE_GTK
 12150       if (!FRAME_X_P (f))
 12151         continue;
 12152 
 12153       if (FRAME_X_OUTPUT (f)->ttip_window)
 12154         widget = GTK_WIDGET (FRAME_X_OUTPUT (f)->ttip_window);
 12155       else
 12156         widget = NULL;
 12157 
 12158       if (widget)
 12159         tooltip_window = gtk_widget_get_window (widget);
 12160       else
 12161         tooltip_window = NULL;
 12162 
 12163 #ifdef HAVE_GTK3
 12164       if (tooltip_window
 12165           && (gdk_x11_window_get_xid (tooltip_window) == wdesc))
 12166         {
 12167           if (unrelated_tooltip_p)
 12168             *unrelated_tooltip_p = true;
 12169           break;
 12170         }
 12171 #else
 12172       if (tooltip_window
 12173           && (GDK_WINDOW_XID (tooltip_window) == wdesc))
 12174         {
 12175           if (unrelated_tooltip_p)
 12176             *unrelated_tooltip_p = true;
 12177           break;
 12178         }
 12179 #endif
 12180 #endif
 12181     }
 12182 
 12183   return NULL;
 12184 }
 12185 
 12186 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
 12187 
 12188 /* Like x_window_to_frame but also compares the window with the widget's
 12189    windows.  */
 12190 
 12191 static struct frame *
 12192 x_any_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
 12193 {
 12194   Lisp_Object tail, frame;
 12195   struct frame *f, *found = NULL;
 12196   struct x_output *x;
 12197 
 12198   if (wdesc == None)
 12199     return NULL;
 12200 
 12201 #ifdef HAVE_XWIDGETS
 12202   struct xwidget_view *xv = xwidget_view_from_window (wdesc);
 12203 
 12204   if (xv)
 12205     return xv->frame;
 12206 #endif
 12207 
 12208   FOR_EACH_FRAME (tail, frame)
 12209     {
 12210       if (found)
 12211         break;
 12212       f = XFRAME (frame);
 12213       if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo)
 12214         {
 12215           /* This frame matches if the window is any of its widgets.  */
 12216           x = f->output_data.x;
 12217           if (x->hourglass_window == wdesc)
 12218             found = f;
 12219           else if (x->widget)
 12220             {
 12221 #ifdef USE_GTK
 12222               GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
 12223               if (gwdesc != 0
 12224                   && gtk_widget_get_toplevel (gwdesc) == x->widget)
 12225                 found = f;
 12226 #else
 12227               if (wdesc == XtWindow (x->widget)
 12228                   || wdesc == XtWindow (x->column_widget)
 12229                   || wdesc == XtWindow (x->edit_widget))
 12230                 found = f;
 12231               /* Match if the window is this frame's menubar.  */
 12232               else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
 12233                 found = f;
 12234 #endif
 12235             }
 12236           else if (FRAME_X_WINDOW (f) == wdesc)
 12237             /* A tooltip frame.  */
 12238             found = f;
 12239         }
 12240     }
 12241 
 12242   return found;
 12243 }
 12244 
 12245 /* Likewise, but consider only the menu bar widget.  */
 12246 
 12247 static struct frame *
 12248 x_menubar_window_to_frame (struct x_display_info *dpyinfo,
 12249                            const XEvent *event)
 12250 {
 12251   Window wdesc;
 12252 #ifdef HAVE_XINPUT2
 12253   if (event->type == GenericEvent
 12254       && dpyinfo->supports_xi2
 12255       && (event->xcookie.evtype == XI_ButtonPress
 12256           || event->xcookie.evtype == XI_ButtonRelease))
 12257     wdesc = ((XIDeviceEvent *) event->xcookie.data)->event;
 12258   else
 12259 #endif
 12260     wdesc = event->xany.window;
 12261   Lisp_Object tail, frame;
 12262   struct frame *f;
 12263   struct x_output *x;
 12264 
 12265   if (wdesc == None)
 12266     return NULL;
 12267 
 12268   FOR_EACH_FRAME (tail, frame)
 12269     {
 12270       f = XFRAME (frame);
 12271       if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
 12272         continue;
 12273       x = f->output_data.x;
 12274 #ifdef USE_GTK
 12275       if (x->menubar_widget && xg_event_is_for_menubar (f, event))
 12276         return f;
 12277 #else
 12278       /* Match if the window is this frame's menubar.  */
 12279       if (x->menubar_widget
 12280           && lw_window_is_in_menubar (wdesc, x->menubar_widget))
 12281         return f;
 12282 #endif
 12283     }
 12284   return 0;
 12285 }
 12286 
 12287 /* Return the frame whose principal (outermost) window is WDESC.
 12288    If WDESC is some other (smaller) window, we return 0.  */
 12289 
 12290 struct frame *
 12291 x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
 12292 {
 12293   Lisp_Object tail, frame;
 12294   struct frame *f;
 12295   struct x_output *x;
 12296 
 12297   if (wdesc == None)
 12298     return NULL;
 12299 
 12300   FOR_EACH_FRAME (tail, frame)
 12301     {
 12302       f = XFRAME (frame);
 12303       if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
 12304         continue;
 12305       x = f->output_data.x;
 12306 
 12307       if (x->widget)
 12308         {
 12309           /* This frame matches if the window is its topmost widget.  */
 12310 #ifdef USE_GTK
 12311           GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
 12312           if (gwdesc == x->widget)
 12313             return f;
 12314 #else
 12315           if (wdesc == XtWindow (x->widget))
 12316             return f;
 12317 #endif
 12318         }
 12319       else if (FRAME_X_WINDOW (f) == wdesc)
 12320         /* Tooltip frame.  */
 12321         return f;
 12322     }
 12323   return 0;
 12324 }
 12325 
 12326 #else /* !USE_X_TOOLKIT && !USE_GTK */
 12327 
 12328 #define x_any_window_to_frame(d, i) x_window_to_frame (d, i)
 12329 
 12330 struct frame *
 12331 x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
 12332 {
 12333   return x_window_to_frame (dpyinfo, wdesc);
 12334 }
 12335 
 12336 static void
 12337 x_next_event_from_any_display (XEvent *event)
 12338 {
 12339   struct x_display_info *dpyinfo;
 12340   fd_set fds, rfds;
 12341   int fd, maxfd, rc;
 12342 
 12343   rc = -1;
 12344   FD_ZERO (&rfds);
 12345 
 12346   while (true)
 12347     {
 12348       FD_ZERO (&fds);
 12349       maxfd = -1;
 12350 
 12351       for (dpyinfo = x_display_list; dpyinfo;
 12352            dpyinfo = dpyinfo->next)
 12353         {
 12354           fd = ConnectionNumber (dpyinfo->display);
 12355 
 12356           if ((rc < 0 || FD_ISSET (fd, &rfds))
 12357               && XPending (dpyinfo->display))
 12358             {
 12359               XNextEvent (dpyinfo->display, event);
 12360               return;
 12361             }
 12362 
 12363           if (fd > maxfd)
 12364             maxfd = fd;
 12365 
 12366           eassert (fd < FD_SETSIZE);
 12367           FD_SET (fd, &fds);
 12368         }
 12369 
 12370       eassert (maxfd >= 0);
 12371 
 12372       /* Continue to read input even if pselect fails, because if an
 12373          error occurs XPending will call the IO error handler, which
 12374          then brings us out of this loop.  */
 12375       rc = pselect (maxfd + 1, &fds, NULL, NULL, NULL, NULL);
 12376 
 12377       if (rc >= 0)
 12378         rfds = fds;
 12379     }
 12380 }
 12381 
 12382 #endif /* USE_X_TOOLKIT || USE_GTK */
 12383 
 12384 static void
 12385 x_handle_pending_selection_requests_1 (struct x_selection_request_event *tem)
 12386 {
 12387   specpdl_ref count;
 12388   struct selection_input_event se;
 12389 
 12390   count = SPECPDL_INDEX ();
 12391   se = tem->se;
 12392 
 12393   record_unwind_protect_ptr (xfree, tem);
 12394   x_handle_selection_event (&se);
 12395   unbind_to (count, Qnil);
 12396 }
 12397 
 12398 /* Handle all pending selection request events from modal event
 12399    loops.  */
 12400 void
 12401 x_handle_pending_selection_requests (void)
 12402 {
 12403   struct x_selection_request_event *tem;
 12404 
 12405   while (pending_selection_requests)
 12406     {
 12407       tem = pending_selection_requests;
 12408       pending_selection_requests = tem->next;
 12409 
 12410       x_handle_pending_selection_requests_1 (tem);
 12411     }
 12412 }
 12413 
 12414 static void
 12415 x_push_selection_request (struct selection_input_event *se)
 12416 {
 12417   struct x_selection_request_event *tem;
 12418 
 12419   tem = xmalloc (sizeof *tem);
 12420   tem->next = pending_selection_requests;
 12421   tem->se = *se;
 12422   pending_selection_requests = tem;
 12423 }
 12424 
 12425 bool
 12426 x_detect_pending_selection_requests (void)
 12427 {
 12428   return !!pending_selection_requests;
 12429 }
 12430 
 12431 static void
 12432 x_clear_dnd_action (void)
 12433 {
 12434   x_dnd_action_symbol = Qnil;
 12435 }
 12436 
 12437 /* Delete action descriptions from F after drag-and-drop.  */
 12438 static void
 12439 x_dnd_delete_action_list (Lisp_Object frame)
 12440 {
 12441   struct frame *f;
 12442 
 12443   /* Delete those two properties, since some clients look at them and
 12444      not the action to decide whether or not the user should be
 12445      prompted to select an action.  This can be called with FRAME no
 12446      longer alive (or its display dead).  */
 12447 
 12448   f = XFRAME (frame);
 12449 
 12450   if (!FRAME_LIVE_P (f) || !FRAME_DISPLAY_INFO (f)->display)
 12451     return;
 12452 
 12453   block_input ();
 12454   XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 12455                    FRAME_DISPLAY_INFO (f)->Xatom_XdndActionList);
 12456   XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 12457                    FRAME_DISPLAY_INFO (f)->Xatom_XdndActionDescription);
 12458   unblock_input ();
 12459 }
 12460 
 12461 static void
 12462 x_dnd_lose_ownership (Lisp_Object timestamp_and_frame)
 12463 {
 12464   struct frame *f;
 12465 
 12466   f = XFRAME (XCDR (timestamp_and_frame));
 12467 
 12468   if (FRAME_LIVE_P (f))
 12469     Fx_disown_selection_internal (QXdndSelection,
 12470                                   XCAR (timestamp_and_frame),
 12471                                   XCDR (timestamp_and_frame));
 12472 }
 12473 
 12474 /* Clean up an existing drag-and-drop operation in preparation for its
 12475    sudden termination.  */
 12476 
 12477 static void
 12478 x_dnd_process_quit (struct frame *f, Time timestamp)
 12479 {
 12480   xm_drop_start_message dmsg;
 12481 
 12482   if (x_dnd_in_progress)
 12483     {
 12484       if (x_dnd_last_seen_window != None
 12485           && x_dnd_last_protocol_version != -1)
 12486         x_dnd_send_leave (f, x_dnd_last_seen_window,
 12487                           x_dnd_last_seen_toplevel);
 12488       else if (x_dnd_last_seen_window != None
 12489                && !XM_DRAG_STYLE_IS_DROP_ONLY (x_dnd_last_motif_style)
 12490                && x_dnd_last_motif_style != XM_DRAG_STYLE_NONE
 12491                && x_dnd_motif_setup_p)
 12492         {
 12493           dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 12494                                         XM_DRAG_REASON_DROP_START);
 12495           dmsg.byte_order = XM_BYTE_ORDER_CUR_FIRST;
 12496           dmsg.timestamp = timestamp;
 12497           dmsg.side_effects
 12498             = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (FRAME_DISPLAY_INFO (f),
 12499                                                                x_dnd_wanted_action),
 12500                                    XM_DROP_SITE_VALID, x_dnd_motif_operations,
 12501                                    XM_DROP_ACTION_DROP_CANCEL);
 12502           dmsg.x = 0;
 12503           dmsg.y = 0;
 12504           dmsg.index_atom = x_dnd_motif_atom;
 12505           dmsg.source_window = FRAME_X_WINDOW (f);
 12506 
 12507           x_dnd_send_xm_leave_for_drop (FRAME_DISPLAY_INFO (f), f,
 12508                                         x_dnd_last_seen_window,
 12509                                         timestamp);
 12510           xm_send_drop_message (FRAME_DISPLAY_INFO (f), FRAME_X_WINDOW (f),
 12511                                 x_dnd_last_seen_window, &dmsg);
 12512         }
 12513 
 12514       x_dnd_end_window = x_dnd_last_seen_window;
 12515       x_dnd_last_seen_window = None;
 12516       x_dnd_last_seen_toplevel = None;
 12517       x_dnd_in_progress = false;
 12518       x_dnd_frame = NULL;
 12519     }
 12520 
 12521   x_dnd_waiting_for_finish = false;
 12522   x_dnd_return_frame_object = NULL;
 12523   x_dnd_movement_frame = NULL;
 12524   x_dnd_wheel_frame = NULL;
 12525 }
 12526 
 12527 /* This function is defined far away from the rest of the XDND code so
 12528    it can utilize `x_any_window_to_frame'.  */
 12529 
 12530 /* Implementors beware!  On most other platforms (where drag-and-drop
 12531    data is not provided via selections, but some kind of serialization
 12532    mechanism), it is usually much easier to implement a suitable
 12533    primitive instead of copying the C code here, and then to build
 12534    `x-begin-drag' on top of that, by making it a wrapper function in
 12535    Lisp that converts the list of targets and value of `XdndSelection'
 12536    to serialized data.  Also be sure to update the data types used in
 12537    dnd.el.
 12538 
 12539    For examples of how to do this, see `haiku-drag-message' and
 12540    `x-begin-drag' in haikuselect.c and lisp/term/haiku-win.el, and
 12541    `ns-begin-drag' and `x-begin-drag' in nsselect.m and
 12542    lisp/term/ns-win.el.  */
 12543 
 12544 Lisp_Object
 12545 x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction,
 12546                            Lisp_Object return_frame, Atom *ask_action_list,
 12547                            const char **ask_action_names, size_t n_ask_actions,
 12548                            bool allow_current_frame, Atom *target_atoms,
 12549                            int ntargets, Lisp_Object selection_target_list,
 12550                            bool follow_tooltip)
 12551 {
 12552 #ifndef USE_GTK
 12553   XEvent next_event;
 12554   int finish;
 12555 #endif
 12556   XWindowAttributes root_window_attrs;
 12557   struct input_event hold_quit;
 12558   char *atom_name, *ask_actions;
 12559   Lisp_Object action, ltimestamp, val;
 12560   specpdl_ref ref, count, base;
 12561   ptrdiff_t i, end, fill;
 12562   XTextProperty prop;
 12563   Lisp_Object frame_object, x, y, frame, local_value;
 12564   bool signals_were_pending, need_sync;
 12565 #ifdef HAVE_XKB
 12566   XkbStateRec keyboard_state;
 12567 #endif
 12568 #ifndef USE_GTK
 12569   struct x_display_info *event_display;
 12570 #endif
 12571   unsigned int additional_mask;
 12572 #ifdef HAVE_XINPUT2
 12573   struct xi_device_t *device;
 12574 #endif
 12575 
 12576   if (FRAME_DISPLAY_INFO (f)->untrusted)
 12577     /* Untrusted clients cannot send messages to trusted clients or
 12578        read the window tree, so drag and drop will likely not work at
 12579        all.  */
 12580     error ("Drag-and-drop is not possible when the client is"
 12581            " not trusted by the X server.");
 12582 
 12583   base = SPECPDL_INDEX ();
 12584 
 12585   /* Bind this here to avoid juggling bindings and SAFE_FREE in
 12586      Fx_begin_drag.  */
 12587   specbind (Qx_dnd_targets_list, selection_target_list);
 12588 
 12589   if (!FRAME_VISIBLE_P (f))
 12590     error ("Frame must be visible");
 12591 
 12592   XSETFRAME (frame, f);
 12593   local_value = assq_no_quit (QXdndSelection,
 12594                               FRAME_TERMINAL (f)->Vselection_alist);
 12595 
 12596   if (x_dnd_in_progress || x_dnd_waiting_for_finish)
 12597     error ("A drag-and-drop session is already in progress");
 12598 
 12599   DEFER_SELECTIONS;
 12600 
 12601   /* If local_value is nil, then we lost ownership of XdndSelection.
 12602      Signal a more informative error than args-out-of-range.  */
 12603   if (NILP (local_value))
 12604     error ("No local value for XdndSelection");
 12605 
 12606   if (popup_activated ())
 12607     error ("Trying to drag-and-drop from within a menu-entry");
 12608 
 12609   x_set_dnd_targets (target_atoms, ntargets);
 12610   record_unwind_protect_void (x_free_dnd_targets);
 12611   record_unwind_protect_void (x_clear_dnd_action);
 12612 
 12613   ltimestamp = x_timestamp_for_selection (FRAME_DISPLAY_INFO (f),
 12614                                           QXdndSelection);
 12615 
 12616   if (NILP (ltimestamp))
 12617     error ("No local value for XdndSelection");
 12618 
 12619   if (BIGNUMP (ltimestamp))
 12620     x_dnd_selection_timestamp = bignum_to_intmax (ltimestamp);
 12621   else
 12622     x_dnd_selection_timestamp = XFIXNUM (ltimestamp);
 12623 
 12624   /* Release ownership of XdndSelection after this function returns.
 12625      VirtualBox uses the owner of XdndSelection to determine whether
 12626      or not mouse motion is part of a drag-and-drop operation.  */
 12627 
 12628   if (!x_dnd_preserve_selection_data)
 12629     record_unwind_protect (x_dnd_lose_ownership,
 12630                            Fcons (ltimestamp, frame));
 12631 
 12632   x_dnd_motif_operations
 12633     = xm_side_effect_from_action (FRAME_DISPLAY_INFO (f), xaction);
 12634 
 12635   x_dnd_first_motif_operation = XM_DRAG_NOOP;
 12636 
 12637   if (n_ask_actions)
 12638     {
 12639       x_dnd_motif_operations
 12640         = xm_operations_from_actions (FRAME_DISPLAY_INFO (f),
 12641                                       ask_action_list,
 12642                                       n_ask_actions);
 12643       x_dnd_first_motif_operation
 12644         = xm_side_effect_from_action (FRAME_DISPLAY_INFO (f),
 12645                                       ask_action_list[0]);
 12646 
 12647       record_unwind_protect (x_dnd_delete_action_list, frame);
 12648 
 12649       ask_actions = NULL;
 12650       end = 0;
 12651       count = SPECPDL_INDEX ();
 12652 
 12653       for (i = 0; i < n_ask_actions; ++i)
 12654         {
 12655           fill = end;
 12656           end += strlen (ask_action_names[i]) + 1;
 12657 
 12658           if (ask_actions)
 12659             ask_actions = xrealloc (ask_actions, end);
 12660           else
 12661             ask_actions = xmalloc (end);
 12662 
 12663           strncpy (ask_actions + fill,
 12664                    ask_action_names[i],
 12665                    end - fill);
 12666         }
 12667 
 12668       prop.value = (unsigned char *) ask_actions;
 12669       prop.encoding = XA_STRING;
 12670       prop.format = 8;
 12671       prop.nitems = end;
 12672 
 12673       record_unwind_protect_ptr (xfree, ask_actions);
 12674 
 12675       /* This can potentially store a lot of data in window
 12676          properties, so check for allocation errors.  */
 12677       block_input ();
 12678       x_catch_errors (FRAME_X_DISPLAY (f));
 12679       XSetTextProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 12680                         &prop, FRAME_DISPLAY_INFO (f)->Xatom_XdndActionDescription);
 12681 
 12682       XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 12683                        FRAME_DISPLAY_INFO (f)->Xatom_XdndActionList, XA_ATOM, 32,
 12684                        PropModeReplace, (unsigned char *) ask_action_list,
 12685                        n_ask_actions);
 12686       x_check_errors (FRAME_X_DISPLAY (f),
 12687                       "Can't set action descriptions: %s");
 12688       x_uncatch_errors_after_check ();
 12689       unblock_input ();
 12690 
 12691       unbind_to (count, Qnil);
 12692     }
 12693 
 12694   record_unwind_protect_void (x_clear_dnd_variables);
 12695 
 12696   if (follow_tooltip)
 12697     {
 12698 #if defined HAVE_XRANDR || defined USE_GTK
 12699       x_dnd_monitors
 12700         = FRAME_DISPLAY_INFO (f)->last_monitor_attributes_list;
 12701 
 12702       if (NILP (x_dnd_monitors))
 12703 #endif
 12704         x_dnd_monitors
 12705           = Fx_display_monitor_attributes_list (frame);
 12706     }
 12707 
 12708   x_dnd_update_tooltip = follow_tooltip;
 12709 
 12710   /* This shouldn't happen.  */
 12711   if (x_dnd_toplevels)
 12712     x_dnd_free_toplevels (true);
 12713 
 12714 #ifdef USE_GTK
 12715   /* Prevent GTK+ timeouts from being run, since they can call
 12716      handle_one_xevent behind our back.  */
 12717   suppress_xg_select ();
 12718   record_unwind_protect_void (release_xg_select);
 12719 #endif
 12720 
 12721   /* Set up a meaningless alias.  */
 12722   XSETCAR (x_dnd_selection_alias_cell, QSECONDARY);
 12723   XSETCDR (x_dnd_selection_alias_cell, QSECONDARY);
 12724 
 12725   /* Bind this here.  The cell doesn't actually alias between
 12726      anything until `xm_setup_dnd_targets' is called.  */
 12727   specbind (Qx_selection_alias_alist,
 12728             Fcons (x_dnd_selection_alias_cell,
 12729                    Vx_selection_alias_alist));
 12730 
 12731   /* Initialize most of the state for the drag-and-drop operation.  */
 12732   x_dnd_in_progress = true;
 12733   x_dnd_recursion_depth = command_loop_level + minibuf_level;
 12734   x_dnd_frame = f;
 12735   x_dnd_last_seen_window = None;
 12736   x_dnd_last_seen_toplevel = None;
 12737   x_dnd_last_protocol_version = -1;
 12738   x_dnd_last_window_is_frame = false;
 12739   x_dnd_last_motif_style = XM_DRAG_STYLE_NONE;
 12740   x_dnd_mouse_rect_target = None;
 12741   x_dnd_action = None;
 12742   x_dnd_action_symbol = Qnil;
 12743   x_dnd_wanted_action = xaction;
 12744   x_dnd_return_frame = 0;
 12745   x_dnd_waiting_for_finish = false;
 12746   x_dnd_waiting_for_motif_finish = 0;
 12747   x_dnd_waiting_for_status_window = None;
 12748   x_dnd_pending_send_position.type = 0;
 12749   x_dnd_xm_use_help = false;
 12750   x_dnd_motif_setup_p = false;
 12751   x_dnd_end_window = None;
 12752   x_dnd_run_unsupported_drop_function = false;
 12753   x_dnd_use_toplevels
 12754     = x_wm_supports (f, FRAME_DISPLAY_INFO (f)->Xatom_net_client_list_stacking);
 12755   x_dnd_last_tooltip_valid = false;
 12756   x_dnd_toplevels = NULL;
 12757   x_dnd_allow_current_frame = allow_current_frame;
 12758   x_dnd_movement_frame = NULL;
 12759   x_dnd_wheel_frame = NULL;
 12760   x_dnd_init_type_lists = false;
 12761   x_dnd_need_send_drop = false;
 12762 
 12763 #ifdef HAVE_XINPUT2
 12764 
 12765   if (FRAME_DISPLAY_INFO (f)->supports_xi2)
 12766     {
 12767       /* Only accept input from the last master pointer to have interacted
 12768          with Emacs.  This prevents another pointer device getting our
 12769          idea of the button state messed up.  */
 12770       if (FRAME_DISPLAY_INFO (f)->client_pointer_device != -1)
 12771         x_dnd_pointer_device
 12772           = FRAME_DISPLAY_INFO (f)->client_pointer_device;
 12773       else
 12774         /* This returns Bool but cannot actually fail.  */
 12775         XIGetClientPointer (FRAME_X_DISPLAY (f), None,
 12776                             &x_dnd_pointer_device);
 12777 
 12778       x_dnd_keyboard_device = -1;
 12779 
 12780       device = xi_device_from_id (FRAME_DISPLAY_INFO (f),
 12781                                   x_dnd_pointer_device);
 12782 
 12783       if (device)
 12784         x_dnd_keyboard_device = device->attachment;
 12785     }
 12786   else
 12787     {
 12788       x_dnd_pointer_device = -1;
 12789       x_dnd_keyboard_device = -1;
 12790     }
 12791 
 12792 #endif
 12793 
 12794 #ifdef HAVE_XKB
 12795   x_dnd_keyboard_state = 0;
 12796 
 12797   if (FRAME_DISPLAY_INFO (f)->supports_xkb)
 12798     {
 12799       XkbSelectEvents (FRAME_X_DISPLAY (f), XkbUseCoreKbd,
 12800                        XkbStateNotifyMask, XkbStateNotifyMask);
 12801       XkbGetState (FRAME_X_DISPLAY (f), XkbUseCoreKbd,
 12802                    &keyboard_state);
 12803 
 12804       x_dnd_keyboard_state = (keyboard_state.mods
 12805                               | keyboard_state.ptr_buttons);
 12806     }
 12807 #endif
 12808 
 12809   if (x_dnd_use_toplevels)
 12810     {
 12811       if (x_dnd_compute_toplevels (FRAME_DISPLAY_INFO (f)))
 12812         {
 12813           x_dnd_free_toplevels (true);
 12814           x_dnd_use_toplevels = false;
 12815         }
 12816       else
 12817         record_unwind_protect_void (x_free_dnd_toplevels);
 12818     }
 12819 
 12820   if (!NILP (return_frame))
 12821     x_dnd_return_frame = 1;
 12822 
 12823   if (EQ (return_frame, Qnow))
 12824     x_dnd_return_frame = 2;
 12825 
 12826   /* Now select for SubstructureNotifyMask and PropertyChangeMask on
 12827      the root window, so we can get notified when window stacking
 12828      changes, a common operation during drag-and-drop.  */
 12829 
 12830   XGetWindowAttributes (FRAME_X_DISPLAY (f),
 12831                         FRAME_DISPLAY_INFO (f)->root_window,
 12832                         &root_window_attrs);
 12833 
 12834   additional_mask = SubstructureNotifyMask;
 12835 
 12836   if (x_dnd_use_toplevels)
 12837     additional_mask |= PropertyChangeMask;
 12838 
 12839   XSelectInput (FRAME_X_DISPLAY (f),
 12840                 FRAME_DISPLAY_INFO (f)->root_window,
 12841                 root_window_attrs.your_event_mask
 12842                 | additional_mask);
 12843 
 12844   if (EQ (return_frame, Qnow))
 12845     x_dnd_update_state (FRAME_DISPLAY_INFO (f), CurrentTime);
 12846 
 12847   while (x_dnd_in_progress || x_dnd_waiting_for_finish)
 12848     {
 12849       EVENT_INIT (hold_quit);
 12850 
 12851 #ifdef USE_GTK
 12852       current_finish = X_EVENT_NORMAL;
 12853       current_hold_quit = &hold_quit;
 12854       current_count = 0;
 12855       xg_pending_quit_event.kind = NO_EVENT;
 12856 #endif
 12857 
 12858       block_input ();
 12859       x_dnd_inside_handle_one_xevent = true;
 12860 #ifdef USE_GTK
 12861       gtk_main_iteration ();
 12862 #elif defined USE_X_TOOLKIT
 12863       XtAppNextEvent (Xt_app_con, &next_event);
 12864 #else
 12865       x_next_event_from_any_display (&next_event);
 12866 #endif
 12867 
 12868 #ifndef USE_GTK
 12869       event_display
 12870         = x_display_info_for_display (next_event.xany.display);
 12871 
 12872       if (event_display)
 12873         {
 12874 #ifdef HAVE_X_I18N
 12875 #ifdef HAVE_XINPUT2
 12876           if (next_event.type != GenericEvent
 12877               || !event_display->supports_xi2
 12878               || (next_event.xgeneric.extension
 12879                   != event_display->xi2_opcode))
 12880             {
 12881 #endif
 12882               if (!x_filter_event (event_display, &next_event))
 12883                 handle_one_xevent (event_display,
 12884                                    &next_event, &finish, &hold_quit);
 12885 #ifdef HAVE_XINPUT2
 12886             }
 12887           else
 12888             handle_one_xevent (event_display,
 12889                                &next_event, &finish, &hold_quit);
 12890 #endif
 12891 #else
 12892           handle_one_xevent (event_display,
 12893                              &next_event, &finish, &hold_quit);
 12894 #endif
 12895         }
 12896 #else
 12897       /* Clear these before the read_socket_hook can be called.  */
 12898       current_count = -1;
 12899       current_hold_quit = NULL;
 12900 #endif
 12901       x_dnd_inside_handle_one_xevent = false;
 12902 
 12903       /* Clean up any event handlers that are now out of date.  */
 12904       x_clean_failable_requests (FRAME_DISPLAY_INFO (f));
 12905 
 12906       /* The unblock_input below might try to read input, but
 12907          XTread_socket does nothing inside a drag-and-drop event
 12908          loop, so don't let it clear the pending_signals flag.  */
 12909       signals_were_pending = pending_signals;
 12910       unblock_input ();
 12911       pending_signals = signals_were_pending;
 12912 
 12913       /* Ignore mouse movement from displays that aren't the DND
 12914          display.  */
 12915 #ifndef USE_GTK
 12916       if (event_display == FRAME_DISPLAY_INFO (f))
 12917         {
 12918 #endif
 12919           if (x_dnd_movement_frame
 12920               /* FIXME: how come this can end up with movement frames
 12921                  from other displays on GTK builds?  */
 12922               && (FRAME_X_DISPLAY (x_dnd_movement_frame)
 12923                   == FRAME_X_DISPLAY (f))
 12924               /* If both those variables are false, then F is no
 12925                  longer protected from deletion by Lisp code.  This
 12926                  can only happen during the final iteration of the DND
 12927                  event loop.  */
 12928               && (x_dnd_in_progress || x_dnd_waiting_for_finish))
 12929             {
 12930               XSETFRAME (frame_object, x_dnd_movement_frame);
 12931               XSETINT (x, x_dnd_movement_x);
 12932               XSETINT (y, x_dnd_movement_y);
 12933               x_dnd_movement_frame = NULL;
 12934 
 12935               if (!NILP (Vx_dnd_movement_function)
 12936                   && FRAME_LIVE_P (XFRAME (frame_object))
 12937                   && !FRAME_TOOLTIP_P (XFRAME (frame_object))
 12938                   && x_dnd_movement_x >= 0
 12939                   && x_dnd_movement_y >= 0
 12940                   && x_dnd_frame
 12941                   && (XFRAME (frame_object) != x_dnd_frame
 12942                       || x_dnd_allow_current_frame))
 12943                 {
 12944                   x_dnd_old_window_attrs = root_window_attrs;
 12945                   x_dnd_unwind_flag = true;
 12946 
 12947                   ref = SPECPDL_INDEX ();
 12948                   record_unwind_protect_ptr (x_dnd_cleanup_drag_and_drop, f);
 12949                   call2 (Vx_dnd_movement_function, frame_object,
 12950                          Fposn_at_x_y (x, y, frame_object, Qnil));
 12951                   x_dnd_unwind_flag = false;
 12952                   unbind_to (ref, Qnil);
 12953 
 12954                   /* Redisplay this way to preserve the echo area.
 12955                      Otherwise, the contents will abruptly disappear
 12956                      when the mouse moves over a frame.  */
 12957                   redisplay_preserve_echo_area (33);
 12958                 }
 12959             }
 12960 
 12961           if (x_dnd_wheel_frame
 12962               && (x_dnd_in_progress || x_dnd_waiting_for_finish))
 12963             {
 12964               XSETFRAME (frame_object, x_dnd_wheel_frame);
 12965               XSETINT (x, x_dnd_wheel_x);
 12966               XSETINT (y, x_dnd_wheel_y);
 12967               x_dnd_wheel_frame = NULL;
 12968 
 12969               if (!NILP (Vx_dnd_wheel_function)
 12970                   && FRAME_LIVE_P (XFRAME (frame_object))
 12971                   && !FRAME_TOOLTIP_P (XFRAME (frame_object))
 12972                   && x_dnd_movement_x >= 0
 12973                   && x_dnd_movement_y >= 0
 12974                   && x_dnd_frame
 12975                   && (XFRAME (frame_object) != x_dnd_frame
 12976                       || x_dnd_allow_current_frame))
 12977                 {
 12978                   x_dnd_old_window_attrs = root_window_attrs;
 12979                   x_dnd_unwind_flag = true;
 12980 
 12981                   ref = SPECPDL_INDEX ();
 12982                   record_unwind_protect_ptr (x_dnd_cleanup_drag_and_drop, f);
 12983                   call4 (Vx_dnd_wheel_function,
 12984                          Fposn_at_x_y (x, y, frame_object, Qnil),
 12985                          make_fixnum (x_dnd_wheel_button),
 12986                          make_uint (x_dnd_wheel_state),
 12987                          make_uint (x_dnd_wheel_time));
 12988                   x_dnd_unwind_flag = false;
 12989                   unbind_to (ref, Qnil);
 12990 
 12991                   /* Redisplay this way to preserve the echo area.
 12992                      Otherwise, the contents will abruptly disappear
 12993                      when the mouse moves over a frame.  */
 12994                   redisplay_preserve_echo_area (33);
 12995                 }
 12996             }
 12997 
 12998           if (hold_quit.kind != NO_EVENT)
 12999             {
 13000               x_dnd_process_quit (f, hold_quit.timestamp);
 13001 #ifdef USE_GTK
 13002               current_hold_quit = NULL;
 13003 #endif
 13004               /* Restore the old event mask.  */
 13005               x_restore_events_after_dnd (f, &root_window_attrs);
 13006 
 13007               /* Call kbd_buffer_store event, which calls
 13008                  handle_interrupt and sets `last-event-frame' along
 13009                  with various other things.  */
 13010               kbd_buffer_store_event (&hold_quit);
 13011               /* Now quit anyway.  */
 13012               quit ();
 13013             }
 13014 
 13015           if (pending_selection_requests
 13016               && (x_dnd_in_progress || x_dnd_waiting_for_finish))
 13017             {
 13018               x_dnd_old_window_attrs = root_window_attrs;
 13019               x_dnd_unwind_flag = true;
 13020 
 13021               ref = SPECPDL_INDEX ();
 13022               record_unwind_protect_ptr (x_dnd_cleanup_drag_and_drop, f);
 13023               x_handle_pending_selection_requests ();
 13024               x_dnd_unwind_flag = false;
 13025               unbind_to (ref, Qnil);
 13026             }
 13027 
 13028           /* Sometimes C-g can be pressed inside a selection
 13029              converter, where quitting is inhibited.  We want
 13030              to quit after the converter exits.  */
 13031           if (!NILP (Vquit_flag) && !NILP (Vinhibit_quit))
 13032             {
 13033               x_dnd_process_quit (f, FRAME_DISPLAY_INFO (f)->last_user_time);
 13034 #ifdef USE_GTK
 13035               current_hold_quit = NULL;
 13036 #endif
 13037               x_restore_events_after_dnd (f, &root_window_attrs);
 13038               quit ();
 13039             }
 13040 
 13041           if (x_dnd_run_unsupported_drop_function
 13042               && x_dnd_waiting_for_finish)
 13043             {
 13044               x_dnd_run_unsupported_drop_function = false;
 13045               x_dnd_waiting_for_finish = false;
 13046               x_dnd_unwind_flag = true;
 13047 
 13048               ref = SPECPDL_INDEX ();
 13049               record_unwind_protect_ptr (x_dnd_cleanup_drag_and_drop, f);
 13050 
 13051               if (!NILP (Vx_dnd_unsupported_drop_function))
 13052                 val = call8 (Vx_dnd_unsupported_drop_function,
 13053                              XCAR (XCDR (x_dnd_unsupported_drop_data)),
 13054                              Fnth (make_fixnum (3), x_dnd_unsupported_drop_data),
 13055                              Fnth (make_fixnum (4), x_dnd_unsupported_drop_data),
 13056                              Fnth (make_fixnum (2), x_dnd_unsupported_drop_data),
 13057                              make_uint (x_dnd_unsupported_drop_window),
 13058                              frame, make_uint (x_dnd_unsupported_drop_time),
 13059                              Fcopy_sequence (XCAR (x_dnd_unsupported_drop_data)));
 13060               else
 13061                 val = Qnil;
 13062 
 13063               if (NILP (val))
 13064                 x_dnd_do_unsupported_drop (FRAME_DISPLAY_INFO (f),
 13065                                            frame, XCAR (x_dnd_unsupported_drop_data),
 13066                                            XCAR (XCDR (x_dnd_unsupported_drop_data)),
 13067                                            x_dnd_unsupported_drop_window,
 13068                                            XFIXNUM (Fnth (make_fixnum (3),
 13069                                                           x_dnd_unsupported_drop_data)),
 13070                                            XFIXNUM (Fnth (make_fixnum (4),
 13071                                                           x_dnd_unsupported_drop_data)),
 13072                                            x_dnd_unsupported_drop_time);
 13073               else if (SYMBOLP (val))
 13074                 x_dnd_action_symbol = val;
 13075 
 13076               x_dnd_unwind_flag = false;
 13077               unbind_to (ref, Qnil);
 13078 
 13079               /* Break out of the loop now, since DND has
 13080                  completed.  */
 13081               break;
 13082             }
 13083 
 13084 #ifdef USE_GTK
 13085           if (xg_pending_quit_event.kind != NO_EVENT)
 13086             {
 13087               xg_pending_quit_event.kind = NO_EVENT;
 13088               current_hold_quit = NULL;
 13089 
 13090               x_dnd_process_quit (f, FRAME_DISPLAY_INFO (f)->last_user_time);
 13091               x_restore_events_after_dnd (f, &root_window_attrs);
 13092               quit ();
 13093             }
 13094 #else
 13095         }
 13096       else
 13097         {
 13098           if (x_dnd_movement_frame)
 13099             x_dnd_movement_frame = NULL;
 13100 
 13101           if (x_dnd_wheel_frame)
 13102             x_dnd_wheel_frame = NULL;
 13103 
 13104           if (hold_quit.kind != NO_EVENT)
 13105             EVENT_INIT (hold_quit);
 13106         }
 13107 #endif
 13108     }
 13109 
 13110   x_dnd_waiting_for_finish = false;
 13111 
 13112 #ifdef USE_GTK
 13113   current_hold_quit = NULL;
 13114 #endif
 13115   x_dnd_movement_frame = NULL;
 13116   x_dnd_wheel_frame = NULL;
 13117   x_restore_events_after_dnd (f, &root_window_attrs);
 13118 
 13119   if (x_dnd_return_frame == 3
 13120       && FRAME_LIVE_P (x_dnd_return_frame_object))
 13121     {
 13122       /* Deliberately preserve the last device if
 13123          x_dnd_return_frame_object is the drag source.  */
 13124 
 13125       if (x_dnd_return_frame_object != x_dnd_frame)
 13126         x_dnd_return_frame_object->last_mouse_device = Qnil;
 13127 
 13128       x_dnd_return_frame_object->mouse_moved = true;
 13129 
 13130       XSETFRAME (action, x_dnd_return_frame_object);
 13131       x_dnd_return_frame_object = NULL;
 13132 
 13133       return unbind_to (base, action);
 13134     }
 13135 
 13136   x_dnd_return_frame_object = NULL;
 13137   FRAME_DISPLAY_INFO (f)->grabbed = 0;
 13138 
 13139   if (!NILP (x_dnd_action_symbol))
 13140     return unbind_to (base, x_dnd_action_symbol);
 13141 
 13142   if (x_dnd_action != None)
 13143     {
 13144       block_input ();
 13145       x_catch_errors (FRAME_X_DISPLAY (f));
 13146       atom_name = x_get_atom_name (FRAME_DISPLAY_INFO (f),
 13147                                    x_dnd_action, &need_sync);
 13148 
 13149       if (need_sync)
 13150         x_uncatch_errors ();
 13151       else
 13152         /* No protocol request actually happened, so avoid the extra
 13153            sync by calling x_uncatch_errors_after_check instead.  */
 13154         x_uncatch_errors_after_check ();
 13155 
 13156       if (atom_name)
 13157         {
 13158           action = intern (atom_name);
 13159           xfree (atom_name);
 13160         }
 13161       else
 13162         action = Qnil;
 13163       unblock_input ();
 13164 
 13165       return unbind_to (base, action);
 13166     }
 13167 
 13168   return unbind_to (base, Qnil);
 13169 }
 13170 
 13171 #ifdef HAVE_XINPUT2
 13172 
 13173 /* Since the input extension assigns a keyboard focus to each master
 13174    device, there is no longer a 1:1 correspondence between the
 13175    selected frame and the focus frame immediately after the keyboard
 13176    focus is switched to a given frame.  This situation is handled by
 13177    keeping track of each master device's focus frame, the time of the
 13178    last interaction with that frame, and always keeping the focus on
 13179    the most recently selected frame.  We also use the pointer of the
 13180    device that is keeping the current frame focused in functions like
 13181    `mouse-position'.  */
 13182 
 13183 static void
 13184 xi_handle_focus_change (struct x_display_info *dpyinfo)
 13185 {
 13186   struct input_event ie;
 13187   struct frame *focus, *new;
 13188   struct xi_device_t *device, *source = NULL;
 13189   ptrdiff_t i;
 13190   Time time;
 13191 #ifdef USE_GTK
 13192   struct x_output *output;
 13193   GtkWidget *widget;
 13194 #endif
 13195 
 13196   focus = dpyinfo->x_focus_frame;
 13197   new = NULL;
 13198   time = 0;
 13199 
 13200   dpyinfo->client_pointer_device = -1;
 13201 
 13202   for (i = 0; i < dpyinfo->num_devices; ++i)
 13203     {
 13204       device = &dpyinfo->devices[i];
 13205 
 13206       if (device->focus_frame
 13207           && device->focus_frame_time > time)
 13208         {
 13209           new = device->focus_frame;
 13210           time = device->focus_frame_time;
 13211           source = device;
 13212 
 13213           /* Use this device for future calls to `mouse-position' etc.
 13214              If it is a keyboard, use its attached pointer.  */
 13215 
 13216           if (device->use == XIMasterKeyboard)
 13217             dpyinfo->client_pointer_device = device->attachment;
 13218           else
 13219             dpyinfo->client_pointer_device = device->device_id;
 13220         }
 13221       /* Even if the implicit focus was set after the explicit focus
 13222          on this specific device, the explicit focus is what really
 13223          matters.  So use it instead.  */
 13224       else if (device->focus_implicit_frame
 13225                && device->focus_implicit_time > time)
 13226         {
 13227           new = device->focus_implicit_frame;
 13228           time = device->focus_implicit_time;
 13229           source = device;
 13230 
 13231           /* Use this device for future calls to `mouse-position' etc.
 13232              If it is a keyboard, use its attached pointer.  */
 13233 
 13234           if (device->use == XIMasterKeyboard)
 13235             dpyinfo->client_pointer_device = device->attachment;
 13236           else
 13237             dpyinfo->client_pointer_device = device->device_id;
 13238         }
 13239     }
 13240 
 13241   if (new != focus && focus)
 13242     {
 13243 #ifdef HAVE_X_I18N
 13244       if (FRAME_XIC (focus))
 13245         XUnsetICFocus (FRAME_XIC (focus));
 13246 #endif
 13247 
 13248 #ifdef USE_GTK
 13249       output = FRAME_X_OUTPUT (focus);
 13250 
 13251       if (x_gtk_use_native_input)
 13252         {
 13253           gtk_im_context_focus_out (output->im_context);
 13254           gtk_im_context_set_client_window (output->im_context,
 13255                                             NULL);
 13256         }
 13257 #endif
 13258 
 13259       EVENT_INIT (ie);
 13260       ie.kind = FOCUS_OUT_EVENT;
 13261       XSETFRAME (ie.frame_or_window, focus);
 13262 
 13263       kbd_buffer_store_event (&ie);
 13264     }
 13265 
 13266   if (new != focus && new)
 13267     {
 13268 #ifdef HAVE_X_I18N
 13269       if (FRAME_XIC (new))
 13270         XSetICFocus (FRAME_XIC (new));
 13271 #endif
 13272 
 13273 #ifdef USE_GTK
 13274       output = FRAME_X_OUTPUT (new);
 13275 
 13276       if (x_gtk_use_native_input)
 13277         {
 13278           widget = FRAME_GTK_OUTER_WIDGET (new);
 13279 
 13280           gtk_im_context_focus_in (output->im_context);
 13281           gtk_im_context_set_client_window (output->im_context,
 13282                                             gtk_widget_get_window (widget));
 13283         }
 13284 #endif
 13285 
 13286       EVENT_INIT (ie);
 13287       ie.kind = FOCUS_IN_EVENT;
 13288       ie.device = source->name;
 13289       XSETFRAME (ie.frame_or_window, new);
 13290 
 13291       kbd_buffer_store_event (&ie);
 13292     }
 13293 
 13294   x_new_focus_frame (dpyinfo, new);
 13295 }
 13296 
 13297 static void
 13298 xi_focus_handle_for_device (struct x_display_info *dpyinfo,
 13299                             struct frame *mentioned_frame,
 13300                             XIEvent *base_event)
 13301 {
 13302   struct xi_device_t *device;
 13303   XIEnterEvent *event;
 13304 
 13305   /* XILeaveEvent, XIFocusInEvent, etc are just synonyms for
 13306      XIEnterEvent.  */
 13307   event = (XIEnterEvent *) base_event;
 13308   device = xi_device_from_id (dpyinfo, event->deviceid);
 13309 
 13310   if (!device)
 13311     return;
 13312 
 13313   switch (event->evtype)
 13314     {
 13315     case XI_FocusIn:
 13316       /* The last-focus-change time of the device changed, so update the
 13317          frame's user time.  */
 13318       x_display_set_last_user_time (dpyinfo, event->time,
 13319                                     event->send_event, true);
 13320 
 13321       device->focus_frame = mentioned_frame;
 13322       device->focus_frame_time = event->time;
 13323       break;
 13324 
 13325     case XI_FocusOut:
 13326       /* The last-focus-change time of the device changed, so update the
 13327          frame's user time.  */
 13328       x_display_set_last_user_time (dpyinfo, event->time,
 13329                                     event->send_event, false);
 13330 
 13331       device->focus_frame = NULL;
 13332 
 13333       /* So, unfortunately, the X Input Extension is implemented such
 13334          that means XI_Leave events will not have their focus field
 13335          set if the core focus is transferred to another window after
 13336          an entry event that pretends to (or really does) set the
 13337          implicit focus.  In addition, if the core focus is set, but
 13338          the extension focus on the client pointer is not, all
 13339          XI_Enter events will have their focus fields set, despite not
 13340          actually changing the effective focus window.  Combined with
 13341          almost all window managers not setting the focus on input
 13342          extension devices, this means that Emacs will continue to
 13343          think the implicit focus is set on one of its frames if the
 13344          actual (core) focus is transferred to another window while
 13345          the pointer remains inside a frame.  The only workaround in
 13346          this case is to clear the implicit focus along with
 13347          XI_FocusOut events, which is not correct at all, but better
 13348          than leaving frames in an incorrectly-focused state.
 13349          (bug#57468) */
 13350       device->focus_implicit_frame = NULL;
 13351       break;
 13352 
 13353     case XI_Enter:
 13354       if (!event->focus)
 13355         break;
 13356 
 13357       if (device->use == XIMasterPointer)
 13358         device = xi_device_from_id (dpyinfo, device->attachment);
 13359 
 13360       if (!device)
 13361         break;
 13362 
 13363       device->focus_implicit_frame = mentioned_frame;
 13364       device->focus_implicit_time = event->time;
 13365       break;
 13366 
 13367     case XI_Leave:
 13368       if (!event->focus)
 13369         break;
 13370 
 13371       if (device->use == XIMasterPointer)
 13372         device = xi_device_from_id (dpyinfo, device->attachment);
 13373 
 13374       if (!device)
 13375         break;
 13376 
 13377       device->focus_implicit_frame = NULL;
 13378       break;
 13379     }
 13380 
 13381   xi_handle_focus_change (dpyinfo);
 13382 }
 13383 
 13384 static void
 13385 xi_handle_delete_frame (struct x_display_info *dpyinfo,
 13386                         struct frame *f)
 13387 {
 13388   struct xi_device_t *device;
 13389   ptrdiff_t i;
 13390 
 13391   for (i = 0; i < dpyinfo->num_devices; ++i)
 13392     {
 13393       device = &dpyinfo->devices[i];
 13394 
 13395       if (device->focus_frame == f)
 13396         device->focus_frame = NULL;
 13397 
 13398       if (device->focus_implicit_frame == f)
 13399         device->focus_implicit_frame = NULL;
 13400     }
 13401 }
 13402 
 13403 /* Handle an interaction by DEVICE on frame F.  TIME is the time of
 13404    the interaction; if F isn't currently the global focus frame, but
 13405    is the focus of DEVICE, make it the focus frame.  */
 13406 
 13407 static void
 13408 xi_handle_interaction (struct x_display_info *dpyinfo,
 13409                        struct frame *f, struct xi_device_t *device,
 13410                        Time time)
 13411 {
 13412   bool change;
 13413 
 13414   /* If DEVICE is a pointer, use its attached keyboard device.  */
 13415   if (device->use == XIMasterPointer)
 13416     device = xi_device_from_id (dpyinfo, device->attachment);
 13417 
 13418   if (!device)
 13419     return;
 13420 
 13421   change = false;
 13422 
 13423   if (device->focus_frame == f)
 13424     {
 13425       device->focus_frame_time = time;
 13426       change = true;
 13427     }
 13428 
 13429   if (device->focus_implicit_frame == f)
 13430     {
 13431       device->focus_implicit_time = time;
 13432       change = true;
 13433     }
 13434 
 13435   /* If F isn't currently focused, update the focus state.  */
 13436   if (change && f != dpyinfo->x_focus_frame)
 13437     xi_handle_focus_change (dpyinfo);
 13438 }
 13439 
 13440 /* Return whether or not XEV actually represents a change in the
 13441    position of the pointer on DEVICE, with respect to the last event
 13442    received.  This is necessary because the input extension reports
 13443    motion events in very high resolution, while Emacs is only fast
 13444    enough to process motion events aligned to the pixel grid.  */
 13445 
 13446 static bool
 13447 xi_position_changed (struct xi_device_t *device, XIDeviceEvent *xev)
 13448 {
 13449   bool changed;
 13450 
 13451   changed = true;
 13452 
 13453   if (xev->event != device->last_motion_window)
 13454     goto out;
 13455 
 13456   if (lrint (xev->event_x) == device->last_motion_x
 13457       && lrint (xev->event_y) == device->last_motion_y)
 13458     {
 13459       changed = false;
 13460       goto out;
 13461     }
 13462 
 13463  out:
 13464   device->last_motion_x = lrint (xev->event_x);
 13465   device->last_motion_y = lrint (xev->event_y);
 13466   device->last_motion_window = xev->event;
 13467 
 13468   return changed;
 13469 }
 13470 
 13471 static void
 13472 xi_report_motion_window_clear (struct xi_device_t *device)
 13473 {
 13474   device->last_motion_window = None;
 13475 }
 13476 
 13477 #ifdef HAVE_XINPUT2_1
 13478 
 13479 /* Look up a scroll valuator in DEVICE by NUMBER.  */
 13480 
 13481 static struct xi_scroll_valuator_t *
 13482 xi_get_scroll_valuator (struct xi_device_t *device, int number)
 13483 {
 13484   int i;
 13485 
 13486   for (i = 0; i < device->scroll_valuator_count; ++i)
 13487     {
 13488       if (device->valuators[i].number == number)
 13489         return &device->valuators[i];
 13490     }
 13491 
 13492   return NULL;
 13493 }
 13494 
 13495 /* Check if EVENT, a DeviceChanged event, contains any scroll
 13496    valuators.  */
 13497 
 13498 static bool
 13499 xi_has_scroll_valuators (XIDeviceChangedEvent *event)
 13500 {
 13501   int i;
 13502 
 13503   for (i = 0; i < event->num_classes; ++i)
 13504     {
 13505       if (event->classes[i]->type == XIScrollClass)
 13506         return true;
 13507     }
 13508 
 13509   return false;
 13510 }
 13511 
 13512 /* Repopulate the information (touchpoint tracking information, scroll
 13513    valuators, etc) in DEVICE with the device classes provided in
 13514    CLASSES.  This is called upon receiving a DeviceChanged event.
 13515 
 13516    This function is not present on XI 2.0 as there are no worthwhile
 13517    classes there.  */
 13518 
 13519 static void
 13520 xi_handle_new_classes (struct x_display_info *dpyinfo, struct xi_device_t *device,
 13521                        XIAnyClassInfo **classes, int num_classes)
 13522 {
 13523   XIScrollClassInfo *scroll;
 13524   struct xi_scroll_valuator_t *valuator;
 13525   XIValuatorClassInfo *valuator_info;
 13526   int i;
 13527 #ifdef HAVE_XINPUT2_2
 13528   XITouchClassInfo *touch;
 13529 #endif
 13530 
 13531   if (dpyinfo->xi2_version < 1)
 13532     /* Emacs is connected to an XI 2.0 server, which reports no
 13533        classes of interest.  */
 13534     return;
 13535 
 13536   device->valuators = xnmalloc (num_classes,
 13537                                 sizeof *device->valuators);
 13538   device->scroll_valuator_count = 0;
 13539 #ifdef HAVE_XINPUT2_2
 13540   device->direct_p = false;
 13541 #endif /* HAVE_XINPUT2_2 */
 13542 
 13543   for (i = 0; i < num_classes; ++i)
 13544     {
 13545       switch (classes[i]->type)
 13546         {
 13547         case XIScrollClass:
 13548           scroll = (XIScrollClassInfo *) classes[i];
 13549 
 13550           xi_populate_scroll_valuator (device,
 13551                                        device->scroll_valuator_count++,
 13552                                        scroll);
 13553           break;
 13554 
 13555 #ifdef HAVE_XINPUT2_2
 13556         case XITouchClass:
 13557           touch = (XITouchClassInfo *) classes[i];
 13558 
 13559           /* touch_info->mode indicates the coordinate space that this
 13560              device reports in its touch events.
 13561 
 13562              DirectTouch means that the device uses a coordinate space
 13563              that corresponds to locations on the screen.  It is set
 13564              by touch screen devices which are overlaid over the
 13565              raster itself.
 13566 
 13567              The other value (DependentTouch) means that the device
 13568              uses a separate abstract coordinate space corresponding
 13569              to its own surface.  Emacs ignores events from these
 13570              devices because it does not support recognizing touch
 13571              gestures from surfaces other than the screen.
 13572 
 13573              Master devices may report multiple touch classes for
 13574              attached slave devices, leaving the nature of touch
 13575              events they send ambiguous.  The problem of
 13576              discriminating between these events is bypassed entirely
 13577              through only processing touch events from the slave
 13578              devices where they originate.  */
 13579 
 13580           if (touch->mode == XIDirectTouch)
 13581             device->direct_p = true;
 13582           else
 13583             device->direct_p = false;
 13584 
 13585           break;
 13586 #endif /* HAVE_XINPUT2_2 */
 13587         }
 13588     }
 13589 
 13590   /* Restore the values of any scroll valuators that we already
 13591      know about.  */
 13592 
 13593   for (i = 0; i < num_classes; ++i)
 13594     {
 13595       if (classes[i]->type != XIValuatorClass)
 13596         continue;
 13597 
 13598       valuator_info = (XIValuatorClassInfo *) classes[i];
 13599 
 13600       /* Avoid restoring bogus values if some driver accidentally
 13601          specifies relative values in scroll valuator classes how the
 13602          input extension spec says they should be, but allow restoring
 13603          values when a value is set, which is how the input extension
 13604          actually behaves.  */
 13605 
 13606       if (valuator_info->value == 0.0
 13607           && valuator_info->mode != XIModeAbsolute)
 13608         continue;
 13609 
 13610       valuator = xi_get_scroll_valuator (device,
 13611                                          valuator_info->number);
 13612 
 13613       if (!valuator)
 13614         continue;
 13615 
 13616       valuator->invalid_p = false;
 13617       valuator->current_value = valuator_info->value;
 13618       valuator->emacs_value = 0;
 13619 
 13620       break;
 13621     }
 13622 }
 13623 
 13624 #endif /* HAVE_XINPUT2_1 */
 13625 
 13626 /* Handle EVENT, a DeviceChanged event.  Look up the device that
 13627    changed, and update its information with the data in EVENT.  */
 13628 
 13629 static void
 13630 xi_handle_device_changed (struct x_display_info *dpyinfo,
 13631                           struct xi_device_t *device,
 13632                           XIDeviceChangedEvent *event)
 13633 {
 13634 #ifdef HAVE_XINPUT2_1
 13635   int ndevices;
 13636   XIDeviceInfo *info;
 13637 #endif
 13638 #ifdef HAVE_XINPUT2_2
 13639   struct xi_touch_point_t *tem, *last;
 13640 #endif
 13641 
 13642 #ifdef HAVE_XINPUT2_1
 13643   if (xi_has_scroll_valuators (event))
 13644     /* Scroll valuators are provided by this event.  Use the values
 13645        provided in this event to populate the device's new scroll
 13646        valuator list: if this event is a SlaveSwitch event caused by
 13647        wheel movement, then querying for the device info will probably
 13648        return the value after the wheel movement, leading to a delta
 13649        of 0 being computed upon handling the subsequent XI_Motion
 13650        event.  (bug#58980) */
 13651     xi_handle_new_classes (dpyinfo, device, event->classes,
 13652                            event->num_classes);
 13653   else
 13654     {
 13655       /* When a DeviceChange event is received for a master device,
 13656          the X server sometimes does not send any scroll valuators
 13657          along with it.  This is possibly an X server bug but I really
 13658          don't want to dig any further, so fetch the scroll valuators
 13659          manually.  (bug#57020) */
 13660 
 13661       x_catch_errors (dpyinfo->display);
 13662       info = XIQueryDevice (dpyinfo->display, event->deviceid,
 13663                             /* ndevices is always 1 if a deviceid is
 13664                                specified.  If the request fails, NULL will
 13665                                be returned.  */
 13666                             &ndevices);
 13667       x_uncatch_errors ();
 13668 
 13669       if (!info)
 13670         return;
 13671 
 13672       /* info contains the classes currently associated with the
 13673          event.  Apply them.  */
 13674       xi_handle_new_classes (dpyinfo, device, info->classes,
 13675                              info->num_classes);
 13676     }
 13677 #endif
 13678 
 13679 #ifdef HAVE_XINPUT2_2
 13680   /* The device is no longer a DirectTouch device, so remove any
 13681      touchpoints that we might have recorded.  */
 13682   if (!device->direct_p)
 13683     {
 13684       tem = device->touchpoints;
 13685 
 13686       while (tem)
 13687         {
 13688           last = tem;
 13689           tem = tem->next;
 13690           xfree (last);
 13691         }
 13692 
 13693       device->touchpoints = NULL;
 13694     }
 13695 #endif
 13696 }
 13697 
 13698 /* Remove the client-side record of every device in TO_DISABLE.
 13699    Called while processing XI_HierarchyChanged events.  We batch up
 13700    multiple disabled devices because it is more efficient to disable
 13701    them at once.  */
 13702 
 13703 static void
 13704 xi_disable_devices (struct x_display_info *dpyinfo,
 13705                     int *to_disable, int n_disabled)
 13706 {
 13707   struct xi_device_t *devices;
 13708   int ndevices, i, j;
 13709 #ifdef HAVE_XINPUT2_2
 13710   struct xi_touch_point_t *tem, *last;
 13711 #endif
 13712 #if defined HAVE_XINPUT2_2 && !defined HAVE_EXT_TOOL_BAR
 13713   struct x_output *output;
 13714   Lisp_Object tail, frame;
 13715 #endif
 13716 
 13717   /* Don't pointlessly copy dpyinfo->devices if there are no devices
 13718      to disable.  */
 13719   if (!n_disabled)
 13720     return;
 13721 
 13722   ndevices = 0;
 13723   devices = xzalloc (sizeof *devices * dpyinfo->num_devices);
 13724 
 13725   /* Loop through every device currently in DPYINFO, and copy it to
 13726      DEVICES if it is not in TO_DISABLE.  Note that this function
 13727      should be called with input blocked, since xfree can otherwise
 13728      call GC, which will call mark_xterm with invalid state.  */
 13729   for (i = 0; i < dpyinfo->num_devices; ++i)
 13730     {
 13731       for (j = 0; j < n_disabled; ++j)
 13732         {
 13733           if (to_disable[j] == dpyinfo->devices[i].device_id)
 13734             {
 13735               if (x_dnd_in_progress
 13736                   /* If the drag-and-drop pointer device is being
 13737                      disabled, then cancel the drag and drop
 13738                      operation.  */
 13739                   && to_disable[j] == x_dnd_pointer_device)
 13740                 x_dnd_cancel_dnd_early ();
 13741 
 13742               /* Free any scroll valuators that might be on this
 13743                  device.  */
 13744 #ifdef HAVE_XINPUT2_1
 13745               xfree (dpyinfo->devices[i].valuators);
 13746 #endif
 13747 
 13748               /* Free any currently active touch points on this
 13749                  device.  */
 13750 #ifdef HAVE_XINPUT2_2
 13751               tem = dpyinfo->devices[i].touchpoints;
 13752               while (tem)
 13753                 {
 13754                   last = tem;
 13755                   tem = tem->next;
 13756                   xfree (last);
 13757                 }
 13758 
 13759 #ifndef HAVE_EXT_TOOL_BAR
 13760 
 13761               /* Now look through each frame on DPYINFO.  If it has an
 13762                  outstanding tool bar press for this device, release
 13763                  the tool bar.  */
 13764 
 13765               FOR_EACH_FRAME (tail, frame)
 13766                 {
 13767                   if (!FRAME_X_P (XFRAME (frame))
 13768                       || (FRAME_DISPLAY_INFO (XFRAME (frame))
 13769                           != dpyinfo))
 13770                     continue;
 13771 
 13772                   output = FRAME_OUTPUT_DATA (XFRAME (frame));
 13773 
 13774                   if (output->tool_bar_touch_device
 13775                       == dpyinfo->devices[i].device_id)
 13776                     {
 13777                       if (XFRAME (frame)->last_tool_bar_item != -1
 13778                           && WINDOWP (XFRAME (frame)->tool_bar_window))
 13779                         handle_tool_bar_click (XFRAME (frame), 0, 0,
 13780                                                false, 0);
 13781 
 13782                       output->tool_bar_touch_device = 0;
 13783                     }
 13784                 }
 13785 #endif
 13786 #endif
 13787 
 13788               goto out;
 13789             }
 13790 
 13791           devices[ndevices++] = dpyinfo->devices[i];
 13792 
 13793         out:
 13794           continue;
 13795         }
 13796     }
 13797 
 13798   /* Free the old devices array and replace it with ndevices.  */
 13799   xfree (dpyinfo->devices);
 13800 
 13801   dpyinfo->devices = devices;
 13802   dpyinfo->num_devices = ndevices;
 13803 }
 13804 
 13805 #endif
 13806 
 13807 /* The focus may have changed.  Figure out if it is a real focus change,
 13808    by checking both FocusIn/Out and Enter/LeaveNotify events.
 13809 
 13810    Returns FOCUS_IN_EVENT event in *BUFP. */
 13811 
 13812 static void
 13813 x_detect_focus_change (struct x_display_info *dpyinfo, struct frame *frame,
 13814                        const XEvent *event, struct input_event *bufp)
 13815 {
 13816   if (!frame)
 13817     return;
 13818 
 13819   switch (event->type)
 13820     {
 13821     case EnterNotify:
 13822     case LeaveNotify:
 13823       {
 13824         struct frame *focus_frame = dpyinfo->x_focus_event_frame;
 13825         int focus_state
 13826           = focus_frame ? focus_frame->output_data.x->focus_state : 0;
 13827 
 13828         if (event->xcrossing.detail != NotifyInferior
 13829             && event->xcrossing.focus
 13830             && ! (focus_state & FOCUS_EXPLICIT))
 13831           x_focus_changed ((event->type == EnterNotify ? FocusIn : FocusOut),
 13832                            FOCUS_IMPLICIT,
 13833                            dpyinfo, frame, bufp);
 13834       }
 13835       break;
 13836 
 13837     case FocusIn:
 13838     case FocusOut:
 13839       /* Ignore transient focus events from hotkeys, window manager
 13840          gadgets, and other odd sources.  Some buggy window managers
 13841          (e.g., Muffin 4.2.4) send FocusIn events of this type without
 13842          corresponding FocusOut events even when some other window
 13843          really has focus, and these kinds of focus event don't
 13844          correspond to real user input changes.  GTK+ uses the same
 13845          filtering. */
 13846       if (event->xfocus.mode == NotifyGrab
 13847           || event->xfocus.mode == NotifyUngrab)
 13848         return;
 13849       x_focus_changed (event->type,
 13850                        (event->xfocus.detail == NotifyPointer ?
 13851                         FOCUS_IMPLICIT : FOCUS_EXPLICIT),
 13852                        dpyinfo, frame, bufp);
 13853       break;
 13854 
 13855     case ClientMessage:
 13856       if (event->xclient.message_type == dpyinfo->Xatom_XEMBED)
 13857         {
 13858           enum xembed_message msg = event->xclient.data.l[1];
 13859           x_focus_changed ((msg == XEMBED_FOCUS_IN ? FocusIn : FocusOut),
 13860                            FOCUS_EXPLICIT, dpyinfo, frame, bufp);
 13861         }
 13862       break;
 13863     }
 13864 }
 13865 
 13866 
 13867 #if (defined USE_LUCID && defined HAVE_XINPUT2) \
 13868   || (!defined USE_X_TOOLKIT && !defined USE_GTK)
 13869 /* Handle an event saying the mouse has moved out of an Emacs frame.  */
 13870 
 13871 void
 13872 x_mouse_leave (struct x_display_info *dpyinfo)
 13873 {
 13874 #if defined HAVE_XINPUT2 && !defined USE_X_TOOLKIT
 13875   struct xi_device_t *device;
 13876 #endif
 13877   Mouse_HLInfo *hlinfo;
 13878 
 13879   hlinfo = &dpyinfo->mouse_highlight;
 13880 
 13881   if (hlinfo->mouse_face_mouse_frame)
 13882     {
 13883       clear_mouse_face (hlinfo);
 13884       hlinfo->mouse_face_mouse_frame = NULL;
 13885     }
 13886 
 13887 #if defined HAVE_XINPUT2 && !defined USE_X_TOOLKIT
 13888   if (!dpyinfo->supports_xi2)
 13889     /* The call below is supposed to reset the implicit focus and
 13890        revert the focus back to the last explicitly focused frame.  It
 13891        doesn't work on input extension builds because focus tracking
 13892        does not set x_focus_event_frame, and proceeds on a per-device
 13893        basis.  On such builds, clear the implicit focus of the client
 13894        pointer instead.  */
 13895 #endif
 13896     x_new_focus_frame (dpyinfo, dpyinfo->x_focus_event_frame);
 13897 #if defined HAVE_XINPUT2 && !defined USE_X_TOOLKIT
 13898   else
 13899     {
 13900       if (dpyinfo->client_pointer_device == -1)
 13901         /* If there's no client pointer device, then no implicit focus
 13902            is currently set.  */
 13903         return;
 13904 
 13905       device = xi_device_from_id (dpyinfo, dpyinfo->client_pointer_device);
 13906 
 13907       if (device && device->focus_implicit_frame)
 13908         {
 13909           device->focus_implicit_frame = NULL;
 13910 
 13911           /* The focus might have changed; compute the new focus.  */
 13912           xi_handle_focus_change (dpyinfo);
 13913         }
 13914     }
 13915 #endif
 13916 }
 13917 #endif
 13918 
 13919 /* The focus has changed, or we have redirected a frame's focus to
 13920    another frame (this happens when a frame uses a surrogate
 13921    mini-buffer frame).  Shift the highlight as appropriate.
 13922 
 13923    The FRAME argument doesn't necessarily have anything to do with which
 13924    frame is being highlighted or un-highlighted; we only use it to find
 13925    the appropriate X display info.  */
 13926 
 13927 static void
 13928 XTframe_rehighlight (struct frame *frame)
 13929 {
 13930   x_frame_rehighlight (FRAME_DISPLAY_INFO (frame));
 13931 }
 13932 
 13933 static void
 13934 x_frame_rehighlight (struct x_display_info *dpyinfo)
 13935 {
 13936   struct frame *old_highlight = dpyinfo->highlight_frame;
 13937 
 13938   if (dpyinfo->x_focus_frame)
 13939     {
 13940       dpyinfo->highlight_frame
 13941         = ((FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame)))
 13942            ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame))
 13943            : dpyinfo->x_focus_frame);
 13944       if (! FRAME_LIVE_P (dpyinfo->highlight_frame))
 13945         {
 13946           fset_focus_frame (dpyinfo->x_focus_frame, Qnil);
 13947           dpyinfo->highlight_frame = dpyinfo->x_focus_frame;
 13948         }
 13949     }
 13950   else
 13951     dpyinfo->highlight_frame = 0;
 13952 
 13953   if (dpyinfo->highlight_frame != old_highlight)
 13954     {
 13955       if (old_highlight)
 13956         x_frame_unhighlight (old_highlight);
 13957       if (dpyinfo->highlight_frame)
 13958         x_frame_highlight (dpyinfo->highlight_frame);
 13959     }
 13960 }
 13961 
 13962 
 13963 
 13964 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc.  */
 13965 
 13966 /* Initialize mode_switch_bit and modifier_meaning.  */
 13967 static void
 13968 x_find_modifier_meanings (struct x_display_info *dpyinfo)
 13969 {
 13970   int min_code, max_code;
 13971   KeySym *syms;
 13972   int syms_per_code;
 13973   XModifierKeymap *mods;
 13974 #ifdef HAVE_XKB
 13975   int i;
 13976   int found_meta_p = false;
 13977   unsigned int vmodmask;
 13978 #endif
 13979 
 13980   dpyinfo->meta_mod_mask = 0;
 13981   dpyinfo->shift_lock_mask = 0;
 13982   dpyinfo->alt_mod_mask = 0;
 13983   dpyinfo->super_mod_mask = 0;
 13984   dpyinfo->hyper_mod_mask = 0;
 13985 
 13986 #ifdef HAVE_XKB
 13987   if (dpyinfo->xkb_desc
 13988       && dpyinfo->xkb_desc->server)
 13989     {
 13990       for (i = 0; i < XkbNumVirtualMods; i++)
 13991         {
 13992           vmodmask = dpyinfo->xkb_desc->server->vmods[i];
 13993 
 13994           if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_Meta)
 13995             {
 13996               dpyinfo->meta_mod_mask |= vmodmask;
 13997 
 13998               if (vmodmask)
 13999                 found_meta_p = true;
 14000             }
 14001           else if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_Alt)
 14002             dpyinfo->alt_mod_mask |= vmodmask;
 14003           else if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_Super)
 14004             dpyinfo->super_mod_mask |= vmodmask;
 14005           else if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_Hyper)
 14006             dpyinfo->hyper_mod_mask |= vmodmask;
 14007           else if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_ShiftLock)
 14008             dpyinfo->shift_lock_mask |= vmodmask;
 14009         }
 14010 
 14011       if (!found_meta_p)
 14012         {
 14013           dpyinfo->meta_mod_mask = dpyinfo->alt_mod_mask;
 14014           dpyinfo->alt_mod_mask = 0;
 14015         }
 14016 
 14017       if (dpyinfo->alt_mod_mask & dpyinfo->meta_mod_mask)
 14018         dpyinfo->alt_mod_mask &= ~dpyinfo->meta_mod_mask;
 14019 
 14020       if (dpyinfo->hyper_mod_mask & dpyinfo->super_mod_mask)
 14021         dpyinfo->hyper_mod_mask &= ~dpyinfo->super_mod_mask;
 14022 
 14023       return;
 14024     }
 14025 #endif
 14026 
 14027   XDisplayKeycodes (dpyinfo->display, &min_code, &max_code);
 14028 
 14029   syms = XGetKeyboardMapping (dpyinfo->display,
 14030                               min_code, max_code - min_code + 1,
 14031                               &syms_per_code);
 14032 
 14033   if (!syms)
 14034     {
 14035       dpyinfo->meta_mod_mask = Mod1Mask;
 14036       dpyinfo->super_mod_mask = Mod2Mask;
 14037       return;
 14038     }
 14039 
 14040   mods = XGetModifierMapping (dpyinfo->display);
 14041 
 14042   /* Scan the modifier table to see which modifier bits the Meta and
 14043      Alt keysyms are on.  */
 14044   {
 14045     int row, col;       /* The row and column in the modifier table.  */
 14046     bool found_alt_or_meta;
 14047 
 14048     for (row = 3; row < 8; row++)
 14049       {
 14050         found_alt_or_meta = false;
 14051         for (col = 0; col < mods->max_keypermod; col++)
 14052           {
 14053             KeyCode code = mods->modifiermap[(row * mods->max_keypermod) + col];
 14054 
 14055             /* Zeroes are used for filler.  Skip them.  */
 14056             if (code == 0)
 14057               continue;
 14058 
 14059             /* Are any of this keycode's keysyms a meta key?  */
 14060             {
 14061               int code_col;
 14062 
 14063               for (code_col = 0; code_col < syms_per_code; code_col++)
 14064                 {
 14065                   int sym = syms[((code - min_code) * syms_per_code) + code_col];
 14066 
 14067                   switch (sym)
 14068                     {
 14069                     case XK_Meta_L:
 14070                     case XK_Meta_R:
 14071                       found_alt_or_meta = true;
 14072                       dpyinfo->meta_mod_mask |= (1 << row);
 14073                       break;
 14074 
 14075                     case XK_Alt_L:
 14076                     case XK_Alt_R:
 14077                       found_alt_or_meta = true;
 14078                       dpyinfo->alt_mod_mask |= (1 << row);
 14079                       break;
 14080 
 14081                     case XK_Hyper_L:
 14082                     case XK_Hyper_R:
 14083                       if (!found_alt_or_meta)
 14084                         dpyinfo->hyper_mod_mask |= (1 << row);
 14085                       code_col = syms_per_code;
 14086                       col = mods->max_keypermod;
 14087                       break;
 14088 
 14089                     case XK_Super_L:
 14090                     case XK_Super_R:
 14091                       if (!found_alt_or_meta)
 14092                         dpyinfo->super_mod_mask |= (1 << row);
 14093                       code_col = syms_per_code;
 14094                       col = mods->max_keypermod;
 14095                       break;
 14096 
 14097                     case XK_Shift_Lock:
 14098                       /* Ignore this if it's not on the lock modifier.  */
 14099                       if (!found_alt_or_meta && ((1 << row) == LockMask))
 14100                         dpyinfo->shift_lock_mask = LockMask;
 14101                       code_col = syms_per_code;
 14102                       col = mods->max_keypermod;
 14103                       break;
 14104                     }
 14105                 }
 14106             }
 14107           }
 14108       }
 14109   }
 14110 
 14111   /* If we couldn't find any meta keys, accept any alt keys as meta keys.  */
 14112   if (! dpyinfo->meta_mod_mask)
 14113     {
 14114       dpyinfo->meta_mod_mask = dpyinfo->alt_mod_mask;
 14115       dpyinfo->alt_mod_mask = 0;
 14116     }
 14117 
 14118   /* If some keys are both alt and meta,
 14119      make them just meta, not alt.  */
 14120   if (dpyinfo->alt_mod_mask & dpyinfo->meta_mod_mask)
 14121     {
 14122       dpyinfo->alt_mod_mask &= ~dpyinfo->meta_mod_mask;
 14123     }
 14124 
 14125   /* If some keys are both super and hyper, make them just super.
 14126      Many X servers are misconfigured so that super and hyper are both
 14127      Mod4, but most users have no hyper key.  */
 14128   if (dpyinfo->hyper_mod_mask & dpyinfo->super_mod_mask)
 14129     dpyinfo->hyper_mod_mask &= ~dpyinfo->super_mod_mask;
 14130 
 14131   XFree (syms);
 14132 
 14133   if (dpyinfo->modmap)
 14134     XFreeModifiermap (dpyinfo->modmap);
 14135   dpyinfo->modmap = mods;
 14136 }
 14137 
 14138 /* Convert between the modifier bits X uses and the modifier bits
 14139    Emacs uses.  */
 14140 
 14141 int
 14142 x_x_to_emacs_modifiers (struct x_display_info *dpyinfo, int state)
 14143 {
 14144   int mod_ctrl = ctrl_modifier;
 14145   int mod_meta = meta_modifier;
 14146   int mod_alt  = alt_modifier;
 14147   int mod_hyper = hyper_modifier;
 14148   int mod_super = super_modifier;
 14149   Lisp_Object tem;
 14150 
 14151   tem = Fget (Vx_ctrl_keysym, Qmodifier_value);
 14152   if (FIXNUMP (tem)) mod_ctrl = XFIXNUM (tem) & INT_MAX;
 14153   tem = Fget (Vx_alt_keysym, Qmodifier_value);
 14154   if (FIXNUMP (tem)) mod_alt = XFIXNUM (tem) & INT_MAX;
 14155   tem = Fget (Vx_meta_keysym, Qmodifier_value);
 14156   if (FIXNUMP (tem)) mod_meta = XFIXNUM (tem) & INT_MAX;
 14157   tem = Fget (Vx_hyper_keysym, Qmodifier_value);
 14158   if (FIXNUMP (tem)) mod_hyper = XFIXNUM (tem) & INT_MAX;
 14159   tem = Fget (Vx_super_keysym, Qmodifier_value);
 14160   if (FIXNUMP (tem)) mod_super = XFIXNUM (tem) & INT_MAX;
 14161 
 14162   return (  ((state & (ShiftMask | dpyinfo->shift_lock_mask)) ? shift_modifier : 0)
 14163             | ((state & ControlMask)                    ? mod_ctrl      : 0)
 14164             | ((state & dpyinfo->meta_mod_mask)         ? mod_meta      : 0)
 14165             | ((state & dpyinfo->alt_mod_mask)          ? mod_alt       : 0)
 14166             | ((state & dpyinfo->super_mod_mask)        ? mod_super     : 0)
 14167             | ((state & dpyinfo->hyper_mod_mask)        ? mod_hyper     : 0));
 14168 }
 14169 
 14170 int
 14171 x_emacs_to_x_modifiers (struct x_display_info *dpyinfo, intmax_t state)
 14172 {
 14173   EMACS_INT mod_ctrl = ctrl_modifier;
 14174   EMACS_INT mod_meta = meta_modifier;
 14175   EMACS_INT mod_alt  = alt_modifier;
 14176   EMACS_INT mod_hyper = hyper_modifier;
 14177   EMACS_INT mod_super = super_modifier;
 14178 
 14179   Lisp_Object tem;
 14180 
 14181   tem = Fget (Vx_ctrl_keysym, Qmodifier_value);
 14182   if (FIXNUMP (tem)) mod_ctrl = XFIXNUM (tem);
 14183   tem = Fget (Vx_alt_keysym, Qmodifier_value);
 14184   if (FIXNUMP (tem)) mod_alt = XFIXNUM (tem);
 14185   tem = Fget (Vx_meta_keysym, Qmodifier_value);
 14186   if (FIXNUMP (tem)) mod_meta = XFIXNUM (tem);
 14187   tem = Fget (Vx_hyper_keysym, Qmodifier_value);
 14188   if (FIXNUMP (tem)) mod_hyper = XFIXNUM (tem);
 14189   tem = Fget (Vx_super_keysym, Qmodifier_value);
 14190   if (FIXNUMP (tem)) mod_super = XFIXNUM (tem);
 14191 
 14192 
 14193   return (  ((state & mod_alt)          ? dpyinfo->alt_mod_mask   : 0)
 14194             | ((state & mod_super)      ? dpyinfo->super_mod_mask : 0)
 14195             | ((state & mod_hyper)      ? dpyinfo->hyper_mod_mask : 0)
 14196             | ((state & shift_modifier) ? ShiftMask        : 0)
 14197             | ((state & mod_ctrl)       ? ControlMask      : 0)
 14198             | ((state & mod_meta)       ? dpyinfo->meta_mod_mask  : 0));
 14199 }
 14200 
 14201 /* Convert a keysym to its name.  */
 14202 
 14203 char *
 14204 get_keysym_name (int keysym)
 14205 {
 14206   char *value;
 14207 
 14208   block_input ();
 14209   value = XKeysymToString (keysym);
 14210   unblock_input ();
 14211 
 14212   return value;
 14213 }
 14214 
 14215 /* Given the root and event coordinates of an X event destined for F's
 14216    edit window, compute the offset between that window and F's root
 14217    window.  This information is then used as an optimization to avoid
 14218    synchronizing when converting coordinates from some other event to
 14219    F's edit window.  */
 14220 
 14221 static void
 14222 x_compute_root_window_offset (struct frame *f, int root_x, int root_y,
 14223                               int event_x, int event_y)
 14224 {
 14225   FRAME_X_OUTPUT (f)->window_offset_certain_p = true;
 14226   FRAME_X_OUTPUT (f)->root_x = root_x - event_x;
 14227   FRAME_X_OUTPUT (f)->root_y = root_y - event_y;
 14228 }
 14229 
 14230 /* Translate the given coordinates from the root window to the edit
 14231    window of FRAME, taking into account any cached root window
 14232    offsets.  This allows Emacs to avoid excessive calls to _XReply in
 14233    many cases while handling events, which would otherwise result in
 14234    slowdowns over slow network connections.  */
 14235 
 14236 void
 14237 x_translate_coordinates (struct frame *f, int root_x, int root_y,
 14238                          int *x_out, int *y_out)
 14239 {
 14240   struct x_output *output;
 14241   Window dummy;
 14242 
 14243   output = FRAME_X_OUTPUT (f);
 14244 
 14245   if (output->window_offset_certain_p)
 14246     {
 14247       /* Use the cached root window offset.  */
 14248       *x_out = root_x - output->root_x;
 14249       *y_out = root_y - output->root_y;
 14250 
 14251       return;
 14252     }
 14253 
 14254   /* Otherwise, do the transformation manually.  Then, cache the root
 14255      window position.  */
 14256   if (!XTranslateCoordinates (FRAME_X_DISPLAY (f),
 14257                               FRAME_DISPLAY_INFO (f)->root_window,
 14258                               FRAME_X_WINDOW (f), root_x, root_y,
 14259                               x_out, y_out, &dummy))
 14260     /* Use some dummy values.  This is not supposed to be called with
 14261        coordinates out of the screen.  */
 14262     *x_out = 0, *y_out = 0;
 14263   else
 14264     {
 14265       /* Cache the root window offset of the edit window.  */
 14266       output->window_offset_certain_p = true;
 14267       output->root_x = root_x - *x_out;
 14268       output->root_y = root_y - *y_out;
 14269     }
 14270 }
 14271 
 14272 /* Translate the given coordinates from the edit window of FRAME,
 14273    taking into account any cached root window offsets.  This is mainly
 14274    used from the popup menu code.  */
 14275 
 14276 void
 14277 x_translate_coordinates_to_root (struct frame *f, int x, int y,
 14278                                  int *x_out, int *y_out)
 14279 {
 14280   struct x_output *output;
 14281   Window dummy;
 14282 
 14283   output = FRAME_X_OUTPUT (f);
 14284 
 14285   if (output->window_offset_certain_p)
 14286     {
 14287       /* Use the cached root window offset.  */
 14288       *x_out = x + output->root_x;
 14289       *y_out = y + output->root_y;
 14290 
 14291       return;
 14292     }
 14293 
 14294   /* Otherwise, do the transform manually and compute and cache the
 14295      root window position.  */
 14296   if (!XTranslateCoordinates (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 14297                               FRAME_DISPLAY_INFO (f)->root_window,
 14298                               x, y, x_out, y_out, &dummy))
 14299     *x_out = 0, *y_out = 0;
 14300   else
 14301     {
 14302       /* Cache the root window offset of the edit window.  */
 14303       output->window_offset_certain_p = true;
 14304       output->root_x = *x_out - x;
 14305       output->root_y = *y_out - y;
 14306     }
 14307 }
 14308 
 14309 /* Do x-translate-coordinates, but try to avoid a roundtrip to the X
 14310    server at the cost of not returning `child', which most callers
 14311    have no reason to use.  */
 14312 
 14313 Lisp_Object
 14314 x_handle_translate_coordinates (struct frame *f, Lisp_Object dest_window,
 14315                                 int source_x, int source_y)
 14316 {
 14317   if (NILP (dest_window))
 14318     {
 14319       /* We are translating coordinates from a frame to the root
 14320          window.  Avoid a roundtrip if possible by using cached
 14321          coordinates.  */
 14322 
 14323       if (!FRAME_X_OUTPUT (f)->window_offset_certain_p)
 14324         return Qnil;
 14325 
 14326       return list3 (make_fixnum (source_x + FRAME_X_OUTPUT (f)->root_x),
 14327                     make_fixnum (source_y + FRAME_X_OUTPUT (f)->root_y),
 14328                     Qnil);
 14329     }
 14330 
 14331   return Qnil;
 14332 }
 14333 
 14334 /* The same, but for an XIDeviceEvent.  */
 14335 
 14336 #ifdef HAVE_XINPUT2
 14337 
 14338 static void
 14339 xi_compute_root_window_offset (struct frame *f, XIDeviceEvent *xev)
 14340 {
 14341   /* Truncate coordinates instead of rounding them, because that is
 14342      how the X server handles window hierarchy.  */
 14343   x_compute_root_window_offset (f, xev->root_x, xev->root_y,
 14344                                 xev->event_x, xev->event_y);
 14345 }
 14346 
 14347 static void
 14348 xi_compute_root_window_offset_enter (struct frame *f, XIEnterEvent *enter)
 14349 {
 14350   x_compute_root_window_offset (f, enter->root_x, enter->root_y,
 14351                                 enter->event_x, enter->event_y);
 14352 }
 14353 
 14354 #ifdef HAVE_XINPUT2_4
 14355 
 14356 static void
 14357 xi_compute_root_window_offset_pinch (struct frame *f, XIGesturePinchEvent *pev)
 14358 {
 14359   /* Truncate coordinates instead of rounding them, because that is
 14360      how the X server handles window hierarchy.  */
 14361   x_compute_root_window_offset (f, pev->root_x, pev->root_y,
 14362                                 pev->event_x, pev->event_y);
 14363 }
 14364 
 14365 #endif
 14366 
 14367 #endif
 14368 
 14369 static Bool
 14370 x_query_pointer_1 (struct x_display_info *dpyinfo,
 14371                    int client_pointer_device, Window w,
 14372                    Window *root_return, Window *child_return,
 14373                    int *root_x_return, int *root_y_return,
 14374                    int *win_x_return, int *win_y_return,
 14375                    unsigned int *mask_return)
 14376 {
 14377   Bool rc;
 14378   Display *dpy;
 14379 #ifdef HAVE_XINPUT2
 14380   bool had_errors;
 14381   XIModifierState modifiers;
 14382   XIButtonState buttons;
 14383   XIGroupState group; /* Unused.  */
 14384   double root_x, root_y, win_x, win_y;
 14385   unsigned int state;
 14386 #endif
 14387 
 14388   dpy = dpyinfo->display;
 14389 
 14390 #ifdef HAVE_XINPUT2
 14391   if (client_pointer_device != -1)
 14392     {
 14393       /* Catch errors caused by the device going away.  This is not
 14394          very expensive, since XIQueryPointer will sync anyway.  */
 14395       x_catch_errors (dpy);
 14396       rc = XIQueryPointer (dpyinfo->display,
 14397                            dpyinfo->client_pointer_device,
 14398                            w, root_return, child_return,
 14399                            &root_x, &root_y, &win_x, &win_y,
 14400                            &buttons, &modifiers, &group);
 14401       had_errors = x_had_errors_p (dpy);
 14402       x_uncatch_errors_after_check ();
 14403 
 14404       if (had_errors)
 14405         {
 14406           /* If the specified client pointer is the display's client
 14407              pointer, clear it now.  A new client pointer might not be
 14408              found before the next call to x_query_pointer_1 and
 14409              waiting for the error leads to excessive syncing.  */
 14410 
 14411           if (client_pointer_device == dpyinfo->client_pointer_device)
 14412             dpyinfo->client_pointer_device = -1;
 14413 
 14414           rc = XQueryPointer (dpyinfo->display, w, root_return,
 14415                               child_return, root_x_return,
 14416                               root_y_return, win_x_return,
 14417                               win_y_return, mask_return);
 14418         }
 14419       else
 14420         {
 14421           state = 0;
 14422 
 14423           xi_convert_button_state (&buttons, &state);
 14424           *mask_return = state | modifiers.effective;
 14425 
 14426           XFree (buttons.mask);
 14427 
 14428           *root_x_return = lrint (root_x);
 14429           *root_y_return = lrint (root_y);
 14430           *win_x_return = lrint (win_x);
 14431           *win_y_return = lrint (win_y);
 14432         }
 14433     }
 14434   else
 14435 #endif
 14436     rc = XQueryPointer (dpy, w, root_return, child_return,
 14437                         root_x_return, root_y_return, win_x_return,
 14438                         win_y_return, mask_return);
 14439 
 14440   return rc;
 14441 }
 14442 
 14443 Bool
 14444 x_query_pointer (Display *dpy, Window w, Window *root_return,
 14445                  Window *child_return, int *root_x_return,
 14446                  int *root_y_return, int *win_x_return,
 14447                  int *win_y_return, unsigned int *mask_return)
 14448 {
 14449   struct x_display_info *dpyinfo;
 14450 
 14451   dpyinfo = x_display_info_for_display (dpy);
 14452 
 14453   if (!dpyinfo)
 14454     emacs_abort ();
 14455 
 14456 #ifdef HAVE_XINPUT2
 14457   return x_query_pointer_1 (dpyinfo, dpyinfo->client_pointer_device,
 14458                             w, root_return, child_return, root_x_return,
 14459                             root_y_return, win_x_return, win_y_return,
 14460                             mask_return);
 14461 #else
 14462   return x_query_pointer_1 (dpyinfo, -1, w, root_return, child_return,
 14463                             root_x_return, root_y_return, win_x_return,
 14464                             win_y_return, mask_return);
 14465 #endif
 14466 }
 14467 
 14468 /* Mouse clicks and mouse movement.  Rah.
 14469 
 14470    Formerly, we used PointerMotionHintMask (in standard_event_mask)
 14471    so that we would have to call XQueryPointer after each MotionNotify
 14472    event to ask for another such event.  However, this made mouse tracking
 14473    slow, and there was a bug that made it eventually stop.
 14474 
 14475    Simply asking for MotionNotify all the time seems to work better.
 14476 
 14477    In order to avoid asking for motion events and then throwing most
 14478    of them away or busy-polling the server for mouse positions, we ask
 14479    the server for pointer motion hints.  This means that we get only
 14480    one event per group of mouse movements.  "Groups" are delimited by
 14481    other kinds of events (focus changes and button clicks, for
 14482    example), or by XQueryPointer calls; when one of these happens, we
 14483    get another MotionNotify event the next time the mouse moves.  This
 14484    is at least as efficient as getting motion events when mouse
 14485    tracking is on, and I suspect only negligibly worse when tracking
 14486    is off.  */
 14487 
 14488 /* Prepare a mouse-event in *RESULT for placement in the input queue.
 14489 
 14490    If the event is a button press, then note that we have grabbed
 14491    the mouse.
 14492 
 14493    The XButtonEvent structure passed as EVENT might not come from the
 14494    X server, and instead be artificially constructed from input
 14495    extension events.  In these special events, the only fields that
 14496    are initialized are `time', `button', `state', `type', `window' and
 14497    `x', `y', `x_root' and `y_root'.  This function should not access
 14498    any other fields in EVENT without also initializing the
 14499    corresponding fields in `bv' under the XI_ButtonPress and
 14500    XI_ButtonRelease labels inside `handle_one_xevent'.  */
 14501 
 14502 static Lisp_Object
 14503 x_construct_mouse_click (struct input_event *result,
 14504                          const XButtonEvent *event,
 14505                          struct frame *f)
 14506 {
 14507   int x = event->x;
 14508   int y = event->y;
 14509 
 14510   /* Make the event type NO_EVENT; we'll change that when we decide
 14511      otherwise.  */
 14512   result->kind = MOUSE_CLICK_EVENT;
 14513   result->code = event->button - Button1;
 14514   result->timestamp = event->time;
 14515   result->modifiers = (x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO (f),
 14516                                                event->state)
 14517                        | (event->type == ButtonRelease
 14518                           ? up_modifier
 14519                           : down_modifier));
 14520 
 14521   /* If result->window is not the frame's edit widget (which can
 14522      happen with GTK+ scroll bars, for example), translate the
 14523      coordinates so they appear at the correct position.  */
 14524   if (event->window != FRAME_X_WINDOW (f))
 14525     x_translate_coordinates (f, event->x_root, event->y_root,
 14526                              &x, &y);
 14527 
 14528   XSETINT (result->x, x);
 14529   XSETINT (result->y, y);
 14530   XSETFRAME (result->frame_or_window, f);
 14531   result->arg = Qnil;
 14532   return Qnil;
 14533 }
 14534 
 14535 /* Function to report a mouse movement to the mainstream Emacs code.
 14536    The input handler calls this.
 14537 
 14538    We have received a mouse movement event, which is given in *event.
 14539    If the mouse is over a different glyph than it was last time, tell
 14540    the mainstream emacs code by setting mouse_moved.  If not, ask for
 14541    another motion event, so we can check again the next time it moves.
 14542 
 14543    The XMotionEvent structure passed as EVENT might not come from the
 14544    X server, and instead be artificially constructed from input
 14545    extension events.  In these special events, the only fields that
 14546    are initialized are `time', `window', `send_event', `x' and `y'.
 14547    This function should not access any other fields in EVENT without
 14548    also initializing the corresponding fields in `ev' under the
 14549    XI_Motion, XI_Enter and XI_Leave labels inside
 14550    `handle_one_xevent'.  */
 14551 
 14552 static bool
 14553 x_note_mouse_movement (struct frame *frame, const XMotionEvent *event,
 14554                        Lisp_Object device)
 14555 {
 14556   XRectangle *r;
 14557   struct x_display_info *dpyinfo;
 14558 
 14559   if (!FRAME_X_OUTPUT (frame))
 14560     return false;
 14561 
 14562   dpyinfo = FRAME_DISPLAY_INFO (frame);
 14563   dpyinfo->last_mouse_movement_time = event->time;
 14564   dpyinfo->last_mouse_movement_time_send_event = event->send_event;
 14565   dpyinfo->last_mouse_motion_frame = frame;
 14566   dpyinfo->last_mouse_motion_x = event->x;
 14567   dpyinfo->last_mouse_motion_y = event->y;
 14568 
 14569   if (event->window != FRAME_X_WINDOW (frame))
 14570     {
 14571       frame->mouse_moved = true;
 14572       frame->last_mouse_device = device;
 14573       dpyinfo->last_mouse_scroll_bar = NULL;
 14574       note_mouse_highlight (frame, -1, -1);
 14575       dpyinfo->last_mouse_glyph_frame = NULL;
 14576       return true;
 14577     }
 14578 
 14579 
 14580   /* Has the mouse moved off the glyph it was on at the last sighting?  */
 14581   r = &dpyinfo->last_mouse_glyph;
 14582   if (frame != dpyinfo->last_mouse_glyph_frame
 14583       || event->x < r->x || event->x >= r->x + r->width
 14584       || event->y < r->y || event->y >= r->y + r->height)
 14585     {
 14586       frame->mouse_moved = true;
 14587       frame->last_mouse_device = device;
 14588       dpyinfo->last_mouse_scroll_bar = NULL;
 14589       note_mouse_highlight (frame, event->x, event->y);
 14590       /* Remember which glyph we're now on.  */
 14591       remember_mouse_glyph (frame, event->x, event->y, r);
 14592       dpyinfo->last_mouse_glyph_frame = frame;
 14593       return true;
 14594     }
 14595 
 14596   return false;
 14597 }
 14598 
 14599 /* Get a sibling below WINDOW on DPY at PARENT_X and PARENT_Y.  */
 14600 static Window
 14601 x_get_window_below (Display *dpy, Window window,
 14602                     int parent_x, int parent_y,
 14603                     int *inner_x, int *inner_y)
 14604 {
 14605   int rc, i, cx, cy;
 14606   XWindowAttributes attrs;
 14607   unsigned int nchildren;
 14608   Window root, parent, *children, value;
 14609   bool window_seen;
 14610 
 14611   /* TODO: rewrite to have less dependencies.  */
 14612 
 14613   children = NULL;
 14614   window_seen = false;
 14615   value = None;
 14616 
 14617   rc = XQueryTree (dpy, window, &root, &parent,
 14618                    &children, &nchildren);
 14619 
 14620   if (rc)
 14621     {
 14622       if (children)
 14623         XFree (children);
 14624 
 14625       rc = XQueryTree (dpy, parent, &root,
 14626                        &parent, &children, &nchildren);
 14627     }
 14628 
 14629   if (rc)
 14630     {
 14631       for (i = nchildren - 1; i >= 0; --i)
 14632         {
 14633           if (children[i] == window)
 14634             {
 14635               window_seen = true;
 14636               continue;
 14637             }
 14638 
 14639           if (!window_seen)
 14640             continue;
 14641 
 14642           rc = XGetWindowAttributes (dpy, children[i], &attrs);
 14643 
 14644           if (rc && attrs.map_state != IsViewable)
 14645             continue;
 14646 
 14647           if (rc && parent_x >= attrs.x
 14648               && parent_y >= attrs.y
 14649               && parent_x < attrs.x + attrs.width
 14650               && parent_y < attrs.y + attrs.height)
 14651             {
 14652               value = children[i];
 14653               cx = parent_x - attrs.x;
 14654               cy = parent_y - attrs.y;
 14655 
 14656               break;
 14657             }
 14658         }
 14659     }
 14660 
 14661   if (children)
 14662     XFree (children);
 14663 
 14664   if (value)
 14665     {
 14666       *inner_x = cx;
 14667       *inner_y = cy;
 14668     }
 14669 
 14670   return value;
 14671 }
 14672 
 14673 /* Like XTmouse_position, but much faster.  */
 14674 
 14675 static void
 14676 x_fast_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
 14677                        enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y,
 14678                        Time *timestamp)
 14679 {
 14680   int root_x, root_y, win_x, win_y;
 14681   unsigned int mask;
 14682   Window dummy;
 14683   struct scroll_bar *bar;
 14684   struct x_display_info *dpyinfo;
 14685   Lisp_Object tail, frame;
 14686   struct frame *f1;
 14687 
 14688   dpyinfo = FRAME_DISPLAY_INFO (*fp);
 14689 
 14690   if (dpyinfo->last_mouse_scroll_bar && !insist)
 14691     {
 14692       bar = dpyinfo->last_mouse_scroll_bar;
 14693 
 14694       if (bar->horizontal)
 14695         x_horizontal_scroll_bar_report_motion (fp, bar_window, part,
 14696                                                x, y, timestamp);
 14697       else
 14698         x_scroll_bar_report_motion (fp, bar_window, part,
 14699                                     x, y, timestamp);
 14700 
 14701       return;
 14702     }
 14703 
 14704   if (!EQ (Vx_use_fast_mouse_position, Qreally_fast))
 14705     {
 14706       /* This means that Emacs should select a frame and report the
 14707          mouse position relative to it.  The approach used here avoids
 14708          making multiple roundtrips to the X server querying for the
 14709          window beneath the pointer, and was borrowed from
 14710          haiku_mouse_position in haikuterm.c.  */
 14711 
 14712       FOR_EACH_FRAME (tail, frame)
 14713         {
 14714           if (FRAME_X_P (XFRAME (frame))
 14715               && (FRAME_DISPLAY_INFO (XFRAME (frame))
 14716                   == dpyinfo))
 14717             XFRAME (frame)->mouse_moved = false;
 14718         }
 14719 
 14720       if (gui_mouse_grabbed (dpyinfo)
 14721           && !EQ (track_mouse, Qdropping)
 14722           && !EQ (track_mouse, Qdrag_source))
 14723         /* Pick the last mouse frame if dropping.  */
 14724         f1 = dpyinfo->last_mouse_frame;
 14725       else
 14726         /* Otherwise, pick the last mouse motion frame.  */
 14727         f1 = dpyinfo->last_mouse_motion_frame;
 14728 
 14729       if (!f1 && (FRAME_X_P (SELECTED_FRAME ())
 14730                   && (FRAME_DISPLAY_INFO (SELECTED_FRAME ())
 14731                       == dpyinfo)))
 14732         f1 = SELECTED_FRAME ();
 14733 
 14734       if (!f1 || (!FRAME_X_P (f1) && (insist > 0)))
 14735         FOR_EACH_FRAME (tail, frame)
 14736           if (FRAME_X_P (XFRAME (frame))
 14737               && (FRAME_DISPLAY_INFO (XFRAME (frame))
 14738                   == dpyinfo)
 14739               && !FRAME_TOOLTIP_P (XFRAME (frame)))
 14740             f1 = XFRAME (frame);
 14741 
 14742       if (f1 && FRAME_TOOLTIP_P (f1))
 14743         f1 = NULL;
 14744 
 14745       if (f1 && FRAME_X_P (f1) && FRAME_X_WINDOW (f1))
 14746         {
 14747           if (!x_query_pointer (dpyinfo->display, FRAME_X_WINDOW (f1),
 14748                                 &dummy, &dummy, &root_x, &root_y,
 14749                                 &win_x, &win_y, &mask))
 14750             /* The pointer is out of the screen.  */
 14751             return;
 14752 
 14753           remember_mouse_glyph (f1, win_x, win_y,
 14754                                 &dpyinfo->last_mouse_glyph);
 14755           dpyinfo->last_mouse_glyph_frame = f1;
 14756 
 14757           *bar_window = Qnil;
 14758           *part = scroll_bar_nowhere;
 14759 
 14760           /* If track-mouse is `drag-source' and the mouse pointer is
 14761              certain to not be actually under the chosen frame, return
 14762              NULL in FP.  */
 14763           if (EQ (track_mouse, Qdrag_source)
 14764               && (win_x < 0 || win_y < 0
 14765                   || win_x >= FRAME_PIXEL_WIDTH (f1)
 14766                   || win_y >= FRAME_PIXEL_HEIGHT (f1)))
 14767             *fp = NULL;
 14768           else
 14769             *fp = f1;
 14770 
 14771           *timestamp = dpyinfo->last_mouse_movement_time;
 14772           XSETINT (*x, win_x);
 14773           XSETINT (*y, win_y);
 14774         }
 14775     }
 14776   else
 14777     {
 14778       /* This means Emacs should only report the coordinates of the
 14779          last mouse motion.  */
 14780 
 14781       if (dpyinfo->last_mouse_motion_frame)
 14782         {
 14783           *fp = dpyinfo->last_mouse_motion_frame;
 14784           *timestamp = dpyinfo->last_mouse_movement_time;
 14785           *x = make_fixnum (dpyinfo->last_mouse_motion_x);
 14786           *y = make_fixnum (dpyinfo->last_mouse_motion_y);
 14787           *bar_window = Qnil;
 14788           *part = scroll_bar_nowhere;
 14789 
 14790           FOR_EACH_FRAME (tail, frame)
 14791             {
 14792               if (FRAME_X_P (XFRAME (frame))
 14793                   && (FRAME_DISPLAY_INFO (XFRAME (frame))
 14794                       == dpyinfo))
 14795                 XFRAME (frame)->mouse_moved = false;
 14796             }
 14797 
 14798           dpyinfo->last_mouse_motion_frame->mouse_moved = false;
 14799         }
 14800     }
 14801 }
 14802 
 14803 /* Return the current position of the mouse.
 14804    *FP should be a frame which indicates which display to ask about.
 14805 
 14806    If the mouse movement started in a scroll bar, set *FP, *BAR_WINDOW,
 14807    and *PART to the frame, window, and scroll bar part that the mouse
 14808    is over.  Set *X and *Y to the portion and whole of the mouse's
 14809    position on the scroll bar.
 14810 
 14811    If the mouse movement started elsewhere, set *FP to the frame the
 14812    mouse is on, *BAR_WINDOW to nil, and *X and *Y to the character cell
 14813    the mouse is over.
 14814 
 14815    Set *TIMESTAMP to the server time-stamp for the time at which the mouse
 14816    was at this position.
 14817 
 14818    Don't store anything if we don't have a valid set of values to report.
 14819 
 14820    This clears the mouse_moved flag, so we can wait for the next mouse
 14821    movement.  */
 14822 
 14823 static void
 14824 XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
 14825                   enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y,
 14826                   Time *timestamp)
 14827 {
 14828   struct frame *f1, *maybe_tooltip;
 14829   struct x_display_info *dpyinfo;
 14830   bool unrelated_tooltip;
 14831 
 14832   dpyinfo = FRAME_DISPLAY_INFO (*fp);
 14833 
 14834   if (!NILP (Vx_use_fast_mouse_position))
 14835     {
 14836       /* The user says that Emacs is running over the network, and a
 14837          fast approximation of `mouse-position' should be used.
 14838 
 14839          Depending on what the value of `x-use-fast-mouse-position'
 14840          is, do one of two things: only perform the XQueryPointer to
 14841          obtain the coordinates from the last mouse frame, or only
 14842          return the last mouse motion frame and the
 14843          last_mouse_motion_x and Y.  */
 14844 
 14845       x_fast_mouse_position (fp, insist, bar_window, part, x,
 14846                              y, timestamp);
 14847       return;
 14848     }
 14849 
 14850   block_input ();
 14851 
 14852   if (dpyinfo->last_mouse_scroll_bar && insist == 0)
 14853     {
 14854       struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar;
 14855 
 14856       if (bar->horizontal)
 14857         x_horizontal_scroll_bar_report_motion (fp, bar_window, part, x, y, timestamp);
 14858       else
 14859         x_scroll_bar_report_motion (fp, bar_window, part, x, y, timestamp);
 14860     }
 14861   else
 14862     {
 14863       Window root;
 14864       int root_x, root_y;
 14865 
 14866       Window dummy_window;
 14867       int dummy;
 14868 
 14869       Lisp_Object frame, tail;
 14870 
 14871       /* Clear the mouse-moved flag for every frame on this display.  */
 14872       FOR_EACH_FRAME (tail, frame)
 14873         if (FRAME_X_P (XFRAME (frame))
 14874             && FRAME_X_DISPLAY (XFRAME (frame)) == FRAME_X_DISPLAY (*fp))
 14875           XFRAME (frame)->mouse_moved = false;
 14876 
 14877       dpyinfo->last_mouse_scroll_bar = NULL;
 14878 
 14879       /* Figure out which root window we're on.  */
 14880       x_query_pointer (FRAME_X_DISPLAY (*fp),
 14881                        DefaultRootWindow (FRAME_X_DISPLAY (*fp)),
 14882                        /* The root window which contains the pointer.  */
 14883                        &root,
 14884                        /* Trash which we can't trust if the pointer is on
 14885                           a different screen.  */
 14886                        &dummy_window,
 14887                        /* The position on that root window.  */
 14888                        &root_x, &root_y,
 14889                        /* More trash we can't trust.  */
 14890                        &dummy, &dummy,
 14891                        /* Modifier keys and pointer buttons, about which
 14892                           we don't care.  */
 14893                        (unsigned int *) &dummy);
 14894 
 14895       /* Now we have a position on the root; find the innermost window
 14896          containing the pointer.  */
 14897       {
 14898         Window win, child;
 14899 #ifdef USE_GTK
 14900         Window first_win = 0;
 14901 #endif
 14902         int win_x, win_y;
 14903         int parent_x, parent_y;
 14904 
 14905         win = root;
 14906         parent_x = root_x;
 14907         parent_y = root_y;
 14908 
 14909         /* XTranslateCoordinates can get errors if the window
 14910            structure is changing at the same time this function
 14911            is running.  So at least we must not crash from them.  */
 14912 
 14913         x_catch_errors (FRAME_X_DISPLAY (*fp));
 14914 
 14915         if (gui_mouse_grabbed (dpyinfo) && !EQ (track_mouse, Qdropping)
 14916             && !EQ (track_mouse, Qdrag_source))
 14917           {
 14918             /* If mouse was grabbed on a frame, give coords for that frame
 14919                even if the mouse is now outside it.  */
 14920             XTranslateCoordinates (FRAME_X_DISPLAY (*fp),
 14921                                    /* From-window.  */
 14922                                    root,
 14923                                    /* To-window.  */
 14924                                    FRAME_X_WINDOW (dpyinfo->last_mouse_frame),
 14925                                    /* From-position, to-position.  */
 14926                                    root_x, root_y, &win_x, &win_y,
 14927                                    /* Child of win.  */
 14928                                    &child);
 14929             f1 = dpyinfo->last_mouse_frame;
 14930           }
 14931         else
 14932           {
 14933             while (true)
 14934               {
 14935                 XTranslateCoordinates (FRAME_X_DISPLAY (*fp),
 14936                                        /* From-window, to-window.  */
 14937                                        root, win,
 14938                                        /* From-position, to-position.  */
 14939                                        root_x, root_y, &win_x, &win_y,
 14940                                        /* Child of win.  */
 14941                                        &child);
 14942 
 14943                 /* If CHILD is a tooltip frame, look below it if
 14944                    track-mouse is drag-source.  */
 14945                 if (child != None
 14946                     && (EQ (track_mouse, Qdrag_source)
 14947                         || EQ (track_mouse, Qdropping)))
 14948                   {
 14949                     maybe_tooltip = x_tooltip_window_to_frame (dpyinfo, child,
 14950                                                                &unrelated_tooltip);
 14951 
 14952                     if (maybe_tooltip || unrelated_tooltip)
 14953                       child = x_get_window_below (dpyinfo->display, child,
 14954                                                   parent_x, parent_y, &win_x,
 14955                                                   &win_y);
 14956                   }
 14957 
 14958                 if (child == None || child == win)
 14959                   {
 14960 #ifdef USE_GTK
 14961                     /* On GTK we have not inspected WIN yet.  If it has
 14962                        a frame and that frame has a parent, use it.  */
 14963                     struct frame *f = x_window_to_frame (dpyinfo, win);
 14964 
 14965                     if (f && FRAME_PARENT_FRAME (f))
 14966                       first_win = win;
 14967 #endif
 14968                     break;
 14969                   }
 14970 #ifdef USE_GTK
 14971                 /* We don't want to know the innermost window.  We
 14972                    want the edit window.  For non-Gtk+ the innermost
 14973                    window is the edit window.  For Gtk+ it might not
 14974                    be.  It might be the tool bar for example.  */
 14975                 if (x_window_to_frame (dpyinfo, win))
 14976                   /* But don't hurry.  We might find a child frame
 14977                      beneath.  */
 14978                   first_win = win;
 14979 #endif
 14980                 win = child;
 14981                 parent_x = win_x;
 14982                 parent_y = win_y;
 14983               }
 14984 
 14985 #ifdef USE_GTK
 14986             if (first_win)
 14987               win = first_win;
 14988 #endif
 14989 
 14990             /* Now we know that:
 14991                win is the innermost window containing the pointer
 14992                (XTC says it has no child containing the pointer),
 14993                win_x and win_y are the pointer's position in it
 14994                (XTC did this the last time through), and
 14995                parent_x and parent_y are the pointer's position in win's parent.
 14996                (They are what win_x and win_y were when win was child.
 14997                If win is the root window, it has no parent, and
 14998                parent_{x,y} are invalid, but that's okay, because we'll
 14999                never use them in that case.)  */
 15000 
 15001 #ifdef USE_GTK
 15002             /* We don't want to know the innermost window.  We
 15003                want the edit window.  */
 15004             f1 = x_window_to_frame (dpyinfo, win);
 15005 #else
 15006             /* Is win one of our frames?  */
 15007             f1 = x_any_window_to_frame (dpyinfo, win);
 15008 #endif
 15009 
 15010 #ifdef USE_X_TOOLKIT
 15011             /* If we end up with the menu bar window, say it's not
 15012                on the frame.  */
 15013             if (f1 != NULL
 15014                 && f1->output_data.x->menubar_widget
 15015                 && win == XtWindow (f1->output_data.x->menubar_widget))
 15016               f1 = NULL;
 15017 #endif /* USE_X_TOOLKIT */
 15018           }
 15019 
 15020         /* Set last user time to avoid confusing some window managers
 15021            about the tooltip displayed during drag-and-drop.  */
 15022 
 15023         if ((EQ (track_mouse, Qdrag_source)
 15024              || EQ (track_mouse, Qdropping))
 15025             && (dpyinfo->last_user_time
 15026                 < dpyinfo->last_mouse_movement_time))
 15027           x_display_set_last_user_time (dpyinfo,
 15028                                         dpyinfo->last_mouse_movement_time,
 15029                                         dpyinfo->last_mouse_movement_time_send_event,
 15030                                         true);
 15031 
 15032         if ((!f1 || FRAME_TOOLTIP_P (f1))
 15033             && (EQ (track_mouse, Qdropping)
 15034                 || EQ (track_mouse, Qdrag_source))
 15035             && gui_mouse_grabbed (dpyinfo))
 15036           {
 15037             /* When dropping then if we didn't get a frame or only a
 15038                tooltip frame and the mouse was grabbed on a frame,
 15039                give coords for that frame even if the mouse is now
 15040                outside it.  */
 15041             XTranslateCoordinates (FRAME_X_DISPLAY (*fp),
 15042                                    /* From-window.  */
 15043                                    root,
 15044                                    /* To-window.  */
 15045                                    FRAME_X_WINDOW (dpyinfo->last_mouse_frame),
 15046                                    /* From-position, to-position.  */
 15047                                    root_x, root_y, &win_x, &win_y,
 15048                                    /* Child of win.  */
 15049                                    &child);
 15050 
 15051             if (!EQ (track_mouse, Qdrag_source)
 15052                 /* Don't let tooltips interfere.  */
 15053                 || (f1 && FRAME_TOOLTIP_P (f1)))
 15054               f1 = dpyinfo->last_mouse_frame;
 15055             else
 15056               {
 15057                 /* Don't set FP but do set WIN_X and WIN_Y in this
 15058                    case, so make_lispy_movement knows which
 15059                    coordinates to report.  */
 15060                 *bar_window = Qnil;
 15061                 *part = 0;
 15062                 *fp = NULL;
 15063                 XSETINT (*x, win_x);
 15064                 XSETINT (*y, win_y);
 15065                 *timestamp = dpyinfo->last_mouse_movement_time;
 15066               }
 15067           }
 15068         else if (f1 && FRAME_TOOLTIP_P (f1))
 15069           f1 = NULL;
 15070 
 15071         if (x_had_errors_p (dpyinfo->display))
 15072           f1 = NULL;
 15073 
 15074         x_uncatch_errors_after_check ();
 15075 
 15076         /* If not, is it one of our scroll bars?  */
 15077         if (!f1)
 15078           {
 15079             struct scroll_bar *bar;
 15080 
 15081             bar = x_window_to_scroll_bar (dpyinfo->display, win, 2);
 15082 
 15083             if (bar)
 15084               {
 15085                 f1 = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 15086                 win_x = parent_x;
 15087                 win_y = parent_y;
 15088               }
 15089           }
 15090 
 15091         if (!f1 && insist > 0)
 15092           f1 = SELECTED_FRAME ();
 15093 
 15094         if (f1 && FRAME_X_P (f1))
 15095           {
 15096             /* Ok, we found a frame.  Store all the values.
 15097                last_mouse_glyph is a rectangle used to reduce the
 15098                generation of mouse events.  To not miss any motion
 15099                events, we must divide the frame into rectangles of the
 15100                size of the smallest character that could be displayed
 15101                on it, i.e. into the same rectangles that matrices on
 15102                the frame are divided into.  */
 15103 
 15104             dpyinfo = FRAME_DISPLAY_INFO (f1);
 15105             remember_mouse_glyph (f1, win_x, win_y, &dpyinfo->last_mouse_glyph);
 15106             dpyinfo->last_mouse_glyph_frame = f1;
 15107 
 15108             *bar_window = Qnil;
 15109             *part = 0;
 15110             *fp = f1;
 15111             XSETINT (*x, win_x);
 15112             XSETINT (*y, win_y);
 15113             *timestamp = dpyinfo->last_mouse_movement_time;
 15114           }
 15115       }
 15116     }
 15117 
 15118   unblock_input ();
 15119 }
 15120 
 15121 
 15122 
 15123 /***********************************************************************
 15124                                Scroll bars
 15125  ***********************************************************************/
 15126 
 15127 /* Scroll bar support.  */
 15128 
 15129 #if defined HAVE_XINPUT2
 15130 
 15131 /* Select for input extension events used by scroll bars.  This will
 15132    result in the corresponding core events not being generated for
 15133    SCROLL_BAR.  */
 15134 
 15135 MAYBE_UNUSED static void
 15136 xi_select_scroll_bar_events (struct x_display_info *dpyinfo,
 15137                              Window scroll_bar)
 15138 {
 15139   XIEventMask mask;
 15140   unsigned char *m;
 15141   ptrdiff_t length;
 15142 
 15143   length = XIMaskLen (XI_LASTEVENT);
 15144   mask.mask = m = alloca (length);
 15145   memset (m, 0, length);
 15146   mask.mask_len = length;
 15147 
 15148   mask.deviceid = XIAllMasterDevices;
 15149   XISetMask (m, XI_ButtonPress);
 15150   XISetMask (m, XI_ButtonRelease);
 15151   XISetMask (m, XI_Motion);
 15152   XISetMask (m, XI_Enter);
 15153   XISetMask (m, XI_Leave);
 15154 
 15155   XISelectEvents (dpyinfo->display, scroll_bar, &mask, 1);
 15156 }
 15157 
 15158 #endif
 15159 
 15160 /* Given an X window ID and a DISPLAY, find the struct scroll_bar which
 15161    manages it.
 15162    This can be called in GC, so we have to make sure to strip off mark
 15163    bits.  */
 15164 
 15165 static struct scroll_bar *
 15166 x_window_to_scroll_bar (Display *display, Window window_id, int type)
 15167 {
 15168   Lisp_Object tail, frame;
 15169 
 15170 #if defined (USE_GTK) && !defined (HAVE_GTK3) && defined (USE_TOOLKIT_SCROLL_BARS)
 15171   window_id = (Window) xg_get_scroll_id_for_window (display, window_id);
 15172 #endif /* USE_GTK && !HAVE_GTK3  && USE_TOOLKIT_SCROLL_BARS */
 15173 
 15174   FOR_EACH_FRAME (tail, frame)
 15175     {
 15176       Lisp_Object bar, condemned;
 15177 
 15178       if (! FRAME_X_P (XFRAME (frame)))
 15179         continue;
 15180 
 15181       /* Scan this frame's scroll bar list for a scroll bar with the
 15182          right window ID.  */
 15183       condemned = FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame));
 15184       for (bar = FRAME_SCROLL_BARS (XFRAME (frame));
 15185            /* This trick allows us to search both the ordinary and
 15186               condemned scroll bar lists with one loop.  */
 15187            ! NILP (bar) || (bar = condemned,
 15188                                condemned = Qnil,
 15189                                ! NILP (bar));
 15190            bar = XSCROLL_BAR (bar)->next)
 15191         if (XSCROLL_BAR (bar)->x_window == window_id
 15192             && FRAME_X_DISPLAY (XFRAME (frame)) == display
 15193             && (type == 2
 15194                 || (type == 1 && XSCROLL_BAR (bar)->horizontal)
 15195                 || (type == 0 && !XSCROLL_BAR (bar)->horizontal)))
 15196           return XSCROLL_BAR (bar);
 15197     }
 15198 
 15199   return NULL;
 15200 }
 15201 
 15202 
 15203 #if defined USE_LUCID
 15204 
 15205 /* Return the Lucid menu bar WINDOW is part of.  Return null
 15206    if WINDOW is not part of a menu bar.  */
 15207 
 15208 static Widget
 15209 x_window_to_menu_bar (Window window)
 15210 {
 15211   Lisp_Object tail, frame;
 15212 
 15213   FOR_EACH_FRAME (tail, frame)
 15214     if (FRAME_X_P (XFRAME (frame)))
 15215       {
 15216         Widget menu_bar = XFRAME (frame)->output_data.x->menubar_widget;
 15217 
 15218         if (menu_bar && xlwmenu_window_p (menu_bar, window))
 15219           return menu_bar;
 15220       }
 15221   return NULL;
 15222 }
 15223 
 15224 #endif /* USE_LUCID */
 15225 
 15226 
 15227 /************************************************************************
 15228                          Toolkit scroll bars
 15229  ************************************************************************/
 15230 
 15231 #ifdef USE_TOOLKIT_SCROLL_BARS
 15232 
 15233 static void x_send_scroll_bar_event (Lisp_Object, enum scroll_bar_part,
 15234                                      int, int, bool);
 15235 
 15236 /* Lisp window being scrolled.  Set when starting to interact with
 15237    a toolkit scroll bar, reset to nil when ending the interaction.  */
 15238 
 15239 static Lisp_Object window_being_scrolled;
 15240 
 15241 static Time
 15242 x_get_last_toolkit_time (struct x_display_info *dpyinfo)
 15243 {
 15244 #ifdef USE_X_TOOLKIT
 15245   return XtLastTimestampProcessed (dpyinfo->display);
 15246 #else
 15247   return dpyinfo->last_user_time;
 15248 #endif
 15249 }
 15250 
 15251 #ifndef USE_GTK
 15252 /* Id of action hook installed for scroll bars and horizontal scroll
 15253    bars.  */
 15254 
 15255 static XtActionHookId action_hook_id;
 15256 static XtActionHookId horizontal_action_hook_id;
 15257 
 15258 /* Whether this is an Xaw with arrow-scrollbars.  This should imply
 15259    that movements of 1/20 of the screen size are mapped to up/down.  */
 15260 
 15261 static Boolean xaw3d_arrow_scroll;
 15262 
 15263 /* Whether the drag scrolling maintains the mouse at the top of the
 15264    thumb.  If not, resizing the thumb needs to be done more carefully
 15265    to avoid jerkiness.  */
 15266 
 15267 static Boolean xaw3d_pick_top;
 15268 
 15269 /* Action hook installed via XtAppAddActionHook when toolkit scroll
 15270    bars are used..  The hook is responsible for detecting when
 15271    the user ends an interaction with the scroll bar, and generates
 15272    a `end-scroll' SCROLL_BAR_CLICK_EVENT' event if so.  */
 15273 
 15274 static void
 15275 xt_action_hook (Widget widget, XtPointer client_data, String action_name,
 15276                 XEvent *event, String *params, Cardinal *num_params)
 15277 {
 15278   bool scroll_bar_p;
 15279   const char *end_action;
 15280 
 15281 #ifdef USE_MOTIF
 15282   scroll_bar_p = XmIsScrollBar (widget);
 15283   end_action = "Release";
 15284 #else /* !USE_MOTIF i.e. use Xaw */
 15285   scroll_bar_p = XtIsSubclass (widget, scrollbarWidgetClass);
 15286   end_action = "EndScroll";
 15287 #endif /* USE_MOTIF */
 15288 
 15289   if (scroll_bar_p
 15290       && strcmp (action_name, end_action) == 0
 15291       && WINDOWP (window_being_scrolled))
 15292     {
 15293       struct window *w;
 15294       struct scroll_bar *bar;
 15295 
 15296       x_send_scroll_bar_event (window_being_scrolled,
 15297                                scroll_bar_end_scroll, 0, 0, false);
 15298       w = XWINDOW (window_being_scrolled);
 15299       bar = XSCROLL_BAR (w->vertical_scroll_bar);
 15300 
 15301       if (bar->dragging != -1)
 15302         {
 15303           bar->dragging = -1;
 15304           /* The thumb size is incorrect while dragging: fix it.  */
 15305           set_vertical_scroll_bar (w);
 15306         }
 15307       window_being_scrolled = Qnil;
 15308 #if defined (USE_LUCID)
 15309       bar->last_seen_part = scroll_bar_nowhere;
 15310 #endif
 15311       /* Xt timeouts no longer needed.  */
 15312       toolkit_scroll_bar_interaction = false;
 15313     }
 15314 }
 15315 
 15316 
 15317 static void
 15318 xt_horizontal_action_hook (Widget widget, XtPointer client_data, String action_name,
 15319                            XEvent *event, String *params, Cardinal *num_params)
 15320 {
 15321   bool scroll_bar_p;
 15322   const char *end_action;
 15323 
 15324 #ifdef USE_MOTIF
 15325   scroll_bar_p = XmIsScrollBar (widget);
 15326   end_action = "Release";
 15327 #else /* !USE_MOTIF i.e. use Xaw */
 15328   scroll_bar_p = XtIsSubclass (widget, scrollbarWidgetClass);
 15329   end_action = "EndScroll";
 15330 #endif /* USE_MOTIF */
 15331 
 15332   if (scroll_bar_p
 15333       && strcmp (action_name, end_action) == 0
 15334       && WINDOWP (window_being_scrolled))
 15335     {
 15336       struct window *w;
 15337       struct scroll_bar *bar;
 15338 
 15339       x_send_scroll_bar_event (window_being_scrolled,
 15340                                scroll_bar_end_scroll, 0, 0, true);
 15341       w = XWINDOW (window_being_scrolled);
 15342       if (!NILP (w->horizontal_scroll_bar))
 15343         {
 15344           bar = XSCROLL_BAR (w->horizontal_scroll_bar);
 15345           if (bar->dragging != -1)
 15346             {
 15347               bar->dragging = -1;
 15348               /* The thumb size is incorrect while dragging: fix it.  */
 15349               set_horizontal_scroll_bar (w);
 15350             }
 15351           window_being_scrolled = Qnil;
 15352 #if defined (USE_LUCID)
 15353           bar->last_seen_part = scroll_bar_nowhere;
 15354 #endif
 15355           /* Xt timeouts no longer needed.  */
 15356           toolkit_scroll_bar_interaction = false;
 15357         }
 15358     }
 15359 }
 15360 #endif /* not USE_GTK */
 15361 
 15362 /* Protect WINDOW from garbage collection until a matching scroll bar
 15363    message is received.  Return whether or not protection
 15364    succeeded.  */
 15365 static bool
 15366 x_protect_window_for_callback (struct x_display_info *dpyinfo,
 15367                                Lisp_Object window)
 15368 {
 15369   if (dpyinfo->n_protected_windows + 1
 15370       >= dpyinfo->protected_windows_max)
 15371     return false;
 15372 
 15373   dpyinfo->protected_windows[dpyinfo->n_protected_windows++]
 15374     = window;
 15375   return true;
 15376 }
 15377 
 15378 static Lisp_Object
 15379 x_unprotect_window_for_callback (struct x_display_info *dpyinfo)
 15380 {
 15381   Lisp_Object window;
 15382 
 15383   if (!dpyinfo->n_protected_windows)
 15384     return Qnil;
 15385 
 15386   window = dpyinfo->protected_windows[0];
 15387 
 15388   dpyinfo->n_protected_windows--;
 15389 
 15390   if (dpyinfo->n_protected_windows)
 15391     memmove (dpyinfo->protected_windows, &dpyinfo->protected_windows[1],
 15392              sizeof (Lisp_Object) * dpyinfo->n_protected_windows);
 15393 
 15394   return window;
 15395 }
 15396 
 15397 /* Send a client message with message type Xatom_Scrollbar for a
 15398    scroll action to the frame of WINDOW.  PART is a value identifying
 15399    the part of the scroll bar that was clicked on.  PORTION is the
 15400    amount to scroll of a whole of WHOLE.  */
 15401 
 15402 static void
 15403 x_send_scroll_bar_event (Lisp_Object window, enum scroll_bar_part part,
 15404                          int portion, int whole, bool horizontal)
 15405 {
 15406   XEvent event;
 15407   XClientMessageEvent *ev = &event.xclient;
 15408   struct window *w = XWINDOW (window);
 15409   struct frame *f = XFRAME (w->frame);
 15410   verify (INTPTR_WIDTH <= 64);
 15411 
 15412   /* Don't do anything if too many scroll bar events have been
 15413      sent but not received.  */
 15414   if (!x_protect_window_for_callback (FRAME_DISPLAY_INFO (f), window))
 15415     return;
 15416 
 15417   block_input ();
 15418   /* Construct a ClientMessage event to send to the frame.  */
 15419   ev->type = ClientMessage;
 15420   ev->message_type = (horizontal
 15421                       ? FRAME_DISPLAY_INFO (f)->Xatom_Horizontal_Scrollbar
 15422                       : FRAME_DISPLAY_INFO (f)->Xatom_Scrollbar);
 15423   ev->display = FRAME_X_DISPLAY (f);
 15424   ev->window = FRAME_X_WINDOW (f);
 15425   ev->format = 32;
 15426 
 15427   /* These messages formerly contained a pointer to the window, but
 15428      now that information is kept internally.  The following two
 15429      fields are thus zero.  */
 15430   ev->data.l[0] = 0;
 15431   ev->data.l[1] = 0;
 15432   ev->data.l[2] = part;
 15433   ev->data.l[3] = portion;
 15434   ev->data.l[4] = whole;
 15435 
 15436   /* Make Xt timeouts work while the scroll bar is active.  */
 15437 #ifdef USE_X_TOOLKIT
 15438   toolkit_scroll_bar_interaction = true;
 15439   x_activate_timeout_atimer ();
 15440 #endif
 15441 
 15442   /* Setting the event mask to zero means that the message will
 15443      be sent to the client that created the window, and if that
 15444      window no longer exists, no event will be sent.  */
 15445   XSendEvent (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), False,
 15446               NoEventMask, &event);
 15447   unblock_input ();
 15448 }
 15449 
 15450 
 15451 /* Transform a scroll bar ClientMessage EVENT to an Emacs input event
 15452    in *IEVENT.  */
 15453 
 15454 static void
 15455 x_scroll_bar_to_input_event (struct x_display_info *dpyinfo,
 15456                              const XEvent *event,
 15457                              struct input_event *ievent)
 15458 {
 15459   Lisp_Object window;
 15460 
 15461   /* Every time a scroll bar ClientMessage event is sent, the window
 15462      is pushed onto a queue that is traced for garbage collection.
 15463      Every time we need a window for a read scroll bar event, we
 15464      simply read from the other side of the queue.  */
 15465   window = x_unprotect_window_for_callback (dpyinfo);
 15466 
 15467   if (NILP (window))
 15468     {
 15469       /* This means we are getting extra scroll bar events for some
 15470          reason, and shouldn't be possible in practice.  */
 15471       EVENT_INIT (*ievent);
 15472       return;
 15473     }
 15474 
 15475   ievent->kind = SCROLL_BAR_CLICK_EVENT;
 15476   ievent->frame_or_window = window;
 15477   ievent->arg = Qnil;
 15478   ievent->timestamp = x_get_last_toolkit_time (dpyinfo);
 15479   ievent->code = 0;
 15480   ievent->part = event->xclient.data.l[2];
 15481   ievent->x = make_fixnum (event->xclient.data.l[3]);
 15482   ievent->y = make_fixnum (event->xclient.data.l[4]);
 15483   ievent->modifiers = 0;
 15484 }
 15485 
 15486 /* Transform a horizontal scroll bar ClientMessage EVENT to an Emacs
 15487    input event in *IEVENT.  */
 15488 
 15489 static void
 15490 x_horizontal_scroll_bar_to_input_event (struct x_display_info *dpyinfo,
 15491                                         const XEvent *event,
 15492                                         struct input_event *ievent)
 15493 {
 15494   Lisp_Object window;
 15495 
 15496   /* Every time a scroll bar ClientMessage event is sent, the window
 15497      is pushed onto a queue that is traced for garbage collection.
 15498      Every time we need a window for a read scroll bar event, we
 15499      simply read from the other side of the queue.  */
 15500   window = x_unprotect_window_for_callback (dpyinfo);
 15501 
 15502   if (NILP (window))
 15503     {
 15504       /* This means we are getting extra scroll bar events for some
 15505          reason, and shouldn't be possible in practice.  */
 15506       EVENT_INIT (*ievent);
 15507       return;
 15508     }
 15509 
 15510   ievent->kind = HORIZONTAL_SCROLL_BAR_CLICK_EVENT;
 15511   ievent->frame_or_window = window;
 15512   ievent->arg = Qnil;
 15513   ievent->timestamp = x_get_last_toolkit_time (dpyinfo);
 15514   ievent->code = 0;
 15515   ievent->part = event->xclient.data.l[2];
 15516   ievent->x = make_fixnum (event->xclient.data.l[3]);
 15517   ievent->y = make_fixnum (event->xclient.data.l[4]);
 15518   ievent->modifiers = 0;
 15519 }
 15520 
 15521 
 15522 #ifdef USE_MOTIF
 15523 
 15524 /* Minimum and maximum values used for Motif scroll bars.  */
 15525 
 15526 #define XM_SB_MAX 10000000
 15527 
 15528 /* Scroll bar callback for Motif scroll bars.  WIDGET is the scroll
 15529    bar widget.  CLIENT_DATA is a pointer to the scroll_bar structure.
 15530    CALL_DATA is a pointer to a XmScrollBarCallbackStruct.  */
 15531 
 15532 static void
 15533 xm_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data)
 15534 {
 15535   struct scroll_bar *bar = client_data;
 15536   XmScrollBarCallbackStruct *cs = call_data;
 15537   enum scroll_bar_part part = scroll_bar_nowhere;
 15538   bool horizontal = bar->horizontal;
 15539   int whole = 0, portion = 0;
 15540 
 15541   switch (cs->reason)
 15542     {
 15543     case XmCR_DECREMENT:
 15544       bar->dragging = -1;
 15545       part = horizontal ? scroll_bar_left_arrow : scroll_bar_up_arrow;
 15546       break;
 15547 
 15548     case XmCR_INCREMENT:
 15549       bar->dragging = -1;
 15550       part = horizontal ? scroll_bar_right_arrow : scroll_bar_down_arrow;
 15551       break;
 15552 
 15553     case XmCR_PAGE_DECREMENT:
 15554       bar->dragging = -1;
 15555       part = horizontal ? scroll_bar_before_handle : scroll_bar_above_handle;
 15556       break;
 15557 
 15558     case XmCR_PAGE_INCREMENT:
 15559       bar->dragging = -1;
 15560       part = horizontal ? scroll_bar_after_handle : scroll_bar_below_handle;
 15561       break;
 15562 
 15563     case XmCR_TO_TOP:
 15564       bar->dragging = -1;
 15565       part = horizontal ? scroll_bar_to_leftmost : scroll_bar_to_top;
 15566       break;
 15567 
 15568     case XmCR_TO_BOTTOM:
 15569       bar->dragging = -1;
 15570       part = horizontal ? scroll_bar_to_rightmost : scroll_bar_to_bottom;
 15571       break;
 15572 
 15573     case XmCR_DRAG:
 15574       {
 15575         int slider_size;
 15576 
 15577         block_input ();
 15578         XtVaGetValues (widget, XmNsliderSize, &slider_size, NULL);
 15579         unblock_input ();
 15580 
 15581         if (horizontal)
 15582           {
 15583             portion = bar->whole * ((float)cs->value / XM_SB_MAX);
 15584             whole = bar->whole * ((float)(XM_SB_MAX - slider_size) / XM_SB_MAX);
 15585             portion = min (portion, whole);
 15586             part = scroll_bar_horizontal_handle;
 15587           }
 15588         else
 15589           {
 15590             whole = XM_SB_MAX - slider_size;
 15591             portion = min (cs->value, whole);
 15592             part = scroll_bar_handle;
 15593           }
 15594 
 15595         bar->dragging = cs->value;
 15596       }
 15597       break;
 15598 
 15599     case XmCR_VALUE_CHANGED:
 15600       break;
 15601     };
 15602 
 15603   if (part != scroll_bar_nowhere)
 15604     {
 15605       window_being_scrolled = bar->window;
 15606       x_send_scroll_bar_event (bar->window, part, portion, whole,
 15607                                bar->horizontal);
 15608     }
 15609 }
 15610 
 15611 #elif defined USE_GTK
 15612 
 15613 /* Scroll bar callback for GTK scroll bars.  WIDGET is the scroll
 15614    bar widget.  DATA is a pointer to the scroll_bar structure. */
 15615 
 15616 static gboolean
 15617 xg_scroll_callback (GtkRange *range, GtkScrollType scroll,
 15618                     gdouble value, gpointer user_data)
 15619 {
 15620   int whole, portion;
 15621   struct scroll_bar *bar;
 15622   enum scroll_bar_part part;
 15623   GtkAdjustment *adj;
 15624   struct frame *f;
 15625   guint32 time;
 15626   struct x_display_info *dpyinfo;
 15627 
 15628   if (xg_ignore_gtk_scrollbar) return false;
 15629 
 15630   whole = 0;
 15631   portion = 0;
 15632   bar = user_data;
 15633   part = scroll_bar_nowhere;
 15634   adj = GTK_ADJUSTMENT (gtk_range_get_adjustment (range));
 15635   f = g_object_get_data (G_OBJECT (range), XG_FRAME_DATA);
 15636   time = gtk_get_current_event_time ();
 15637   dpyinfo = FRAME_DISPLAY_INFO (f);
 15638 
 15639   if (time != GDK_CURRENT_TIME)
 15640     x_display_set_last_user_time (dpyinfo, time, true,
 15641                                   true);
 15642 
 15643   switch (scroll)
 15644     {
 15645     case GTK_SCROLL_JUMP:
 15646       /* Buttons 1 2 or 3 must be grabbed.  */
 15647       if (FRAME_DISPLAY_INFO (f)->grabbed != 0
 15648           && FRAME_DISPLAY_INFO (f)->grabbed < (1 << 4))
 15649         {
 15650           if (bar->horizontal)
 15651             {
 15652               part = scroll_bar_horizontal_handle;
 15653               whole = (int)(gtk_adjustment_get_upper (adj) -
 15654                             gtk_adjustment_get_page_size (adj));
 15655               portion = min ((int)value, whole);
 15656               bar->dragging = portion;
 15657             }
 15658           else
 15659             {
 15660               part = scroll_bar_handle;
 15661               whole = gtk_adjustment_get_upper (adj) -
 15662                 gtk_adjustment_get_page_size (adj);
 15663               portion = min ((int)value, whole);
 15664               bar->dragging = portion;
 15665             }
 15666         }
 15667       break;
 15668     case GTK_SCROLL_STEP_BACKWARD:
 15669       part = (bar->horizontal
 15670               ? scroll_bar_left_arrow : scroll_bar_up_arrow);
 15671       bar->dragging = -1;
 15672       break;
 15673     case GTK_SCROLL_STEP_FORWARD:
 15674       part = (bar->horizontal
 15675               ? scroll_bar_right_arrow : scroll_bar_down_arrow);
 15676       bar->dragging = -1;
 15677       break;
 15678     case GTK_SCROLL_PAGE_BACKWARD:
 15679       part = (bar->horizontal
 15680               ? scroll_bar_before_handle : scroll_bar_above_handle);
 15681       bar->dragging = -1;
 15682       break;
 15683     case GTK_SCROLL_PAGE_FORWARD:
 15684       part = (bar->horizontal
 15685               ? scroll_bar_after_handle : scroll_bar_below_handle);
 15686       bar->dragging = -1;
 15687       break;
 15688     default:
 15689       break;
 15690     }
 15691 
 15692   if (part != scroll_bar_nowhere)
 15693     {
 15694       window_being_scrolled = bar->window;
 15695       x_send_scroll_bar_event (bar->window, part, portion, whole,
 15696                                bar->horizontal);
 15697     }
 15698 
 15699   return false;
 15700 }
 15701 
 15702 /* Callback for button release. Sets dragging to -1 when dragging is done.  */
 15703 
 15704 static gboolean
 15705 xg_end_scroll_callback (GtkWidget *widget,
 15706                         GdkEventButton *event,
 15707                         gpointer user_data)
 15708 {
 15709   struct scroll_bar *bar;
 15710 
 15711   bar = user_data;
 15712   bar->dragging = -1;
 15713 
 15714   if (WINDOWP (window_being_scrolled))
 15715     {
 15716       x_send_scroll_bar_event (window_being_scrolled,
 15717                                scroll_bar_end_scroll, 0, 0, bar->horizontal);
 15718       window_being_scrolled = Qnil;
 15719     }
 15720 
 15721   return false;
 15722 }
 15723 
 15724 
 15725 #else /* not USE_GTK and not USE_MOTIF */
 15726 
 15727 /* Xaw scroll bar callback.  Invoked when the thumb is dragged.
 15728    WIDGET is the scroll bar widget.  CLIENT_DATA is a pointer to the
 15729    scroll bar struct.  CALL_DATA is a pointer to a float saying where
 15730    the thumb is.  */
 15731 
 15732 static void
 15733 xaw_jump_callback (Widget widget, XtPointer client_data, XtPointer call_data)
 15734 {
 15735   struct scroll_bar *bar = client_data;
 15736   float *top_addr = call_data;
 15737   float top = *top_addr;
 15738   float shown;
 15739   int whole, portion, height, width;
 15740   enum scroll_bar_part part;
 15741   bool horizontal = bar->horizontal;
 15742 
 15743   if (horizontal)
 15744     {
 15745       /* Get the size of the thumb, a value between 0 and 1.  */
 15746       block_input ();
 15747       XtVaGetValues (widget, XtNshown, &shown, XtNwidth, &width, NULL);
 15748       unblock_input ();
 15749 
 15750       if (shown < 1)
 15751         {
 15752           whole = bar->whole - (shown * bar->whole);
 15753           portion = min (top * bar->whole, whole);
 15754         }
 15755       else
 15756         {
 15757           whole = bar->whole;
 15758           portion = 0;
 15759         }
 15760 
 15761       part = scroll_bar_horizontal_handle;
 15762     }
 15763   else
 15764     {
 15765       /* Get the size of the thumb, a value between 0 and 1.  */
 15766       block_input ();
 15767       XtVaGetValues (widget, XtNshown, &shown, XtNheight, &height, NULL);
 15768       unblock_input ();
 15769 
 15770       whole = 10000000;
 15771       portion = shown < 1 ? top * whole : 0;
 15772 
 15773       if (shown < 1 && (eabs (top + shown - 1) < 1.0f / height))
 15774         /* Some derivatives of Xaw refuse to shrink the thumb when you reach
 15775            the bottom, so we force the scrolling whenever we see that we're
 15776            too close to the bottom (in x_set_toolkit_scroll_bar_thumb
 15777            we try to ensure that we always stay two pixels away from the
 15778            bottom).  */
 15779         part = scroll_bar_down_arrow;
 15780       else
 15781         part = scroll_bar_handle;
 15782     }
 15783 
 15784   window_being_scrolled = bar->window;
 15785   bar->dragging = portion;
 15786   bar->last_seen_part = part;
 15787   x_send_scroll_bar_event (bar->window, part, portion, whole, bar->horizontal);
 15788 }
 15789 
 15790 
 15791 /* Xaw scroll bar callback.  Invoked for incremental scrolling.,
 15792    i.e. line or page up or down.  WIDGET is the Xaw scroll bar
 15793    widget.  CLIENT_DATA is a pointer to the scroll_bar structure for
 15794    the scroll bar.  CALL_DATA is an integer specifying the action that
 15795    has taken place.  Its magnitude is in the range 0..height of the
 15796    scroll bar.  Negative values mean scroll towards buffer start.
 15797    Values < height of scroll bar mean line-wise movement.  */
 15798 
 15799 static void
 15800 xaw_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data)
 15801 {
 15802   struct scroll_bar *bar = client_data;
 15803   /* The position really is stored cast to a pointer.  */
 15804   int position = (intptr_t) call_data;
 15805   Dimension height, width;
 15806   enum scroll_bar_part part;
 15807 
 15808   if (bar->horizontal)
 15809     {
 15810       /* Get the width of the scroll bar.  */
 15811       block_input ();
 15812       XtVaGetValues (widget, XtNwidth, &width, NULL);
 15813       unblock_input ();
 15814 
 15815       if (eabs (position) >= width)
 15816         part = (position < 0) ? scroll_bar_before_handle : scroll_bar_after_handle;
 15817 
 15818       /* If Xaw3d was compiled with ARROW_SCROLLBAR,
 15819          it maps line-movement to call_data = max(5, height/20).  */
 15820       else if (xaw3d_arrow_scroll && eabs (position) <= max (5, width / 20))
 15821         part = (position < 0) ? scroll_bar_left_arrow : scroll_bar_right_arrow;
 15822       else
 15823         part = scroll_bar_move_ratio;
 15824 
 15825       window_being_scrolled = bar->window;
 15826       bar->dragging = -1;
 15827       bar->last_seen_part = part;
 15828       x_send_scroll_bar_event (bar->window, part, position, width,
 15829                                bar->horizontal);
 15830     }
 15831   else
 15832     {
 15833 
 15834       /* Get the height of the scroll bar.  */
 15835       block_input ();
 15836       XtVaGetValues (widget, XtNheight, &height, NULL);
 15837       unblock_input ();
 15838 
 15839       if (eabs (position) >= height)
 15840         part = (position < 0) ? scroll_bar_above_handle : scroll_bar_below_handle;
 15841 
 15842       /* If Xaw3d was compiled with ARROW_SCROLLBAR,
 15843          it maps line-movement to call_data = max(5, height/20).  */
 15844       else if (xaw3d_arrow_scroll && eabs (position) <= max (5, height / 20))
 15845         part = (position < 0) ? scroll_bar_up_arrow : scroll_bar_down_arrow;
 15846       else
 15847         part = scroll_bar_move_ratio;
 15848 
 15849       window_being_scrolled = bar->window;
 15850       bar->dragging = -1;
 15851       bar->last_seen_part = part;
 15852       x_send_scroll_bar_event (bar->window, part, position, height,
 15853                                bar->horizontal);
 15854     }
 15855 }
 15856 
 15857 #endif /* not USE_GTK and not USE_MOTIF */
 15858 
 15859 #define SCROLL_BAR_NAME "verticalScrollBar"
 15860 #define SCROLL_BAR_HORIZONTAL_NAME "horizontalScrollBar"
 15861 
 15862 /* Create the widget for scroll bar BAR on frame F.  Record the widget
 15863    and X window of the scroll bar in BAR.  */
 15864 
 15865 #ifdef USE_GTK
 15866 static void
 15867 x_create_toolkit_scroll_bar (struct frame *f, struct scroll_bar *bar)
 15868 {
 15869   const char *scroll_bar_name = SCROLL_BAR_NAME;
 15870 
 15871   block_input ();
 15872   xg_create_scroll_bar (f, bar, G_CALLBACK (xg_scroll_callback),
 15873                         G_CALLBACK (xg_end_scroll_callback),
 15874                         scroll_bar_name);
 15875   unblock_input ();
 15876 }
 15877 
 15878 static void
 15879 x_create_horizontal_toolkit_scroll_bar (struct frame *f, struct scroll_bar *bar)
 15880 {
 15881   const char *scroll_bar_name = SCROLL_BAR_HORIZONTAL_NAME;
 15882 
 15883   block_input ();
 15884   xg_create_horizontal_scroll_bar (f, bar, G_CALLBACK (xg_scroll_callback),
 15885                                    G_CALLBACK (xg_end_scroll_callback),
 15886                                    scroll_bar_name);
 15887   unblock_input ();
 15888 }
 15889 
 15890 #else /* not USE_GTK */
 15891 
 15892 static void
 15893 x_create_toolkit_scroll_bar (struct frame *f, struct scroll_bar *bar)
 15894 {
 15895   Window xwindow;
 15896   Widget widget;
 15897   Arg av[20];
 15898   int ac = 0;
 15899   const char *scroll_bar_name = SCROLL_BAR_NAME;
 15900   unsigned long pixel;
 15901 
 15902   block_input ();
 15903 
 15904 #ifdef USE_MOTIF
 15905   /* Set resources.  Create the widget.  */
 15906   XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac;
 15907   XtSetArg (av[ac], XmNminimum, 0); ++ac;
 15908   XtSetArg (av[ac], XmNmaximum, XM_SB_MAX); ++ac;
 15909   XtSetArg (av[ac], XmNorientation, XmVERTICAL); ++ac;
 15910   XtSetArg (av[ac], XmNprocessingDirection, XmMAX_ON_BOTTOM), ++ac;
 15911   XtSetArg (av[ac], XmNincrement, 1); ++ac;
 15912   XtSetArg (av[ac], XmNpageIncrement, 1); ++ac;
 15913 
 15914   /* Note: "background" is the thumb color, and "trough" is the color behind
 15915      everything. */
 15916   pixel = f->output_data.x->scroll_bar_foreground_pixel;
 15917   if (pixel != -1)
 15918     {
 15919       XtSetArg (av[ac], XmNbackground, pixel);
 15920       ++ac;
 15921     }
 15922 
 15923   pixel = f->output_data.x->scroll_bar_background_pixel;
 15924   if (pixel != -1)
 15925     {
 15926       XtSetArg (av[ac], XmNtroughColor, pixel);
 15927       ++ac;
 15928     }
 15929 
 15930   widget = XmCreateScrollBar (f->output_data.x->edit_widget,
 15931                               (char *) scroll_bar_name, av, ac);
 15932 
 15933   /* Add one callback for everything that can happen.  */
 15934   XtAddCallback (widget, XmNdecrementCallback, xm_scroll_callback,
 15935                  (XtPointer) bar);
 15936   XtAddCallback (widget, XmNdragCallback, xm_scroll_callback,
 15937                  (XtPointer) bar);
 15938   XtAddCallback (widget, XmNincrementCallback, xm_scroll_callback,
 15939                  (XtPointer) bar);
 15940   XtAddCallback (widget, XmNpageDecrementCallback, xm_scroll_callback,
 15941                  (XtPointer) bar);
 15942   XtAddCallback (widget, XmNpageIncrementCallback, xm_scroll_callback,
 15943                  (XtPointer) bar);
 15944   XtAddCallback (widget, XmNtoBottomCallback, xm_scroll_callback,
 15945                  (XtPointer) bar);
 15946   XtAddCallback (widget, XmNtoTopCallback, xm_scroll_callback,
 15947                  (XtPointer) bar);
 15948 
 15949   /* Realize the widget.  Only after that is the X window created.  */
 15950   XtRealizeWidget (widget);
 15951 
 15952   /* Set the cursor to an arrow.  I didn't find a resource to do that.
 15953      And I'm wondering why it hasn't an arrow cursor by default.  */
 15954   XDefineCursor (XtDisplay (widget), XtWindow (widget),
 15955                  f->output_data.x->nontext_cursor);
 15956 
 15957 #ifdef HAVE_XINPUT2
 15958   /* Ask for input extension button and motion events.  This lets us
 15959      send the proper `wheel-up' or `wheel-down' events to Emacs.  */
 15960   if (FRAME_DISPLAY_INFO (f)->supports_xi2)
 15961     xi_select_scroll_bar_events (FRAME_DISPLAY_INFO (f),
 15962                                  XtWindow (widget));
 15963 #endif
 15964 #else /* !USE_MOTIF i.e. use Xaw */
 15965 
 15966   /* Set resources.  Create the widget.  The background of the
 15967      Xaw3d scroll bar widget is a little bit light for my taste.
 15968      We don't alter it here to let users change it according
 15969      to their taste with `emacs*verticalScrollBar.background: xxx'.  */
 15970   XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac;
 15971   XtSetArg (av[ac], XtNorientation, XtorientVertical); ++ac;
 15972   /* For smoother scrolling with Xaw3d   -sm */
 15973   /* XtSetArg (av[ac], XtNpickTop, True); ++ac; */
 15974 
 15975   pixel = f->output_data.x->scroll_bar_foreground_pixel;
 15976   if (pixel != -1)
 15977     {
 15978       XtSetArg (av[ac], XtNforeground, pixel);
 15979       ++ac;
 15980     }
 15981 
 15982   pixel = f->output_data.x->scroll_bar_background_pixel;
 15983   if (pixel != -1)
 15984     {
 15985       XtSetArg (av[ac], XtNbackground, pixel);
 15986       ++ac;
 15987     }
 15988 
 15989   /* Top/bottom shadow colors.  */
 15990 
 15991   /* Allocate them, if necessary.  */
 15992   if (f->output_data.x->scroll_bar_top_shadow_pixel == -1)
 15993     {
 15994       pixel = f->output_data.x->scroll_bar_background_pixel;
 15995       if (pixel != -1)
 15996         {
 15997           if (!x_alloc_lighter_color (f, FRAME_X_DISPLAY (f),
 15998                                       FRAME_X_COLORMAP (f),
 15999                                       &pixel, 1.2, 0x8000))
 16000             pixel = -1;
 16001           f->output_data.x->scroll_bar_top_shadow_pixel = pixel;
 16002         }
 16003     }
 16004   if (f->output_data.x->scroll_bar_bottom_shadow_pixel == -1)
 16005     {
 16006       pixel = f->output_data.x->scroll_bar_background_pixel;
 16007       if (pixel != -1)
 16008         {
 16009           if (!x_alloc_lighter_color (f, FRAME_X_DISPLAY (f),
 16010                                       FRAME_X_COLORMAP (f),
 16011                                       &pixel, 0.6, 0x4000))
 16012             pixel = -1;
 16013           f->output_data.x->scroll_bar_bottom_shadow_pixel = pixel;
 16014         }
 16015     }
 16016 
 16017 #ifdef XtNbeNiceToColormap
 16018   /* Tell the toolkit about them.  */
 16019   if (f->output_data.x->scroll_bar_top_shadow_pixel == -1
 16020       || f->output_data.x->scroll_bar_bottom_shadow_pixel == -1)
 16021     /* We tried to allocate a color for the top/bottom shadow, and
 16022        failed, so tell Xaw3d to use dithering instead.   */
 16023     /* But only if we have a small colormap.  Xaw3d can allocate nice
 16024        colors itself.  */
 16025     {
 16026       XtSetArg (av[ac], (String) XtNbeNiceToColormap,
 16027                 DefaultDepthOfScreen (FRAME_X_SCREEN (f)) < 16);
 16028       ++ac;
 16029     }
 16030   else
 16031     /* Tell what colors Xaw3d should use for the top/bottom shadow, to
 16032        be more consistent with other emacs 3d colors, and since Xaw3d is
 16033        not good at dealing with allocation failure.  */
 16034     {
 16035       /* This tells Xaw3d to use real colors instead of dithering for
 16036          the shadows.  */
 16037       XtSetArg (av[ac], (String) XtNbeNiceToColormap, False);
 16038       ++ac;
 16039 
 16040       /* Specify the colors.  */
 16041       pixel = f->output_data.x->scroll_bar_top_shadow_pixel;
 16042       if (pixel != -1)
 16043         {
 16044           XtSetArg (av[ac], (String) XtNtopShadowPixel, pixel);
 16045           ++ac;
 16046         }
 16047       pixel = f->output_data.x->scroll_bar_bottom_shadow_pixel;
 16048       if (pixel != -1)
 16049         {
 16050           XtSetArg (av[ac], (String) XtNbottomShadowPixel, pixel);
 16051           ++ac;
 16052         }
 16053     }
 16054 #endif
 16055 
 16056   widget = XtCreateWidget (scroll_bar_name, scrollbarWidgetClass,
 16057                            f->output_data.x->edit_widget, av, ac);
 16058 
 16059   {
 16060     char const *initial = "";
 16061     char const *val = initial;
 16062     XtVaGetValues (widget, XtNscrollVCursor, (XtPointer) &val,
 16063 #ifdef XtNarrowScrollbars
 16064                    XtNarrowScrollbars, (XtPointer) &xaw3d_arrow_scroll,
 16065 #endif
 16066                    XtNpickTop, (XtPointer) &xaw3d_pick_top, NULL);
 16067     if (xaw3d_arrow_scroll || val == initial)
 16068       { /* ARROW_SCROLL */
 16069         xaw3d_arrow_scroll = True;
 16070         /* Isn't that just a personal preference ?   --Stef */
 16071         XtVaSetValues (widget, XtNcursorName, "top_left_arrow", NULL);
 16072       }
 16073   }
 16074 
 16075   /* Define callbacks.  */
 16076   XtAddCallback (widget, XtNjumpProc, xaw_jump_callback, (XtPointer) bar);
 16077   XtAddCallback (widget, XtNscrollProc, xaw_scroll_callback,
 16078                  (XtPointer) bar);
 16079 
 16080   /* Realize the widget.  Only after that is the X window created.  */
 16081   XtRealizeWidget (widget);
 16082 
 16083 #endif /* !USE_MOTIF */
 16084 
 16085   /* Install an action hook that lets us detect when the user
 16086      finishes interacting with a scroll bar.  */
 16087   if (action_hook_id == 0)
 16088     action_hook_id = XtAppAddActionHook (Xt_app_con, xt_action_hook, 0);
 16089 
 16090   /* Remember X window and widget in the scroll bar vector.  */
 16091   SET_SCROLL_BAR_X_WIDGET (bar, widget);
 16092   xwindow = XtWindow (widget);
 16093   bar->x_window = xwindow;
 16094   bar->whole = 1;
 16095   bar->horizontal = false;
 16096 
 16097   unblock_input ();
 16098 }
 16099 
 16100 static void
 16101 x_create_horizontal_toolkit_scroll_bar (struct frame *f, struct scroll_bar *bar)
 16102 {
 16103   Window xwindow;
 16104   Widget widget;
 16105   Arg av[20];
 16106   int ac = 0;
 16107   const char *scroll_bar_name = SCROLL_BAR_HORIZONTAL_NAME;
 16108   unsigned long pixel;
 16109 
 16110   block_input ();
 16111 
 16112 #ifdef USE_MOTIF
 16113   /* Set resources.  Create the widget.  */
 16114   XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac;
 16115   XtSetArg (av[ac], XmNminimum, 0); ++ac;
 16116   XtSetArg (av[ac], XmNmaximum, XM_SB_MAX); ++ac;
 16117   XtSetArg (av[ac], XmNorientation, XmHORIZONTAL); ++ac;
 16118   XtSetArg (av[ac], XmNprocessingDirection, XmMAX_ON_RIGHT), ++ac;
 16119   XtSetArg (av[ac], XmNincrement, 1); ++ac;
 16120   XtSetArg (av[ac], XmNpageIncrement, 1); ++ac;
 16121 
 16122   /* Note: "background" is the thumb color, and "trough" is the color behind
 16123      everything. */
 16124   pixel = f->output_data.x->scroll_bar_foreground_pixel;
 16125   if (pixel != -1)
 16126     {
 16127       XtSetArg (av[ac], XmNbackground, pixel);
 16128       ++ac;
 16129     }
 16130 
 16131   pixel = f->output_data.x->scroll_bar_background_pixel;
 16132   if (pixel != -1)
 16133     {
 16134       XtSetArg (av[ac], XmNtroughColor, pixel);
 16135       ++ac;
 16136     }
 16137 
 16138   widget = XmCreateScrollBar (f->output_data.x->edit_widget,
 16139                               (char *) scroll_bar_name, av, ac);
 16140 
 16141   /* Add one callback for everything that can happen.  */
 16142   XtAddCallback (widget, XmNdecrementCallback, xm_scroll_callback,
 16143                  (XtPointer) bar);
 16144   XtAddCallback (widget, XmNdragCallback, xm_scroll_callback,
 16145                  (XtPointer) bar);
 16146   XtAddCallback (widget, XmNincrementCallback, xm_scroll_callback,
 16147                  (XtPointer) bar);
 16148   XtAddCallback (widget, XmNpageDecrementCallback, xm_scroll_callback,
 16149                  (XtPointer) bar);
 16150   XtAddCallback (widget, XmNpageIncrementCallback, xm_scroll_callback,
 16151                  (XtPointer) bar);
 16152   XtAddCallback (widget, XmNtoBottomCallback, xm_scroll_callback,
 16153                  (XtPointer) bar);
 16154   XtAddCallback (widget, XmNtoTopCallback, xm_scroll_callback,
 16155                  (XtPointer) bar);
 16156 
 16157   /* Realize the widget.  Only after that is the X window created.  */
 16158   XtRealizeWidget (widget);
 16159 
 16160   /* Set the cursor to an arrow.  I didn't find a resource to do that.
 16161      And I'm wondering why it hasn't an arrow cursor by default.  */
 16162   XDefineCursor (XtDisplay (widget), XtWindow (widget),
 16163                  f->output_data.x->nontext_cursor);
 16164 
 16165 #ifdef HAVE_XINPUT2
 16166   /* Ask for input extension button and motion events.  This lets us
 16167      send the proper `wheel-up' or `wheel-down' events to Emacs.  */
 16168   if (FRAME_DISPLAY_INFO (f)->supports_xi2)
 16169     xi_select_scroll_bar_events (FRAME_DISPLAY_INFO (f),
 16170                                  XtWindow (widget));
 16171 #endif
 16172 #else /* !USE_MOTIF i.e. use Xaw */
 16173 
 16174   /* Set resources.  Create the widget.  The background of the
 16175      Xaw3d scroll bar widget is a little bit light for my taste.
 16176      We don't alter it here to let users change it according
 16177      to their taste with `emacs*verticalScrollBar.background: xxx'.  */
 16178   XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac;
 16179   XtSetArg (av[ac], XtNorientation, XtorientHorizontal); ++ac;
 16180   /* For smoother scrolling with Xaw3d   -sm */
 16181   /* XtSetArg (av[ac], XtNpickTop, True); ++ac; */
 16182 
 16183   pixel = f->output_data.x->scroll_bar_foreground_pixel;
 16184   if (pixel != -1)
 16185     {
 16186       XtSetArg (av[ac], XtNforeground, pixel);
 16187       ++ac;
 16188     }
 16189 
 16190   pixel = f->output_data.x->scroll_bar_background_pixel;
 16191   if (pixel != -1)
 16192     {
 16193       XtSetArg (av[ac], XtNbackground, pixel);
 16194       ++ac;
 16195     }
 16196 
 16197   /* Top/bottom shadow colors.  */
 16198 
 16199   /* Allocate them, if necessary.  */
 16200   if (f->output_data.x->scroll_bar_top_shadow_pixel == -1)
 16201     {
 16202       pixel = f->output_data.x->scroll_bar_background_pixel;
 16203       if (pixel != -1)
 16204         {
 16205           if (!x_alloc_lighter_color (f, FRAME_X_DISPLAY (f),
 16206                                       FRAME_X_COLORMAP (f),
 16207                                       &pixel, 1.2, 0x8000))
 16208             pixel = -1;
 16209           f->output_data.x->scroll_bar_top_shadow_pixel = pixel;
 16210         }
 16211     }
 16212   if (f->output_data.x->scroll_bar_bottom_shadow_pixel == -1)
 16213     {
 16214       pixel = f->output_data.x->scroll_bar_background_pixel;
 16215       if (pixel != -1)
 16216         {
 16217           if (!x_alloc_lighter_color (f, FRAME_X_DISPLAY (f),
 16218                                       FRAME_X_COLORMAP (f),
 16219                                       &pixel, 0.6, 0x4000))
 16220             pixel = -1;
 16221           f->output_data.x->scroll_bar_bottom_shadow_pixel = pixel;
 16222         }
 16223     }
 16224 
 16225 #ifdef XtNbeNiceToColormap
 16226   /* Tell the toolkit about them.  */
 16227   if (f->output_data.x->scroll_bar_top_shadow_pixel == -1
 16228       || f->output_data.x->scroll_bar_bottom_shadow_pixel == -1)
 16229     /* We tried to allocate a color for the top/bottom shadow, and
 16230        failed, so tell Xaw3d to use dithering instead.   */
 16231     /* But only if we have a small colormap.  Xaw3d can allocate nice
 16232        colors itself.  */
 16233     {
 16234       XtSetArg (av[ac], (String) XtNbeNiceToColormap,
 16235                 DefaultDepthOfScreen (FRAME_X_SCREEN (f)) < 16);
 16236       ++ac;
 16237     }
 16238   else
 16239     /* Tell what colors Xaw3d should use for the top/bottom shadow, to
 16240        be more consistent with other emacs 3d colors, and since Xaw3d is
 16241        not good at dealing with allocation failure.  */
 16242     {
 16243       /* This tells Xaw3d to use real colors instead of dithering for
 16244          the shadows.  */
 16245       XtSetArg (av[ac], (String) XtNbeNiceToColormap, False);
 16246       ++ac;
 16247 
 16248       /* Specify the colors.  */
 16249       pixel = f->output_data.x->scroll_bar_top_shadow_pixel;
 16250       if (pixel != -1)
 16251         {
 16252           XtSetArg (av[ac], (String) XtNtopShadowPixel, pixel);
 16253           ++ac;
 16254         }
 16255       pixel = f->output_data.x->scroll_bar_bottom_shadow_pixel;
 16256       if (pixel != -1)
 16257         {
 16258           XtSetArg (av[ac], (String) XtNbottomShadowPixel, pixel);
 16259           ++ac;
 16260         }
 16261     }
 16262 #endif
 16263 
 16264   widget = XtCreateWidget (scroll_bar_name, scrollbarWidgetClass,
 16265                            f->output_data.x->edit_widget, av, ac);
 16266 
 16267   {
 16268     char const *initial = "";
 16269     char const *val = initial;
 16270     XtVaGetValues (widget, XtNscrollVCursor, (XtPointer) &val,
 16271 #ifdef XtNarrowScrollbars
 16272                    XtNarrowScrollbars, (XtPointer) &xaw3d_arrow_scroll,
 16273 #endif
 16274                    XtNpickTop, (XtPointer) &xaw3d_pick_top, NULL);
 16275     if (xaw3d_arrow_scroll || val == initial)
 16276       { /* ARROW_SCROLL */
 16277         xaw3d_arrow_scroll = True;
 16278         /* Isn't that just a personal preference ?   --Stef */
 16279         XtVaSetValues (widget, XtNcursorName, "top_left_arrow", NULL);
 16280       }
 16281   }
 16282 
 16283   /* Define callbacks.  */
 16284   XtAddCallback (widget, XtNjumpProc, xaw_jump_callback, (XtPointer) bar);
 16285   XtAddCallback (widget, XtNscrollProc, xaw_scroll_callback,
 16286                  (XtPointer) bar);
 16287 
 16288   /* Realize the widget.  Only after that is the X window created.  */
 16289   XtRealizeWidget (widget);
 16290 
 16291 #endif /* !USE_MOTIF */
 16292 
 16293   /* Install an action hook that lets us detect when the user
 16294      finishes interacting with a scroll bar.  */
 16295   if (horizontal_action_hook_id == 0)
 16296    horizontal_action_hook_id
 16297      = XtAppAddActionHook (Xt_app_con, xt_horizontal_action_hook, 0);
 16298 
 16299   /* Remember X window and widget in the scroll bar vector.  */
 16300   SET_SCROLL_BAR_X_WIDGET (bar, widget);
 16301   xwindow = XtWindow (widget);
 16302   bar->x_window = xwindow;
 16303   bar->whole = 1;
 16304   bar->horizontal = true;
 16305 
 16306   unblock_input ();
 16307 }
 16308 #endif /* not USE_GTK */
 16309 
 16310 
 16311 /* Set the thumb size and position of scroll bar BAR.  We are currently
 16312    displaying PORTION out of a whole WHOLE, and our position POSITION.  */
 16313 
 16314 #ifdef USE_GTK
 16315 static void
 16316 x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int position, int whole)
 16317 {
 16318   xg_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
 16319 }
 16320 
 16321 static void
 16322 x_set_toolkit_horizontal_scroll_bar_thumb (struct scroll_bar *bar, int portion, int position, int whole)
 16323 {
 16324   xg_set_toolkit_horizontal_scroll_bar_thumb (bar, portion, position, whole);
 16325 }
 16326 
 16327 #else /* not USE_GTK */
 16328 static void
 16329 x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int position,
 16330                                 int whole)
 16331 {
 16332   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 16333   Widget widget = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
 16334   float top, shown;
 16335 
 16336   block_input ();
 16337 
 16338 #ifdef USE_MOTIF
 16339 
 16340   if (scroll_bar_adjust_thumb_portion_p)
 16341     {
 16342       /* We use an estimate of 30 chars per line rather than the real
 16343          `portion' value.  This has the disadvantage that the thumb size
 16344          is not very representative, but it makes our life a lot easier.
 16345          Otherwise, we have to constantly adjust the thumb size, which
 16346          we can't always do quickly enough: while dragging, the size of
 16347          the thumb might prevent the user from dragging the thumb all the
 16348          way to the end.  but Motif and some versions of Xaw3d don't allow
 16349          updating the thumb size while dragging.  Also, even if we can update
 16350          its size, the update will often happen too late.
 16351          If you don't believe it, check out revision 1.650 of xterm.c to see
 16352          what hoops we were going through and the still poor behavior we got.  */
 16353       portion = WINDOW_TOTAL_LINES (XWINDOW (bar->window)) * 30;
 16354       /* When the thumb is at the bottom, position == whole.
 16355          So we need to increase `whole' to make space for the thumb.  */
 16356       whole += portion;
 16357     }
 16358 
 16359   if (whole <= 0)
 16360     top = 0, shown = 1;
 16361   else
 16362     {
 16363       top = (float) position / whole;
 16364       shown = (float) portion / whole;
 16365     }
 16366 
 16367   if (bar->dragging == -1)
 16368     {
 16369       int size, value;
 16370 
 16371       /* Slider size.  Must be in the range [1 .. MAX - MIN] where MAX
 16372          is the scroll bar's maximum and MIN is the scroll bar's minimum
 16373          value.  */
 16374       size = clip_to_bounds (1, shown * XM_SB_MAX, XM_SB_MAX);
 16375 
 16376       /* Position.  Must be in the range [MIN .. MAX - SLIDER_SIZE].  */
 16377       value = top * XM_SB_MAX;
 16378       value = min (value, XM_SB_MAX - size);
 16379 
 16380       XmScrollBarSetValues (widget, value, size, 0, 0, False);
 16381     }
 16382 #else /* !USE_MOTIF i.e. use Xaw */
 16383 
 16384   if (whole == 0)
 16385     top = 0, shown = 1;
 16386   else
 16387     {
 16388       top = (float) position / whole;
 16389       shown = (float) portion / whole;
 16390     }
 16391 
 16392   {
 16393     float old_top, old_shown;
 16394     Dimension height;
 16395     XtVaGetValues (widget,
 16396                    XtNtopOfThumb, &old_top,
 16397                    XtNshown, &old_shown,
 16398                    XtNheight, &height,
 16399                    NULL);
 16400 
 16401     /* Massage the top+shown values.  */
 16402     if (bar->dragging == -1 || bar->last_seen_part == scroll_bar_down_arrow)
 16403       top = max (0, min (1, top));
 16404     else
 16405       top = old_top;
 16406 #if ! defined (HAVE_XAW3D)
 16407     /* With Xaw, 'top' values too closer to 1.0 may
 16408        cause the thumb to disappear.  Fix that.  */
 16409     top = min (top, 0.99f);
 16410 #endif
 16411     /* Keep two pixels available for moving the thumb down.  */
 16412     shown = max (0, min (1 - top - (2.0f / height), shown));
 16413 #if ! defined (HAVE_XAW3D)
 16414     /* Likewise with too small 'shown'.  */
 16415     shown = max (shown, 0.01f);
 16416 #endif
 16417 
 16418     /* If the call to XawScrollbarSetThumb below doesn't seem to
 16419        work, check that 'NARROWPROTO' is defined in src/config.h.
 16420        If this is not so, most likely you need to fix configure.  */
 16421     if (top != old_top || shown != old_shown)
 16422       {
 16423         if (bar->dragging == -1)
 16424           XawScrollbarSetThumb (widget, top, shown);
 16425         else
 16426           {
 16427             /* Try to make the scrolling a tad smoother.  */
 16428             if (!xaw3d_pick_top)
 16429               shown = min (shown, old_shown);
 16430 
 16431             XawScrollbarSetThumb (widget, top, shown);
 16432           }
 16433       }
 16434   }
 16435 #endif /* !USE_MOTIF */
 16436 
 16437   unblock_input ();
 16438 }
 16439 
 16440 static void
 16441 x_set_toolkit_horizontal_scroll_bar_thumb (struct scroll_bar *bar, int portion, int position,
 16442                                 int whole)
 16443 {
 16444   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 16445   Widget widget = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
 16446   float top, shown;
 16447 
 16448   block_input ();
 16449 
 16450 #ifdef USE_MOTIF
 16451   bar->whole = whole;
 16452   shown = (float) portion / whole;
 16453   top = (float) position / (whole - portion);
 16454   {
 16455     int size = clip_to_bounds (1, shown * XM_SB_MAX, XM_SB_MAX);
 16456     int value = clip_to_bounds (0, top * (XM_SB_MAX - size), XM_SB_MAX - size);
 16457 
 16458     XmScrollBarSetValues (widget, value, size, 0, 0, False);
 16459   }
 16460 #else /* !USE_MOTIF i.e. use Xaw */
 16461   bar->whole = whole;
 16462   if (whole == 0)
 16463     top = 0, shown = 1;
 16464   else
 16465     {
 16466       top = (float) position / whole;
 16467       shown = (float) portion / whole;
 16468     }
 16469 
 16470   {
 16471     float old_top, old_shown;
 16472     Dimension height;
 16473     XtVaGetValues (widget,
 16474                    XtNtopOfThumb, &old_top,
 16475                    XtNshown, &old_shown,
 16476                    XtNheight, &height,
 16477                    NULL);
 16478 
 16479 #if false
 16480     /* Massage the top+shown values.  */
 16481     if (bar->dragging == -1 || bar->last_seen_part == scroll_bar_down_arrow)
 16482       top = max (0, min (1, top));
 16483     else
 16484       top = old_top;
 16485 #if ! defined (HAVE_XAW3D)
 16486     /* With Xaw, 'top' values too closer to 1.0 may
 16487        cause the thumb to disappear.  Fix that.  */
 16488     top = min (top, 0.99f);
 16489 #endif
 16490     /* Keep two pixels available for moving the thumb down.  */
 16491     shown = max (0, min (1 - top - (2.0f / height), shown));
 16492 #if ! defined (HAVE_XAW3D)
 16493     /* Likewise with too small 'shown'.  */
 16494     shown = max (shown, 0.01f);
 16495 #endif
 16496 #endif
 16497 
 16498     /* If the call to XawScrollbarSetThumb below doesn't seem to
 16499        work, check that 'NARROWPROTO' is defined in src/config.h.
 16500        If this is not so, most likely you need to fix configure.  */
 16501     XawScrollbarSetThumb (widget, top, shown);
 16502 #if false
 16503     if (top != old_top || shown != old_shown)
 16504       {
 16505         if (bar->dragging == -1)
 16506           XawScrollbarSetThumb (widget, top, shown);
 16507         else
 16508           {
 16509             /* Try to make the scrolling a tad smoother.  */
 16510             if (!xaw3d_pick_top)
 16511               shown = min (shown, old_shown);
 16512 
 16513             XawScrollbarSetThumb (widget, top, shown);
 16514           }
 16515       }
 16516 #endif
 16517   }
 16518 #endif /* !USE_MOTIF */
 16519 
 16520   unblock_input ();
 16521 }
 16522 #endif /* not USE_GTK */
 16523 
 16524 #endif /* USE_TOOLKIT_SCROLL_BARS */
 16525 
 16526 
 16527 
 16528 /************************************************************************
 16529                          Scroll bars, general
 16530  ************************************************************************/
 16531 
 16532 /* Create a scroll bar and return the scroll bar vector for it.  W is
 16533    the Emacs window on which to create the scroll bar. TOP, LEFT,
 16534    WIDTH and HEIGHT are the pixel coordinates and dimensions of the
 16535    scroll bar. */
 16536 
 16537 static struct scroll_bar *
 16538 x_scroll_bar_create (struct window *w, int top, int left,
 16539                      int width, int height, bool horizontal)
 16540 {
 16541   struct frame *f = XFRAME (w->frame);
 16542   struct scroll_bar *bar = ALLOCATE_PSEUDOVECTOR (struct scroll_bar, prev,
 16543                                                   PVEC_OTHER);
 16544   Lisp_Object barobj;
 16545 
 16546   block_input ();
 16547 
 16548 #ifdef USE_TOOLKIT_SCROLL_BARS
 16549   if (horizontal)
 16550     x_create_horizontal_toolkit_scroll_bar (f, bar);
 16551   else
 16552     x_create_toolkit_scroll_bar (f, bar);
 16553 #else /* not USE_TOOLKIT_SCROLL_BARS */
 16554   {
 16555     XSetWindowAttributes a;
 16556     unsigned long mask;
 16557     Window window;
 16558 
 16559     a.event_mask = (ButtonPressMask | ButtonReleaseMask
 16560                     | ButtonMotionMask | PointerMotionHintMask);
 16561     a.cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
 16562 
 16563     mask = (CWEventMask | CWCursor);
 16564 
 16565     /* Clear the area of W that will serve as a scroll bar.  This is
 16566        for the case that a window has been split horizontally.  In
 16567        this case, no clear_frame is generated to reduce flickering.  */
 16568     if (width > 0 && window_box_height (w) > 0)
 16569       x_clear_area (f, left, top, width, window_box_height (w));
 16570 
 16571     /* Create an input only window.  Scroll bar contents are drawn to
 16572        the frame window itself, so they can be double buffered and
 16573        synchronized using the same mechanism as the frame.  */
 16574     window = XCreateWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 16575                             /* Position and size of scroll bar.  */
 16576                             left, top, width, height,
 16577                             /* Border width.  */
 16578                             0,
 16579                             /* Depth.  */
 16580                             CopyFromParent,
 16581                             /* Class.  */
 16582                             InputOnly,
 16583                             /* Visual class.  */
 16584                             CopyFromParent,
 16585                              /* Attributes.  */
 16586                             mask, &a);
 16587 
 16588 #ifdef HAVE_XINPUT2
 16589   /* Ask for input extension button and motion events.  This lets us
 16590      send the proper `wheel-up' or `wheel-down' events to Emacs.  */
 16591   if (FRAME_DISPLAY_INFO (f)->supports_xi2)
 16592     xi_select_scroll_bar_events (FRAME_DISPLAY_INFO (f),
 16593                                  window);
 16594 #endif
 16595 
 16596     bar->x_window = window;
 16597   }
 16598 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 16599 
 16600   XSETWINDOW (bar->window, w);
 16601   bar->top = top;
 16602   bar->left = left;
 16603   bar->width = width;
 16604   bar->height = height;
 16605   bar->start = 0;
 16606   bar->end = 0;
 16607   bar->dragging = -1;
 16608   bar->horizontal = horizontal;
 16609 #if defined (USE_TOOLKIT_SCROLL_BARS) && defined (USE_LUCID)
 16610   bar->last_seen_part = scroll_bar_nowhere;
 16611 #endif
 16612 
 16613   /* Add bar to its frame's list of scroll bars.  */
 16614   bar->next = FRAME_SCROLL_BARS (f);
 16615   bar->prev = Qnil;
 16616   XSETVECTOR (barobj, bar);
 16617   fset_scroll_bars (f, barobj);
 16618   if (!NILP (bar->next))
 16619     XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
 16620 
 16621   /* Map the window/widget.  */
 16622 #ifdef USE_TOOLKIT_SCROLL_BARS
 16623   {
 16624 #ifdef USE_GTK
 16625     if (horizontal)
 16626       xg_update_horizontal_scrollbar_pos (f, bar->x_window, top,
 16627                                           left, width, max (height, 1));
 16628     else
 16629       xg_update_scrollbar_pos (f, bar->x_window, top,
 16630                                left, width, max (height, 1));
 16631 #else /* not USE_GTK */
 16632     Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
 16633     XtConfigureWidget (scroll_bar, left, top, width, max (height, 1), 0);
 16634     XtMapWidget (scroll_bar);
 16635     /* Don't obscure any child frames.  */
 16636     XLowerWindow (FRAME_X_DISPLAY (f), bar->x_window);
 16637 #endif /* not USE_GTK */
 16638     }
 16639 #else /* not USE_TOOLKIT_SCROLL_BARS */
 16640   XMapWindow (FRAME_X_DISPLAY (f), bar->x_window);
 16641   /* Don't obscure any child frames.  */
 16642   XLowerWindow (FRAME_X_DISPLAY (f), bar->x_window);
 16643 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 16644 
 16645   unblock_input ();
 16646   return bar;
 16647 }
 16648 
 16649 
 16650 #ifndef USE_TOOLKIT_SCROLL_BARS
 16651 
 16652 /* Draw BAR's handle in the proper position.
 16653 
 16654    If the handle is already drawn from START to END, don't bother
 16655    redrawing it, unless REBUILD; in that case, always
 16656    redraw it.  (REBUILD is handy for drawing the handle after expose
 16657    events.)
 16658 
 16659    Normally, we want to constrain the start and end of the handle to
 16660    fit inside its rectangle, but if the user is dragging the scroll
 16661    bar handle, we want to let them drag it down all the way, so that
 16662    the bar's top is as far down as it goes; otherwise, there's no way
 16663    to move to the very end of the buffer.  */
 16664 
 16665 static void
 16666 x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end,
 16667                          bool rebuild)
 16668 {
 16669   bool dragging;
 16670   struct frame *f;
 16671   Drawable w;
 16672   GC gc;
 16673   int inside_width, inside_height, top_range, length;
 16674 
 16675   /* If the display is already accurate, do nothing.  */
 16676   if (! rebuild
 16677       && start == bar->start
 16678       && end == bar->end)
 16679     return;
 16680 
 16681   f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 16682   dragging = bar->dragging != -1;
 16683   gc = f->output_data.x->normal_gc;
 16684   w = FRAME_X_DRAWABLE (f);
 16685 
 16686   block_input ();
 16687 
 16688   inside_width = VERTICAL_SCROLL_BAR_INSIDE_WIDTH (f, bar->width);
 16689   inside_height = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f, bar->height);
 16690   top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height);
 16691 
 16692   /* Make sure the values are reasonable, and try to preserve
 16693      the distance between start and end.  */
 16694   length = end - start;
 16695 
 16696   if (start < 0)
 16697     start = 0;
 16698   else if (start > top_range)
 16699     start = top_range;
 16700   end = start + length;
 16701 
 16702   if (end < start)
 16703     end = start;
 16704   else if (end > top_range && ! dragging)
 16705     end = top_range;
 16706 
 16707   /* Store the adjusted setting in the scroll bar.  */
 16708   bar->start = start;
 16709   bar->end = end;
 16710 
 16711   /* Clip the end position, just for display.  */
 16712   if (end > top_range)
 16713     end = top_range;
 16714 
 16715   /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels
 16716      below top positions, to make sure the handle is always at least
 16717      that many pixels tall.  */
 16718   end += VERTICAL_SCROLL_BAR_MIN_HANDLE;
 16719 
 16720   /* Draw the empty space above the handle.  Note that we can't clear
 16721      zero-height areas; that means "clear to end of window."  */
 16722   if ((inside_width > 0) && (start > 0))
 16723     {
 16724       if (f->output_data.x->scroll_bar_background_pixel != -1)
 16725         XSetForeground (FRAME_X_DISPLAY (f), gc,
 16726                         f->output_data.x->scroll_bar_background_pixel);
 16727       else
 16728         XSetForeground (FRAME_X_DISPLAY (f), gc,
 16729                         FRAME_BACKGROUND_PIXEL (f));
 16730 
 16731       XFillRectangle (FRAME_X_DISPLAY (f), w, gc,
 16732                       bar->left + VERTICAL_SCROLL_BAR_LEFT_BORDER,
 16733                       bar->top + VERTICAL_SCROLL_BAR_TOP_BORDER,
 16734                       inside_width, start);
 16735 
 16736       XSetForeground (FRAME_X_DISPLAY (f), gc,
 16737                       FRAME_FOREGROUND_PIXEL (f));
 16738     }
 16739 
 16740   /* Change to proper foreground color if one is specified.  */
 16741   if (f->output_data.x->scroll_bar_foreground_pixel != -1)
 16742     XSetForeground (FRAME_X_DISPLAY (f), gc,
 16743                     f->output_data.x->scroll_bar_foreground_pixel);
 16744 
 16745   /* Draw the handle itself.  */
 16746   XFillRectangle (FRAME_X_DISPLAY (f), w, gc,
 16747                   /* x, y, width, height */
 16748                   bar->left + VERTICAL_SCROLL_BAR_LEFT_BORDER,
 16749                   bar->top + VERTICAL_SCROLL_BAR_TOP_BORDER + start,
 16750                   inside_width, end - start);
 16751 
 16752 
 16753   /* Draw the empty space below the handle.  Note that we can't
 16754      clear zero-height areas; that means "clear to end of window." */
 16755   if ((inside_width > 0) && (end < inside_height))
 16756     {
 16757       if (f->output_data.x->scroll_bar_background_pixel != -1)
 16758         XSetForeground (FRAME_X_DISPLAY (f), gc,
 16759                         f->output_data.x->scroll_bar_background_pixel);
 16760       else
 16761         XSetForeground (FRAME_X_DISPLAY (f), gc,
 16762                         FRAME_BACKGROUND_PIXEL (f));
 16763 
 16764       XFillRectangle (FRAME_X_DISPLAY (f), w, gc,
 16765                       bar->left + VERTICAL_SCROLL_BAR_LEFT_BORDER,
 16766                       bar->top + VERTICAL_SCROLL_BAR_TOP_BORDER + end,
 16767                       inside_width, inside_height - end);
 16768 
 16769       XSetForeground (FRAME_X_DISPLAY (f), gc,
 16770                       FRAME_FOREGROUND_PIXEL (f));
 16771     }
 16772 
 16773   /* Restore the foreground color of the GC if we changed it above.  */
 16774   if (f->output_data.x->scroll_bar_foreground_pixel != -1)
 16775     XSetForeground (FRAME_X_DISPLAY (f), gc,
 16776                     FRAME_FOREGROUND_PIXEL (f));
 16777 
 16778   unblock_input ();
 16779 }
 16780 
 16781 #endif /* !USE_TOOLKIT_SCROLL_BARS */
 16782 
 16783 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
 16784    nil.  */
 16785 
 16786 static void
 16787 x_scroll_bar_remove (struct scroll_bar *bar)
 16788 {
 16789   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 16790   block_input ();
 16791 
 16792 #ifdef USE_TOOLKIT_SCROLL_BARS
 16793 #ifdef USE_GTK
 16794   xg_remove_scroll_bar (f, bar->x_window);
 16795 #else /* not USE_GTK */
 16796   XtDestroyWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar));
 16797 #endif /* not USE_GTK */
 16798 #else
 16799   XDestroyWindow (FRAME_X_DISPLAY (f), bar->x_window);
 16800 #endif
 16801 
 16802   /* Dissociate this scroll bar from its window.  */
 16803   if (bar->horizontal)
 16804     wset_horizontal_scroll_bar (XWINDOW (bar->window), Qnil);
 16805   else
 16806     wset_vertical_scroll_bar (XWINDOW (bar->window), Qnil);
 16807 
 16808   unblock_input ();
 16809 }
 16810 
 16811 
 16812 /* Set the handle of the vertical scroll bar for WINDOW to indicate
 16813    that we are displaying PORTION characters out of a total of WHOLE
 16814    characters, starting at POSITION.  If WINDOW has no scroll bar,
 16815    create one.  */
 16816 
 16817 static void
 16818 XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int position)
 16819 {
 16820   struct frame *f = XFRAME (w->frame);
 16821   Lisp_Object barobj;
 16822   struct scroll_bar *bar;
 16823   int top, height, left, width;
 16824   int window_y, window_height;
 16825 
 16826   /* Get window dimensions.  */
 16827   window_box (w, ANY_AREA, 0, &window_y, 0, &window_height);
 16828   top = window_y;
 16829   height = window_height;
 16830   left = WINDOW_SCROLL_BAR_AREA_X (w);
 16831   width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
 16832 
 16833   /* Does the scroll bar exist yet?  */
 16834   if (NILP (w->vertical_scroll_bar))
 16835     {
 16836       if (width > 0 && height > 0)
 16837         {
 16838           block_input ();
 16839           x_clear_area (f, left, top, width, height);
 16840           unblock_input ();
 16841         }
 16842 
 16843       bar = x_scroll_bar_create (w, top, left, width, max (height, 1), false);
 16844 #ifndef USE_TOOLKIT_SCROLL_BARS
 16845       /* Since non-toolkit scroll bars don't display their contents to
 16846          a dedicated window, no expose event will be generated.
 16847          Redraw the scroll bar manually.  */
 16848       x_scroll_bar_redraw (bar);
 16849 #endif
 16850     }
 16851   else
 16852     {
 16853       /* It may just need to be moved and resized.  */
 16854       unsigned int mask = 0;
 16855 
 16856       bar = XSCROLL_BAR (w->vertical_scroll_bar);
 16857 
 16858       block_input ();
 16859 
 16860       if (left != bar->left)
 16861         mask |= CWX;
 16862       if (top != bar->top)
 16863         mask |= CWY;
 16864       if (width != bar->width)
 16865         mask |= CWWidth;
 16866       if (height != bar->height)
 16867         mask |= CWHeight;
 16868 
 16869 #ifdef USE_TOOLKIT_SCROLL_BARS
 16870 
 16871       /* Move/size the scroll bar widget.  */
 16872       if (mask)
 16873         {
 16874           /* Since toolkit scroll bars are smaller than the space reserved
 16875              for them on the frame, we have to clear "under" them.  */
 16876           if (width > 0 && height > 0)
 16877             x_clear_area (f, left, top, width, height);
 16878 #ifdef USE_GTK
 16879           xg_update_scrollbar_pos (f, bar->x_window, top,
 16880                                    left, width, max (height, 1));
 16881 #else /* not USE_GTK */
 16882           XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar),
 16883                              left, top, width, max (height, 1), 0);
 16884 #endif /* not USE_GTK */
 16885         }
 16886 #else /* not USE_TOOLKIT_SCROLL_BARS */
 16887 
 16888       /* Move/size the scroll bar window.  */
 16889       if (mask)
 16890         {
 16891           XWindowChanges wc;
 16892 
 16893           wc.x = left;
 16894           wc.y = top;
 16895           wc.width = width;
 16896           wc.height = height;
 16897           XConfigureWindow (FRAME_X_DISPLAY (f), bar->x_window,
 16898                             mask, &wc);
 16899         }
 16900 
 16901 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 16902 
 16903       /* Remember new settings.  */
 16904       bar->left = left;
 16905       bar->top = top;
 16906       bar->width = width;
 16907       bar->height = height;
 16908 
 16909 #ifndef USE_TOOLKIT_SCROLL_BARS
 16910       /* Redraw the scroll bar.  */
 16911       x_scroll_bar_redraw (bar);
 16912 #endif
 16913 
 16914       unblock_input ();
 16915     }
 16916 
 16917 #ifdef USE_TOOLKIT_SCROLL_BARS
 16918   x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
 16919 #else /* not USE_TOOLKIT_SCROLL_BARS */
 16920   /* Set the scroll bar's current state, unless we're currently being
 16921      dragged.  */
 16922   if (bar->dragging == -1)
 16923     {
 16924       int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height);
 16925 
 16926       if (whole == 0)
 16927         x_scroll_bar_set_handle (bar, 0, top_range, false);
 16928       else
 16929         {
 16930           int start = ((double) position * top_range) / whole;
 16931           int end = ((double) (position + portion) * top_range) / whole;
 16932           x_scroll_bar_set_handle (bar, start, end, false);
 16933         }
 16934     }
 16935 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 16936 
 16937   XSETVECTOR (barobj, bar);
 16938   wset_vertical_scroll_bar (w, barobj);
 16939 }
 16940 
 16941 
 16942 static void
 16943 XTset_horizontal_scroll_bar (struct window *w, int portion, int whole, int position)
 16944 {
 16945   struct frame *f = XFRAME (w->frame);
 16946   Lisp_Object barobj;
 16947   struct scroll_bar *bar;
 16948   int top, height, left, width;
 16949   int window_x, window_width;
 16950   int pixel_width = WINDOW_PIXEL_WIDTH (w);
 16951 
 16952   /* Get window dimensions.  */
 16953   window_box (w, ANY_AREA, &window_x, 0, &window_width, 0);
 16954   left = window_x;
 16955   width = window_width;
 16956   top = WINDOW_SCROLL_BAR_AREA_Y (w);
 16957   height = WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
 16958 
 16959   /* Does the scroll bar exist yet?  */
 16960   if (NILP (w->horizontal_scroll_bar))
 16961     {
 16962       if (width > 0 && height > 0)
 16963         {
 16964           block_input ();
 16965 
 16966           /* Clear also part between window_width and
 16967              WINDOW_PIXEL_WIDTH.  */
 16968           x_clear_area (f, left, top, pixel_width, height);
 16969           unblock_input ();
 16970         }
 16971 
 16972       bar = x_scroll_bar_create (w, top, left, width, height, true);
 16973     }
 16974   else
 16975     {
 16976       /* It may just need to be moved and resized.  */
 16977       unsigned int mask = 0;
 16978 
 16979       bar = XSCROLL_BAR (w->horizontal_scroll_bar);
 16980 
 16981       block_input ();
 16982 
 16983       if (left != bar->left)
 16984         mask |= CWX;
 16985       if (top != bar->top)
 16986         mask |= CWY;
 16987       if (width != bar->width)
 16988         mask |= CWWidth;
 16989       if (height != bar->height)
 16990         mask |= CWHeight;
 16991 
 16992 #ifdef USE_TOOLKIT_SCROLL_BARS
 16993       /* Move/size the scroll bar widget.  */
 16994       if (mask)
 16995         {
 16996           /* Since toolkit scroll bars are smaller than the space reserved
 16997              for them on the frame, we have to clear "under" them.  */
 16998           if (width > 0 && height > 0)
 16999             x_clear_area (f,
 17000                           WINDOW_LEFT_EDGE_X (w), top,
 17001                           pixel_width - WINDOW_RIGHT_DIVIDER_WIDTH (w), height);
 17002 #ifdef USE_GTK
 17003           xg_update_horizontal_scrollbar_pos (f, bar->x_window, top, left,
 17004                                               width, height);
 17005 #else /* not USE_GTK */
 17006           XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar),
 17007                              left, top, width, height, 0);
 17008 #endif /* not USE_GTK */
 17009         }
 17010 #else /* not USE_TOOLKIT_SCROLL_BARS */
 17011 
 17012       /* Clear areas not covered by the scroll bar because it's not as
 17013          wide as the area reserved for it.  This makes sure a
 17014          previous mode line display is cleared after C-x 2 C-x 1, for
 17015          example.  */
 17016       {
 17017         int area_height = WINDOW_CONFIG_SCROLL_BAR_HEIGHT (w);
 17018         int rest = area_height - height;
 17019         if (rest > 0 && width > 0)
 17020           x_clear_area (f, left, top, width, rest);
 17021       }
 17022 
 17023       /* Move/size the scroll bar window.  */
 17024       if (mask)
 17025         {
 17026           XWindowChanges wc;
 17027 
 17028           wc.x = left;
 17029           wc.y = top;
 17030           wc.width = width;
 17031           wc.height = height;
 17032           XConfigureWindow (FRAME_X_DISPLAY (f), bar->x_window,
 17033                             mask, &wc);
 17034         }
 17035 
 17036 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 17037 
 17038       /* Remember new settings.  */
 17039       bar->left = left;
 17040       bar->top = top;
 17041       bar->width = width;
 17042       bar->height = height;
 17043 
 17044       unblock_input ();
 17045     }
 17046 
 17047 #ifdef USE_TOOLKIT_SCROLL_BARS
 17048   x_set_toolkit_horizontal_scroll_bar_thumb (bar, portion, position, whole);
 17049 #else /* not USE_TOOLKIT_SCROLL_BARS */
 17050   /* Set the scroll bar's current state, unless we're currently being
 17051      dragged.  */
 17052   if (bar->dragging == -1)
 17053     {
 17054       int left_range = HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, width);
 17055 
 17056       if (whole == 0)
 17057         x_scroll_bar_set_handle (bar, 0, left_range, false);
 17058       else
 17059         {
 17060           int start = ((double) position * left_range) / whole;
 17061           int end = ((double) (position + portion) * left_range) / whole;
 17062           x_scroll_bar_set_handle (bar, start, end, false);
 17063         }
 17064     }
 17065 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 17066 
 17067   XSETVECTOR (barobj, bar);
 17068   wset_horizontal_scroll_bar (w, barobj);
 17069 }
 17070 
 17071 
 17072 /* The following three hooks are used when we're doing a thorough
 17073    redisplay of the frame.  We don't explicitly know which scroll bars
 17074    are going to be deleted, because keeping track of when windows go
 17075    away is a real pain - "Can you say set-window-configuration, boys
 17076    and girls?"  Instead, we just assert at the beginning of redisplay
 17077    that *all* scroll bars are to be removed, and then save a scroll bar
 17078    from the fiery pit when we actually redisplay its window.  */
 17079 
 17080 /* Arrange for all scroll bars on FRAME to be removed at the next call
 17081    to `*judge_scroll_bars_hook'.  A scroll bar may be spared if
 17082    `*redeem_scroll_bar_hook' is applied to its window before the judgment.  */
 17083 
 17084 static void
 17085 XTcondemn_scroll_bars (struct frame *frame)
 17086 {
 17087   if (!NILP (FRAME_SCROLL_BARS (frame)))
 17088     {
 17089       if (!NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
 17090         {
 17091           /* Prepend scrollbars to already condemned ones.  */
 17092           Lisp_Object last = FRAME_SCROLL_BARS (frame);
 17093 
 17094           while (!NILP (XSCROLL_BAR (last)->next))
 17095             last = XSCROLL_BAR (last)->next;
 17096 
 17097           XSCROLL_BAR (last)->next = FRAME_CONDEMNED_SCROLL_BARS (frame);
 17098           XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = last;
 17099         }
 17100 
 17101       fset_condemned_scroll_bars (frame, FRAME_SCROLL_BARS (frame));
 17102       fset_scroll_bars (frame, Qnil);
 17103     }
 17104 }
 17105 
 17106 
 17107 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
 17108    Note that WINDOW isn't necessarily condemned at all.  */
 17109 
 17110 static void
 17111 XTredeem_scroll_bar (struct window *w)
 17112 {
 17113   struct scroll_bar *bar;
 17114   Lisp_Object barobj;
 17115   struct frame *f;
 17116 
 17117   /* We can't redeem this window's scroll bar if it doesn't have one.  */
 17118   if (NILP (w->vertical_scroll_bar) && NILP (w->horizontal_scroll_bar))
 17119     emacs_abort ();
 17120 
 17121   if (!NILP (w->vertical_scroll_bar) && WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
 17122     {
 17123       bar = XSCROLL_BAR (w->vertical_scroll_bar);
 17124       /* Unlink it from the condemned list.  */
 17125       f = XFRAME (WINDOW_FRAME (w));
 17126       if (NILP (bar->prev))
 17127         {
 17128           /* If the prev pointer is nil, it must be the first in one of
 17129              the lists.  */
 17130           if (EQ (FRAME_SCROLL_BARS (f), w->vertical_scroll_bar))
 17131             /* It's not condemned.  Everything's fine.  */
 17132             goto horizontal;
 17133           else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
 17134                        w->vertical_scroll_bar))
 17135             fset_condemned_scroll_bars (f, bar->next);
 17136           else
 17137             /* If its prev pointer is nil, it must be at the front of
 17138                one or the other!  */
 17139             emacs_abort ();
 17140         }
 17141       else
 17142         XSCROLL_BAR (bar->prev)->next = bar->next;
 17143 
 17144       if (! NILP (bar->next))
 17145         XSCROLL_BAR (bar->next)->prev = bar->prev;
 17146 
 17147       bar->next = FRAME_SCROLL_BARS (f);
 17148       bar->prev = Qnil;
 17149       XSETVECTOR (barobj, bar);
 17150       fset_scroll_bars (f, barobj);
 17151       if (! NILP (bar->next))
 17152         XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
 17153     }
 17154 
 17155  horizontal:
 17156   if (!NILP (w->horizontal_scroll_bar) && WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
 17157     {
 17158       bar = XSCROLL_BAR (w->horizontal_scroll_bar);
 17159       /* Unlink it from the condemned list.  */
 17160       f = XFRAME (WINDOW_FRAME (w));
 17161       if (NILP (bar->prev))
 17162         {
 17163           /* If the prev pointer is nil, it must be the first in one of
 17164              the lists.  */
 17165           if (EQ (FRAME_SCROLL_BARS (f), w->horizontal_scroll_bar))
 17166             /* It's not condemned.  Everything's fine.  */
 17167             return;
 17168           else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
 17169                        w->horizontal_scroll_bar))
 17170             fset_condemned_scroll_bars (f, bar->next);
 17171           else
 17172             /* If its prev pointer is nil, it must be at the front of
 17173                one or the other!  */
 17174             emacs_abort ();
 17175         }
 17176       else
 17177         XSCROLL_BAR (bar->prev)->next = bar->next;
 17178 
 17179       if (! NILP (bar->next))
 17180         XSCROLL_BAR (bar->next)->prev = bar->prev;
 17181 
 17182       bar->next = FRAME_SCROLL_BARS (f);
 17183       bar->prev = Qnil;
 17184       XSETVECTOR (barobj, bar);
 17185       fset_scroll_bars (f, barobj);
 17186       if (! NILP (bar->next))
 17187         XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
 17188     }
 17189 }
 17190 
 17191 /* Remove all scroll bars on FRAME that haven't been saved since the
 17192    last call to `*condemn_scroll_bars_hook'.  */
 17193 
 17194 static void
 17195 XTjudge_scroll_bars (struct frame *f)
 17196 {
 17197   Lisp_Object bar, next;
 17198 
 17199   bar = FRAME_CONDEMNED_SCROLL_BARS (f);
 17200 
 17201   /* Clear out the condemned list now so we won't try to process any
 17202      more events on the hapless scroll bars.  */
 17203   fset_condemned_scroll_bars (f, Qnil);
 17204 
 17205   for (; ! NILP (bar); bar = next)
 17206     {
 17207       struct scroll_bar *b = XSCROLL_BAR (bar);
 17208 
 17209       x_scroll_bar_remove (b);
 17210 
 17211       next = b->next;
 17212       b->next = b->prev = Qnil;
 17213     }
 17214 
 17215   /* Now there should be no references to the condemned scroll bars,
 17216      and they should get garbage-collected.  */
 17217 }
 17218 
 17219 
 17220 #ifndef USE_TOOLKIT_SCROLL_BARS
 17221 /* Handle exposure event EVENT generated for F, by redrawing all
 17222    intersecting scroll bars.  */
 17223 
 17224 static void
 17225 x_scroll_bar_handle_exposure (struct frame *f, XEvent *event)
 17226 {
 17227   int x, y, width, height;
 17228   XRectangle rect, scroll_bar_rect, intersection;
 17229   Lisp_Object bar, condemned;
 17230   struct scroll_bar *b;
 17231 
 17232   if (event->type == GraphicsExpose)
 17233     {
 17234       x = event->xgraphicsexpose.x;
 17235       y = event->xgraphicsexpose.y;
 17236       width = event->xgraphicsexpose.width;
 17237       height = event->xgraphicsexpose.height;
 17238     }
 17239   else
 17240     {
 17241       x = event->xexpose.x;
 17242       y = event->xexpose.y;
 17243       width = event->xexpose.width;
 17244       height = event->xexpose.height;
 17245     }
 17246 
 17247   rect.x = x;
 17248   rect.y = y;
 17249   rect.width = width;
 17250   rect.height = height;
 17251 
 17252   /* Scan this frame's scroll bar list for intersecting scroll
 17253      bars.  */
 17254   condemned = FRAME_CONDEMNED_SCROLL_BARS (f);
 17255   for (bar = FRAME_SCROLL_BARS (f);
 17256        /* This trick allows us to search both the ordinary and
 17257           condemned scroll bar lists with one loop.  */
 17258        !NILP (bar) || (bar = condemned,
 17259                        condemned = Qnil,
 17260                        !NILP (bar));
 17261        bar = XSCROLL_BAR (bar)->next)
 17262     {
 17263       b = XSCROLL_BAR (bar);
 17264 
 17265       scroll_bar_rect.x = b->left;
 17266       scroll_bar_rect.y = b->top;
 17267       scroll_bar_rect.width = b->width;
 17268       scroll_bar_rect.height = b->height;
 17269 
 17270       if (gui_intersect_rectangles (&rect,
 17271                                     &scroll_bar_rect,
 17272                                     &intersection))
 17273         x_scroll_bar_redraw (b);
 17274     }
 17275 }
 17276 
 17277 /* Redraw the scroll bar BAR.  Draw its border and set its thumb.
 17278    This is usually called from x_clear_frame, but is also used to
 17279    handle exposure events that overlap scroll bars.  */
 17280 
 17281 static void
 17282 x_scroll_bar_redraw (struct scroll_bar *bar)
 17283 {
 17284   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 17285   GC gc = f->output_data.x->normal_gc;
 17286 
 17287   if (f->output_data.x->scroll_bar_background_pixel != -1)
 17288     XSetForeground (FRAME_X_DISPLAY (f), gc,
 17289                     f->output_data.x->scroll_bar_background_pixel);
 17290   else
 17291     XSetForeground (FRAME_X_DISPLAY (f), gc,
 17292                     FRAME_BACKGROUND_PIXEL (f));
 17293 
 17294   XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), gc,
 17295                   bar->left, bar->top, bar->width, bar->height);
 17296 
 17297   XSetForeground (FRAME_X_DISPLAY (f), gc,
 17298                   FRAME_FOREGROUND_PIXEL (f));
 17299 
 17300   x_scroll_bar_set_handle (bar, bar->start, bar->end, true);
 17301 
 17302   /* Switch to scroll bar foreground color.  */
 17303   if (f->output_data.x->scroll_bar_foreground_pixel != -1)
 17304     XSetForeground (FRAME_X_DISPLAY (f), gc,
 17305                     f->output_data.x->scroll_bar_foreground_pixel);
 17306 
 17307   /* Draw a one-pixel border just inside the edges of the scroll bar.  */
 17308   XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), gc,
 17309                   bar->left, bar->top, bar->width - 1, bar->height - 1);
 17310 
 17311   /* Restore the foreground color of the GC if we changed it above.  */
 17312   if (f->output_data.x->scroll_bar_foreground_pixel != -1)
 17313     XSetForeground (FRAME_X_DISPLAY (f), gc,
 17314                     FRAME_FOREGROUND_PIXEL (f));
 17315 }
 17316 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 17317 
 17318 /* Handle a mouse click on the scroll bar BAR.  If *EMACS_EVENT's kind
 17319    is set to something other than NO_EVENT, it is enqueued.
 17320 
 17321    This may be called from a signal handler, so we have to ignore GC
 17322    mark bits.  */
 17323 
 17324 
 17325 static void
 17326 x_scroll_bar_handle_click (struct scroll_bar *bar,
 17327                            const XEvent *event,
 17328                            struct input_event *emacs_event,
 17329                            Lisp_Object device)
 17330 {
 17331   int left_range, x, top_range, y;
 17332 #ifndef USE_TOOLKIT_SCROLL_BARS
 17333   int new_start, new_end;
 17334 #endif
 17335 
 17336   if (! WINDOWP (bar->window))
 17337     emacs_abort ();
 17338 
 17339   emacs_event->kind = (bar->horizontal
 17340                        ? HORIZONTAL_SCROLL_BAR_CLICK_EVENT
 17341                        : SCROLL_BAR_CLICK_EVENT);
 17342   emacs_event->code = event->xbutton.button - Button1;
 17343   emacs_event->modifiers
 17344     = (x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO
 17345                                (XFRAME (WINDOW_FRAME (XWINDOW (bar->window)))),
 17346                                event->xbutton.state)
 17347        | (event->type == ButtonRelease
 17348           ? up_modifier
 17349           : down_modifier));
 17350   emacs_event->frame_or_window = bar->window;
 17351   emacs_event->arg = Qnil;
 17352   emacs_event->timestamp = event->xbutton.time;
 17353 
 17354   if (!NILP (device))
 17355     emacs_event->device = device;
 17356 
 17357   if (bar->horizontal)
 17358     {
 17359 
 17360       left_range = HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, bar->width);
 17361       x = event->xbutton.x - HORIZONTAL_SCROLL_BAR_LEFT_BORDER;
 17362 
 17363       if (x < 0) x = 0;
 17364       if (x > left_range) x = left_range;
 17365 
 17366       if (x < bar->start)
 17367         emacs_event->part = scroll_bar_before_handle;
 17368       else if (x < bar->end + HORIZONTAL_SCROLL_BAR_MIN_HANDLE)
 17369         emacs_event->part = scroll_bar_horizontal_handle;
 17370       else
 17371         emacs_event->part = scroll_bar_after_handle;
 17372 
 17373 #ifndef USE_TOOLKIT_SCROLL_BARS
 17374       /* If the user has released the handle, set it to its final position.  */
 17375       if (event->type == ButtonRelease && bar->dragging != -1)
 17376         {
 17377           new_start = - bar->dragging;
 17378           new_end = new_start + bar->end - bar->start;
 17379 
 17380           x_scroll_bar_set_handle (bar, new_start, new_end, false);
 17381           bar->dragging = -1;
 17382         }
 17383 #endif
 17384 
 17385       XSETINT (emacs_event->x, left_range);
 17386       XSETINT (emacs_event->y, x);
 17387     }
 17388   else
 17389     {
 17390       top_range
 17391         = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height);
 17392       y = event->xbutton.y - VERTICAL_SCROLL_BAR_TOP_BORDER;
 17393 
 17394       if (y < 0) y = 0;
 17395       if (y > top_range) y = top_range;
 17396 
 17397       if (y < bar->start)
 17398         emacs_event->part = scroll_bar_above_handle;
 17399       else if (y < bar->end + VERTICAL_SCROLL_BAR_MIN_HANDLE)
 17400         emacs_event->part = scroll_bar_handle;
 17401       else
 17402         emacs_event->part = scroll_bar_below_handle;
 17403 
 17404 #ifndef USE_TOOLKIT_SCROLL_BARS
 17405       /* If the user has released the handle, set it to its final position.  */
 17406       if (event->type == ButtonRelease && bar->dragging != -1)
 17407         {
 17408           new_start = y - bar->dragging;
 17409           new_end = new_start + bar->end - bar->start;
 17410 
 17411           x_scroll_bar_set_handle (bar, new_start, new_end, false);
 17412           bar->dragging = -1;
 17413         }
 17414 #endif
 17415 
 17416       XSETINT (emacs_event->x, y);
 17417       XSETINT (emacs_event->y, top_range);
 17418     }
 17419 }
 17420 
 17421 #ifndef USE_TOOLKIT_SCROLL_BARS
 17422 
 17423 /* Handle some mouse motion while someone is dragging the scroll bar.
 17424 
 17425    This may be called from a signal handler, so we have to ignore GC
 17426    mark bits.  */
 17427 
 17428 static void
 17429 x_scroll_bar_note_movement (struct scroll_bar *bar,
 17430                             const XMotionEvent *event)
 17431 {
 17432   struct frame *f = XFRAME (XWINDOW (bar->window)->frame);
 17433   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 17434 
 17435   dpyinfo->last_mouse_movement_time = event->time;
 17436   dpyinfo->last_mouse_movement_time_send_event = event->send_event;
 17437   dpyinfo->last_mouse_scroll_bar = bar;
 17438   f->mouse_moved = true;
 17439 
 17440   /* If we're dragging the bar, display it.  */
 17441   if (bar->dragging != -1)
 17442     {
 17443       /* Where should the handle be now?  */
 17444       int new_start = event->y - bar->dragging;
 17445 
 17446       if (new_start != bar->start)
 17447         {
 17448           int new_end = new_start + bar->end - bar->start;
 17449 
 17450           x_scroll_bar_set_handle (bar, new_start, new_end, false);
 17451         }
 17452     }
 17453 }
 17454 
 17455 #endif /* !USE_TOOLKIT_SCROLL_BARS */
 17456 
 17457 /* Return information to the user about the current position of the mouse
 17458    on the scroll bar.  */
 17459 
 17460 static void
 17461 x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
 17462                             enum scroll_bar_part *part, Lisp_Object *x,
 17463                             Lisp_Object *y, Time *timestamp)
 17464 {
 17465   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
 17466   struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar;
 17467   Window w = bar->x_window;
 17468   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 17469   int win_x, win_y;
 17470   Window dummy_window;
 17471   int dummy_coord;
 17472   unsigned int dummy_mask;
 17473 
 17474   block_input ();
 17475 
 17476   /* Get the mouse's position relative to the scroll bar window, and
 17477      report that.  */
 17478   if (x_query_pointer (FRAME_X_DISPLAY (f), w,
 17479 
 17480                        /* Root, child, root x and root y.  */
 17481                        &dummy_window, &dummy_window,
 17482                        &dummy_coord, &dummy_coord,
 17483 
 17484                        /* Position relative to scroll bar.  */
 17485                        &win_x, &win_y,
 17486 
 17487                        /* Mouse buttons and modifier keys.  */
 17488                        &dummy_mask))
 17489     {
 17490       int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height);
 17491 
 17492       win_y -= VERTICAL_SCROLL_BAR_TOP_BORDER;
 17493 
 17494       if (bar->dragging != -1)
 17495         win_y -= bar->dragging;
 17496 
 17497       if (win_y < 0)
 17498         win_y = 0;
 17499       if (win_y > top_range)
 17500         win_y = top_range;
 17501 
 17502       *fp = f;
 17503       *bar_window = bar->window;
 17504 
 17505       if (bar->dragging != -1)
 17506         *part = scroll_bar_handle;
 17507       else if (win_y < bar->start)
 17508         *part = scroll_bar_above_handle;
 17509       else if (win_y < bar->end + VERTICAL_SCROLL_BAR_MIN_HANDLE)
 17510         *part = scroll_bar_handle;
 17511       else
 17512         *part = scroll_bar_below_handle;
 17513 
 17514       XSETINT (*x, win_y);
 17515       XSETINT (*y, top_range);
 17516 
 17517       f->mouse_moved = false;
 17518       dpyinfo->last_mouse_scroll_bar = NULL;
 17519       *timestamp = dpyinfo->last_mouse_movement_time;
 17520     }
 17521 
 17522   unblock_input ();
 17523 }
 17524 
 17525 
 17526 /* Return information to the user about the current position of the mouse
 17527    on the scroll bar.  */
 17528 
 17529 static void
 17530 x_horizontal_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
 17531                                        enum scroll_bar_part *part, Lisp_Object *x,
 17532                                        Lisp_Object *y, Time *timestamp)
 17533 {
 17534   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
 17535   struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar;
 17536   Window w = bar->x_window;
 17537   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 17538   int win_x, win_y;
 17539   Window dummy_window;
 17540   int dummy_coord;
 17541   unsigned int dummy_mask;
 17542 
 17543   block_input ();
 17544 
 17545   /* Get the mouse's position relative to the scroll bar window, and
 17546      report that.  */
 17547   if (x_query_pointer (FRAME_X_DISPLAY (f), w,
 17548 
 17549                        /* Root, child, root x and root y.  */
 17550                        &dummy_window, &dummy_window,
 17551                        &dummy_coord, &dummy_coord,
 17552 
 17553                        /* Position relative to scroll bar.  */
 17554                        &win_x, &win_y,
 17555 
 17556                        /* Mouse buttons and modifier keys.  */
 17557                        &dummy_mask))
 17558     {
 17559       int left_range = HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, bar->width);
 17560 
 17561       win_x -= HORIZONTAL_SCROLL_BAR_LEFT_BORDER;
 17562 
 17563       if (bar->dragging != -1)
 17564         win_x -= bar->dragging;
 17565 
 17566       if (win_x < 0)
 17567         win_x = 0;
 17568       if (win_x > left_range)
 17569         win_x = left_range;
 17570 
 17571       *fp = f;
 17572       *bar_window = bar->window;
 17573 
 17574       if (bar->dragging != -1)
 17575         *part = scroll_bar_horizontal_handle;
 17576       else if (win_x < bar->start)
 17577         *part = scroll_bar_before_handle;
 17578       else if (win_x < bar->end + HORIZONTAL_SCROLL_BAR_MIN_HANDLE)
 17579         *part = scroll_bar_handle;
 17580       else
 17581         *part = scroll_bar_after_handle;
 17582 
 17583       XSETINT (*y, win_x);
 17584       XSETINT (*x, left_range);
 17585 
 17586       f->mouse_moved = false;
 17587       dpyinfo->last_mouse_scroll_bar = NULL;
 17588       *timestamp = dpyinfo->last_mouse_movement_time;
 17589     }
 17590 
 17591   unblock_input ();
 17592 }
 17593 
 17594 
 17595 /* The screen has been cleared and foreground or background colors may
 17596    have changed, so the scroll bars need to be redrawn.  Clear the
 17597    scroll bars and redraw them.  */
 17598 
 17599 static void
 17600 x_scroll_bar_clear (struct frame *f)
 17601 {
 17602 #ifndef USE_TOOLKIT_SCROLL_BARS
 17603   Lisp_Object bar, condemned;
 17604   GC gc = f->output_data.x->normal_gc;
 17605 
 17606   if (f->output_data.x->scroll_bar_background_pixel != -1)
 17607     XSetForeground (FRAME_X_DISPLAY (f), gc,
 17608                     f->output_data.x->scroll_bar_background_pixel);
 17609   else
 17610     XSetForeground (FRAME_X_DISPLAY (f), gc,
 17611                     FRAME_BACKGROUND_PIXEL (f));
 17612 
 17613   /* We can have scroll bars even if this is 0,
 17614      if we just turned off scroll bar mode.
 17615      But in that case we should not clear them.  */
 17616   if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
 17617     {
 17618       condemned = FRAME_CONDEMNED_SCROLL_BARS (f);
 17619       for (bar = FRAME_SCROLL_BARS (f);
 17620            /* This trick allows us to search both the ordinary and
 17621               condemned scroll bar lists with one loop.  */
 17622            !NILP (bar) || (bar = condemned,
 17623                            condemned = Qnil,
 17624                            !NILP (bar));
 17625            bar = XSCROLL_BAR (bar)->next)
 17626         x_scroll_bar_redraw (XSCROLL_BAR (bar));
 17627     }
 17628 
 17629   XSetForeground (FRAME_X_DISPLAY (f), gc,
 17630                   FRAME_FOREGROUND_PIXEL (f));
 17631 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 17632 }
 17633 
 17634 #ifdef ENABLE_CHECKING
 17635 
 17636 /* Record the last 100 characters stored
 17637    to help debug the loss-of-chars-during-GC problem.  */
 17638 
 17639 static int temp_index;
 17640 static short temp_buffer[100];
 17641 
 17642 #define STORE_KEYSYM_FOR_DEBUG(keysym)                          \
 17643   if (temp_index == ARRAYELTS (temp_buffer))                    \
 17644     temp_index = 0;                                             \
 17645   temp_buffer[temp_index++] = (keysym)
 17646 
 17647 #else /* not ENABLE_CHECKING */
 17648 
 17649 #define STORE_KEYSYM_FOR_DEBUG(keysym) ((void)0)
 17650 
 17651 #endif /* ENABLE_CHECKING */
 17652 
 17653 /* Set this to nonzero to fake an "X I/O error"
 17654    on a particular display.  */
 17655 
 17656 static struct x_display_info *XTread_socket_fake_io_error;
 17657 
 17658 /* When we find no input here, we occasionally do a no-op command
 17659    to verify that the X server is still running and we can still talk with it.
 17660    We try all the open displays, one by one.
 17661    This variable is used for cycling thru the displays.  */
 17662 
 17663 static struct x_display_info *next_noop_dpyinfo;
 17664 
 17665 /* Filter events for the current X input method.
 17666    DPYINFO is the display this event is for.
 17667    EVENT is the X event to filter.
 17668 
 17669    Returns non-zero if the event was filtered, caller shall not process
 17670    this event further.
 17671    Returns zero if event is wasn't filtered.  */
 17672 
 17673 #ifdef HAVE_X_I18N
 17674 static int
 17675 x_filter_event (struct x_display_info *dpyinfo, XEvent *event)
 17676 {
 17677   /* XFilterEvent returns non-zero if the input method has
 17678    consumed the event.  We pass the frame's X window to
 17679    XFilterEvent because that's the one for which the IC
 17680    was created.  */
 17681 
 17682   struct frame *f1;
 17683 
 17684 #if defined HAVE_XINPUT2 && defined USE_GTK
 17685   bool xinput_event = false;
 17686   if (dpyinfo->supports_xi2
 17687       && event->type == GenericEvent
 17688       && (event->xgeneric.extension
 17689           == dpyinfo->xi2_opcode)
 17690       && ((event->xgeneric.evtype
 17691            == XI_KeyPress)
 17692           || (event->xgeneric.evtype
 17693               == XI_KeyRelease)))
 17694     {
 17695       f1 = x_any_window_to_frame (dpyinfo,
 17696                                   ((XIDeviceEvent *)
 17697                                    event->xcookie.data)->event);
 17698       xinput_event = true;
 17699     }
 17700   else
 17701 #endif
 17702     f1 = x_any_window_to_frame (dpyinfo,
 17703                                 event->xclient.window);
 17704 
 17705 #ifdef USE_GTK
 17706   if (!x_gtk_use_native_input
 17707       && !dpyinfo->prefer_native_input)
 17708     {
 17709 #endif
 17710       return XFilterEvent (event, f1 ? FRAME_X_WINDOW (f1) : None);
 17711 #ifdef USE_GTK
 17712     }
 17713   else if (f1 && (event->type == KeyPress
 17714                   || event->type == KeyRelease
 17715 #ifdef HAVE_XINPUT2
 17716                   || xinput_event
 17717 #endif
 17718                   ))
 17719     {
 17720       bool result;
 17721 
 17722       block_input ();
 17723       result = xg_filter_key (f1, event);
 17724       unblock_input ();
 17725 
 17726       /* Clear `xg_pending_quit_event' so we don't end up reacting to quit
 17727          events sent outside the main event loop (i.e. those sent from
 17728          inside a popup menu event loop).  */
 17729 
 17730       if (popup_activated ())
 17731         xg_pending_quit_event.kind = NO_EVENT;
 17732 
 17733       if (result && f1)
 17734         /* There will probably be a GDK event generated soon, so
 17735            exercise the wire to make pselect return.  */
 17736         XNoOp (FRAME_X_DISPLAY (f1));
 17737 
 17738       return result;
 17739     }
 17740 
 17741   return 0;
 17742 #endif
 17743 }
 17744 #endif
 17745 
 17746 #ifdef USE_GTK
 17747 /* This is the filter function invoked by the GTK event loop.
 17748    It is invoked before the XEvent is translated to a GdkEvent,
 17749    so we have a chance to act on the event before GTK.  */
 17750 static GdkFilterReturn
 17751 event_handler_gdk (GdkXEvent *gxev, GdkEvent *ev, gpointer data)
 17752 {
 17753   XEvent *xev = (XEvent *) gxev;
 17754 
 17755   block_input ();
 17756   if (current_count >= 0)
 17757     {
 17758       struct x_display_info *dpyinfo;
 17759 
 17760       dpyinfo = x_display_info_for_display (xev->xany.display);
 17761 
 17762 #ifdef HAVE_X_I18N
 17763       /* Filter events for the current X input method.
 17764          GTK calls XFilterEvent but not for key press and release,
 17765          so we do it here.  */
 17766       if ((xev->type == KeyPress || xev->type == KeyRelease)
 17767           && dpyinfo
 17768           && x_filter_event (dpyinfo, xev))
 17769         {
 17770           unblock_input ();
 17771           return GDK_FILTER_REMOVE;
 17772         }
 17773 #elif USE_GTK
 17774       if (dpyinfo && (dpyinfo->prefer_native_input
 17775                       || x_gtk_use_native_input)
 17776           && (xev->type == KeyPress
 17777 #ifdef HAVE_XINPUT2
 17778               /* GTK claims cookies for us, so we don't have to claim
 17779                  them here.  */
 17780               || (dpyinfo->supports_xi2
 17781                   && xev->type == GenericEvent
 17782                   && (xev->xgeneric.extension
 17783                       == dpyinfo->xi2_opcode)
 17784                   && ((xev->xgeneric.evtype
 17785                        == XI_KeyPress)
 17786                       || (xev->xgeneric.evtype
 17787                           == XI_KeyRelease)))
 17788 #endif
 17789               ))
 17790         {
 17791           struct frame *f;
 17792 
 17793 #ifdef HAVE_XINPUT2
 17794           if (xev->type == GenericEvent)
 17795             f = x_any_window_to_frame (dpyinfo,
 17796                                        ((XIDeviceEvent *) xev->xcookie.data)->event);
 17797           else
 17798 #endif
 17799             f = x_any_window_to_frame (dpyinfo, xev->xany.window);
 17800 
 17801           if (f && xg_filter_key (f, xev))
 17802             {
 17803               unblock_input ();
 17804               return GDK_FILTER_REMOVE;
 17805             }
 17806         }
 17807 #endif
 17808 
 17809       if (! dpyinfo)
 17810         current_finish = X_EVENT_NORMAL;
 17811       else
 17812         current_count
 17813           += handle_one_xevent (dpyinfo, xev, &current_finish,
 17814                                 current_hold_quit);
 17815     }
 17816   else
 17817     current_finish = x_dispatch_event (xev, xev->xany.display);
 17818 
 17819   unblock_input ();
 17820 
 17821   if (current_finish == X_EVENT_GOTO_OUT || current_finish == X_EVENT_DROP)
 17822     return GDK_FILTER_REMOVE;
 17823 
 17824   return GDK_FILTER_CONTINUE;
 17825 }
 17826 #endif /* USE_GTK */
 17827 
 17828 
 17829 static void xembed_send_message (struct frame *f, Time,
 17830                                  enum xembed_message,
 17831                                  long detail, long data1, long data2);
 17832 
 17833 static void
 17834 x_net_wm_state (struct frame *f, Window window)
 17835 {
 17836   int value = FULLSCREEN_NONE;
 17837   Lisp_Object lval = Qnil;
 17838   bool sticky = false, shaded = false;
 17839 
 17840   x_get_current_wm_state (f, window, &value, &sticky, &shaded);
 17841 
 17842   switch (value)
 17843     {
 17844     case FULLSCREEN_WIDTH:
 17845       lval = Qfullwidth;
 17846       break;
 17847     case FULLSCREEN_HEIGHT:
 17848       lval = Qfullheight;
 17849       break;
 17850     case FULLSCREEN_BOTH:
 17851       lval = Qfullboth;
 17852       break;
 17853     case FULLSCREEN_MAXIMIZED:
 17854       lval = Qmaximized;
 17855       break;
 17856     }
 17857 
 17858   store_frame_param (f, Qfullscreen, lval);
 17859   store_frame_param (f, Qsticky, sticky ? Qt : Qnil);
 17860   store_frame_param (f, Qshaded, shaded ? Qt : Qnil);
 17861 }
 17862 
 17863 /* Flip back buffers on F if it has undrawn content.  */
 17864 
 17865 static void
 17866 x_flush_dirty_back_buffer_on (struct frame *f)
 17867 {
 17868 #ifdef HAVE_XDBE
 17869   if (FRAME_GARBAGED_P (f)
 17870       || buffer_flipping_blocked_p ()
 17871       /* If the frame is not already up to date, do not flush buffers
 17872          on input, as that will result in flicker.  */
 17873       || !FRAME_X_COMPLETE_P (f)
 17874       || !FRAME_X_NEED_BUFFER_FLIP (f))
 17875     return;
 17876 
 17877   show_back_buffer (f);
 17878 #endif
 17879 }
 17880 
 17881 #ifdef HAVE_GTK3
 17882 void
 17883 x_scroll_bar_configure (GdkEvent *event)
 17884 {
 17885   XEvent configure;
 17886   GdkDisplay *gdpy;
 17887   Display *dpy;
 17888 
 17889   configure.xconfigure.type = ConfigureNotify;
 17890   configure.xconfigure.serial = 0;
 17891   configure.xconfigure.send_event = event->configure.send_event;
 17892   configure.xconfigure.x = event->configure.x;
 17893   configure.xconfigure.y = event->configure.y;
 17894   configure.xconfigure.width = event->configure.width;
 17895   configure.xconfigure.height = event->configure.height;
 17896   configure.xconfigure.border_width = 0;
 17897   configure.xconfigure.event = GDK_WINDOW_XID (event->configure.window);
 17898   configure.xconfigure.window = GDK_WINDOW_XID (event->configure.window);
 17899   configure.xconfigure.above = None;
 17900   configure.xconfigure.override_redirect = False;
 17901 
 17902   gdpy = gdk_window_get_display (event->configure.window);
 17903   dpy = gdk_x11_display_get_xdisplay (gdpy);
 17904 
 17905   x_dispatch_event (&configure, dpy);
 17906 }
 17907 #endif
 17908 
 17909 /**
 17910   mouse_or_wdesc_frame: When not dropping and the mouse was grabbed
 17911   for DPYINFO, return the frame where the mouse was seen last.  If
 17912   there's no such frame, return the frame according to WDESC.  When
 17913   dropping, return the frame according to WDESC.  If there's no such
 17914   frame and the mouse was grabbed for DPYINFO, return the frame where
 17915   the mouse was seen last.  In either case, never return a tooltip
 17916   frame.  */
 17917 static struct frame *
 17918 mouse_or_wdesc_frame (struct x_display_info *dpyinfo, int wdesc)
 17919 {
 17920   struct frame *lm_f = (gui_mouse_grabbed (dpyinfo)
 17921                         ? dpyinfo->last_mouse_frame
 17922                         : NULL);
 17923 
 17924   if (lm_f && !EQ (track_mouse, Qdropping)
 17925       && !EQ (track_mouse, Qdrag_source))
 17926     return lm_f;
 17927   else
 17928     {
 17929       struct frame *w_f = x_window_to_frame (dpyinfo, wdesc);
 17930 
 17931       /* Do not return a tooltip frame.  */
 17932       if (!w_f || FRAME_TOOLTIP_P (w_f))
 17933         return EQ (track_mouse, Qdropping) ? lm_f : NULL;
 17934       else
 17935         /* When dropping it would be probably nice to raise w_f
 17936            here.  */
 17937         return w_f;
 17938     }
 17939 }
 17940 
 17941 static void
 17942 x_dnd_compute_tip_xy (int *root_x, int *root_y, Lisp_Object attributes)
 17943 {
 17944   Lisp_Object monitor, geometry;
 17945   int min_x, min_y, max_x, max_y;
 17946   int width, height;
 17947 
 17948   width = FRAME_PIXEL_WIDTH (XFRAME (tip_frame));
 17949   height = FRAME_PIXEL_HEIGHT (XFRAME (tip_frame));
 17950 
 17951   max_y = -1;
 17952 
 17953   /* Try to determine the monitor where the mouse pointer is and
 17954      its geometry.  See bug#22549.  */
 17955   while (CONSP (attributes))
 17956     {
 17957       monitor = XCAR (attributes);
 17958       geometry = assq_no_quit (Qgeometry, monitor);
 17959 
 17960       if (CONSP (geometry))
 17961         {
 17962           min_x = XFIXNUM (Fnth (make_fixnum (1), geometry));
 17963           min_y = XFIXNUM (Fnth (make_fixnum (2), geometry));
 17964           max_x = min_x + XFIXNUM (Fnth (make_fixnum (3), geometry));
 17965           max_y = min_y + XFIXNUM (Fnth (make_fixnum (4), geometry));
 17966 
 17967           if (min_x <= *root_x && *root_x < max_x
 17968               && min_y <= *root_y && *root_y < max_y)
 17969             break;
 17970 
 17971           max_y = -1;
 17972         }
 17973 
 17974       attributes = XCDR (attributes);
 17975     }
 17976 
 17977   /* It was not possible to determine the monitor's geometry, so we
 17978      assign some sane defaults here: */
 17979   if (max_y < 0)
 17980     {
 17981       min_x = 0;
 17982       min_y = 0;
 17983       max_x = x_display_pixel_width (FRAME_DISPLAY_INFO (x_dnd_frame));
 17984       max_y = x_display_pixel_height (FRAME_DISPLAY_INFO (x_dnd_frame));
 17985     }
 17986 
 17987   if (*root_y + XFIXNUM (tip_dy) <= min_y)
 17988     *root_y = min_y; /* Can happen for negative dy */
 17989   else if (*root_y + XFIXNUM (tip_dy) + height <= max_y)
 17990     /* It fits below the pointer */
 17991     *root_y += XFIXNUM (tip_dy);
 17992   else if (height + XFIXNUM (tip_dy) + min_y <= *root_y)
 17993     /* It fits above the pointer.  */
 17994     *root_y -= height + XFIXNUM (tip_dy);
 17995   else
 17996     /* Put it on the top.  */
 17997     *root_y = min_y;
 17998 
 17999   if (*root_x + XFIXNUM (tip_dx) <= min_x)
 18000     *root_x = 0; /* Can happen for negative dx */
 18001   else if (*root_x + XFIXNUM (tip_dx) + width <= max_x)
 18002     /* It fits to the right of the pointer.  */
 18003     *root_x += XFIXNUM (tip_dx);
 18004   else if (width + XFIXNUM (tip_dx) + min_x <= *root_x)
 18005     /* It fits to the left of the pointer.  */
 18006     *root_x -= width + XFIXNUM (tip_dx);
 18007   else
 18008     /* Put it left justified on the screen -- it ought to fit that way.  */
 18009     *root_x = min_x;
 18010 }
 18011 
 18012 static void
 18013 x_dnd_update_tooltip_position (int root_x, int root_y)
 18014 {
 18015   struct frame *tip_f;
 18016 
 18017   if (!x_dnd_in_progress || !x_dnd_update_tooltip)
 18018     return;
 18019 
 18020   if (!FRAMEP (tip_frame))
 18021     return;
 18022 
 18023   tip_f = XFRAME (tip_frame);
 18024 
 18025   if (!FRAME_LIVE_P (tip_f)
 18026       || !FRAME_VISIBLE_P (tip_f)
 18027       || (FRAME_X_DISPLAY (tip_f)
 18028           != FRAME_X_DISPLAY (x_dnd_frame)))
 18029     return;
 18030 
 18031   if (tip_window != None
 18032       && FIXNUMP (tip_dx) && FIXNUMP (tip_dy))
 18033     {
 18034       x_dnd_compute_tip_xy (&root_x, &root_y,
 18035                             x_dnd_monitors);
 18036 
 18037       if (x_dnd_last_tooltip_valid
 18038           && root_x == x_dnd_last_tooltip_x
 18039           && root_y == x_dnd_last_tooltip_y)
 18040         return;
 18041 
 18042       x_dnd_last_tooltip_x = root_x;
 18043       x_dnd_last_tooltip_y = root_y;
 18044       x_dnd_last_tooltip_valid = true;
 18045 
 18046       XMoveWindow (FRAME_X_DISPLAY (x_dnd_frame),
 18047                    tip_window, root_x, root_y);
 18048     }
 18049 }
 18050 
 18051 static void
 18052 x_dnd_update_tooltip_now (void)
 18053 {
 18054   int root_x, root_y;
 18055   Window root, child;
 18056   int win_x, win_y;
 18057   unsigned int mask;
 18058   Bool rc;
 18059   struct x_display_info *dpyinfo;
 18060 
 18061   if (!x_dnd_in_progress || !x_dnd_update_tooltip)
 18062     return;
 18063 
 18064   dpyinfo = FRAME_DISPLAY_INFO (x_dnd_frame);
 18065 
 18066 #ifndef HAVE_XINPUT2
 18067   rc = XQueryPointer (dpyinfo->display,
 18068                       dpyinfo->root_window,
 18069                       &root, &child, &root_x,
 18070                       &root_y, &win_x, &win_y,
 18071                       &mask);
 18072 #else
 18073   rc = x_query_pointer_1 (dpyinfo, x_dnd_pointer_device,
 18074                           dpyinfo->root_window,
 18075                           &root, &child, &root_x,
 18076                           &root_y, &win_x, &win_y,
 18077                           &mask);
 18078 #endif
 18079 
 18080   if (rc)
 18081     x_dnd_update_tooltip_position (root_x, root_y);
 18082 }
 18083 
 18084 /* Get the window underneath the pointer, see if it moved, and update
 18085    the DND state accordingly.  */
 18086 static void
 18087 x_dnd_update_state (struct x_display_info *dpyinfo, Time timestamp)
 18088 {
 18089   int root_x, root_y, dummy_x, dummy_y, target_proto, motif_style;
 18090   unsigned int dummy_mask;
 18091   Window dummy, dummy_child, target, toplevel;
 18092   xm_top_level_leave_message lmsg;
 18093   xm_top_level_enter_message emsg;
 18094   xm_drag_motion_message dmsg;
 18095   xm_drop_start_message dsmsg;
 18096   bool was_frame;
 18097 
 18098   if (x_query_pointer_1 (dpyinfo,
 18099 #ifdef HAVE_XINPUT2
 18100                          x_dnd_pointer_device,
 18101 #else
 18102                          -1,
 18103 #endif
 18104                          dpyinfo->root_window,
 18105                          &dummy, &dummy_child,
 18106                          &root_x, &root_y,
 18107                          &dummy_x, &dummy_y,
 18108                          &dummy_mask))
 18109     {
 18110       target = x_dnd_get_target_window (dpyinfo, root_x,
 18111                                         root_y, &target_proto,
 18112                                         &motif_style, &toplevel,
 18113                                         &was_frame);
 18114 
 18115       if (toplevel != x_dnd_last_seen_toplevel)
 18116         {
 18117           if (toplevel != FRAME_OUTER_WINDOW (x_dnd_frame)
 18118               && x_dnd_return_frame == 1)
 18119             x_dnd_return_frame = 2;
 18120 
 18121           if (x_dnd_return_frame == 2
 18122               && x_any_window_to_frame (dpyinfo, toplevel))
 18123             {
 18124               if (x_dnd_last_seen_window != None
 18125                   && x_dnd_last_protocol_version != -1
 18126                   && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 18127                 x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window,
 18128                                   x_dnd_last_seen_toplevel);
 18129               else if (x_dnd_last_seen_window != None
 18130                        && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)
 18131                        && !x_dnd_disable_motif_drag
 18132                        && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 18133                 {
 18134                   if (!x_dnd_motif_setup_p)
 18135                     xm_setup_drag_info (dpyinfo, x_dnd_frame);
 18136 
 18137                   lmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 18138                                                 XM_DRAG_REASON_TOP_LEVEL_LEAVE);
 18139                   lmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 18140                   lmsg.zero = 0;
 18141                   lmsg.timestamp = timestamp;
 18142                   lmsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 18143 
 18144                   if (x_dnd_motif_setup_p)
 18145                     xm_send_top_level_leave_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 18146                                                      x_dnd_last_seen_window, &lmsg);
 18147                 }
 18148 
 18149               x_dnd_end_window = x_dnd_last_seen_window;
 18150               x_dnd_last_seen_window = None;
 18151               x_dnd_last_seen_toplevel = None;
 18152               x_dnd_in_progress = false;
 18153               x_dnd_return_frame_object
 18154                 = x_any_window_to_frame (dpyinfo, toplevel);
 18155               x_dnd_return_frame = 3;
 18156               x_dnd_waiting_for_finish = false;
 18157               target = None;
 18158             }
 18159         }
 18160 
 18161       if (target != x_dnd_last_seen_window)
 18162         {
 18163           if (x_dnd_last_seen_window != None
 18164               && x_dnd_last_protocol_version != -1
 18165               && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 18166             x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window,
 18167                               x_dnd_last_seen_toplevel);
 18168           else if (x_dnd_last_seen_window != None
 18169                    && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)
 18170                    && !x_dnd_disable_motif_drag
 18171                    && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 18172             {
 18173               if (!x_dnd_motif_setup_p)
 18174                 xm_setup_drag_info (dpyinfo, x_dnd_frame);
 18175 
 18176               lmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 18177                                             XM_DRAG_REASON_TOP_LEVEL_LEAVE);
 18178               lmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 18179               lmsg.zero = 0;
 18180               lmsg.timestamp = timestamp;
 18181               lmsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 18182 
 18183               if (x_dnd_motif_setup_p)
 18184                 xm_send_top_level_leave_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 18185                                                  x_dnd_last_seen_window, &lmsg);
 18186             }
 18187 
 18188           x_dnd_action = None;
 18189           x_dnd_last_seen_toplevel = toplevel;
 18190           x_dnd_last_seen_window = target;
 18191           x_dnd_last_protocol_version = target_proto;
 18192           x_dnd_last_motif_style = motif_style;
 18193           x_dnd_last_window_is_frame = was_frame;
 18194 
 18195           if (target != None && x_dnd_last_protocol_version != -1)
 18196             x_dnd_send_enter (x_dnd_frame, target, x_dnd_last_seen_toplevel,
 18197                               x_dnd_last_protocol_version);
 18198           else if (target != None && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)
 18199                    && !x_dnd_disable_motif_drag)
 18200             {
 18201               if (!x_dnd_motif_setup_p)
 18202                 xm_setup_drag_info (dpyinfo, x_dnd_frame);
 18203 
 18204               emsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 18205                                             XM_DRAG_REASON_TOP_LEVEL_ENTER);
 18206               emsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 18207               emsg.zero = 0;
 18208               emsg.timestamp = timestamp;
 18209               emsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 18210               emsg.index_atom = x_dnd_motif_atom;
 18211 
 18212               if (x_dnd_motif_setup_p)
 18213                 xm_send_top_level_enter_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 18214                                                  target, &emsg);
 18215             }
 18216         }
 18217       else
 18218         x_dnd_last_seen_toplevel = toplevel;
 18219 
 18220       if (x_dnd_last_window_is_frame && target != None)
 18221         x_dnd_note_self_position (dpyinfo, target, root_x, root_y);
 18222       else if (x_dnd_last_protocol_version != -1 && target != None)
 18223         x_dnd_send_position (x_dnd_frame, target,
 18224                              x_dnd_last_seen_toplevel,
 18225                              x_dnd_last_protocol_version,
 18226                              root_x, root_y,
 18227                              x_dnd_selection_timestamp,
 18228                              x_dnd_wanted_action, 0,
 18229 #ifdef HAVE_XKB
 18230                              x_dnd_keyboard_state
 18231 #else
 18232                              0
 18233 #endif
 18234                              );
 18235       else if (XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) && target != None
 18236                && !x_dnd_disable_motif_drag)
 18237         {
 18238           if (!x_dnd_motif_setup_p)
 18239             xm_setup_drag_info (dpyinfo, x_dnd_frame);
 18240 
 18241           dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 18242                                         XM_DRAG_REASON_DRAG_MOTION);
 18243           dmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 18244           dmsg.side_effects
 18245             = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo,
 18246                                                                x_dnd_wanted_action),
 18247                                    XM_DROP_SITE_VALID, x_dnd_motif_operations,
 18248                                    (!x_dnd_xm_use_help
 18249                                     ? XM_DROP_ACTION_DROP
 18250                                     : XM_DROP_ACTION_DROP_HELP));
 18251           dmsg.timestamp = timestamp;
 18252           dmsg.x = root_x;
 18253           dmsg.y = root_y;
 18254 
 18255           if (x_dnd_motif_setup_p)
 18256             xm_send_drag_motion_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 18257                                          target, &dmsg);
 18258         }
 18259 
 18260       x_dnd_update_tooltip_position (root_x, root_y);
 18261     }
 18262   /* The pointer moved out of the screen.  */
 18263   else if (x_dnd_last_protocol_version != -1)
 18264     {
 18265       if (x_dnd_last_seen_window != None
 18266           && x_dnd_last_protocol_version != -1)
 18267         x_dnd_send_leave (x_dnd_frame,
 18268                           x_dnd_last_seen_window,
 18269                           x_dnd_last_seen_toplevel);
 18270       else if (x_dnd_last_seen_window != None
 18271                && !XM_DRAG_STYLE_IS_DROP_ONLY (x_dnd_last_motif_style)
 18272                && x_dnd_last_motif_style != XM_DRAG_STYLE_NONE
 18273                && x_dnd_motif_setup_p)
 18274         {
 18275           dsmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 18276                                          XM_DRAG_REASON_DROP_START);
 18277           dmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 18278           dsmsg.timestamp = timestamp;
 18279           dsmsg.side_effects
 18280             = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo,
 18281                                                                x_dnd_wanted_action),
 18282                                    XM_DROP_SITE_VALID, x_dnd_motif_operations,
 18283                                    XM_DROP_ACTION_DROP_CANCEL);
 18284           dsmsg.x = 0;
 18285           dsmsg.y = 0;
 18286           dsmsg.index_atom = x_dnd_motif_atom;
 18287           dsmsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 18288 
 18289           x_dnd_send_xm_leave_for_drop (dpyinfo, x_dnd_frame,
 18290                                         x_dnd_last_seen_window, timestamp);
 18291           xm_send_drop_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 18292                                 x_dnd_last_seen_window, &dsmsg);
 18293         }
 18294 
 18295       x_dnd_end_window = x_dnd_last_seen_window;
 18296       x_dnd_last_seen_window = None;
 18297       x_dnd_last_seen_toplevel = None;
 18298       x_dnd_in_progress = false;
 18299       x_dnd_waiting_for_finish = false;
 18300       x_dnd_frame = NULL;
 18301     }
 18302 }
 18303 
 18304 int
 18305 x_display_pixel_height (struct x_display_info *dpyinfo)
 18306 {
 18307   if (dpyinfo->screen_height)
 18308     return dpyinfo->screen_height;
 18309 
 18310   return HeightOfScreen (dpyinfo->screen);
 18311 }
 18312 
 18313 int
 18314 x_display_pixel_width (struct x_display_info *dpyinfo)
 18315 {
 18316   if (dpyinfo->screen_width)
 18317     return dpyinfo->screen_width;
 18318 
 18319   return WidthOfScreen (dpyinfo->screen);
 18320 }
 18321 
 18322 /* Handle events from each display until CELL's car becomes non-nil,
 18323    or TIMEOUT elapses.  */
 18324 void
 18325 x_wait_for_cell_change (Lisp_Object cell, struct timespec timeout)
 18326 {
 18327   struct x_display_info *dpyinfo;
 18328   fd_set fds;
 18329   int fd, maxfd;
 18330 #ifndef USE_GTK
 18331   int finish, rc;
 18332   XEvent event;
 18333   fd_set rfds;
 18334 #endif
 18335   struct input_event hold_quit;
 18336   struct timespec current, at;
 18337 
 18338   at = timespec_add (current_timespec (), timeout);
 18339 
 18340 #ifndef USE_GTK
 18341   FD_ZERO (&rfds);
 18342   rc = -1;
 18343 #endif
 18344 
 18345   while (true)
 18346     {
 18347       FD_ZERO (&fds);
 18348       maxfd = -1;
 18349 
 18350       for (dpyinfo = x_display_list; dpyinfo;
 18351            dpyinfo = dpyinfo->next)
 18352         {
 18353           fd = ConnectionNumber (dpyinfo->display);
 18354 
 18355 #ifndef USE_GTK
 18356           if ((rc < 0 || FD_ISSET (fd, &rfds))
 18357               /* If pselect failed, the erroring display's IO error
 18358                  handler will eventually be called.  */
 18359               && XPending (dpyinfo->display))
 18360             {
 18361               while (XPending (dpyinfo->display))
 18362                 {
 18363                   EVENT_INIT (hold_quit);
 18364 
 18365                   XNextEvent (dpyinfo->display, &event);
 18366                   handle_one_xevent (dpyinfo, &event,
 18367                                      &finish, &hold_quit);
 18368 
 18369                   if (!NILP (XCAR (cell)))
 18370                     return;
 18371 
 18372                   if (finish == X_EVENT_GOTO_OUT)
 18373                     break;
 18374 
 18375                   /* Make us quit now.  */
 18376                   if (hold_quit.kind != NO_EVENT)
 18377                     kbd_buffer_store_event (&hold_quit);
 18378                 }
 18379             }
 18380 #endif
 18381 
 18382           if (fd > maxfd)
 18383             maxfd = fd;
 18384 
 18385           eassert (fd < FD_SETSIZE);
 18386           FD_SET (fd, &fds);
 18387         }
 18388 
 18389       /* Prevent events from being lost (from GTK's point of view) by
 18390          using GDK to run the event loop.  */
 18391 #ifdef USE_GTK
 18392       while (gtk_events_pending ())
 18393         {
 18394           EVENT_INIT (hold_quit);
 18395           current_count = 0;
 18396           current_hold_quit = &hold_quit;
 18397           current_finish = X_EVENT_NORMAL;
 18398 
 18399           gtk_main_iteration ();
 18400 
 18401           current_count = -1;
 18402           current_hold_quit = NULL;
 18403 
 18404           /* Make us quit now.  */
 18405           if (hold_quit.kind != NO_EVENT)
 18406             kbd_buffer_store_event (&hold_quit);
 18407 
 18408           if (!NILP (XCAR (cell)))
 18409             return;
 18410 
 18411           if (current_finish == X_EVENT_GOTO_OUT)
 18412             break;
 18413         }
 18414 #endif
 18415 
 18416       eassert (maxfd >= 0);
 18417 
 18418       current = current_timespec ();
 18419 
 18420       if (timespec_cmp (at, current) < 0
 18421           || !NILP (XCAR (cell)))
 18422         return;
 18423 
 18424       timeout = timespec_sub (at, current);
 18425 
 18426 #ifndef USE_GTK
 18427       rc = pselect (maxfd + 1, &fds, NULL, NULL, &timeout, NULL);
 18428 
 18429       if (rc >= 0)
 18430         rfds = fds;
 18431 #else
 18432       pselect (maxfd + 1, &fds, NULL, NULL, &timeout, NULL);
 18433 #endif
 18434     }
 18435 }
 18436 
 18437 /* Find whether or not an undelivered MONITORS_CHANGED_EVENT is
 18438    already on the event queue.  DPYINFO is the display any such event
 18439    must apply to.  */
 18440 
 18441 static bool
 18442 x_find_monitors_changed_event (struct x_display_info *dpyinfo)
 18443 {
 18444   union buffered_input_event *event;
 18445 
 18446   event = kbd_fetch_ptr;
 18447 
 18448   while (event != kbd_store_ptr)
 18449     {
 18450       if (event->ie.kind == MONITORS_CHANGED_EVENT
 18451           && XTERMINAL (event->ie.arg) == dpyinfo->terminal)
 18452         return true;
 18453 
 18454       event = X_NEXT_KBD_EVENT (event);
 18455     }
 18456 
 18457   return false;
 18458 }
 18459 
 18460 #ifdef USE_GTK
 18461 static void
 18462 x_monitors_changed_cb (GdkScreen *gscr, gpointer user_data)
 18463 {
 18464   struct x_display_info *dpyinfo;
 18465   struct input_event ie;
 18466   Lisp_Object current_monitors, terminal;
 18467   GdkDisplay *gdpy;
 18468   Display *dpy;
 18469 
 18470   gdpy = gdk_screen_get_display (gscr);
 18471   dpy = gdk_x11_display_get_xdisplay (gdpy);
 18472   dpyinfo = x_display_info_for_display (dpy);
 18473 
 18474   if (!dpyinfo)
 18475     return;
 18476 
 18477   if (x_find_monitors_changed_event (dpyinfo))
 18478     return;
 18479 
 18480   XSETTERMINAL (terminal, dpyinfo->terminal);
 18481 
 18482   current_monitors
 18483     = Fx_display_monitor_attributes_list (terminal);
 18484 
 18485   if (NILP (Fequal (current_monitors,
 18486                     dpyinfo->last_monitor_attributes_list)))
 18487     {
 18488       EVENT_INIT (ie);
 18489       ie.kind = MONITORS_CHANGED_EVENT;
 18490       ie.arg = terminal;
 18491 
 18492       kbd_buffer_store_event (&ie);
 18493 
 18494       if (x_dnd_in_progress && x_dnd_update_tooltip)
 18495         x_dnd_monitors = current_monitors;
 18496 
 18497       x_dnd_update_tooltip_now ();
 18498     }
 18499 
 18500   dpyinfo->last_monitor_attributes_list = current_monitors;
 18501 }
 18502 #endif
 18503 
 18504 /* Extract the root window coordinates from the client message EVENT
 18505    if it is a message that we already understand.  Return false if the
 18506    event was not understood.  */
 18507 static bool
 18508 x_coords_from_dnd_message (struct x_display_info *dpyinfo,
 18509                            XEvent *event, int *x_out, int *y_out)
 18510 {
 18511   xm_drag_motion_message dmsg;
 18512   xm_drag_motion_reply dreply;
 18513   xm_drop_start_message smsg;
 18514   xm_drop_start_reply reply;
 18515   unsigned long kde_data;
 18516 
 18517   if (event->type != ClientMessage)
 18518     return false;
 18519 
 18520   if (event->xclient.message_type == dpyinfo->Xatom_XdndPosition)
 18521     {
 18522       if (event->xclient.format != 32)
 18523         return false;
 18524 
 18525       *x_out = (((unsigned long) event->xclient.data.l[2]) >> 16
 18526                 & 0xffff);
 18527       *y_out = (event->xclient.data.l[2] & 0xffff);
 18528 
 18529       return true;
 18530     }
 18531 
 18532   if ((event->xclient.message_type
 18533        == dpyinfo->Xatom_MOTIF_DRAG_AND_DROP_MESSAGE)
 18534       && event->xclient.format == 8)
 18535     {
 18536       if (!xm_read_drag_motion_message (event, &dmsg))
 18537         {
 18538           *x_out = dmsg.x;
 18539           *y_out = dmsg.y;
 18540 
 18541           return true;
 18542         }
 18543       else if (!xm_read_drag_motion_reply (event, &dreply))
 18544         {
 18545           *x_out = dreply.better_x;
 18546           *y_out = dreply.better_y;
 18547 
 18548           return true;
 18549         }
 18550       else if (!xm_read_drop_start_message (event, &smsg))
 18551         {
 18552           *x_out = smsg.x;
 18553           *y_out = smsg.y;
 18554 
 18555           return true;
 18556         }
 18557       else if (!xm_read_drop_start_reply (event, &reply))
 18558         {
 18559           *x_out = reply.better_x;
 18560           *y_out = reply.better_y;
 18561 
 18562           return true;
 18563         }
 18564     }
 18565 
 18566   if (((event->xclient.message_type
 18567         == dpyinfo->Xatom_DndProtocol)
 18568        || (event->xclient.message_type
 18569            == dpyinfo->Xatom_DND_PROTOCOL))
 18570       && event->xclient.format == 32
 18571       /* Check that the version of the old KDE protocol is new
 18572          enough to include coordinates.  */
 18573       && event->xclient.data.l[4])
 18574     {
 18575       kde_data = (unsigned long) event->xclient.data.l[3];
 18576 
 18577       *x_out = (kde_data & 0xffff);
 18578       *y_out = (kde_data >> 16 & 0xffff);
 18579 
 18580       return true;
 18581     }
 18582 
 18583   return false;
 18584 }
 18585 
 18586 static void
 18587 x_handle_wm_state (struct frame *f, struct input_event *ie)
 18588 {
 18589   struct x_display_info *dpyinfo;
 18590   Atom type;
 18591   int format;
 18592   unsigned long nitems, bytes_after;
 18593   unsigned char *data;
 18594   unsigned long *state;
 18595 
 18596   data = NULL;
 18597   dpyinfo = FRAME_DISPLAY_INFO (f);
 18598 
 18599   if (XGetWindowProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 18600                           dpyinfo->Xatom_wm_state, 0, 2, False,
 18601                           AnyPropertyType, &type, &format, &nitems,
 18602                           &bytes_after, &data) != Success)
 18603     return;
 18604 
 18605   if (!data || nitems != 2 || format != 32)
 18606     {
 18607       if (data)
 18608         XFree (data);
 18609 
 18610       return;
 18611     }
 18612 
 18613   state = (unsigned long *) data;
 18614 
 18615   if (state[0] == NormalState && FRAME_ICONIFIED_P (f))
 18616     {
 18617       /* The frame has been deiconified.  It has not been withdrawn
 18618          and is now visible.  */
 18619       SET_FRAME_VISIBLE (f, 1);
 18620       SET_FRAME_ICONIFIED (f, false);
 18621       f->output_data.x->has_been_visible = true;
 18622 
 18623       ie->kind = DEICONIFY_EVENT;
 18624       XSETFRAME (ie->frame_or_window, f);
 18625     }
 18626   else if (state[0] == IconicState
 18627            /* _NET_WM_STATE_HIDDEN should be used if the window
 18628               manager supports that.  */
 18629            && !x_wm_supports (f, dpyinfo->Xatom_net_wm_state_hidden))
 18630     {
 18631       /* The frame is actually iconified right now.  Mark it as
 18632          such.  */
 18633 
 18634       SET_FRAME_VISIBLE (f, 0);
 18635       SET_FRAME_ICONIFIED (f, true);
 18636 
 18637       ie->kind = ICONIFY_EVENT;
 18638       XSETFRAME (ie->frame_or_window, f);
 18639     }
 18640 
 18641   /* state[0] can also be WithdrawnState, meaning that the window has
 18642      been withdrawn and is no longer iconified.  However, Emacs sets
 18643      the correct flags upon withdrawing the window, so there is no
 18644      need to do anything here.  */
 18645 
 18646   XFree (data);
 18647 }
 18648 
 18649 #ifdef HAVE_XFIXES
 18650 
 18651 static bool
 18652 x_handle_selection_monitor_event (struct x_display_info *dpyinfo,
 18653                                   const XEvent *event)
 18654 {
 18655   XFixesSelectionNotifyEvent *notify;
 18656   int i;
 18657 
 18658   notify = (XFixesSelectionNotifyEvent *) event;
 18659 
 18660   if (notify->window != dpyinfo->selection_tracking_window)
 18661     return false;
 18662 
 18663   for (i = 0; i < dpyinfo->n_monitored_selections; ++i)
 18664     {
 18665       /* We don't have to keep track of timestamps here.  */
 18666       if (notify->selection == dpyinfo->monitored_selections[i].name)
 18667         dpyinfo->monitored_selections[i].owner = notify->owner;
 18668     }
 18669 
 18670   return true;
 18671 }
 18672 
 18673 Window
 18674 x_find_selection_owner (struct x_display_info *dpyinfo, Atom selection)
 18675 {
 18676   int i;
 18677 
 18678   for (i = 0; i < dpyinfo->n_monitored_selections; ++i)
 18679     {
 18680       if (selection == dpyinfo->monitored_selections[i].name)
 18681         return dpyinfo->monitored_selections[i].owner;
 18682     }
 18683 
 18684   return X_INVALID_WINDOW;
 18685 }
 18686 
 18687 #endif
 18688 
 18689 /* Handles the XEvent EVENT on display DPYINFO.
 18690 
 18691    *FINISH is X_EVENT_GOTO_OUT if caller should stop reading events.
 18692    *FINISH is zero if caller should continue reading events.
 18693    *FINISH is X_EVENT_DROP if event should not be passed to the toolkit.
 18694    *EVENT is unchanged unless we're processing KeyPress event.
 18695 
 18696    We return the number of characters stored into the buffer.  */
 18697 
 18698 static int
 18699 handle_one_xevent (struct x_display_info *dpyinfo,
 18700 #ifndef HAVE_XINPUT2
 18701                    const XEvent *event,
 18702 #else
 18703                    XEvent *event,
 18704 #endif
 18705                    int *finish, struct input_event *hold_quit)
 18706 {
 18707   union buffered_input_event inev;
 18708   int count = 0;
 18709   int do_help = 0;
 18710 #ifdef HAVE_XINPUT2
 18711   struct xi_device_t *gen_help_device;
 18712   Time gen_help_time UNINIT;
 18713 #endif
 18714   ptrdiff_t nbytes = 0;
 18715   struct frame *any, *f = NULL, *mouse_frame;
 18716   Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
 18717   /* This holds the state XLookupString needs to implement dead keys
 18718      and other tricks known as "compose processing".  _X Window System_
 18719      says that a portable program can't use this, but Stephen Gildea assures
 18720      me that letting the compiler initialize it to zeros will work okay.  */
 18721   static XComposeStatus compose_status;
 18722   XEvent configureEvent;
 18723   XEvent next_event;
 18724   Lisp_Object coding;
 18725 #if defined USE_X_TOOLKIT && defined HAVE_XINPUT2
 18726   /* Some XInput 2 events are important for Motif and Lucid menu bars
 18727      to work correctly, so they must be translated into core events
 18728      before being passed to XtDispatchEvent.  */
 18729   bool use_copy = false;
 18730   XEvent copy;
 18731 #elif defined USE_GTK && !defined HAVE_GTK3 && defined HAVE_XINPUT2
 18732   GdkEvent *copy = NULL;
 18733   GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display);
 18734 #endif
 18735   int dx, dy;
 18736 
 18737   /* Avoid warnings when SAFE_ALLOCA is not actually used.  */
 18738 #if defined HAVE_XINPUT2 || defined HAVE_XKB || defined HAVE_X_I18N
 18739   USE_SAFE_ALLOCA;
 18740 #endif
 18741 
 18742   /* This function is not reentrant, so input should be blocked before
 18743      it is called.  */
 18744 
 18745   if (!input_blocked_p ())
 18746     emacs_abort ();
 18747 
 18748   *finish = X_EVENT_NORMAL;
 18749 
 18750   EVENT_INIT (inev.ie);
 18751   inev.ie.kind = NO_EVENT;
 18752   inev.ie.arg = Qnil;
 18753 #ifdef HAVE_XINPUT2
 18754   gen_help_device = NULL;
 18755 #endif
 18756 
 18757   /* Ignore events coming from various extensions, such as XFIXES and
 18758      XKB.  */
 18759   if (event->type < LASTEvent)
 18760     {
 18761 #ifdef HAVE_XINPUT2
 18762       if (event->type != GenericEvent)
 18763 #endif
 18764         any = x_any_window_to_frame (dpyinfo, event->xany.window);
 18765 #ifdef HAVE_XINPUT2
 18766       else
 18767         any = NULL;
 18768 #endif
 18769     }
 18770   else
 18771     any = NULL;
 18772 
 18773   if (any && any->wait_event_type == event->type)
 18774     any->wait_event_type = 0; /* Indicates we got it.  */
 18775 
 18776   switch (event->type)
 18777     {
 18778     case ClientMessage:
 18779       {
 18780         int rc;
 18781 
 18782         if (((x_dnd_in_progress
 18783               && FRAME_DISPLAY_INFO (x_dnd_frame) == dpyinfo)
 18784              || (x_dnd_waiting_for_finish
 18785                  && FRAME_DISPLAY_INFO (x_dnd_finish_frame) == dpyinfo))
 18786             && event->xclient.message_type == dpyinfo->Xatom_XdndStatus)
 18787           {
 18788             Window target;
 18789             unsigned long r1, r2;
 18790             int root_x, root_y;
 18791             bool button;
 18792 
 18793             target = event->xclient.data.l[0];
 18794 
 18795             if (x_dnd_last_protocol_version != -1
 18796                 && x_dnd_in_progress
 18797                 && target == x_dnd_last_seen_toplevel
 18798                 /* The XDND documentation is not very clearly worded.
 18799                    But this should be the correct behavior, since
 18800                    "kDNDStatusSendHereFlag" in the reference
 18801                    implementation is 2, and means the mouse rect
 18802                    should be ignored.  */
 18803                 && !(event->xclient.data.l[1] & 2))
 18804               {
 18805                 r1 = event->xclient.data.l[2];
 18806                 r2 = event->xclient.data.l[3];
 18807 
 18808                 x_dnd_mouse_rect_target = target;
 18809                 x_dnd_mouse_rect.x = (r1 & 0xffff0000) >> 16;
 18810                 x_dnd_mouse_rect.y = (r1 & 0xffff);
 18811                 x_dnd_mouse_rect.width = (r2 & 0xffff0000) >> 16;
 18812                 x_dnd_mouse_rect.height = (r2 & 0xffff);
 18813               }
 18814             else
 18815               x_dnd_mouse_rect_target = None;
 18816 
 18817             if (x_dnd_last_protocol_version != -1
 18818                 && (x_dnd_in_progress
 18819                     && target == x_dnd_last_seen_window))
 18820               {
 18821                 if (event->xclient.data.l[1] & 1)
 18822                   {
 18823                     if (x_dnd_last_protocol_version >= 2)
 18824                       x_dnd_action = event->xclient.data.l[4];
 18825                     else
 18826                       x_dnd_action = dpyinfo->Xatom_XdndActionCopy;
 18827                   }
 18828                 else
 18829                   x_dnd_action = None;
 18830               }
 18831 
 18832             /* Send any pending XdndPosition message.  */
 18833             if (x_dnd_waiting_for_status_window == target)
 18834               {
 18835                 if (x_dnd_pending_send_position.type != 0)
 18836                   {
 18837                     /* If the last XdndStatus specified a mouse
 18838                        rectangle and this event falls inside, don't
 18839                        send the event, but clear
 18840                        x_dnd_waiting_for_status_window instead.  */
 18841 
 18842                     root_x = x_dnd_pending_send_position_root_x;
 18843                     root_y = x_dnd_pending_send_position_root_y;
 18844                     button = x_dnd_pending_send_position_button;
 18845 
 18846                     if (target == x_dnd_mouse_rect_target
 18847                         && x_dnd_mouse_rect.width
 18848                         && x_dnd_mouse_rect.height
 18849                         /* Ignore the mouse rectangle if we're
 18850                            supposed to be sending a button press
 18851                            instead.  */
 18852                         && !button
 18853                         && (root_x >= x_dnd_mouse_rect.x
 18854                             && root_x < (x_dnd_mouse_rect.x
 18855                                          + x_dnd_mouse_rect.width)
 18856                             && root_y >= x_dnd_mouse_rect.y
 18857                             && root_y < (x_dnd_mouse_rect.y
 18858                                          + x_dnd_mouse_rect.height)))
 18859                       x_dnd_waiting_for_status_window = None;
 18860                     else
 18861                       {
 18862                         x_ignore_errors_for_next_request (dpyinfo, 0);
 18863                         XSendEvent (dpyinfo->display, target,
 18864                                     False, NoEventMask,
 18865                                     &x_dnd_pending_send_position);
 18866                         x_stop_ignoring_errors (dpyinfo);
 18867                         x_dnd_pending_send_position.type = 0;
 18868 
 18869                         /* Since we sent another XdndPosition message, we
 18870                            have to wait for another one in reply, so don't
 18871                            reset `x_dnd_waiting_for_status_window'
 18872                            here.  */
 18873                       }
 18874                   }
 18875                 else
 18876                   x_dnd_waiting_for_status_window = None;
 18877 
 18878                 /* Send any pending drop if warranted.  */
 18879                 if (x_dnd_waiting_for_finish && x_dnd_need_send_drop
 18880                     && x_dnd_waiting_for_status_window == None)
 18881                   {
 18882                     if (event->xclient.data.l[1] & 1)
 18883                       {
 18884                         if (x_dnd_send_drop_proto >= 2)
 18885                           x_dnd_action = event->xclient.data.l[4];
 18886                         else
 18887                           x_dnd_action = dpyinfo->Xatom_XdndActionCopy;
 18888                       }
 18889                     else
 18890                       x_dnd_action = None;
 18891 
 18892                     x_dnd_waiting_for_finish
 18893                       = x_dnd_send_drop (x_dnd_finish_frame,
 18894                                          target,
 18895                                          x_dnd_last_seen_toplevel,
 18896                                          x_dnd_selection_timestamp,
 18897                                          x_dnd_send_drop_proto);
 18898                   }
 18899               }
 18900 
 18901             goto done;
 18902           }
 18903 
 18904         if (event->xclient.message_type == dpyinfo->Xatom_XdndFinished
 18905             && (x_dnd_waiting_for_finish && !x_dnd_waiting_for_motif_finish)
 18906             /* Also check that the display is correct, since
 18907                `x_dnd_pending_finish_target' could still be valid on
 18908                another X server.  */
 18909             && dpyinfo->display == x_dnd_finish_display
 18910             && event->xclient.data.l[0] == x_dnd_pending_finish_target)
 18911           {
 18912             x_dnd_waiting_for_finish = false;
 18913 
 18914             if (x_dnd_waiting_for_finish_proto >= 5)
 18915               x_dnd_action = event->xclient.data.l[2];
 18916 
 18917             if (x_dnd_waiting_for_finish_proto >= 5
 18918                 && !(event->xclient.data.l[1] & 1))
 18919               x_dnd_action = None;
 18920 
 18921             goto done;
 18922           }
 18923 
 18924         if ((event->xclient.message_type
 18925              == dpyinfo->Xatom_MOTIF_DRAG_AND_DROP_MESSAGE)
 18926             && x_dnd_waiting_for_finish
 18927             && x_dnd_waiting_for_motif_finish == 1
 18928             && dpyinfo == x_dnd_waiting_for_motif_finish_display)
 18929           {
 18930             xm_drop_start_reply reply;
 18931             uint16_t operation, status, action;
 18932 
 18933             if (!xm_read_drop_start_reply (event, &reply))
 18934               {
 18935                 operation = XM_DRAG_SIDE_EFFECT_OPERATION (reply.side_effects);
 18936                 status = XM_DRAG_SIDE_EFFECT_SITE_STATUS (reply.side_effects);
 18937                 action = XM_DRAG_SIDE_EFFECT_DROP_ACTION (reply.side_effects);
 18938 
 18939                 if (operation != XM_DRAG_MOVE
 18940                     && operation != XM_DRAG_COPY
 18941                     && XM_DRAG_OPERATION_IS_LINK (operation))
 18942                   {
 18943                     x_dnd_waiting_for_finish = false;
 18944                     goto done;
 18945                   }
 18946 
 18947                 if (status != XM_DROP_SITE_VALID
 18948                     || (action == XM_DROP_ACTION_DROP_CANCEL
 18949                         || action == XM_DROP_ACTION_DROP_HELP))
 18950                   {
 18951                     x_dnd_waiting_for_finish = false;
 18952                     goto done;
 18953                   }
 18954 
 18955                 switch (operation)
 18956                   {
 18957                   case XM_DRAG_MOVE:
 18958                     x_dnd_action_symbol = QXdndActionMove;
 18959                     break;
 18960 
 18961                   case XM_DRAG_COPY:
 18962                     x_dnd_action_symbol = QXdndActionCopy;
 18963                     break;
 18964 
 18965                     /* This means XM_DRAG_OPERATION_IS_LINK (operation).  */
 18966                   default:
 18967                     x_dnd_action_symbol = QXdndActionLink;
 18968                     break;
 18969                   }
 18970 
 18971                 x_dnd_waiting_for_motif_finish = 2;
 18972                 goto done;
 18973               }
 18974           }
 18975 
 18976         if (event->xclient.message_type == dpyinfo->Xatom_EMACS_TMP
 18977             && event->xclient.format == 8)
 18978           {
 18979             /* This is actually an hourglass message.  Set whether or
 18980                not events from here on have the hourglass enabled.  */
 18981 
 18982             if (any)
 18983               FRAME_X_OUTPUT (any)->hourglass_p = event->xclient.data.b[0];
 18984           }
 18985 
 18986         if (event->xclient.message_type == dpyinfo->Xatom_wm_protocols
 18987             && event->xclient.format == 32)
 18988           {
 18989             if (event->xclient.data.l[0] == dpyinfo->Xatom_wm_take_focus)
 18990               {
 18991                 /* Use the value returned by x_any_window_to_frame
 18992                    because this could be the shell widget window
 18993                    if the frame has no title bar.  */
 18994                 f = any;
 18995 #ifdef HAVE_X_I18N
 18996                 /* Not quite sure this is needed -pd */
 18997                 if (f && FRAME_XIC (f))
 18998                   XSetICFocus (FRAME_XIC (f));
 18999 #endif
 19000 #if false
 19001       /* Emacs sets WM hints whose `input' field is `true'.  This
 19002          instructs the WM to set the input focus automatically for
 19003          Emacs with a call to XSetInputFocus.  Setting WM_TAKE_FOCUS
 19004          tells the WM to send us a ClientMessage WM_TAKE_FOCUS after
 19005          it has set the focus.  So, XSetInputFocus below is not
 19006          needed.
 19007 
 19008          The call to XSetInputFocus below has also caused trouble.  In
 19009          cases where the XSetInputFocus done by the WM and the one
 19010          below are temporally close (on a fast machine), the call
 19011          below can generate additional FocusIn events which confuse
 19012          Emacs.  */
 19013 
 19014                 /* Since we set WM_TAKE_FOCUS, we must call
 19015                    XSetInputFocus explicitly.  But not if f is null,
 19016                    since that might be an event for a deleted frame.  */
 19017                 if (f)
 19018                   {
 19019                     Display *d = event->xclient.display;
 19020                     /* Catch and ignore errors, in case window has been
 19021                        iconified by a window manager such as GWM.  */
 19022                     x_catch_errors (d);
 19023                     XSetInputFocus (d, event->xclient.window,
 19024                                     /* The ICCCM says this is
 19025                                        the only valid choice.  */
 19026                                     RevertToParent,
 19027                                     event->xclient.data.l[1]);
 19028                     x_uncatch_errors ();
 19029                   }
 19030                 /* Not certain about handling scroll bars here */
 19031 #endif
 19032                 /* Set the provided time as the user time, which is
 19033                    required for SetInputFocus to work correctly after
 19034                    taking the input focus.  */
 19035 
 19036                 /* Time can be sign extended if retrieved from a client message.
 19037                    Make sure it is always 32 bits, or systems with 64-bit longs
 19038                    will crash after 24 days of X server uptime.  (bug#59480) */
 19039                 x_display_set_last_user_time (dpyinfo, (event->xclient.data.l[1]
 19040                                                         & 0xffffffff),
 19041                                               true, true);
 19042                 goto done;
 19043               }
 19044 
 19045             if (event->xclient.data.l[0] == dpyinfo->Xatom_wm_save_yourself)
 19046               {
 19047                 /* Save state modify the WM_COMMAND property to
 19048                    something which can reinstate us.  This notifies
 19049                    the session manager, who's looking for such a
 19050                    PropertyNotify.  Can restart processing when
 19051                    a keyboard or mouse event arrives.  */
 19052                 /* If we have a session manager, don't set this.
 19053                    KDE will then start two Emacsen, one for the
 19054                    session manager and one for this. */
 19055 #ifdef HAVE_X_SM
 19056                 if (! x_session_have_connection ())
 19057 #endif
 19058                   {
 19059                     f = x_top_window_to_frame (dpyinfo,
 19060                                                event->xclient.window);
 19061                     /* This is just so we only give real data once
 19062                        for a single Emacs process.  */
 19063                     if (f == SELECTED_FRAME ())
 19064                       XSetCommand (FRAME_X_DISPLAY (f),
 19065                                    event->xclient.window,
 19066                                    initial_argv, initial_argc);
 19067                     else if (f)
 19068                       XSetCommand (FRAME_X_DISPLAY (f),
 19069                                    event->xclient.window,
 19070                                    0, 0);
 19071                   }
 19072                 goto done;
 19073               }
 19074 
 19075             if (event->xclient.data.l[0] == dpyinfo->Xatom_wm_delete_window)
 19076               {
 19077                 f = x_top_window_to_frame (dpyinfo,
 19078                                            event->xclient.window);
 19079 
 19080                 if (!f)
 19081                   goto OTHER; /* May be a dialog that is to be removed  */
 19082 
 19083                 inev.ie.kind = DELETE_WINDOW_EVENT;
 19084                 inev.ie.timestamp = event->xclient.data.l[1];
 19085                 XSETFRAME (inev.ie.frame_or_window, f);
 19086                 goto done;
 19087               }
 19088 
 19089 
 19090             if (event->xclient.data.l[0] == dpyinfo->Xatom_net_wm_ping
 19091                 /* Handling window stacking changes during
 19092                    drag-and-drop requires Emacs to select for
 19093                    SubstructureNotifyMask, which in turn causes the
 19094                    message to be sent to Emacs itself using the event
 19095                    mask specified by the EWMH.  To avoid an infinite
 19096                    loop, make sure the client message's window is not
 19097                    the root window if DND is in progress.  */
 19098                 && (!(x_dnd_in_progress
 19099                       || x_dnd_waiting_for_finish)
 19100                     || event->xclient.window != dpyinfo->root_window)
 19101                 && event->xclient.format == 32)
 19102               {
 19103                 XEvent send_event = *event;
 19104 
 19105                 send_event.xclient.window = dpyinfo->root_window;
 19106                 XSendEvent (dpyinfo->display, dpyinfo->root_window, False,
 19107                             SubstructureRedirectMask | SubstructureNotifyMask,
 19108                             &send_event);
 19109 
 19110                 *finish = X_EVENT_DROP;
 19111                 goto done;
 19112               }
 19113 
 19114 #if defined HAVE_XSYNC
 19115             if (event->xclient.data.l[0] == dpyinfo->Xatom_net_wm_sync_request
 19116                 && event->xclient.format == 32
 19117                 && dpyinfo->xsync_supported_p)
 19118               {
 19119                 struct frame *f
 19120                   = x_top_window_to_frame (dpyinfo,
 19121                                            event->xclient.window);
 19122 #if defined HAVE_GTK3
 19123                 GtkWidget *widget;
 19124                 GdkWindow *window;
 19125                 GdkFrameClock *frame_clock;
 19126 #endif
 19127 
 19128                 if (f)
 19129                   {
 19130 #ifndef HAVE_GTK3
 19131                     if (event->xclient.data.l[4] == 0)
 19132                       {
 19133                         XSyncIntsToValue (&FRAME_X_OUTPUT (f)->pending_basic_counter_value,
 19134                                           event->xclient.data.l[2], event->xclient.data.l[3]);
 19135                         FRAME_X_OUTPUT (f)->sync_end_pending_p = true;
 19136                       }
 19137                     else if (event->xclient.data.l[4] == 1)
 19138                       {
 19139                         XSyncIntsToValue (&FRAME_X_OUTPUT (f)->resize_counter_value,
 19140                                           event->xclient.data.l[2],
 19141                                           event->xclient.data.l[3]);
 19142 
 19143                         FRAME_X_OUTPUT (f)->ext_sync_end_pending_p = true;
 19144                       }
 19145 
 19146                     *finish = X_EVENT_DROP;
 19147 #else
 19148                     widget = FRAME_GTK_OUTER_WIDGET (f);
 19149                     window = gtk_widget_get_window (widget);
 19150                     eassert (window);
 19151 
 19152                     /* This could be a (former) child frame for which
 19153                        frame synchronization was disabled.  Enable it
 19154                        now.  */
 19155                     gdk_x11_window_set_frame_sync_enabled (window, TRUE);
 19156 
 19157                     if (widget && !FRAME_X_OUTPUT (f)->xg_sync_end_pending_p)
 19158                       {
 19159                         frame_clock = gdk_window_get_frame_clock (window);
 19160                         eassert (frame_clock);
 19161 
 19162                         gdk_frame_clock_request_phase (frame_clock,
 19163                                                        GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT);
 19164                         FRAME_X_OUTPUT (f)->xg_sync_end_pending_p = true;
 19165                       }
 19166 #endif
 19167                     goto done;
 19168                   }
 19169               }
 19170 #endif
 19171 
 19172             goto done;
 19173           }
 19174 
 19175         if (event->xclient.message_type == dpyinfo->Xatom_wm_configure_denied)
 19176           goto done;
 19177 
 19178         if (event->xclient.message_type == dpyinfo->Xatom_wm_window_moved)
 19179           {
 19180             int new_x, new_y;
 19181             f = x_window_to_frame (dpyinfo, event->xclient.window);
 19182 
 19183             new_x = event->xclient.data.s[0];
 19184             new_y = event->xclient.data.s[1];
 19185 
 19186             if (f)
 19187               {
 19188                 f->left_pos = new_x;
 19189                 f->top_pos = new_y;
 19190               }
 19191             goto done;
 19192           }
 19193 
 19194 #ifdef X_TOOLKIT_EDITRES
 19195         if (event->xclient.message_type == dpyinfo->Xatom_editres)
 19196           {
 19197             f = any;
 19198             if (f)
 19199               {
 19200                 _XEditResCheckMessages (f->output_data.x->widget,
 19201                                         NULL, (XEvent *) event, NULL);
 19202                 goto done;
 19203               }
 19204 
 19205             goto OTHER;
 19206           }
 19207 #endif /* X_TOOLKIT_EDITRES */
 19208 
 19209         if (event->xclient.message_type == dpyinfo->Xatom_DONE
 19210             || event->xclient.message_type == dpyinfo->Xatom_PAGE)
 19211           {
 19212             /* Ghostview job completed.  Kill it.  We could
 19213                reply with "Next" if we received "Page", but we
 19214                currently never do because we are interested in
 19215                images, only, which should have 1 page.  */
 19216             f = x_window_to_frame (dpyinfo, event->xclient.window);
 19217             if (!f)
 19218               goto OTHER;
 19219 #ifndef USE_CAIRO
 19220             Pixmap pixmap = (Pixmap) event->xclient.data.l[1];
 19221             /* FIXME: why does this sometimes generate a BadMatch
 19222                error?  */
 19223             x_catch_errors (dpyinfo->display);
 19224             x_kill_gs_process (pixmap, f);
 19225             x_uncatch_errors ();
 19226             expose_frame (f, 0, 0, 0, 0);
 19227 #endif  /* !USE_CAIRO */
 19228             goto done;
 19229           }
 19230 
 19231 #ifdef USE_TOOLKIT_SCROLL_BARS
 19232         /* Scroll bar callbacks send a ClientMessage from which
 19233            we construct an input_event.  */
 19234         if (event->xclient.message_type == dpyinfo->Xatom_Scrollbar)
 19235           {
 19236             /* Convert the scroll bar event to an input event using
 19237                the first window entered into the scroll bar event
 19238                queue. */
 19239             x_scroll_bar_to_input_event (dpyinfo, event, &inev.ie);
 19240 
 19241             *finish = X_EVENT_GOTO_OUT;
 19242             goto done;
 19243           }
 19244         else if (event->xclient.message_type == dpyinfo->Xatom_Horizontal_Scrollbar)
 19245           {
 19246             /* Convert the horizontal scroll bar event to an input
 19247                event using the first window entered into the scroll
 19248                bar event queue. */
 19249             x_horizontal_scroll_bar_to_input_event (dpyinfo, event,
 19250                                                     &inev.ie);
 19251 
 19252             *finish = X_EVENT_GOTO_OUT;
 19253             goto done;
 19254           }
 19255 #endif /* USE_TOOLKIT_SCROLL_BARS */
 19256 
 19257         /* XEmbed messages from the embedder (if any).  */
 19258         if (event->xclient.message_type == dpyinfo->Xatom_XEMBED)
 19259           {
 19260             enum xembed_message msg = event->xclient.data.l[1];
 19261             if (msg == XEMBED_FOCUS_IN || msg == XEMBED_FOCUS_OUT)
 19262               x_detect_focus_change (dpyinfo, any, event, &inev.ie);
 19263 
 19264             *finish = X_EVENT_GOTO_OUT;
 19265             goto done;
 19266           }
 19267 
 19268 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
 19269         /* These messages are sent by the compositing manager after a
 19270            frame is drawn under extended synchronization.  */
 19271         if (event->xclient.message_type
 19272             == dpyinfo->Xatom_net_wm_frame_drawn)
 19273           {
 19274             if (any)
 19275               x_sync_handle_frame_drawn (dpyinfo, (XEvent *) event, any);
 19276 
 19277             goto done;
 19278           }
 19279 
 19280         if (event->xclient.message_type
 19281             == dpyinfo->Xatom_net_wm_frame_timings)
 19282           goto done;
 19283 #endif
 19284 
 19285         if (xft_settings_event (dpyinfo, event))
 19286           goto done;
 19287 
 19288         f = any;
 19289         /* We don't want to ever leak tooltip frames to Lisp code.  */
 19290         if (!f || FRAME_TOOLTIP_P (f))
 19291           goto OTHER;
 19292 
 19293         /* These values are always used initialized, but GCC doesn't
 19294            know that.  */
 19295         dx = 0;
 19296         dy = 0;
 19297 
 19298         rc = x_coords_from_dnd_message (dpyinfo, (XEvent *) event,
 19299                                         &dx, &dy);
 19300 
 19301         if (x_handle_dnd_message (f, &event->xclient, dpyinfo, &inev.ie,
 19302                                   rc, dx, dy))
 19303           *finish = X_EVENT_DROP;
 19304       }
 19305       break;
 19306 
 19307     case SelectionNotify:
 19308 #if defined USE_X_TOOLKIT || defined USE_GTK
 19309       if (!x_window_to_frame (dpyinfo, event->xselection.requestor))
 19310         goto OTHER;
 19311 #endif /* not USE_X_TOOLKIT and not USE_GTK */
 19312 #ifdef HAVE_GTK3
 19313       /* GTK 3 apparently chokes on these events since they have no
 19314          associated device.  (bug#56869, another bug as well that I
 19315          can't find) */
 19316       *finish = X_EVENT_DROP;
 19317 #endif
 19318       x_handle_selection_notify (&event->xselection);
 19319       break;
 19320 
 19321     case SelectionClear:        /* Someone has grabbed ownership.  */
 19322 #if defined USE_X_TOOLKIT || defined USE_GTK
 19323       if (!x_window_to_frame (dpyinfo, event->xselectionclear.window))
 19324         goto OTHER;
 19325 #endif /* not USE_X_TOOLKIT and not USE_GTK */
 19326 #ifdef HAVE_GTK3
 19327       *finish = X_EVENT_DROP;
 19328 #endif
 19329       {
 19330         const XSelectionClearEvent *eventp = &event->xselectionclear;
 19331 
 19332         if (eventp->selection == dpyinfo->motif_drag_atom
 19333             && (eventp->time == CurrentTime
 19334                 || dpyinfo->motif_drag_atom_time <= eventp->time))
 19335           dpyinfo->motif_drag_atom = None;
 19336 
 19337         inev.sie.kind = SELECTION_CLEAR_EVENT;
 19338         SELECTION_EVENT_DPYINFO (&inev.sie) = dpyinfo;
 19339         SELECTION_EVENT_SELECTION (&inev.sie) = eventp->selection;
 19340         SELECTION_EVENT_TIME (&inev.sie) = eventp->time;
 19341 
 19342         if (x_use_pending_selection_requests)
 19343           {
 19344             x_push_selection_request (&inev.sie);
 19345             EVENT_INIT (inev.ie);
 19346           }
 19347       }
 19348       break;
 19349 
 19350     case SelectionRequest:      /* Someone wants our selection.  */
 19351 #ifdef USE_X_TOOLKIT
 19352       if (!x_window_to_frame (dpyinfo, event->xselectionrequest.owner))
 19353         goto OTHER;
 19354 #endif /* USE_X_TOOLKIT */
 19355 #ifdef HAVE_GTK3
 19356       *finish = X_EVENT_DROP;
 19357 #endif
 19358       {
 19359         const XSelectionRequestEvent *eventp = &event->xselectionrequest;
 19360 
 19361         inev.sie.kind = SELECTION_REQUEST_EVENT;
 19362         SELECTION_EVENT_DPYINFO (&inev.sie) = dpyinfo;
 19363         SELECTION_EVENT_REQUESTOR (&inev.sie) = eventp->requestor;
 19364         SELECTION_EVENT_SELECTION (&inev.sie) = eventp->selection;
 19365         SELECTION_EVENT_TARGET (&inev.sie) = eventp->target;
 19366         SELECTION_EVENT_PROPERTY (&inev.sie) = eventp->property;
 19367         SELECTION_EVENT_TIME (&inev.sie) = eventp->time;
 19368 
 19369         /* If drag-and-drop or another modal dialog/menu is in
 19370            progress, handle SelectionRequest events immediately, by
 19371            pushing it onto the selection queue.  */
 19372 
 19373         if (x_use_pending_selection_requests)
 19374           {
 19375             x_push_selection_request (&inev.sie);
 19376             EVENT_INIT (inev.ie);
 19377           }
 19378 
 19379         if (x_dnd_waiting_for_finish
 19380             && x_dnd_waiting_for_motif_finish == 2
 19381             && dpyinfo == x_dnd_waiting_for_motif_finish_display
 19382             && eventp->selection == x_dnd_motif_atom
 19383             && (eventp->target == dpyinfo->Xatom_XmTRANSFER_SUCCESS
 19384                 || eventp->target == dpyinfo->Xatom_XmTRANSFER_FAILURE))
 19385           {
 19386             x_dnd_waiting_for_finish = false;
 19387 
 19388             /* If the transfer failed, then return nil from
 19389                `x-begin-drag'.  */
 19390             if (eventp->target == dpyinfo->Xatom_XmTRANSFER_FAILURE)
 19391               x_dnd_action = None;
 19392           }
 19393       }
 19394       break;
 19395 
 19396     case PropertyNotify:
 19397       if (x_dnd_in_progress && x_dnd_use_toplevels
 19398           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame)
 19399           && event->xproperty.atom == dpyinfo->Xatom_wm_state)
 19400         {
 19401           struct x_client_list_window *tem, *last;
 19402 
 19403           for (last = NULL, tem = x_dnd_toplevels; tem;
 19404                last = tem, tem = tem->next)
 19405             {
 19406               if (tem->window == event->xproperty.window)
 19407                 {
 19408                   Atom actual_type;
 19409                   int actual_format, rc;
 19410                   unsigned long nitems, bytesafter;
 19411                   unsigned char *data = NULL;
 19412 
 19413                   if (event->xproperty.state == PropertyDelete)
 19414                     {
 19415                       if (!last)
 19416                         x_dnd_toplevels = tem->next;
 19417                       else
 19418                         last->next = tem->next;
 19419 
 19420 #ifdef HAVE_XSHAPE
 19421                       if (tem->n_input_rects != -1)
 19422                         xfree (tem->input_rects);
 19423                       if (tem->n_bounding_rects != -1)
 19424                         xfree (tem->bounding_rects);
 19425 #endif
 19426                       xfree (tem);
 19427                     }
 19428                   else
 19429                     {
 19430                       x_catch_errors (dpyinfo->display);
 19431                       rc = XGetWindowProperty (dpyinfo->display,
 19432                                                event->xproperty.window,
 19433                                                dpyinfo->Xatom_wm_state,
 19434                                                0, 2, False, AnyPropertyType,
 19435                                                &actual_type, &actual_format,
 19436                                                &nitems, &bytesafter, &data);
 19437 
 19438                       if (!x_had_errors_p (dpyinfo->display) && rc == Success && data
 19439                           && nitems == 2 && actual_format == 32)
 19440                         tem->wm_state = ((unsigned long *) data)[0];
 19441                       else
 19442                         tem->wm_state = WithdrawnState;
 19443 
 19444                       if (data)
 19445                         XFree (data);
 19446                       x_uncatch_errors_after_check ();
 19447                     }
 19448 
 19449                   x_dnd_update_state (dpyinfo, event->xproperty.time);
 19450                   break;
 19451                 }
 19452             }
 19453         }
 19454 
 19455       f = x_top_window_to_frame (dpyinfo, event->xproperty.window);
 19456       if (f && event->xproperty.atom == dpyinfo->Xatom_net_wm_state
 19457           /* This should never happen with embedded windows.  */
 19458           && !FRAME_X_EMBEDDED_P (f))
 19459         {
 19460           bool not_hidden = x_handle_net_wm_state (f, &event->xproperty);
 19461 
 19462           if (not_hidden && FRAME_ICONIFIED_P (f))
 19463             {
 19464               if (CONSP (frame_size_history))
 19465                 frame_size_history_plain
 19466                   (f, build_string ("PropertyNotify, not hidden & iconified"));
 19467 
 19468               /* Gnome shell does not iconify us when C-z is pressed.
 19469                  It hides the frame.  So if our state says we aren't
 19470                  hidden anymore, treat it as deiconified.  */
 19471               SET_FRAME_VISIBLE (f, 1);
 19472               SET_FRAME_ICONIFIED (f, false);
 19473 
 19474               f->output_data.x->has_been_visible = true;
 19475               inev.ie.kind = DEICONIFY_EVENT;
 19476 #if defined USE_GTK && defined HAVE_GTK3
 19477               /* If GTK3 wants to impose some old size here (Bug#24526),
 19478                  tell it that the current size is what we want.  */
 19479               if (f->was_invisible)
 19480                 {
 19481                   xg_frame_set_char_size
 19482                     (f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
 19483                   f->was_invisible = false;
 19484                 }
 19485 #endif
 19486               XSETFRAME (inev.ie.frame_or_window, f);
 19487             }
 19488           else if (!not_hidden && !FRAME_ICONIFIED_P (f))
 19489             {
 19490               if (CONSP (frame_size_history))
 19491                 frame_size_history_plain
 19492                   (f, build_string ("PropertyNotify, hidden & not iconified"));
 19493 
 19494               SET_FRAME_VISIBLE (f, 0);
 19495               SET_FRAME_ICONIFIED (f, true);
 19496               inev.ie.kind = ICONIFY_EVENT;
 19497               XSETFRAME (inev.ie.frame_or_window, f);
 19498             }
 19499         }
 19500 
 19501       if (f && event->xproperty.atom == dpyinfo->Xatom_wm_state
 19502           && !FRAME_X_EMBEDDED_P (f) && !FRAME_PARENT_FRAME (f))
 19503         /* Handle WM_STATE.  We use this to clear the iconified flag
 19504            on a frame if it is set.
 19505 
 19506            GTK builds ignore deiconifying frames on FocusIn or Expose
 19507            by default, and cannot wait for the window manager to
 19508            remove _NET_WM_STATE_HIDDEN, as it is ambiguous when not
 19509            set.  Handling UnmapNotify also checks for
 19510            _NET_WM_STATE_HIDDEN, and thus suffers from the same
 19511            problem.  */
 19512         x_handle_wm_state (f, &inev.ie);
 19513 
 19514       if (f && FRAME_X_OUTPUT (f)->alpha_identical_p
 19515           && (event->xproperty.atom
 19516               == dpyinfo->Xatom_net_wm_window_opacity))
 19517         {
 19518 #ifndef USE_XCB
 19519           int rc, actual_format;
 19520           Atom actual;
 19521           unsigned char *tmp_data;
 19522           unsigned long n, left, opacity;
 19523 
 19524           tmp_data = NULL;
 19525 #else
 19526           xcb_get_property_cookie_t opacity_cookie;
 19527           xcb_get_property_reply_t *opacity_reply;
 19528           xcb_generic_error_t *error;
 19529           bool rc;
 19530           uint32_t value;
 19531 #endif
 19532 
 19533           if (event->xproperty.state == PropertyDelete)
 19534             {
 19535               f->alpha[0] = 1.0;
 19536               f->alpha[1] = 1.0;
 19537 
 19538               store_frame_param (f, Qalpha, Qnil);
 19539             }
 19540           else
 19541             {
 19542 #ifndef USE_XCB
 19543               rc = XGetWindowProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
 19544                                        dpyinfo->Xatom_net_wm_window_opacity,
 19545                                        0, 1, False, AnyPropertyType, &actual,
 19546                                        &actual_format, &n, &left, &tmp_data);
 19547 
 19548               if (rc == Success && actual_format == 32
 19549                   && (actual == XA_CARDINAL
 19550                       /* Some broken programs set the opacity property
 19551                          to those types, but window managers accept
 19552                          them anyway.  */
 19553                       || actual == XA_ATOM
 19554                       || actual == XA_WINDOW) && n)
 19555                 {
 19556                   opacity = *(unsigned long *) tmp_data & OPAQUE;
 19557                   f->alpha[0] = (double) opacity / (double) OPAQUE;
 19558                   f->alpha[1] = (double) opacity / (double) OPAQUE;
 19559 
 19560                   store_frame_param (f, Qalpha, make_float (f->alpha[0]));
 19561                 }
 19562               else
 19563                 {
 19564                   f->alpha[0] = 1.0;
 19565                   f->alpha[1] = 1.0;
 19566 
 19567                   store_frame_param (f, Qalpha, Qnil);
 19568                 }
 19569 #else
 19570               opacity_cookie
 19571                 = xcb_get_property (dpyinfo->xcb_connection, 0,
 19572                                     (xcb_window_t) FRAME_OUTER_WINDOW (f),
 19573                                     (xcb_atom_t) dpyinfo->Xatom_net_wm_window_opacity,
 19574                                     XA_CARDINAL, 0, 1);
 19575               opacity_reply
 19576                 = xcb_get_property_reply (dpyinfo->xcb_connection,
 19577                                           opacity_cookie, &error);
 19578 
 19579               if (!opacity_reply)
 19580                 free (error), rc = false;
 19581               else
 19582                 rc = (opacity_reply->format == 32
 19583                       && (opacity_reply->type == XA_CARDINAL
 19584                           || opacity_reply->type == XA_ATOM
 19585                           || opacity_reply->type == XA_WINDOW)
 19586                       && (xcb_get_property_value_length (opacity_reply) >= 4));
 19587 
 19588               if (rc)
 19589                 {
 19590                   value = *(uint32_t *) xcb_get_property_value (opacity_reply);
 19591 
 19592                   f->alpha[0] = (double) value / (double) OPAQUE;
 19593                   f->alpha[1] = (double) value / (double) OPAQUE;
 19594                   store_frame_param (f, Qalpha, make_float (f->alpha[0]));
 19595                 }
 19596               else
 19597                 {
 19598                   f->alpha[0] = 1.0;
 19599                   f->alpha[1] = 1.0;
 19600 
 19601                   store_frame_param (f, Qalpha, Qnil);
 19602                 }
 19603 
 19604               if (opacity_reply)
 19605                 free (opacity_reply);
 19606 #endif
 19607             }
 19608 
 19609 #ifndef USE_XCB
 19610           if (tmp_data)
 19611             XFree (tmp_data);
 19612 #endif
 19613         }
 19614 
 19615       if (event->xproperty.window == dpyinfo->root_window
 19616           && (event->xproperty.atom == dpyinfo->Xatom_net_client_list_stacking
 19617               || event->xproperty.atom == dpyinfo->Xatom_net_current_desktop)
 19618           && x_dnd_in_progress
 19619           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 19620         {
 19621           if (x_dnd_use_toplevels)
 19622             {
 19623               x_dnd_free_toplevels (true);
 19624 
 19625               if (x_dnd_compute_toplevels (dpyinfo))
 19626                 {
 19627                   x_dnd_free_toplevels (true);
 19628                   x_dnd_use_toplevels = false;
 19629                 }
 19630             }
 19631 
 19632           x_dnd_update_state (dpyinfo, event->xproperty.time);
 19633         }
 19634 
 19635       x_handle_property_notify (&event->xproperty);
 19636       xft_settings_event (dpyinfo, event);
 19637       goto OTHER;
 19638 
 19639     case ReparentNotify:
 19640       f = x_top_window_to_frame (dpyinfo, event->xreparent.window);
 19641       if (f)
 19642         {
 19643 #ifndef USE_GTK
 19644           if (FRAME_OUTPUT_DATA (f)->parent_desc
 19645               && FRAME_X_EMBEDDED_P (f))
 19646             {
 19647               /* The frame's embedder was destroyed; mark the frame as
 19648                  no longer embedded, and map the frame.  An
 19649                  UnmapNotify event must have previously been received
 19650                  during the start of save-set processing.  */
 19651 
 19652               FRAME_X_OUTPUT (f)->explicit_parent = false;
 19653 
 19654               /* Remove the leftover XEMBED_INFO property.  */
 19655               XDeleteProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
 19656                                dpyinfo->Xatom_XEMBED_INFO);
 19657               x_make_frame_visible (f);
 19658             }
 19659 #endif
 19660 
 19661           /* Maybe we shouldn't set this for child frames ??  */
 19662           f->output_data.x->parent_desc = event->xreparent.parent;
 19663 
 19664           if (!FRAME_PARENT_FRAME (f))
 19665             {
 19666               x_real_positions (f, &f->left_pos, &f->top_pos);
 19667 
 19668               /* Perhaps reparented due to a WM restart.  Reset this.  */
 19669               dpyinfo->wm_type = X_WMTYPE_UNKNOWN;
 19670               dpyinfo->net_supported_window = 0;
 19671 
 19672 #ifndef USE_GTK
 19673               /* The window manager could have restarted and the new
 19674                  window manager might not support user time windows,
 19675                  so update what is used accordingly.
 19676 
 19677                  Note that this doesn't handle changes between
 19678                  non-reparenting window managers.  */
 19679               if (FRAME_X_OUTPUT (f)->has_been_visible)
 19680                 x_update_frame_user_time_window (f);
 19681 #endif
 19682             }
 19683           else
 19684             {
 19685               Window root;
 19686               unsigned int dummy_uint;
 19687 
 19688               XGetGeometry (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 19689                             &root, &f->left_pos, &f->top_pos,
 19690                             &dummy_uint, &dummy_uint, &dummy_uint, &dummy_uint);
 19691             }
 19692 
 19693           x_set_frame_alpha (f);
 19694         }
 19695       goto OTHER;
 19696 
 19697     case Expose:
 19698 
 19699 #ifdef HAVE_XWIDGETS
 19700       {
 19701         struct xwidget_view *xv;
 19702 
 19703         xv = xwidget_view_from_window (event->xexpose.window);
 19704 
 19705         if (xv)
 19706           {
 19707             xwidget_expose (xv);
 19708             goto OTHER;
 19709           }
 19710       }
 19711 #endif
 19712 
 19713       f = x_window_to_frame (dpyinfo, event->xexpose.window);
 19714       if (f)
 19715         {
 19716           if (!FRAME_VISIBLE_P (f))
 19717             {
 19718               /* By default, do not set the frame's visibility here, see
 19719                  https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html.
 19720                  The default behavior can be overridden by setting
 19721                  'x-set-frame-visibility-more-laxly' (Bug#49955,
 19722                  Bug#53298).  */
 19723               if (EQ (x_set_frame_visibility_more_laxly, Qexpose)
 19724                   || EQ (x_set_frame_visibility_more_laxly, Qt))
 19725                 {
 19726                   SET_FRAME_VISIBLE (f, 1);
 19727                   SET_FRAME_ICONIFIED (f, false);
 19728                 }
 19729 
 19730 #ifdef HAVE_XDBE
 19731               if (FRAME_X_DOUBLE_BUFFERED_P (f))
 19732                 x_drop_xrender_surfaces (f);
 19733 #endif
 19734               f->output_data.x->has_been_visible = true;
 19735               SET_FRAME_GARBAGED (f);
 19736             }
 19737           else if (FRAME_GARBAGED_P (f))
 19738             {
 19739 #ifdef USE_GTK
 19740               /* Go around the back buffer and manually clear the
 19741                  window the first time we show it.  This way, we avoid
 19742                  showing users the sanity-defying horror of whatever
 19743                  GtkWindow is rendering beneath us.  We've garbaged
 19744                  the frame, so we'll redraw the whole thing on next
 19745                  redisplay anyway.  Yuck.  */
 19746               x_clear_area1 (FRAME_X_DISPLAY (f),
 19747                              FRAME_X_WINDOW (f),
 19748                              event->xexpose.x, event->xexpose.y,
 19749                              event->xexpose.width, event->xexpose.height,
 19750                              0);
 19751               x_clear_under_internal_border (f);
 19752 #endif
 19753             }
 19754 
 19755           if (!FRAME_GARBAGED_P (f))
 19756             {
 19757 #if defined USE_X_TOOLKIT && defined USE_TOOLKIT_SCROLL_BARS
 19758               if (f->output_data.x->edit_widget)
 19759                 /* The widget's expose proc will be run in this
 19760                    case.  */
 19761                 goto OTHER;
 19762 #endif
 19763 #ifdef USE_GTK
 19764               /* This seems to be needed for GTK 2.6 and later, see
 19765                  https://debbugs.gnu.org/cgi/bugreport.cgi?bug=15398.  */
 19766               x_clear_area (f,
 19767                             event->xexpose.x, event->xexpose.y,
 19768                             event->xexpose.width, event->xexpose.height);
 19769 #endif
 19770               expose_frame (f, event->xexpose.x, event->xexpose.y,
 19771                             event->xexpose.width, event->xexpose.height);
 19772 #ifndef USE_TOOLKIT_SCROLL_BARS
 19773               x_scroll_bar_handle_exposure (f, (XEvent *) event);
 19774 #endif
 19775 #ifdef USE_GTK
 19776               x_clear_under_internal_border (f);
 19777 #endif
 19778             }
 19779 #ifndef USE_TOOLKIT_SCROLL_BARS
 19780           else
 19781             x_scroll_bar_handle_exposure (f, (XEvent *) event);
 19782 #endif
 19783 
 19784 #ifdef HAVE_XDBE
 19785           if (!FRAME_GARBAGED_P (f))
 19786             show_back_buffer (f);
 19787 #endif
 19788         }
 19789       else
 19790         {
 19791 #if defined USE_LUCID
 19792           /* Submenus of the Lucid menu bar aren't widgets
 19793              themselves, so there's no way to dispatch events
 19794              to them.  Recognize this case separately.  */
 19795           {
 19796             Widget widget = x_window_to_menu_bar (event->xexpose.window);
 19797             if (widget)
 19798               xlwmenu_redisplay (widget);
 19799           }
 19800 #endif /* USE_LUCID */
 19801 
 19802           /* Dispatch event to the widget.  */
 19803           goto OTHER;
 19804         }
 19805       break;
 19806 
 19807     case GraphicsExpose:        /* This occurs when an XCopyArea's
 19808                                    source area was obscured or not
 19809                                    available.  */
 19810       f = x_window_to_frame (dpyinfo, event->xgraphicsexpose.drawable);
 19811       if (f)
 19812         {
 19813           expose_frame (f, event->xgraphicsexpose.x,
 19814                         event->xgraphicsexpose.y,
 19815                         event->xgraphicsexpose.width,
 19816                         event->xgraphicsexpose.height);
 19817 #ifndef USE_TOOLKIT_SCROLL_BARS
 19818           x_scroll_bar_handle_exposure (f, (XEvent *) event);
 19819 #endif
 19820 #ifdef USE_GTK
 19821           x_clear_under_internal_border (f);
 19822 #endif
 19823 #ifdef HAVE_XDBE
 19824           show_back_buffer (f);
 19825 #endif
 19826         }
 19827 #ifdef USE_X_TOOLKIT
 19828       else
 19829         goto OTHER;
 19830 #endif /* USE_X_TOOLKIT */
 19831       break;
 19832 
 19833     case NoExpose:              /* This occurs when an XCopyArea's
 19834                                    source area was completely
 19835                                    available.  */
 19836 #ifdef USE_X_TOOLKIT
 19837       *finish = X_EVENT_DROP;
 19838 #endif
 19839       break;
 19840 
 19841     case UnmapNotify:
 19842       if (x_dnd_in_progress && x_dnd_use_toplevels
 19843           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 19844         {
 19845           for (struct x_client_list_window *tem = x_dnd_toplevels; tem;
 19846                tem = tem->next)
 19847             {
 19848               if (tem->window == event->xunmap.window)
 19849                 {
 19850                   tem->mapped_p = false;
 19851                   break;
 19852                 }
 19853             }
 19854         }
 19855 
 19856       /* Redo the mouse-highlight after the tooltip has gone.  */
 19857       if (event->xunmap.window == tip_window)
 19858         {
 19859           tip_window = None;
 19860           gui_redo_mouse_highlight (dpyinfo);
 19861         }
 19862 
 19863       f = x_top_window_to_frame (dpyinfo, event->xunmap.window);
 19864       if (f)            /* F may no longer exist if
 19865                            the frame was deleted.  */
 19866         {
 19867           bool visible = FRAME_VISIBLE_P (f);
 19868 
 19869 #ifdef USE_LUCID
 19870           /* Bloodcurdling hack alert: The Lucid menu bar widget's
 19871              redisplay procedure is not called when a tip frame over
 19872              menu items is unmapped.  Redisplay the menu manually...  */
 19873           if (FRAME_TOOLTIP_P (f) && popup_activated ())
 19874             {
 19875               Widget w;
 19876               Lisp_Object tail, frame;
 19877               struct frame *f1;
 19878 
 19879               FOR_EACH_FRAME (tail, frame)
 19880                 {
 19881                   if (!FRAME_X_P (XFRAME (frame)))
 19882                     continue;
 19883 
 19884                   f1 = XFRAME (frame);
 19885 
 19886                   if (FRAME_LIVE_P (f1))
 19887                     {
 19888                       w = FRAME_X_OUTPUT (f1)->menubar_widget;
 19889 
 19890                       if (w && !DoesSaveUnders (FRAME_DISPLAY_INFO (f1)->screen))
 19891                         xlwmenu_redisplay (w);
 19892                     }
 19893                 }
 19894             }
 19895 #endif /* USE_LUCID */
 19896 
 19897           /* While a frame is unmapped, display generation is
 19898              disabled; you don't want to spend time updating a
 19899              display that won't ever be seen.  */
 19900           SET_FRAME_VISIBLE (f, 0);
 19901           /* We can't distinguish, from the event, whether the window
 19902              has become iconified or invisible.  So assume, if it
 19903              was previously visible, than now it is iconified.
 19904              But x_make_frame_invisible clears both
 19905              the visible flag and the iconified flag;
 19906              and that way, we know the window is not iconified now.  */
 19907           if (visible || FRAME_ICONIFIED_P (f))
 19908             {
 19909               if (CONSP (frame_size_history))
 19910                 frame_size_history_plain
 19911                   (f, build_string ("UnmapNotify, visible | iconified"));
 19912 
 19913               SET_FRAME_ICONIFIED (f, true);
 19914               inev.ie.kind = ICONIFY_EVENT;
 19915               XSETFRAME (inev.ie.frame_or_window, f);
 19916             }
 19917           else if (CONSP (frame_size_history))
 19918             frame_size_history_plain
 19919               (f, build_string ("UnmapNotify, not visible & not iconified"));
 19920         }
 19921       goto OTHER;
 19922 
 19923     case MapNotify:
 19924 #if defined HAVE_XINPUT2 && defined HAVE_GTK3
 19925       if (xg_is_menu_window (dpyinfo->display, event->xmap.window))
 19926         popup_activated_flag = 1;
 19927 #endif
 19928 
 19929       if (x_dnd_in_progress
 19930           /* When _NET_WM_CLIENT_LIST stacking is being used, changes
 19931              in that property are watched for, and it's not necessary
 19932              to update the state in response to ordinary window
 19933              substructure events.  */
 19934           && !x_dnd_use_toplevels
 19935           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 19936         x_dnd_update_state (dpyinfo, dpyinfo->last_user_time);
 19937 
 19938       if (x_dnd_in_progress && x_dnd_use_toplevels
 19939           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 19940         {
 19941           for (struct x_client_list_window *tem = x_dnd_toplevels; tem;
 19942                tem = tem->next)
 19943             {
 19944               if (tem->window == event->xmap.window)
 19945                 {
 19946                   tem->mapped_p = true;
 19947                   break;
 19948                 }
 19949             }
 19950         }
 19951 
 19952       /* We use x_top_window_to_frame because map events can
 19953          come for sub-windows and they don't mean that the
 19954          frame is visible.  */
 19955       f = x_top_window_to_frame (dpyinfo, event->xmap.window);
 19956       if (f)
 19957         {
 19958           bool iconified = FRAME_ICONIFIED_P (f);
 19959           int value;
 19960           bool sticky, shaded;
 19961           bool not_hidden = x_get_current_wm_state (f, event->xmap.window, &value, &sticky,
 19962                                                     &shaded);
 19963 
 19964           if (CONSP (frame_size_history))
 19965             frame_size_history_extra
 19966               (f,
 19967                iconified
 19968                ? (not_hidden
 19969                   ? build_string ("MapNotify, not hidden & iconified")
 19970                   : build_string ("MapNotify, hidden & iconified"))
 19971                : (not_hidden
 19972                   ? build_string ("MapNotify, not hidden & not iconified")
 19973                   : build_string ("MapNotify, hidden & not iconified")),
 19974                FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
 19975                -1, -1, f->new_width, f->new_height);
 19976 
 19977           /* Check if fullscreen was specified before we where mapped the
 19978              first time, i.e. from the command line.  */
 19979           if (!f->output_data.x->has_been_visible)
 19980             {
 19981 
 19982               x_check_fullscreen (f);
 19983 #ifndef USE_GTK
 19984               /* For systems that cannot synthesize `skip_taskbar' for
 19985                  unmapped windows do the following.  */
 19986               if (FRAME_SKIP_TASKBAR (f))
 19987                 x_set_skip_taskbar (f, Qt, Qnil);
 19988 #endif /* Not USE_GTK */
 19989             }
 19990 
 19991           if (!iconified)
 19992             {
 19993               /* The `z-group' is reset every time a frame becomes
 19994                  invisible.  Handle this here.  */
 19995               if (FRAME_Z_GROUP (f) == z_group_above)
 19996                 x_set_z_group (f, Qabove, Qnil);
 19997               else if (FRAME_Z_GROUP (f) == z_group_below)
 19998                 x_set_z_group (f, Qbelow, Qnil);
 19999             }
 20000 
 20001           /* Embedded frames might have NET_WM_STATE left over, but
 20002              are always visible once mapped.  */
 20003           if (not_hidden || FRAME_X_EMBEDDED_P (f))
 20004             {
 20005               SET_FRAME_VISIBLE (f, 1);
 20006               SET_FRAME_ICONIFIED (f, false);
 20007 #if defined USE_GTK && defined HAVE_GTK3
 20008               /* If GTK3 wants to impose some old size here (Bug#24526),
 20009                  tell it that the current size is what we want.  */
 20010               if (f->was_invisible)
 20011                 {
 20012                   xg_frame_set_char_size
 20013                     (f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
 20014                   f->was_invisible = false;
 20015                 }
 20016 #endif
 20017               f->output_data.x->has_been_visible = true;
 20018             }
 20019 
 20020           x_update_opaque_region (f, NULL);
 20021 
 20022           if ((not_hidden || FRAME_X_EMBEDDED_P (f)) && iconified)
 20023             {
 20024               inev.ie.kind = DEICONIFY_EVENT;
 20025               XSETFRAME (inev.ie.frame_or_window, f);
 20026             }
 20027         }
 20028       goto OTHER;
 20029 
 20030     case KeyPress:
 20031       x_display_set_last_user_time (dpyinfo, event->xkey.time,
 20032                                     event->xkey.send_event,
 20033                                     true);
 20034       ignore_next_mouse_click_timeout = 0;
 20035 
 20036       coding = Qlatin_1;
 20037 
 20038 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
 20039       /* Dispatch KeyPress events when in menu.  */
 20040       if (popup_activated ())
 20041         goto OTHER;
 20042 #endif
 20043 
 20044       f = any;
 20045 
 20046 #ifdef USE_GTK
 20047       if (f)
 20048         x_set_gtk_user_time (f, event->xkey.time);
 20049 #endif
 20050 
 20051       /* If mouse-highlight is an integer, input clears out
 20052          mouse highlighting.  */
 20053       if (!hlinfo->mouse_face_hidden && FIXNUMP (Vmouse_highlight)
 20054           && (f == 0
 20055 #if ! defined (USE_GTK)
 20056               || !EQ (f->tool_bar_window, hlinfo->mouse_face_window)
 20057 #endif
 20058               || !EQ (f->tab_bar_window, hlinfo->mouse_face_window))
 20059           )
 20060         {
 20061           mouse_frame = hlinfo->mouse_face_mouse_frame;
 20062 
 20063           clear_mouse_face (hlinfo);
 20064           hlinfo->mouse_face_hidden = true;
 20065 
 20066           if (mouse_frame)
 20067             x_flush_dirty_back_buffer_on (mouse_frame);
 20068         }
 20069 
 20070 #if defined USE_MOTIF && defined USE_TOOLKIT_SCROLL_BARS
 20071       if (f == 0)
 20072         {
 20073           /* Scroll bars consume key events, but we want
 20074              the keys to go to the scroll bar's frame.  */
 20075           Widget widget = XtWindowToWidget (dpyinfo->display,
 20076                                             event->xkey.window);
 20077           if (widget && XmIsScrollBar (widget))
 20078             {
 20079               widget = XtParent (widget);
 20080               f = x_any_window_to_frame (dpyinfo, XtWindow (widget));
 20081             }
 20082         }
 20083 #endif /* USE_MOTIF and USE_TOOLKIT_SCROLL_BARS */
 20084 
 20085       if (f != 0)
 20086         {
 20087           KeySym keysym, orig_keysym;
 20088           /* al%imercury@uunet.uu.net says that making this 81
 20089              instead of 80 fixed a bug whereby meta chars made
 20090              his Emacs hang.
 20091 
 20092              It seems that some version of XmbLookupString has
 20093              a bug of not returning XBufferOverflow in
 20094              status_return even if the input is too long to
 20095              fit in 81 bytes.  So, we must prepare sufficient
 20096              bytes for copy_buffer.  513 bytes (256 chars for
 20097              two-byte character set) seems to be a fairly good
 20098              approximation.  -- 2000.8.10 handa@gnu.org  */
 20099           unsigned char copy_buffer[513];
 20100           unsigned char *copy_bufptr = copy_buffer;
 20101           int copy_bufsiz = sizeof (copy_buffer);
 20102           int modifiers;
 20103           Lisp_Object c;
 20104           /* `xkey' will be modified, but it's not important to modify
 20105              `event' itself.  */
 20106           XKeyEvent xkey = event->xkey;
 20107 
 20108           if (event->xkey.window == FRAME_X_WINDOW (f))
 20109             /* See the comment above x_compute_root_window_offset for
 20110                why this optimization is performed.  */
 20111             x_compute_root_window_offset (f, event->xkey.x_root,
 20112                                           event->xkey.y_root,
 20113                                           event->xkey.x, event->xkey.y);
 20114 
 20115 #ifdef HAVE_XINPUT2
 20116           Time pending_keystroke_time;
 20117           struct xi_device_t *source;
 20118 
 20119           pending_keystroke_time = dpyinfo->pending_keystroke_time;
 20120 
 20121           if (event->xkey.time >= pending_keystroke_time)
 20122             {
 20123 #if defined USE_GTK && !defined HAVE_GTK3
 20124               if (!dpyinfo->pending_keystroke_time_special_p)
 20125 #endif
 20126                 dpyinfo->pending_keystroke_time = 0;
 20127 #if defined USE_GTK && !defined HAVE_GTK3
 20128               else
 20129                 dpyinfo->pending_keystroke_time_special_p = false;
 20130 #endif
 20131             }
 20132 #endif
 20133 
 20134 #ifdef USE_GTK
 20135           /* Don't pass keys to GTK.  A Tab will shift focus to the
 20136              tool bar in GTK 2.4.  Keys will still go to menus and
 20137              dialogs because in that case popup_activated is nonzero
 20138              (see above).  */
 20139           *finish = X_EVENT_DROP;
 20140 #endif
 20141 
 20142           xkey.state |= x_emacs_to_x_modifiers (dpyinfo,
 20143                                                 extra_keyboard_modifiers);
 20144           modifiers = xkey.state;
 20145 
 20146           /* This will have to go some day...  */
 20147 
 20148           /* make_lispy_event turns chars into control chars.
 20149              Don't do it here because XLookupString is too eager.  */
 20150           xkey.state &= ~ControlMask;
 20151           xkey.state &= ~(dpyinfo->meta_mod_mask
 20152                           | dpyinfo->super_mod_mask
 20153                           | dpyinfo->hyper_mod_mask
 20154                           | dpyinfo->alt_mod_mask);
 20155 
 20156           /* In case Meta is ComposeCharacter,
 20157              clear its status.  According to Markus Ehrnsperger
 20158              Markus.Ehrnsperger@lehrstuhl-bross.physik.uni-muenchen.de
 20159              this enables ComposeCharacter to work whether or
 20160              not it is combined with Meta.  */
 20161           if (modifiers & dpyinfo->meta_mod_mask)
 20162             memset (&compose_status, 0, sizeof (compose_status));
 20163 
 20164 #ifdef HAVE_X_I18N
 20165           if (FRAME_XIC (f))
 20166             {
 20167               Status status_return;
 20168 
 20169               nbytes = XmbLookupString (FRAME_XIC (f),
 20170                                         &xkey, (char *) copy_bufptr,
 20171                                         copy_bufsiz, &keysym,
 20172                                         &status_return);
 20173               coding = FRAME_X_XIM_CODING (f);
 20174               if (status_return == XBufferOverflow)
 20175                 {
 20176                   copy_bufsiz = nbytes + 1;
 20177                   copy_bufptr = SAFE_ALLOCA (copy_bufsiz);
 20178                   nbytes = XmbLookupString (FRAME_XIC (f),
 20179                                             &xkey, (char *) copy_bufptr,
 20180                                             copy_bufsiz, &keysym,
 20181                                             &status_return);
 20182                 }
 20183               /* Xutf8LookupString is a new but already deprecated interface.  -stef  */
 20184               if (status_return == XLookupNone)
 20185                 break;
 20186               else if (status_return == XLookupChars)
 20187                 {
 20188                   keysym = NoSymbol;
 20189                   modifiers = 0;
 20190                 }
 20191               else if (status_return != XLookupKeySym
 20192                        && status_return != XLookupBoth)
 20193                 emacs_abort ();
 20194             }
 20195           else
 20196 #endif
 20197             {
 20198 #ifdef HAVE_XKB
 20199               int overflow;
 20200               unsigned int consumed;
 20201               KeySym sym;
 20202 
 20203               if (dpyinfo->xkb_desc)
 20204                 {
 20205                   /* Translate the keycode into the keysym it
 20206                      represents, using STATE.  CONSUMED is set to the
 20207                      modifier bits consumed while undertaking this
 20208                      translation and should be subsequently ignored
 20209                      during keysym translation.  */
 20210 
 20211                   if (!XkbTranslateKeyCode (dpyinfo->xkb_desc,
 20212                                             xkey.keycode, xkey.state,
 20213                                             &consumed, &keysym))
 20214                     goto done_keysym;
 20215 
 20216                   /* Save the original keysym in case
 20217                      XkbTranslateKeysym overflows.  */
 20218                   sym = keysym, overflow = 0;
 20219 
 20220                   nbytes = XkbTranslateKeySym (dpyinfo->display, &keysym,
 20221                                                xkey.state & ~consumed,
 20222                                                (char *) copy_bufptr,
 20223                                                copy_bufsiz, &overflow);
 20224 
 20225                   if (overflow)
 20226                     {
 20227                       copy_bufptr = SAFE_ALLOCA ((copy_bufsiz += overflow)
 20228                                                  * sizeof *copy_bufptr);
 20229                       overflow = 0;
 20230 
 20231                       /* Use the original keysym derived from the
 20232                          keycode translation in this second call to
 20233                          XkbTranslateKeysym.  */
 20234                       nbytes = XkbTranslateKeySym (dpyinfo->display, &sym,
 20235                                                    xkey.state & ~consumed,
 20236                                                    (char *) copy_bufptr,
 20237                                                    copy_bufsiz, &overflow);
 20238 
 20239                       if (overflow)
 20240                         nbytes = 0;
 20241                     }
 20242 
 20243                   if (nbytes)
 20244                     coding = Qnil;
 20245                 }
 20246               else
 20247 #endif
 20248                 nbytes = XLookupString (&xkey, (char *) copy_bufptr,
 20249                                         copy_bufsiz, &keysym,
 20250                                         &compose_status);
 20251             }
 20252 
 20253 #ifdef XK_F1
 20254           if (x_dnd_in_progress && keysym == XK_F1)
 20255             {
 20256               x_dnd_xm_use_help = true;
 20257               goto done_keysym;
 20258             }
 20259 #endif
 20260 
 20261           /* See if keysym should make Emacs quit.  */
 20262 
 20263           if (keysym == dpyinfo->quit_keysym
 20264               && (xkey.time - dpyinfo->quit_keysym_time
 20265                   <= 350))
 20266             {
 20267               Vquit_flag = Qt;
 20268               goto done_keysym;
 20269             }
 20270 
 20271           if (keysym == dpyinfo->quit_keysym)
 20272             {
 20273               /* Otherwise, set the last time that keysym was
 20274                  pressed.  */
 20275               dpyinfo->quit_keysym_time = xkey.time;
 20276               goto done_keysym;
 20277             }
 20278 
 20279           /* If not using XIM/XIC, and a compose sequence is in progress,
 20280              we break here.  Otherwise, chars_matched is always 0.  */
 20281           if (compose_status.chars_matched > 0 && nbytes == 0)
 20282             break;
 20283 
 20284           memset (&compose_status, 0, sizeof (compose_status));
 20285           orig_keysym = keysym;
 20286 
 20287           /* Common for all keysym input events.  */
 20288           XSETFRAME (inev.ie.frame_or_window, f);
 20289           inev.ie.modifiers
 20290             = x_x_to_emacs_modifiers (dpyinfo, modifiers);
 20291           inev.ie.timestamp = xkey.time;
 20292 
 20293           /* First deal with keysyms which have defined
 20294              translations to characters.  */
 20295           if (keysym >= 32 && keysym < 128)
 20296             /* Avoid explicitly decoding each ASCII character.  */
 20297             {
 20298               inev.ie.kind = ASCII_KEYSTROKE_EVENT;
 20299               inev.ie.code = keysym;
 20300 
 20301 #ifdef HAVE_XINPUT2
 20302               if (event->xkey.time == pending_keystroke_time)
 20303                 {
 20304                   source = xi_device_from_id (dpyinfo,
 20305                                               dpyinfo->pending_keystroke_source);
 20306 
 20307                   if (source)
 20308                     inev.ie.device = source->name;
 20309                 }
 20310 #endif
 20311 
 20312               goto done_keysym;
 20313             }
 20314 
 20315           /* Keysyms directly mapped to Unicode characters.  */
 20316           if (keysym >= 0x01000000 && keysym <= 0x0110FFFF)
 20317             {
 20318               if (keysym < 0x01000080)
 20319                 inev.ie.kind = ASCII_KEYSTROKE_EVENT;
 20320               else
 20321                 inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
 20322               inev.ie.code = keysym & 0xFFFFFF;
 20323 
 20324 #ifdef HAVE_XINPUT2
 20325               if (event->xkey.time == pending_keystroke_time)
 20326                 {
 20327                   source = xi_device_from_id (dpyinfo,
 20328                                               dpyinfo->pending_keystroke_source);
 20329 
 20330                   if (source)
 20331                     inev.ie.device = source->name;
 20332                 }
 20333 #endif
 20334 
 20335               goto done_keysym;
 20336             }
 20337 
 20338           /* Now non-ASCII.  */
 20339           if (HASH_TABLE_P (Vx_keysym_table)
 20340               && (c = Fgethash (make_fixnum (keysym),
 20341                                 Vx_keysym_table,
 20342                                 Qnil),
 20343                   FIXNATP (c)))
 20344             {
 20345               inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFIXNAT (c))
 20346                               ? ASCII_KEYSTROKE_EVENT
 20347                               : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
 20348               inev.ie.code = XFIXNAT (c);
 20349 
 20350 #ifdef HAVE_XINPUT2
 20351               if (event->xkey.time == pending_keystroke_time)
 20352                 {
 20353                   source = xi_device_from_id (dpyinfo,
 20354                                               dpyinfo->pending_keystroke_source);
 20355 
 20356                   if (source)
 20357                     inev.ie.device = source->name;
 20358                 }
 20359 #endif
 20360 
 20361               goto done_keysym;
 20362             }
 20363 
 20364           /* Random non-modifier sorts of keysyms.  */
 20365           if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
 20366                || keysym == XK_Delete
 20367 #ifdef XK_ISO_Left_Tab
 20368                || (keysym >= XK_ISO_Left_Tab
 20369                    && keysym <= XK_ISO_Enter)
 20370 #endif
 20371                || IsCursorKey (keysym) /* 0xff50 <= x < 0xff60 */
 20372                || IsMiscFunctionKey (keysym) /* 0xff60 <= x < VARIES */
 20373 #ifdef HPUX
 20374                /* This recognizes the "extended function
 20375                   keys".  It seems there's no cleaner way.
 20376                   Test IsModifierKey to avoid handling
 20377                   mode_switch incorrectly.  */
 20378                || (XK_Select <= keysym && keysym < XK_KP_Space)
 20379 #endif
 20380 #ifdef XK_dead_circumflex
 20381                || orig_keysym == XK_dead_circumflex
 20382 #endif
 20383 #ifdef XK_dead_grave
 20384                || orig_keysym == XK_dead_grave
 20385 #endif
 20386 #ifdef XK_dead_tilde
 20387                || orig_keysym == XK_dead_tilde
 20388 #endif
 20389 #ifdef XK_dead_diaeresis
 20390                || orig_keysym == XK_dead_diaeresis
 20391 #endif
 20392 #ifdef XK_dead_macron
 20393                || orig_keysym == XK_dead_macron
 20394 #endif
 20395 #ifdef XK_dead_degree
 20396                || orig_keysym == XK_dead_degree
 20397 #endif
 20398 #ifdef XK_dead_acute
 20399                || orig_keysym == XK_dead_acute
 20400 #endif
 20401 #ifdef XK_dead_cedilla
 20402                || orig_keysym == XK_dead_cedilla
 20403 #endif
 20404 #ifdef XK_dead_breve
 20405                || orig_keysym == XK_dead_breve
 20406 #endif
 20407 #ifdef XK_dead_ogonek
 20408                || orig_keysym == XK_dead_ogonek
 20409 #endif
 20410 #ifdef XK_dead_caron
 20411                || orig_keysym == XK_dead_caron
 20412 #endif
 20413 #ifdef XK_dead_doubleacute
 20414                || orig_keysym == XK_dead_doubleacute
 20415 #endif
 20416 #ifdef XK_dead_abovedot
 20417                || orig_keysym == XK_dead_abovedot
 20418 #endif
 20419 #ifdef XK_dead_abovering
 20420                || orig_keysym == XK_dead_abovering
 20421 #endif
 20422 #ifdef XK_dead_belowdot
 20423                || orig_keysym == XK_dead_belowdot
 20424 #endif
 20425 #ifdef XK_dead_voiced_sound
 20426                || orig_keysym == XK_dead_voiced_sound
 20427 #endif
 20428 #ifdef XK_dead_semivoiced_sound
 20429                || orig_keysym == XK_dead_semivoiced_sound
 20430 #endif
 20431 #ifdef XK_dead_hook
 20432                || orig_keysym == XK_dead_hook
 20433 #endif
 20434 #ifdef XK_dead_horn
 20435                || orig_keysym == XK_dead_horn
 20436 #endif
 20437 #ifdef XK_dead_stroke
 20438                || orig_keysym == XK_dead_stroke
 20439 #endif
 20440 #ifdef XK_dead_abovecomma
 20441                || orig_keysym == XK_dead_abovecomma
 20442 #endif
 20443                || IsKeypadKey (keysym) /* 0xff80 <= x < 0xffbe */
 20444                || IsFunctionKey (keysym) /* 0xffbe <= x < 0xffe1 */
 20445                /* Any "vendor-specific" key is ok.  */
 20446                || (orig_keysym & (1 << 28))
 20447                || (keysym != NoSymbol && nbytes == 0))
 20448               && ! (IsModifierKey (orig_keysym)
 20449                     /* The symbols from XK_ISO_Lock
 20450                        to XK_ISO_Last_Group_Lock
 20451                        don't have real modifiers but
 20452                        should be treated similarly to
 20453                        Mode_switch by Emacs. */
 20454 #if defined XK_ISO_Lock && defined XK_ISO_Last_Group_Lock
 20455                     || (XK_ISO_Lock <= orig_keysym
 20456                         && orig_keysym <= XK_ISO_Last_Group_Lock)
 20457 #endif
 20458                     ))
 20459             {
 20460               STORE_KEYSYM_FOR_DEBUG (keysym);
 20461               /* make_lispy_event will convert this to a symbolic
 20462                  key.  */
 20463               inev.ie.kind = NON_ASCII_KEYSTROKE_EVENT;
 20464               inev.ie.code = keysym;
 20465 
 20466 #ifdef HAVE_XINPUT2
 20467               if (event->xkey.time == pending_keystroke_time)
 20468                 {
 20469                   source = xi_device_from_id (dpyinfo,
 20470                                               dpyinfo->pending_keystroke_source);
 20471 
 20472                   if (source)
 20473                     inev.ie.device = source->name;
 20474                 }
 20475 #endif
 20476 
 20477               goto done_keysym;
 20478             }
 20479 
 20480           {     /* Raw bytes, not keysym.  */
 20481             ptrdiff_t i;
 20482 
 20483             for (i = 0; i < nbytes; i++)
 20484               {
 20485                 STORE_KEYSYM_FOR_DEBUG (copy_bufptr[i]);
 20486               }
 20487 
 20488             if (nbytes)
 20489               {
 20490                 inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
 20491                 inev.ie.arg = make_unibyte_string ((char *) copy_bufptr, nbytes);
 20492 
 20493                 Fput_text_property (make_fixnum (0), make_fixnum (nbytes),
 20494                                     Qcoding, coding, inev.ie.arg);
 20495 
 20496 #ifdef HAVE_XINPUT2
 20497                 if (event->xkey.time == pending_keystroke_time
 20498                     /* I-Bus sometimes sends events generated from
 20499                        multiple filtered keystrokes with a time of 0,
 20500                        so just use the recorded source device if it
 20501                        exists.  */
 20502                     || (pending_keystroke_time && !event->xkey.time))
 20503                   {
 20504                     source = xi_device_from_id (dpyinfo,
 20505                                                 dpyinfo->pending_keystroke_source);
 20506 
 20507                     if (source)
 20508                       inev.ie.device = source->name;
 20509                   }
 20510 #endif
 20511               }
 20512 
 20513             if (keysym == NoSymbol)
 20514               break;
 20515           }
 20516         }
 20517     done_keysym:
 20518 #ifdef HAVE_X_I18N
 20519       if (f)
 20520         {
 20521           struct window *w = XWINDOW (f->selected_window);
 20522           xic_set_preeditarea (w, w->cursor.x, w->cursor.y);
 20523 
 20524           if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea))
 20525             xic_set_statusarea (f);
 20526         }
 20527 
 20528       /* Don't dispatch this event since XtDispatchEvent calls
 20529          XFilterEvent, and two calls in a row may freeze the
 20530          client.  */
 20531       break;
 20532 #else
 20533       goto OTHER;
 20534 #endif
 20535 
 20536     case KeyRelease:
 20537 #ifdef HAVE_X_I18N
 20538       /* Don't dispatch this event since XtDispatchEvent calls
 20539          XFilterEvent, and two calls in a row may freeze the
 20540          client.  */
 20541       break;
 20542 #else
 20543       goto OTHER;
 20544 #endif
 20545 
 20546     case EnterNotify:
 20547       x_display_set_last_user_time (dpyinfo, event->xcrossing.time,
 20548                                     event->xcrossing.send_event,
 20549                                     false);
 20550 
 20551 #ifdef HAVE_XWIDGETS
 20552       {
 20553         struct xwidget_view *xvw;
 20554         Mouse_HLInfo *hlinfo;
 20555 
 20556         xvw = xwidget_view_from_window (event->xcrossing.window);
 20557 
 20558         if (xvw)
 20559           {
 20560             xwidget_motion_or_crossing (xvw, event);
 20561             hlinfo = MOUSE_HL_INFO (xvw->frame);
 20562 
 20563             if (xvw->frame == hlinfo->mouse_face_mouse_frame)
 20564               {
 20565                 clear_mouse_face (hlinfo);
 20566                 hlinfo->mouse_face_mouse_frame = 0;
 20567                 x_flush_dirty_back_buffer_on (xvw->frame);
 20568               }
 20569 
 20570             if (any_help_event_p)
 20571               do_help = -1;
 20572 
 20573             goto OTHER;
 20574           }
 20575       }
 20576 #endif
 20577 
 20578 #ifdef HAVE_XINPUT2
 20579       /* For whatever reason, the X server continues to deliver
 20580          EnterNotify and LeaveNotify events despite us selecting for
 20581          related XI_Enter and XI_Leave events.  It's not just our
 20582          problem, since windows created by "xinput test-xi2" suffer
 20583          from the same defect.  Simply ignore all such events while
 20584          the input extension is enabled.  (bug#57468) */
 20585 
 20586       if (dpyinfo->supports_xi2)
 20587         goto OTHER;
 20588 #endif
 20589 
 20590       if (x_top_window_to_frame (dpyinfo, event->xcrossing.window))
 20591         x_detect_focus_change (dpyinfo, any, event, &inev.ie);
 20592 
 20593       f = any;
 20594 
 20595       if (f && event->xcrossing.window == FRAME_X_WINDOW (f))
 20596         x_compute_root_window_offset (f, event->xcrossing.x_root,
 20597                                       event->xcrossing.y_root,
 20598                                       event->xcrossing.x,
 20599                                       event->xcrossing.y);
 20600 
 20601       /* The code below relies on the first several fields of
 20602          XCrossingEvent being laid out the same way as
 20603          XMotionEvent.  */
 20604 
 20605       if (f && x_mouse_click_focus_ignore_position)
 20606         {
 20607           ignore_next_mouse_click_timeout = (event->xmotion.time
 20608                                              + x_mouse_click_focus_ignore_time);
 20609           mouse_click_timeout_display = dpyinfo;
 20610         }
 20611 
 20612       /* EnterNotify counts as mouse movement,
 20613          so update things that depend on mouse position.  */
 20614       if (f && !f->output_data.x->hourglass_p)
 20615         x_note_mouse_movement (f, &event->xmotion, Qnil);
 20616 #ifdef USE_GTK
 20617       /* We may get an EnterNotify on the buttons in the toolbar.  In that
 20618          case we moved out of any highlighted area and need to note this.  */
 20619       if (!f && dpyinfo->last_mouse_glyph_frame)
 20620         x_note_mouse_movement (dpyinfo->last_mouse_glyph_frame, &event->xmotion,
 20621                                Qnil);
 20622 #endif
 20623       goto OTHER;
 20624 
 20625     case FocusIn:
 20626 #if defined HAVE_XINPUT2                                                \
 20627   && (defined HAVE_GTK3 || (!defined USE_GTK && !defined USE_X_TOOLKIT))
 20628       /* If a FocusIn event is received (because the window manager
 20629          sent us one), don't set the core focus if XInput 2 is
 20630          enabled, since that would mess up the device-specific focus
 20631          tracking.
 20632 
 20633          The long looking preprocessor conditional only enables this
 20634          code on GTK 3 and no toolkit builds, since those are the only
 20635          builds where focus is tracked specific to each master device.
 20636          Other builds use core events and the client pointer to handle
 20637          focus, much like on a build without XInput 2.  */
 20638       if (dpyinfo->supports_xi2)
 20639         goto OTHER;
 20640 #endif
 20641 #ifdef USE_GTK
 20642       /* Some WMs (e.g. Mutter in Gnome Shell), don't unmap
 20643          minimized/iconified windows; thus, for those WMs we won't get
 20644          a MapNotify when unminimizing/deiconifying.  Check here if we
 20645          are deiconizing a window (Bug42655).
 20646 
 20647          But don't do that by default on GTK since it may cause a plain
 20648          invisible frame get reported as iconified, compare
 20649          https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html.
 20650          That is fixed above but bites us here again.
 20651 
 20652          The option x_set_frame_visibility_more_laxly allows to override
 20653          the default behavior (Bug#49955, Bug#53298).  */
 20654       if (EQ (x_set_frame_visibility_more_laxly, Qfocus_in)
 20655           || EQ (x_set_frame_visibility_more_laxly, Qt))
 20656 #endif /* USE_GTK */
 20657         {
 20658           f = any;
 20659           if (f && FRAME_ICONIFIED_P (f))
 20660             {
 20661               SET_FRAME_VISIBLE (f, 1);
 20662               SET_FRAME_ICONIFIED (f, false);
 20663               f->output_data.x->has_been_visible = true;
 20664               inev.ie.kind = DEICONIFY_EVENT;
 20665               XSETFRAME (inev.ie.frame_or_window, f);
 20666             }
 20667         }
 20668 
 20669       x_detect_focus_change (dpyinfo, any, event, &inev.ie);
 20670       goto OTHER;
 20671 
 20672     case LeaveNotify:
 20673       x_display_set_last_user_time (dpyinfo, event->xcrossing.time,
 20674                                     event->xcrossing.send_event, false);
 20675 
 20676 #ifdef HAVE_XINPUT2
 20677       /* For whatever reason, the X server continues to deliver
 20678          EnterNotify and LeaveNotify events despite us selecting for
 20679          related XI_Enter and XI_Leave events.  It's not just our
 20680          problem, since windows created by "xinput test-xi2" suffer
 20681          from the same defect.  Simply ignore all such events while
 20682          the input extension is enabled.  (bug#57468) */
 20683 
 20684       if (dpyinfo->supports_xi2)
 20685         {
 20686 #if !defined USE_X_TOOLKIT && (!defined USE_GTK || defined HAVE_GTK3)
 20687           goto OTHER;
 20688 #else
 20689           /* Unfortunately, X toolkit popups generate LeaveNotify
 20690              events due to the core grabs they acquire (and our
 20691              releasing of the device grab).  This leads to the mouse
 20692              face persisting if a popup is activated by clicking on a
 20693              button, and then dismissed by releasing the mouse button
 20694              outside the frame, in which case no XI_Enter event is
 20695              generated for the grab.  */
 20696           goto just_clear_mouse_face;
 20697 #endif
 20698         }
 20699 #endif
 20700 
 20701 #ifdef HAVE_XWIDGETS
 20702       {
 20703         struct xwidget_view *xvw;
 20704 
 20705         xvw = xwidget_view_from_window (event->xcrossing.window);
 20706 
 20707         if (xvw)
 20708           {
 20709             xwidget_motion_or_crossing (xvw, event);
 20710             goto OTHER;
 20711           }
 20712       }
 20713 #endif
 20714 
 20715       if (x_top_window_to_frame (dpyinfo, event->xcrossing.window))
 20716         x_detect_focus_change (dpyinfo, any, event, &inev.ie);
 20717 
 20718 #if defined HAVE_XINPUT2                                                \
 20719   && (defined USE_X_TOOLKIT || (defined USE_GTK && !defined HAVE_GTK3))
 20720     just_clear_mouse_face:
 20721 #endif
 20722 
 20723 #if defined USE_X_TOOLKIT
 20724       /* If the mouse leaves the edit widget, then any mouse highlight
 20725          should be cleared.  */
 20726       f = x_window_to_frame (dpyinfo, event->xcrossing.window);
 20727 
 20728       if (!f)
 20729         f = x_top_window_to_frame (dpyinfo, event->xcrossing.window);
 20730 #else
 20731       f = x_top_window_to_frame (dpyinfo, event->xcrossing.window);
 20732 #endif
 20733 
 20734       if (f)
 20735         {
 20736           /* Now clear dpyinfo->last_mouse_motion_frame, or
 20737              gui_redo_mouse_highlight will end up highlighting the
 20738              last known position of the mouse if a tooltip frame is
 20739              later unmapped.  */
 20740 
 20741           if (f == dpyinfo->last_mouse_motion_frame)
 20742             dpyinfo->last_mouse_motion_frame = NULL;
 20743 
 20744           /* Something similar applies to
 20745              dpyinfo->last_mouse_glyph_frame.  */
 20746           if (f == dpyinfo->last_mouse_glyph_frame)
 20747             dpyinfo->last_mouse_glyph_frame = NULL;
 20748 
 20749           if (f == hlinfo->mouse_face_mouse_frame)
 20750             {
 20751               /* If we move outside the frame, then we're
 20752                  certainly no longer on any text in the frame.  */
 20753               clear_mouse_face (hlinfo);
 20754               hlinfo->mouse_face_mouse_frame = 0;
 20755               x_flush_dirty_back_buffer_on (f);
 20756             }
 20757 
 20758           /* Generate a nil HELP_EVENT to cancel a help-echo.
 20759              Do it only if there's something to cancel.
 20760              Otherwise, the startup message is cleared when
 20761              the mouse leaves the frame.  */
 20762           if (any_help_event_p
 20763               /* But never if `mouse-drag-and-drop-region' is in
 20764                  progress, since that results in the tooltip being
 20765                  dismissed when the mouse moves on top.  */
 20766               && !((EQ (track_mouse, Qdrag_source)
 20767                     || EQ (track_mouse, Qdropping))
 20768                    && gui_mouse_grabbed (dpyinfo)))
 20769             do_help = -1;
 20770 
 20771           if (event->xcrossing.window == FRAME_X_WINDOW (f))
 20772             x_compute_root_window_offset (f, event->xcrossing.x_root,
 20773                                           event->xcrossing.y_root,
 20774                                           event->xcrossing.x,
 20775                                           event->xcrossing.y);
 20776 
 20777         }
 20778 #ifdef USE_GTK
 20779       /* See comment in EnterNotify above */
 20780       else if (dpyinfo->last_mouse_glyph_frame)
 20781         x_note_mouse_movement (dpyinfo->last_mouse_glyph_frame,
 20782                                &event->xmotion, Qnil);
 20783 #endif
 20784       goto OTHER;
 20785 
 20786     case FocusOut:
 20787 #if defined HAVE_XINPUT2                                                \
 20788   && (defined HAVE_GTK3 || (!defined USE_GTK && !defined USE_X_TOOLKIT))
 20789       /* If a FocusIn event is received (because the window manager
 20790          sent us one), don't set the core focus if XInput 2 is
 20791          enabled, since that would mess up the device-specific focus
 20792          tracking.
 20793 
 20794          The long looking preprocessor conditional only enables this
 20795          code on GTK 3 and no toolkit builds, since those are the only
 20796          builds where focus is tracked specific to each master device.
 20797          Other builds use core events and the client pointer to handle
 20798          focus, much like on a build without XInput 2.  */
 20799       if (dpyinfo->supports_xi2)
 20800         goto OTHER;
 20801 #endif
 20802       x_detect_focus_change (dpyinfo, any, event, &inev.ie);
 20803       goto OTHER;
 20804 
 20805     case MotionNotify:
 20806       {
 20807         XMotionEvent xmotion = event->xmotion;
 20808 
 20809         previous_help_echo_string = help_echo_string;
 20810         help_echo_string = Qnil;
 20811 
 20812         if (hlinfo->mouse_face_hidden)
 20813           {
 20814             hlinfo->mouse_face_hidden = false;
 20815             clear_mouse_face (hlinfo);
 20816           }
 20817 
 20818         f = mouse_or_wdesc_frame (dpyinfo, event->xmotion.window);
 20819 
 20820         if (f && event->xmotion.window == FRAME_X_WINDOW (f))
 20821           /* See the comment above x_compute_root_window_offset for
 20822              why this optimization is performed.  */
 20823           x_compute_root_window_offset (f, event->xmotion.x_root,
 20824                                         event->xmotion.y_root,
 20825                                         event->xmotion.x,
 20826                                         event->xmotion.y);
 20827 
 20828         if (x_dnd_in_progress
 20829             /* Handle these events normally if the recursion
 20830                level is higher than when the drag-and-drop
 20831                operation was initiated.  This is so that mouse
 20832                input works while we're in the debugger for, say,
 20833                `x-dnd-movement-function`.  */
 20834             && (command_loop_level + minibuf_level
 20835                 <= x_dnd_recursion_depth)
 20836             && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 20837           {
 20838             Window target, toplevel;
 20839             int target_proto, motif_style;
 20840             xm_top_level_leave_message lmsg;
 20841             xm_top_level_enter_message emsg;
 20842             xm_drag_motion_message dmsg;
 20843             XRectangle *r;
 20844             bool was_frame;
 20845 
 20846             /* Always clear mouse face.  */
 20847             clear_mouse_face (hlinfo);
 20848             hlinfo->mouse_face_hidden = true;
 20849 
 20850             /* Sometimes the drag-and-drop operation starts with the
 20851                pointer of a frame invisible due to input.  Since
 20852                motion events are ignored during that, make the pointer
 20853                visible manually.  */
 20854 
 20855             if (f)
 20856               {
 20857                 XTtoggle_invisible_pointer (f, false);
 20858 
 20859                 r = &dpyinfo->last_mouse_glyph;
 20860 
 20861                 /* Also remember the mouse glyph and set
 20862                    mouse_moved.  */
 20863                 if (f != dpyinfo->last_mouse_glyph_frame
 20864                     || event->xmotion.x < r->x
 20865                     || event->xmotion.x >= r->x + r->width
 20866                     || event->xmotion.y < r->y
 20867                     || event->xmotion.y >= r->y + r->height)
 20868                   {
 20869                     f->mouse_moved = true;
 20870                     f->last_mouse_device = Qnil;
 20871                     dpyinfo->last_mouse_scroll_bar = NULL;
 20872 
 20873                     remember_mouse_glyph (f, event->xmotion.x,
 20874                                           event->xmotion.y, r);
 20875                     dpyinfo->last_mouse_glyph_frame = f;
 20876                   }
 20877               }
 20878 
 20879             if (event->xmotion.same_screen)
 20880               target = x_dnd_get_target_window (dpyinfo,
 20881                                                 event->xmotion.x_root,
 20882                                                 event->xmotion.y_root,
 20883                                                 &target_proto,
 20884                                                 &motif_style, &toplevel,
 20885                                                 &was_frame);
 20886             else
 20887               target = x_dnd_fill_empty_target (&target_proto, &motif_style,
 20888                                                 &toplevel, &was_frame);
 20889 
 20890             if (toplevel != x_dnd_last_seen_toplevel)
 20891               {
 20892                 if (toplevel != FRAME_OUTER_WINDOW (x_dnd_frame)
 20893                     && x_dnd_return_frame == 1)
 20894                   x_dnd_return_frame = 2;
 20895 
 20896                 if (x_dnd_return_frame == 2
 20897                     && x_any_window_to_frame (dpyinfo, toplevel))
 20898                   {
 20899                     if (x_dnd_last_seen_window != None
 20900                         && x_dnd_last_protocol_version != -1
 20901                         && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 20902                       x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window,
 20903                                         x_dnd_last_seen_toplevel);
 20904                     else if (x_dnd_last_seen_window != None
 20905                              && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)
 20906                              && !x_dnd_disable_motif_drag
 20907                              && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 20908                       {
 20909                         if (!x_dnd_motif_setup_p)
 20910                           xm_setup_drag_info (dpyinfo, x_dnd_frame);
 20911 
 20912                         lmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 20913                                                       XM_DRAG_REASON_TOP_LEVEL_LEAVE);
 20914                         lmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 20915                         lmsg.zero = 0;
 20916                         lmsg.timestamp = event->xmotion.time;
 20917                         lmsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 20918 
 20919                         if (x_dnd_motif_setup_p)
 20920                           xm_send_top_level_leave_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 20921                                                            x_dnd_last_seen_window, &lmsg);
 20922                       }
 20923 
 20924                     x_dnd_end_window = x_dnd_last_seen_window;
 20925                     x_dnd_last_seen_window = None;
 20926                     x_dnd_last_seen_toplevel = None;
 20927                     x_dnd_in_progress = false;
 20928                     x_dnd_return_frame_object
 20929                       = x_any_window_to_frame (dpyinfo, toplevel);
 20930                     x_dnd_return_frame = 3;
 20931                     x_dnd_waiting_for_finish = false;
 20932                     target = None;
 20933                   }
 20934               }
 20935 
 20936             if (target != x_dnd_last_seen_window)
 20937               {
 20938                 if (x_dnd_last_seen_window != None
 20939                     && x_dnd_last_protocol_version != -1
 20940                     && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 20941                   x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window,
 20942                                     x_dnd_last_seen_toplevel);
 20943                 else if (x_dnd_last_seen_window != None
 20944                          && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)
 20945                          && x_dnd_disable_motif_drag
 20946                          && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 20947                   {
 20948                     if (!x_dnd_motif_setup_p)
 20949                       xm_setup_drag_info (dpyinfo, x_dnd_frame);
 20950 
 20951                     /* This is apparently required.  If we don't send
 20952                        a motion event with the current root window
 20953                        coordinates of the pointer before the top level
 20954                        leave, then Motif displays an ugly black border
 20955                        around the previous drop site.  */
 20956 
 20957                     dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 20958                                                   XM_DRAG_REASON_DRAG_MOTION);
 20959                     dmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 20960                     dmsg.side_effects = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo,
 20961                                                                                          x_dnd_wanted_action),
 20962                                                              XM_DROP_SITE_NONE, x_dnd_motif_operations,
 20963                                                              XM_DROP_ACTION_DROP_CANCEL);
 20964                     dmsg.timestamp = event->xmotion.time;
 20965                     dmsg.x = event->xmotion.x_root;
 20966                     dmsg.y = event->xmotion.y_root;
 20967 
 20968                     lmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 20969                                                   XM_DRAG_REASON_TOP_LEVEL_LEAVE);
 20970                     lmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 20971                     lmsg.zero = 0;
 20972                     lmsg.timestamp = event->xbutton.time;
 20973                     lmsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 20974 
 20975                     if (x_dnd_motif_setup_p)
 20976                       {
 20977                         xm_send_drag_motion_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 20978                                                      x_dnd_last_seen_window, &dmsg);
 20979                         xm_send_top_level_leave_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 20980                                                          x_dnd_last_seen_window, &lmsg);
 20981                       }
 20982                   }
 20983 
 20984                 x_dnd_action = None;
 20985                 x_dnd_last_seen_toplevel = toplevel;
 20986                 x_dnd_last_seen_window = target;
 20987                 x_dnd_last_protocol_version = target_proto;
 20988                 x_dnd_last_motif_style = motif_style;
 20989                 x_dnd_last_window_is_frame = was_frame;
 20990 
 20991                 if (target != None && x_dnd_last_protocol_version != -1)
 20992                   x_dnd_send_enter (x_dnd_frame, target,
 20993                                     x_dnd_last_seen_toplevel,
 20994                                     x_dnd_last_protocol_version);
 20995                 else if (target != None && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)
 20996                          && !x_dnd_disable_motif_drag)
 20997                   {
 20998                     if (!x_dnd_motif_setup_p)
 20999                       xm_setup_drag_info (dpyinfo, x_dnd_frame);
 21000 
 21001                     emsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 21002                                                   XM_DRAG_REASON_TOP_LEVEL_ENTER);
 21003                     emsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 21004                     emsg.zero = 0;
 21005                     emsg.timestamp = event->xbutton.time;
 21006                     emsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 21007                     emsg.index_atom = x_dnd_motif_atom;
 21008 
 21009                     if (x_dnd_motif_setup_p)
 21010                       xm_send_top_level_enter_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 21011                                                        target, &emsg);
 21012                   }
 21013               }
 21014             else
 21015               x_dnd_last_seen_toplevel = toplevel;
 21016 
 21017             if (x_dnd_last_window_is_frame && target != None)
 21018               x_dnd_note_self_position (dpyinfo, target,
 21019                                         event->xbutton.x_root,
 21020                                         event->xbutton.y_root);
 21021             else if (x_dnd_last_protocol_version != -1 && target != None)
 21022               x_dnd_send_position (x_dnd_frame, target,
 21023                                    x_dnd_last_seen_toplevel,
 21024                                    x_dnd_last_protocol_version,
 21025                                    event->xmotion.x_root,
 21026                                    event->xmotion.y_root,
 21027                                    x_dnd_selection_timestamp,
 21028                                    x_dnd_wanted_action, 0,
 21029                                    event->xmotion.state);
 21030             else if (XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) && target != None
 21031                      && !x_dnd_disable_motif_drag)
 21032               {
 21033                 if (!x_dnd_motif_setup_p)
 21034                   xm_setup_drag_info (dpyinfo, x_dnd_frame);
 21035 
 21036                 dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 21037                                               XM_DRAG_REASON_DRAG_MOTION);
 21038                 dmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 21039                 dmsg.side_effects = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo,
 21040                                                                                      x_dnd_wanted_action),
 21041                                                          XM_DROP_SITE_VALID, x_dnd_motif_operations,
 21042                                                          (!x_dnd_xm_use_help
 21043                                                           ? XM_DROP_ACTION_DROP
 21044                                                           : XM_DROP_ACTION_DROP_HELP));
 21045                 dmsg.timestamp = event->xbutton.time;
 21046                 dmsg.x = event->xmotion.x_root;
 21047                 dmsg.y = event->xmotion.y_root;
 21048 
 21049                 if (x_dnd_motif_setup_p)
 21050                   xm_send_drag_motion_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 21051                                                target, &dmsg);
 21052               }
 21053 
 21054             x_dnd_update_tooltip_position (event->xmotion.x_root,
 21055                                            event->xmotion.y_root);
 21056 
 21057             goto OTHER;
 21058           }
 21059 
 21060 #ifdef USE_GTK
 21061         if (f && xg_event_is_for_scrollbar (f, event, false))
 21062           f = 0;
 21063 #endif
 21064 #ifdef HAVE_XWIDGETS
 21065         struct xwidget_view *xvw;
 21066 
 21067         xvw = xwidget_view_from_window (event->xmotion.window);
 21068 
 21069         if (xvw)
 21070           xwidget_motion_or_crossing (xvw, event);
 21071 #endif
 21072         if (f)
 21073           {
 21074             /* Maybe generate a SELECT_WINDOW_EVENT for
 21075                `mouse-autoselect-window' but don't let popup menus
 21076                interfere with this (Bug#1261).  */
 21077             if (!NILP (Vmouse_autoselect_window)
 21078                 && !popup_activated ()
 21079                 /* Don't switch if we're currently in the minibuffer.
 21080                    This tries to work around problems where the
 21081                    minibuffer gets unselected unexpectedly, and where
 21082                    you then have to move your mouse all the way down to
 21083                    the minibuffer to select it.  */
 21084                 && !MINI_WINDOW_P (XWINDOW (selected_window))
 21085                 /* With `focus-follows-mouse' non-nil create an event
 21086                    also when the target window is on another frame.  */
 21087                 && (f == XFRAME (selected_frame)
 21088                     || !NILP (focus_follows_mouse)))
 21089               {
 21090                 static Lisp_Object last_mouse_window;
 21091 
 21092                 if (xmotion.window != FRAME_X_WINDOW (f))
 21093                   {
 21094                     x_translate_coordinates (f, xmotion.x_root, xmotion.y_root,
 21095                                              &xmotion.x, &xmotion.y);
 21096                     xmotion.window = FRAME_X_WINDOW (f);
 21097                   }
 21098 
 21099                 Lisp_Object window = window_from_coordinates
 21100                   (f, xmotion.x, xmotion.y, 0, false, false);
 21101 
 21102                 /* A window will be autoselected only when it is not
 21103                    selected now and the last mouse movement event was
 21104                    not in it.  The remainder of the code is a bit vague
 21105                    wrt what a "window" is.  For immediate autoselection,
 21106                    the window is usually the entire window but for GTK
 21107                    where the scroll bars don't count.  For delayed
 21108                    autoselection the window is usually the window's text
 21109                    area including the margins.  */
 21110                 if (WINDOWP (window)
 21111                     && !EQ (window, last_mouse_window)
 21112                     && !EQ (window, selected_window))
 21113                   {
 21114                     inev.ie.kind = SELECT_WINDOW_EVENT;
 21115                     inev.ie.frame_or_window = window;
 21116                   }
 21117 
 21118                 /* Remember the last window where we saw the mouse.  */
 21119                 last_mouse_window = window;
 21120               }
 21121 
 21122             if (!x_note_mouse_movement (f, &xmotion, Qnil))
 21123               help_echo_string = previous_help_echo_string;
 21124           }
 21125         else
 21126           {
 21127 #ifndef USE_TOOLKIT_SCROLL_BARS
 21128             struct scroll_bar *bar
 21129               = x_window_to_scroll_bar (event->xmotion.display,
 21130                                         event->xmotion.window, 2);
 21131 
 21132             if (bar)
 21133               x_scroll_bar_note_movement (bar, &event->xmotion);
 21134 #endif /* USE_TOOLKIT_SCROLL_BARS */
 21135 
 21136             /* If we move outside the frame, then we're
 21137                certainly no longer on any text in the frame.  */
 21138             clear_mouse_face (hlinfo);
 21139           }
 21140 
 21141         /* If the contents of the global variable help_echo_string
 21142            has changed, generate a HELP_EVENT.  */
 21143         if (!NILP (help_echo_string)
 21144             || !NILP (previous_help_echo_string))
 21145           do_help = 1;
 21146 
 21147         if (f)
 21148           x_flush_dirty_back_buffer_on (f);
 21149         goto OTHER;
 21150       }
 21151 
 21152     case ConfigureNotify:
 21153       /* An opaque move can generate a stream of events as the window
 21154          is dragged around.  If the connection round trip time isn't
 21155          really short, they may come faster than we can respond to
 21156          them, given the multiple queries we can do to check window
 21157          manager state, translate coordinates, etc.
 21158 
 21159          So if this ConfigureNotify is immediately followed by another
 21160          for the same window, use the info from the latest update, and
 21161          consider the events all handled.  */
 21162 
 21163       /* Opaque resize may be trickier; ConfigureNotify events are
 21164          mixed with Expose events for multiple windows.  */
 21165       configureEvent = *event;
 21166       while (XPending (dpyinfo->display))
 21167         {
 21168           XNextEvent (dpyinfo->display, &next_event);
 21169           if (next_event.type != ConfigureNotify
 21170               || next_event.xconfigure.window != event->xconfigure.window
 21171               /* Skipping events with different sizes can lead to a
 21172                  mispositioned mode line at initial window creation.
 21173                  Only drop window motion events for now.  */
 21174               || next_event.xconfigure.width != event->xconfigure.width
 21175               || next_event.xconfigure.height != event->xconfigure.height)
 21176             {
 21177               XPutBackEvent (dpyinfo->display, &next_event);
 21178               break;
 21179             }
 21180           else
 21181             configureEvent = next_event;
 21182         }
 21183 
 21184       /* If we get a ConfigureNotify for the root window, this means
 21185          the dimensions of the screen it's on changed.  */
 21186 
 21187       if (configureEvent.xconfigure.window == dpyinfo->root_window)
 21188         {
 21189 #ifdef HAVE_XRANDR
 21190           /* This function is OK to call even if the X server doesn't
 21191              support RandR.  */
 21192           XRRUpdateConfiguration (&configureEvent);
 21193 #elif !defined USE_GTK
 21194           /* Catch screen size changes even if RandR is not available
 21195              on the client.  GTK does this internally.  */
 21196 
 21197           if (configureEvent.xconfigure.width != dpyinfo->screen_width
 21198               || configureEvent.xconfigure.height != dpyinfo->screen_height)
 21199             {
 21200               /* Also avoid storing duplicate events here, since
 21201                  Fx_display_monitor_attributes_list will return the
 21202                  same information for both invocations of the
 21203                  hook.  */
 21204               if (!x_find_monitors_changed_event (dpyinfo))
 21205                 {
 21206                   inev.ie.kind = MONITORS_CHANGED_EVENT;
 21207                   XSETTERMINAL (inev.ie.arg, dpyinfo->terminal);
 21208 
 21209                   /* Store this event now since inev.ie.type could be set to
 21210                      MOVE_FRAME_EVENT later.  */
 21211                   kbd_buffer_store_event (&inev.ie);
 21212                   inev.ie.kind = NO_EVENT;
 21213                 }
 21214 
 21215               /* Also update the position of the drag-and-drop
 21216                  tooltip.  */
 21217               x_dnd_update_tooltip_now ();
 21218             }
 21219 #endif
 21220 
 21221           dpyinfo->screen_width = configureEvent.xconfigure.width;
 21222           dpyinfo->screen_height = configureEvent.xconfigure.height;
 21223         }
 21224 
 21225       if (x_dnd_in_progress && x_dnd_use_toplevels
 21226           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 21227         {
 21228           int rc, dest_x, dest_y;
 21229           Window child;
 21230           struct x_client_list_window *tem, *last = NULL;
 21231 
 21232           for (tem = x_dnd_toplevels; tem; last = tem, tem = tem->next)
 21233             {
 21234               /* Not completely right, since the parent could be
 21235                  unmapped, but good enough.  */
 21236 
 21237               if (tem->window == configureEvent.xconfigure.window)
 21238                 {
 21239                   x_catch_errors (dpyinfo->display);
 21240                   rc = (XTranslateCoordinates (dpyinfo->display,
 21241                                                configureEvent.xconfigure.window,
 21242                                                dpyinfo->root_window,
 21243                                                -configureEvent.xconfigure.border_width,
 21244                                                -configureEvent.xconfigure.border_width,
 21245                                                &dest_x, &dest_y, &child)
 21246                         && !x_had_errors_p (dpyinfo->display));
 21247                   x_uncatch_errors_after_check ();
 21248 
 21249                   if (rc)
 21250                     {
 21251                       tem->x = dest_x;
 21252                       tem->y = dest_y;
 21253                       tem->width = (configureEvent.xconfigure.width
 21254                                     + configureEvent.xconfigure.border_width);
 21255                       tem->height = (configureEvent.xconfigure.height
 21256                                      + configureEvent.xconfigure.border_width);
 21257                     }
 21258                   else
 21259                     {
 21260                       /* The window was probably destroyed, so get rid
 21261                          of it.  */
 21262 
 21263                       if (!last)
 21264                         x_dnd_toplevels = tem->next;
 21265                       else
 21266                         last->next = tem->next;
 21267 
 21268 #ifdef HAVE_XSHAPE
 21269                       if (tem->n_input_rects != -1)
 21270                         xfree (tem->input_rects);
 21271                       if (tem->n_bounding_rects != -1)
 21272                         xfree (tem->bounding_rects);
 21273 #endif
 21274                       xfree (tem);
 21275                     }
 21276 
 21277                   break;
 21278                 }
 21279             }
 21280         }
 21281 
 21282 #if defined HAVE_GTK3 && defined USE_TOOLKIT_SCROLL_BARS
 21283           struct scroll_bar *bar = x_window_to_scroll_bar (dpyinfo->display,
 21284                                                            configureEvent.xconfigure.window, 2);
 21285 
 21286           /* There is really no other way to make GTK scroll bars fit
 21287              in the dimensions we want them to.  */
 21288           if (bar)
 21289             {
 21290               /* Skip all the pending configure events, not just the
 21291                  ones where window motion occurred.  */
 21292               while (XPending (dpyinfo->display))
 21293                 {
 21294                   XNextEvent (dpyinfo->display, &next_event);
 21295                   if (next_event.type != ConfigureNotify
 21296                       || next_event.xconfigure.window != event->xconfigure.window)
 21297                     {
 21298                       XPutBackEvent (dpyinfo->display, &next_event);
 21299                       break;
 21300                     }
 21301                   else
 21302                     configureEvent = next_event;
 21303                 }
 21304 
 21305               if (configureEvent.xconfigure.width != max (bar->width, 1)
 21306                   || configureEvent.xconfigure.height != max (bar->height, 1))
 21307                 {
 21308                   XResizeWindow (dpyinfo->display, bar->x_window,
 21309                                  max (bar->width, 1), max (bar->height, 1));
 21310                   x_flush (WINDOW_XFRAME (XWINDOW (bar->window)));
 21311                 }
 21312 
 21313 #ifdef HAVE_XDBE
 21314               if (f && FRAME_X_DOUBLE_BUFFERED_P (f))
 21315                 x_drop_xrender_surfaces (f);
 21316 #endif
 21317 
 21318               goto OTHER;
 21319             }
 21320 #endif
 21321 
 21322       f = x_top_window_to_frame (dpyinfo, configureEvent.xconfigure.window);
 21323 
 21324       /* This means we can no longer be certain of the root window
 21325          coordinates of any's edit window.  */
 21326       if (any)
 21327         FRAME_X_OUTPUT (any)->window_offset_certain_p = false;
 21328 
 21329       /* Unfortunately, we need to call x_drop_xrender_surfaces for
 21330          _all_ ConfigureNotify events, otherwise we miss some and
 21331          flicker.  Don't try to optimize these calls by looking only
 21332          for size changes: that's not sufficient.  We miss some
 21333          surface invalidations and flicker.  */
 21334 #ifdef HAVE_XDBE
 21335       if (f && FRAME_X_DOUBLE_BUFFERED_P (f))
 21336         x_drop_xrender_surfaces (f);
 21337 #endif
 21338 #if defined USE_CAIRO && !defined USE_GTK
 21339       if (f)
 21340         x_cr_update_surface_desired_size (f, configureEvent.xconfigure.width,
 21341                                           configureEvent.xconfigure.height);
 21342       else if (any && configureEvent.xconfigure.window == FRAME_X_WINDOW (any))
 21343         x_cr_update_surface_desired_size (any,
 21344                                           configureEvent.xconfigure.width,
 21345                                           configureEvent.xconfigure.height);
 21346 #endif
 21347 
 21348 #if !defined USE_X_TOOLKIT && !defined USE_GTK
 21349 
 21350       /* Make the new size of the frame its opaque region.  This is a
 21351          region describing areas of the window which are always
 21352          guaranteed to be completely opaque and can be treated as such
 21353          by the compositor.  It is set to the width and height of the
 21354          only window in no-toolkit builds when `alpha_background' is
 21355          not set, and is cleared otherwise.  */
 21356 
 21357       if (f || (any && configureEvent.xconfigure.window
 21358                 == FRAME_OUTER_WINDOW (any)))
 21359         x_update_opaque_region (f ? f : any, &configureEvent);
 21360 
 21361 #endif /* !defined USE_X_TOOLKIT && !defined USE_GTK */
 21362 
 21363 #ifdef USE_GTK
 21364       if (!f
 21365           && (f = any)
 21366           && configureEvent.xconfigure.window == FRAME_X_WINDOW (f)
 21367           && (FRAME_VISIBLE_P (f)
 21368               || !(configureEvent.xconfigure.width <= 1
 21369                    && configureEvent.xconfigure.height <= 1)))
 21370         {
 21371 
 21372           if (CONSP (frame_size_history))
 21373             frame_size_history_extra
 21374               (f, build_string ("ConfigureNotify"),
 21375                FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
 21376                configureEvent.xconfigure.width,
 21377                configureEvent.xconfigure.height,
 21378                f->new_width, f->new_height);
 21379 
 21380 #ifdef HAVE_XDBE
 21381           if (FRAME_X_DOUBLE_BUFFERED_P (f))
 21382             x_drop_xrender_surfaces (f);
 21383 #endif
 21384           xg_frame_resized (f, configureEvent.xconfigure.width,
 21385                             configureEvent.xconfigure.height);
 21386 #ifdef USE_CAIRO
 21387           x_cr_update_surface_desired_size (f, configureEvent.xconfigure.width,
 21388                                             configureEvent.xconfigure.height);
 21389 #endif
 21390           x_update_opaque_region (f, &configureEvent);
 21391           f = 0;
 21392         }
 21393 #endif
 21394       if (f && (FRAME_VISIBLE_P (f)
 21395                 || !(configureEvent.xconfigure.width <= 1
 21396                      && configureEvent.xconfigure.height <= 1)))
 21397         {
 21398 #ifdef USE_GTK
 21399           /* For GTK+ don't call x_net_wm_state for the scroll bar
 21400              window.  (Bug#24963, Bug#25887) */
 21401           if (configureEvent.xconfigure.window == FRAME_X_WINDOW (f))
 21402 #endif
 21403             x_net_wm_state (f, configureEvent.xconfigure.window);
 21404 
 21405 #if defined USE_X_TOOLKIT || defined USE_GTK
 21406           /* Tip frames are pure X window, set size for them.  */
 21407           if (FRAME_TOOLTIP_P (f))
 21408             {
 21409               if (FRAME_PIXEL_HEIGHT (f) != configureEvent.xconfigure.height
 21410                   || FRAME_PIXEL_WIDTH (f) != configureEvent.xconfigure.width)
 21411                 SET_FRAME_GARBAGED (f);
 21412 
 21413               FRAME_PIXEL_HEIGHT (f) = configureEvent.xconfigure.height;
 21414               FRAME_PIXEL_WIDTH (f) = configureEvent.xconfigure.width;
 21415             }
 21416 #endif
 21417 
 21418 #ifndef USE_X_TOOLKIT
 21419 #ifndef USE_GTK
 21420           int width = configureEvent.xconfigure.width;
 21421           int height = configureEvent.xconfigure.height;
 21422 
 21423           if (CONSP (frame_size_history))
 21424             frame_size_history_extra
 21425               (f, build_string ("ConfigureNotify"),
 21426                FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
 21427                width, height, f->new_width, f->new_height);
 21428 
 21429           /* In the toolkit version, change_frame_size
 21430              is called by the code that handles resizing
 21431              of the EmacsFrame widget.  */
 21432 
 21433           /* Even if the number of character rows and columns has
 21434              not changed, the font size may have changed, so we need
 21435              to check the pixel dimensions as well.  */
 21436 
 21437           if (width != FRAME_PIXEL_WIDTH (f)
 21438               || height != FRAME_PIXEL_HEIGHT (f)
 21439               || (f->new_size_p
 21440                   && ((f->new_width >= 0 && width != f->new_width)
 21441                       || (f->new_height >= 0 && height != f->new_height))))
 21442             {
 21443               change_frame_size (f, width, height, false, true, false);
 21444               x_clear_under_internal_border (f);
 21445               SET_FRAME_GARBAGED (f);
 21446               cancel_mouse_face (f);
 21447             }
 21448 #endif /* not USE_GTK */
 21449 #endif
 21450 
 21451 #ifdef USE_GTK
 21452           /* GTK creates windows but doesn't map them.
 21453              Only get real positions when mapped.  */
 21454           if (FRAME_GTK_OUTER_WIDGET (f)
 21455               && gtk_widget_get_mapped (FRAME_GTK_OUTER_WIDGET (f)))
 21456 #endif
 21457             {
 21458               int old_left = f->left_pos;
 21459               int old_top = f->top_pos;
 21460               Lisp_Object frame;
 21461 
 21462               XSETFRAME (frame, f);
 21463 
 21464               if (!FRAME_PARENT_FRAME (f))
 21465                 x_real_positions (f, &f->left_pos, &f->top_pos);
 21466               else
 21467                 {
 21468                   Window root;
 21469                   unsigned int dummy_uint;
 21470 
 21471                   XGetGeometry (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 21472                                 &root, &f->left_pos, &f->top_pos,
 21473                                 &dummy_uint, &dummy_uint, &dummy_uint, &dummy_uint);
 21474                 }
 21475 
 21476               if (!FRAME_TOOLTIP_P (f)
 21477                   && (old_left != f->left_pos || old_top != f->top_pos))
 21478                 {
 21479                   inev.ie.kind = MOVE_FRAME_EVENT;
 21480                   XSETFRAME (inev.ie.frame_or_window, f);
 21481                 }
 21482             }
 21483 
 21484 
 21485 #ifdef HAVE_X_I18N
 21486           if (f)
 21487             {
 21488               if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea))
 21489                 xic_set_statusarea (f);
 21490 
 21491               struct window *w = XWINDOW (f->selected_window);
 21492               xic_set_preeditarea (w, w->cursor.x, w->cursor.y);
 21493             }
 21494 #endif
 21495 
 21496 #ifdef HAVE_XINPUT2
 21497           if (f && dpyinfo->supports_xi2)
 21498             {
 21499               Mouse_HLInfo *hlinfo;
 21500 
 21501               /* The input extension doesn't report motion events when
 21502                  the part of the window below the pointer changes.  To
 21503                  avoid outdated information from keeping
 21504                  i.e. mouse-highlight at the wrong position after the
 21505                  frame is moved or resized, reset the mouse highlight
 21506                  and last_mouse_motion_frame.  */
 21507 
 21508               if (dpyinfo->last_mouse_motion_frame == f)
 21509                 dpyinfo->last_mouse_motion_frame = NULL;
 21510 
 21511               hlinfo = MOUSE_HL_INFO (f);
 21512 
 21513               if (hlinfo->mouse_face_mouse_frame == f)
 21514                 reset_mouse_highlight (hlinfo);
 21515             }
 21516 #endif
 21517 
 21518         }
 21519 
 21520       if (x_dnd_in_progress
 21521           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 21522         x_dnd_update_state (dpyinfo, dpyinfo->last_user_time);
 21523       goto OTHER;
 21524 
 21525     case ButtonRelease:
 21526     case ButtonPress:
 21527       {
 21528         if (event->xbutton.type == ButtonPress)
 21529           x_display_set_last_user_time (dpyinfo, event->xbutton.time,
 21530                                         event->xbutton.send_event, true);
 21531 
 21532 #ifdef HAVE_XWIDGETS
 21533         struct xwidget_view *xvw;
 21534 
 21535         xvw = xwidget_view_from_window (event->xbutton.window);
 21536 
 21537         if (xvw)
 21538           {
 21539             xwidget_button (xvw, event->type == ButtonPress,
 21540                             event->xbutton.x, event->xbutton.y,
 21541                             event->xbutton.button, event->xbutton.state,
 21542                             event->xbutton.time);
 21543 
 21544             if (!EQ (selected_window, xvw->w) && (event->xbutton.button < 4))
 21545               {
 21546                 inev.ie.kind = SELECT_WINDOW_EVENT;
 21547                 inev.ie.frame_or_window = xvw->w;
 21548               }
 21549 
 21550             *finish = X_EVENT_DROP;
 21551             goto OTHER;
 21552           }
 21553 #endif
 21554         /* If we decide we want to generate an event to be seen
 21555            by the rest of Emacs, we put it here.  */
 21556         Lisp_Object tab_bar_arg = Qnil;
 21557         bool tab_bar_p = false;
 21558         bool tool_bar_p = false;
 21559         bool dnd_grab = false;
 21560 
 21561         if (x_dnd_in_progress
 21562             /* Handle these events normally if the recursion
 21563                level is higher than when the drag-and-drop
 21564                operation was initiated.  This is so that mouse
 21565                input works while we're in the debugger for, say,
 21566                `x-dnd-movement-function`.  */
 21567             && (command_loop_level + minibuf_level
 21568                 <= x_dnd_recursion_depth)
 21569             && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 21570           {
 21571             f = mouse_or_wdesc_frame (dpyinfo, event->xbutton.window);
 21572 
 21573             if (f && event->xbutton.window == FRAME_X_WINDOW (f))
 21574               /* See the comment above x_compute_root_window_offset
 21575                  for why this optimization is performed.  */
 21576               x_compute_root_window_offset (f, event->xbutton.x_root,
 21577                                             event->xbutton.y_root,
 21578                                             event->xbutton.x,
 21579                                             event->xbutton.y);
 21580 
 21581             if (event->type == ButtonPress)
 21582               {
 21583                 x_display_set_last_user_time (dpyinfo, event->xbutton.time,
 21584                                               event->xbutton.send_event, true);
 21585 
 21586                 dpyinfo->grabbed |= (1 << event->xbutton.button);
 21587                 dpyinfo->last_mouse_frame = f;
 21588 
 21589                 if (f)
 21590                   f->last_tab_bar_item = -1;
 21591 #if ! defined (USE_GTK)
 21592                 if (f)
 21593                   f->last_tool_bar_item = -1;
 21594 #endif /* not USE_GTK */
 21595               }
 21596             else
 21597               dpyinfo->grabbed &= ~(1 << event->xbutton.button);
 21598 
 21599             if (event->xbutton.type == ButtonPress
 21600                 && x_dnd_last_seen_window != None)
 21601               {
 21602                 if (x_dnd_last_window_is_frame)
 21603                   x_dnd_note_self_wheel (dpyinfo,
 21604                                          x_dnd_last_seen_window,
 21605                                          event->xbutton.x_root,
 21606                                          event->xbutton.y_root,
 21607                                          event->xbutton.button,
 21608                                          event->xbutton.state,
 21609                                          event->xbutton.time);
 21610                 else if (x_dnd_last_protocol_version != -1)
 21611                   x_dnd_send_position (x_dnd_frame,
 21612                                        x_dnd_last_seen_window,
 21613                                        x_dnd_last_seen_toplevel,
 21614                                        x_dnd_last_protocol_version,
 21615                                        event->xbutton.x_root,
 21616                                        event->xbutton.y_root,
 21617                                        event->xbutton.time,
 21618                                        x_dnd_wanted_action,
 21619                                        event->xbutton.button,
 21620                                        event->xbutton.state);
 21621 
 21622                 goto OTHER;
 21623               }
 21624 
 21625             if (event->xbutton.type == ButtonRelease)
 21626               {
 21627                 for (int i = 1; i < 8; ++i)
 21628                   {
 21629                     if (i != event->xbutton.button
 21630                         && event->xbutton.state & (Button1Mask << (i - 1)))
 21631                       dnd_grab = true;
 21632                   }
 21633 
 21634                 if (!dnd_grab)
 21635                   {
 21636                     x_dnd_end_window = x_dnd_last_seen_window;
 21637                     x_dnd_in_progress = false;
 21638 
 21639                     if (x_dnd_update_tooltip
 21640                         && FRAMEP (tip_frame)
 21641                         && FRAME_LIVE_P (XFRAME (tip_frame))
 21642                         && (FRAME_X_DISPLAY (XFRAME (tip_frame))
 21643                             == FRAME_X_DISPLAY (x_dnd_frame)))
 21644                       Fx_hide_tip ();
 21645 
 21646                     x_dnd_finish_frame = x_dnd_frame;
 21647 
 21648                     if (x_dnd_last_seen_window != None
 21649                         && x_dnd_last_window_is_frame)
 21650                       {
 21651                         x_dnd_waiting_for_finish = false;
 21652                         x_dnd_note_self_drop (dpyinfo,
 21653                                               x_dnd_last_seen_window,
 21654                                               event->xbutton.x_root,
 21655                                               event->xbutton.y_root,
 21656                                               event->xbutton.time);
 21657                       }
 21658                     else if (x_dnd_last_seen_window != None
 21659                              && x_dnd_last_protocol_version != -1)
 21660                       {
 21661                         x_dnd_pending_finish_target = x_dnd_last_seen_toplevel;
 21662                         x_dnd_waiting_for_finish_proto = x_dnd_last_protocol_version;
 21663 
 21664                         x_dnd_waiting_for_finish
 21665                           = x_dnd_do_drop (x_dnd_last_seen_window,
 21666                                            x_dnd_last_seen_toplevel,
 21667                                            x_dnd_last_protocol_version);
 21668                         x_dnd_finish_display = dpyinfo->display;
 21669                       }
 21670                     else if (x_dnd_last_seen_window != None)
 21671                       {
 21672                         xm_drop_start_message dmsg;
 21673                         xm_drag_receiver_info drag_receiver_info;
 21674 
 21675                         if (!xm_read_drag_receiver_info (dpyinfo, x_dnd_last_seen_window,
 21676                                                          &drag_receiver_info)
 21677                             && !x_dnd_disable_motif_protocol
 21678                             && drag_receiver_info.protocol_style != XM_DRAG_STYLE_NONE
 21679                             && (x_dnd_allow_current_frame
 21680                                 || x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame)))
 21681                           {
 21682                             if (!x_dnd_motif_setup_p)
 21683                               xm_setup_drag_info (dpyinfo, x_dnd_frame);
 21684 
 21685                             if (x_dnd_motif_setup_p)
 21686                               {
 21687                                 memset (&dmsg, 0, sizeof dmsg);
 21688 
 21689                                 dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 21690                                                               XM_DRAG_REASON_DROP_START);
 21691                                 dmsg.byte_order = XM_BYTE_ORDER_CUR_FIRST;
 21692                                 dmsg.side_effects
 21693                                   = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo,
 21694                                                                                      x_dnd_wanted_action),
 21695                                                          XM_DROP_SITE_VALID, x_dnd_motif_operations,
 21696                                                          (!x_dnd_xm_use_help
 21697                                                           ? XM_DROP_ACTION_DROP
 21698                                                           : XM_DROP_ACTION_DROP_HELP));
 21699                                 dmsg.timestamp = event->xbutton.time;
 21700                                 dmsg.x = event->xbutton.x_root;
 21701                                 dmsg.y = event->xbutton.y_root;
 21702                                 dmsg.index_atom = x_dnd_motif_atom;
 21703                                 dmsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 21704 
 21705                                 if (!XM_DRAG_STYLE_IS_DROP_ONLY (drag_receiver_info.protocol_style))
 21706                                   x_dnd_send_xm_leave_for_drop (FRAME_DISPLAY_INFO (x_dnd_frame),
 21707                                                                 x_dnd_frame, x_dnd_last_seen_window,
 21708                                                                 event->xbutton.time);
 21709 
 21710                                 xm_send_drop_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 21711                                                       x_dnd_last_seen_window, &dmsg);
 21712 
 21713                                 x_dnd_waiting_for_finish = true;
 21714                                 x_dnd_waiting_for_motif_finish_display = dpyinfo;
 21715                                 x_dnd_waiting_for_motif_finish = 1;
 21716                                 x_dnd_finish_display = dpyinfo->display;
 21717                               }
 21718                           }
 21719                         else
 21720                           x_dnd_send_unsupported_drop (dpyinfo, (x_dnd_last_seen_toplevel != None
 21721                                                                  ? x_dnd_last_seen_toplevel
 21722                                                                  : x_dnd_last_seen_window),
 21723                                                        event->xbutton.x_root, event->xbutton.y_root,
 21724                                                        event->xbutton.time);
 21725                       }
 21726                     else if (x_dnd_last_seen_toplevel != None)
 21727                       x_dnd_send_unsupported_drop (dpyinfo, x_dnd_last_seen_toplevel,
 21728                                                    event->xbutton.x_root,
 21729                                                    event->xbutton.y_root,
 21730                                                    event->xbutton.time);
 21731 
 21732 
 21733                     x_dnd_last_protocol_version = -1;
 21734                     x_dnd_last_motif_style = XM_DRAG_STYLE_NONE;
 21735                     x_dnd_last_seen_window = None;
 21736                     x_dnd_last_seen_toplevel = None;
 21737                     x_dnd_last_window_is_frame = false;
 21738                     x_dnd_frame = NULL;
 21739                   }
 21740               }
 21741 
 21742             goto OTHER;
 21743           }
 21744 
 21745         if (x_dnd_in_progress
 21746             && (command_loop_level + minibuf_level
 21747                 <= x_dnd_recursion_depth))
 21748           goto OTHER;
 21749 
 21750         memset (&compose_status, 0, sizeof (compose_status));
 21751         dpyinfo->last_mouse_glyph_frame = NULL;
 21752 
 21753         f = mouse_or_wdesc_frame (dpyinfo, event->xbutton.window);
 21754 
 21755         if (f && event->xbutton.window == FRAME_X_WINDOW (f))
 21756           /* See the comment above x_compute_root_window_offset
 21757              for why this optimization is performed.  */
 21758           x_compute_root_window_offset (f, event->xbutton.x_root,
 21759                                         event->xbutton.y_root,
 21760                                         event->xbutton.x,
 21761                                         event->xbutton.y);
 21762 
 21763         if (f && event->xbutton.type == ButtonPress
 21764             && !popup_activated ()
 21765             && !x_window_to_scroll_bar (event->xbutton.display,
 21766                                         event->xbutton.window, 2)
 21767             && !FRAME_NO_ACCEPT_FOCUS (f))
 21768           {
 21769             /* When clicking into a child frame or when clicking
 21770                into a parent frame with the child frame selected and
 21771                `no-accept-focus' is not set, select the clicked
 21772                frame.  */
 21773             struct frame *hf = dpyinfo->highlight_frame;
 21774 
 21775             if (FRAME_PARENT_FRAME (f) || (hf && frame_ancestor_p (f, hf)))
 21776               {
 21777                 x_ignore_errors_for_next_request (dpyinfo, 0);
 21778                 XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 21779                                 RevertToParent, event->xbutton.time);
 21780                 x_stop_ignoring_errors (dpyinfo);
 21781 
 21782                 if (FRAME_PARENT_FRAME (f))
 21783                   XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f));
 21784               }
 21785           }
 21786 
 21787 #ifdef USE_GTK
 21788         if (!f)
 21789           {
 21790             f = x_any_window_to_frame (dpyinfo, event->xbutton.window);
 21791 
 21792             if (event->xbutton.button > 3
 21793                 && event->xbutton.button < 8
 21794                 && f)
 21795               {
 21796                 if (ignore_next_mouse_click_timeout
 21797                     && dpyinfo == mouse_click_timeout_display)
 21798                   {
 21799                     if (event->type == ButtonPress
 21800                         && event->xbutton.time > ignore_next_mouse_click_timeout)
 21801                       {
 21802                         ignore_next_mouse_click_timeout = 0;
 21803                         x_construct_mouse_click (&inev.ie, &event->xbutton, f);
 21804                       }
 21805                     if (event->type == ButtonRelease)
 21806                       ignore_next_mouse_click_timeout = 0;
 21807                   }
 21808                 else
 21809                   x_construct_mouse_click (&inev.ie, &event->xbutton, f);
 21810 
 21811                 *finish = X_EVENT_DROP;
 21812                 goto OTHER;
 21813               }
 21814             else
 21815               f = NULL;
 21816           }
 21817 
 21818         if (f && xg_event_is_for_scrollbar (f, event, false))
 21819           f = 0;
 21820 #endif
 21821         if (f)
 21822           {
 21823             /* Is this in the tab-bar?  */
 21824             if (WINDOWP (f->tab_bar_window)
 21825                 && WINDOW_TOTAL_LINES (XWINDOW (f->tab_bar_window)))
 21826               {
 21827                 Lisp_Object window;
 21828                 int x = event->xbutton.x;
 21829                 int y = event->xbutton.y;
 21830 
 21831                 window = window_from_coordinates (f, x, y, 0, true, true);
 21832                 tab_bar_p = EQ (window, f->tab_bar_window);
 21833 
 21834                 if (tab_bar_p)
 21835                   {
 21836                     tab_bar_arg = handle_tab_bar_click
 21837                       (f, x, y, event->xbutton.type == ButtonPress,
 21838                        x_x_to_emacs_modifiers (dpyinfo, event->xbutton.state));
 21839                     x_flush_dirty_back_buffer_on (f);
 21840                   }
 21841               }
 21842 
 21843 #if ! defined (USE_GTK)
 21844             /* Is this in the tool-bar?  */
 21845             if (WINDOWP (f->tool_bar_window)
 21846                 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)))
 21847               {
 21848                 Lisp_Object window;
 21849                 int x = event->xbutton.x;
 21850                 int y = event->xbutton.y;
 21851 
 21852                 window = window_from_coordinates (f, x, y, 0, true, true);
 21853                 tool_bar_p = (EQ (window, f->tool_bar_window)
 21854                               && (event->xbutton.type != ButtonRelease
 21855                                   || f->last_tool_bar_item != -1));
 21856 
 21857                 if (tool_bar_p && event->xbutton.button < 4)
 21858                   {
 21859                     handle_tool_bar_click
 21860                       (f, x, y, event->xbutton.type == ButtonPress,
 21861                        x_x_to_emacs_modifiers (dpyinfo, event->xbutton.state));
 21862                     x_flush_dirty_back_buffer_on (f);
 21863                   }
 21864               }
 21865 #endif /* !USE_GTK */
 21866 
 21867             if (!(tab_bar_p && NILP (tab_bar_arg)) && !tool_bar_p)
 21868 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
 21869               if (! popup_activated ())
 21870 #endif
 21871                 {
 21872                   if (ignore_next_mouse_click_timeout
 21873                       && dpyinfo == mouse_click_timeout_display)
 21874                     {
 21875                       if (event->type == ButtonPress
 21876                           && event->xbutton.time > ignore_next_mouse_click_timeout)
 21877                         {
 21878                           ignore_next_mouse_click_timeout = 0;
 21879                           x_construct_mouse_click (&inev.ie, &event->xbutton, f);
 21880                         }
 21881                       if (event->type == ButtonRelease)
 21882                         ignore_next_mouse_click_timeout = 0;
 21883                     }
 21884                   else
 21885                     x_construct_mouse_click (&inev.ie, &event->xbutton, f);
 21886 
 21887                   if (!NILP (tab_bar_arg))
 21888                     inev.ie.arg = tab_bar_arg;
 21889                 }
 21890 
 21891             if (FRAME_X_EMBEDDED_P (f)
 21892                 && !FRAME_NO_ACCEPT_FOCUS (f))
 21893               xembed_send_message (f, event->xbutton.time,
 21894                                    XEMBED_REQUEST_FOCUS, 0, 0, 0);
 21895           }
 21896         else
 21897           {
 21898             struct scroll_bar *bar
 21899               = x_window_to_scroll_bar (event->xbutton.display,
 21900                                         event->xbutton.window, 2);
 21901 
 21902 #ifdef USE_TOOLKIT_SCROLL_BARS
 21903             /* Make the "Ctrl-Mouse-2 splits window" work for toolkit
 21904                scroll bars.  */
 21905             if (bar && event->xbutton.state & ControlMask)
 21906               {
 21907                 x_scroll_bar_handle_click (bar, event, &inev.ie, Qnil);
 21908                 *finish = X_EVENT_DROP;
 21909               }
 21910 #else /* not USE_TOOLKIT_SCROLL_BARS */
 21911             if (bar)
 21912               x_scroll_bar_handle_click (bar, event, &inev.ie, Qnil);
 21913 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 21914           }
 21915 
 21916         if (event->type == ButtonPress)
 21917           {
 21918             dpyinfo->grabbed |= (1 << event->xbutton.button);
 21919             dpyinfo->last_mouse_frame = f;
 21920             if (f && !tab_bar_p)
 21921               f->last_tab_bar_item = -1;
 21922 #if ! defined (USE_GTK)
 21923             if (f && !tool_bar_p)
 21924               f->last_tool_bar_item = -1;
 21925 #endif /* not USE_GTK */
 21926           }
 21927         else
 21928           dpyinfo->grabbed &= ~(1 << event->xbutton.button);
 21929 
 21930         /* Ignore any mouse motion that happened before this event;
 21931            any subsequent mouse-movement Emacs events should reflect
 21932            only motion after the ButtonPress/Release.  */
 21933         if (f != 0)
 21934           f->mouse_moved = false;
 21935 
 21936 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
 21937         f = x_menubar_window_to_frame (dpyinfo, event);
 21938         /* For a down-event in the menu bar, don't pass it to Xt or
 21939            GTK right away.  Instead, save it and pass it to Xt or GTK
 21940            from kbd_buffer_get_event.  That way, we can run some Lisp
 21941            code first.  */
 21942         if (! popup_activated ()
 21943 #ifdef USE_GTK
 21944             /* Gtk+ menus only react to the first three buttons. */
 21945             && event->xbutton.button < 3
 21946 #endif
 21947             && f && event->type == ButtonPress
 21948             /* Verify the event is really within the menu bar
 21949                and not just sent to it due to grabbing.  */
 21950             && event->xbutton.x >= 0
 21951             && event->xbutton.x < FRAME_PIXEL_WIDTH (f)
 21952             && event->xbutton.y >= 0
 21953             && event->xbutton.y < FRAME_MENUBAR_HEIGHT (f)
 21954             && event->xbutton.same_screen)
 21955           {
 21956 #ifdef USE_MOTIF
 21957             Widget widget;
 21958 
 21959             widget = XtWindowToWidget (dpyinfo->display,
 21960                                        event->xbutton.window);
 21961 
 21962             if (widget && XmIsCascadeButton (widget)
 21963                 && XtIsSensitive (widget))
 21964               {
 21965 #endif
 21966                 if (!f->output_data.x->saved_menu_event)
 21967                   f->output_data.x->saved_menu_event = xmalloc (sizeof *event);
 21968                 *f->output_data.x->saved_menu_event = *event;
 21969                 inev.ie.kind = MENU_BAR_ACTIVATE_EVENT;
 21970                 XSETFRAME (inev.ie.frame_or_window, f);
 21971                 *finish = X_EVENT_DROP;
 21972 #ifdef USE_MOTIF
 21973               }
 21974 #endif
 21975           }
 21976         else
 21977           goto OTHER;
 21978 #endif /* USE_X_TOOLKIT || USE_GTK */
 21979       }
 21980       break;
 21981 
 21982     case CirculateNotify:
 21983       if (x_dnd_in_progress
 21984           /* When _NET_WM_CLIENT_LIST stacking is being used, changes
 21985              in that property are watched for, and it's not necessary
 21986              to update the state in response to ordinary window
 21987              substructure events.  */
 21988           && !x_dnd_use_toplevels
 21989           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 21990         x_dnd_update_state (dpyinfo, dpyinfo->last_user_time);
 21991       goto OTHER;
 21992 
 21993     case CirculateRequest:
 21994       goto OTHER;
 21995 
 21996     case VisibilityNotify:
 21997       f = x_top_window_to_frame (dpyinfo, event->xvisibility.window);
 21998 
 21999       if (f)
 22000         FRAME_X_OUTPUT (f)->visibility_state = event->xvisibility.state;
 22001 
 22002       goto OTHER;
 22003 
 22004     case MappingNotify:
 22005       /* Someone has changed the keyboard mapping - update the
 22006          local cache.  */
 22007       switch (event->xmapping.request)
 22008         {
 22009         case MappingModifier:
 22010           x_find_modifier_meanings (dpyinfo);
 22011           FALLTHROUGH;
 22012         case MappingKeyboard:
 22013           XRefreshKeyboardMapping ((XMappingEvent *) &event->xmapping);
 22014         }
 22015       goto OTHER;
 22016 
 22017     case DestroyNotify:
 22018       if (event->xdestroywindow.window
 22019           == dpyinfo->net_supported_window)
 22020         dpyinfo->net_supported_window = None;
 22021 
 22022       if (event->xdestroywindow.window
 22023           == dpyinfo->motif_drag_window)
 22024         /* We get DestroyNotify events for the drag window because
 22025            x_special_window_exists_p selects for structure
 22026            notification.  The drag window is not supposed to go away
 22027            but not all clients obey that requirement when setting the
 22028            drag window property.  */
 22029         dpyinfo->motif_drag_window = None;
 22030 
 22031       xft_settings_event (dpyinfo, event);
 22032       break;
 22033 
 22034 #ifdef HAVE_XINPUT2
 22035     case GenericEvent:
 22036       {
 22037         if (!dpyinfo->supports_xi2)
 22038           goto OTHER;
 22039 
 22040         if (event->xgeneric.extension != dpyinfo->xi2_opcode)
 22041           /* Not an XI2 event. */
 22042           goto OTHER;
 22043 
 22044         bool must_free_data = false;
 22045         XIEvent *xi_event = (XIEvent *) event->xcookie.data;
 22046 
 22047         /* Sometimes the event is already claimed by GTK, which
 22048            will free its data in due course. */
 22049         if (!xi_event)
 22050           {
 22051             if (XGetEventData (dpyinfo->display, &event->xcookie))
 22052               must_free_data = true;
 22053 
 22054             xi_event = (XIEvent *) event->xcookie.data;
 22055           }
 22056 
 22057         XIDeviceEvent *xev = (XIDeviceEvent *) xi_event;
 22058 
 22059         if (!xi_event)
 22060           {
 22061             /* It may turn out that the event data has already been
 22062                implicitly freed for various reasons up to and
 22063                including XMenuActivate pushing some other event onto
 22064                the foreign-event queue, or x_menu_wait_for_events
 22065                calling XNextEvent through a timer that tries to wait
 22066                for input.
 22067 
 22068                In that case, XGetEventData will return True, but
 22069                cookie->data will be NULL.  Since handling such input
 22070                events is not really important, we can afford to
 22071                discard them.
 22072 
 22073                The way Xlib is currently implemented makes calling
 22074                XFreeEventData unnecessary in this case, but call it
 22075                anyway, since not doing so may lead to a memory leak in
 22076                the future.  */
 22077 
 22078             if (must_free_data)
 22079               XFreeEventData (dpyinfo->display, &event->xcookie);
 22080             goto OTHER;
 22081           }
 22082 
 22083         switch (event->xcookie.evtype)
 22084           {
 22085           case XI_FocusIn:
 22086             {
 22087               XIFocusInEvent *focusin;
 22088 
 22089               focusin = (XIFocusInEvent *) xi_event;
 22090               any = x_any_window_to_frame (dpyinfo, focusin->event);
 22091 
 22092 #ifdef USE_GTK
 22093               /* Some WMs (e.g. Mutter in Gnome Shell), don't unmap
 22094                  minimized/iconified windows; thus, for those WMs we won't get
 22095                  a MapNotify when unminimizing/deiconifying.  Check here if we
 22096                  are deiconizing a window (Bug42655).
 22097 
 22098                  But don't do that by default on GTK since it may cause a plain
 22099                  invisible frame get reported as iconified, compare
 22100                  https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html.
 22101                  That is fixed above but bites us here again.
 22102 
 22103                  The option x_set_frame_visibility_more_laxly allows to override
 22104                  the default behavior (Bug#49955, Bug#53298).  */
 22105               if (EQ (x_set_frame_visibility_more_laxly, Qfocus_in)
 22106                   || EQ (x_set_frame_visibility_more_laxly, Qt))
 22107 #endif /* USE_GTK */
 22108                 {
 22109                   f = any;
 22110                   if (f && FRAME_ICONIFIED_P (f))
 22111                     {
 22112                       SET_FRAME_VISIBLE (f, 1);
 22113                       SET_FRAME_ICONIFIED (f, false);
 22114                       f->output_data.x->has_been_visible = true;
 22115                       inev.ie.kind = DEICONIFY_EVENT;
 22116                       XSETFRAME (inev.ie.frame_or_window, f);
 22117                     }
 22118                 }
 22119 
 22120               xi_focus_handle_for_device (dpyinfo, any, xi_event);
 22121 
 22122               goto XI_OTHER;
 22123             }
 22124 
 22125           case XI_FocusOut:
 22126             {
 22127               XIFocusOutEvent *focusout;
 22128 
 22129               focusout = (XIFocusOutEvent *) xi_event;
 22130               any = x_any_window_to_frame (dpyinfo, focusout->event);
 22131               xi_focus_handle_for_device (dpyinfo, any, xi_event);
 22132 
 22133               goto XI_OTHER;
 22134             }
 22135 
 22136           case XI_Enter:
 22137             {
 22138               XIEnterEvent *enter = (XIEnterEvent *) xi_event;
 22139               XMotionEvent ev;
 22140               struct xi_device_t *source;
 22141 
 22142               any = x_top_window_to_frame (dpyinfo, enter->event);
 22143               source = xi_device_from_id (dpyinfo, enter->sourceid);
 22144 
 22145               ev.x = lrint (enter->event_x);
 22146               ev.y = lrint (enter->event_y);
 22147               ev.window = enter->event;
 22148               ev.time = enter->time;
 22149               ev.send_event = enter->send_event;
 22150 
 22151               x_display_set_last_user_time (dpyinfo, enter->time,
 22152                                             enter->send_event, false);
 22153 
 22154 #ifdef USE_MOTIF
 22155               use_copy = true;
 22156 
 22157               copy.xcrossing.type = EnterNotify;
 22158               copy.xcrossing.serial = enter->serial;
 22159               copy.xcrossing.send_event = enter->send_event;
 22160               copy.xcrossing.display = dpyinfo->display;
 22161               copy.xcrossing.window = enter->event;
 22162               copy.xcrossing.root = enter->root;
 22163               copy.xcrossing.subwindow = enter->child;
 22164               copy.xcrossing.time = enter->time;
 22165               copy.xcrossing.x = lrint (enter->event_x);
 22166               copy.xcrossing.y = lrint (enter->event_y);
 22167               copy.xcrossing.x_root = lrint (enter->root_x);
 22168               copy.xcrossing.y_root = lrint (enter->root_y);
 22169               copy.xcrossing.mode = enter->mode;
 22170               copy.xcrossing.detail = enter->detail;
 22171               copy.xcrossing.focus = enter->focus;
 22172               copy.xcrossing.state = 0;
 22173               copy.xcrossing.same_screen = True;
 22174 #endif
 22175 
 22176               /* There is no need to handle entry/exit events for
 22177                  passive focus from non-top windows at all, since they
 22178                  are an inferiors of the frame's top window, which will
 22179                  get virtual events.  */
 22180               if (any)
 22181                 xi_focus_handle_for_device (dpyinfo, any, xi_event);
 22182 
 22183               if (!any)
 22184                 any = x_any_window_to_frame (dpyinfo, enter->event);
 22185 
 22186 #ifdef HAVE_XINPUT2_1
 22187               /* xfwm4 selects for button events on the frame window,
 22188                  resulting in passive grabs being generated along with
 22189                  the delivery of emulated button events; this then
 22190                  interferes with scrolling, since device valuators
 22191                  will constantly be reset as the crossing events
 22192                  related to those grabs arrive.  The only way to
 22193                  remedy this is to never reset scroll valuators on a
 22194                  grab-related crossing event.  (bug#57476) */
 22195 
 22196               if (enter->mode != XINotifyUngrab
 22197                   && enter->mode != XINotifyGrab
 22198                   && enter->mode != XINotifyPassiveGrab
 22199                   && enter->mode != XINotifyPassiveUngrab)
 22200                 xi_reset_scroll_valuators_for_device_id (dpyinfo,
 22201                                                          enter->deviceid);
 22202 #endif
 22203 
 22204               {
 22205 #ifdef HAVE_XWIDGETS
 22206                 struct xwidget_view *xwidget_view;
 22207 
 22208                 xwidget_view = xwidget_view_from_window (enter->event);
 22209 
 22210                 if (xwidget_view)
 22211                   {
 22212                     xwidget_motion_or_crossing (xwidget_view, event);
 22213 
 22214                     goto XI_OTHER;
 22215                   }
 22216 #endif
 22217               }
 22218 
 22219               f = any;
 22220 
 22221               if (f && enter->event == FRAME_X_WINDOW (f))
 22222                 xi_compute_root_window_offset_enter (f, enter);
 22223 
 22224               if (f && x_mouse_click_focus_ignore_position)
 22225                 {
 22226                   ignore_next_mouse_click_timeout = (enter->time
 22227                                                      + x_mouse_click_focus_ignore_time);
 22228                   mouse_click_timeout_display = dpyinfo;
 22229                 }
 22230 
 22231               /* EnterNotify counts as mouse movement,
 22232                  so update things that depend on mouse position.  */
 22233               if (f && !f->output_data.x->hourglass_p)
 22234                 x_note_mouse_movement (f, &ev, source ? source->name : Qnil);
 22235 #ifdef USE_GTK
 22236               /* We may get an EnterNotify on the buttons in the toolbar.  In that
 22237                  case we moved out of any highlighted area and need to note this.  */
 22238               if (!f && dpyinfo->last_mouse_glyph_frame)
 22239                 x_note_mouse_movement (dpyinfo->last_mouse_glyph_frame, &ev,
 22240                                        source ? source->name : Qnil);
 22241 #endif
 22242               goto XI_OTHER;
 22243             }
 22244 
 22245           case XI_Leave:
 22246             {
 22247               XILeaveEvent *leave;
 22248               struct xi_device_t *device;
 22249 
 22250               leave = (XILeaveEvent *) xi_event;
 22251 #ifdef USE_GTK
 22252               struct xi_device_t *source;
 22253               XMotionEvent ev;
 22254 
 22255               ev.x = lrint (leave->event_x);
 22256               ev.y = lrint (leave->event_y);
 22257               ev.window = leave->event;
 22258               ev.time = leave->time;
 22259               ev.send_event = leave->send_event;
 22260 #endif
 22261 
 22262               any = x_top_window_to_frame (dpyinfo, leave->event);
 22263 
 22264 #ifdef USE_GTK
 22265               source = xi_device_from_id (dpyinfo, leave->sourceid);
 22266 #endif
 22267               device = xi_device_from_id (dpyinfo, leave->deviceid);
 22268 
 22269               if (device)
 22270                 xi_report_motion_window_clear (device);
 22271 
 22272               /* This allows us to catch LeaveNotify events generated by
 22273                  popup menu grabs.  FIXME: this is right when there is a
 22274                  focus menu, but implicit focus tracking can get screwed
 22275                  up if we get this and no XI_Enter event later.   */
 22276 
 22277 #ifdef USE_X_TOOLKIT
 22278               if (popup_activated ()
 22279                   && (leave->mode == XINotifyPassiveUngrab
 22280                       || leave->mode == XINotifyUngrab))
 22281                 any = x_any_window_to_frame (dpyinfo, leave->event);
 22282 #endif
 22283 
 22284 #ifdef USE_MOTIF
 22285               use_copy = true;
 22286 
 22287               copy.xcrossing.type = LeaveNotify;
 22288               copy.xcrossing.serial = leave->serial;
 22289               copy.xcrossing.send_event = leave->send_event;
 22290               copy.xcrossing.display = dpyinfo->display;
 22291               copy.xcrossing.window = leave->event;
 22292               copy.xcrossing.root = leave->root;
 22293               copy.xcrossing.subwindow = leave->child;
 22294               copy.xcrossing.time = leave->time;
 22295               copy.xcrossing.x = lrint (leave->event_x);
 22296               copy.xcrossing.y = lrint (leave->event_y);
 22297               copy.xcrossing.x_root = lrint (leave->root_x);
 22298               copy.xcrossing.y_root = lrint (leave->root_y);
 22299               copy.xcrossing.mode = leave->mode;
 22300               copy.xcrossing.detail = leave->detail;
 22301               copy.xcrossing.focus = leave->focus;
 22302               copy.xcrossing.state = 0;
 22303               copy.xcrossing.same_screen = True;
 22304 #endif
 22305 
 22306               /* One problem behind the design of XInput 2 scrolling is
 22307                  that valuators are not unique to each window, but only
 22308                  the window that has grabbed the valuator's device or
 22309                  the window that the device's pointer is on top of can
 22310                  receive motion events.  There is also no way to
 22311                  retrieve the value of a valuator outside of each motion
 22312                  event.
 22313 
 22314                  As such, to prevent wildly inaccurate results when
 22315                  the valuators have changed outside Emacs, we reset
 22316                  our records of each valuator's value whenever the
 22317                  pointer moves out of a frame.  Ideally, this would
 22318                  ignore events with a detail of XINotifyInferior, as
 22319                  the window the pointer moved to would be one known to
 22320                  Emacs, but the code to keep track of which valuators
 22321                  had to be reset upon the corresponding XI_Enter event
 22322                  was very complicated and kept running into server
 22323                  bugs.  */
 22324 #ifdef HAVE_XINPUT2_1
 22325               /* xfwm4 selects for button events on the frame window,
 22326                  resulting in passive grabs being generated along with
 22327                  the delivery of emulated button events; this then
 22328                  interferes with scrolling, since device valuators
 22329                  will constantly be reset as the crossing events
 22330                  related to those grabs arrive.  The only way to
 22331                  remedy this is to never reset scroll valuators on a
 22332                  grab-related crossing event.  (bug#57476) */
 22333 
 22334               if (leave->mode != XINotifyUngrab
 22335                   && leave->mode != XINotifyGrab
 22336                   && leave->mode != XINotifyPassiveUngrab
 22337                   && leave->mode != XINotifyPassiveGrab)
 22338                 xi_reset_scroll_valuators_for_device_id (dpyinfo,
 22339                                                          leave->deviceid);
 22340 #endif
 22341 
 22342               x_display_set_last_user_time (dpyinfo, leave->time,
 22343                                             leave->send_event, false);
 22344 
 22345 #ifdef HAVE_XWIDGETS
 22346               {
 22347                 struct xwidget_view *xvw;
 22348 
 22349                 xvw = xwidget_view_from_window (leave->event);
 22350 
 22351                 if (xvw)
 22352                   {
 22353                     *finish = X_EVENT_DROP;
 22354                     xwidget_motion_or_crossing (xvw, event);
 22355 
 22356                     goto XI_OTHER;
 22357                   }
 22358               }
 22359 #endif
 22360 
 22361               if (any)
 22362                 xi_focus_handle_for_device (dpyinfo, any, xi_event);
 22363 
 22364 #ifndef USE_X_TOOLKIT
 22365               f = x_top_window_to_frame (dpyinfo, leave->event);
 22366 #else
 22367               /* On Xt builds that have XI2, the enter and leave event
 22368                  masks are set on the frame widget's window.  */
 22369               f = x_window_to_frame (dpyinfo, leave->event);
 22370 
 22371               if (!f)
 22372                 f = x_top_window_to_frame (dpyinfo, leave->event);
 22373 #endif
 22374 
 22375               if (f)
 22376                 {
 22377                   /* Now clear dpyinfo->last_mouse_motion_frame, or
 22378                      gui_redo_mouse_highlight will end up highlighting
 22379                      the last known position of the mouse if a
 22380                      tooltip frame is later unmapped.  */
 22381 
 22382                   if (f == dpyinfo->last_mouse_motion_frame)
 22383                     dpyinfo->last_mouse_motion_frame = NULL;
 22384 
 22385                   /* Something similar applies to
 22386                      dpyinfo->last_mouse_glyph_frame.  */
 22387                   if (f == dpyinfo->last_mouse_glyph_frame)
 22388                     dpyinfo->last_mouse_glyph_frame = NULL;
 22389 
 22390                   if (f == hlinfo->mouse_face_mouse_frame)
 22391                     {
 22392                       /* If we move outside the frame, then we're
 22393                          certainly no longer on any text in the frame.  */
 22394                       clear_mouse_face (hlinfo);
 22395                       hlinfo->mouse_face_mouse_frame = 0;
 22396                       x_flush_dirty_back_buffer_on (f);
 22397                     }
 22398 
 22399                   /* Generate a nil HELP_EVENT to cancel a help-echo.
 22400                      Do it only if there's something to cancel.
 22401                      Otherwise, the startup message is cleared when
 22402                      the mouse leaves the frame.  */
 22403                   if (any_help_event_p
 22404                       /* But never if `mouse-drag-and-drop-region' is
 22405                          in progress, since that results in the
 22406                          tooltip being dismissed when the mouse moves
 22407                          on top.  */
 22408                       && !((EQ (track_mouse, Qdrag_source)
 22409                             || EQ (track_mouse, Qdropping))
 22410                            && gui_mouse_grabbed (dpyinfo)))
 22411                     do_help = -1;
 22412 
 22413                   if (f && leave->event == FRAME_X_WINDOW (f))
 22414                     xi_compute_root_window_offset_enter (f, leave);
 22415                 }
 22416 #ifdef USE_GTK
 22417               /* See comment in EnterNotify above */
 22418               else if (dpyinfo->last_mouse_glyph_frame)
 22419                 x_note_mouse_movement (dpyinfo->last_mouse_glyph_frame, &ev,
 22420                                        source ? source->name : Qnil);
 22421 #endif
 22422               goto XI_OTHER;
 22423             }
 22424 
 22425           case XI_Motion:
 22426             {
 22427               struct xi_device_t *device, *source;
 22428 #ifdef HAVE_XINPUT2_1
 22429               XIValuatorState *states;
 22430               double *values;
 22431               bool found_valuator = false;
 22432               bool other_valuators_found = false;
 22433 #endif
 22434               /* A fake XMotionEvent for x_note_mouse_movement. */
 22435               XMotionEvent ev;
 22436               xm_top_level_leave_message lmsg;
 22437               xm_top_level_enter_message emsg;
 22438               xm_drag_motion_message dmsg;
 22439               unsigned int dnd_state;
 22440 
 22441               source = xi_device_from_id (dpyinfo, xev->sourceid);
 22442 
 22443 #ifdef HAVE_XINPUT2_1
 22444               states = &xev->valuators;
 22445               values = states->values;
 22446 #endif
 22447 
 22448               device = xi_device_from_id (dpyinfo, xev->deviceid);
 22449 
 22450               if (!device)
 22451                 goto XI_OTHER;
 22452 
 22453 #ifdef HAVE_XINPUT2_2
 22454               if (xev->flags & XIPointerEmulated)
 22455                 goto XI_OTHER;
 22456 #endif
 22457 
 22458 #ifdef HAVE_XINPUT2_1
 22459 #ifdef HAVE_XWIDGETS
 22460               struct xwidget_view *xv = xwidget_view_from_window (xev->event);
 22461               double xv_total_x = 0.0;
 22462               double xv_total_y = 0.0;
 22463 #endif
 22464               double total_x = 0.0;
 22465               double total_y = 0.0;
 22466 
 22467               int real_x, real_y;
 22468 
 22469               for (int i = 0; i < states->mask_len * 8; i++)
 22470                 {
 22471                   if (XIMaskIsSet (states->mask, i))
 22472                     {
 22473                       struct xi_scroll_valuator_t *val;
 22474                       double delta, scroll_unit;
 22475                       int scroll_height;
 22476                       Lisp_Object window;
 22477                       struct scroll_bar *bar;
 22478 
 22479                       bar = NULL;
 22480 
 22481                       /* See the comment on top of x_cache_xi_devices
 22482                          for more details on how scroll wheel movement
 22483                          is reported on XInput 2.  */
 22484                       delta = x_get_scroll_valuator_delta (dpyinfo, device,
 22485                                                            i, *values, &val);
 22486                       values++;
 22487 
 22488                       if (!val)
 22489                         {
 22490                           other_valuators_found = true;
 22491                           continue;
 22492                         }
 22493 
 22494                       if (delta != DBL_MAX)
 22495                         {
 22496                           if (!f)
 22497                             {
 22498                               f = x_any_window_to_frame (dpyinfo, xev->event);
 22499 
 22500                               if (!f)
 22501                                 {
 22502 #if defined USE_MOTIF || !defined USE_TOOLKIT_SCROLL_BARS
 22503                                   bar = x_window_to_scroll_bar (dpyinfo->display,
 22504                                                                 xev->event, 2);
 22505 
 22506                                   if (bar)
 22507                                     f = WINDOW_XFRAME (XWINDOW (bar->window));
 22508 
 22509                                   if (!f)
 22510 #endif
 22511                                     goto XI_OTHER;
 22512                                 }
 22513                             }
 22514 
 22515 #ifdef USE_GTK
 22516                           if (f && xg_event_is_for_scrollbar (f, event, true))
 22517                             *finish = X_EVENT_DROP;
 22518 #endif
 22519 
 22520                           if (FRAME_X_WINDOW (f) != xev->event)
 22521                             {
 22522                               if (!bar)
 22523                                 bar = x_window_to_scroll_bar (dpyinfo->display, xev->event, 2);
 22524 
 22525                               /* If this is a scroll bar, compute the
 22526                                  actual position directly to avoid an
 22527                                  extra roundtrip.  */
 22528 
 22529                               if (bar)
 22530                                 {
 22531                                   real_x = lrint (xev->event_x + bar->left);
 22532                                   real_y = lrint (xev->event_y + bar->top);
 22533                                 }
 22534                               else
 22535                                 x_translate_coordinates (f,
 22536                                                          lrint (xev->root_x),
 22537                                                          lrint (xev->root_y),
 22538                                                          &real_x, &real_y);
 22539                             }
 22540                           else
 22541                             {
 22542                               real_x = lrint (xev->event_x);
 22543                               real_y = lrint (xev->event_y);
 22544                             }
 22545 
 22546 #ifdef HAVE_XWIDGETS
 22547                           if (xv)
 22548                             {
 22549                               if (val->horizontal)
 22550                                 xv_total_x += delta;
 22551                               else
 22552                                 xv_total_y += delta;
 22553 
 22554                               found_valuator = true;
 22555                               continue;
 22556                             }
 22557 #endif
 22558 
 22559                           if (delta == 0.0)
 22560                             found_valuator = true;
 22561 
 22562                           if (signbit (delta) != signbit (val->emacs_value))
 22563                             val->emacs_value = 0;
 22564 
 22565                           val->emacs_value += delta;
 22566 
 22567                           if (mwheel_coalesce_scroll_events
 22568                               && (fabs (val->emacs_value) < 1)
 22569                               && (fabs (delta) > 0))
 22570                             continue;
 22571 
 22572                           window = window_from_coordinates (f, real_x, real_y, NULL,
 22573                                                             false, false);
 22574 
 22575                           if (WINDOWP (window))
 22576                             scroll_height = XWINDOW (window)->pixel_height;
 22577                           else
 22578                             /* EVENT_X and EVENT_Y can be outside the
 22579                                frame if F holds the input grab, so fall
 22580                                back to the height of the frame instead.  */
 22581                             scroll_height = FRAME_PIXEL_HEIGHT (f);
 22582 
 22583                           scroll_unit = pow (scroll_height, 2.0 / 3.0);
 22584 
 22585                           if (NUMBERP (Vx_scroll_event_delta_factor))
 22586                             scroll_unit *= XFLOATINT (Vx_scroll_event_delta_factor);
 22587 
 22588                           if (val->horizontal)
 22589                             total_x += val->emacs_value * scroll_unit;
 22590                           else
 22591                             total_y += val->emacs_value * scroll_unit;
 22592 
 22593                           found_valuator = true;
 22594                           val->emacs_value = 0;
 22595                         }
 22596                     }
 22597                 }
 22598 
 22599 #ifdef HAVE_XWIDGETS
 22600               if (xv)
 22601                 {
 22602                   unsigned int state;
 22603 
 22604                   state = xi_convert_event_state (xev);
 22605                   x_display_set_last_user_time (dpyinfo, xev->time,
 22606                                                 xev->send_event, true);
 22607 
 22608                   if (found_valuator)
 22609                     xwidget_scroll (xv, xev->event_x, xev->event_y,
 22610                                     -xv_total_x, -xv_total_y, state,
 22611                                     xev->time, (xv_total_x == 0.0
 22612                                                 && xv_total_y == 0.0));
 22613                   else
 22614                     xwidget_motion_notify (xv, xev->event_x, xev->event_y,
 22615                                            xev->root_x, xev->root_y, state,
 22616                                            xev->time);
 22617 
 22618                   goto XI_OTHER;
 22619                 }
 22620               else
 22621                 {
 22622 #endif
 22623                   if (found_valuator)
 22624                     {
 22625                       x_display_set_last_user_time (dpyinfo, xev->time,
 22626                                                     xev->send_event, true);
 22627 
 22628 
 22629 #if defined USE_GTK && !defined HAVE_GTK3
 22630                       /* Unlike on Motif, we can't select for XI
 22631                          events on the scroll bar window under GTK+ 2.
 22632                          So instead of that, just ignore XI wheel
 22633                          events which land on a scroll bar.
 22634 
 22635                          Here we assume anything which isn't the edit
 22636                          widget window is a scroll bar.  */
 22637 
 22638                       if (xev->child != None
 22639                           && xev->child != FRAME_X_WINDOW (f))
 22640                         goto XI_OTHER;
 22641 #endif
 22642 
 22643                       /* If this happened during a drag-and-drop
 22644                          operation, don't send an event.  We only have
 22645                          to set the user time.  */
 22646                       if (x_dnd_in_progress
 22647                           /* If another master device moved the
 22648                              pointer, we should put a wheel event on
 22649                              the keyboard buffer as usual.  It will be
 22650                              run once the drag-and-drop operation
 22651                              completes.  */
 22652                           && xev->deviceid == x_dnd_pointer_device
 22653                           && (command_loop_level + minibuf_level
 22654                               <= x_dnd_recursion_depth)
 22655                           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 22656                         goto XI_OTHER;
 22657 
 22658                       if (fabs (total_x) > 0 || fabs (total_y) > 0)
 22659                         {
 22660                           inev.ie.kind = (fabs (total_y) >= fabs (total_x)
 22661                                           ? WHEEL_EVENT : HORIZ_WHEEL_EVENT);
 22662                           inev.ie.timestamp = xev->time;
 22663 
 22664                           XSETINT (inev.ie.x, lrint (real_x));
 22665                           XSETINT (inev.ie.y, lrint (real_y));
 22666                           XSETFRAME (inev.ie.frame_or_window, f);
 22667 
 22668                           inev.ie.modifiers = (signbit (fabs (total_y) >= fabs (total_x)
 22669                                                         ? total_y : total_x)
 22670                                                ? down_modifier : up_modifier);
 22671                           inev.ie.modifiers
 22672                             |= x_x_to_emacs_modifiers (dpyinfo,
 22673                                                        xev->mods.effective);
 22674                           inev.ie.arg = list3 (Qnil,
 22675                                                make_float (total_x),
 22676                                                make_float (total_y));
 22677                         }
 22678                       else
 22679                         {
 22680                           inev.ie.kind = TOUCH_END_EVENT;
 22681                           inev.ie.timestamp = xev->time;
 22682 
 22683                           XSETINT (inev.ie.x, lrint (real_x));
 22684                           XSETINT (inev.ie.y, lrint (real_y));
 22685                           XSETFRAME (inev.ie.frame_or_window, f);
 22686                         }
 22687 
 22688                       if (source && !NILP (source->name))
 22689                         inev.ie.device = source->name;
 22690 
 22691                       if (!other_valuators_found)
 22692                         goto XI_OTHER;
 22693                     }
 22694 #ifdef HAVE_XWIDGETS
 22695                 }
 22696 #endif
 22697 #endif /* HAVE_XINPUT2_1 */
 22698 
 22699               if (!xi_position_changed (device, xev))
 22700                 goto XI_OTHER;
 22701 
 22702               ev.x = lrint (xev->event_x);
 22703               ev.y = lrint (xev->event_y);
 22704               ev.window = xev->event;
 22705               ev.time = xev->time;
 22706               ev.send_event = xev->send_event;
 22707 
 22708 #ifdef USE_MOTIF
 22709               use_copy = true;
 22710 
 22711               copy.xmotion.type = MotionNotify;
 22712               copy.xmotion.serial = xev->serial;
 22713               copy.xmotion.send_event = xev->send_event;
 22714               copy.xmotion.display = dpyinfo->display;
 22715               copy.xmotion.window = xev->event;
 22716               copy.xmotion.root = xev->root;
 22717               copy.xmotion.subwindow = xev->child;
 22718               copy.xmotion.time = xev->time;
 22719               copy.xmotion.x = lrint (xev->event_x);
 22720               copy.xmotion.y = lrint (xev->event_y);
 22721               copy.xmotion.x_root = lrint (xev->root_x);
 22722               copy.xmotion.y_root = lrint (xev->root_y);
 22723               copy.xmotion.state = xi_convert_event_state (xev);
 22724 
 22725               copy.xmotion.is_hint = False;
 22726               copy.xmotion.same_screen = True;
 22727 #endif
 22728 
 22729               previous_help_echo_string = help_echo_string;
 22730               help_echo_string = Qnil;
 22731 
 22732               if (hlinfo->mouse_face_hidden)
 22733                 {
 22734                   hlinfo->mouse_face_hidden = false;
 22735                   clear_mouse_face (hlinfo);
 22736                 }
 22737 
 22738               f = mouse_or_wdesc_frame (dpyinfo, xev->event);
 22739 
 22740               if (f && xev->event == FRAME_X_WINDOW (f))
 22741                 /* See the comment above x_compute_root_window_offset
 22742                    for why this optimization is performed.  */
 22743                 xi_compute_root_window_offset (f, xev);
 22744 
 22745               if (x_dnd_in_progress
 22746                   /* Handle these events normally if the recursion
 22747                      level is higher than when the drag-and-drop
 22748                      operation was initiated.  This is so that mouse
 22749                      input works while we're in the debugger for, say,
 22750                      `x-dnd-movement-function`.  */
 22751                   && (command_loop_level + minibuf_level
 22752                       <= x_dnd_recursion_depth)
 22753                   && xev->deviceid == x_dnd_pointer_device
 22754                   && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 22755                 {
 22756                   Window target, toplevel;
 22757                   int target_proto, motif_style;
 22758                   XRectangle *r;
 22759                   bool was_frame;
 22760 
 22761                   /* Always clear mouse face.  */
 22762                   clear_mouse_face (hlinfo);
 22763                   hlinfo->mouse_face_hidden = true;
 22764 
 22765                   /* Sometimes the drag-and-drop operation starts with the
 22766                      pointer of a frame invisible due to input.  Since
 22767                      motion events are ignored during that, make the pointer
 22768                      visible manually.  */
 22769 
 22770                   if (f)
 22771                     {
 22772                       XTtoggle_invisible_pointer (f, false);
 22773 
 22774                       r = &dpyinfo->last_mouse_glyph;
 22775 
 22776                       /* Also remember the mouse glyph and set
 22777                          mouse_moved.  */
 22778                       if (f != dpyinfo->last_mouse_glyph_frame
 22779                           || lrint (xev->event_x) < r->x
 22780                           || lrint (xev->event_x) >= r->x + r->width
 22781                           || lrint (xev->event_y) < r->y
 22782                           || lrint (xev->event_y) >= r->y + r->height)
 22783                         {
 22784                           f->mouse_moved = true;
 22785                           f->last_mouse_device = (source ? source->name
 22786                                                   : Qnil);
 22787                           dpyinfo->last_mouse_scroll_bar = NULL;
 22788 
 22789                           remember_mouse_glyph (f, lrint (xev->event_x),
 22790                                                 lrint (xev->event_y), r);
 22791                           dpyinfo->last_mouse_glyph_frame = f;
 22792                         }
 22793                     }
 22794 
 22795                   if (xev->root == dpyinfo->root_window)
 22796                     target = x_dnd_get_target_window (dpyinfo,
 22797                                                       lrint (xev->root_x),
 22798                                                       lrint (xev->root_y),
 22799                                                       &target_proto,
 22800                                                       &motif_style,
 22801                                                       &toplevel,
 22802                                                       &was_frame);
 22803                   else
 22804                     target = x_dnd_fill_empty_target (&target_proto,
 22805                                                       &motif_style,
 22806                                                       &toplevel,
 22807                                                       &was_frame);
 22808 
 22809                   if (toplevel != x_dnd_last_seen_toplevel)
 22810                     {
 22811                       if (toplevel != FRAME_OUTER_WINDOW (x_dnd_frame)
 22812                           && x_dnd_return_frame == 1)
 22813                         x_dnd_return_frame = 2;
 22814 
 22815                       if (x_dnd_return_frame == 2
 22816                           && x_any_window_to_frame (dpyinfo, toplevel))
 22817                         {
 22818                           if (x_dnd_last_seen_window != None
 22819                               && x_dnd_last_protocol_version != -1
 22820                               && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 22821                             x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window,
 22822                                               x_dnd_last_seen_toplevel);
 22823                           else if (x_dnd_last_seen_window != None
 22824                                    && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)
 22825                                    && !x_dnd_disable_motif_drag
 22826                                    && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 22827                             {
 22828                               if (!x_dnd_motif_setup_p)
 22829                                 xm_setup_drag_info (dpyinfo, x_dnd_frame);
 22830 
 22831                               lmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 22832                                                             XM_DRAG_REASON_TOP_LEVEL_LEAVE);
 22833                               lmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 22834                               lmsg.zero = 0;
 22835                               lmsg.timestamp = xev->time;
 22836                               lmsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 22837 
 22838                               if (x_dnd_motif_setup_p)
 22839                                 xm_send_top_level_leave_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 22840                                                                  x_dnd_last_seen_window, &lmsg);
 22841                             }
 22842 
 22843                           x_dnd_end_window = x_dnd_last_seen_window;
 22844                           x_dnd_last_seen_window = None;
 22845                           x_dnd_last_seen_toplevel = None;
 22846                           x_dnd_in_progress = false;
 22847                           x_dnd_return_frame_object
 22848                             = x_any_window_to_frame (dpyinfo, toplevel);
 22849                           x_dnd_return_frame = 3;
 22850                           x_dnd_waiting_for_finish = false;
 22851                           target = None;
 22852                         }
 22853                     }
 22854 
 22855                   if (target != x_dnd_last_seen_window)
 22856                     {
 22857                       if (x_dnd_last_seen_window != None
 22858                           && x_dnd_last_protocol_version != -1
 22859                           && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 22860                         x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window,
 22861                                           x_dnd_last_seen_toplevel);
 22862                       else if (x_dnd_last_seen_window != None
 22863                                && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)
 22864                                && !x_dnd_disable_motif_drag
 22865                                && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 22866                         {
 22867                           if (!x_dnd_motif_setup_p)
 22868                             xm_setup_drag_info (dpyinfo, x_dnd_frame);
 22869 
 22870                           /* This is apparently required.  If we don't
 22871                              send a motion event with the current root
 22872                              window coordinates of the pointer before
 22873                              the top level leave, then Motif displays
 22874                              an ugly black border around the previous
 22875                              drop site.  */
 22876 
 22877                           dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 22878                                                         XM_DRAG_REASON_DRAG_MOTION);
 22879                           dmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 22880                           dmsg.side_effects
 22881                             = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo,
 22882                                                                                x_dnd_wanted_action),
 22883                                                    XM_DROP_SITE_NONE, x_dnd_motif_operations,
 22884                                                    XM_DROP_ACTION_DROP_CANCEL);
 22885                           dmsg.timestamp = xev->time;
 22886                           dmsg.x = lrint (xev->root_x);
 22887                           dmsg.y = lrint (xev->root_y);
 22888 
 22889                           lmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 22890                                                         XM_DRAG_REASON_TOP_LEVEL_LEAVE);
 22891                           lmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 22892                           lmsg.zero = 0;
 22893                           lmsg.timestamp = xev->time;
 22894                           lmsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 22895 
 22896                           if (x_dnd_motif_setup_p)
 22897                             {
 22898                               xm_send_drag_motion_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 22899                                                            x_dnd_last_seen_window, &dmsg);
 22900                               xm_send_top_level_leave_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 22901                                                                x_dnd_last_seen_window, &lmsg);
 22902                             }
 22903                         }
 22904 
 22905                       x_dnd_action = None;
 22906                       x_dnd_last_seen_toplevel = toplevel;
 22907                       x_dnd_last_seen_window = target;
 22908                       x_dnd_last_protocol_version = target_proto;
 22909                       x_dnd_last_motif_style = motif_style;
 22910                       x_dnd_last_window_is_frame = was_frame;
 22911 
 22912                       if (target != None && x_dnd_last_protocol_version != -1)
 22913                         x_dnd_send_enter (x_dnd_frame, target,
 22914                                           x_dnd_last_seen_toplevel,
 22915                                           x_dnd_last_protocol_version);
 22916                       else if (target != None && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)
 22917                                && !x_dnd_disable_motif_drag)
 22918                         {
 22919                           if (!x_dnd_motif_setup_p)
 22920                             xm_setup_drag_info (dpyinfo, x_dnd_frame);
 22921 
 22922                           emsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 22923                                                         XM_DRAG_REASON_TOP_LEVEL_ENTER);
 22924                           emsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 22925                           emsg.zero = 0;
 22926                           emsg.timestamp = xev->time;
 22927                           emsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 22928                           emsg.index_atom = x_dnd_motif_atom;
 22929 
 22930                           if (x_dnd_motif_setup_p)
 22931                             xm_send_top_level_enter_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 22932                                                              target, &emsg);
 22933                         }
 22934                     }
 22935                   else
 22936                     x_dnd_last_seen_toplevel = toplevel;
 22937 
 22938                   if (x_dnd_last_window_is_frame && target != None)
 22939                     x_dnd_note_self_position (dpyinfo, target,
 22940                                               lrint (xev->root_x),
 22941                                               lrint (xev->root_y));
 22942                   else if (x_dnd_last_protocol_version != -1 && target != None)
 22943                     {
 22944                       dnd_state = xi_convert_event_state (xev);
 22945 
 22946                       x_dnd_send_position (x_dnd_frame, target,
 22947                                            x_dnd_last_seen_toplevel,
 22948                                            x_dnd_last_protocol_version,
 22949                                            lrint (xev->root_x),
 22950                                            lrint (xev->root_y),
 22951                                            x_dnd_selection_timestamp,
 22952                                            x_dnd_wanted_action, 0,
 22953                                            dnd_state);
 22954                     }
 22955                   else if (XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) && target != None
 22956                            && !x_dnd_disable_motif_drag)
 22957                     {
 22958                       if (!x_dnd_motif_setup_p)
 22959                         xm_setup_drag_info (dpyinfo, x_dnd_frame);
 22960 
 22961                       dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 22962                                                     XM_DRAG_REASON_DRAG_MOTION);
 22963                       dmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 22964                       dmsg.side_effects
 22965                         = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo,
 22966                                                                            x_dnd_wanted_action),
 22967                                                XM_DROP_SITE_VALID, x_dnd_motif_operations,
 22968                                                (!x_dnd_xm_use_help
 22969                                                 ? XM_DROP_ACTION_DROP
 22970                                                 : XM_DROP_ACTION_DROP_HELP));
 22971                       dmsg.timestamp = xev->time;
 22972                       dmsg.x = lrint (xev->root_x);
 22973                       dmsg.y = lrint (xev->root_y);
 22974 
 22975                       if (x_dnd_motif_setup_p)
 22976                         xm_send_drag_motion_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 22977                                                      target, &dmsg);
 22978                     }
 22979 
 22980                   x_dnd_update_tooltip_position (xev->root_x, xev->root_y);
 22981 
 22982                   goto XI_OTHER;
 22983                 }
 22984 
 22985 #ifdef USE_GTK
 22986               if (f && xg_event_is_for_scrollbar (f, event, false))
 22987                 f = 0;
 22988 #endif
 22989               if (f)
 22990                 {
 22991                   if (xev->event != FRAME_X_WINDOW (f))
 22992                     {
 22993                       x_translate_coordinates (f, lrint (xev->root_x),
 22994                                                lrint (xev->root_y),
 22995                                                &ev.x, &ev.y);
 22996                       ev.window = FRAME_X_WINDOW (f);
 22997                     }
 22998 
 22999                   /* Maybe generate a SELECT_WINDOW_EVENT for
 23000                      `mouse-autoselect-window' but don't let popup menus
 23001                      interfere with this (Bug#1261).  */
 23002                   if (!NILP (Vmouse_autoselect_window)
 23003                       && !popup_activated ()
 23004                       /* Don't switch if we're currently in the minibuffer.
 23005                          This tries to work around problems where the
 23006                          minibuffer gets unselected unexpectedly, and where
 23007                          you then have to move your mouse all the way down to
 23008                          the minibuffer to select it.  */
 23009                       && !MINI_WINDOW_P (XWINDOW (selected_window))
 23010                       /* With `focus-follows-mouse' non-nil create an event
 23011                          also when the target window is on another frame.  */
 23012                       && (f == XFRAME (selected_frame)
 23013                           || !NILP (focus_follows_mouse)))
 23014                     {
 23015                       static Lisp_Object last_mouse_window;
 23016                       Lisp_Object window = window_from_coordinates (f, ev.x, ev.y, 0, false, false);
 23017 
 23018                       /* A window will be autoselected only when it is not
 23019                          selected now and the last mouse movement event was
 23020                          not in it.  The remainder of the code is a bit vague
 23021                          wrt what a "window" is.  For immediate autoselection,
 23022                          the window is usually the entire window but for GTK
 23023                          where the scroll bars don't count.  For delayed
 23024                          autoselection the window is usually the window's text
 23025                          area including the margins.  */
 23026                       if (WINDOWP (window)
 23027                           && !EQ (window, last_mouse_window)
 23028                           && !EQ (window, selected_window))
 23029                         {
 23030                           inev.ie.kind = SELECT_WINDOW_EVENT;
 23031                           inev.ie.frame_or_window = window;
 23032 
 23033                           if (source)
 23034                             inev.ie.device = source->name;
 23035                         }
 23036 
 23037                       /* Remember the last window where we saw the mouse.  */
 23038                       last_mouse_window = window;
 23039                     }
 23040 
 23041                   if (!x_note_mouse_movement (f, &ev, source ? source->name : Qnil))
 23042                     help_echo_string = previous_help_echo_string;
 23043                 }
 23044               else
 23045                 {
 23046 #ifndef USE_TOOLKIT_SCROLL_BARS
 23047                   struct scroll_bar *bar
 23048                     = x_window_to_scroll_bar (dpyinfo->display, xev->event, 2);
 23049 
 23050                   if (bar)
 23051                     x_scroll_bar_note_movement (bar, &ev);
 23052 #endif /* USE_TOOLKIT_SCROLL_BARS */
 23053 
 23054                   /* If we move outside the frame, then we're
 23055                      certainly no longer on any text in the frame.  */
 23056                   clear_mouse_face (hlinfo);
 23057                 }
 23058 
 23059               /* If the contents of the global variable help_echo_string
 23060                  has changed, generate a HELP_EVENT.  */
 23061               if (!NILP (help_echo_string)
 23062                   || !NILP (previous_help_echo_string))
 23063                 {
 23064                   /* Also allow the focus and client pointer to be
 23065                      adjusted accordingly, in case a help tooltip is
 23066                      shown.  */
 23067                   gen_help_device = device;
 23068                   gen_help_time = xev->time;
 23069 
 23070                   do_help = 1;
 23071                 }
 23072 
 23073               if (f)
 23074                 x_flush_dirty_back_buffer_on (f);
 23075               goto XI_OTHER;
 23076             }
 23077 
 23078           case XI_ButtonRelease:
 23079           case XI_ButtonPress:
 23080             {
 23081               /* If we decide we want to generate an event to be seen
 23082                  by the rest of Emacs, we put it here.  */
 23083               Lisp_Object tab_bar_arg = Qnil;
 23084               bool tab_bar_p = false;
 23085               bool tool_bar_p = false;
 23086               struct xi_device_t *device, *source;
 23087 #ifdef HAVE_XWIDGETS
 23088               struct xwidget_view *xvw;
 23089 #endif
 23090               /* A fake XButtonEvent for x_construct_mouse_click. */
 23091               XButtonEvent bv;
 23092               bool dnd_grab = false;
 23093               int dnd_state;
 23094 
 23095               if (x_dnd_in_progress
 23096                   && (command_loop_level + minibuf_level
 23097                       <= x_dnd_recursion_depth)
 23098                   && xev->deviceid == x_dnd_pointer_device
 23099                   && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 23100                 {
 23101                   f = mouse_or_wdesc_frame (dpyinfo, xev->event);
 23102                   device = xi_device_from_id (dpyinfo, xev->deviceid);
 23103 
 23104                   if (f && xev->event == FRAME_X_WINDOW (f))
 23105                     /* See the comment above
 23106                        x_compute_root_window_offset for why this
 23107                        optimization is performed.  */
 23108                     xi_compute_root_window_offset (f, xev);
 23109 
 23110                   /* Don't track grab status for emulated pointer
 23111                      events, because they are ignored by the regular
 23112                      mouse click processing code.  */
 23113 #ifdef XIPointerEmulated
 23114                   if (!(xev->flags & XIPointerEmulated))
 23115                     {
 23116 #endif
 23117                       if (xev->evtype == XI_ButtonPress)
 23118                         {
 23119                           x_display_set_last_user_time (dpyinfo, xev->time,
 23120                                                         xev->send_event, true);
 23121 
 23122                           dpyinfo->grabbed |= (1 << xev->detail);
 23123                           dpyinfo->last_mouse_frame = f;
 23124 
 23125                           if (device)
 23126                             device->grab |= (1 << xev->detail);
 23127 
 23128                           if (f)
 23129                             f->last_tab_bar_item = -1;
 23130 #if ! defined (USE_GTK)
 23131                           if (f)
 23132                             f->last_tool_bar_item = -1;
 23133 #endif /* not USE_GTK */
 23134                         }
 23135                       else
 23136                         {
 23137                           dpyinfo->grabbed &= ~(1 << xev->detail);
 23138                           if (device)
 23139                             device->grab &= ~(1 << xev->detail);
 23140                         }
 23141 #ifdef XIPointerEmulated
 23142                     }
 23143 #endif
 23144 
 23145                   if (f && device)
 23146                     xi_handle_interaction (dpyinfo, f, device,
 23147                                            xev->time);
 23148 
 23149                   if (xev->evtype == XI_ButtonPress
 23150                       && x_dnd_last_seen_window != None)
 23151                     {
 23152                       dnd_state = xi_convert_event_state (xev);
 23153 
 23154                       if (x_dnd_last_window_is_frame)
 23155                         {
 23156 #ifdef XI_PointerEmulated
 23157                           /* Set the last user time here even if this
 23158                              is an emulated button event, since
 23159                              something happened in response.  */
 23160 
 23161                           if (xev->flags & XIPointerEmulated)
 23162                             x_display_set_last_user_time (dpyinfo, xev->time,
 23163                                                           xev->send_event, true);
 23164 #endif
 23165                           x_dnd_note_self_wheel (dpyinfo,
 23166                                                  x_dnd_last_seen_window,
 23167                                                  lrint (xev->root_x),
 23168                                                  lrint (xev->root_y),
 23169                                                  xev->detail, dnd_state,
 23170                                                  xev->time);
 23171                         }
 23172                       else
 23173                         x_dnd_send_position (x_dnd_frame,
 23174                                              x_dnd_last_seen_window,
 23175                                              x_dnd_last_seen_toplevel,
 23176                                              x_dnd_last_protocol_version,
 23177                                              lrint (xev->root_x),
 23178                                              lrint (xev->root_y),
 23179                                              xev->time, x_dnd_wanted_action,
 23180                                              xev->detail, dnd_state);
 23181 
 23182                       goto OTHER;
 23183                     }
 23184 
 23185                   if (xev->evtype == XI_ButtonRelease)
 23186                     {
 23187                       for (int i = 0; i < xev->buttons.mask_len * 8; ++i)
 23188                         {
 23189                           if (i != xev->detail && XIMaskIsSet (xev->buttons.mask, i))
 23190                             dnd_grab = true;
 23191                         }
 23192 
 23193                       if (!dnd_grab)
 23194                         {
 23195                           x_dnd_end_window = x_dnd_last_seen_window;
 23196                           x_dnd_in_progress = false;
 23197 
 23198                           /* If a tooltip that we're following is
 23199                              displayed, hide it now.  */
 23200 
 23201                           if (x_dnd_update_tooltip
 23202                               && FRAMEP (tip_frame)
 23203                               && FRAME_LIVE_P (XFRAME (tip_frame))
 23204                               && (FRAME_X_DISPLAY (XFRAME (tip_frame))
 23205                                   == FRAME_X_DISPLAY (x_dnd_frame)))
 23206                             Fx_hide_tip ();
 23207 
 23208                           /* This doesn't have to be marked since it
 23209                              is only accessed if
 23210                              x_dnd_waiting_for_finish is true, which
 23211                              is only possible inside the DND event
 23212                              loop where that frame is on the
 23213                              stack.  */
 23214                           x_dnd_finish_frame = x_dnd_frame;
 23215 
 23216                           if (x_dnd_last_seen_window != None
 23217                               && x_dnd_last_window_is_frame)
 23218                             {
 23219                               x_dnd_waiting_for_finish = false;
 23220                               x_dnd_note_self_drop (dpyinfo, x_dnd_last_seen_window,
 23221                                                     lrint (xev->root_x),
 23222                                                     lrint (xev->root_y), xev->time);
 23223                             }
 23224                           else if (x_dnd_last_seen_window != None
 23225                                    && x_dnd_last_protocol_version != -1)
 23226                             {
 23227                               x_dnd_pending_finish_target = x_dnd_last_seen_toplevel;
 23228                               x_dnd_waiting_for_finish_proto = x_dnd_last_protocol_version;
 23229 
 23230                               x_dnd_waiting_for_finish
 23231                                 = x_dnd_do_drop (x_dnd_last_seen_window,
 23232                                                  x_dnd_last_seen_toplevel,
 23233                                                  x_dnd_last_protocol_version);
 23234                               x_dnd_finish_display = dpyinfo->display;
 23235                             }
 23236                           else if (x_dnd_last_seen_window != None)
 23237                             {
 23238                               xm_drop_start_message dmsg;
 23239                               xm_drag_receiver_info drag_receiver_info;
 23240 
 23241                               if (!xm_read_drag_receiver_info (dpyinfo, x_dnd_last_seen_window,
 23242                                                                &drag_receiver_info)
 23243                                   && !x_dnd_disable_motif_protocol
 23244                                   && drag_receiver_info.protocol_style != XM_DRAG_STYLE_NONE
 23245                                   && (x_dnd_allow_current_frame
 23246                                       || x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame)))
 23247                                 {
 23248                                   if (!x_dnd_motif_setup_p)
 23249                                     xm_setup_drag_info (dpyinfo, x_dnd_frame);
 23250 
 23251                                   if (x_dnd_motif_setup_p)
 23252                                     {
 23253                                       memset (&dmsg, 0, sizeof dmsg);
 23254 
 23255                                       dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 23256                                                                     XM_DRAG_REASON_DROP_START);
 23257                                       dmsg.byte_order = XM_BYTE_ORDER_CUR_FIRST;
 23258                                       dmsg.side_effects
 23259                                         = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo,
 23260                                                                                            x_dnd_wanted_action),
 23261                                                                XM_DROP_SITE_VALID, x_dnd_motif_operations,
 23262                                                                (!x_dnd_xm_use_help
 23263                                                                 ? XM_DROP_ACTION_DROP
 23264                                                                 : XM_DROP_ACTION_DROP_HELP));
 23265                                       dmsg.timestamp = xev->time;
 23266                                       dmsg.x = lrint (xev->root_x);
 23267                                       dmsg.y = lrint (xev->root_y);
 23268                                       /* This atom technically has to be
 23269                                          unique to each drag-and-drop
 23270                                          operation, but that isn't easy to
 23271                                          accomplish, since we cannot
 23272                                          randomly move data around between
 23273                                          selections.  Let's hope no two
 23274                                          instances of Emacs try to drag
 23275                                          into the same window at the same
 23276                                          time.  */
 23277                                       dmsg.index_atom = x_dnd_motif_atom;
 23278                                       dmsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 23279 
 23280                                       if (!XM_DRAG_STYLE_IS_DROP_ONLY (drag_receiver_info.protocol_style))
 23281                                         x_dnd_send_xm_leave_for_drop (FRAME_DISPLAY_INFO (x_dnd_frame),
 23282                                                                       x_dnd_frame, x_dnd_last_seen_window,
 23283                                                                       xev->time);
 23284 
 23285                                       xm_send_drop_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 23286                                                             x_dnd_last_seen_window, &dmsg);
 23287 
 23288                                       x_dnd_waiting_for_finish = true;
 23289                                       x_dnd_waiting_for_motif_finish_display = dpyinfo;
 23290                                       x_dnd_waiting_for_motif_finish = 1;
 23291                                       x_dnd_finish_display = dpyinfo->display;
 23292                                     }
 23293                                 }
 23294                               else
 23295                                 x_dnd_send_unsupported_drop (dpyinfo, (x_dnd_last_seen_toplevel != None
 23296                                                                        ? x_dnd_last_seen_toplevel
 23297                                                                        : x_dnd_last_seen_window),
 23298                                                              lrint (xev->root_x),
 23299                                                              lrint (xev->root_y), xev->time);
 23300                             }
 23301                           else if (x_dnd_last_seen_toplevel != None)
 23302                             x_dnd_send_unsupported_drop (dpyinfo,
 23303                                                          x_dnd_last_seen_toplevel,
 23304                                                          lrint (xev->root_x),
 23305                                                          lrint (xev->root_y),
 23306                                                          xev->time);
 23307 
 23308                           x_dnd_last_protocol_version = -1;
 23309                           x_dnd_last_motif_style = XM_DRAG_STYLE_NONE;
 23310                           x_dnd_last_seen_window = None;
 23311                           x_dnd_last_seen_toplevel = None;
 23312                           x_dnd_last_window_is_frame = false;
 23313                           x_dnd_frame = NULL;
 23314 
 23315                           goto XI_OTHER;
 23316                         }
 23317                     }
 23318                 }
 23319 
 23320               if (x_dnd_in_progress
 23321                   && (command_loop_level + minibuf_level
 23322                       <= x_dnd_recursion_depth))
 23323                 goto XI_OTHER;
 23324 
 23325 #ifdef USE_MOTIF
 23326 #ifdef USE_TOOLKIT_SCROLL_BARS
 23327               struct scroll_bar *bar
 23328                 = x_window_to_scroll_bar (dpyinfo->display,
 23329                                           xev->event, 2);
 23330 #endif
 23331 
 23332               use_copy = true;
 23333               copy.xbutton.type = (xev->evtype == XI_ButtonPress
 23334                                    ? ButtonPress : ButtonRelease);
 23335               copy.xbutton.serial = xev->serial;
 23336               copy.xbutton.send_event = xev->send_event;
 23337               copy.xbutton.display = dpyinfo->display;
 23338               copy.xbutton.window = xev->event;
 23339               copy.xbutton.root = xev->root;
 23340               copy.xbutton.subwindow = xev->child;
 23341               copy.xbutton.time = xev->time;
 23342               copy.xbutton.x = lrint (xev->event_x);
 23343               copy.xbutton.y = lrint (xev->event_y);
 23344               copy.xbutton.x_root = lrint (xev->root_x);
 23345               copy.xbutton.y_root = lrint (xev->root_y);
 23346               copy.xbutton.state = xi_convert_event_state (xev);
 23347               copy.xbutton.button = xev->detail;
 23348               copy.xbutton.same_screen = True;
 23349 
 23350 #elif defined USE_GTK && !defined HAVE_GTK3
 23351               copy = gdk_event_new (xev->evtype == XI_ButtonPress
 23352                                     ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE);
 23353 
 23354               copy->button.window = gdk_x11_window_lookup_for_display (gdpy, xev->event);
 23355               copy->button.send_event = xev->send_event;
 23356               copy->button.time = xev->time;
 23357               copy->button.x = xev->event_x;
 23358               copy->button.y = xev->event_y;
 23359               copy->button.x_root = xev->root_x;
 23360               copy->button.y_root = xev->root_y;
 23361               copy->button.state = xi_convert_event_state (xev);
 23362               copy->button.button = xev->detail;
 23363 
 23364               if (!copy->button.window)
 23365                 emacs_abort ();
 23366 
 23367               g_object_ref (copy->button.window);
 23368 
 23369               if (popup_activated ())
 23370                 {
 23371                   /* GTK+ popup menus don't respond to core buttons
 23372                      after Button3, so don't dismiss popup menus upon
 23373                      wheel movement here either.  */
 23374                   if (xev->detail > 3)
 23375                     *finish = X_EVENT_DROP;
 23376 
 23377                   if (xev->evtype == XI_ButtonRelease)
 23378                     goto XI_OTHER;
 23379                 }
 23380 #endif
 23381 
 23382 #ifdef HAVE_XINPUT2_1
 23383               /* Ignore emulated scroll events when XI2 native
 23384                  scroll events are present.  */
 23385               if (xev->flags & XIPointerEmulated)
 23386                 {
 23387 #if !defined USE_MOTIF || !defined USE_TOOLKIT_SCROLL_BARS
 23388                   *finish = X_EVENT_DROP;
 23389 #else
 23390                   if (bar)
 23391                     *finish = X_EVENT_DROP;
 23392 #endif
 23393                   goto XI_OTHER;
 23394                 }
 23395 #endif
 23396 
 23397               if (xev->evtype == XI_ButtonPress)
 23398                 x_display_set_last_user_time (dpyinfo, xev->time,
 23399                                               xev->send_event, true);
 23400 
 23401               source = xi_device_from_id (dpyinfo, xev->sourceid);
 23402               device = xi_device_from_id (dpyinfo, xev->deviceid);
 23403 
 23404 #ifdef HAVE_XWIDGETS
 23405               xvw = xwidget_view_from_window (xev->event);
 23406               if (xvw)
 23407                 {
 23408                   /* If the user interacts with a frame that's focused
 23409                      on another device, but not the current focus
 23410                      frame, make it the focus frame.  */
 23411                   if (device)
 23412                     xi_handle_interaction (dpyinfo, xvw->frame,
 23413                                            device, xev->time);
 23414 
 23415                   xwidget_button (xvw, xev->evtype == XI_ButtonPress,
 23416                                   lrint (xev->event_x), lrint (xev->event_y),
 23417                                   xev->detail, xi_convert_event_state (xev),
 23418                                   xev->time);
 23419 
 23420                   if (!EQ (selected_window, xvw->w) && (xev->detail < 4))
 23421                     {
 23422                       inev.ie.kind = SELECT_WINDOW_EVENT;
 23423                       inev.ie.frame_or_window = xvw->w;
 23424 
 23425                       if (source)
 23426                         inev.ie.device = source->name;
 23427                     }
 23428 
 23429                   *finish = X_EVENT_DROP;
 23430                   goto XI_OTHER;
 23431                 }
 23432 #endif
 23433 
 23434               if (!device)
 23435                 goto XI_OTHER;
 23436 
 23437               bv.button = xev->detail;
 23438               bv.type = xev->evtype == XI_ButtonPress ? ButtonPress : ButtonRelease;
 23439               bv.x = lrint (xev->event_x);
 23440               bv.y = lrint (xev->event_y);
 23441               bv.x_root = lrint (xev->root_x);
 23442               bv.y_root = lrint (xev->root_y);
 23443               bv.window = xev->event;
 23444               bv.state = xi_convert_event_state (xev);
 23445               bv.time = xev->time;
 23446 
 23447               dpyinfo->last_mouse_glyph_frame = NULL;
 23448 
 23449               f = mouse_or_wdesc_frame (dpyinfo, xev->event);
 23450 
 23451               if (f && xev->event == FRAME_X_WINDOW (f))
 23452                 /* See the comment above x_compute_root_window_offset
 23453                    for why this optimization is performed.  */
 23454                 xi_compute_root_window_offset (f, xev);
 23455 
 23456               if (f && xev->evtype == XI_ButtonPress
 23457                   && !popup_activated ()
 23458                   && !x_window_to_scroll_bar (dpyinfo->display, xev->event, 2)
 23459                   && !FRAME_NO_ACCEPT_FOCUS (f))
 23460                 {
 23461                   /* When clicking into a child frame or when clicking
 23462                      into a parent frame with the child frame selected and
 23463                      `no-accept-focus' is not set, select the clicked
 23464                      frame.  */
 23465                   struct frame *hf = dpyinfo->highlight_frame;
 23466 
 23467                   if (FRAME_PARENT_FRAME (f) || (hf && frame_ancestor_p (f, hf)))
 23468                     {
 23469 #if defined HAVE_GTK3 || (!defined USE_GTK && !defined USE_X_TOOLKIT)
 23470                       if (device)
 23471                         {
 23472                           /* This can generate XI_BadDevice if the
 23473                              device's attachment was destroyed
 23474                              server-side.  */
 23475                           x_ignore_errors_for_next_request (dpyinfo, 0);
 23476                           XISetFocus (dpyinfo->display, device->attachment,
 23477                                       /* Note that the input extension
 23478                                          only supports RevertToParent-type
 23479                                          behavior.  */
 23480                                       FRAME_OUTER_WINDOW (f), xev->time);
 23481                           x_stop_ignoring_errors (dpyinfo);
 23482                         }
 23483 #else
 23484                       /* Non-no toolkit builds without GTK 3 use core
 23485                          events to handle focus.  Errors are still
 23486                          caught here in case the window is not
 23487                          viewable.  */
 23488                       x_ignore_errors_for_next_request (dpyinfo, 0);
 23489                       XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 23490                                       RevertToParent, xev->time);
 23491                       x_stop_ignoring_errors (dpyinfo);
 23492 #endif
 23493                       if (FRAME_PARENT_FRAME (f))
 23494                         XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f));
 23495                     }
 23496                 }
 23497 
 23498               if (f)
 23499                 {
 23500                   /* If the user interacts with a frame that's focused
 23501                      on another device, but not the current focus
 23502                      frame, make it the focus frame.  */
 23503                   if (device)
 23504                     xi_handle_interaction (dpyinfo, f, device,
 23505                                            xev->time);
 23506                 }
 23507 
 23508 #ifdef USE_GTK
 23509               if (!f)
 23510                 {
 23511                   int real_x = lrint (xev->root_x);
 23512                   int real_y = lrint (xev->root_y);
 23513 
 23514                   f = x_any_window_to_frame (dpyinfo, xev->event);
 23515 
 23516                   if (xev->detail > 3 && xev->detail < 8 && f)
 23517                     {
 23518                       if (xev->evtype == XI_ButtonRelease)
 23519                         {
 23520                           if (FRAME_X_WINDOW (f) != xev->event)
 23521                             x_translate_coordinates (f, real_x, real_y,
 23522                                                      &real_x, &real_y);
 23523 
 23524                           if (xev->detail <= 5)
 23525                             inev.ie.kind = WHEEL_EVENT;
 23526                           else
 23527                             inev.ie.kind = HORIZ_WHEEL_EVENT;
 23528 
 23529                           if (source)
 23530                             inev.ie.device = source->name;
 23531 
 23532                           inev.ie.timestamp = xev->time;
 23533 
 23534                           XSETINT (inev.ie.x, real_x);
 23535                           XSETINT (inev.ie.y, real_y);
 23536                           XSETFRAME (inev.ie.frame_or_window, f);
 23537 
 23538                           inev.ie.modifiers
 23539                             |= x_x_to_emacs_modifiers (dpyinfo,
 23540                                                        xev->mods.effective);
 23541 
 23542                           inev.ie.modifiers |= xev->detail % 2 ? down_modifier : up_modifier;
 23543                         }
 23544 
 23545                       *finish = X_EVENT_DROP;
 23546                       goto XI_OTHER;
 23547                     }
 23548                   else
 23549                     f = NULL;
 23550                 }
 23551 
 23552               if (f && xg_event_is_for_scrollbar (f, event, false))
 23553                 f = 0;
 23554 #endif
 23555 
 23556               if (f)
 23557                 {
 23558                   if (xev->detail >= 4 && xev->detail < 8)
 23559                     {
 23560                       if (xev->evtype == XI_ButtonRelease)
 23561                         {
 23562                           if (xev->detail <= 5)
 23563                             inev.ie.kind = WHEEL_EVENT;
 23564                           else
 23565                             inev.ie.kind = HORIZ_WHEEL_EVENT;
 23566 
 23567                           if (source)
 23568                             inev.ie.device = source->name;
 23569 
 23570                           inev.ie.timestamp = xev->time;
 23571 
 23572                           XSETINT (inev.ie.x, lrint (xev->event_x));
 23573                           XSETINT (inev.ie.y, lrint (xev->event_y));
 23574                           XSETFRAME (inev.ie.frame_or_window, f);
 23575 
 23576                           inev.ie.modifiers
 23577                             |= x_x_to_emacs_modifiers (dpyinfo,
 23578                                                        xev->mods.effective);
 23579 
 23580                           inev.ie.modifiers |= xev->detail % 2 ? down_modifier : up_modifier;
 23581                         }
 23582 
 23583                       goto XI_OTHER;
 23584                     }
 23585 
 23586                   /* Is this in the tab-bar?  */
 23587                   if (WINDOWP (f->tab_bar_window)
 23588                       && WINDOW_TOTAL_LINES (XWINDOW (f->tab_bar_window)))
 23589                     {
 23590                       Lisp_Object window;
 23591                       int x = bv.x;
 23592                       int y = bv.y;
 23593 
 23594                       window = window_from_coordinates (f, x, y, 0, true, true);
 23595                       tab_bar_p = EQ (window, f->tab_bar_window);
 23596 
 23597                       if (tab_bar_p)
 23598                         {
 23599                           tab_bar_arg = handle_tab_bar_click
 23600                             (f, x, y, xev->evtype == XI_ButtonPress,
 23601                              x_x_to_emacs_modifiers (dpyinfo, bv.state));
 23602                           x_flush_dirty_back_buffer_on (f);
 23603                         }
 23604                     }
 23605 
 23606 #if ! defined (USE_GTK)
 23607                   /* Is this in the tool-bar?  */
 23608                   if (WINDOWP (f->tool_bar_window)
 23609                       && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)))
 23610                     {
 23611                       Lisp_Object window;
 23612                       int x = bv.x;
 23613                       int y = bv.y;
 23614 
 23615                       window = window_from_coordinates (f, x, y, 0, true, true);
 23616                       /* Ignore button release events if the mouse
 23617                          wasn't previously pressed on the tool bar.
 23618                          We do this because otherwise selecting some
 23619                          text with the mouse and then releasing it on
 23620                          the tool bar doesn't stop selecting text,
 23621                          since the tool bar eats the button up
 23622                          event.  */
 23623                       tool_bar_p = (EQ (window, f->tool_bar_window)
 23624                                     && (xev->evtype != XI_ButtonRelease
 23625                                         || f->last_tool_bar_item != -1));
 23626 
 23627                       if (tool_bar_p && xev->detail < 4)
 23628                         {
 23629                           handle_tool_bar_click_with_device
 23630                             (f, x, y, xev->evtype == XI_ButtonPress,
 23631                              x_x_to_emacs_modifiers (dpyinfo, bv.state),
 23632                              source ? source->name : Qt);
 23633                           x_flush_dirty_back_buffer_on (f);
 23634                         }
 23635                     }
 23636 #endif /* !USE_GTK */
 23637 
 23638                   if (!(tab_bar_p && NILP (tab_bar_arg)) && !tool_bar_p)
 23639 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
 23640                     if (! popup_activated ())
 23641 #endif
 23642                       {
 23643                         if (ignore_next_mouse_click_timeout)
 23644                           {
 23645                             if (xev->evtype == XI_ButtonPress
 23646                                 && xev->time > ignore_next_mouse_click_timeout)
 23647                               {
 23648                                 ignore_next_mouse_click_timeout = 0;
 23649                                 x_construct_mouse_click (&inev.ie, &bv, f);
 23650                               }
 23651                             if (xev->evtype == XI_ButtonRelease)
 23652                               ignore_next_mouse_click_timeout = 0;
 23653                           }
 23654                         else
 23655                           x_construct_mouse_click (&inev.ie, &bv, f);
 23656 
 23657                         if (!NILP (tab_bar_arg))
 23658                           inev.ie.arg = tab_bar_arg;
 23659                       }
 23660 
 23661                   if (FRAME_X_EMBEDDED_P (f)
 23662                       && !FRAME_NO_ACCEPT_FOCUS (f))
 23663                     xembed_send_message (f, xev->time,
 23664                                          XEMBED_REQUEST_FOCUS, 0, 0, 0);
 23665                 }
 23666               else
 23667                 {
 23668                   struct scroll_bar *bar
 23669                     = x_window_to_scroll_bar (dpyinfo->display,
 23670                                               xev->event, 2);
 23671 
 23672 #ifndef USE_TOOLKIT_SCROLL_BARS
 23673                   if (bar)
 23674                     x_scroll_bar_handle_click (bar, (XEvent *) &bv, &inev.ie,
 23675                                                source ? source->name : Qnil);
 23676 #else
 23677                   /* Make the "Ctrl-Mouse-2 splits window" work for toolkit
 23678                      scroll bars.  */
 23679                   if (bar && xev->mods.effective & ControlMask)
 23680                     {
 23681                       x_scroll_bar_handle_click (bar, (XEvent *) &bv, &inev.ie,
 23682                                                  source ? source->name : Qnil);
 23683                       *finish = X_EVENT_DROP;
 23684                     }
 23685 #endif
 23686                 }
 23687 
 23688               if (xev->evtype == XI_ButtonPress)
 23689                 {
 23690                   dpyinfo->grabbed |= (1 << xev->detail);
 23691                   device->grab |= (1 << xev->detail);
 23692                   dpyinfo->last_mouse_frame = f;
 23693                   if (f && !tab_bar_p)
 23694                     f->last_tab_bar_item = -1;
 23695 #if ! defined (USE_GTK)
 23696                   if (f && !tool_bar_p)
 23697                     f->last_tool_bar_item = -1;
 23698 #endif /* not USE_GTK */
 23699 
 23700                 }
 23701               else
 23702                 {
 23703                   dpyinfo->grabbed &= ~(1 << xev->detail);
 23704                   device->grab &= ~(1 << xev->detail);
 23705                 }
 23706 
 23707               if (source && inev.ie.kind != NO_EVENT)
 23708                 inev.ie.device = source->name;
 23709 
 23710               if (f)
 23711                 f->mouse_moved = false;
 23712 
 23713 #if defined (USE_GTK)
 23714               /* No Xt toolkit currently available has support for XI2.
 23715                  So the code here assumes use of GTK.  */
 23716               f = x_menubar_window_to_frame (dpyinfo, event);
 23717               if (f /* Gtk+ menus only react to the first three buttons. */
 23718                   && xev->detail < 3)
 23719                 {
 23720                   /* What is done with Core Input ButtonPressed is not
 23721                      possible here, because GenericEvents cannot be saved.  */
 23722                   bool was_waiting_for_input = waiting_for_input;
 23723                   /* This hack was adopted from the NS port.  Whether
 23724                      or not it is actually safe is a different story
 23725                      altogether.  */
 23726                   if (waiting_for_input)
 23727                     waiting_for_input = 0;
 23728                   set_frame_menubar (f, true);
 23729                   waiting_for_input = was_waiting_for_input;
 23730                 }
 23731 #endif
 23732               goto XI_OTHER;
 23733             }
 23734 
 23735           case XI_KeyPress:
 23736             {
 23737               int state = xev->mods.effective;
 23738               Lisp_Object c;
 23739 #ifdef HAVE_XKB
 23740               unsigned int mods_rtrn;
 23741 #endif /* HAVE_XKB */
 23742               int keycode = xev->detail;
 23743               KeySym keysym;
 23744               char copy_buffer[81];
 23745               char *copy_bufptr = copy_buffer;
 23746               int copy_bufsiz = sizeof (copy_buffer);
 23747               ptrdiff_t i;
 23748               unsigned int old_state;
 23749               struct xi_device_t *device, *source;
 23750               XKeyPressedEvent xkey;
 23751 
 23752               coding = Qlatin_1;
 23753 
 23754               /* The code under this label is quite desultory.  There
 23755                  are also several important discrepancies with the
 23756                  core KeyPress code to mind.
 23757 
 23758                  There are three principal objectives:
 23759 
 23760                  The first is to produce a core or GDK translation of
 23761                  this XI_KeyPress event, which is relayed to the
 23762                  toolkit.  This transpires by setting `copy' to a
 23763                  close copy of XEV, which is later copied or
 23764                  dispatched to the toolkit by the code beneath the
 23765                  OTHER label.
 23766 
 23767                  The second objective is to filter the event through
 23768                  an input method, by generating a second copy of the
 23769                  event expressly tailored for such a purpose.  The
 23770                  core KeyPress code does not endeavor to do so;
 23771                  instead, this action is taken prior to calling
 23772                  handle_one_xevent.  Calls to `x_filter_event' or
 23773                  `xg_filter_key' serve to implement this objective.
 23774 
 23775                  If the event is not removed by the input method's
 23776                  filter, the third objective is to establish either a
 23777                  keysym or a sequence of characters to insert, using
 23778                  the information supplied within the key event.
 23779 
 23780                  When an input method connection is available, this
 23781                  responsibility is vested in the hands of the input
 23782                  method -- yet another copy of XEV as a core event is
 23783                  produced, and the input method is responsible for
 23784                  deriving a keysym or text to insert.
 23785 
 23786                  Otherwise, if the XKB extension is available, calls
 23787                  are made to XkbTranslateKeyCode and
 23788                  XkbTranslateKeySym.
 23789 
 23790                  And if all else fails, XEV is transformed into a core
 23791                  event and provided to XLookupString, in a manner
 23792                  analogous to the core event processing under the
 23793                  KeyPress label.
 23794 
 23795                  A wide number of variables are employed during this
 23796                  translation process.  The most pertinent ones are:
 23797 
 23798                  `copy'
 23799 
 23800                    This variable is defined when an X toolkit
 23801                    incognizant of input extension events is being
 23802                    employed.  If a popup is active, Emacs copies
 23803                    fields of interest from the extension event to
 23804                    COPY, sets the `use_copy' flag, and jumps to the
 23805                    XI_OTHER label.  `copy' is then relayed to the
 23806                    toolkit.
 23807 
 23808                  `xkey'
 23809 
 23810                    This variable is defined to a copy of the event
 23811                    used by input methods or XLookupString at various
 23812                    points during the execution of this label.
 23813 
 23814                  `coding'
 23815 
 23816                    This variable is consulted at the conclusion of
 23817                    event generation, and holds the coding system
 23818                    for any generated string.
 23819 
 23820                  `keysym'
 23821 
 23822                    This variable is eventually set to the keysym tied
 23823                    to the event, which may be directly provided within
 23824                    a generated struct input_event, should it bear a
 23825                    direct relation to an ASCII or Unicode character,
 23826                    or if it is a control key.
 23827 
 23828                  `copy_buffer', `copy_bufptr', `copy_bufsiz'
 23829 
 23830                    These variables hold the buffer that incorporates
 23831                    characters generated during the keycode-to-keysym
 23832                    conversion process.
 23833 
 23834                  `nbytes'
 23835 
 23836                    Holds the number of characters within that buffer,
 23837                    in bytes.  These characters are encoded using the
 23838                    coding system in `coding'.
 23839 
 23840                    If greater than 0 and KEYSYM does not immediately
 23841                    relate to a function key, control key or character,
 23842                    it is provided as the string to insert within a
 23843                    MULTIBYTE_CHAR_KEYSTROKE_EVENT.
 23844 
 23845                  `state'
 23846 
 23847                    Holds the keyboard and group (but not button)
 23848                    state.  After event filtering concludes, modifier
 23849                    bits within `extra_keyboard_modifiers' are also
 23850                    introduced.
 23851 
 23852                  This illustration may reflect the treatment taken
 23853                  towards core key events to some degree.  */
 23854 
 23855               device = xi_device_from_id (dpyinfo, xev->deviceid);
 23856               source = xi_device_from_id (dpyinfo, xev->sourceid);
 23857 
 23858               if (!device)
 23859                 goto XI_OTHER;
 23860 
 23861               /* Convert the keyboard state within XEV to a core
 23862                  modifier mask, later supplied as arguments to XKB and
 23863                  core functions.  This encompasses the keyboard group
 23864                  and effective modifiers but not the button state.  */
 23865               state = xi_convert_event_keyboard_state (xev);
 23866 
 23867 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
 23868               /* Dispatch XI_KeyPress events when in menu.  */
 23869               if (popup_activated ())
 23870                 {
 23871 #ifdef USE_LUCID
 23872                   /* This makes key navigation work inside menus.  */
 23873                   use_copy = true;
 23874                   copy.xkey.type = KeyPress;
 23875                   copy.xkey.serial = xev->serial;
 23876                   copy.xkey.send_event = xev->send_event;
 23877                   copy.xkey.display = dpyinfo->display;
 23878                   copy.xkey.window = xev->event;
 23879                   copy.xkey.root = xev->root;
 23880                   copy.xkey.subwindow = xev->child;
 23881                   copy.xkey.time = xev->time;
 23882                   copy.xkey.state = state;
 23883                   xi_convert_button_state (&xev->buttons, &copy.xkey.state);
 23884 
 23885                   copy.xkey.x = lrint (xev->event_x);
 23886                   copy.xkey.y = lrint (xev->event_y);
 23887                   copy.xkey.x_root = lrint (xev->root_x);
 23888                   copy.xkey.y_root = lrint (xev->root_y);
 23889                   copy.xkey.keycode = xev->detail;
 23890                   copy.xkey.same_screen = True;
 23891 #endif /* USE_LUCID */
 23892                   goto XI_OTHER;
 23893                 }
 23894 #endif /* USE_X_TOOLKIT || USE_GTK */
 23895 
 23896               x_display_set_last_user_time (dpyinfo, xev->time,
 23897                                             xev->send_event, true);
 23898               ignore_next_mouse_click_timeout = 0;
 23899 
 23900               f = x_any_window_to_frame (dpyinfo, xev->event);
 23901 
 23902               if (f && xev->event == FRAME_X_WINDOW (f))
 23903                 /* See the comment above x_compute_root_window_offset
 23904                    for why this optimization is performed.  */
 23905                 xi_compute_root_window_offset (f, xev);
 23906 
 23907               /* GTK handles TAB events in an undesirable manner, so
 23908                  keyboard events are always dropped.  But as a side
 23909                  effect, the user time will no longer be set by GDK,
 23910                  so do that manually.  */
 23911 #ifdef USE_GTK
 23912               if (f)
 23913                 x_set_gtk_user_time (f, xev->time);
 23914 #endif /* USE_GTK */
 23915 
 23916               if (f)
 23917                 {
 23918                   /* If the user interacts with a frame that's focused
 23919                      on another device, but not the current focus
 23920                      frame, make it the focus frame.  */
 23921                   if (device)
 23922                     xi_handle_interaction (dpyinfo, f, device,
 23923                                            xev->time);
 23924                 }
 23925 
 23926               /* Convert the XI event into a core event structure
 23927                  provided to old Xlib functions and input method
 23928                  filter functions.  */
 23929 
 23930               memset (&xkey, 0, sizeof xkey);
 23931 
 23932               xkey.type = KeyPress;
 23933               xkey.serial = xev->serial;
 23934               xkey.send_event = xev->send_event;
 23935               xkey.display = dpyinfo->display;
 23936               xkey.window = xev->event;
 23937               xkey.root = xev->root;
 23938               xkey.subwindow = xev->child;
 23939               xkey.time = xev->time;
 23940               xkey.state = state;
 23941               xkey.x = lrint (xev->event_x);
 23942               xkey.y = lrint (xev->event_y);
 23943               xkey.x_root = lrint (xev->root_x);
 23944               xkey.y_root = lrint (xev->root_y);
 23945 
 23946               /* Some input methods react differently depending on the
 23947                  buttons that are pressed.  */
 23948               xi_convert_button_state (&xev->buttons, &xkey.state);
 23949 
 23950               xkey.keycode = xev->detail;
 23951               xkey.same_screen = True;
 23952 
 23953 #ifdef HAVE_X_I18N
 23954 #ifdef USE_GTK
 23955               if ((!x_gtk_use_native_input
 23956                    && x_filter_event (dpyinfo, (XEvent *) &xkey))
 23957                   || (x_gtk_use_native_input
 23958                       && x_filter_event (dpyinfo, event)))
 23959                 {
 23960                   /* Try to attribute core key events from the input
 23961                      method to the input extension event that caused
 23962                      them.  */
 23963                   dpyinfo->pending_keystroke_time = xev->time;
 23964                   dpyinfo->pending_keystroke_source = xev->sourceid;
 23965 
 23966                   *finish = X_EVENT_DROP;
 23967                   goto XI_OTHER;
 23968                 }
 23969 #else /* !USE_GTK */
 23970               if (x_filter_event (dpyinfo, (XEvent *) &xkey))
 23971                 {
 23972                   /* Try to attribute core key events from the input
 23973                      method to the input extension event that caused
 23974                      them.  */
 23975                   dpyinfo->pending_keystroke_time = xev->time;
 23976                   dpyinfo->pending_keystroke_source = xev->sourceid;
 23977 
 23978                   *finish = X_EVENT_DROP;
 23979                   goto XI_OTHER;
 23980                 }
 23981 #endif /* HAVE_X_I18N */
 23982 #elif USE_GTK /* && !HAVE_X_I18N */
 23983               if ((x_gtk_use_native_input
 23984                    || dpyinfo->prefer_native_input)
 23985                   && xg_filter_key (any, event))
 23986                 {
 23987                   /* Try to attribute core key events from the input
 23988                      method to the input extension event that caused
 23989                      them.  */
 23990                   dpyinfo->pending_keystroke_time = xev->time;
 23991                   dpyinfo->pending_keystroke_source = xev->sourceid;
 23992 
 23993                   *finish = X_EVENT_DROP;
 23994                   goto XI_OTHER;
 23995                 }
 23996 #endif /* HAVE_X_I18N || USE_GTK */
 23997 
 23998               state |= x_emacs_to_x_modifiers (dpyinfo, extra_keyboard_modifiers);
 23999 
 24000               /* If mouse-highlight is an integer, input clears out
 24001                  mouse highlighting.  */
 24002               if (!hlinfo->mouse_face_hidden && FIXNUMP (Vmouse_highlight)
 24003                   && (f == 0
 24004 #if ! defined (USE_GTK)
 24005                       || !EQ (f->tool_bar_window, hlinfo->mouse_face_window)
 24006 #endif /* !USE_GTK */
 24007                       || !EQ (f->tab_bar_window, hlinfo->mouse_face_window))
 24008                   )
 24009                 {
 24010                   mouse_frame = hlinfo->mouse_face_mouse_frame;
 24011 
 24012                   clear_mouse_face (hlinfo);
 24013                   hlinfo->mouse_face_hidden = true;
 24014 
 24015                   if (mouse_frame)
 24016                     x_flush_dirty_back_buffer_on (mouse_frame);
 24017                 }
 24018 
 24019               if (f != 0)
 24020                 {
 24021 #ifdef USE_GTK
 24022                   /* Don't pass keys to GTK.  A Tab will shift focus to the
 24023                      tool bar in GTK 2.4.  Keys will still go to menus and
 24024                      dialogs because in that case popup_activated is nonzero
 24025                      (see above).  */
 24026                   *finish = X_EVENT_DROP;
 24027 #endif /* USE_GTK */
 24028 
 24029                   XSETFRAME (inev.ie.frame_or_window, f);
 24030                   inev.ie.timestamp = xev->time;
 24031 
 24032 #ifdef HAVE_X_I18N
 24033                   if (FRAME_XIC (f))
 24034                     {
 24035                       Status status_return;
 24036                       nbytes = XmbLookupString (FRAME_XIC (f),
 24037                                                 &xkey, (char *) copy_bufptr,
 24038                                                 copy_bufsiz, &keysym,
 24039                                                 &status_return);
 24040                       coding = FRAME_X_XIM_CODING (f);
 24041 
 24042                       if (status_return == XBufferOverflow)
 24043                         {
 24044                           copy_bufsiz = nbytes + 1;
 24045                           copy_bufptr = SAFE_ALLOCA (copy_bufsiz);
 24046                           nbytes = XmbLookupString (FRAME_XIC (f),
 24047                                                     &xkey, (char *) copy_bufptr,
 24048                                                     copy_bufsiz, &keysym,
 24049                                                     &status_return);
 24050                         }
 24051 
 24052                       if (status_return == XLookupNone)
 24053                         goto xi_done_keysym;
 24054                       else if (status_return == XLookupChars)
 24055                         {
 24056                           keysym = NoSymbol;
 24057                           state = 0;
 24058                         }
 24059                       else if (status_return != XLookupKeySym
 24060                                && status_return != XLookupBoth)
 24061                         emacs_abort ();
 24062                     }
 24063                   else
 24064 #endif /* HAVE_X_I18N */
 24065                     {
 24066 #ifdef HAVE_XKB
 24067                       if (dpyinfo->xkb_desc)
 24068                         {
 24069                           KeySym sym;
 24070                           int overflow;
 24071 
 24072                           /* Translate the keycode into the keysym it
 24073                              represents, using STATE.  MODS_RTRN is
 24074                              set to the modifier bits consumed while
 24075                              undertaking this translation and should
 24076                              be subsequently ignored during keysym
 24077                              translation.  */
 24078 
 24079                           if (!XkbTranslateKeyCode (dpyinfo->xkb_desc,
 24080                                                     keycode, state,
 24081                                                     &mods_rtrn, &keysym))
 24082                             goto xi_done_keysym;
 24083 
 24084                           /* Save the original keysym in case
 24085                              XkbTranslateKeySym overflows.  */
 24086                           sym = keysym, overflow = 0;
 24087 
 24088                           /* Translate this keysym and its modifier
 24089                              state into the actual symbol and string
 24090                              it represents.  */
 24091                           nbytes = XkbTranslateKeySym (dpyinfo->display,
 24092                                                        &keysym,
 24093                                                        state & ~mods_rtrn,
 24094                                                        copy_bufptr,
 24095                                                        copy_bufsiz,
 24096                                                        &overflow);
 24097                           if (overflow)
 24098                             {
 24099                               copy_bufptr
 24100                                 = SAFE_ALLOCA ((copy_bufsiz += overflow)
 24101                                                * sizeof *copy_bufptr);
 24102                               overflow = 0;
 24103 
 24104                               /* Use the original keysym derived from
 24105                                  the keycode translation.  */
 24106                               nbytes = XkbTranslateKeySym (dpyinfo->display,
 24107                                                            &sym,
 24108                                                            state & ~mods_rtrn,
 24109                                                            copy_bufptr,
 24110                                                            copy_bufsiz,
 24111                                                            &overflow);
 24112 
 24113                               if (overflow)
 24114                                 nbytes = 0;
 24115                             }
 24116 
 24117                           coding = Qnil;
 24118                         }
 24119                       else
 24120 #endif /* HAVE_XKB */
 24121                         {
 24122                           /* Save the state within XKEY, then remove
 24123                              all modifier keys Emacs understands from
 24124                              it, forestalling any attempt by
 24125                              XLookupString to introduce control
 24126                              characters.  */
 24127 
 24128                           old_state = xkey.state;
 24129                           xkey.state &= ~ControlMask;
 24130                           xkey.state &= ~(dpyinfo->meta_mod_mask
 24131                                           | dpyinfo->super_mod_mask
 24132                                           | dpyinfo->hyper_mod_mask
 24133                                           | dpyinfo->alt_mod_mask);
 24134 
 24135                           nbytes = XLookupString (&xkey, copy_bufptr,
 24136                                                   copy_bufsiz, &keysym,
 24137                                                   NULL);
 24138 
 24139                           xkey.state = old_state;
 24140                         }
 24141                     }
 24142 
 24143                   inev.ie.modifiers = x_x_to_emacs_modifiers (dpyinfo, state);
 24144 
 24145 #ifdef XK_F1
 24146                   if (x_dnd_in_progress
 24147                       && xev->deviceid == x_dnd_keyboard_device
 24148                       && keysym == XK_F1)
 24149                     {
 24150                       x_dnd_xm_use_help = true;
 24151                       goto xi_done_keysym;
 24152                     }
 24153 #endif /* XK_F1 */
 24154 
 24155                   /* See if keysym should make Emacs quit.  */
 24156 
 24157                   if (keysym == dpyinfo->quit_keysym
 24158                       && (xev->time - dpyinfo->quit_keysym_time
 24159                           <= 350))
 24160                     {
 24161                       Vquit_flag = Qt;
 24162                       goto xi_done_keysym;
 24163                     }
 24164 
 24165                   if (keysym == dpyinfo->quit_keysym)
 24166                     {
 24167                       /* Otherwise, set the last time that keysym was
 24168                          pressed.  */
 24169                       dpyinfo->quit_keysym_time = xev->time;
 24170                       goto xi_done_keysym;
 24171                     }
 24172 
 24173                   /* First deal with keysyms which have defined
 24174                      translations to characters.  */
 24175                   if (keysym >= 32 && keysym < 128)
 24176                     /* Avoid explicitly decoding each ASCII character.  */
 24177                     {
 24178                       inev.ie.kind = ASCII_KEYSTROKE_EVENT;
 24179                       inev.ie.code = keysym;
 24180 
 24181                       if (source)
 24182                         inev.ie.device = source->name;
 24183 
 24184                       goto xi_done_keysym;
 24185                     }
 24186 
 24187                   /* Keysyms directly mapped to Unicode characters.  */
 24188                   if (keysym >= 0x01000000 && keysym <= 0x0110FFFF)
 24189                     {
 24190                       if (keysym < 0x01000080)
 24191                         inev.ie.kind = ASCII_KEYSTROKE_EVENT;
 24192                       else
 24193                         inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
 24194 
 24195                       if (source)
 24196                         inev.ie.device = source->name;
 24197 
 24198                       inev.ie.code = keysym & 0xFFFFFF;
 24199                       goto xi_done_keysym;
 24200                     }
 24201 
 24202                   /* Now non-ASCII.  */
 24203                   if (HASH_TABLE_P (Vx_keysym_table)
 24204                       && (c = Fgethash (make_fixnum (keysym),
 24205                                         Vx_keysym_table,
 24206                                         Qnil),
 24207                           FIXNATP (c)))
 24208                     {
 24209                       inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFIXNAT (c))
 24210                                       ? ASCII_KEYSTROKE_EVENT
 24211                                       : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
 24212                       inev.ie.code = XFIXNAT (c);
 24213 
 24214                       if (source)
 24215                         inev.ie.device = source->name;
 24216 
 24217                       goto xi_done_keysym;
 24218                     }
 24219 
 24220                   /* Random non-modifier sorts of keysyms.  */
 24221                   if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
 24222                        || keysym == XK_Delete
 24223 #ifdef XK_ISO_Left_Tab
 24224                        || (keysym >= XK_ISO_Left_Tab
 24225                            && keysym <= XK_ISO_Enter)
 24226 #endif
 24227                        || IsCursorKey (keysym) /* 0xff50 <= x < 0xff60 */
 24228                        || IsMiscFunctionKey (keysym) /* 0xff60 <= x < VARIES */
 24229 #ifdef HPUX
 24230                        /* This recognizes the "extended function
 24231                           keys".  It seems there's no cleaner way.
 24232                           Test IsModifierKey to avoid handling
 24233                           mode_switch incorrectly.  */
 24234                        || (XK_Select <= keysym && keysym < XK_KP_Space)
 24235 #endif
 24236 #ifdef XK_dead_circumflex
 24237                        || keysym == XK_dead_circumflex
 24238 #endif
 24239 #ifdef XK_dead_grave
 24240                        || keysym == XK_dead_grave
 24241 #endif
 24242 #ifdef XK_dead_tilde
 24243                        || keysym == XK_dead_tilde
 24244 #endif
 24245 #ifdef XK_dead_diaeresis
 24246                        || keysym == XK_dead_diaeresis
 24247 #endif
 24248 #ifdef XK_dead_macron
 24249                        || keysym == XK_dead_macron
 24250 #endif
 24251 #ifdef XK_dead_degree
 24252                        || keysym == XK_dead_degree
 24253 #endif
 24254 #ifdef XK_dead_acute
 24255                        || keysym == XK_dead_acute
 24256 #endif
 24257 #ifdef XK_dead_cedilla
 24258                        || keysym == XK_dead_cedilla
 24259 #endif
 24260 #ifdef XK_dead_breve
 24261                        || keysym == XK_dead_breve
 24262 #endif
 24263 #ifdef XK_dead_ogonek
 24264                        || keysym == XK_dead_ogonek
 24265 #endif
 24266 #ifdef XK_dead_caron
 24267                        || keysym == XK_dead_caron
 24268 #endif
 24269 #ifdef XK_dead_doubleacute
 24270                        || keysym == XK_dead_doubleacute
 24271 #endif
 24272 #ifdef XK_dead_abovedot
 24273                        || keysym == XK_dead_abovedot
 24274 #endif
 24275 #ifdef XK_dead_abovering
 24276                        || keysym == XK_dead_abovering
 24277 #endif
 24278 #ifdef XK_dead_belowdot
 24279                        || keysym == XK_dead_belowdot
 24280 #endif
 24281 #ifdef XK_dead_voiced_sound
 24282                        || keysym == XK_dead_voiced_sound
 24283 #endif
 24284 #ifdef XK_dead_semivoiced_sound
 24285                        || keysym == XK_dead_semivoiced_sound
 24286 #endif
 24287 #ifdef XK_dead_hook
 24288                        || keysym == XK_dead_hook
 24289 #endif
 24290 #ifdef XK_dead_horn
 24291                        || keysym == XK_dead_horn
 24292 #endif
 24293 #ifdef XK_dead_stroke
 24294                        || keysym == XK_dead_stroke
 24295 #endif
 24296 #ifdef XK_dead_abovecomma
 24297                        || keysym == XK_dead_abovecomma
 24298 #endif
 24299                        || IsKeypadKey (keysym) /* 0xff80 <= x < 0xffbe */
 24300                        || IsFunctionKey (keysym) /* 0xffbe <= x < 0xffe1 */
 24301                        /* Any "vendor-specific" key is ok.  */
 24302                        || (keysym & (1 << 28))
 24303                        || (keysym != NoSymbol && nbytes == 0))
 24304                       && ! (IsModifierKey (keysym)
 24305                             /* The symbols from XK_ISO_Lock
 24306                                to XK_ISO_Last_Group_Lock
 24307                                don't have real modifiers but
 24308                                should be treated similarly to
 24309                                Mode_switch by Emacs. */
 24310 #if defined XK_ISO_Lock && defined XK_ISO_Last_Group_Lock
 24311                             || (XK_ISO_Lock <= keysym
 24312                                 && keysym <= XK_ISO_Last_Group_Lock)
 24313 #endif
 24314                             ))
 24315                     {
 24316                       STORE_KEYSYM_FOR_DEBUG (keysym);
 24317                       /* make_lispy_event will convert this to a symbolic
 24318                          key.  */
 24319                       inev.ie.kind = NON_ASCII_KEYSTROKE_EVENT;
 24320                       inev.ie.code = keysym;
 24321 
 24322                       if (source)
 24323                         inev.ie.device = source->name;
 24324 
 24325                       goto xi_done_keysym;
 24326                     }
 24327 
 24328                   for (i = 0; i < nbytes; i++)
 24329                     {
 24330                       STORE_KEYSYM_FOR_DEBUG (copy_bufptr[i]);
 24331                     }
 24332 
 24333                   if (nbytes)
 24334                     {
 24335                       inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
 24336                       inev.ie.arg = make_unibyte_string (copy_bufptr, nbytes);
 24337 
 24338                       Fput_text_property (make_fixnum (0), make_fixnum (nbytes),
 24339                                           Qcoding, coding, inev.ie.arg);
 24340 
 24341                       if (source)
 24342                         inev.ie.device = source->name;
 24343                     }
 24344                   goto xi_done_keysym;
 24345                 }
 24346 
 24347               goto XI_OTHER;
 24348             }
 24349 
 24350 #if defined USE_GTK && !defined HAVE_GTK3
 24351           case XI_RawKeyPress:
 24352             {
 24353               XIRawEvent *raw_event = (XIRawEvent *) xi_event;
 24354 
 24355               /* This is the only way to attribute core keyboard
 24356                  events generated on GTK+ 2.x to the extension device
 24357                  that generated them.  */
 24358               dpyinfo->pending_keystroke_time = raw_event->time;
 24359               dpyinfo->pending_keystroke_source = raw_event->sourceid;
 24360               dpyinfo->pending_keystroke_time_special_p = true;
 24361               goto XI_OTHER;
 24362             }
 24363 #endif
 24364 
 24365           case XI_KeyRelease:
 24366 #if defined HAVE_X_I18N || defined USE_GTK || defined USE_LUCID
 24367             {
 24368               XKeyPressedEvent xkey;
 24369 
 24370               memset (&xkey, 0, sizeof xkey);
 24371 
 24372               xkey.type = KeyRelease;
 24373               xkey.serial = xev->serial;
 24374               xkey.send_event = xev->send_event;
 24375               xkey.display = dpyinfo->display;
 24376               xkey.window = xev->event;
 24377               xkey.root = xev->root;
 24378               xkey.subwindow = xev->child;
 24379               xkey.time = xev->time;
 24380               xkey.state = xi_convert_event_keyboard_state (xev);
 24381               xkey.x = lrint (xev->event_x);
 24382               xkey.y = lrint (xev->event_y);
 24383               xkey.x_root = lrint (xev->root_x);
 24384               xkey.y_root = lrint (xev->root_y);
 24385 
 24386               /* Some input methods react differently depending on the
 24387                  buttons that are pressed.  */
 24388               xi_convert_button_state (&xev->buttons, &xkey.state);
 24389 
 24390               xkey.keycode = xev->detail;
 24391               xkey.same_screen = True;
 24392 
 24393 #ifdef USE_LUCID
 24394               if (!popup_activated ())
 24395                 {
 24396 #endif
 24397 #ifdef HAVE_X_I18N
 24398                   if (x_filter_event (dpyinfo, (XEvent *) &xkey))
 24399                     *finish = X_EVENT_DROP;
 24400 #elif defined USE_GTK
 24401                   f = x_any_window_to_frame (xkey->event);
 24402 
 24403                   if (f && xg_filter_key (f, event))
 24404                     *finish = X_EVENT_DROP;
 24405 #endif
 24406 #ifdef USE_LUCID
 24407                 }
 24408               else
 24409                 {
 24410                   /* FIXME: the Lucid menu bar pops down upon any key
 24411                      release event, so we don't dispatch these events
 24412                      at all, which doesn't seem to be the right
 24413                      solution.
 24414 
 24415                      use_copy = true;
 24416                      copy.xkey = xkey; */
 24417                 }
 24418 #endif
 24419             }
 24420 #endif
 24421 
 24422             goto XI_OTHER;
 24423 
 24424           case XI_PropertyEvent:
 24425             goto XI_OTHER;
 24426 
 24427           case XI_HierarchyChanged:
 24428             {
 24429               XIHierarchyEvent *hev;
 24430               XIDeviceInfo *info;
 24431               int i, ndevices, n_disabled, *disabled;
 24432               struct xi_device_t *device;
 24433               bool any_changed;
 24434 
 24435               any_changed = false;
 24436               hev = (XIHierarchyEvent *) xi_event;
 24437               disabled = SAFE_ALLOCA (sizeof *disabled * hev->num_info);
 24438               n_disabled = 0;
 24439 
 24440               for (i = 0; i < hev->num_info; ++i)
 24441                 {
 24442                   if (hev->info[i].flags & XIDeviceEnabled)
 24443                     {
 24444                       /* Handle all disabled devices now, to prevent
 24445                          things happening out-of-order later.  */
 24446 
 24447                       if (n_disabled)
 24448                         {
 24449                           xi_disable_devices (dpyinfo, disabled, n_disabled);
 24450                           n_disabled = 0;
 24451 
 24452                           /* This flag really just means that disabled
 24453                              devices were handled early and should be
 24454                              used in conjunction with n_disabled.  */
 24455                           any_changed = true;
 24456                         }
 24457 
 24458                       /* Under unknown circumstances, multiple
 24459                          XIDeviceEnabled events are sent at once,
 24460                          causing the device to be duplicated.  Check
 24461                          that the device doesn't exist before adding
 24462                          it.  */
 24463 
 24464                       if (!xi_device_from_id (dpyinfo,
 24465                                               hev->info[i].deviceid))
 24466                         {
 24467                           x_catch_errors (dpyinfo->display);
 24468                           info = XIQueryDevice (dpyinfo->display,
 24469                                                 hev->info[i].deviceid,
 24470                                                 &ndevices);
 24471                           x_uncatch_errors ();
 24472 
 24473                           if (info && info->enabled)
 24474                             {
 24475                               dpyinfo->devices
 24476                                 = xrealloc (dpyinfo->devices,
 24477                                             (sizeof *dpyinfo->devices
 24478                                              * ++dpyinfo->num_devices));
 24479                               memset (dpyinfo->devices + dpyinfo->num_devices - 1,
 24480                                       0, sizeof *dpyinfo->devices);
 24481                               device = &dpyinfo->devices[dpyinfo->num_devices - 1];
 24482                               xi_populate_device_from_info (dpyinfo, device, info);
 24483                             }
 24484 
 24485                           if (info)
 24486                             XIFreeDeviceInfo (info);
 24487                         }
 24488                     }
 24489                   else if (hev->info[i].flags & XIDeviceDisabled)
 24490                     disabled[n_disabled++] = hev->info[i].deviceid;
 24491                   else if (hev->info[i].flags & XISlaveDetached
 24492                            || hev->info[i].flags & XISlaveAttached)
 24493                     {
 24494                       device = xi_device_from_id (dpyinfo, hev->info[i].deviceid);
 24495                       x_catch_errors (dpyinfo->display);
 24496                       info = XIQueryDevice (dpyinfo->display, hev->info[i].deviceid,
 24497                                             &ndevices);
 24498                       x_uncatch_errors ();
 24499 
 24500                       if (info)
 24501                         {
 24502                           if (device)
 24503                             {
 24504                               device->use = info->use;
 24505                               device->attachment = info->attachment;
 24506                             }
 24507 
 24508                           /* device could have been disabled by now.
 24509                              But instead of removing it immediately,
 24510                              wait for XIDeviceDisabled, or internal
 24511                              state could be left inconsistent.  */
 24512 
 24513                           XIFreeDeviceInfo (info);
 24514                         }
 24515                     }
 24516                 }
 24517 
 24518               /* Delete all devices that were disabled by this
 24519                  event.  */
 24520               xi_disable_devices (dpyinfo, disabled, n_disabled);
 24521 
 24522               /* If the device hierarchy has been changed, recompute
 24523                  focus.  This might seem like a micro-optimization but
 24524                  it actually keeps the focus from changing in some
 24525                  cases where it would be undesierable.  */
 24526               if (any_changed || n_disabled)
 24527                 xi_handle_focus_change (dpyinfo);
 24528 
 24529               goto XI_OTHER;
 24530             }
 24531 
 24532           case XI_DeviceChanged:
 24533             {
 24534               XIDeviceChangedEvent *device_changed;
 24535               struct xi_device_t *device;
 24536 
 24537               device_changed = (XIDeviceChangedEvent *) xi_event;
 24538               device = xi_device_from_id (dpyinfo, device_changed->deviceid);
 24539 
 24540               /* If the device isn't enabled, then stop handling this
 24541                  event.  A HierarchyChanged event will be sent if it
 24542                  is enabled afterwards.  */
 24543               if (!device)
 24544                 goto XI_OTHER;
 24545 
 24546               /* Now handle the event by retrieving scroll valuators
 24547                  and touch info.  */
 24548               xi_handle_device_changed (dpyinfo, device, device_changed);
 24549               goto XI_OTHER;
 24550             }
 24551 
 24552 #ifdef HAVE_XINPUT2_2
 24553           case XI_TouchBegin:
 24554             {
 24555               struct xi_device_t *device, *source;
 24556               bool menu_bar_p = false, tool_bar_p = false;
 24557 #ifdef HAVE_GTK3
 24558               GdkRectangle test_rect;
 24559 #endif
 24560               device = xi_device_from_id (dpyinfo, xev->deviceid);
 24561               source = xi_device_from_id (dpyinfo, xev->sourceid);
 24562               x_display_set_last_user_time (dpyinfo, xev->time,
 24563                                             xev->send_event, true);
 24564 
 24565               /* Don't process touch sequences from this device if
 24566                  it's a master pointer.  Touch sequences aren't
 24567                  canceled by the X server if a slave device is
 24568                  detached, and master pointers may also represent
 24569                  dependent touch devices.  */
 24570 
 24571               if (!device || device->use == XIMasterPointer)
 24572                 goto XI_OTHER;
 24573 
 24574               if (xi_find_touch_point (device, xev->detail))
 24575                 emacs_abort ();
 24576 
 24577               f = x_window_to_frame (dpyinfo, xev->event);
 24578 
 24579               if (f)
 24580                 /* See the comment above x_compute_root_window_offset
 24581                    for why this optimization is performed.  */
 24582                 xi_compute_root_window_offset (f, xev);
 24583 
 24584 #ifdef HAVE_GTK3
 24585               menu_bar_p = (f && FRAME_X_OUTPUT (f)->menubar_widget
 24586                             && xg_event_is_for_menubar (f, event));
 24587               if (f && FRAME_X_OUTPUT (f)->toolbar_widget)
 24588                 {
 24589                   int scale = xg_get_scale (f);
 24590 
 24591                   test_rect.x = xev->event_x / scale;
 24592                   test_rect.y = xev->event_y / scale;
 24593                   test_rect.width = 1;
 24594                   test_rect.height = 1;
 24595 
 24596                   tool_bar_p = gtk_widget_intersect (FRAME_X_OUTPUT (f)->toolbar_widget,
 24597                                                      &test_rect, NULL);
 24598                 }
 24599 #endif
 24600 
 24601 #ifndef HAVE_EXT_TOOL_BAR
 24602               /* Is this a touch from a direct touch device that is in
 24603                  the tool-bar?  */
 24604               if (device->direct_p
 24605                   && WINDOWP (f->tool_bar_window)
 24606                   && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)))
 24607                 {
 24608                   Lisp_Object window;
 24609                   int x = xev->event_x;
 24610                   int y = xev->event_y;
 24611 
 24612                   window = window_from_coordinates (f, x, y, 0, true, true);
 24613                   /* Ignore button release events if the mouse
 24614                      wasn't previously pressed on the tool bar.
 24615                      We do this because otherwise selecting some
 24616                      text with the mouse and then releasing it on
 24617                      the tool bar doesn't stop selecting text,
 24618                      since the tool bar eats the button up
 24619                      event.  */
 24620                   tool_bar_p = EQ (window, f->tool_bar_window);
 24621 
 24622                   /* If this touch has started in the tool bar, do not
 24623                      send it to Lisp.  Instead, simulate a tool bar
 24624                      click, releasing it once it goes away.  */
 24625 
 24626                   if (tool_bar_p)
 24627                     {
 24628                       /* Call note_mouse_highlight on the tool bar
 24629                          item.  Otherwise, get_tool_bar_item will
 24630                          return 1.
 24631 
 24632                          This is not necessary when mouse-highlight is
 24633                          nil.  */
 24634 
 24635                       if (!NILP (Vmouse_highlight))
 24636                         {
 24637                           note_mouse_highlight (f, x, y);
 24638 
 24639                           /* Always allow future mouse motion to
 24640                              update the mouse highlight, no matter
 24641                              where it is.  */
 24642                           memset (&dpyinfo->last_mouse_glyph, 0,
 24643                                   sizeof dpyinfo->last_mouse_glyph);
 24644                           dpyinfo->last_mouse_glyph_frame = f;
 24645                         }
 24646 
 24647                       handle_tool_bar_click_with_device (f, x, y, true, 0,
 24648                                                          (source
 24649                                                           ? source->name : Qt));
 24650 
 24651                       /* Flush any changes made by that to the front
 24652                          buffer.  */
 24653                       x_flush_dirty_back_buffer_on (f);
 24654 
 24655                       /* Record the device and the touch ID on the
 24656                          frame.  That way, Emacs knows when to dismiss
 24657                          the tool bar click later.  */
 24658 
 24659                       FRAME_OUTPUT_DATA (f)->tool_bar_touch_device
 24660                         = device->device_id;
 24661                       FRAME_OUTPUT_DATA (f)->tool_bar_touch_id = xev->detail;
 24662 
 24663                       goto XI_OTHER;
 24664                     }
 24665                 }
 24666 #endif
 24667 
 24668               if (!menu_bar_p && !tool_bar_p)
 24669                 {
 24670                   if (f && device->direct_p)
 24671                     {
 24672                       *finish = X_EVENT_DROP;
 24673 
 24674                       x_catch_errors (dpyinfo->display);
 24675 
 24676                       if (x_input_grab_touch_events)
 24677                         XIAllowTouchEvents (dpyinfo->display,
 24678                                             xev->deviceid,
 24679                                             xev->detail, xev->event,
 24680                                             XIAcceptTouch);
 24681 
 24682                       if (!x_had_errors_p (dpyinfo->display))
 24683                         {
 24684                           xi_link_touch_point (device, xev->detail,
 24685                                                xev->event_x,
 24686                                                xev->event_y, f);
 24687 
 24688                           inev.ie.kind = TOUCHSCREEN_BEGIN_EVENT;
 24689                           inev.ie.timestamp = xev->time;
 24690                           XSETFRAME (inev.ie.frame_or_window, f);
 24691                           XSETINT (inev.ie.x, lrint (xev->event_x));
 24692                           XSETINT (inev.ie.y, lrint (xev->event_y));
 24693                           XSETINT (inev.ie.arg, xev->detail);
 24694 
 24695                           if (source)
 24696                             inev.ie.device = source->name;
 24697                         }
 24698 
 24699                       x_uncatch_errors ();
 24700                     }
 24701 #ifndef HAVE_GTK3
 24702                   else if (x_input_grab_touch_events)
 24703                     {
 24704                       x_ignore_errors_for_next_request (dpyinfo, 0);
 24705                       XIAllowTouchEvents (dpyinfo->display, xev->deviceid,
 24706                                           xev->detail, xev->event, XIRejectTouch);
 24707                       x_stop_ignoring_errors (dpyinfo);
 24708                     }
 24709 #endif
 24710                 }
 24711               else
 24712                 {
 24713 #ifdef HAVE_GTK3
 24714                   bool was_waiting_for_input = waiting_for_input;
 24715                   /* This hack was adopted from the NS port.  Whether
 24716                      or not it is actually safe is a different story
 24717                      altogether.  */
 24718                   if (waiting_for_input)
 24719                     waiting_for_input = 0;
 24720                   set_frame_menubar (f, true);
 24721                   waiting_for_input = was_waiting_for_input;
 24722 #endif
 24723                 }
 24724 
 24725               goto XI_OTHER;
 24726             }
 24727 
 24728           case XI_TouchOwnership:
 24729             {
 24730               struct xi_device_t *device;
 24731               struct xi_touch_point_t *touchpoint;
 24732               XITouchOwnershipEvent *event;
 24733 
 24734               /* All grabbing clients have decided to reject ownership
 24735                  of this touch sequence.  */
 24736 
 24737               event  = (XITouchOwnershipEvent *) xi_event;
 24738               device = xi_device_from_id (dpyinfo, event->deviceid);
 24739 
 24740               if (!device || device->use == XIMasterPointer)
 24741                 goto XI_OTHER;
 24742 
 24743               touchpoint = xi_find_touch_point (device, event->touchid);
 24744 
 24745               if (!touchpoint)
 24746                 goto XI_OTHER;
 24747 
 24748               /* As a result, Emacs should complete whatever editing
 24749                  operations result from this touch sequence.  */
 24750               touchpoint->ownership = TOUCH_OWNERSHIP_SELF;
 24751 
 24752               goto XI_OTHER;
 24753             }
 24754 
 24755           case XI_TouchUpdate:
 24756             {
 24757               struct xi_device_t *device, *source;
 24758               struct xi_touch_point_t *touchpoint;
 24759               Lisp_Object arg = Qnil;
 24760 
 24761               /* If flags & TouchPendingEnd, the touch sequence has
 24762                  already ended, but some grabbing clients remain
 24763                  undecided as to whether they will obtain ownership of
 24764                  the touch sequence.
 24765 
 24766                  Wait for them to make their decision, resulting in
 24767                  TouchOwnership and TouchEnd events being sent.  */
 24768 
 24769               if (xev->flags & XITouchPendingEnd)
 24770                 goto XI_OTHER;
 24771 
 24772               device = xi_device_from_id (dpyinfo, xev->deviceid);
 24773               source = xi_device_from_id (dpyinfo, xev->sourceid);
 24774               x_display_set_last_user_time (dpyinfo, xev->time,
 24775                                             xev->send_event, true);
 24776 
 24777               /* Don't process touch sequences from this device if
 24778                  it's a master pointer.  Touch sequences aren't
 24779                  canceled by the X server if a slave device is
 24780                  detached, and master pointers may also represent
 24781                  dependent touch devices.  */
 24782 
 24783               if (!device || device->use == XIMasterPointer)
 24784                 goto XI_OTHER;
 24785 
 24786               touchpoint = xi_find_touch_point (device, xev->detail);
 24787 
 24788               if (!touchpoint
 24789                   /* Don't send this event if nothing has changed
 24790                      either.  */
 24791                   || (touchpoint->x == lrint (xev->event_x)
 24792                       && touchpoint->y == lrint (xev->event_y)))
 24793                 goto XI_OTHER;
 24794 
 24795               touchpoint->x = lrint (xev->event_x);
 24796               touchpoint->y = lrint (xev->event_y);
 24797 
 24798               f = x_window_to_frame (dpyinfo, xev->event);
 24799 
 24800               if (f && device->direct_p)
 24801                 {
 24802                   inev.ie.kind = TOUCHSCREEN_UPDATE_EVENT;
 24803                   inev.ie.timestamp = xev->time;
 24804                   XSETFRAME (inev.ie.frame_or_window, f);
 24805 
 24806                   for (touchpoint = device->touchpoints;
 24807                        touchpoint; touchpoint = touchpoint->next)
 24808                     {
 24809                       if (touchpoint->frame == f)
 24810                         arg = Fcons (list3i (touchpoint->x, touchpoint->y,
 24811                                              lrint (touchpoint->number)),
 24812                                      arg);
 24813                     }
 24814 
 24815                   if (source)
 24816                     inev.ie.device = source->name;
 24817 
 24818                   inev.ie.arg = arg;
 24819                 }
 24820 
 24821               goto XI_OTHER;
 24822             }
 24823 
 24824           case XI_TouchEnd:
 24825             {
 24826               struct xi_device_t *device, *source;
 24827               int state;
 24828 
 24829               device = xi_device_from_id (dpyinfo, xev->deviceid);
 24830               source = xi_device_from_id (dpyinfo, xev->sourceid);
 24831               x_display_set_last_user_time (dpyinfo, xev->time,
 24832                                             xev->send_event, true);
 24833 
 24834               /* Don't process touch sequences from this device if
 24835                  it's a master pointer.  Touch sequences aren't
 24836                  canceled by the X server if a slave device is
 24837                  detached, and master pointers may also represent
 24838                  dependent touch devices.  */
 24839 
 24840               if (!device || device->use == XIMasterPointer)
 24841                 goto XI_OTHER;
 24842 
 24843               state = xi_unlink_touch_point (xev->detail, device);
 24844 
 24845               if (state)
 24846                 {
 24847                   f = x_window_to_frame (dpyinfo, xev->event);
 24848 
 24849                   if (f && device->direct_p)
 24850                     {
 24851                       inev.ie.kind = TOUCHSCREEN_END_EVENT;
 24852                       inev.ie.timestamp = xev->time;
 24853                       inev.ie.modifiers = state != 2;
 24854 
 24855                       XSETFRAME (inev.ie.frame_or_window, f);
 24856                       XSETINT (inev.ie.x, lrint (xev->event_x));
 24857                       XSETINT (inev.ie.y, lrint (xev->event_y));
 24858                       XSETINT (inev.ie.arg, xev->detail);
 24859 
 24860                       if (source)
 24861                         inev.ie.device = source->name;
 24862                     }
 24863                 }
 24864 
 24865 #ifndef HAVE_EXT_TOOL_BAR
 24866               /* Now see if the touchpoint was previously on the tool bar.
 24867                  If it was, release the tool bar.  */
 24868 
 24869               if (!f)
 24870                 f = x_window_to_frame (dpyinfo, xev->event);
 24871 
 24872               if (f && (FRAME_OUTPUT_DATA (f)->tool_bar_touch_id
 24873                         == xev->detail))
 24874                 {
 24875                   if (f->last_tool_bar_item != -1)
 24876                     handle_tool_bar_click_with_device (f, xev->event_x,
 24877                                                        xev->event_y,
 24878                                                        false, 0,
 24879                                                        (source
 24880                                                         ? source->name
 24881                                                         : Qnil));
 24882 
 24883                   /* Cancel any outstanding mouse highlight.  */
 24884                   note_mouse_highlight (f, -1, -1);
 24885                   x_flush_dirty_back_buffer_on (f);
 24886 
 24887                   /* Now clear the tool bar device.  */
 24888                   FRAME_OUTPUT_DATA (f)->tool_bar_touch_device = 0;
 24889                 }
 24890 #endif
 24891 
 24892               goto XI_OTHER;
 24893             }
 24894 
 24895 #endif
 24896 
 24897 #ifdef HAVE_XINPUT2_4
 24898           case XI_GesturePinchBegin:
 24899           case XI_GesturePinchUpdate:
 24900             {
 24901               XIGesturePinchEvent *pev = (XIGesturePinchEvent *) xi_event;
 24902               struct xi_device_t *device, *source;
 24903 
 24904               device = xi_device_from_id (dpyinfo, pev->deviceid);
 24905               source = xi_device_from_id (dpyinfo, pev->sourceid);
 24906               x_display_set_last_user_time (dpyinfo, pev->time,
 24907                                             pev->send_event, true);
 24908 
 24909               if (!device || device->use != XIMasterPointer)
 24910                 goto XI_OTHER;
 24911 
 24912 #ifdef HAVE_XWIDGETS
 24913               struct xwidget_view *xvw = xwidget_view_from_window (pev->event);
 24914 
 24915               if (xvw)
 24916                 {
 24917                   *finish = X_EVENT_DROP;
 24918                   xwidget_pinch (xvw, pev);
 24919                   goto XI_OTHER;
 24920                 }
 24921 #endif
 24922 
 24923               any = x_window_to_frame (dpyinfo, pev->event);
 24924 
 24925               if (any)
 24926                 {
 24927                   if (pev->event == FRAME_X_WINDOW (any))
 24928                     xi_compute_root_window_offset_pinch (any, pev);
 24929 
 24930                   inev.ie.kind = PINCH_EVENT;
 24931                   inev.ie.modifiers
 24932                     = x_x_to_emacs_modifiers (dpyinfo, pev->mods.effective);
 24933 
 24934                   XSETINT (inev.ie.x, lrint (pev->event_x));
 24935                   XSETINT (inev.ie.y, lrint (pev->event_y));
 24936                   XSETFRAME (inev.ie.frame_or_window, any);
 24937                   inev.ie.arg = list4 (make_float (pev->delta_x),
 24938                                        make_float (pev->delta_y),
 24939                                        make_float (pev->scale),
 24940                                        make_float (pev->delta_angle));
 24941 
 24942                   if (source)
 24943                     inev.ie.device = source->name;
 24944                 }
 24945 
 24946               /* Once again GTK seems to crash when confronted by
 24947                  events it doesn't understand.  */
 24948               *finish = X_EVENT_DROP;
 24949               goto XI_OTHER;
 24950             }
 24951 
 24952           case XI_GesturePinchEnd:
 24953             {
 24954 #if defined HAVE_XWIDGETS
 24955               XIGesturePinchEvent *pev = (XIGesturePinchEvent *) xi_event;
 24956               struct xwidget_view *xvw = xwidget_view_from_window (pev->event);
 24957 
 24958               if (xvw)
 24959                 xwidget_pinch (xvw, pev);
 24960 #endif
 24961               *finish = X_EVENT_DROP;
 24962               goto XI_OTHER;
 24963             }
 24964 #endif
 24965           default:
 24966             goto XI_OTHER;
 24967           }
 24968 
 24969       xi_done_keysym:
 24970 #ifdef HAVE_X_I18N
 24971       if (f)
 24972         {
 24973           struct window *w = XWINDOW (f->selected_window);
 24974           xic_set_preeditarea (w, w->cursor.x, w->cursor.y);
 24975 
 24976           if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea))
 24977             xic_set_statusarea (f);
 24978         }
 24979 #endif
 24980         if (must_free_data)
 24981           XFreeEventData (dpyinfo->display, &event->xcookie);
 24982         goto done_keysym;
 24983 
 24984       XI_OTHER:
 24985         if (must_free_data)
 24986           XFreeEventData (dpyinfo->display, &event->xcookie);
 24987         goto OTHER;
 24988       }
 24989 #endif
 24990 
 24991     default:
 24992 #ifdef HAVE_XKB
 24993       if (dpyinfo->supports_xkb
 24994           && event->type == dpyinfo->xkb_event_type)
 24995         {
 24996           XkbEvent *xkbevent = (XkbEvent *) event;
 24997 
 24998           if (xkbevent->any.xkb_type == XkbNewKeyboardNotify
 24999               || xkbevent->any.xkb_type == XkbMapNotify)
 25000             {
 25001               XkbRefreshKeyboardMapping (&xkbevent->map);
 25002 
 25003               if (dpyinfo->xkb_desc)
 25004                 {
 25005                   if (XkbGetUpdatedMap (dpyinfo->display,
 25006                                         (XkbKeySymsMask
 25007                                          | XkbKeyTypesMask
 25008                                          | XkbModifierMapMask
 25009                                          | XkbVirtualModsMask),
 25010                                         dpyinfo->xkb_desc) == Success)
 25011                     XkbGetNames (dpyinfo->display, XkbAllNamesMask,
 25012                                  dpyinfo->xkb_desc);
 25013                   else
 25014                     {
 25015                       XkbFreeKeyboard (dpyinfo->xkb_desc,
 25016                                        XkbAllComponentsMask, True);
 25017                       dpyinfo->xkb_desc = NULL;
 25018                     }
 25019                 }
 25020               else
 25021                 {
 25022                   dpyinfo->xkb_desc = XkbGetMap (dpyinfo->display,
 25023                                                  (XkbKeySymsMask
 25024                                                   | XkbKeyTypesMask
 25025                                                   | XkbModifierMapMask
 25026                                                   | XkbVirtualModsMask),
 25027                                                  XkbUseCoreKbd);
 25028 
 25029                   if (dpyinfo->xkb_desc)
 25030                     XkbGetNames (dpyinfo->display, XkbAllNamesMask,
 25031                                  dpyinfo->xkb_desc);
 25032                 }
 25033 
 25034               x_find_modifier_meanings (dpyinfo);
 25035             }
 25036           else if (x_dnd_in_progress
 25037                    && xkbevent->any.xkb_type == XkbStateNotify)
 25038             x_dnd_keyboard_state = (xkbevent->state.mods
 25039                                     | xkbevent->state.ptr_buttons);
 25040         }
 25041 #endif
 25042 #ifdef HAVE_XSHAPE
 25043       if (dpyinfo->xshape_supported_p
 25044           && event->type == dpyinfo->xshape_event_base + ShapeNotify
 25045           && x_dnd_in_progress && x_dnd_use_toplevels
 25046           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 25047         {
 25048 #ifndef USE_GTK
 25049           XEvent xevent;
 25050 #endif
 25051           XShapeEvent *xse = (XShapeEvent *) event;
 25052 #if defined HAVE_XCB_SHAPE && defined HAVE_XCB_SHAPE_INPUT_RECTS
 25053           xcb_shape_get_rectangles_cookie_t bounding_rect_cookie;
 25054           xcb_shape_get_rectangles_reply_t *bounding_rect_reply;
 25055           xcb_rectangle_iterator_t bounding_rect_iterator;
 25056 
 25057           xcb_shape_get_rectangles_cookie_t input_rect_cookie;
 25058           xcb_shape_get_rectangles_reply_t *input_rect_reply;
 25059           xcb_rectangle_iterator_t input_rect_iterator;
 25060 
 25061           xcb_generic_error_t *error;
 25062 #else
 25063           XRectangle *rects;
 25064           int rc, ordering;
 25065 #endif
 25066 
 25067           /* Somehow this really interferes with GTK's own processing
 25068              of ShapeNotify events.  Not sure what GTK uses them for,
 25069              but we cannot skip any of them here.  */
 25070 #ifndef USE_GTK
 25071           while (XPending (dpyinfo->display))
 25072             {
 25073               XNextEvent (dpyinfo->display, &xevent);
 25074 
 25075               if (xevent.type == dpyinfo->xshape_event_base + ShapeNotify
 25076                   && ((XShapeEvent *) &xevent)->window == xse->window)
 25077                 xse = (XShapeEvent *) &xevent;
 25078               else
 25079                 {
 25080                   XPutBackEvent (dpyinfo->display, &xevent);
 25081                   break;
 25082                 }
 25083             }
 25084 #endif
 25085 
 25086           for (struct x_client_list_window *tem = x_dnd_toplevels; tem;
 25087                tem = tem->next)
 25088             {
 25089               if (tem->window == xse->window)
 25090                 {
 25091                   if (tem->n_input_rects != -1)
 25092                     xfree (tem->input_rects);
 25093                   if (tem->n_bounding_rects != -1)
 25094                     xfree (tem->bounding_rects);
 25095 
 25096                   tem->n_input_rects = -1;
 25097                   tem->n_bounding_rects = -1;
 25098 
 25099 #if defined HAVE_XCB_SHAPE && defined HAVE_XCB_SHAPE_INPUT_RECTS
 25100                   bounding_rect_cookie = xcb_shape_get_rectangles (dpyinfo->xcb_connection,
 25101                                                                    (xcb_window_t) xse->window,
 25102                                                                    XCB_SHAPE_SK_BOUNDING);
 25103                   if (dpyinfo->xshape_major > 1
 25104                       || (dpyinfo->xshape_major == 1
 25105                           && dpyinfo->xshape_minor >= 1))
 25106                     input_rect_cookie
 25107                       = xcb_shape_get_rectangles (dpyinfo->xcb_connection,
 25108                                                   (xcb_window_t) xse->window,
 25109                                                   XCB_SHAPE_SK_INPUT);
 25110 
 25111                   bounding_rect_reply = xcb_shape_get_rectangles_reply (dpyinfo->xcb_connection,
 25112                                                                         bounding_rect_cookie,
 25113                                                                         &error);
 25114 
 25115                   if (bounding_rect_reply)
 25116                     {
 25117                       bounding_rect_iterator
 25118                         = xcb_shape_get_rectangles_rectangles_iterator (bounding_rect_reply);
 25119                       tem->n_bounding_rects = bounding_rect_iterator.rem + 1;
 25120                       tem->bounding_rects = xmalloc (tem->n_bounding_rects
 25121                                                      * sizeof *tem->bounding_rects);
 25122                       tem->n_bounding_rects = 0;
 25123 
 25124                       for (; bounding_rect_iterator.rem; xcb_rectangle_next (&bounding_rect_iterator))
 25125                         {
 25126                           tem->bounding_rects[tem->n_bounding_rects].x
 25127                             = bounding_rect_iterator.data->x;
 25128                           tem->bounding_rects[tem->n_bounding_rects].y
 25129                             = bounding_rect_iterator.data->y;
 25130                           tem->bounding_rects[tem->n_bounding_rects].width
 25131                             = bounding_rect_iterator.data->width;
 25132                           tem->bounding_rects[tem->n_bounding_rects].height
 25133                             = bounding_rect_iterator.data->height;
 25134 
 25135                           tem->n_bounding_rects++;
 25136                         }
 25137 
 25138                       free (bounding_rect_reply);
 25139                     }
 25140                   else
 25141                     free (error);
 25142 
 25143                   if (dpyinfo->xshape_major > 1
 25144                       || (dpyinfo->xshape_major == 1
 25145                           && dpyinfo->xshape_minor >= 1))
 25146                     {
 25147                       input_rect_reply = xcb_shape_get_rectangles_reply (dpyinfo->xcb_connection,
 25148                                                                          input_rect_cookie, &error);
 25149 
 25150                       if (input_rect_reply)
 25151                         {
 25152                           input_rect_iterator
 25153                             = xcb_shape_get_rectangles_rectangles_iterator (input_rect_reply);
 25154                           tem->n_input_rects = input_rect_iterator.rem + 1;
 25155                           tem->input_rects = xmalloc (tem->n_input_rects
 25156                                                       * sizeof *tem->input_rects);
 25157                           tem->n_input_rects = 0;
 25158 
 25159                           for (; input_rect_iterator.rem; xcb_rectangle_next (&input_rect_iterator))
 25160                             {
 25161                               tem->input_rects[tem->n_input_rects].x
 25162                                 = input_rect_iterator.data->x;
 25163                               tem->input_rects[tem->n_input_rects].y
 25164                                 = input_rect_iterator.data->y;
 25165                               tem->input_rects[tem->n_input_rects].width
 25166                                 = input_rect_iterator.data->width;
 25167                               tem->input_rects[tem->n_input_rects].height
 25168                                 = input_rect_iterator.data->height;
 25169 
 25170                               tem->n_input_rects++;
 25171                             }
 25172 
 25173                           free (input_rect_reply);
 25174                         }
 25175                       else
 25176                         free (error);
 25177                     }
 25178 #else
 25179                   x_catch_errors (dpyinfo->display);
 25180                   rects = XShapeGetRectangles (dpyinfo->display,
 25181                                                xse->window,
 25182                                                ShapeBounding,
 25183                                                &count, &ordering);
 25184                   rc = x_had_errors_p (dpyinfo->display);
 25185                   x_uncatch_errors_after_check ();
 25186 
 25187                   /* Does XShapeGetRectangles allocate anything upon an
 25188                      error?  */
 25189                   if (!rc)
 25190                     {
 25191                       tem->n_bounding_rects = count;
 25192                       tem->bounding_rects
 25193                         = xmalloc (sizeof *tem->bounding_rects * count);
 25194                       memcpy (tem->bounding_rects, rects,
 25195                               sizeof *tem->bounding_rects * count);
 25196 
 25197                       XFree (rects);
 25198                     }
 25199 
 25200 #ifdef ShapeInput
 25201                   if (dpyinfo->xshape_major > 1
 25202                       || (dpyinfo->xshape_major == 1
 25203                           && dpyinfo->xshape_minor >= 1))
 25204                     {
 25205                       x_catch_errors (dpyinfo->display);
 25206                       rects = XShapeGetRectangles (dpyinfo->display,
 25207                                                    xse->window, ShapeInput,
 25208                                                    &count, &ordering);
 25209                       rc = x_had_errors_p (dpyinfo->display);
 25210                       x_uncatch_errors_after_check ();
 25211 
 25212                       /* Does XShapeGetRectangles allocate anything upon
 25213                          an error?  */
 25214                       if (!rc)
 25215                         {
 25216                           tem->n_input_rects = count;
 25217                           tem->input_rects
 25218                             = xmalloc (sizeof *tem->input_rects * count);
 25219                           memcpy (tem->input_rects, rects,
 25220                                   sizeof *tem->input_rects * count);
 25221 
 25222                           XFree (rects);
 25223                         }
 25224                     }
 25225 #endif
 25226 #endif
 25227 
 25228                   /* Handle the common case where the input shape equals the
 25229                      bounding shape.  */
 25230 
 25231                   if (tem->n_input_rects != -1
 25232                       && tem->n_bounding_rects == tem->n_input_rects
 25233                       && !memcmp (tem->bounding_rects, tem->input_rects,
 25234                                   tem->n_input_rects * sizeof *tem->input_rects))
 25235                     {
 25236                       xfree (tem->input_rects);
 25237                       tem->n_input_rects = -1;
 25238                     }
 25239 
 25240                   /* And the common case where there is no input rect and the
 25241                      bounding rect equals the window dimensions.  */
 25242 
 25243                   if (tem->n_input_rects == -1
 25244                       && tem->n_bounding_rects == 1
 25245                       && tem->bounding_rects[0].width == tem->width
 25246                       && tem->bounding_rects[0].height == tem->height
 25247                       && tem->bounding_rects[0].x == -tem->border_width
 25248                       && tem->bounding_rects[0].y == -tem->border_width)
 25249                     {
 25250                       xfree (tem->bounding_rects);
 25251                       tem->n_bounding_rects = -1;
 25252                     }
 25253 
 25254                   break;
 25255                 }
 25256             }
 25257         }
 25258 #endif
 25259 #if defined HAVE_XRANDR && !defined USE_GTK
 25260       if (dpyinfo->xrandr_supported_p
 25261           && (event->type == (dpyinfo->xrandr_event_base
 25262                               + RRScreenChangeNotify)
 25263               || event->type == (dpyinfo->xrandr_event_base
 25264                                  + RRNotify)))
 25265         {
 25266           Time timestamp;
 25267           Lisp_Object current_monitors;
 25268           XRRScreenChangeNotifyEvent *notify;
 25269 
 25270           if (event->type == (dpyinfo->xrandr_event_base
 25271                               + RRScreenChangeNotify))
 25272             XRRUpdateConfiguration ((XEvent *) event);
 25273 
 25274           if (event->type == (dpyinfo->xrandr_event_base
 25275                               + RRScreenChangeNotify))
 25276             {
 25277               notify = ((XRRScreenChangeNotifyEvent *) event);
 25278               timestamp = notify->timestamp;
 25279 
 25280               /* Don't set screen dimensions if the notification is
 25281                  for a different screen.  */
 25282               if (notify->root == dpyinfo->root_window)
 25283                 {
 25284                   dpyinfo->screen_width = notify->width;
 25285                   dpyinfo->screen_height = notify->height;
 25286                   dpyinfo->screen_mm_width = notify->mwidth;
 25287                   dpyinfo->screen_mm_height = notify->mheight;
 25288                 }
 25289             }
 25290           else
 25291             timestamp = 0;
 25292 
 25293           if (x_find_monitors_changed_event (dpyinfo))
 25294             /* Don't store a MONITORS_CHANGED_EVENT if there is
 25295                already an undelivered event on the queue.  */
 25296             goto OTHER;
 25297 
 25298           inev.ie.kind = MONITORS_CHANGED_EVENT;
 25299           inev.ie.timestamp = timestamp;
 25300           XSETTERMINAL (inev.ie.arg, dpyinfo->terminal);
 25301 
 25302           /* Also don't do anything if the monitor configuration
 25303              didn't really change.  */
 25304 
 25305           current_monitors
 25306             = Fx_display_monitor_attributes_list (inev.ie.arg);
 25307 
 25308           if (!NILP (Fequal (current_monitors,
 25309                              dpyinfo->last_monitor_attributes_list)))
 25310             inev.ie.kind = NO_EVENT;
 25311 
 25312           dpyinfo->last_monitor_attributes_list = current_monitors;
 25313 
 25314           if (x_dnd_in_progress && x_dnd_update_tooltip)
 25315             x_dnd_monitors = current_monitors;
 25316 
 25317           if (inev.ie.kind != NO_EVENT)
 25318             x_dnd_update_tooltip_now ();
 25319         }
 25320 #endif
 25321 #ifdef HAVE_XFIXES
 25322       if (dpyinfo->xfixes_supported_p
 25323           && event->type == (dpyinfo->xfixes_event_base
 25324                              + XFixesSelectionNotify)
 25325           && x_handle_selection_monitor_event (dpyinfo, event))
 25326         /* GTK 3 crashes if an XFixesSelectionNotify arrives with a
 25327            window other than the root window, because it wants to know
 25328            the screen in order to determine the compositing manager
 25329            selection name.  (bug#58584) */
 25330         *finish = X_EVENT_DROP;
 25331 #endif
 25332     OTHER:
 25333 #ifdef USE_X_TOOLKIT
 25334       if (*finish != X_EVENT_DROP)
 25335         {
 25336           /* Ignore some obviously bogus ConfigureNotify events that
 25337              other clients have been known to send Emacs.
 25338              (bug#54051) */
 25339           if (event->type != ConfigureNotify
 25340               || (event->xconfigure.width != 0
 25341                   && event->xconfigure.height != 0))
 25342             {
 25343 #if defined USE_X_TOOLKIT && defined HAVE_XINPUT2
 25344               XtDispatchEvent (use_copy ? &copy : (XEvent *) event);
 25345 #else
 25346               XtDispatchEvent ((XEvent *) event);
 25347 #endif
 25348             }
 25349         }
 25350 #endif /* USE_X_TOOLKIT */
 25351 #if defined USE_GTK && !defined HAVE_GTK3 && defined HAVE_XINPUT2
 25352       if (*finish != X_EVENT_DROP && copy)
 25353         {
 25354           gtk_main_do_event (copy);
 25355           *finish = X_EVENT_DROP;
 25356         }
 25357 
 25358       if (copy)
 25359         gdk_event_free (copy);
 25360 #endif
 25361     break;
 25362     }
 25363 
 25364  done:
 25365   if (inev.ie.kind != NO_EVENT)
 25366     {
 25367       kbd_buffer_store_buffered_event (&inev, hold_quit);
 25368       count++;
 25369     }
 25370 
 25371   if (do_help
 25372       && !(hold_quit && hold_quit->kind != NO_EVENT))
 25373     {
 25374       Lisp_Object frame;
 25375 
 25376       if (f)
 25377         XSETFRAME (frame, f);
 25378       else
 25379         frame = Qnil;
 25380 
 25381       if (do_help > 0)
 25382         {
 25383           any_help_event_p = true;
 25384 #ifdef HAVE_XINPUT2
 25385           if (gen_help_device)
 25386             xi_handle_interaction (dpyinfo, f,
 25387                                    gen_help_device,
 25388                                    gen_help_time);
 25389 #endif
 25390           gen_help_event (help_echo_string, frame, help_echo_window,
 25391                           help_echo_object, help_echo_pos);
 25392         }
 25393       else
 25394         {
 25395           help_echo_string = Qnil;
 25396           gen_help_event (Qnil, frame, Qnil, Qnil, 0);
 25397         }
 25398       count++;
 25399     }
 25400 
 25401 #if defined HAVE_XINPUT2 || defined HAVE_XKB || defined HAVE_X_I18N
 25402   SAFE_FREE ();
 25403 #endif
 25404 
 25405   return count;
 25406 }
 25407 
 25408 /* Handles the XEvent EVENT on display DISPLAY.
 25409    This is used for event loops outside the normal event handling,
 25410    i.e. looping while a popup menu or a dialog is posted.
 25411 
 25412    Returns the value handle_one_xevent sets in the finish argument.  */
 25413 
 25414 #ifdef USE_GTK
 25415 static int
 25416 #else
 25417 int
 25418 #endif
 25419 x_dispatch_event (XEvent *event, Display *display)
 25420 {
 25421   struct x_display_info *dpyinfo;
 25422   int finish = X_EVENT_NORMAL;
 25423 
 25424   dpyinfo = x_display_info_for_display (display);
 25425 
 25426   if (dpyinfo)
 25427     {
 25428       /* Block input before calling x_dispatch_event.  */
 25429       block_input ();
 25430       handle_one_xevent (dpyinfo, event, &finish, 0);
 25431       unblock_input ();
 25432     }
 25433 
 25434   return finish;
 25435 }
 25436 
 25437 /* Read events coming from the X server.
 25438    Return as soon as there are no more events to be read.
 25439 
 25440    Return the number of characters stored into the buffer,
 25441    thus pretending to be `read' (except the characters we store
 25442    in the keyboard buffer can be multibyte, so are not necessarily
 25443    C chars).  */
 25444 
 25445 static int
 25446 XTread_socket (struct terminal *terminal, struct input_event *hold_quit)
 25447 {
 25448   int count = 0;
 25449   bool event_found = false;
 25450   struct x_display_info *dpyinfo = terminal->display_info.x;
 25451 
 25452   /* Don't allow XTread_socket to do anything if drag-and-drop is in
 25453      progress.  If unblock_input causes XTread_socket to be called and
 25454      read X events while the drag-and-drop event loop is in progress,
 25455      things can go wrong very quick.
 25456 
 25457      When x_dnd_unwind_flag is true, the above doesn't apply, since
 25458      the surrounding code takes special precautions to keep it safe.
 25459 
 25460      That doesn't matter for events from displays other than the
 25461      display of the drag-and-drop operation, though.  */
 25462   if (!x_dnd_unwind_flag
 25463       && ((x_dnd_in_progress
 25464            && dpyinfo->display == FRAME_X_DISPLAY (x_dnd_frame))
 25465           || (x_dnd_waiting_for_finish
 25466               && dpyinfo->display == x_dnd_finish_display)))
 25467     return 0;
 25468 
 25469   x_clean_failable_requests (dpyinfo);
 25470 
 25471   block_input ();
 25472 
 25473   /* For debugging, this gives a way to fake an I/O error.  */
 25474   if (dpyinfo == XTread_socket_fake_io_error)
 25475     {
 25476       XTread_socket_fake_io_error = 0;
 25477       x_io_error_quitter (dpyinfo->display);
 25478     }
 25479 
 25480 #ifndef USE_GTK
 25481   while (XPending (dpyinfo->display))
 25482     {
 25483       int finish;
 25484       XEvent event;
 25485 
 25486       XNextEvent (dpyinfo->display, &event);
 25487 
 25488 #ifdef HAVE_X_I18N
 25489       /* Filter events for the current X input method.  */
 25490 #ifdef HAVE_XINPUT2
 25491       if (event.type != GenericEvent
 25492           || !dpyinfo->supports_xi2
 25493           || event.xgeneric.extension != dpyinfo->xi2_opcode)
 25494         {
 25495           /* Input extension key events are filtered inside
 25496              handle_one_xevent.  */
 25497 #endif
 25498           if (x_filter_event (dpyinfo, &event))
 25499             continue;
 25500 #ifdef HAVE_XINPUT2
 25501         }
 25502 #endif
 25503 #endif
 25504       event_found = true;
 25505 
 25506       count += handle_one_xevent (dpyinfo, &event, &finish, hold_quit);
 25507 
 25508       if (finish == X_EVENT_GOTO_OUT)
 25509         break;
 25510     }
 25511 
 25512 #else /* USE_GTK */
 25513 
 25514   /* For GTK we must use the GTK event loop.  But XEvents gets passed
 25515      to our filter function above, and then to the big event switch.
 25516      We use a bunch of globals to communicate with our filter function,
 25517      that is kind of ugly, but it works.
 25518 
 25519      There is no way to do one display at the time, GTK just does events
 25520      from all displays.  */
 25521 
 25522   while (gtk_events_pending ())
 25523     {
 25524       current_count = count;
 25525       current_hold_quit = hold_quit;
 25526 
 25527       gtk_main_iteration ();
 25528 
 25529       count = current_count;
 25530       current_count = -1;
 25531       current_hold_quit = 0;
 25532 
 25533       if (current_finish == X_EVENT_GOTO_OUT)
 25534         break;
 25535     }
 25536 
 25537   /* Now see if `xg_pending_quit_event' was set.  */
 25538   if (xg_pending_quit_event.kind != NO_EVENT)
 25539     {
 25540       /* Check that the frame is still valid.  It could have been
 25541          deleted between now and the time the event was recorded.  */
 25542       if (FRAME_LIVE_P (XFRAME (xg_pending_quit_event.frame_or_window)))
 25543         /* Store that event into hold_quit and clear the pending quit
 25544            event.  */
 25545         *hold_quit = xg_pending_quit_event;
 25546 
 25547       /* If the frame is invalid, just clear the event as well.  */
 25548       xg_pending_quit_event.kind = NO_EVENT;
 25549     }
 25550 #endif /* USE_GTK */
 25551 
 25552   /* On some systems, an X bug causes Emacs to get no more events
 25553      when the window is destroyed.  Detect that.  (1994.)  */
 25554   if (! event_found)
 25555     {
 25556       /* Emacs and the X Server eats up CPU time if XNoOp is done every time.
 25557          One XNOOP in 100 loops will make Emacs terminate.
 25558          B. Bretthauer, 1994 */
 25559       x_noop_count++;
 25560       if (x_noop_count >= 100)
 25561         {
 25562           x_noop_count=0;
 25563 
 25564           if (next_noop_dpyinfo == 0)
 25565             next_noop_dpyinfo = x_display_list;
 25566 
 25567           XNoOp (next_noop_dpyinfo->display);
 25568 
 25569           /* Each time we get here, cycle through the displays now open.  */
 25570           next_noop_dpyinfo = next_noop_dpyinfo->next;
 25571         }
 25572     }
 25573 
 25574   /* If the focus was just given to an auto-raising frame,
 25575      raise it now.  FIXME: handle more than one such frame.  */
 25576   if (dpyinfo->x_pending_autoraise_frame)
 25577     {
 25578       x_raise_frame (dpyinfo->x_pending_autoraise_frame);
 25579       dpyinfo->x_pending_autoraise_frame = NULL;
 25580     }
 25581 
 25582   unblock_input ();
 25583 
 25584   return count;
 25585 }
 25586 
 25587 
 25588 
 25589 
 25590 /***********************************************************************
 25591                              Text Cursor
 25592  ***********************************************************************/
 25593 
 25594 /* Set clipping for output in glyph row ROW.  W is the window in which
 25595    we operate.  GC is the graphics context to set clipping in.
 25596 
 25597    ROW may be a text row or, e.g., a mode line.  Text rows must be
 25598    clipped to the interior of the window dedicated to text display,
 25599    mode lines must be clipped to the whole window.  */
 25600 
 25601 static void
 25602 x_clip_to_row (struct window *w, struct glyph_row *row,
 25603                enum glyph_row_area area, GC gc)
 25604 {
 25605   struct frame *f = XFRAME (WINDOW_FRAME (w));
 25606   XRectangle clip_rect;
 25607   int window_x, window_y, window_width;
 25608 
 25609   window_box (w, area, &window_x, &window_y, &window_width, 0);
 25610 
 25611   clip_rect.x = window_x;
 25612   clip_rect.y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, row->y));
 25613   clip_rect.y = max (clip_rect.y, window_y);
 25614   clip_rect.width = window_width;
 25615   clip_rect.height = row->visible_height;
 25616 
 25617   x_set_clip_rectangles (f, gc, &clip_rect, 1);
 25618 }
 25619 
 25620 
 25621 /* Draw a hollow box cursor on window W in glyph row ROW.  */
 25622 
 25623 static void
 25624 x_draw_hollow_cursor (struct window *w, struct glyph_row *row)
 25625 {
 25626   struct frame *f = XFRAME (WINDOW_FRAME (w));
 25627   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 25628   Display *dpy = FRAME_X_DISPLAY (f);
 25629   int x, y, wd, h;
 25630   XGCValues xgcv;
 25631   struct glyph *cursor_glyph;
 25632   GC gc;
 25633 
 25634   /* Get the glyph the cursor is on.  If we can't tell because
 25635      the current matrix is invalid or such, give up.  */
 25636   cursor_glyph = get_phys_cursor_glyph (w);
 25637   if (cursor_glyph == NULL)
 25638     return;
 25639 
 25640   /* Compute frame-relative coordinates for phys cursor.  */
 25641   get_phys_cursor_geometry (w, row, cursor_glyph, &x, &y, &h);
 25642   wd = w->phys_cursor_width - 1;
 25643 
 25644   /* The foreground of cursor_gc is typically the same as the normal
 25645      background color, which can cause the cursor box to be invisible.  */
 25646   xgcv.foreground = f->output_data.x->cursor_pixel;
 25647   xgcv.line_width = 1;
 25648   if (dpyinfo->scratch_cursor_gc)
 25649     XChangeGC (dpy, dpyinfo->scratch_cursor_gc, GCForeground | GCLineWidth, &xgcv);
 25650   else
 25651     dpyinfo->scratch_cursor_gc = XCreateGC (dpy, FRAME_X_DRAWABLE (f),
 25652                                             GCForeground | GCLineWidth, &xgcv);
 25653   gc = dpyinfo->scratch_cursor_gc;
 25654 
 25655   /* When on R2L character, show cursor at the right edge of the
 25656      glyph, unless the cursor box is as wide as the glyph or wider
 25657      (the latter happens when x-stretch-cursor is non-nil).  */
 25658   if ((cursor_glyph->resolved_level & 1) != 0
 25659       && cursor_glyph->pixel_width > wd)
 25660     {
 25661       x += cursor_glyph->pixel_width - wd;
 25662       if (wd > 0)
 25663         wd -= 1;
 25664     }
 25665   /* Set clipping, draw the rectangle, and reset clipping again.  */
 25666   x_clip_to_row (w, row, TEXT_AREA, gc);
 25667   x_draw_rectangle (f, gc, x, y, wd, h - 1);
 25668   x_reset_clip_rectangles (f, gc);
 25669 }
 25670 
 25671 
 25672 /* Draw a bar cursor on window W in glyph row ROW.
 25673 
 25674    Implementation note: One would like to draw a bar cursor with an
 25675    angle equal to the one given by the font property XA_ITALIC_ANGLE.
 25676    Unfortunately, I didn't find a font yet that has this property set.
 25677    --gerd.  */
 25678 
 25679 static void
 25680 x_draw_bar_cursor (struct window *w, struct glyph_row *row, int width, enum text_cursor_kinds kind)
 25681 {
 25682   struct frame *f = XFRAME (w->frame);
 25683   struct glyph *cursor_glyph;
 25684 
 25685   /* If cursor is out of bounds, don't draw garbage.  This can happen
 25686      in mini-buffer windows when switching between echo area glyphs
 25687      and mini-buffer.  */
 25688   cursor_glyph = get_phys_cursor_glyph (w);
 25689   if (cursor_glyph == NULL)
 25690     return;
 25691 
 25692   /* Experimental avoidance of cursor on xwidget.  */
 25693   if (cursor_glyph->type == XWIDGET_GLYPH)
 25694     return;
 25695 
 25696   /* If on an image, draw like a normal cursor.  That's usually better
 25697      visible than drawing a bar, esp. if the image is large so that
 25698      the bar might not be in the window.  */
 25699   if (cursor_glyph->type == IMAGE_GLYPH)
 25700     {
 25701       struct glyph_row *r;
 25702       r = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
 25703       draw_phys_cursor_glyph (w, r, DRAW_CURSOR);
 25704     }
 25705   else
 25706     {
 25707       Display *dpy = FRAME_X_DISPLAY (f);
 25708       Drawable drawable = FRAME_X_DRAWABLE (f);
 25709       GC gc = FRAME_DISPLAY_INFO (f)->scratch_cursor_gc;
 25710       unsigned long mask = GCForeground | GCBackground | GCGraphicsExposures;
 25711       struct face *face = FACE_FROM_ID (f, cursor_glyph->face_id);
 25712       XGCValues xgcv;
 25713 
 25714       /* If the glyph's background equals the color we normally draw
 25715          the bars cursor in, the bar cursor in its normal color is
 25716          invisible.  Use the glyph's foreground color instead in this
 25717          case, on the assumption that the glyph's colors are chosen so
 25718          that the glyph is legible.  */
 25719       if (face->background == f->output_data.x->cursor_pixel)
 25720         xgcv.background = xgcv.foreground = face->foreground;
 25721       else
 25722         xgcv.background = xgcv.foreground = f->output_data.x->cursor_pixel;
 25723       xgcv.graphics_exposures = False;
 25724       xgcv.line_width = 1;
 25725 
 25726       mask |= GCLineWidth;
 25727 
 25728       if (gc)
 25729         XChangeGC (dpy, gc, mask, &xgcv);
 25730       else
 25731         {
 25732           gc = XCreateGC (dpy, drawable, mask, &xgcv);
 25733           FRAME_DISPLAY_INFO (f)->scratch_cursor_gc = gc;
 25734         }
 25735 
 25736       x_clip_to_row (w, row, TEXT_AREA, gc);
 25737 
 25738       if (kind == BAR_CURSOR)
 25739         {
 25740           int x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
 25741 
 25742           if (width < 0)
 25743             width = FRAME_CURSOR_WIDTH (f);
 25744           width = min (cursor_glyph->pixel_width, width);
 25745 
 25746           w->phys_cursor_width = width;
 25747 
 25748           /* If the character under cursor is R2L, draw the bar cursor
 25749              on the right of its glyph, rather than on the left.  */
 25750           if ((cursor_glyph->resolved_level & 1) != 0)
 25751             x += cursor_glyph->pixel_width - width;
 25752 
 25753           x_fill_rectangle (f, gc, x,
 25754                             WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
 25755                             width, row->height, false);
 25756         }
 25757       else /* HBAR_CURSOR */
 25758         {
 25759           int dummy_x, dummy_y, dummy_h;
 25760           int x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
 25761 
 25762           if (width < 0)
 25763             width = row->height;
 25764 
 25765           width = min (row->height, width);
 25766 
 25767           get_phys_cursor_geometry (w, row, cursor_glyph, &dummy_x,
 25768                                     &dummy_y, &dummy_h);
 25769 
 25770           if ((cursor_glyph->resolved_level & 1) != 0
 25771               && cursor_glyph->pixel_width > w->phys_cursor_width - 1)
 25772             x += cursor_glyph->pixel_width - w->phys_cursor_width + 1;
 25773           x_fill_rectangle (f, gc, x,
 25774                             WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
 25775                                                      row->height - width),
 25776                             w->phys_cursor_width - 1, width, false);
 25777         }
 25778 
 25779       x_reset_clip_rectangles (f, gc);
 25780     }
 25781 }
 25782 
 25783 
 25784 /* RIF: Define cursor CURSOR on frame F.  */
 25785 
 25786 static void
 25787 x_define_frame_cursor (struct frame *f, Emacs_Cursor cursor)
 25788 {
 25789   if (!f->pointer_invisible
 25790       && f->output_data.x->current_cursor != cursor)
 25791     XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), cursor);
 25792   f->output_data.x->current_cursor = cursor;
 25793 }
 25794 
 25795 
 25796 /* RIF: Clear area on frame F.  */
 25797 
 25798 static void
 25799 x_clear_frame_area (struct frame *f, int x, int y, int width, int height)
 25800 {
 25801   x_clear_area (f, x, y, width, height);
 25802 }
 25803 
 25804 
 25805 /* RIF: Draw cursor on window W.  */
 25806 
 25807 static void
 25808 x_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, int x,
 25809                       int y, enum text_cursor_kinds cursor_type,
 25810                       int cursor_width, bool on_p, bool active_p)
 25811 {
 25812 #ifdef HAVE_X_I18N
 25813   struct frame *f = XFRAME (WINDOW_FRAME (w));
 25814 #endif
 25815 
 25816   if (on_p)
 25817     {
 25818       w->phys_cursor_type = cursor_type;
 25819       w->phys_cursor_on_p = true;
 25820 
 25821       if (glyph_row->exact_window_width_line_p
 25822           && (glyph_row->reversed_p
 25823               ? (w->phys_cursor.hpos < 0)
 25824               : (w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])))
 25825         {
 25826           glyph_row->cursor_in_fringe_p = true;
 25827           draw_fringe_bitmap (w, glyph_row, glyph_row->reversed_p);
 25828         }
 25829       else
 25830         {
 25831           switch (cursor_type)
 25832             {
 25833             case HOLLOW_BOX_CURSOR:
 25834               x_draw_hollow_cursor (w, glyph_row);
 25835               break;
 25836 
 25837             case FILLED_BOX_CURSOR:
 25838               draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
 25839               break;
 25840 
 25841             case BAR_CURSOR:
 25842               x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
 25843               break;
 25844 
 25845             case HBAR_CURSOR:
 25846               x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
 25847               break;
 25848 
 25849             case NO_CURSOR:
 25850               w->phys_cursor_width = 0;
 25851               break;
 25852 
 25853             default:
 25854               emacs_abort ();
 25855             }
 25856         }
 25857 
 25858 #ifdef HAVE_X_I18N
 25859       if (w == XWINDOW (f->selected_window))
 25860         xic_set_preeditarea (w, x, y);
 25861 #endif
 25862     }
 25863 }
 25864 
 25865 
 25866 /* Icons.  */
 25867 
 25868 /* Make the x-window of frame F use the gnu icon bitmap.  */
 25869 
 25870 static bool
 25871 x_bitmap_icon (struct frame *f, Lisp_Object file)
 25872 {
 25873   ptrdiff_t bitmap_id;
 25874 
 25875   if (FRAME_X_WINDOW (f) == 0)
 25876     return true;
 25877 
 25878   /* Free up our existing icon bitmap and mask if any.  */
 25879   if (f->output_data.x->icon_bitmap > 0)
 25880     image_destroy_bitmap (f, f->output_data.x->icon_bitmap);
 25881   f->output_data.x->icon_bitmap = 0;
 25882 
 25883   if (STRINGP (file))
 25884     {
 25885 #ifdef USE_GTK
 25886       /* Use gtk_window_set_icon_from_file () if available,
 25887          It's not restricted to bitmaps */
 25888       if (xg_set_icon (f, file))
 25889         return false;
 25890 #endif /* USE_GTK */
 25891       bitmap_id = image_create_bitmap_from_file (f, file);
 25892       x_create_bitmap_mask (f, bitmap_id);
 25893     }
 25894   else
 25895     {
 25896       /* Create the GNU bitmap and mask if necessary.  */
 25897       if (FRAME_DISPLAY_INFO (f)->icon_bitmap_id < 0)
 25898         {
 25899           ptrdiff_t rc = -1;
 25900 
 25901 #ifdef USE_GTK
 25902 
 25903           if (xg_set_icon (f, xg_default_icon_file)
 25904               || xg_set_icon_from_xpm_data (f, gnu_xpm_bits))
 25905             {
 25906               FRAME_DISPLAY_INFO (f)->icon_bitmap_id = -2;
 25907               return false;
 25908             }
 25909 
 25910 #elif defined (HAVE_XPM) && defined (HAVE_X_WINDOWS)
 25911           /* This allocates too many colors.  */
 25912           if ((FRAME_X_VISUAL_INFO (f)->class == TrueColor
 25913                || FRAME_X_VISUAL_INFO (f)->class == StaticColor
 25914                || FRAME_X_VISUAL_INFO (f)->class == StaticGray)
 25915               /* That pixmap needs about 240 colors, and we should
 25916                  also leave some more space for other colors as
 25917                  well.  */
 25918               || FRAME_X_VISUAL_INFO (f)->colormap_size >= (240 * 4))
 25919             {
 25920               rc = x_create_bitmap_from_xpm_data (f, gnu_xpm_bits);
 25921               if (rc != -1)
 25922                 FRAME_DISPLAY_INFO (f)->icon_bitmap_id = rc;
 25923             }
 25924 #endif
 25925 
 25926           /* If all else fails, use the (black and white) xbm image. */
 25927           if (rc == -1)
 25928             {
 25929               rc = image_create_bitmap_from_data (f,
 25930                                                   (char *) gnu_xbm_bits,
 25931                                                   gnu_xbm_width,
 25932                                                   gnu_xbm_height);
 25933               if (rc == -1)
 25934                 return true;
 25935 
 25936               FRAME_DISPLAY_INFO (f)->icon_bitmap_id = rc;
 25937               x_create_bitmap_mask (f, FRAME_DISPLAY_INFO (f)->icon_bitmap_id);
 25938             }
 25939         }
 25940 
 25941       /* The first time we create the GNU bitmap and mask,
 25942          this increments the ref-count one extra time.
 25943          As a result, the GNU bitmap and mask are never freed.
 25944          That way, we don't have to worry about allocating it again.  */
 25945       image_reference_bitmap (f, FRAME_DISPLAY_INFO (f)->icon_bitmap_id);
 25946 
 25947       bitmap_id = FRAME_DISPLAY_INFO (f)->icon_bitmap_id;
 25948     }
 25949 
 25950   x_wm_set_icon_pixmap (f, bitmap_id);
 25951   f->output_data.x->icon_bitmap = bitmap_id;
 25952 
 25953   return false;
 25954 }
 25955 
 25956 
 25957 /* Make the x-window of frame F use a rectangle with text.
 25958    Use ICON_NAME as the text.  */
 25959 
 25960 bool
 25961 x_text_icon (struct frame *f, const char *icon_name)
 25962 {
 25963   if (FRAME_X_WINDOW (f) == 0)
 25964     return true;
 25965 
 25966   {
 25967     XTextProperty text;
 25968     text.value = (unsigned char *) icon_name;
 25969     text.encoding = XA_STRING;
 25970     text.format = 8;
 25971     text.nitems = strlen (icon_name);
 25972     XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
 25973   }
 25974 
 25975   if (f->output_data.x->icon_bitmap > 0)
 25976     image_destroy_bitmap (f, f->output_data.x->icon_bitmap);
 25977   f->output_data.x->icon_bitmap = 0;
 25978   x_wm_set_icon_pixmap (f, 0);
 25979 
 25980   return false;
 25981 }
 25982 
 25983 
 25984 struct x_error_message_stack
 25985 {
 25986   /* Pointer to the error message of any error that was generated, or
 25987      NULL.  */
 25988   char *string;
 25989 
 25990   /* The display this error handler applies to.  */
 25991   Display *dpy;
 25992 
 25993   /* A function to call upon an error if non-NULL.  */
 25994   x_special_error_handler handler;
 25995 
 25996   /* Some data to pass to that handler function.  */
 25997   void *handler_data;
 25998 
 25999   /* The previous handler in this stack.  */
 26000   struct x_error_message_stack *prev;
 26001 
 26002   /* The first request that this error handler applies to.  Keeping
 26003      track of this allows us to avoid an XSync yet still have errors
 26004      for previously made requests be handled correctly.  */
 26005   unsigned long first_request;
 26006 };
 26007 
 26008 /* Stack of X error message handlers.  Whenever an error is generated
 26009    on a display, look in this stack for an appropriate error handler,
 26010    set its `string' to the error message and call its `handler' with
 26011    `handler_data'.  If no handler applies to the error, don't catch
 26012    it, and let it crash Emacs instead.
 26013 
 26014    This used to be a pointer to a string in which any error would be
 26015    placed before 2006.  */
 26016 static struct x_error_message_stack *x_error_message;
 26017 
 26018 /* The amount of items (depth) in that stack.  */
 26019 int x_error_message_count;
 26020 
 26021 /* Compare various request serials while handling wraparound.  Treat a
 26022    difference of more than X_ULONG_MAX / 2 as wraparound.
 26023 
 26024    Note that these functions truncate serials to 32 bits before
 26025    comparison.  */
 26026 
 26027 static bool
 26028 x_is_serial_more_than (unsigned int a, unsigned int b)
 26029 {
 26030   if (a > b)
 26031     return true;
 26032 
 26033   return (b - a > X_ULONG_MAX / 2);
 26034 }
 26035 
 26036 static bool
 26037 x_is_serial_more_than_or_equal_to (unsigned int a, unsigned int b)
 26038 {
 26039   if (a >= b)
 26040     return true;
 26041 
 26042   return (b - a > X_ULONG_MAX / 2);
 26043 }
 26044 
 26045 static bool
 26046 x_is_serial_less_than (unsigned int a, unsigned int b)
 26047 {
 26048   if (a < b)
 26049     return true;
 26050 
 26051   return (a - b > X_ULONG_MAX / 2);
 26052 }
 26053 
 26054 static bool
 26055 x_is_serial_less_than_or_equal_to (unsigned int a, unsigned int b)
 26056 {
 26057   if (a <= b)
 26058     return true;
 26059 
 26060   return (a - b > X_ULONG_MAX / 2);
 26061 }
 26062 
 26063 static struct x_error_message_stack *
 26064 x_find_error_handler (Display *dpy, XErrorEvent *event)
 26065 {
 26066   struct x_error_message_stack *stack;
 26067 
 26068   stack = x_error_message;
 26069 
 26070   while (stack)
 26071     {
 26072       if (x_is_serial_more_than_or_equal_to (event->serial,
 26073                                              stack->first_request)
 26074           && dpy == stack->dpy)
 26075         return stack;
 26076 
 26077       stack = stack->prev;
 26078     }
 26079 
 26080   return NULL;
 26081 }
 26082 
 26083 void
 26084 x_unwind_errors_to (int depth)
 26085 {
 26086   while (x_error_message_count > depth)
 26087     /* This is safe to call because we check whether or not
 26088        x_error_message->dpy is still alive before calling XSync.  */
 26089     x_uncatch_errors ();
 26090 }
 26091 
 26092 #define X_ERROR_MESSAGE_SIZE 200
 26093 
 26094 /* An X error handler which stores the error message in the first
 26095    applicable handler in the x_error_message stack.  This is called
 26096    from *x_error_handler if an x_catch_errors for DISPLAY is in
 26097    effect.  */
 26098 
 26099 static void
 26100 x_error_catcher (Display *display, XErrorEvent *event,
 26101                  struct x_error_message_stack *stack)
 26102 {
 26103   char buf[X_ERROR_MESSAGE_SIZE];
 26104 
 26105   XGetErrorText (display, event->error_code,
 26106                  buf, X_ERROR_MESSAGE_SIZE);
 26107 
 26108   if (stack->string)
 26109     xfree (stack->string);
 26110 
 26111   stack->string = xstrdup (buf);
 26112 
 26113   if (stack->handler)
 26114     stack->handler (display, event, stack->string,
 26115                     stack->handler_data);
 26116 }
 26117 
 26118 /* Begin trapping X errors for display DPY.
 26119 
 26120    After calling this function, X protocol errors generated on DPY no
 26121    longer cause Emacs to exit; instead, they are recorded in an error
 26122    handler pushed onto the stack `x_error_message'.
 26123 
 26124    Calling x_check_errors signals an Emacs error if an X error has
 26125    occurred since the last call to x_catch_errors or x_check_errors.
 26126 
 26127    Calling x_uncatch_errors resumes the normal error handling,
 26128    skipping an XSync if the last request made is known to have been
 26129    processed.  Calling x_uncatch_errors_after_check is similar, but
 26130    always skips an XSync to the server, and should be used only
 26131    immediately after x_had_errors_p or x_check_errors, or when it is
 26132    known that no requests have been made since the last x_catch_errors
 26133    call for DPY.
 26134 
 26135    There is no need to use this mechanism for ignoring errors from
 26136    single asynchronous requests, such as sending a ClientMessage to a
 26137    window that might no longer exist.  Use
 26138    x_ignore_errors_for_next_request (paired with
 26139    x_stop_ignoring_errors) instead.  */
 26140 
 26141 void
 26142 x_catch_errors_with_handler (Display *dpy, x_special_error_handler handler,
 26143                              void *handler_data)
 26144 {
 26145   struct x_error_message_stack *data;
 26146 
 26147   data = xzalloc (sizeof *data);
 26148   data->dpy = dpy;
 26149   data->handler = handler;
 26150   data->handler_data = handler_data;
 26151   data->prev = x_error_message;
 26152   data->first_request = XNextRequest (dpy);
 26153   x_error_message = data;
 26154 
 26155   ++x_error_message_count;
 26156 }
 26157 
 26158 void
 26159 x_catch_errors (Display *dpy)
 26160 {
 26161   x_catch_errors_with_handler (dpy, NULL, NULL);
 26162 }
 26163 
 26164 /* Return if errors for REQUEST should be ignored even if there is no
 26165    error handler applied.  */
 26166 static struct x_failable_request *
 26167 x_request_can_fail (struct x_display_info *dpyinfo,
 26168                     unsigned long request)
 26169 {
 26170   struct x_failable_request *failable_requests;
 26171 
 26172   for (failable_requests = dpyinfo->failable_requests;
 26173        failable_requests < dpyinfo->next_failable_request;
 26174        failable_requests++)
 26175     {
 26176       if (x_is_serial_more_than_or_equal_to (request,
 26177                                              failable_requests->start)
 26178           && (!failable_requests->end
 26179               || x_is_serial_less_than_or_equal_to (request,
 26180                                                     failable_requests->end)))
 26181         return failable_requests;
 26182     }
 26183 
 26184   return NULL;
 26185 }
 26186 
 26187 /* Remove outdated request serials from
 26188    dpyinfo->failable_requests.  */
 26189 static void
 26190 x_clean_failable_requests (struct x_display_info *dpyinfo)
 26191 {
 26192   struct x_failable_request *first, *last;
 26193 
 26194   last = dpyinfo->next_failable_request;
 26195 
 26196   for (first = dpyinfo->failable_requests; first < last; first++)
 26197     {
 26198       if (x_is_serial_more_than (first->start,
 26199                                  LastKnownRequestProcessed (dpyinfo->display))
 26200           || !first->end
 26201           || x_is_serial_more_than (first->end,
 26202                                     LastKnownRequestProcessed (dpyinfo->display)))
 26203         break;
 26204     }
 26205 
 26206   if (first != last)
 26207     memmove (&dpyinfo->failable_requests, first,
 26208              sizeof *first * (last - first));
 26209 
 26210   dpyinfo->next_failable_request = (dpyinfo->failable_requests
 26211                                     + (last - first));
 26212 }
 26213 
 26214 /* Protect a section of X requests.
 26215 
 26216    Ignore errors generated by X requests made from now until
 26217    `x_stop_ignoring_errors'.  Each call must be paired with a call to
 26218    `x_stop_ignoring_errors', and recursive calls inside the protected
 26219    section are not allowed.
 26220 
 26221    The advantage over x_catch_errors followed by
 26222    x_uncatch_errors_after_check is that this function does not sync to
 26223    catch errors if requests were made.  It should be used instead of
 26224    those two functions for catching errors around requests that do not
 26225    require a reply.
 26226 
 26227    If SELECTION_SERIAL is an arbitrary number greater than zero,
 26228    x_select_handle_selection_error is called with the specified number
 26229    after any errors within the protected section are received to
 26230    delete the selection request that encountered errors.  */
 26231 
 26232 void
 26233 x_ignore_errors_for_next_request (struct x_display_info *dpyinfo,
 26234                                   unsigned int selection_serial)
 26235 {
 26236   struct x_failable_request *request, *max;
 26237   unsigned long next_request;
 26238 #ifdef HAVE_GTK3
 26239   GdkDisplay *gdpy;
 26240 #endif
 26241 
 26242   /* This code is not reentrant, so be sure nothing calls it
 26243      recursively in response to input.  */
 26244   block_input ();
 26245 
 26246 #ifdef HAVE_GTK3
 26247   /* GTK 3 tends to override our own error handler inside certain
 26248      callbacks, which this can be called from.  Instead of trying to
 26249      restore our own, add a trap for the following requests with
 26250      GDK as well.  */
 26251 
 26252   gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display);
 26253 
 26254   if (gdpy)
 26255     gdk_x11_display_error_trap_push (gdpy);
 26256 #endif
 26257 
 26258   if ((dpyinfo->next_failable_request
 26259        != dpyinfo->failable_requests)
 26260       && (dpyinfo->next_failable_request - 1)->end == 0)
 26261     /* A new sequence should never be started before an old one
 26262        finishes.  Use `x_catch_errors' to nest error handlers.  */
 26263     emacs_abort ();
 26264 
 26265   request = dpyinfo->next_failable_request;
 26266   max = dpyinfo->failable_requests + N_FAILABLE_REQUESTS;
 26267   next_request = XNextRequest (dpyinfo->display);
 26268 
 26269   if (request >= max)
 26270     {
 26271       /* There is no point in making this extra sync if all requests
 26272          are known to have been fully processed.  */
 26273       if ((LastKnownRequestProcessed (dpyinfo->display)
 26274            != next_request - 1))
 26275         XSync (dpyinfo->display, False);
 26276 
 26277       x_clean_failable_requests (dpyinfo);
 26278       request = dpyinfo->next_failable_request;
 26279     }
 26280 
 26281   if (request >= max)
 26282     /* A request should always be made immediately after calling this
 26283        function.  */
 26284     emacs_abort ();
 26285 
 26286   request->start = next_request;
 26287   request->end = 0;
 26288   request->selection_serial = selection_serial;
 26289 
 26290   dpyinfo->next_failable_request++;
 26291 }
 26292 
 26293 void
 26294 x_stop_ignoring_errors (struct x_display_info *dpyinfo)
 26295 {
 26296   struct x_failable_request *range;
 26297 #ifdef HAVE_GTK3
 26298   GdkDisplay *gdpy;
 26299 #endif
 26300 
 26301   range = dpyinfo->next_failable_request - 1;
 26302   range->end = XNextRequest (dpyinfo->display) - 1;
 26303 
 26304   /* Abort if no request was made since
 26305      `x_ignore_errors_for_next_request'.  */
 26306 
 26307   if (x_is_serial_less_than (range->end, range->start))
 26308     emacs_abort ();
 26309 
 26310 #ifdef HAVE_GTK3
 26311   gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display);
 26312 
 26313   if (gdpy)
 26314     gdk_x11_display_error_trap_pop_ignored (gdpy);
 26315 #endif
 26316 
 26317   unblock_input ();
 26318 }
 26319 
 26320 /* Undo the last x_catch_errors call.
 26321    DPY should be the display that was passed to x_catch_errors.
 26322 
 26323    This version should be used only if the immediately preceding
 26324    X-protocol-related thing was x_check_errors or x_had_error_p, both
 26325    of which issue XSync calls, so we don't need to re-sync here.  */
 26326 
 26327 void
 26328 x_uncatch_errors_after_check (void)
 26329 {
 26330   struct x_error_message_stack *tmp;
 26331 
 26332   block_input ();
 26333   tmp = x_error_message;
 26334   x_error_message = x_error_message->prev;
 26335   --x_error_message_count;
 26336   if (tmp->string)
 26337     xfree (tmp->string);
 26338   xfree (tmp);
 26339   unblock_input ();
 26340 }
 26341 
 26342 /* Undo the last x_catch_errors call.  */
 26343 
 26344 void
 26345 x_uncatch_errors (void)
 26346 {
 26347   struct x_error_message_stack *tmp;
 26348   struct x_display_info *dpyinfo;
 26349 
 26350   /* In rare situations when running Emacs run in daemon mode,
 26351      shutting down an emacsclient via delete-frame can cause
 26352      x_uncatch_errors to be called when x_error_message is set to
 26353      NULL.  */
 26354   if (x_error_message == NULL)
 26355     return;
 26356 
 26357   block_input ();
 26358 
 26359   dpyinfo = x_display_info_for_display (x_error_message->dpy);
 26360 
 26361   /* The display may have been closed before this function is called.
 26362      Check if it is still open before calling XSync.  */
 26363   if (dpyinfo != 0
 26364       /* There is no point in making this extra sync if all requests
 26365          are known to have been fully processed.  */
 26366       && (LastKnownRequestProcessed (x_error_message->dpy)
 26367           != XNextRequest (x_error_message->dpy) - 1)
 26368       /* Likewise if no request was made since the trap was
 26369          installed.  */
 26370       && (NextRequest (x_error_message->dpy)
 26371           > x_error_message->first_request))
 26372     {
 26373       XSync (x_error_message->dpy, False);
 26374       x_clean_failable_requests (dpyinfo);
 26375     }
 26376 
 26377   tmp = x_error_message;
 26378   x_error_message = x_error_message->prev;
 26379   --x_error_message_count;
 26380   if (tmp->string)
 26381     xfree (tmp->string);
 26382   xfree (tmp);
 26383   unblock_input ();
 26384 }
 26385 
 26386 /* If any X protocol errors have arrived since the last call to
 26387    x_catch_errors or x_check_errors, signal an Emacs error using
 26388    sprintf (a buffer, FORMAT, the x error message text) as the text.  */
 26389 
 26390 void
 26391 x_check_errors (Display *dpy, const char *format)
 26392 {
 26393   struct x_display_info *dpyinfo;
 26394   char *string;
 26395 
 26396   /* This shouldn't happen, since x_check_errors should be called
 26397      immediately inside an x_catch_errors block.  */
 26398   if (dpy != x_error_message->dpy)
 26399     emacs_abort ();
 26400 
 26401   /* There is no point in making this extra sync if all requests
 26402      are known to have been fully processed.  */
 26403   if ((LastKnownRequestProcessed (dpy)
 26404        != XNextRequest (dpy) - 1)
 26405       && (NextRequest (dpy)
 26406           > x_error_message->first_request))
 26407     XSync (dpy, False);
 26408 
 26409   dpyinfo = x_display_info_for_display (dpy);
 26410 
 26411   /* Clean the array of failable requests, since a sync happened.  */
 26412   if (dpyinfo)
 26413     x_clean_failable_requests (dpyinfo);
 26414 
 26415   if (x_error_message->string)
 26416     {
 26417       string = alloca (strlen (x_error_message->string) + 1);
 26418       strcpy (string, x_error_message->string);
 26419 
 26420       error (format, string);
 26421     }
 26422 }
 26423 
 26424 /* Nonzero if any X protocol errors were generated since the last call
 26425    to x_catch_errors on DPY.  */
 26426 
 26427 bool
 26428 x_had_errors_p (Display *dpy)
 26429 {
 26430   struct x_display_info *dpyinfo;
 26431 
 26432   /* This shouldn't happen, since x_check_errors should be called
 26433      immediately inside an x_catch_errors block.  */
 26434   if (dpy != x_error_message->dpy)
 26435     emacs_abort ();
 26436 
 26437   /* Make sure to catch any errors incurred so far.  */
 26438   if ((LastKnownRequestProcessed (dpy)
 26439        != XNextRequest (dpy) - 1)
 26440       && (NextRequest (dpy)
 26441           > x_error_message->first_request))
 26442     XSync (dpy, False);
 26443 
 26444   dpyinfo = x_display_info_for_display (dpy);
 26445 
 26446   /* Clean the array of failable requests, since a sync happened.  */
 26447   if (dpyinfo)
 26448     x_clean_failable_requests (dpyinfo);
 26449 
 26450   return !!x_error_message->string;
 26451 }
 26452 
 26453 /* Forget about any errors we have had, since we did x_catch_errors on
 26454    DPY.  */
 26455 
 26456 void
 26457 x_clear_errors (Display *dpy)
 26458 {
 26459   /* This shouldn't happen, since x_check_errors should be called
 26460      immediately inside an x_catch_errors block.  */
 26461   if (dpy != x_error_message->dpy)
 26462     emacs_abort ();
 26463 
 26464   xfree (x_error_message->string);
 26465   x_error_message->string = NULL;
 26466 }
 26467 
 26468 #if false
 26469       /* See comment in unwind_to_catch why calling this is a bad
 26470        * idea.  --lorentey   */
 26471 /* Close off all unclosed x_catch_errors calls.  */
 26472 
 26473 void
 26474 x_fully_uncatch_errors (void)
 26475 {
 26476   while (x_error_message)
 26477     x_uncatch_errors ();
 26478 }
 26479 #endif
 26480 
 26481 #if false
 26482 static unsigned int x_wire_count;
 26483 
 26484 static int
 26485 x_trace_wire (Display *dpy)
 26486 {
 26487   fprintf (stderr, "Lib call: %u\n", ++x_wire_count);
 26488   return 0;
 26489 }
 26490 #endif
 26491 
 26492 
 26493 /************************************************************************
 26494                           Handling X errors
 26495  ************************************************************************/
 26496 
 26497 /* Error message passed to x_connection_closed.  */
 26498 
 26499 static char *error_msg;
 26500 
 26501 /* Try to find a frame in Vframe_list, and make it the selected frame.
 26502    `delete_frame' sometimes misses the initial frame for an unknown
 26503    reason when Emacs is running as a background daemon.  */
 26504 
 26505 static void
 26506 x_try_restore_frame (void)
 26507 {
 26508   Lisp_Object tail, frame;
 26509 
 26510   FOR_EACH_FRAME (tail, frame)
 26511     {
 26512       if (!NILP (do_switch_frame (frame, 0, 1, Qnil)))
 26513         return;
 26514     }
 26515 }
 26516 
 26517 /* Handle the loss of connection to display DPY.  ERROR_MESSAGE is
 26518    the text of an error message that lead to the connection loss.  */
 26519 
 26520 static void
 26521 x_connection_closed (Display *dpy, const char *error_message, bool ioerror)
 26522 {
 26523   struct x_display_info *dpyinfo;
 26524   Lisp_Object frame, tail;
 26525   specpdl_ref idx = SPECPDL_INDEX ();
 26526   Emacs_XIOErrorHandler io_error_handler;
 26527   xm_drop_start_message dmsg;
 26528   struct frame *f;
 26529   Lisp_Object minibuf_frame, tmp;
 26530   struct x_failable_request *failable;
 26531   struct x_error_message_stack *stack;
 26532   static Display *current_display;
 26533 
 26534   /* Prevent recursive calls of this function for the same display.
 26535      This is because destroying a frame might still cause an IO error
 26536      in some cases.  (bug#56528) */
 26537   if (current_display == dpy)
 26538     return;
 26539 
 26540   current_display = dpy;
 26541 
 26542   dpyinfo = x_display_info_for_display (dpy);
 26543   error_msg = alloca (strlen (error_message) + 1);
 26544   strcpy (error_msg, error_message);
 26545 
 26546   /* Inhibit redisplay while frames are being deleted. */
 26547   specbind (Qinhibit_redisplay, Qt);
 26548 
 26549   /* If drag-and-drop is in progress, cancel drag-and-drop.  If DND
 26550      frame's display is DPY, don't reset event masks or try to send
 26551      responses to other programs because the display is going
 26552      away.  */
 26553 
 26554   if (x_dnd_in_progress || x_dnd_waiting_for_finish)
 26555     {
 26556       if (!ioerror)
 26557         {
 26558           /* Handle display disconnect errors here because this function
 26559              is not reentrant at this particular spot.  */
 26560           io_error_handler = XSetIOErrorHandler (x_dnd_io_error_handler);
 26561 
 26562           if (!!sigsetjmp (x_dnd_disconnect_handler, 1)
 26563               && x_dnd_in_progress
 26564               && dpy == (x_dnd_waiting_for_finish
 26565                          ? x_dnd_finish_display
 26566                          : FRAME_X_DISPLAY (x_dnd_frame)))
 26567             {
 26568               /* Clean up drag and drop if the drag frame's display isn't
 26569                  the one being disconnected.  */
 26570               f = x_dnd_frame;
 26571 
 26572               if (x_dnd_last_seen_window != None
 26573                   && x_dnd_last_protocol_version != -1)
 26574                 x_dnd_send_leave (x_dnd_frame,
 26575                                   x_dnd_last_seen_window,
 26576                                   x_dnd_last_seen_toplevel);
 26577               else if (x_dnd_last_seen_window != None
 26578                        && !XM_DRAG_STYLE_IS_DROP_ONLY (x_dnd_last_motif_style)
 26579                        && x_dnd_last_motif_style != XM_DRAG_STYLE_NONE
 26580                        && x_dnd_motif_setup_p)
 26581                 {
 26582                   dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 26583                                                 XM_DRAG_REASON_DROP_START);
 26584                   dmsg.byte_order = XM_BYTE_ORDER_CUR_FIRST;
 26585                   dmsg.timestamp = FRAME_DISPLAY_INFO (f)->last_user_time;
 26586                   dmsg.side_effects
 26587                     = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (FRAME_DISPLAY_INFO (f),
 26588                                                                        x_dnd_wanted_action),
 26589                                            XM_DROP_SITE_VALID, x_dnd_motif_operations,
 26590                                            XM_DROP_ACTION_DROP_CANCEL);
 26591                   dmsg.x = 0;
 26592                   dmsg.y = 0;
 26593                   dmsg.index_atom = x_dnd_motif_atom;
 26594                   dmsg.source_window = FRAME_X_WINDOW (f);
 26595 
 26596                   x_dnd_send_xm_leave_for_drop (FRAME_DISPLAY_INFO (f), f,
 26597                                                 x_dnd_last_seen_window, 0);
 26598                   xm_send_drop_message (FRAME_DISPLAY_INFO (f), FRAME_X_WINDOW (f),
 26599                                         x_dnd_last_seen_window, &dmsg);
 26600                 }
 26601             }
 26602 
 26603           XSetIOErrorHandler (io_error_handler);
 26604         }
 26605 
 26606       dpyinfo = x_display_info_for_display (dpy);
 26607 
 26608       x_dnd_last_seen_window = None;
 26609       x_dnd_last_seen_toplevel = None;
 26610       x_dnd_in_progress = false;
 26611       x_dnd_waiting_for_finish = false;
 26612 
 26613       if (x_dnd_use_toplevels)
 26614         x_dnd_free_toplevels (!ioerror);
 26615 
 26616       x_dnd_return_frame_object = NULL;
 26617       x_dnd_movement_frame = NULL;
 26618       x_dnd_wheel_frame = NULL;
 26619       x_dnd_frame = NULL;
 26620     }
 26621 
 26622   if (dpyinfo)
 26623     {
 26624       /* Protect display from being closed when we delete the last
 26625          frame on it. */
 26626       dpyinfo->reference_count++;
 26627       dpyinfo->terminal->reference_count++;
 26628       if (ioerror)
 26629         dpyinfo->display = 0;
 26630     }
 26631 
 26632   /* delete_frame can still try to read async input (even though we
 26633      tell pass `noelisp'), because looking up the `delete-before'
 26634      parameter calls Fassq which then calls maybe_quit.  So block
 26635      input while deleting frames.  */
 26636   block_input ();
 26637 
 26638   /* First delete frames whose mini-buffers are on frames
 26639      that are on the dead display.  */
 26640   FOR_EACH_FRAME (tail, frame)
 26641     {
 26642       /* Tooltip frames don't have these, so avoid crashing.  */
 26643 
 26644       if (FRAME_TOOLTIP_P (XFRAME (frame)))
 26645         continue;
 26646 
 26647       minibuf_frame
 26648         = WINDOW_FRAME (XWINDOW (FRAME_MINIBUF_WINDOW (XFRAME (frame))));
 26649 
 26650       if (FRAME_X_P (XFRAME (frame))
 26651           && FRAME_X_P (XFRAME (minibuf_frame))
 26652           && ! EQ (frame, minibuf_frame)
 26653           && FRAME_DISPLAY_INFO (XFRAME (minibuf_frame)) == dpyinfo)
 26654         delete_frame (frame, Qnoelisp);
 26655     }
 26656 
 26657   /* Now delete all remaining frames on the dead display.
 26658      We are now sure none of these is used as the mini-buffer
 26659      for another frame that we need to delete.  */
 26660   FOR_EACH_FRAME (tail, frame)
 26661     if (FRAME_X_P (XFRAME (frame))
 26662         && FRAME_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
 26663       {
 26664         /* Set this to t so that delete_frame won't get confused
 26665            trying to find a replacement.  */
 26666         kset_default_minibuffer_frame (FRAME_KBOARD (XFRAME (frame)), Qt);
 26667         delete_frame (frame, Qnoelisp);
 26668       }
 26669 
 26670   /* If DPYINFO is null, this means we didn't open the display in the
 26671      first place, so don't try to close it.  */
 26672   if (dpyinfo)
 26673     {
 26674       /* We can not call XtCloseDisplay here because it calls XSync.
 26675          XSync inside the error handler apparently hangs Emacs.  On
 26676          current Xt versions, this isn't needed either.  */
 26677 #ifdef USE_GTK
 26678       /* A long-standing GTK bug prevents proper disconnect handling
 26679          <https://gitlab.gnome.org/GNOME/gtk/issues/221>.  Once,
 26680          the resulting Glib error message loop filled a user's disk.
 26681          To avoid this, kill Emacs unconditionally on disconnect.  */
 26682       shut_down_emacs (0, Qnil);
 26683       fprintf (stderr, "%s\n\
 26684 When compiled with GTK, Emacs cannot recover from X disconnects.\n\
 26685 This is a GTK bug: https://gitlab.gnome.org/GNOME/gtk/issues/221\n\
 26686 For details, see etc/PROBLEMS.\n",
 26687                error_msg);
 26688       emacs_abort ();
 26689 #endif /* USE_GTK */
 26690 
 26691       /* Indicate that this display is dead.  */
 26692       dpyinfo->display = 0;
 26693 
 26694       dpyinfo->reference_count--;
 26695       dpyinfo->terminal->reference_count--;
 26696       if (dpyinfo->reference_count != 0)
 26697         /* We have just closed all frames on this display. */
 26698         emacs_abort ();
 26699 
 26700       /* This was the last terminal remaining, so print the error
 26701          message and associated error handlers and kill Emacs.  */
 26702       if (dpyinfo->terminal == terminal_list
 26703           && !terminal_list->next_terminal)
 26704         {
 26705           fprintf (stderr, "%s\n", error_msg);
 26706 
 26707           if (!ioerror && dpyinfo)
 26708             {
 26709               /* Dump the list of error handlers for debugging
 26710                  purposes if the list exists.  */
 26711 
 26712               if ((dpyinfo->failable_requests
 26713                    != dpyinfo->next_failable_request) || x_error_message)
 26714                 fprintf (stderr, "X error handlers currently installed:\n");
 26715 
 26716               for (failable = dpyinfo->failable_requests;
 26717                    failable < dpyinfo->next_failable_request;
 26718                    ++failable)
 26719                 {
 26720                   if (failable->end)
 26721                     fprintf (stderr, "Ignoring errors between %lu to %lu\n",
 26722                              failable->start, failable->end);
 26723                   else
 26724                     fprintf (stderr, "Ignoring errors from %lu onwards\n",
 26725                              failable->start);
 26726                 }
 26727 
 26728               for (stack = x_error_message; stack; stack = stack->prev)
 26729                 fprintf (stderr, "Trapping errors from %lu\n",
 26730                          stack->first_request);
 26731             }
 26732         }
 26733 
 26734       XSETTERMINAL (tmp, dpyinfo->terminal);
 26735       Fdelete_terminal (tmp, Qnoelisp);
 26736     }
 26737 
 26738   /* The initial "daemon" frame is sometimes not selected by
 26739      `delete_frame' when Emacs is a background daemon.  */
 26740   if (NILP (selected_frame))
 26741     x_try_restore_frame ();
 26742 
 26743   unblock_input ();
 26744 
 26745   /* Sometimes another terminal is still alive, but deleting this
 26746      terminal caused all frames to vanish.  In that case, simply kill
 26747      Emacs, since the next redisplay will abort as there is no more
 26748      selected frame.  (bug#56528) */
 26749   if (terminal_list == 0 || NILP (selected_frame))
 26750     Fkill_emacs (make_fixnum (70), Qnil);
 26751 
 26752   totally_unblock_input ();
 26753 
 26754   unbind_to (idx, Qnil);
 26755   clear_waiting_for_input ();
 26756 
 26757   /* Here, we absolutely have to use a non-local exit (e.g. signal, throw,
 26758      longjmp), because returning from this function would get us back into
 26759      Xlib's code which will directly call `exit'.  */
 26760   current_display = NULL;
 26761   error ("%s", error_msg);
 26762 }
 26763 
 26764 static void x_error_quitter (Display *, XErrorEvent *);
 26765 
 26766 /* This is the first-level handler for X protocol errors.
 26767    It calls x_error_quitter or x_error_catcher.  */
 26768 
 26769 static int
 26770 x_error_handler (Display *display, XErrorEvent *event)
 26771 {
 26772   struct x_error_message_stack *stack;
 26773   struct x_display_info *dpyinfo;
 26774   struct x_failable_request *fail, *last;
 26775 
 26776 #if defined USE_GTK && defined HAVE_GTK3
 26777   if ((event->error_code == BadMatch
 26778        || event->error_code == BadWindow)
 26779       && event->request_code == X_SetInputFocus)
 26780     return 0;
 26781 #endif
 26782 
 26783   dpyinfo = x_display_info_for_display (display);
 26784 
 26785   if (dpyinfo)
 26786     {
 26787       fail = x_request_can_fail (dpyinfo, event->serial);
 26788 
 26789       if (fail)
 26790         {
 26791           /* Now that this request sequence has been fully handled,
 26792              remove it from the list of requests that can fail.  */
 26793 
 26794           if (event->serial == fail->end)
 26795             {
 26796               last = dpyinfo->next_failable_request;
 26797               memmove (&dpyinfo->failable_requests, fail,
 26798                        sizeof *fail * (last - fail));
 26799               dpyinfo->next_failable_request = (dpyinfo->failable_requests
 26800                                                 + (last - fail));
 26801             }
 26802 
 26803           /* If a selection transfer is the cause of this error,
 26804              remove the selection transfer now.  */
 26805 
 26806           if (fail->selection_serial)
 26807             {
 26808               x_handle_selection_error (fail->selection_serial,
 26809                                         event);
 26810 
 26811               /* Clear selection_serial to prevent
 26812                  x_handle_selection_error from being called again if
 26813                  any more requests within the protected section cause
 26814                  errors to be reported.  */
 26815               fail->selection_serial = 0;
 26816             }
 26817 
 26818           return 0;
 26819         }
 26820     }
 26821 
 26822   /* If we try to ungrab or grab a device that doesn't exist anymore
 26823      (that happens a lot in xmenu.c), just ignore the error.  */
 26824 
 26825 #ifdef HAVE_XINPUT2
 26826   /* Handle errors from some specific XI2 requests here to avoid a
 26827      sync in handle_one_xevent.  */
 26828   if (dpyinfo && dpyinfo->supports_xi2
 26829       && event->request_code == dpyinfo->xi2_opcode
 26830       && (event->minor_code == X_XIGrabDevice
 26831           || event->minor_code == X_XIUngrabDevice
 26832           || event->minor_code == X_XIAllowEvents))
 26833     return 0;
 26834 #endif
 26835 
 26836   stack = x_find_error_handler (display, event);
 26837 
 26838   if (stack)
 26839     x_error_catcher (display, event, stack);
 26840   else
 26841     x_error_quitter (display, event);
 26842   return 0;
 26843 }
 26844 
 26845 /* This is the usual handler for X protocol errors.
 26846    It kills all frames on the display that we got the error for.
 26847    If that was the only one, it prints an error message and kills Emacs.  */
 26848 
 26849 /* .gdbinit puts a breakpoint here, so make sure it is not inlined.  */
 26850 
 26851 static void NO_INLINE
 26852 x_error_quitter (Display *display, XErrorEvent *event)
 26853 {
 26854   char buf[256], buf1[800 + INT_STRLEN_BOUND (int)
 26855                       + INT_STRLEN_BOUND (unsigned long)
 26856                       + INT_STRLEN_BOUND (XID)
 26857                       + INT_STRLEN_BOUND (int)];
 26858 
 26859   /* Ignore BadName errors.  They can happen because of fonts
 26860      or colors that are not defined.  */
 26861 
 26862   if (event->error_code == BadName)
 26863     return;
 26864 
 26865   /* Note that there is no real way portable across R3/R4 to get the
 26866      original error handler.  */
 26867 
 26868   XGetErrorText (display, event->error_code, buf, sizeof (buf));
 26869   sprintf (buf1, "X protocol error: %s on protocol request %d\n"
 26870            "Serial no: %lu\n"
 26871            "Failing resource ID (if any): 0x%lx\n"
 26872            "Minor code: %d\n"
 26873            "This is a bug!  Please report this to bug-gnu-emacs@gnu.org!\n",
 26874            buf, event->request_code, event->serial, event->resourceid,
 26875            event->minor_code);
 26876   x_connection_closed (display, buf1, false);
 26877 }
 26878 
 26879 
 26880 /* This is the handler for X IO errors, always.
 26881    It kills all frames on the display that we lost touch with.
 26882    If that was the only one, it prints an error message and kills Emacs.  */
 26883 
 26884 static int NO_INLINE
 26885 x_io_error_quitter (Display *display)
 26886 {
 26887   char buf[256];
 26888 
 26889   snprintf (buf, sizeof buf, "Connection lost to X server '%s'",
 26890             DisplayString (display));
 26891   x_connection_closed (display, buf, true);
 26892 
 26893   return 0;
 26894 }
 26895 
 26896 
 26897 /* Changing the font of the frame.  */
 26898 
 26899 /* Give frame F the font FONT-OBJECT as its default font.  The return
 26900    value is FONT-OBJECT.  FONTSET is an ID of the fontset for the
 26901    frame.  If it is negative, generate a new fontset from
 26902    FONT-OBJECT.  */
 26903 
 26904 static Lisp_Object
 26905 x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
 26906 {
 26907   struct font *font = XFONT_OBJECT (font_object);
 26908   int unit, font_ascent, font_descent;
 26909 
 26910   if (fontset < 0)
 26911     fontset = fontset_from_font (font_object);
 26912   FRAME_FONTSET (f) = fontset;
 26913   if (FRAME_FONT (f) == font)
 26914     /* This font is already set in frame F.  There's nothing more to
 26915        do.  */
 26916     return font_object;
 26917 
 26918   FRAME_FONT (f) = font;
 26919   FRAME_BASELINE_OFFSET (f) = font->baseline_offset;
 26920   FRAME_COLUMN_WIDTH (f) = font->average_width;
 26921   get_font_ascent_descent (font, &font_ascent, &font_descent);
 26922   FRAME_LINE_HEIGHT (f) = font_ascent + font_descent;
 26923 
 26924 #ifndef USE_X_TOOLKIT
 26925   FRAME_MENU_BAR_HEIGHT (f) = FRAME_MENU_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
 26926 #endif
 26927   /* We could use a more elaborate calculation here.  */
 26928   FRAME_TAB_BAR_HEIGHT (f) = FRAME_TAB_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
 26929 
 26930   /* Compute character columns occupied by scrollbar.
 26931 
 26932      Don't do things differently for non-toolkit scrollbars
 26933      (Bug#17163).  */
 26934   unit = FRAME_COLUMN_WIDTH (f);
 26935   if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
 26936     FRAME_CONFIG_SCROLL_BAR_COLS (f)
 26937       = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + unit - 1) / unit;
 26938   else
 26939     FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + unit - 1) / unit;
 26940 
 26941 
 26942   /* Don't change the size of a tip frame; there's no point in doing it
 26943      because it's done in Fx_show_tip, and it leads to problems because
 26944      the tip frame has no widget.  */
 26945   if (FRAME_X_WINDOW (f) != 0 && !FRAME_TOOLTIP_P (f))
 26946     adjust_frame_size
 26947       (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
 26948        FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3, false, Qfont);
 26949 
 26950 #ifdef HAVE_X_I18N
 26951   if (FRAME_XIC (f)
 26952       && (FRAME_XIC_STYLE (f) & (XIMPreeditPosition | XIMStatusArea)))
 26953     {
 26954       block_input ();
 26955       xic_set_xfontset (f, SSDATA (fontset_ascii (fontset)));
 26956       unblock_input ();
 26957     }
 26958 #endif
 26959 
 26960   return font_object;
 26961 }
 26962 
 26963 
 26964 /***********************************************************************
 26965                            X Input Methods
 26966  ***********************************************************************/
 26967 
 26968 #ifdef HAVE_X_I18N
 26969 
 26970 #ifdef HAVE_X11R6
 26971 
 26972 /* HAVE_X11R6 means Xlib conforms to the R6 specification or later.
 26973    HAVE_X11R6_XIM, OTOH, means that Emacs should try to use R6-style
 26974    callback driven input method initialization.  They are separate
 26975    because Sun apparently ships buggy Xlib with some versions of
 26976    Solaris... */
 26977 
 26978 #ifdef HAVE_X11R6_XIM
 26979 
 26980 /* If preedit text is set on F, cancel preedit, free the text, and
 26981    generate the appropriate events to cancel the preedit display.
 26982 
 26983    This is mainly useful when the connection to the IM server is
 26984    dropped during preconversion.  */
 26985 
 26986 static void
 26987 x_maybe_clear_preedit (struct frame *f)
 26988 {
 26989   struct x_output *output;
 26990   struct input_event ie;
 26991 
 26992   output = FRAME_X_OUTPUT (f);
 26993 
 26994   if (!output->preedit_chars)
 26995     return;
 26996 
 26997   EVENT_INIT (ie);
 26998   ie.kind = PREEDIT_TEXT_EVENT;
 26999   ie.arg = Qnil;
 27000   XSETFRAME (ie.frame_or_window, f);
 27001   XSETINT (ie.x, 0);
 27002   XSETINT (ie.y, 0);
 27003   kbd_buffer_store_event (&ie);
 27004 
 27005   xfree (output->preedit_chars);
 27006 
 27007   output->preedit_size = 0;
 27008   output->preedit_active = false;
 27009   output->preedit_chars = NULL;
 27010   output->preedit_caret = 0;
 27011 }
 27012 
 27013 /* XIM destroy callback function, which is called whenever the
 27014    connection to input method XIM dies.  CLIENT_DATA contains a
 27015    pointer to the x_display_info structure corresponding to XIM.  */
 27016 
 27017 static void
 27018 xim_destroy_callback (XIM xim, XPointer client_data, XPointer call_data)
 27019 {
 27020   struct x_display_info *dpyinfo = (struct x_display_info *) client_data;
 27021   Lisp_Object frame, tail;
 27022 
 27023   block_input ();
 27024 
 27025   /* No need to call XDestroyIC.. */
 27026   FOR_EACH_FRAME (tail, frame)
 27027     {
 27028       struct frame *f = XFRAME (frame);
 27029       if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo)
 27030         {
 27031           FRAME_XIC (f) = NULL;
 27032           xic_free_xfontset (f);
 27033 
 27034           /* Free the preedit text if necessary.  */
 27035           x_maybe_clear_preedit (f);
 27036         }
 27037     }
 27038 
 27039   /* No need to call XCloseIM.  */
 27040   dpyinfo->xim = NULL;
 27041 
 27042   /* Also free IM values; those are allocated separately upon
 27043      XGetIMValues.  */
 27044   if (dpyinfo->xim_styles)
 27045     XFree (dpyinfo->xim_styles);
 27046   dpyinfo->xim_styles = NULL;
 27047   unblock_input ();
 27048 }
 27049 
 27050 #endif
 27051 
 27052 #endif /* HAVE_X11R6 */
 27053 
 27054 /* Open the connection to the XIM server on display DPYINFO.
 27055    RESOURCE_NAME is the resource name Emacs uses.  */
 27056 
 27057 static void
 27058 xim_open_dpy (struct x_display_info *dpyinfo, char *resource_name)
 27059 {
 27060 #ifdef HAVE_XIM
 27061   XIM xim;
 27062   const char *locale;
 27063 
 27064   if (dpyinfo->use_xim)
 27065     {
 27066       if (dpyinfo->xim)
 27067         {
 27068           XCloseIM (dpyinfo->xim);
 27069 
 27070           /* Free values left over from the last time the IM
 27071              connection was established.  */
 27072 
 27073           if (dpyinfo->xim_styles)
 27074             XFree (dpyinfo->xim_styles);
 27075           dpyinfo->xim_styles = NULL;
 27076         }
 27077 
 27078       xim = XOpenIM (dpyinfo->display, dpyinfo->rdb, resource_name,
 27079                      emacs_class);
 27080       dpyinfo->xim = xim;
 27081 
 27082       if (xim)
 27083         {
 27084 #ifdef HAVE_X11R6_XIM
 27085           XIMCallback destroy;
 27086 #endif
 27087 
 27088           /* Get supported styles and XIM values.  */
 27089           XGetIMValues (xim, XNQueryInputStyle, &dpyinfo->xim_styles, NULL);
 27090 
 27091 #ifdef HAVE_X11R6_XIM
 27092           destroy.callback = xim_destroy_callback;
 27093           destroy.client_data = (XPointer)dpyinfo;
 27094           XSetIMValues (xim, XNDestroyCallback, &destroy, NULL);
 27095 #endif
 27096 
 27097           locale = XLocaleOfIM (xim);
 27098 
 27099           /* Now try to determine the coding system that should be
 27100              used.  locale is in Host Portable Character Encoding, and
 27101              as such can be passed to build_string as is.  */
 27102           dpyinfo->xim_coding = safe_call1 (Vx_input_coding_function,
 27103                                             build_string (locale));
 27104         }
 27105     }
 27106   else
 27107 #endif /* HAVE_XIM */
 27108     dpyinfo->xim = NULL;
 27109 }
 27110 
 27111 
 27112 #ifdef HAVE_X11R6_XIM
 27113 
 27114 /* XIM instantiate callback function, which is called whenever an XIM
 27115    server is available.  DISPLAY is the display of the XIM.
 27116    CLIENT_DATA contains a pointer to an xim_inst_t structure created
 27117    when the callback was registered.  */
 27118 
 27119 static void
 27120 xim_instantiate_callback (Display *display, XPointer client_data, XPointer call_data)
 27121 {
 27122   struct xim_inst_t *xim_inst = (struct xim_inst_t *) client_data;
 27123   struct x_display_info *dpyinfo = xim_inst->dpyinfo;
 27124 
 27125   if (x_dnd_in_progress)
 27126     return;
 27127 
 27128   /* We don't support multiple XIM connections. */
 27129   if (dpyinfo->xim)
 27130     return;
 27131 
 27132   xim_open_dpy (dpyinfo, xim_inst->resource_name);
 27133 
 27134   /* Create XIC for the existing frames on the same display, as long
 27135      as they have no XIC.  */
 27136   if (dpyinfo->xim && dpyinfo->reference_count > 0)
 27137     {
 27138       Lisp_Object tail, frame;
 27139 
 27140       block_input ();
 27141       FOR_EACH_FRAME (tail, frame)
 27142         {
 27143           struct frame *f = XFRAME (frame);
 27144 
 27145           if (FRAME_X_P (f)
 27146               && FRAME_DISPLAY_INFO (f) == xim_inst->dpyinfo)
 27147             if (FRAME_XIC (f) == NULL)
 27148               {
 27149                 create_frame_xic (f);
 27150                 if (FRAME_XIC_STYLE (f) & XIMStatusArea)
 27151                   xic_set_statusarea (f);
 27152                 struct window *w = XWINDOW (f->selected_window);
 27153                 xic_set_preeditarea (w, w->cursor.x, w->cursor.y);
 27154               }
 27155         }
 27156 
 27157       unblock_input ();
 27158     }
 27159 }
 27160 
 27161 #endif /* HAVE_X11R6_XIM */
 27162 
 27163 
 27164 /* Open a connection to the XIM server on display DPYINFO.
 27165    RESOURCE_NAME is the resource name for Emacs.  On X11R5, open the
 27166    connection only at the first time.  On X11R6, open the connection
 27167    in the XIM instantiate callback function.  */
 27168 
 27169 static void
 27170 xim_initialize (struct x_display_info *dpyinfo, char *resource_name)
 27171 {
 27172   dpyinfo->xim = NULL;
 27173 #ifdef HAVE_XIM
 27174   if (dpyinfo->use_xim)
 27175     {
 27176 #ifdef HAVE_X11R6_XIM
 27177       struct xim_inst_t *xim_inst = xmalloc (sizeof *xim_inst);
 27178       Bool ret;
 27179 
 27180       dpyinfo->xim_callback_data = xim_inst;
 27181       xim_inst->dpyinfo = dpyinfo;
 27182       xim_inst->resource_name = xstrdup (resource_name);
 27183 
 27184       /* The last argument is XPointer in XFree86 but (XPointer *) on
 27185          Tru64, at least, but the configure test doesn't work because
 27186          xim_instantiate_callback can either be XIMProc or XIDProc, so
 27187          just cast to void *.  */
 27188 
 27189       ret = XRegisterIMInstantiateCallback (dpyinfo->display,
 27190                                             dpyinfo->rdb,
 27191                                             xim_inst->resource_name,
 27192                                             emacs_class,
 27193                                             xim_instantiate_callback,
 27194                                             (void *) xim_inst);
 27195       eassert (ret);
 27196 #else /* not HAVE_X11R6_XIM */
 27197       xim_open_dpy (dpyinfo, resource_name);
 27198 #endif /* not HAVE_X11R6_XIM */
 27199     }
 27200 #endif /* HAVE_XIM */
 27201 }
 27202 
 27203 
 27204 /* Close the connection to the XIM server on display DPYINFO.
 27205    Unregister any IM instantiation callback previously installed,
 27206    close the connection to the IM server if possible, and free any
 27207    retrieved IM values.  */
 27208 
 27209 static void
 27210 xim_close_dpy (struct x_display_info *dpyinfo)
 27211 {
 27212 #ifdef HAVE_XIM
 27213 #ifdef HAVE_X11R6_XIM
 27214   struct xim_inst_t *xim_inst;
 27215   Bool rc;
 27216 
 27217   /* If dpyinfo->xim_callback_data is not set, then IM support wasn't
 27218      initialized, which can happen if Xlib doesn't understand the C
 27219      locale being used.  */
 27220 
 27221   if (dpyinfo->xim_callback_data)
 27222     {
 27223       xim_inst = dpyinfo->xim_callback_data;
 27224 
 27225       if (dpyinfo->display)
 27226         {
 27227           rc = XUnregisterIMInstantiateCallback (dpyinfo->display,
 27228                                                  dpyinfo->rdb,
 27229                                                  xim_inst->resource_name,
 27230                                                  emacs_class,
 27231                                                  xim_instantiate_callback,
 27232                                                  (void *) xim_inst);
 27233           eassert (rc);
 27234         }
 27235 
 27236       xfree (xim_inst->resource_name);
 27237       xfree (xim_inst);
 27238     }
 27239 #endif /* HAVE_X11R6_XIM */
 27240 
 27241   /* Now close the connection to the input method server.  This may
 27242      access the display connection, and isn't safe if the display has
 27243      already been closed.  */
 27244 
 27245   if (dpyinfo->display && dpyinfo->xim)
 27246     XCloseIM (dpyinfo->xim);
 27247   dpyinfo->xim = NULL;
 27248 
 27249   /* Free the list of XIM styles retrieved.  */
 27250 
 27251   if (dpyinfo->xim_styles)
 27252     XFree (dpyinfo->xim_styles);
 27253   dpyinfo->xim_styles = NULL;
 27254 #endif /* HAVE_XIM */
 27255 }
 27256 
 27257 #endif /* not HAVE_X11R6_XIM */
 27258 
 27259 
 27260 
 27261 /* Calculate the absolute position in frame F
 27262    from its current recorded position values and gravity.  */
 27263 
 27264 static void
 27265 x_calc_absolute_position (struct frame *f)
 27266 {
 27267   int flags = f->size_hint_flags;
 27268   struct frame *p = FRAME_PARENT_FRAME (f);
 27269 
 27270   /* We have nothing to do if the current position
 27271      is already for the top-left corner.  */
 27272   if (! ((flags & XNegative) || (flags & YNegative)))
 27273     return;
 27274 
 27275   /* Treat negative positions as relative to the leftmost bottommost
 27276      position that fits on the screen.  */
 27277   if ((flags & XNegative) && (f->left_pos <= 0))
 27278     {
 27279       int width = FRAME_PIXEL_WIDTH (f);
 27280 
 27281       /* A frame that has been visible at least once should have outer
 27282          edges.  */
 27283       if (f->output_data.x->has_been_visible && !p)
 27284         {
 27285           Lisp_Object frame;
 27286           Lisp_Object edges = Qnil;
 27287 
 27288           XSETFRAME (frame, f);
 27289           edges = Fx_frame_edges (frame, Qouter_edges);
 27290           if (!NILP (edges))
 27291             width = (XFIXNUM (Fnth (make_fixnum (2), edges))
 27292                      - XFIXNUM (Fnth (make_fixnum (0), edges)));
 27293         }
 27294 
 27295       if (p)
 27296         f->left_pos = (FRAME_PIXEL_WIDTH (p) - width - 2 * f->border_width
 27297                        + f->left_pos);
 27298       else
 27299         f->left_pos = (x_display_pixel_width (FRAME_DISPLAY_INFO (f))
 27300                        - width + f->left_pos);
 27301 
 27302     }
 27303 
 27304   if ((flags & YNegative) && (f->top_pos <= 0))
 27305     {
 27306       int height = FRAME_PIXEL_HEIGHT (f);
 27307 
 27308 #if defined USE_X_TOOLKIT && defined USE_MOTIF
 27309       /* Something is fishy here.  When using Motif, starting Emacs with
 27310          `-g -0-0', the frame appears too low by a few pixels.
 27311 
 27312          This seems to be so because initially, while Emacs is starting,
 27313          the column widget's height and the frame's pixel height are
 27314          different.  The column widget's height is the right one.  In
 27315          later invocations, when Emacs is up, the frame's pixel height
 27316          is right, though.
 27317 
 27318          It's not obvious where the initial small difference comes from.
 27319          2000-12-01, gerd.  */
 27320 
 27321       XtVaGetValues (f->output_data.x->column_widget, XtNheight, &height, NULL);
 27322 #endif
 27323 
 27324       if (f->output_data.x->has_been_visible && !p)
 27325         {
 27326           Lisp_Object frame;
 27327           Lisp_Object edges = Qnil;
 27328 
 27329           XSETFRAME (frame, f);
 27330           if (NILP (edges))
 27331             edges = Fx_frame_edges (frame, Qouter_edges);
 27332           if (!NILP (edges))
 27333             height = (XFIXNUM (Fnth (make_fixnum (3), edges))
 27334                       - XFIXNUM (Fnth (make_fixnum (1), edges)));
 27335         }
 27336 
 27337       if (p)
 27338         f->top_pos = (FRAME_PIXEL_HEIGHT (p) - height - 2 * f->border_width
 27339                        + f->top_pos);
 27340       else
 27341         f->top_pos = (x_display_pixel_height (FRAME_DISPLAY_INFO (f))
 27342                       - height + f->top_pos);
 27343   }
 27344 
 27345   /* The left_pos and top_pos
 27346      are now relative to the top and left screen edges,
 27347      so the flags should correspond.  */
 27348   f->size_hint_flags &= ~ (XNegative | YNegative);
 27349 }
 27350 
 27351 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
 27352    to really change the position, and 0 when calling from
 27353    x_make_frame_visible (in that case, XOFF and YOFF are the current
 27354    position values).  It is -1 when calling from gui_set_frame_parameters,
 27355    which means, do adjust for borders but don't change the gravity.  */
 27356 
 27357 static void
 27358 x_set_offset (struct frame *f, int xoff, int yoff, int change_gravity)
 27359 {
 27360   int modified_top, modified_left;
 27361 #ifdef USE_GTK
 27362   int scale = xg_get_scale (f);
 27363 #endif
 27364 
 27365   if (change_gravity > 0)
 27366     {
 27367       f->top_pos = yoff;
 27368       f->left_pos = xoff;
 27369       f->size_hint_flags &= ~ (XNegative | YNegative);
 27370       if (xoff < 0)
 27371         f->size_hint_flags |= XNegative;
 27372       if (yoff < 0)
 27373         f->size_hint_flags |= YNegative;
 27374       f->win_gravity = NorthWestGravity;
 27375     }
 27376 
 27377   x_calc_absolute_position (f);
 27378 
 27379   block_input ();
 27380   x_wm_set_size_hint (f, 0, false);
 27381 
 27382 #ifdef USE_GTK
 27383   if (x_gtk_use_window_move)
 27384     {
 27385       /* When a position change was requested and the outer GTK widget
 27386          has been realized already, leave it to gtk_window_move to
 27387          DTRT and return.  Used for Bug#25851 and Bug#25943.  Convert
 27388          from X pixels to GTK scaled pixels.  */
 27389       if (change_gravity != 0 && FRAME_GTK_OUTER_WIDGET (f))
 27390         gtk_window_move (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
 27391                          f->left_pos / scale, f->top_pos / scale);
 27392       unblock_input ();
 27393       return;
 27394     }
 27395 #endif /* USE_GTK */
 27396 
 27397   modified_left = f->left_pos;
 27398   modified_top = f->top_pos;
 27399 
 27400   if (change_gravity != 0 && FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A)
 27401     {
 27402       /* Some WMs (twm, wmaker at least) has an offset that is smaller
 27403          than the WM decorations.  So we use the calculated offset instead
 27404          of the WM decoration sizes here (x/y_pixels_outer_diff).  */
 27405       modified_left += FRAME_X_OUTPUT (f)->move_offset_left;
 27406       modified_top += FRAME_X_OUTPUT (f)->move_offset_top;
 27407     }
 27408 
 27409 #ifdef USE_GTK
 27410   /* Make sure we adjust for possible scaling.  */
 27411   gtk_window_move (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
 27412                    modified_left / scale, modified_top / scale);
 27413 #else
 27414   XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 27415                modified_left, modified_top);
 27416 #endif
 27417 
 27418   /* The following code is too slow over a latent network
 27419      connection.  */
 27420   if (NILP (Vx_lax_frame_positioning))
 27421     {
 27422       /* 'x_sync_with_move' is too costly for dragging child frames.  */
 27423       if (!FRAME_PARENT_FRAME (f)
 27424           /* If no window manager exists, just calling XSync will be
 27425              sufficient to ensure that the window geometry has been
 27426              updated.  */
 27427           && NILP (Vx_no_window_manager))
 27428         {
 27429           x_sync_with_move (f, f->left_pos, f->top_pos,
 27430                             FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN);
 27431 
 27432           /* change_gravity is non-zero when this function is called from Lisp to
 27433              programmatically move a frame.  In that case, we call
 27434              x_check_expected_move to discover if we have a "Type A" or "Type B"
 27435              window manager, and, for a "Type A" window manager, adjust the position
 27436              of the frame.
 27437 
 27438              We call x_check_expected_move if a programmatic move occurred, and
 27439              either the window manager type (A/B) is unknown or it is Type A but we
 27440              need to compute the top/left offset adjustment for this frame.  */
 27441 
 27442           if (change_gravity != 0
 27443               && (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN
 27444                   || (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A
 27445                       && (FRAME_X_OUTPUT (f)->move_offset_left == 0
 27446                           && FRAME_X_OUTPUT (f)->move_offset_top == 0))))
 27447             x_check_expected_move (f, modified_left, modified_top);
 27448         }
 27449       /* Instead, just wait for the last ConfigureWindow request to
 27450          complete.  No window manager is involved when moving child
 27451          frames.  */
 27452       else
 27453         XSync (FRAME_X_DISPLAY (f), False);
 27454     }
 27455 
 27456   unblock_input ();
 27457 }
 27458 
 27459 static Window
 27460 x_get_wm_check_window (struct x_display_info *dpyinfo)
 27461 {
 27462   Window result;
 27463   unsigned char *tmp_data = NULL;
 27464   int rc, actual_format;
 27465   unsigned long actual_size, bytes_remaining;
 27466   Atom actual_type;
 27467 
 27468   rc = XGetWindowProperty (dpyinfo->display, dpyinfo->root_window,
 27469                            dpyinfo->Xatom_net_supporting_wm_check,
 27470                            0, 1, False, XA_WINDOW, &actual_type,
 27471                            &actual_format, &actual_size,
 27472                            &bytes_remaining, &tmp_data);
 27473 
 27474   if (rc != Success || actual_type != XA_WINDOW
 27475       || actual_format != 32 || actual_size != 1)
 27476     {
 27477       if (tmp_data)
 27478         XFree (tmp_data);
 27479 
 27480       return None;
 27481     }
 27482 
 27483   result = *(Window *) tmp_data;
 27484   XFree (tmp_data);
 27485 
 27486   return result;
 27487 }
 27488 
 27489 /* Return true if _NET_SUPPORTING_WM_CHECK window exists and _NET_SUPPORTED
 27490    on the root window for frame F contains ATOMNAME.
 27491    This is how a WM check shall be done according to the Window Manager
 27492    Specification/Extended Window Manager Hints at
 27493    https://freedesktop.org/wiki/Specifications/wm-spec/.  */
 27494 
 27495 bool
 27496 x_wm_supports_1 (struct x_display_info *dpyinfo, Atom want_atom)
 27497 {
 27498   Atom actual_type;
 27499   unsigned long actual_size, bytes_remaining;
 27500   int i, rc, actual_format;
 27501   bool ret;
 27502   Window wmcheck_window;
 27503   Window target_window = dpyinfo->root_window;
 27504   int max_len = 65536;
 27505   Display *dpy = dpyinfo->display;
 27506   unsigned char *tmp_data = NULL;
 27507   Atom target_type = XA_WINDOW;
 27508 
 27509   /* The user says there's no window manager, so take him up on
 27510      it.  */
 27511   if (!NILP (Vx_no_window_manager))
 27512     return false;
 27513 
 27514   /* If the window system says Emacs is untrusted, there will be no
 27515      way to send any information to the window manager, making any
 27516      hints useless.  */
 27517   if (dpyinfo->untrusted)
 27518     return false;
 27519 
 27520   block_input ();
 27521 
 27522   x_catch_errors (dpy);
 27523 
 27524   wmcheck_window = dpyinfo->net_supported_window;
 27525 
 27526   if (wmcheck_window == None)
 27527     wmcheck_window = x_get_wm_check_window (dpyinfo);
 27528 
 27529   if (!x_special_window_exists_p (dpyinfo, wmcheck_window))
 27530     {
 27531       if (dpyinfo->net_supported_window != None)
 27532         {
 27533           dpyinfo->net_supported_window = None;
 27534           wmcheck_window = x_get_wm_check_window (dpyinfo);
 27535 
 27536           if (!x_special_window_exists_p (dpyinfo, wmcheck_window))
 27537             {
 27538               x_uncatch_errors ();
 27539               unblock_input ();
 27540               return false;
 27541             }
 27542         }
 27543       else
 27544         {
 27545           x_uncatch_errors ();
 27546           unblock_input ();
 27547           return false;
 27548         }
 27549     }
 27550 
 27551   if (dpyinfo->net_supported_window != wmcheck_window)
 27552     {
 27553       /* Window changed, reload atoms */
 27554       if (dpyinfo->net_supported_atoms != NULL)
 27555         XFree (dpyinfo->net_supported_atoms);
 27556       dpyinfo->net_supported_atoms = NULL;
 27557       dpyinfo->nr_net_supported_atoms = 0;
 27558       dpyinfo->net_supported_window = 0;
 27559 
 27560       target_type = XA_ATOM;
 27561       tmp_data = NULL;
 27562       rc = XGetWindowProperty (dpy, target_window,
 27563                                dpyinfo->Xatom_net_supported,
 27564                                0, max_len, False, target_type,
 27565                                &actual_type, &actual_format, &actual_size,
 27566                                &bytes_remaining, &tmp_data);
 27567 
 27568       if (rc != Success || actual_type != XA_ATOM || x_had_errors_p (dpy))
 27569         {
 27570           if (tmp_data)
 27571             XFree (tmp_data);
 27572           x_uncatch_errors ();
 27573           unblock_input ();
 27574           return false;
 27575         }
 27576 
 27577       dpyinfo->net_supported_atoms = (Atom *) tmp_data;
 27578       dpyinfo->nr_net_supported_atoms = actual_size;
 27579       dpyinfo->net_supported_window = wmcheck_window;
 27580     }
 27581 
 27582   ret = false;
 27583 
 27584   for (i = 0; !ret && i < dpyinfo->nr_net_supported_atoms; ++i)
 27585     ret = dpyinfo->net_supported_atoms[i] == want_atom;
 27586 
 27587   x_uncatch_errors ();
 27588   unblock_input ();
 27589 
 27590   return ret;
 27591 }
 27592 
 27593 bool
 27594 x_wm_supports (struct frame *f, Atom want_atom)
 27595 {
 27596   return x_wm_supports_1 (FRAME_DISPLAY_INFO (f),
 27597                           want_atom);
 27598 }
 27599 
 27600 static void
 27601 set_wm_state (Lisp_Object frame, bool add, Atom atom, Atom value)
 27602 {
 27603   struct x_display_info *dpyinfo;
 27604   XEvent msg;
 27605 
 27606   dpyinfo = FRAME_DISPLAY_INFO (XFRAME (frame));
 27607   msg.xclient.type = ClientMessage;
 27608   msg.xclient.window = FRAME_OUTER_WINDOW (XFRAME (frame));
 27609   msg.xclient.message_type = dpyinfo->Xatom_net_wm_state;
 27610   msg.xclient.format = 32;
 27611 
 27612   msg.xclient.data.l[0] = add ? 1 : 0;
 27613   msg.xclient.data.l[1] = atom;
 27614   msg.xclient.data.l[2] = value;
 27615   msg.xclient.data.l[3] = 1; /* Source indication.  */
 27616   msg.xclient.data.l[4] = 0;
 27617 
 27618   block_input ();
 27619   XSendEvent (dpyinfo->display, dpyinfo->root_window,
 27620               False, (SubstructureRedirectMask
 27621                       | SubstructureNotifyMask), &msg);
 27622   unblock_input ();
 27623 }
 27624 
 27625 void
 27626 x_set_sticky (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
 27627 {
 27628   Lisp_Object frame;
 27629   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 27630 
 27631   XSETFRAME (frame, f);
 27632 
 27633   set_wm_state (frame, !NILP (new_value),
 27634                 dpyinfo->Xatom_net_wm_state_sticky, None);
 27635 }
 27636 
 27637 void
 27638 x_set_shaded (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
 27639 {
 27640   Lisp_Object frame;
 27641   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 27642 
 27643   XSETFRAME (frame, f);
 27644 
 27645   set_wm_state (frame, !NILP (new_value),
 27646                 dpyinfo->Xatom_net_wm_state_shaded, None);
 27647 }
 27648 
 27649 /**
 27650  * x_set_skip_taskbar:
 27651  *
 27652  * Set frame F's `skip-taskbar' parameter.  If non-nil, this should
 27653  * remove F's icon from the taskbar associated with the display of F's
 27654  * window-system window and inhibit switching to F's window via
 27655  * <Alt>-<TAB>.  If nil, lift these restrictions.
 27656  *
 27657  * Some window managers may not honor this parameter.
 27658  */
 27659 void
 27660 x_set_skip_taskbar (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
 27661 {
 27662   if (!EQ (new_value, old_value))
 27663     {
 27664 #ifdef USE_GTK
 27665       xg_set_skip_taskbar (f, new_value);
 27666 #else
 27667       Lisp_Object frame;
 27668       struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 27669 
 27670       XSETFRAME (frame, f);
 27671       set_wm_state (frame, !NILP (new_value),
 27672                     dpyinfo->Xatom_net_wm_state_skip_taskbar, None);
 27673 #endif /* USE_GTK */
 27674       FRAME_SKIP_TASKBAR (f) = !NILP (new_value);
 27675     }
 27676 }
 27677 
 27678 /**
 27679  * x_set_z_group:
 27680  *
 27681  * Set frame F's `z-group' parameter.  If `above', F's window-system
 27682  * window is displayed above all windows that do not have the `above'
 27683  * property set.  If nil, F's window is shown below all windows that
 27684  * have the `above' property set and above all windows that have the
 27685  * `below' property set.  If `below', F's window is displayed below all
 27686  * windows that do not have the `below' property set.
 27687  *
 27688  * Some window managers may not honor this parameter.
 27689  *
 27690  * Internally, this function also handles a value 'above-suspended'.
 27691  * That value is used to temporarily remove F from the 'above' group
 27692  * to make sure that it does not obscure a menu currently popped up.
 27693  */
 27694 void
 27695 x_set_z_group (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
 27696 {
 27697   /* We don't care about old_value.  The window manager might have
 27698      reset the value without telling us.  */
 27699   Lisp_Object frame;
 27700   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 27701 
 27702   XSETFRAME (frame, f);
 27703 
 27704   if (NILP (new_value))
 27705     {
 27706       set_wm_state (frame, false,
 27707                     dpyinfo->Xatom_net_wm_state_above, None);
 27708       set_wm_state (frame, false,
 27709                     dpyinfo->Xatom_net_wm_state_below, None);
 27710       FRAME_Z_GROUP (f) = z_group_none;
 27711     }
 27712   else if (EQ (new_value, Qabove))
 27713     {
 27714       set_wm_state (frame, true,
 27715                     dpyinfo->Xatom_net_wm_state_above, None);
 27716       set_wm_state (frame, false,
 27717                     dpyinfo->Xatom_net_wm_state_below, None);
 27718       FRAME_Z_GROUP (f) = z_group_above;
 27719     }
 27720   else if (EQ (new_value, Qbelow))
 27721     {
 27722       set_wm_state (frame, false,
 27723                     dpyinfo->Xatom_net_wm_state_above, None);
 27724       set_wm_state (frame, true,
 27725                     dpyinfo->Xatom_net_wm_state_below, None);
 27726       FRAME_Z_GROUP (f) = z_group_below;
 27727     }
 27728   else if (EQ (new_value, Qabove_suspended))
 27729     {
 27730       set_wm_state (frame, false,
 27731                     dpyinfo->Xatom_net_wm_state_above, None);
 27732       FRAME_Z_GROUP (f) = z_group_above_suspended;
 27733     }
 27734   else
 27735     error ("Invalid z-group specification");
 27736 }
 27737 
 27738 
 27739 /* Return the current _NET_WM_STATE.
 27740    SIZE_STATE is set to one of the FULLSCREEN_* values.
 27741    Set *STICKY to the sticky state.
 27742 
 27743    Return true iff we are not hidden.  */
 27744 
 27745 static bool
 27746 x_get_current_wm_state (struct frame *f,
 27747                         Window window,
 27748                         int *size_state,
 27749                         bool *sticky,
 27750                         bool *shaded)
 27751 {
 27752   unsigned long actual_size;
 27753   int i;
 27754   bool is_hidden = false;
 27755   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 27756   long max_len = 65536;
 27757   Atom target_type = XA_ATOM;
 27758   /* If XCB is available, we can avoid three XSync calls.  */
 27759 #ifdef USE_XCB
 27760   xcb_get_property_cookie_t prop_cookie;
 27761   xcb_get_property_reply_t *prop;
 27762   typedef xcb_atom_t reply_data_object;
 27763 #else
 27764   Display *dpy = FRAME_X_DISPLAY (f);
 27765   unsigned long bytes_remaining;
 27766   int rc, actual_format;
 27767   Atom actual_type;
 27768   unsigned char *tmp_data = NULL;
 27769   typedef Atom reply_data_object;
 27770 #endif
 27771   reply_data_object *reply_data;
 27772 # if defined GCC_LINT || defined lint
 27773   reply_data_object reply_data_dummy;
 27774   reply_data = &reply_data_dummy;
 27775 # endif
 27776 
 27777   *sticky = false;
 27778   *size_state = FULLSCREEN_NONE;
 27779   *shaded = false;
 27780 
 27781   block_input ();
 27782 
 27783 #ifdef USE_XCB
 27784   prop_cookie = xcb_get_property (dpyinfo->xcb_connection, 0, window,
 27785                                   dpyinfo->Xatom_net_wm_state,
 27786                                   target_type, 0, max_len);
 27787   prop = xcb_get_property_reply (dpyinfo->xcb_connection, prop_cookie, NULL);
 27788   if (prop && prop->type == target_type)
 27789     {
 27790       int actual_bytes = xcb_get_property_value_length (prop);
 27791       eassume (0 <= actual_bytes);
 27792       actual_size = actual_bytes / sizeof *reply_data;
 27793       reply_data = xcb_get_property_value (prop);
 27794     }
 27795   else
 27796     {
 27797       actual_size = 0;
 27798       is_hidden = FRAME_ICONIFIED_P (f);
 27799     }
 27800 #else
 27801   x_catch_errors (dpy);
 27802   rc = XGetWindowProperty (dpy, window, dpyinfo->Xatom_net_wm_state,
 27803                            0, max_len, False, target_type,
 27804                            &actual_type, &actual_format, &actual_size,
 27805                            &bytes_remaining, &tmp_data);
 27806 
 27807   if (rc == Success && actual_type == target_type && ! x_had_errors_p (dpy))
 27808     reply_data = (Atom *) tmp_data;
 27809   else
 27810     {
 27811       actual_size = 0;
 27812       is_hidden = FRAME_ICONIFIED_P (f);
 27813     }
 27814 
 27815   x_uncatch_errors ();
 27816 #endif
 27817 
 27818   for (i = 0; i < actual_size; ++i)
 27819     {
 27820       Atom a = reply_data[i];
 27821       if (a == dpyinfo->Xatom_net_wm_state_hidden)
 27822         is_hidden = true;
 27823       else if (a == dpyinfo->Xatom_net_wm_state_maximized_horz)
 27824         {
 27825           if (*size_state == FULLSCREEN_HEIGHT)
 27826             *size_state = FULLSCREEN_MAXIMIZED;
 27827           else
 27828             *size_state = FULLSCREEN_WIDTH;
 27829         }
 27830       else if (a == dpyinfo->Xatom_net_wm_state_maximized_vert)
 27831         {
 27832           if (*size_state == FULLSCREEN_WIDTH)
 27833             *size_state = FULLSCREEN_MAXIMIZED;
 27834           else
 27835             *size_state = FULLSCREEN_HEIGHT;
 27836         }
 27837       else if (a == dpyinfo->Xatom_net_wm_state_fullscreen)
 27838         *size_state = FULLSCREEN_BOTH;
 27839       else if (a == dpyinfo->Xatom_net_wm_state_sticky)
 27840         *sticky = true;
 27841       else if (a == dpyinfo->Xatom_net_wm_state_shaded)
 27842         *shaded = true;
 27843     }
 27844 
 27845 #ifdef USE_XCB
 27846   free (prop);
 27847 #else
 27848   if (tmp_data) XFree (tmp_data);
 27849 #endif
 27850 
 27851   unblock_input ();
 27852   return ! is_hidden;
 27853 }
 27854 
 27855 /* Do fullscreen as specified in extended window manager hints */
 27856 
 27857 static bool
 27858 do_ewmh_fullscreen (struct frame *f)
 27859 {
 27860   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 27861   bool have_net_atom = x_wm_supports (f, dpyinfo->Xatom_net_wm_state);
 27862   int cur;
 27863   bool dummy;
 27864 
 27865   x_get_current_wm_state (f, FRAME_OUTER_WINDOW (f), &cur, &dummy, &dummy);
 27866 
 27867   /* Some window managers don't say they support _NET_WM_STATE, but they do say
 27868      they support _NET_WM_STATE_FULLSCREEN.  Try that also.  */
 27869   if (!have_net_atom)
 27870     have_net_atom = x_wm_supports (f, dpyinfo->Xatom_net_wm_state_fullscreen);
 27871 
 27872   if (have_net_atom && cur != f->want_fullscreen)
 27873     {
 27874       Lisp_Object frame;
 27875 
 27876       XSETFRAME (frame, f);
 27877 
 27878       /* Keep number of calls to set_wm_state as low as possible.
 27879          Some window managers, or possible Gtk+, hangs when too many
 27880          are sent at once.  */
 27881       switch (f->want_fullscreen)
 27882         {
 27883         case FULLSCREEN_BOTH:
 27884           if (cur != FULLSCREEN_BOTH)
 27885             set_wm_state (frame, true, dpyinfo->Xatom_net_wm_state_fullscreen,
 27886                           None);
 27887           break;
 27888         case FULLSCREEN_WIDTH:
 27889           if (x_frame_normalize_before_maximize && cur == FULLSCREEN_MAXIMIZED)
 27890             {
 27891               set_wm_state (frame, false,
 27892                             dpyinfo->Xatom_net_wm_state_maximized_horz,
 27893                             dpyinfo->Xatom_net_wm_state_maximized_vert);
 27894               set_wm_state (frame, true,
 27895                             dpyinfo->Xatom_net_wm_state_maximized_horz, None);
 27896             }
 27897           else
 27898             {
 27899               if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_HEIGHT
 27900                   || cur == FULLSCREEN_MAXIMIZED)
 27901                 set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen,
 27902                               dpyinfo->Xatom_net_wm_state_maximized_vert);
 27903               if (cur != FULLSCREEN_MAXIMIZED || x_frame_normalize_before_maximize)
 27904                 set_wm_state (frame, true,
 27905                               dpyinfo->Xatom_net_wm_state_maximized_horz, None);
 27906             }
 27907           break;
 27908         case FULLSCREEN_HEIGHT:
 27909           if (x_frame_normalize_before_maximize && cur == FULLSCREEN_MAXIMIZED)
 27910             {
 27911               set_wm_state (frame, false,
 27912                             dpyinfo->Xatom_net_wm_state_maximized_horz,
 27913                             dpyinfo->Xatom_net_wm_state_maximized_vert);
 27914               set_wm_state (frame, true,
 27915                             dpyinfo->Xatom_net_wm_state_maximized_vert, None);
 27916             }
 27917           else
 27918             {
 27919               if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_WIDTH
 27920                   || cur == FULLSCREEN_MAXIMIZED)
 27921                 set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen,
 27922                               dpyinfo->Xatom_net_wm_state_maximized_horz);
 27923               if (cur != FULLSCREEN_MAXIMIZED || x_frame_normalize_before_maximize)
 27924                 set_wm_state (frame, true,
 27925                               dpyinfo->Xatom_net_wm_state_maximized_vert, None);
 27926             }
 27927           break;
 27928         case FULLSCREEN_MAXIMIZED:
 27929           if (x_frame_normalize_before_maximize && cur == FULLSCREEN_BOTH)
 27930             {
 27931               set_wm_state (frame, false,
 27932                             dpyinfo->Xatom_net_wm_state_fullscreen, None);
 27933               set_wm_state (frame, true,
 27934                             dpyinfo->Xatom_net_wm_state_maximized_horz,
 27935                             dpyinfo->Xatom_net_wm_state_maximized_vert);
 27936             }
 27937           else if (x_frame_normalize_before_maximize && cur == FULLSCREEN_WIDTH)
 27938             {
 27939               set_wm_state (frame, false,
 27940                             dpyinfo->Xatom_net_wm_state_maximized_horz, None);
 27941               set_wm_state (frame, true,
 27942                             dpyinfo->Xatom_net_wm_state_maximized_horz,
 27943                             dpyinfo->Xatom_net_wm_state_maximized_vert);
 27944             }
 27945           else if (x_frame_normalize_before_maximize && cur == FULLSCREEN_HEIGHT)
 27946             {
 27947               set_wm_state (frame, false,
 27948                             dpyinfo->Xatom_net_wm_state_maximized_vert, None);
 27949               set_wm_state (frame, true,
 27950                             dpyinfo->Xatom_net_wm_state_maximized_horz,
 27951                             dpyinfo->Xatom_net_wm_state_maximized_vert);
 27952             }
 27953           else
 27954             {
 27955               if (cur == FULLSCREEN_BOTH)
 27956                 set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen,
 27957                               None);
 27958               else if (cur == FULLSCREEN_HEIGHT)
 27959                 set_wm_state (frame, true,
 27960                               dpyinfo->Xatom_net_wm_state_maximized_horz, None);
 27961               else if (cur == FULLSCREEN_WIDTH)
 27962                 set_wm_state (frame, true, None,
 27963                               dpyinfo->Xatom_net_wm_state_maximized_vert);
 27964               else
 27965                 set_wm_state (frame, true,
 27966                               dpyinfo->Xatom_net_wm_state_maximized_horz,
 27967                               dpyinfo->Xatom_net_wm_state_maximized_vert);
 27968             }
 27969           break;
 27970         case FULLSCREEN_NONE:
 27971           if (cur == FULLSCREEN_BOTH)
 27972             set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen,
 27973                           None);
 27974           else
 27975             set_wm_state (frame, false,
 27976                           dpyinfo->Xatom_net_wm_state_maximized_horz,
 27977                           dpyinfo->Xatom_net_wm_state_maximized_vert);
 27978         }
 27979 
 27980       f->want_fullscreen = FULLSCREEN_NONE;
 27981 
 27982     }
 27983 
 27984   return have_net_atom;
 27985 }
 27986 
 27987 static void
 27988 XTfullscreen_hook (struct frame *f)
 27989 {
 27990   if (!FRAME_VISIBLE_P (f))
 27991     return;
 27992 
 27993   block_input ();
 27994   x_check_fullscreen (f);
 27995   unblock_input ();
 27996 }
 27997 
 27998 
 27999 static bool
 28000 x_handle_net_wm_state (struct frame *f, const XPropertyEvent *event)
 28001 {
 28002   int value = FULLSCREEN_NONE;
 28003   Lisp_Object lval;
 28004   bool sticky = false, shaded = false;
 28005   bool not_hidden = x_get_current_wm_state (f, event->window,
 28006                                             &value, &sticky,
 28007                                             &shaded);
 28008 
 28009   lval = Qnil;
 28010   switch (value)
 28011     {
 28012     case FULLSCREEN_WIDTH:
 28013       lval = Qfullwidth;
 28014       break;
 28015     case FULLSCREEN_HEIGHT:
 28016       lval = Qfullheight;
 28017       break;
 28018     case FULLSCREEN_BOTH:
 28019       lval = Qfullboth;
 28020       break;
 28021     case FULLSCREEN_MAXIMIZED:
 28022       lval = Qmaximized;
 28023       break;
 28024     }
 28025 
 28026   store_frame_param (f, Qfullscreen, lval);
 28027   store_frame_param (f, Qsticky, sticky ? Qt : Qnil);
 28028   store_frame_param (f, Qshaded, shaded ? Qt : Qnil);
 28029 
 28030   return not_hidden;
 28031 }
 28032 
 28033 /* Check if we need to resize the frame due to a fullscreen request.
 28034    If so needed, resize the frame. */
 28035 static void
 28036 x_check_fullscreen (struct frame *f)
 28037 {
 28038   Lisp_Object lval = Qnil;
 28039 
 28040   if (do_ewmh_fullscreen (f))
 28041     return;
 28042 
 28043   if (f->output_data.x->parent_desc != FRAME_DISPLAY_INFO (f)->root_window)
 28044     return; /* Only fullscreen without WM or with EWM hints (above). */
 28045 
 28046   /* Setting fullscreen to nil doesn't do anything.  We could save the
 28047      last non-fullscreen size and restore it, but it seems like a
 28048      lot of work for this unusual case (no window manager running).  */
 28049 
 28050   if (f->want_fullscreen != FULLSCREEN_NONE)
 28051     {
 28052       int width = FRAME_PIXEL_WIDTH (f), height = FRAME_PIXEL_HEIGHT (f);
 28053       struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 28054 
 28055       switch (f->want_fullscreen)
 28056         {
 28057           /* No difference between these two when there is no WM */
 28058         case FULLSCREEN_MAXIMIZED:
 28059           lval = Qmaximized;
 28060           width = x_display_pixel_width (dpyinfo);
 28061           height = x_display_pixel_height (dpyinfo);
 28062           break;
 28063         case FULLSCREEN_BOTH:
 28064           lval = Qfullboth;
 28065           width = x_display_pixel_width (dpyinfo);
 28066           height = x_display_pixel_height (dpyinfo);
 28067           break;
 28068         case FULLSCREEN_WIDTH:
 28069           lval = Qfullwidth;
 28070           width = x_display_pixel_width (dpyinfo);
 28071           height = height + FRAME_MENUBAR_HEIGHT (f);
 28072           break;
 28073         case FULLSCREEN_HEIGHT:
 28074           lval = Qfullheight;
 28075           height = x_display_pixel_height (dpyinfo);
 28076           break;
 28077         default:
 28078           emacs_abort ();
 28079         }
 28080 
 28081       x_wm_set_size_hint (f, 0, false);
 28082 
 28083       XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 28084                      width, height);
 28085 
 28086       if (FRAME_VISIBLE_P (f))
 28087         x_wait_for_event (f, ConfigureNotify);
 28088       else
 28089         change_frame_size (f, width, height, false, true, false);
 28090     }
 28091 
 28092   /* `x_net_wm_state' might have reset the fullscreen frame parameter,
 28093      restore it. */
 28094   store_frame_param (f, Qfullscreen, lval);
 28095 }
 28096 
 28097 /* This function is called by x_set_offset to determine whether the window
 28098    manager interfered with the positioning of the frame.  Type A window
 28099    managers position the surrounding window manager decorations a small
 28100    amount above and left of the user-supplied position.  Type B window
 28101    managers position the surrounding window manager decorations at the
 28102    user-specified position.  If we detect a Type A window manager, we
 28103    compensate by moving the window right and down by the proper amount.  */
 28104 
 28105 static void
 28106 x_check_expected_move (struct frame *f, int expected_left, int expected_top)
 28107 {
 28108   int current_left = 0, current_top = 0;
 28109 
 28110   /* x_real_positions returns the left and top offsets of the outermost
 28111      window manager window around the frame.  */
 28112 
 28113   x_real_positions (f, &current_left, &current_top);
 28114 
 28115   if (current_left != expected_left || current_top != expected_top)
 28116     {
 28117       /* It's a "Type A" window manager. */
 28118 
 28119       int adjusted_left;
 28120       int adjusted_top;
 28121 
 28122       FRAME_DISPLAY_INFO (f)->wm_type = X_WMTYPE_A;
 28123       FRAME_X_OUTPUT (f)->move_offset_left = expected_left - current_left;
 28124       FRAME_X_OUTPUT (f)->move_offset_top = expected_top - current_top;
 28125 
 28126       /* Now fix the mispositioned frame's location. */
 28127 
 28128       adjusted_left = expected_left + FRAME_X_OUTPUT (f)->move_offset_left;
 28129       adjusted_top = expected_top + FRAME_X_OUTPUT (f)->move_offset_top;
 28130 
 28131       XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 28132                    adjusted_left, adjusted_top);
 28133 
 28134       x_sync_with_move (f, expected_left, expected_top, false);
 28135     }
 28136   else
 28137     /* It's a "Type B" window manager.  We don't have to adjust the
 28138        frame's position. */
 28139       FRAME_DISPLAY_INFO (f)->wm_type = X_WMTYPE_B;
 28140 }
 28141 
 28142 
 28143 /* Wait for XGetGeometry to return up-to-date position information for a
 28144    recently-moved frame.  Call this immediately after calling XMoveWindow.
 28145    If FUZZY is non-zero, then LEFT and TOP are just estimates of where the
 28146    frame has been moved to, so we use a fuzzy position comparison instead
 28147    of an exact comparison.  */
 28148 
 28149 static void
 28150 x_sync_with_move (struct frame *f, int left, int top, bool fuzzy)
 28151 {
 28152   sigset_t emptyset;
 28153   int count, current_left, current_top;
 28154   struct timespec fallback;
 28155 
 28156   sigemptyset (&emptyset);
 28157   count = 0;
 28158 
 28159   while (count++ < 50)
 28160     {
 28161       current_left = 0;
 28162       current_top = 0;
 28163 
 28164       /* There is no need to call XSync (even when no window manager
 28165          is present) because x_real_positions already does that
 28166          implicitly.  */
 28167       x_real_positions (f, &current_left, &current_top);
 28168 
 28169       if (fuzzy)
 28170         {
 28171           /* The left fuzz-factor is 10 pixels.  The top fuzz-factor is 40
 28172              pixels.  */
 28173 
 28174           if (eabs (current_left - left) <= 10
 28175               && eabs (current_top - top) <= 40)
 28176             return;
 28177         }
 28178       else if (current_left == left && current_top == top)
 28179         return;
 28180     }
 28181 
 28182   /* As a last resort, just wait 0.5 seconds and hope that XGetGeometry
 28183      will then return up-to-date position info. */
 28184 
 28185   fallback = dtotimespec (0.5);
 28186 
 28187   /* This will hang if input is blocked, so use pselect to wait
 28188      instead.  */
 28189   if (input_blocked_p ())
 28190     pselect (0, NULL, NULL, NULL, &fallback, &emptyset);
 28191   else
 28192     wait_reading_process_output (0, 500000000, 0, false, Qnil, NULL, 0);
 28193 }
 28194 
 28195 /* Wait for an event on frame F matching EVENTTYPE.  */
 28196 void
 28197 x_wait_for_event (struct frame *f, int eventtype)
 28198 {
 28199   if (!FLOATP (Vx_wait_for_event_timeout))
 28200     return;
 28201 
 28202   int level = interrupt_input_blocked;
 28203   fd_set fds;
 28204   struct timespec tmo, tmo_at, time_now;
 28205   int fd = ConnectionNumber (FRAME_X_DISPLAY (f));
 28206 
 28207   f->wait_event_type = eventtype;
 28208 
 28209   /* Default timeout is 0.1 second.  Hopefully not noticeable.  */
 28210   double timeout = XFLOAT_DATA (Vx_wait_for_event_timeout);
 28211   time_t timeout_seconds = (time_t) timeout;
 28212   tmo = make_timespec
 28213     (timeout_seconds, (long int) ((timeout - timeout_seconds)
 28214                                   * 1000 * 1000 * 1000));
 28215   tmo_at = timespec_add (current_timespec (), tmo);
 28216 
 28217   while (f->wait_event_type)
 28218     {
 28219       pending_signals = true;
 28220       totally_unblock_input ();
 28221       /* XTread_socket is called after unblock.  */
 28222       block_input ();
 28223       interrupt_input_blocked = level;
 28224 
 28225       FD_ZERO (&fds);
 28226       FD_SET (fd, &fds);
 28227 
 28228       time_now = current_timespec ();
 28229       if (timespec_cmp (tmo_at, time_now) < 0)
 28230         break;
 28231 
 28232       tmo = timespec_sub (tmo_at, time_now);
 28233       if (pselect (fd + 1, &fds, NULL, NULL, &tmo, NULL) == 0)
 28234         break; /* Timeout */
 28235     }
 28236 
 28237   f->wait_event_type = 0;
 28238 }
 28239 
 28240 
 28241 /* Change the size of frame F's X window to WIDTH/HEIGHT in the case F
 28242    doesn't have a widget.  If CHANGE_GRAVITY, change to
 28243    top-left-corner window gravity for this size change and subsequent
 28244    size changes.  Otherwise leave the window gravity unchanged.  */
 28245 
 28246 static void
 28247 x_set_window_size_1 (struct frame *f, bool change_gravity,
 28248                      int width, int height)
 28249 {
 28250   if (change_gravity)
 28251     f->win_gravity = NorthWestGravity;
 28252   x_wm_set_size_hint (f, 0, false);
 28253 
 28254   XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 28255                  width, height + FRAME_MENUBAR_HEIGHT (f));
 28256 
 28257   /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
 28258      receive in the ConfigureNotify event; if we get what we asked
 28259      for, then the event won't cause the screen to become garbaged, so
 28260      we have to make sure to do it here.  */
 28261   SET_FRAME_GARBAGED (f);
 28262 
 28263   /* The following code is too slow over a latent network
 28264      connection, so skip it when the user says so.  */
 28265 
 28266   if (!NILP (Vx_lax_frame_positioning))
 28267     return;
 28268 
 28269   /* Now, strictly speaking, we can't be sure that this is accurate,
 28270      but the window manager will get around to dealing with the size
 28271      change request eventually, and we'll hear how it went when the
 28272      ConfigureNotify event gets here.
 28273 
 28274      We could just not bother storing any of this information here,
 28275      and let the ConfigureNotify event set everything up, but that
 28276      might be kind of confusing to the Lisp code, since size changes
 28277      wouldn't be reported in the frame parameters until some random
 28278      point in the future when the ConfigureNotify event arrives.
 28279 
 28280      Pass true for DELAY since we can't run Lisp code inside of
 28281      a BLOCK_INPUT.  */
 28282 
 28283   /* But the ConfigureNotify may in fact never arrive, and then this is
 28284      not right if the frame is visible.  Instead wait (with timeout)
 28285      for the ConfigureNotify.  */
 28286   if (FRAME_VISIBLE_P (f))
 28287     {
 28288       x_wait_for_event (f, ConfigureNotify);
 28289 
 28290       if (CONSP (frame_size_history))
 28291         frame_size_history_extra
 28292           (f, build_string ("x_set_window_size_1, visible"),
 28293            FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f), width, height,
 28294            f->new_width, f->new_height);
 28295     }
 28296   else
 28297     {
 28298       if (CONSP (frame_size_history))
 28299         frame_size_history_extra
 28300           (f, build_string ("x_set_window_size_1, invisible"),
 28301            FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f), width, height,
 28302            f->new_width, f->new_height);
 28303 
 28304       /* Call adjust_frame_size right away as with GTK.  It might be
 28305          tempting to clear out f->new_width and f->new_height here.  */
 28306       adjust_frame_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, width),
 28307                          FRAME_PIXEL_TO_TEXT_HEIGHT (f, height),
 28308                          5, 0, Qx_set_window_size_1);
 28309     }
 28310 }
 28311 
 28312 
 28313 /* Change the size of frame F's X window to WIDTH and HEIGHT pixels.  If
 28314    CHANGE_GRAVITY, change to top-left-corner window gravity for this
 28315    size change and subsequent size changes.  Otherwise we leave the
 28316    window gravity unchanged.  */
 28317 
 28318 void
 28319 x_set_window_size (struct frame *f, bool change_gravity,
 28320                    int width, int height)
 28321 {
 28322   block_input ();
 28323 
 28324 #ifdef USE_GTK
 28325   if (FRAME_GTK_WIDGET (f))
 28326     xg_frame_set_char_size (f, width, height);
 28327   else
 28328     x_set_window_size_1 (f, change_gravity, width, height);
 28329 #else /* not USE_GTK */
 28330   x_set_window_size_1 (f, change_gravity, width, height);
 28331   x_clear_under_internal_border (f);
 28332 #endif /* not USE_GTK */
 28333 
 28334   /* If cursor was outside the new size, mark it as off.  */
 28335   mark_window_cursors_off (XWINDOW (f->root_window));
 28336 
 28337   /* Clear out any recollection of where the mouse highlighting was,
 28338      since it might be in a place that's outside the new frame size.
 28339      Actually checking whether it is outside is a pain in the neck,
 28340      so don't try--just let the highlighting be done afresh with new size.  */
 28341   cancel_mouse_face (f);
 28342 
 28343   unblock_input ();
 28344 
 28345   do_pending_window_change (false);
 28346 }
 28347 
 28348 /* Move the mouse to position pixel PIX_X, PIX_Y relative to frame F.  */
 28349 
 28350 void
 28351 frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y)
 28352 {
 28353 #ifdef HAVE_XINPUT2
 28354   int deviceid;
 28355 
 28356   deviceid = FRAME_DISPLAY_INFO (f)->client_pointer_device;
 28357 
 28358   if (FRAME_DISPLAY_INFO (f)->supports_xi2
 28359       && deviceid != -1)
 28360     {
 28361       block_input ();
 28362       x_ignore_errors_for_next_request (FRAME_DISPLAY_INFO (f), 0);
 28363       XIWarpPointer (FRAME_X_DISPLAY (f), deviceid, None,
 28364                      FRAME_X_WINDOW (f), 0, 0, 0, 0, pix_x, pix_y);
 28365       x_stop_ignoring_errors (FRAME_DISPLAY_INFO (f));
 28366       unblock_input ();
 28367     }
 28368   else
 28369 #endif
 28370     XWarpPointer (FRAME_X_DISPLAY (f), None, FRAME_X_WINDOW (f),
 28371                   0, 0, 0, 0, pix_x, pix_y);
 28372 }
 28373 
 28374 /* Raise frame F.  */
 28375 
 28376 static void
 28377 x_raise_frame (struct frame *f)
 28378 {
 28379   block_input ();
 28380 
 28381   if (FRAME_VISIBLE_P (f))
 28382     {
 28383       XRaiseWindow (FRAME_X_DISPLAY (f),
 28384                     FRAME_OUTER_WINDOW (f));
 28385       XFlush (FRAME_X_DISPLAY (f));
 28386     }
 28387 
 28388   unblock_input ();
 28389 }
 28390 
 28391 static void
 28392 x_lower_frame_1 (struct frame *f)
 28393 {
 28394   Window *windows;
 28395   Lisp_Object frame, tail;
 28396   struct frame *sibling;
 28397 
 28398   windows = alloca (2 * sizeof *windows);
 28399 
 28400   /* Lowering a child frame leads to the window being put below any
 28401      scroll bars on the parent.  To avoid that, restack the child
 28402      frame below all of its siblings instead of just lowering it.  */
 28403 
 28404   FOR_EACH_FRAME (tail, frame)
 28405     {
 28406       sibling = XFRAME (frame);
 28407 
 28408       if (sibling == f)
 28409         continue;
 28410 
 28411       if (FRAME_PARENT_FRAME (sibling)
 28412           != FRAME_PARENT_FRAME (f))
 28413         continue;
 28414 
 28415       windows[0] = FRAME_OUTER_WINDOW (sibling);
 28416       windows[1] = FRAME_OUTER_WINDOW (f);
 28417 
 28418       XRestackWindows (FRAME_X_DISPLAY (f), windows, 2);
 28419     }
 28420 }
 28421 
 28422 /* Lower frame F.  */
 28423 
 28424 static void
 28425 x_lower_frame (struct frame *f)
 28426 {
 28427   if (FRAME_PARENT_FRAME (f)
 28428       && (FRAME_HAS_VERTICAL_SCROLL_BARS (FRAME_PARENT_FRAME (f))
 28429           || FRAME_HAS_HORIZONTAL_SCROLL_BARS (FRAME_PARENT_FRAME (f))))
 28430     x_lower_frame_1 (f);
 28431   else
 28432     XLowerWindow (FRAME_X_DISPLAY (f),
 28433                   FRAME_OUTER_WINDOW (f));
 28434 
 28435 #ifdef HAVE_XWIDGETS
 28436   /* Make sure any X windows owned by xwidget views of the parent
 28437      still display below the lowered frame.  */
 28438 
 28439   if (FRAME_PARENT_FRAME (f))
 28440     lower_frame_xwidget_views (FRAME_PARENT_FRAME (f));
 28441 #endif
 28442 
 28443   XFlush (FRAME_X_DISPLAY (f));
 28444 }
 28445 
 28446 static void
 28447 XTframe_raise_lower (struct frame *f, bool raise_flag)
 28448 {
 28449   if (raise_flag)
 28450     x_raise_frame (f);
 28451   else
 28452     x_lower_frame (f);
 28453 }
 28454 
 28455 /* Request focus with XEmbed */
 28456 
 28457 static void
 28458 xembed_request_focus (struct frame *f)
 28459 {
 28460   /* See XEmbed Protocol Specification at
 28461      https://freedesktop.org/wiki/Specifications/xembed-spec/  */
 28462   if (FRAME_VISIBLE_P (f))
 28463     xembed_send_message (f, CurrentTime,
 28464                          XEMBED_REQUEST_FOCUS, 0, 0, 0);
 28465 }
 28466 
 28467 static Bool
 28468 server_timestamp_predicate (Display *display, XEvent *xevent,
 28469                             XPointer arg)
 28470 {
 28471   XID *args = (XID *) arg;
 28472 
 28473   if (xevent->type == PropertyNotify
 28474       && xevent->xproperty.window == args[0]
 28475       && xevent->xproperty.atom == args[1])
 28476     return True;
 28477 
 28478   return False;
 28479 }
 28480 
 28481 /* Get the server time.  The X server is guaranteed to deliver the
 28482    PropertyNotify event, so there is no reason to use x_if_event.  */
 28483 
 28484 static Time
 28485 x_get_server_time (struct frame *f)
 28486 {
 28487   Atom property_atom;
 28488   XEvent property_dummy;
 28489   struct x_display_info *dpyinfo;
 28490   XID client_data[2];
 28491 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
 28492   uint_fast64_t current_monotonic_time;
 28493 #endif
 28494 
 28495   /* If the server time is the same as the monotonic time, avoid a
 28496      roundtrip by using that instead.  */
 28497 
 28498 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
 28499   if (FRAME_DISPLAY_INFO (f)->server_time_monotonic_p)
 28500     {
 28501       current_monotonic_time = x_sync_current_monotonic_time ();
 28502 
 28503       if (current_monotonic_time)
 28504         /* Truncate the time to CARD32.  */
 28505         return (current_monotonic_time / 1000) & X_ULONG_MAX;
 28506     }
 28507 #endif
 28508 
 28509   dpyinfo = FRAME_DISPLAY_INFO (f);
 28510   property_atom = dpyinfo->Xatom_EMACS_SERVER_TIME_PROP;
 28511   client_data[0] = FRAME_OUTER_WINDOW (f);
 28512   client_data[1] = property_atom;
 28513 
 28514   XChangeProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
 28515                    property_atom, XA_ATOM, 32,
 28516                    PropModeReplace,
 28517                    (unsigned char *) &property_atom, 1);
 28518 
 28519   XIfEvent (dpyinfo->display, &property_dummy,
 28520             server_timestamp_predicate, (XPointer) client_data);
 28521 
 28522   return property_dummy.xproperty.time;
 28523 }
 28524 
 28525 /* Activate frame with Extended Window Manager Hints */
 28526 
 28527 static void
 28528 x_ewmh_activate_frame (struct frame *f)
 28529 {
 28530   XEvent msg;
 28531   struct x_display_info *dpyinfo;
 28532   Time time;
 28533 
 28534   dpyinfo = FRAME_DISPLAY_INFO (f);
 28535 
 28536   if (FRAME_VISIBLE_P (f))
 28537     {
 28538       /* See the documentation at
 28539          https://specifications.freedesktop.org/wm-spec/wm-spec-latest.html
 28540          for more details on the format of this message.  */
 28541       msg.xclient.type = ClientMessage;
 28542       msg.xclient.window = FRAME_OUTER_WINDOW (f);
 28543       msg.xclient.message_type = dpyinfo->Xatom_net_active_window;
 28544       msg.xclient.format = 32;
 28545       msg.xclient.data.l[0] = 1;
 28546       msg.xclient.data.l[1] = dpyinfo->last_user_time;
 28547       msg.xclient.data.l[2] = (!dpyinfo->x_focus_frame
 28548                                ? None
 28549                                : FRAME_OUTER_WINDOW (dpyinfo->x_focus_frame));
 28550       msg.xclient.data.l[3] = 0;
 28551       msg.xclient.data.l[4] = 0;
 28552 
 28553       /* No frame is currently focused on that display, so apply any
 28554          bypass for focus stealing prevention that the user has
 28555          specified.  */
 28556       if (!dpyinfo->x_focus_frame)
 28557         {
 28558           if (EQ (Vx_allow_focus_stealing, Qimitate_pager))
 28559             msg.xclient.data.l[0] = 2;
 28560           else if (EQ (Vx_allow_focus_stealing, Qnewer_time))
 28561             {
 28562               block_input ();
 28563               time = x_get_server_time (f);
 28564 #ifdef USE_GTK
 28565               x_set_gtk_user_time (f, time);
 28566 #endif
 28567               /* Temporarily override dpyinfo->x_focus_frame so the
 28568                  user time property is set on the right window.  */
 28569               dpyinfo->x_focus_frame = f;
 28570               x_display_set_last_user_time (dpyinfo, time, true, true);
 28571               dpyinfo->x_focus_frame = NULL;
 28572               unblock_input ();
 28573 
 28574               msg.xclient.data.l[1] = time;
 28575             }
 28576           else if (EQ (Vx_allow_focus_stealing, Qraise_and_focus))
 28577             {
 28578               time = x_get_server_time (f);
 28579 
 28580               x_set_input_focus (FRAME_DISPLAY_INFO (f),
 28581                                  FRAME_OUTER_WINDOW (f),
 28582                                  time);
 28583               XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f));
 28584 
 28585               return;
 28586             }
 28587         }
 28588 
 28589       XSendEvent (dpyinfo->display, dpyinfo->root_window,
 28590                   False, (SubstructureRedirectMask
 28591                           | SubstructureNotifyMask), &msg);
 28592     }
 28593 }
 28594 
 28595 static Lisp_Object
 28596 x_get_focus_frame (struct frame *f)
 28597 {
 28598   Lisp_Object lisp_focus;
 28599 
 28600   struct frame *focus =  FRAME_DISPLAY_INFO (f)->x_focus_frame;
 28601 
 28602   if (!focus)
 28603     return Qnil;
 28604 
 28605   XSETFRAME (lisp_focus, focus);
 28606   return lisp_focus;
 28607 }
 28608 
 28609 /* Return the toplevel parent of F, if it is a child frame.
 28610    Otherwise, return NULL.  */
 28611 
 28612 static struct frame *
 28613 x_get_toplevel_parent (struct frame *f)
 28614 {
 28615   struct frame *parent;
 28616 
 28617   if (!FRAME_PARENT_FRAME (f))
 28618     return NULL;
 28619 
 28620   parent = FRAME_PARENT_FRAME (f);
 28621 
 28622   while (FRAME_PARENT_FRAME (parent))
 28623     parent = FRAME_PARENT_FRAME (parent);
 28624 
 28625   return parent;
 28626 }
 28627 
 28628 static void
 28629 x_set_input_focus (struct x_display_info *dpyinfo, Window window,
 28630                    Time time)
 28631 {
 28632 #ifdef HAVE_XINPUT2
 28633   struct xi_device_t *device;
 28634 #endif
 28635 
 28636   /* Do the equivalent of XSetInputFocus with the specified window and
 28637      time, but use the attachment to the device that Emacs has
 28638      designated the client pointer on X Input Extension builds.
 28639      Asynchronously trap errors around the generated XI_SetFocus or
 28640      SetInputFocus request, in case the device has been destroyed or
 28641      the window obscured.
 28642 
 28643      The revert_to will be set to RevertToParent for generated
 28644      SetInputFocus requests.  */
 28645 
 28646 #ifdef HAVE_XINPUT2
 28647   if (dpyinfo->supports_xi2
 28648       && dpyinfo->client_pointer_device != -1)
 28649     {
 28650       device = xi_device_from_id (dpyinfo, dpyinfo->client_pointer_device);
 28651 
 28652       /* The device is a master pointer.  Use its attachment, which
 28653          should be the master keyboard.  */
 28654 
 28655       if (device)
 28656         {
 28657           eassert (device->use == XIMasterPointer);
 28658 
 28659           x_ignore_errors_for_next_request (dpyinfo, 0);
 28660           XISetFocus (dpyinfo->display, device->attachment,
 28661                       /* Note that the input extension
 28662                          only supports RevertToParent-type
 28663                          behavior.  */
 28664                       window, time);
 28665           x_stop_ignoring_errors (dpyinfo);
 28666 
 28667           return;
 28668         }
 28669     }
 28670 #endif
 28671 
 28672   /* Otherwise, use the pointer device that the X server says is the
 28673      client pointer.  */
 28674   x_ignore_errors_for_next_request (dpyinfo, 0);
 28675   XSetInputFocus (dpyinfo->display, window, RevertToParent, time);
 28676   x_stop_ignoring_errors (dpyinfo);
 28677 }
 28678 
 28679 /* In certain situations, when the window manager follows a
 28680    click-to-focus policy, there seems to be no way around calling
 28681    XSetInputFocus to give another frame the input focus.
 28682 
 28683    In an ideal world, XSetInputFocus should generally be avoided so
 28684    that applications don't interfere with the window manager's focus
 28685    policy.  But I think it's okay to use when it's clearly done
 28686    following a user-command.  */
 28687 
 28688 static void
 28689 x_focus_frame (struct frame *f, bool noactivate)
 28690 {
 28691   struct x_display_info *dpyinfo;
 28692   Time time;
 28693 
 28694   dpyinfo = FRAME_DISPLAY_INFO (f);
 28695 
 28696   if (dpyinfo->untrusted)
 28697     /* The X server ignores all input focus related requests from
 28698        untrusted clients.  */
 28699     return;
 28700 
 28701   /* The code below is not reentrant wrt to dpyinfo->x_focus_frame and
 28702      friends being set.  */
 28703   block_input ();
 28704 
 28705   if (FRAME_X_EMBEDDED_P (f))
 28706     /* For Xembedded frames, normally the embedder forwards key
 28707        events.  See XEmbed Protocol Specification at
 28708        https://freedesktop.org/wiki/Specifications/xembed-spec/  */
 28709     xembed_request_focus (f);
 28710   else
 28711     {
 28712       if (!noactivate
 28713           /* If F is override-redirect, use SetInputFocus instead.
 28714              Override-redirect frames are not subject to window
 28715              management.  */
 28716           && !FRAME_OVERRIDE_REDIRECT (f)
 28717           /* If F is a child frame, use SetInputFocus instead.  This
 28718              may not work if its parent is not activated.  */
 28719           && !FRAME_PARENT_FRAME (f)
 28720           /* If the focus is being transferred from a child frame to
 28721              its toplevel parent, also use SetInputFocus.  */
 28722           && (!dpyinfo->x_focus_frame
 28723               || (x_get_toplevel_parent (dpyinfo->x_focus_frame)
 28724                   != f))
 28725           && x_wm_supports (f, dpyinfo->Xatom_net_active_window))
 28726         {
 28727           /* When window manager activation is possible, use it
 28728              instead.  The window manager is expected to perform any
 28729              necessary actions such as raising the frame, moving it to
 28730              the current workspace, and mapping it, etc, before moving
 28731              input focus to the frame.  */
 28732           x_ewmh_activate_frame (f);
 28733           goto out;
 28734         }
 28735 
 28736       if (NILP (Vx_no_window_manager))
 28737         {
 28738           /* Use the last user time.  It is invalid to use CurrentTime
 28739              according to the ICCCM:
 28740 
 28741                Clients that use a SetInputFocus request must set the
 28742                time field to the timestamp of the event that caused
 28743                them to make the attempt. [...] Note that clients must
 28744                not use CurrentTime in the time field.  */
 28745           time = dpyinfo->last_user_time;
 28746 
 28747           /* Unless the focus doesn't belong to Emacs anymore and
 28748              `x-allow-focus-stealing' is set to Qnewer_time.  */
 28749           if (EQ (Vx_allow_focus_stealing, Qnewer_time)
 28750               && !dpyinfo->x_focus_frame)
 28751             time = x_get_server_time (f);
 28752 
 28753           /* Ignore any BadMatch error this request might result in.
 28754              A BadMatch error can occur if the window was obscured
 28755              after the time of the last user interaction without
 28756              changing the last-focus-change-time.  */
 28757           x_set_input_focus (FRAME_DISPLAY_INFO (f), FRAME_OUTER_WINDOW (f),
 28758                              time);
 28759         }
 28760       else
 28761         x_set_input_focus (FRAME_DISPLAY_INFO (f), FRAME_OUTER_WINDOW (f),
 28762                            /* But when no window manager is in use,
 28763                               respecting the ICCCM doesn't really
 28764                               matter.  */
 28765                            CurrentTime);
 28766     }
 28767 
 28768  out:
 28769   unblock_input ();
 28770 }
 28771 
 28772 
 28773 /* XEmbed implementation.  */
 28774 
 28775 #if defined USE_X_TOOLKIT || ! defined USE_GTK
 28776 
 28777 /* XEmbed implementation.  */
 28778 
 28779 #define XEMBED_VERSION 0
 28780 
 28781 static void
 28782 xembed_set_info (struct frame *f, enum xembed_info flags)
 28783 {
 28784   unsigned long data[2];
 28785   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 28786 
 28787   data[0] = XEMBED_VERSION;
 28788   data[1] = flags;
 28789 
 28790   XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 28791                    dpyinfo->Xatom_XEMBED_INFO, dpyinfo->Xatom_XEMBED_INFO,
 28792                    32, PropModeReplace, (unsigned char *) data, 2);
 28793 }
 28794 #endif /* defined USE_X_TOOLKIT || ! defined USE_GTK */
 28795 
 28796 static void
 28797 xembed_send_message (struct frame *f, Time t, enum xembed_message msg,
 28798                      long int detail, long int data1, long int data2)
 28799 {
 28800   XEvent event;
 28801 
 28802   event.xclient.type = ClientMessage;
 28803   event.xclient.window = FRAME_X_OUTPUT (f)->parent_desc;
 28804   event.xclient.message_type = FRAME_DISPLAY_INFO (f)->Xatom_XEMBED;
 28805   event.xclient.format = 32;
 28806   event.xclient.data.l[0] = t;
 28807   event.xclient.data.l[1] = msg;
 28808   event.xclient.data.l[2] = detail;
 28809   event.xclient.data.l[3] = data1;
 28810   event.xclient.data.l[4] = data2;
 28811 
 28812   /* XXX: the XEmbed spec tells us to trap errors around this request,
 28813      but I don't understand why: there is no way for clients to
 28814      survive the death of the parent anyway.  */
 28815 
 28816   x_ignore_errors_for_next_request (FRAME_DISPLAY_INFO (f), 0);
 28817   XSendEvent (FRAME_X_DISPLAY (f), FRAME_X_OUTPUT (f)->parent_desc,
 28818               False, NoEventMask, &event);
 28819   x_stop_ignoring_errors (FRAME_DISPLAY_INFO (f));
 28820 }
 28821 
 28822 /* Change of visibility.  */
 28823 
 28824 /* This tries to wait until the frame is really visible, depending on
 28825    the value of Vx_wait_for_event_timeout.
 28826    However, if the window manager asks the user where to position
 28827    the frame, this will return before the user finishes doing that.
 28828    The frame will not actually be visible at that time,
 28829    but it will become visible later when the window manager
 28830    finishes with it.  */
 28831 
 28832 void
 28833 x_make_frame_visible (struct frame *f)
 28834 {
 28835 #ifndef USE_GTK
 28836   struct x_display_info *dpyinfo;
 28837   struct x_output *output;
 28838 #endif
 28839   bool output_flushed;
 28840 
 28841   if (FRAME_PARENT_FRAME (f))
 28842     {
 28843       if (!FRAME_VISIBLE_P (f))
 28844         {
 28845           block_input ();
 28846 #ifdef USE_GTK
 28847           gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
 28848           XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 28849                        f->left_pos, f->top_pos);
 28850 #else
 28851           XMapRaised (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f));
 28852 #endif
 28853           unblock_input ();
 28854 
 28855           SET_FRAME_VISIBLE (f, true);
 28856           SET_FRAME_ICONIFIED (f, false);
 28857         }
 28858       return;
 28859     }
 28860 
 28861   block_input ();
 28862 
 28863   gui_set_bitmap_icon (f);
 28864 
 28865 #ifndef USE_GTK
 28866   dpyinfo = FRAME_DISPLAY_INFO (f);
 28867 #endif
 28868 
 28869   if (! FRAME_VISIBLE_P (f))
 28870     {
 28871       /* We test asked_for_visible here to make sure we don't
 28872          call x_set_offset a second time
 28873          if we get to x_make_frame_visible a second time
 28874          before the window gets really visible.  */
 28875       if (! FRAME_ICONIFIED_P (f)
 28876           && ! FRAME_X_EMBEDDED_P (f)
 28877           && ! f->output_data.x->asked_for_visible)
 28878         x_set_offset (f, f->left_pos, f->top_pos, 0);
 28879 
 28880 #ifndef USE_GTK
 28881       output = FRAME_X_OUTPUT (f);
 28882       x_update_frame_user_time_window (f);
 28883 
 28884       /* It's been a while since I wrote that code...  I don't
 28885          remember if it can leave `user_time_window' unset or not.  */
 28886       if (output->user_time_window != None)
 28887         {
 28888           if (dpyinfo->last_user_time)
 28889             XChangeProperty (dpyinfo->display, output->user_time_window,
 28890                              dpyinfo->Xatom_net_wm_user_time,
 28891                              XA_CARDINAL, 32, PropModeReplace,
 28892                              (unsigned char *) &dpyinfo->last_user_time, 1);
 28893           else
 28894             XDeleteProperty (dpyinfo->display, output->user_time_window,
 28895                              dpyinfo->Xatom_net_wm_user_time);
 28896         }
 28897 #endif
 28898 
 28899       f->output_data.x->asked_for_visible = true;
 28900 
 28901       if (! EQ (Vx_no_window_manager, Qt))
 28902         x_wm_set_window_state (f, NormalState);
 28903 #ifdef USE_X_TOOLKIT
 28904       if (FRAME_X_EMBEDDED_P (f))
 28905         xembed_set_info (f, XEMBED_MAPPED);
 28906       else
 28907         {
 28908           /* This was XtPopup, but that did nothing for an iconified frame.  */
 28909           XtMapWidget (f->output_data.x->widget);
 28910         }
 28911 #else /* not USE_X_TOOLKIT */
 28912 #ifdef USE_GTK
 28913       gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
 28914       gtk_window_deiconify (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
 28915 #else
 28916       if (FRAME_X_EMBEDDED_P (f))
 28917         xembed_set_info (f, XEMBED_MAPPED);
 28918       else
 28919         XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
 28920 #endif /* not USE_GTK */
 28921 #endif /* not USE_X_TOOLKIT */
 28922 
 28923       if (FRAME_X_EMBEDDED_P (f))
 28924         {
 28925           SET_FRAME_VISIBLE (f, true);
 28926           SET_FRAME_ICONIFIED (f, false);
 28927         }
 28928     }
 28929 
 28930   /* Synchronize to ensure Emacs knows the frame is visible
 28931      before we do anything else.  We do this loop with input not blocked
 28932      so that incoming events are handled.  */
 28933   {
 28934     Lisp_Object frame;
 28935     /* This must be before UNBLOCK_INPUT
 28936        since events that arrive in response to the actions above
 28937        will set it when they are handled.  */
 28938     bool previously_visible = f->output_data.x->has_been_visible;
 28939 
 28940     XSETFRAME (frame, f);
 28941 
 28942     int original_left = f->left_pos;
 28943     int original_top = f->top_pos;
 28944 
 28945     /* This must come after we set COUNT.  */
 28946     unblock_input ();
 28947 
 28948     /* Keep track of whether or not the output buffer was flushed, to
 28949        avoid any extra flushes.  */
 28950     output_flushed = false;
 28951 
 28952     /* We unblock here so that arriving X events are processed.  */
 28953 
 28954     /* Now move the window back to where it was "supposed to be".
 28955        But don't do it if the gravity is negative.
 28956        When the gravity is negative, this uses a position
 28957        that is 3 pixels too low.  Perhaps that's really the border width.
 28958 
 28959        Don't do this if the window has never been visible before,
 28960        because the window manager may choose the position
 28961        and we don't want to override it.  */
 28962 
 28963     if (!FRAME_VISIBLE_P (f)
 28964         && !FRAME_ICONIFIED_P (f)
 28965         && !FRAME_X_EMBEDDED_P (f)
 28966         && !FRAME_PARENT_FRAME (f)
 28967         && NILP (Vx_lax_frame_positioning)
 28968         && f->win_gravity == NorthWestGravity
 28969         && previously_visible)
 28970       {
 28971         Drawable rootw;
 28972         int x, y;
 28973         unsigned int width, height, border, depth;
 28974 
 28975         block_input ();
 28976 
 28977         /* On some window managers (such as FVWM) moving an existing
 28978            window, even to the same place, causes the window manager
 28979            to introduce an offset.  This can cause the window to move
 28980            to an unexpected location.  Check the geometry (a little
 28981            slow here) and then verify that the window is in the right
 28982            place.  If the window is not in the right place, move it
 28983            there, and take the potential window manager hit.  */
 28984         XGetGeometry (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 28985                       &rootw, &x, &y, &width, &height, &border, &depth);
 28986         output_flushed = true;
 28987 
 28988         if (original_left != x || original_top != y)
 28989           XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 28990                        original_left, original_top);
 28991 
 28992         unblock_input ();
 28993       }
 28994 
 28995     /* Try to wait for a MapNotify event (that is what tells us when a
 28996        frame becomes visible).  Unless `x-lax-frame-positioning' is
 28997        non-nil: there, that is a little slow.  */
 28998 
 28999 #ifdef CYGWIN
 29000     /* On Cygwin, which uses input polling, we need to force input to
 29001        be read.  See
 29002        https://lists.gnu.org/r/emacs-devel/2013-12/msg00351.html
 29003        and https://debbugs.gnu.org/cgi/bugreport.cgi?bug=24091#131.
 29004        Fake an alarm signal to let the handler know that there's
 29005        something to be read.
 29006 
 29007        It could be confusing if a real alarm arrives while processing
 29008        the fake one.  Turn it off and let the handler reset it.  */
 29009     int old_poll_suppress_count = poll_suppress_count;
 29010     poll_suppress_count = 1;
 29011     poll_for_input_1 ();
 29012     poll_suppress_count = old_poll_suppress_count;
 29013 #endif
 29014 
 29015     if (!FRAME_VISIBLE_P (f)
 29016         && NILP (Vx_lax_frame_positioning))
 29017       {
 29018         if (CONSP (frame_size_history))
 29019           frame_size_history_plain
 29020             (f, build_string ("x_make_frame_visible"));
 29021 
 29022         x_wait_for_event (f, MapNotify);
 29023         output_flushed = true;
 29024       }
 29025 
 29026     if (!output_flushed)
 29027       x_flush (f);
 29028   }
 29029 }
 29030 
 29031 /* Change from mapped state to withdrawn state.  */
 29032 
 29033 /* Make the frame visible (mapped and not iconified).  */
 29034 
 29035 void
 29036 x_make_frame_invisible (struct frame *f)
 29037 {
 29038   Window window;
 29039 
 29040   /* Use the frame's outermost window, not the one we normally draw on.  */
 29041   window = FRAME_OUTER_WINDOW (f);
 29042 
 29043   /* Don't keep the highlight on an invisible frame.  */
 29044   if (FRAME_DISPLAY_INFO (f)->highlight_frame == f)
 29045     FRAME_DISPLAY_INFO (f)->highlight_frame = 0;
 29046 
 29047   block_input ();
 29048 
 29049 #ifdef HAVE_XINPUT2_2
 29050   /* Remove any touch points associated with F.  */
 29051   xi_unlink_touch_points (f);
 29052 #endif
 29053 
 29054   /* Before unmapping the window, update the WM_SIZE_HINTS property to claim
 29055      that the current position of the window is user-specified, rather than
 29056      program-specified, so that when the window is mapped again, it will be
 29057      placed at the same location, without forcing the user to position it
 29058      by hand again (they have already done that once for this window.)  */
 29059   x_wm_set_size_hint (f, 0, true);
 29060 
 29061 #ifdef USE_GTK
 29062   if (FRAME_GTK_OUTER_WIDGET (f))
 29063     gtk_widget_hide (FRAME_GTK_OUTER_WIDGET (f));
 29064   else
 29065 #else
 29066   if (FRAME_X_EMBEDDED_P (f))
 29067     xembed_set_info (f, 0);
 29068   else
 29069 #endif
 29070 
 29071     if (! XWithdrawWindow (FRAME_X_DISPLAY (f), window,
 29072                            DefaultScreen (FRAME_X_DISPLAY (f))))
 29073       {
 29074         unblock_input ();
 29075         error ("Can't notify window manager of window withdrawal");
 29076       }
 29077 
 29078   /* Don't perform the synchronization if the network connection is
 29079      slow, and the user says it is unwanted.  */
 29080   if (NILP (Vx_lax_frame_positioning))
 29081     XSync (FRAME_X_DISPLAY (f), False);
 29082 
 29083   /* We can't distinguish this from iconification
 29084      just by the event that we get from the server.
 29085      So we can't win using the usual strategy of letting
 29086      FRAME_SAMPLE_VISIBILITY set this.  So do it by hand,
 29087      and synchronize with the server to make sure we agree.  */
 29088   SET_FRAME_VISIBLE (f, 0);
 29089   SET_FRAME_ICONIFIED (f, false);
 29090 
 29091   if (CONSP (frame_size_history))
 29092     frame_size_history_plain (f, build_string ("x_make_frame_invisible"));
 29093 
 29094   unblock_input ();
 29095 }
 29096 
 29097 static void
 29098 x_make_frame_visible_invisible (struct frame *f, bool visible)
 29099 {
 29100   if (visible)
 29101     x_make_frame_visible (f);
 29102   else
 29103     x_make_frame_invisible (f);
 29104 }
 29105 
 29106 Cursor
 29107 x_create_font_cursor (struct x_display_info *dpyinfo, int glyph)
 29108 {
 29109   if (glyph <= 65535)
 29110     return XCreateFontCursor (dpyinfo->display, glyph);
 29111 
 29112   /* x-pointer-invisible cannot fit in CARD16, and thus cannot be any
 29113      existing cursor.  */
 29114   return make_invisible_cursor (dpyinfo);
 29115 }
 29116 
 29117 
 29118 /* Change window state from mapped to iconified.  */
 29119 
 29120 void
 29121 x_iconify_frame (struct frame *f)
 29122 {
 29123 #ifdef USE_X_TOOLKIT
 29124   int result;
 29125 #endif
 29126 
 29127   /* Don't keep the highlight on an invisible frame.  */
 29128   if (FRAME_DISPLAY_INFO (f)->highlight_frame == f)
 29129     FRAME_DISPLAY_INFO (f)->highlight_frame = 0;
 29130 
 29131   if (FRAME_ICONIFIED_P (f))
 29132     return;
 29133 
 29134   block_input ();
 29135 
 29136   gui_set_bitmap_icon (f);
 29137 
 29138 #if defined (USE_GTK)
 29139   if (FRAME_GTK_OUTER_WIDGET (f))
 29140     {
 29141       if (! FRAME_VISIBLE_P (f))
 29142         gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
 29143 
 29144       gtk_window_iconify (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
 29145       SET_FRAME_VISIBLE (f, 0);
 29146       SET_FRAME_ICONIFIED (f, true);
 29147       unblock_input ();
 29148       return;
 29149     }
 29150 #endif
 29151 
 29152 #ifdef USE_X_TOOLKIT
 29153 
 29154   if (! FRAME_VISIBLE_P (f))
 29155     {
 29156       if (! EQ (Vx_no_window_manager, Qt))
 29157         x_wm_set_window_state (f, IconicState);
 29158       /* This was XtPopup, but that did nothing for an iconified frame.  */
 29159       XtMapWidget (f->output_data.x->widget);
 29160       /* The server won't give us any event to indicate
 29161          that an invisible frame was changed to an icon,
 29162          so we have to record it here.  */
 29163       SET_FRAME_VISIBLE (f, 0);
 29164       SET_FRAME_ICONIFIED (f, true);
 29165       unblock_input ();
 29166       return;
 29167     }
 29168 
 29169   result = XIconifyWindow (FRAME_X_DISPLAY (f),
 29170                            XtWindow (f->output_data.x->widget),
 29171                            DefaultScreen (FRAME_X_DISPLAY (f)));
 29172   unblock_input ();
 29173 
 29174   if (!result)
 29175     error ("Can't notify window manager of iconification");
 29176 
 29177   SET_FRAME_ICONIFIED (f, true);
 29178   SET_FRAME_VISIBLE (f, 0);
 29179 
 29180   block_input ();
 29181   XFlush (FRAME_X_DISPLAY (f));
 29182   unblock_input ();
 29183 #else /* not USE_X_TOOLKIT */
 29184 
 29185   /* Make sure the X server knows where the window should be positioned,
 29186      in case the user deiconifies with the window manager.  */
 29187   if (! FRAME_VISIBLE_P (f)
 29188       && ! FRAME_ICONIFIED_P (f)
 29189       && ! FRAME_X_EMBEDDED_P (f))
 29190     x_set_offset (f, f->left_pos, f->top_pos, 0);
 29191 
 29192   /* Since we don't know which revision of X we're running, we'll use both
 29193      the X11R3 and X11R4 techniques.  I don't know if this is a good idea.  */
 29194 
 29195   /* X11R4: send a ClientMessage to the window manager using the
 29196      WM_CHANGE_STATE type.  */
 29197   {
 29198     XEvent msg;
 29199 
 29200     msg.xclient.window = FRAME_X_WINDOW (f);
 29201     msg.xclient.type = ClientMessage;
 29202     msg.xclient.message_type = FRAME_DISPLAY_INFO (f)->Xatom_wm_change_state;
 29203     msg.xclient.format = 32;
 29204     msg.xclient.data.l[0] = IconicState;
 29205     msg.xclient.data.l[1] = 0;
 29206     msg.xclient.data.l[2] = 0;
 29207     msg.xclient.data.l[3] = 0;
 29208     msg.xclient.data.l[4] = 0;
 29209 
 29210     if (! XSendEvent (FRAME_X_DISPLAY (f),
 29211                       FRAME_DISPLAY_INFO (f)->root_window,
 29212                       False,
 29213                       SubstructureRedirectMask | SubstructureNotifyMask,
 29214                       &msg))
 29215       {
 29216         unblock_input ();
 29217         error ("Can't notify window manager of iconification");
 29218       }
 29219   }
 29220 
 29221   /* X11R3: set the initial_state field of the window manager hints to
 29222      IconicState.  */
 29223   x_wm_set_window_state (f, IconicState);
 29224 
 29225   if (!FRAME_VISIBLE_P (f))
 29226     {
 29227       /* If the frame was withdrawn, before, we must map it.  */
 29228       XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
 29229     }
 29230 
 29231   SET_FRAME_ICONIFIED (f, true);
 29232   SET_FRAME_VISIBLE (f, 0);
 29233 
 29234   XFlush (FRAME_X_DISPLAY (f));
 29235   unblock_input ();
 29236 #endif /* not USE_X_TOOLKIT */
 29237 }
 29238 
 29239 
 29240 /* Free X resources of frame F.  */
 29241 
 29242 void
 29243 x_free_frame_resources (struct frame *f)
 29244 {
 29245   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 29246   Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
 29247 #ifdef USE_X_TOOLKIT
 29248   Lisp_Object bar;
 29249   struct scroll_bar *b;
 29250 #endif
 29251 
 29252   block_input ();
 29253 
 29254 #ifdef HAVE_XINPUT2
 29255   /* Remove any record of this frame being focused.  */
 29256   xi_handle_delete_frame (dpyinfo, f);
 29257 #endif
 29258 
 29259 #ifdef HAVE_XINPUT2_2
 29260   /* Remove any touch points associated with F.  */
 29261   xi_unlink_touch_points (f);
 29262 #endif
 29263 
 29264   /* If a display connection is dead, don't try sending more
 29265      commands to the X server.  */
 29266   if (dpyinfo->display)
 29267     {
 29268       /* Always exit with visible pointer to avoid weird issue
 29269          with Xfixes (Bug#17609).  */
 29270       if (f->pointer_invisible)
 29271         XTtoggle_invisible_pointer (f, 0);
 29272 
 29273       /* We must free faces before destroying windows because some
 29274          font-driver (e.g. xft) access a window while finishing a
 29275          face.  */
 29276       free_frame_faces (f);
 29277       tear_down_x_back_buffer (f);
 29278 
 29279       if (f->output_data.x->icon_desc)
 29280         XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->icon_desc);
 29281 
 29282 #ifdef USE_X_TOOLKIT
 29283       /* Explicitly destroy the scroll bars of the frame.  Without
 29284          this, we get "BadDrawable" errors from the toolkit later on,
 29285          presumably from expose events generated for the disappearing
 29286          toolkit scroll bars.  */
 29287       for (bar = FRAME_SCROLL_BARS (f); !NILP (bar); bar = b->next)
 29288         {
 29289           b = XSCROLL_BAR (bar);
 29290           x_scroll_bar_remove (b);
 29291         }
 29292 #endif
 29293 
 29294 #ifdef HAVE_X_I18N
 29295       if (FRAME_XIC (f))
 29296         free_frame_xic (f);
 29297 #endif
 29298 
 29299 #ifdef USE_CAIRO
 29300       x_cr_destroy_frame_context (f);
 29301 #endif
 29302 #ifdef USE_X_TOOLKIT
 29303       if (f->output_data.x->widget)
 29304         {
 29305           XtDestroyWidget (f->output_data.x->widget);
 29306           f->output_data.x->widget = NULL;
 29307         }
 29308       /* Tooltips don't have widgets, only a simple X window, even if
 29309          we are using a toolkit.  */
 29310       else if (FRAME_X_WINDOW (f))
 29311         XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
 29312 
 29313       free_frame_menubar (f);
 29314 
 29315       if (f->shell_position)
 29316         xfree (f->shell_position);
 29317 #else  /* !USE_X_TOOLKIT */
 29318 
 29319 #ifdef HAVE_XWIDGETS
 29320       kill_frame_xwidget_views (f);
 29321 #endif
 29322 
 29323 #ifdef USE_GTK
 29324       xg_free_frame_widgets (f);
 29325 #endif /* USE_GTK */
 29326 
 29327       tear_down_x_back_buffer (f);
 29328       if (FRAME_X_WINDOW (f))
 29329         XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
 29330 #endif /* !USE_X_TOOLKIT */
 29331 
 29332 #ifdef HAVE_XSYNC
 29333       if (FRAME_X_BASIC_COUNTER (f) != None)
 29334         XSyncDestroyCounter (FRAME_X_DISPLAY (f),
 29335                              FRAME_X_BASIC_COUNTER (f));
 29336 
 29337       if (FRAME_X_EXTENDED_COUNTER (f) != None)
 29338         XSyncDestroyCounter (FRAME_X_DISPLAY (f),
 29339                              FRAME_X_EXTENDED_COUNTER (f));
 29340 #endif
 29341 
 29342       unload_color (f, FRAME_FOREGROUND_PIXEL (f));
 29343       unload_color (f, FRAME_BACKGROUND_PIXEL (f));
 29344       unload_color (f, f->output_data.x->cursor_pixel);
 29345       unload_color (f, f->output_data.x->cursor_foreground_pixel);
 29346       unload_color (f, f->output_data.x->border_pixel);
 29347       unload_color (f, f->output_data.x->mouse_pixel);
 29348 
 29349       if (f->output_data.x->scroll_bar_background_pixel != -1)
 29350         unload_color (f, f->output_data.x->scroll_bar_background_pixel);
 29351       if (f->output_data.x->scroll_bar_foreground_pixel != -1)
 29352         unload_color (f, f->output_data.x->scroll_bar_foreground_pixel);
 29353 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
 29354       /* Scrollbar shadow colors.  */
 29355       if (f->output_data.x->scroll_bar_top_shadow_pixel != -1)
 29356         unload_color (f, f->output_data.x->scroll_bar_top_shadow_pixel);
 29357       if (f->output_data.x->scroll_bar_bottom_shadow_pixel != -1)
 29358         unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
 29359 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
 29360       if (f->output_data.x->white_relief.pixel != -1)
 29361         unload_color (f, f->output_data.x->white_relief.pixel);
 29362       if (f->output_data.x->black_relief.pixel != -1)
 29363         unload_color (f, f->output_data.x->black_relief.pixel);
 29364 
 29365       x_free_gcs (f);
 29366 
 29367       /* Free extra GCs allocated by x_setup_relief_colors.  */
 29368       if (f->output_data.x->white_relief.gc)
 29369         {
 29370           XFreeGC (dpyinfo->display, f->output_data.x->white_relief.gc);
 29371           f->output_data.x->white_relief.gc = 0;
 29372         }
 29373       if (f->output_data.x->black_relief.gc)
 29374         {
 29375           XFreeGC (dpyinfo->display, f->output_data.x->black_relief.gc);
 29376           f->output_data.x->black_relief.gc = 0;
 29377         }
 29378 
 29379       /* Free cursors.  */
 29380       if (f->output_data.x->text_cursor != 0)
 29381         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->text_cursor);
 29382       if (f->output_data.x->nontext_cursor != 0)
 29383         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->nontext_cursor);
 29384       if (f->output_data.x->modeline_cursor != 0)
 29385         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->modeline_cursor);
 29386       if (f->output_data.x->hand_cursor != 0)
 29387         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->hand_cursor);
 29388       if (f->output_data.x->hourglass_cursor != 0)
 29389         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->hourglass_cursor);
 29390       if (f->output_data.x->horizontal_drag_cursor != 0)
 29391         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->horizontal_drag_cursor);
 29392       if (f->output_data.x->vertical_drag_cursor != 0)
 29393         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->vertical_drag_cursor);
 29394       if (f->output_data.x->left_edge_cursor != 0)
 29395         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->left_edge_cursor);
 29396       if (f->output_data.x->top_left_corner_cursor != 0)
 29397         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->top_left_corner_cursor);
 29398       if (f->output_data.x->top_edge_cursor != 0)
 29399         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->top_edge_cursor);
 29400       if (f->output_data.x->top_right_corner_cursor != 0)
 29401         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->top_right_corner_cursor);
 29402       if (f->output_data.x->right_edge_cursor != 0)
 29403         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->right_edge_cursor);
 29404       if (f->output_data.x->bottom_right_corner_cursor != 0)
 29405         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->bottom_right_corner_cursor);
 29406       if (f->output_data.x->bottom_edge_cursor != 0)
 29407         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->bottom_edge_cursor);
 29408       if (f->output_data.x->bottom_left_corner_cursor != 0)
 29409         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->bottom_left_corner_cursor);
 29410 
 29411       /* Free sync fences.  */
 29412 #if defined HAVE_XSYNCTRIGGERFENCE && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
 29413       x_sync_free_fences (f);
 29414 #endif
 29415 
 29416 #ifdef USE_TOOLKIT_SCROLL_BARS
 29417       /* Since the frame was destroyed, we can no longer guarantee
 29418          that scroll bar events will be received.  Clear
 29419          protected_windows.  */
 29420       dpyinfo->n_protected_windows = 0;
 29421 #endif
 29422     }
 29423 
 29424 #ifdef HAVE_GTK3
 29425   if (FRAME_OUTPUT_DATA (f)->scrollbar_background_css_provider)
 29426     g_object_unref (FRAME_OUTPUT_DATA (f)->scrollbar_background_css_provider);
 29427 
 29428   if (FRAME_OUTPUT_DATA (f)->scrollbar_foreground_css_provider)
 29429     g_object_unref (FRAME_OUTPUT_DATA (f)->scrollbar_foreground_css_provider);
 29430 #endif
 29431 
 29432   if (f == dpyinfo->motif_drag_atom_owner)
 29433     {
 29434       dpyinfo->motif_drag_atom_owner = NULL;
 29435       dpyinfo->motif_drag_atom = None;
 29436     }
 29437 
 29438   if (f == dpyinfo->x_focus_frame)
 29439     dpyinfo->x_focus_frame = 0;
 29440   if (f == dpyinfo->x_focus_event_frame)
 29441     dpyinfo->x_focus_event_frame = 0;
 29442   if (f == dpyinfo->highlight_frame)
 29443     dpyinfo->highlight_frame = 0;
 29444   if (f == hlinfo->mouse_face_mouse_frame)
 29445     reset_mouse_highlight (hlinfo);
 29446 
 29447   /* These two need to be freed now that they are used to compute the
 29448      mouse position, I think.  */
 29449   if (f == dpyinfo->last_mouse_motion_frame)
 29450     dpyinfo->last_mouse_motion_frame = NULL;
 29451   if (f == dpyinfo->last_mouse_frame)
 29452     dpyinfo->last_mouse_frame = NULL;
 29453 
 29454 #ifdef HAVE_XINPUT2
 29455   /* Consider a frame being unfocused with no following FocusIn event
 29456      while an older focus from another seat exists.  The client
 29457      pointer should then revert to the other seat, so handle potential
 29458      focus changes.  */
 29459 
 29460   if (dpyinfo->supports_xi2)
 29461     xi_handle_focus_change (dpyinfo);
 29462 #endif
 29463 
 29464   unblock_input ();
 29465 }
 29466 
 29467 
 29468 /* Destroy the X window of frame F.  */
 29469 
 29470 static void
 29471 x_destroy_window (struct frame *f)
 29472 {
 29473   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 29474 
 29475   /* If a display connection is dead, don't try sending more
 29476      commands to the X server.  */
 29477   if (dpyinfo->display != 0)
 29478     x_free_frame_resources (f);
 29479 
 29480   xfree (f->output_data.x->saved_menu_event);
 29481 
 29482 #ifdef HAVE_X_I18N
 29483   if (f->output_data.x->preedit_chars)
 29484     xfree (f->output_data.x->preedit_chars);
 29485 #endif
 29486 
 29487 #ifdef HAVE_XINPUT2
 29488 #ifdef HAVE_XINPUT2_1
 29489   if (f->output_data.x->xi_masks)
 29490     XFree (f->output_data.x->xi_masks);
 29491 #else
 29492   /* This is allocated by us under very old versions of libXi; see
 29493      `setup_xi_event_mask'.  */
 29494   if (f->output_data.x->xi_masks)
 29495     xfree (f->output_data.x->xi_masks);
 29496 #endif
 29497 #endif
 29498 
 29499   xfree (f->output_data.x);
 29500   f->output_data.x = NULL;
 29501 
 29502   dpyinfo->reference_count--;
 29503 }
 29504 
 29505 /* Intern NAME in DPYINFO, but check to see if the atom was already
 29506    interned when the X connection was opened, and use that instead.
 29507 
 29508    If PREDEFINED_ONLY, return None if the atom was not interned during
 29509    connection setup or is predefined.  */
 29510 Atom
 29511 x_intern_cached_atom (struct x_display_info *dpyinfo,
 29512                       const char *name, bool predefined_only)
 29513 {
 29514   int i;
 29515   char *ptr;
 29516   Atom *atom;
 29517 
 29518   /* Special atoms that depend on the screen number.  */
 29519   char xsettings_atom_name[sizeof "_XSETTINGS_S%d" - 2
 29520                            + INT_STRLEN_BOUND (int)];
 29521   char cm_atom_name[sizeof "_NET_WM_CM_S%d" - 2
 29522                     + INT_STRLEN_BOUND (int)];
 29523 
 29524   sprintf (xsettings_atom_name, "_XSETTINGS_S%d",
 29525            XScreenNumberOfScreen (dpyinfo->screen));
 29526   sprintf (cm_atom_name, "_NET_WM_CM_S%d",
 29527            XScreenNumberOfScreen (dpyinfo->screen));
 29528 
 29529   if (!strcmp (name, xsettings_atom_name))
 29530     return dpyinfo->Xatom_xsettings_sel;
 29531 
 29532   if (!strcmp (name, cm_atom_name))
 29533     return dpyinfo->Xatom_NET_WM_CM_Sn;
 29534 
 29535   /* Now do some common predefined atoms.  */
 29536   if (!strcmp (name, "PRIMARY"))
 29537     return XA_PRIMARY;
 29538 
 29539   if (!strcmp (name, "SECONDARY"))
 29540     return XA_SECONDARY;
 29541 
 29542   if (!strcmp (name, "STRING"))
 29543     return XA_STRING;
 29544 
 29545   if (!strcmp (name, "INTEGER"))
 29546     return XA_INTEGER;
 29547 
 29548   if (!strcmp (name, "ATOM"))
 29549     return XA_ATOM;
 29550 
 29551   if (!strcmp (name, "WINDOW"))
 29552     return XA_WINDOW;
 29553 
 29554   if (!strcmp (name, "DRAWABLE"))
 29555     return XA_DRAWABLE;
 29556 
 29557   if (!strcmp (name, "BITMAP"))
 29558     return XA_BITMAP;
 29559 
 29560   if (!strcmp (name, "CARDINAL"))
 29561     return XA_CARDINAL;
 29562 
 29563   if (!strcmp (name, "COLORMAP"))
 29564     return XA_COLORMAP;
 29565 
 29566   if (!strcmp (name, "CURSOR"))
 29567     return XA_CURSOR;
 29568 
 29569   if (!strcmp (name, "FONT"))
 29570     return XA_FONT;
 29571 
 29572   if (dpyinfo->motif_drag_atom != None
 29573       && !strcmp (name, dpyinfo->motif_drag_atom_name))
 29574     return dpyinfo->motif_drag_atom;
 29575 
 29576   for (i = 0; i < ARRAYELTS (x_atom_refs); ++i)
 29577     {
 29578       ptr = (char *) dpyinfo;
 29579 
 29580       if (!strcmp (x_atom_refs[i].name, name))
 29581         {
 29582           atom = (Atom *) (ptr + x_atom_refs[i].offset);
 29583 
 29584           return *atom;
 29585         }
 29586     }
 29587 
 29588   if (predefined_only)
 29589     return None;
 29590 
 29591   return XInternAtom (dpyinfo->display, name, False);
 29592 }
 29593 
 29594 /* Get the name of ATOM, but try not to make a request to the X
 29595    server.  Whether or not a request to the X server happened is
 29596    placed in NEED_SYNC.  */
 29597 char *
 29598 x_get_atom_name (struct x_display_info *dpyinfo, Atom atom,
 29599                  bool *need_sync)
 29600 {
 29601   char *dpyinfo_pointer, *name, *value, *buffer;
 29602   int i;
 29603   Atom ref_atom;
 29604 
 29605   dpyinfo_pointer = (char *) dpyinfo;
 29606   value = NULL;
 29607 
 29608   if (need_sync)
 29609     *need_sync = false;
 29610 
 29611   buffer = alloca (45 + INT_STRLEN_BOUND (int));
 29612 
 29613   switch (atom)
 29614     {
 29615     case XA_PRIMARY:
 29616       return xstrdup ("PRIMARY");
 29617 
 29618     case XA_SECONDARY:
 29619       return xstrdup ("SECONDARY");
 29620 
 29621     case XA_INTEGER:
 29622       return xstrdup ("INTEGER");
 29623 
 29624     case XA_ATOM:
 29625       return xstrdup ("ATOM");
 29626 
 29627     case XA_CARDINAL:
 29628       return xstrdup ("CARDINAL");
 29629 
 29630     case XA_WINDOW:
 29631       return xstrdup ("WINDOW");
 29632 
 29633     case XA_DRAWABLE:
 29634       return xstrdup ("DRAWABLE");
 29635 
 29636     case XA_BITMAP:
 29637       return xstrdup ("BITMAP");
 29638 
 29639     case XA_COLORMAP:
 29640       return xstrdup ("COLORMAP");
 29641 
 29642     case XA_FONT:
 29643       return xstrdup ("FONT");
 29644 
 29645     default:
 29646       if (dpyinfo->motif_drag_atom
 29647           && atom == dpyinfo->motif_drag_atom)
 29648         return xstrdup (dpyinfo->motif_drag_atom_name);
 29649 
 29650       if (atom == dpyinfo->Xatom_xsettings_sel)
 29651         {
 29652           sprintf (buffer, "_XSETTINGS_S%d",
 29653                    XScreenNumberOfScreen (dpyinfo->screen));
 29654           return xstrdup (buffer);
 29655         }
 29656 
 29657       if (atom == dpyinfo->Xatom_NET_WM_CM_Sn)
 29658         {
 29659           sprintf (buffer, "_NET_WM_CM_S%d",
 29660                    XScreenNumberOfScreen (dpyinfo->screen));
 29661           return xstrdup (buffer);
 29662         }
 29663 
 29664       for (i = 0; i < ARRAYELTS (x_atom_refs); ++i)
 29665         {
 29666           ref_atom = *(Atom *) (dpyinfo_pointer
 29667                                 + x_atom_refs[i].offset);
 29668 
 29669           if (atom == ref_atom)
 29670             return xstrdup (x_atom_refs[i].name);
 29671         }
 29672 
 29673       name = XGetAtomName (dpyinfo->display, atom);
 29674 
 29675       if (need_sync)
 29676         *need_sync = true;
 29677 
 29678       if (name)
 29679         {
 29680           value = xstrdup (name);
 29681           XFree (name);
 29682         }
 29683 
 29684       break;
 29685     }
 29686 
 29687   return value;
 29688 }
 29689 
 29690 /* Intern an array of atoms, and do so quickly, avoiding extraneous
 29691    roundtrips to the X server.
 29692 
 29693    Avoid sending atoms that have already been found to the X server.
 29694    This cannot do anything that will end up triggering garbage
 29695    collection.  */
 29696 
 29697 void
 29698 x_intern_atoms (struct x_display_info *dpyinfo, char **names, int count,
 29699                 Atom *atoms_return)
 29700 {
 29701   int i, j, indices[256];
 29702   char *new_names[256];
 29703   Atom results[256], candidate;
 29704 
 29705   if (count > 256)
 29706     /* Atoms array too big to inspect reasonably, just send it to the
 29707        server and back.  */
 29708     XInternAtoms (dpyinfo->display, new_names, count, False, atoms_return);
 29709   else
 29710     {
 29711       for (i = 0, j = 0; i < count; ++i)
 29712         {
 29713           candidate = x_intern_cached_atom (dpyinfo, names[i],
 29714                                             true);
 29715 
 29716           if (candidate)
 29717             atoms_return[i] = candidate;
 29718           else
 29719             {
 29720               indices[j++] = i;
 29721               new_names[j - 1] = names[i];
 29722             }
 29723         }
 29724 
 29725       if (!j)
 29726         return;
 29727 
 29728       /* Now, get the results back from the X server.  */
 29729       XInternAtoms (dpyinfo->display, new_names, j, False,
 29730                     results);
 29731 
 29732       for (i = 0; i < j; ++i)
 29733         atoms_return[indices[i]] = results[i];
 29734     }
 29735 }
 29736 
 29737 #ifndef USE_GTK
 29738 
 29739 /* Set up XEmbed for F, and change its save set to handle the parent
 29740    being destroyed.  */
 29741 
 29742 bool
 29743 x_embed_frame (struct x_display_info *dpyinfo, struct frame *f)
 29744 {
 29745   bool rc;
 29746 
 29747   x_catch_errors (dpyinfo->display);
 29748   /* Catch errors; the target window might no longer exist.  */
 29749   XReparentWindow (dpyinfo->display, FRAME_OUTER_WINDOW (f),
 29750                    FRAME_OUTPUT_DATA (f)->parent_desc, 0, 0);
 29751   rc = x_had_errors_p (dpyinfo->display);
 29752   x_uncatch_errors_after_check ();
 29753 
 29754   if (rc)
 29755     return false;
 29756 
 29757   return true;
 29758 }
 29759 
 29760 #endif
 29761 
 29762 
 29763 /* Setting window manager hints.  */
 29764 
 29765 /* Set the normal size hints for the window manager, for frame F.
 29766    FLAGS is the flags word to use--or 0 meaning preserve the flags
 29767    that the window now has.
 29768    If USER_POSITION, set the USPosition
 29769    flag (this is useful when FLAGS is 0).
 29770    The GTK version is in gtkutils.c.  */
 29771 
 29772 void
 29773 x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
 29774 {
 29775 #ifndef USE_GTK
 29776   XSizeHints size_hints;
 29777   Window window = FRAME_OUTER_WINDOW (f);
 29778 #ifdef USE_X_TOOLKIT
 29779   WMShellWidget shell;
 29780 #ifndef USE_MOTIF
 29781   bool hints_changed;
 29782 #endif
 29783 #endif
 29784 
 29785   if (!window)
 29786     return;
 29787 
 29788 #ifdef USE_X_TOOLKIT
 29789   if (f->output_data.x->widget)
 29790     {
 29791       /* Do this dance in xterm.c because some stuff is not as easily
 29792          available in widget.c.  */
 29793 
 29794       eassert (XtIsWMShell (f->output_data.x->widget));
 29795       shell = (WMShellWidget) f->output_data.x->widget;
 29796 
 29797       if (flags)
 29798         {
 29799           shell->wm.size_hints.flags &= ~(PPosition | USPosition);
 29800           shell->wm.size_hints.flags |= flags & (PPosition | USPosition);
 29801         }
 29802 
 29803       if (user_position)
 29804         {
 29805           shell->wm.size_hints.flags &= ~PPosition;
 29806           shell->wm.size_hints.flags |= USPosition;
 29807         }
 29808 
 29809 #ifndef USE_MOTIF
 29810       hints_changed
 29811         = widget_update_wm_size_hints (f->output_data.x->widget,
 29812                                        f->output_data.x->edit_widget);
 29813 #else
 29814       widget_update_wm_size_hints (f->output_data.x->widget,
 29815                                    f->output_data.x->edit_widget);
 29816 
 29817       /* Do this all over again for the benefit of Motif, which always
 29818          knows better than the programmer.  */
 29819       shell->wm.size_hints.flags &= ~(PPosition | USPosition);
 29820       shell->wm.size_hints.flags |= flags & (PPosition | USPosition);
 29821 
 29822       if (user_position)
 29823         {
 29824           shell->wm.size_hints.flags &= ~PPosition;
 29825           shell->wm.size_hints.flags |= USPosition;
 29826         }
 29827 #endif
 29828 
 29829       /* Drill hints into Motif, since it keeps setting its own.  */
 29830       size_hints.flags = shell->wm.size_hints.flags;
 29831       size_hints.x = shell->wm.size_hints.x;
 29832       size_hints.y = shell->wm.size_hints.y;
 29833       size_hints.width = shell->wm.size_hints.width;
 29834       size_hints.height = shell->wm.size_hints.height;
 29835       size_hints.min_width = shell->wm.size_hints.min_width;
 29836       size_hints.min_height = shell->wm.size_hints.min_height;
 29837       size_hints.max_width = shell->wm.size_hints.max_width;
 29838       size_hints.max_height = shell->wm.size_hints.max_height;
 29839       size_hints.width_inc = shell->wm.size_hints.width_inc;
 29840       size_hints.height_inc = shell->wm.size_hints.height_inc;
 29841       size_hints.min_aspect.x = shell->wm.size_hints.min_aspect.x;
 29842       size_hints.min_aspect.y = shell->wm.size_hints.min_aspect.y;
 29843       size_hints.max_aspect.x = shell->wm.size_hints.max_aspect.x;
 29844       size_hints.max_aspect.y = shell->wm.size_hints.max_aspect.y;
 29845       size_hints.base_width = shell->wm.base_width;
 29846       size_hints.base_height = shell->wm.base_height;
 29847       size_hints.win_gravity = shell->wm.win_gravity;
 29848 
 29849 #ifdef USE_MOTIF
 29850       XSetWMNormalHints (XtDisplay (f->output_data.x->widget),
 29851                          XtWindow (f->output_data.x->widget),
 29852                          &size_hints);
 29853 #else
 29854       /* In many cases, widget_update_wm_size_hints will not have
 29855          updated the size hints if only flags changed.  When that
 29856          happens, set the WM hints manually.  */
 29857 
 29858       if (!hints_changed)
 29859         XSetWMNormalHints (XtDisplay (f->output_data.x->widget),
 29860                            XtWindow (f->output_data.x->widget),
 29861                            &size_hints);
 29862 #endif
 29863 
 29864       return;
 29865     }
 29866 #endif
 29867 
 29868   /* Setting PMaxSize caused various problems.  */
 29869   size_hints.flags = PResizeInc | PMinSize /* | PMaxSize */;
 29870 
 29871   size_hints.x = f->left_pos;
 29872   size_hints.y = f->top_pos;
 29873 
 29874   size_hints.width = FRAME_PIXEL_WIDTH (f);
 29875   size_hints.height = FRAME_PIXEL_HEIGHT (f);
 29876 
 29877   size_hints.width_inc = frame_resize_pixelwise ? 1 : FRAME_COLUMN_WIDTH (f);
 29878   size_hints.height_inc = frame_resize_pixelwise ? 1 : FRAME_LINE_HEIGHT (f);
 29879 
 29880   size_hints.max_width = x_display_pixel_width (FRAME_DISPLAY_INFO (f))
 29881     - FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
 29882   size_hints.max_height = x_display_pixel_height (FRAME_DISPLAY_INFO (f))
 29883     - FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0);
 29884 
 29885   /* Calculate the base and minimum sizes.  */
 29886   {
 29887     int base_width, base_height;
 29888 
 29889     base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
 29890     base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0);
 29891 
 29892     /* The window manager uses the base width hints to calculate the
 29893        current number of rows and columns in the frame while
 29894        resizing; min_width and min_height aren't useful for this
 29895        purpose, since they might not give the dimensions for a
 29896        zero-row, zero-column frame.  */
 29897 
 29898     size_hints.flags |= PBaseSize;
 29899     size_hints.base_width = base_width;
 29900     size_hints.base_height = base_height + FRAME_MENUBAR_HEIGHT (f);
 29901     size_hints.min_width  = base_width;
 29902     size_hints.min_height = base_height;
 29903   }
 29904 
 29905   /* If we don't need the old flags, we don't need the old hint at all.  */
 29906   if (flags)
 29907     {
 29908       size_hints.flags |= flags;
 29909       goto no_read;
 29910     }
 29911 
 29912   {
 29913     XSizeHints hints;           /* Sometimes I hate X Windows... */
 29914     long supplied_return;
 29915     int value;
 29916 
 29917     value = XGetWMNormalHints (FRAME_X_DISPLAY (f), window, &hints,
 29918                                &supplied_return);
 29919 
 29920     if (flags)
 29921       size_hints.flags |= flags;
 29922     else
 29923       {
 29924         if (value == 0)
 29925           hints.flags = 0;
 29926         if (hints.flags & PSize)
 29927           size_hints.flags |= PSize;
 29928         if (hints.flags & PPosition)
 29929           size_hints.flags |= PPosition;
 29930         if (hints.flags & USPosition)
 29931           size_hints.flags |= USPosition;
 29932         if (hints.flags & USSize)
 29933           size_hints.flags |= USSize;
 29934       }
 29935   }
 29936 
 29937  no_read:
 29938 
 29939 #ifdef PWinGravity
 29940   size_hints.win_gravity = f->win_gravity;
 29941   size_hints.flags |= PWinGravity;
 29942 
 29943   if (user_position)
 29944     {
 29945       size_hints.flags &= ~ PPosition;
 29946       size_hints.flags |= USPosition;
 29947     }
 29948 #endif /* PWinGravity */
 29949 
 29950   XSetWMNormalHints (FRAME_X_DISPLAY (f), window, &size_hints);
 29951 #else
 29952   xg_wm_set_size_hint (f, flags, user_position);
 29953 #endif /* USE_GTK */
 29954 }
 29955 
 29956 /* Used for IconicState or NormalState */
 29957 
 29958 static void
 29959 x_wm_set_window_state (struct frame *f, int state)
 29960 {
 29961 #ifdef USE_X_TOOLKIT
 29962   Arg al[1];
 29963 
 29964   XtSetArg (al[0], XtNinitialState, state);
 29965   XtSetValues (f->output_data.x->widget, al, 1);
 29966 #else /* not USE_X_TOOLKIT */
 29967   Window window = FRAME_X_WINDOW (f);
 29968 
 29969   f->output_data.x->wm_hints.flags |= StateHint;
 29970   f->output_data.x->wm_hints.initial_state = state;
 29971 
 29972   XSetWMHints (FRAME_X_DISPLAY (f), window, &f->output_data.x->wm_hints);
 29973 #endif /* not USE_X_TOOLKIT */
 29974 }
 29975 
 29976 static void
 29977 x_wm_set_icon_pixmap (struct frame *f, ptrdiff_t pixmap_id)
 29978 {
 29979   Pixmap icon_pixmap, icon_mask;
 29980 
 29981 #if !defined USE_X_TOOLKIT && !defined USE_GTK
 29982   Window window = FRAME_OUTER_WINDOW (f);
 29983 #endif
 29984 
 29985   if (pixmap_id > 0)
 29986     {
 29987       icon_pixmap = image_bitmap_pixmap (f, pixmap_id);
 29988       f->output_data.x->wm_hints.icon_pixmap = icon_pixmap;
 29989       icon_mask = x_bitmap_mask (f, pixmap_id);
 29990       f->output_data.x->wm_hints.icon_mask = icon_mask;
 29991     }
 29992   else
 29993     {
 29994       /* It seems there is no way to turn off use of an icon
 29995          pixmap.  */
 29996       return;
 29997     }
 29998 
 29999 
 30000 #ifdef USE_GTK
 30001   {
 30002     xg_set_frame_icon (f, icon_pixmap, icon_mask);
 30003     return;
 30004   }
 30005 
 30006 #elif defined (USE_X_TOOLKIT) /* same as in x_wm_set_window_state.  */
 30007 
 30008   {
 30009     Arg al[1];
 30010     XtSetArg (al[0], XtNiconPixmap, icon_pixmap);
 30011     XtSetValues (f->output_data.x->widget, al, 1);
 30012     XtSetArg (al[0], XtNiconMask, icon_mask);
 30013     XtSetValues (f->output_data.x->widget, al, 1);
 30014   }
 30015 
 30016 #else /* not USE_X_TOOLKIT && not USE_GTK */
 30017 
 30018   f->output_data.x->wm_hints.flags |= (IconPixmapHint | IconMaskHint);
 30019   XSetWMHints (FRAME_X_DISPLAY (f), window, &f->output_data.x->wm_hints);
 30020 
 30021 #endif /* not USE_X_TOOLKIT && not USE_GTK */
 30022 }
 30023 
 30024 void
 30025 x_wm_set_icon_position (struct frame *f, int icon_x, int icon_y)
 30026 {
 30027   Window window = FRAME_OUTER_WINDOW (f);
 30028 
 30029   f->output_data.x->wm_hints.flags |= IconPositionHint;
 30030   f->output_data.x->wm_hints.icon_x = icon_x;
 30031   f->output_data.x->wm_hints.icon_y = icon_y;
 30032 
 30033   XSetWMHints (FRAME_X_DISPLAY (f), window, &f->output_data.x->wm_hints);
 30034 }
 30035 
 30036 
 30037 /***********************************************************************
 30038                                 Fonts
 30039  ***********************************************************************/
 30040 
 30041 #ifdef GLYPH_DEBUG
 30042 
 30043 /* Check that FONT is valid on frame F.  It is if it can be found in F's
 30044    font table.  */
 30045 
 30046 static void
 30047 x_check_font (struct frame *f, struct font *font)
 30048 {
 30049   eassert (font != NULL && ! NILP (font->props[FONT_TYPE_INDEX]));
 30050   if (font->driver->check)
 30051     eassert (font->driver->check (f, font) == 0);
 30052 }
 30053 
 30054 #endif /* GLYPH_DEBUG */
 30055 
 30056 
 30057 /***********************************************************************
 30058                              Image Hooks
 30059  ***********************************************************************/
 30060 
 30061 static void
 30062 x_free_pixmap (struct frame *f, Emacs_Pixmap pixmap)
 30063 {
 30064 #ifdef USE_CAIRO
 30065   if (pixmap)
 30066     {
 30067       xfree (pixmap->data);
 30068       xfree (pixmap);
 30069     }
 30070 #else
 30071   XFreePixmap (FRAME_X_DISPLAY (f), pixmap);
 30072 #endif
 30073 }
 30074 
 30075 
 30076 /***********************************************************************
 30077                             Initialization
 30078  ***********************************************************************/
 30079 
 30080 #ifdef USE_X_TOOLKIT
 30081 static XrmOptionDescRec emacs_options[] = {
 30082   {(char *) "-geometry", (char *) ".geometry", XrmoptionSepArg, NULL},
 30083   {(char *) "-iconic", (char *) ".iconic", XrmoptionNoArg, (XtPointer) "yes"},
 30084 
 30085   {(char *) "-internal-border-width",
 30086    (char *) "*EmacsScreen.internalBorderWidth", XrmoptionSepArg, NULL},
 30087   {(char *) "-ib", (char *) "*EmacsScreen.internalBorderWidth",
 30088    XrmoptionSepArg, NULL},
 30089   {(char *) "-T", (char *) "*EmacsShell.title", XrmoptionSepArg, NULL},
 30090   {(char *) "-wn", (char *) "*EmacsShell.title", XrmoptionSepArg, NULL},
 30091   {(char *) "-title", (char *) "*EmacsShell.title", XrmoptionSepArg, NULL},
 30092   {(char *) "-iconname", (char *) "*EmacsShell.iconName",
 30093    XrmoptionSepArg, NULL},
 30094   {(char *) "-in", (char *) "*EmacsShell.iconName", XrmoptionSepArg, NULL},
 30095   {(char *) "-mc", (char *) "*pointerColor", XrmoptionSepArg, NULL},
 30096   {(char *) "-cr", (char *) "*cursorColor", XrmoptionSepArg, NULL}
 30097 };
 30098 
 30099 /* Whether atimer for Xt timeouts is activated or not.  */
 30100 
 30101 static bool x_timeout_atimer_activated_flag;
 30102 
 30103 #endif /* USE_X_TOOLKIT */
 30104 
 30105 static int x_initialized;
 30106 
 30107 /* Test whether two display-name strings agree up to the dot that separates
 30108    the screen number from the server number.  */
 30109 static bool
 30110 same_x_server (const char *name1, const char *name2)
 30111 {
 30112   bool seen_colon = false;
 30113   Lisp_Object sysname = Fsystem_name ();
 30114   if (! STRINGP (sysname))
 30115     sysname = empty_unibyte_string;
 30116   const char *system_name = SSDATA (sysname);
 30117   ptrdiff_t system_name_length = SBYTES (sysname);
 30118   ptrdiff_t length_until_period = 0;
 30119 
 30120   while (system_name[length_until_period] != 0
 30121          && system_name[length_until_period] != '.')
 30122     length_until_period++;
 30123 
 30124   /* Treat `unix' like an empty host name.  */
 30125   if (! strncmp (name1, "unix:", 5))
 30126     name1 += 4;
 30127   if (! strncmp (name2, "unix:", 5))
 30128     name2 += 4;
 30129   /* Treat this host's name like an empty host name.  */
 30130   if (! strncmp (name1, system_name, system_name_length)
 30131       && name1[system_name_length] == ':')
 30132     name1 += system_name_length;
 30133   if (! strncmp (name2, system_name, system_name_length)
 30134       && name2[system_name_length] == ':')
 30135     name2 += system_name_length;
 30136   /* Treat this host's domainless name like an empty host name.  */
 30137   if (! strncmp (name1, system_name, length_until_period)
 30138       && name1[length_until_period] == ':')
 30139     name1 += length_until_period;
 30140   if (! strncmp (name2, system_name, length_until_period)
 30141       && name2[length_until_period] == ':')
 30142     name2 += length_until_period;
 30143 
 30144   for (; *name1 != '\0' && *name1 == *name2; name1++, name2++)
 30145     {
 30146       if (*name1 == ':')
 30147         seen_colon = true;
 30148       if (seen_colon && *name1 == '.')
 30149         return true;
 30150     }
 30151   return (seen_colon
 30152           && (*name1 == '.' || *name1 == '\0')
 30153           && (*name2 == '.' || *name2 == '\0'));
 30154 }
 30155 
 30156 /* Count number of set bits in mask and number of bits to shift to
 30157    get to the first bit.  With MASK 0x7e0, *BITS is set to 6, and *OFFSET
 30158    to 5.  */
 30159 static void
 30160 get_bits_and_offset (unsigned long mask, int *bits, int *offset)
 30161 {
 30162   int nr = 0;
 30163   int off = 0;
 30164 
 30165   while (!(mask & 1))
 30166     {
 30167       off++;
 30168       mask >>= 1;
 30169     }
 30170 
 30171   while (mask & 1)
 30172     {
 30173       nr++;
 30174       mask >>= 1;
 30175     }
 30176 
 30177   *offset = off;
 30178   *bits = nr;
 30179 }
 30180 
 30181 /* Return true iff display DISPLAY is available for use.
 30182    But don't permanently open it, just test its availability.  */
 30183 
 30184 bool
 30185 x_display_ok (const char *display)
 30186 {
 30187   /* XOpenDisplay fails if it gets a signal.  Block SIGIO which may arrive.  */
 30188   unrequest_sigio ();
 30189   Display *dpy = XOpenDisplay (display);
 30190   request_sigio ();
 30191   if (!dpy)
 30192     return false;
 30193   XCloseDisplay (dpy);
 30194   return true;
 30195 }
 30196 
 30197 #ifdef USE_GTK
 30198 static void
 30199 my_log_handler (const gchar *log_domain, GLogLevelFlags log_level,
 30200                 const gchar *msg, gpointer user_data)
 30201 {
 30202   if (!strstr (msg, "g_set_prgname"))
 30203       fprintf (stderr, "%s-WARNING **: %s\n", log_domain, msg);
 30204 }
 30205 #endif
 30206 
 30207 /* Current X display connection identifier.  Incremented for each next
 30208    connection established.  */
 30209 static unsigned x_display_id;
 30210 
 30211 #if defined HAVE_XINPUT2 && !defined HAVE_GTK3
 30212 
 30213 /* Select for device change events on the root window of DPYINFO.
 30214    These include device change and hierarchy change notifications.  */
 30215 
 30216 static void
 30217 xi_select_hierarchy_events (struct x_display_info *dpyinfo)
 30218 {
 30219   XIEventMask mask;
 30220   ptrdiff_t l;
 30221   unsigned char *m;
 30222 
 30223   l = XIMaskLen (XI_LASTEVENT);
 30224   mask.mask = m = alloca (l);
 30225   memset (m, 0, l);
 30226   mask.mask_len = l;
 30227 
 30228   mask.deviceid = XIAllDevices;
 30229 
 30230   XISetMask (m, XI_PropertyEvent);
 30231   XISetMask (m, XI_HierarchyChanged);
 30232   XISetMask (m, XI_DeviceChanged);
 30233 
 30234   XISelectEvents (dpyinfo->display, dpyinfo->root_window,
 30235                   &mask, 1);
 30236 }
 30237 
 30238 #endif
 30239 
 30240 #if defined HAVE_XINPUT2 && defined HAVE_GTK3
 30241 
 30242 /* Look up whether or not GTK already initialized the X input
 30243    extension.
 30244 
 30245    Value is 0 if GTK was not built with the input extension, or if it
 30246    was explicitly disabled, 1 if GTK enabled the input extension and
 30247    the version was successfully determined, and 2 if that information
 30248    could not be determined.  */
 30249 
 30250 static int
 30251 xi_check_toolkit (Display *display)
 30252 {
 30253   GdkDisplay *gdpy;
 30254   GdkDeviceManager *manager;
 30255 
 30256   gdpy = gdk_x11_lookup_xdisplay (display);
 30257   eassume (gdpy);
 30258   manager = gdk_display_get_device_manager (gdpy);
 30259 
 30260   if (!strcmp (G_OBJECT_TYPE_NAME (manager),
 30261                "GdkX11DeviceManagerXI2"))
 30262     return 1;
 30263 
 30264   if (!strcmp (G_OBJECT_TYPE_NAME (manager),
 30265                "GdkX11DeviceManagerCore"))
 30266     return 0;
 30267 
 30268   /* Something changed in GDK so this information is no longer
 30269      available.  */
 30270 
 30271   return 2;
 30272 }
 30273 
 30274 #endif
 30275 
 30276 /* Open a connection to X display DISPLAY_NAME, and return the
 30277    structure that describes the open display.  If obtaining the XCB
 30278    connection or toolkit-specific display fails, return NULL.  Signal
 30279    an error if opening the display itself failed.  */
 30280 
 30281 struct x_display_info *
 30282 x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
 30283 {
 30284   Display *dpy;
 30285   XKeyboardState keyboard_state;
 30286   struct terminal *terminal;
 30287   struct x_display_info *dpyinfo;
 30288   XrmDatabase xrdb;
 30289   Lisp_Object tem, quit_keysym;
 30290 #ifdef USE_XCB
 30291   xcb_connection_t *xcb_conn;
 30292 #endif
 30293   static char const cm_atom_fmt[] = "_NET_WM_CM_S%d";
 30294   char cm_atom_sprintf[sizeof cm_atom_fmt - 2 + INT_STRLEN_BOUND (int)];
 30295 #ifdef USE_GTK
 30296   GdkDisplay *gdpy;
 30297   GdkScreen *gscr;
 30298 #endif
 30299 #ifdef HAVE_XFIXES
 30300   Lisp_Object lisp_name;
 30301   int num_fast_selections;
 30302   Atom selection_name;
 30303 #ifdef USE_XCB
 30304   xcb_get_selection_owner_cookie_t *selection_cookies;
 30305   xcb_get_selection_owner_reply_t *selection_reply;
 30306   xcb_generic_error_t *selection_error;
 30307 #endif
 30308 #endif
 30309   int i;
 30310 
 30311 #if defined HAVE_XFIXES && defined USE_XCB
 30312   USE_SAFE_ALLOCA;
 30313 #endif
 30314 
 30315   block_input ();
 30316 
 30317   if (!x_initialized)
 30318     {
 30319       x_initialize ();
 30320       ++x_initialized;
 30321     }
 30322 
 30323 #if defined USE_X_TOOLKIT || defined USE_GTK
 30324 
 30325   if (!x_display_ok (SSDATA (display_name)))
 30326     error ("Display %s can't be opened", SSDATA (display_name));
 30327 
 30328 #endif
 30329 
 30330 #ifdef USE_GTK
 30331   {
 30332 #define NUM_ARGV 10
 30333     int argc;
 30334     char *argv[NUM_ARGV];
 30335     char **argv2 = argv;
 30336     guint id;
 30337 
 30338     if (x_initialized++ > 1)
 30339       {
 30340         xg_display_open (SSDATA (display_name), &dpy);
 30341       }
 30342     else
 30343       {
 30344         static char display_opt[] = "--display";
 30345         static char name_opt[] = "--name";
 30346 
 30347         for (argc = 0; argc < NUM_ARGV; ++argc)
 30348           argv[argc] = 0;
 30349 
 30350         argc = 0;
 30351         argv[argc++] = initial_argv[0];
 30352 
 30353         if (! NILP (display_name))
 30354           {
 30355             argv[argc++] = display_opt;
 30356             argv[argc++] = SSDATA (display_name);
 30357           }
 30358 
 30359         argv[argc++] = name_opt;
 30360         argv[argc++] = resource_name;
 30361 
 30362         XSetLocaleModifiers ("");
 30363 
 30364         /* Work around GLib bug that outputs a faulty warning. See
 30365            https://bugzilla.gnome.org/show_bug.cgi?id=563627.  */
 30366         id = g_log_set_handler ("GLib", G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL
 30367                                   | G_LOG_FLAG_RECURSION, my_log_handler, NULL);
 30368 
 30369         /* NULL window -> events for all windows go to our function.
 30370            Call before gtk_init so Gtk+ event filters comes after our.  */
 30371         gdk_window_add_filter (NULL, event_handler_gdk, NULL);
 30372 
 30373         /* gtk_init does set_locale.  Fix locale before and after.  */
 30374         fixup_locale ();
 30375         unrequest_sigio (); /* See comment in x_display_ok.  */
 30376         gtk_init (&argc, &argv2);
 30377         request_sigio ();
 30378 
 30379         g_log_remove_handler ("GLib", id);
 30380 
 30381         xg_initialize ();
 30382 
 30383         /* Do this after the call to xg_initialize, because when
 30384            Fontconfig is used, xg_initialize calls its initialization
 30385            function which in some versions of Fontconfig calls setlocale.  */
 30386         fixup_locale ();
 30387 
 30388         dpy = DEFAULT_GDK_DISPLAY ();
 30389 
 30390 #ifndef HAVE_GTK3
 30391         /* Load our own gtkrc if it exists.  */
 30392         {
 30393           const char *file = "~/.emacs.d/gtkrc";
 30394           Lisp_Object s, abs_file;
 30395 
 30396           s = build_string (file);
 30397           abs_file = Fexpand_file_name (s, Qnil);
 30398 
 30399           if (! NILP (abs_file) && !NILP (Ffile_readable_p (abs_file)))
 30400             gtk_rc_parse (SSDATA (abs_file));
 30401         }
 30402 #endif
 30403 
 30404         XSetErrorHandler (x_error_handler);
 30405         XSetIOErrorHandler (x_io_error_quitter);
 30406       }
 30407   }
 30408 #else /* not USE_GTK */
 30409 #ifdef USE_X_TOOLKIT
 30410   /* weiner@footloose.sps.mot.com reports that this causes
 30411      errors with X11R5:
 30412            X protocol error: BadAtom (invalid Atom parameter)
 30413            on protocol request 18skiloaf.
 30414      So let's not use it until R6.  */
 30415 #ifdef HAVE_X11XTR6
 30416   XtSetLanguageProc (NULL, NULL, NULL);
 30417 #endif
 30418 
 30419   {
 30420     int argc = 0;
 30421     char *argv[3];
 30422 
 30423     argv[0] = (char *) "";
 30424     argc = 1;
 30425     if (xrm_option)
 30426       {
 30427         argv[argc++] = (char *) "-xrm";
 30428         argv[argc++] = xrm_option;
 30429       }
 30430     turn_on_atimers (false);
 30431     unrequest_sigio ();  /* See comment in x_display_ok.  */
 30432     dpy = XtOpenDisplay (Xt_app_con, SSDATA (display_name),
 30433                          resource_name, EMACS_CLASS,
 30434                          emacs_options, XtNumber (emacs_options),
 30435                          &argc, argv);
 30436     request_sigio ();
 30437     turn_on_atimers (true);
 30438 
 30439 #ifdef HAVE_X11XTR6
 30440     /* I think this is to compensate for XtSetLanguageProc.  */
 30441     fixup_locale ();
 30442 #endif
 30443   }
 30444 
 30445 #else /* not USE_X_TOOLKIT */
 30446   XSetLocaleModifiers ("");
 30447   unrequest_sigio ();  /* See comment in x_display_ok.  */
 30448   dpy = XOpenDisplay (SSDATA (display_name));
 30449   request_sigio ();
 30450 #endif /* not USE_X_TOOLKIT */
 30451 #endif /* not USE_GTK*/
 30452 
 30453   /* Detect failure.  */
 30454   if (dpy == 0)
 30455     {
 30456 #if !defined USE_X_TOOLKIT && !defined USE_GTK
 30457       /* Avoid opening a display three times (once in dispextern.c
 30458          upon startup, once in x_display_ok, and once above) to
 30459          determine whether or not the display is alive on no toolkit
 30460          builds, where no toolkit initialization happens at all.  */
 30461 
 30462       error ("Display %s can't be opened", SSDATA (display_name));
 30463 #endif
 30464 
 30465       unblock_input ();
 30466 
 30467 #if defined HAVE_XFIXES && defined USE_XCB
 30468       SAFE_FREE ();
 30469 #endif
 30470       return 0;
 30471     }
 30472 
 30473 #ifdef USE_XCB
 30474   xcb_conn = XGetXCBConnection (dpy);
 30475   if (!xcb_conn)
 30476     {
 30477 #ifdef USE_GTK
 30478       xg_display_close (dpy);
 30479 #else
 30480 #ifdef USE_X_TOOLKIT
 30481       XtCloseDisplay (dpy);
 30482 #else
 30483       XCloseDisplay (dpy);
 30484 #endif
 30485 #endif /* ! USE_GTK */
 30486 
 30487       unblock_input ();
 30488 
 30489 #if defined HAVE_XFIXES && defined USE_XCB
 30490       SAFE_FREE ();
 30491 #endif
 30492       return 0;
 30493     }
 30494 #endif
 30495 
 30496   /* Select for structure events on the root window, since this allows
 30497      us to record changes to the size of the screen.  */
 30498 
 30499   XSelectInput (dpy, DefaultRootWindow (dpy), StructureNotifyMask);
 30500 
 30501   /* We have definitely succeeded.  Record the new connection.  */
 30502 
 30503   dpyinfo = xzalloc (sizeof *dpyinfo);
 30504   terminal = x_create_terminal (dpyinfo);
 30505 
 30506   if (!NILP (Vx_detect_server_trust))
 30507     {
 30508       /* Detect whether or not the X server trusts this client, which
 30509          is done by making a SetKeyboardControl request and checking
 30510          for an Access error.  */
 30511       XGrabServer (dpy);
 30512       XGetKeyboardControl (dpy, &keyboard_state);
 30513 
 30514       x_catch_errors (dpy);
 30515 
 30516       /* At this point, the display is not on x_display_list, so
 30517          x_uncatch_errors won't sync.  However, that's okay because
 30518          x_had_errors_p will.  */
 30519 
 30520       if (keyboard_state.global_auto_repeat
 30521           == AutoRepeatModeOn)
 30522         XAutoRepeatOn (dpy);
 30523       else
 30524         XAutoRepeatOff (dpy);
 30525 
 30526       if (x_had_errors_p (dpy))
 30527         dpyinfo->untrusted = true;
 30528       x_uncatch_errors_after_check ();
 30529       XUngrabServer (dpy);
 30530     }
 30531 
 30532   dpyinfo->next_failable_request = dpyinfo->failable_requests;
 30533 
 30534   {
 30535     struct x_display_info *share;
 30536 
 30537     for (share = x_display_list; share; share = share->next)
 30538       if (same_x_server (SSDATA (XCAR (share->name_list_element)),
 30539                          SSDATA (display_name)))
 30540         break;
 30541     if (share)
 30542       terminal->kboard = share->terminal->kboard;
 30543     else
 30544       {
 30545         terminal->kboard = allocate_kboard (Qx);
 30546 
 30547         if (!BASE_EQ (XSYMBOL (Qvendor_specific_keysyms)->u.s.function,
 30548                       Qunbound))
 30549           {
 30550             char *vendor = ServerVendor (dpy);
 30551 
 30552             /* Temporarily hide the partially initialized terminal.
 30553                Use safe_call so that if a signal happens, a partially
 30554                initialized display (and display connection) is not
 30555                kept around.  */
 30556             terminal_list = terminal->next_terminal;
 30557             unblock_input ();
 30558             kset_system_key_alist (terminal->kboard,
 30559                                    safe_call1 (Qvendor_specific_keysyms,
 30560                                                (vendor
 30561                                                 ? build_string (vendor)
 30562                                                 : empty_unibyte_string)));
 30563             block_input ();
 30564             terminal->next_terminal = terminal_list;
 30565             terminal_list = terminal;
 30566           }
 30567 
 30568         /* Don't let the initial kboard remain current longer than necessary.
 30569            That would cause problems if a file loaded on startup tries to
 30570            prompt in the mini-buffer.  */
 30571         if (current_kboard == initial_kboard)
 30572           current_kboard = terminal->kboard;
 30573       }
 30574     terminal->kboard->reference_count++;
 30575   }
 30576 
 30577   /* Now look through Vx_quit_keysym for the quit keysym associated
 30578      with this display.  */
 30579   tem = Vx_quit_keysym;
 30580   FOR_EACH_TAIL_SAFE (tem)
 30581     {
 30582       quit_keysym = XCAR (tem);
 30583 
 30584       /* Check if its car is a string and its cdr a valid keysym.
 30585          Skip if it is not.  */
 30586 
 30587       if (!CONSP (quit_keysym) || !FIXNUMP (XCDR (quit_keysym))
 30588           || !STRINGP (XCAR (quit_keysym)))
 30589         continue;
 30590 
 30591       /* Check if this is the keysym to be used.  */
 30592 
 30593       if (strcmp (SSDATA (XCAR (quit_keysym)), ServerVendor (dpy)))
 30594         continue;
 30595 
 30596       dpyinfo->quit_keysym = XFIXNUM (XCDR (quit_keysym));
 30597     }
 30598 
 30599   /* Put this display on the chain.  */
 30600   dpyinfo->next = x_display_list;
 30601   x_display_list = dpyinfo;
 30602 
 30603   dpyinfo->name_list_element = Fcons (display_name, Qnil);
 30604   dpyinfo->display = dpy;
 30605   dpyinfo->connection = ConnectionNumber (dpyinfo->display);
 30606 #ifdef USE_XCB
 30607   dpyinfo->xcb_connection = xcb_conn;
 30608 #endif
 30609 
 30610   /* https://lists.gnu.org/r/emacs-devel/2015-11/msg00194.html  */
 30611   dpyinfo->smallest_font_height = 1;
 30612   dpyinfo->smallest_char_width = 1;
 30613 
 30614   dpyinfo->color_names_size = 256;
 30615   dpyinfo->color_names = xzalloc (dpyinfo->color_names_size
 30616                                   * sizeof *dpyinfo->color_names);
 30617   dpyinfo->color_names_length = xzalloc (dpyinfo->color_names_size
 30618                                          * sizeof *dpyinfo->color_names_length);
 30619 
 30620   /* Set the name of the terminal. */
 30621   terminal->name = xlispstrdup (display_name);
 30622 
 30623 #if false
 30624   XSetAfterFunction (dpyinfo->display, x_trace_wire);
 30625 #endif
 30626 
 30627   Lisp_Object system_name = Fsystem_name ();
 30628   static char const title[] = "GNU Emacs";
 30629   if (STRINGP (system_name))
 30630     {
 30631       static char const at[] = " at ";
 30632       ptrdiff_t nbytes = sizeof (title) + sizeof (at);
 30633       if (ckd_add (&nbytes, nbytes, SBYTES (system_name)))
 30634         memory_full (SIZE_MAX);
 30635       dpyinfo->x_id_name = xmalloc (nbytes);
 30636       sprintf (dpyinfo->x_id_name, "%s%s%s", title, at, SDATA (system_name));
 30637     }
 30638   else
 30639     {
 30640       dpyinfo->x_id_name = xmalloc (sizeof (title));
 30641       strcpy (dpyinfo->x_id_name, title);
 30642     }
 30643 
 30644   dpyinfo->x_id = ++x_display_id;
 30645 
 30646 #ifndef HAVE_XKB
 30647   /* Figure out which modifier bits mean what.  */
 30648   x_find_modifier_meanings (dpyinfo);
 30649 #endif
 30650 
 30651   /* Get the scroll bar cursor.  */
 30652 #ifdef USE_GTK
 30653   /* We must create a GTK cursor, it is required for GTK widgets.  */
 30654   dpyinfo->xg_cursor = xg_create_default_cursor (dpyinfo->display);
 30655 #endif /* USE_GTK */
 30656 
 30657   dpyinfo->vertical_scroll_bar_cursor
 30658     = XCreateFontCursor (dpyinfo->display, XC_sb_v_double_arrow);
 30659 
 30660   dpyinfo->horizontal_scroll_bar_cursor
 30661     = XCreateFontCursor (dpyinfo->display, XC_sb_h_double_arrow);
 30662 
 30663   xrdb = x_load_resources (dpyinfo->display, xrm_option,
 30664                            resource_name, EMACS_CLASS);
 30665 #ifdef HAVE_XRMSETDATABASE
 30666   XrmSetDatabase (dpyinfo->display, xrdb);
 30667 #else
 30668   dpyinfo->display->db = xrdb;
 30669 #endif
 30670 
 30671 #ifdef HAVE_XRENDER
 30672   int event_base, error_base;
 30673   dpyinfo->xrender_supported_p
 30674     = XRenderQueryExtension (dpyinfo->display, &event_base, &error_base);
 30675 
 30676   if (dpyinfo->xrender_supported_p)
 30677     dpyinfo->xrender_supported_p
 30678       = XRenderQueryVersion (dpyinfo->display, &dpyinfo->xrender_major,
 30679                              &dpyinfo->xrender_minor);
 30680 #endif
 30681 
 30682   /* This must come after XRenderQueryVersion! */
 30683 #ifdef HAVE_XCOMPOSITE
 30684   int composite_event_base, composite_error_base;
 30685   dpyinfo->composite_supported_p = XCompositeQueryExtension (dpyinfo->display,
 30686                                                              &composite_event_base,
 30687                                                              &composite_error_base);
 30688 
 30689   if (dpyinfo->composite_supported_p)
 30690     dpyinfo->composite_supported_p
 30691       = XCompositeQueryVersion (dpyinfo->display,
 30692                                 &dpyinfo->composite_major,
 30693                                 &dpyinfo->composite_minor);
 30694 #endif
 30695 
 30696 #ifdef HAVE_XSHAPE
 30697   dpyinfo->xshape_supported_p
 30698     = XShapeQueryExtension (dpyinfo->display,
 30699                             &dpyinfo->xshape_event_base,
 30700                             &dpyinfo->xshape_error_base);
 30701 
 30702   if (dpyinfo->xshape_supported_p)
 30703     dpyinfo->xshape_supported_p
 30704       = XShapeQueryVersion (dpyinfo->display,
 30705                             &dpyinfo->xshape_major,
 30706                             &dpyinfo->xshape_minor);
 30707 #endif
 30708 
 30709   /* Put the rdb where we can find it in a way that works on
 30710      all versions.  */
 30711   dpyinfo->rdb = xrdb;
 30712 
 30713   dpyinfo->screen = ScreenOfDisplay (dpyinfo->display,
 30714                                      DefaultScreen (dpyinfo->display));
 30715   select_visual (dpyinfo);
 30716   dpyinfo->cmap = DefaultColormapOfScreen (dpyinfo->screen);
 30717   dpyinfo->root_window = RootWindowOfScreen (dpyinfo->screen);
 30718   dpyinfo->icon_bitmap_id = -1;
 30719   dpyinfo->wm_type = X_WMTYPE_UNKNOWN;
 30720 
 30721   reset_mouse_highlight (&dpyinfo->mouse_highlight);
 30722 
 30723 #ifdef HAVE_XRENDER
 30724   if (dpyinfo->xrender_supported_p
 30725       /* This could already have been initialized by
 30726          `select_visual'.  */
 30727       && !dpyinfo->pict_format)
 30728     dpyinfo->pict_format = XRenderFindVisualFormat (dpyinfo->display,
 30729                                                     dpyinfo->visual);
 30730 #endif
 30731 
 30732 #ifdef HAVE_XSYNC
 30733   int xsync_event_base, xsync_error_base;
 30734   dpyinfo->xsync_supported_p
 30735     = XSyncQueryExtension (dpyinfo->display,
 30736                            &xsync_event_base,
 30737                            &xsync_error_base);
 30738 
 30739   if (dpyinfo->xsync_supported_p)
 30740     dpyinfo->xsync_supported_p = XSyncInitialize (dpyinfo->display,
 30741                                                   &dpyinfo->xsync_major,
 30742                                                   &dpyinfo->xsync_minor);
 30743 
 30744   {
 30745     AUTO_STRING (synchronizeResize, "synchronizeResize");
 30746     AUTO_STRING (SynchronizeResize, "SynchronizeResize");
 30747 
 30748     Lisp_Object value = gui_display_get_resource (dpyinfo,
 30749                                                   synchronizeResize,
 30750                                                   SynchronizeResize,
 30751                                                   Qnil, Qnil);
 30752 
 30753     if (STRINGP (value)
 30754         && (!strcmp (SSDATA (value), "false")
 30755             || !strcmp (SSDATA (value), "off")))
 30756       dpyinfo->xsync_supported_p = false;
 30757   }
 30758 #endif
 30759 
 30760 #ifdef HAVE_XINERAMA
 30761   int xin_event_base, xin_error_base;
 30762   dpyinfo->xinerama_supported_p
 30763     = XineramaQueryExtension (dpy, &xin_event_base, &xin_error_base);
 30764 #endif
 30765 
 30766   /* See if a private colormap is requested.  */
 30767   if (dpyinfo->visual == DefaultVisualOfScreen (dpyinfo->screen))
 30768     {
 30769       if (dpyinfo->visual_info.class == PseudoColor)
 30770         {
 30771           AUTO_STRING (privateColormap, "privateColormap");
 30772           AUTO_STRING (PrivateColormap, "PrivateColormap");
 30773           Lisp_Object value
 30774             = gui_display_get_resource (dpyinfo, privateColormap,
 30775                                         PrivateColormap, Qnil, Qnil);
 30776           if (STRINGP (value)
 30777               && (!strcmp (SSDATA (value), "true")
 30778                   || !strcmp (SSDATA (value), "on")))
 30779             dpyinfo->cmap = XCopyColormapAndFree (dpyinfo->display, dpyinfo->cmap);
 30780         }
 30781     }
 30782   else
 30783     dpyinfo->cmap = XCreateColormap (dpyinfo->display, dpyinfo->root_window,
 30784                                      dpyinfo->visual, AllocNone);
 30785 
 30786   /* See if we can construct pixel values from RGB values.  */
 30787   if (dpyinfo->visual_info.class == TrueColor)
 30788     {
 30789       get_bits_and_offset (dpyinfo->visual_info.red_mask,
 30790                            &dpyinfo->red_bits, &dpyinfo->red_offset);
 30791       get_bits_and_offset (dpyinfo->visual_info.blue_mask,
 30792                            &dpyinfo->blue_bits, &dpyinfo->blue_offset);
 30793       get_bits_and_offset (dpyinfo->visual_info.green_mask,
 30794                            &dpyinfo->green_bits, &dpyinfo->green_offset);
 30795 
 30796 #ifdef HAVE_XRENDER
 30797       if (dpyinfo->pict_format)
 30798         {
 30799           unsigned long channel_mask
 30800             = ((unsigned long) dpyinfo->pict_format->direct.alphaMask
 30801                << dpyinfo->pict_format->direct.alpha);
 30802 
 30803           if (channel_mask)
 30804             get_bits_and_offset (channel_mask, &dpyinfo->alpha_bits,
 30805                                  &dpyinfo->alpha_offset);
 30806           dpyinfo->alpha_mask = channel_mask;
 30807         }
 30808       else
 30809 #endif
 30810         {
 30811           XColor xc;
 30812           unsigned long alpha_mask;
 30813           xc.red = 65535;
 30814           xc.green = 65535;
 30815           xc.blue = 65535;
 30816 
 30817           if (XAllocColor (dpyinfo->display,
 30818                            dpyinfo->cmap, &xc) != 0)
 30819             {
 30820               alpha_mask = xc.pixel & ~(dpyinfo->visual_info.red_mask
 30821                                         | dpyinfo->visual_info.blue_mask
 30822                                         | dpyinfo->visual_info.green_mask);
 30823 
 30824               if (alpha_mask)
 30825                 get_bits_and_offset (alpha_mask, &dpyinfo->alpha_bits,
 30826                                      &dpyinfo->alpha_offset);
 30827               dpyinfo->alpha_mask = alpha_mask;
 30828             }
 30829         }
 30830     }
 30831 
 30832 #ifdef HAVE_XDBE
 30833   dpyinfo->supports_xdbe = false;
 30834   int xdbe_major;
 30835   int xdbe_minor;
 30836   if (XdbeQueryExtension (dpyinfo->display, &xdbe_major, &xdbe_minor))
 30837     dpyinfo->supports_xdbe = true;
 30838 #endif
 30839 
 30840 #ifdef USE_XCB
 30841   xcb_screen_t *xcb_screen = NULL;
 30842   xcb_screen_iterator_t iter;
 30843   xcb_visualid_t wanted = { XVisualIDFromVisual (dpyinfo->visual) };
 30844   xcb_depth_iterator_t depth_iter;
 30845   xcb_visualtype_iterator_t visual_iter;
 30846 
 30847   int screen = DefaultScreen (dpyinfo->display);
 30848 
 30849   iter = xcb_setup_roots_iterator (xcb_get_setup (dpyinfo->xcb_connection));
 30850   for (; iter.rem; --screen, xcb_screen_next (&iter))
 30851     {
 30852       if (!screen)
 30853         xcb_screen = iter.data;
 30854     }
 30855 
 30856   if (xcb_screen)
 30857     {
 30858       depth_iter = xcb_screen_allowed_depths_iterator (xcb_screen);
 30859       for (; depth_iter.rem; xcb_depth_next (&depth_iter))
 30860         {
 30861           visual_iter = xcb_depth_visuals_iterator (depth_iter.data);
 30862           for (; visual_iter.rem; xcb_visualtype_next (&visual_iter))
 30863             {
 30864               if (wanted == visual_iter.data->visual_id)
 30865                 {
 30866                   dpyinfo->xcb_visual = visual_iter.data;
 30867                   break;
 30868                 }
 30869             }
 30870         }
 30871     }
 30872 #endif
 30873 
 30874 #ifdef HAVE_XINPUT2
 30875   dpyinfo->supports_xi2 = false;
 30876   int rc;
 30877   int major = 2;
 30878   int xi_first_event, xi_first_error;
 30879 
 30880 #ifndef HAVE_GTK3
 30881   {
 30882     AUTO_STRING (disableInputExtension, "disableInputExtension");
 30883     AUTO_STRING (DisableInputExtension, "DisableInputExtension");
 30884 
 30885     Lisp_Object value = gui_display_get_resource (dpyinfo,
 30886                                                   disableInputExtension,
 30887                                                   DisableInputExtension,
 30888                                                   Qnil, Qnil);
 30889 
 30890     if (STRINGP (value)
 30891         && (!strcmp (SSDATA (value), "on")
 30892             || !strcmp (SSDATA (value), "true")))
 30893       goto skip_xi_setup;
 30894   }
 30895 #endif
 30896 
 30897 #ifdef HAVE_XINPUT2_4
 30898   int minor = 4;
 30899 #elif defined HAVE_XINPUT2_3 /* XInput 2.3 */
 30900   int minor = 3;
 30901 #elif defined HAVE_XINPUT2_2 /* XInput 2.2 */
 30902   int minor = 2;
 30903 #elif defined HAVE_XINPUT2_1 /* XInput 2.1 */
 30904   int minor = 1;
 30905 #else /* Some old version of XI2 we're not interested in. */
 30906   int minor = 0;
 30907 #endif
 30908 
 30909   dpyinfo->client_pointer_device = -1;
 30910 
 30911 #ifdef HAVE_GTK3
 30912   /* GTK gets a chance to request use of the input extension first.
 30913      If we later try to enable it if GDK did not, then GTK will not
 30914      get the resulting extension events.  */
 30915 
 30916   rc = xi_check_toolkit (dpyinfo->display);
 30917 
 30918   if (!rc)
 30919     goto skip_xi_setup;
 30920 #endif
 30921 
 30922   if (XQueryExtension (dpyinfo->display, "XInputExtension",
 30923                        &dpyinfo->xi2_opcode, &xi_first_event,
 30924                        &xi_first_error))
 30925     {
 30926 #ifdef HAVE_GTK3
 30927       bool move_backwards = false;
 30928       int original_minor = minor;
 30929 
 30930     query:
 30931 
 30932       /* Catch errors caused by GTK requesting a different version of
 30933          XInput 2 than what Emacs was built with.  Usually, the X
 30934          server tolerates these mistakes, but a BadValue error can
 30935          result if only one of GTK or Emacs wasn't built with support
 30936          for XInput 2.2.
 30937 
 30938          To work around the first, it suffices to increase the minor
 30939          version until the X server is happy if the XIQueryVersion
 30940          request results in an error.  If that doesn't work, however,
 30941          then it's the latter, so decrease the minor until the version
 30942          that GTK requested is found.  */
 30943 #endif
 30944 
 30945       x_catch_errors (dpyinfo->display);
 30946 
 30947       rc = XIQueryVersion (dpyinfo->display, &major, &minor);
 30948 
 30949 #ifdef HAVE_GTK3
 30950       /* Increase the minor version until we find one the X
 30951          server agrees with.  If that didn't work, then
 30952          decrease the version until it either hits zero or
 30953          becomes agreeable to the X server.  */
 30954 
 30955       if (x_had_errors_p (dpyinfo->display))
 30956         {
 30957           x_uncatch_errors_after_check ();
 30958 
 30959           /* Since BadValue errors can't be generated if both the
 30960              prior and current requests specify a version of 2.2 or
 30961              later, this means the prior request specified a version
 30962              of the input extension less than 2.2.  */
 30963           if (minor >= 2)
 30964             {
 30965               move_backwards = true;
 30966               minor = original_minor;
 30967 
 30968               if (--minor < 0)
 30969                 rc = BadRequest;
 30970               else
 30971                 goto query;
 30972             }
 30973           else
 30974             {
 30975               if (!move_backwards)
 30976                 {
 30977                   minor++;
 30978                   goto query;
 30979                 }
 30980 
 30981               if (--minor < 0)
 30982                 rc = BadRequest;
 30983               else
 30984                 goto query;
 30985 
 30986             }
 30987         }
 30988       else
 30989         x_uncatch_errors_after_check ();
 30990 
 30991       /* But don't delude ourselves into thinking that we can use
 30992          features provided by a version of the input extension that
 30993          libXi itself doesn't support.  */
 30994 
 30995       if (minor > original_minor)
 30996         minor = original_minor;
 30997 #else
 30998       if (x_had_errors_p (dpyinfo->display))
 30999         rc = BadRequest;
 31000 
 31001       x_uncatch_errors_after_check ();
 31002 #endif
 31003 
 31004       if (rc == Success)
 31005         {
 31006           dpyinfo->supports_xi2 = true;
 31007 #ifndef HAVE_GTK3
 31008           /* Select for hierarchy events on the root window.  GTK 3.x
 31009              does this itself.  */
 31010           xi_select_hierarchy_events (dpyinfo);
 31011 #endif
 31012 
 31013           dpyinfo->xi2_version = minor;
 31014           x_cache_xi_devices (dpyinfo);
 31015         }
 31016     }
 31017  skip_xi_setup:
 31018   ;
 31019 #endif
 31020 
 31021 #if defined HAVE_XRANDR || defined USE_GTK
 31022   Lisp_Object term;
 31023 
 31024   XSETTERMINAL (term, terminal);
 31025 #endif
 31026 
 31027 #ifdef HAVE_XRANDR
 31028   dpyinfo->xrandr_supported_p
 31029     = XRRQueryExtension (dpy, &dpyinfo->xrandr_event_base,
 31030                          &dpyinfo->xrandr_error_base);
 31031 
 31032 #ifndef USE_GTK
 31033   dpyinfo->last_monitor_attributes_list = Qnil;
 31034 #endif
 31035 
 31036   if (dpyinfo->xrandr_supported_p)
 31037     {
 31038       XRRQueryVersion (dpy, &dpyinfo->xrandr_major_version,
 31039                        &dpyinfo->xrandr_minor_version);
 31040 
 31041 #ifndef USE_GTK
 31042       if (dpyinfo->xrandr_major_version == 1
 31043           && dpyinfo->xrandr_minor_version >= 2)
 31044         {
 31045           XRRSelectInput (dpyinfo->display,
 31046                           dpyinfo->root_window,
 31047                           (RRScreenChangeNotifyMask
 31048                            | RRCrtcChangeNotifyMask
 31049                            | RROutputChangeNotifyMask
 31050 #ifdef USE_GTK
 31051                            /* Emacs doesn't actually need this, but
 31052                               GTK selects for it when the display is
 31053                               initialized.  */
 31054                            | RROutputPropertyNotifyMask
 31055 #endif
 31056                            ));
 31057 
 31058           dpyinfo->last_monitor_attributes_list
 31059             = Fx_display_monitor_attributes_list (term);
 31060         }
 31061 #endif
 31062     }
 31063 #endif
 31064 
 31065 #ifdef USE_GTK
 31066   dpyinfo->last_monitor_attributes_list
 31067     = Fx_display_monitor_attributes_list (term);
 31068 
 31069   gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display);
 31070   gscr = gdk_display_get_default_screen (gdpy);
 31071 
 31072   g_signal_connect (G_OBJECT (gscr), "monitors-changed",
 31073                     G_CALLBACK (x_monitors_changed_cb),
 31074                     NULL);
 31075 #endif
 31076 
 31077 #ifdef HAVE_XKB
 31078   int xkb_major, xkb_minor, xkb_op, xkb_error_code;
 31079   xkb_major = XkbMajorVersion;
 31080   xkb_minor = XkbMinorVersion;
 31081 
 31082   if (XkbLibraryVersion (&xkb_major, &xkb_minor)
 31083       && XkbQueryExtension (dpyinfo->display, &xkb_op, &dpyinfo->xkb_event_type,
 31084                             &xkb_error_code, &xkb_major, &xkb_minor))
 31085     {
 31086       dpyinfo->supports_xkb = true;
 31087       dpyinfo->xkb_desc = XkbGetMap (dpyinfo->display,
 31088                                      (XkbKeySymsMask
 31089                                       | XkbKeyTypesMask
 31090                                       | XkbModifierMapMask
 31091                                       | XkbVirtualModsMask),
 31092                                      XkbUseCoreKbd);
 31093 
 31094       if (dpyinfo->xkb_desc)
 31095         XkbGetNames (dpyinfo->display, XkbAllNamesMask,
 31096                      dpyinfo->xkb_desc);
 31097 
 31098       XkbSelectEvents (dpyinfo->display, XkbUseCoreKbd,
 31099                        XkbNewKeyboardNotifyMask | XkbMapNotifyMask,
 31100                        XkbNewKeyboardNotifyMask | XkbMapNotifyMask);
 31101     }
 31102 
 31103   /* XFree86 extends XKBlib with a new Xlib control `ControlFallback',
 31104      which enables a search for symbols designating ASCII characters
 31105      within inactive groups during keycode translation when
 31106      ControlMask is set.  Users find this behavior gratuitous, so
 31107      disable it if present.  */
 31108 
 31109 #ifdef XkbLC_ControlFallback
 31110   XkbSetXlibControls (dpyinfo->display, XkbLC_ControlFallback, 0);
 31111 #endif /* XkbLC_ControlFallback */
 31112 #endif /* HAVE_XKB */
 31113 
 31114 #ifdef HAVE_XFIXES
 31115   int xfixes_error_base;
 31116   dpyinfo->xfixes_supported_p
 31117     = XFixesQueryExtension (dpyinfo->display,
 31118                             &dpyinfo->xfixes_event_base,
 31119                             &xfixes_error_base);
 31120 
 31121   if (dpyinfo->xfixes_supported_p)
 31122     {
 31123       if (!XFixesQueryVersion (dpyinfo->display, &dpyinfo->xfixes_major,
 31124                                &dpyinfo->xfixes_minor))
 31125         dpyinfo->xfixes_supported_p = false;
 31126     }
 31127 #endif
 31128 
 31129 #if defined USE_CAIRO || defined HAVE_XFT
 31130   {
 31131     /* If we are using Xft, the following precautions should be made:
 31132 
 31133        1. Make sure that the Xrender extension is added before the Xft one.
 31134        Otherwise, the close-display hook set by Xft is called after the one
 31135        for Xrender, and the former tries to re-add the latter.  This results
 31136        in inconsistency of internal states and leads to X protocol error when
 31137        one reconnects to the same X server (Bug#1696).
 31138 
 31139        2. Check dpi value in X resources.  It is better we use it as well,
 31140        since Xft will use it, as will all Gnome applications.  If our real DPI
 31141        is smaller or larger than the one Xft uses, our font will look smaller
 31142        or larger than other for other applications, even if it is the same
 31143        font name (monospace-10 for example).  */
 31144 
 31145     char *v = XGetDefault (dpyinfo->display, "Xft", "dpi");
 31146     double d;
 31147     if (v != NULL && sscanf (v, "%lf", &d) == 1)
 31148       dpyinfo->resy = dpyinfo->resx = d;
 31149   }
 31150 #endif
 31151 
 31152   if (dpyinfo->resy < 1)
 31153     {
 31154       int screen_number = XScreenNumberOfScreen (dpyinfo->screen);
 31155       double pixels = DisplayHeight (dpyinfo->display, screen_number);
 31156       double mm = DisplayHeightMM (dpyinfo->display, screen_number);
 31157       /* Mac OS X 10.3's Xserver sometimes reports 0.0mm.  */
 31158       dpyinfo->resy = (mm < 1) ? 100 : pixels * 25.4 / mm;
 31159       pixels = DisplayWidth (dpyinfo->display, screen_number);
 31160       mm = DisplayWidthMM (dpyinfo->display, screen_number);
 31161       /* Mac OS X 10.3's Xserver sometimes reports 0.0mm.  */
 31162       dpyinfo->resx = (mm < 1) ? 100 : pixels * 25.4 / mm;
 31163     }
 31164 
 31165   sprintf (cm_atom_sprintf, cm_atom_fmt,
 31166            XScreenNumberOfScreen (dpyinfo->screen));
 31167 
 31168   {
 31169     enum { atom_count = ARRAYELTS (x_atom_refs) };
 31170     /* 1 for _XSETTINGS_SN.  */
 31171     enum { total_atom_count = 2 + atom_count };
 31172     Atom atoms_return[total_atom_count];
 31173     char *atom_names[total_atom_count];
 31174     static char const xsettings_fmt[] = "_XSETTINGS_S%d";
 31175     char xsettings_atom_name[sizeof xsettings_fmt - 2
 31176                              + INT_STRLEN_BOUND (int)];
 31177 
 31178     for (i = 0; i < atom_count; i++)
 31179       atom_names[i] = (char *) x_atom_refs[i].name;
 31180 
 31181     /* Build _XSETTINGS_SN atom name.  */
 31182     sprintf (xsettings_atom_name, xsettings_fmt,
 31183              XScreenNumberOfScreen (dpyinfo->screen));
 31184     atom_names[i] = xsettings_atom_name;
 31185     atom_names[i + 1] = cm_atom_sprintf;
 31186 
 31187     XInternAtoms (dpyinfo->display, atom_names, total_atom_count,
 31188                   False, atoms_return);
 31189 
 31190     for (i = 0; i < atom_count; i++)
 31191       *(Atom *) ((char *) dpyinfo + x_atom_refs[i].offset) = atoms_return[i];
 31192 
 31193     /* Manually copy last two atoms.  */
 31194     dpyinfo->Xatom_xsettings_sel = atoms_return[i];
 31195     dpyinfo->Xatom_NET_WM_CM_Sn = atoms_return[i + 1];
 31196   }
 31197 
 31198 #ifdef HAVE_XKB
 31199   /* Figure out which modifier bits mean what.  */
 31200   x_find_modifier_meanings (dpyinfo);
 31201 #endif
 31202 
 31203   dpyinfo->x_dnd_atoms_size = 16;
 31204   dpyinfo->x_dnd_atoms = xmalloc (sizeof *dpyinfo->x_dnd_atoms
 31205                                   * dpyinfo->x_dnd_atoms_size);
 31206   dpyinfo->gray
 31207     = XCreatePixmapFromBitmapData (dpyinfo->display, dpyinfo->root_window,
 31208                                    gray_bits, gray_width, gray_height,
 31209                                    1, 0, 1);
 31210 
 31211   dpyinfo->invisible_cursor = make_invisible_cursor (dpyinfo);
 31212 #if defined HAVE_XFIXES && XFIXES_VERSION >= 40000
 31213   dpyinfo->fixes_pointer_blanking = (egetenv ("EMACS_XFIXES") != NULL);
 31214 #endif
 31215 
 31216   xsettings_initialize (dpyinfo);
 31217 
 31218   /* This is only needed for distinguishing keyboard and process input.  */
 31219   if (dpyinfo->connection != 0)
 31220     add_keyboard_wait_descriptor (dpyinfo->connection);
 31221 
 31222 #ifdef F_SETOWN
 31223   fcntl (dpyinfo->connection, F_SETOWN, getpid ());
 31224 #endif /* ! defined (F_SETOWN) */
 31225 
 31226   if (interrupt_input)
 31227     init_sigio (dpyinfo->connection);
 31228 
 31229 #ifdef USE_LUCID
 31230   {
 31231     XrmValue d, fr, to;
 31232     Font font;
 31233     XFontStruct *query_result;
 31234 
 31235     dpy = dpyinfo->display;
 31236     d.addr = (XPointer) &dpy;
 31237     d.size = sizeof (Display *);
 31238     fr.addr = (char *) XtDefaultFont;
 31239     fr.size = sizeof (XtDefaultFont);
 31240     to.size = sizeof (Font *);
 31241     to.addr = (XPointer) &font;
 31242     x_catch_errors (dpy);
 31243     if (!XtCallConverter (dpy, XtCvtStringToFont, &d, 1, &fr, &to, NULL))
 31244       emacs_abort ();
 31245     query_result = XQueryFont (dpy, font);
 31246 
 31247     /* Set the dialog font to some fallback (here, 9x15) if the font
 31248        specified is invalid.  */
 31249     if (x_had_errors_p (dpy) || !font)
 31250       XrmPutLineResource (&xrdb, "Emacs.dialog.*.font: 9x15");
 31251 
 31252     /* Do not destroy the font struct returned above with XFreeFont;
 31253        that also destroys the font, leading to X protocol errors at
 31254        XtCloseDisplay.  Just free the font info structure.
 31255        (Bug#18403) */
 31256     XFreeFontInfo (NULL, query_result, 1);
 31257     x_uncatch_errors ();
 31258   }
 31259 #endif
 31260 
 31261   /* See if we should run in synchronous mode.  This is useful
 31262      for debugging X code.  */
 31263   {
 31264     AUTO_STRING (synchronous, "synchronous");
 31265     AUTO_STRING (Synchronous, "Synchronous");
 31266     Lisp_Object value = gui_display_get_resource (dpyinfo, synchronous,
 31267                                                   Synchronous, Qnil, Qnil);
 31268     if (STRINGP (value)
 31269         && (!strcmp (SSDATA (value), "true")
 31270             || !strcmp (SSDATA (value), "on")))
 31271       XSynchronize (dpyinfo->display, True);
 31272   }
 31273 
 31274 #ifdef HAVE_X_I18N
 31275   {
 31276     AUTO_STRING (useXIM, "useXIM");
 31277     AUTO_STRING (UseXIM, "UseXIM");
 31278     Lisp_Object value = gui_display_get_resource (dpyinfo, useXIM, UseXIM,
 31279                                                   Qnil, Qnil);
 31280 
 31281     /* `USE_XIM' controls whether Emacs should use X input methods by
 31282        default, not whether or not XIM is available.  */
 31283 
 31284 #ifdef USE_XIM
 31285     dpyinfo->use_xim = true;
 31286 
 31287     if (STRINGP (value)
 31288         && (!strcmp (SSDATA (value), "false")
 31289             || !strcmp (SSDATA (value), "off")))
 31290       dpyinfo->use_xim = false;
 31291 #else /* !USE_XIM */
 31292     dpyinfo->use_xim = false;
 31293 
 31294     if (STRINGP (value)
 31295         && (!strcmp (SSDATA (value), "true")
 31296             || !strcmp (SSDATA (value), "on")))
 31297       dpyinfo->use_xim = true;
 31298 #endif /* USE_XIM */
 31299   }
 31300 
 31301   {
 31302     AUTO_STRING (inputStyle, "inputStyle");
 31303     AUTO_STRING (InputStyle, "InputStyle");
 31304     Lisp_Object value = gui_display_get_resource (dpyinfo, inputStyle, InputStyle,
 31305                                                   Qnil, Qnil);
 31306 
 31307     if (STRINGP (value))
 31308       {
 31309         if (!strcmp (SSDATA (value), "callback"))
 31310           dpyinfo->preferred_xim_style = STYLE_CALLBACK;
 31311         else if (!strcmp (SSDATA (value), "none"))
 31312           dpyinfo->preferred_xim_style = STYLE_NONE;
 31313         else if (!strcmp (SSDATA (value), "overthespot"))
 31314           dpyinfo->preferred_xim_style = STYLE_OVERTHESPOT;
 31315         else if (!strcmp (SSDATA (value), "offthespot"))
 31316           dpyinfo->preferred_xim_style = STYLE_OFFTHESPOT;
 31317         else if (!strcmp (SSDATA (value), "root"))
 31318           dpyinfo->preferred_xim_style = STYLE_ROOT;
 31319 #ifdef USE_GTK
 31320         else if (!strcmp (SSDATA (value), "native"))
 31321           dpyinfo->prefer_native_input = true;
 31322 #endif /* HAVE_GTK */
 31323       }
 31324   }
 31325 
 31326   /* Now that defaults have been set up, initialize input method
 31327      support.  */
 31328 
 31329   /* Avoid initializing input methods if the X library does not
 31330      support Emacs's locale.  When the current locale is not
 31331      supported, decoding input method strings becomes undefined.  */
 31332   if (XSupportsLocale ())
 31333     xim_initialize (dpyinfo, resource_name);
 31334 #endif /* HAVE_X_I18N */
 31335 
 31336 #ifdef HAVE_X_SM
 31337   /* Only do this for the very first display in the Emacs session.
 31338      Ignore X session management when Emacs was first started on a
 31339      tty or started as a daemon.  */
 31340   if (!dpyinfo->next && ! IS_DAEMON)
 31341     x_session_initialize (dpyinfo);
 31342 #endif
 31343 
 31344 #if defined USE_CAIRO || defined HAVE_XRENDER
 31345   x_extension_initialize (dpyinfo);
 31346 #endif
 31347 
 31348 #ifdef USE_TOOLKIT_SCROLL_BARS
 31349   dpyinfo->protected_windows = xmalloc (sizeof (Lisp_Object) * 256);
 31350   dpyinfo->n_protected_windows = 0;
 31351   dpyinfo->protected_windows_max = 256;
 31352 #endif
 31353 
 31354 #ifdef HAVE_XFIXES
 31355   /* Initialize selection tracking for the selections in
 31356      x-fast-selection-list.  */
 31357 
 31358   if (CONSP (Vx_fast_selection_list)
 31359       && dpyinfo->xfixes_supported_p
 31360       && dpyinfo->xfixes_major >= 1)
 31361     {
 31362       num_fast_selections = 0;
 31363       tem = Vx_fast_selection_list;
 31364 
 31365       FOR_EACH_TAIL_SAFE (tem)
 31366         {
 31367           if (!SYMBOLP (XCAR (tem)))
 31368             continue;
 31369 
 31370           num_fast_selections++;
 31371         }
 31372 
 31373       dpyinfo->n_monitored_selections = num_fast_selections;
 31374       dpyinfo->selection_tracking_window
 31375         = x_create_special_window (dpyinfo, dpyinfo->root_window);
 31376       dpyinfo->monitored_selections
 31377         = xmalloc (num_fast_selections
 31378                    * sizeof *dpyinfo->monitored_selections);
 31379 
 31380       num_fast_selections = 0;
 31381       tem = Vx_fast_selection_list;
 31382 
 31383       FOR_EACH_TAIL_SAFE (tem)
 31384         {
 31385           lisp_name = XCAR (tem);
 31386 
 31387           if (!SYMBOLP (lisp_name))
 31388             continue;
 31389 
 31390           selection_name = symbol_to_x_atom (dpyinfo, lisp_name);
 31391           dpyinfo->monitored_selections[num_fast_selections++].name
 31392             = selection_name;
 31393           dpyinfo->monitored_selections[num_fast_selections - 1].owner
 31394             = X_INVALID_WINDOW;
 31395 
 31396           /* Select for selection input.  */
 31397           XFixesSelectSelectionInput (dpyinfo->display,
 31398                                       dpyinfo->selection_tracking_window,
 31399                                       selection_name,
 31400                                       (XFixesSetSelectionOwnerNotifyMask
 31401                                        | XFixesSetSelectionOwnerNotifyMask
 31402                                        | XFixesSelectionClientCloseNotifyMask));
 31403         }
 31404 
 31405 #ifdef USE_XCB
 31406       selection_cookies = SAFE_ALLOCA (sizeof *selection_cookies
 31407                                        * num_fast_selections);
 31408 #endif
 31409 
 31410       /* Now, ask for the current owners of all those selections.  */
 31411       for (i = 0; i < num_fast_selections; ++i)
 31412         {
 31413 #ifdef USE_XCB
 31414           selection_cookies[i]
 31415             = xcb_get_selection_owner (dpyinfo->xcb_connection,
 31416                                        dpyinfo->monitored_selections[i].name);
 31417 #else
 31418           dpyinfo->monitored_selections[i].owner
 31419             = XGetSelectionOwner (dpyinfo->display,
 31420                                   dpyinfo->monitored_selections[i].name);
 31421 #endif
 31422         }
 31423 
 31424 #ifdef USE_XCB
 31425       for (i = 0; i < num_fast_selections; ++i)
 31426         {
 31427           selection_reply
 31428             = xcb_get_selection_owner_reply (dpyinfo->xcb_connection,
 31429                                              selection_cookies[i],
 31430                                              &selection_error);
 31431 
 31432           if (selection_reply)
 31433             {
 31434               dpyinfo->monitored_selections[i].owner
 31435                 = selection_reply->owner;
 31436               free (selection_reply);
 31437             }
 31438           else if (selection_error)
 31439             free (selection_error);
 31440         }
 31441 #endif
 31442     }
 31443 #endif
 31444 
 31445   unblock_input ();
 31446 
 31447 #if defined HAVE_XFIXES && defined USE_XCB
 31448   SAFE_FREE ();
 31449 #endif
 31450   return dpyinfo;
 31451 }
 31452 
 31453 
 31454 
 31455 /* Remove all the selection input events on the keyboard buffer
 31456    intended for DPYINFO.  */
 31457 
 31458 static void
 31459 x_delete_selection_requests (struct x_display_info *dpyinfo)
 31460 {
 31461   union buffered_input_event *event;
 31462   int moved_events;
 31463 
 31464   for (event = kbd_fetch_ptr; event != kbd_store_ptr;
 31465        event = X_NEXT_KBD_EVENT (event))
 31466     {
 31467       if (event->kind == SELECTION_REQUEST_EVENT
 31468           || event->kind == SELECTION_CLEAR_EVENT)
 31469         {
 31470           if (SELECTION_EVENT_DPYINFO (&event->sie) != dpyinfo)
 31471             continue;
 31472 
 31473           /* Remove the event from the fifo buffer before processing;
 31474              otherwise swallow_events called recursively could see it
 31475              and process it again.  To do this, we move the events
 31476              between kbd_fetch_ptr and EVENT one slot to the right,
 31477              cyclically.  */
 31478 
 31479           if (event < kbd_fetch_ptr)
 31480             {
 31481               memmove (kbd_buffer + 1, kbd_buffer,
 31482                        (event - kbd_buffer) * sizeof *kbd_buffer);
 31483               kbd_buffer[0] = kbd_buffer[KBD_BUFFER_SIZE - 1];
 31484               moved_events = kbd_buffer + KBD_BUFFER_SIZE - 1 - kbd_fetch_ptr;
 31485             }
 31486           else
 31487             moved_events = event - kbd_fetch_ptr;
 31488 
 31489           memmove (kbd_fetch_ptr + 1, kbd_fetch_ptr,
 31490                    moved_events * sizeof *kbd_fetch_ptr);
 31491           kbd_fetch_ptr = X_NEXT_KBD_EVENT (kbd_fetch_ptr);
 31492 
 31493           /* `detect_input_pending' will then recompute whether or not
 31494              pending input events exist.  */
 31495           input_pending = false;
 31496         }
 31497     }
 31498 }
 31499 
 31500 /* Get rid of display DPYINFO, deleting all frames on it,
 31501    and without sending any more commands to the X server.  */
 31502 
 31503 static void
 31504 x_delete_display (struct x_display_info *dpyinfo)
 31505 {
 31506   struct terminal *t;
 31507   struct color_name_cache_entry *color_entry, *next_color_entry;
 31508   int i;
 31509   struct x_selection_request_event *ie, *last, *temp;
 31510 
 31511   /* Close all frames and delete the generic struct terminal for this
 31512      X display.  */
 31513   for (t = terminal_list; t; t = t->next_terminal)
 31514     if (t->type == output_x_window && t->display_info.x == dpyinfo)
 31515       {
 31516 #ifdef HAVE_X_SM
 31517         /* Close X session management when we close its display.  */
 31518         if (t->id == 1 && x_session_have_connection ())
 31519           x_session_close ();
 31520 #endif
 31521         delete_terminal (t);
 31522         break;
 31523       }
 31524 
 31525   /* Find any pending selection requests for this display and unchain
 31526      them.  */
 31527 
 31528   last = NULL;
 31529 
 31530   for (ie = pending_selection_requests; ie; ie = ie->next)
 31531     {
 31532     again:
 31533 
 31534       if (SELECTION_EVENT_DPYINFO (&ie->se) == dpyinfo)
 31535         {
 31536           if (last)
 31537             last->next = ie->next;
 31538 
 31539           temp = ie;
 31540           ie = ie->next;
 31541           xfree (temp);
 31542 
 31543           goto again;
 31544         }
 31545 
 31546       last = ie;
 31547     }
 31548 
 31549   /* Delete selection requests bound for dpyinfo from the keyboard
 31550      buffer.  */
 31551   x_delete_selection_requests (dpyinfo);
 31552 
 31553   /* And remove any outstanding selection transfers.  */
 31554   x_remove_selection_transfers (dpyinfo);
 31555 
 31556   if (next_noop_dpyinfo == dpyinfo)
 31557     next_noop_dpyinfo = dpyinfo->next;
 31558 
 31559   if (mouse_click_timeout_display == dpyinfo)
 31560     mouse_click_timeout_display = NULL;
 31561 
 31562   if (x_display_list == dpyinfo)
 31563     x_display_list = dpyinfo->next;
 31564   else
 31565     {
 31566       struct x_display_info *tail;
 31567 
 31568       for (tail = x_display_list; tail; tail = tail->next)
 31569         if (tail->next == dpyinfo)
 31570           tail->next = tail->next->next;
 31571     }
 31572 
 31573   for (i = 0; i < dpyinfo->color_names_size; ++i)
 31574     {
 31575       for (color_entry = dpyinfo->color_names[i];
 31576            color_entry; color_entry = next_color_entry)
 31577         {
 31578           next_color_entry = color_entry->next;
 31579 
 31580           xfree (color_entry->name);
 31581           xfree (color_entry);
 31582         }
 31583     }
 31584 
 31585   if (dpyinfo->net_supported_atoms)
 31586     XFree (dpyinfo->net_supported_atoms);
 31587 
 31588   xfree (dpyinfo->color_names);
 31589   xfree (dpyinfo->color_names_length);
 31590   xfree (dpyinfo->x_id_name);
 31591   xfree (dpyinfo->x_dnd_atoms);
 31592   xfree (dpyinfo->color_cells);
 31593 #ifdef HAVE_XFIXES
 31594   if (dpyinfo->monitored_selections)
 31595     xfree (dpyinfo->monitored_selections);
 31596 #endif
 31597 #ifdef USE_TOOLKIT_SCROLL_BARS
 31598   xfree (dpyinfo->protected_windows);
 31599 #endif
 31600 #ifdef HAVE_XINPUT2
 31601   if (dpyinfo->supports_xi2)
 31602     x_free_xi_devices (dpyinfo);
 31603 #endif
 31604   xfree (dpyinfo);
 31605 }
 31606 
 31607 #ifdef USE_X_TOOLKIT
 31608 
 31609 /* Atimer callback function for TIMER.  Called every 0.1s to process
 31610    Xt timeouts, if needed.  We must avoid calling XtAppPending as
 31611    much as possible because that function does an implicit XFlush
 31612    that slows us down.  */
 31613 
 31614 static void
 31615 x_process_timeouts (struct atimer *timer)
 31616 {
 31617   block_input ();
 31618   x_timeout_atimer_activated_flag = false;
 31619   if (toolkit_scroll_bar_interaction || popup_activated ())
 31620     {
 31621       while (XtAppPending (Xt_app_con) & XtIMTimer)
 31622         XtAppProcessEvent (Xt_app_con, XtIMTimer);
 31623       /* Reactivate the atimer for next time.  */
 31624       x_activate_timeout_atimer ();
 31625     }
 31626   unblock_input ();
 31627 }
 31628 
 31629 /* Install an asynchronous timer that processes Xt timeout events
 31630    every 0.1s as long as either `toolkit_scroll_bar_interaction' or
 31631    `popup_activated_flag' (in xmenu.c) is set.  Make sure to call this
 31632    function whenever these variables are set.  This is necessary
 31633    because some widget sets use timeouts internally, for example the
 31634    LessTif menu bar, or the Xaw3d scroll bar.  When Xt timeouts aren't
 31635    processed, these widgets don't behave normally.  */
 31636 
 31637 void
 31638 x_activate_timeout_atimer (void)
 31639 {
 31640   block_input ();
 31641   if (!x_timeout_atimer_activated_flag)
 31642     {
 31643       struct timespec interval = make_timespec (0, 100 * 1000 * 1000);
 31644       start_atimer (ATIMER_RELATIVE, interval, x_process_timeouts, 0);
 31645       x_timeout_atimer_activated_flag = true;
 31646     }
 31647   unblock_input ();
 31648 }
 31649 
 31650 #endif /* USE_X_TOOLKIT */
 31651 
 31652 
 31653 /* Set up use of X before we make the first connection.  */
 31654 
 31655 extern frame_parm_handler x_frame_parm_handlers[];
 31656 
 31657 static struct redisplay_interface x_redisplay_interface =
 31658   {
 31659     x_frame_parm_handlers,
 31660     gui_produce_glyphs,
 31661     gui_write_glyphs,
 31662     gui_insert_glyphs,
 31663     gui_clear_end_of_line,
 31664     x_scroll_run,
 31665     x_after_update_window_line,
 31666     NULL, /* update_window_begin */
 31667     NULL, /* update_window_end   */
 31668     x_flip_and_flush,
 31669     gui_clear_window_mouse_face,
 31670     gui_get_glyph_overhangs,
 31671     gui_fix_overlapping_area,
 31672     x_draw_fringe_bitmap,
 31673 #ifdef USE_CAIRO
 31674     x_cr_define_fringe_bitmap,
 31675     x_cr_destroy_fringe_bitmap,
 31676 #else
 31677     0, /* define_fringe_bitmap */
 31678     0, /* destroy_fringe_bitmap */
 31679 #endif
 31680     x_compute_glyph_string_overhangs,
 31681     x_draw_glyph_string,
 31682     x_define_frame_cursor,
 31683     x_clear_frame_area,
 31684     x_clear_under_internal_border,
 31685     x_draw_window_cursor,
 31686     x_draw_vertical_window_border,
 31687     x_draw_window_divider,
 31688     x_shift_glyphs_for_insert, /* Never called; see comment in function.  */
 31689     x_show_hourglass,
 31690     x_hide_hourglass,
 31691     x_default_font_parameter
 31692   };
 31693 
 31694 
 31695 /* This function is called when the last frame on a display is deleted. */
 31696 void
 31697 x_delete_terminal (struct terminal *terminal)
 31698 {
 31699   struct x_display_info *dpyinfo;
 31700   struct frame *f;
 31701   Lisp_Object tail, frame;
 31702 
 31703   dpyinfo = terminal->display_info.x;
 31704 
 31705   /* Protect against recursive calls.  delete_frame in
 31706      delete_terminal calls us back when it deletes our last frame.  */
 31707   if (!terminal->name)
 31708     return;
 31709 
 31710   block_input ();
 31711 
 31712   /* Delete all remaining frames on the display that is going away.
 31713      Otherwise, font backends assume the display is still up, and
 31714      xftfont_end_for_frame crashes.  */
 31715   FOR_EACH_FRAME (tail, frame)
 31716     {
 31717       f = XFRAME (frame);
 31718 
 31719       if (FRAME_LIVE_P (f) && f->terminal == terminal)
 31720         /* Pass Qnoelisp rather than Qt.  */
 31721         delete_frame (frame, Qnoelisp);
 31722     }
 31723 
 31724 #ifdef HAVE_X_I18N
 31725   /* We must close our connection to the XIM server before closing the
 31726      X display.  */
 31727   xim_close_dpy (dpyinfo);
 31728 #endif
 31729 
 31730   /* Destroy all bitmap images created on the display.  */
 31731   image_destroy_all_bitmaps (dpyinfo);
 31732 
 31733   /* Free the storage allocated to hold bitmap records.  */
 31734   xfree (dpyinfo->bitmaps);
 31735 
 31736   /* In case someone decides to use `bitmaps' again... */
 31737   dpyinfo->bitmaps = NULL;
 31738   dpyinfo->bitmaps_last = 0;
 31739 
 31740   /* Normally, the display is available...  */
 31741   if (dpyinfo->display)
 31742     {
 31743       XSetCloseDownMode (dpyinfo->display, DestroyAll);
 31744 
 31745       /* Delete the scratch cursor GC, should it exist.  */
 31746       if (dpyinfo->scratch_cursor_gc)
 31747         XFreeGC (dpyinfo->display, dpyinfo->scratch_cursor_gc);
 31748 
 31749       /* Get rid of any drag-and-drop operation that might be in
 31750          progress as well.  */
 31751       if ((x_dnd_in_progress || x_dnd_waiting_for_finish)
 31752           && dpyinfo->display == (x_dnd_waiting_for_finish
 31753                                   ? x_dnd_finish_display
 31754                                   : FRAME_X_DISPLAY (x_dnd_frame)))
 31755         {
 31756           x_dnd_last_seen_window = None;
 31757           x_dnd_last_seen_toplevel = None;
 31758           x_dnd_in_progress = false;
 31759           x_dnd_waiting_for_finish = false;
 31760 
 31761           /* The display is going away, so there's no point in
 31762              de-selecting for input on the DND toplevels.  */
 31763           if (x_dnd_use_toplevels)
 31764             x_dnd_free_toplevels (false);
 31765 
 31766           x_dnd_return_frame_object = NULL;
 31767           x_dnd_movement_frame = NULL;
 31768           x_dnd_wheel_frame = NULL;
 31769           x_dnd_frame = NULL;
 31770         }
 31771 
 31772       /* Whether or not XCloseDisplay destroys the associated resource
 31773          database depends on the version of libX11.  To avoid both
 31774          crash and memory leak, we dissociate the database from the
 31775          display and then destroy dpyinfo->rdb ourselves.
 31776 
 31777          Unfortunately, the above strategy does not work in some
 31778          situations due to a bug in newer versions of libX11: because
 31779          XrmSetDatabase doesn't clear the flag XlibDisplayDfltRMDB if
 31780          dpy->db is NULL, XCloseDisplay destroys the associated
 31781          database whereas it has not been created by XGetDefault
 31782          (Bug#21974 in freedesktop.org Bugzilla).  As a workaround, we
 31783          don't destroy the database here in order to avoid the crash
 31784          in the above situations for now, though that may cause memory
 31785          leaks in other situations.  */
 31786 #if false
 31787 #ifdef HAVE_XRMSETDATABASE
 31788       XrmSetDatabase (dpyinfo->display, NULL);
 31789 #else
 31790       dpyinfo->display->db = NULL;
 31791 #endif
 31792       /* We used to call XrmDestroyDatabase from x_delete_display, but
 31793          some older versions of libX11 crash if we call it after
 31794          closing all the displays.  */
 31795       XrmDestroyDatabase (dpyinfo->rdb);
 31796 #endif
 31797 #ifdef USE_GTK
 31798       xg_display_close (dpyinfo->display);
 31799 #else
 31800 #ifdef USE_X_TOOLKIT
 31801       XtCloseDisplay (dpyinfo->display);
 31802 #else
 31803       XCloseDisplay (dpyinfo->display);
 31804 #endif
 31805 #endif /* ! USE_GTK */
 31806       /* Do not close the connection here because it's already closed
 31807          by X(t)CloseDisplay (Bug#18403).  */
 31808       dpyinfo->display = NULL;
 31809     }
 31810 
 31811   /* ...but if called from x_connection_closed, the display may already
 31812      be closed and dpyinfo->display was set to 0 to indicate that.  Since
 31813      X server is most likely gone, explicit close is the only reliable
 31814      way to continue and avoid Bug#19147.  */
 31815   else if (dpyinfo->connection >= 0)
 31816     emacs_close (dpyinfo->connection);
 31817 
 31818   /* Free the keyboard and modifier maps here; that is safe to do
 31819      without a display, and not doing so leads to a lot of data being
 31820      leaked upon IO error.  */
 31821 
 31822 #ifdef HAVE_XKB
 31823   if (dpyinfo->xkb_desc)
 31824     XkbFreeKeyboard (dpyinfo->xkb_desc, XkbAllComponentsMask, True);
 31825 #endif
 31826 
 31827   if (dpyinfo->modmap)
 31828     XFreeModifiermap (dpyinfo->modmap);
 31829 
 31830   /* No more input on this descriptor.  */
 31831   delete_keyboard_wait_descriptor (dpyinfo->connection);
 31832   /* Mark as dead. */
 31833   dpyinfo->connection = -1;
 31834 
 31835   x_delete_display (dpyinfo);
 31836   unblock_input ();
 31837 }
 31838 
 31839 #ifdef HAVE_XINPUT2
 31840 static bool
 31841 x_have_any_grab (struct x_display_info *dpyinfo)
 31842 {
 31843   int i;
 31844 
 31845   if (!dpyinfo->supports_xi2)
 31846     return false;
 31847 
 31848   for (i = 0; i < dpyinfo->num_devices; ++i)
 31849     {
 31850       if (dpyinfo->devices[i].grab)
 31851         return true;
 31852     }
 31853 
 31854   return false;
 31855 }
 31856 #endif
 31857 
 31858 /* Create a struct terminal, initialize it with the X11 specific
 31859    functions and make DISPLAY->TERMINAL point to it.  */
 31860 
 31861 static struct terminal *
 31862 x_create_terminal (struct x_display_info *dpyinfo)
 31863 {
 31864   struct terminal *terminal;
 31865 
 31866   terminal = create_terminal (output_x_window, &x_redisplay_interface);
 31867 
 31868   terminal->display_info.x = dpyinfo;
 31869   dpyinfo->terminal = terminal;
 31870 
 31871   /* kboard is initialized in x_term_init. */
 31872 
 31873   terminal->clear_frame_hook = x_clear_frame;
 31874   terminal->ins_del_lines_hook = x_ins_del_lines;
 31875   terminal->delete_glyphs_hook = x_delete_glyphs;
 31876   terminal->ring_bell_hook = XTring_bell;
 31877   terminal->toggle_invisible_pointer_hook = XTtoggle_invisible_pointer;
 31878   terminal->update_begin_hook = x_update_begin;
 31879   terminal->update_end_hook = x_update_end;
 31880   terminal->read_socket_hook = XTread_socket;
 31881   terminal->frame_up_to_date_hook = XTframe_up_to_date;
 31882 #ifdef HAVE_XDBE
 31883   terminal->buffer_flipping_unblocked_hook = XTbuffer_flipping_unblocked_hook;
 31884 #endif
 31885   terminal->defined_color_hook = x_defined_color;
 31886   terminal->query_frame_background_color = x_query_frame_background_color;
 31887   terminal->query_colors = x_query_colors;
 31888   terminal->mouse_position_hook = XTmouse_position;
 31889   terminal->get_focus_frame = x_get_focus_frame;
 31890   terminal->focus_frame_hook = x_focus_frame;
 31891   terminal->frame_rehighlight_hook = XTframe_rehighlight;
 31892   terminal->frame_raise_lower_hook = XTframe_raise_lower;
 31893   terminal->frame_visible_invisible_hook = x_make_frame_visible_invisible;
 31894   terminal->fullscreen_hook = XTfullscreen_hook;
 31895   terminal->iconify_frame_hook = x_iconify_frame;
 31896   terminal->set_window_size_hook = x_set_window_size;
 31897   terminal->set_frame_offset_hook = x_set_offset;
 31898   terminal->set_frame_alpha_hook = x_set_frame_alpha;
 31899   terminal->set_new_font_hook = x_new_font;
 31900   terminal->set_bitmap_icon_hook = x_bitmap_icon;
 31901   terminal->implicit_set_name_hook = x_implicitly_set_name;
 31902   terminal->menu_show_hook = x_menu_show;
 31903 #ifdef HAVE_EXT_MENU_BAR
 31904   terminal->activate_menubar_hook = x_activate_menubar;
 31905 #endif
 31906 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
 31907   terminal->popup_dialog_hook = xw_popup_dialog;
 31908 #endif
 31909   terminal->change_tab_bar_height_hook = x_change_tab_bar_height;
 31910 #ifndef HAVE_EXT_TOOL_BAR
 31911   terminal->change_tool_bar_height_hook = x_change_tool_bar_height;
 31912 #endif
 31913   terminal->set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
 31914   terminal->set_horizontal_scroll_bar_hook = XTset_horizontal_scroll_bar;
 31915   terminal->set_scroll_bar_default_width_hook = x_set_scroll_bar_default_width;
 31916   terminal->set_scroll_bar_default_height_hook = x_set_scroll_bar_default_height;
 31917   terminal->condemn_scroll_bars_hook = XTcondemn_scroll_bars;
 31918   terminal->redeem_scroll_bar_hook = XTredeem_scroll_bar;
 31919   terminal->judge_scroll_bars_hook = XTjudge_scroll_bars;
 31920   terminal->get_string_resource_hook = x_get_string_resource;
 31921   terminal->free_pixmap = x_free_pixmap;
 31922   terminal->delete_frame_hook = x_destroy_window;
 31923   terminal->delete_terminal_hook = x_delete_terminal;
 31924   terminal->toolkit_position_hook = x_toolkit_position;
 31925 #ifdef HAVE_XINPUT2
 31926   terminal->any_grab_hook = x_have_any_grab;
 31927 #endif
 31928   /* Other hooks are NULL by default.  */
 31929 
 31930   return terminal;
 31931 }
 31932 
 31933 static void
 31934 x_initialize (void)
 31935 {
 31936   baud_rate = 19200;
 31937 
 31938   x_noop_count = 0;
 31939   any_help_event_p = false;
 31940   ignore_next_mouse_click_timeout = 0;
 31941   mouse_click_timeout_display = NULL;
 31942 
 31943 #ifdef USE_GTK
 31944   current_count = -1;
 31945 #endif
 31946 
 31947   /* Try to use interrupt input; if we can't, then start polling.  */
 31948   Fset_input_interrupt_mode (Qt);
 31949 
 31950 #if THREADS_ENABLED
 31951   /* This must be called before any other Xlib routines.  */
 31952   if (XInitThreads () == 0)
 31953     fputs ("Warning: An error occurred initializing X11 thread support!\n",
 31954            stderr);
 31955 #endif
 31956 
 31957 #ifdef USE_X_TOOLKIT
 31958   XtToolkitInitialize ();
 31959 
 31960   Xt_app_con = XtCreateApplicationContext ();
 31961 
 31962   /* Register a converter from strings to pixels, which uses
 31963      Emacs' color allocation infrastructure.  */
 31964   XtAppSetTypeConverter (Xt_app_con,
 31965                          XtRString, XtRPixel, cvt_string_to_pixel,
 31966                          cvt_string_to_pixel_args,
 31967                          XtNumber (cvt_string_to_pixel_args),
 31968                          XtCacheByDisplay, cvt_pixel_dtor);
 31969 
 31970   XtAppSetFallbackResources (Xt_app_con, Xt_default_resources);
 31971 #endif
 31972 
 31973 #ifdef USE_TOOLKIT_SCROLL_BARS
 31974 #ifndef USE_GTK
 31975   xaw3d_arrow_scroll = False;
 31976   xaw3d_pick_top = True;
 31977 #endif
 31978 #endif
 31979 
 31980 #ifdef USE_CAIRO
 31981   gui_init_fringe (&x_redisplay_interface);
 31982 #endif
 31983 
 31984   /* Note that there is no real way portable across R3/R4 to get the
 31985      original error handler.  */
 31986   XSetErrorHandler (x_error_handler);
 31987   XSetIOErrorHandler (x_io_error_quitter);
 31988 }
 31989 
 31990 #ifdef HAVE_X_I18N
 31991 
 31992 /* Notice that a change has occured on F that requires its input
 31993    method state to be reset.  */
 31994 
 31995 static void
 31996 x_reset_conversion (struct frame *f)
 31997 {
 31998   char *string;
 31999 
 32000   if (FRAME_XIC (f))
 32001     {
 32002       string = XmbResetIC (FRAME_XIC (f));
 32003 
 32004       /* string is actually any string that was being composed at the
 32005          time of the reset.  */
 32006 
 32007       if (string)
 32008         XFree (string);
 32009     }
 32010 }
 32011 
 32012 /* Interface used to control input method ``text conversion''.  */
 32013 
 32014 static struct textconv_interface text_conversion_interface =
 32015   {
 32016     x_reset_conversion,
 32017   };
 32018 
 32019 #endif
 32020 
 32021 void
 32022 init_xterm (void)
 32023 {
 32024 #ifndef HAVE_XINPUT2
 32025   /* Emacs can handle only core input events when built without XI2
 32026      support, so make sure Gtk doesn't use Xinput or Xinput2
 32027      extensions.  */
 32028 #ifndef HAVE_GTK3
 32029   xputenv ("GDK_CORE_DEVICE_EVENTS=1");
 32030 #else
 32031   gdk_disable_multidevice ();
 32032 #endif
 32033 #endif
 32034 
 32035 #ifdef HAVE_X_I18N
 32036   register_textconv_interface (&text_conversion_interface);
 32037 #endif
 32038 }
 32039 
 32040 void
 32041 mark_xterm (void)
 32042 {
 32043   Lisp_Object val;
 32044 #if defined HAVE_XINPUT2 || defined USE_TOOLKIT_SCROLL_BARS \
 32045   || defined HAVE_XRANDR || defined USE_GTK || defined HAVE_X_I18N
 32046   struct x_display_info *dpyinfo;
 32047 #if defined HAVE_XINPUT2 || defined USE_TOOLKIT_SCROLL_BARS
 32048   int i;
 32049 #endif
 32050 #endif
 32051 
 32052   if (x_dnd_return_frame_object)
 32053     {
 32054       XSETFRAME (val, x_dnd_return_frame_object);
 32055       mark_object (val);
 32056     }
 32057 
 32058   if (x_dnd_movement_frame)
 32059     {
 32060       XSETFRAME (val, x_dnd_movement_frame);
 32061       mark_object (val);
 32062     }
 32063 
 32064   if (x_dnd_wheel_frame)
 32065     {
 32066       XSETFRAME (val, x_dnd_wheel_frame);
 32067       mark_object (val);
 32068     }
 32069 
 32070 #if defined HAVE_XINPUT2 || defined USE_TOOLKIT_SCROLL_BARS \
 32071   || defined HAVE_XRANDR || defined USE_GTK || defined HAVE_X_I18N
 32072   for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
 32073     {
 32074 #ifdef HAVE_XINPUT2
 32075       for (i = 0; i < dpyinfo->num_devices; ++i)
 32076         mark_object (dpyinfo->devices[i].name);
 32077 #endif
 32078 #ifdef USE_TOOLKIT_SCROLL_BARS
 32079       for (i = 0; i < dpyinfo->n_protected_windows; ++i)
 32080         mark_object (dpyinfo->protected_windows[i]);
 32081 #endif
 32082 #if defined HAVE_XRANDR || defined USE_GTK
 32083       mark_object (dpyinfo->last_monitor_attributes_list);
 32084 #endif
 32085 #if defined HAVE_X_I18N
 32086       mark_object (dpyinfo->xim_coding);
 32087 #endif
 32088     }
 32089 #endif
 32090 }
 32091 
 32092 /* Error handling functions for Lisp functions that expose X protocol
 32093    requests.  They are mostly like `x_catch_errors' and friends, but
 32094    respect `x-fast-protocol-requests'.  */
 32095 
 32096 void
 32097 x_catch_errors_for_lisp (struct x_display_info *dpyinfo)
 32098 {
 32099   if (!x_fast_protocol_requests)
 32100     x_catch_errors (dpyinfo->display);
 32101   else
 32102     x_ignore_errors_for_next_request (dpyinfo, 0);
 32103 }
 32104 
 32105 void
 32106 x_check_errors_for_lisp (struct x_display_info *dpyinfo,
 32107                          const char *format)
 32108 {
 32109   if (!x_fast_protocol_requests)
 32110     x_check_errors (dpyinfo->display, format);
 32111 }
 32112 
 32113 void
 32114 x_uncatch_errors_for_lisp (struct x_display_info *dpyinfo)
 32115 {
 32116   if (!x_fast_protocol_requests)
 32117     x_uncatch_errors ();
 32118   else
 32119     x_stop_ignoring_errors (dpyinfo);
 32120 }
 32121 
 32122 /* Preserve the selections in LOST in another frame on DPYINFO.  LOST
 32123    is a list of local selections that were lost, due to their frame
 32124    being deleted.  */
 32125 
 32126 void
 32127 x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost,
 32128                        Lisp_Object current_owner)
 32129 {
 32130   Lisp_Object tail, frame, new_owner;
 32131   Time timestamp;
 32132   Window *owners;
 32133   Atom *names;
 32134   ptrdiff_t nowners, counter;
 32135   struct selection_input_event clear;
 32136 #ifdef USE_XCB
 32137   xcb_get_selection_owner_cookie_t *cookies;
 32138   xcb_generic_error_t *error;
 32139   xcb_get_selection_owner_reply_t *reply;
 32140 #endif
 32141 
 32142   new_owner = Qnil;
 32143 
 32144   FOR_EACH_FRAME (tail, frame)
 32145     {
 32146       if (FRAME_X_P (XFRAME (frame))
 32147           && !EQ (frame, current_owner)
 32148           && FRAME_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
 32149         {
 32150           new_owner = frame;
 32151           break;
 32152         }
 32153     }
 32154 
 32155   tail = lost;
 32156   nowners = 0;
 32157 
 32158   FOR_EACH_TAIL_SAFE (tail)
 32159     {
 32160       Lisp_Object tem = XCAR (tail);
 32161       ++nowners;
 32162 
 32163       /* The selection is really lost (since we cannot find a new
 32164          owner), so run the appropriate hooks.  */
 32165       if (NILP (new_owner))
 32166         CALLN (Frun_hook_with_args, Qx_lost_selection_functions,
 32167                XCAR (tem));
 32168       else
 32169         {
 32170           CONS_TO_INTEGER (XCAR (XCDR (XCDR (tem))), Time, timestamp);
 32171 
 32172           /* This shouldn't be able to signal any errors, despite the
 32173              call to `x_check_errors' inside.  */
 32174           x_own_selection (XCAR (tem), XCAR (XCDR (tem)),
 32175                            new_owner, XCAR (XCDR (XCDR (XCDR (XCDR (tem))))),
 32176                            timestamp);
 32177         }
 32178     }
 32179 
 32180   if (!NILP (new_owner))
 32181     {
 32182       owners = alloca (sizeof *owners * nowners);
 32183       names = alloca (sizeof *names * nowners);
 32184 #ifdef USE_XCB
 32185       cookies = alloca (sizeof *cookies * nowners);
 32186 #endif
 32187 
 32188       tail = lost;
 32189       nowners = 0;
 32190       counter = 0;
 32191 
 32192       FOR_EACH_TAIL_SAFE (tail)
 32193         {
 32194           Lisp_Object tem = XCAR (tail);
 32195 
 32196           /* Now check if we still don't own that selection, which can
 32197              happen if another program set itself as the owner.  */
 32198           names[counter++] = symbol_to_x_atom (dpyinfo, XCAR (tem));
 32199 
 32200 #ifndef USE_XCB
 32201           owners[nowners++] = XGetSelectionOwner (dpyinfo->display,
 32202                                                   names[counter - 1]);
 32203 #else
 32204           cookies[nowners++]
 32205             = xcb_get_selection_owner (dpyinfo->xcb_connection,
 32206                                        names[counter - 1]);
 32207         }
 32208 
 32209       nowners = 0;
 32210       tail = lost;
 32211 
 32212       FOR_EACH_TAIL_SAFE (tail)
 32213         {
 32214           Lisp_Object tem = XCAR (tail);
 32215 
 32216           reply = xcb_get_selection_owner_reply (dpyinfo->xcb_connection,
 32217                                                  cookies[nowners++], &error);
 32218           if (reply)
 32219             owners[nowners - 1] = reply->owner;
 32220           else
 32221             owners[nowners - 1] = None;
 32222 
 32223           free (reply ? (void *) reply : (void *) error);
 32224 #endif
 32225 
 32226           if (owners[nowners - 1] != FRAME_X_WINDOW (XFRAME (new_owner)))
 32227             {
 32228               /* Clear the local selection, since we know we don't own
 32229                  it any longer.  */
 32230               CONS_TO_INTEGER (XCAR (XCDR (XCDR (tem))), Time, timestamp);
 32231 
 32232               clear.kind = SELECTION_CLEAR_EVENT;
 32233 
 32234               SELECTION_EVENT_DPYINFO (&clear) = dpyinfo;
 32235               SELECTION_EVENT_SELECTION (&clear) = names[nowners - 1];
 32236               SELECTION_EVENT_TIME (&clear) = timestamp;
 32237 
 32238               x_handle_selection_event (&clear);
 32239             }
 32240         }
 32241 
 32242       tail = lost;
 32243       nowners = 0;
 32244 
 32245       FOR_EACH_TAIL_SAFE (tail)
 32246         {
 32247           Lisp_Object tem = XCAR (tail);
 32248 
 32249           /* If the selection isn't owned by us anymore, note that the
 32250              selection was lost.  */
 32251           if (owners[nowners++] != FRAME_X_WINDOW (XFRAME (new_owner)))
 32252             CALLN (Frun_hook_with_args, Qx_lost_selection_functions,
 32253                    XCAR (tem));
 32254         }
 32255     }
 32256 }
 32257 
 32258 /* Return a list of the keyboard modifier masks in DPYINFO.
 32259 
 32260    Value is a list of (HYPER SUPER ALT SHIFT-LOCK META), each element
 32261    being the appropriate modifier mask.  */
 32262 
 32263 Lisp_Object
 32264 x_get_keyboard_modifiers (struct x_display_info *dpyinfo)
 32265 {
 32266   /* This sometimes happens when the function is called during display
 32267      initialization, which can happen while obtaining vendor specific
 32268      keysyms.  */
 32269 
 32270 #ifdef HAVE_XKB
 32271   if (!dpyinfo->xkb_desc && !dpyinfo->modmap)
 32272     x_find_modifier_meanings (dpyinfo);
 32273 #else
 32274   if (!dpyinfo->modmap)
 32275     x_find_modifier_meanings (dpyinfo);
 32276 #endif
 32277 
 32278   return list5 (make_uint (dpyinfo->hyper_mod_mask),
 32279                 make_uint (dpyinfo->super_mod_mask),
 32280                 make_uint (dpyinfo->alt_mod_mask),
 32281                 make_uint (dpyinfo->shift_lock_mask),
 32282                 make_uint (dpyinfo->meta_mod_mask));
 32283 }
 32284 
 32285 void
 32286 syms_of_xterm (void)
 32287 {
 32288   x_error_message = NULL;
 32289   PDUMPER_IGNORE (x_error_message);
 32290 
 32291   x_dnd_monitors = Qnil;
 32292   staticpro (&x_dnd_monitors);
 32293 
 32294   x_dnd_action_symbol = Qnil;
 32295   staticpro (&x_dnd_action_symbol);
 32296 
 32297   x_dnd_selection_alias_cell = Fcons (Qnil, Qnil);
 32298   staticpro (&x_dnd_selection_alias_cell);
 32299 
 32300   x_dnd_unsupported_drop_data = Qnil;
 32301   staticpro (&x_dnd_unsupported_drop_data);
 32302 
 32303   /* Used by x_cr_export_frames.  */
 32304   DEFSYM (Qconcat, "concat");
 32305 
 32306   DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms");
 32307   DEFSYM (Qlatin_1, "latin-1");
 32308   DEFSYM (Qnow, "now");
 32309   DEFSYM (Qx_dnd_targets_list, "x-dnd-targets-list");
 32310   DEFSYM (Qx_auto_preserve_selections, "x-auto-preserve-selections");
 32311   DEFSYM (Qexpose, "expose");
 32312   DEFSYM (Qdont_save, "dont-save");
 32313 
 32314 #ifdef USE_GTK
 32315   xg_default_icon_file = build_pure_c_string ("icons/hicolor/scalable/apps/emacs.svg");
 32316   staticpro (&xg_default_icon_file);
 32317 
 32318   DEFSYM (Qx_gtk_map_stock, "x-gtk-map-stock");
 32319 #endif
 32320 
 32321   DEFVAR_BOOL ("x-use-underline-position-properties",
 32322                x_use_underline_position_properties,
 32323      doc: /* Non-nil means make use of UNDERLINE_POSITION font properties.
 32324 A value of nil means ignore them.  If you encounter fonts with bogus
 32325 UNDERLINE_POSITION font properties, set this to nil.  You can also use
 32326 `underline-minimum-offset' to override the font's UNDERLINE_POSITION for
 32327 small font display sizes.  */);
 32328   x_use_underline_position_properties = true;
 32329   DEFSYM (Qx_use_underline_position_properties,
 32330           "x-use-underline-position-properties");
 32331 
 32332   DEFVAR_BOOL ("x-underline-at-descent-line",
 32333                x_underline_at_descent_line,
 32334      doc: /* Non-nil means to draw the underline at the same place as the descent line.
 32335 (If `line-spacing' is in effect, that moves the underline lower by
 32336 that many pixels.)
 32337 A value of nil means to draw the underline according to the value of the
 32338 variable `x-use-underline-position-properties', which is usually at the
 32339 baseline level.  The default value is nil.  */);
 32340   x_underline_at_descent_line = false;
 32341   DEFSYM (Qx_underline_at_descent_line, "x-underline-at-descent-line");
 32342 
 32343   DEFVAR_BOOL ("x-mouse-click-focus-ignore-position",
 32344                x_mouse_click_focus_ignore_position,
 32345     doc: /* Non-nil means that a mouse click to focus a frame does not move point.
 32346 This variable is used only when the window manager requires that you
 32347 click on a frame to select it (give it focus).  In that case, a value
 32348 of nil, means that the selected window and cursor position changes to
 32349 reflect the mouse click position, while a non-nil value means that the
 32350 selected window or cursor position is preserved.
 32351 
 32352 This option works by ignoring button press events for a given amount
 32353 of time after a frame might've been focused.  If it does not work for
 32354 you, try increasing the value of
 32355 `x-mouse-click-focus-ignore-time'.  */);
 32356   x_mouse_click_focus_ignore_position = false;
 32357 
 32358   DEFVAR_INT ("x-mouse-click-focus-ignore-time", x_mouse_click_focus_ignore_time,
 32359     doc: /* Number of milliseconds for which to ignore buttons after focus change.
 32360 This variable only takes effect if
 32361 `x-mouse-click-focus-ignore-position' is non-nil, and should be
 32362 adjusted if the default value does not work for whatever reason.  */);
 32363   x_mouse_click_focus_ignore_time = 200;
 32364 
 32365   DEFVAR_LISP ("x-toolkit-scroll-bars", Vx_toolkit_scroll_bars,
 32366     doc: /* Which toolkit scroll bars Emacs uses, if any.
 32367 A value of nil means Emacs doesn't use toolkit scroll bars.
 32368 With the X Window system, the value is a symbol describing the
 32369 X toolkit.  Possible values are: gtk, motif, xaw, or xaw3d.
 32370 With MS Windows, Haiku windowing or Nextstep, the value is t.
 32371 With Android, the value is nil, but that is because Emacs on
 32372 Android does not support scroll bars at all.  */);
 32373 #ifdef USE_TOOLKIT_SCROLL_BARS
 32374 #ifdef USE_MOTIF
 32375   Vx_toolkit_scroll_bars = intern_c_string ("motif");
 32376 #elif defined HAVE_XAW3D
 32377   Vx_toolkit_scroll_bars = intern_c_string ("xaw3d");
 32378 #elif USE_GTK
 32379   Vx_toolkit_scroll_bars = intern_c_string ("gtk");
 32380 #else
 32381   Vx_toolkit_scroll_bars = intern_c_string ("xaw");
 32382 #endif
 32383 #else
 32384   Vx_toolkit_scroll_bars = Qnil;
 32385 #endif
 32386 
 32387   DEFSYM (Qmodifier_value, "modifier-value");
 32388   DEFSYM (Qctrl, "ctrl");
 32389   Fput (Qctrl, Qmodifier_value, make_fixnum (ctrl_modifier));
 32390   DEFSYM (Qalt, "alt");
 32391   Fput (Qalt, Qmodifier_value, make_fixnum (alt_modifier));
 32392   DEFSYM (Qhyper, "hyper");
 32393   Fput (Qhyper, Qmodifier_value, make_fixnum (hyper_modifier));
 32394   DEFSYM (Qmeta, "meta");
 32395   Fput (Qmeta, Qmodifier_value, make_fixnum (meta_modifier));
 32396   DEFSYM (Qsuper, "super");
 32397   Fput (Qsuper, Qmodifier_value, make_fixnum (super_modifier));
 32398   DEFSYM (QXdndSelection, "XdndSelection");
 32399   DEFSYM (Qx_selection_alias_alist, "x-selection-alias-alist");
 32400   DEFSYM (Qimitate_pager, "imitate-pager");
 32401   DEFSYM (Qnewer_time, "newer-time");
 32402   DEFSYM (Qraise_and_focus, "raise-and-focus");
 32403   DEFSYM (Qreally_fast, "really-fast");
 32404 
 32405   DEFVAR_LISP ("x-ctrl-keysym", Vx_ctrl_keysym,
 32406     doc: /* Which keys Emacs uses for the ctrl modifier.
 32407 This should be one of the symbols `ctrl', `alt', `hyper', `meta',
 32408 `super'.  For example, `ctrl' means use the Ctrl_L and Ctrl_R keysyms.
 32409 The default is nil, which is the same as `ctrl'.  */);
 32410   Vx_ctrl_keysym = Qnil;
 32411 
 32412   DEFVAR_LISP ("x-alt-keysym", Vx_alt_keysym,
 32413     doc: /* Which keys Emacs uses for the alt modifier.
 32414 This should be one of the symbols `ctrl', `alt', `hyper', `meta',
 32415 `super'.  For example, `alt' means use the Alt_L and Alt_R keysyms.
 32416 The default is nil, which is the same as `alt'.  */);
 32417   Vx_alt_keysym = Qnil;
 32418 
 32419   DEFVAR_LISP ("x-hyper-keysym", Vx_hyper_keysym,
 32420     doc: /* Which keys Emacs uses for the hyper modifier.
 32421 This should be one of the symbols `ctrl', `alt', `hyper', `meta',
 32422 `super'.  For example, `hyper' means use the Hyper_L and Hyper_R
 32423 keysyms.  The default is nil, which is the same as `hyper'.  */);
 32424   Vx_hyper_keysym = Qnil;
 32425 
 32426   DEFVAR_LISP ("x-meta-keysym", Vx_meta_keysym,
 32427     doc: /* Which keys Emacs uses for the meta modifier.
 32428 This should be one of the symbols `ctrl', `alt', `hyper', `meta',
 32429 `super'.  For example, `meta' means use the Meta_L and Meta_R keysyms.
 32430 The default is nil, which is the same as `meta'.  */);
 32431   Vx_meta_keysym = Qnil;
 32432 
 32433   DEFVAR_LISP ("x-super-keysym", Vx_super_keysym,
 32434     doc: /* Which keys Emacs uses for the super modifier.
 32435 This should be one of the symbols `ctrl', `alt', `hyper', `meta',
 32436 `super'.  For example, `super' means use the Super_L and Super_R
 32437 keysyms.  The default is nil, which is the same as `super'.  */);
 32438   Vx_super_keysym = Qnil;
 32439 
 32440   DEFVAR_LISP ("x-wait-for-event-timeout", Vx_wait_for_event_timeout,
 32441     doc: /* How long to wait for X events.
 32442 
 32443 Emacs will wait up to this many seconds to receive X events after
 32444 making changes which affect the state of the graphical interface.
 32445 Under some window managers this can take an indefinite amount of time,
 32446 so it is important to limit the wait.
 32447 
 32448 If set to a non-float value, there will be no wait at all.  */);
 32449   Vx_wait_for_event_timeout = make_float (0.1);
 32450 
 32451   DEFVAR_LISP ("x-keysym-table", Vx_keysym_table,
 32452     doc: /* Hash table of character codes indexed by X keysym codes.  */);
 32453   Vx_keysym_table = make_hash_table (hashtest_eql, 900,
 32454                                      DEFAULT_REHASH_SIZE,
 32455                                      DEFAULT_REHASH_THRESHOLD,
 32456                                      Qnil, false);
 32457 
 32458   DEFVAR_BOOL ("x-frame-normalize-before-maximize",
 32459                x_frame_normalize_before_maximize,
 32460     doc: /* Non-nil means normalize frame before maximizing.
 32461 If this variable is t, Emacs first asks the window manager to give the
 32462 frame its normal size, and only then the final state, whenever changing
 32463 from a full-height, full-width or full-both state to the maximized one
 32464 or when changing from the maximized to the full-height or full-width
 32465 state.
 32466 
 32467 Set this variable only if your window manager cannot handle the
 32468 transition between the various maximization states.  */);
 32469   x_frame_normalize_before_maximize = false;
 32470 
 32471   DEFVAR_BOOL ("x-gtk-use-window-move", x_gtk_use_window_move,
 32472     doc: /* Non-nil means rely on gtk_window_move to set frame positions.
 32473 If this variable is t (the default), the GTK build uses the function
 32474 gtk_window_move to set or store frame positions and disables some time
 32475 consuming frame position adjustments.  In newer versions of GTK, Emacs
 32476 always uses gtk_window_move and ignores the value of this variable.  */);
 32477   x_gtk_use_window_move = true;
 32478 
 32479   DEFVAR_LISP ("x-scroll-event-delta-factor", Vx_scroll_event_delta_factor,
 32480                doc: /* A scale to apply to pixel deltas reported in scroll events.
 32481 This option is only effective when Emacs is built with XInput 2
 32482 support. */);
 32483   Vx_scroll_event_delta_factor = make_float (1.0);
 32484 
 32485   DEFVAR_BOOL ("x-gtk-use-native-input", x_gtk_use_native_input,
 32486                doc: /* Non-nil means to use GTK for input method support.
 32487 This provides better support for some modern input methods, and is
 32488 only effective when Emacs is built with GTK.  */);
 32489   x_gtk_use_native_input = false;
 32490 
 32491   DEFVAR_LISP ("x-set-frame-visibility-more-laxly",
 32492                x_set_frame_visibility_more_laxly,
 32493     doc: /* Non-nil means set frame visibility more laxly.
 32494 If this is nil, Emacs is more strict when marking a frame as visible.
 32495 Since this may cause problems on some window managers, this variable can
 32496 be also set as follows: The value `focus-in' means to mark a frame as
 32497 visible also when a FocusIn event is received for it on GTK builds.  The
 32498 value `expose' means to mark a frame as visible also when an Expose
 32499 event is received for it on any X build.  The value `t' means to mark a
 32500 frame as visible in either of these two cases.
 32501 
 32502 Note that any non-nil setting may cause invisible frames get erroneously
 32503 reported as iconified.  */);
 32504   x_set_frame_visibility_more_laxly = Qnil;
 32505 
 32506   DEFVAR_BOOL ("x-input-grab-touch-events", x_input_grab_touch_events,
 32507                doc: /* Non-nil means to actively grab touch events.
 32508 This means touch sequences that are obtained through a passive grab on
 32509 an Emacs frame (or a parent window of such a frame) will reliably
 32510 continue to receive updates, but may cause crashes with some window
 32511 managers and/or external programs.  Changing this option is only
 32512 useful when other programs are making their own X requests pertaining
 32513 to the window hierarchy of an Emacs frame.  */);
 32514   x_input_grab_touch_events = true;
 32515 
 32516   DEFVAR_BOOL ("x-dnd-fix-motif-leave", x_dnd_fix_motif_leave,
 32517                doc: /* Work around Motif bug during drag-and-drop.
 32518 When non-nil, Emacs will send a motion event containing impossible
 32519 coordinates to a Motif drop receiver when the mouse moves outside it
 32520 during a drag-and-drop session, to work around broken implementations
 32521 of Motif.  */);
 32522   x_dnd_fix_motif_leave = true;
 32523 
 32524   DEFVAR_BOOL ("x-dnd-disable-motif-drag", x_dnd_disable_motif_drag,
 32525                doc: /* Disable the Motif drag protocol during DND.
 32526 This reduces network usage, but also means you can no longer scroll
 32527 around inside the Motif window underneath the cursor during
 32528 drag-and-drop.  */);
 32529   x_dnd_disable_motif_drag = false;
 32530 
 32531   DEFVAR_LISP ("x-dnd-movement-function", Vx_dnd_movement_function,
 32532     doc: /* Function called upon mouse movement on a frame during drag-and-drop.
 32533 It should either be nil, or accept two arguments FRAME and POSITION,
 32534 where FRAME is the frame the mouse is on top of, and POSITION is a
 32535 mouse position list.  */);
 32536   Vx_dnd_movement_function = Qnil;
 32537 
 32538   DEFVAR_LISP ("x-dnd-wheel-function", Vx_dnd_wheel_function,
 32539     doc: /* Function called upon wheel movement on a frame during drag-and-drop.
 32540 It should either be nil, or accept four arguments POSITION, BUTTON,
 32541 STATE and TIME, where POSITION is a mouse position list describing
 32542 where the wheel moved, BUTTON is the wheel button that was pressed,
 32543 STATE is the X modifier state at the time of the wheel movement, and
 32544 TIME is the X server time at which the wheel moved.  */);
 32545   Vx_dnd_wheel_function = Qnil;
 32546 
 32547   DEFVAR_LISP ("x-dnd-unsupported-drop-function", Vx_dnd_unsupported_drop_function,
 32548     doc: /* Function called when trying to drop on an unsupported window.
 32549 This function is called whenever the user tries to drop something on a
 32550 window that does not support either the XDND or Motif protocols for
 32551 drag-and-drop.  It should return a non-nil value if the drop was
 32552 handled by the function, and nil if it was not.  It should accept
 32553 several arguments TARGETS, X, Y, ACTION, WINDOW-ID, FRAME, TIME and
 32554 LOCAL-SELECTION, where TARGETS is the list of targets that was passed
 32555 to `x-begin-drag', WINDOW-ID is the numeric XID of the window that is
 32556 being dropped on, X and Y are the root window-relative coordinates
 32557 where the drop happened, ACTION is the action that was passed to
 32558 `x-begin-drag', FRAME is the frame which initiated the drag-and-drop
 32559 operation, TIME is the X server time when the drop happened, and
 32560 LOCAL-SELECTION is the contents of the `XdndSelection' when
 32561 `x-begin-drag' was run; its contents can be retrieved by calling the
 32562 function `x-get-local-selection'.
 32563 
 32564 If a symbol is returned, then it will be used as the return value of
 32565 `x-begin-drag'.  */);
 32566   Vx_dnd_unsupported_drop_function = Qnil;
 32567 
 32568   DEFVAR_INT ("x-color-cache-bucket-size", x_color_cache_bucket_size,
 32569     doc: /* Max number of buckets allowed per display in the internal color cache.
 32570 Values less than 1 mean 128.  This option is for debugging only.  */);
 32571   x_color_cache_bucket_size = 128;
 32572 
 32573   DEFVAR_LISP ("x-dnd-targets-list", Vx_dnd_targets_list,
 32574     doc: /* List of drag-and-drop targets.
 32575 This variable contains the list of drag-and-drop selection targets
 32576 during a drag-and-drop operation, in the same format as the TARGET
 32577 argument to `x-begin-drag'.  */);
 32578   Vx_dnd_targets_list = Qnil;
 32579 
 32580   DEFVAR_LISP ("x-dnd-native-test-function", Vx_dnd_native_test_function,
 32581     doc: /* Function that determines return value of drag-and-drop on Emacs frames.
 32582 If the value is a function, `x-begin-drag' will call it with two
 32583 arguments, POS and ACTION, where POS is a mouse position list
 32584 that specifies the location of the drop, and ACTION is the
 32585 action specified by the caller of `x-begin-drag'.  The function
 32586 should return a symbol describing what to return from
 32587 `x-begin-drag' if the drop happens on an Emacs frame.
 32588 
 32589 If the value is nil, or the function returns a value that is not
 32590 a symbol, a drop on an Emacs frame will be canceled.  */);
 32591   Vx_dnd_native_test_function = Qnil;
 32592 
 32593   DEFVAR_BOOL ("x-dnd-preserve-selection-data", x_dnd_preserve_selection_data,
 32594     doc: /* Preserve selection data after `x-begin-drag' returns.
 32595 This lets you inspect the contents of `XdndSelection' after a
 32596 drag-and-drop operation, which is useful when writing tests for
 32597 drag-and-drop code.  */);
 32598   x_dnd_preserve_selection_data = false;
 32599 
 32600   DEFVAR_BOOL ("x-dnd-disable-motif-protocol", x_dnd_disable_motif_protocol,
 32601     doc: /* Disable the Motif drag-and-drop protocols.
 32602 When non-nil, `x-begin-drag' will not drop onto any window that only
 32603 supports the Motif drag-and-drop protocols.  */);
 32604   x_dnd_disable_motif_protocol = false;
 32605 
 32606   DEFVAR_BOOL ("x-dnd-use-unsupported-drop", x_dnd_use_unsupported_drop,
 32607     doc: /* Enable the emulation of drag-and-drop based on the primary selection.
 32608 When nil, do not use the primary selection and synthetic mouse clicks
 32609 to emulate the drag-and-drop of `STRING', `UTF8_STRING',
 32610 `COMPOUND_TEXT' or `TEXT'.  */);
 32611   x_dnd_use_unsupported_drop = true;
 32612 
 32613   DEFVAR_BOOL ("x-fast-protocol-requests", x_fast_protocol_requests,
 32614     doc: /* Whether or not X protocol-related functions should wait for errors.
 32615 When this is nil, functions such as `x-delete-window-property',
 32616 `x-change-window-property' and `x-send-client-message' will wait for a
 32617 reply from the X server, and signal any errors that occurred while
 32618 executing the protocol request.  Otherwise, errors will be silently
 32619 ignored without waiting, which is generally faster.  */);
 32620   x_fast_protocol_requests = false;
 32621 
 32622   DEFVAR_LISP ("x-auto-preserve-selections", Vx_auto_preserve_selections,
 32623     doc: /* Whether or not to transfer selection ownership when deleting a frame.
 32624 When non-nil, deleting a frame that is currently the owner of a
 32625 selection will cause its ownership to be transferred to another frame
 32626 on the same display.
 32627 
 32628 In addition, when this variable is a list, only preserve the
 32629 selections whose names are contained within.  */);
 32630   Vx_auto_preserve_selections = list2 (QCLIPBOARD, QPRIMARY);
 32631 
 32632   DEFVAR_LISP ("x-input-coding-system", Vx_input_coding_system,
 32633     doc: /* Coding system used for input from X input methods.
 32634 If a symbol and non-nil, this is the coding system that will be used
 32635 to decode input from X input methods.  It does not affect input from
 32636 GTK native input methods enabled through `x-gtk-use-native-input'.  */);
 32637   Vx_input_coding_system = Qnil;
 32638 
 32639   DEFVAR_LISP ("x-input-coding-function", Vx_input_coding_function,
 32640     doc: /* Function used to determine the coding system used by input methods.
 32641 It should accept a single argument, a string describing the locale of
 32642 the input method, and return a coding system that can decode keyboard
 32643 input generated by said input method.  */);
 32644   Vx_input_coding_function = Qnil;
 32645 
 32646   DEFVAR_LISP ("x-fast-selection-list", Vx_fast_selection_list,
 32647     doc: /* List of selections for which `x-selection-exists-p' should be fast.
 32648 
 32649 List of selection names as atoms that will be monitored by Emacs for
 32650 ownership changes when the X server supports the XFIXES extension.
 32651 The result of the monitoring is then used by `x-selection-exists-p' to
 32652 avoid a server round trip, which is important as it is called while
 32653 updating the tool bar.  The value of this variable is only read upon
 32654 connection setup.  */);
 32655   /* The default value of this variable is chosen so that updating the
 32656      tool bar does not require a call to _XReply.  */
 32657   Vx_fast_selection_list = list1 (QCLIPBOARD);
 32658 
 32659   DEFVAR_LISP ("x-allow-focus-stealing", Vx_allow_focus_stealing,
 32660     doc: /* How to bypass window manager focus stealing prevention.
 32661 
 32662 Some window managers prevent `x-focus-frame' from activating the given
 32663 frame when Emacs is in the background, which is especially prone to
 32664 cause problems when the Emacs server wants to activate itself.
 32665 
 32666 In addition, when an old-fashioned (pre-EWMH) window manager is being
 32667 run and `x-no-window-manager' is nil, the X server will not let Emacs
 32668 focus itself if another program was focused after the last time Emacs
 32669 obtained the input focus.
 32670 
 32671 This variable specifies the strategy used to activate frames when that
 32672 is the case, and has several valid values (any other value means to
 32673 not bypass window manager focus stealing prevention):
 32674 
 32675   - The symbol `imitate-pager', which means to pretend that Emacs is a
 32676     pager.
 32677 
 32678   - The symbol `newer-time', which means to fetch the current time
 32679     from the X server and use it to activate the frame.
 32680 
 32681   - The symbol `raise-and-focus', which means to raise the window and
 32682     focus it manually.  */);
 32683   Vx_allow_focus_stealing = Qnewer_time;
 32684 
 32685   DEFVAR_LISP ("x-use-fast-mouse-position", Vx_use_fast_mouse_position,
 32686     doc: /* How to make `mouse-position' faster.
 32687 
 32688 `mouse-position' and `mouse-pixel-position' default to querying the X
 32689 server for the window under the mouse pointer.  This results in
 32690 accurate results, but is also very slow when the X connection has
 32691 moderate to high latency.  Setting this variable to a non-nil value
 32692 makes Emacs query only for the position of the pointer, which is
 32693 usually faster.  Doing so improves the performance of dragging to
 32694 select text over slow X connections.
 32695 
 32696 If that is still too slow, setting this variable to the symbol
 32697 `really-fast' will make Emacs return only cached values.  */);
 32698   Vx_use_fast_mouse_position = Qnil;
 32699 
 32700   DEFVAR_LISP ("x-detect-server-trust", Vx_detect_server_trust,
 32701     doc: /* If non-nil, Emacs should detect whether or not it is trusted by X.
 32702 
 32703 If non-nil, Emacs will make an X request at connection startup that is
 32704 prohibited to untrusted clients under the X Security Extension and
 32705 check whether or not a resulting Access error is generated by the X
 32706 server.  If the X server reports the error, Emacs will disable certain
 32707 features that do not work for untrusted clients.  */);
 32708   Vx_detect_server_trust = Qnil;
 32709 
 32710   DEFVAR_LISP ("x-lax-frame-positioning", Vx_lax_frame_positioning,
 32711     doc: /* If non-nil, Emacs won't compensate for WM geometry behavior.
 32712 
 32713 Setting this to non-nil is useful when the compensation proves to be
 32714 too slow, which is usually true when the X server is located over a
 32715 network connection with high latency.  Doing so will make frame
 32716 creation and placement faster at the cost of reducing the accuracy of
 32717 frame placement via frame parameters, `set-frame-position', and
 32718 `set-frame-size', along with the actual state of a frame after
 32719 `x_make_frame_invisible'.  */);
 32720   Vx_lax_frame_positioning = Qnil;
 32721 
 32722   DEFVAR_LISP ("x-quit-keysym", Vx_quit_keysym,
 32723     doc: /* Keysyms which will cause Emacs to quit if rapidly pressed twice.
 32724 
 32725 This is used to support quitting on devices that do not have any kind
 32726 of physical keyboard, or where the physical keyboard is incapable of
 32727 entering `C-g'.  It defaults to `XF86XK_AudioLowerVolume' on XFree86
 32728 and X.Org servers, and is unset.
 32729 
 32730 The value is an alist associating between strings, describing X server
 32731 vendor names, and a single number describing the keysym to use.  The
 32732 keysym to use for each display connection is determined upon
 32733 connection setup, and does not reflect further changes to this
 32734 variable.  */);
 32735   Vx_quit_keysym
 32736     = list2 (Fcons (build_string ("The X.Org Foundation"),
 32737                     make_int (269025041)),
 32738              Fcons (build_string ("The XFree86 Project, Inc."),
 32739                     make_int (269025041)));
 32740 }

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