root/src/xterm.c

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

DEFINITIONS

This source file includes following definitions.
  1. x_defer_selection_requests
  2. x_release_selection_requests
  3. x_release_selection_requests_and_flush
  4. xm_side_effect_from_action
  5. xm_operations_from_actions
  6. xm_read_targets_table_header
  7. xm_read_targets_table_rec
  8. xm_find_targets_table_idx
  9. x_atoms_compare
  10. xm_write_targets_table
  11. xm_write_drag_initiator_info
  12. xm_drag_window_error_handler
  13. xm_drag_window_io_error_handler
  14. x_special_window_exists_p
  15. xm_get_drag_window_1
  16. xm_get_drag_window
  17. xm_setup_dnd_targets
  18. xm_get_drag_atom_1
  19. xm_get_drag_atom
  20. xm_setup_drag_info
  21. xm_send_drop_message
  22. xm_send_top_level_enter_message
  23. xm_send_drag_motion_message
  24. xm_send_top_level_leave_message
  25. xm_read_drop_start_reply
  26. xm_read_drop_start_message
  27. xm_read_drag_receiver_info
  28. xm_read_drag_motion_message
  29. xm_read_drag_motion_reply
  30. x_dnd_send_xm_leave_for_drop
  31. x_dnd_free_toplevels
  32. x_dnd_compute_toplevels
  33. x_dnd_io_error_handler
  34. x_dnd_get_proxy_proto
  35. x_dnd_get_target_window_2
  36. x_dnd_get_target_window_1
  37. x_dnd_get_wm_state_and_proto
  38. x_dnd_do_unsupported_drop
  39. x_dnd_send_unsupported_drop
  40. x_dnd_fill_empty_target
  41. x_dnd_get_target_window
  42. x_dnd_get_window_proxy
  43. x_dnd_get_window_proto
  44. x_dnd_send_enter
  45. x_dnd_send_position
  46. x_dnd_send_leave
  47. x_dnd_send_drop
  48. x_dnd_do_drop
  49. x_set_dnd_targets
  50. x_free_dnd_targets
  51. x_clear_dnd_variables
  52. x_free_dnd_toplevels
  53. x_restore_events_after_dnd
  54. x_dnd_cancel_dnd_early
  55. x_dnd_cleanup_drag_and_drop
  56. x_dnd_note_self_position
  57. x_dnd_note_self_wheel
  58. x_dnd_note_self_drop
  59. x_flush
  60. x_drop_xrender_surfaces
  61. x_xr_ensure_picture
  62. record_event
  63. xi_frame_selected_for
  64. x_toolkit_position
  65. x_update_opaque_region
  66. x_gc_free_ext_data_private
  67. x_gc_get_ext_data
  68. x_extension_initialize
  69. xi_convert_button_state
  70. xi_convert_event_state
  71. xi_convert_event_keyboard_state
  72. x_free_xi_devices
  73. xi_populate_scroll_valuator
  74. xi_populate_device_from_info
  75. x_cache_xi_devices
  76. x_get_scroll_valuator_delta
  77. xi_device_from_id
  78. xi_link_touch_point
  79. xi_unlink_touch_point
  80. xi_find_touch_point
  81. xi_reset_scroll_valuators_for_device_id
  82. x_cr_destroy_frame_context
  83. x_cr_update_surface_desired_size
  84. x_cr_gc_clip
  85. x_begin_cr_clip
  86. x_end_cr_clip
  87. x_set_cr_source_with_gc_foreground
  88. x_set_cr_source_with_gc_background
  89. x_cr_destroy_xlib_surface
  90. x_try_cr_xlib_drawable
  91. x_end_cr_xlib_drawable
  92. x_cr_define_fringe_bitmap
  93. x_cr_destroy_fringe_bitmap
  94. x_cr_draw_image
  95. x_cr_draw_frame
  96. x_cr_accumulate_data
  97. x_cr_destroy
  98. x_cr_export_frames
  99. x_xr_apply_ext_clip
  100. x_xr_reset_ext_clip
  101. x_set_clip_rectangles
  102. x_reset_clip_rectangles
  103. x_xrender_color_from_gc_foreground
  104. x_xrender_color_from_gc_background
  105. x_fill_rectangle
  106. x_clear_rectangle
  107. x_draw_rectangle
  108. x_clear_window
  109. x_fill_trapezoid_for_relief
  110. x_erase_corners_for_relief
  111. x_draw_horizontal_wave
  112. x_display_info_for_display
  113. x_find_topmost_parent
  114. x_set_frame_alpha
  115. x_if_event
  116. x_sync_get_monotonic_time
  117. x_sync_current_monotonic_time
  118. x_sync_note_frame_times
  119. x_sync_is_frame_drawn_event
  120. x_sync_wait_for_frame_drawn_event
  121. x_sync_update_begin
  122. x_sync_trigger_fence
  123. x_sync_init_fences
  124. x_sync_free_fences
  125. x_sync_update_finish
  126. x_sync_handle_frame_drawn
  127. x_update_begin
  128. x_draw_vertical_window_border
  129. x_draw_window_divider
  130. show_back_buffer
  131. x_flip_and_flush
  132. x_update_end
  133. XTframe_up_to_date
  134. XTbuffer_flipping_unblocked_hook
  135. x_clear_under_internal_border
  136. x_after_update_window_line
  137. x_draw_fringe_bitmap
  138. x_display_set_last_user_time
  139. x_set_gtk_user_time
  140. x_create_special_window
  141. x_update_frame_user_time_window
  142. x_set_last_user_time_from_lisp
  143. x_set_cursor_gc
  144. x_set_mouse_face_gc
  145. x_set_mode_line_face_gc
  146. x_set_glyph_string_gc
  147. x_set_glyph_string_clipping
  148. x_set_glyph_string_clipping_exactly
  149. x_compute_glyph_string_overhangs
  150. x_clear_glyph_string_rect
  151. x_clear_point
  152. x_draw_glyph_string_background
  153. x_draw_glyph_string_foreground
  154. x_draw_composite_glyph_string_foreground
  155. x_draw_glyphless_glyph_string_foreground
  156. x_frame_of_widget
  157. x_alloc_lighter_color_for_widget
  158. cvt_string_to_pixel
  159. cvt_pixel_dtor
  160. x_color_cells
  161. x_query_colors
  162. x_query_frame_background_color
  163. x_hash_string_ignore_case
  164. x_parse_color
  165. x_alloc_nearest_color_1
  166. x_alloc_nearest_color
  167. x_copy_color
  168. x_alloc_lighter_color
  169. x_setup_relief_color
  170. x_setup_relief_colors
  171. x_fill_triangle
  172. x_make_point
  173. x_inside_rect_p
  174. x_draw_relief_rect
  175. x_draw_box_rect
  176. x_draw_glyph_string_box
  177. x_composite_image
  178. x_draw_image_foreground
  179. x_draw_image_relief
  180. x_draw_image_foreground_1
  181. x_draw_glyph_string_bg_rect
  182. x_draw_image_glyph_string
  183. x_draw_stretch_glyph_string
  184. x_get_scale_factor
  185. x_draw_underwave
  186. x_draw_glyph_string
  187. x_shift_glyphs_for_insert
  188. x_delete_glyphs
  189. x_clear_area1
  190. x_clear_area
  191. x_clear_frame
  192. x_show_hourglass
  193. x_hide_hourglass
  194. XTflash
  195. XTring_bell
  196. x_ins_del_lines
  197. x_scroll_run
  198. x_frame_highlight
  199. x_frame_unhighlight
  200. x_new_focus_frame
  201. x_fixes_pointer_blanking_supported
  202. xfixes_toggle_visible_pointer
  203. make_invisible_cursor
  204. x_toggle_visible_pointer
  205. XTtoggle_invisible_pointer
  206. x_focus_changed
  207. x_window_to_frame
  208. x_tooltip_window_to_frame
  209. x_any_window_to_frame
  210. x_menubar_window_to_frame
  211. x_top_window_to_frame
  212. x_top_window_to_frame
  213. x_next_event_from_any_display
  214. x_handle_pending_selection_requests_1
  215. x_handle_pending_selection_requests
  216. x_push_selection_request
  217. x_detect_pending_selection_requests
  218. x_clear_dnd_action
  219. x_dnd_delete_action_list
  220. x_dnd_lose_ownership
  221. x_dnd_process_quit
  222. 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    Some of what is explained below also applies to the other window
    30    systems that Emacs supports, to varying degrees.  YMMV.
    31 
    32    INPUT
    33 
    34    Emacs handles input by running pselect in a loop, which returns
    35    whenever there is input available on the connection to the X
    36    server.  On some systems, Emacs also arranges for any new input on
    37    that connection to send an asynchronous signal.  Whenever pselect
    38    returns, or such a signal is received and input is not blocked,
    39    XTread_socket is called and translates X11 events read by Xlib into
    40    struct input_events, which are then stored in the keyboard buffer,
    41    to be processed and acted upon at some later time.  The function
    42    handle_one_xevent is responsible for handling core events after
    43    they are filtered, and filtering X Input Extension events.  It also
    44    performs actions on some special events, such as updating the
    45    dimensions of a frame after a ConfigureNotify is sent by the X
    46    server to inform us that it changed.
    47 
    48    Before such events are translated, an Emacs build with
    49    internationalization enabled (the default since X11R6) will filter
    50    events through an X Input Method (XIM) or GTK, which might decide
    51    to intercept the event and send a different one in its place, for
    52    reasons such as enabling the user to insert international
    53    characters that aren't on his keyboard by typing a sequence of
    54    characters which are.  See the function x_filter_event and its
    55    callers for more details.
    56 
    57    Events that cause Emacs to quit are treated specially by the code
    58    that stores them in the keyboard buffer and generally cause an
    59    immediate interrupt.  Such an interrupt can lead to a longjmp from
    60    the code that stored the keyboard event, which isn't safe inside
    61    XTread_socket.  To avoid this problem, XTread_socket is provided a
    62    special event buffer named hold_quit.  When a quit event is
    63    encountered, it is stored inside this special buffer, which will
    64    cause the keyboard code that called XTread_socket to store it at a
    65    later time when it is safe to do so.
    66 
    67    handle_one_xevent will generally have to determine which frame an
    68    event should be attributed to.  This is not easy, because events
    69    can come from multiple X windows, and a frame can also have
    70    multiple windows.  handle_one_xevent usually calls the function
    71    x_any_window_to_frame, which searches for a frame by toplevel
    72    window and widget windows.  There are also some other functions for
    73    searching by specific types of window, such as
    74    x_top_window_to_frame (which only searches for frames by toplevel
    75    window), and x_menubar_window_to_frame (which will only search
    76    through frame menu bars).
    77 
    78    INPUT FOCUS
    79 
    80    Under X, the window where keyboard input is sent is not always
    81    explicitly defined.  When there is a focus window, it receives what
    82    is referred to as "explicit focus", but when there is none, it
    83    receives "implicit focus" whenever the pointer enters it, and loses
    84    that focus when the pointer leaves.  When the toplevel window of a
    85    frame receives an explicit focus event (FocusIn or FocusOut), we
    86    treat that frame as having the current input focus, but when there
    87    is no focus window, we treat each frame as having the input focus
    88    whenever the pointer enters it, and undo that treatment when the
    89    pointer leaves it.  See the callers of x_detect_focus_change for
    90    more details.
    91 
    92    REDISPLAY
    93 
    94    The redisplay engine communicates with X through the "redisplay
    95    interface", which is a structure containing pointers to functions
    96    which output graphics to a frame.
    97 
    98    Some of the functions included in the redisplay interface include
    99    `x_clear_frame_area', which is called by the display engine when it
   100    determines that a part of the display has to be cleared,
   101    x_draw_window_cursor, which is called to perform the calculations
   102    necessary to display the cursor glyph with a special "highlight"
   103    (more on that later) and to set the input method spot location.
   104 
   105    Most of the actual display is performed by the function
   106    `x_draw_glyph_string', also included in the redisplay interface.
   107    It takes a list of glyphs of the same type and face, computes the
   108    correct graphics context for the string through the function
   109    `x_set_glyph_string_gc', and draws whichever glyphs it might
   110    contain, along with decorations such as the box face, underline and
   111    overline.  That list is referred to as a "glyph string".
   112 
   113    GRAPHICS CONTEXTS
   114 
   115    A graphics context ("GC") is an X server-side object which contains
   116    drawing attributes such as fill style, stipple, and foreground and
   117    background pixel values.
   118 
   119    Usually, one graphics context is computed for each face when it is
   120    about to be displayed for the first time, and this graphics context
   121    is the one which is used for future X drawing operations in a glyph
   122    string with that face.  (See `prepare_face_for_display' in
   123    xfaces.c).
   124 
   125    However, when drawing glyph strings for special display elements
   126    such as the cursor, or mouse sensitive text, different GCs may be
   127    used.  When displaying the cursor, for example, the frame's cursor
   128    graphics context is used for the common case where the cursor is
   129    drawn with the default font, and the colors of the string's face
   130    are the same as the default face.  In all other cases, a temporary
   131    graphics context is created with the foreground and background
   132    colors of the cursor face adjusted to ensure that the cursor can be
   133    distinguished from its surroundings and that the text inside the
   134    cursor stays visible.
   135 
   136    Various graphics contexts are also calculated when the frame is
   137    created by the function `x_make_gcs' in xfns.c, and are adjusted
   138    whenever the foreground or background colors change.  The "normal"
   139    graphics context is used for operations performed without a face,
   140    and always corresponds to the foreground and background colors of
   141    the frame's default face, the "reverse" graphics context is used to
   142    draw text in inverse video, and the cursor graphics context is used
   143    to display the cursor in the most common case.
   144 
   145    N.B. that some of the other window systems supported by use an
   146    emulation of graphics contexts to hold the foreground and
   147    background colors used in a glyph string, while the some others
   148    ports compute those colors directly based on the colors of the
   149    string's face and its highlight, but only on X are graphics
   150    contexts a data structure inherent to the window system.
   151 
   152    COLOR ALLOCATION
   153 
   154    In (and only in) X, pixel values for colors are not guaranteed to
   155    correspond to their individual components.  The rules for
   156    converting colors into pixel values are defined by the visual class
   157    of each display opened by Emacs.  When a display is opened, a
   158    suitable visual is obtained from the X server, and a colormap is
   159    created based on that visual, which is then used for each frame
   160    created.
   161 
   162    The colormap is then used by the X server to convert pixel values
   163    from a frame created by Emacs into actual colors which are output
   164    onto the physical display.
   165 
   166    When the visual class is TrueColor, the colormap will be indexed
   167    based on the red, green, and blue (RGB) components of the pixel
   168    values, and the colormap will be statically allocated so as to
   169    contain linear ramps for each component.  As such, most of the
   170    color allocation described below is bypassed, and the pixel values
   171    are computed directly from the color.
   172 
   173    Otherwise, each time Emacs wants a pixel value that corresponds to
   174    a color, Emacs has to ask the X server to obtain the pixel value
   175    that corresponds to a "color cell" containing the color (or a close
   176    approximation) from the colormap.  Exactly how this is accomplished
   177    further depends on the visual class, since some visuals have
   178    immutable colormaps which contain color cells with pre-defined
   179    values, while others have colormaps where the color cells are
   180    dynamically allocated by individual X clients.
   181 
   182    With visuals that have a visual class of StaticColor and StaticGray
   183    (where the former is the case), the X server is asked to procure
   184    the pixel value of a color cell that contains the closest
   185    approximation of the color which Emacs wants.  On the other hand,
   186    when the visual class is DirectColor, PseudoColor, or GrayScale,
   187    where color cells are dynamically allocated by clients, Emacs asks
   188    the X server to allocate a color cell containing the desired color,
   189    and uses its pixel value.
   190 
   191    (If the color already exists, the X server returns an existing color
   192    cell, but increases its reference count, so it still has to be
   193    freed afterwards.)
   194 
   195    Otherwise, if no color could be allocated (due to the colormap
   196    being full), Emacs looks for a color cell inside the colormap
   197    closest to the desired color, and uses its pixel value instead.
   198 
   199    Since the capacity of a colormap is finite, X clients have to take
   200    special precautions in order to not allocate too many color cells
   201    that are never used.  Emacs allocates its color cells when a face
   202    is being realized or when a frame changes its foreground and
   203    background colors, and releases them alongside the face or frame.
   204    See calls to `unload_color' and `load_color' in xterm.c, xfaces.c
   205    and xfns.c for more details.
   206 
   207    The driving logic behind color allocation is in
   208    `x_alloc_nearest_color_1', while the optimization for TrueColor
   209    visuals is in `x_make_truecolor_pixel'.  Also see `x_query_colors`,
   210    which is used to determine the color values for given pixel
   211    values.
   212 
   213    In other window systems supported by Emacs, color allocation is
   214    handled by the window system itself, to whom Emacs simply passes 24
   215    (or 32-bit) RGB values.
   216 
   217    OPTIONAL FEATURES
   218 
   219    While X servers and client libraries tend to come with many
   220    extensions to the core X11R6 protocol, dependencies on anything
   221    other than the core X11R6 protocol and Xlib should be optional at
   222    both compile-time and runtime.  Emacs should also not crash
   223    regardless of what combination of X server and client-side features
   224    are present.  For example, if you are developing a feature that
   225    will need Xfixes, then add a test in configure.ac for the library
   226    at compile-time which defines `HAVE_XFIXES', like this:
   227 
   228      ### Use Xfixes (-lXfixes) if available
   229      HAVE_XFIXES=no
   230      if test "${HAVE_X11}" = "yes"; then
   231        XFIXES_REQUIRED=4.0.0
   232        XFIXES_MODULES="xfixes >= $XFIXES_REQUIRED"
   233        EMACS_CHECK_MODULES([XFIXES], [$XFIXES_MODULES])
   234        if test $HAVE_XFIXES = no; then
   235          # Test old way in case pkg-config doesn't have it (older machines).
   236          AC_CHECK_HEADER([X11/extensions/Xfixes.h],
   237            [AC_CHECK_LIB([Xfixes], [XFixesHideCursor], [HAVE_XFIXES=yes])])
   238          if test $HAVE_XFIXES = yes; then
   239            XFIXES_LIBS=-lXfixes
   240          fi
   241        fi
   242        if test $HAVE_XFIXES = yes; then
   243          AC_DEFINE([HAVE_XFIXES], [1],
   244            [Define to 1 if you have the Xfixes extension.])
   245        fi
   246      fi
   247      AC_SUBST([XFIXES_CFLAGS])
   248      AC_SUBST([XFIXES_LIBS])
   249 
   250   Then, make sure to adjust CFLAGS and LIBES in src/Makefile.in and
   251   add the new XFIXES_CFLAGS and XFIXES_LIBS variables to
   252   msdos/sed1v2.inp.  (The latter has to be adjusted for any new
   253   variables that are included in CFLAGS and LIBES even if the
   254   libraries are not used by the MS-DOS port.)
   255 
   256   Finally, add some fields in `struct x_display_info' which specify
   257   the major and minor versions of the extension, and whether or not to
   258   support them.  They (and their accessors) should be protected by the
   259   `HAVE_XFIXES' preprocessor conditional.  Then, these fields should
   260   be set in `x_term_init', and all Xfixes calls must be protected by
   261   not only the preprocessor conditional, but also by checks against
   262   those variables.
   263 
   264   X TOOLKIT SUPPORT
   265 
   266   Emacs supports being built with many different toolkits (and also no
   267   toolkit at all), which provide decorations such as menu bars and
   268   scroll bars, along with handy features like file panels, dialog
   269   boxes, font panels, and popup menus.  Those configurations can
   270   roughly be classified as belonging to one of three categories:
   271 
   272     - Using no toolkit at all.
   273     - Using the X Toolkit Intrinsics (Xt).
   274     - Using GTK.
   275 
   276   The no toolkit configuration is the simplest: no toolkit widgets are
   277   used, Emacs uses its own implementation of scroll bars, and the
   278   XMenu library that came with X11R2 and earlier versions of X is used
   279   for popup menus.  There is also no complicated window structure to
   280   speak of.
   281 
   282   The Xt configurations come in either the Lucid or Motif flavors.
   283   The former utilizes Emacs's own Xt-based Lucid widget library for
   284   menus, and Xaw (or derivatives such as neXTaw and Xaw3d) for dialog
   285   boxes and, optionally, scroll bars.  It does not support file
   286   panels.  The latter uses either Motif or LessTif for menu bars,
   287   popup menus, dialogs and file panels.
   288 
   289   The GTK configurations come in the GTK+ 2 or GTK 3 configurations,
   290   where the toolkit provides all the aforementioned decorations and
   291   features.  They work mostly the same, though GTK 3 has various small
   292   annoyances that complicate maintenance.
   293 
   294   All of those configurations have various special technicalities
   295   about event handling and the layout of windows inside a frame that
   296   must be kept in mind when writing X code which is run on all of
   297   them.
   298 
   299   The no toolkit configuration has no noteworthy aspects about the
   300   layout of windows inside a frame, since each frame has only one
   301   associated window aside from scroll bars.  However, in the Xt
   302   configurations, every widget is a separate window, and there are
   303   quite a few widgets.  The "outer widget", a widget of class
   304   ApplicationShell, is the top-level window of a frame.  Its window is
   305   accessed via the macro `FRAME_OUTER_WINDOW'.  The "edit widget", a
   306   widget class of EmacsFrame, is a child of the outer widget that
   307   controls the size of a frame as known to Emacs, and is the widget
   308   that Emacs draws to during display operations.  The "menu bar
   309   widget" is the widget holding the menu bar.
   310 
   311   Special care must be taken when performing operations on a frame.
   312   Properties that are used by the window manager, for example, must be
   313   set on the outer widget.  Drawing, on the other hand, must be done
   314   to the edit widget, and button press events on the menu bar widget
   315   must be redirected and not sent to Xt until the Lisp code is run to
   316   update the menu bar.
   317 
   318   The EmacsFrame widget is specific to Emacs and is implemented in
   319   widget.c.  See that file for more details.
   320 
   321   In the GTK configurations, GTK widgets do not necessarily correspond
   322   to X windows, since the toolkit might decide to keep only a
   323   client-side record of the widgets for performance reasons.
   324 
   325   Because the GtkFixed widget that holds the "edit area" might not
   326   correspond to an X window, drawing operations may be directly
   327   performed on the outer window, with special care taken to not
   328   overwrite the surrounding GTK widgets.  This also means that the
   329   only important window for most purposes is the outer window, which
   330   on GTK builds can usually be accessed using the macro
   331   `FRAME_X_WINDOW'.
   332 
   333   How `handle_one_xevent' is called also depends on the configuration.
   334   Without a toolkit, Emacs performs all event processing by itself,
   335   running XPending and XNextEvent in a loop whenever there is input,
   336   passing the event to `handle_one_xevent'.
   337 
   338   When using Xt, the same is performed, but `handle_one_xevent' may
   339   also decide to call XtDispatchEvent on an event after Emacs finishes
   340   processing it.
   341 
   342   When using GTK, however, `handle_one_xevent' is called from an event
   343   filter installed on the GTK event loop.  Unless the event filter
   344   elects to drop the event, it will be passed to GTK right after
   345   leaving the event filter.
   346 
   347   Fortunately, `handle_one_xevent' is provided a `*finish' parameter
   348   that abstracts away all these details.  If it is `X_EVENT_DROP',
   349   then the event will not be dispatched to Xt or utilized by GTK.
   350   Code inside `handle_one_xevent' should thus avoid making assumptions
   351   about the event dispatch mechanism and use that parameter
   352   instead.
   353 
   354   FRAME RESIZING
   355 
   356   In the following explanations "frame size" refers to the "native
   357   size" of a frame as reported by the (frame.h) macros
   358   FRAME_PIXEL_WIDTH and FRAME_PIXEL_HEIGHT.  These specify the size of
   359   a frame as the values passed to/received from a toolkit and the
   360   window manager.  The "text size" Emacs Lisp code uses in functions
   361   like 'set-frame-size' or sees in the ‘width’ and 'height' frame
   362   parameters is only loosely related to the native size.  The
   363   necessary translations are provided by the macros
   364   FRAME_TEXT_TO_PIXEL_WIDTH and FRAME_TEXT_TO_PIXEL_HEIGHT as well as
   365   FRAME_PIXEL_TO_TEXT_WIDTH and FRAME_PIXEL_TO_TEXT_HEIGHT (in
   366   frame.h).
   367 
   368   Lisp functions may ask for resizing a frame either explicitly, using
   369   one of the interfaces provided for that purpose like, for example,
   370   'set-frame-size' or changing the 'height' or 'width' parameter of
   371   that frame, or implicitly, for example, by turning off/on or
   372   changing the width of fringes or scroll bars for that frame.  Any
   373   such request passes through the routine 'adjust_frame_size' (in
   374   frame.c) which decides, among others, whether the native frame size
   375   would really change and whether it is allowed to change it at that
   376   moment.  Only if 'adjust_frame_size' decides that the corresponding
   377   terminal's 'set_window_size_hook' may be run, it will dispatch
   378   execution to the appropriate function which, for X builds, is
   379   'x_set_window_size' in this file.
   380 
   381   For GTK builds, 'x_set_window_size' calls 'xg_frame_set_char_size'
   382   in gtkutil.c if the frame has an edit widget and
   383   'x_set_window_size_1' in this file otherwise.  For non-GTK builds,
   384   'x_set_window_size' always calls 'x_set_window_size_1' directly.
   385 
   386   'xg_frame_set_char_size' calls the GTK function 'gtk_window_resize'
   387   for the frame's outer widget; x_set_window_size_1 calls the Xlib
   388   function 'XResizeWindow' instead.  In either case, if Emacs thinks
   389   that the frame is visible, it will wait for a ConfigureNotify event
   390   (see below) to occur within a timeout of 'x-wait-for-event-timeout'
   391   (the default is 0.1 seconds).  If Emacs thinks that the frame is not
   392   visible, it calls 'adjust_frame_size' to run 'resize_frame_windows'
   393   (see below) and hopes for the best.
   394 
   395   Note that if Emacs receives a ConfigureEvent in response to an
   396   earlier resize request, the sizes specified by that event are not
   397   necessarily the sizes Emacs requested.  Window manager and toolkit
   398   may override any of the requested sizes for their own reasons.
   399 
   400   On X, size notifications are received as ConfigureNotify events.
   401   The expected reaction to such an event on the Emacs side is to
   402   resize all Emacs windows that are on the frame referred to by the
   403   event.  Since resizing Emacs windows and redisplaying their buffers
   404   is a costly operation, Emacs may collapse several subsequent
   405   ConfigureNotify events into one to avoid that Emacs falls behind in
   406   user interactions like resizing a frame by dragging one of its
   407   borders with the mouse.
   408 
   409   Each ConfigureEvent event specifies a window, a width and a height.
   410   The event loop uses 'x_top_window_to_frame' to associate the window
   411   with its frame.  Once the frame has been identified, on GTK the
   412   event is dispatched to 'xg_frame_resized'.  On Motif/Lucid
   413   'x_window' has installed 'EmacsFrameResize' as the routine that
   414   handles resize events.  In either case, these routines end up
   415   calling the function 'change_frame_size' in dispnew.c.  On
   416   non-toolkit builds the effect is to call 'change_frame_size'
   417   directly from the event loop.  In either case, the value true is
   418   passed as the DELAY argument.
   419 
   420   'change_frame_size' is the central function to decide whether it is
   421   safe to process a resize request immediately or it has to be delayed
   422   (usually because its DELAY argument is true).  Since resizing a
   423   frame's windows may run arbitrary Lisp code, Emacs cannot generally
   424   process resize requests during redisplay and therefore has to queue
   425   them.  If processing the event must be delayed, the new sizes (that
   426   is, the ones requested by the ConfigureEvent) are stored in the
   427   new_width and new_height slots of the respective frame structure,
   428   possibly replacing ones that have been stored there upon the receipt
   429   of a preceding ConfigureEvent.
   430 
   431   Delayed size changes are applied eventually upon calls of the
   432   function 'do_pending_window_change' (in dispnew.c) which is called
   433   by the redisplay code at suitable spots where it's safe to change
   434   sizes.  'do_pending_window_change' calls 'change_frame_size' with
   435   its DELAY argument false in the hope that it is now safe to call the
   436   function 'resize_frame_windows' (in window.c) which is in charge of
   437   adjusting the sizes of all Emacs windows on the frame accordingly.
   438   Note that if 'resize_frame_windows' decides that the windows of a
   439   frame do not fit into the constraints set up by the new frame sizes,
   440   it will resize the windows to some minimum sizes with the effect
   441   that parts of the frame at the right and bottom will appear clipped
   442   off.
   443 
   444   In addition to explicitly passing width and height values in
   445   functions like 'gtk_window_resize' or 'XResizeWindow', Emacs also
   446   sets window manager size hints - a more implicit form of asking for
   447   the size Emacs would like its frames to assume.  Some of these hints
   448   only restate the size and the position explicitly requested for a
   449   frame.  Another hint specifies the increments in which the window
   450   manager should resize a frame to - either set to the default
   451   character size of a frame or to one pixel for a non-nil value of
   452   'frame-resize-pixelwise'.  See the function 'x_wm_set_size_hint' -
   453   in gtkutil.c for GTK and in this file for other builds - for the
   454   details.
   455 
   456   We have not discussed here a number of special issues like, for
   457   example, how to handle size requests and notifications for maximized
   458   and fullscreen frames or how to resize child frames.  Some of these
   459   require special treatment depending on the desktop or window manager
   460   used.
   461 
   462   One thing that might come handy when investigating problems wrt
   463   resizing frames is the variable 'frame-size-history'.  Setting this
   464   to a non-nil value, will cause Emacs to start recording frame size
   465   adjustments, usually specified by the function that asked for an
   466   adjustment, a sizes part that records the old and new values of the
   467   frame's width and height and maybe some additional information.  The
   468   internal function `frame--size-history' can then be used to display
   469   the value of this variable in a more readable form.
   470 
   471   FRAME RESIZE SYNCHRONIZATION
   472 
   473   The X window system operates asynchronously.  That is to say, the
   474   window manager and X server might think a window has been resized
   475   before Emacs has a chance to process the ConfigureNotify event that
   476   was sent.
   477 
   478   When a compositing manager is present, and the X server and Emacs
   479   both support the X synchronization extension, the semi-standard
   480   frame synchronization protocol can be used to notify the compositing
   481   manager of when Emacs has actually finished redisplaying the
   482   contents of a frame after a resize.  The compositing manager will
   483   customarily then postpone displaying the contents of the frame until
   484   the redisplay is complete.
   485 
   486   Emacs announces support for this protocol by creating an X
   487   server-side counter object, and setting it as the
   488   `_NET_WM_SYNC_REQUEST_COUNTER' property of the frame's top-level
   489   window.  The window manager then initiates the synchronized resize
   490   process by sending Emacs a ClientMessage event before the
   491   ConfigureNotify event where:
   492 
   493     type = ClientMessage
   494     window = the respective client window
   495     message_type = WM_PROTOCOLS
   496     format = 32
   497     data.l[0] = _NET_WM_SYNC_REQUEST
   498     data.l[1] = timestamp
   499     data.l[2] = low 32 bits of a provided frame counter value
   500     data.l[3] = high 32 bits of a provided frame counter value
   501     data.l[4] = 1 if the extended frame counter should be updated,
   502     otherwise 0
   503 
   504   Upon receiving such an event, Emacs constructs and saves a counter
   505   value from the provided low and high 32 bits.  Then, when the
   506   display engine tells us that a frame has been completely updated
   507   (presumably because of a redisplay caused by a ConfigureNotify
   508   event), we set the counter to the saved value, telling the
   509   compositing manager that the contents of the window now accurately
   510   reflect the new size.  The compositing manager will then display the
   511   contents of the window, and the window manager might also postpone
   512   updating the window decorations until this moment.
   513 
   514   DRAG AND DROP
   515 
   516   Drag and drop in Emacs is implemented in two ways, depending on
   517   which side initiated the drag-and-drop operation.  When another X
   518   client initiates a drag, and the user drops something on Emacs, a
   519   `drag-n-drop-event' is sent with the contents of the ClientMessage,
   520   and further processing (i.e. retrieving selection contents and
   521   replying to the initiating client) is performed from Lisp inside
   522   `x-dnd.el'.
   523 
   524   However, dragging contents from Emacs is implemented almost entirely
   525   in C.  X Windows has several competing drag-and-drop protocols, of
   526   which Emacs supports two on the C level: the XDND protocol (see
   527   https://freedesktop.org/wiki/Specifications/XDND) and the Motif drag
   528   and drop protocols.  These protocols are based on the initiator
   529   owning a special selection, specifying an action the recipient
   530   should perform, grabbing the mouse, and sending various different
   531   client messages to the toplevel window underneath the mouse as it
   532   moves, or when buttons are released.
   533 
   534   The Lisp interface to drag-and-drop is synchronous, and involves
   535   running a nested event loop with some global state until the drag
   536   finishes.  When the mouse moves, Emacs looks up the toplevel window
   537   underneath the pointer (the target window) either using a cache
   538   provided by window managers that support the
   539   _NET_WM_CLIENT_LIST_STACKING root window property, or by calling
   540   XTranslateCoordinates in a loop until a toplevel window is found,
   541   and sends various entry, exit, or motion events to the window
   542   containing a list of targets the special selection can be converted
   543   to, and the chosen action that the recipient should perform.  The
   544   recipient can then send messages in reply detailing the action it
   545   has actually chosen to perform.  Finally, when the mouse buttons are
   546   released over the recipient window, Emacs sends a "drop" message to
   547   the target window, waits for a reply, and returns the action
   548   selected by the recipient to the Lisp code that initiated the
   549   drag-and-drop operation.
   550 
   551   When a drop happens on a window not supporting any protocol
   552   implemented on the C level, the function inside
   553   `x-dnd-unsupported-drop-function' is called with some parameters of
   554   the drop.  If it returns non-nil, then Emacs tries to simulate a
   555   drop happening with the primary selection and synthetic button
   556   events (see `x_dnd_do_unsupported_drop').  That function implements
   557   the OffiX drag-and-drop protocol by default.  See
   558   `x-dnd-handle-unsupported-drop' in `x-dnd.el' for more details.  */
   559 
   560 #include <config.h>
   561 #include <stdlib.h>
   562 #include <math.h>
   563 #include <signal.h>
   564 
   565 #include "lisp.h"
   566 #include "blockinput.h"
   567 #include "sysstdio.h"
   568 
   569 /* This may include sys/types.h, and that somehow loses
   570    if this is not done before the other system files.  */
   571 #include "xterm.h"
   572 #include <X11/cursorfont.h>
   573 
   574 #ifdef USE_XCB
   575 #include <xcb/xproto.h>
   576 #include <xcb/xcb.h>
   577 #include <xcb/xcb_aux.h>
   578 #endif
   579 
   580 /* If we have Xfixes extension, use it for pointer blanking.  */
   581 #ifdef HAVE_XFIXES
   582 #include <X11/extensions/Xfixes.h>
   583 #endif
   584 
   585 #ifdef HAVE_XDBE
   586 #include <X11/extensions/Xdbe.h>
   587 #endif
   588 
   589 #ifdef HAVE_XINPUT2
   590 #include <X11/extensions/XInput2.h>
   591 #endif
   592 
   593 #ifdef HAVE_XRANDR
   594 #include <X11/extensions/Xrandr.h>
   595 #endif
   596 
   597 #ifdef HAVE_XSYNC
   598 #include <X11/extensions/sync.h>
   599 #endif
   600 
   601 #ifdef HAVE_XINERAMA
   602 #include <X11/extensions/Xinerama.h>
   603 #endif
   604 
   605 #ifdef HAVE_XCOMPOSITE
   606 #include <X11/extensions/Xcomposite.h>
   607 #endif
   608 
   609 #ifdef HAVE_XSHAPE
   610 #include <X11/extensions/shape.h>
   611 #endif
   612 
   613 #ifdef HAVE_XCB_SHAPE
   614 #include <xcb/shape.h>
   615 #endif
   616 
   617 /* Load sys/types.h if not already loaded.
   618    In some systems loading it twice is suicidal.  */
   619 #ifndef makedev
   620 #include <sys/types.h>
   621 #endif /* makedev */
   622 
   623 #include <sys/ioctl.h>
   624 
   625 #include "systime.h"
   626 
   627 #include <fcntl.h>
   628 #include <errno.h>
   629 #include <sys/stat.h>
   630 #include <flexmember.h>
   631 #include <c-ctype.h>
   632 #include <byteswap.h>
   633 
   634 #include "character.h"
   635 #include "coding.h"
   636 #include "composite.h"
   637 #include "frame.h"
   638 #include "dispextern.h"
   639 #include "xwidget.h"
   640 #include "fontset.h"
   641 #include "termhooks.h"
   642 #include "termopts.h"
   643 #include "termchar.h"
   644 #include "emacs-icon.h"
   645 #include "buffer.h"
   646 #include "window.h"
   647 #include "keyboard.h"
   648 #include "atimer.h"
   649 #include "font.h"
   650 #include "xsettings.h"
   651 #include "sysselect.h"
   652 #include "menu.h"
   653 #include "pdumper.h"
   654 
   655 #ifdef USE_X_TOOLKIT
   656 #include <X11/Shell.h>
   657 #include <X11/ShellP.h>
   658 #endif
   659 
   660 #include <unistd.h>
   661 
   662 #ifdef USE_GTK
   663 #include "gtkutil.h"
   664 #ifdef HAVE_GTK3
   665 #include <X11/Xproto.h>
   666 #endif
   667 #endif
   668 
   669 #if defined (USE_LUCID) || defined (USE_MOTIF)
   670 #include "../lwlib/xlwmenu.h"
   671 #endif
   672 
   673 #ifdef HAVE_XWIDGETS
   674 #include <cairo-xlib.h>
   675 #endif
   676 
   677 #ifdef USE_MOTIF
   678 #include <Xm/Xm.h>
   679 #include <Xm/CascadeB.h>
   680 #endif
   681 
   682 #ifdef USE_X_TOOLKIT
   683 
   684 /* Include toolkit specific headers for the scroll bar widget.  */
   685 #ifdef USE_TOOLKIT_SCROLL_BARS
   686 #if defined USE_MOTIF
   687 #include <Xm/ScrollBar.h>
   688 #else /* !USE_MOTIF i.e. use Xaw */
   689 
   690 #ifdef HAVE_XAW3D
   691 #include <X11/Xaw3d/Simple.h>
   692 #include <X11/Xaw3d/Scrollbar.h>
   693 #include <X11/Xaw3d/ThreeD.h>
   694 #else /* !HAVE_XAW3D */
   695 #include <X11/Xaw/Simple.h>
   696 #include <X11/Xaw/Scrollbar.h>
   697 #endif /* !HAVE_XAW3D */
   698 #ifndef XtNpickTop
   699 #define XtNpickTop "pickTop"
   700 #endif /* !XtNpickTop */
   701 #endif /* !USE_MOTIF */
   702 #endif /* USE_TOOLKIT_SCROLL_BARS */
   703 
   704 #endif /* USE_X_TOOLKIT */
   705 
   706 #ifdef USE_X_TOOLKIT
   707 #include "widget.h"
   708 #ifndef XtNinitialState
   709 #define XtNinitialState "initialState"
   710 #endif
   711 #endif
   712 
   713 #ifdef USE_GTK
   714 #include <xgselect.h>
   715 #endif
   716 
   717 #include "bitmaps/gray.xbm"
   718 
   719 #ifdef HAVE_XKB
   720 #include <X11/XKBlib.h>
   721 #endif
   722 
   723 /* Although X11/Xlib.h commonly defines the types XErrorHandler and
   724    XIOErrorHandler, they are not in the Xlib spec, so for portability
   725    define and use names with an Emacs_ prefix instead.  */
   726 typedef int (*Emacs_XErrorHandler) (Display *, XErrorEvent *);
   727 typedef int (*Emacs_XIOErrorHandler) (Display *);
   728 
   729 #if defined USE_XCB && defined USE_CAIRO_XCB
   730 #define USE_CAIRO_XCB_SURFACE
   731 #endif
   732 
   733 /* Default to using XIM if available.  */
   734 #ifdef USE_XIM
   735 bool use_xim = true;
   736 #else
   737 bool use_xim = false;  /* configure --without-xim */
   738 #endif
   739 
   740 #if XCB_SHAPE_MAJOR_VERSION > 1       \
   741   || (XCB_SHAPE_MAJOR_VERSION == 1 && \
   742       XCB_SHAPE_MINOR_VERSION >= 1)
   743 #define HAVE_XCB_SHAPE_INPUT_RECTS
   744 #endif
   745 
   746 #ifdef USE_GTK
   747 /* GTK can't tolerate a call to `handle_interrupt' inside an event
   748    signal handler, but we have to store input events inside the
   749    handler for native input to work.
   750 
   751    This acts as a `hold_quit', and it is stored in the keyboard buffer
   752    (thereby causing the call to `handle_interrupt') after the GTK
   753    signal handler exits and control returns to XTread_socket.  */
   754 struct input_event xg_pending_quit_event = { .kind = NO_EVENT };
   755 #endif
   756 
   757 /* Non-zero means that a HELP_EVENT has been generated since Emacs
   758    start.  */
   759 
   760 static bool any_help_event_p;
   761 
   762 /* This is a chain of structures for all the X displays currently in
   763    use.  */
   764 
   765 struct x_display_info *x_display_list;
   766 
   767 #ifdef USE_X_TOOLKIT
   768 
   769 /* The application context for Xt use.  */
   770 XtAppContext Xt_app_con;
   771 static String Xt_default_resources[] = {0};
   772 
   773 /* Non-zero means user is interacting with a toolkit scroll bar.  */
   774 static bool toolkit_scroll_bar_interaction;
   775 
   776 #endif /* USE_X_TOOLKIT */
   777 
   778 /* Non-zero timeout value means ignore next mouse click if it arrives
   779    before that timeout elapses (i.e. as part of the same sequence of
   780    events resulting from clicking on a frame to select it).  */
   781 
   782 static Time ignore_next_mouse_click_timeout;
   783 
   784 /* The display that ignore_next_mouse_click_timeout applies to.  */
   785 
   786 static struct x_display_info *mouse_click_timeout_display;
   787 
   788 /* Used locally within XTread_socket.  */
   789 
   790 static int x_noop_count;
   791 
   792 #ifdef USE_GTK
   793 /* The name of the Emacs icon file.  */
   794 static Lisp_Object xg_default_icon_file;
   795 #endif
   796 
   797 #ifdef HAVE_X_I18N
   798 /* Some functions take this as char *, not const char *.  */
   799 static char emacs_class[] = EMACS_CLASS;
   800 #endif
   801 
   802 #ifdef USE_GTK
   803 static int current_count;
   804 static int current_finish;
   805 static struct input_event *current_hold_quit;
   806 #endif
   807 
   808 #ifdef HAVE_XINPUT2
   809 #ifndef X_XIGrabDevice
   810 #define X_XIGrabDevice 51
   811 #endif
   812 
   813 #ifndef X_XIUngrabDevice
   814 #define X_XIUngrabDevice 52
   815 #endif
   816 
   817 #ifndef X_XIAllowEvents
   818 #define X_XIAllowEvents 53
   819 #endif
   820 #endif
   821 
   822 /* Queue selection requests in `pending_selection_requests' if more
   823    than 0.  */
   824 static int x_use_pending_selection_requests;
   825 
   826 /* Like `next_kbd_event', but for use in X code.  */
   827 #define X_NEXT_KBD_EVENT(ptr) \
   828   ((ptr) == kbd_buffer + KBD_BUFFER_SIZE - 1 ? kbd_buffer : (ptr) + 1)
   829 
   830 static void x_push_selection_request (struct selection_input_event *);
   831 
   832 /* Defer selection requests.  Between this and
   833    x_release_selection_requests, any selection requests can be
   834    processed by calling `x_handle_pending_selection_requests'.
   835 
   836    Also run through and queue all the selection events already in the
   837    keyboard buffer.  */
   838 void
   839 x_defer_selection_requests (void)
   840 {
   841   union buffered_input_event *event;
   842   bool between;
   843 
   844   between = false;
   845 
   846   block_input ();
   847   if (!x_use_pending_selection_requests)
   848     {
   849       event = kbd_fetch_ptr;
   850 
   851       while (event != kbd_store_ptr)
   852         {
   853           if (event->ie.kind == SELECTION_REQUEST_EVENT
   854               || event->ie.kind == SELECTION_CLEAR_EVENT)
   855             {
   856               x_push_selection_request (&event->sie);
   857 
   858               /* Mark this selection event as invalid.   */
   859               SELECTION_EVENT_DPYINFO (&event->sie) = NULL;
   860 
   861               /* Move the kbd_fetch_ptr along if doing so would not
   862                  result in any other events being skipped.  This
   863                  avoids exhausting the keyboard buffer with some
   864                  over-enthusiastic clipboard managers.  */
   865               if (!between)
   866                 {
   867                   kbd_fetch_ptr = X_NEXT_KBD_EVENT (event);
   868 
   869                   /* `detect_input_pending' will then recompute
   870                      whether or not pending input events exist.  */
   871                   input_pending = false;
   872                 }
   873             }
   874           else
   875             between = true;
   876 
   877           event = X_NEXT_KBD_EVENT (event);
   878         }
   879     }
   880 
   881   x_use_pending_selection_requests++;
   882   unblock_input ();
   883 }
   884 
   885 static void
   886 x_release_selection_requests (void)
   887 {
   888   x_use_pending_selection_requests--;
   889 }
   890 
   891 void
   892 x_release_selection_requests_and_flush (void)
   893 {
   894   x_release_selection_requests ();
   895 
   896   if (!x_use_pending_selection_requests)
   897     x_handle_pending_selection_requests ();
   898 }
   899 
   900 struct x_selection_request_event
   901 {
   902   /* The selection request event.  */
   903   struct selection_input_event se;
   904 
   905   /* The next unprocessed selection request event.  */
   906   struct x_selection_request_event *next;
   907 };
   908 
   909 /* Chain of unprocessed selection request events.  Used to handle
   910    selection requests inside long-lasting modal event loops, such as
   911    the drag-and-drop loop.  */
   912 
   913 struct x_selection_request_event *pending_selection_requests;
   914 
   915 struct x_atom_ref
   916 {
   917   /* Atom name.  */
   918   const char *name;
   919 
   920   /* Offset of atom in the display info structure.  */
   921   int offset;
   922 };
   923 
   924 /* List of all atoms that should be interned when connecting to a
   925    display.  */
   926 static const struct x_atom_ref x_atom_refs[] =
   927   {
   928 #define ATOM_REFS_INIT(string, member)                          \
   929     { string, offsetof (struct x_display_info, member) },
   930     ATOM_REFS_INIT ("WM_PROTOCOLS", Xatom_wm_protocols)
   931     ATOM_REFS_INIT ("WM_TAKE_FOCUS", Xatom_wm_take_focus)
   932     ATOM_REFS_INIT ("WM_SAVE_YOURSELF", Xatom_wm_save_yourself)
   933     ATOM_REFS_INIT ("WM_DELETE_WINDOW", Xatom_wm_delete_window)
   934     ATOM_REFS_INIT ("WM_CHANGE_STATE", Xatom_wm_change_state)
   935     ATOM_REFS_INIT ("WM_STATE", Xatom_wm_state)
   936     ATOM_REFS_INIT ("WM_CONFIGURE_DENIED", Xatom_wm_configure_denied)
   937     ATOM_REFS_INIT ("WM_MOVED", Xatom_wm_window_moved)
   938     ATOM_REFS_INIT ("WM_CLIENT_LEADER", Xatom_wm_client_leader)
   939     ATOM_REFS_INIT ("WM_TRANSIENT_FOR", Xatom_wm_transient_for)
   940     ATOM_REFS_INIT ("Editres", Xatom_editres)
   941     ATOM_REFS_INIT ("CLIPBOARD", Xatom_CLIPBOARD)
   942     ATOM_REFS_INIT ("TIMESTAMP", Xatom_TIMESTAMP)
   943     ATOM_REFS_INIT ("TEXT", Xatom_TEXT)
   944     ATOM_REFS_INIT ("COMPOUND_TEXT", Xatom_COMPOUND_TEXT)
   945     ATOM_REFS_INIT ("UTF8_STRING", Xatom_UTF8_STRING)
   946     ATOM_REFS_INIT ("DELETE", Xatom_DELETE)
   947     ATOM_REFS_INIT ("MULTIPLE", Xatom_MULTIPLE)
   948     ATOM_REFS_INIT ("INCR", Xatom_INCR)
   949     ATOM_REFS_INIT ("_EMACS_TMP_",  Xatom_EMACS_TMP)
   950     ATOM_REFS_INIT ("_EMACS_SERVER_TIME_PROP", Xatom_EMACS_SERVER_TIME_PROP)
   951     ATOM_REFS_INIT ("TARGETS", Xatom_TARGETS)
   952     ATOM_REFS_INIT ("NULL", Xatom_NULL)
   953     ATOM_REFS_INIT ("ATOM", Xatom_ATOM)
   954     ATOM_REFS_INIT ("ATOM_PAIR", Xatom_ATOM_PAIR)
   955     ATOM_REFS_INIT ("CLIPBOARD_MANAGER", Xatom_CLIPBOARD_MANAGER)
   956     ATOM_REFS_INIT ("_XEMBED_INFO", Xatom_XEMBED_INFO)
   957     ATOM_REFS_INIT ("_MOTIF_WM_HINTS", Xatom_MOTIF_WM_HINTS)
   958     ATOM_REFS_INIT ("_EMACS_DRAG_ATOM", Xatom_EMACS_DRAG_ATOM)
   959     /* For properties of font.  */
   960     ATOM_REFS_INIT ("PIXEL_SIZE", Xatom_PIXEL_SIZE)
   961     ATOM_REFS_INIT ("AVERAGE_WIDTH", Xatom_AVERAGE_WIDTH)
   962     ATOM_REFS_INIT ("_MULE_BASELINE_OFFSET", Xatom_MULE_BASELINE_OFFSET)
   963     ATOM_REFS_INIT ("_MULE_RELATIVE_COMPOSE", Xatom_MULE_RELATIVE_COMPOSE)
   964     ATOM_REFS_INIT ("_MULE_DEFAULT_ASCENT", Xatom_MULE_DEFAULT_ASCENT)
   965     /* Ghostscript support.  */
   966     ATOM_REFS_INIT ("DONE", Xatom_DONE)
   967     ATOM_REFS_INIT ("PAGE", Xatom_PAGE)
   968     ATOM_REFS_INIT ("_EMACS_SCROLLBAR", Xatom_Scrollbar)
   969     ATOM_REFS_INIT ("_EMACS_HORIZONTAL_SCROLLBAR", Xatom_Horizontal_Scrollbar)
   970     ATOM_REFS_INIT ("_XEMBED", Xatom_XEMBED)
   971     /* EWMH */
   972     ATOM_REFS_INIT ("_NET_WM_STATE", Xatom_net_wm_state)
   973     ATOM_REFS_INIT ("_NET_WM_STATE_FULLSCREEN", Xatom_net_wm_state_fullscreen)
   974     ATOM_REFS_INIT ("_NET_WM_STATE_MAXIMIZED_HORZ",
   975                     Xatom_net_wm_state_maximized_horz)
   976     ATOM_REFS_INIT ("_NET_WM_STATE_MAXIMIZED_VERT",
   977                     Xatom_net_wm_state_maximized_vert)
   978     ATOM_REFS_INIT ("_NET_WM_STATE_STICKY", Xatom_net_wm_state_sticky)
   979     ATOM_REFS_INIT ("_NET_WM_STATE_SHADED", Xatom_net_wm_state_shaded)
   980     ATOM_REFS_INIT ("_NET_WM_STATE_HIDDEN", Xatom_net_wm_state_hidden)
   981     ATOM_REFS_INIT ("_NET_WM_WINDOW_TYPE", Xatom_net_window_type)
   982     ATOM_REFS_INIT ("_NET_WM_WINDOW_TYPE_TOOLTIP",
   983                     Xatom_net_window_type_tooltip)
   984     ATOM_REFS_INIT ("_NET_WM_ICON_NAME", Xatom_net_wm_icon_name)
   985     ATOM_REFS_INIT ("_NET_WM_NAME", Xatom_net_wm_name)
   986     ATOM_REFS_INIT ("_NET_SUPPORTED",  Xatom_net_supported)
   987     ATOM_REFS_INIT ("_NET_SUPPORTING_WM_CHECK", Xatom_net_supporting_wm_check)
   988     ATOM_REFS_INIT ("_NET_WM_WINDOW_OPACITY", Xatom_net_wm_window_opacity)
   989     ATOM_REFS_INIT ("_NET_ACTIVE_WINDOW", Xatom_net_active_window)
   990     ATOM_REFS_INIT ("_NET_FRAME_EXTENTS", Xatom_net_frame_extents)
   991     ATOM_REFS_INIT ("_NET_CURRENT_DESKTOP", Xatom_net_current_desktop)
   992     ATOM_REFS_INIT ("_NET_WORKAREA", Xatom_net_workarea)
   993     ATOM_REFS_INIT ("_NET_WM_SYNC_REQUEST", Xatom_net_wm_sync_request)
   994     ATOM_REFS_INIT ("_NET_WM_SYNC_REQUEST_COUNTER", Xatom_net_wm_sync_request_counter)
   995     ATOM_REFS_INIT ("_NET_WM_SYNC_FENCES", Xatom_net_wm_sync_fences)
   996     ATOM_REFS_INIT ("_NET_WM_BYPASS_COMPOSITOR", Xatom_net_wm_bypass_compositor)
   997     ATOM_REFS_INIT ("_NET_WM_FRAME_DRAWN", Xatom_net_wm_frame_drawn)
   998     ATOM_REFS_INIT ("_NET_WM_FRAME_TIMINGS", Xatom_net_wm_frame_timings)
   999     ATOM_REFS_INIT ("_NET_WM_USER_TIME", Xatom_net_wm_user_time)
  1000     ATOM_REFS_INIT ("_NET_WM_USER_TIME_WINDOW", Xatom_net_wm_user_time_window)
  1001     ATOM_REFS_INIT ("_NET_CLIENT_LIST_STACKING", Xatom_net_client_list_stacking)
  1002     /* Session management */
  1003     ATOM_REFS_INIT ("SM_CLIENT_ID", Xatom_SM_CLIENT_ID)
  1004     ATOM_REFS_INIT ("_XSETTINGS_SETTINGS", Xatom_xsettings_prop)
  1005     ATOM_REFS_INIT ("MANAGER", Xatom_xsettings_mgr)
  1006     ATOM_REFS_INIT ("_NET_WM_STATE_SKIP_TASKBAR", Xatom_net_wm_state_skip_taskbar)
  1007     ATOM_REFS_INIT ("_NET_WM_STATE_ABOVE", Xatom_net_wm_state_above)
  1008     ATOM_REFS_INIT ("_NET_WM_STATE_BELOW", Xatom_net_wm_state_below)
  1009     ATOM_REFS_INIT ("_NET_WM_OPAQUE_REGION", Xatom_net_wm_opaque_region)
  1010     ATOM_REFS_INIT ("_NET_WM_PING", Xatom_net_wm_ping)
  1011     ATOM_REFS_INIT ("_NET_WM_PID", Xatom_net_wm_pid)
  1012 #ifdef HAVE_XKB
  1013     ATOM_REFS_INIT ("Meta", Xatom_Meta)
  1014     ATOM_REFS_INIT ("Super", Xatom_Super)
  1015     ATOM_REFS_INIT ("Hyper", Xatom_Hyper)
  1016     ATOM_REFS_INIT ("ShiftLock", Xatom_ShiftLock)
  1017     ATOM_REFS_INIT ("Alt", Xatom_Alt)
  1018 #endif
  1019     /* DND source.  */
  1020     ATOM_REFS_INIT ("XdndAware", Xatom_XdndAware)
  1021     ATOM_REFS_INIT ("XdndSelection", Xatom_XdndSelection)
  1022     ATOM_REFS_INIT ("XdndTypeList", Xatom_XdndTypeList)
  1023     ATOM_REFS_INIT ("XdndActionCopy", Xatom_XdndActionCopy)
  1024     ATOM_REFS_INIT ("XdndActionMove", Xatom_XdndActionMove)
  1025     ATOM_REFS_INIT ("XdndActionLink", Xatom_XdndActionLink)
  1026     ATOM_REFS_INIT ("XdndActionAsk", Xatom_XdndActionAsk)
  1027     ATOM_REFS_INIT ("XdndActionPrivate", Xatom_XdndActionPrivate)
  1028     ATOM_REFS_INIT ("XdndActionList", Xatom_XdndActionList)
  1029     ATOM_REFS_INIT ("XdndActionDescription", Xatom_XdndActionDescription)
  1030     ATOM_REFS_INIT ("XdndProxy", Xatom_XdndProxy)
  1031     ATOM_REFS_INIT ("XdndEnter", Xatom_XdndEnter)
  1032     ATOM_REFS_INIT ("XdndPosition", Xatom_XdndPosition)
  1033     ATOM_REFS_INIT ("XdndStatus", Xatom_XdndStatus)
  1034     ATOM_REFS_INIT ("XdndLeave", Xatom_XdndLeave)
  1035     ATOM_REFS_INIT ("XdndDrop", Xatom_XdndDrop)
  1036     ATOM_REFS_INIT ("XdndFinished", Xatom_XdndFinished)
  1037     /* XDS source and target.  */
  1038     ATOM_REFS_INIT ("XdndDirectSave0", Xatom_XdndDirectSave0)
  1039     ATOM_REFS_INIT ("XdndActionDirectSave", Xatom_XdndActionDirectSave)
  1040     ATOM_REFS_INIT ("text/plain", Xatom_text_plain)
  1041     /* Motif drop protocol support.  */
  1042     ATOM_REFS_INIT ("_MOTIF_DRAG_WINDOW", Xatom_MOTIF_DRAG_WINDOW)
  1043     ATOM_REFS_INIT ("_MOTIF_DRAG_TARGETS", Xatom_MOTIF_DRAG_TARGETS)
  1044     ATOM_REFS_INIT ("_MOTIF_DRAG_AND_DROP_MESSAGE",
  1045                     Xatom_MOTIF_DRAG_AND_DROP_MESSAGE)
  1046     ATOM_REFS_INIT ("_MOTIF_DRAG_INITIATOR_INFO",
  1047                     Xatom_MOTIF_DRAG_INITIATOR_INFO)
  1048     ATOM_REFS_INIT ("_MOTIF_DRAG_RECEIVER_INFO",
  1049                     Xatom_MOTIF_DRAG_RECEIVER_INFO)
  1050     ATOM_REFS_INIT ("XmTRANSFER_SUCCESS", Xatom_XmTRANSFER_SUCCESS)
  1051     ATOM_REFS_INIT ("XmTRANSFER_FAILURE", Xatom_XmTRANSFER_FAILURE)
  1052     /* Old OffiX (a.k.a. old KDE) drop protocol support.  */
  1053     ATOM_REFS_INIT ("DndProtocol", Xatom_DndProtocol)
  1054     ATOM_REFS_INIT ("_DND_PROTOCOL", Xatom_DND_PROTOCOL)
  1055   };
  1056 
  1057 enum
  1058 {
  1059   X_EVENT_NORMAL,
  1060   X_EVENT_GOTO_OUT,
  1061   X_EVENT_DROP
  1062 };
  1063 
  1064 enum xembed_info
  1065   {
  1066     XEMBED_MAPPED = 1 << 0
  1067   };
  1068 
  1069 enum xembed_message
  1070   {
  1071     XEMBED_EMBEDDED_NOTIFY        = 0,
  1072     XEMBED_WINDOW_ACTIVATE        = 1,
  1073     XEMBED_WINDOW_DEACTIVATE      = 2,
  1074     XEMBED_REQUEST_FOCUS          = 3,
  1075     XEMBED_FOCUS_IN               = 4,
  1076     XEMBED_FOCUS_OUT              = 5,
  1077     XEMBED_FOCUS_NEXT             = 6,
  1078     XEMBED_FOCUS_PREV             = 7,
  1079 
  1080     XEMBED_MODALITY_ON            = 10,
  1081     XEMBED_MODALITY_OFF           = 11,
  1082     XEMBED_REGISTER_ACCELERATOR   = 12,
  1083     XEMBED_UNREGISTER_ACCELERATOR = 13,
  1084     XEMBED_ACTIVATE_ACCELERATOR   = 14
  1085   };
  1086 
  1087 static bool x_alloc_nearest_color_1 (Display *, Colormap, XColor *);
  1088 static void x_raise_frame (struct frame *);
  1089 static void x_lower_frame (struct frame *);
  1090 static int x_io_error_quitter (Display *);
  1091 static struct terminal *x_create_terminal (struct x_display_info *);
  1092 static void x_frame_rehighlight (struct x_display_info *);
  1093 
  1094 static void x_clip_to_row (struct window *, struct glyph_row *,
  1095                            enum glyph_row_area, GC);
  1096 static struct scroll_bar *x_window_to_scroll_bar (Display *, Window, int);
  1097 static struct frame *x_window_to_frame (struct x_display_info *, int);
  1098 static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *,
  1099                                         enum scroll_bar_part *,
  1100                                         Lisp_Object *, Lisp_Object *,
  1101                                         Time *);
  1102 static void x_horizontal_scroll_bar_report_motion (struct frame **, Lisp_Object *,
  1103                                                    enum scroll_bar_part *,
  1104                                                    Lisp_Object *, Lisp_Object *,
  1105                                                    Time *);
  1106 static bool x_handle_net_wm_state (struct frame *, const XPropertyEvent *);
  1107 static void x_check_fullscreen (struct frame *);
  1108 static void x_check_expected_move (struct frame *, int, int);
  1109 static void x_sync_with_move (struct frame *, int, int, bool);
  1110 #ifndef HAVE_XINPUT2
  1111 static int handle_one_xevent (struct x_display_info *,
  1112                               const XEvent *, int *,
  1113                               struct input_event *);
  1114 #else
  1115 static int handle_one_xevent (struct x_display_info *,
  1116                               XEvent *, int *,
  1117                               struct input_event *);
  1118 #endif
  1119 #if ! (defined USE_X_TOOLKIT || defined USE_MOTIF) && defined USE_GTK
  1120 static int x_dispatch_event (XEvent *, Display *);
  1121 #endif
  1122 static void x_wm_set_window_state (struct frame *, int);
  1123 static void x_wm_set_icon_pixmap (struct frame *, ptrdiff_t);
  1124 static void x_initialize (void);
  1125 
  1126 static bool x_get_current_wm_state (struct frame *, Window, int *, bool *, bool *);
  1127 static void x_update_opaque_region (struct frame *, XEvent *);
  1128 
  1129 #ifdef HAVE_X_I18N
  1130 static int x_filter_event (struct x_display_info *, XEvent *);
  1131 #endif
  1132 static void x_clean_failable_requests (struct x_display_info *);
  1133 
  1134 static struct frame *x_tooltip_window_to_frame (struct x_display_info *,
  1135                                                 Window, bool *);
  1136 static Window x_get_window_below (Display *, Window, int, int, int *, int *);
  1137 static void x_set_input_focus (struct x_display_info *, Window, Time);
  1138 
  1139 #ifndef USE_TOOLKIT_SCROLL_BARS
  1140 static void x_scroll_bar_redraw (struct scroll_bar *);
  1141 #endif
  1142 
  1143 /* Global state maintained during a drag-and-drop operation.  */
  1144 
  1145 /* Flag that indicates if a drag-and-drop operation is in progress.  */
  1146 bool x_dnd_in_progress;
  1147 
  1148 /* The frame where the drag-and-drop operation originated.  */
  1149 struct frame *x_dnd_frame;
  1150 
  1151 /* That frame, but set when x_dnd_waiting_for_finish is true.  Used to
  1152    prevent the frame from being deleted inside selection handlers and
  1153    other callbacks.  */
  1154 struct frame *x_dnd_finish_frame;
  1155 
  1156 /* Flag that indicates if a drag-and-drop operation is no longer in
  1157    progress, but the nested event loop should continue to run, because
  1158    handle_one_xevent is waiting for the drop target to return some
  1159    important information.  */
  1160 bool x_dnd_waiting_for_finish;
  1161 
  1162 /* Flag that means (when set in addition to
  1163    `x_dnd_waiting_for_finish') to run the unsupported drop function
  1164    with the given arguments.  */
  1165 static bool x_dnd_run_unsupported_drop_function;
  1166 
  1167 /* The "before"-time of the unsupported drop.  */
  1168 static Time x_dnd_unsupported_drop_time;
  1169 
  1170 /* The target window of the unsupported drop.  */
  1171 static Window x_dnd_unsupported_drop_window;
  1172 
  1173 /* The Lisp data associated with the unsupported drop function.  */
  1174 static Lisp_Object x_dnd_unsupported_drop_data;
  1175 
  1176 /* Whether or not to move the tooltip along with the mouse pointer
  1177    during drag-and-drop.  */
  1178 static bool x_dnd_update_tooltip;
  1179 
  1180 /* Monitor attribute list used for updating the tooltip position.  */
  1181 static Lisp_Object x_dnd_monitors;
  1182 
  1183 /* The display the drop target that is supposed to send information is
  1184    on.  */
  1185 static Display *x_dnd_finish_display;
  1186 
  1187 /* State of the Motif drop operation.
  1188 
  1189    0 means nothing has happened, i.e. the event loop should not wait
  1190    for the receiver to send any data.  1 means an XmDROP_START message
  1191    was sent to the target, but no response has yet been received.  2
  1192    means a response to our XmDROP_START message was received and the
  1193    target accepted the drop, so Emacs should start waiting for the
  1194    drop target to convert one of the special selections
  1195    XmTRANSFER_SUCCESS or XmTRANSFER_FAILURE.  */
  1196 static int x_dnd_waiting_for_motif_finish;
  1197 
  1198 /* The display the Motif drag receiver will send response data
  1199    from.  */
  1200 struct x_display_info *x_dnd_waiting_for_motif_finish_display;
  1201 
  1202 /* Whether or not F1 was pressed during the drag-and-drop operation.
  1203 
  1204    Motif programs rely on this to decide whether or not help
  1205    information about the drop site should be displayed.  */
  1206 static bool x_dnd_xm_use_help;
  1207 
  1208 /* Whether or not Motif drag initiator info was set up.  */
  1209 static bool x_dnd_motif_setup_p;
  1210 
  1211 /* The Motif drag atom used during the drag-and-drop operation.  */
  1212 static Atom x_dnd_motif_atom;
  1213 
  1214 /* The target window we are waiting for an XdndFinished message
  1215    from.  */
  1216 static Window x_dnd_pending_finish_target;
  1217 
  1218 /* The protocol version of that target window.  */
  1219 static int x_dnd_waiting_for_finish_proto;
  1220 
  1221 /* Whether or not it is OK for something to be dropped on the frame
  1222    where the drag-and-drop operation originated.  */
  1223 static bool x_dnd_allow_current_frame;
  1224 
  1225 /* Whether or not the `XdndTypeList' property has already been set on
  1226    the drag frame.  */
  1227 static bool x_dnd_init_type_lists;
  1228 
  1229 /* Whether or not to return a frame from `x_dnd_begin_drag_and_drop'.
  1230 
  1231    0 means to do nothing.  1 means to wait for the mouse to first exit
  1232    `x_dnd_frame'.  2 means to wait for the mouse to move onto a frame,
  1233    and 3 means to return `x_dnd_return_frame_object'.  */
  1234 static int x_dnd_return_frame;
  1235 
  1236 /* The frame that should be returned by
  1237    `x_dnd_begin_drag_and_drop'.  */
  1238 static struct frame *x_dnd_return_frame_object;
  1239 
  1240 /* The last drop target window the mouse pointer moved over.  This can
  1241    be different from `x_dnd_last_seen_toplevel' if that window had an
  1242    XdndProxy.  */
  1243 static Window x_dnd_last_seen_window;
  1244 
  1245 /* The last toplevel the mouse pointer moved over.  */
  1246 static Window x_dnd_last_seen_toplevel;
  1247 
  1248 /* The window where the drop happened.  Normally None, but it is set
  1249    when something is actually dropped.  */
  1250 static Window x_dnd_end_window;
  1251 
  1252 /* The XDND protocol version of `x_dnd_last_seen_window'.  -1 means it
  1253    did not support XDND.  */
  1254 static int x_dnd_last_protocol_version;
  1255 
  1256 /* Whether or not the last seen window is actually one of our
  1257    frames.  */
  1258 static bool x_dnd_last_window_is_frame;
  1259 
  1260 /* The Motif drag and drop protocol style of `x_dnd_last_seen_window'.
  1261    XM_DRAG_STYLE_NONE means the window does not support the Motif drag
  1262    or drop protocol.  XM_DRAG_STYLE_DROP_ONLY means the window does
  1263    not respond to any drag protocol messages, so only drops should be
  1264    sent.  Any other value means that the window supports both the drag
  1265    and drop protocols.  */
  1266 static int x_dnd_last_motif_style;
  1267 
  1268 /* The timestamp where Emacs last acquired ownership of the
  1269    `XdndSelection' selection.  */
  1270 static Time x_dnd_selection_timestamp;
  1271 
  1272 /* The drop target window to which the rectangle below applies.  */
  1273 static Window x_dnd_mouse_rect_target;
  1274 
  1275 /* A rectangle where XDND position messages should not be sent to the
  1276    drop target if the mouse pointer lies within.  */
  1277 static XRectangle x_dnd_mouse_rect;
  1278 
  1279 /* If not None, Emacs is waiting for an XdndStatus event from this
  1280    window.  */
  1281 static Window x_dnd_waiting_for_status_window;
  1282 
  1283 /* If .type != 0, an event that should be sent to .xclient.window
  1284    upon receiving an XdndStatus event from said window.  */
  1285 static XEvent x_dnd_pending_send_position;
  1286 
  1287 /* Whether or not that event corresponds to a button press.  */
  1288 static bool x_dnd_pending_send_position_button;
  1289 
  1290 /* The root-window position of that event.  */
  1291 static int x_dnd_pending_send_position_root_x;
  1292 
  1293 /* Likewise.  */
  1294 static int x_dnd_pending_send_position_root_y;
  1295 
  1296 /* If true, send a drop from `x_dnd_finish_frame' to the pending
  1297    status window after receiving all pending XdndStatus events.  */
  1298 static bool x_dnd_need_send_drop;
  1299 
  1300 /* The protocol version of any such drop.  */
  1301 static int x_dnd_send_drop_proto;
  1302 
  1303 /* The action the drop target actually chose to perform.
  1304 
  1305    Under XDND, this is set upon receiving the XdndFinished or
  1306    XdndStatus messages from the drop target.
  1307 
  1308    Under Motif, this is changed upon receiving a XmDROP_START message
  1309    in reply to our own.
  1310 
  1311    When dropping on a target that doesn't support any drag-and-drop
  1312    protocol, this is set to the atom XdndActionPrivate.  */
  1313 static Atom x_dnd_action;
  1314 
  1315 /* The symbol to return from `x-begin-drag' if non-nil.  Takes
  1316    precedence over `x_dnd_action`.  */
  1317 static Lisp_Object x_dnd_action_symbol;
  1318 
  1319 /* The action we want the drop target to perform.  The drop target may
  1320    elect to perform some different action, which is guaranteed to be
  1321    in `x_dnd_action' upon completion of a drop.  */
  1322 static Atom x_dnd_wanted_action;
  1323 
  1324 /* The set of optional actions available to a Motif drop target
  1325    computed at the start of the drag-and-drop operation.  */
  1326 static uint8_t x_dnd_motif_operations;
  1327 
  1328 /* The preferred optional action out of that set.  Only takes effect
  1329    if `x_dnd_action' is XdndAsk.  */
  1330 static uint8_t x_dnd_first_motif_operation;
  1331 
  1332 /* Array of selection targets available to the drop target.  */
  1333 static Atom *x_dnd_targets;
  1334 
  1335 /* The number of elements in that array.  */
  1336 static int x_dnd_n_targets;
  1337 
  1338 /* The old window attributes of the root window before the
  1339    drag-and-drop operation started.  It is used to keep the old event
  1340    mask around, since that should be restored after the operation
  1341    finishes.  */
  1342 static XWindowAttributes x_dnd_old_window_attrs;
  1343 
  1344 /* Whether or not `x_dnd_cleaup_drag_and_drop' should actually clean
  1345    up the drag and drop operation.  */
  1346 static bool x_dnd_unwind_flag;
  1347 
  1348 /* The frame for which `x-dnd-movement-function' should be called.  */
  1349 static struct frame *x_dnd_movement_frame;
  1350 
  1351 /* The coordinates which the movement function should be called
  1352    with.  */
  1353 static int x_dnd_movement_x, x_dnd_movement_y;
  1354 
  1355 /* The frame for which `x-dnd-wheel-function' should be called.  */
  1356 static struct frame *x_dnd_wheel_frame;
  1357 
  1358 /* The coordinates which the wheel function should be called with.  */
  1359 static int x_dnd_wheel_x, x_dnd_wheel_y;
  1360 
  1361 /* The button that was pressed.  */
  1362 static int x_dnd_wheel_button;
  1363 
  1364 /* The modifier state when the button was pressed.  */
  1365 static int x_dnd_wheel_state;
  1366 
  1367 /* When the button was pressed.  */
  1368 static Time x_dnd_wheel_time;
  1369 
  1370 #ifdef HAVE_XKB
  1371 /* The keyboard state during the drag-and-drop operation.  */
  1372 static unsigned int x_dnd_keyboard_state;
  1373 #endif
  1374 
  1375 /* jmp_buf that gets us out of the IO error handler if an error occurs
  1376    terminating DND as part of the display disconnect handler.  */
  1377 static sigjmp_buf x_dnd_disconnect_handler;
  1378 
  1379 /* Whether or not the current invocation of handle_one_xevent
  1380    happened inside the drag_and_drop event loop.  */
  1381 static bool x_dnd_inside_handle_one_xevent;
  1382 
  1383 /* The recursive edit depth when the drag-and-drop operation was
  1384    started.  */
  1385 static int x_dnd_recursion_depth;
  1386 
  1387 /* The cons cell containing the selection alias between the Motif drag
  1388    selection and `XdndSelection'.  The car and cdr are only set when
  1389    initiating Motif drag-and-drop for the first time.  */
  1390 static Lisp_Object x_dnd_selection_alias_cell;
  1391 
  1392 /* The last known position of the tooltip window.  */
  1393 static int x_dnd_last_tooltip_x, x_dnd_last_tooltip_y;
  1394 
  1395 /* Whether or not those values are actually known yet.  */
  1396 static bool x_dnd_last_tooltip_valid;
  1397 
  1398 #ifdef HAVE_XINPUT2
  1399 /* The master pointer device being used for the drag-and-drop
  1400    operation.  */
  1401 static int x_dnd_pointer_device;
  1402 
  1403 /* The keyboard device attached to that pointer device.  */
  1404 static int x_dnd_keyboard_device;
  1405 #endif
  1406 
  1407 /* Structure describing a single window that can be the target of
  1408    drag-and-drop operations.  */
  1409 struct x_client_list_window
  1410 {
  1411   /* The window itself.  */
  1412   Window window;
  1413 
  1414   /* The display that window is on.  */
  1415   Display *dpy;
  1416 
  1417   /* Its X and Y coordinates from the root window.  */
  1418   int x, y;
  1419 
  1420   /* The width and height of the window.  */
  1421   int width, height;
  1422 
  1423   /* A bitmask describing events Emacs was listening for from the
  1424      window before some extra events were added in
  1425      `x_dnd_compute_toplevels'.  */
  1426   long previous_event_mask;
  1427 
  1428   /* The window manager state of the window.  */
  1429   unsigned long wm_state;
  1430 
  1431   /* The next window in this list.  */
  1432   struct x_client_list_window *next;
  1433 
  1434   /* The extents of the frame window in each direction.  */
  1435   int frame_extents_left;
  1436   int frame_extents_right;
  1437   int frame_extents_top;
  1438   int frame_extents_bottom;
  1439 
  1440 #ifdef HAVE_XSHAPE
  1441   /* The border width of this window.  */
  1442   int border_width;
  1443 
  1444   /* The number of rectangles composing the input shape.  */
  1445   int n_input_rects;
  1446 
  1447   /* The rectangles making up the input shape.  */
  1448   XRectangle *input_rects;
  1449 
  1450   /* The rectangles making up the bounding shape.  */
  1451   XRectangle *bounding_rects;
  1452 
  1453   /* The number of rectangles composing the bounding shape.  */
  1454   int n_bounding_rects;
  1455 #endif
  1456 
  1457   /* The Motif protocol style of this window, if any.  */
  1458   uint8_t xm_protocol_style;
  1459 
  1460   /* Whether or not the window is mapped.  */
  1461   bool mapped_p;
  1462 };
  1463 
  1464 /* List of all toplevels in stacking order, from top to bottom.  */
  1465 static struct x_client_list_window *x_dnd_toplevels;
  1466 
  1467 /* Whether or not the window manager supports the required features
  1468    for `x_dnd_toplevels' to work.  */
  1469 static bool x_dnd_use_toplevels;
  1470 
  1471 /* Motif drag-and-drop protocol support.  */
  1472 
  1473 /* Pointer to a variable which stores whether or not an X error
  1474    occurred while trying to create the Motif drag window.  */
  1475 static volatile bool *xm_drag_window_error;
  1476 
  1477 typedef enum xm_byte_order
  1478   {
  1479     XM_BYTE_ORDER_LSB_FIRST = 'l',
  1480     XM_BYTE_ORDER_MSB_FIRST = 'B',
  1481 #ifndef WORDS_BIGENDIAN
  1482     XM_BYTE_ORDER_CUR_FIRST = 'l',
  1483 #else
  1484     XM_BYTE_ORDER_CUR_FIRST = 'B',
  1485 #endif
  1486   } xm_byte_order;
  1487 
  1488 #ifdef ENABLE_CHECKING
  1489 
  1490 #define SWAPCARD32(l)                           \
  1491   {                                             \
  1492     struct { unsigned t : 32; } bit32;          \
  1493     char n, *tp = (char *) &bit32;              \
  1494     bit32.t = l;                                \
  1495     n = tp[0]; tp[0] = tp[3]; tp[3] = n;        \
  1496     n = tp[1]; tp[1] = tp[2]; tp[2] = n;        \
  1497     l = bit32.t;                                \
  1498   }
  1499 
  1500 #define SWAPCARD16(s)                           \
  1501   {                                             \
  1502     struct { unsigned t : 16; } bit16;          \
  1503     char n, *tp = (char *) &bit16;              \
  1504     bit16.t = s;                                \
  1505     n = tp[0]; tp[0] = tp[1]; tp[1] = n;        \
  1506     s = bit16.t;                                \
  1507   }
  1508 
  1509 #else
  1510 #define SWAPCARD32(l)   ((l) = bswap_32 (l))
  1511 #define SWAPCARD16(l)   ((l) = bswap_16 (l))
  1512 #endif
  1513 
  1514 typedef struct xm_targets_table_header
  1515 {
  1516   /* BYTE   */ uint8_t byte_order;
  1517   /* BYTE   */ uint8_t protocol;
  1518 
  1519   /* CARD16 */ uint16_t target_list_count;
  1520   /* CARD32 */ uint32_t total_data_size;
  1521 } xm_targets_table_header;
  1522 
  1523 typedef struct xm_targets_table_rec
  1524 {
  1525   /* CARD16 */ uint16_t n_targets;
  1526   /* CARD32 */ uint32_t targets[FLEXIBLE_ARRAY_MEMBER];
  1527 } xm_targets_table_rec;
  1528 
  1529 typedef struct xm_drop_start_message
  1530 {
  1531   /* BYTE   */ uint8_t reason;
  1532   /* BYTE   */ uint8_t byte_order;
  1533 
  1534   /* CARD16 */ uint16_t side_effects;
  1535   /* CARD32 */ uint32_t timestamp;
  1536   /* CARD16 */ uint16_t x, y;
  1537   /* CARD32 */ uint32_t index_atom;
  1538   /* CARD32 */ uint32_t source_window;
  1539 } xm_drop_start_message;
  1540 
  1541 typedef struct xm_drop_start_reply
  1542 {
  1543   /* BYTE   */ uint8_t reason;
  1544   /* BYTE   */ uint8_t byte_order;
  1545 
  1546   /* CARD16 */ uint16_t side_effects;
  1547   /* CARD16 */ uint16_t better_x;
  1548   /* CARD16 */ uint16_t better_y;
  1549 } xm_drop_start_reply;
  1550 
  1551 typedef struct xm_drag_initiator_info
  1552 {
  1553   /* BYTE   */ uint8_t byteorder;
  1554   /* BYTE   */ uint8_t protocol;
  1555 
  1556   /* CARD16 */ uint16_t table_index;
  1557   /* CARD32 */ uint32_t selection;
  1558 } xm_drag_initiator_info;
  1559 
  1560 typedef struct xm_drag_receiver_info
  1561 {
  1562   /* BYTE   */ uint8_t byteorder;
  1563   /* BYTE   */ uint8_t protocol;
  1564 
  1565   /* BYTE   */ uint8_t protocol_style;
  1566   /* BYTE   */ uint8_t unspecified0;
  1567   /* CARD32 */ uint32_t unspecified1;
  1568   /* CARD32 */ uint32_t unspecified2;
  1569   /* CARD32 */ uint32_t unspecified3;
  1570 } xm_drag_receiver_info;
  1571 
  1572 typedef struct xm_top_level_enter_message
  1573 {
  1574   /* BYTE   */ uint8_t reason;
  1575   /* BYTE   */ uint8_t byteorder;
  1576 
  1577   /* CARD16 */ uint16_t zero;
  1578   /* CARD32 */ uint32_t timestamp;
  1579   /* CARD32 */ uint32_t source_window;
  1580   /* CARD32 */ uint32_t index_atom;
  1581 } xm_top_level_enter_message;
  1582 
  1583 typedef struct xm_drag_motion_message
  1584 {
  1585   /* BYTE   */ uint8_t reason;
  1586   /* BYTE   */ uint8_t byteorder;
  1587 
  1588   /* CARD16 */ uint16_t side_effects;
  1589   /* CARD32 */ uint32_t timestamp;
  1590   /* CARD16 */ uint16_t x, y;
  1591 } xm_drag_motion_message;
  1592 
  1593 typedef struct xm_drag_motion_reply
  1594 {
  1595   /* BYTE   */ uint8_t reason;
  1596   /* BYTE   */ uint8_t byte_order;
  1597 
  1598   /* CARD16 */ uint16_t side_effects;
  1599   /* CARD32 */ uint32_t timestamp;
  1600   /* CARD16 */ uint16_t better_x;
  1601   /* CARD16 */ uint16_t better_y;
  1602 } xm_drag_motion_reply;
  1603 
  1604 typedef struct xm_top_level_leave_message
  1605 {
  1606   /* BYTE   */ uint8_t reason;
  1607   /* BYTE   */ uint8_t byteorder;
  1608 
  1609   /* CARD16 */ uint16_t zero;
  1610   /* CARD32 */ uint32_t timestamp;
  1611   /* CARD32 */ uint32_t source_window;
  1612 } xm_top_level_leave_message;
  1613 
  1614 #define XM_DRAG_SIDE_EFFECT(op, site, ops, act)         \
  1615   ((op) | ((site) << 4) | ((ops) << 8) | ((act) << 12))
  1616 
  1617 /* Some of the macros below are temporarily unused.  */
  1618 
  1619 #define XM_DRAG_SIDE_EFFECT_OPERATION(effect)   ((effect) & 0xf)
  1620 #define XM_DRAG_SIDE_EFFECT_SITE_STATUS(effect) (((effect) & 0xf0) >> 4)
  1621 /* #define XM_DRAG_SIDE_EFFECT_OPERATIONS(effect)       (((effect) & 0xf00) >> 8) */
  1622 #define XM_DRAG_SIDE_EFFECT_DROP_ACTION(effect) (((effect) & 0xf000) >> 12)
  1623 
  1624 enum xm_drag_operation
  1625   {
  1626     XM_DRAG_NOOP     = 0,
  1627     XM_DRAG_MOVE     = (1L << 0),
  1628     XM_DRAG_COPY     = (1L << 1),
  1629     XM_DRAG_LINK     = (1L << 2),
  1630     XM_DRAG_LINK_REC = 3,
  1631   };
  1632 
  1633 #define XM_DRAG_OPERATION_IS_LINK(op)   ((op) == XM_DRAG_LINK           \
  1634                                          || (op) == XM_DRAG_LINK_REC)
  1635 
  1636 enum xm_drag_action
  1637   {
  1638     XM_DROP_ACTION_DROP        = 0,
  1639     XM_DROP_ACTION_DROP_HELP   = 1,
  1640     XM_DROP_ACTION_DROP_CANCEL = 2,
  1641   };
  1642 
  1643 #define XM_DRAG_REASON(originator, code)        ((code) | ((originator) << 7))
  1644 #define XM_DRAG_REASON_ORIGINATOR(reason)       (((reason) & 0x80) ? 1 : 0)
  1645 #define XM_DRAG_REASON_CODE(reason)             ((reason) & 0x7f)
  1646 
  1647 enum xm_drag_reason
  1648   {
  1649     XM_DRAG_REASON_DROP_START      = 5,
  1650     XM_DRAG_REASON_TOP_LEVEL_ENTER = 0,
  1651     XM_DRAG_REASON_TOP_LEVEL_LEAVE = 1,
  1652     XM_DRAG_REASON_DRAG_MOTION     = 2,
  1653   };
  1654 
  1655 enum xm_drag_originator
  1656   {
  1657     XM_DRAG_ORIGINATOR_INITIATOR = 0,
  1658     XM_DRAG_ORIGINATOR_RECEIVER  = 1,
  1659   };
  1660 
  1661 enum xm_drag_style
  1662   {
  1663     /* The values ending with _REC should be treated as equivalent to
  1664        the ones without in messages from the receiver.  */
  1665     XM_DRAG_STYLE_NONE          = 0,
  1666     XM_DRAG_STYLE_DROP_ONLY     = 1,
  1667     XM_DRAG_STYLE_DROP_ONLY_REC = 3,
  1668     XM_DRAG_STYLE_DYNAMIC       = 5,
  1669     XM_DRAG_STYLE_DYNAMIC_REC   = 2,
  1670     XM_DRAG_STYLE_DYNAMIC_REC1  = 4,
  1671   };
  1672 
  1673 #define XM_DRAG_STYLE_IS_DROP_ONLY(n)   ((n) == XM_DRAG_STYLE_DROP_ONLY \
  1674                                          || (n) == XM_DRAG_STYLE_DROP_ONLY_REC)
  1675 #define XM_DRAG_STYLE_IS_DYNAMIC(n)     ((n) == XM_DRAG_STYLE_DYNAMIC   \
  1676                                          || (n) == XM_DRAG_STYLE_DYNAMIC_REC \
  1677                                          || (n) == XM_DRAG_STYLE_DYNAMIC_REC1)
  1678 
  1679 enum xm_drop_site_status
  1680   {
  1681     XM_DROP_SITE_VALID   = 3,
  1682     XM_DROP_SITE_INVALID = 2,
  1683     XM_DROP_SITE_NONE    = 1,
  1684   };
  1685 
  1686 /* The version of the Motif drag-and-drop protocols that Emacs
  1687    supports.  */
  1688 #define XM_DRAG_PROTOCOL_VERSION        0
  1689 
  1690 static uint8_t
  1691 xm_side_effect_from_action (struct x_display_info *dpyinfo, Atom action)
  1692 {
  1693   if (action == dpyinfo->Xatom_XdndActionCopy)
  1694     return XM_DRAG_COPY;
  1695   else if (action == dpyinfo->Xatom_XdndActionMove)
  1696     return XM_DRAG_MOVE;
  1697   else if (action == dpyinfo->Xatom_XdndActionLink)
  1698     return XM_DRAG_LINK;
  1699   else if (action == dpyinfo->Xatom_XdndActionAsk)
  1700     return x_dnd_first_motif_operation;
  1701 
  1702   return XM_DRAG_NOOP;
  1703 }
  1704 
  1705 static uint8_t
  1706 xm_operations_from_actions (struct x_display_info *dpyinfo,
  1707                             Atom *ask_actions, int n_ask_actions)
  1708 {
  1709   int i;
  1710   uint8_t flags;
  1711 
  1712   flags = 0;
  1713 
  1714   for (i = 0; i < n_ask_actions; ++i)
  1715     {
  1716       if (ask_actions[i] == dpyinfo->Xatom_XdndActionCopy)
  1717         flags |= XM_DRAG_COPY;
  1718       else if (ask_actions[i] == dpyinfo->Xatom_XdndActionMove)
  1719         flags |= XM_DRAG_MOVE;
  1720       else if (ask_actions[i] == dpyinfo->Xatom_XdndActionLink)
  1721         flags |= XM_DRAG_LINK;
  1722     }
  1723 
  1724   return flags;
  1725 }
  1726 
  1727 static int
  1728 xm_read_targets_table_header (uint8_t *bytes, ptrdiff_t length,
  1729                               xm_targets_table_header *header_return,
  1730                               xm_byte_order *byteorder_return)
  1731 {
  1732   if (length < 8)
  1733     return -1;
  1734 
  1735   header_return->byte_order = *byteorder_return = *(bytes++);
  1736   header_return->protocol = *(bytes++);
  1737 
  1738   header_return->target_list_count = *(uint16_t *) bytes;
  1739   header_return->total_data_size = *(uint32_t *) (bytes + 2);
  1740 
  1741   if (header_return->byte_order != XM_BYTE_ORDER_CUR_FIRST)
  1742     {
  1743       SWAPCARD16 (header_return->target_list_count);
  1744       SWAPCARD32 (header_return->total_data_size);
  1745     }
  1746 
  1747   header_return->byte_order = XM_BYTE_ORDER_CUR_FIRST;
  1748 
  1749   return 8;
  1750 }
  1751 
  1752 static xm_targets_table_rec *
  1753 xm_read_targets_table_rec (uint8_t *bytes, ptrdiff_t length,
  1754                            xm_byte_order byteorder)
  1755 {
  1756   uint16_t nitems, i;
  1757   xm_targets_table_rec *rec;
  1758 
  1759   if (length < 2)
  1760     return NULL;
  1761 
  1762   nitems = *(uint16_t *) bytes;
  1763 
  1764   if (byteorder != XM_BYTE_ORDER_CUR_FIRST)
  1765     SWAPCARD16 (nitems);
  1766 
  1767   if (length < 2 + nitems * 4)
  1768     return NULL;
  1769 
  1770   rec = xmalloc (FLEXSIZEOF (struct xm_targets_table_rec,
  1771                              targets, nitems * 4));
  1772   rec->n_targets = nitems;
  1773 
  1774   for (i = 0; i < nitems; ++i)
  1775     {
  1776       rec->targets[i] = ((uint32_t *) (bytes + 2))[i];
  1777 
  1778       if (byteorder != XM_BYTE_ORDER_CUR_FIRST)
  1779         SWAPCARD32 (rec->targets[i]);
  1780     }
  1781 
  1782   return rec;
  1783 }
  1784 
  1785 static int
  1786 xm_find_targets_table_idx (xm_targets_table_header *header,
  1787                            xm_targets_table_rec **recs,
  1788                            Atom *sorted_targets, int ntargets)
  1789 {
  1790   int j;
  1791   uint16_t i;
  1792   uint32_t *targets;
  1793 
  1794   targets = alloca (sizeof *targets * ntargets);
  1795 
  1796   for (j = 0; j < ntargets; ++j)
  1797     targets[j] = sorted_targets[j];
  1798 
  1799   for (i = 0; i < header->target_list_count; ++i)
  1800     {
  1801       if (recs[i]->n_targets == ntargets
  1802           && !memcmp (&recs[i]->targets, targets,
  1803                       sizeof *targets * ntargets))
  1804         return i;
  1805     }
  1806 
  1807   return -1;
  1808 }
  1809 
  1810 static int
  1811 x_atoms_compare (const void *a, const void *b)
  1812 {
  1813   return *(Atom *) a - *(Atom *) b;
  1814 }
  1815 
  1816 static void
  1817 xm_write_targets_table (Display *dpy, Window wdesc,
  1818                         Atom targets_table_atom,
  1819                         xm_targets_table_header *header,
  1820                         xm_targets_table_rec **recs)
  1821 {
  1822   uint8_t *header_buffer, *ptr, *rec_buffer;
  1823   ptrdiff_t rec_buffer_size;
  1824   uint16_t i, j;
  1825 
  1826   header_buffer = alloca (8);
  1827   ptr = header_buffer;
  1828 
  1829   *(header_buffer++) = header->byte_order;
  1830   *(header_buffer++) = header->protocol;
  1831   *((uint16_t *) header_buffer) = header->target_list_count;
  1832   *((uint32_t *) (header_buffer + 2)) = header->total_data_size;
  1833 
  1834   rec_buffer = xmalloc (600);
  1835   rec_buffer_size = 600;
  1836 
  1837   XChangeProperty (dpy, wdesc, targets_table_atom,
  1838                    targets_table_atom, 8, PropModeReplace,
  1839                    (unsigned char *) ptr, 8);
  1840 
  1841   for (i = 0; i < header->target_list_count; ++i)
  1842     {
  1843       if (rec_buffer_size < 2 + recs[i]->n_targets * 4)
  1844         {
  1845           rec_buffer_size = 2 + recs[i]->n_targets * 4;
  1846           rec_buffer = xrealloc (rec_buffer, rec_buffer_size);
  1847         }
  1848 
  1849       *((uint16_t *) rec_buffer) = recs[i]->n_targets;
  1850 
  1851       for (j = 0; j < recs[i]->n_targets; ++j)
  1852         ((uint32_t *) (rec_buffer + 2))[j] = recs[i]->targets[j];
  1853 
  1854       XChangeProperty (dpy, wdesc, targets_table_atom,
  1855                        targets_table_atom, 8, PropModeAppend,
  1856                        (unsigned char *) rec_buffer,
  1857                        2 + recs[i]->n_targets * 4);
  1858     }
  1859 
  1860   xfree (rec_buffer);
  1861 }
  1862 
  1863 static void
  1864 xm_write_drag_initiator_info (Display *dpy, Window wdesc,
  1865                               Atom prop_name, Atom type_name,
  1866                               xm_drag_initiator_info *info)
  1867 {
  1868   uint8_t *buf;
  1869 
  1870   buf = alloca (8);
  1871   buf[0] = info->byteorder;
  1872   buf[1] = info->protocol;
  1873 
  1874   if (info->byteorder != XM_BYTE_ORDER_CUR_FIRST)
  1875     {
  1876       SWAPCARD16 (info->table_index);
  1877       SWAPCARD16 (info->selection);
  1878     }
  1879 
  1880   *((uint16_t *) (buf + 2)) = info->table_index;
  1881   *((uint32_t *) (buf + 4)) = info->selection;
  1882 
  1883   XChangeProperty (dpy, wdesc, prop_name, type_name, 8,
  1884                    PropModeReplace, (unsigned char *) buf, 8);
  1885 }
  1886 
  1887 static int
  1888 xm_drag_window_error_handler (Display *display, XErrorEvent *event)
  1889 {
  1890   if (xm_drag_window_error)
  1891     *xm_drag_window_error = true;
  1892 
  1893   return 0;
  1894 }
  1895 
  1896 static _Noreturn int
  1897 xm_drag_window_io_error_handler (Display *dpy)
  1898 {
  1899   /* DPY isn't created through GDK, so it doesn't matter if we don't
  1900      crash here.  */
  1901   siglongjmp (x_dnd_disconnect_handler, 1);
  1902 }
  1903 
  1904 /* Determine whether or not WINDOW exists on DPYINFO by selecting for
  1905    input from it.  */
  1906 static bool
  1907 x_special_window_exists_p (struct x_display_info *dpyinfo,
  1908                            Window window)
  1909 {
  1910   bool rc;
  1911 
  1912   x_catch_errors (dpyinfo->display);
  1913   XSelectInput (dpyinfo->display, window,
  1914                 StructureNotifyMask);
  1915   rc = !x_had_errors_p (dpyinfo->display);
  1916   x_uncatch_errors_after_check ();
  1917 
  1918   return rc;
  1919 }
  1920 
  1921 /* Drag window creation strategy (very tricky, but race-free):
  1922 
  1923    First look for _MOTIF_DRAG_WINDOW.  If it is already present,
  1924    return it immediately to avoid the overhead of new display
  1925    connections.
  1926 
  1927    Otherwise, create a new connection to the display. In that
  1928    connection, create a window, which will be the new drag window. Set
  1929    the client disconnect mode of the new connection to
  1930    RetainPermanent, and close it.
  1931 
  1932    Grab the current display.  Look up _MOTIF_DRAG_WINDOW, the current
  1933    drag window.  If it exists (which means _MOTIF_DRAG_WINDOW was
  1934    created between the first step and now), kill the client that
  1935    created the new drag window to free the client slot on the X
  1936    server.  Otherwise, set _MOTIF_DRAG_WINDOW to the new drag window.
  1937 
  1938    Ungrab the display and return whichever window is currently in
  1939    _MOTIF_DRAG_WINDOW.  */
  1940 
  1941 static Window
  1942 xm_get_drag_window_1 (struct x_display_info *dpyinfo)
  1943 {
  1944   Atom actual_type;
  1945   int rc, actual_format;
  1946   unsigned long nitems, bytes_remaining;
  1947   unsigned char *tmp_data = NULL;
  1948   Window drag_window;
  1949   XSetWindowAttributes attrs;
  1950   Display *temp_display;
  1951   Emacs_XErrorHandler old_handler;
  1952   Emacs_XIOErrorHandler old_io_handler;
  1953 
  1954   /* This is volatile because GCC mistakenly warns about them being
  1955      clobbered by longjmp.  */
  1956   volatile bool error;
  1957 
  1958   drag_window = None;
  1959   rc = XGetWindowProperty (dpyinfo->display, dpyinfo->root_window,
  1960                            dpyinfo->Xatom_MOTIF_DRAG_WINDOW,
  1961                            0, 1, False, XA_WINDOW, &actual_type,
  1962                            &actual_format, &nitems, &bytes_remaining,
  1963                            &tmp_data) == Success;
  1964 
  1965   if (rc && actual_type == XA_WINDOW
  1966       && actual_format == 32 && nitems == 1
  1967       && tmp_data)
  1968     {
  1969       drag_window = *(Window *) tmp_data;
  1970 
  1971       /* This has the side effect of selecting for
  1972          StructureNotifyMask, meaning that we will get notifications
  1973          once it is deleted.  */
  1974       rc = x_special_window_exists_p (dpyinfo, drag_window);
  1975 
  1976       if (!rc)
  1977         drag_window = None;
  1978     }
  1979 
  1980   if (tmp_data)
  1981     XFree (tmp_data);
  1982 
  1983   if (drag_window == None)
  1984     {
  1985       block_input ();
  1986       old_io_handler = XSetIOErrorHandler (xm_drag_window_io_error_handler);
  1987 
  1988       if (sigsetjmp (x_dnd_disconnect_handler, 1))
  1989         {
  1990           XSetIOErrorHandler (old_io_handler);
  1991           unblock_input ();
  1992 
  1993           return None;
  1994         }
  1995 
  1996       unrequest_sigio ();
  1997       temp_display = XOpenDisplay (XDisplayString (dpyinfo->display));
  1998       request_sigio ();
  1999 
  2000       if (!temp_display)
  2001         {
  2002           XSetIOErrorHandler (old_io_handler);
  2003           unblock_input ();
  2004 
  2005           return None;
  2006         }
  2007 
  2008       error = false;
  2009       xm_drag_window_error = &error;
  2010 
  2011       XSetCloseDownMode (temp_display, RetainPermanent);
  2012       old_handler = XSetErrorHandler (xm_drag_window_error_handler);
  2013 
  2014       attrs.override_redirect = True;
  2015       drag_window = XCreateWindow (temp_display, DefaultRootWindow (temp_display),
  2016                                    -1, -1, 1, 1, 0, CopyFromParent, InputOnly,
  2017                                    CopyFromParent, CWOverrideRedirect, &attrs);
  2018 
  2019       /* Handle all errors now.   */
  2020       XSync (temp_display, False);
  2021 
  2022       /* Some part of the drag window creation process failed, so
  2023          punt.  Release all resources too.  */
  2024       if (error)
  2025         {
  2026           XSetCloseDownMode (temp_display, DestroyAll);
  2027           drag_window = None;
  2028         }
  2029 
  2030       xm_drag_window_error = NULL;
  2031 
  2032       /* FIXME: why does XCloseDisplay hang if SIGIO arrives and there
  2033          are multiple displays? */
  2034       unrequest_sigio ();
  2035       XCloseDisplay (temp_display);
  2036       request_sigio ();
  2037 
  2038       XSetErrorHandler (old_handler);
  2039       XSetIOErrorHandler (old_io_handler);
  2040 
  2041       /* Make sure the drag window created is actually valid for the
  2042          current display, and the XOpenDisplay above didn't
  2043          accidentally connect to some other display.  */
  2044       if (!x_special_window_exists_p (dpyinfo, drag_window))
  2045         drag_window = None;
  2046       unblock_input ();
  2047 
  2048       if (drag_window != None)
  2049         {
  2050           XGrabServer (dpyinfo->display);
  2051 
  2052           x_catch_errors (dpyinfo->display);
  2053           tmp_data = NULL;
  2054 
  2055           rc = XGetWindowProperty (dpyinfo->display, dpyinfo->root_window,
  2056                                    dpyinfo->Xatom_MOTIF_DRAG_WINDOW,
  2057                                    0, 1, False, XA_WINDOW, &actual_type,
  2058                                    &actual_format, &nitems, &bytes_remaining,
  2059                                    &tmp_data) == Success;
  2060 
  2061           if (rc && actual_type == XA_WINDOW
  2062               && actual_format == 32 && nitems == 1
  2063               && tmp_data
  2064               && x_special_window_exists_p (dpyinfo,
  2065                                             *(Window *) tmp_data))
  2066             {
  2067               /* Kill the client now to avoid leaking a client slot,
  2068                  which is a limited resource.  */
  2069               XKillClient (dpyinfo->display, drag_window);
  2070               drag_window = *(Window *) tmp_data;
  2071             }
  2072           else
  2073             XChangeProperty (dpyinfo->display, dpyinfo->root_window,
  2074                              dpyinfo->Xatom_MOTIF_DRAG_WINDOW,
  2075                              XA_WINDOW, 32, PropModeReplace,
  2076                              (unsigned char *) &drag_window, 1);
  2077 
  2078           if (tmp_data)
  2079             XFree (tmp_data);
  2080 
  2081           if (x_had_errors_p (dpyinfo->display))
  2082             drag_window = None;
  2083           x_uncatch_errors ();
  2084 
  2085           XUngrabServer (dpyinfo->display);
  2086         }
  2087     }
  2088 
  2089   return drag_window;
  2090 }
  2091 
  2092 static Window
  2093 xm_get_drag_window (struct x_display_info *dpyinfo)
  2094 {
  2095   if (dpyinfo->motif_drag_window != None)
  2096     return dpyinfo->motif_drag_window;
  2097 
  2098   dpyinfo->motif_drag_window = xm_get_drag_window_1 (dpyinfo);
  2099   return dpyinfo->motif_drag_window;
  2100 }
  2101 
  2102 static int
  2103 xm_setup_dnd_targets (struct x_display_info *dpyinfo,
  2104                       Atom *targets, int ntargets)
  2105 {
  2106   Window drag_window;
  2107   Atom *targets_sorted, actual_type;
  2108   unsigned char *tmp_data = NULL;
  2109   unsigned long nitems, bytes_remaining;
  2110   int rc, actual_format, idx;
  2111   bool had_errors;
  2112   xm_targets_table_header header;
  2113   xm_targets_table_rec **recs UNINIT;
  2114   xm_byte_order byteorder;
  2115   uint8_t *data;
  2116   ptrdiff_t total_bytes, total_items, i;
  2117   uint32_t size, target_count;
  2118 
  2119  retry_drag_window:
  2120 
  2121   drag_window = xm_get_drag_window (dpyinfo);
  2122 
  2123   if (drag_window == None || ntargets > 64)
  2124     return -1;
  2125 
  2126   targets_sorted = xmalloc (sizeof *targets * ntargets);
  2127   memcpy (targets_sorted, targets,
  2128           sizeof *targets * ntargets);
  2129   qsort (targets_sorted, ntargets,
  2130          sizeof (Atom), x_atoms_compare);
  2131 
  2132   XGrabServer (dpyinfo->display);
  2133 
  2134   x_catch_errors (dpyinfo->display);
  2135   rc = XGetWindowProperty (dpyinfo->display, drag_window,
  2136                            dpyinfo->Xatom_MOTIF_DRAG_TARGETS,
  2137                            0L, LONG_MAX, False,
  2138                            dpyinfo->Xatom_MOTIF_DRAG_TARGETS,
  2139                            &actual_type, &actual_format, &nitems,
  2140                            &bytes_remaining, &tmp_data) == Success;
  2141   had_errors = x_had_errors_p (dpyinfo->display);
  2142   x_uncatch_errors_after_check ();
  2143 
  2144   /* The drag window is probably invalid, so remove our record of
  2145      it.  */
  2146   if (had_errors)
  2147     {
  2148       dpyinfo->motif_drag_window = None;
  2149       XUngrabServer (dpyinfo->display);
  2150 
  2151       goto retry_drag_window;
  2152     }
  2153 
  2154   if (rc && tmp_data && !bytes_remaining
  2155       && actual_type == dpyinfo->Xatom_MOTIF_DRAG_TARGETS
  2156       && actual_format == 8)
  2157     {
  2158       data = (uint8_t *) tmp_data;
  2159       if (xm_read_targets_table_header ((uint8_t *) tmp_data,
  2160                                         nitems, &header,
  2161                                         &byteorder) == 8)
  2162         {
  2163           data += 8;
  2164           nitems -= 8;
  2165           total_bytes = 0;
  2166           total_items = 0;
  2167 
  2168           /* The extra rec is used to store a new target list if a
  2169              preexisting one doesn't already exist.  */
  2170           recs = xmalloc ((header.target_list_count + 1)
  2171                           * sizeof *recs);
  2172 
  2173           while (total_items < header.target_list_count)
  2174             {
  2175               recs[total_items] = xm_read_targets_table_rec (data + total_bytes,
  2176                                                              nitems, byteorder);
  2177 
  2178               if (!recs[total_items])
  2179                 break;
  2180 
  2181               total_bytes += 2 + recs[total_items]->n_targets * 4;
  2182               nitems -= 2 + recs[total_items]->n_targets * 4;
  2183               total_items++;
  2184             }
  2185 
  2186           if (header.target_list_count != total_items
  2187               || header.total_data_size != 8 + total_bytes)
  2188             {
  2189               for (i = 0; i < total_items; ++i)
  2190                 {
  2191                   if (recs[i])
  2192                       xfree (recs[i]);
  2193                   else
  2194                     break;
  2195                 }
  2196 
  2197               xfree (recs);
  2198 
  2199               rc = false;
  2200             }
  2201         }
  2202       else
  2203         rc = false;
  2204     }
  2205   else
  2206     rc = false;
  2207 
  2208   if (tmp_data)
  2209     XFree (tmp_data);
  2210 
  2211   /* Now rc means whether or not the target lists weren't updated and
  2212      shouldn't be written to the drag window.  */
  2213 
  2214   if (!rc)
  2215     {
  2216       header.byte_order = XM_BYTE_ORDER_CUR_FIRST;
  2217       header.protocol = XM_DRAG_PROTOCOL_VERSION;
  2218       header.target_list_count = 1;
  2219       header.total_data_size = 8 + 2 + ntargets * 4;
  2220 
  2221       recs = xmalloc (sizeof *recs);
  2222       recs[0] = xmalloc (FLEXSIZEOF (struct xm_targets_table_rec,
  2223                                      targets, ntargets * 4));
  2224 
  2225       recs[0]->n_targets = ntargets;
  2226 
  2227       for (i = 0; i < ntargets; ++i)
  2228         recs[0]->targets[i] = targets_sorted[i];
  2229 
  2230       idx = 0;
  2231     }
  2232   else
  2233     {
  2234       idx = xm_find_targets_table_idx (&header, recs,
  2235                                        targets_sorted,
  2236                                        ntargets);
  2237 
  2238       if (idx == -1)
  2239         {
  2240           target_count = header.target_list_count;
  2241           rc = false;
  2242 
  2243           if (INT_ADD_WRAPV (header.target_list_count, 1,
  2244                              &header.target_list_count)
  2245               || INT_MULTIPLY_WRAPV (ntargets, 4, &size)
  2246               || INT_ADD_WRAPV (header.total_data_size, size,
  2247                                 &header.total_data_size)
  2248               || INT_ADD_WRAPV (header.total_data_size, 2,
  2249                                 &header.total_data_size))
  2250             {
  2251               /* Overflow, remove every entry from the targets table
  2252                  and add one for our current targets list.  This
  2253                  confuses real Motif but not GTK 2.x, and there is no
  2254                  other choice.  */
  2255 
  2256               for (i = 0; i < target_count; ++i)
  2257                 xfree (recs[i]);
  2258 
  2259               xfree (recs);
  2260 
  2261               header.byte_order = XM_BYTE_ORDER_CUR_FIRST;
  2262               header.protocol = XM_DRAG_PROTOCOL_VERSION;
  2263               header.target_list_count = 1;
  2264               header.total_data_size = 8 + 2 + ntargets * 4;
  2265 
  2266               recs = xmalloc (sizeof *recs);
  2267               recs[0] = xmalloc (FLEXSIZEOF (struct xm_targets_table_rec,
  2268                                              targets, ntargets * 4));
  2269 
  2270               recs[0]->n_targets = ntargets;
  2271 
  2272               for (i = 0; i < ntargets; ++i)
  2273                 recs[0]->targets[i] = targets_sorted[i];
  2274 
  2275               idx = 0;
  2276             }
  2277           else
  2278             {
  2279               recs[header.target_list_count - 1]
  2280                 = xmalloc (FLEXSIZEOF (struct xm_targets_table_rec,
  2281                                        targets, ntargets * 4));
  2282               recs[header.target_list_count - 1]->n_targets = ntargets;
  2283 
  2284               for (i = 0; i < ntargets; ++i)
  2285                 recs[header.target_list_count - 1]->targets[i] = targets_sorted[i];
  2286 
  2287               idx = header.target_list_count - 1;
  2288             }
  2289         }
  2290     }
  2291 
  2292   if (!rc)
  2293     {
  2294       /* Some implementations of Motif DND set the protocol version of
  2295          just the targets table to 1 without actually changing the
  2296          data format.  To avoid confusing Motif when that happens, set
  2297          it back to 0.  There will probably be no more updates to the
  2298          protocol either.  */
  2299       header.protocol = XM_DRAG_PROTOCOL_VERSION;
  2300 
  2301       x_catch_errors (dpyinfo->display);
  2302       xm_write_targets_table (dpyinfo->display, drag_window,
  2303                               dpyinfo->Xatom_MOTIF_DRAG_TARGETS,
  2304                               &header, recs);
  2305       /* Presumably we got a BadAlloc upon writing the targets
  2306          table.  */
  2307       if (x_had_errors_p (dpyinfo->display))
  2308         idx = -1;
  2309       x_uncatch_errors_after_check ();
  2310     }
  2311 
  2312   XUngrabServer (dpyinfo->display);
  2313 
  2314   for (i = 0; i < header.target_list_count; ++i)
  2315     xfree (recs[i]);
  2316 
  2317   xfree (recs);
  2318   xfree (targets_sorted);
  2319 
  2320   return idx;
  2321 }
  2322 
  2323 /* Allocate an atom that will be used for the Motif selection during
  2324    the drag-and-drop operation.
  2325 
  2326    Grab the server, and then retrieve a list of atoms named
  2327    _EMACS_DRAG_ATOM from the root window.  Find the first atom that
  2328    has no selection owner, own it and return it.  If there is no such
  2329    atom, add a unique atom to the end of the list and return that
  2330    instead.  */
  2331 
  2332 static Atom
  2333 xm_get_drag_atom_1 (struct x_display_info *dpyinfo,
  2334                     struct frame *source_frame)
  2335 {
  2336   Atom actual_type, *atoms, atom;
  2337   unsigned long nitems, bytes_remaining;
  2338   unsigned char *tmp_data;
  2339   int rc, actual_format;
  2340   unsigned long i;
  2341   char *buffer;
  2342   Window owner;
  2343 
  2344   /* Make sure this operation is done atomically.  */
  2345   XGrabServer (dpyinfo->display);
  2346 
  2347   rc = XGetWindowProperty (dpyinfo->display, dpyinfo->root_window,
  2348                            dpyinfo->Xatom_EMACS_DRAG_ATOM,
  2349                            0, LONG_MAX, False, XA_ATOM, &actual_type,
  2350                            &actual_format, &nitems, &bytes_remaining,
  2351                            &tmp_data);
  2352   atom = None;
  2353   /* GCC thinks i is used uninitialized, but it's always initialized if
  2354      `atoms' exists at that particular spot.  */
  2355   i = 0;
  2356 
  2357   if (rc == Success
  2358       && actual_format == 32 && nitems
  2359       && actual_type == XA_ATOM)
  2360     {
  2361       atoms = (Atom *) tmp_data;
  2362 
  2363       x_catch_errors (dpyinfo->display);
  2364 
  2365       for (i = 0; i < nitems; ++i)
  2366         {
  2367           owner = XGetSelectionOwner (dpyinfo->display, atoms[i]);
  2368 
  2369           if (!x_had_errors_p (dpyinfo->display)
  2370               && (owner == None
  2371                   /* If we already own this selection (even if another
  2372                      frame owns it), use it.  There is no way of
  2373                      knowing when ownership was asserted, so it still
  2374                      has to be owned again.  */
  2375                   || x_window_to_frame (dpyinfo, owner)))
  2376             {
  2377               atom = atoms[i];
  2378 
  2379               break;
  2380             }
  2381         }
  2382 
  2383       x_uncatch_errors ();
  2384     }
  2385 
  2386   if (tmp_data)
  2387     XFree (tmp_data);
  2388 
  2389   buffer = dpyinfo->motif_drag_atom_name;
  2390 
  2391   if (atom)
  2392     {
  2393       sprintf (buffer, "_EMACS_ATOM_%lu", i + 1);
  2394       XSetSelectionOwner (dpyinfo->display, atom,
  2395                           FRAME_X_WINDOW (source_frame),
  2396                           dpyinfo->last_user_time);
  2397 
  2398       /* The selection's last-change time is newer than our
  2399          last_user_time, so create a new selection instead.  */
  2400       if (XGetSelectionOwner (dpyinfo->display, atom)
  2401           != FRAME_X_WINDOW (source_frame))
  2402         atom = None;
  2403     }
  2404 
  2405   while (!atom)
  2406     {
  2407       sprintf (buffer, "_EMACS_ATOM_%lu", nitems + 1);
  2408       atom = XInternAtom (dpyinfo->display, buffer, False);
  2409 
  2410       XSetSelectionOwner (dpyinfo->display, atom,
  2411                           FRAME_X_WINDOW (source_frame),
  2412                           dpyinfo->last_user_time);
  2413 
  2414       XChangeProperty (dpyinfo->display, dpyinfo->root_window,
  2415                        dpyinfo->Xatom_EMACS_DRAG_ATOM, XA_ATOM, 32,
  2416                        (rc != Success
  2417                         || (actual_format != 32
  2418                             || actual_type != XA_ATOM)
  2419                         ? PropModeReplace : PropModeAppend),
  2420                        (unsigned char *) &atom, 1);
  2421 
  2422       actual_format = 32;
  2423       actual_type = XA_ATOM;
  2424       rc = Success;
  2425       nitems += 1;
  2426 
  2427       /* The selection's last-change time is newer than our
  2428          last_user_time, so create a new selection (again).  */
  2429       if (XGetSelectionOwner (dpyinfo->display, atom)
  2430           != FRAME_X_WINDOW (source_frame))
  2431         atom = None;
  2432     }
  2433 
  2434   dpyinfo->motif_drag_atom_time = dpyinfo->last_user_time;
  2435   dpyinfo->motif_drag_atom_owner = source_frame;
  2436 
  2437   XUngrabServer (dpyinfo->display);
  2438   return atom;
  2439 }
  2440 
  2441 static Atom
  2442 xm_get_drag_atom (struct x_display_info *dpyinfo)
  2443 {
  2444   Atom atom;
  2445 
  2446   if (dpyinfo->motif_drag_atom != None)
  2447     atom = dpyinfo->motif_drag_atom;
  2448   else
  2449     atom = xm_get_drag_atom_1 (dpyinfo, x_dnd_frame);
  2450 
  2451   dpyinfo->motif_drag_atom = atom;
  2452   return atom;
  2453 }
  2454 
  2455 static void
  2456 xm_setup_drag_info (struct x_display_info *dpyinfo,
  2457                     struct frame *source_frame)
  2458 {
  2459   Atom atom;
  2460   xm_drag_initiator_info drag_initiator_info;
  2461   int idx;
  2462 
  2463   atom = xm_get_drag_atom (dpyinfo);
  2464 
  2465   if (atom == None)
  2466     return;
  2467 
  2468   XSETCAR (x_dnd_selection_alias_cell,
  2469            x_atom_to_symbol (dpyinfo, atom));
  2470   XSETCDR (x_dnd_selection_alias_cell, QXdndSelection);
  2471 
  2472   idx = xm_setup_dnd_targets (dpyinfo, x_dnd_targets,
  2473                               x_dnd_n_targets);
  2474 
  2475   if (idx != -1)
  2476     {
  2477       drag_initiator_info.byteorder = XM_BYTE_ORDER_CUR_FIRST;
  2478       drag_initiator_info.protocol = XM_DRAG_PROTOCOL_VERSION;
  2479       drag_initiator_info.table_index = idx;
  2480       drag_initiator_info.selection = atom;
  2481 
  2482       xm_write_drag_initiator_info (dpyinfo->display,
  2483                                     FRAME_X_WINDOW (source_frame), atom,
  2484                                     dpyinfo->Xatom_MOTIF_DRAG_INITIATOR_INFO,
  2485                                     &drag_initiator_info);
  2486 
  2487       x_dnd_motif_setup_p = true;
  2488       x_dnd_motif_atom = atom;
  2489     }
  2490 }
  2491 
  2492 static void
  2493 xm_send_drop_message (struct x_display_info *dpyinfo, Window source,
  2494                       Window target, xm_drop_start_message *dmsg)
  2495 {
  2496   XEvent msg;
  2497 
  2498   msg.xclient.type = ClientMessage;
  2499   msg.xclient.message_type
  2500     = dpyinfo->Xatom_MOTIF_DRAG_AND_DROP_MESSAGE;
  2501   msg.xclient.format = 8;
  2502   msg.xclient.window = target;
  2503   msg.xclient.data.b[0] = dmsg->reason;
  2504   msg.xclient.data.b[1] = dmsg->byte_order;
  2505   *((uint16_t *) &msg.xclient.data.b[2]) = dmsg->side_effects;
  2506   *((uint32_t *) &msg.xclient.data.b[4]) = dmsg->timestamp;
  2507   *((uint16_t *) &msg.xclient.data.b[8]) = dmsg->x;
  2508   *((uint16_t *) &msg.xclient.data.b[10]) = dmsg->y;
  2509   *((uint32_t *) &msg.xclient.data.b[12]) = dmsg->index_atom;
  2510   *((uint32_t *) &msg.xclient.data.b[16]) = dmsg->source_window;
  2511 
  2512   x_ignore_errors_for_next_request (dpyinfo);
  2513   XSendEvent (dpyinfo->display, target, False, NoEventMask, &msg);
  2514   x_stop_ignoring_errors (dpyinfo);
  2515 }
  2516 
  2517 static void
  2518 xm_send_top_level_enter_message (struct x_display_info *dpyinfo, Window source,
  2519                                  Window target, xm_top_level_enter_message *dmsg)
  2520 {
  2521   XEvent msg;
  2522 
  2523   msg.xclient.type = ClientMessage;
  2524   msg.xclient.message_type
  2525     = dpyinfo->Xatom_MOTIF_DRAG_AND_DROP_MESSAGE;
  2526   msg.xclient.format = 8;
  2527   msg.xclient.window = target;
  2528   msg.xclient.data.b[0] = dmsg->reason;
  2529   msg.xclient.data.b[1] = dmsg->byteorder;
  2530   *((uint16_t *) &msg.xclient.data.b[2]) = dmsg->zero;
  2531   *((uint32_t *) &msg.xclient.data.b[4]) = dmsg->timestamp;
  2532   *((uint32_t *) &msg.xclient.data.b[8]) = dmsg->source_window;
  2533   *((uint32_t *) &msg.xclient.data.b[12]) = dmsg->index_atom;
  2534   msg.xclient.data.b[16] = 0;
  2535   msg.xclient.data.b[17] = 0;
  2536   msg.xclient.data.b[18] = 0;
  2537   msg.xclient.data.b[19] = 0;
  2538 
  2539   x_ignore_errors_for_next_request (dpyinfo);
  2540   XSendEvent (dpyinfo->display, target, False, NoEventMask, &msg);
  2541   x_stop_ignoring_errors (dpyinfo);
  2542 }
  2543 
  2544 static void
  2545 xm_send_drag_motion_message (struct x_display_info *dpyinfo, Window source,
  2546                              Window target, xm_drag_motion_message *dmsg)
  2547 {
  2548   XEvent msg;
  2549 
  2550   msg.xclient.type = ClientMessage;
  2551   msg.xclient.message_type
  2552     = dpyinfo->Xatom_MOTIF_DRAG_AND_DROP_MESSAGE;
  2553   msg.xclient.format = 8;
  2554   msg.xclient.window = target;
  2555   msg.xclient.data.b[0] = dmsg->reason;
  2556   msg.xclient.data.b[1] = dmsg->byteorder;
  2557   *((uint16_t *) &msg.xclient.data.b[2]) = dmsg->side_effects;
  2558   *((uint32_t *) &msg.xclient.data.b[4]) = dmsg->timestamp;
  2559   *((uint16_t *) &msg.xclient.data.b[8]) = dmsg->x;
  2560   *((uint16_t *) &msg.xclient.data.b[10]) = dmsg->y;
  2561   msg.xclient.data.b[12] = 0;
  2562   msg.xclient.data.b[13] = 0;
  2563   msg.xclient.data.b[14] = 0;
  2564   msg.xclient.data.b[15] = 0;
  2565   msg.xclient.data.b[16] = 0;
  2566   msg.xclient.data.b[17] = 0;
  2567   msg.xclient.data.b[18] = 0;
  2568   msg.xclient.data.b[19] = 0;
  2569 
  2570   x_ignore_errors_for_next_request (dpyinfo);
  2571   XSendEvent (dpyinfo->display, target, False, NoEventMask, &msg);
  2572   x_stop_ignoring_errors (dpyinfo);
  2573 }
  2574 
  2575 static void
  2576 xm_send_top_level_leave_message (struct x_display_info *dpyinfo, Window source,
  2577                                  Window target, xm_top_level_leave_message *dmsg)
  2578 {
  2579   XEvent msg;
  2580   xm_drag_motion_message mmsg;
  2581 
  2582   /* Motif support for TOP_LEVEL_LEAVE has bitrotted, since these days
  2583      it assumes every client supports the preregister protocol style,
  2584      but we only support drop-only and dynamic.  (Interestingly enough
  2585      LessTif works fine.)  Sending an event with impossible
  2586      coordinates serves to get rid of any active drop site that might
  2587      still be around in the target drag context.  */
  2588 
  2589   if (x_dnd_fix_motif_leave)
  2590     {
  2591       mmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
  2592                                     XM_DRAG_REASON_DRAG_MOTION);
  2593       mmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
  2594       mmsg.side_effects = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo,
  2595                                                                            x_dnd_wanted_action),
  2596                                                XM_DROP_SITE_NONE, x_dnd_motif_operations,
  2597                                                XM_DROP_ACTION_DROP_CANCEL);
  2598       mmsg.timestamp = dmsg->timestamp;
  2599 
  2600       /* Use X_SHRT_MAX instead of the max value of uint16_t since
  2601          that will be interpreted as a plausible position by Motif,
  2602          and as such breaks if the drop target is beneath that
  2603          position.  */
  2604       mmsg.x = X_SHRT_MAX;
  2605       mmsg.y = X_SHRT_MAX;
  2606 
  2607       xm_send_drag_motion_message (dpyinfo, source, target, &mmsg);
  2608     }
  2609 
  2610   msg.xclient.type = ClientMessage;
  2611   msg.xclient.message_type
  2612     = dpyinfo->Xatom_MOTIF_DRAG_AND_DROP_MESSAGE;
  2613   msg.xclient.format = 8;
  2614   msg.xclient.window = target;
  2615   msg.xclient.data.b[0] = dmsg->reason;
  2616   msg.xclient.data.b[1] = dmsg->byteorder;
  2617   *((uint16_t *) &msg.xclient.data.b[2]) = dmsg->zero;
  2618   *((uint32_t *) &msg.xclient.data.b[4]) = dmsg->timestamp;
  2619   *((uint32_t *) &msg.xclient.data.b[8]) = dmsg->source_window;
  2620   msg.xclient.data.b[12] = 0;
  2621   msg.xclient.data.b[13] = 0;
  2622   msg.xclient.data.b[14] = 0;
  2623   msg.xclient.data.b[15] = 0;
  2624   msg.xclient.data.b[16] = 0;
  2625   msg.xclient.data.b[17] = 0;
  2626   msg.xclient.data.b[18] = 0;
  2627   msg.xclient.data.b[19] = 0;
  2628 
  2629   x_ignore_errors_for_next_request (dpyinfo);
  2630   XSendEvent (dpyinfo->display, target, False, NoEventMask, &msg);
  2631   x_stop_ignoring_errors (dpyinfo);
  2632 }
  2633 
  2634 static int
  2635 xm_read_drop_start_reply (const XEvent *msg, xm_drop_start_reply *reply)
  2636 {
  2637   const uint8_t *data;
  2638 
  2639   data = (const uint8_t *) &msg->xclient.data.b[0];
  2640 
  2641   if ((XM_DRAG_REASON_ORIGINATOR (data[0])
  2642        != XM_DRAG_ORIGINATOR_RECEIVER)
  2643       || (XM_DRAG_REASON_CODE (data[0])
  2644           != XM_DRAG_REASON_DROP_START))
  2645     return 1;
  2646 
  2647   reply->reason = *(data++);
  2648   reply->byte_order = *(data++);
  2649   reply->side_effects = *(uint16_t *) data;
  2650   reply->better_x = *(uint16_t *) (data + 2);
  2651   reply->better_y = *(uint16_t *) (data + 4);
  2652 
  2653   if (reply->byte_order != XM_BYTE_ORDER_CUR_FIRST)
  2654     {
  2655       SWAPCARD16 (reply->side_effects);
  2656       SWAPCARD16 (reply->better_x);
  2657       SWAPCARD16 (reply->better_y);
  2658     }
  2659 
  2660   reply->byte_order = XM_BYTE_ORDER_CUR_FIRST;
  2661 
  2662   return 0;
  2663 }
  2664 
  2665 static int
  2666 xm_read_drop_start_message (const XEvent *msg,
  2667                             xm_drop_start_message *dmsg)
  2668 {
  2669   const uint8_t *data;
  2670 
  2671   data = (const uint8_t *) &msg->xclient.data.b[0];
  2672 
  2673   if ((XM_DRAG_REASON_ORIGINATOR (data[0])
  2674        != XM_DRAG_ORIGINATOR_INITIATOR)
  2675       || (XM_DRAG_REASON_CODE (data[0])
  2676           != XM_DRAG_REASON_DROP_START))
  2677     return 1;
  2678 
  2679   dmsg->reason = *(data++);
  2680   dmsg->byte_order = *(data++);
  2681   dmsg->side_effects = *(uint16_t *) data;
  2682   dmsg->timestamp = *(uint32_t *) (data + 2);
  2683   dmsg->x = *(uint16_t *) (data + 6);
  2684   dmsg->y = *(uint16_t *) (data + 8);
  2685   dmsg->index_atom = *(uint32_t *) (data + 10);
  2686   dmsg->source_window = *(uint32_t *) (data + 14);
  2687 
  2688   if (dmsg->byte_order != XM_BYTE_ORDER_CUR_FIRST)
  2689     {
  2690       SWAPCARD16 (dmsg->side_effects);
  2691       SWAPCARD32 (dmsg->timestamp);
  2692       SWAPCARD16 (dmsg->x);
  2693       SWAPCARD16 (dmsg->y);
  2694       SWAPCARD32 (dmsg->index_atom);
  2695       SWAPCARD32 (dmsg->source_window);
  2696     }
  2697 
  2698   dmsg->byte_order = XM_BYTE_ORDER_CUR_FIRST;
  2699 
  2700   return 0;
  2701 }
  2702 
  2703 static int
  2704 xm_read_drag_receiver_info (struct x_display_info *dpyinfo,
  2705                             Window wdesc, xm_drag_receiver_info *rec)
  2706 {
  2707   Atom actual_type;
  2708   int rc, actual_format;
  2709   unsigned long nitems, bytes_remaining;
  2710   unsigned char *tmp_data = NULL;
  2711   uint8_t *data;
  2712 
  2713   x_catch_errors (dpyinfo->display);
  2714   rc = XGetWindowProperty (dpyinfo->display, wdesc,
  2715                            dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO,
  2716                            0, 4, False,
  2717                            dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO,
  2718                            &actual_type, &actual_format, &nitems,
  2719                            &bytes_remaining,
  2720                            &tmp_data) == Success;
  2721 
  2722   if (x_had_errors_p (dpyinfo->display)
  2723       || actual_format != 8 || nitems < 16 || !tmp_data
  2724       || actual_type != dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO)
  2725     rc = 0;
  2726   x_uncatch_errors_after_check ();
  2727 
  2728   if (rc)
  2729     {
  2730       data = (uint8_t *) tmp_data;
  2731 
  2732       if (data[1] > XM_DRAG_PROTOCOL_VERSION)
  2733         return 1;
  2734 
  2735       rec->byteorder = data[0];
  2736       rec->protocol = data[1];
  2737       rec->protocol_style = data[2];
  2738       rec->unspecified0 = data[3];
  2739       rec->unspecified1 = *(uint32_t *) &data[4];
  2740       rec->unspecified2 = *(uint32_t *) &data[8];
  2741       rec->unspecified3 = *(uint32_t *) &data[12];
  2742 
  2743       if (rec->byteorder != XM_BYTE_ORDER_CUR_FIRST)
  2744         {
  2745           SWAPCARD32 (rec->unspecified1);
  2746           SWAPCARD32 (rec->unspecified2);
  2747           SWAPCARD32 (rec->unspecified3);
  2748         }
  2749 
  2750       rec->byteorder = XM_BYTE_ORDER_CUR_FIRST;
  2751     }
  2752 
  2753   if (tmp_data)
  2754     XFree (tmp_data);
  2755 
  2756   return !rc;
  2757 }
  2758 
  2759 static int
  2760 xm_read_drag_motion_message (const XEvent *msg,
  2761                              xm_drag_motion_message *dmsg)
  2762 {
  2763   const uint8_t *data;
  2764 
  2765   data = (const uint8_t *) &msg->xclient.data.b[0];
  2766 
  2767   if ((XM_DRAG_REASON_CODE (data[0])
  2768        != XM_DRAG_REASON_DRAG_MOTION)
  2769       || (XM_DRAG_REASON_ORIGINATOR (data[0])
  2770           != XM_DRAG_ORIGINATOR_INITIATOR))
  2771     return 1;
  2772 
  2773   dmsg->reason = *(data++);
  2774   dmsg->byteorder = *(data++);
  2775   dmsg->side_effects = *(uint16_t *) data;
  2776   dmsg->timestamp = *(uint32_t *) (data + 2);
  2777   dmsg->x = *(uint16_t *) (data + 6);
  2778   dmsg->y = *(uint16_t *) (data + 8);
  2779 
  2780   if (dmsg->byteorder != XM_BYTE_ORDER_CUR_FIRST)
  2781     {
  2782       SWAPCARD16 (dmsg->side_effects);
  2783       SWAPCARD32 (dmsg->timestamp);
  2784       SWAPCARD16 (dmsg->x);
  2785       SWAPCARD16 (dmsg->y);
  2786     }
  2787 
  2788   dmsg->byteorder = XM_BYTE_ORDER_CUR_FIRST;
  2789 
  2790   return 0;
  2791 }
  2792 
  2793 static int
  2794 xm_read_drag_motion_reply (const XEvent *msg, xm_drag_motion_reply *reply)
  2795 {
  2796   const uint8_t *data;
  2797 
  2798   data = (const uint8_t *) &msg->xclient.data.b[0];
  2799 
  2800   if ((XM_DRAG_REASON_CODE (data[0])
  2801        != XM_DRAG_REASON_DRAG_MOTION)
  2802       || (XM_DRAG_REASON_ORIGINATOR (data[0])
  2803           != XM_DRAG_ORIGINATOR_RECEIVER))
  2804     return 1;
  2805 
  2806   reply->reason = *(data++);
  2807   reply->byte_order = *(data++);
  2808   reply->side_effects = *(uint16_t *) data;
  2809   reply->timestamp = *(uint32_t *) (data + 2);
  2810   reply->better_x = *(uint16_t *) (data + 6);
  2811   reply->better_y = *(uint16_t *) (data + 8);
  2812 
  2813   if (reply->byte_order != XM_BYTE_ORDER_CUR_FIRST)
  2814     {
  2815       SWAPCARD16 (reply->side_effects);
  2816       SWAPCARD32 (reply->timestamp);
  2817       SWAPCARD16 (reply->better_x);
  2818       SWAPCARD16 (reply->better_y);
  2819     }
  2820 
  2821   reply->byte_order = XM_BYTE_ORDER_CUR_FIRST;
  2822 
  2823   return 0;
  2824 }
  2825 
  2826 static void
  2827 x_dnd_send_xm_leave_for_drop (struct x_display_info *dpyinfo,
  2828                               struct frame *f, Window wdesc,
  2829                               Time timestamp)
  2830 {
  2831   xm_top_level_leave_message lmsg;
  2832 
  2833   lmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
  2834                                 XM_DRAG_REASON_TOP_LEVEL_LEAVE);
  2835   lmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
  2836   lmsg.zero = 0;
  2837   lmsg.timestamp = timestamp;
  2838   lmsg.source_window = FRAME_X_WINDOW (f);
  2839 
  2840   if (x_dnd_motif_setup_p)
  2841     xm_send_top_level_leave_message (dpyinfo, FRAME_X_WINDOW (f),
  2842                                      wdesc, &lmsg);
  2843 }
  2844 
  2845 static void
  2846 x_dnd_free_toplevels (bool display_alive)
  2847 {
  2848   struct x_client_list_window *last;
  2849   struct x_client_list_window *tem = x_dnd_toplevels;
  2850   ptrdiff_t n_windows, i, buffer_size;
  2851   Window *destroy_windows UNINIT;
  2852   unsigned long *prev_masks UNINIT;
  2853   specpdl_ref count;
  2854   Display *dpy UNINIT;
  2855   struct x_display_info *dpyinfo;
  2856 
  2857   if (!x_dnd_toplevels)
  2858     /* Probably called inside an IO error handler.  */
  2859     return;
  2860 
  2861   if (display_alive)
  2862     {
  2863       buffer_size = 1024;
  2864       destroy_windows = xmalloc (sizeof *destroy_windows
  2865                                  * buffer_size);
  2866       prev_masks = xmalloc (sizeof *prev_masks *
  2867                             buffer_size);
  2868       n_windows = 0;
  2869     }
  2870 
  2871   block_input ();
  2872   while (tem)
  2873     {
  2874       last = tem;
  2875       tem = tem->next;
  2876 
  2877       if (display_alive)
  2878         {
  2879           if (++n_windows >= buffer_size)
  2880             {
  2881               buffer_size += 1024;
  2882               destroy_windows
  2883                 = xrealloc (destroy_windows, (sizeof *destroy_windows
  2884                                               * buffer_size));
  2885               prev_masks
  2886                 = xrealloc (prev_masks, (sizeof *prev_masks
  2887                                          * buffer_size));
  2888             }
  2889 
  2890           dpy = last->dpy;
  2891           prev_masks[n_windows - 1] = last->previous_event_mask;
  2892           destroy_windows[n_windows - 1] = last->window;
  2893         }
  2894 
  2895 #ifdef HAVE_XSHAPE
  2896       if (last->n_input_rects != -1)
  2897         xfree (last->input_rects);
  2898       if (last->n_bounding_rects != -1)
  2899         xfree (last->bounding_rects);
  2900 #endif
  2901 
  2902       xfree (last);
  2903     }
  2904 
  2905   x_dnd_toplevels = NULL;
  2906 
  2907   if (!display_alive)
  2908     {
  2909       unblock_input ();
  2910       return;
  2911     }
  2912 
  2913   count = SPECPDL_INDEX ();
  2914   record_unwind_protect_ptr (xfree, destroy_windows);
  2915   record_unwind_protect_ptr (xfree, prev_masks);
  2916 
  2917   if (display_alive)
  2918     {
  2919       dpyinfo = x_display_info_for_display (dpy);
  2920 
  2921       if (n_windows)
  2922         {
  2923           eassume (dpyinfo);
  2924           x_ignore_errors_for_next_request (dpyinfo);
  2925 
  2926           for (i = 0; i < n_windows; ++i)
  2927             {
  2928               XSelectInput (dpy, destroy_windows[i], prev_masks[i]);
  2929 #ifdef HAVE_XSHAPE
  2930               XShapeSelectInput (dpy, destroy_windows[i], None);
  2931 #endif
  2932             }
  2933 
  2934           x_stop_ignoring_errors (dpyinfo);
  2935         }
  2936     }
  2937 
  2938   unbind_to (count, Qnil);
  2939   unblock_input ();
  2940 }
  2941 
  2942 static int
  2943 x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
  2944 {
  2945   Atom type;
  2946   Window *toplevels;
  2947   int format, rc;
  2948   unsigned long nitems, bytes_after;
  2949   unsigned long i, real_nitems;
  2950   unsigned char *data = NULL;
  2951   int frame_extents[4];
  2952 
  2953 #ifndef USE_XCB
  2954   int dest_x, dest_y;
  2955   unsigned long *wmstate;
  2956   unsigned long wmstate_items, extent_items;
  2957   unsigned char *wmstate_data = NULL, *extent_data = NULL;
  2958   XWindowAttributes attrs;
  2959   Window child;
  2960   xm_drag_receiver_info xm_info;
  2961 #else
  2962   uint32_t *wmstate, *fextents;
  2963   uint8_t *xmdata;
  2964   xcb_get_window_attributes_cookie_t *window_attribute_cookies;
  2965   xcb_translate_coordinates_cookie_t *translate_coordinate_cookies;
  2966   xcb_get_property_cookie_t *get_property_cookies;
  2967   xcb_get_property_cookie_t *xm_property_cookies;
  2968   xcb_get_property_cookie_t *extent_property_cookies;
  2969   xcb_get_geometry_cookie_t *get_geometry_cookies;
  2970   xcb_get_window_attributes_reply_t attrs, *attrs_reply;
  2971   xcb_translate_coordinates_reply_t *coordinates_reply;
  2972   xcb_get_property_reply_t *property_reply;
  2973   xcb_get_property_reply_t *xm_property_reply;
  2974   xcb_get_property_reply_t *extent_property_reply;
  2975   xcb_get_geometry_reply_t *geometry_reply;
  2976   xcb_generic_error_t *error;
  2977 #endif
  2978 
  2979 #ifdef HAVE_XCB_SHAPE
  2980   xcb_shape_get_rectangles_cookie_t *bounding_rect_cookies;
  2981   xcb_shape_get_rectangles_reply_t *bounding_rect_reply;
  2982   xcb_rectangle_iterator_t bounding_rect_iterator;
  2983 #endif
  2984 
  2985 #ifdef HAVE_XCB_SHAPE_INPUT_RECTS
  2986   xcb_shape_get_rectangles_cookie_t *input_rect_cookies;
  2987   xcb_shape_get_rectangles_reply_t *input_rect_reply;
  2988   xcb_rectangle_iterator_t input_rect_iterator;
  2989 #endif
  2990 
  2991   struct x_client_list_window *tem;
  2992 #if defined HAVE_XSHAPE && !defined HAVE_XCB_SHAPE_INPUT_RECTS
  2993   int count, ordering;
  2994   XRectangle *rects;
  2995 #endif
  2996 
  2997   rc = XGetWindowProperty (dpyinfo->display, dpyinfo->root_window,
  2998                            dpyinfo->Xatom_net_client_list_stacking,
  2999                            0, LONG_MAX, False, XA_WINDOW, &type,
  3000                            &format, &nitems, &bytes_after, &data);
  3001 
  3002   if (rc != Success)
  3003     return 1;
  3004 
  3005   if (format != 32 || type != XA_WINDOW)
  3006     {
  3007       XFree (data);
  3008       return 1;
  3009     }
  3010 
  3011   toplevels = (Window *) data;
  3012 
  3013   for (i = 0, real_nitems = 0; i < nitems; ++i)
  3014     {
  3015       /* Some window managers with built in compositors end up putting
  3016          tooltips in the client list, which is silly.  */
  3017       if (!x_tooltip_window_to_frame (dpyinfo, toplevels[i], NULL))
  3018         toplevels[real_nitems++] = toplevels[i];
  3019     }
  3020 
  3021   nitems = real_nitems;
  3022 
  3023 #ifdef USE_XCB
  3024   USE_SAFE_ALLOCA;
  3025 
  3026   window_attribute_cookies
  3027     = SAFE_ALLOCA (sizeof *window_attribute_cookies * nitems);
  3028   translate_coordinate_cookies
  3029     = SAFE_ALLOCA (sizeof *translate_coordinate_cookies * nitems);
  3030   get_property_cookies
  3031     = SAFE_ALLOCA (sizeof *get_property_cookies * nitems);
  3032   xm_property_cookies
  3033     = SAFE_ALLOCA (sizeof *xm_property_cookies * nitems);
  3034   extent_property_cookies
  3035     = SAFE_ALLOCA (sizeof *extent_property_cookies * nitems);
  3036   get_geometry_cookies
  3037     = SAFE_ALLOCA (sizeof *get_geometry_cookies * nitems);
  3038 
  3039 #ifdef HAVE_XCB_SHAPE
  3040   bounding_rect_cookies
  3041     = SAFE_ALLOCA (sizeof *bounding_rect_cookies * nitems);
  3042 #endif
  3043 
  3044 #ifdef HAVE_XCB_SHAPE_INPUT_RECTS
  3045   input_rect_cookies
  3046     = SAFE_ALLOCA (sizeof *input_rect_cookies * nitems);
  3047 #endif
  3048 
  3049   for (i = 0; i < nitems; ++i)
  3050     {
  3051       window_attribute_cookies[i]
  3052         = xcb_get_window_attributes (dpyinfo->xcb_connection,
  3053                                      (xcb_window_t) toplevels[i]);
  3054       translate_coordinate_cookies[i]
  3055         = xcb_translate_coordinates (dpyinfo->xcb_connection,
  3056                                      (xcb_window_t) toplevels[i],
  3057                                      (xcb_window_t) dpyinfo->root_window,
  3058                                      0, 0);
  3059       get_property_cookies[i]
  3060         = xcb_get_property (dpyinfo->xcb_connection, 0, (xcb_window_t) toplevels[i],
  3061                             (xcb_atom_t) dpyinfo->Xatom_wm_state, XCB_ATOM_ANY,
  3062                             0, 2);
  3063       xm_property_cookies[i]
  3064         = xcb_get_property (dpyinfo->xcb_connection, 0, (xcb_window_t) toplevels[i],
  3065                             (xcb_atom_t) dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO,
  3066                             (xcb_atom_t) dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO,
  3067                             0, 4);
  3068       extent_property_cookies[i]
  3069         = xcb_get_property (dpyinfo->xcb_connection, 0,
  3070                             (xcb_window_t) toplevels[i],
  3071                             (xcb_atom_t) dpyinfo->Xatom_net_frame_extents,
  3072                             XCB_ATOM_CARDINAL, 0, 4);
  3073       get_geometry_cookies[i]
  3074         = xcb_get_geometry (dpyinfo->xcb_connection, (xcb_window_t) toplevels[i]);
  3075 
  3076 #ifdef HAVE_XCB_SHAPE
  3077       bounding_rect_cookies[i]
  3078         = xcb_shape_get_rectangles (dpyinfo->xcb_connection,
  3079                                     (xcb_window_t) toplevels[i],
  3080                                     XCB_SHAPE_SK_BOUNDING);
  3081 #endif
  3082 
  3083 #ifdef HAVE_XCB_SHAPE_INPUT_RECTS
  3084       if (dpyinfo->xshape_major > 1
  3085           || (dpyinfo->xshape_major == 1
  3086               && dpyinfo->xshape_minor >= 1))
  3087         input_rect_cookies[i]
  3088           = xcb_shape_get_rectangles (dpyinfo->xcb_connection,
  3089                                       (xcb_window_t) toplevels[i],
  3090                                       XCB_SHAPE_SK_INPUT);
  3091 #endif
  3092     }
  3093 #endif
  3094 
  3095   /* Actually right because _NET_CLIENT_LIST_STACKING has bottom-up
  3096      order.  */
  3097   for (i = 0; i < nitems; ++i)
  3098     {
  3099       frame_extents[0] = 0;
  3100       frame_extents[1] = 0;
  3101       frame_extents[2] = 0;
  3102       frame_extents[3] = 0;
  3103 
  3104 #ifndef USE_XCB
  3105       x_catch_errors (dpyinfo->display);
  3106       rc = (XGetWindowAttributes (dpyinfo->display,
  3107                                   toplevels[i], &attrs)
  3108             && !x_had_errors_p (dpyinfo->display));
  3109 
  3110       if (rc)
  3111         rc = (XTranslateCoordinates (dpyinfo->display, toplevels[i],
  3112                                      attrs.root, -attrs.border_width,
  3113                                      -attrs.border_width, &dest_x,
  3114                                      &dest_y, &child)
  3115               && !x_had_errors_p (dpyinfo->display));
  3116       if (rc)
  3117         rc = ((XGetWindowProperty (dpyinfo->display,
  3118                                    toplevels[i],
  3119                                    dpyinfo->Xatom_wm_state,
  3120                                    0, 2, False, AnyPropertyType,
  3121                                    &type, &format, &wmstate_items,
  3122                                    &bytes_after, &wmstate_data)
  3123                == Success)
  3124               && !x_had_errors_p (dpyinfo->display)
  3125               && wmstate_data && wmstate_items == 2 && format == 32);
  3126 
  3127       if (XGetWindowProperty (dpyinfo->display, toplevels[i],
  3128                               dpyinfo->Xatom_net_frame_extents,
  3129                               0, 4, False, XA_CARDINAL, &type,
  3130                               &format, &extent_items, &bytes_after,
  3131                               &extent_data) == Success
  3132           && !x_had_errors_p (dpyinfo->display)
  3133           && extent_data && extent_items >= 4 && format == 32)
  3134         {
  3135           frame_extents[0] = ((unsigned long *) extent_data)[0];
  3136           frame_extents[1] = ((unsigned long *) extent_data)[1];
  3137           frame_extents[2] = ((unsigned long *) extent_data)[2];
  3138           frame_extents[3] = ((unsigned long *) extent_data)[3];
  3139         }
  3140 
  3141       if (extent_data)
  3142         XFree (extent_data);
  3143 
  3144       x_uncatch_errors ();
  3145 #else
  3146       rc = true;
  3147 
  3148       attrs_reply
  3149         = xcb_get_window_attributes_reply (dpyinfo->xcb_connection,
  3150                                            window_attribute_cookies[i],
  3151                                            &error);
  3152 
  3153       if (!attrs_reply)
  3154         {
  3155           rc = false;
  3156           free (error);
  3157         }
  3158 
  3159       coordinates_reply
  3160         = xcb_translate_coordinates_reply (dpyinfo->xcb_connection,
  3161                                            translate_coordinate_cookies[i],
  3162                                            &error);
  3163 
  3164       if (!coordinates_reply)
  3165         {
  3166           rc = false;
  3167           free (error);
  3168         }
  3169 
  3170       property_reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  3171                                                get_property_cookies[i],
  3172                                                &error);
  3173 
  3174       if (!property_reply)
  3175         {
  3176           rc = false;
  3177           free (error);
  3178         }
  3179 
  3180       /* These requests don't set rc on failure because they aren't
  3181          required.  */
  3182 
  3183       xm_property_reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  3184                                                   xm_property_cookies[i],
  3185                                                   &error);
  3186 
  3187       if (!xm_property_reply)
  3188         free (error);
  3189 
  3190       extent_property_reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  3191                                                       extent_property_cookies[i],
  3192                                                       &error);
  3193 
  3194       if (!extent_property_reply)
  3195         free (error);
  3196       else
  3197         {
  3198           if (xcb_get_property_value_length (extent_property_reply) == 16
  3199               && extent_property_reply->format == 32
  3200               && extent_property_reply->type == XCB_ATOM_CARDINAL)
  3201             {
  3202               fextents = xcb_get_property_value (extent_property_reply);
  3203               frame_extents[0] = fextents[0];
  3204               frame_extents[1] = fextents[1];
  3205               frame_extents[2] = fextents[2];
  3206               frame_extents[3] = fextents[3];
  3207             }
  3208 
  3209           free (extent_property_reply);
  3210         }
  3211 
  3212       if (property_reply
  3213           && (xcb_get_property_value_length (property_reply) != 8
  3214               || property_reply->format != 32))
  3215         rc = false;
  3216 
  3217       geometry_reply = xcb_get_geometry_reply (dpyinfo->xcb_connection,
  3218                                                get_geometry_cookies[i],
  3219                                                &error);
  3220 
  3221       if (!geometry_reply)
  3222         {
  3223           rc = false;
  3224           free (error);
  3225         }
  3226 #endif
  3227 
  3228       if (rc)
  3229         {
  3230 #ifdef USE_XCB
  3231           wmstate = (uint32_t *) xcb_get_property_value (property_reply);
  3232           attrs = *attrs_reply;
  3233 #else
  3234           wmstate = (unsigned long *) wmstate_data;
  3235 #endif
  3236 
  3237           tem = xmalloc (sizeof *tem);
  3238           tem->window = toplevels[i];
  3239           tem->dpy = dpyinfo->display;
  3240           tem->frame_extents_left = frame_extents[0];
  3241           tem->frame_extents_right = frame_extents[1];
  3242           tem->frame_extents_top = frame_extents[2];
  3243           tem->frame_extents_bottom = frame_extents[3];
  3244 
  3245 #ifndef USE_XCB
  3246           tem->x = dest_x;
  3247           tem->y = dest_y;
  3248           tem->width = attrs.width + attrs.border_width;
  3249           tem->height = attrs.height + attrs.border_width;
  3250           tem->mapped_p = (attrs.map_state != IsUnmapped);
  3251 #else
  3252           tem->x = (coordinates_reply->dst_x
  3253                     - geometry_reply->border_width);
  3254           tem->y = (coordinates_reply->dst_y
  3255                     - geometry_reply->border_width);
  3256           tem->width = (geometry_reply->width
  3257                         + geometry_reply->border_width);
  3258           tem->height = (geometry_reply->height
  3259                          + geometry_reply->border_width);
  3260           tem->mapped_p = (attrs.map_state != XCB_MAP_STATE_UNMAPPED);
  3261 #endif
  3262           tem->next = x_dnd_toplevels;
  3263           tem->previous_event_mask = attrs.your_event_mask;
  3264           tem->wm_state = wmstate[0];
  3265           tem->xm_protocol_style = XM_DRAG_STYLE_NONE;
  3266 
  3267 #ifndef USE_XCB
  3268           if (!xm_read_drag_receiver_info (dpyinfo, toplevels[i], &xm_info))
  3269             tem->xm_protocol_style = xm_info.protocol_style;
  3270 #else
  3271           if (xm_property_reply
  3272               && xm_property_reply->format == 8
  3273               && xm_property_reply->type == dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO
  3274               && xcb_get_property_value_length (xm_property_reply) >= 4)
  3275             {
  3276               xmdata = xcb_get_property_value (xm_property_reply);
  3277 
  3278               if (xmdata[1] <= XM_DRAG_PROTOCOL_VERSION)
  3279                 tem->xm_protocol_style = xmdata[2];
  3280             }
  3281 #endif
  3282 
  3283 #ifdef HAVE_XSHAPE
  3284 #ifndef USE_XCB
  3285           tem->border_width = attrs.border_width;
  3286 #else
  3287           tem->border_width = geometry_reply->border_width;
  3288 #endif
  3289           tem->n_bounding_rects = -1;
  3290           tem->n_input_rects = -1;
  3291 
  3292           if (dpyinfo->xshape_supported_p)
  3293             {
  3294               x_ignore_errors_for_next_request (dpyinfo);
  3295               XShapeSelectInput (dpyinfo->display,
  3296                                  toplevels[i],
  3297                                  ShapeNotifyMask);
  3298               x_stop_ignoring_errors (dpyinfo);
  3299 
  3300 #ifndef HAVE_XCB_SHAPE
  3301               x_catch_errors (dpyinfo->display);
  3302               rects = XShapeGetRectangles (dpyinfo->display,
  3303                                            toplevels[i],
  3304                                            ShapeBounding,
  3305                                            &count, &ordering);
  3306               rc = x_had_errors_p (dpyinfo->display);
  3307               x_uncatch_errors_after_check ();
  3308 
  3309               /* Does XShapeGetRectangles allocate anything upon an
  3310                  error?  */
  3311               if (!rc)
  3312                 {
  3313                   tem->n_bounding_rects = count;
  3314                   tem->bounding_rects
  3315                     = xmalloc (sizeof *tem->bounding_rects * count);
  3316                   memcpy (tem->bounding_rects, rects,
  3317                           sizeof *tem->bounding_rects * count);
  3318 
  3319                   XFree (rects);
  3320                 }
  3321 #else
  3322               bounding_rect_reply = xcb_shape_get_rectangles_reply (dpyinfo->xcb_connection,
  3323                                                                     bounding_rect_cookies[i],
  3324                                                                     &error);
  3325 
  3326               if (bounding_rect_reply)
  3327                 {
  3328                   bounding_rect_iterator
  3329                     = xcb_shape_get_rectangles_rectangles_iterator (bounding_rect_reply);
  3330                   tem->n_bounding_rects = bounding_rect_iterator.rem + 1;
  3331                   tem->bounding_rects = xmalloc (tem->n_bounding_rects
  3332                                                  * sizeof *tem->bounding_rects);
  3333                   tem->n_bounding_rects = 0;
  3334 
  3335                   for (; bounding_rect_iterator.rem; xcb_rectangle_next (&bounding_rect_iterator))
  3336                     {
  3337                       tem->bounding_rects[tem->n_bounding_rects].x
  3338                         = bounding_rect_iterator.data->x;
  3339                       tem->bounding_rects[tem->n_bounding_rects].y
  3340                         = bounding_rect_iterator.data->y;
  3341                       tem->bounding_rects[tem->n_bounding_rects].width
  3342                         = bounding_rect_iterator.data->width;
  3343                       tem->bounding_rects[tem->n_bounding_rects].height
  3344                         = bounding_rect_iterator.data->height;
  3345 
  3346                       tem->n_bounding_rects++;
  3347                     }
  3348 
  3349                   free (bounding_rect_reply);
  3350                 }
  3351               else
  3352                 free (error);
  3353 #endif
  3354 
  3355 #ifdef HAVE_XCB_SHAPE_INPUT_RECTS
  3356               if (dpyinfo->xshape_major > 1
  3357                   || (dpyinfo->xshape_major == 1
  3358                       && dpyinfo->xshape_minor >= 1))
  3359                 {
  3360                   input_rect_reply = xcb_shape_get_rectangles_reply (dpyinfo->xcb_connection,
  3361                                                                      input_rect_cookies[i],
  3362                                                                      &error);
  3363 
  3364                   if (input_rect_reply)
  3365                     {
  3366                       input_rect_iterator
  3367                         = xcb_shape_get_rectangles_rectangles_iterator (input_rect_reply);
  3368                       tem->n_input_rects = input_rect_iterator.rem + 1;
  3369                       tem->input_rects = xmalloc (tem->n_input_rects
  3370                                                   * sizeof *tem->input_rects);
  3371                       tem->n_input_rects = 0;
  3372 
  3373                       for (; input_rect_iterator.rem; xcb_rectangle_next (&input_rect_iterator))
  3374                         {
  3375                           tem->input_rects[tem->n_input_rects].x
  3376                             = input_rect_iterator.data->x;
  3377                           tem->input_rects[tem->n_input_rects].y
  3378                             = input_rect_iterator.data->y;
  3379                           tem->input_rects[tem->n_input_rects].width
  3380                             = input_rect_iterator.data->width;
  3381                           tem->input_rects[tem->n_input_rects].height
  3382                             = input_rect_iterator.data->height;
  3383 
  3384                           tem->n_input_rects++;
  3385                         }
  3386 
  3387                       free (input_rect_reply);
  3388                     }
  3389                   else
  3390                     free (error);
  3391                 }
  3392 #else
  3393 #ifdef ShapeInput
  3394               if (dpyinfo->xshape_major > 1
  3395                   || (dpyinfo->xshape_major == 1
  3396                       && dpyinfo->xshape_minor >= 1))
  3397                 {
  3398                   x_catch_errors (dpyinfo->display);
  3399                   rects = XShapeGetRectangles (dpyinfo->display,
  3400                                                toplevels[i], ShapeInput,
  3401                                                &count, &ordering);
  3402                   rc = x_had_errors_p (dpyinfo->display);
  3403                   x_uncatch_errors_after_check ();
  3404 
  3405                   /* Does XShapeGetRectangles allocate anything upon
  3406                      an error?  */
  3407                   if (!rc)
  3408                     {
  3409                       tem->n_input_rects = count;
  3410                       tem->input_rects
  3411                         = xmalloc (sizeof *tem->input_rects * count);
  3412                       memcpy (tem->input_rects, rects,
  3413                               sizeof *tem->input_rects * count);
  3414 
  3415                       XFree (rects);
  3416                     }
  3417                 }
  3418 #endif
  3419 #endif
  3420             }
  3421 
  3422           /* Handle the common case where the input shape equals the
  3423              bounding shape.  */
  3424 
  3425           if (tem->n_input_rects != -1
  3426               && tem->n_bounding_rects == tem->n_input_rects
  3427               && !memcmp (tem->bounding_rects, tem->input_rects,
  3428                           tem->n_input_rects * sizeof *tem->input_rects))
  3429             {
  3430               xfree (tem->input_rects);
  3431               tem->n_input_rects = -1;
  3432             }
  3433 
  3434           /* And the common case where there is no input rect and the
  3435              bounding rect equals the window dimensions.  */
  3436 
  3437           if (tem->n_input_rects == -1
  3438               && tem->n_bounding_rects == 1
  3439 #ifdef USE_XCB
  3440               && tem->bounding_rects[0].width == (geometry_reply->width
  3441                                                   + geometry_reply->border_width)
  3442               && tem->bounding_rects[0].height == (geometry_reply->height
  3443                                                    + geometry_reply->border_width)
  3444               && tem->bounding_rects[0].x == -geometry_reply->border_width
  3445               && tem->bounding_rects[0].y == -geometry_reply->border_width
  3446 #else
  3447               && tem->bounding_rects[0].width == attrs.width + attrs.border_width
  3448               && tem->bounding_rects[0].height == attrs.height + attrs.border_width
  3449               && tem->bounding_rects[0].x == -attrs.border_width
  3450               && tem->bounding_rects[0].y == -attrs.border_width
  3451 #endif
  3452               )
  3453             {
  3454               xfree (tem->bounding_rects);
  3455               tem->n_bounding_rects = -1;
  3456             }
  3457 #endif
  3458 
  3459           x_ignore_errors_for_next_request (dpyinfo);
  3460           XSelectInput (dpyinfo->display, toplevels[i],
  3461                         (attrs.your_event_mask
  3462                          | StructureNotifyMask
  3463                          | PropertyChangeMask));
  3464           x_stop_ignoring_errors (dpyinfo);
  3465 
  3466           x_dnd_toplevels = tem;
  3467         }
  3468       else
  3469         {
  3470 #ifdef HAVE_XCB_SHAPE
  3471           if (dpyinfo->xshape_supported_p)
  3472             {
  3473               bounding_rect_reply = xcb_shape_get_rectangles_reply (dpyinfo->xcb_connection,
  3474                                                                     bounding_rect_cookies[i],
  3475                                                                     &error);
  3476 
  3477               if (bounding_rect_reply)
  3478                 free (bounding_rect_reply);
  3479               else
  3480                 free (error);
  3481             }
  3482 #endif
  3483 
  3484 #ifdef HAVE_XCB_SHAPE_INPUT_RECTS
  3485           if (dpyinfo->xshape_supported_p
  3486               && (dpyinfo->xshape_major > 1
  3487                   || (dpyinfo->xshape_major == 1
  3488                       && dpyinfo->xshape_minor >= 1)))
  3489             {
  3490               input_rect_reply = xcb_shape_get_rectangles_reply (dpyinfo->xcb_connection,
  3491                                                                  input_rect_cookies[i],
  3492                                                                  &error);
  3493 
  3494               if (input_rect_reply)
  3495                 free (input_rect_reply);
  3496               else
  3497                 free (error);
  3498             }
  3499 #endif
  3500         }
  3501 
  3502 #ifdef USE_XCB
  3503       if (attrs_reply)
  3504         free (attrs_reply);
  3505 
  3506       if (coordinates_reply)
  3507         free (coordinates_reply);
  3508 
  3509       if (property_reply)
  3510         free (property_reply);
  3511 
  3512       if (xm_property_reply)
  3513         free (xm_property_reply);
  3514 
  3515       if (geometry_reply)
  3516         free (geometry_reply);
  3517 #endif
  3518 
  3519 #ifndef USE_XCB
  3520       if (wmstate_data)
  3521         {
  3522           XFree (wmstate_data);
  3523           wmstate_data = NULL;
  3524         }
  3525 #endif
  3526     }
  3527 
  3528 #ifdef USE_XCB
  3529   SAFE_FREE ();
  3530 #endif
  3531 
  3532   if (data)
  3533     XFree (data);
  3534 
  3535   return 0;
  3536 }
  3537 
  3538 static _Noreturn int
  3539 x_dnd_io_error_handler (Display *display)
  3540 {
  3541 #ifdef USE_GTK
  3542   emacs_abort ();
  3543 #else
  3544   siglongjmp (x_dnd_disconnect_handler, 1);
  3545 #endif
  3546 }
  3547 
  3548 #define X_DND_SUPPORTED_VERSION 5
  3549 
  3550 static int x_dnd_get_window_proto (struct x_display_info *, Window);
  3551 static Window x_dnd_get_window_proxy (struct x_display_info *, Window);
  3552 static void x_dnd_update_state (struct x_display_info *, Time);
  3553 
  3554 #ifdef USE_XCB
  3555 static void
  3556 x_dnd_get_proxy_proto (struct x_display_info *dpyinfo, Window wdesc,
  3557                        Window *proxy_out, int *proto_out)
  3558 {
  3559   xcb_get_property_cookie_t xdnd_proto_cookie;
  3560   xcb_get_property_cookie_t xdnd_proxy_cookie;
  3561   xcb_get_property_reply_t *reply;
  3562   xcb_generic_error_t *error;
  3563 
  3564   if (proxy_out)
  3565     *proxy_out = None;
  3566 
  3567   if (proto_out)
  3568     *proto_out = -1;
  3569 
  3570   if (proxy_out)
  3571     xdnd_proxy_cookie = xcb_get_property (dpyinfo->xcb_connection, 0,
  3572                                           (xcb_window_t) wdesc,
  3573                                           (xcb_atom_t) dpyinfo->Xatom_XdndProxy,
  3574                                           XCB_ATOM_WINDOW, 0, 1);
  3575 
  3576   if (proto_out)
  3577     xdnd_proto_cookie = xcb_get_property (dpyinfo->xcb_connection, 0,
  3578                                           (xcb_window_t) wdesc,
  3579                                           (xcb_atom_t) dpyinfo->Xatom_XdndAware,
  3580                                           XCB_ATOM_ATOM, 0, 1);
  3581 
  3582   if (proxy_out)
  3583     {
  3584       reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  3585                                       xdnd_proxy_cookie, &error);
  3586 
  3587       if (!reply)
  3588         free (error);
  3589       else
  3590         {
  3591           if (reply->format == 32
  3592               && reply->type == XCB_ATOM_WINDOW
  3593               && (xcb_get_property_value_length (reply) >= 4))
  3594             *proxy_out = *(xcb_window_t *) xcb_get_property_value (reply);
  3595 
  3596           free (reply);
  3597         }
  3598     }
  3599 
  3600   if (proto_out)
  3601     {
  3602       reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  3603                                       xdnd_proto_cookie, &error);
  3604 
  3605       if (!reply)
  3606         free (error);
  3607       else
  3608         {
  3609           if (reply->format == 32
  3610               && reply->type == XCB_ATOM_ATOM
  3611               && (xcb_get_property_value_length (reply) >= 4))
  3612             *proto_out = (int) *(xcb_atom_t *) xcb_get_property_value (reply);
  3613 
  3614           free (reply);
  3615         }
  3616     }
  3617 }
  3618 #endif
  3619 
  3620 #ifdef HAVE_XSHAPE
  3621 static bool
  3622 x_dnd_get_target_window_2 (XRectangle *rects, int nrects,
  3623                            int x, int y)
  3624 {
  3625   int i;
  3626   XRectangle *tem;
  3627 
  3628   for (i = 0; i < nrects; ++i)
  3629     {
  3630       tem = &rects[i];
  3631 
  3632       if (x >= tem->x && y >= tem->y
  3633           && x < tem->x + tem->width
  3634           && y < tem->y + tem->height)
  3635         return true;
  3636     }
  3637 
  3638   return false;
  3639 }
  3640 #endif
  3641 
  3642 static Window
  3643 x_dnd_get_target_window_1 (struct x_display_info *dpyinfo,
  3644                            int root_x, int root_y, int *motif_out,
  3645                            bool *extents_p)
  3646 {
  3647   struct x_client_list_window *tem, *chosen = NULL;
  3648 
  3649   /* Loop through x_dnd_toplevels until we find the toplevel where
  3650      root_x and root_y are.  */
  3651 
  3652   *motif_out = XM_DRAG_STYLE_NONE;
  3653 
  3654   for (tem = x_dnd_toplevels; tem; tem = tem->next)
  3655     {
  3656       if (!tem->mapped_p || tem->wm_state != NormalState)
  3657         continue;
  3658 
  3659       /* Test if the coordinates are inside the window's frame
  3660          extents, and return None in that case.  */
  3661 
  3662       *extents_p = true;
  3663       if (root_x > tem->x - tem->frame_extents_left
  3664           && root_x < tem->x
  3665           && root_y > tem->y - tem->frame_extents_top
  3666           && root_y < (tem->y + tem->height - 1
  3667                        + tem->frame_extents_bottom))
  3668         return None;
  3669 
  3670       if (root_x > tem->x + tem->width
  3671           && root_x < (tem->x + tem->width - 1
  3672                        + tem->frame_extents_right)
  3673           && root_y > tem->y - tem->frame_extents_top
  3674           && root_y < (tem->y + tem->height - 1
  3675                        + tem->frame_extents_bottom))
  3676         return None;
  3677 
  3678       if (root_y > tem->y - tem->frame_extents_top
  3679           && root_y < tem->y
  3680           && root_x > tem->x - tem->frame_extents_left
  3681           && root_x < (tem->x + tem->width - 1
  3682                        + tem->frame_extents_right))
  3683         return None;
  3684 
  3685       if (root_y > tem->y + tem->height
  3686           && root_y < (tem->y + tem->height - 1
  3687                        + tem->frame_extents_bottom)
  3688           && root_x >= tem->x - tem->frame_extents_left
  3689           && root_x < (tem->x + tem->width - 1
  3690                        + tem->frame_extents_right))
  3691         return None;
  3692       *extents_p = false;
  3693 
  3694       if (root_x >= tem->x && root_y >= tem->y
  3695           && root_x < tem->x + tem->width
  3696           && root_y < tem->y + tem->height)
  3697         {
  3698 #ifdef HAVE_XSHAPE
  3699           if (tem->n_bounding_rects == -1)
  3700 #endif
  3701             {
  3702               chosen = tem;
  3703               break;
  3704             }
  3705 
  3706 #ifdef HAVE_XSHAPE
  3707           if (x_dnd_get_target_window_2 (tem->bounding_rects,
  3708                                          tem->n_bounding_rects,
  3709                                          tem->border_width + root_x - tem->x,
  3710                                          tem->border_width + root_y - tem->y))
  3711             {
  3712               if (tem->n_input_rects == -1
  3713                   || x_dnd_get_target_window_2 (tem->input_rects,
  3714                                                 tem->n_input_rects,
  3715                                                 tem->border_width + root_x - tem->x,
  3716                                                 tem->border_width + root_y - tem->y))
  3717                 {
  3718                   chosen = tem;
  3719                   break;
  3720                 }
  3721             }
  3722 #endif
  3723         }
  3724     }
  3725 
  3726   if (chosen)
  3727     {
  3728       *motif_out = (x_dnd_disable_motif_protocol
  3729                     ? XM_DRAG_STYLE_NONE
  3730                     : chosen->xm_protocol_style);
  3731       return chosen->window;
  3732     }
  3733   else
  3734     *motif_out = XM_DRAG_STYLE_NONE;
  3735 
  3736   return None;
  3737 }
  3738 
  3739 static int
  3740 x_dnd_get_wm_state_and_proto (struct x_display_info *dpyinfo,
  3741                               Window window, int *wmstate_out,
  3742                               int *proto_out, int *motif_out,
  3743                               Window *proxy_out)
  3744 {
  3745 #ifndef USE_XCB
  3746   Atom type;
  3747   int format;
  3748   unsigned long nitems, bytes_after;
  3749   unsigned char *data = NULL;
  3750   xm_drag_receiver_info xm_info;
  3751 #else
  3752   xcb_get_property_cookie_t wmstate_cookie;
  3753   xcb_get_property_cookie_t xdnd_proto_cookie;
  3754   xcb_get_property_cookie_t xdnd_proxy_cookie;
  3755   xcb_get_property_cookie_t xm_style_cookie;
  3756   xcb_get_property_reply_t *reply;
  3757   xcb_generic_error_t *error;
  3758   uint8_t *xmdata;
  3759 #endif
  3760   int rc;
  3761 
  3762 #ifndef USE_XCB
  3763   x_catch_errors (dpyinfo->display);
  3764   rc = ((XGetWindowProperty (dpyinfo->display, window,
  3765                              dpyinfo->Xatom_wm_state,
  3766                              0, 2, False, AnyPropertyType,
  3767                              &type, &format, &nitems,
  3768                              &bytes_after, &data)
  3769          == Success)
  3770         && !x_had_errors_p (dpyinfo->display)
  3771         && data && nitems == 2 && format == 32);
  3772   x_uncatch_errors ();
  3773 
  3774   if (rc)
  3775     *wmstate_out = *(unsigned long *) data;
  3776 
  3777   *proto_out = x_dnd_get_window_proto (dpyinfo, window);
  3778 
  3779   if (!xm_read_drag_receiver_info (dpyinfo, window, &xm_info))
  3780     *motif_out = xm_info.protocol_style;
  3781   else
  3782     *motif_out = XM_DRAG_STYLE_NONE;
  3783 
  3784   *proxy_out = x_dnd_get_window_proxy (dpyinfo, window);
  3785 
  3786   if (data)
  3787     XFree (data);
  3788 #else
  3789   rc = true;
  3790 
  3791   wmstate_cookie = xcb_get_property (dpyinfo->xcb_connection, 0,
  3792                                      (xcb_window_t) window,
  3793                                      (xcb_atom_t) dpyinfo->Xatom_wm_state,
  3794                                      XCB_ATOM_ANY, 0, 2);
  3795   xdnd_proto_cookie = xcb_get_property (dpyinfo->xcb_connection, 0,
  3796                                         (xcb_window_t) window,
  3797                                         (xcb_atom_t) dpyinfo->Xatom_XdndAware,
  3798                                         XCB_ATOM_ATOM, 0, 1);
  3799   xdnd_proxy_cookie = xcb_get_property (dpyinfo->xcb_connection, 0,
  3800                                         (xcb_window_t) window,
  3801                                         (xcb_atom_t) dpyinfo->Xatom_XdndProxy,
  3802                                         XCB_ATOM_WINDOW, 0, 1);
  3803   xm_style_cookie = xcb_get_property (dpyinfo->xcb_connection, 0,
  3804                                       (xcb_window_t) window,
  3805                                       (xcb_atom_t) dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO,
  3806                                       (xcb_atom_t) dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO,
  3807                                       0, 4);
  3808 
  3809   reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  3810                                   wmstate_cookie, &error);
  3811 
  3812   if (!reply)
  3813     free (error), rc = false;
  3814   else
  3815     {
  3816       if (reply->format != 32
  3817           || xcb_get_property_value_length (reply) != 8)
  3818         rc = false;
  3819       else
  3820         *wmstate_out = *(uint32_t *) xcb_get_property_value (reply);
  3821 
  3822       free (reply);
  3823     }
  3824 
  3825   reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  3826                                   xdnd_proto_cookie, &error);
  3827 
  3828   *proto_out = -1;
  3829   if (!reply)
  3830     free (error);
  3831   else
  3832     {
  3833       if (reply->format == 32
  3834           && xcb_get_property_value_length (reply) >= 4)
  3835         *proto_out = *(uint32_t *) xcb_get_property_value (reply);
  3836 
  3837       free (reply);
  3838     }
  3839 
  3840   *proxy_out = None;
  3841   reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  3842                                   xdnd_proxy_cookie, &error);
  3843 
  3844   if (!reply)
  3845     free (error);
  3846   else
  3847     {
  3848       if (reply->format == 32
  3849           && reply->type == XCB_ATOM_WINDOW
  3850           && (xcb_get_property_value_length (reply) >= 4))
  3851         *proxy_out = *(xcb_window_t *) xcb_get_property_value (reply);
  3852 
  3853       free (reply);
  3854     }
  3855 
  3856   *motif_out = XM_DRAG_STYLE_NONE;
  3857 
  3858   reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  3859                                   xm_style_cookie, &error);
  3860 
  3861   if (!reply)
  3862     free (error);
  3863  else
  3864    {
  3865      if (reply->format == 8
  3866          && reply->type == dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO
  3867          && xcb_get_property_value_length (reply) >= 4)
  3868        {
  3869          xmdata = xcb_get_property_value (reply);
  3870          *motif_out = xmdata[2];
  3871        }
  3872 
  3873      free (reply);
  3874    }
  3875 #endif
  3876 
  3877   return rc;
  3878 }
  3879 
  3880 /* From the XDND protocol specification:
  3881 
  3882    Dropping on windows that do not support XDND
  3883 
  3884    Since middle clicking is the universal shortcut for pasting
  3885    in X, one can drop data into a window that does not support
  3886    XDND by:
  3887 
  3888    1. After the mouse has been released to trigger the drop,
  3889    obtain ownership of XA_PRIMARY.
  3890 
  3891    2. Send a ButtonPress event and then a ButtonRelease event to
  3892    the deepest subwindow containing the mouse to simulate a
  3893    middle click.  The times for these events should be the time
  3894    of the actual button release +1 and +2, respectively.  These
  3895    values will not be used by anybody else, so one can
  3896    unambiguously recognize the resulting `XConvertSelection'
  3897    request.
  3898 
  3899    3. If a request for XA_PRIMARY arrives bearing the timestamp
  3900    of either the ButtonPress or the ButtonRelease event, treat
  3901    it as a request for XdndSelection.  Note that you must use
  3902    the X data types instead of the MIME types in this case.
  3903    (e.g. XA_STRING instead of text/plain).  */
  3904 void
  3905 x_dnd_do_unsupported_drop (struct x_display_info *dpyinfo,
  3906                            Lisp_Object frame, Lisp_Object value,
  3907                            Lisp_Object targets, Window target_window,
  3908                            int root_x, int root_y, Time before)
  3909 {
  3910   XEvent event;
  3911   int dest_x, dest_y;
  3912   Window child_return, child, owner;
  3913   Lisp_Object current_value;
  3914   struct frame *f;
  3915 
  3916   f = decode_window_system_frame (frame);
  3917 
  3918   if (NILP (value))
  3919     return;
  3920 
  3921   if (!x_dnd_use_unsupported_drop)
  3922     return;
  3923 
  3924   event.xbutton.serial = 0;
  3925   event.xbutton.send_event = True;
  3926   event.xbutton.display = dpyinfo->display;
  3927   event.xbutton.root = dpyinfo->root_window;
  3928   event.xbutton.x_root = root_x;
  3929   event.xbutton.y_root = root_y;
  3930 
  3931   x_catch_errors (dpyinfo->display);
  3932 
  3933   child = dpyinfo->root_window;
  3934   dest_x = root_x;
  3935   dest_y = root_y;
  3936 
  3937   while (XTranslateCoordinates (dpyinfo->display, dpyinfo->root_window,
  3938                                 child, root_x, root_y, &dest_x, &dest_y,
  3939                                 &child_return)
  3940          && child_return != None)
  3941     child = child_return;
  3942 
  3943   x_uncatch_errors ();
  3944 
  3945   if (!CONSP (value))
  3946     return;
  3947 
  3948   current_value = assq_no_quit (QPRIMARY,
  3949                                 dpyinfo->terminal->Vselection_alist);
  3950 
  3951   if (!NILP (current_value))
  3952     current_value = XCAR (XCDR (current_value));
  3953 
  3954   x_own_selection (QPRIMARY, current_value, frame,
  3955                    XCAR (XCDR (value)), before);
  3956 
  3957   owner = XGetSelectionOwner (dpyinfo->display, XA_PRIMARY);
  3958 
  3959   /* If we didn't successfully obtain selection ownership, refrain
  3960      from generating events that will insert something else.  */
  3961 
  3962   if (owner != FRAME_X_WINDOW (f))
  3963     return;
  3964 
  3965   event.xbutton.window = child;
  3966   event.xbutton.subwindow = None;
  3967   event.xbutton.x = dest_x;
  3968   event.xbutton.y = dest_y;
  3969   event.xbutton.state = 0;
  3970   event.xbutton.button = 2;
  3971   event.xbutton.same_screen = True;
  3972 
  3973   dpyinfo->pending_dnd_time = before;
  3974 
  3975   event.xbutton.type = ButtonPress;
  3976   event.xbutton.time = before + 1;
  3977 
  3978   x_ignore_errors_for_next_request (dpyinfo);
  3979   XSendEvent (dpyinfo->display, child,
  3980               True, ButtonPressMask, &event);
  3981 
  3982   event.xbutton.type = ButtonRelease;
  3983   event.xbutton.time = before + 2;
  3984 
  3985   XSendEvent (dpyinfo->display, child,
  3986               True, ButtonReleaseMask, &event);
  3987   x_stop_ignoring_errors (dpyinfo);
  3988 
  3989   x_dnd_action_symbol = QXdndActionPrivate;
  3990 
  3991   return;
  3992 }
  3993 
  3994 static void
  3995 x_dnd_send_unsupported_drop (struct x_display_info *dpyinfo, Window target_window,
  3996                              int root_x, int root_y, Time before)
  3997 {
  3998   Lisp_Object targets, arg;
  3999   int i;
  4000   char **atom_names, *name;
  4001 
  4002   targets = Qnil;
  4003   atom_names = alloca (sizeof *atom_names * x_dnd_n_targets);
  4004 
  4005   if (!XGetAtomNames (dpyinfo->display, x_dnd_targets,
  4006                       x_dnd_n_targets, atom_names))
  4007       return;
  4008 
  4009   for (i = x_dnd_n_targets; i > 0; --i)
  4010     {
  4011       targets = Fcons (build_string (atom_names[i - 1]),
  4012                        targets);
  4013       XFree (atom_names[i - 1]);
  4014     }
  4015 
  4016   name = x_get_atom_name (dpyinfo, x_dnd_wanted_action,
  4017                           NULL);
  4018 
  4019   if (name)
  4020     {
  4021       arg = intern (name);
  4022       xfree (name);
  4023     }
  4024   else
  4025     arg = Qnil;
  4026 
  4027   x_dnd_run_unsupported_drop_function = true;
  4028   x_dnd_unsupported_drop_time = before;
  4029   x_dnd_unsupported_drop_window = target_window;
  4030   x_dnd_unsupported_drop_data
  4031     = listn (5, assq_no_quit (QXdndSelection,
  4032                               dpyinfo->terminal->Vselection_alist),
  4033              targets, arg, make_fixnum (root_x),
  4034              make_fixnum (root_y));
  4035 
  4036   x_dnd_waiting_for_finish = true;
  4037   x_dnd_finish_display = dpyinfo->display;
  4038 }
  4039 
  4040 static Window
  4041 x_dnd_fill_empty_target (int *proto_out, int *motif_out,
  4042                          Window *toplevel_out, bool *was_frame)
  4043 {
  4044   *proto_out = -1;
  4045   *motif_out = XM_DRAG_STYLE_NONE;
  4046   *toplevel_out = None;
  4047   *was_frame = false;
  4048 
  4049   return None;
  4050 }
  4051 
  4052 static Window
  4053 x_dnd_get_target_window (struct x_display_info *dpyinfo,
  4054                          int root_x, int root_y, int *proto_out,
  4055                          int *motif_out, Window *toplevel_out,
  4056                          bool *was_frame)
  4057 {
  4058   Window child_return, child, proxy;
  4059   int dest_x_return, dest_y_return, rc, proto, motif;
  4060   int parent_x, parent_y;
  4061   bool extents_p;
  4062 #if defined HAVE_XCOMPOSITE && (XCOMPOSITE_MAJOR > 0 || XCOMPOSITE_MINOR > 2)
  4063   Window overlay_window;
  4064   XWindowAttributes attrs;
  4065 #endif
  4066   int wmstate;
  4067   struct frame *tooltip, *f;
  4068   bool unrelated;
  4069 
  4070   child_return = dpyinfo->root_window;
  4071   dest_x_return = root_x;
  4072   dest_y_return = root_y;
  4073 
  4074   proto = -1;
  4075   *motif_out = XM_DRAG_STYLE_NONE;
  4076   *toplevel_out = None;
  4077   *was_frame = false;
  4078 
  4079   if (x_dnd_use_toplevels)
  4080     {
  4081       extents_p = false;
  4082       child = x_dnd_get_target_window_1 (dpyinfo, root_x,
  4083                                          root_y, motif_out,
  4084                                          &extents_p);
  4085 
  4086       if (!x_dnd_allow_current_frame
  4087           && FRAME_X_WINDOW (x_dnd_frame) == child)
  4088         *motif_out = XM_DRAG_STYLE_NONE;
  4089 
  4090       f = x_top_window_to_frame (dpyinfo, child);
  4091 
  4092       *toplevel_out = child;
  4093 
  4094       if (child != None)
  4095         {
  4096           if (f)
  4097             {
  4098               *was_frame = true;
  4099               *proto_out = -1;
  4100               *motif_out = XM_DRAG_STYLE_NONE;
  4101 
  4102               return child;
  4103             }
  4104 
  4105 #ifndef USE_XCB
  4106           proxy = x_dnd_get_window_proxy (dpyinfo, child);
  4107 #else
  4108           x_dnd_get_proxy_proto (dpyinfo, child, &proxy, proto_out);
  4109 #endif
  4110 
  4111           if (proxy != None)
  4112             {
  4113               proto = x_dnd_get_window_proto (dpyinfo, proxy);
  4114 
  4115               if (proto != -1)
  4116                 {
  4117                   *proto_out = proto;
  4118                   return proxy;
  4119                 }
  4120             }
  4121 
  4122 #ifndef USE_XCB
  4123           *proto_out = x_dnd_get_window_proto (dpyinfo, child);
  4124 #endif
  4125           return child;
  4126         }
  4127 
  4128       if (extents_p)
  4129         {
  4130           *proto_out = -1;
  4131           *motif_out = XM_DRAG_STYLE_NONE;
  4132           *toplevel_out = None;
  4133 
  4134           return None;
  4135         }
  4136 
  4137       /* Then look at the composite overlay window.  */
  4138 #if defined HAVE_XCOMPOSITE && (XCOMPOSITE_MAJOR > 0 || XCOMPOSITE_MINOR > 2)
  4139       if (dpyinfo->composite_supported_p
  4140           && (dpyinfo->composite_major > 0
  4141               || dpyinfo->composite_minor > 2))
  4142         {
  4143           if (XGetSelectionOwner (dpyinfo->display,
  4144                                   dpyinfo->Xatom_NET_WM_CM_Sn) != None)
  4145             {
  4146               x_catch_errors (dpyinfo->display);
  4147               XGrabServer (dpyinfo->display);
  4148               overlay_window = XCompositeGetOverlayWindow (dpyinfo->display,
  4149                                                            dpyinfo->root_window);
  4150               XCompositeReleaseOverlayWindow (dpyinfo->display,
  4151                                               dpyinfo->root_window);
  4152               XUngrabServer (dpyinfo->display);
  4153 
  4154               if (!x_had_errors_p (dpyinfo->display))
  4155                 {
  4156                   XGetWindowAttributes (dpyinfo->display, overlay_window, &attrs);
  4157 
  4158                   if (attrs.map_state == IsViewable)
  4159                     {
  4160                       proxy = x_dnd_get_window_proxy (dpyinfo, overlay_window);
  4161 
  4162                       if (proxy != None)
  4163                         {
  4164                           proto = x_dnd_get_window_proto (dpyinfo, proxy);
  4165 
  4166                           if (proto != -1)
  4167                             {
  4168                               *proto_out = proto;
  4169                               *toplevel_out = overlay_window;
  4170                               x_uncatch_errors_after_check ();
  4171 
  4172                               return proxy;
  4173                             }
  4174                         }
  4175                     }
  4176                 }
  4177               x_uncatch_errors_after_check ();
  4178             }
  4179         }
  4180 #endif
  4181 
  4182       /* Now look for an XdndProxy on the root window.  */
  4183 
  4184       proxy = x_dnd_get_window_proxy (dpyinfo, dpyinfo->root_window);
  4185 
  4186       if (proxy != None)
  4187         {
  4188           proto = x_dnd_get_window_proto (dpyinfo, dpyinfo->root_window);
  4189 
  4190           if (proto != -1)
  4191             {
  4192               *toplevel_out = dpyinfo->root_window;
  4193               *proto_out = proto;
  4194               return proxy;
  4195             }
  4196         }
  4197 
  4198       /* No toplevel was found and the overlay and root windows were
  4199          not proxies, so return None.  */
  4200       *proto_out = -1;
  4201       *toplevel_out = dpyinfo->root_window;
  4202       return None;
  4203     }
  4204 
  4205   /* Not strictly necessary, but satisfies GCC.  */
  4206   child = dpyinfo->root_window;
  4207 
  4208   while (child_return != None)
  4209     {
  4210       child = child_return;
  4211       parent_x = dest_x_return;
  4212       parent_y = dest_y_return;
  4213 
  4214       x_catch_errors (dpyinfo->display);
  4215       rc = XTranslateCoordinates (dpyinfo->display, dpyinfo->root_window,
  4216                                   child_return, root_x, root_y, &dest_x_return,
  4217                                   &dest_y_return, &child_return);
  4218 
  4219       if (x_had_errors_p (dpyinfo->display) || !rc)
  4220         {
  4221           x_uncatch_errors_after_check ();
  4222           break;
  4223         }
  4224 
  4225       if (child_return)
  4226         {
  4227           /* If child_return is a tooltip frame, look beneath it.  We
  4228              never want to drop anything onto a tooltip frame.  */
  4229 
  4230           tooltip = x_tooltip_window_to_frame (dpyinfo, child_return,
  4231                                                &unrelated);
  4232 
  4233           if (tooltip || unrelated)
  4234             child_return = x_get_window_below (dpyinfo->display, child_return,
  4235                                                parent_x, parent_y, &dest_x_return,
  4236                                                &dest_y_return);
  4237 
  4238           if (!child_return)
  4239             {
  4240               x_uncatch_errors ();
  4241               break;
  4242             }
  4243 
  4244           f = x_top_window_to_frame (dpyinfo, child_return);
  4245 
  4246           if (f)
  4247             {
  4248               *proto_out = -1;
  4249               *motif_out = XM_DRAG_STYLE_NONE;
  4250               *toplevel_out = child_return;
  4251               *was_frame = true;
  4252 
  4253               return child_return;
  4254             }
  4255 
  4256           if (x_dnd_get_wm_state_and_proto (dpyinfo, child_return,
  4257                                             &wmstate, &proto, &motif,
  4258                                             &proxy)
  4259               /* `proto' and `motif' are set by x_dnd_get_wm_state
  4260                  even if getting the wm state failed.  */
  4261               || proto != -1 || motif != XM_DRAG_STYLE_NONE)
  4262             {
  4263               *proto_out = proto;
  4264               *motif_out = (x_dnd_disable_motif_protocol
  4265                             ? XM_DRAG_STYLE_NONE : motif);
  4266               *toplevel_out = child_return;
  4267               x_uncatch_errors ();
  4268 
  4269               return child_return;
  4270             }
  4271 
  4272           if (proxy != None)
  4273             {
  4274               proto = x_dnd_get_window_proto (dpyinfo, proxy);
  4275 
  4276               if (proto != -1)
  4277                 {
  4278                   *proto_out = proto;
  4279                   *toplevel_out = child_return;
  4280 
  4281                   x_uncatch_errors ();
  4282                   return proxy;
  4283                 }
  4284             }
  4285         }
  4286 
  4287       x_uncatch_errors ();
  4288     }
  4289 
  4290 #if defined HAVE_XCOMPOSITE && (XCOMPOSITE_MAJOR > 0 || XCOMPOSITE_MINOR > 2)
  4291   if (child != dpyinfo->root_window)
  4292     {
  4293 #endif
  4294       if (child != None)
  4295         {
  4296           proxy = x_dnd_get_window_proxy (dpyinfo, child);
  4297 
  4298           if (proxy)
  4299             {
  4300               proto = x_dnd_get_window_proto (dpyinfo, proxy);
  4301 
  4302               if (proto != -1)
  4303                 {
  4304                   *proto_out = proto;
  4305                   *toplevel_out = child;
  4306                   return proxy;
  4307                 }
  4308             }
  4309         }
  4310 
  4311       *proto_out = x_dnd_get_window_proto (dpyinfo, child);
  4312       return child;
  4313 #if defined HAVE_XCOMPOSITE && (XCOMPOSITE_MAJOR > 0 || XCOMPOSITE_MINOR > 2)
  4314     }
  4315   else if (dpyinfo->composite_supported_p
  4316            && (dpyinfo->composite_major > 0
  4317                || dpyinfo->composite_minor > 2))
  4318     {
  4319       /* Only do this if a compositing manager is present.  */
  4320       if (XGetSelectionOwner (dpyinfo->display,
  4321                               dpyinfo->Xatom_NET_WM_CM_Sn) != None)
  4322         {
  4323           x_catch_errors (dpyinfo->display);
  4324           XGrabServer (dpyinfo->display);
  4325           overlay_window = XCompositeGetOverlayWindow (dpyinfo->display,
  4326                                                        dpyinfo->root_window);
  4327           XCompositeReleaseOverlayWindow (dpyinfo->display,
  4328                                           dpyinfo->root_window);
  4329           XUngrabServer (dpyinfo->display);
  4330 
  4331           if (!x_had_errors_p (dpyinfo->display))
  4332             {
  4333               XGetWindowAttributes (dpyinfo->display, overlay_window, &attrs);
  4334 
  4335               if (attrs.map_state == IsViewable)
  4336                 {
  4337                   proxy = x_dnd_get_window_proxy (dpyinfo, overlay_window);
  4338 
  4339                   if (proxy != None)
  4340                     {
  4341                       proto = x_dnd_get_window_proto (dpyinfo, proxy);
  4342 
  4343                       if (proto != -1)
  4344                         {
  4345                           *proto_out = proto;
  4346                           *toplevel_out = overlay_window;
  4347                           x_uncatch_errors_after_check ();
  4348 
  4349                           return proxy;
  4350                         }
  4351                     }
  4352                 }
  4353             }
  4354           x_uncatch_errors_after_check ();
  4355         }
  4356     }
  4357 
  4358   if (child != None)
  4359     {
  4360       proxy = x_dnd_get_window_proxy (dpyinfo, child);
  4361 
  4362       if (proxy)
  4363         {
  4364           proto = x_dnd_get_window_proto (dpyinfo, proxy);
  4365 
  4366           if (proto != -1)
  4367             {
  4368               *toplevel_out = child;
  4369               *proto_out = proto;
  4370               return proxy;
  4371             }
  4372         }
  4373     }
  4374 
  4375   *proto_out = x_dnd_get_window_proto (dpyinfo, child);
  4376   *toplevel_out = child;
  4377   return child;
  4378 #endif
  4379 }
  4380 
  4381 static Window
  4382 x_dnd_get_window_proxy (struct x_display_info *dpyinfo, Window wdesc)
  4383 {
  4384   int rc, actual_format;
  4385   unsigned long actual_size, bytes_remaining;
  4386   unsigned char *tmp_data = NULL;
  4387   XWindowAttributes attrs;
  4388   Atom actual_type;
  4389   Window proxy;
  4390 
  4391   proxy = None;
  4392   x_catch_errors (dpyinfo->display);
  4393   rc = XGetWindowProperty (dpyinfo->display, wdesc,
  4394                            dpyinfo->Xatom_XdndProxy,
  4395                            0, 1, False, XA_WINDOW,
  4396                            &actual_type, &actual_format,
  4397                            &actual_size, &bytes_remaining,
  4398                            &tmp_data);
  4399 
  4400   if (!x_had_errors_p (dpyinfo->display)
  4401       && rc == Success
  4402       && tmp_data
  4403       && actual_type == XA_WINDOW
  4404       && actual_format == 32
  4405       && actual_size == 1)
  4406     {
  4407       proxy = *(Window *) tmp_data;
  4408 
  4409       /* Verify the proxy window exists.  */
  4410       XGetWindowAttributes (dpyinfo->display, proxy, &attrs);
  4411 
  4412       if (x_had_errors_p (dpyinfo->display))
  4413         proxy = None;
  4414     }
  4415 
  4416   if (tmp_data)
  4417     XFree (tmp_data);
  4418   x_uncatch_errors_after_check ();
  4419 
  4420   return proxy;
  4421 }
  4422 
  4423 static int
  4424 x_dnd_get_window_proto (struct x_display_info *dpyinfo, Window wdesc)
  4425 {
  4426   Atom actual, value;
  4427   unsigned char *tmp_data = NULL;
  4428   int rc, format;
  4429   unsigned long n, left;
  4430   bool had_errors;
  4431 
  4432   if (wdesc == None || (!x_dnd_allow_current_frame
  4433                         && wdesc == FRAME_OUTER_WINDOW (x_dnd_frame)))
  4434     return -1;
  4435 
  4436   x_catch_errors (dpyinfo->display);
  4437   rc = XGetWindowProperty (dpyinfo->display, wdesc, dpyinfo->Xatom_XdndAware,
  4438                            0, 1, False, XA_ATOM, &actual, &format, &n, &left,
  4439                            &tmp_data);
  4440   had_errors = x_had_errors_p (dpyinfo->display);
  4441   x_uncatch_errors_after_check ();
  4442 
  4443   if (had_errors || rc != Success || actual != XA_ATOM || format != 32 || n < 1
  4444       || !tmp_data)
  4445     {
  4446       if (tmp_data)
  4447         XFree (tmp_data);
  4448       return -1;
  4449     }
  4450 
  4451   value = (int) *(Atom *) tmp_data;
  4452   XFree (tmp_data);
  4453 
  4454   return min (X_DND_SUPPORTED_VERSION, (int) value);
  4455 }
  4456 
  4457 static void
  4458 x_dnd_send_enter (struct frame *f, Window target, Window toplevel,
  4459                   int supported)
  4460 {
  4461   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  4462   int i;
  4463   XEvent msg;
  4464 
  4465   msg.xclient.type = ClientMessage;
  4466   msg.xclient.message_type = dpyinfo->Xatom_XdndEnter;
  4467   msg.xclient.format = 32;
  4468   msg.xclient.window = toplevel;
  4469   msg.xclient.data.l[0] = FRAME_X_WINDOW (f);
  4470   msg.xclient.data.l[1] = (((unsigned int) min (X_DND_SUPPORTED_VERSION,
  4471                                                 supported) << 24)
  4472                            | (x_dnd_n_targets > 3 ? 1 : 0));
  4473   msg.xclient.data.l[2] = 0;
  4474   msg.xclient.data.l[3] = 0;
  4475   msg.xclient.data.l[4] = 0;
  4476 
  4477   for (i = 0; i < min (3, x_dnd_n_targets); ++i)
  4478     msg.xclient.data.l[i + 2] = x_dnd_targets[i];
  4479 
  4480   if (x_dnd_n_targets > 3 && !x_dnd_init_type_lists)
  4481     XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
  4482                      dpyinfo->Xatom_XdndTypeList, XA_ATOM, 32,
  4483                      PropModeReplace, (unsigned char *) x_dnd_targets,
  4484                      x_dnd_n_targets);
  4485 
  4486   /* Now record that the type list has already been set (if required),
  4487      so we don't have to set it again.  */
  4488   x_dnd_init_type_lists = true;
  4489 
  4490   x_ignore_errors_for_next_request (dpyinfo);
  4491   XSendEvent (FRAME_X_DISPLAY (f), target, False, NoEventMask, &msg);
  4492   x_stop_ignoring_errors (dpyinfo);
  4493 }
  4494 
  4495 static void
  4496 x_dnd_send_position (struct frame *f, Window target, Window toplevel,
  4497                      int supported, unsigned short root_x,
  4498                      unsigned short root_y, Time timestamp, Atom action,
  4499                      int button, unsigned state)
  4500 {
  4501   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  4502   XEvent msg;
  4503 
  4504   msg.xclient.type = ClientMessage;
  4505   msg.xclient.message_type = dpyinfo->Xatom_XdndPosition;
  4506   msg.xclient.format = 32;
  4507   msg.xclient.window = toplevel;
  4508   msg.xclient.data.l[0] = FRAME_X_WINDOW (f);
  4509   msg.xclient.data.l[1] = 0;
  4510 
  4511   /* This is problematic because it's not specified in the
  4512      freedesktop.org copy of the protocol specification, but the copy
  4513      maintained by the original author of the protocol specifies it
  4514      for all versions.  Since at least one program supports these
  4515      flags, but uses protocol v4 (and not v5), set them for all
  4516      protocol versions.  */
  4517   if (button >= 4 && button <= 7)
  4518     {
  4519       msg.xclient.data.l[1] |= (1 << 10);
  4520       msg.xclient.data.l[1] |= (button - 4) << 8;
  4521     }
  4522   else if (button)
  4523     return;
  4524 
  4525   msg.xclient.data.l[1] |= state & 0xff;
  4526 
  4527   msg.xclient.data.l[2] = (root_x << 16) | root_y;
  4528   msg.xclient.data.l[3] = 0;
  4529   msg.xclient.data.l[4] = 0;
  4530 
  4531   if (supported >= 3)
  4532     msg.xclient.data.l[3] = timestamp;
  4533 
  4534   if (supported >= 4)
  4535     msg.xclient.data.l[4] = action;
  4536 
  4537   if (x_dnd_waiting_for_status_window == target)
  4538     {
  4539       x_dnd_pending_send_position = msg;
  4540       x_dnd_pending_send_position_button = button;
  4541       x_dnd_pending_send_position_root_x = root_x;
  4542       x_dnd_pending_send_position_root_y = root_y;
  4543     }
  4544   else
  4545     {
  4546       if (target == x_dnd_mouse_rect_target
  4547           && x_dnd_mouse_rect.width
  4548           && x_dnd_mouse_rect.height
  4549           /* Ignore the mouse rectangle if we're supposed to be sending a
  4550              button press instead.  */
  4551           && !button)
  4552         {
  4553           if (root_x >= x_dnd_mouse_rect.x
  4554               && root_x < (x_dnd_mouse_rect.x
  4555                            + x_dnd_mouse_rect.width)
  4556               && root_y >= x_dnd_mouse_rect.y
  4557               && root_y < (x_dnd_mouse_rect.y
  4558                            + x_dnd_mouse_rect.height))
  4559             return;
  4560         }
  4561 
  4562       x_ignore_errors_for_next_request (dpyinfo);
  4563       XSendEvent (FRAME_X_DISPLAY (f), target, False, NoEventMask, &msg);
  4564       x_stop_ignoring_errors (dpyinfo);
  4565 
  4566       x_dnd_waiting_for_status_window = target;
  4567     }
  4568 }
  4569 
  4570 static void
  4571 x_dnd_send_leave (struct frame *f, Window target, Window toplevel)
  4572 {
  4573   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  4574   XEvent msg;
  4575 
  4576   msg.xclient.type = ClientMessage;
  4577   msg.xclient.message_type = dpyinfo->Xatom_XdndLeave;
  4578   msg.xclient.format = 32;
  4579   msg.xclient.window = toplevel;
  4580   msg.xclient.data.l[0] = FRAME_X_WINDOW (f);
  4581   msg.xclient.data.l[1] = 0;
  4582   msg.xclient.data.l[2] = 0;
  4583   msg.xclient.data.l[3] = 0;
  4584   msg.xclient.data.l[4] = 0;
  4585 
  4586   x_dnd_waiting_for_status_window = None;
  4587   x_dnd_pending_send_position.type = 0;
  4588 
  4589   x_ignore_errors_for_next_request (dpyinfo);
  4590   XSendEvent (FRAME_X_DISPLAY (f), target, False, NoEventMask, &msg);
  4591   x_stop_ignoring_errors (dpyinfo);
  4592 }
  4593 
  4594 static bool
  4595 x_dnd_send_drop (struct frame *f, Window target, Window toplevel,
  4596                  Time timestamp, int supported)
  4597 {
  4598   struct x_display_info *dpyinfo;
  4599   XEvent msg;
  4600 
  4601   if (x_dnd_action == None)
  4602     {
  4603       x_dnd_send_leave (f, target, toplevel);
  4604       return false;
  4605     }
  4606 
  4607   dpyinfo = FRAME_DISPLAY_INFO (f);
  4608 
  4609   msg.xclient.type = ClientMessage;
  4610   msg.xclient.message_type = dpyinfo->Xatom_XdndDrop;
  4611   msg.xclient.format = 32;
  4612   msg.xclient.window = toplevel;
  4613   msg.xclient.data.l[0] = FRAME_X_WINDOW (f);
  4614   msg.xclient.data.l[1] = 0;
  4615   msg.xclient.data.l[2] = 0;
  4616   msg.xclient.data.l[3] = 0;
  4617   msg.xclient.data.l[4] = 0;
  4618 
  4619   if (supported >= 1)
  4620     msg.xclient.data.l[2] = timestamp;
  4621 
  4622   x_ignore_errors_for_next_request (dpyinfo);
  4623   XSendEvent (FRAME_X_DISPLAY (f), target, False, NoEventMask, &msg);
  4624   x_stop_ignoring_errors (dpyinfo);
  4625   return true;
  4626 }
  4627 
  4628 static bool
  4629 x_dnd_do_drop (Window target, Window toplevel, int supported)
  4630 {
  4631   if (x_dnd_waiting_for_status_window != target)
  4632     return x_dnd_send_drop (x_dnd_frame, target, toplevel,
  4633                             x_dnd_selection_timestamp, supported);
  4634 
  4635   x_dnd_need_send_drop = true;
  4636   x_dnd_send_drop_proto = supported;
  4637 
  4638   return true;
  4639 }
  4640 
  4641 static void
  4642 x_set_dnd_targets (Atom *targets, int ntargets)
  4643 {
  4644   if (x_dnd_targets)
  4645     xfree (x_dnd_targets);
  4646 
  4647   block_input ();
  4648   x_dnd_targets = xmalloc (sizeof *targets * ntargets);
  4649   x_dnd_n_targets = ntargets;
  4650 
  4651   memcpy (x_dnd_targets, targets,
  4652           sizeof *targets * ntargets);
  4653   unblock_input ();
  4654 }
  4655 
  4656 static void
  4657 x_free_dnd_targets (void)
  4658 {
  4659   if (!x_dnd_targets)
  4660     return;
  4661 
  4662   xfree (x_dnd_targets);
  4663   x_dnd_targets = NULL;
  4664   x_dnd_n_targets = 0;
  4665 }
  4666 
  4667 /* Clear some Lisp variables after the drop finishes, so they are
  4668    freed by the GC.  */
  4669 
  4670 static void
  4671 x_clear_dnd_variables (void)
  4672 {
  4673   x_dnd_monitors = Qnil;
  4674   x_dnd_unsupported_drop_data = Qnil;
  4675 }
  4676 
  4677 static void
  4678 x_free_dnd_toplevels (void)
  4679 {
  4680   if (!x_dnd_use_toplevels || !x_dnd_toplevels)
  4681     return;
  4682 
  4683   /* If the display is deleted, x_dnd_toplevels will already be
  4684      NULL, so we can always assume the display is alive here.  */
  4685 
  4686   x_dnd_free_toplevels (true);
  4687 }
  4688 
  4689 /* Restore event masks and window properties changed during a
  4690    drag-and-drop operation, after it finishes.  */
  4691 static void
  4692 x_restore_events_after_dnd (struct frame *f, XWindowAttributes *wa)
  4693 {
  4694   struct x_display_info *dpyinfo;
  4695 
  4696   dpyinfo = FRAME_DISPLAY_INFO (f);
  4697 
  4698   /* Restore the old event mask.  */
  4699   XSelectInput (dpyinfo->display, dpyinfo->root_window,
  4700                 wa->your_event_mask);
  4701 #ifdef HAVE_XKB
  4702   if (dpyinfo->supports_xkb)
  4703     XkbSelectEvents (dpyinfo->display, XkbUseCoreKbd,
  4704                      XkbStateNotifyMask, 0);
  4705 #endif
  4706   /* Delete the Motif drag initiator info if it was set up.  */
  4707   if (x_dnd_motif_setup_p)
  4708     XDeleteProperty (dpyinfo->display, FRAME_X_WINDOW (f),
  4709                      x_dnd_motif_atom);
  4710 
  4711   /* Remove any type list set as well.  */
  4712   if (x_dnd_init_type_lists && x_dnd_n_targets > 3)
  4713     XDeleteProperty (dpyinfo->display, FRAME_X_WINDOW (f),
  4714                      dpyinfo->Xatom_XdndTypeList);
  4715 }
  4716 
  4717 #ifdef HAVE_XINPUT2
  4718 
  4719 /* Cancel the current drag-and-drop operation, sending leave messages
  4720    to any relevant toplevels.  This is called from the event loop when
  4721    an event is received telling Emacs to gracefully cancel the
  4722    drag-and-drop operation.  */
  4723 
  4724 static void
  4725 x_dnd_cancel_dnd_early (void)
  4726 {
  4727   struct frame *f;
  4728   xm_drop_start_message dmsg;
  4729 
  4730   eassert (x_dnd_frame && x_dnd_in_progress);
  4731 
  4732   f = x_dnd_frame;
  4733 
  4734   if (x_dnd_last_seen_window != None
  4735       && x_dnd_last_protocol_version != -1)
  4736     x_dnd_send_leave (x_dnd_frame,
  4737                       x_dnd_last_seen_window,
  4738                       x_dnd_last_seen_toplevel);
  4739   else if (x_dnd_last_seen_window != None
  4740            && !XM_DRAG_STYLE_IS_DROP_ONLY (x_dnd_last_motif_style)
  4741            && x_dnd_last_motif_style != XM_DRAG_STYLE_NONE
  4742            && x_dnd_motif_setup_p)
  4743     {
  4744       dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
  4745                                     XM_DRAG_REASON_DROP_START);
  4746       dmsg.byte_order = XM_BYTE_ORDER_CUR_FIRST;
  4747       dmsg.timestamp = FRAME_DISPLAY_INFO (f)->last_user_time;
  4748       dmsg.side_effects
  4749         = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (FRAME_DISPLAY_INFO (f),
  4750                                                            x_dnd_wanted_action),
  4751                                XM_DROP_SITE_VALID, x_dnd_motif_operations,
  4752                                XM_DROP_ACTION_DROP_CANCEL);
  4753       dmsg.x = 0;
  4754       dmsg.y = 0;
  4755       dmsg.index_atom = x_dnd_motif_atom;
  4756       dmsg.source_window = FRAME_X_WINDOW (f);
  4757 
  4758       x_dnd_send_xm_leave_for_drop (FRAME_DISPLAY_INFO (f), f,
  4759                                     x_dnd_last_seen_window,
  4760                                     FRAME_DISPLAY_INFO (f)->last_user_time);
  4761       xm_send_drop_message (FRAME_DISPLAY_INFO (f), FRAME_X_WINDOW (f),
  4762                             x_dnd_last_seen_window, &dmsg);
  4763     }
  4764 
  4765   x_dnd_last_seen_window = None;
  4766   x_dnd_last_seen_toplevel = None;
  4767   x_dnd_in_progress = false;
  4768   x_dnd_waiting_for_finish = false;
  4769   x_dnd_return_frame_object = NULL;
  4770   x_dnd_movement_frame = NULL;
  4771   x_dnd_wheel_frame = NULL;
  4772   x_dnd_frame = NULL;
  4773   x_dnd_action = None;
  4774   x_dnd_action_symbol = Qnil;
  4775 }
  4776 
  4777 #endif
  4778 
  4779 static void
  4780 x_dnd_cleanup_drag_and_drop (void *frame)
  4781 {
  4782   struct frame *f = frame;
  4783   xm_drop_start_message dmsg;
  4784 
  4785   if (!x_dnd_unwind_flag)
  4786     return;
  4787 
  4788   if (x_dnd_in_progress)
  4789     {
  4790       eassert (x_dnd_frame);
  4791 
  4792       block_input ();
  4793       if (x_dnd_last_seen_window != None
  4794           && x_dnd_last_protocol_version != -1)
  4795         x_dnd_send_leave (x_dnd_frame,
  4796                           x_dnd_last_seen_window,
  4797                           x_dnd_last_seen_toplevel);
  4798       else if (x_dnd_last_seen_window != None
  4799                && !XM_DRAG_STYLE_IS_DROP_ONLY (x_dnd_last_motif_style)
  4800                && x_dnd_last_motif_style != XM_DRAG_STYLE_NONE
  4801                && x_dnd_motif_setup_p)
  4802         {
  4803           dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
  4804                                         XM_DRAG_REASON_DROP_START);
  4805           dmsg.byte_order = XM_BYTE_ORDER_CUR_FIRST;
  4806           dmsg.timestamp = FRAME_DISPLAY_INFO (f)->last_user_time;
  4807           dmsg.side_effects
  4808             = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (FRAME_DISPLAY_INFO (f),
  4809                                                                x_dnd_wanted_action),
  4810                                    XM_DROP_SITE_VALID, x_dnd_motif_operations,
  4811                                    XM_DROP_ACTION_DROP_CANCEL);
  4812           dmsg.x = 0;
  4813           dmsg.y = 0;
  4814           dmsg.index_atom = x_dnd_motif_atom;
  4815           dmsg.source_window = FRAME_X_WINDOW (f);
  4816 
  4817           x_dnd_send_xm_leave_for_drop (FRAME_DISPLAY_INFO (f), f,
  4818                                         x_dnd_last_seen_window,
  4819                                         FRAME_DISPLAY_INFO (f)->last_user_time);
  4820           xm_send_drop_message (FRAME_DISPLAY_INFO (f), FRAME_X_WINDOW (f),
  4821                                 x_dnd_last_seen_window, &dmsg);
  4822         }
  4823       unblock_input ();
  4824 
  4825       x_dnd_end_window = x_dnd_last_seen_window;
  4826       x_dnd_last_seen_window = None;
  4827       x_dnd_last_seen_toplevel = None;
  4828       x_dnd_in_progress = false;
  4829     }
  4830 
  4831   x_dnd_waiting_for_finish = false;
  4832 
  4833   FRAME_DISPLAY_INFO (f)->grabbed = 0;
  4834 #ifdef USE_GTK
  4835   current_hold_quit = NULL;
  4836 #endif
  4837   x_dnd_return_frame_object = NULL;
  4838   x_dnd_movement_frame = NULL;
  4839   x_dnd_wheel_frame = NULL;
  4840   x_dnd_frame = NULL;
  4841 
  4842   x_restore_events_after_dnd (f, &x_dnd_old_window_attrs);
  4843 }
  4844 
  4845 static void
  4846 x_dnd_note_self_position (struct x_display_info *dpyinfo, Window target,
  4847                           unsigned short root_x, unsigned short root_y)
  4848 {
  4849   struct frame *f;
  4850   int dest_x, dest_y;
  4851 
  4852   f = x_top_window_to_frame (dpyinfo, target);
  4853 
  4854   if (f)
  4855     {
  4856       x_translate_coordinates (f, root_x, root_y, &dest_x, &dest_y);
  4857 
  4858       x_dnd_movement_frame = f;
  4859       x_dnd_movement_x = dest_x;
  4860       x_dnd_movement_y = dest_y;
  4861 
  4862       return;
  4863     }
  4864 }
  4865 
  4866 static void
  4867 x_dnd_note_self_wheel (struct x_display_info *dpyinfo, Window target,
  4868                        unsigned short root_x, unsigned short root_y,
  4869                        int button, unsigned int state, Time time)
  4870 {
  4871   struct frame *f;
  4872   int dest_x, dest_y;
  4873 
  4874   if (button < 4 || button > 7)
  4875     return;
  4876 
  4877   f = x_top_window_to_frame (dpyinfo, target);
  4878 
  4879   if (f)
  4880     {
  4881       x_translate_coordinates (f, root_x, root_y, &dest_x, &dest_y);
  4882 
  4883       x_dnd_wheel_frame = f;
  4884       x_dnd_wheel_x = dest_x;
  4885       x_dnd_wheel_y = dest_y;
  4886       x_dnd_wheel_button = button;
  4887       x_dnd_wheel_state = state;
  4888       x_dnd_wheel_time = time;
  4889 
  4890       return;
  4891     }
  4892 }
  4893 
  4894 static void
  4895 x_dnd_note_self_drop (struct x_display_info *dpyinfo, Window target,
  4896                       unsigned short root_x, unsigned short root_y,
  4897                       Time timestamp)
  4898 {
  4899   struct input_event ie;
  4900   struct frame *f;
  4901   Lisp_Object lval;
  4902   char **atom_names;
  4903   char *name;
  4904   int win_x, win_y, i;
  4905 
  4906   if (!x_dnd_allow_current_frame
  4907       && (FRAME_OUTER_WINDOW (x_dnd_frame)
  4908           == target))
  4909     return;
  4910 
  4911   f = x_top_window_to_frame (dpyinfo, target);
  4912 
  4913   if (!f)
  4914     return;
  4915 
  4916   if (NILP (Vx_dnd_native_test_function))
  4917     return;
  4918 
  4919   x_translate_coordinates (f, root_x, root_y, &win_x, &win_y);
  4920 
  4921   /* Emacs can't respond to DND events inside the nested event loop,
  4922      so when dragging items to itself, call the test function
  4923      manually.  */
  4924 
  4925   XSETFRAME (lval, f);
  4926   x_dnd_action = None;
  4927   x_dnd_action_symbol
  4928     = safe_call2 (Vx_dnd_native_test_function,
  4929                   Fposn_at_x_y (make_fixnum (win_x),
  4930                                 make_fixnum (win_y),
  4931                                 lval, Qnil),
  4932                   x_atom_to_symbol (dpyinfo,
  4933                                     x_dnd_wanted_action));
  4934 
  4935   if (!SYMBOLP (x_dnd_action_symbol))
  4936     return;
  4937 
  4938   EVENT_INIT (ie);
  4939 
  4940   ie.kind = DRAG_N_DROP_EVENT;
  4941   XSETFRAME (ie.frame_or_window, f);
  4942 
  4943   lval = Qnil;
  4944   atom_names = alloca (x_dnd_n_targets * sizeof *atom_names);
  4945   name = x_get_atom_name (dpyinfo, x_dnd_wanted_action, NULL);
  4946 
  4947   if (!XGetAtomNames (dpyinfo->display, x_dnd_targets,
  4948                       x_dnd_n_targets, atom_names))
  4949     {
  4950       xfree (name);
  4951       return;
  4952     }
  4953 
  4954   for (i = x_dnd_n_targets; i != 0; --i)
  4955     {
  4956       lval = Fcons (intern (atom_names[i - 1]), lval);
  4957       XFree (atom_names[i - 1]);
  4958     }
  4959 
  4960   lval = Fcons (assq_no_quit (QXdndSelection,
  4961                               FRAME_TERMINAL (f)->Vselection_alist),
  4962                 lval);
  4963   lval = Fcons (intern (name), lval);
  4964   lval = Fcons (QXdndSelection, lval);
  4965   ie.arg = lval;
  4966   ie.timestamp = timestamp;
  4967 
  4968   XSETINT (ie.x, win_x);
  4969   XSETINT (ie.y, win_y);
  4970 
  4971   xfree (name);
  4972   kbd_buffer_store_event (&ie);
  4973 }
  4974 
  4975 /* Flush display of frame F.  */
  4976 
  4977 static void
  4978 x_flush (struct frame *f)
  4979 {
  4980   eassert (f && FRAME_X_P (f));
  4981   /* Don't call XFlush when it is not safe to redisplay; the X
  4982      connection may be broken.  */
  4983   if (!NILP (Vinhibit_redisplay))
  4984     return;
  4985 
  4986   block_input ();
  4987   XFlush (FRAME_X_DISPLAY (f));
  4988   unblock_input ();
  4989 }
  4990 
  4991 #ifdef HAVE_XDBE
  4992 static void
  4993 x_drop_xrender_surfaces (struct frame *f)
  4994 {
  4995   font_drop_xrender_surfaces (f);
  4996 
  4997 #ifdef HAVE_XRENDER
  4998   if (f && FRAME_X_DOUBLE_BUFFERED_P (f)
  4999       && FRAME_X_PICTURE (f) != None)
  5000     {
  5001       XRenderFreePicture (FRAME_X_DISPLAY (f),
  5002                           FRAME_X_PICTURE (f));
  5003       FRAME_X_PICTURE (f) = None;
  5004     }
  5005 #endif
  5006 }
  5007 #endif
  5008 
  5009 #ifdef HAVE_XRENDER
  5010 void
  5011 x_xr_ensure_picture (struct frame *f)
  5012 {
  5013   if (FRAME_X_PICTURE (f) == None && FRAME_X_PICTURE_FORMAT (f))
  5014     {
  5015       XRenderPictureAttributes attrs;
  5016       attrs.clip_mask = None;
  5017       XRenderPictFormat *fmt = FRAME_X_PICTURE_FORMAT (f);
  5018 
  5019       FRAME_X_PICTURE (f) = XRenderCreatePicture (FRAME_X_DISPLAY (f),
  5020                                                   FRAME_X_RAW_DRAWABLE (f),
  5021                                                   fmt, CPClipMask, &attrs);
  5022     }
  5023 }
  5024 #endif
  5025 
  5026 
  5027 /***********************************************************************
  5028                               Debugging
  5029  ***********************************************************************/
  5030 
  5031 #if false
  5032 
  5033 /* This is a function useful for recording debugging information about
  5034    the sequence of occurrences in this file.  */
  5035 
  5036 struct record
  5037 {
  5038   char *locus;
  5039   int type;
  5040 };
  5041 
  5042 struct record event_record[100];
  5043 
  5044 int event_record_index;
  5045 
  5046 void
  5047 record_event (char *locus, int type)
  5048 {
  5049   if (event_record_index == ARRAYELTS (event_record))
  5050     event_record_index = 0;
  5051 
  5052   event_record[event_record_index].locus = locus;
  5053   event_record[event_record_index].type = type;
  5054   event_record_index++;
  5055 }
  5056 
  5057 #endif
  5058 
  5059 #ifdef HAVE_XINPUT2
  5060 bool
  5061 xi_frame_selected_for (struct frame *f, unsigned long event)
  5062 {
  5063   XIEventMask *masks;
  5064   int i;
  5065 
  5066   masks = FRAME_X_OUTPUT (f)->xi_masks;
  5067 
  5068   if (!masks)
  5069     return false;
  5070 
  5071   for (i = 0; i < FRAME_X_OUTPUT (f)->num_xi_masks; ++i)
  5072     {
  5073       if (masks[i].mask_len >= XIMaskLen (event)
  5074           && XIMaskIsSet (masks[i].mask, event))
  5075         return true;
  5076     }
  5077 
  5078   return false;
  5079 }
  5080 #endif
  5081 
  5082 static void
  5083 x_toolkit_position (struct frame *f, int x, int y,
  5084                     bool *menu_bar_p, bool *tool_bar_p)
  5085 {
  5086 #ifdef USE_GTK
  5087   GdkRectangle test_rect;
  5088   int scale;
  5089 
  5090   y += (FRAME_MENUBAR_HEIGHT (f)
  5091         + FRAME_TOOLBAR_TOP_HEIGHT (f));
  5092   x += FRAME_TOOLBAR_LEFT_WIDTH (f);
  5093 
  5094   if (FRAME_EXTERNAL_MENU_BAR (f))
  5095     *menu_bar_p = (x >= 0 && x < FRAME_PIXEL_WIDTH (f)
  5096                    && y >= 0 && y < FRAME_MENUBAR_HEIGHT (f));
  5097 
  5098   if (FRAME_X_OUTPUT (f)->toolbar_widget)
  5099     {
  5100       scale = xg_get_scale (f);
  5101       test_rect.x = x / scale;
  5102       test_rect.y = y / scale;
  5103       test_rect.width = 1;
  5104       test_rect.height = 1;
  5105 
  5106       *tool_bar_p = gtk_widget_intersect (FRAME_X_OUTPUT (f)->toolbar_widget,
  5107                                           &test_rect, NULL);
  5108     }
  5109 #elif defined USE_X_TOOLKIT
  5110   *menu_bar_p = (x > 0 && x < FRAME_PIXEL_WIDTH (f)
  5111                  && (y < 0 && y >= -FRAME_MENUBAR_HEIGHT (f)));
  5112 #else
  5113   *menu_bar_p = (WINDOWP (f->menu_bar_window)
  5114                  && (x > 0 && x < FRAME_PIXEL_WIDTH (f)
  5115                      && (y > 0 && y < FRAME_MENU_BAR_HEIGHT (f))));
  5116 #endif
  5117 }
  5118 
  5119 static void
  5120 x_update_opaque_region (struct frame *f, XEvent *configure)
  5121 {
  5122   unsigned long opaque_region[] = {0, 0,
  5123                                    (configure
  5124                                     ? configure->xconfigure.width
  5125                                     : FRAME_PIXEL_WIDTH (f)),
  5126                                    (configure
  5127                                     ? configure->xconfigure.height
  5128                                     : FRAME_PIXEL_HEIGHT (f))};
  5129 #ifdef HAVE_GTK3
  5130   GObjectClass *object_class;
  5131   GtkWidgetClass *class;
  5132 #endif
  5133 
  5134   if (!FRAME_DISPLAY_INFO (f)->alpha_bits)
  5135     return;
  5136 
  5137   if (f->alpha_background < 1.0)
  5138     XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
  5139                      FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region,
  5140                      XA_CARDINAL, 32, PropModeReplace,
  5141                      NULL, 0);
  5142 #ifndef HAVE_GTK3
  5143   else
  5144     XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
  5145                      FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region,
  5146                      XA_CARDINAL, 32, PropModeReplace,
  5147                      (unsigned char *) &opaque_region, 4);
  5148 #else
  5149   else if (FRAME_TOOLTIP_P (f))
  5150     XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
  5151                      FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region,
  5152                      XA_CARDINAL, 32, PropModeReplace,
  5153                      (unsigned char *) &opaque_region, 4);
  5154   else
  5155     {
  5156       /* This causes child frames to not update correctly for an
  5157          unknown reason.  (bug#55779) */
  5158       if (!FRAME_PARENT_FRAME (f))
  5159         {
  5160           object_class = G_OBJECT_GET_CLASS (FRAME_GTK_OUTER_WIDGET (f));
  5161           class = GTK_WIDGET_CLASS (object_class);
  5162 
  5163           if (class->style_updated)
  5164             class->style_updated (FRAME_GTK_OUTER_WIDGET (f));
  5165         }
  5166     }
  5167 #endif
  5168 }
  5169 
  5170 
  5171 #if defined USE_CAIRO || defined HAVE_XRENDER
  5172 static int
  5173 x_gc_free_ext_data_private (XExtData *extension)
  5174 {
  5175   xfree (extension->private_data);
  5176 
  5177   return 0;
  5178 }
  5179 
  5180 static struct x_gc_ext_data *
  5181 x_gc_get_ext_data (struct frame *f, GC gc, int create_if_not_found_p)
  5182 {
  5183   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  5184   XEDataObject object;
  5185   XExtData **head, *ext_data;
  5186 
  5187   object.gc = gc;
  5188   head = XEHeadOfExtensionList (object);
  5189   ext_data = XFindOnExtensionList (head, dpyinfo->ext_codes->extension);
  5190   if (ext_data == NULL)
  5191     {
  5192       if (!create_if_not_found_p)
  5193         return NULL;
  5194       else
  5195         {
  5196           ext_data = xzalloc (sizeof (*ext_data));
  5197           ext_data->number = dpyinfo->ext_codes->extension;
  5198           ext_data->private_data = xzalloc (sizeof (struct x_gc_ext_data));
  5199           ext_data->free_private = x_gc_free_ext_data_private;
  5200           XAddToExtensionList (head, ext_data);
  5201         }
  5202     }
  5203   return (struct x_gc_ext_data *) ext_data->private_data;
  5204 }
  5205 
  5206 static void
  5207 x_extension_initialize (struct x_display_info *dpyinfo)
  5208 {
  5209   XExtCodes *ext_codes = XAddExtension (dpyinfo->display);
  5210 
  5211   dpyinfo->ext_codes = ext_codes;
  5212 }
  5213 #endif
  5214 
  5215 #ifdef USE_CAIRO
  5216 
  5217 #define FRAME_CR_CONTEXT(f)     ((f)->output_data.x->cr_context)
  5218 #define FRAME_CR_SURFACE_DESIRED_WIDTH(f) \
  5219   ((f)->output_data.x->cr_surface_desired_width)
  5220 #define FRAME_CR_SURFACE_DESIRED_HEIGHT(f) \
  5221   ((f)->output_data.x->cr_surface_desired_height)
  5222 
  5223 #endif /* HAVE_CAIRO */
  5224 
  5225 #ifdef HAVE_XINPUT2
  5226 
  5227 /* Convert XI2 button state IN to a standard X button modifier
  5228    mask, and place it in OUT.  */
  5229 static void
  5230 xi_convert_button_state (XIButtonState *in, unsigned int *out)
  5231 {
  5232   int i;
  5233 
  5234   if (in->mask_len)
  5235     {
  5236       for (i = 1; i <= 8; ++i)
  5237         {
  5238           if (XIMaskIsSet (in->mask, i))
  5239             *out |= (Button1Mask << (i - 1));
  5240         }
  5241     }
  5242 }
  5243 
  5244 /* Return the modifier state in XEV as a standard X modifier mask.
  5245    This should be used for non-keyboard events, where the group does
  5246    not matter.  */
  5247 
  5248 #ifdef USE_GTK
  5249 static
  5250 #endif
  5251 unsigned int
  5252 xi_convert_event_state (XIDeviceEvent *xev)
  5253 {
  5254   unsigned int mods, buttons;
  5255 
  5256   mods = xev->mods.effective;
  5257   buttons = 0;
  5258 
  5259   xi_convert_button_state (&xev->buttons, &buttons);
  5260 
  5261   return mods | buttons;
  5262 }
  5263 
  5264 /* Like the above.  However, buttons are not converted, while the
  5265    group is.  This should be used for key events being passed to the
  5266    likes of input methods and Xt.  */
  5267 
  5268 static unsigned int
  5269 xi_convert_event_keyboard_state (XIDeviceEvent *xev)
  5270 {
  5271   return ((xev->mods.effective & ~(1 << 13 | 1 << 14))
  5272           | (xev->group.effective << 13));
  5273 }
  5274 
  5275 /* Free all XI2 devices on DPYINFO.  */
  5276 static void
  5277 x_free_xi_devices (struct x_display_info *dpyinfo)
  5278 {
  5279 #ifdef HAVE_XINPUT2_2
  5280   struct xi_touch_point_t *tem, *last;
  5281 #endif
  5282 
  5283   block_input ();
  5284 
  5285   if (dpyinfo->num_devices)
  5286     {
  5287       for (int i = 0; i < dpyinfo->num_devices; ++i)
  5288         {
  5289 #ifdef HAVE_XINPUT2_1
  5290           xfree (dpyinfo->devices[i].valuators);
  5291 #endif
  5292 
  5293 #ifdef HAVE_XINPUT2_2
  5294           tem = dpyinfo->devices[i].touchpoints;
  5295           while (tem)
  5296             {
  5297               last = tem;
  5298               tem = tem->next;
  5299               xfree (last);
  5300             }
  5301 #endif
  5302         }
  5303 
  5304       xfree (dpyinfo->devices);
  5305       dpyinfo->devices = NULL;
  5306       dpyinfo->num_devices = 0;
  5307     }
  5308 
  5309   unblock_input ();
  5310 }
  5311 
  5312 #ifdef HAVE_XINPUT2_1
  5313 
  5314 struct xi_known_valuator
  5315 {
  5316   /* The current value of this valuator.  */
  5317   double current_value;
  5318 
  5319   /* The number of the valuator.  */
  5320   int number;
  5321 
  5322   /* The next valuator whose value we already know.  */
  5323   struct xi_known_valuator *next;
  5324 };
  5325 
  5326 /* Populate the scroll valuator at INDEX in DEVICE with the scroll
  5327    valuator information provided in INFO.
  5328 
  5329    The information consists of:
  5330 
  5331      - whether or not the valuator is horizontal.
  5332 
  5333      - whether or not the valuator's value is currently unknown,
  5334        until the next XI_Motion event is received or the valuator's
  5335        value is restored by the caller upon encountering valuator
  5336        class data.
  5337 
  5338      - what the current value of the valuator is.  This is set to
  5339        DBL_MIN for debugging purposes, but can be any value, as
  5340        invalid_p is currently true.
  5341 
  5342      - the increment, which defines the amount of movement equal to a
  5343        single unit of scrolling.  For example, if the increment is
  5344        2.0, then a WHEEL_DOWN or WHEEL_UP event will be sent every
  5345        time the valuator value changes by 2.0, unless
  5346        mwheel-coalesce-scroll-events is nil.
  5347 
  5348      - the number used in XI_Motion events and elsewhere to identify
  5349        the valuator.  */
  5350 
  5351 static void
  5352 xi_populate_scroll_valuator (struct xi_device_t *device,
  5353                              int index, XIScrollClassInfo *info)
  5354 {
  5355   struct xi_scroll_valuator_t *valuator;
  5356 
  5357   valuator = &device->valuators[index];
  5358   valuator->horizontal
  5359     = (info->scroll_type == XIScrollTypeHorizontal);
  5360   valuator->invalid_p = true;
  5361   valuator->emacs_value = DBL_MIN;
  5362   valuator->increment = info->increment;
  5363   valuator->number = info->number;
  5364 }
  5365 
  5366 #endif
  5367 
  5368 static void
  5369 xi_populate_device_from_info (struct x_display_info *dpyinfo,
  5370                               struct xi_device_t *xi_device,
  5371                               XIDeviceInfo *device)
  5372 {
  5373 #ifdef HAVE_XINPUT2_1
  5374   struct xi_known_valuator *values, *tem;
  5375   int actual_valuator_count, c;
  5376   XIScrollClassInfo *info;
  5377   XIValuatorClassInfo *valuator_info;
  5378 #endif
  5379 #ifdef HAVE_XINPUT2_2
  5380   XITouchClassInfo *touch_info;
  5381 #endif
  5382 
  5383 #ifdef HAVE_XINPUT2_1
  5384   USE_SAFE_ALLOCA;
  5385 #endif
  5386 
  5387   /* Initialize generic information about the device: its ID, which
  5388      buttons are currently pressed and thus presumably actively
  5389      grabbing the device, what kind of device it is (master pointer,
  5390      master keyboard, slave pointer, slave keyboard, or floating
  5391      slave), and its attachment.
  5392 
  5393      Here is a brief description of what device uses and attachments
  5394      are.  Under XInput 2, user input from individual input devices is
  5395      multiplexed into specific seats before being delivered, with each
  5396      seat corresponding to a single on-screen mouse pointer and having
  5397      its own keyboard focus.  Each seat consists of two virtual
  5398      devices: the master keyboard and the master pointer, the first of
  5399      which is used to report all keyboard input, with the other used
  5400      to report all other input.
  5401 
  5402      Input from each physical device (mouse, trackpad or keyboard) is
  5403      then associated with that slave device's paired master device.
  5404      For example, moving the device "Logitech USB Optical Mouse",
  5405      enslaved by the master pointer device "Virtual core pointer",
  5406      will result in movement of the mouse pointer associated with that
  5407      master device's seat.  If the pointer moves over an Emacs frame,
  5408      then the frame will receive XI_Enter and XI_Motion events from
  5409      that master pointer.
  5410 
  5411      Likewise, keyboard input from the device "AT Translated Set 2
  5412      keyboard", enslaved by the master keyboard device "Virtual core
  5413      keyboard", will be reported to its seat's input focus window.
  5414 
  5415      The device use describes what the device is.  The meanings of
  5416      MasterPointer, MasterKeyboard, SlavePointer and SlaveKeyboard
  5417      should be obvious.  FloatingSlave means the device is a slave
  5418      device that is not associated with any seat, and thus generates
  5419      no input.
  5420 
  5421      The device attachment is a device ID whose meaning varies
  5422      depending on the device use.  If the device is a master device,
  5423      then the attachment is the device ID of the other device in its
  5424      seat (the master keyboard for master pointer devices, and vice
  5425      versa).  Otherwise, it is the ID of the master device the slave
  5426      device is attached to.  For slave devices not attached to any
  5427      seat, its value is undefined.  */
  5428 
  5429   xi_device->device_id = device->deviceid;
  5430   xi_device->grab = 0;
  5431   xi_device->use = device->use;
  5432   xi_device->name = build_string (device->name);
  5433   xi_device->attachment = device->attachment;
  5434 
  5435   /* Clear the list of active touch points on the device, which are
  5436      individual touches tracked by a touchscreen.  */
  5437 
  5438 #ifdef HAVE_XINPUT2_2
  5439   xi_device->touchpoints = NULL;
  5440   xi_device->direct_p = false;
  5441 #endif
  5442 
  5443 #ifdef HAVE_XINPUT2_1
  5444   if (!dpyinfo->xi2_version)
  5445     {
  5446       /* Skip everything below as there are no classes of interest on
  5447          XI 2.0 servers.  */
  5448       xi_device->valuators = NULL;
  5449       xi_device->scroll_valuator_count = 0;
  5450 
  5451       SAFE_FREE ();
  5452       return;
  5453     }
  5454 
  5455   actual_valuator_count = 0;
  5456   xi_device->valuators = xnmalloc (device->num_classes,
  5457                                    sizeof *xi_device->valuators);
  5458   values = NULL;
  5459 
  5460   /* Initialize device info based on a list of "device classes".
  5461      Device classes are little pieces of information associated with a
  5462      device.  Emacs is interested in scroll valuator information and
  5463      touch handling information, which respectively describe the axes
  5464      (if any) along which the device's scroll wheel rotates, and how
  5465      the device reports touch input.  */
  5466 
  5467   for (c = 0; c < device->num_classes; ++c)
  5468     {
  5469       switch (device->classes[c]->type)
  5470         {
  5471         case XIScrollClass:
  5472           {
  5473             info = (XIScrollClassInfo *) device->classes[c];
  5474             xi_populate_scroll_valuator (xi_device, actual_valuator_count++,
  5475                                          info);
  5476             break;
  5477           }
  5478 
  5479         case XIValuatorClass:
  5480           {
  5481             valuator_info = (XIValuatorClassInfo *) device->classes[c];
  5482             tem = SAFE_ALLOCA (sizeof *tem);
  5483 
  5484             /* Avoid restoring bogus values if some driver
  5485                accidentally specifies relative values in scroll
  5486                valuator classes how the input extension spec says they
  5487                should be, but allow restoring values when a value is
  5488                set, which is how the input extension actually
  5489                behaves.  */
  5490 
  5491             if (valuator_info->value == 0.0
  5492                 && valuator_info->mode != XIModeAbsolute)
  5493               continue;
  5494 
  5495             tem->next = values;
  5496             tem->number = valuator_info->number;
  5497             tem->current_value = valuator_info->value;
  5498 
  5499             values = tem;
  5500             break;
  5501           }
  5502 
  5503 #ifdef HAVE_XINPUT2_2
  5504         case XITouchClass:
  5505           {
  5506             touch_info = (XITouchClassInfo *) device->classes[c];
  5507             xi_device->direct_p = touch_info->mode == XIDirectTouch;
  5508           }
  5509 #endif
  5510         default:
  5511           break;
  5512         }
  5513     }
  5514 
  5515   xi_device->scroll_valuator_count = actual_valuator_count;
  5516 
  5517   /* Now look through all the valuators whose values are already known
  5518      and populate our client-side records with their current
  5519      values.  */
  5520 
  5521   for (tem = values; values; values = values->next)
  5522     {
  5523       for (c = 0; c < xi_device->scroll_valuator_count; ++c)
  5524         {
  5525           if (xi_device->valuators[c].number == tem->number)
  5526             {
  5527               xi_device->valuators[c].invalid_p = false;
  5528               xi_device->valuators[c].current_value
  5529                 = tem->current_value;
  5530               xi_device->valuators[c].emacs_value = 0.0;
  5531             }
  5532         }
  5533     }
  5534 
  5535   SAFE_FREE ();
  5536 #endif
  5537 }
  5538 
  5539 /* Populate our client-side record of all devices, which includes
  5540    basic information about the device and also touchscreen tracking
  5541    information and scroll valuators.
  5542 
  5543    Keeping track of scroll valuators is required in order to support
  5544    scroll wheels that report information in a fashion more detailed
  5545    than a single turn of a "step" in the wheel.
  5546 
  5547    When the input extension is being utilized, the states of the mouse
  5548    wheels on each axis are stored as absolute values inside
  5549    "valuators" attached to each mouse device.  To obtain the delta of
  5550    the scroll wheel from a motion event (which is used to report that
  5551    some valuator has changed), it is necessary to iterate over every
  5552    valuator that changed, and compare its previous value to the
  5553    current value of the valuator.
  5554 
  5555    Each individual valuator also has an "interval", which is the
  5556    amount you must divide that delta by in order to obtain a delta in
  5557    the terms of scroll units.
  5558 
  5559    This delta however is still intermediate, to make driver
  5560    implementations easier.  The XInput developers recommend (and most
  5561    programs use) the following algorithm to convert from scroll unit
  5562    deltas to pixel deltas by which the display must actually be
  5563    scrolled:
  5564 
  5565      pixels_scrolled = pow (window_height, 2.0 / 3.0) * delta;  */
  5566 
  5567 static void
  5568 x_cache_xi_devices (struct x_display_info *dpyinfo)
  5569 {
  5570   int ndevices, actual_devices, i;
  5571   XIDeviceInfo *infos;
  5572 
  5573   actual_devices = 0;
  5574   block_input ();
  5575   x_free_xi_devices (dpyinfo);
  5576   infos = XIQueryDevice (dpyinfo->display,
  5577                          XIAllDevices,
  5578                          &ndevices);
  5579 
  5580   if (!ndevices)
  5581     {
  5582       XIFreeDeviceInfo (infos);
  5583       unblock_input ();
  5584       return;
  5585     }
  5586 
  5587   dpyinfo->devices = xzalloc (sizeof *dpyinfo->devices * ndevices);
  5588 
  5589   for (i = 0; i < ndevices; ++i)
  5590     {
  5591       if (infos[i].enabled)
  5592         xi_populate_device_from_info (dpyinfo,
  5593                                       &dpyinfo->devices[actual_devices++],
  5594                                       &infos[i]);
  5595     }
  5596 
  5597   dpyinfo->num_devices = actual_devices;
  5598   XIFreeDeviceInfo (infos);
  5599   unblock_input ();
  5600 }
  5601 
  5602 #ifdef HAVE_XINPUT2_1
  5603 /* Return the delta of the scroll valuator VALUATOR_NUMBER under
  5604    DEVICE in the display DPYINFO with VALUE.  The valuator's valuator
  5605    will be set to VALUE afterwards.  In case no scroll valuator is
  5606    found, or if the valuator state is invalid (see the comment under
  5607    XI_Enter in handle_one_xevent).  Otherwise, the valuator is
  5608    returned in VALUATOR_RETURN.  */
  5609 static double
  5610 x_get_scroll_valuator_delta (struct x_display_info *dpyinfo,
  5611                              struct xi_device_t *device,
  5612                              int valuator_number, double value,
  5613                              struct xi_scroll_valuator_t **valuator_return)
  5614 {
  5615   struct xi_scroll_valuator_t *sv;
  5616   double delta;
  5617   int i;
  5618 
  5619   for (i = 0; i < device->scroll_valuator_count; ++i)
  5620     {
  5621       sv = &device->valuators[i];
  5622 
  5623       if (sv->number == valuator_number)
  5624         {
  5625           *valuator_return = sv;
  5626 
  5627           if (sv->increment == 0)
  5628             return DBL_MAX;
  5629 
  5630           if (sv->invalid_p)
  5631             {
  5632               sv->current_value = value;
  5633               sv->invalid_p = false;
  5634 
  5635               return DBL_MAX;
  5636             }
  5637           else
  5638             {
  5639               delta = (sv->current_value - value) / sv->increment;
  5640               sv->current_value = value;
  5641 
  5642               return delta;
  5643             }
  5644         }
  5645     }
  5646 
  5647   *valuator_return = NULL;
  5648   return DBL_MAX;
  5649 }
  5650 
  5651 #endif
  5652 
  5653 struct xi_device_t *
  5654 xi_device_from_id (struct x_display_info *dpyinfo, int deviceid)
  5655 {
  5656   for (int i = 0; i < dpyinfo->num_devices; ++i)
  5657     {
  5658       if (dpyinfo->devices[i].device_id == deviceid)
  5659         return &dpyinfo->devices[i];
  5660     }
  5661 
  5662   return NULL;
  5663 }
  5664 
  5665 #ifdef HAVE_XINPUT2_2
  5666 
  5667 static void
  5668 xi_link_touch_point (struct xi_device_t *device,
  5669                      int detail, double x, double y)
  5670 {
  5671   struct xi_touch_point_t *touchpoint;
  5672 
  5673   touchpoint = xmalloc (sizeof *touchpoint);
  5674   touchpoint->next = device->touchpoints;
  5675   touchpoint->x = x;
  5676   touchpoint->y = y;
  5677   touchpoint->number = detail;
  5678 
  5679   device->touchpoints = touchpoint;
  5680 }
  5681 
  5682 static bool
  5683 xi_unlink_touch_point (int detail,
  5684                        struct xi_device_t *device)
  5685 {
  5686   struct xi_touch_point_t *last, *tem;
  5687 
  5688   for (last = NULL, tem = device->touchpoints; tem;
  5689        last = tem, tem = tem->next)
  5690     {
  5691       if (tem->number == detail)
  5692         {
  5693           if (!last)
  5694             device->touchpoints = tem->next;
  5695           else
  5696             last->next = tem->next;
  5697 
  5698           xfree (tem);
  5699           return true;
  5700         }
  5701     }
  5702 
  5703   return false;
  5704 }
  5705 
  5706 static struct xi_touch_point_t *
  5707 xi_find_touch_point (struct xi_device_t *device, int detail)
  5708 {
  5709   struct xi_touch_point_t *point;
  5710 
  5711   for (point = device->touchpoints; point; point = point->next)
  5712     {
  5713       if (point->number == detail)
  5714         return point;
  5715     }
  5716 
  5717   return NULL;
  5718 }
  5719 
  5720 #endif /* HAVE_XINPUT2_2 */
  5721 
  5722 #ifdef HAVE_XINPUT2_1
  5723 
  5724 static void
  5725 xi_reset_scroll_valuators_for_device_id (struct x_display_info *dpyinfo,
  5726                                          int id)
  5727 {
  5728   struct xi_device_t *device;
  5729   struct xi_scroll_valuator_t *valuator;
  5730   int i;
  5731 
  5732   device = xi_device_from_id (dpyinfo, id);
  5733 
  5734   if (!device)
  5735     return;
  5736 
  5737   if (!device->scroll_valuator_count)
  5738     return;
  5739 
  5740   for (i = 0; i < device->scroll_valuator_count; ++i)
  5741     {
  5742       valuator = &device->valuators[i];
  5743       valuator->invalid_p = true;
  5744       valuator->emacs_value = 0.0;
  5745     }
  5746 
  5747   return;
  5748 }
  5749 
  5750 #endif /* HAVE_XINPUT2_1 */
  5751 
  5752 #endif
  5753 
  5754 #ifdef USE_CAIRO
  5755 
  5756 void
  5757 x_cr_destroy_frame_context (struct frame *f)
  5758 {
  5759   if (FRAME_CR_CONTEXT (f))
  5760     {
  5761       cairo_destroy (FRAME_CR_CONTEXT (f));
  5762       FRAME_CR_CONTEXT (f) = NULL;
  5763     }
  5764 }
  5765 
  5766 void
  5767 x_cr_update_surface_desired_size (struct frame *f, int width, int height)
  5768 {
  5769   if (FRAME_CR_SURFACE_DESIRED_WIDTH (f) != width
  5770       || FRAME_CR_SURFACE_DESIRED_HEIGHT (f) != height)
  5771     {
  5772       x_cr_destroy_frame_context (f);
  5773       FRAME_CR_SURFACE_DESIRED_WIDTH (f) = width;
  5774       FRAME_CR_SURFACE_DESIRED_HEIGHT (f) = height;
  5775     }
  5776 }
  5777 
  5778 static void
  5779 x_cr_gc_clip (cairo_t *cr, struct frame *f, GC gc)
  5780 {
  5781   if (gc)
  5782     {
  5783       struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0);
  5784 
  5785       if (gc_ext && gc_ext->n_clip_rects)
  5786         {
  5787           for (int i = 0; i < gc_ext->n_clip_rects; i++)
  5788             cairo_rectangle (cr, gc_ext->clip_rects[i].x,
  5789                              gc_ext->clip_rects[i].y,
  5790                              gc_ext->clip_rects[i].width,
  5791                              gc_ext->clip_rects[i].height);
  5792           cairo_clip (cr);
  5793         }
  5794     }
  5795 }
  5796 
  5797 cairo_t *
  5798 x_begin_cr_clip (struct frame *f, GC gc)
  5799 {
  5800   cairo_t *cr = FRAME_CR_CONTEXT (f);
  5801 
  5802   if (!cr)
  5803     {
  5804       int width = FRAME_CR_SURFACE_DESIRED_WIDTH (f);
  5805       int height = FRAME_CR_SURFACE_DESIRED_HEIGHT (f);
  5806       cairo_surface_t *surface;
  5807 #ifdef USE_CAIRO_XCB_SURFACE
  5808       if (FRAME_DISPLAY_INFO (f)->xcb_visual)
  5809         surface = cairo_xcb_surface_create (FRAME_DISPLAY_INFO (f)->xcb_connection,
  5810                                             (xcb_drawable_t) FRAME_X_RAW_DRAWABLE (f),
  5811                                             FRAME_DISPLAY_INFO (f)->xcb_visual,
  5812                                             width, height);
  5813       else
  5814 #endif
  5815         surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
  5816                                              FRAME_X_RAW_DRAWABLE (f),
  5817                                              FRAME_X_VISUAL (f),
  5818                                              width, height);
  5819 
  5820       cr = FRAME_CR_CONTEXT (f) = cairo_create (surface);
  5821       cairo_surface_destroy (surface);
  5822     }
  5823   cairo_save (cr);
  5824   x_cr_gc_clip (cr, f, gc);
  5825 
  5826   return cr;
  5827 }
  5828 
  5829 void
  5830 x_end_cr_clip (struct frame *f)
  5831 {
  5832   cairo_restore (FRAME_CR_CONTEXT (f));
  5833 #ifdef HAVE_XDBE
  5834   if (FRAME_X_DOUBLE_BUFFERED_P (f))
  5835     x_mark_frame_dirty (f);
  5836 #endif
  5837 }
  5838 
  5839 void
  5840 x_set_cr_source_with_gc_foreground (struct frame *f, GC gc,
  5841                                     bool respect_alpha_background)
  5842 {
  5843   XGCValues xgcv;
  5844   XColor color;
  5845   unsigned int depth;
  5846 
  5847   XGetGCValues (FRAME_X_DISPLAY (f), gc, GCForeground, &xgcv);
  5848   color.pixel = xgcv.foreground;
  5849   x_query_colors (f, &color, 1);
  5850   depth = FRAME_DISPLAY_INFO (f)->n_planes;
  5851 
  5852   if (f->alpha_background < 1.0 && depth == 32
  5853       && respect_alpha_background)
  5854     {
  5855       cairo_set_source_rgba (FRAME_CR_CONTEXT (f), color.red / 65535.0,
  5856                              color.green / 65535.0, color.blue / 65535.0,
  5857                              f->alpha_background);
  5858 
  5859       cairo_set_operator (FRAME_CR_CONTEXT (f), CAIRO_OPERATOR_SOURCE);
  5860     }
  5861   else
  5862     {
  5863       cairo_set_source_rgb (FRAME_CR_CONTEXT (f), color.red / 65535.0,
  5864                             color.green / 65535.0, color.blue / 65535.0);
  5865       cairo_set_operator (FRAME_CR_CONTEXT (f), CAIRO_OPERATOR_OVER);
  5866     }
  5867 }
  5868 
  5869 void
  5870 x_set_cr_source_with_gc_background (struct frame *f, GC gc,
  5871                                     bool respect_alpha_background)
  5872 {
  5873   XGCValues xgcv;
  5874   XColor color;
  5875   unsigned int depth;
  5876 
  5877   XGetGCValues (FRAME_X_DISPLAY (f), gc, GCBackground, &xgcv);
  5878   color.pixel = xgcv.background;
  5879 
  5880   x_query_colors (f, &color, 1);
  5881 
  5882   depth = FRAME_DISPLAY_INFO (f)->n_planes;
  5883 
  5884   if (f->alpha_background < 1.0 && depth == 32
  5885       && respect_alpha_background)
  5886     {
  5887       cairo_set_source_rgba (FRAME_CR_CONTEXT (f), color.red / 65535.0,
  5888                              color.green / 65535.0, color.blue / 65535.0,
  5889                              f->alpha_background);
  5890 
  5891       cairo_set_operator (FRAME_CR_CONTEXT (f), CAIRO_OPERATOR_SOURCE);
  5892     }
  5893   else
  5894     {
  5895       cairo_set_source_rgb (FRAME_CR_CONTEXT (f), color.red / 65535.0,
  5896                             color.green / 65535.0, color.blue / 65535.0);
  5897       cairo_set_operator (FRAME_CR_CONTEXT (f), CAIRO_OPERATOR_OVER);
  5898     }
  5899 }
  5900 
  5901 static const cairo_user_data_key_t xlib_surface_key, saved_drawable_key;
  5902 
  5903 static void
  5904 x_cr_destroy_xlib_surface (cairo_surface_t *xlib_surface)
  5905 {
  5906   if (xlib_surface)
  5907     {
  5908       XFreePixmap (cairo_xlib_surface_get_display (xlib_surface),
  5909                    cairo_xlib_surface_get_drawable (xlib_surface));
  5910       cairo_surface_destroy (xlib_surface);
  5911     }
  5912 }
  5913 
  5914 static bool
  5915 x_try_cr_xlib_drawable (struct frame *f, GC gc)
  5916 {
  5917   cairo_t *cr = FRAME_CR_CONTEXT (f);
  5918   if (!cr)
  5919     return true;
  5920 
  5921   cairo_surface_t *surface = cairo_get_target (cr);
  5922   switch (cairo_surface_get_type (surface))
  5923     {
  5924     case CAIRO_SURFACE_TYPE_XLIB:
  5925 #ifdef USE_CAIRO_XCB_SURFACE
  5926     case CAIRO_SURFACE_TYPE_XCB:
  5927 #endif
  5928       cairo_surface_flush (surface);
  5929       return true;
  5930 
  5931     case CAIRO_SURFACE_TYPE_IMAGE:
  5932       break;
  5933 
  5934     default:
  5935       return false;
  5936     }
  5937 
  5938   /* FRAME_CR_CONTEXT (f) is an image surface we can not draw into
  5939      directly with Xlib.  Set up a Pixmap so we can copy back the
  5940      result later in x_end_cr_xlib_drawable.  */
  5941   cairo_surface_t *xlib_surface = cairo_get_user_data (cr, &xlib_surface_key);
  5942   int width = FRAME_CR_SURFACE_DESIRED_WIDTH (f);
  5943   int height = FRAME_CR_SURFACE_DESIRED_HEIGHT (f);
  5944   Pixmap pixmap;
  5945   if (xlib_surface
  5946       && cairo_xlib_surface_get_width (xlib_surface) == width
  5947       && cairo_xlib_surface_get_height (xlib_surface) == height)
  5948     pixmap = cairo_xlib_surface_get_drawable (xlib_surface);
  5949   else
  5950     {
  5951       pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_RAW_DRAWABLE (f),
  5952                               width, height,
  5953                               DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
  5954       xlib_surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
  5955                                                 pixmap, FRAME_X_VISUAL (f),
  5956                                                 width, height);
  5957       cairo_set_user_data (cr, &xlib_surface_key, xlib_surface,
  5958                            (cairo_destroy_func_t) x_cr_destroy_xlib_surface);
  5959     }
  5960 
  5961   cairo_t *buf = cairo_create (xlib_surface);
  5962   cairo_set_source_surface (buf, surface, 0, 0);
  5963   cairo_matrix_t matrix;
  5964   cairo_get_matrix (cr, &matrix);
  5965   cairo_pattern_set_matrix (cairo_get_source (cr), &matrix);
  5966   cairo_set_operator (buf, CAIRO_OPERATOR_SOURCE);
  5967   x_cr_gc_clip (buf, f, gc);
  5968   cairo_paint (buf);
  5969   cairo_destroy (buf);
  5970 
  5971   cairo_set_user_data (cr, &saved_drawable_key,
  5972                        (void *) (uintptr_t) FRAME_X_RAW_DRAWABLE (f), NULL);
  5973   FRAME_X_RAW_DRAWABLE (f) = pixmap;
  5974   cairo_surface_flush (xlib_surface);
  5975 
  5976   return true;
  5977 }
  5978 
  5979 static void
  5980 x_end_cr_xlib_drawable (struct frame *f, GC gc)
  5981 {
  5982   cairo_t *cr = FRAME_CR_CONTEXT (f);
  5983   if (!cr)
  5984     return;
  5985 
  5986   Drawable saved_drawable
  5987     = (uintptr_t) cairo_get_user_data (cr, &saved_drawable_key);
  5988   cairo_surface_t *surface = (saved_drawable
  5989                               ? cairo_get_user_data (cr, &xlib_surface_key)
  5990                               : cairo_get_target (cr));
  5991   struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0);
  5992   if (gc_ext && gc_ext->n_clip_rects)
  5993     for (int i = 0; i < gc_ext->n_clip_rects; i++)
  5994       cairo_surface_mark_dirty_rectangle (surface, gc_ext->clip_rects[i].x,
  5995                                           gc_ext->clip_rects[i].y,
  5996                                           gc_ext->clip_rects[i].width,
  5997                                           gc_ext->clip_rects[i].height);
  5998   else
  5999     cairo_surface_mark_dirty (surface);
  6000   if (!saved_drawable)
  6001     return;
  6002 
  6003   cairo_save (cr);
  6004   cairo_set_source_surface (cr, surface, 0, 0);
  6005   cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
  6006   x_cr_gc_clip (cr, f, gc);
  6007   cairo_paint (cr);
  6008   cairo_restore (cr);
  6009 
  6010   FRAME_X_RAW_DRAWABLE (f) = saved_drawable;
  6011   cairo_set_user_data (cr, &saved_drawable_key, NULL, NULL);
  6012 }
  6013 
  6014 /* Fringe bitmaps.  */
  6015 
  6016 static int max_fringe_bmp = 0;
  6017 static cairo_pattern_t **fringe_bmp = 0;
  6018 
  6019 static void
  6020 x_cr_define_fringe_bitmap (int which, unsigned short *bits, int h, int wd)
  6021 {
  6022   int i, stride;
  6023   cairo_surface_t *surface;
  6024   cairo_pattern_t *pattern;
  6025   unsigned char *data;
  6026 
  6027   if (which >= max_fringe_bmp)
  6028     {
  6029       i = max_fringe_bmp;
  6030       max_fringe_bmp = which + 20;
  6031       fringe_bmp = xrealloc (fringe_bmp, max_fringe_bmp * sizeof (*fringe_bmp));
  6032       while (i < max_fringe_bmp)
  6033         fringe_bmp[i++] = 0;
  6034     }
  6035 
  6036   block_input ();
  6037 
  6038   surface = cairo_image_surface_create (CAIRO_FORMAT_A1, wd, h);
  6039   stride = cairo_image_surface_get_stride (surface);
  6040   data = cairo_image_surface_get_data (surface);
  6041 
  6042   for (i = 0; i < h; i++)
  6043     {
  6044       *((unsigned short *) data) = bits[i];
  6045       data += stride;
  6046     }
  6047 
  6048   cairo_surface_mark_dirty (surface);
  6049   pattern = cairo_pattern_create_for_surface (surface);
  6050   cairo_surface_destroy (surface);
  6051 
  6052   unblock_input ();
  6053 
  6054   fringe_bmp[which] = pattern;
  6055 }
  6056 
  6057 static void
  6058 x_cr_destroy_fringe_bitmap (int which)
  6059 {
  6060   if (which >= max_fringe_bmp)
  6061     return;
  6062 
  6063   if (fringe_bmp[which])
  6064     {
  6065       block_input ();
  6066       cairo_pattern_destroy (fringe_bmp[which]);
  6067       unblock_input ();
  6068     }
  6069   fringe_bmp[which] = 0;
  6070 }
  6071 
  6072 static void
  6073 x_cr_draw_image (struct frame *f, GC gc, cairo_pattern_t *image,
  6074                  int src_x, int src_y, int width, int height,
  6075                  int dest_x, int dest_y, bool overlay_p)
  6076 {
  6077   cairo_t *cr = x_begin_cr_clip (f, gc);
  6078 
  6079   if (overlay_p)
  6080     cairo_rectangle (cr, dest_x, dest_y, width, height);
  6081   else
  6082     {
  6083       x_set_cr_source_with_gc_background (f, gc, false);
  6084       cairo_rectangle (cr, dest_x, dest_y, width, height);
  6085       cairo_fill_preserve (cr);
  6086     }
  6087 
  6088   cairo_translate (cr, dest_x - src_x, dest_y - src_y);
  6089 
  6090   cairo_surface_t *surface;
  6091   cairo_pattern_get_surface (image, &surface);
  6092   cairo_format_t format = cairo_image_surface_get_format (surface);
  6093   if (format != CAIRO_FORMAT_A8 && format != CAIRO_FORMAT_A1)
  6094     {
  6095       cairo_set_source (cr, image);
  6096       cairo_fill (cr);
  6097     }
  6098   else
  6099     {
  6100       x_set_cr_source_with_gc_foreground (f, gc, false);
  6101       cairo_clip (cr);
  6102       cairo_mask (cr, image);
  6103     }
  6104 
  6105   x_end_cr_clip (f);
  6106 }
  6107 
  6108 void
  6109 x_cr_draw_frame (cairo_t *cr, struct frame *f)
  6110 {
  6111   int width, height;
  6112 
  6113   width = FRAME_PIXEL_WIDTH (f);
  6114   height = FRAME_PIXEL_HEIGHT (f);
  6115 
  6116   cairo_t *saved_cr = FRAME_CR_CONTEXT (f);
  6117   FRAME_CR_CONTEXT (f) = cr;
  6118   x_clear_area (f, 0, 0, width, height);
  6119   expose_frame (f, 0, 0, width, height);
  6120   FRAME_CR_CONTEXT (f) = saved_cr;
  6121 }
  6122 
  6123 static cairo_status_t
  6124 x_cr_accumulate_data (void *closure, const unsigned char *data,
  6125                       unsigned int length)
  6126 {
  6127   Lisp_Object *acc = (Lisp_Object *) closure;
  6128 
  6129   *acc = Fcons (make_unibyte_string ((char const *) data, length), *acc);
  6130 
  6131   return CAIRO_STATUS_SUCCESS;
  6132 }
  6133 
  6134 static void
  6135 x_cr_destroy (void *cr)
  6136 {
  6137   block_input ();
  6138   cairo_destroy (cr);
  6139   unblock_input ();
  6140 }
  6141 
  6142 Lisp_Object
  6143 x_cr_export_frames (Lisp_Object frames, cairo_surface_type_t surface_type)
  6144 {
  6145   struct frame *f;
  6146   cairo_surface_t *surface;
  6147   cairo_t *cr;
  6148   int width, height;
  6149   void (*surface_set_size_func) (cairo_surface_t *, double, double) = NULL;
  6150   Lisp_Object acc = Qnil;
  6151   specpdl_ref count = SPECPDL_INDEX ();
  6152 
  6153   specbind (Qredisplay_dont_pause, Qt);
  6154   redisplay_preserve_echo_area (31);
  6155 
  6156   f = XFRAME (XCAR (frames));
  6157   frames = XCDR (frames);
  6158   width = FRAME_PIXEL_WIDTH (f);
  6159   height = FRAME_PIXEL_HEIGHT (f);
  6160 
  6161   block_input ();
  6162 #ifdef CAIRO_HAS_PDF_SURFACE
  6163   if (surface_type == CAIRO_SURFACE_TYPE_PDF)
  6164     {
  6165       surface = cairo_pdf_surface_create_for_stream (x_cr_accumulate_data, &acc,
  6166                                                      width, height);
  6167       surface_set_size_func = cairo_pdf_surface_set_size;
  6168     }
  6169   else
  6170 #endif
  6171 #ifdef CAIRO_HAS_PNG_FUNCTIONS
  6172   if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
  6173     surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
  6174   else
  6175 #endif
  6176 #ifdef CAIRO_HAS_PS_SURFACE
  6177   if (surface_type == CAIRO_SURFACE_TYPE_PS)
  6178     {
  6179       surface = cairo_ps_surface_create_for_stream (x_cr_accumulate_data, &acc,
  6180                                                     width, height);
  6181       surface_set_size_func = cairo_ps_surface_set_size;
  6182     }
  6183   else
  6184 #endif
  6185 #ifdef CAIRO_HAS_SVG_SURFACE
  6186   if (surface_type == CAIRO_SURFACE_TYPE_SVG)
  6187     surface = cairo_svg_surface_create_for_stream (x_cr_accumulate_data, &acc,
  6188                                                    width, height);
  6189   else
  6190 #endif
  6191     abort ();
  6192 
  6193   cr = cairo_create (surface);
  6194   cairo_surface_destroy (surface);
  6195   record_unwind_protect_ptr (x_cr_destroy, cr);
  6196 
  6197   while (1)
  6198     {
  6199       cairo_t *saved_cr = FRAME_CR_CONTEXT (f);
  6200       FRAME_CR_CONTEXT (f) = cr;
  6201       x_clear_area (f, 0, 0, width, height);
  6202       expose_frame (f, 0, 0, width, height);
  6203       FRAME_CR_CONTEXT (f) = saved_cr;
  6204 
  6205       if (NILP (frames))
  6206         break;
  6207 
  6208       cairo_surface_show_page (surface);
  6209       f = XFRAME (XCAR (frames));
  6210       frames = XCDR (frames);
  6211       width = FRAME_PIXEL_WIDTH (f);
  6212       height = FRAME_PIXEL_HEIGHT (f);
  6213       if (surface_set_size_func)
  6214         (*surface_set_size_func) (surface, width, height);
  6215 
  6216       unblock_input ();
  6217       maybe_quit ();
  6218       block_input ();
  6219     }
  6220 
  6221 #ifdef CAIRO_HAS_PNG_FUNCTIONS
  6222   if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
  6223     {
  6224       cairo_surface_flush (surface);
  6225       cairo_surface_write_to_png_stream (surface, x_cr_accumulate_data, &acc);
  6226     }
  6227 #endif
  6228   unblock_input ();
  6229 
  6230   unbind_to (count, Qnil);
  6231 
  6232   return CALLN (Fapply, Qconcat, Fnreverse (acc));
  6233 }
  6234 
  6235 #endif  /* USE_CAIRO */
  6236 
  6237 #if defined HAVE_XRENDER
  6238 void
  6239 x_xr_apply_ext_clip (struct frame *f, GC gc)
  6240 {
  6241   eassert (FRAME_X_PICTURE (f) != None);
  6242 
  6243   struct x_gc_ext_data *data = x_gc_get_ext_data (f, gc, 1);
  6244 
  6245   if (data->n_clip_rects)
  6246     XRenderSetPictureClipRectangles (FRAME_X_DISPLAY (f),
  6247                                      FRAME_X_PICTURE (f),
  6248                                      0, 0, data->clip_rects,
  6249                                      data->n_clip_rects);
  6250 }
  6251 
  6252 void
  6253 x_xr_reset_ext_clip (struct frame *f)
  6254 {
  6255   XRenderPictureAttributes attrs = { .clip_mask = None };
  6256 
  6257   XRenderChangePicture (FRAME_X_DISPLAY (f),
  6258                         FRAME_X_PICTURE (f),
  6259                         CPClipMask, &attrs);
  6260 }
  6261 #endif
  6262 
  6263 static void
  6264 x_set_clip_rectangles (struct frame *f, GC gc, XRectangle *rectangles, int n)
  6265 {
  6266   XSetClipRectangles (FRAME_X_DISPLAY (f), gc, 0, 0, rectangles, n, Unsorted);
  6267 #if defined USE_CAIRO || defined HAVE_XRENDER
  6268   eassert (n >= 0 && n <= MAX_CLIP_RECTS);
  6269 
  6270   {
  6271     struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 1);
  6272 
  6273     gc_ext->n_clip_rects = n;
  6274     memcpy (gc_ext->clip_rects, rectangles, sizeof (XRectangle) * n);
  6275   }
  6276 #endif
  6277 }
  6278 
  6279 static void
  6280 x_reset_clip_rectangles (struct frame *f, GC gc)
  6281 {
  6282   XSetClipMask (FRAME_X_DISPLAY (f), gc, None);
  6283 #if defined USE_CAIRO || defined HAVE_XRENDER
  6284   {
  6285     struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0);
  6286 
  6287     if (gc_ext)
  6288       gc_ext->n_clip_rects = 0;
  6289   }
  6290 #endif
  6291 }
  6292 
  6293 #ifdef HAVE_XRENDER
  6294 # if !defined USE_CAIRO && (RENDER_MAJOR > 0 || RENDER_MINOR >= 2)
  6295 static void
  6296 x_xrender_color_from_gc_foreground (struct frame *f, GC gc, XRenderColor *color,
  6297                                     bool apply_alpha_background)
  6298 {
  6299   XGCValues xgcv;
  6300   XColor xc;
  6301 
  6302   XGetGCValues (FRAME_X_DISPLAY (f), gc, GCForeground, &xgcv);
  6303   xc.pixel = xgcv.foreground;
  6304   x_query_colors (f, &xc, 1);
  6305 
  6306   color->alpha = (apply_alpha_background
  6307                   ? 65535 * f->alpha_background
  6308                   : 65535);
  6309 
  6310   if (color->alpha == 65535)
  6311     {
  6312       color->red = xc.red;
  6313       color->blue = xc.blue;
  6314       color->green = xc.green;
  6315     }
  6316   else
  6317     {
  6318       color->red = (xc.red * color->alpha) / 65535;
  6319       color->blue = (xc.blue * color->alpha) / 65535;
  6320       color->green = (xc.green * color->alpha) / 65535;
  6321     }
  6322 }
  6323 # endif
  6324 
  6325 void
  6326 x_xrender_color_from_gc_background (struct frame *f, GC gc, XRenderColor *color,
  6327                                     bool apply_alpha_background)
  6328 {
  6329   XGCValues xgcv;
  6330   XColor xc;
  6331 
  6332   XGetGCValues (FRAME_X_DISPLAY (f), gc, GCBackground, &xgcv);
  6333   xc.pixel = xgcv.background;
  6334   x_query_colors (f, &xc, 1);
  6335 
  6336   color->alpha = (apply_alpha_background
  6337                   ? 65535 * f->alpha_background
  6338                   : 65535);
  6339 
  6340   if (color->alpha == 65535)
  6341     {
  6342       color->red = xc.red;
  6343       color->blue = xc.blue;
  6344       color->green = xc.green;
  6345     }
  6346   else
  6347     {
  6348       color->red = (xc.red * color->alpha) / 65535;
  6349       color->blue = (xc.blue * color->alpha) / 65535;
  6350       color->green = (xc.green * color->alpha) / 65535;
  6351     }
  6352 }
  6353 #endif
  6354 
  6355 static void
  6356 x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height,
  6357                   bool respect_alpha_background)
  6358 {
  6359 #ifdef USE_CAIRO
  6360   Display *dpy = FRAME_X_DISPLAY (f);
  6361   cairo_t *cr;
  6362   XGCValues xgcv;
  6363 
  6364   cr = x_begin_cr_clip (f, gc);
  6365   XGetGCValues (dpy, gc, GCFillStyle | GCStipple, &xgcv);
  6366   if (xgcv.fill_style == FillSolid
  6367       /* Invalid resource ID (one or more of the three most
  6368          significant bits set to 1) is obtained if the GCStipple
  6369          component has never been explicitly set.  It should be
  6370          regarded as Pixmap of unspecified size filled with ones.  */
  6371       || (xgcv.stipple & ((Pixmap) 7 << (sizeof (Pixmap) * CHAR_BIT - 3))))
  6372     {
  6373       x_set_cr_source_with_gc_foreground (f, gc, respect_alpha_background);
  6374       cairo_rectangle (cr, x, y, width, height);
  6375       cairo_fill (cr);
  6376     }
  6377   else
  6378     {
  6379       eassert (xgcv.fill_style == FillOpaqueStippled);
  6380       eassert (xgcv.stipple != None);
  6381       x_set_cr_source_with_gc_background (f, gc, respect_alpha_background);
  6382       cairo_rectangle (cr, x, y, width, height);
  6383       cairo_fill_preserve (cr);
  6384 
  6385       cairo_pattern_t *pattern = x_bitmap_stipple (f, xgcv.stipple);
  6386       if (pattern)
  6387         {
  6388           x_set_cr_source_with_gc_foreground (f, gc, respect_alpha_background);
  6389           cairo_clip (cr);
  6390           cairo_mask (cr, pattern);
  6391         }
  6392     }
  6393   x_end_cr_clip (f);
  6394 #else
  6395 #if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2))
  6396   if (respect_alpha_background
  6397       && f->alpha_background != 1.0
  6398       && FRAME_DISPLAY_INFO (f)->alpha_bits
  6399       && FRAME_CHECK_XR_VERSION (f, 0, 2))
  6400     {
  6401       x_xr_ensure_picture (f);
  6402 
  6403       if (FRAME_X_PICTURE (f) != None)
  6404         {
  6405           XRenderColor xc;
  6406 
  6407 #if RENDER_MAJOR > 0 || (RENDER_MINOR >= 10)
  6408           XGCValues xgcv;
  6409           XRenderPictureAttributes attrs;
  6410           XRenderColor alpha;
  6411           Picture stipple, fill;
  6412 #endif
  6413 
  6414           x_xr_apply_ext_clip (f, gc);
  6415 
  6416 #if RENDER_MAJOR > 0 || (RENDER_MINOR >= 10)
  6417           XGetGCValues (FRAME_X_DISPLAY (f),
  6418                         gc, GCFillStyle | GCStipple, &xgcv);
  6419 
  6420           if (xgcv.fill_style == FillOpaqueStippled
  6421               && FRAME_CHECK_XR_VERSION (f, 0, 10))
  6422             {
  6423               x_xrender_color_from_gc_background (f, gc, &alpha, true);
  6424               x_xrender_color_from_gc_foreground (f, gc, &xc, true);
  6425               attrs.repeat = RepeatNormal;
  6426 
  6427               stipple = XRenderCreatePicture (FRAME_X_DISPLAY (f),
  6428                                               xgcv.stipple,
  6429                                               XRenderFindStandardFormat (FRAME_X_DISPLAY (f),
  6430                                                                          PictStandardA1),
  6431                                               CPRepeat, &attrs);
  6432 
  6433               XRenderFillRectangle (FRAME_X_DISPLAY (f), PictOpSrc,
  6434                                     FRAME_X_PICTURE (f),
  6435                                     &alpha, x, y, width, height);
  6436 
  6437               fill = XRenderCreateSolidFill (FRAME_X_DISPLAY (f), &xc);
  6438 
  6439               XRenderComposite (FRAME_X_DISPLAY (f), PictOpOver, fill, stipple,
  6440                                 FRAME_X_PICTURE (f), 0, 0, x, y, x, y, width, height);
  6441 
  6442               XRenderFreePicture (FRAME_X_DISPLAY (f), stipple);
  6443               XRenderFreePicture (FRAME_X_DISPLAY (f), fill);
  6444             }
  6445           else
  6446 #endif
  6447             {
  6448               x_xrender_color_from_gc_foreground (f, gc, &xc, true);
  6449               XRenderFillRectangle (FRAME_X_DISPLAY (f),
  6450                                     PictOpSrc, FRAME_X_PICTURE (f),
  6451                                     &xc, x, y, width, height);
  6452             }
  6453           x_xr_reset_ext_clip (f);
  6454           x_mark_frame_dirty (f);
  6455 
  6456           return;
  6457         }
  6458     }
  6459 #endif
  6460   XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
  6461                   gc, x, y, width, height);
  6462 #endif
  6463 }
  6464 
  6465 
  6466 static void
  6467 x_clear_rectangle (struct frame *f, GC gc, int x, int y, int width, int height,
  6468                    bool respect_alpha_background)
  6469 {
  6470 #ifdef USE_CAIRO
  6471   cairo_t *cr;
  6472 
  6473   cr = x_begin_cr_clip (f, gc);
  6474   x_set_cr_source_with_gc_background (f, gc, respect_alpha_background);
  6475   cairo_rectangle (cr, x, y, width, height);
  6476   cairo_fill (cr);
  6477   x_end_cr_clip (f);
  6478 #else
  6479 #if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2))
  6480   if (respect_alpha_background
  6481       && f->alpha_background != 1.0
  6482       && FRAME_DISPLAY_INFO (f)->alpha_bits
  6483       && FRAME_CHECK_XR_VERSION (f, 0, 2))
  6484     {
  6485       x_xr_ensure_picture (f);
  6486 
  6487       if (FRAME_X_PICTURE (f) != None)
  6488         {
  6489           XRenderColor xc;
  6490 
  6491           x_xr_apply_ext_clip (f, gc);
  6492           x_xrender_color_from_gc_background (f, gc, &xc, true);
  6493           XRenderFillRectangle (FRAME_X_DISPLAY (f),
  6494                                 PictOpSrc, FRAME_X_PICTURE (f),
  6495                                 &xc, x, y, width, height);
  6496           x_xr_reset_ext_clip (f);
  6497           x_mark_frame_dirty (f);
  6498 
  6499           return;
  6500         }
  6501     }
  6502 #endif
  6503 
  6504   XGCValues xgcv;
  6505   Display *dpy = FRAME_X_DISPLAY (f);
  6506   XGetGCValues (dpy, gc, GCBackground | GCForeground, &xgcv);
  6507   XSetForeground (dpy, gc, xgcv.background);
  6508   XFillRectangle (dpy, FRAME_X_DRAWABLE (f),
  6509                   gc, x, y, width, height);
  6510   XSetForeground (dpy, gc, xgcv.foreground);
  6511 #endif
  6512 }
  6513 
  6514 static void
  6515 x_draw_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
  6516 {
  6517 #ifdef USE_CAIRO
  6518   cairo_t *cr;
  6519 
  6520   cr = x_begin_cr_clip (f, gc);
  6521   x_set_cr_source_with_gc_foreground (f, gc, false);
  6522   cairo_rectangle (cr, x + 0.5, y + 0.5, width, height);
  6523   cairo_set_line_width (cr, 1);
  6524   cairo_stroke (cr);
  6525   x_end_cr_clip (f);
  6526 #else
  6527   XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
  6528                   gc, x, y, width, height);
  6529 #endif
  6530 }
  6531 
  6532 static void
  6533 x_clear_window (struct frame *f)
  6534 {
  6535 #ifdef USE_CAIRO
  6536   cairo_t *cr;
  6537 
  6538   cr = x_begin_cr_clip (f, NULL);
  6539   x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc, true);
  6540   cairo_paint (cr);
  6541   x_end_cr_clip (f);
  6542 #else
  6543 #ifndef USE_GTK
  6544   if (f->alpha_background != 1.0
  6545 #ifdef HAVE_XDBE
  6546       || FRAME_X_DOUBLE_BUFFERED_P (f)
  6547 #endif
  6548       )
  6549 #endif
  6550     x_clear_area (f, 0, 0, FRAME_PIXEL_WIDTH (f),
  6551                   FRAME_PIXEL_HEIGHT (f));
  6552 #ifndef USE_GTK
  6553   else
  6554     XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
  6555 #endif
  6556 #endif
  6557 }
  6558 
  6559 #ifdef USE_CAIRO
  6560 static void
  6561 x_fill_trapezoid_for_relief (struct frame *f, GC gc, int x, int y,
  6562                              int width, int height, int top_p)
  6563 {
  6564   cairo_t *cr;
  6565 
  6566   cr = x_begin_cr_clip (f, gc);
  6567   x_set_cr_source_with_gc_foreground (f, gc, false);
  6568   cairo_move_to (cr, top_p ? x : x + height, y);
  6569   cairo_line_to (cr, x, y + height);
  6570   cairo_line_to (cr, top_p ? x + width - height : x + width, y + height);
  6571   cairo_line_to (cr, x + width, y);
  6572   cairo_fill (cr);
  6573   x_end_cr_clip (f);
  6574 }
  6575 
  6576 enum corners
  6577   {
  6578     CORNER_BOTTOM_RIGHT,        /* 0 -> pi/2 */
  6579     CORNER_BOTTOM_LEFT,         /* pi/2 -> pi */
  6580     CORNER_TOP_LEFT,            /* pi -> 3pi/2 */
  6581     CORNER_TOP_RIGHT,           /* 3pi/2 -> 2pi */
  6582     CORNER_LAST
  6583   };
  6584 
  6585 static void
  6586 x_erase_corners_for_relief (struct frame *f, GC gc, int x, int y,
  6587                             int width, int height,
  6588                             double radius, double margin, int corners)
  6589 {
  6590   cairo_t *cr;
  6591   int i;
  6592 
  6593   cr = x_begin_cr_clip (f, gc);
  6594   x_set_cr_source_with_gc_background (f, gc, false);
  6595   for (i = 0; i < CORNER_LAST; i++)
  6596     if (corners & (1 << i))
  6597       {
  6598         double xm, ym, xc, yc;
  6599 
  6600         if (i == CORNER_TOP_LEFT || i == CORNER_BOTTOM_LEFT)
  6601           xm = x - margin, xc = xm + radius;
  6602         else
  6603           xm = x + width + margin, xc = xm - radius;
  6604         if (i == CORNER_TOP_LEFT || i == CORNER_TOP_RIGHT)
  6605           ym = y - margin, yc = ym + radius;
  6606         else
  6607           ym = y + height + margin, yc = ym - radius;
  6608 
  6609         cairo_move_to (cr, xm, ym);
  6610         cairo_arc (cr, xc, yc, radius, i * M_PI_2, (i + 1) * M_PI_2);
  6611       }
  6612   cairo_clip (cr);
  6613   cairo_rectangle (cr, x, y, width, height);
  6614   cairo_fill (cr);
  6615   x_end_cr_clip (f);
  6616 }
  6617 
  6618 static void
  6619 x_draw_horizontal_wave (struct frame *f, GC gc, int x, int y,
  6620                         int width, int height, int wave_length)
  6621 {
  6622   cairo_t *cr;
  6623   double dx = wave_length, dy = height - 1;
  6624   int xoffset, n;
  6625 
  6626   cr = x_begin_cr_clip (f, gc);
  6627   x_set_cr_source_with_gc_foreground (f, gc, false);
  6628   cairo_rectangle (cr, x, y, width, height);
  6629   cairo_clip (cr);
  6630 
  6631   if (x >= 0)
  6632     {
  6633       xoffset = x % (wave_length * 2);
  6634       if (xoffset == 0)
  6635         xoffset = wave_length * 2;
  6636     }
  6637   else
  6638     xoffset = x % (wave_length * 2) + wave_length * 2;
  6639   n = (width + xoffset) / wave_length + 1;
  6640   if (xoffset > wave_length)
  6641     {
  6642       xoffset -= wave_length;
  6643       --n;
  6644       y += height - 1;
  6645       dy = -dy;
  6646     }
  6647 
  6648   cairo_move_to (cr, x - xoffset + 0.5, y + 0.5);
  6649   while (--n >= 0)
  6650     {
  6651       cairo_rel_line_to (cr, dx, dy);
  6652       dy = -dy;
  6653     }
  6654   cairo_set_line_width (cr, 1);
  6655   cairo_stroke (cr);
  6656   x_end_cr_clip (f);
  6657 }
  6658 #endif
  6659 
  6660 
  6661 /* Return the struct x_display_info corresponding to DPY.  */
  6662 
  6663 struct x_display_info *
  6664 x_display_info_for_display (Display *dpy)
  6665 {
  6666   struct x_display_info *dpyinfo;
  6667 
  6668   for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
  6669     if (dpyinfo->display == dpy)
  6670       return dpyinfo;
  6671 
  6672   return 0;
  6673 }
  6674 
  6675 static Window
  6676 x_find_topmost_parent (struct frame *f)
  6677 {
  6678   struct x_output *x = f->output_data.x;
  6679   Window win = None, wi = x->parent_desc;
  6680   Display *dpy = FRAME_X_DISPLAY (f);
  6681 
  6682   while (wi != FRAME_DISPLAY_INFO (f)->root_window)
  6683     {
  6684       Window root;
  6685       Window *children;
  6686       unsigned int nchildren;
  6687 
  6688       win = wi;
  6689       if (XQueryTree (dpy, win, &root, &wi, &children, &nchildren))
  6690         XFree (children);
  6691       else
  6692         break;
  6693     }
  6694 
  6695   return win;
  6696 }
  6697 
  6698 #define OPAQUE  0xffffffff
  6699 
  6700 static void
  6701 x_set_frame_alpha (struct frame *f)
  6702 {
  6703   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  6704   Display *dpy = FRAME_X_DISPLAY (f);
  6705   Window win = FRAME_OUTER_WINDOW (f);
  6706   double alpha = 1.0;
  6707   double alpha_min = 1.0;
  6708   unsigned long opac;
  6709   Window parent;
  6710 
  6711   if (dpyinfo->highlight_frame == f)
  6712     alpha = f->alpha[0];
  6713   else
  6714     alpha = f->alpha[1];
  6715 
  6716   if (alpha < 0.0)
  6717     return;
  6718 
  6719   if (FLOATP (Vframe_alpha_lower_limit))
  6720     alpha_min = XFLOAT_DATA (Vframe_alpha_lower_limit);
  6721   else if (FIXNUMP (Vframe_alpha_lower_limit))
  6722     alpha_min = (XFIXNUM (Vframe_alpha_lower_limit)) / 100.0;
  6723 
  6724   if (alpha > 1.0)
  6725     alpha = 1.0;
  6726   else if (alpha < alpha_min && alpha_min <= 1.0)
  6727     alpha = alpha_min;
  6728 
  6729   opac = alpha * OPAQUE;
  6730 
  6731   /* If there is a parent from the window manager, put the property there
  6732      also, to work around broken window managers that fail to do that.
  6733      Do this unconditionally as this function is called on reparent when
  6734      alpha has not changed on the frame.  */
  6735 
  6736   x_ignore_errors_for_next_request (dpyinfo);
  6737 
  6738   if (!FRAME_PARENT_FRAME (f))
  6739     {
  6740       parent = x_find_topmost_parent (f);
  6741 
  6742       if (parent != None)
  6743         {
  6744           XChangeProperty (dpy, parent,
  6745                            dpyinfo->Xatom_net_wm_window_opacity,
  6746                            XA_CARDINAL, 32, PropModeReplace,
  6747                            (unsigned char *) &opac, 1);
  6748         }
  6749     }
  6750 
  6751   XChangeProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity,
  6752                    XA_CARDINAL, 32, PropModeReplace,
  6753                    (unsigned char *) &opac, 1);
  6754   x_stop_ignoring_errors (dpyinfo);
  6755 }
  6756 
  6757 /***********************************************************************
  6758                     Starting and ending an update
  6759  ***********************************************************************/
  6760 
  6761 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
  6762 
  6763 /* Wait for an event matching PREDICATE to show up in the event
  6764    queue, or TIMEOUT to elapse.
  6765 
  6766    If TIMEOUT passes without an event being found, return 1.
  6767    Otherwise, return 0 and behave as XIfEvent would.  */
  6768 
  6769 static int
  6770 x_if_event (Display *dpy, XEvent *event_return,
  6771             Bool (*predicate) (Display *, XEvent *, XPointer),
  6772             XPointer arg, struct timespec timeout)
  6773 {
  6774   struct timespec current_time, target;
  6775   int fd;
  6776   fd_set fds;
  6777 
  6778   fd = ConnectionNumber (dpy);
  6779   current_time = current_timespec ();
  6780   target = timespec_add (current_time, timeout);
  6781 
  6782   /* Check if an event is already in the queue.  If it is, avoid
  6783      syncing.  */
  6784   if (XCheckIfEvent (dpy, event_return, predicate, arg))
  6785     return 0;
  6786 
  6787   while (true)
  6788     {
  6789       /* Get events into the queue.  */
  6790       XSync (dpy, False);
  6791 
  6792       /* Look for an event again.  */
  6793       if (XCheckIfEvent (dpy, event_return, predicate, arg))
  6794         return 0;
  6795 
  6796       /* Calculate the timeout.  */
  6797       current_time = current_timespec ();
  6798       timeout = timespec_sub (target, current_time);
  6799 
  6800       /* If not, wait for some input to show up on the X connection,
  6801          or for the timeout to elapse.  */
  6802       FD_ZERO (&fds);
  6803       FD_SET (fd, &fds);
  6804 
  6805       /* If this fails due to an IO error, XSync will call the IO
  6806          error handler.  */
  6807       pselect (fd + 1, &fds, NULL, NULL, &timeout, NULL);
  6808 
  6809       /* Timeout elapsed.  */
  6810       current_time = current_timespec ();
  6811       if (timespec_cmp (target, current_time) < 0)
  6812         return 1;
  6813     }
  6814 }
  6815 
  6816 /* Return the monotonic time corresponding to the high-resolution
  6817    server timestamp TIMESTAMP.  Return 0 if the necessary information
  6818    is not available.  */
  6819 
  6820 static uint_fast64_t
  6821 x_sync_get_monotonic_time (struct x_display_info *dpyinfo,
  6822                            uint_fast64_t timestamp)
  6823 {
  6824   if (dpyinfo->server_time_monotonic_p)
  6825     return timestamp;
  6826 
  6827   /* This means we haven't yet initialized the server time offset.  */
  6828   if (!dpyinfo->server_time_offset)
  6829     return 0;
  6830 
  6831   uint_fast64_t t;
  6832   return (INT_SUBTRACT_WRAPV (timestamp, dpyinfo->server_time_offset, &t)
  6833           ? 0 : t);
  6834 }
  6835 
  6836 # ifndef CLOCK_MONOTONIC
  6837 #  define CLOCK_MONOTONIC CLOCK_REALTIME
  6838 # endif
  6839 
  6840 /* Return the current monotonic time in the same format as a
  6841    high-resolution server timestamp, or 0 if not available.  */
  6842 
  6843 static uint_fast64_t
  6844 x_sync_current_monotonic_time (void)
  6845 {
  6846   struct timespec time;
  6847   uint_fast64_t t;
  6848   return (((clock_gettime (CLOCK_MONOTONIC, &time) != 0
  6849             && (CLOCK_MONOTONIC == CLOCK_REALTIME
  6850                 || clock_gettime (CLOCK_REALTIME, &time) != 0))
  6851            || INT_MULTIPLY_WRAPV (time.tv_sec, 1000000, &t)
  6852            || INT_ADD_WRAPV (t, time.tv_nsec / 1000, &t))
  6853           ? 0 : t);
  6854 }
  6855 
  6856 /* Decode a _NET_WM_FRAME_DRAWN message and calculate the time it took
  6857    to draw the last frame.  */
  6858 
  6859 static void
  6860 x_sync_note_frame_times (struct x_display_info *dpyinfo,
  6861                          struct frame *f, XEvent *event)
  6862 {
  6863   uint_fast64_t low, high, time;
  6864   struct x_output *output;
  6865 
  6866   low = event->xclient.data.l[2];
  6867   high = event->xclient.data.l[3];
  6868   output = FRAME_X_OUTPUT (f);
  6869 
  6870   time = x_sync_get_monotonic_time (dpyinfo, low | (high << 32));
  6871 
  6872   if (!time || !output->temp_frame_time
  6873       || INT_SUBTRACT_WRAPV (time, output->temp_frame_time,
  6874                              &output->last_frame_time))
  6875     output->last_frame_time = 0;
  6876 
  6877 #ifdef FRAME_DEBUG
  6878   uint_fast64_t last_frame_ms = output->last_frame_time / 1000;
  6879   fprintf (stderr,
  6880            "Drawing the last frame took: %"PRIuFAST64" ms (%"PRIuFAST64")\n",
  6881            last_frame_ms, time);
  6882 #endif
  6883 }
  6884 
  6885 static Bool
  6886 x_sync_is_frame_drawn_event (Display *dpy, XEvent *event,
  6887                              XPointer user_data)
  6888 {
  6889   struct frame *f;
  6890   struct x_display_info *dpyinfo;
  6891 
  6892   f = (struct frame *) user_data;
  6893   dpyinfo = FRAME_DISPLAY_INFO (f);
  6894 
  6895   if (event->type == ClientMessage
  6896       && (event->xclient.message_type
  6897           == dpyinfo->Xatom_net_wm_frame_drawn)
  6898       && event->xclient.window == FRAME_OUTER_WINDOW (f))
  6899     return True;
  6900 
  6901   return False;
  6902 }
  6903 
  6904 /* Wait for the compositing manager to finish drawing the last frame.
  6905    If the compositing manager has already drawn everything, do
  6906    nothing.  */
  6907 
  6908 static void
  6909 x_sync_wait_for_frame_drawn_event (struct frame *f)
  6910 {
  6911   XEvent event;
  6912 
  6913   if (!FRAME_X_WAITING_FOR_DRAW (f)
  6914       /* The compositing manager can't draw a frame if it is
  6915          unmapped.  */
  6916       || !FRAME_VISIBLE_P (f))
  6917     return;
  6918 
  6919   /* Wait for the frame drawn message to arrive.  */
  6920   if (x_if_event (FRAME_X_DISPLAY (f), &event,
  6921                   x_sync_is_frame_drawn_event, (XPointer) f,
  6922                   make_timespec (1, 0)))
  6923     {
  6924       /* The first time a draw hangs, treat it as a random fluctuation
  6925          on the part of the compositor.  If the next draw continues to
  6926          hang, disable frame synchronization.  */
  6927       if (FRAME_X_DRAW_JUST_HUNG (f))
  6928         {
  6929           fprintf (stderr, "Warning: compositing manager spent more than 1 "
  6930                    "second drawing a frame.  Frame synchronization has "
  6931                    "been disabled\n");
  6932           FRAME_X_OUTPUT (f)->use_vsync_p = false;
  6933 
  6934           /* Also change the frame parameter to reflect the new
  6935              state.  */
  6936           store_frame_param (f, Quse_frame_synchronization, Qnil);
  6937         }
  6938       else
  6939         {
  6940           fprintf (stderr, "Warning: compositing manager spent more than 1 "
  6941                    "second drawing a frame.  Frame synchronization will be "
  6942                    "disabled if this happens again\n");
  6943           FRAME_X_DRAW_JUST_HUNG (f) = true;
  6944         }
  6945     }
  6946   else
  6947     x_sync_note_frame_times (FRAME_DISPLAY_INFO (f), f, &event);
  6948 
  6949   FRAME_X_WAITING_FOR_DRAW (f) = false;
  6950 }
  6951 
  6952 /* Tell the compositing manager to postpone updates of F until a frame
  6953    has finished drawing.  */
  6954 
  6955 static void
  6956 x_sync_update_begin (struct frame *f)
  6957 {
  6958   XSyncValue value, add;
  6959   Bool overflow;
  6960 
  6961   if (FRAME_X_EXTENDED_COUNTER (f) == None)
  6962     return;
  6963 
  6964   value = FRAME_X_COUNTER_VALUE (f);
  6965 
  6966   if (FRAME_X_OUTPUT (f)->ext_sync_end_pending_p)
  6967     {
  6968       FRAME_X_COUNTER_VALUE (f)
  6969         = FRAME_X_OUTPUT (f)->resize_counter_value;
  6970 
  6971       value = FRAME_X_COUNTER_VALUE (f);
  6972 
  6973       if (XSyncValueLow32 (value) % 2)
  6974         {
  6975           XSyncIntToValue (&add, 1);
  6976           XSyncValueAdd (&value, value, add, &overflow);
  6977 
  6978           if (overflow)
  6979             XSyncIntToValue (&value, 0);
  6980         }
  6981 
  6982       FRAME_X_OUTPUT (f)->ext_sync_end_pending_p = false;
  6983     }
  6984 
  6985   /* Since a frame is already in progress, there is no point in
  6986      continuing.  */
  6987   if (XSyncValueLow32 (value) % 2)
  6988     return;
  6989 
  6990   /* Wait for the last frame to be drawn before drawing this one.  */
  6991   x_sync_wait_for_frame_drawn_event (f);
  6992 
  6993   /* Make a note of the time at which we started to draw this
  6994      frame.  */
  6995   FRAME_X_OUTPUT (f)->temp_frame_time = x_sync_current_monotonic_time ();
  6996 
  6997   /* Since Emacs needs a non-urgent redraw, ensure that value % 4 ==
  6998      1.  Later, add 3 to create the even counter value.  */
  6999   if (XSyncValueLow32 (value) % 4 == 2)
  7000     XSyncIntToValue (&add, 3);
  7001   else
  7002     XSyncIntToValue (&add, 1);
  7003 
  7004   XSyncValueAdd (&FRAME_X_COUNTER_VALUE (f),
  7005                  value, add, &overflow);
  7006 
  7007   if (overflow)
  7008     XSyncIntToValue (&FRAME_X_COUNTER_VALUE (f), 3);
  7009 
  7010   eassert (XSyncValueLow32 (FRAME_X_COUNTER_VALUE (f)) % 4 == 1);
  7011 
  7012   XSyncSetCounter (FRAME_X_DISPLAY (f),
  7013                    FRAME_X_EXTENDED_COUNTER (f),
  7014                    FRAME_X_COUNTER_VALUE (f));
  7015 }
  7016 
  7017 #ifdef HAVE_XSYNCTRIGGERFENCE
  7018 
  7019 /* Trigger the sync fence for counter VALUE immediately before a frame
  7020    finishes.  */
  7021 
  7022 static void
  7023 x_sync_trigger_fence (struct frame *f, XSyncValue value)
  7024 {
  7025   uint_fast64_t n, low, high, idx;
  7026 
  7027   /* Sync fences aren't supported by the X server.  */
  7028   if (FRAME_DISPLAY_INFO (f)->xsync_major < 3
  7029       || (FRAME_DISPLAY_INFO (f)->xsync_major == 3
  7030           && FRAME_DISPLAY_INFO (f)->xsync_minor < 1))
  7031     return;
  7032 
  7033   low = XSyncValueLow32 (value);
  7034   high = XSyncValueHigh32 (value);
  7035 
  7036   n = low | (high << 32);
  7037   idx = (n / 4) % 2;
  7038 
  7039 #ifdef FRAME_DEBUG
  7040   fprintf (stderr, "Triggering synchronization fence: %lu\n", idx);
  7041 #endif
  7042 
  7043   XSyncTriggerFence (FRAME_X_DISPLAY (f),
  7044                      FRAME_X_OUTPUT (f)->sync_fences[idx]);
  7045 }
  7046 
  7047 /* Initialize the sync fences on F.  */
  7048 
  7049 void
  7050 x_sync_init_fences (struct frame *f)
  7051 {
  7052   struct x_output *output;
  7053   struct x_display_info *dpyinfo;
  7054 
  7055   output = FRAME_X_OUTPUT (f);
  7056   dpyinfo = FRAME_DISPLAY_INFO (f);
  7057 
  7058   /* Sync fences aren't supported by the X server.  */
  7059   if (dpyinfo->xsync_major < 3
  7060       || (dpyinfo->xsync_major == 3
  7061           && dpyinfo->xsync_minor < 1))
  7062     return;
  7063 
  7064   output->sync_fences[0]
  7065     = XSyncCreateFence (FRAME_X_DISPLAY (f),
  7066                         /* The drawable given below is only used to
  7067                            determine the screen on which the fence is
  7068                            created.  */
  7069                         FRAME_X_WINDOW (f),
  7070                         False);
  7071   output->sync_fences[1]
  7072     = XSyncCreateFence (FRAME_X_DISPLAY (f),
  7073                         FRAME_X_WINDOW (f),
  7074                         False);
  7075 
  7076   XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
  7077                    dpyinfo->Xatom_net_wm_sync_fences, XA_CARDINAL,
  7078                    32, PropModeReplace,
  7079                    (unsigned char *) &output->sync_fences, 2);
  7080 }
  7081 
  7082 static void
  7083 x_sync_free_fences (struct frame *f)
  7084 {
  7085   if (FRAME_X_OUTPUT (f)->sync_fences[0] != None)
  7086     XSyncDestroyFence (FRAME_X_DISPLAY (f),
  7087                        FRAME_X_OUTPUT (f)->sync_fences[0]);
  7088 
  7089   if (FRAME_X_OUTPUT (f)->sync_fences[1] != None)
  7090     XSyncDestroyFence (FRAME_X_DISPLAY (f),
  7091                        FRAME_X_OUTPUT (f)->sync_fences[1]);
  7092 }
  7093 
  7094 #endif
  7095 
  7096 /* Tell the compositing manager that FRAME has been drawn and can be
  7097    updated.  */
  7098 
  7099 static void
  7100 x_sync_update_finish (struct frame *f)
  7101 {
  7102   XSyncValue value, add;
  7103   Bool overflow;
  7104 
  7105   if (FRAME_X_EXTENDED_COUNTER (f) == None)
  7106     return;
  7107 
  7108   value = FRAME_X_COUNTER_VALUE (f);
  7109 
  7110   if (!(XSyncValueLow32 (value) % 2))
  7111     return;
  7112 
  7113   if ((XSyncValueLow32 (value) % 4) == 1)
  7114     /* This means the frame is non-urgent and should be drawn at the
  7115        next redraw point.  */
  7116     XSyncIntToValue (&add, 3);
  7117   else
  7118     /* Otherwise, the frame is urgent and should be drawn as soon as
  7119        possible.  */
  7120     XSyncIntToValue (&add, 1);
  7121 
  7122   XSyncValueAdd (&FRAME_X_COUNTER_VALUE (f),
  7123                  value, add, &overflow);
  7124 
  7125   if (overflow)
  7126     XSyncIntToValue (&FRAME_X_COUNTER_VALUE (f), 0);
  7127 
  7128   /* Trigger any sync fences if necessary.  */
  7129 #ifdef HAVE_XSYNCTRIGGERFENCE
  7130   x_sync_trigger_fence (f, FRAME_X_COUNTER_VALUE (f));
  7131 #endif
  7132 
  7133   XSyncSetCounter (FRAME_X_DISPLAY (f),
  7134                    FRAME_X_EXTENDED_COUNTER (f),
  7135                    FRAME_X_COUNTER_VALUE (f));
  7136 
  7137   if (FRAME_OUTPUT_DATA (f)->use_vsync_p)
  7138     FRAME_X_WAITING_FOR_DRAW (f) = true;
  7139 }
  7140 
  7141 /* Handle a _NET_WM_FRAME_DRAWN message from the compositor.  */
  7142 
  7143 static void
  7144 x_sync_handle_frame_drawn (struct x_display_info *dpyinfo,
  7145                            XEvent *message, struct frame *f)
  7146 {
  7147   XSyncValue value, counter;
  7148 
  7149   if (FRAME_OUTER_WINDOW (f) == message->xclient.window)
  7150     {
  7151       counter = FRAME_X_COUNTER_VALUE (f);
  7152 
  7153       /* Check that the counter in the message is the same as the
  7154          counter in the frame.  */
  7155       XSyncIntsToValue (&value,
  7156                         message->xclient.data.l[0] & 0xffffffff,
  7157                         message->xclient.data.l[1] & 0xffffffff);
  7158 
  7159       if (XSyncValueEqual (value, counter))
  7160         FRAME_X_WAITING_FOR_DRAW (f) = false;
  7161 
  7162       /* As long as a _NET_WM_FRAME_DRAWN message arrives, we know
  7163          that the compositor is still sending events, so avoid timing
  7164          out.  */
  7165       FRAME_X_DRAW_JUST_HUNG (f) = false;
  7166     }
  7167 
  7168   x_sync_note_frame_times (dpyinfo, f, message);
  7169 }
  7170 #endif
  7171 
  7172 /* Start an update of frame F.  This function is installed as a hook
  7173    for update_begin, i.e. it is called when update_begin is called.
  7174    This function is called prior to calls to gui_update_window_begin for
  7175    each window being updated.  Currently, there is nothing to do here
  7176    because all interesting stuff is done on a window basis.  */
  7177 
  7178 static void
  7179 x_update_begin (struct frame *f)
  7180 {
  7181 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
  7182   /* If F is double-buffered, we can make the entire frame center
  7183      around XdbeSwapBuffers.  */
  7184 #ifdef HAVE_XDBE
  7185   if (!FRAME_X_DOUBLE_BUFFERED_P (f))
  7186 #endif
  7187     x_sync_update_begin (f);
  7188 #else
  7189   /* Nothing to do.  */
  7190 #endif
  7191 
  7192 #ifdef HAVE_XDBE
  7193   if (FRAME_X_DOUBLE_BUFFERED_P (f))
  7194     /* The frame is no longer complete, as it is in the midst of an
  7195        update.  */
  7196     FRAME_X_COMPLETE_P (f) = false;
  7197 #endif
  7198 }
  7199 
  7200 /* Draw a vertical window border from (x,y0) to (x,y1)  */
  7201 
  7202 static void
  7203 x_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
  7204 {
  7205   struct frame *f = XFRAME (WINDOW_FRAME (w));
  7206   struct face *face;
  7207 
  7208   face = FACE_FROM_ID_OR_NULL (f, VERTICAL_BORDER_FACE_ID);
  7209   if (face)
  7210     XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc,
  7211                     face->foreground);
  7212 
  7213 #ifdef USE_CAIRO
  7214   x_fill_rectangle (f, f->output_data.x->normal_gc, x, y0, 1, y1 - y0, false);
  7215 #else
  7216   XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
  7217              f->output_data.x->normal_gc, x, y0, x, y1);
  7218 #endif
  7219 }
  7220 
  7221 /* Draw a window divider from (x0,y0) to (x1,y1)  */
  7222 
  7223 static void
  7224 x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
  7225 {
  7226   struct frame *f = XFRAME (WINDOW_FRAME (w));
  7227   struct face *face = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FACE_ID);
  7228   struct face *face_first
  7229     = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID);
  7230   struct face *face_last
  7231     = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
  7232   unsigned long color = face ? face->foreground : FRAME_FOREGROUND_PIXEL (f);
  7233   unsigned long color_first = (face_first
  7234                                ? face_first->foreground
  7235                                : FRAME_FOREGROUND_PIXEL (f));
  7236   unsigned long color_last = (face_last
  7237                               ? face_last->foreground
  7238                               : FRAME_FOREGROUND_PIXEL (f));
  7239   Display *display = FRAME_X_DISPLAY (f);
  7240 
  7241   if ((y1 - y0 > x1 - x0) && (x1 - x0 >= 3))
  7242     /* A vertical divider, at least three pixels wide: Draw first and
  7243        last pixels differently.  */
  7244     {
  7245       XSetForeground (display, f->output_data.x->normal_gc, color_first);
  7246       x_fill_rectangle (f, f->output_data.x->normal_gc,
  7247                         x0, y0, 1, y1 - y0, false);
  7248       XSetForeground (display, f->output_data.x->normal_gc, color);
  7249       x_fill_rectangle (f, f->output_data.x->normal_gc,
  7250                         x0 + 1, y0, x1 - x0 - 2, y1 - y0, false);
  7251       XSetForeground (display, f->output_data.x->normal_gc, color_last);
  7252       x_fill_rectangle (f, f->output_data.x->normal_gc,
  7253                         x1 - 1, y0, 1, y1 - y0, false);
  7254     }
  7255   else if ((x1 - x0 > y1 - y0) && (y1 - y0 >= 3))
  7256     /* A horizontal divider, at least three pixels high: Draw first and
  7257        last pixels differently.  */
  7258     {
  7259       XSetForeground (display, f->output_data.x->normal_gc, color_first);
  7260       x_fill_rectangle (f, f->output_data.x->normal_gc,
  7261                         x0, y0, x1 - x0, 1, false);
  7262       XSetForeground (display, f->output_data.x->normal_gc, color);
  7263       x_fill_rectangle (f, f->output_data.x->normal_gc,
  7264                         x0, y0 + 1, x1 - x0, y1 - y0 - 2, false);
  7265       XSetForeground (display, f->output_data.x->normal_gc, color_last);
  7266       x_fill_rectangle (f, f->output_data.x->normal_gc,
  7267                         x0, y1 - 1, x1 - x0, 1, false);
  7268     }
  7269   else
  7270     {
  7271     /* In any other case do not draw the first and last pixels
  7272        differently.  */
  7273       XSetForeground (display, f->output_data.x->normal_gc, color);
  7274       x_fill_rectangle (f, f->output_data.x->normal_gc,
  7275                         x0, y0, x1 - x0, y1 - y0, false);
  7276     }
  7277 }
  7278 
  7279 #ifdef HAVE_XDBE
  7280 
  7281 /* Show the frame back buffer.  If frame is double-buffered,
  7282    atomically publish to the user's screen graphics updates made since
  7283    the last call to show_back_buffer.  */
  7284 
  7285 static void
  7286 show_back_buffer (struct frame *f)
  7287 {
  7288   XdbeSwapInfo swap_info;
  7289 #ifdef USE_CAIRO
  7290   cairo_t *cr;
  7291 #endif
  7292 
  7293   if (FRAME_X_DOUBLE_BUFFERED_P (f))
  7294     {
  7295 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
  7296       /* Wait for drawing of the previous frame to complete before
  7297          displaying this new frame.  */
  7298       x_sync_wait_for_frame_drawn_event (f);
  7299 
  7300       /* Begin a new frame.  */
  7301       x_sync_update_begin (f);
  7302 #endif
  7303 
  7304 #ifdef USE_CAIRO
  7305       cr = FRAME_CR_CONTEXT (f);
  7306       if (cr)
  7307         cairo_surface_flush (cairo_get_target (cr));
  7308 #endif
  7309       memset (&swap_info, 0, sizeof (swap_info));
  7310       swap_info.swap_window = FRAME_X_WINDOW (f);
  7311       swap_info.swap_action = XdbeCopied;
  7312       XdbeSwapBuffers (FRAME_X_DISPLAY (f), &swap_info, 1);
  7313 
  7314 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
  7315       /* Finish the frame here.  */
  7316       x_sync_update_finish (f);
  7317 #endif
  7318     }
  7319 
  7320   FRAME_X_NEED_BUFFER_FLIP (f) = false;
  7321 }
  7322 
  7323 #endif
  7324 
  7325 /* Updates back buffer and flushes changes to display.  Called from
  7326    minibuf read code.  Note that we display the back buffer even if
  7327    buffer flipping is blocked.  */
  7328 static void
  7329 x_flip_and_flush (struct frame *f)
  7330 {
  7331   /* Flipping buffers requires a working connection to the X server,
  7332      which isn't always present if `inhibit-redisplay' is t, since
  7333      this can be called from the IO error handler.  */
  7334   if (!NILP (Vinhibit_redisplay)
  7335       /* This has to work for tooltip frames, however, and redisplay
  7336          cannot happen when they are being flushed anyway.  (bug#55519) */
  7337       && !FRAME_TOOLTIP_P (f))
  7338     return;
  7339 
  7340   block_input ();
  7341 #ifdef HAVE_XDBE
  7342   if (FRAME_X_NEED_BUFFER_FLIP (f))
  7343     show_back_buffer (f);
  7344 
  7345   /* The frame is complete again as its contents were just
  7346      flushed.  */
  7347   FRAME_X_COMPLETE_P (f) = true;
  7348 #endif
  7349   x_flush (f);
  7350   unblock_input ();
  7351 }
  7352 
  7353 /* End update of frame F.  This function is installed as a hook in
  7354    update_end.  */
  7355 
  7356 static void
  7357 x_update_end (struct frame *f)
  7358 {
  7359   /* Mouse highlight may be displayed again.  */
  7360   MOUSE_HL_INFO (f)->mouse_face_defer = false;
  7361 
  7362 #ifdef USE_CAIRO
  7363 # ifdef HAVE_XDBE
  7364   if (!FRAME_X_DOUBLE_BUFFERED_P (f) && FRAME_CR_CONTEXT (f))
  7365     cairo_surface_flush (cairo_get_target (FRAME_CR_CONTEXT (f)));
  7366 # endif
  7367 #endif
  7368 
  7369   /* If double buffering is disabled, finish the update here.
  7370      Otherwise, finish the update when the back buffer is next
  7371      displayed.  */
  7372 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
  7373 #ifdef HAVE_XDBE
  7374   if (!FRAME_X_DOUBLE_BUFFERED_P (f))
  7375 #endif
  7376     x_sync_update_finish (f);
  7377 #endif
  7378 }
  7379 
  7380 /* This function is called from various places in xdisp.c
  7381    whenever a complete update has been performed.  */
  7382 
  7383 static void
  7384 XTframe_up_to_date (struct frame *f)
  7385 {
  7386 #if defined HAVE_XSYNC && defined HAVE_GTK3
  7387   GtkWidget *widget;
  7388   GdkWindow *window;
  7389   GdkFrameClock *clock;
  7390 #endif
  7391 
  7392   eassert (FRAME_X_P (f));
  7393   block_input ();
  7394   FRAME_MOUSE_UPDATE (f);
  7395 
  7396 #ifdef HAVE_XDBE
  7397   if (!buffer_flipping_blocked_p ()
  7398       && FRAME_X_NEED_BUFFER_FLIP (f))
  7399     show_back_buffer (f);
  7400 
  7401   /* The frame is now complete, as its contents have been drawn.  */
  7402   FRAME_X_COMPLETE_P (f) = true;
  7403 #endif
  7404 
  7405 #ifdef HAVE_XSYNC
  7406 #ifndef HAVE_GTK3
  7407   if (FRAME_X_OUTPUT (f)->sync_end_pending_p
  7408       && FRAME_X_BASIC_COUNTER (f) != None)
  7409     {
  7410       XSyncSetCounter (FRAME_X_DISPLAY (f),
  7411                        FRAME_X_BASIC_COUNTER (f),
  7412                        FRAME_X_OUTPUT (f)->pending_basic_counter_value);
  7413       FRAME_X_OUTPUT (f)->sync_end_pending_p = false;
  7414     }
  7415 #else
  7416   if (FRAME_X_OUTPUT (f)->xg_sync_end_pending_p)
  7417     {
  7418       widget = FRAME_GTK_OUTER_WIDGET (f);
  7419       window = gtk_widget_get_window (widget);
  7420       eassert (window);
  7421       clock = gdk_window_get_frame_clock (window);
  7422       eassert (clock);
  7423 
  7424       gdk_frame_clock_request_phase (clock,
  7425                                      GDK_FRAME_CLOCK_PHASE_AFTER_PAINT);
  7426       FRAME_X_OUTPUT (f)->xg_sync_end_pending_p = false;
  7427     }
  7428 #endif
  7429 #endif
  7430   unblock_input ();
  7431 }
  7432 
  7433 #ifdef HAVE_XDBE
  7434 static void
  7435 XTbuffer_flipping_unblocked_hook (struct frame *f)
  7436 {
  7437   block_input ();
  7438 
  7439   if (FRAME_X_NEED_BUFFER_FLIP (f))
  7440     show_back_buffer (f);
  7441 
  7442   unblock_input ();
  7443 }
  7444 #endif
  7445 
  7446 /**
  7447  * x_clear_under_internal_border:
  7448  *
  7449  * Clear area of frame F's internal border.  If the internal border face
  7450  * of F has been specified (is not null), fill the area with that face.
  7451  */
  7452 void
  7453 x_clear_under_internal_border (struct frame *f)
  7454 {
  7455   if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
  7456     {
  7457       int border = FRAME_INTERNAL_BORDER_WIDTH (f);
  7458       int width = FRAME_PIXEL_WIDTH (f);
  7459       int height = FRAME_PIXEL_HEIGHT (f);
  7460       int margin = FRAME_TOP_MARGIN_HEIGHT (f);
  7461       int face_id =
  7462         (FRAME_PARENT_FRAME (f)
  7463          ? (!NILP (Vface_remapping_alist)
  7464             ? lookup_basic_face (NULL, f, CHILD_FRAME_BORDER_FACE_ID)
  7465             : CHILD_FRAME_BORDER_FACE_ID)
  7466          : (!NILP (Vface_remapping_alist)
  7467             ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
  7468             : INTERNAL_BORDER_FACE_ID));
  7469       struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
  7470 
  7471       if (face)
  7472         {
  7473           unsigned long color = face->background;
  7474           Display *display = FRAME_X_DISPLAY (f);
  7475           GC gc = f->output_data.x->normal_gc;
  7476 
  7477           XSetForeground (display, gc, color);
  7478           x_fill_rectangle (f, gc, 0, margin, width, border, false);
  7479           x_fill_rectangle (f, gc, 0, 0, border, height, false);
  7480           x_fill_rectangle (f, gc, width - border, 0, border, height, false);
  7481           x_fill_rectangle (f, gc, 0, height - border, width, border, false);
  7482           XSetForeground (display, gc, FRAME_FOREGROUND_PIXEL (f));
  7483         }
  7484       else
  7485         {
  7486           x_clear_area (f, 0, 0, border, height);
  7487           x_clear_area (f, 0, margin, width, border);
  7488           x_clear_area (f, width - border, 0, border, height);
  7489           x_clear_area (f, 0, height - border, width, border);
  7490         }
  7491     }
  7492 }
  7493 
  7494 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
  7495    arrow bitmaps, or clear the fringes if no bitmaps are required
  7496    before DESIRED_ROW is made current.  This function is called from
  7497    update_window_line only if it is known that there are differences
  7498    between bitmaps to be drawn between current row and DESIRED_ROW.  */
  7499 
  7500 static void
  7501 x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
  7502 {
  7503   eassert (w);
  7504 
  7505   if (!desired_row->mode_line_p && !w->pseudo_window_p)
  7506     desired_row->redraw_fringe_bitmaps_p = true;
  7507 
  7508 #ifdef USE_X_TOOLKIT
  7509   /* When a window has disappeared, make sure that no rest of
  7510      full-width rows stays visible in the internal border.  Could
  7511      check here if updated window is the leftmost/rightmost window,
  7512      but I guess it's not worth doing since vertically split windows
  7513      are almost never used, internal border is rarely set, and the
  7514      overhead is very small.  */
  7515   {
  7516     struct frame *f;
  7517     int width, height;
  7518 
  7519     if (windows_or_buffers_changed
  7520         && desired_row->full_width_p
  7521         && (f = XFRAME (w->frame),
  7522             width = FRAME_INTERNAL_BORDER_WIDTH (f),
  7523             width != 0)
  7524         && (height = desired_row->visible_height,
  7525             height > 0))
  7526       {
  7527         int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
  7528         int face_id =
  7529           (FRAME_PARENT_FRAME (f)
  7530            ? (!NILP (Vface_remapping_alist)
  7531               ? lookup_basic_face (NULL, f, CHILD_FRAME_BORDER_FACE_ID)
  7532               : CHILD_FRAME_BORDER_FACE_ID)
  7533            : (!NILP (Vface_remapping_alist)
  7534               ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
  7535               : INTERNAL_BORDER_FACE_ID));
  7536         struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
  7537 
  7538         if (face)
  7539           {
  7540             unsigned long color = face->background;
  7541             Display *display = FRAME_X_DISPLAY (f);
  7542             GC gc = f->output_data.x->normal_gc;
  7543 
  7544             XSetForeground (display, gc, color);
  7545             x_fill_rectangle (f, gc, 0, y, width, height, true);
  7546             x_fill_rectangle (f, gc, FRAME_PIXEL_WIDTH (f) - width, y,
  7547                               width, height, true);
  7548             XSetForeground (display, gc, FRAME_FOREGROUND_PIXEL (f));
  7549           }
  7550         else
  7551           {
  7552             x_clear_area (f, 0, y, width, height);
  7553             x_clear_area (f, FRAME_PIXEL_WIDTH (f) - width, y, width, height);
  7554           }
  7555       }
  7556   }
  7557 #endif
  7558 }
  7559 
  7560 static void
  7561 x_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
  7562                       struct draw_fringe_bitmap_params *p)
  7563 {
  7564   struct frame *f = XFRAME (WINDOW_FRAME (w));
  7565   Display *display = FRAME_X_DISPLAY (f);
  7566   GC gc = f->output_data.x->normal_gc;
  7567   struct face *face = p->face;
  7568 
  7569   /* Must clip because of partially visible lines.  */
  7570   x_clip_to_row (w, row, ANY_AREA, gc);
  7571 
  7572   if (p->bx >= 0 && !p->overlay_p)
  7573     {
  7574       /* In case the same realized face is used for fringes and
  7575          for something displayed in the text (e.g. face `region' on
  7576          mono-displays, the fill style may have been changed to
  7577          FillSolid in x_draw_glyph_string_background.  */
  7578       if (face->stipple)
  7579         {
  7580           XSetFillStyle (display, face->gc, FillOpaqueStippled);
  7581           x_fill_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny,
  7582                             true);
  7583           XSetFillStyle (display, face->gc, FillSolid);
  7584 
  7585           row->stipple_p = true;
  7586         }
  7587       else
  7588         {
  7589           XSetBackground (display, face->gc, face->background);
  7590           x_clear_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny,
  7591                            true);
  7592           XSetForeground (display, face->gc, face->foreground);
  7593         }
  7594     }
  7595 
  7596 #ifdef USE_CAIRO
  7597   if (p->which
  7598       && p->which < max_fringe_bmp
  7599       && p->which < max_used_fringe_bitmap)
  7600     {
  7601       XGCValues gcv;
  7602 
  7603       XGetGCValues (display, gc, GCForeground | GCBackground, &gcv);
  7604       XSetForeground (display, gc, (p->cursor_p
  7605                                     ? (p->overlay_p ? face->background
  7606                                        : f->output_data.x->cursor_pixel)
  7607                                     : face->foreground));
  7608       XSetBackground (display, gc, face->background);
  7609       if (!fringe_bmp[p->which])
  7610         {
  7611           /* This fringe bitmap is known to fringe.c, but lacks the
  7612              cairo_pattern_t pattern which shadows that bitmap.  This
  7613              is typical to define-fringe-bitmap being called when the
  7614              selected frame was not a GUI frame, for example, when
  7615              packages that define fringe bitmaps are loaded by a
  7616              daemon Emacs.  Create the missing pattern now.  */
  7617           gui_define_fringe_bitmap (f, p->which);
  7618         }
  7619       x_cr_draw_image (f, gc, fringe_bmp[p->which], 0, p->dh,
  7620                        p->wd, p->h, p->x, p->y, p->overlay_p);
  7621       XSetForeground (display, gc, gcv.foreground);
  7622       XSetBackground (display, gc, gcv.background);
  7623     }
  7624 #else  /* not USE_CAIRO */
  7625   if (p->which)
  7626     {
  7627       Drawable drawable = FRAME_X_DRAWABLE (f);
  7628       char *bits;
  7629       Pixmap pixmap, clipmask = None;
  7630       int depth = FRAME_DISPLAY_INFO (f)->n_planes;
  7631       XGCValues gcv;
  7632       unsigned long background = face->background;
  7633       XColor bg;
  7634 #ifdef HAVE_XRENDER
  7635       Picture picture = None;
  7636       XRenderPictureAttributes attrs;
  7637 
  7638       memset (&attrs, 0, sizeof attrs);
  7639 #endif
  7640 
  7641       if (p->wd > 8)
  7642         bits = (char *) (p->bits + p->dh);
  7643       else
  7644         bits = (char *) p->bits + p->dh;
  7645 
  7646       if (FRAME_DISPLAY_INFO (f)->alpha_bits
  7647           && f->alpha_background < 1.0)
  7648         {
  7649           bg.pixel = background;
  7650           x_query_colors (f, &bg, 1);
  7651           bg.red *= f->alpha_background;
  7652           bg.green *= f->alpha_background;
  7653           bg.blue *= f->alpha_background;
  7654 
  7655           background = x_make_truecolor_pixel (FRAME_DISPLAY_INFO (f),
  7656                                                bg.red, bg.green, bg.blue);
  7657           background &= ~FRAME_DISPLAY_INFO (f)->alpha_mask;
  7658           background |= (((unsigned long) (f->alpha_background * 0xffff)
  7659                           >> (16 - FRAME_DISPLAY_INFO (f)->alpha_bits))
  7660                          << FRAME_DISPLAY_INFO (f)->alpha_offset);
  7661         }
  7662 
  7663       /* Draw the bitmap.  I believe these small pixmaps can be cached
  7664          by the server.  */
  7665       pixmap = XCreatePixmapFromBitmapData (display, drawable, bits, p->wd, p->h,
  7666                                             (p->cursor_p
  7667                                              ? (p->overlay_p ? face->background
  7668                                                 : f->output_data.x->cursor_pixel)
  7669                                              : face->foreground),
  7670                                             background, depth);
  7671 
  7672 #ifdef HAVE_XRENDER
  7673       if (FRAME_X_PICTURE_FORMAT (f)
  7674           && (x_xr_ensure_picture (f), FRAME_X_PICTURE (f)))
  7675         picture = XRenderCreatePicture (display, pixmap,
  7676                                         FRAME_X_PICTURE_FORMAT (f),
  7677                                         0, &attrs);
  7678 #endif
  7679 
  7680       if (p->overlay_p)
  7681         {
  7682           clipmask = XCreatePixmapFromBitmapData (display,
  7683                                                   FRAME_DISPLAY_INFO (f)->root_window,
  7684                                                   bits, p->wd, p->h,
  7685                                                   1, 0, 1);
  7686 
  7687 #ifdef HAVE_XRENDER
  7688           if (picture != None)
  7689             {
  7690               attrs.clip_mask = clipmask;
  7691               attrs.clip_x_origin = p->x;
  7692               attrs.clip_y_origin = p->y;
  7693 
  7694               XRenderChangePicture (display, FRAME_X_PICTURE (f),
  7695                                     CPClipMask | CPClipXOrigin | CPClipYOrigin,
  7696                                     &attrs);
  7697             }
  7698           else
  7699 #endif
  7700             {
  7701               gcv.clip_mask = clipmask;
  7702               gcv.clip_x_origin = p->x;
  7703               gcv.clip_y_origin = p->y;
  7704               XChangeGC (display, gc, GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv);
  7705             }
  7706         }
  7707 
  7708 #ifdef HAVE_XRENDER
  7709       if (picture != None)
  7710         {
  7711           x_xr_apply_ext_clip (f, gc);
  7712           XRenderComposite (display, PictOpSrc, picture,
  7713                             None, FRAME_X_PICTURE (f),
  7714                             0, 0, 0, 0, p->x, p->y, p->wd, p->h);
  7715           x_xr_reset_ext_clip (f);
  7716 
  7717           XRenderFreePicture (display, picture);
  7718         }
  7719       else
  7720 #endif
  7721         XCopyArea (display, pixmap, drawable, gc, 0, 0,
  7722                    p->wd, p->h, p->x, p->y);
  7723       XFreePixmap (display, pixmap);
  7724 
  7725       if (p->overlay_p)
  7726         {
  7727           gcv.clip_mask = (Pixmap) 0;
  7728           XChangeGC (display, gc, GCClipMask, &gcv);
  7729           XFreePixmap (display, clipmask);
  7730         }
  7731     }
  7732 #endif  /* not USE_CAIRO */
  7733 
  7734   x_reset_clip_rectangles (f, gc);
  7735 }
  7736 
  7737 /***********************************************************************
  7738                             Glyph display
  7739  ***********************************************************************/
  7740 
  7741 static bool x_alloc_lighter_color (struct frame *, Display *, Colormap,
  7742                                    unsigned long *, double, int);
  7743 static void x_scroll_bar_clear (struct frame *);
  7744 
  7745 #ifdef GLYPH_DEBUG
  7746 static void x_check_font (struct frame *, struct font *);
  7747 #endif
  7748 
  7749 /* If SEND_EVENT, make sure that TIME is larger than the current last
  7750    user time.  We don't sanitize timestamps from events sent by the X
  7751    server itself because some Lisp might have set the user time to a
  7752    ridiculously large value, and this way a more reasonable timestamp
  7753    can be obtained upon the next event.
  7754 
  7755    Alternatively, the server time could've overflowed.
  7756 
  7757    SET_PROPERTY specifies whether or not to change the user time
  7758    property for the active frame.  The important thing is to not set
  7759    the last user time upon leave events; on Metacity and GNOME Shell,
  7760    mapping a new frame on top of the old frame potentially causes
  7761    crossing events to be sent to the old frame if it contains the
  7762    pointer, as the new frame will initially stack above the old frame.
  7763    If _NET_WM_USER_TIME is changed at that point, then GNOME may get
  7764    notified about the user time change on the old frame before it
  7765    tries to focus the new frame, which will make it consider the new
  7766    frame (whose user time property will not have been updated at that
  7767    point, due to not being focused) as having been mapped
  7768    out-of-order, and lower the new frame, which is typically not what
  7769    users want.  */
  7770 
  7771 static void
  7772 x_display_set_last_user_time (struct x_display_info *dpyinfo, Time time,
  7773                               bool send_event, bool set_property)
  7774 {
  7775 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
  7776   uint_fast64_t monotonic_time;
  7777   uint_fast64_t monotonic_ms;
  7778   int_fast64_t diff_ms;
  7779 #endif
  7780 #ifndef USE_GTK
  7781   struct frame *focus_frame;
  7782   Time old_time;
  7783 
  7784   focus_frame = dpyinfo->x_focus_frame;
  7785   old_time = dpyinfo->last_user_time;
  7786 #endif
  7787 
  7788 #ifdef ENABLE_CHECKING
  7789   eassert (time <= X_ULONG_MAX);
  7790 #endif
  7791 
  7792   if (!send_event || time > dpyinfo->last_user_time)
  7793     dpyinfo->last_user_time = time;
  7794 
  7795 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
  7796   if (!send_event)
  7797     {
  7798       /* See if the current CLOCK_MONOTONIC time is reasonably close
  7799          to the X server time.  */
  7800       monotonic_time = x_sync_current_monotonic_time ();
  7801       monotonic_ms = monotonic_time / 1000;
  7802 
  7803       dpyinfo->server_time_monotonic_p
  7804         = (monotonic_time != 0
  7805            && !INT_SUBTRACT_WRAPV (time, monotonic_ms, &diff_ms)
  7806            && -500 < diff_ms && diff_ms < 500);
  7807 
  7808       if (!dpyinfo->server_time_monotonic_p)
  7809         {
  7810           /* Compute an offset that can be subtracted from the server
  7811              time to estimate the monotonic time on the X server.  */
  7812 
  7813           if (!monotonic_time
  7814               || INT_MULTIPLY_WRAPV (time, 1000, &dpyinfo->server_time_offset)
  7815               || INT_SUBTRACT_WRAPV (dpyinfo->server_time_offset,
  7816                                      monotonic_time,
  7817                                      &dpyinfo->server_time_offset))
  7818             dpyinfo->server_time_offset = 0;
  7819 
  7820           /* If the server time is reasonably close to the monotonic
  7821              time after the latter is truncated to CARD32, simply make
  7822              the offset that between the server time in ms and the
  7823              actual time in ms.  */
  7824 
  7825           monotonic_ms = monotonic_ms & 0xffffffff;
  7826           if (!INT_SUBTRACT_WRAPV (time, monotonic_ms, &diff_ms)
  7827               && -500 < diff_ms && diff_ms < 500)
  7828             {
  7829               /* The server timestamp overflowed.  Make the time
  7830                  offset exactly how much it overflowed by.  */
  7831 
  7832               if (INT_SUBTRACT_WRAPV (monotonic_time / 1000, monotonic_ms,
  7833                                       &dpyinfo->server_time_offset)
  7834                   || INT_MULTIPLY_WRAPV (dpyinfo->server_time_offset,
  7835                                          1000, &dpyinfo->server_time_offset)
  7836                   || INT_SUBTRACT_WRAPV (0, dpyinfo->server_time_offset,
  7837                                          &dpyinfo->server_time_offset))
  7838                 dpyinfo->server_time_offset = 0;
  7839             }
  7840         }
  7841     }
  7842 #endif
  7843 
  7844 #ifndef USE_GTK
  7845   /* Don't waste bandwidth if the time hasn't actually changed.  */
  7846   if (focus_frame && old_time != dpyinfo->last_user_time
  7847       && set_property)
  7848     {
  7849       time = dpyinfo->last_user_time;
  7850 
  7851       while (FRAME_PARENT_FRAME (focus_frame))
  7852         focus_frame = FRAME_PARENT_FRAME (focus_frame);
  7853 
  7854       if (FRAME_X_OUTPUT (focus_frame)->user_time_window != None)
  7855         XChangeProperty (dpyinfo->display,
  7856                          FRAME_X_OUTPUT (focus_frame)->user_time_window,
  7857                          dpyinfo->Xatom_net_wm_user_time,
  7858                          XA_CARDINAL, 32, PropModeReplace,
  7859                          (unsigned char *) &time, 1);
  7860     }
  7861 #endif
  7862 }
  7863 
  7864 #ifdef USE_GTK
  7865 
  7866 static void
  7867 x_set_gtk_user_time (struct frame *f, Time time)
  7868 {
  7869   GtkWidget *widget;
  7870   GdkWindow *window;
  7871 
  7872   widget = FRAME_GTK_OUTER_WIDGET (f);
  7873   window = gtk_widget_get_window (widget);
  7874 
  7875   /* This widget isn't realized yet.  */
  7876   if (!window)
  7877     return;
  7878 
  7879   gdk_x11_window_set_user_time (window, time);
  7880 }
  7881 
  7882 #endif
  7883 
  7884 #if !defined USE_GTK || defined HAVE_XFIXES
  7885 
  7886 /* Create and return a special window for receiving events such as
  7887    selection notify events, and reporting user time.  The window is an
  7888    1x1 unmapped override-redirect InputOnly window at -1, -1 relative
  7889    to the parent, which should prevent it from doing anything.  */
  7890 
  7891 static Window
  7892 x_create_special_window (struct x_display_info *dpyinfo,
  7893                          Window parent_window)
  7894 {
  7895   XSetWindowAttributes attrs;
  7896 
  7897   attrs.override_redirect = True;
  7898 
  7899   return XCreateWindow (dpyinfo->display, parent_window,
  7900                         -1, -1, 1, 1, 0, CopyFromParent, InputOnly,
  7901                         CopyFromParent, CWOverrideRedirect, &attrs);
  7902 }
  7903 
  7904 #endif
  7905 
  7906 /* Not needed on GTK because GTK handles reporting the user time
  7907    itself.  */
  7908 
  7909 #ifndef USE_GTK
  7910 
  7911 static void
  7912 x_update_frame_user_time_window (struct frame *f)
  7913 {
  7914   struct x_output *output;
  7915   struct x_display_info *dpyinfo;
  7916 
  7917   output = FRAME_X_OUTPUT (f);
  7918   dpyinfo = FRAME_DISPLAY_INFO (f);
  7919 
  7920   if (!NILP (Vx_no_window_manager)
  7921       || !x_wm_supports (f, dpyinfo->Xatom_net_wm_user_time))
  7922     {
  7923       if (output->user_time_window != None
  7924           && output->user_time_window != FRAME_OUTER_WINDOW (f))
  7925         {
  7926           XDestroyWindow (dpyinfo->display, output->user_time_window);
  7927           XDeleteProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
  7928                            dpyinfo->Xatom_net_wm_user_time_window);
  7929         }
  7930       else
  7931         XDeleteProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
  7932                          dpyinfo->Xatom_net_wm_user_time);
  7933 
  7934       output->user_time_window = None;
  7935       return;
  7936     }
  7937 
  7938   if (!x_wm_supports (f, dpyinfo->Xatom_net_wm_user_time_window))
  7939     {
  7940       if (output->user_time_window == None)
  7941         output->user_time_window = FRAME_OUTER_WINDOW (f);
  7942       else if (output->user_time_window != FRAME_OUTER_WINDOW (f))
  7943         {
  7944           XDestroyWindow (dpyinfo->display,
  7945                           output->user_time_window);
  7946           XDeleteProperty (dpyinfo->display,
  7947                            FRAME_OUTER_WINDOW (f),
  7948                            dpyinfo->Xatom_net_wm_user_time_window);
  7949           output->user_time_window = FRAME_OUTER_WINDOW (f);
  7950         }
  7951     }
  7952   else
  7953     {
  7954       if (output->user_time_window == FRAME_OUTER_WINDOW (f)
  7955           || output->user_time_window == None)
  7956         {
  7957           /* Create a "user time" window that is used to report user
  7958              activity on a given frame.  This is used in preference to
  7959              _NET_WM_USER_TIME, as using a separate window allows the
  7960              window manager to express interest in other properties
  7961              while only reading the user time when necessary, thereby
  7962              improving battery life by not involving the window
  7963              manager in each key press.  */
  7964 
  7965           output->user_time_window
  7966             = x_create_special_window (dpyinfo, FRAME_X_WINDOW (f));
  7967 
  7968           XDeleteProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
  7969                            dpyinfo->Xatom_net_wm_user_time);
  7970           XChangeProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
  7971                            dpyinfo->Xatom_net_wm_user_time_window,
  7972                            XA_WINDOW, 32, PropModeReplace,
  7973                            (unsigned char *) &output->user_time_window, 1);
  7974         }
  7975     }
  7976 }
  7977 
  7978 #endif
  7979 
  7980 void
  7981 x_set_last_user_time_from_lisp (struct x_display_info *dpyinfo,
  7982                                 Time time)
  7983 {
  7984   x_display_set_last_user_time (dpyinfo, time, true, true);
  7985 }
  7986 
  7987 
  7988 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
  7989    face.  */
  7990 
  7991 static void
  7992 x_set_cursor_gc (struct glyph_string *s)
  7993 {
  7994   if (s->font == FRAME_FONT (s->f)
  7995       && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
  7996       && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
  7997       && !s->cmp)
  7998     s->gc = s->f->output_data.x->cursor_gc;
  7999   else
  8000     {
  8001       /* Cursor on non-default face: must merge.  */
  8002       XGCValues xgcv;
  8003       unsigned long mask;
  8004       Display *display = FRAME_X_DISPLAY (s->f);
  8005 
  8006       xgcv.background = s->f->output_data.x->cursor_pixel;
  8007       xgcv.foreground = s->face->background;
  8008 
  8009       /* If the glyph would be invisible, try a different foreground.  */
  8010       if (xgcv.foreground == xgcv.background)
  8011         xgcv.foreground = s->face->foreground;
  8012       if (xgcv.foreground == xgcv.background)
  8013         xgcv.foreground = s->f->output_data.x->cursor_foreground_pixel;
  8014       if (xgcv.foreground == xgcv.background)
  8015         xgcv.foreground = s->face->foreground;
  8016 
  8017       /* Make sure the cursor is distinct from text in this face.  */
  8018       if (xgcv.background == s->face->background
  8019           && xgcv.foreground == s->face->foreground)
  8020         {
  8021           xgcv.background = s->face->foreground;
  8022           xgcv.foreground = s->face->background;
  8023         }
  8024 
  8025       IF_DEBUG (x_check_font (s->f, s->font));
  8026       xgcv.graphics_exposures = False;
  8027       xgcv.line_width = 1;
  8028       mask = (GCForeground | GCBackground
  8029               | GCGraphicsExposures
  8030               | GCLineWidth);
  8031 
  8032       if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
  8033         XChangeGC (display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
  8034                    mask, &xgcv);
  8035       else
  8036         FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
  8037           = XCreateGC (display, FRAME_X_DRAWABLE (s->f), mask, &xgcv);
  8038 
  8039       s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
  8040     }
  8041 }
  8042 
  8043 
  8044 /* Set up S->gc of glyph string S for drawing text in mouse face.  */
  8045 
  8046 static void
  8047 x_set_mouse_face_gc (struct glyph_string *s)
  8048 {
  8049   if (s->font == s->face->font)
  8050     s->gc = s->face->gc;
  8051   else
  8052     {
  8053       /* Otherwise construct scratch_cursor_gc with values from FACE
  8054          except for FONT.  */
  8055       XGCValues xgcv;
  8056       unsigned long mask;
  8057       Display *display = FRAME_X_DISPLAY (s->f);
  8058 
  8059       xgcv.background = s->face->background;
  8060       xgcv.foreground = s->face->foreground;
  8061       xgcv.graphics_exposures = False;
  8062       xgcv.line_width = 1;
  8063 
  8064       mask = (GCForeground | GCBackground
  8065               | GCGraphicsExposures
  8066               | GCLineWidth);
  8067 
  8068       if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
  8069         XChangeGC (display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
  8070                    mask, &xgcv);
  8071       else
  8072         FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
  8073           = XCreateGC (display, FRAME_X_DRAWABLE (s->f), mask, &xgcv);
  8074 
  8075       s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
  8076 
  8077     }
  8078   eassert (s->gc != 0);
  8079 }
  8080 
  8081 
  8082 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
  8083    Faces to use in the mode line have already been computed when the
  8084    matrix was built, so there isn't much to do, here.  */
  8085 
  8086 static void
  8087 x_set_mode_line_face_gc (struct glyph_string *s)
  8088 {
  8089   s->gc = s->face->gc;
  8090 }
  8091 
  8092 
  8093 /* Set S->gc of glyph string S for drawing that glyph string.  Set
  8094    S->stippled_p to a non-zero value if the face of S has a stipple
  8095    pattern.  */
  8096 
  8097 static void
  8098 x_set_glyph_string_gc (struct glyph_string *s)
  8099 {
  8100   prepare_face_for_display (s->f, s->face);
  8101 
  8102   if (s->hl == DRAW_NORMAL_TEXT)
  8103     {
  8104       s->gc = s->face->gc;
  8105       s->stippled_p = s->face->stipple != 0;
  8106     }
  8107   else if (s->hl == DRAW_INVERSE_VIDEO)
  8108     {
  8109       x_set_mode_line_face_gc (s);
  8110       s->stippled_p = s->face->stipple != 0;
  8111     }
  8112   else if (s->hl == DRAW_CURSOR)
  8113     {
  8114       x_set_cursor_gc (s);
  8115       s->stippled_p = false;
  8116     }
  8117   else if (s->hl == DRAW_MOUSE_FACE)
  8118     {
  8119       x_set_mouse_face_gc (s);
  8120       s->stippled_p = s->face->stipple != 0;
  8121     }
  8122   else if (s->hl == DRAW_IMAGE_RAISED
  8123            || s->hl == DRAW_IMAGE_SUNKEN)
  8124     {
  8125       s->gc = s->face->gc;
  8126       s->stippled_p = s->face->stipple != 0;
  8127     }
  8128   else
  8129     emacs_abort ();
  8130 
  8131   /* GC must have been set.  */
  8132   eassert (s->gc != 0);
  8133 }
  8134 
  8135 
  8136 /* Set clipping for output of glyph string S.  S may be part of a mode
  8137    line or menu if we don't have X toolkit support.  */
  8138 
  8139 static void
  8140 x_set_glyph_string_clipping (struct glyph_string *s)
  8141 {
  8142   XRectangle *r = s->clip;
  8143   int n = get_glyph_string_clip_rects (s, r, 2);
  8144 
  8145   if (n > 0)
  8146     x_set_clip_rectangles (s->f, s->gc, r, n);
  8147   s->num_clips = n;
  8148 }
  8149 
  8150 
  8151 /* Set SRC's clipping for output of glyph string DST.  This is called
  8152    when we are drawing DST's left_overhang or right_overhang only in
  8153    the area of SRC.  */
  8154 
  8155 static void
  8156 x_set_glyph_string_clipping_exactly (struct glyph_string *src, struct glyph_string *dst)
  8157 {
  8158   XRectangle r;
  8159 
  8160   r.x = src->x;
  8161   r.width = src->width;
  8162   r.y = src->y;
  8163   r.height = src->height;
  8164   dst->clip[0] = r;
  8165   dst->num_clips = 1;
  8166   x_set_clip_rectangles (dst->f, dst->gc, &r, 1);
  8167 }
  8168 
  8169 
  8170 /* RIF:
  8171    Compute left and right overhang of glyph string S.  */
  8172 
  8173 static void
  8174 x_compute_glyph_string_overhangs (struct glyph_string *s)
  8175 {
  8176   if (s->cmp == NULL
  8177       && (s->first_glyph->type == CHAR_GLYPH
  8178           || s->first_glyph->type == COMPOSITE_GLYPH))
  8179     {
  8180       struct font_metrics metrics;
  8181 
  8182       if (s->first_glyph->type == CHAR_GLYPH)
  8183         {
  8184           struct font *font = s->font;
  8185           font->driver->text_extents (font, s->char2b, s->nchars, &metrics);
  8186         }
  8187       else
  8188         {
  8189           Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
  8190 
  8191           composition_gstring_width (gstring, s->cmp_from, s->cmp_to, &metrics);
  8192         }
  8193       s->right_overhang = (metrics.rbearing > metrics.width
  8194                            ? metrics.rbearing - metrics.width : 0);
  8195       s->left_overhang = metrics.lbearing < 0 ? - metrics.lbearing : 0;
  8196     }
  8197   else if (s->cmp)
  8198     {
  8199       s->right_overhang = s->cmp->rbearing - s->cmp->pixel_width;
  8200       s->left_overhang = - s->cmp->lbearing;
  8201     }
  8202 }
  8203 
  8204 
  8205 /* Fill rectangle X, Y, W, H with background color of glyph string S.  */
  8206 
  8207 static void
  8208 x_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h)
  8209 {
  8210   x_clear_rectangle (s->f, s->gc, x, y, w, h, s->hl != DRAW_CURSOR);
  8211 }
  8212 
  8213 #ifndef USE_CAIRO
  8214 
  8215 static void
  8216 x_clear_point (struct frame *f, GC gc, int x, int y,
  8217                bool respect_alpha_background)
  8218 {
  8219   XGCValues xgcv;
  8220   Display *dpy;
  8221 
  8222   dpy = FRAME_X_DISPLAY (f);
  8223 
  8224   if (f->alpha_background != 1.0
  8225       && respect_alpha_background)
  8226     {
  8227       x_clear_rectangle (f, gc, x, y, 1, 1, true);
  8228       return;
  8229     }
  8230 
  8231   XGetGCValues (dpy, gc, GCBackground | GCForeground, &xgcv);
  8232   XSetForeground (dpy, gc, xgcv.background);
  8233   XDrawPoint (dpy, FRAME_X_DRAWABLE (f), gc, x, y);
  8234   XSetForeground (dpy, gc, xgcv.foreground);
  8235 }
  8236 
  8237 #endif
  8238 
  8239 /* Draw the background of glyph_string S.  If S->background_filled_p
  8240    is non-zero don't draw it.  FORCE_P non-zero means draw the
  8241    background even if it wouldn't be drawn normally.  This is used
  8242    when a string preceding S draws into the background of S, or S
  8243    contains the first component of a composition.  */
  8244 
  8245 static void
  8246 x_draw_glyph_string_background (struct glyph_string *s, bool force_p)
  8247 {
  8248   /* Nothing to do if background has already been drawn or if it
  8249      shouldn't be drawn in the first place.  */
  8250   if (!s->background_filled_p)
  8251     {
  8252       int box_line_width = max (s->face->box_horizontal_line_width, 0);
  8253 
  8254       if (s->stippled_p)
  8255         {
  8256           Display *display = FRAME_X_DISPLAY (s->f);
  8257 
  8258           /* Fill background with a stipple pattern.  */
  8259           XSetFillStyle (display, s->gc, FillOpaqueStippled);
  8260           x_fill_rectangle (s->f, s->gc, s->x,
  8261                             s->y + box_line_width,
  8262                             s->background_width,
  8263                             s->height - 2 * box_line_width,
  8264                             s->hl != DRAW_CURSOR);
  8265           XSetFillStyle (display, s->gc, FillSolid);
  8266           s->background_filled_p = true;
  8267         }
  8268       else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
  8269                /* When xdisp.c ignores FONT_HEIGHT, we cannot trust
  8270                   font dimensions, since the actual glyphs might be
  8271                   much smaller.  So in that case we always clear the
  8272                   rectangle with background color.  */
  8273                || FONT_TOO_HIGH (s->font)
  8274                || s->font_not_found_p
  8275                || s->extends_to_end_of_line_p
  8276                || force_p)
  8277         {
  8278           x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
  8279                                      s->background_width,
  8280                                      s->height - 2 * box_line_width);
  8281           s->background_filled_p = true;
  8282         }
  8283     }
  8284 }
  8285 
  8286 
  8287 /* Draw the foreground of glyph string S.  */
  8288 
  8289 static void
  8290 x_draw_glyph_string_foreground (struct glyph_string *s)
  8291 {
  8292   int i, x;
  8293 
  8294   /* If first glyph of S has a left box line, start drawing the text
  8295      of S to the right of that box line.  */
  8296   if (s->face->box != FACE_NO_BOX
  8297       && s->first_glyph->left_box_line_p)
  8298     x = s->x + max (s->face->box_vertical_line_width, 0);
  8299   else
  8300     x = s->x;
  8301 
  8302   /* Draw characters of S as rectangles if S's font could not be
  8303      loaded.  */
  8304   if (s->font_not_found_p)
  8305     {
  8306       for (i = 0; i < s->nchars; ++i)
  8307         {
  8308           struct glyph *g = s->first_glyph + i;
  8309           x_draw_rectangle (s->f,
  8310                           s->gc, x, s->y, g->pixel_width - 1,
  8311                           s->height - 1);
  8312           x += g->pixel_width;
  8313         }
  8314     }
  8315   else
  8316     {
  8317       struct font *font = s->font;
  8318 #ifdef USE_CAIRO
  8319       if (!EQ (font->driver->type, Qx)
  8320           || x_try_cr_xlib_drawable (s->f, s->gc))
  8321         {
  8322 #endif  /* USE_CAIRO */
  8323           int boff = font->baseline_offset;
  8324           int y;
  8325 
  8326           if (font->vertical_centering)
  8327             boff = VCENTER_BASELINE_OFFSET (font, s->f) - boff;
  8328 
  8329           y = s->ybase - boff;
  8330           if (s->for_overlaps
  8331               || (s->background_filled_p && s->hl != DRAW_CURSOR))
  8332             font->driver->draw (s, 0, s->nchars, x, y, false);
  8333           else
  8334             font->driver->draw (s, 0, s->nchars, x, y, true);
  8335           if (s->face->overstrike)
  8336             font->driver->draw (s, 0, s->nchars, x + 1, y, false);
  8337 #ifdef USE_CAIRO
  8338           if (EQ (font->driver->type, Qx))
  8339             x_end_cr_xlib_drawable (s->f, s->gc);
  8340         }
  8341       else
  8342         {
  8343           /* Fallback for the case that no Xlib Drawable is available
  8344              for drawing text with X core fonts.  */
  8345           if (!(s->for_overlaps
  8346                 || (s->background_filled_p && s->hl != DRAW_CURSOR)))
  8347             {
  8348               int box_line_width = max (s->face->box_horizontal_line_width, 0);
  8349 
  8350               if (s->stippled_p)
  8351                 {
  8352                   Display *display = FRAME_X_DISPLAY (s->f);
  8353 
  8354                   /* Fill background with a stipple pattern.  */
  8355                   XSetFillStyle (display, s->gc, FillOpaqueStippled);
  8356                   x_fill_rectangle (s->f, s->gc, s->x,
  8357                                     s->y + box_line_width,
  8358                                     s->background_width,
  8359                                     s->height - 2 * box_line_width,
  8360                                     false);
  8361                   XSetFillStyle (display, s->gc, FillSolid);
  8362                 }
  8363               else
  8364                 x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
  8365                                            s->background_width,
  8366                                            s->height - 2 * box_line_width);
  8367             }
  8368           for (i = 0; i < s->nchars; ++i)
  8369             {
  8370               struct glyph *g = s->first_glyph + i;
  8371               x_draw_rectangle (s->f,
  8372                                 s->gc, x, s->y, g->pixel_width - 1,
  8373                                 s->height - 1);
  8374               x += g->pixel_width;
  8375             }
  8376         }
  8377 #endif  /* USE_CAIRO */
  8378     }
  8379 }
  8380 
  8381 /* Draw the foreground of composite glyph string S.  */
  8382 
  8383 static void
  8384 x_draw_composite_glyph_string_foreground (struct glyph_string *s)
  8385 {
  8386   int i, j, x;
  8387   struct font *font = s->font;
  8388 
  8389   /* If first glyph of S has a left box line, start drawing the text
  8390      of S to the right of that box line.  */
  8391   if (s->face && s->face->box != FACE_NO_BOX
  8392       && s->first_glyph->left_box_line_p)
  8393     x = s->x + max (s->face->box_vertical_line_width, 0);
  8394   else
  8395     x = s->x;
  8396 
  8397   /* S is a glyph string for a composition.  S->cmp_from is the index
  8398      of the first character drawn for glyphs of this composition.
  8399      S->cmp_from == 0 means we are drawing the very first character of
  8400      this composition.  */
  8401 
  8402   /* Draw a rectangle for the composition if the font for the very
  8403      first character of the composition could not be loaded.  */
  8404   if (s->font_not_found_p)
  8405     {
  8406       if (s->cmp_from == 0)
  8407         x_draw_rectangle (s->f, s->gc, x, s->y,
  8408                         s->width - 1, s->height - 1);
  8409     }
  8410   else
  8411 #ifdef USE_CAIRO
  8412     if (!EQ (font->driver->type, Qx)
  8413         || x_try_cr_xlib_drawable (s->f, s->gc))
  8414       {
  8415 #endif  /* USE_CAIRO */
  8416         if (! s->first_glyph->u.cmp.automatic)
  8417           {
  8418             int y = s->ybase;
  8419 
  8420             for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++)
  8421               /* TAB in a composition means display glyphs with
  8422                  padding space on the left or right.  */
  8423               if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
  8424                 {
  8425                   int xx = x + s->cmp->offsets[j * 2];
  8426                   int yy = y - s->cmp->offsets[j * 2 + 1];
  8427 
  8428                   font->driver->draw (s, j, j + 1, xx, yy, false);
  8429                   if (s->face->overstrike)
  8430                     font->driver->draw (s, j, j + 1, xx + 1, yy, false);
  8431                 }
  8432           }
  8433         else
  8434           {
  8435             Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
  8436             Lisp_Object glyph;
  8437             int y = s->ybase;
  8438             int width = 0;
  8439 
  8440             for (i = j = s->cmp_from; i < s->cmp_to; i++)
  8441               {
  8442                 glyph = LGSTRING_GLYPH (gstring, i);
  8443                 if (NILP (LGLYPH_ADJUSTMENT (glyph)))
  8444                   width += LGLYPH_WIDTH (glyph);
  8445                 else
  8446                   {
  8447                     int xoff, yoff, wadjust;
  8448 
  8449                     if (j < i)
  8450                       {
  8451                         font->driver->draw (s, j, i, x, y, false);
  8452                         if (s->face->overstrike)
  8453                           font->driver->draw (s, j, i, x + 1, y, false);
  8454                         x += width;
  8455                       }
  8456                     xoff = LGLYPH_XOFF (glyph);
  8457                     yoff = LGLYPH_YOFF (glyph);
  8458                     wadjust = LGLYPH_WADJUST (glyph);
  8459                     font->driver->draw (s, i, i + 1, x + xoff, y + yoff, false);
  8460                     if (s->face->overstrike)
  8461                       font->driver->draw (s, i, i + 1, x + xoff + 1, y + yoff,
  8462                                           false);
  8463                     x += wadjust;
  8464                     j = i + 1;
  8465                     width = 0;
  8466                   }
  8467               }
  8468             if (j < i)
  8469               {
  8470                 font->driver->draw (s, j, i, x, y, false);
  8471                 if (s->face->overstrike)
  8472                   font->driver->draw (s, j, i, x + 1, y, false);
  8473               }
  8474           }
  8475 #ifdef USE_CAIRO
  8476         if (EQ (font->driver->type, Qx))
  8477           x_end_cr_xlib_drawable (s->f, s->gc);
  8478       }
  8479     else
  8480       {
  8481         /* Fallback for the case that no Xlib Drawable is available
  8482            for drawing text with X core fonts.  */
  8483         if (s->cmp_from == 0)
  8484           x_draw_rectangle (s->f, s->gc, x, s->y,
  8485                             s->width - 1, s->height - 1);
  8486       }
  8487 #endif  /* USE_CAIRO */
  8488 }
  8489 
  8490 
  8491 /* Draw the foreground of glyph string S for glyphless characters.  */
  8492 
  8493 static void
  8494 x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
  8495 {
  8496   struct glyph *glyph = s->first_glyph;
  8497   unsigned char2b[8];
  8498   int x, i, j;
  8499 
  8500   /* If first glyph of S has a left box line, start drawing the text
  8501      of S to the right of that box line.  */
  8502   if (s->face && s->face->box != FACE_NO_BOX
  8503       && s->first_glyph->left_box_line_p)
  8504     x = s->x + max (s->face->box_vertical_line_width, 0);
  8505   else
  8506     x = s->x;
  8507 
  8508   s->char2b = char2b;
  8509 
  8510   for (i = 0; i < s->nchars; i++, glyph++)
  8511     {
  8512 #ifdef GCC_LINT
  8513       enum { PACIFY_GCC_BUG_81401 = 1 };
  8514 #else
  8515       enum { PACIFY_GCC_BUG_81401 = 0 };
  8516 #endif
  8517       char buf[7 + PACIFY_GCC_BUG_81401];
  8518       char *str = NULL;
  8519       int len = glyph->u.glyphless.len;
  8520 
  8521       if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM)
  8522         {
  8523           if (len > 0
  8524               && CHAR_TABLE_P (Vglyphless_char_display)
  8525               && (CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display))
  8526                   >= 1))
  8527             {
  8528               Lisp_Object acronym
  8529                 = (! glyph->u.glyphless.for_no_font
  8530                    ? CHAR_TABLE_REF (Vglyphless_char_display,
  8531                                      glyph->u.glyphless.ch)
  8532                    : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
  8533               if (CONSP (acronym))
  8534                 acronym = XCAR (acronym);
  8535               if (STRINGP (acronym))
  8536                 str = SSDATA (acronym);
  8537             }
  8538         }
  8539       else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE)
  8540         {
  8541           unsigned int ch = glyph->u.glyphless.ch;
  8542           eassume (ch <= MAX_CHAR);
  8543           sprintf (buf, "%0*X", ch < 0x10000 ? 4 : 6, ch);
  8544           str = buf;
  8545         }
  8546 
  8547       if (str)
  8548         {
  8549           int upper_len = (len + 1) / 2;
  8550 
  8551           /* It is assured that all LEN characters in STR is ASCII.  */
  8552           for (j = 0; j < len; j++)
  8553             char2b[j] = s->font->driver->encode_char (s->font, str[j]) & 0xFFFF;
  8554           s->font->driver->draw (s, 0, upper_len,
  8555                                  x + glyph->slice.glyphless.upper_xoff,
  8556                                  s->ybase + glyph->slice.glyphless.upper_yoff,
  8557                                  false);
  8558           s->font->driver->draw (s, upper_len, len,
  8559                                  x + glyph->slice.glyphless.lower_xoff,
  8560                                  s->ybase + glyph->slice.glyphless.lower_yoff,
  8561                                  false);
  8562         }
  8563       if (glyph->u.glyphless.method != GLYPHLESS_DISPLAY_THIN_SPACE)
  8564         x_draw_rectangle (s->f, s->gc,
  8565                         x, s->ybase - glyph->ascent,
  8566                         glyph->pixel_width - 1,
  8567                         glyph->ascent + glyph->descent - 1);
  8568       x += glyph->pixel_width;
  8569    }
  8570 
  8571   /* Defend against hypothetical bad code elsewhere that uses
  8572      s->char2b after this function returns.  */
  8573   s->char2b = NULL;
  8574 }
  8575 
  8576 #ifdef USE_X_TOOLKIT
  8577 
  8578 #ifdef USE_LUCID
  8579 
  8580 /* Return the frame on which widget WIDGET is used.. Abort if frame
  8581    cannot be determined.  */
  8582 
  8583 static struct frame *
  8584 x_frame_of_widget (Widget widget)
  8585 {
  8586   struct x_display_info *dpyinfo;
  8587   Lisp_Object tail, frame;
  8588   struct frame *f;
  8589 
  8590   dpyinfo = x_display_info_for_display (XtDisplay (widget));
  8591 
  8592   /* Find the top-level shell of the widget.  Note that this function
  8593      can be called when the widget is not yet realized, so XtWindow
  8594      (widget) == 0.  That's the reason we can't simply use
  8595      x_any_window_to_frame.  */
  8596   while (!XtIsTopLevelShell (widget))
  8597     widget = XtParent (widget);
  8598 
  8599   /* Look for a frame with that top-level widget.  Allocate the color
  8600      on that frame to get the right gamma correction value.  */
  8601   FOR_EACH_FRAME (tail, frame)
  8602     {
  8603       f = XFRAME (frame);
  8604       if (FRAME_X_P (f)
  8605           && FRAME_DISPLAY_INFO (f) == dpyinfo
  8606           && f->output_data.x->widget == widget)
  8607         return f;
  8608     }
  8609   emacs_abort ();
  8610 }
  8611 
  8612 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
  8613    or DELTA.  Try a color with RGB values multiplied by FACTOR first.
  8614    If this produces the same color as PIXEL, try a color where all RGB
  8615    values have DELTA added.  Return the allocated color in *PIXEL.
  8616    DISPLAY is the X display, CMAP is the colormap to operate on.
  8617    Value is true if successful.  */
  8618 
  8619 bool
  8620 x_alloc_lighter_color_for_widget (Widget widget, Display *display, Colormap cmap,
  8621                                   unsigned long *pixel, double factor, int delta)
  8622 {
  8623   struct frame *f = x_frame_of_widget (widget);
  8624   return x_alloc_lighter_color (f, display, cmap, pixel, factor, delta);
  8625 }
  8626 
  8627 #endif /* USE_LUCID */
  8628 
  8629 
  8630 /* Structure specifying which arguments should be passed by Xt to
  8631    cvt_string_to_pixel.  We want the widget's screen and colormap.  */
  8632 
  8633 static XtConvertArgRec cvt_string_to_pixel_args[] =
  8634   {
  8635     {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.screen),
  8636      sizeof (Screen *)},
  8637     {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.colormap),
  8638      sizeof (Colormap)}
  8639   };
  8640 
  8641 
  8642 /* The address of this variable is returned by
  8643    cvt_string_to_pixel.  */
  8644 
  8645 static Pixel cvt_string_to_pixel_value;
  8646 
  8647 
  8648 /* Convert a color name to a pixel color.
  8649 
  8650    DPY is the display we are working on.
  8651 
  8652    ARGS is an array of *NARGS XrmValue structures holding additional
  8653    information about the widget for which the conversion takes place.
  8654    The contents of this array are determined by the specification
  8655    in cvt_string_to_pixel_args.
  8656 
  8657    FROM is a pointer to an XrmValue which points to the color name to
  8658    convert.  TO is an XrmValue in which to return the pixel color.
  8659 
  8660    CLOSURE_RET is a pointer to user-data, in which we record if
  8661    we allocated the color or not.
  8662 
  8663    Value is True if successful, False otherwise.  */
  8664 
  8665 static Boolean
  8666 cvt_string_to_pixel (Display *dpy, XrmValue *args, Cardinal *nargs,
  8667                      XrmValue *from, XrmValue *to,
  8668                      XtPointer *closure_ret)
  8669 {
  8670   Screen *screen;
  8671   Colormap cmap;
  8672   Pixel pixel;
  8673   String color_name;
  8674   XColor color;
  8675 
  8676   if (*nargs != 2)
  8677     {
  8678       XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
  8679                        "wrongParameters", "cvt_string_to_pixel",
  8680                        "XtToolkitError",
  8681                        "Screen and colormap args required", NULL, NULL);
  8682       return False;
  8683     }
  8684 
  8685   screen = *(Screen **) args[0].addr;
  8686   cmap = *(Colormap *) args[1].addr;
  8687   color_name = (String) from->addr;
  8688 
  8689   if (strcmp (color_name, XtDefaultBackground) == 0)
  8690     {
  8691       *closure_ret = (XtPointer) False;
  8692       pixel = WhitePixelOfScreen (screen);
  8693     }
  8694   else if (strcmp (color_name, XtDefaultForeground) == 0)
  8695     {
  8696       *closure_ret = (XtPointer) False;
  8697       pixel = BlackPixelOfScreen (screen);
  8698     }
  8699   else if (XParseColor (dpy, cmap, color_name, &color)
  8700            && x_alloc_nearest_color_1 (dpy, cmap, &color))
  8701     {
  8702       pixel = color.pixel;
  8703       *closure_ret = (XtPointer) True;
  8704     }
  8705   else
  8706     {
  8707       String params[1];
  8708       Cardinal nparams = 1;
  8709 
  8710       params[0] = color_name;
  8711       XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
  8712                        "badValue", "cvt_string_to_pixel",
  8713                        "XtToolkitError", "Invalid color '%s'",
  8714                        params, &nparams);
  8715       return False;
  8716     }
  8717 
  8718   if (to->addr != NULL)
  8719     {
  8720       if (to->size < sizeof (Pixel))
  8721         {
  8722           to->size = sizeof (Pixel);
  8723           return False;
  8724         }
  8725 
  8726       *(Pixel *) to->addr = pixel;
  8727     }
  8728   else
  8729     {
  8730       cvt_string_to_pixel_value = pixel;
  8731       to->addr = (XtPointer) &cvt_string_to_pixel_value;
  8732     }
  8733 
  8734   to->size = sizeof (Pixel);
  8735   return True;
  8736 }
  8737 
  8738 
  8739 /* Free a pixel color which was previously allocated via
  8740    cvt_string_to_pixel.  This is registered as the destructor
  8741    for this type of resource via XtSetTypeConverter.
  8742 
  8743    APP is the application context in which we work.
  8744 
  8745    TO is a pointer to an XrmValue holding the color to free.
  8746    CLOSURE is the value we stored in CLOSURE_RET for this color
  8747    in cvt_string_to_pixel.
  8748 
  8749    ARGS and NARGS are like for cvt_string_to_pixel.  */
  8750 
  8751 static void
  8752 cvt_pixel_dtor (XtAppContext app, XrmValuePtr to, XtPointer closure, XrmValuePtr args,
  8753                 Cardinal *nargs)
  8754 {
  8755   if (*nargs != 2)
  8756     {
  8757       XtAppWarningMsg (app, "wrongParameters", "cvt_pixel_dtor",
  8758                        "XtToolkitError",
  8759                        "Screen and colormap arguments required",
  8760                        NULL, NULL);
  8761     }
  8762   else if (closure != NULL)
  8763     {
  8764       /* We did allocate the pixel, so free it.  */
  8765       Screen *screen = *(Screen **) args[0].addr;
  8766       Colormap cmap = *(Colormap *) args[1].addr;
  8767       x_free_dpy_colors (DisplayOfScreen (screen), screen, cmap,
  8768                          (Pixel *) to->addr, 1);
  8769     }
  8770 }
  8771 
  8772 
  8773 #endif /* USE_X_TOOLKIT */
  8774 
  8775 
  8776 /* Value is an array of XColor structures for the contents of the
  8777    color map of display DPY.  Set *NCELLS to the size of the array.
  8778    Note that this probably shouldn't be called for large color maps,
  8779    say a 24-bit TrueColor map.  */
  8780 
  8781 static const XColor *
  8782 x_color_cells (Display *dpy, int *ncells)
  8783 {
  8784   struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
  8785   eassume (dpyinfo);
  8786 
  8787   if (dpyinfo->color_cells == NULL)
  8788     {
  8789       int ncolor_cells = dpyinfo->visual_info.colormap_size;
  8790       int i;
  8791 
  8792       dpyinfo->color_cells = xnmalloc (ncolor_cells,
  8793                                        sizeof *dpyinfo->color_cells);
  8794       dpyinfo->ncolor_cells = ncolor_cells;
  8795 
  8796       for (i = 0; i < ncolor_cells; ++i)
  8797         dpyinfo->color_cells[i].pixel = i;
  8798 
  8799       XQueryColors (dpy, dpyinfo->cmap,
  8800                     dpyinfo->color_cells, ncolor_cells);
  8801     }
  8802 
  8803   *ncells = dpyinfo->ncolor_cells;
  8804   return dpyinfo->color_cells;
  8805 }
  8806 
  8807 
  8808 /* On frame F, translate pixel colors to RGB values for the NCOLORS
  8809    colors in COLORS.  Use cached information, if available.  */
  8810 
  8811 void
  8812 x_query_colors (struct frame *f, XColor *colors, int ncolors)
  8813 {
  8814   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  8815   int i;
  8816 
  8817   if (dpyinfo->red_bits > 0)
  8818     {
  8819       /* For TrueColor displays, we can decompose the RGB value
  8820          directly.  */
  8821       unsigned int rmult, gmult, bmult;
  8822       unsigned int rmask, gmask, bmask;
  8823 
  8824       rmask = (1 << dpyinfo->red_bits) - 1;
  8825       gmask = (1 << dpyinfo->green_bits) - 1;
  8826       bmask = (1 << dpyinfo->blue_bits) - 1;
  8827       /* If we're widening, for example, 8 bits in the pixel value to
  8828          16 bits for the separate-color representation, we want to
  8829          extrapolate the lower bits based on those bits available --
  8830          in other words, we'd like 0xff to become 0xffff instead of
  8831          the 0xff00 we'd get by just zero-filling the lower bits.
  8832 
  8833          We generate a 32-bit scaled-up value and shift it, in case
  8834          the bit count doesn't divide 16 evenly (e.g., when dealing
  8835          with a 3-3-2 bit RGB display), to get more of the lower bits
  8836          correct.
  8837 
  8838          Should we cache the multipliers in dpyinfo?  Maybe
  8839          special-case the 8-8-8 common case?  */
  8840       rmult = 0xffffffff / rmask;
  8841       gmult = 0xffffffff / gmask;
  8842       bmult = 0xffffffff / bmask;
  8843 
  8844       for (i = 0; i < ncolors; ++i)
  8845         {
  8846           unsigned int r, g, b;
  8847           unsigned long pixel = colors[i].pixel;
  8848 
  8849           r = (pixel >> dpyinfo->red_offset) & rmask;
  8850           g = (pixel >> dpyinfo->green_offset) & gmask;
  8851           b = (pixel >> dpyinfo->blue_offset) & bmask;
  8852 
  8853           colors[i].red = (r * rmult) >> 16;
  8854           colors[i].green = (g * gmult) >> 16;
  8855           colors[i].blue = (b * bmult) >> 16;
  8856         }
  8857       return;
  8858     }
  8859 
  8860   if (dpyinfo->color_cells)
  8861     {
  8862       int i;
  8863       for (i = 0; i < ncolors; ++i)
  8864         {
  8865           unsigned long pixel = colors[i].pixel;
  8866           eassert (pixel < dpyinfo->ncolor_cells);
  8867           eassert (dpyinfo->color_cells[pixel].pixel == pixel);
  8868           colors[i] = dpyinfo->color_cells[pixel];
  8869         }
  8870       return;
  8871     }
  8872 
  8873   XQueryColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), colors, ncolors);
  8874 }
  8875 
  8876 /* Store F's real background color into *BGCOLOR.  */
  8877 
  8878 static void
  8879 x_query_frame_background_color (struct frame *f, XColor *bgcolor)
  8880 {
  8881   unsigned long background = FRAME_BACKGROUND_PIXEL (f);
  8882 #ifndef USE_CAIRO
  8883   XColor bg;
  8884 #endif
  8885 
  8886   if (FRAME_DISPLAY_INFO (f)->alpha_bits)
  8887     {
  8888 #ifdef USE_CAIRO
  8889       background = (background & ~FRAME_DISPLAY_INFO (f)->alpha_mask);
  8890       background |= (((unsigned long) (f->alpha_background * 0xffff)
  8891                       >> (16 - FRAME_DISPLAY_INFO (f)->alpha_bits))
  8892                      << FRAME_DISPLAY_INFO (f)->alpha_offset);
  8893 #else
  8894       if (FRAME_DISPLAY_INFO (f)->alpha_bits
  8895           && f->alpha_background < 1.0)
  8896         {
  8897           bg.pixel = background;
  8898           x_query_colors (f, &bg, 1);
  8899           bg.red *= f->alpha_background;
  8900           bg.green *= f->alpha_background;
  8901           bg.blue *= f->alpha_background;
  8902 
  8903           background = x_make_truecolor_pixel (FRAME_DISPLAY_INFO (f),
  8904                                                bg.red, bg.green, bg.blue);
  8905           background &= ~FRAME_DISPLAY_INFO (f)->alpha_mask;
  8906           background |= (((unsigned long) (f->alpha_background * 0xffff)
  8907                           >> (16 - FRAME_DISPLAY_INFO (f)->alpha_bits))
  8908                          << FRAME_DISPLAY_INFO (f)->alpha_offset);
  8909         }
  8910 #endif
  8911     }
  8912 
  8913   bgcolor->pixel = background;
  8914 
  8915   x_query_colors (f, bgcolor, 1);
  8916 }
  8917 
  8918 static unsigned int
  8919 x_hash_string_ignore_case (const char *string)
  8920 {
  8921   unsigned int i;
  8922 
  8923   i = 3323198485ul;
  8924   for (; *string; ++string)
  8925     {
  8926       i ^= c_tolower (*string);
  8927       i *= 0x5bd1e995;
  8928       i ^= i >> 15;
  8929     }
  8930   return i;
  8931 }
  8932 
  8933 /* On frame F, translate the color name to RGB values.  Use cached
  8934    information, if possible.
  8935 
  8936    If too many entries are placed in the cache, the least recently
  8937    used entries are removed.  */
  8938 
  8939 Status
  8940 x_parse_color (struct frame *f, const char *color_name,
  8941                XColor *color)
  8942 {
  8943   unsigned short r, g, b;
  8944   Display *dpy;
  8945   Colormap cmap;
  8946   struct x_display_info *dpyinfo;
  8947   struct color_name_cache_entry *cache_entry, *last;
  8948   struct color_name_cache_entry *next, *color_entry;
  8949   unsigned int hash, idx;
  8950   int rc, i;
  8951 
  8952   /* Don't pass #RGB strings directly to XParseColor, because that
  8953      follows the X convention of zero-extending each channel
  8954      value: #f00 means #f00000.  We want the convention of scaling
  8955      channel values, so #f00 means #ff0000, just as it does for
  8956      HTML, SVG, and CSS.  */
  8957   if (parse_color_spec (color_name, &r, &g, &b))
  8958     {
  8959       color->red = r;
  8960       color->green = g;
  8961       color->blue = b;
  8962 
  8963       return 1;
  8964     }
  8965 
  8966   /* Some X servers send BadValue on empty color names.  */
  8967   if (!strlen (color_name))
  8968     return 0;
  8969 
  8970   cmap = FRAME_X_COLORMAP (f);
  8971   dpy = FRAME_X_DISPLAY (f);
  8972   dpyinfo = FRAME_DISPLAY_INFO (f);
  8973 
  8974   hash = x_hash_string_ignore_case (color_name);
  8975   idx = hash % dpyinfo->color_names_size;
  8976 
  8977   last = NULL;
  8978 
  8979   for (cache_entry = dpyinfo->color_names[idx];
  8980        cache_entry; cache_entry = cache_entry->next)
  8981     {
  8982       if (!xstrcasecmp (cache_entry->name, color_name))
  8983         {
  8984           /* Move recently used entries to the start of the color
  8985              cache.  */
  8986 
  8987           if (last)
  8988             {
  8989               last->next = cache_entry->next;
  8990               cache_entry->next = dpyinfo->color_names[idx];
  8991 
  8992               dpyinfo->color_names[idx] = cache_entry;
  8993             }
  8994 
  8995           if (cache_entry->valid)
  8996             *color = cache_entry->rgb;
  8997 
  8998           return cache_entry->valid;
  8999         }
  9000 
  9001       last = cache_entry;
  9002     }
  9003 
  9004   block_input ();
  9005   rc = XParseColor (dpy, cmap, color_name, color);
  9006   unblock_input ();
  9007 
  9008   cache_entry = xzalloc (sizeof *cache_entry);
  9009   dpyinfo->color_names_length[idx] += 1;
  9010 
  9011   if (rc)
  9012     cache_entry->rgb = *color;
  9013 
  9014   cache_entry->valid = rc;
  9015   cache_entry->name = xstrdup (color_name);
  9016   cache_entry->next = dpyinfo->color_names[idx];
  9017 
  9018   dpyinfo->color_names[idx] = cache_entry;
  9019 
  9020   /* Don't let the color cache become too big.  */
  9021   if (dpyinfo->color_names_length[idx] > (x_color_cache_bucket_size > 0
  9022                                           ? x_color_cache_bucket_size : 128))
  9023     {
  9024       i = 0;
  9025 
  9026       for (last = dpyinfo->color_names[idx]; last; last = last->next)
  9027         {
  9028           if (++i == (x_color_cache_bucket_size > 0
  9029                       ? x_color_cache_bucket_size : 128))
  9030             {
  9031               next = last->next;
  9032               last->next = NULL;
  9033 
  9034               for (color_entry = next; color_entry; color_entry = last)
  9035                 {
  9036                   last = color_entry->next;
  9037 
  9038                   xfree (color_entry->name);
  9039                   xfree (color_entry);
  9040 
  9041                   dpyinfo->color_names_length[idx] -= 1;
  9042                 }
  9043 
  9044               return rc;
  9045             }
  9046         }
  9047     }
  9048 
  9049   return rc;
  9050 }
  9051 
  9052 
  9053 /* Allocate the color COLOR->pixel on DISPLAY, colormap CMAP.  If an
  9054    exact match can't be allocated, try the nearest color available.
  9055    Value is true if successful.  Set *COLOR to the color
  9056    allocated.  */
  9057 
  9058 static bool
  9059 x_alloc_nearest_color_1 (Display *dpy, Colormap cmap, XColor *color)
  9060 {
  9061   struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
  9062   bool rc;
  9063 
  9064   eassume (dpyinfo);
  9065   rc = XAllocColor (dpy, cmap, color) != 0;
  9066 
  9067   if (dpyinfo->visual_info.class == DirectColor)
  9068     return rc;
  9069 
  9070   if (rc == 0)
  9071     {
  9072       /* If we got to this point, the colormap is full, so we're going
  9073          to try and get the next closest color.  The algorithm used is
  9074          a least-squares matching, which is what X uses for closest
  9075          color matching with StaticColor visuals.  */
  9076 
  9077       const XColor *cells;
  9078       int no_cells;
  9079       int nearest;
  9080       long nearest_delta, trial_delta;
  9081       int x;
  9082       Status status;
  9083       bool retry = false;
  9084       int ncolor_cells, i;
  9085       bool temp_allocated;
  9086       XColor temp;
  9087 
  9088     start:
  9089       cells = x_color_cells (dpy, &no_cells);
  9090       temp_allocated = false;
  9091 
  9092       nearest = 0;
  9093       /* I'm assuming CSE so I'm not going to condense this. */
  9094       nearest_delta = ((((color->red >> 8) - (cells[0].red >> 8))
  9095                         * ((color->red >> 8) - (cells[0].red >> 8)))
  9096                        + (((color->green >> 8) - (cells[0].green >> 8))
  9097                           * ((color->green >> 8) - (cells[0].green >> 8)))
  9098                        + (((color->blue >> 8) - (cells[0].blue >> 8))
  9099                           * ((color->blue >> 8) - (cells[0].blue >> 8))));
  9100       for (x = 1; x < no_cells; x++)
  9101         {
  9102           trial_delta = ((((color->red >> 8) - (cells[x].red >> 8))
  9103                           * ((color->red >> 8) - (cells[x].red >> 8)))
  9104                          + (((color->green >> 8) - (cells[x].green >> 8))
  9105                             * ((color->green >> 8) - (cells[x].green >> 8)))
  9106                          + (((color->blue >> 8) - (cells[x].blue >> 8))
  9107                             * ((color->blue >> 8) - (cells[x].blue >> 8))));
  9108           if (trial_delta < nearest_delta)
  9109             {
  9110               /* We didn't decide to use this color, so free it.  */
  9111               if (temp_allocated)
  9112                 {
  9113                   XFreeColors (dpy, cmap, &temp.pixel, 1, 0);
  9114                   temp_allocated = false;
  9115                 }
  9116 
  9117               temp.red = cells[x].red;
  9118               temp.green = cells[x].green;
  9119               temp.blue = cells[x].blue;
  9120               status = XAllocColor (dpy, cmap, &temp);
  9121 
  9122               if (status)
  9123                 {
  9124                   temp_allocated = true;
  9125                   nearest = x;
  9126                   nearest_delta = trial_delta;
  9127                 }
  9128             }
  9129         }
  9130       color->red = cells[nearest].red;
  9131       color->green = cells[nearest].green;
  9132       color->blue = cells[nearest].blue;
  9133 
  9134       if (!temp_allocated)
  9135         status = XAllocColor (dpy, cmap, color);
  9136       else
  9137         {
  9138           *color = temp;
  9139           status = 1;
  9140         }
  9141 
  9142       if (status == 0 && !retry)
  9143         {
  9144           /* Our private cache of color cells is probably out of date.
  9145              Refresh it here, and try to allocate the nearest color
  9146              from the new colormap.  */
  9147 
  9148           retry = true;
  9149           xfree (dpyinfo->color_cells);
  9150 
  9151           ncolor_cells = dpyinfo->visual_info.colormap_size;
  9152 
  9153           dpyinfo->color_cells = xnmalloc (ncolor_cells,
  9154                                            sizeof *dpyinfo->color_cells);
  9155           dpyinfo->ncolor_cells = ncolor_cells;
  9156 
  9157           for (i = 0; i < ncolor_cells; ++i)
  9158             dpyinfo->color_cells[i].pixel = i;
  9159 
  9160           XQueryColors (dpy, dpyinfo->cmap,
  9161                         dpyinfo->color_cells, ncolor_cells);
  9162 
  9163           goto start;
  9164         }
  9165 
  9166       rc = status != 0;
  9167     }
  9168   else
  9169     {
  9170       /* If allocation succeeded, and the allocated pixel color is not
  9171          equal to a cached pixel color recorded earlier, there was a
  9172          change in the colormap, so clear the color cache.  */
  9173       struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
  9174       eassume (dpyinfo);
  9175 
  9176       if (dpyinfo->color_cells)
  9177         {
  9178           XColor *cached_color = &dpyinfo->color_cells[color->pixel];
  9179           if (cached_color->red != color->red
  9180               || cached_color->blue != color->blue
  9181               || cached_color->green != color->green)
  9182             {
  9183               xfree (dpyinfo->color_cells);
  9184               dpyinfo->color_cells = NULL;
  9185               dpyinfo->ncolor_cells = 0;
  9186             }
  9187         }
  9188     }
  9189 
  9190 #ifdef DEBUG_X_COLORS
  9191   if (rc)
  9192     register_color (color->pixel);
  9193 #endif /* DEBUG_X_COLORS */
  9194 
  9195   return rc;
  9196 }
  9197 
  9198 
  9199 /* Allocate the color COLOR->pixel on frame F, colormap CMAP, after
  9200    gamma correction.  If an exact match can't be allocated, try the
  9201    nearest color available.  Value is true if successful.  Set *COLOR
  9202    to the color allocated.  */
  9203 
  9204 bool
  9205 x_alloc_nearest_color (struct frame *f, Colormap cmap, XColor *color)
  9206 {
  9207   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  9208 
  9209   gamma_correct (f, color);
  9210 
  9211   if (dpyinfo->red_bits > 0)
  9212     {
  9213       color->pixel = x_make_truecolor_pixel (dpyinfo,
  9214                                              color->red,
  9215                                              color->green,
  9216                                              color->blue);
  9217       return true;
  9218     }
  9219 
  9220   return x_alloc_nearest_color_1 (FRAME_X_DISPLAY (f), cmap, color);
  9221 }
  9222 
  9223 
  9224 /* Allocate color PIXEL on frame F.  PIXEL must already be allocated.
  9225    It's necessary to do this instead of just using PIXEL directly to
  9226    get color reference counts right.  */
  9227 
  9228 unsigned long
  9229 x_copy_color (struct frame *f, unsigned long pixel)
  9230 {
  9231   XColor color;
  9232 
  9233   /* If display has an immutable color map, freeing colors is not
  9234      necessary and some servers don't allow it.  Since we won't free a
  9235      color once we've allocated it, we don't need to re-allocate it to
  9236      maintain the server's reference count.  */
  9237   if (!x_mutable_colormap (FRAME_X_VISUAL_INFO (f)))
  9238     return pixel;
  9239 
  9240   color.pixel = pixel;
  9241   block_input ();
  9242   /* The color could still be found in the color_cells array.  */
  9243   x_query_colors (f, &color, 1);
  9244   XAllocColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &color);
  9245   unblock_input ();
  9246 #ifdef DEBUG_X_COLORS
  9247   register_color (pixel);
  9248 #endif
  9249   return color.pixel;
  9250 }
  9251 
  9252 
  9253 /* Brightness beyond which a color won't have its highlight brightness
  9254    boosted.
  9255 
  9256    Nominally, highlight colors for `3d' faces are calculated by
  9257    brightening an object's color by a constant scale factor, but this
  9258    doesn't yield good results for dark colors, so for colors who's
  9259    brightness is less than this value (on a scale of 0-65535) have an
  9260    use an additional additive factor.
  9261 
  9262    The value here is set so that the default menu-bar/mode-line color
  9263    (grey75) will not have its highlights changed at all.  */
  9264 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 48000
  9265 
  9266 
  9267 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
  9268    or DELTA.  Try a color with RGB values multiplied by FACTOR first.
  9269    If this produces the same color as PIXEL, try a color where all RGB
  9270    values have DELTA added.  Return the allocated color in *PIXEL.
  9271    DISPLAY is the X display, CMAP is the colormap to operate on.
  9272    Value is non-zero if successful.  */
  9273 
  9274 static bool
  9275 x_alloc_lighter_color (struct frame *f, Display *display, Colormap cmap,
  9276                        unsigned long *pixel, double factor, int delta)
  9277 {
  9278   XColor color, new;
  9279   long bright;
  9280   bool success_p;
  9281 
  9282   /* Get RGB color values.  */
  9283   color.pixel = *pixel;
  9284   x_query_colors (f, &color, 1);
  9285 
  9286   /* Change RGB values by specified FACTOR.  Avoid overflow!  */
  9287   eassert (factor >= 0);
  9288   new.red = min (0xffff, factor * color.red);
  9289   new.green = min (0xffff, factor * color.green);
  9290   new.blue = min (0xffff, factor * color.blue);
  9291 
  9292   /* Calculate brightness of COLOR.  */
  9293   bright = (2 * color.red + 3 * color.green + color.blue) / 6;
  9294 
  9295   /* We only boost colors that are darker than
  9296      HIGHLIGHT_COLOR_DARK_BOOST_LIMIT.  */
  9297   if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
  9298     /* Make an additive adjustment to NEW, because it's dark enough so
  9299        that scaling by FACTOR alone isn't enough.  */
  9300     {
  9301       /* How far below the limit this color is (0 - 1, 1 being darker).  */
  9302       double dimness = 1 - (double) bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
  9303       /* The additive adjustment.  */
  9304       int min_delta = delta * dimness * factor / 2;
  9305 
  9306       if (factor < 1)
  9307         {
  9308           new.red =   max (0, new.red -   min_delta);
  9309           new.green = max (0, new.green - min_delta);
  9310           new.blue =  max (0, new.blue -  min_delta);
  9311         }
  9312       else
  9313         {
  9314           new.red =   min (0xffff, min_delta + new.red);
  9315           new.green = min (0xffff, min_delta + new.green);
  9316           new.blue =  min (0xffff, min_delta + new.blue);
  9317         }
  9318     }
  9319 
  9320   /* Try to allocate the color.  */
  9321   success_p = x_alloc_nearest_color (f, cmap, &new);
  9322   if (success_p)
  9323     {
  9324       if (new.pixel == *pixel)
  9325         {
  9326           /* If we end up with the same color as before, try adding
  9327              delta to the RGB values.  */
  9328           x_free_colors (f, &new.pixel, 1);
  9329 
  9330           new.red = min (0xffff, delta + color.red);
  9331           new.green = min (0xffff, delta + color.green);
  9332           new.blue = min (0xffff, delta + color.blue);
  9333           success_p = x_alloc_nearest_color (f, cmap, &new);
  9334         }
  9335       else
  9336         success_p = true;
  9337       *pixel = new.pixel;
  9338     }
  9339 
  9340   return success_p;
  9341 }
  9342 
  9343 
  9344 /* Set up the foreground color for drawing relief lines of glyph
  9345    string S.  RELIEF is a pointer to a struct relief containing the GC
  9346    with which lines will be drawn.  Use a color that is FACTOR or
  9347    DELTA lighter or darker than the relief's background which is found
  9348    in S->f->output_data.x->relief_background.  If such a color cannot
  9349    be allocated, use DEFAULT_PIXEL, instead.  */
  9350 
  9351 static void
  9352 x_setup_relief_color (struct frame *f, struct relief *relief, double factor,
  9353                       int delta, unsigned long default_pixel)
  9354 {
  9355   XGCValues xgcv;
  9356   struct x_output *di = f->output_data.x;
  9357   unsigned long mask = GCForeground | GCLineWidth | GCGraphicsExposures;
  9358   unsigned long pixel;
  9359   unsigned long background = di->relief_background;
  9360   Colormap cmap = FRAME_X_COLORMAP (f);
  9361   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  9362   Display *dpy = FRAME_X_DISPLAY (f);
  9363 
  9364   xgcv.graphics_exposures = False;
  9365   xgcv.line_width = 1;
  9366 
  9367   /* Free previously allocated color.  The color cell will be reused
  9368      when it has been freed as many times as it was allocated, so this
  9369      doesn't affect faces using the same colors.  */
  9370   if (relief->gc && relief->pixel != -1)
  9371     {
  9372       x_free_colors (f, &relief->pixel, 1);
  9373       relief->pixel = -1;
  9374     }
  9375 
  9376   /* Allocate new color.  */
  9377   xgcv.foreground = default_pixel;
  9378   pixel = background;
  9379   if (dpyinfo->n_planes != 1
  9380       && x_alloc_lighter_color (f, dpy, cmap, &pixel, factor, delta))
  9381     xgcv.foreground = relief->pixel = pixel;
  9382 
  9383   if (relief->gc == 0)
  9384     {
  9385       xgcv.stipple = dpyinfo->gray;
  9386       mask |= GCStipple;
  9387       relief->gc = XCreateGC (dpy, FRAME_X_DRAWABLE (f), mask, &xgcv);
  9388     }
  9389   else
  9390     XChangeGC (dpy, relief->gc, mask, &xgcv);
  9391 }
  9392 
  9393 
  9394 /* Set up colors for the relief lines around glyph string S.  */
  9395 
  9396 static void
  9397 x_setup_relief_colors (struct glyph_string *s)
  9398 {
  9399   struct x_output *di = s->f->output_data.x;
  9400   unsigned long color;
  9401 
  9402   if (s->face->use_box_color_for_shadows_p)
  9403     color = s->face->box_color;
  9404   else if (s->first_glyph->type == IMAGE_GLYPH
  9405            && s->img->pixmap
  9406            && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
  9407     color = IMAGE_BACKGROUND (s->img, s->f, 0);
  9408   else
  9409     {
  9410       XGCValues xgcv;
  9411 
  9412       /* Get the background color of the face.  */
  9413       XGetGCValues (FRAME_X_DISPLAY (s->f), s->gc, GCBackground, &xgcv);
  9414       color = xgcv.background;
  9415     }
  9416 
  9417   if (di->white_relief.gc == 0
  9418       || color != di->relief_background)
  9419     {
  9420       di->relief_background = color;
  9421       x_setup_relief_color (s->f, &di->white_relief, 1.2, 0x8000,
  9422                             WHITE_PIX_DEFAULT (s->f));
  9423       x_setup_relief_color (s->f, &di->black_relief, 0.6, 0x4000,
  9424                             BLACK_PIX_DEFAULT (s->f));
  9425     }
  9426 }
  9427 
  9428 #ifndef USE_CAIRO
  9429 static void
  9430 x_fill_triangle (struct frame *f, GC gc, XPoint point1,
  9431                  XPoint point2, XPoint point3)
  9432 {
  9433   XPoint abc[3];
  9434 
  9435   abc[0] = point1;
  9436   abc[1] = point2;
  9437   abc[2] = point3;
  9438 
  9439   XFillPolygon (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
  9440                 gc, abc, 3, Convex, CoordModeOrigin);
  9441 }
  9442 
  9443 static XPoint
  9444 x_make_point (int x, int y)
  9445 {
  9446   XPoint pt;
  9447 
  9448   pt.x = x;
  9449   pt.y = y;
  9450 
  9451   return pt;
  9452 }
  9453 
  9454 static bool
  9455 x_inside_rect_p (XRectangle *rects, int nrects, int x, int y)
  9456 {
  9457   int i;
  9458 
  9459   for (i = 0; i < nrects; ++i)
  9460     {
  9461       if (x >= rects[i].x && y >= rects[i].y
  9462           && x < rects[i].x + rects[i].width
  9463           && y < rects[i].y + rects[i].height)
  9464         return true;
  9465     }
  9466 
  9467   return false;
  9468 }
  9469 #endif
  9470 
  9471 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
  9472    TOP_Y, RIGHT_X, and BOTTOM_Y.  VWIDTH and HWIDTH are respectively
  9473    the thickness of the vertical relief (left and right) and
  9474    horizontal relief (top and bottom) to draw, it must be >= 0.
  9475    RAISED_P means draw a raised relief.  LEFT_P means draw a relief on
  9476    the left side of the rectangle.  RIGHT_P means draw a relief on the
  9477    right side of the rectangle.  CLIP_RECT is the clipping rectangle
  9478    to use when drawing.  */
  9479 
  9480 static void
  9481 x_draw_relief_rect (struct frame *f, int left_x, int top_y, int right_x,
  9482                     int bottom_y, int hwidth, int vwidth, bool raised_p,
  9483                     bool top_p, bool bot_p, bool left_p, bool right_p,
  9484                     XRectangle *clip_rect)
  9485 {
  9486 #ifdef USE_CAIRO
  9487   GC top_left_gc, bottom_right_gc;
  9488   int corners = 0;
  9489 
  9490   if (raised_p)
  9491     {
  9492       top_left_gc = f->output_data.x->white_relief.gc;
  9493       bottom_right_gc = f->output_data.x->black_relief.gc;
  9494     }
  9495   else
  9496     {
  9497       top_left_gc = f->output_data.x->black_relief.gc;
  9498       bottom_right_gc = f->output_data.x->white_relief.gc;
  9499     }
  9500 
  9501   x_set_clip_rectangles (f, top_left_gc, clip_rect, 1);
  9502   x_set_clip_rectangles (f, bottom_right_gc, clip_rect, 1);
  9503 
  9504   if (left_p)
  9505     {
  9506       x_fill_rectangle (f, top_left_gc, left_x, top_y,
  9507                         vwidth, bottom_y + 1 - top_y, false);
  9508       if (top_p)
  9509         corners |= 1 << CORNER_TOP_LEFT;
  9510       if (bot_p)
  9511         corners |= 1 << CORNER_BOTTOM_LEFT;
  9512     }
  9513   if (right_p)
  9514     {
  9515       x_fill_rectangle (f, bottom_right_gc, right_x + 1 - vwidth, top_y,
  9516                         vwidth, bottom_y + 1 - top_y, false);
  9517       if (top_p)
  9518         corners |= 1 << CORNER_TOP_RIGHT;
  9519       if (bot_p)
  9520         corners |= 1 << CORNER_BOTTOM_RIGHT;
  9521     }
  9522   if (top_p)
  9523     {
  9524       if (!right_p)
  9525         x_fill_rectangle (f, top_left_gc, left_x, top_y,
  9526                           right_x + 1 - left_x, hwidth, false);
  9527       else
  9528         x_fill_trapezoid_for_relief (f, top_left_gc, left_x, top_y,
  9529                                      right_x + 1 - left_x, hwidth, 1);
  9530     }
  9531   if (bot_p)
  9532     {
  9533       if (!left_p)
  9534         x_fill_rectangle (f, bottom_right_gc, left_x, bottom_y + 1 - hwidth,
  9535                           right_x + 1 - left_x, hwidth, false);
  9536       else
  9537         x_fill_trapezoid_for_relief (f, bottom_right_gc,
  9538                                      left_x, bottom_y + 1 - hwidth,
  9539                                      right_x + 1 - left_x, hwidth, 0);
  9540     }
  9541   if (left_p && vwidth > 1)
  9542     x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
  9543                       1, bottom_y + 1 - top_y, false);
  9544   if (top_p && hwidth > 1)
  9545     x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
  9546                       right_x + 1 - left_x, 1, false);
  9547   if (corners)
  9548     {
  9549       XSetBackground (FRAME_X_DISPLAY (f), top_left_gc,
  9550                       FRAME_BACKGROUND_PIXEL (f));
  9551       x_erase_corners_for_relief (f, top_left_gc, left_x, top_y,
  9552                                   right_x - left_x + 1, bottom_y - top_y + 1,
  9553                                   6, 1, corners);
  9554     }
  9555 
  9556   x_reset_clip_rectangles (f, top_left_gc);
  9557   x_reset_clip_rectangles (f, bottom_right_gc);
  9558 #else
  9559   GC gc, white_gc, black_gc, normal_gc;
  9560   Drawable drawable;
  9561   Display *dpy;
  9562 
  9563   /* This code is more complicated than it has to be, because of two
  9564      minor hacks to make the boxes look nicer: (i) if width > 1, draw
  9565      the outermost line using the black relief.  (ii) Omit the four
  9566      corner pixels.  */
  9567 
  9568   white_gc = f->output_data.x->white_relief.gc;
  9569   black_gc = f->output_data.x->black_relief.gc;
  9570   normal_gc = f->output_data.x->normal_gc;
  9571 
  9572   drawable = FRAME_X_DRAWABLE (f);
  9573   dpy = FRAME_X_DISPLAY (f);
  9574 
  9575   x_set_clip_rectangles (f, white_gc, clip_rect, 1);
  9576   x_set_clip_rectangles (f, black_gc, clip_rect, 1);
  9577 
  9578   if (raised_p)
  9579     gc = white_gc;
  9580   else
  9581     gc = black_gc;
  9582 
  9583   /* Draw lines.  */
  9584 
  9585   if (top_p)
  9586     x_fill_rectangle (f, gc, left_x, top_y,
  9587                       right_x - left_x + 1, hwidth,
  9588                       false);
  9589 
  9590   if (left_p)
  9591     x_fill_rectangle (f, gc, left_x, top_y, vwidth,
  9592                       bottom_y - top_y + 1, false);
  9593 
  9594   if (raised_p)
  9595     gc = black_gc;
  9596   else
  9597     gc = white_gc;
  9598 
  9599   if (bot_p)
  9600     x_fill_rectangle (f, gc, left_x, bottom_y - hwidth + 1,
  9601                       right_x - left_x + 1, hwidth, false);
  9602 
  9603   if (right_p)
  9604     x_fill_rectangle (f, gc, right_x - vwidth + 1, top_y,
  9605                       vwidth, bottom_y - top_y + 1, false);
  9606 
  9607   /* Draw corners.  */
  9608 
  9609   if (bot_p && left_p)
  9610     x_fill_triangle (f, raised_p ? white_gc : black_gc,
  9611                      x_make_point (left_x, bottom_y - hwidth),
  9612                      x_make_point (left_x + vwidth, bottom_y - hwidth),
  9613                      x_make_point (left_x, bottom_y));
  9614 
  9615   if (top_p && right_p)
  9616     x_fill_triangle (f, raised_p ? white_gc : black_gc,
  9617                      x_make_point (right_x - vwidth, top_y),
  9618                      x_make_point (right_x, top_y),
  9619                      x_make_point (right_x - vwidth, top_y + hwidth));
  9620 
  9621   /* Draw outer line.  */
  9622 
  9623   if (top_p && left_p && bot_p && right_p
  9624       && hwidth > 1 && vwidth > 1)
  9625     x_draw_rectangle (f, black_gc, left_x, top_y,
  9626                       right_x - left_x, bottom_y - top_y);
  9627   else
  9628     {
  9629       if (top_p && hwidth > 1)
  9630         XDrawLine (dpy, drawable, black_gc, left_x, top_y,
  9631                    right_x + 1, top_y);
  9632 
  9633       if (bot_p && hwidth > 1)
  9634         XDrawLine (dpy, drawable, black_gc, left_x, bottom_y,
  9635                    right_x + 1, bottom_y);
  9636 
  9637       if (left_p && vwidth > 1)
  9638         XDrawLine (dpy, drawable, black_gc, left_x, top_y,
  9639                    left_x, bottom_y + 1);
  9640 
  9641       if (right_p && vwidth > 1)
  9642         XDrawLine (dpy, drawable, black_gc, right_x, top_y,
  9643                    right_x, bottom_y + 1);
  9644     }
  9645 
  9646   /* Erase corners.  */
  9647 
  9648   if (hwidth > 1 && vwidth > 1)
  9649     {
  9650       if (left_p && top_p && x_inside_rect_p (clip_rect, 1,
  9651                                               left_x, top_y))
  9652         /* This should respect `alpha-background' since it's being
  9653            cleared with the background color of the frame.  */
  9654         x_clear_point (f, normal_gc, left_x, top_y, true);
  9655 
  9656       if (left_p && bot_p && x_inside_rect_p (clip_rect, 1,
  9657                                               left_x, bottom_y))
  9658         x_clear_point (f, normal_gc, left_x, bottom_y, true);
  9659 
  9660       if (right_p && top_p && x_inside_rect_p (clip_rect, 1,
  9661                                                right_x, top_y))
  9662         x_clear_point (f, normal_gc, right_x, top_y, true);
  9663 
  9664       if (right_p && bot_p && x_inside_rect_p (clip_rect, 1,
  9665                                                right_x, bottom_y))
  9666         x_clear_point (f, normal_gc, right_x, bottom_y, true);
  9667     }
  9668 
  9669   x_reset_clip_rectangles (f, white_gc);
  9670   x_reset_clip_rectangles (f, black_gc);
  9671 #endif
  9672 }
  9673 
  9674 
  9675 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
  9676    RIGHT_X, and BOTTOM_Y.  WIDTH is the thickness of the lines to
  9677    draw, it must be >= 0.  LEFT_P means draw a line on the
  9678    left side of the rectangle.  RIGHT_P means draw a line
  9679    on the right side of the rectangle.  CLIP_RECT is the clipping
  9680    rectangle to use when drawing.  */
  9681 
  9682 static void
  9683 x_draw_box_rect (struct glyph_string *s,
  9684                  int left_x, int top_y, int right_x, int bottom_y, int hwidth,
  9685                  int vwidth, bool left_p, bool right_p, XRectangle *clip_rect)
  9686 {
  9687   Display *display = FRAME_X_DISPLAY (s->f);
  9688   XGCValues xgcv;
  9689 
  9690   XGetGCValues (display, s->gc, GCForeground, &xgcv);
  9691   XSetForeground (display, s->gc, s->face->box_color);
  9692   x_set_clip_rectangles (s->f, s->gc, clip_rect, 1);
  9693 
  9694   /* Top.  */
  9695   x_fill_rectangle (s->f, s->gc,
  9696                     left_x, top_y, right_x - left_x + 1, hwidth,
  9697                     false);
  9698 
  9699   /* Left.  */
  9700   if (left_p)
  9701     x_fill_rectangle (s->f, s->gc,
  9702                       left_x, top_y, vwidth, bottom_y - top_y + 1,
  9703                       false);
  9704 
  9705   /* Bottom.  */
  9706   x_fill_rectangle (s->f, s->gc,
  9707                     left_x, bottom_y - hwidth + 1, right_x - left_x + 1, hwidth,
  9708                     false);
  9709 
  9710   /* Right.  */
  9711   if (right_p)
  9712     x_fill_rectangle (s->f, s->gc,
  9713                       right_x - vwidth + 1, top_y, vwidth, bottom_y - top_y + 1,
  9714                       false);
  9715 
  9716   XSetForeground (display, s->gc, xgcv.foreground);
  9717   x_reset_clip_rectangles (s->f, s->gc);
  9718 }
  9719 
  9720 
  9721 /* Draw a box around glyph string S.  */
  9722 
  9723 static void
  9724 x_draw_glyph_string_box (struct glyph_string *s)
  9725 {
  9726   int hwidth, vwidth, left_x, right_x, top_y, bottom_y, last_x;
  9727   bool raised_p, left_p, right_p;
  9728   struct glyph *last_glyph;
  9729   XRectangle clip_rect;
  9730 
  9731   last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
  9732             ? WINDOW_RIGHT_EDGE_X (s->w)
  9733             : window_box_right (s->w, s->area));
  9734 
  9735   /* The glyph that may have a right box line.  For static
  9736      compositions and images, the right-box flag is on the first glyph
  9737      of the glyph string; for other types it's on the last glyph.  */
  9738   if (s->cmp || s->img)
  9739     last_glyph = s->first_glyph;
  9740   else if (s->first_glyph->type == COMPOSITE_GLYPH
  9741            && s->first_glyph->u.cmp.automatic)
  9742     {
  9743       /* For automatic compositions, we need to look up the last glyph
  9744          in the composition.  */
  9745         struct glyph *end = s->row->glyphs[s->area] + s->row->used[s->area];
  9746         struct glyph *g = s->first_glyph;
  9747         for (last_glyph = g++;
  9748              g < end && g->u.cmp.automatic && g->u.cmp.id == s->cmp_id
  9749                && g->slice.cmp.to < s->cmp_to;
  9750              last_glyph = g++)
  9751           ;
  9752     }
  9753   else
  9754     last_glyph = s->first_glyph + s->nchars - 1;
  9755 
  9756   vwidth = eabs (s->face->box_vertical_line_width);
  9757   hwidth = eabs (s->face->box_horizontal_line_width);
  9758   raised_p = s->face->box == FACE_RAISED_BOX;
  9759   left_x = s->x;
  9760   right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
  9761              ? last_x - 1
  9762              : min (last_x, s->x + s->background_width) - 1);
  9763   top_y = s->y;
  9764   bottom_y = top_y + s->height - 1;
  9765 
  9766   left_p = (s->first_glyph->left_box_line_p
  9767             || (s->hl == DRAW_MOUSE_FACE
  9768                 && (s->prev == NULL
  9769                     || s->prev->hl != s->hl)));
  9770   right_p = (last_glyph->right_box_line_p
  9771              || (s->hl == DRAW_MOUSE_FACE
  9772                  && (s->next == NULL
  9773                      || s->next->hl != s->hl)));
  9774 
  9775   get_glyph_string_clip_rect (s, &clip_rect);
  9776 
  9777   if (s->face->box == FACE_SIMPLE_BOX)
  9778     x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, hwidth,
  9779                      vwidth, left_p, right_p, &clip_rect);
  9780   else
  9781     {
  9782       x_setup_relief_colors (s);
  9783       x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y, hwidth,
  9784                           vwidth, raised_p, true, true, left_p, right_p,
  9785                           &clip_rect);
  9786     }
  9787 }
  9788 
  9789 
  9790 #ifndef USE_CAIRO
  9791 
  9792 static void
  9793 x_composite_image (struct glyph_string *s, Pixmap dest,
  9794 #ifdef HAVE_XRENDER
  9795                    Picture destination,
  9796 #endif
  9797                    int srcX, int srcY, int dstX, int dstY,
  9798                    int width, int height)
  9799 {
  9800   Display *display;
  9801 #ifdef HAVE_XRENDER
  9802   XRenderPictFormat *default_format;
  9803   XRenderPictureAttributes attr UNINIT;
  9804 #endif
  9805 
  9806   display = FRAME_X_DISPLAY (s->f);
  9807 
  9808 #ifdef HAVE_XRENDER
  9809   if (s->img->picture && FRAME_X_PICTURE_FORMAT (s->f))
  9810     {
  9811       if (destination == None)
  9812         {
  9813           /* The destination picture was not specified.  This means we
  9814              have to create a picture representing the */
  9815           default_format = FRAME_X_PICTURE_FORMAT (s->f);
  9816           destination = XRenderCreatePicture (display, dest,
  9817                                               default_format, 0, &attr);
  9818 
  9819           XRenderComposite (display, (s->img->mask_picture
  9820                                       ? PictOpOver : PictOpSrc),
  9821                             s->img->picture, s->img->mask_picture,
  9822                             destination, srcX, srcY, srcX, srcY,
  9823                             dstX, dstY, width, height);
  9824 
  9825           XRenderFreePicture (display, destination);
  9826         }
  9827       else
  9828         XRenderComposite (display, (s->img->mask_picture
  9829                                     ? PictOpOver : PictOpSrc),
  9830                           s->img->picture, s->img->mask_picture,
  9831                           destination, srcX, srcY, srcX, srcY,
  9832                           dstX, dstY, width, height);
  9833 
  9834       return;
  9835     }
  9836 #endif
  9837 
  9838   XCopyArea (display, s->img->pixmap,
  9839              dest, s->gc,
  9840              srcX, srcY,
  9841              width, height, dstX, dstY);
  9842 }
  9843 
  9844 #endif  /* !USE_CAIRO */
  9845 
  9846 
  9847 /* Draw foreground of image glyph string S.  */
  9848 
  9849 static void
  9850 x_draw_image_foreground (struct glyph_string *s)
  9851 {
  9852   int x = s->x;
  9853   int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
  9854 
  9855   /* If first glyph of S has a left box line, start drawing it to the
  9856      right of that line.  */
  9857   if (s->face->box != FACE_NO_BOX
  9858       && s->first_glyph->left_box_line_p
  9859       && s->slice.x == 0)
  9860     x += max (s->face->box_vertical_line_width, 0);
  9861 
  9862   /* If there is a margin around the image, adjust x- and y-position
  9863      by that margin.  */
  9864   if (s->slice.x == 0)
  9865     x += s->img->hmargin;
  9866   if (s->slice.y == 0)
  9867     y += s->img->vmargin;
  9868 
  9869 #ifdef USE_CAIRO
  9870   if (s->img->cr_data)
  9871     {
  9872       x_set_glyph_string_clipping (s);
  9873       x_cr_draw_image (s->f, s->gc, s->img->cr_data,
  9874                        s->slice.x, s->slice.y, s->slice.width, s->slice.height,
  9875                        x, y, true);
  9876       if (!s->img->mask)
  9877         {
  9878           /* When the image has a mask, we can expect that at
  9879              least part of a mouse highlight or a block cursor will
  9880              be visible.  If the image doesn't have a mask, make
  9881              a block cursor visible by drawing a rectangle around
  9882              the image.  I believe it's looking better if we do
  9883              nothing here for mouse-face.  */
  9884           if (s->hl == DRAW_CURSOR)
  9885             {
  9886               int relief = eabs (s->img->relief);
  9887               x_draw_rectangle (s->f, s->gc, x - relief, y - relief,
  9888                                 s->slice.width + relief*2 - 1,
  9889                                 s->slice.height + relief*2 - 1);
  9890             }
  9891         }
  9892     }
  9893 #else  /* ! USE_CAIRO */
  9894   if (s->img->pixmap)
  9895     {
  9896       if (s->img->mask)
  9897         {
  9898           /* We can't set both a clip mask and use XSetClipRectangles
  9899              because the latter also sets a clip mask.  We also can't
  9900              trust on the shape extension to be available
  9901              (XShapeCombineRegion).  So, compute the rectangle to draw
  9902              manually.  */
  9903           /* FIXME: Do we need to do this when using XRender compositing?  */
  9904           unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
  9905                                 | GCFunction);
  9906           XGCValues xgcv;
  9907           XRectangle clip_rect, image_rect, r;
  9908 
  9909           xgcv.clip_mask = s->img->mask;
  9910           xgcv.clip_x_origin = x;
  9911           xgcv.clip_y_origin = y;
  9912           xgcv.function = GXcopy;
  9913           XChangeGC (FRAME_X_DISPLAY (s->f), s->gc, mask, &xgcv);
  9914 
  9915           get_glyph_string_clip_rect (s, &clip_rect);
  9916           image_rect.x = x;
  9917           image_rect.y = y;
  9918           image_rect.width = s->slice.width;
  9919           image_rect.height = s->slice.height;
  9920           if (gui_intersect_rectangles (&clip_rect, &image_rect, &r))
  9921             x_composite_image (s, FRAME_X_DRAWABLE (s->f),
  9922 #ifdef HAVE_XRENDER
  9923                                FRAME_X_PICTURE (s->f),
  9924 #endif
  9925                                s->slice.x + r.x - x, s->slice.y + r.y - y,
  9926                                r.x, r.y, r.width, r.height);
  9927         }
  9928       else
  9929         {
  9930           XRectangle clip_rect, image_rect, r;
  9931 
  9932           get_glyph_string_clip_rect (s, &clip_rect);
  9933           image_rect.x = x;
  9934           image_rect.y = y;
  9935           image_rect.width = s->slice.width;
  9936           image_rect.height = s->slice.height;
  9937           if (gui_intersect_rectangles (&clip_rect, &image_rect, &r))
  9938             x_composite_image (s, FRAME_X_DRAWABLE (s->f),
  9939 #ifdef HAVE_XRENDER
  9940                                FRAME_X_PICTURE (s->f),
  9941 #endif
  9942                                s->slice.x + r.x - x,
  9943                                s->slice.y + r.y - y,
  9944                                r.x, r.y, r.width, r.height);
  9945 
  9946           /* When the image has a mask, we can expect that at
  9947              least part of a mouse highlight or a block cursor will
  9948              be visible.  If the image doesn't have a mask, make
  9949              a block cursor visible by drawing a rectangle around
  9950              the image.  I believe it's looking better if we do
  9951              nothing here for mouse-face.  */
  9952           if (s->hl == DRAW_CURSOR)
  9953             {
  9954               int relief = eabs (s->img->relief);
  9955               x_draw_rectangle (s->f, s->gc,
  9956                               x - relief, y - relief,
  9957                               s->slice.width + relief*2 - 1,
  9958                               s->slice.height + relief*2 - 1);
  9959             }
  9960         }
  9961     }
  9962 #endif  /* ! USE_CAIRO */
  9963   else
  9964     /* Draw a rectangle if image could not be loaded.  */
  9965     x_draw_rectangle (s->f, s->gc, x, y,
  9966                     s->slice.width - 1, s->slice.height - 1);
  9967 }
  9968 
  9969 
  9970 /* Draw a relief around the image glyph string S.  */
  9971 
  9972 static void
  9973 x_draw_image_relief (struct glyph_string *s)
  9974 {
  9975   int x1, y1, thick;
  9976   bool raised_p, top_p, bot_p, left_p, right_p;
  9977   int extra_x, extra_y;
  9978   XRectangle r;
  9979   int x = s->x;
  9980   int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
  9981 
  9982   /* If first glyph of S has a left box line, start drawing it to the
  9983      right of that line.  */
  9984   if (s->face->box != FACE_NO_BOX
  9985       && s->first_glyph->left_box_line_p
  9986       && s->slice.x == 0)
  9987     x += max (s->face->box_vertical_line_width, 0);
  9988 
  9989   /* If there is a margin around the image, adjust x- and y-position
  9990      by that margin.  */
  9991   if (s->slice.x == 0)
  9992     x += s->img->hmargin;
  9993   if (s->slice.y == 0)
  9994     y += s->img->vmargin;
  9995 
  9996   if (s->hl == DRAW_IMAGE_SUNKEN
  9997       || s->hl == DRAW_IMAGE_RAISED)
  9998     {
  9999       if (s->face->id == TAB_BAR_FACE_ID)
 10000         thick = (tab_bar_button_relief < 0
 10001                  ? DEFAULT_TAB_BAR_BUTTON_RELIEF
 10002                  : min (tab_bar_button_relief, 1000000));
 10003       else
 10004         thick = (tool_bar_button_relief < 0
 10005                  ? DEFAULT_TOOL_BAR_BUTTON_RELIEF
 10006                  : min (tool_bar_button_relief, 1000000));
 10007       raised_p = s->hl == DRAW_IMAGE_RAISED;
 10008     }
 10009   else
 10010     {
 10011       thick = eabs (s->img->relief);
 10012       raised_p = s->img->relief > 0;
 10013     }
 10014 
 10015   x1 = x + s->slice.width - 1;
 10016   y1 = y + s->slice.height - 1;
 10017 
 10018   extra_x = extra_y = 0;
 10019   if (s->face->id == TAB_BAR_FACE_ID)
 10020     {
 10021       if (CONSP (Vtab_bar_button_margin)
 10022           && FIXNUMP (XCAR (Vtab_bar_button_margin))
 10023           && FIXNUMP (XCDR (Vtab_bar_button_margin)))
 10024         {
 10025           extra_x = XFIXNUM (XCAR (Vtab_bar_button_margin)) - thick;
 10026           extra_y = XFIXNUM (XCDR (Vtab_bar_button_margin)) - thick;
 10027         }
 10028       else if (FIXNUMP (Vtab_bar_button_margin))
 10029         extra_x = extra_y = XFIXNUM (Vtab_bar_button_margin) - thick;
 10030     }
 10031 
 10032   if (s->face->id == TOOL_BAR_FACE_ID)
 10033     {
 10034       if (CONSP (Vtool_bar_button_margin)
 10035           && FIXNUMP (XCAR (Vtool_bar_button_margin))
 10036           && FIXNUMP (XCDR (Vtool_bar_button_margin)))
 10037         {
 10038           extra_x = XFIXNUM (XCAR (Vtool_bar_button_margin));
 10039           extra_y = XFIXNUM (XCDR (Vtool_bar_button_margin));
 10040         }
 10041       else if (FIXNUMP (Vtool_bar_button_margin))
 10042         extra_x = extra_y = XFIXNUM (Vtool_bar_button_margin);
 10043     }
 10044 
 10045   top_p = bot_p = left_p = right_p = false;
 10046 
 10047   if (s->slice.x == 0)
 10048     x -= thick + extra_x, left_p = true;
 10049   if (s->slice.y == 0)
 10050     y -= thick + extra_y, top_p = true;
 10051   if (s->slice.x + s->slice.width == s->img->width)
 10052     x1 += thick + extra_x, right_p = true;
 10053   if (s->slice.y + s->slice.height == s->img->height)
 10054     y1 += thick + extra_y, bot_p = true;
 10055 
 10056   x_setup_relief_colors (s);
 10057   get_glyph_string_clip_rect (s, &r);
 10058   x_draw_relief_rect (s->f, x, y, x1, y1, thick, thick, raised_p,
 10059                       top_p, bot_p, left_p, right_p, &r);
 10060 }
 10061 
 10062 
 10063 #ifndef USE_CAIRO
 10064 /* Draw the foreground of image glyph string S to PIXMAP.  */
 10065 
 10066 static void
 10067 x_draw_image_foreground_1 (struct glyph_string *s, Pixmap pixmap)
 10068 {
 10069   int x = 0;
 10070   int y = s->ybase - s->y - image_ascent (s->img, s->face, &s->slice);
 10071 
 10072   /* If first glyph of S has a left box line, start drawing it to the
 10073      right of that line.  */
 10074   if (s->face->box != FACE_NO_BOX
 10075       && s->first_glyph->left_box_line_p
 10076       && s->slice.x == 0)
 10077     x += max (s->face->box_vertical_line_width, 0);
 10078 
 10079   /* If there is a margin around the image, adjust x- and y-position
 10080      by that margin.  */
 10081   if (s->slice.x == 0)
 10082     x += s->img->hmargin;
 10083   if (s->slice.y == 0)
 10084     y += s->img->vmargin;
 10085 
 10086   if (s->img->pixmap)
 10087     {
 10088       Display *display = FRAME_X_DISPLAY (s->f);
 10089 
 10090       if (s->img->mask)
 10091         {
 10092           /* We can't set both a clip mask and use XSetClipRectangles
 10093              because the latter also sets a clip mask.  We also can't
 10094              trust on the shape extension to be available
 10095              (XShapeCombineRegion).  So, compute the rectangle to draw
 10096              manually.  */
 10097           /* FIXME: Do we need to do this when using XRender compositing?  */
 10098           unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
 10099                                 | GCFunction);
 10100           XGCValues xgcv;
 10101 
 10102           xgcv.clip_mask = s->img->mask;
 10103           xgcv.clip_x_origin = x - s->slice.x;
 10104           xgcv.clip_y_origin = y - s->slice.y;
 10105           xgcv.function = GXcopy;
 10106           XChangeGC (display, s->gc, mask, &xgcv);
 10107 
 10108           x_composite_image (s, pixmap,
 10109 #ifdef HAVE_XRENDER
 10110                              None,
 10111 #endif
 10112                              s->slice.x, s->slice.y, x, y,
 10113                              s->slice.width, s->slice.height);
 10114           XSetClipMask (display, s->gc, None);
 10115         }
 10116       else
 10117         {
 10118           XCopyArea (display, s->img->pixmap, pixmap, s->gc,
 10119                      s->slice.x, s->slice.y,
 10120                      s->slice.width, s->slice.height, x, y);
 10121 
 10122           /* When the image has a mask, we can expect that at
 10123              least part of a mouse highlight or a block cursor will
 10124              be visible.  If the image doesn't have a mask, make
 10125              a block cursor visible by drawing a rectangle around
 10126              the image.  I believe it's looking better if we do
 10127              nothing here for mouse-face.  */
 10128           if (s->hl == DRAW_CURSOR)
 10129             {
 10130               int r = eabs (s->img->relief);
 10131               x_draw_rectangle (s->f, s->gc, x - r, y - r,
 10132                               s->slice.width + r*2 - 1,
 10133                               s->slice.height + r*2 - 1);
 10134             }
 10135         }
 10136     }
 10137   else
 10138     /* Draw a rectangle if image could not be loaded.  */
 10139     x_draw_rectangle (s->f, s->gc, x, y,
 10140                     s->slice.width - 1, s->slice.height - 1);
 10141 }
 10142 #endif  /* ! USE_CAIRO */
 10143 
 10144 
 10145 /* Draw part of the background of glyph string S.  X, Y, W, and H
 10146    give the rectangle to draw.  */
 10147 
 10148 static void
 10149 x_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h)
 10150 {
 10151   if (s->stippled_p)
 10152     {
 10153       Display *display = FRAME_X_DISPLAY (s->f);
 10154 
 10155       /* Fill background with a stipple pattern.  */
 10156       XSetFillStyle (display, s->gc, FillOpaqueStippled);
 10157       x_fill_rectangle (s->f, s->gc, x, y, w, h, true);
 10158       XSetFillStyle (display, s->gc, FillSolid);
 10159     }
 10160   else
 10161     x_clear_glyph_string_rect (s, x, y, w, h);
 10162 }
 10163 
 10164 
 10165 /* Draw image glyph string S.
 10166 
 10167             s->y
 10168    s->x      +-------------------------
 10169              |   s->face->box
 10170              |
 10171              |     +-------------------------
 10172              |     |  s->img->margin
 10173              |     |
 10174              |     |       +-------------------
 10175              |     |       |  the image
 10176 
 10177  */
 10178 
 10179 static void
 10180 x_draw_image_glyph_string (struct glyph_string *s)
 10181 {
 10182   int box_line_hwidth = max (s->face->box_vertical_line_width, 0);
 10183   int box_line_vwidth = max (s->face->box_horizontal_line_width, 0);
 10184   int height;
 10185 #ifndef USE_CAIRO
 10186   Display *display = FRAME_X_DISPLAY (s->f);
 10187   Pixmap pixmap = None;
 10188 #endif
 10189 
 10190   height = s->height;
 10191   if (s->slice.y == 0)
 10192     height -= box_line_vwidth;
 10193   if (s->slice.y + s->slice.height >= s->img->height)
 10194     height -= box_line_vwidth;
 10195 
 10196   /* Fill background with face under the image.  Do it only if row is
 10197      taller than image or if image has a clip mask to reduce
 10198      flickering.  */
 10199   s->stippled_p = s->face->stipple != 0;
 10200   if (height > s->slice.height
 10201       || s->img->hmargin
 10202       || s->img->vmargin
 10203       || s->img->mask
 10204       || s->img->pixmap == 0
 10205       || s->width != s->background_width)
 10206     {
 10207       if (s->stippled_p)
 10208         s->row->stipple_p = true;
 10209 
 10210 #ifndef USE_CAIRO
 10211       if (s->img->mask)
 10212         {
 10213           /* Create a pixmap as large as the glyph string.  Fill it
 10214              with the background color.  Copy the image to it, using
 10215              its mask.  Copy the temporary pixmap to the display.  */
 10216           int depth = FRAME_DISPLAY_INFO (s->f)->n_planes;
 10217 
 10218           /* Create a pixmap as large as the glyph string.  */
 10219           pixmap = XCreatePixmap (display, FRAME_X_DRAWABLE (s->f),
 10220                                   s->background_width,
 10221                                   s->height, depth);
 10222 
 10223           /* Don't clip in the following because we're working on the
 10224              pixmap.  */
 10225           XSetClipMask (display, s->gc, None);
 10226 
 10227           /* Fill the pixmap with the background color/stipple.  */
 10228           if (s->stippled_p)
 10229             {
 10230               /* Fill background with a stipple pattern.  */
 10231               XSetFillStyle (display, s->gc, FillOpaqueStippled);
 10232               XSetTSOrigin (display, s->gc, - s->x, - s->y);
 10233               XFillRectangle (display, pixmap, s->gc,
 10234                               0, 0, s->background_width, s->height);
 10235               XSetFillStyle (display, s->gc, FillSolid);
 10236               XSetTSOrigin (display, s->gc, 0, 0);
 10237             }
 10238           else
 10239             {
 10240               XGCValues xgcv;
 10241 #if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2))
 10242               if (FRAME_DISPLAY_INFO (s->f)->alpha_bits
 10243                   && s->f->alpha_background != 1.0
 10244                   && FRAME_CHECK_XR_VERSION (s->f, 0, 2)
 10245                   && FRAME_X_PICTURE_FORMAT (s->f))
 10246                 {
 10247                   XRenderColor xc;
 10248                   XRenderPictureAttributes attrs;
 10249                   Picture pict;
 10250                   memset (&attrs, 0, sizeof attrs);
 10251 
 10252                   pict = XRenderCreatePicture (display, pixmap,
 10253                                                FRAME_X_PICTURE_FORMAT (s->f),
 10254                                                0, &attrs);
 10255                   x_xrender_color_from_gc_background (s->f, s->gc, &xc, true);
 10256                   XRenderFillRectangle (FRAME_X_DISPLAY (s->f), PictOpSrc, pict,
 10257                                         &xc, 0, 0, s->background_width, s->height);
 10258                   XRenderFreePicture (display, pict);
 10259                 }
 10260               else
 10261 #endif
 10262                 {
 10263                   XGetGCValues (display, s->gc, GCForeground | GCBackground,
 10264                                 &xgcv);
 10265                   XSetForeground (display, s->gc, xgcv.background);
 10266                   XFillRectangle (display, pixmap, s->gc,
 10267                                   0, 0, s->background_width, s->height);
 10268                   XSetForeground (display, s->gc, xgcv.foreground);
 10269                 }
 10270             }
 10271         }
 10272       else
 10273 #endif  /* ! USE_CAIRO */
 10274         {
 10275           int x = s->x;
 10276           int y = s->y;
 10277           int width = s->background_width;
 10278 
 10279           if (s->first_glyph->left_box_line_p
 10280               && s->slice.x == 0)
 10281             {
 10282               x += box_line_hwidth;
 10283               width -= box_line_hwidth;
 10284             }
 10285 
 10286           if (s->slice.y == 0)
 10287             y += box_line_vwidth;
 10288 
 10289           x_draw_glyph_string_bg_rect (s, x, y, width, height);
 10290         }
 10291 
 10292       s->background_filled_p = true;
 10293     }
 10294 
 10295   /* Draw the foreground.  */
 10296 #ifndef USE_CAIRO
 10297   if (pixmap != None)
 10298     {
 10299       x_draw_image_foreground_1 (s, pixmap);
 10300       x_set_glyph_string_clipping (s);
 10301       XCopyArea (display, pixmap, FRAME_X_DRAWABLE (s->f), s->gc,
 10302                  0, 0, s->background_width, s->height, s->x, s->y);
 10303       XFreePixmap (display, pixmap);
 10304     }
 10305   else
 10306 #endif  /* ! USE_CAIRO */
 10307     x_draw_image_foreground (s);
 10308 
 10309   /* If we must draw a relief around the image, do it.  */
 10310   if (s->img->relief
 10311       || s->hl == DRAW_IMAGE_RAISED
 10312       || s->hl == DRAW_IMAGE_SUNKEN)
 10313     x_draw_image_relief (s);
 10314 }
 10315 
 10316 
 10317 /* Draw stretch glyph string S.  */
 10318 
 10319 static void
 10320 x_draw_stretch_glyph_string (struct glyph_string *s)
 10321 {
 10322   eassert (s->first_glyph->type == STRETCH_GLYPH);
 10323 
 10324   if (s->hl == DRAW_CURSOR
 10325       && !x_stretch_cursor_p)
 10326     {
 10327       /* If `x-stretch-cursor' is nil, don't draw a block cursor as
 10328          wide as the stretch glyph.  */
 10329       int width, background_width = s->background_width;
 10330       int x = s->x;
 10331 
 10332       if (!s->row->reversed_p)
 10333         {
 10334           int left_x = window_box_left_offset (s->w, TEXT_AREA);
 10335 
 10336           if (x < left_x)
 10337             {
 10338               background_width -= left_x - x;
 10339               x = left_x;
 10340             }
 10341         }
 10342       else
 10343         {
 10344           /* In R2L rows, draw the cursor on the right edge of the
 10345              stretch glyph.  */
 10346           int right_x = window_box_right (s->w, TEXT_AREA);
 10347 
 10348           if (x + background_width > right_x)
 10349             background_width -= x - right_x;
 10350           x += background_width;
 10351         }
 10352       width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
 10353       if (s->row->reversed_p)
 10354         x -= width;
 10355 
 10356       /* Draw cursor.  */
 10357       x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
 10358 
 10359       /* Clear rest using the GC of the original non-cursor face.  */
 10360       if (width < background_width)
 10361         {
 10362           int y = s->y;
 10363           int w = background_width - width, h = s->height;
 10364           Display *display = FRAME_X_DISPLAY (s->f);
 10365           XRectangle r;
 10366           GC gc;
 10367 
 10368           if (!s->row->reversed_p)
 10369             x += width;
 10370           else
 10371             x = s->x;
 10372           if (s->row->mouse_face_p
 10373               && cursor_in_mouse_face_p (s->w))
 10374             {
 10375               x_set_mouse_face_gc (s);
 10376               gc = s->gc;
 10377             }
 10378           else
 10379             gc = s->face->gc;
 10380 
 10381           get_glyph_string_clip_rect (s, &r);
 10382           x_set_clip_rectangles (s->f, gc, &r, 1);
 10383 
 10384           if (s->face->stipple)
 10385             {
 10386               /* Fill background with a stipple pattern.  */
 10387               XSetFillStyle (display, gc, FillOpaqueStippled);
 10388               x_fill_rectangle (s->f, gc, x, y, w, h, true);
 10389               XSetFillStyle (display, gc, FillSolid);
 10390 
 10391               s->row->stipple_p = true;
 10392             }
 10393           else
 10394             {
 10395               XGCValues xgcv;
 10396               XGetGCValues (display, gc, GCForeground | GCBackground, &xgcv);
 10397               XSetForeground (display, gc, xgcv.background);
 10398               x_fill_rectangle (s->f, gc, x, y, w, h, true);
 10399               XSetForeground (display, gc, xgcv.foreground);
 10400             }
 10401 
 10402           x_reset_clip_rectangles (s->f, gc);
 10403         }
 10404     }
 10405   else if (!s->background_filled_p)
 10406     {
 10407       int background_width = s->background_width;
 10408       int x = s->x, text_left_x = window_box_left (s->w, TEXT_AREA);
 10409 
 10410       /* Don't draw into left fringe or scrollbar area except for
 10411          header line and mode line.  */
 10412       if (s->area == TEXT_AREA
 10413           && x < text_left_x && !s->row->mode_line_p)
 10414         {
 10415           background_width -= text_left_x - x;
 10416           x = text_left_x;
 10417         }
 10418 
 10419       if (!s->row->stipple_p)
 10420         s->row->stipple_p = s->stippled_p;
 10421 
 10422       if (background_width > 0)
 10423         x_draw_glyph_string_bg_rect (s, x, s->y,
 10424                                      background_width, s->height);
 10425     }
 10426 
 10427   s->background_filled_p = true;
 10428 }
 10429 
 10430 static void
 10431 x_get_scale_factor (Display *disp, int *scale_x, int *scale_y)
 10432 {
 10433   const int base_res = 96;
 10434   struct x_display_info * dpyinfo = x_display_info_for_display (disp);
 10435 
 10436   *scale_x = *scale_y = 1;
 10437 
 10438   if (dpyinfo)
 10439     {
 10440       if (dpyinfo->resx > base_res)
 10441         *scale_x = floor (dpyinfo->resx / base_res);
 10442       if (dpyinfo->resy > base_res)
 10443         *scale_y = floor (dpyinfo->resy / base_res);
 10444     }
 10445 }
 10446 
 10447 /*
 10448    Draw a wavy line under S. The wave fills wave_height pixels from y0.
 10449 
 10450                     x0         wave_length = 2
 10451                                  --
 10452                 y0   *   *   *   *   *
 10453                      |* * * * * * * * *
 10454     wave_height = 3  | *   *   *   *
 10455 
 10456 */
 10457 static void
 10458 x_draw_underwave (struct glyph_string *s, int decoration_width)
 10459 {
 10460   Display *display = FRAME_X_DISPLAY (s->f);
 10461 
 10462   /* Adjust for scale/HiDPI.  */
 10463   int scale_x, scale_y;
 10464 
 10465   x_get_scale_factor (display, &scale_x, &scale_y);
 10466 
 10467   int wave_height = 3 * scale_y, wave_length = 2 * scale_x;
 10468 
 10469 #ifdef USE_CAIRO
 10470   x_draw_horizontal_wave (s->f, s->gc, s->x, s->ybase - wave_height + 3,
 10471                           decoration_width, wave_height, wave_length);
 10472 #else  /* not USE_CAIRO */
 10473   int dx, dy, x0, y0, width, x1, y1, x2, y2, xmax, thickness = scale_y;;
 10474   bool odd;
 10475   XRectangle wave_clip, string_clip, final_clip;
 10476 
 10477   dx = wave_length;
 10478   dy = wave_height - 1;
 10479   x0 = s->x;
 10480   y0 = s->ybase + wave_height / 2 - scale_y;
 10481   width = decoration_width;
 10482   xmax = x0 + width;
 10483 
 10484   /* Find and set clipping rectangle */
 10485 
 10486   wave_clip.x = x0;
 10487   wave_clip.y = y0;
 10488   wave_clip.width = width;
 10489   wave_clip.height = wave_height;
 10490   get_glyph_string_clip_rect (s, &string_clip);
 10491 
 10492   if (!gui_intersect_rectangles (&wave_clip, &string_clip, &final_clip))
 10493     return;
 10494 
 10495   XSetClipRectangles (display, s->gc, 0, 0, &final_clip, 1, Unsorted);
 10496 
 10497   /* Draw the waves */
 10498 
 10499   x1 = x0 - (x0 % dx);
 10500   x2 = x1 + dx;
 10501   odd = (x1 / dx) & 1;
 10502   y1 = y2 = y0;
 10503 
 10504   if (odd)
 10505     y1 += dy;
 10506   else
 10507     y2 += dy;
 10508 
 10509   if (INT_MAX - dx < xmax)
 10510     emacs_abort ();
 10511 
 10512   while (x1 <= xmax)
 10513     {
 10514       XSetLineAttributes (display, s->gc, thickness, LineSolid, CapButt,
 10515                           JoinRound);
 10516       XDrawLine (display, FRAME_X_DRAWABLE (s->f), s->gc, x1, y1, x2, y2);
 10517       x1  = x2, y1 = y2;
 10518       x2 += dx, y2 = y0 + odd*dy;
 10519       odd = !odd;
 10520     }
 10521 
 10522   /* Restore previous clipping rectangle(s) */
 10523   XSetClipRectangles (display, s->gc, 0, 0, s->clip, s->num_clips, Unsorted);
 10524 #endif  /* not USE_CAIRO */
 10525 }
 10526 
 10527 
 10528 /* Draw glyph string S.  */
 10529 
 10530 static void
 10531 x_draw_glyph_string (struct glyph_string *s)
 10532 {
 10533   bool relief_drawn_p = false;
 10534 
 10535   /* If S draws into the background of its successors, draw the
 10536      background of the successors first so that S can draw into it.
 10537      This makes S->next use XDrawString instead of XDrawImageString.  */
 10538   if (s->next && s->right_overhang && !s->for_overlaps)
 10539     {
 10540       int width;
 10541       struct glyph_string *next;
 10542 
 10543       for (width = 0, next = s->next;
 10544            next && width < s->right_overhang;
 10545            width += next->width, next = next->next)
 10546         if (next->first_glyph->type != IMAGE_GLYPH)
 10547           {
 10548             x_set_glyph_string_gc (next);
 10549             x_set_glyph_string_clipping (next);
 10550             if (next->first_glyph->type == STRETCH_GLYPH)
 10551               x_draw_stretch_glyph_string (next);
 10552             else
 10553               x_draw_glyph_string_background (next, true);
 10554             next->num_clips = 0;
 10555           }
 10556     }
 10557 
 10558   /* Set up S->gc, set clipping and draw S.  */
 10559   x_set_glyph_string_gc (s);
 10560 
 10561   /* Draw relief (if any) in advance for char/composition so that the
 10562      glyph string can be drawn over it.  */
 10563   if (!s->for_overlaps
 10564       && s->face->box != FACE_NO_BOX
 10565       && (s->first_glyph->type == CHAR_GLYPH
 10566           || s->first_glyph->type == COMPOSITE_GLYPH))
 10567 
 10568     {
 10569       x_set_glyph_string_clipping (s);
 10570       x_draw_glyph_string_background (s, true);
 10571       x_draw_glyph_string_box (s);
 10572       x_set_glyph_string_clipping (s);
 10573       relief_drawn_p = true;
 10574     }
 10575   else if (!s->clip_head /* draw_glyphs didn't specify a clip mask. */
 10576            && !s->clip_tail
 10577            && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
 10578                || (s->next && s->next->hl != s->hl && s->right_overhang)))
 10579     /* We must clip just this glyph.  left_overhang part has already
 10580        drawn when s->prev was drawn, and right_overhang part will be
 10581        drawn later when s->next is drawn. */
 10582     x_set_glyph_string_clipping_exactly (s, s);
 10583   else
 10584     x_set_glyph_string_clipping (s);
 10585 
 10586   switch (s->first_glyph->type)
 10587     {
 10588     case IMAGE_GLYPH:
 10589       x_draw_image_glyph_string (s);
 10590       break;
 10591 
 10592     case XWIDGET_GLYPH:
 10593       x_draw_xwidget_glyph_string (s);
 10594       break;
 10595 
 10596     case STRETCH_GLYPH:
 10597       x_draw_stretch_glyph_string (s);
 10598       break;
 10599 
 10600     case CHAR_GLYPH:
 10601       if (s->for_overlaps)
 10602         s->background_filled_p = true;
 10603       else
 10604         x_draw_glyph_string_background (s, false);
 10605       x_draw_glyph_string_foreground (s);
 10606       break;
 10607 
 10608     case COMPOSITE_GLYPH:
 10609       if (s->for_overlaps || (s->cmp_from > 0
 10610                               && ! s->first_glyph->u.cmp.automatic))
 10611         s->background_filled_p = true;
 10612       else
 10613         x_draw_glyph_string_background (s, true);
 10614       x_draw_composite_glyph_string_foreground (s);
 10615       break;
 10616 
 10617     case GLYPHLESS_GLYPH:
 10618       if (s->for_overlaps)
 10619         s->background_filled_p = true;
 10620       else
 10621         x_draw_glyph_string_background (s, true);
 10622       x_draw_glyphless_glyph_string_foreground (s);
 10623       break;
 10624 
 10625     default:
 10626       emacs_abort ();
 10627     }
 10628 
 10629   if (!s->for_overlaps)
 10630     {
 10631       int area_x, area_y, area_width, area_height;
 10632       int area_max_x, decoration_width;
 10633 
 10634       /* Prevent the underline from overwriting surrounding areas
 10635          and the fringe.  */
 10636       window_box (s->w, s->area, &area_x, &area_y,
 10637                   &area_width, &area_height);
 10638       area_max_x = area_x + area_width - 1;
 10639 
 10640       decoration_width = s->width;
 10641       if (!s->row->mode_line_p
 10642           && !s->row->tab_line_p
 10643           && area_max_x < (s->x + decoration_width - 1))
 10644         decoration_width -= (s->x + decoration_width - 1) - area_max_x;
 10645 
 10646       /* Draw relief if not yet drawn.  */
 10647       if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
 10648         x_draw_glyph_string_box (s);
 10649 
 10650       /* Draw underline.  */
 10651       if (s->face->underline)
 10652         {
 10653           if (s->face->underline == FACE_UNDER_WAVE)
 10654             {
 10655               if (s->face->underline_defaulted_p)
 10656                 x_draw_underwave (s, decoration_width);
 10657               else
 10658                 {
 10659                   Display *display = FRAME_X_DISPLAY (s->f);
 10660                   XGCValues xgcv;
 10661                   XGetGCValues (display, s->gc, GCForeground, &xgcv);
 10662                   XSetForeground (display, s->gc, s->face->underline_color);
 10663                   x_draw_underwave (s, decoration_width);
 10664                   XSetForeground (display, s->gc, xgcv.foreground);
 10665                 }
 10666             }
 10667           else if (s->face->underline == FACE_UNDER_LINE)
 10668             {
 10669               unsigned long thickness, position;
 10670               int y;
 10671 
 10672               if (s->prev
 10673                   && s->prev->face->underline == FACE_UNDER_LINE
 10674                   && (s->prev->face->underline_at_descent_line_p
 10675                       == s->face->underline_at_descent_line_p)
 10676                   && (s->prev->face->underline_pixels_above_descent_line
 10677                       == s->face->underline_pixels_above_descent_line))
 10678                 {
 10679                   /* We use the same underline style as the previous one.  */
 10680                   thickness = s->prev->underline_thickness;
 10681                   position = s->prev->underline_position;
 10682                 }
 10683               else
 10684                 {
 10685                   struct font *font = font_for_underline_metrics (s);
 10686                   unsigned long minimum_offset;
 10687                   bool underline_at_descent_line;
 10688                   bool use_underline_position_properties;
 10689                   Lisp_Object val = (WINDOW_BUFFER_LOCAL_VALUE
 10690                                      (Qunderline_minimum_offset, s->w));
 10691 
 10692                   if (FIXNUMP (val))
 10693                     minimum_offset = max (0, XFIXNUM (val));
 10694                   else
 10695                     minimum_offset = 1;
 10696 
 10697                   val = (WINDOW_BUFFER_LOCAL_VALUE
 10698                          (Qx_underline_at_descent_line, s->w));
 10699                   underline_at_descent_line
 10700                     = (!(NILP (val) || BASE_EQ (val, Qunbound))
 10701                        || s->face->underline_at_descent_line_p);
 10702 
 10703                   val = (WINDOW_BUFFER_LOCAL_VALUE
 10704                          (Qx_use_underline_position_properties, s->w));
 10705                   use_underline_position_properties
 10706                     = !(NILP (val) || BASE_EQ (val, Qunbound));
 10707 
 10708                   /* Get the underline thickness.  Default is 1 pixel.  */
 10709                   if (font && font->underline_thickness > 0)
 10710                     thickness = font->underline_thickness;
 10711                   else
 10712                     thickness = 1;
 10713                   if (underline_at_descent_line)
 10714                     position = ((s->height - thickness)
 10715                                 - (s->ybase - s->y)
 10716                                 - s->face->underline_pixels_above_descent_line);
 10717                   else
 10718                     {
 10719                       /* Get the underline position.  This is the
 10720                          recommended vertical offset in pixels from
 10721                          the baseline to the top of the underline.
 10722                          This is a signed value according to the
 10723                          specs, and its default is
 10724 
 10725                          ROUND ((maximum descent) / 2), with
 10726                          ROUND(x) = floor (x + 0.5)  */
 10727 
 10728                       if (use_underline_position_properties
 10729                           && font && font->underline_position >= 0)
 10730                         position = font->underline_position;
 10731                       else if (font)
 10732                         position = (font->descent + 1) / 2;
 10733                       else
 10734                         position = minimum_offset;
 10735                     }
 10736 
 10737                   /* Ignore minimum_offset if the amount of pixels was
 10738                      explicitly specified.  */
 10739                   if (!s->face->underline_pixels_above_descent_line)
 10740                     position = max (position, minimum_offset);
 10741                 }
 10742               /* Check the sanity of thickness and position.  We should
 10743                  avoid drawing underline out of the current line area.  */
 10744               if (s->y + s->height <= s->ybase + position)
 10745                 position = (s->height - 1) - (s->ybase - s->y);
 10746               if (s->y + s->height < s->ybase + position + thickness)
 10747                 thickness = (s->y + s->height) - (s->ybase + position);
 10748               s->underline_thickness = thickness;
 10749               s->underline_position = position;
 10750               y = s->ybase + position;
 10751               if (s->face->underline_defaulted_p)
 10752                 x_fill_rectangle (s->f, s->gc,
 10753                                   s->x, y, decoration_width, thickness,
 10754                                   false);
 10755               else
 10756                 {
 10757                   Display *display = FRAME_X_DISPLAY (s->f);
 10758                   XGCValues xgcv;
 10759                   XGetGCValues (display, s->gc, GCForeground, &xgcv);
 10760                   XSetForeground (display, s->gc, s->face->underline_color);
 10761                   x_fill_rectangle (s->f, s->gc,
 10762                                     s->x, y, decoration_width, thickness,
 10763                                     false);
 10764                   XSetForeground (display, s->gc, xgcv.foreground);
 10765                 }
 10766             }
 10767         }
 10768       /* Draw overline.  */
 10769       if (s->face->overline_p)
 10770         {
 10771           unsigned long dy = 0, h = 1;
 10772 
 10773           if (s->face->overline_color_defaulted_p)
 10774             x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
 10775                               decoration_width, h, false);
 10776           else
 10777             {
 10778               Display *display = FRAME_X_DISPLAY (s->f);
 10779               XGCValues xgcv;
 10780               XGetGCValues (display, s->gc, GCForeground, &xgcv);
 10781               XSetForeground (display, s->gc, s->face->overline_color);
 10782               x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
 10783                                 decoration_width, h, false);
 10784               XSetForeground (display, s->gc, xgcv.foreground);
 10785             }
 10786         }
 10787 
 10788       /* Draw strike-through.  */
 10789       if (s->face->strike_through_p)
 10790         {
 10791           /* Y-coordinate and height of the glyph string's first
 10792              glyph.  We cannot use s->y and s->height because those
 10793              could be larger if there are taller display elements
 10794              (e.g., characters displayed with a larger font) in the
 10795              same glyph row.  */
 10796           int glyph_y = s->ybase - s->first_glyph->ascent;
 10797           int glyph_height = s->first_glyph->ascent + s->first_glyph->descent;
 10798           /* Strike-through width and offset from the glyph string's
 10799              top edge.  */
 10800           unsigned long h = 1;
 10801           unsigned long dy = (glyph_height - h) / 2;
 10802 
 10803           if (s->face->strike_through_color_defaulted_p)
 10804             x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy,
 10805                               s->width, h, false);
 10806           else
 10807             {
 10808               Display *display = FRAME_X_DISPLAY (s->f);
 10809               XGCValues xgcv;
 10810               XGetGCValues (display, s->gc, GCForeground, &xgcv);
 10811               XSetForeground (display, s->gc, s->face->strike_through_color);
 10812               x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy,
 10813                                 decoration_width, h, false);
 10814               XSetForeground (display, s->gc, xgcv.foreground);
 10815             }
 10816         }
 10817 
 10818       if (s->prev)
 10819         {
 10820           struct glyph_string *prev;
 10821 
 10822           for (prev = s->prev; prev; prev = prev->prev)
 10823             if (prev->hl != s->hl
 10824                 && prev->x + prev->width + prev->right_overhang > s->x)
 10825               {
 10826                 /* As prev was drawn while clipped to its own area, we
 10827                    must draw the right_overhang part using s->hl now.  */
 10828                 enum draw_glyphs_face save = prev->hl;
 10829 
 10830                 prev->hl = s->hl;
 10831                 x_set_glyph_string_gc (prev);
 10832                 x_set_glyph_string_clipping_exactly (s, prev);
 10833                 if (prev->first_glyph->type == CHAR_GLYPH)
 10834                   x_draw_glyph_string_foreground (prev);
 10835                 else
 10836                   x_draw_composite_glyph_string_foreground (prev);
 10837                 x_reset_clip_rectangles (prev->f, prev->gc);
 10838                 prev->hl = save;
 10839                 prev->num_clips = 0;
 10840               }
 10841         }
 10842 
 10843       if (s->next)
 10844         {
 10845           struct glyph_string *next;
 10846 
 10847           for (next = s->next; next; next = next->next)
 10848             if (next->hl != s->hl
 10849                 && next->x - next->left_overhang < s->x + s->width)
 10850               {
 10851                 /* As next will be drawn while clipped to its own area,
 10852                    we must draw the left_overhang part using s->hl now.  */
 10853                 enum draw_glyphs_face save = next->hl;
 10854 
 10855                 next->hl = s->hl;
 10856                 x_set_glyph_string_gc (next);
 10857                 x_set_glyph_string_clipping_exactly (s, next);
 10858                 if (next->first_glyph->type == CHAR_GLYPH)
 10859                   x_draw_glyph_string_foreground (next);
 10860                 else
 10861                   x_draw_composite_glyph_string_foreground (next);
 10862                 x_reset_clip_rectangles (next->f, next->gc);
 10863                 next->hl = save;
 10864                 next->num_clips = 0;
 10865                 next->clip_head = s->next;
 10866               }
 10867         }
 10868     }
 10869 
 10870   /* Reset clipping.  */
 10871   x_reset_clip_rectangles (s->f, s->gc);
 10872   s->num_clips = 0;
 10873 
 10874   /* Set the stippled flag that tells redisplay whether or not a
 10875      stipple was actually draw.  */
 10876 
 10877   if (s->first_glyph->type != STRETCH_GLYPH
 10878       && s->first_glyph->type != IMAGE_GLYPH
 10879       && !s->row->stipple_p)
 10880     s->row->stipple_p = s->stippled_p;
 10881 }
 10882 
 10883 /* Shift display to make room for inserted glyphs.   */
 10884 
 10885 static void
 10886 x_shift_glyphs_for_insert (struct frame *f, int x, int y, int width, int height, int shift_by)
 10887 {
 10888 /* Never called on a GUI frame, see
 10889    https://lists.gnu.org/r/emacs-devel/2015-05/msg00456.html
 10890 */
 10891   XCopyArea (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f),
 10892              f->output_data.x->normal_gc,
 10893              x, y, width, height,
 10894              x + shift_by, y);
 10895 }
 10896 
 10897 /* Delete N glyphs at the nominal cursor position.  Not implemented
 10898    for X frames.  */
 10899 
 10900 static void
 10901 x_delete_glyphs (struct frame *f, int n)
 10902 {
 10903   emacs_abort ();
 10904 }
 10905 
 10906 
 10907 /* Like XClearArea, but check that WIDTH and HEIGHT are reasonable.
 10908    If they are <= 0, this is probably an error.  */
 10909 
 10910 #if defined USE_GTK || !defined USE_CAIRO
 10911 static void
 10912 x_clear_area1 (Display *dpy, Window window,
 10913                int x, int y, int width, int height, int exposures)
 10914 {
 10915   eassert (width > 0 && height > 0);
 10916   XClearArea (dpy, window, x, y, width, height, exposures);
 10917 }
 10918 #endif
 10919 
 10920 void
 10921 x_clear_area (struct frame *f, int x, int y, int width, int height)
 10922 {
 10923 #ifdef USE_CAIRO
 10924   cairo_t *cr;
 10925 
 10926   eassert (width > 0 && height > 0);
 10927 
 10928   cr = x_begin_cr_clip (f, NULL);
 10929   x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc,
 10930                                       true);
 10931   cairo_rectangle (cr, x, y, width, height);
 10932   cairo_fill (cr);
 10933   x_end_cr_clip (f);
 10934 #else
 10935 #ifndef USE_GTK
 10936   if (f->alpha_background != 1.0
 10937 #ifdef HAVE_XDBE
 10938       || FRAME_X_DOUBLE_BUFFERED_P (f)
 10939 #endif
 10940       )
 10941 #endif
 10942     {
 10943 #if defined HAVE_XRENDER && \
 10944   (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2))
 10945       x_xr_ensure_picture (f);
 10946       if (FRAME_DISPLAY_INFO (f)->alpha_bits
 10947           && FRAME_X_PICTURE (f) != None
 10948           && f->alpha_background != 1.0
 10949           && FRAME_CHECK_XR_VERSION (f, 0, 2))
 10950         {
 10951           XRenderColor xc;
 10952           GC gc = f->output_data.x->normal_gc;
 10953 
 10954           x_xr_apply_ext_clip (f, gc);
 10955           x_xrender_color_from_gc_background (f, gc, &xc, true);
 10956           XRenderFillRectangle (FRAME_X_DISPLAY (f),
 10957                                 PictOpSrc, FRAME_X_PICTURE (f),
 10958                                 &xc, x, y, width, height);
 10959           x_xr_reset_ext_clip (f);
 10960           x_mark_frame_dirty (f);
 10961         }
 10962       else
 10963 #endif
 10964         XFillRectangle (FRAME_X_DISPLAY (f),
 10965                         FRAME_X_DRAWABLE (f),
 10966                         f->output_data.x->reverse_gc,
 10967                         x, y, width, height);
 10968     }
 10969 #ifndef USE_GTK
 10970   else
 10971     x_clear_area1 (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 10972                    x, y, width, height, False);
 10973 #endif
 10974 #endif
 10975 }
 10976 
 10977 
 10978 /* Clear an entire frame.  */
 10979 
 10980 static void
 10981 x_clear_frame (struct frame *f)
 10982 {
 10983   /* Clearing the frame will erase any cursor, so mark them all as no
 10984      longer visible.  */
 10985   mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
 10986 
 10987   block_input ();
 10988   font_drop_xrender_surfaces (f);
 10989   x_clear_window (f);
 10990 
 10991   /* We have to clear the scroll bars.  If we have changed colors or
 10992      something like that, then they should be notified.  */
 10993   x_scroll_bar_clear (f);
 10994 
 10995   unblock_input ();
 10996 }
 10997 
 10998 /* RIF: Show hourglass cursor on frame F.  */
 10999 
 11000 static void
 11001 x_show_hourglass (struct frame *f)
 11002 {
 11003   Display *dpy = FRAME_X_DISPLAY (f);
 11004 
 11005   if (dpy)
 11006     {
 11007       struct x_output *x = FRAME_X_OUTPUT (f);
 11008 
 11009       /* If the hourglass window is mapped inside a popup menu, input
 11010          could be lost if the menu is popped down and the grab is
 11011          relinquished, but the hourglass window is still up.  Just
 11012          avoid displaying the hourglass at all while popups are
 11013          active.  */
 11014 
 11015       if (popup_activated ())
 11016         return;
 11017 
 11018 #ifdef USE_X_TOOLKIT
 11019       if (x->widget)
 11020 #else
 11021       if (FRAME_OUTER_WINDOW (f))
 11022 #endif
 11023        {
 11024          x->hourglass_p = true;
 11025 
 11026          if (!x->hourglass_window)
 11027            {
 11028 #ifndef USE_XCB
 11029              unsigned long mask = CWCursor;
 11030              XSetWindowAttributes attrs;
 11031 #ifdef USE_GTK
 11032              Window parent = FRAME_X_WINDOW (f);
 11033 #else
 11034              Window parent = FRAME_OUTER_WINDOW (f);
 11035 #endif
 11036              attrs.cursor = x->hourglass_cursor;
 11037 
 11038              x->hourglass_window = XCreateWindow
 11039                (dpy, parent, 0, 0, 32000, 32000, 0, 0,
 11040                 InputOnly, CopyFromParent, mask, &attrs);
 11041 #else
 11042              uint32_t cursor = (uint32_t) x->hourglass_cursor;
 11043 #ifdef USE_GTK
 11044              xcb_window_t parent = (xcb_window_t) FRAME_X_WINDOW (f);
 11045 #else
 11046              xcb_window_t parent = (xcb_window_t) FRAME_OUTER_WINDOW (f);
 11047 #endif
 11048              x->hourglass_window
 11049                = (Window) xcb_generate_id (FRAME_DISPLAY_INFO (f)->xcb_connection);
 11050 
 11051              xcb_create_window (FRAME_DISPLAY_INFO (f)->xcb_connection,
 11052                                 XCB_COPY_FROM_PARENT,
 11053                                 (xcb_window_t) x->hourglass_window,
 11054                                 parent, 0, 0, FRAME_PIXEL_WIDTH (f),
 11055                                 FRAME_PIXEL_HEIGHT (f), 0,
 11056                                 XCB_WINDOW_CLASS_INPUT_ONLY,
 11057                                 XCB_COPY_FROM_PARENT, XCB_CW_CURSOR,
 11058                                 &cursor);
 11059 #endif
 11060            }
 11061 
 11062 #ifndef USE_XCB
 11063          XMapRaised (dpy, x->hourglass_window);
 11064          /* Ensure that the spinning hourglass is shown.  */
 11065          flush_frame (f);
 11066 #else
 11067          uint32_t value = XCB_STACK_MODE_ABOVE;
 11068 
 11069          xcb_configure_window (FRAME_DISPLAY_INFO (f)->xcb_connection,
 11070                                (xcb_window_t) x->hourglass_window,
 11071                                XCB_CONFIG_WINDOW_STACK_MODE, &value);
 11072          xcb_map_window (FRAME_DISPLAY_INFO (f)->xcb_connection,
 11073                          (xcb_window_t) x->hourglass_window);
 11074          xcb_flush (FRAME_DISPLAY_INFO (f)->xcb_connection);
 11075 #endif
 11076        }
 11077     }
 11078 }
 11079 
 11080 /* RIF: Cancel hourglass cursor on frame F.  */
 11081 
 11082 static void
 11083 x_hide_hourglass (struct frame *f)
 11084 {
 11085   struct x_output *x = FRAME_X_OUTPUT (f);
 11086 
 11087   /* Watch out for newly created frames.  */
 11088   if (x->hourglass_window)
 11089     {
 11090 #ifndef USE_XCB
 11091       XUnmapWindow (FRAME_X_DISPLAY (f), x->hourglass_window);
 11092       /* Sync here because XTread_socket looks at the
 11093          hourglass_p flag that is reset to zero below.  */
 11094       XSync (FRAME_X_DISPLAY (f), False);
 11095 #else
 11096       xcb_unmap_window (FRAME_DISPLAY_INFO (f)->xcb_connection,
 11097                         (xcb_window_t) x->hourglass_window);
 11098       xcb_aux_sync (FRAME_DISPLAY_INFO (f)->xcb_connection);
 11099 #endif
 11100       x->hourglass_p = false;
 11101     }
 11102 }
 11103 
 11104 /* Invert the middle quarter of the frame for .15 sec.  */
 11105 
 11106 static void
 11107 XTflash (struct frame *f)
 11108 {
 11109   GC gc;
 11110   XGCValues values;
 11111   fd_set fds;
 11112   int fd, rc;
 11113 
 11114   block_input ();
 11115 
 11116   if (FRAME_X_VISUAL_INFO (f)->class == TrueColor)
 11117     {
 11118       values.function = GXxor;
 11119       values.foreground = (FRAME_FOREGROUND_PIXEL (f)
 11120                            ^ FRAME_BACKGROUND_PIXEL (f));
 11121 
 11122       gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 11123                       GCFunction | GCForeground, &values);
 11124     }
 11125   else
 11126     gc = FRAME_X_OUTPUT (f)->normal_gc;
 11127 
 11128 
 11129   /* Get the height not including a menu bar widget.  */
 11130   int height = FRAME_PIXEL_HEIGHT (f);
 11131   /* Height of each line to flash.  */
 11132   int flash_height = FRAME_LINE_HEIGHT (f);
 11133   /* These will be the left and right margins of the rectangles.  */
 11134   int flash_left = FRAME_INTERNAL_BORDER_WIDTH (f);
 11135   int flash_right = FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f);
 11136   int width = flash_right - flash_left;
 11137 
 11138   /* If window is tall, flash top and bottom line.  */
 11139   if (height > 3 * FRAME_LINE_HEIGHT (f))
 11140     {
 11141       XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
 11142                       flash_left,
 11143                       (FRAME_INTERNAL_BORDER_WIDTH (f)
 11144                        + FRAME_TOP_MARGIN_HEIGHT (f)),
 11145                       width, flash_height);
 11146       XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
 11147                       flash_left,
 11148                       (height - flash_height
 11149                        - FRAME_INTERNAL_BORDER_WIDTH (f)),
 11150                       width, flash_height);
 11151 
 11152     }
 11153   else
 11154     /* If it is short, flash it all.  */
 11155     XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
 11156                     flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
 11157                     width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
 11158 
 11159   x_flush (f);
 11160 
 11161   struct timespec delay = make_timespec (0, 150 * 1000 * 1000);
 11162   struct timespec wakeup = timespec_add (current_timespec (), delay);
 11163   fd = ConnectionNumber (FRAME_X_DISPLAY (f));
 11164 
 11165   /* Keep waiting until past the time wakeup or any input gets
 11166      available.  */
 11167   while (! detect_input_pending ())
 11168     {
 11169       struct timespec current = current_timespec ();
 11170       struct timespec timeout;
 11171 
 11172       /* Break if result would not be positive.  */
 11173       if (timespec_cmp (wakeup, current) <= 0)
 11174         break;
 11175 
 11176       /* How long `select' should wait.  */
 11177       timeout = make_timespec (0, 10 * 1000 * 1000);
 11178 
 11179       /* Wait for some input to become available on the X
 11180          connection.  */
 11181       FD_ZERO (&fds);
 11182       FD_SET (fd, &fds);
 11183 
 11184       /* Try to wait that long--but we might wake up sooner.  */
 11185       rc = pselect (fd + 1, &fds, NULL, NULL, &timeout, NULL);
 11186 
 11187       /* Some input is available, exit the visible bell.  */
 11188       if (rc >= 0 && FD_ISSET (fd, &fds))
 11189         break;
 11190     }
 11191 
 11192   /* If window is tall, flash top and bottom line.  */
 11193   if (height > 3 * FRAME_LINE_HEIGHT (f))
 11194     {
 11195       XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
 11196                       flash_left,
 11197                       (FRAME_INTERNAL_BORDER_WIDTH (f)
 11198                        + FRAME_TOP_MARGIN_HEIGHT (f)),
 11199                       width, flash_height);
 11200       XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
 11201                       flash_left,
 11202                       (height - flash_height
 11203                        - FRAME_INTERNAL_BORDER_WIDTH (f)),
 11204                       width, flash_height);
 11205     }
 11206   else
 11207     /* If it is short, flash it all.  */
 11208     XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
 11209                     flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
 11210                     width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
 11211 
 11212   if (FRAME_X_VISUAL_INFO (f)->class == TrueColor)
 11213     XFreeGC (FRAME_X_DISPLAY (f), gc);
 11214   x_flush (f);
 11215 
 11216   unblock_input ();
 11217 }
 11218 
 11219 /* Make audible bell.  */
 11220 
 11221 static void
 11222 XTring_bell (struct frame *f)
 11223 {
 11224   if (FRAME_X_DISPLAY (f))
 11225     {
 11226       if (visible_bell)
 11227         XTflash (f);
 11228       else
 11229         {
 11230           block_input ();
 11231 #ifdef HAVE_XKB
 11232           XkbBell (FRAME_X_DISPLAY (f), None, 0, None);
 11233 #else
 11234           XBell (FRAME_X_DISPLAY (f), 0);
 11235 #endif
 11236           XFlush (FRAME_X_DISPLAY (f));
 11237           unblock_input ();
 11238         }
 11239     }
 11240 }
 11241 
 11242 /***********************************************************************
 11243                               Line Dance
 11244  ***********************************************************************/
 11245 
 11246 /* Perform an insert-lines or delete-lines operation, inserting N
 11247    lines or deleting -N lines at vertical position VPOS.  */
 11248 
 11249 static void
 11250 x_ins_del_lines (struct frame *f, int vpos, int n)
 11251 {
 11252   emacs_abort ();
 11253 }
 11254 
 11255 
 11256 /* Scroll part of the display as described by RUN.  */
 11257 
 11258 static void
 11259 x_scroll_run (struct window *w, struct run *run)
 11260 {
 11261   struct frame *f = XFRAME (w->frame);
 11262   int x, y, width, height, from_y, to_y, bottom_y;
 11263 
 11264   /* Get frame-relative bounding box of the text display area of W,
 11265      without mode lines.  Include in this box the left and right
 11266      fringe of W.  */
 11267   window_box (w, ANY_AREA, &x, &y, &width, &height);
 11268 
 11269   from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
 11270   to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
 11271   bottom_y = y + height;
 11272 
 11273   if (to_y < from_y)
 11274     {
 11275       /* Scrolling up.  Make sure we don't copy part of the mode
 11276          line at the bottom.  */
 11277       if (from_y + run->height > bottom_y)
 11278         height = bottom_y - from_y;
 11279       else
 11280         height = run->height;
 11281     }
 11282   else
 11283     {
 11284       /* Scrolling down.  Make sure we don't copy over the mode line.
 11285          at the bottom.  */
 11286       if (to_y + run->height > bottom_y)
 11287         height = bottom_y - to_y;
 11288       else
 11289         height = run->height;
 11290     }
 11291 
 11292   block_input ();
 11293 
 11294   /* Cursor off.  Will be switched on again in gui_update_window_end.  */
 11295   gui_clear_cursor (w);
 11296 
 11297 #ifdef HAVE_XWIDGETS
 11298   /* "Copy" xwidget windows in the area that will be scrolled.  */
 11299   Display *dpy = FRAME_X_DISPLAY (f);
 11300   Window window = FRAME_X_WINDOW (f);
 11301 
 11302   Window root, parent, *children;
 11303   unsigned int nchildren;
 11304 
 11305   if (XQueryTree (dpy, window, &root, &parent, &children, &nchildren))
 11306     {
 11307       /* Now find xwidget views situated between from_y and to_y, and
 11308          attached to w.  */
 11309       for (unsigned int i = 0; i < nchildren; ++i)
 11310         {
 11311           Window child = children[i];
 11312           struct xwidget_view *view = xwidget_view_from_window (child);
 11313 
 11314           if (view && !view->hidden)
 11315             {
 11316               int window_y = view->y + view->clip_top;
 11317               int window_height = view->clip_bottom - view->clip_top;
 11318 
 11319               Emacs_Rectangle r1, r2, result;
 11320               r1.x = w->pixel_left;
 11321               r1.y = from_y;
 11322               r1.width = w->pixel_width;
 11323               r1.height = height;
 11324               r2 = r1;
 11325               r2.y = window_y;
 11326               r2.height = window_height;
 11327 
 11328               /* The window is offscreen, just unmap it.  */
 11329               if (window_height == 0)
 11330                 {
 11331                   view->hidden = true;
 11332                   XUnmapWindow (dpy, child);
 11333                   continue;
 11334                 }
 11335 
 11336               bool intersects_p =
 11337                 gui_intersect_rectangles (&r1, &r2, &result);
 11338 
 11339               if (XWINDOW (view->w) == w && intersects_p)
 11340                 {
 11341                   int y = view->y + (to_y - from_y);
 11342                   int text_area_x, text_area_y, text_area_width, text_area_height;
 11343                   int clip_top, clip_bottom;
 11344 
 11345                   window_box (w, view->area, &text_area_x, &text_area_y,
 11346                               &text_area_width, &text_area_height);
 11347 
 11348                   view->y = y;
 11349 
 11350                   clip_top = 0;
 11351                   clip_bottom = XXWIDGET (view->model)->height;
 11352 
 11353                   if (y < text_area_y)
 11354                     clip_top = text_area_y - y;
 11355 
 11356                   if ((y + clip_bottom) > (text_area_y + text_area_height))
 11357                     {
 11358                       clip_bottom -= (y + clip_bottom) - (text_area_y + text_area_height);
 11359                     }
 11360 
 11361                   view->clip_top = clip_top;
 11362                   view->clip_bottom = clip_bottom;
 11363 
 11364                   /* This means the view has moved offscreen.  Unmap
 11365                      it and hide it here.  */
 11366                   if ((view->clip_bottom - view->clip_top) <= 0)
 11367                     {
 11368                       view->hidden = true;
 11369                       XUnmapWindow (dpy, child);
 11370                     }
 11371                   else
 11372                     {
 11373                       XMoveResizeWindow (dpy, child, view->x + view->clip_left,
 11374                                          view->y + view->clip_top,
 11375                                          view->clip_right - view->clip_left,
 11376                                          view->clip_bottom - view->clip_top);
 11377                       cairo_xlib_surface_set_size (view->cr_surface,
 11378                                                    view->clip_right - view->clip_left,
 11379                                                    view->clip_bottom - view->clip_top);
 11380                     }
 11381                   xwidget_expose (view);
 11382                 }
 11383             }
 11384         }
 11385       XFree (children);
 11386     }
 11387 #endif
 11388 
 11389 #ifdef USE_CAIRO_XCB_SURFACE
 11390   /* Some of the following code depends on `normal_gc' being
 11391      up-to-date on the X server, but doesn't call a routine that will
 11392      flush it first.  So do this ourselves instead.  */
 11393   XFlushGC (FRAME_X_DISPLAY (f),
 11394             f->output_data.x->normal_gc);
 11395 #endif
 11396 
 11397 #ifdef USE_CAIRO
 11398   if (FRAME_CR_CONTEXT (f))
 11399     {
 11400       cairo_surface_t *surface = cairo_get_target (FRAME_CR_CONTEXT (f));
 11401       if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_XLIB)
 11402         {
 11403           eassert (cairo_xlib_surface_get_display (surface)
 11404                    == FRAME_X_DISPLAY (f));
 11405           eassert (cairo_xlib_surface_get_drawable (surface)
 11406                    == FRAME_X_RAW_DRAWABLE (f));
 11407           cairo_surface_flush (surface);
 11408           XCopyArea (FRAME_X_DISPLAY (f),
 11409                      FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f),
 11410                      f->output_data.x->normal_gc,
 11411                      x, from_y,
 11412                      width, height,
 11413                      x, to_y);
 11414           cairo_surface_mark_dirty_rectangle (surface, x, to_y, width, height);
 11415         }
 11416 #ifdef USE_CAIRO_XCB_SURFACE
 11417       else if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_XCB)
 11418         {
 11419           cairo_surface_flush (surface);
 11420           xcb_copy_area (FRAME_DISPLAY_INFO (f)->xcb_connection,
 11421                          (xcb_drawable_t) FRAME_X_DRAWABLE (f),
 11422                          (xcb_drawable_t) FRAME_X_DRAWABLE (f),
 11423                          (xcb_gcontext_t) XGContextFromGC (f->output_data.x->normal_gc),
 11424                          x, from_y, x, to_y, width, height);
 11425           cairo_surface_mark_dirty_rectangle (surface, x, to_y, width, height);
 11426         }
 11427 #endif
 11428       else
 11429         {
 11430           cairo_surface_t *s
 11431             = cairo_surface_create_similar (surface,
 11432                                             cairo_surface_get_content (surface),
 11433                                             width, height);
 11434           cairo_t *cr = cairo_create (s);
 11435           cairo_set_source_surface (cr, surface, -x, -from_y);
 11436           cairo_paint (cr);
 11437           cairo_destroy (cr);
 11438 
 11439           cr = FRAME_CR_CONTEXT (f);
 11440           cairo_save (cr);
 11441           cairo_set_source_surface (cr, s, x, to_y);
 11442           cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
 11443           cairo_rectangle (cr, x, to_y, width, height);
 11444           cairo_fill (cr);
 11445           cairo_restore (cr);
 11446           cairo_surface_destroy (s);
 11447         }
 11448     }
 11449   else
 11450 #endif  /* USE_CAIRO */
 11451     XCopyArea (FRAME_X_DISPLAY (f),
 11452                FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f),
 11453                f->output_data.x->normal_gc,
 11454                x, from_y,
 11455                width, height,
 11456                x, to_y);
 11457 
 11458   unblock_input ();
 11459 }
 11460 
 11461 
 11462 
 11463 /***********************************************************************
 11464                            Exposure Events
 11465  ***********************************************************************/
 11466 
 11467 
 11468 static void
 11469 x_frame_highlight (struct frame *f)
 11470 {
 11471   struct x_display_info *dpyinfo;
 11472 
 11473   dpyinfo = FRAME_DISPLAY_INFO (f);
 11474 
 11475   /* We used to only do this if Vx_no_window_manager was non-nil, but
 11476      the ICCCM (section 4.1.6) says that the window's border pixmap
 11477      and border pixel are window attributes which are "private to the
 11478      client", so we can always change it to whatever we want.  */
 11479   block_input ();
 11480   /* I recently started to get errors in this XSetWindowBorder, depending on
 11481      the window-manager in use, tho something more is at play since I've been
 11482      using that same window-manager binary for ever.  Let's not crash just
 11483      because of this (bug#9310).  */
 11484   x_ignore_errors_for_next_request (dpyinfo);
 11485   XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 11486                     f->output_data.x->border_pixel);
 11487   x_stop_ignoring_errors (dpyinfo);
 11488   unblock_input ();
 11489   gui_update_cursor (f, true);
 11490   x_set_frame_alpha (f);
 11491 }
 11492 
 11493 static void
 11494 x_frame_unhighlight (struct frame *f)
 11495 {
 11496   struct x_display_info *dpyinfo;
 11497 
 11498   dpyinfo = FRAME_DISPLAY_INFO (f);
 11499 
 11500   /* We used to only do this if Vx_no_window_manager was non-nil, but
 11501      the ICCCM (section 4.1.6) says that the window's border pixmap
 11502      and border pixel are window attributes which are "private to the
 11503      client", so we can always change it to whatever we want.  */
 11504 
 11505   block_input ();
 11506   /* Same as above for XSetWindowBorder (bug#9310).  */
 11507   x_ignore_errors_for_next_request (dpyinfo);
 11508   XSetWindowBorderPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 11509                           f->output_data.x->border_tile);
 11510   x_stop_ignoring_errors (dpyinfo);
 11511   unblock_input ();
 11512 
 11513   gui_update_cursor (f, true);
 11514   x_set_frame_alpha (f);
 11515 }
 11516 
 11517 /* The focus has changed.  Update the frames as necessary to reflect
 11518    the new situation.  Note that we can't change the selected frame
 11519    here, because the Lisp code we are interrupting might become confused.
 11520    Each event gets marked with the frame in which it occurred, so the
 11521    Lisp code can tell when the switch took place by examining the events.  */
 11522 
 11523 static void
 11524 x_new_focus_frame (struct x_display_info *dpyinfo, struct frame *frame)
 11525 {
 11526   struct frame *old_focus = dpyinfo->x_focus_frame;
 11527 #if defined USE_GTK && !defined HAVE_GTK3 && defined HAVE_XINPUT2
 11528   XIEventMask mask;
 11529   ptrdiff_t l;
 11530 
 11531   if (dpyinfo->supports_xi2)
 11532     {
 11533       l = XIMaskLen (XI_LASTEVENT);
 11534       mask.mask = alloca (l);
 11535       mask.mask_len = l;
 11536       memset (mask.mask, 0, l);
 11537 
 11538       mask.deviceid = XIAllDevices;
 11539     }
 11540 #endif
 11541 
 11542   if (frame != dpyinfo->x_focus_frame)
 11543     {
 11544       /* Set this before calling other routines, so that they see
 11545          the correct value of x_focus_frame.  */
 11546       dpyinfo->x_focus_frame = frame;
 11547 
 11548       /* Once none of our frames are focused anymore, stop selecting
 11549          for raw input events from the root window.  */
 11550 
 11551 #if defined USE_GTK && !defined HAVE_GTK3 && defined HAVE_XINPUT2
 11552       if (frame && dpyinfo->supports_xi2)
 11553         XISetMask (mask.mask, XI_RawKeyPress);
 11554 
 11555       if (dpyinfo->supports_xi2)
 11556         XISelectEvents (dpyinfo->display, dpyinfo->root_window, &mask, 1);
 11557 #endif
 11558 
 11559       if (old_focus && old_focus->auto_lower)
 11560         x_lower_frame (old_focus);
 11561 
 11562       if (dpyinfo->x_focus_frame && dpyinfo->x_focus_frame->auto_raise)
 11563         dpyinfo->x_pending_autoraise_frame = dpyinfo->x_focus_frame;
 11564       else
 11565         dpyinfo->x_pending_autoraise_frame = NULL;
 11566     }
 11567 
 11568   x_frame_rehighlight (dpyinfo);
 11569 }
 11570 
 11571 #ifdef HAVE_XFIXES
 11572 
 11573 /* True if the display in DPYINFO supports a version of Xfixes
 11574    sufficient for pointer blanking.  */
 11575 
 11576 static bool
 11577 x_fixes_pointer_blanking_supported (struct x_display_info *dpyinfo)
 11578 {
 11579   return (dpyinfo->xfixes_supported_p
 11580           && dpyinfo->xfixes_major >= 4);
 11581 }
 11582 
 11583 #endif /* HAVE_XFIXES */
 11584 
 11585 /* Toggle mouse pointer visibility on frame F using the XFixes
 11586    extension.  */
 11587 #ifdef HAVE_XFIXES
 11588 static void
 11589 xfixes_toggle_visible_pointer (struct frame *f, bool invisible)
 11590 
 11591 {
 11592   if (invisible)
 11593     XFixesHideCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
 11594   else
 11595     XFixesShowCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
 11596   f->pointer_invisible = invisible;
 11597 }
 11598 #endif /* HAVE_XFIXES */
 11599 
 11600 /* Create invisible cursor on the X display referred by DPYINFO.  */
 11601 static Cursor
 11602 make_invisible_cursor (struct x_display_info *dpyinfo)
 11603 {
 11604   Display *dpy = dpyinfo->display;
 11605   static char const no_data[] = { 0 };
 11606   Pixmap pix;
 11607   XColor col;
 11608   Cursor c;
 11609 
 11610   c = None;
 11611 
 11612   x_catch_errors (dpy);
 11613   pix = XCreateBitmapFromData (dpy, dpyinfo->root_window, no_data, 1, 1);
 11614   if (!x_had_errors_p (dpy) && pix != None)
 11615     {
 11616       Cursor pixc;
 11617       col.pixel = 0;
 11618       col.red = col.green = col.blue = 0;
 11619       col.flags = DoRed | DoGreen | DoBlue;
 11620       pixc = XCreatePixmapCursor (dpy, pix, pix, &col, &col, 0, 0);
 11621       if (! x_had_errors_p (dpy) && pixc != None)
 11622         c = pixc;
 11623       XFreePixmap (dpy, pix);
 11624     }
 11625 
 11626   x_uncatch_errors ();
 11627 
 11628   return c;
 11629 }
 11630 
 11631 /* Toggle mouse pointer visibility on frame F by using an invisible
 11632    cursor.  */
 11633 static void
 11634 x_toggle_visible_pointer (struct frame *f, bool invisible)
 11635 {
 11636   struct x_display_info *dpyinfo;
 11637 
 11638   dpyinfo = FRAME_DISPLAY_INFO (f);
 11639 
 11640   /* We could have gotten a BadAlloc error while creating the
 11641      invisible cursor.  Try to create it again, but if that fails,
 11642      just give up.  */
 11643   if (dpyinfo->invisible_cursor == None)
 11644     dpyinfo->invisible_cursor = make_invisible_cursor (dpyinfo);
 11645 
 11646 #ifndef HAVE_XFIXES
 11647   if (dpyinfo->invisible_cursor == None)
 11648     invisible = false;
 11649 #else
 11650   /* But if Xfixes is available, try using it instead.  */
 11651   if (dpyinfo->invisible_cursor == None)
 11652     {
 11653       if (x_fixes_pointer_blanking_supported (dpyinfo))
 11654         {
 11655           dpyinfo->fixes_pointer_blanking = true;
 11656           xfixes_toggle_visible_pointer (f, invisible);
 11657 
 11658           return;
 11659         }
 11660       else
 11661         invisible = false;
 11662     }
 11663 #endif
 11664 
 11665   if (invisible)
 11666     XDefineCursor (dpyinfo->display, FRAME_X_WINDOW (f),
 11667                    dpyinfo->invisible_cursor);
 11668   else
 11669     XDefineCursor (dpyinfo->display, FRAME_X_WINDOW (f),
 11670                    f->output_data.x->current_cursor);
 11671 
 11672   f->pointer_invisible = invisible;
 11673 }
 11674 
 11675 static void
 11676 XTtoggle_invisible_pointer (struct frame *f, bool invisible)
 11677 {
 11678   block_input ();
 11679 #ifdef HAVE_XFIXES
 11680   if (FRAME_DISPLAY_INFO (f)->fixes_pointer_blanking
 11681       && x_fixes_pointer_blanking_supported (FRAME_DISPLAY_INFO (f)))
 11682     xfixes_toggle_visible_pointer (f, invisible);
 11683   else
 11684 #endif
 11685     x_toggle_visible_pointer (f, invisible);
 11686   unblock_input ();
 11687 }
 11688 
 11689 /* Handle FocusIn and FocusOut state changes for FRAME.  If FRAME has
 11690    focus and there exists more than one frame, puts a FOCUS_IN_EVENT
 11691    into *BUFP.  Note that this code is not used to handle focus
 11692    changes on builds that can use the X Input extension for handling
 11693    input focus when it is available (currently the no toolkit and GTK
 11694    3 toolkits).  */
 11695 
 11696 static void
 11697 x_focus_changed (int type, int state, struct x_display_info *dpyinfo,
 11698                  struct frame *frame, struct input_event *bufp)
 11699 {
 11700   if (type == FocusIn)
 11701     {
 11702       if (dpyinfo->x_focus_event_frame != frame)
 11703         {
 11704           x_new_focus_frame (dpyinfo, frame);
 11705           dpyinfo->x_focus_event_frame = frame;
 11706           bufp->kind = FOCUS_IN_EVENT;
 11707           XSETFRAME (bufp->frame_or_window, frame);
 11708         }
 11709 
 11710       frame->output_data.x->focus_state |= state;
 11711 
 11712 #ifdef HAVE_X_I18N
 11713       if (FRAME_XIC (frame))
 11714         XSetICFocus (FRAME_XIC (frame));
 11715 #ifdef USE_GTK
 11716       GtkWidget *widget;
 11717 
 11718       if (x_gtk_use_native_input)
 11719         {
 11720           gtk_im_context_focus_in (FRAME_X_OUTPUT (frame)->im_context);
 11721           widget = FRAME_GTK_OUTER_WIDGET (frame);
 11722           gtk_im_context_set_client_window (FRAME_X_OUTPUT (frame)->im_context,
 11723                                             gtk_widget_get_window (widget));
 11724         }
 11725 #endif
 11726 #endif
 11727     }
 11728   else if (type == FocusOut)
 11729     {
 11730       frame->output_data.x->focus_state &= ~state;
 11731 
 11732       if (dpyinfo->x_focus_event_frame == frame)
 11733         {
 11734           dpyinfo->x_focus_event_frame = 0;
 11735           x_new_focus_frame (dpyinfo, 0);
 11736 
 11737           bufp->kind = FOCUS_OUT_EVENT;
 11738           XSETFRAME (bufp->frame_or_window, frame);
 11739         }
 11740 
 11741       if (!frame->output_data.x->focus_state)
 11742         {
 11743 #ifdef HAVE_X_I18N
 11744           if (FRAME_XIC (frame))
 11745             XUnsetICFocus (FRAME_XIC (frame));
 11746 #ifdef USE_GTK
 11747           if (x_gtk_use_native_input)
 11748             {
 11749               gtk_im_context_focus_out (FRAME_X_OUTPUT (frame)->im_context);
 11750               gtk_im_context_set_client_window (FRAME_X_OUTPUT (frame)->im_context, NULL);
 11751             }
 11752 #endif
 11753 #endif
 11754         }
 11755 
 11756       if (frame->pointer_invisible)
 11757         XTtoggle_invisible_pointer (frame, false);
 11758     }
 11759 }
 11760 
 11761 /* Return the Emacs frame-object corresponding to an X window.  It
 11762    could be the frame's main window, an icon window, or an xwidget
 11763    window.  */
 11764 
 11765 static struct frame *
 11766 x_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
 11767 {
 11768   Lisp_Object tail, frame;
 11769   struct frame *f;
 11770 
 11771   if (wdesc == None)
 11772     return NULL;
 11773 
 11774 #ifdef HAVE_XWIDGETS
 11775   struct xwidget_view *xvw = xwidget_view_from_window (wdesc);
 11776 
 11777   if (xvw && xvw->frame)
 11778     return xvw->frame;
 11779 #endif
 11780 
 11781   FOR_EACH_FRAME (tail, frame)
 11782     {
 11783       f = XFRAME (frame);
 11784       if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
 11785         continue;
 11786       if (f->output_data.x->hourglass_window == wdesc)
 11787         return f;
 11788 #ifdef USE_X_TOOLKIT
 11789       if ((f->output_data.x->edit_widget
 11790            && XtWindow (f->output_data.x->edit_widget) == wdesc)
 11791           /* A tooltip frame?  */
 11792           || (!f->output_data.x->edit_widget
 11793               && FRAME_X_WINDOW (f) == wdesc)
 11794           || f->output_data.x->icon_desc == wdesc)
 11795         return f;
 11796 #else /* not USE_X_TOOLKIT */
 11797 #ifdef USE_GTK
 11798       if (f->output_data.x->edit_widget)
 11799       {
 11800         GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
 11801         struct x_output *x = f->output_data.x;
 11802         if (gwdesc != 0 && gwdesc == x->edit_widget)
 11803           return f;
 11804       }
 11805 #endif /* USE_GTK */
 11806       if (FRAME_X_WINDOW (f) == wdesc
 11807           || f->output_data.x->icon_desc == wdesc)
 11808         return f;
 11809 #endif /* not USE_X_TOOLKIT */
 11810     }
 11811   return 0;
 11812 }
 11813 
 11814 /* Like x_any_window_to_frame but only try to find tooltip frames.
 11815 
 11816    If wdesc is a toolkit tooltip without an associated frame, set
 11817    UNRELATED_TOOLTIP_P to true.  Otherwise, set it to false.  */
 11818 static struct frame *
 11819 x_tooltip_window_to_frame (struct x_display_info *dpyinfo,
 11820                            Window wdesc, bool *unrelated_tooltip_p)
 11821 {
 11822   Lisp_Object tail, frame;
 11823   struct frame *f;
 11824 #ifdef USE_GTK
 11825   GtkWidget *widget;
 11826   GdkWindow *tooltip_window;
 11827 #endif
 11828 
 11829   if (unrelated_tooltip_p)
 11830     *unrelated_tooltip_p = false;
 11831 
 11832   FOR_EACH_FRAME (tail, frame)
 11833     {
 11834       f = XFRAME (frame);
 11835 
 11836       if (FRAME_X_P (f) && FRAME_TOOLTIP_P (f)
 11837           && FRAME_DISPLAY_INFO (f) == dpyinfo
 11838           && FRAME_X_WINDOW (f) == wdesc)
 11839         return f;
 11840 
 11841 #ifdef USE_GTK
 11842       if (!FRAME_X_P (f))
 11843         continue;
 11844 
 11845       if (FRAME_X_OUTPUT (f)->ttip_window)
 11846         widget = GTK_WIDGET (FRAME_X_OUTPUT (f)->ttip_window);
 11847       else
 11848         widget = NULL;
 11849 
 11850       if (widget)
 11851         tooltip_window = gtk_widget_get_window (widget);
 11852       else
 11853         tooltip_window = NULL;
 11854 
 11855 #ifdef HAVE_GTK3
 11856       if (tooltip_window
 11857           && (gdk_x11_window_get_xid (tooltip_window) == wdesc))
 11858         {
 11859           if (unrelated_tooltip_p)
 11860             *unrelated_tooltip_p = true;
 11861           break;
 11862         }
 11863 #else
 11864       if (tooltip_window
 11865           && (GDK_WINDOW_XID (tooltip_window) == wdesc))
 11866         {
 11867           if (unrelated_tooltip_p)
 11868             *unrelated_tooltip_p = true;
 11869           break;
 11870         }
 11871 #endif
 11872 #endif
 11873     }
 11874 
 11875   return NULL;
 11876 }
 11877 
 11878 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
 11879 
 11880 /* Like x_window_to_frame but also compares the window with the widget's
 11881    windows.  */
 11882 
 11883 static struct frame *
 11884 x_any_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
 11885 {
 11886   Lisp_Object tail, frame;
 11887   struct frame *f, *found = NULL;
 11888   struct x_output *x;
 11889 
 11890   if (wdesc == None)
 11891     return NULL;
 11892 
 11893 #ifdef HAVE_XWIDGETS
 11894   struct xwidget_view *xv = xwidget_view_from_window (wdesc);
 11895 
 11896   if (xv)
 11897     return xv->frame;
 11898 #endif
 11899 
 11900   FOR_EACH_FRAME (tail, frame)
 11901     {
 11902       if (found)
 11903         break;
 11904       f = XFRAME (frame);
 11905       if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo)
 11906         {
 11907           /* This frame matches if the window is any of its widgets.  */
 11908           x = f->output_data.x;
 11909           if (x->hourglass_window == wdesc)
 11910             found = f;
 11911           else if (x->widget)
 11912             {
 11913 #ifdef USE_GTK
 11914               GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
 11915               if (gwdesc != 0
 11916                   && gtk_widget_get_toplevel (gwdesc) == x->widget)
 11917                 found = f;
 11918 #else
 11919               if (wdesc == XtWindow (x->widget)
 11920                   || wdesc == XtWindow (x->column_widget)
 11921                   || wdesc == XtWindow (x->edit_widget))
 11922                 found = f;
 11923               /* Match if the window is this frame's menubar.  */
 11924               else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
 11925                 found = f;
 11926 #endif
 11927             }
 11928           else if (FRAME_X_WINDOW (f) == wdesc)
 11929             /* A tooltip frame.  */
 11930             found = f;
 11931         }
 11932     }
 11933 
 11934   return found;
 11935 }
 11936 
 11937 /* Likewise, but consider only the menu bar widget.  */
 11938 
 11939 static struct frame *
 11940 x_menubar_window_to_frame (struct x_display_info *dpyinfo,
 11941                            const XEvent *event)
 11942 {
 11943   Window wdesc;
 11944 #ifdef HAVE_XINPUT2
 11945   if (event->type == GenericEvent
 11946       && dpyinfo->supports_xi2
 11947       && (event->xcookie.evtype == XI_ButtonPress
 11948           || event->xcookie.evtype == XI_ButtonRelease))
 11949     wdesc = ((XIDeviceEvent *) event->xcookie.data)->event;
 11950   else
 11951 #endif
 11952     wdesc = event->xany.window;
 11953   Lisp_Object tail, frame;
 11954   struct frame *f;
 11955   struct x_output *x;
 11956 
 11957   if (wdesc == None)
 11958     return NULL;
 11959 
 11960   FOR_EACH_FRAME (tail, frame)
 11961     {
 11962       f = XFRAME (frame);
 11963       if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
 11964         continue;
 11965       x = f->output_data.x;
 11966 #ifdef USE_GTK
 11967       if (x->menubar_widget && xg_event_is_for_menubar (f, event))
 11968         return f;
 11969 #else
 11970       /* Match if the window is this frame's menubar.  */
 11971       if (x->menubar_widget
 11972           && lw_window_is_in_menubar (wdesc, x->menubar_widget))
 11973         return f;
 11974 #endif
 11975     }
 11976   return 0;
 11977 }
 11978 
 11979 /* Return the frame whose principal (outermost) window is WDESC.
 11980    If WDESC is some other (smaller) window, we return 0.  */
 11981 
 11982 struct frame *
 11983 x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
 11984 {
 11985   Lisp_Object tail, frame;
 11986   struct frame *f;
 11987   struct x_output *x;
 11988 
 11989   if (wdesc == None)
 11990     return NULL;
 11991 
 11992   FOR_EACH_FRAME (tail, frame)
 11993     {
 11994       f = XFRAME (frame);
 11995       if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
 11996         continue;
 11997       x = f->output_data.x;
 11998 
 11999       if (x->widget)
 12000         {
 12001           /* This frame matches if the window is its topmost widget.  */
 12002 #ifdef USE_GTK
 12003           GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
 12004           if (gwdesc == x->widget)
 12005             return f;
 12006 #else
 12007           if (wdesc == XtWindow (x->widget))
 12008             return f;
 12009 #endif
 12010         }
 12011       else if (FRAME_X_WINDOW (f) == wdesc)
 12012         /* Tooltip frame.  */
 12013         return f;
 12014     }
 12015   return 0;
 12016 }
 12017 
 12018 #else /* !USE_X_TOOLKIT && !USE_GTK */
 12019 
 12020 #define x_any_window_to_frame(d, i) x_window_to_frame (d, i)
 12021 
 12022 struct frame *
 12023 x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
 12024 {
 12025   return x_window_to_frame (dpyinfo, wdesc);
 12026 }
 12027 
 12028 static void
 12029 x_next_event_from_any_display (XEvent *event)
 12030 {
 12031   struct x_display_info *dpyinfo;
 12032   fd_set fds, rfds;
 12033   int fd, maxfd, rc;
 12034 
 12035   rc = -1;
 12036   FD_ZERO (&rfds);
 12037 
 12038   while (true)
 12039     {
 12040       FD_ZERO (&fds);
 12041       maxfd = -1;
 12042 
 12043       for (dpyinfo = x_display_list; dpyinfo;
 12044            dpyinfo = dpyinfo->next)
 12045         {
 12046           fd = ConnectionNumber (dpyinfo->display);
 12047 
 12048           if ((rc < 0 || FD_ISSET (fd, &rfds))
 12049               && XPending (dpyinfo->display))
 12050             {
 12051               XNextEvent (dpyinfo->display, event);
 12052               return;
 12053             }
 12054 
 12055           if (fd > maxfd)
 12056             maxfd = fd;
 12057 
 12058           eassert (fd < FD_SETSIZE);
 12059           FD_SET (fd, &fds);
 12060         }
 12061 
 12062       eassert (maxfd >= 0);
 12063 
 12064       /* Continue to read input even if pselect fails, because if an
 12065          error occurs XPending will call the IO error handler, which
 12066          then brings us out of this loop.  */
 12067       rc = pselect (maxfd + 1, &fds, NULL, NULL, NULL, NULL);
 12068 
 12069       if (rc >= 0)
 12070         rfds = fds;
 12071     }
 12072 }
 12073 
 12074 #endif /* USE_X_TOOLKIT || USE_GTK */
 12075 
 12076 static void
 12077 x_handle_pending_selection_requests_1 (struct x_selection_request_event *tem)
 12078 {
 12079   specpdl_ref count;
 12080   struct selection_input_event se;
 12081 
 12082   count = SPECPDL_INDEX ();
 12083   se = tem->se;
 12084 
 12085   record_unwind_protect_ptr (xfree, tem);
 12086   x_handle_selection_event (&se);
 12087   unbind_to (count, Qnil);
 12088 }
 12089 
 12090 /* Handle all pending selection request events from modal event
 12091    loops.  */
 12092 void
 12093 x_handle_pending_selection_requests (void)
 12094 {
 12095   struct x_selection_request_event *tem;
 12096 
 12097   while (pending_selection_requests)
 12098     {
 12099       tem = pending_selection_requests;
 12100       pending_selection_requests = tem->next;
 12101 
 12102       x_handle_pending_selection_requests_1 (tem);
 12103     }
 12104 }
 12105 
 12106 static void
 12107 x_push_selection_request (struct selection_input_event *se)
 12108 {
 12109   struct x_selection_request_event *tem;
 12110 
 12111   tem = xmalloc (sizeof *tem);
 12112   tem->next = pending_selection_requests;
 12113   tem->se = *se;
 12114   pending_selection_requests = tem;
 12115 }
 12116 
 12117 bool
 12118 x_detect_pending_selection_requests (void)
 12119 {
 12120   return !!pending_selection_requests;
 12121 }
 12122 
 12123 static void
 12124 x_clear_dnd_action (void)
 12125 {
 12126   x_dnd_action_symbol = Qnil;
 12127 }
 12128 
 12129 /* Delete action descriptions from F after drag-and-drop.  */
 12130 static void
 12131 x_dnd_delete_action_list (Lisp_Object frame)
 12132 {
 12133   struct frame *f;
 12134 
 12135   /* Delete those two properties, since some clients look at them and
 12136      not the action to decide whether or not the user should be
 12137      prompted to select an action.  This can be called with FRAME no
 12138      longer alive (or its display dead).  */
 12139 
 12140   f = XFRAME (frame);
 12141 
 12142   if (!FRAME_LIVE_P (f) || !FRAME_DISPLAY_INFO (f)->display)
 12143     return;
 12144 
 12145   block_input ();
 12146   XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 12147                    FRAME_DISPLAY_INFO (f)->Xatom_XdndActionList);
 12148   XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 12149                    FRAME_DISPLAY_INFO (f)->Xatom_XdndActionDescription);
 12150   unblock_input ();
 12151 }
 12152 
 12153 static void
 12154 x_dnd_lose_ownership (Lisp_Object timestamp_and_frame)
 12155 {
 12156   struct frame *f;
 12157 
 12158   f = XFRAME (XCDR (timestamp_and_frame));
 12159 
 12160   if (FRAME_LIVE_P (f))
 12161     Fx_disown_selection_internal (QXdndSelection,
 12162                                   XCAR (timestamp_and_frame),
 12163                                   XCDR (timestamp_and_frame));
 12164 }
 12165 
 12166 /* Clean up an existing drag-and-drop operation in preparation for its
 12167    sudden termination.  */
 12168 
 12169 static void
 12170 x_dnd_process_quit (struct frame *f, Time timestamp)
 12171 {
 12172   xm_drop_start_message dmsg;
 12173 
 12174   if (x_dnd_in_progress)
 12175     {
 12176       if (x_dnd_last_seen_window != None
 12177           && x_dnd_last_protocol_version != -1)
 12178         x_dnd_send_leave (f, x_dnd_last_seen_window,
 12179                           x_dnd_last_seen_toplevel);
 12180       else if (x_dnd_last_seen_window != None
 12181                && !XM_DRAG_STYLE_IS_DROP_ONLY (x_dnd_last_motif_style)
 12182                && x_dnd_last_motif_style != XM_DRAG_STYLE_NONE
 12183                && x_dnd_motif_setup_p)
 12184         {
 12185           dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 12186                                         XM_DRAG_REASON_DROP_START);
 12187           dmsg.byte_order = XM_BYTE_ORDER_CUR_FIRST;
 12188           dmsg.timestamp = timestamp;
 12189           dmsg.side_effects
 12190             = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (FRAME_DISPLAY_INFO (f),
 12191                                                                x_dnd_wanted_action),
 12192                                    XM_DROP_SITE_VALID, x_dnd_motif_operations,
 12193                                    XM_DROP_ACTION_DROP_CANCEL);
 12194           dmsg.x = 0;
 12195           dmsg.y = 0;
 12196           dmsg.index_atom = x_dnd_motif_atom;
 12197           dmsg.source_window = FRAME_X_WINDOW (f);
 12198 
 12199           x_dnd_send_xm_leave_for_drop (FRAME_DISPLAY_INFO (f), f,
 12200                                         x_dnd_last_seen_window,
 12201                                         timestamp);
 12202           xm_send_drop_message (FRAME_DISPLAY_INFO (f), FRAME_X_WINDOW (f),
 12203                                 x_dnd_last_seen_window, &dmsg);
 12204         }
 12205 
 12206       x_dnd_end_window = x_dnd_last_seen_window;
 12207       x_dnd_last_seen_window = None;
 12208       x_dnd_last_seen_toplevel = None;
 12209       x_dnd_in_progress = false;
 12210       x_dnd_frame = NULL;
 12211     }
 12212 
 12213   x_dnd_waiting_for_finish = false;
 12214   x_dnd_return_frame_object = NULL;
 12215   x_dnd_movement_frame = NULL;
 12216   x_dnd_wheel_frame = NULL;
 12217 }
 12218 
 12219 /* This function is defined far away from the rest of the XDND code so
 12220    it can utilize `x_any_window_to_frame'.  */
 12221 
 12222 /* Implementors beware!  On most other platforms (where drag-and-drop
 12223    data is not provided via selections, but some kind of serialization
 12224    mechanism), it is usually much easier to implement a suitable
 12225    primitive instead of copying the C code here, and then to build
 12226    `x-begin-drag' on top of that, by making it a wrapper function in
 12227    Lisp that converts the list of targets and value of `XdndSelection'
 12228    to serialized data.  Also be sure to update the data types used in
 12229    dnd.el.
 12230 
 12231    For examples of how to do this, see `haiku-drag-message' and
 12232    `x-begin-drag' in haikuselect.c and lisp/term/haiku-win.el, and
 12233    `ns-begin-drag' and `x-begin-drag' in nsselect.m and
 12234    lisp/term/ns-win.el.  */
 12235 
 12236 Lisp_Object
 12237 x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction,
 12238                            Lisp_Object return_frame, Atom *ask_action_list,
 12239                            const char **ask_action_names, size_t n_ask_actions,
 12240                            bool allow_current_frame, Atom *target_atoms,
 12241                            int ntargets, Lisp_Object selection_target_list,
 12242                            bool follow_tooltip)
 12243 {
 12244 #ifndef USE_GTK
 12245   XEvent next_event;
 12246   int finish;
 12247 #endif
 12248   XWindowAttributes root_window_attrs;
 12249   struct input_event hold_quit;
 12250   char *atom_name, *ask_actions;
 12251   Lisp_Object action, ltimestamp, val;
 12252   specpdl_ref ref, count, base;
 12253   ptrdiff_t i, end, fill;
 12254   XTextProperty prop;
 12255   Lisp_Object frame_object, x, y, frame, local_value;
 12256   bool signals_were_pending, need_sync;
 12257 #ifdef HAVE_XKB
 12258   XkbStateRec keyboard_state;
 12259 #endif
 12260 #ifndef USE_GTK
 12261   struct x_display_info *event_display;
 12262 #endif
 12263   unsigned int additional_mask;
 12264 #ifdef HAVE_XINPUT2
 12265   struct xi_device_t *device;
 12266 #endif
 12267 
 12268   base = SPECPDL_INDEX ();
 12269 
 12270   /* Bind this here to avoid juggling bindings and SAFE_FREE in
 12271      Fx_begin_drag.  */
 12272   specbind (Qx_dnd_targets_list, selection_target_list);
 12273 
 12274   if (!FRAME_VISIBLE_P (f))
 12275     error ("Frame must be visible");
 12276 
 12277   XSETFRAME (frame, f);
 12278   local_value = assq_no_quit (QXdndSelection,
 12279                               FRAME_TERMINAL (f)->Vselection_alist);
 12280 
 12281   if (x_dnd_in_progress || x_dnd_waiting_for_finish)
 12282     error ("A drag-and-drop session is already in progress");
 12283 
 12284   DEFER_SELECTIONS;
 12285 
 12286   /* If local_value is nil, then we lost ownership of XdndSelection.
 12287      Signal a more informative error than args-out-of-range.  */
 12288   if (NILP (local_value))
 12289     error ("No local value for XdndSelection");
 12290 
 12291   if (popup_activated ())
 12292     error ("Trying to drag-and-drop from within a menu-entry");
 12293 
 12294   x_set_dnd_targets (target_atoms, ntargets);
 12295   record_unwind_protect_void (x_free_dnd_targets);
 12296   record_unwind_protect_void (x_clear_dnd_action);
 12297 
 12298   ltimestamp = x_timestamp_for_selection (FRAME_DISPLAY_INFO (f),
 12299                                           QXdndSelection);
 12300 
 12301   if (NILP (ltimestamp))
 12302     error ("No local value for XdndSelection");
 12303 
 12304   if (BIGNUMP (ltimestamp))
 12305     x_dnd_selection_timestamp = bignum_to_intmax (ltimestamp);
 12306   else
 12307     x_dnd_selection_timestamp = XFIXNUM (ltimestamp);
 12308 
 12309   /* Release ownership of XdndSelection after this function returns.
 12310      VirtualBox uses the owner of XdndSelection to determine whether
 12311      or not mouse motion is part of a drag-and-drop operation.  */
 12312 
 12313   if (!x_dnd_preserve_selection_data)
 12314     record_unwind_protect (x_dnd_lose_ownership,
 12315                            Fcons (ltimestamp, frame));
 12316 
 12317   x_dnd_motif_operations
 12318     = xm_side_effect_from_action (FRAME_DISPLAY_INFO (f), xaction);
 12319 
 12320   x_dnd_first_motif_operation = XM_DRAG_NOOP;
 12321 
 12322   if (n_ask_actions)
 12323     {
 12324       x_dnd_motif_operations
 12325         = xm_operations_from_actions (FRAME_DISPLAY_INFO (f),
 12326                                       ask_action_list,
 12327                                       n_ask_actions);
 12328       x_dnd_first_motif_operation
 12329         = xm_side_effect_from_action (FRAME_DISPLAY_INFO (f),
 12330                                       ask_action_list[0]);
 12331 
 12332       record_unwind_protect (x_dnd_delete_action_list, frame);
 12333 
 12334       ask_actions = NULL;
 12335       end = 0;
 12336       count = SPECPDL_INDEX ();
 12337 
 12338       for (i = 0; i < n_ask_actions; ++i)
 12339         {
 12340           fill = end;
 12341           end += strlen (ask_action_names[i]) + 1;
 12342 
 12343           if (ask_actions)
 12344             ask_actions = xrealloc (ask_actions, end);
 12345           else
 12346             ask_actions = xmalloc (end);
 12347 
 12348           strncpy (ask_actions + fill,
 12349                    ask_action_names[i],
 12350                    end - fill);
 12351         }
 12352 
 12353       prop.value = (unsigned char *) ask_actions;
 12354       prop.encoding = XA_STRING;
 12355       prop.format = 8;
 12356       prop.nitems = end;
 12357 
 12358       record_unwind_protect_ptr (xfree, ask_actions);
 12359 
 12360       /* This can potentially store a lot of data in window
 12361          properties, so check for allocation errors.  */
 12362       block_input ();
 12363       x_catch_errors (FRAME_X_DISPLAY (f));
 12364       XSetTextProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 12365                         &prop, FRAME_DISPLAY_INFO (f)->Xatom_XdndActionDescription);
 12366 
 12367       XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 12368                        FRAME_DISPLAY_INFO (f)->Xatom_XdndActionList, XA_ATOM, 32,
 12369                        PropModeReplace, (unsigned char *) ask_action_list,
 12370                        n_ask_actions);
 12371       x_check_errors (FRAME_X_DISPLAY (f),
 12372                       "Can't set action descriptions: %s");
 12373       x_uncatch_errors_after_check ();
 12374       unblock_input ();
 12375 
 12376       unbind_to (count, Qnil);
 12377     }
 12378 
 12379   record_unwind_protect_void (x_clear_dnd_variables);
 12380 
 12381   if (follow_tooltip)
 12382     {
 12383 #if defined HAVE_XRANDR || defined USE_GTK
 12384       x_dnd_monitors
 12385         = FRAME_DISPLAY_INFO (f)->last_monitor_attributes_list;
 12386 
 12387       if (NILP (x_dnd_monitors))
 12388 #endif
 12389         x_dnd_monitors
 12390           = Fx_display_monitor_attributes_list (frame);
 12391     }
 12392 
 12393   x_dnd_update_tooltip = follow_tooltip;
 12394 
 12395   /* This shouldn't happen.  */
 12396   if (x_dnd_toplevels)
 12397     x_dnd_free_toplevels (true);
 12398 
 12399 #ifdef USE_GTK
 12400   /* Prevent GTK+ timeouts from being run, since they can call
 12401      handle_one_xevent behind our back.  */
 12402   suppress_xg_select ();
 12403   record_unwind_protect_void (release_xg_select);
 12404 #endif
 12405 
 12406   /* Set up a meaningless alias.  */
 12407   XSETCAR (x_dnd_selection_alias_cell, QSECONDARY);
 12408   XSETCDR (x_dnd_selection_alias_cell, QSECONDARY);
 12409 
 12410   /* Bind this here.  The cell doesn't actually alias between
 12411      anything until `xm_setup_dnd_targets' is called.  */
 12412   specbind (Qx_selection_alias_alist,
 12413             Fcons (x_dnd_selection_alias_cell,
 12414                    Vx_selection_alias_alist));
 12415 
 12416   /* Initialize most of the state for the drag-and-drop operation.  */
 12417   x_dnd_in_progress = true;
 12418   x_dnd_recursion_depth = command_loop_level + minibuf_level;
 12419   x_dnd_frame = f;
 12420   x_dnd_last_seen_window = None;
 12421   x_dnd_last_seen_toplevel = None;
 12422   x_dnd_last_protocol_version = -1;
 12423   x_dnd_last_window_is_frame = false;
 12424   x_dnd_last_motif_style = XM_DRAG_STYLE_NONE;
 12425   x_dnd_mouse_rect_target = None;
 12426   x_dnd_action = None;
 12427   x_dnd_action_symbol = Qnil;
 12428   x_dnd_wanted_action = xaction;
 12429   x_dnd_return_frame = 0;
 12430   x_dnd_waiting_for_finish = false;
 12431   x_dnd_waiting_for_motif_finish = 0;
 12432   x_dnd_waiting_for_status_window = None;
 12433   x_dnd_pending_send_position.type = 0;
 12434   x_dnd_xm_use_help = false;
 12435   x_dnd_motif_setup_p = false;
 12436   x_dnd_end_window = None;
 12437   x_dnd_run_unsupported_drop_function = false;
 12438   x_dnd_use_toplevels
 12439     = x_wm_supports (f, FRAME_DISPLAY_INFO (f)->Xatom_net_client_list_stacking);
 12440   x_dnd_last_tooltip_valid = false;
 12441   x_dnd_toplevels = NULL;
 12442   x_dnd_allow_current_frame = allow_current_frame;
 12443   x_dnd_movement_frame = NULL;
 12444   x_dnd_wheel_frame = NULL;
 12445   x_dnd_init_type_lists = false;
 12446   x_dnd_need_send_drop = false;
 12447 
 12448 #ifdef HAVE_XINPUT2
 12449 
 12450   if (FRAME_DISPLAY_INFO (f)->supports_xi2)
 12451     {
 12452       /* Only accept input from the last master pointer to have interacted
 12453          with Emacs.  This prevents another pointer device getting our
 12454          idea of the button state messed up.  */
 12455       if (FRAME_DISPLAY_INFO (f)->client_pointer_device != -1)
 12456         x_dnd_pointer_device
 12457           = FRAME_DISPLAY_INFO (f)->client_pointer_device;
 12458       else
 12459         /* This returns Bool but cannot actually fail.  */
 12460         XIGetClientPointer (FRAME_X_DISPLAY (f), None,
 12461                             &x_dnd_pointer_device);
 12462 
 12463       x_dnd_keyboard_device = -1;
 12464 
 12465       device = xi_device_from_id (FRAME_DISPLAY_INFO (f),
 12466                                   x_dnd_pointer_device);
 12467 
 12468       if (device)
 12469         x_dnd_keyboard_device = device->attachment;
 12470     }
 12471   else
 12472     {
 12473       x_dnd_pointer_device = -1;
 12474       x_dnd_keyboard_device = -1;
 12475     }
 12476 
 12477 #endif
 12478 
 12479 #ifdef HAVE_XKB
 12480   x_dnd_keyboard_state = 0;
 12481 
 12482   if (FRAME_DISPLAY_INFO (f)->supports_xkb)
 12483     {
 12484       XkbSelectEvents (FRAME_X_DISPLAY (f), XkbUseCoreKbd,
 12485                        XkbStateNotifyMask, XkbStateNotifyMask);
 12486       XkbGetState (FRAME_X_DISPLAY (f), XkbUseCoreKbd,
 12487                    &keyboard_state);
 12488 
 12489       x_dnd_keyboard_state = (keyboard_state.mods
 12490                               | keyboard_state.ptr_buttons);
 12491     }
 12492 #endif
 12493 
 12494   if (x_dnd_use_toplevels)
 12495     {
 12496       if (x_dnd_compute_toplevels (FRAME_DISPLAY_INFO (f)))
 12497         {
 12498           x_dnd_free_toplevels (true);
 12499           x_dnd_use_toplevels = false;
 12500         }
 12501       else
 12502         record_unwind_protect_void (x_free_dnd_toplevels);
 12503     }
 12504 
 12505   if (!NILP (return_frame))
 12506     x_dnd_return_frame = 1;
 12507 
 12508   if (EQ (return_frame, Qnow))
 12509     x_dnd_return_frame = 2;
 12510 
 12511   /* Now select for SubstructureNotifyMask and PropertyChangeMask on
 12512      the root window, so we can get notified when window stacking
 12513      changes, a common operation during drag-and-drop.  */
 12514 
 12515   XGetWindowAttributes (FRAME_X_DISPLAY (f),
 12516                         FRAME_DISPLAY_INFO (f)->root_window,
 12517                         &root_window_attrs);
 12518 
 12519   additional_mask = SubstructureNotifyMask;
 12520 
 12521   if (x_dnd_use_toplevels)
 12522     additional_mask |= PropertyChangeMask;
 12523 
 12524   XSelectInput (FRAME_X_DISPLAY (f),
 12525                 FRAME_DISPLAY_INFO (f)->root_window,
 12526                 root_window_attrs.your_event_mask
 12527                 | additional_mask);
 12528 
 12529   if (EQ (return_frame, Qnow))
 12530     x_dnd_update_state (FRAME_DISPLAY_INFO (f), CurrentTime);
 12531 
 12532   while (x_dnd_in_progress || x_dnd_waiting_for_finish)
 12533     {
 12534       EVENT_INIT (hold_quit);
 12535 
 12536 #ifdef USE_GTK
 12537       current_finish = X_EVENT_NORMAL;
 12538       current_hold_quit = &hold_quit;
 12539       current_count = 0;
 12540       xg_pending_quit_event.kind = NO_EVENT;
 12541 #endif
 12542 
 12543       block_input ();
 12544       x_dnd_inside_handle_one_xevent = true;
 12545 #ifdef USE_GTK
 12546       gtk_main_iteration ();
 12547 #elif defined USE_X_TOOLKIT
 12548       XtAppNextEvent (Xt_app_con, &next_event);
 12549 #else
 12550       x_next_event_from_any_display (&next_event);
 12551 #endif
 12552 
 12553 #ifndef USE_GTK
 12554       event_display
 12555         = x_display_info_for_display (next_event.xany.display);
 12556 
 12557       if (event_display)
 12558         {
 12559 #ifdef HAVE_X_I18N
 12560 #ifdef HAVE_XINPUT2
 12561           if (next_event.type != GenericEvent
 12562               || !event_display->supports_xi2
 12563               || (next_event.xgeneric.extension
 12564                   != event_display->xi2_opcode))
 12565             {
 12566 #endif
 12567               if (!x_filter_event (event_display, &next_event))
 12568                 handle_one_xevent (event_display,
 12569                                    &next_event, &finish, &hold_quit);
 12570 #ifdef HAVE_XINPUT2
 12571             }
 12572           else
 12573             handle_one_xevent (event_display,
 12574                                &next_event, &finish, &hold_quit);
 12575 #endif
 12576 #else
 12577           handle_one_xevent (event_display,
 12578                              &next_event, &finish, &hold_quit);
 12579 #endif
 12580         }
 12581 #else
 12582       /* Clear these before the read_socket_hook can be called.  */
 12583       current_count = -1;
 12584       current_hold_quit = NULL;
 12585 #endif
 12586       x_dnd_inside_handle_one_xevent = false;
 12587 
 12588       /* Clean up any event handlers that are now out of date.  */
 12589       x_clean_failable_requests (FRAME_DISPLAY_INFO (f));
 12590 
 12591       /* The unblock_input below might try to read input, but
 12592          XTread_socket does nothing inside a drag-and-drop event
 12593          loop, so don't let it clear the pending_signals flag.  */
 12594       signals_were_pending = pending_signals;
 12595       unblock_input ();
 12596       pending_signals = signals_were_pending;
 12597 
 12598       /* Ignore mouse movement from displays that aren't the DND
 12599          display.  */
 12600 #ifndef USE_GTK
 12601       if (event_display == FRAME_DISPLAY_INFO (f))
 12602         {
 12603 #endif
 12604           if (x_dnd_movement_frame
 12605               /* FIXME: how come this can end up with movement frames
 12606                  from other displays on GTK builds?  */
 12607               && (FRAME_X_DISPLAY (x_dnd_movement_frame)
 12608                   == FRAME_X_DISPLAY (f))
 12609               /* If both those variables are false, then F is no
 12610                  longer protected from deletion by Lisp code.  This
 12611                  can only happen during the final iteration of the DND
 12612                  event loop.  */
 12613               && (x_dnd_in_progress || x_dnd_waiting_for_finish))
 12614             {
 12615               XSETFRAME (frame_object, x_dnd_movement_frame);
 12616               XSETINT (x, x_dnd_movement_x);
 12617               XSETINT (y, x_dnd_movement_y);
 12618               x_dnd_movement_frame = NULL;
 12619 
 12620               if (!NILP (Vx_dnd_movement_function)
 12621                   && FRAME_LIVE_P (XFRAME (frame_object))
 12622                   && !FRAME_TOOLTIP_P (XFRAME (frame_object))
 12623                   && x_dnd_movement_x >= 0
 12624                   && x_dnd_movement_y >= 0
 12625                   && x_dnd_frame
 12626                   && (XFRAME (frame_object) != x_dnd_frame
 12627                       || x_dnd_allow_current_frame))
 12628                 {
 12629                   x_dnd_old_window_attrs = root_window_attrs;
 12630                   x_dnd_unwind_flag = true;
 12631 
 12632                   ref = SPECPDL_INDEX ();
 12633                   record_unwind_protect_ptr (x_dnd_cleanup_drag_and_drop, f);
 12634                   call2 (Vx_dnd_movement_function, frame_object,
 12635                          Fposn_at_x_y (x, y, frame_object, Qnil));
 12636                   x_dnd_unwind_flag = false;
 12637                   unbind_to (ref, Qnil);
 12638 
 12639                   /* Redisplay this way to preserve the echo area.
 12640                      Otherwise, the contents will abruptly disappear
 12641                      when the mouse moves over a frame.  */
 12642                   redisplay_preserve_echo_area (33);
 12643                 }
 12644             }
 12645 
 12646           if (x_dnd_wheel_frame
 12647               && (x_dnd_in_progress || x_dnd_waiting_for_finish))
 12648             {
 12649               XSETFRAME (frame_object, x_dnd_wheel_frame);
 12650               XSETINT (x, x_dnd_wheel_x);
 12651               XSETINT (y, x_dnd_wheel_y);
 12652               x_dnd_wheel_frame = NULL;
 12653 
 12654               if (!NILP (Vx_dnd_wheel_function)
 12655                   && FRAME_LIVE_P (XFRAME (frame_object))
 12656                   && !FRAME_TOOLTIP_P (XFRAME (frame_object))
 12657                   && x_dnd_movement_x >= 0
 12658                   && x_dnd_movement_y >= 0
 12659                   && x_dnd_frame
 12660                   && (XFRAME (frame_object) != x_dnd_frame
 12661                       || x_dnd_allow_current_frame))
 12662                 {
 12663                   x_dnd_old_window_attrs = root_window_attrs;
 12664                   x_dnd_unwind_flag = true;
 12665 
 12666                   ref = SPECPDL_INDEX ();
 12667                   record_unwind_protect_ptr (x_dnd_cleanup_drag_and_drop, f);
 12668                   call4 (Vx_dnd_wheel_function,
 12669                          Fposn_at_x_y (x, y, frame_object, Qnil),
 12670                          make_fixnum (x_dnd_wheel_button),
 12671                          make_uint (x_dnd_wheel_state),
 12672                          make_uint (x_dnd_wheel_time));
 12673                   x_dnd_unwind_flag = false;
 12674                   unbind_to (ref, Qnil);
 12675 
 12676                   /* Redisplay this way to preserve the echo area.
 12677                      Otherwise, the contents will abruptly disappear
 12678                      when the mouse moves over a frame.  */
 12679                   redisplay_preserve_echo_area (33);
 12680                 }
 12681             }
 12682 
 12683           if (hold_quit.kind != NO_EVENT)
 12684             {
 12685               x_dnd_process_quit (f, hold_quit.timestamp);
 12686 #ifdef USE_GTK
 12687               current_hold_quit = NULL;
 12688 #endif
 12689               /* Restore the old event mask.  */
 12690               x_restore_events_after_dnd (f, &root_window_attrs);
 12691 
 12692               /* Call kbd_buffer_store event, which calls
 12693                  handle_interrupt and sets `last-event-frame' along
 12694                  with various other things.  */
 12695               kbd_buffer_store_event (&hold_quit);
 12696               /* Now quit anyway.  */
 12697               quit ();
 12698             }
 12699 
 12700           if (pending_selection_requests
 12701               && (x_dnd_in_progress || x_dnd_waiting_for_finish))
 12702             {
 12703               x_dnd_old_window_attrs = root_window_attrs;
 12704               x_dnd_unwind_flag = true;
 12705 
 12706               ref = SPECPDL_INDEX ();
 12707               record_unwind_protect_ptr (x_dnd_cleanup_drag_and_drop, f);
 12708               x_handle_pending_selection_requests ();
 12709               x_dnd_unwind_flag = false;
 12710               unbind_to (ref, Qnil);
 12711             }
 12712 
 12713           /* Sometimes C-g can be pressed inside a selection
 12714              converter, where quitting is inhibited.  We want
 12715              to quit after the converter exits.  */
 12716           if (!NILP (Vquit_flag) && !NILP (Vinhibit_quit))
 12717             {
 12718               x_dnd_process_quit (f, FRAME_DISPLAY_INFO (f)->last_user_time);
 12719 #ifdef USE_GTK
 12720               current_hold_quit = NULL;
 12721 #endif
 12722               x_restore_events_after_dnd (f, &root_window_attrs);
 12723               quit ();
 12724             }
 12725 
 12726           if (x_dnd_run_unsupported_drop_function
 12727               && x_dnd_waiting_for_finish)
 12728             {
 12729               x_dnd_run_unsupported_drop_function = false;
 12730               x_dnd_waiting_for_finish = false;
 12731               x_dnd_unwind_flag = true;
 12732 
 12733               ref = SPECPDL_INDEX ();
 12734               record_unwind_protect_ptr (x_dnd_cleanup_drag_and_drop, f);
 12735 
 12736               if (!NILP (Vx_dnd_unsupported_drop_function))
 12737                 val = call8 (Vx_dnd_unsupported_drop_function,
 12738                              XCAR (XCDR (x_dnd_unsupported_drop_data)),
 12739                              Fnth (make_fixnum (3), x_dnd_unsupported_drop_data),
 12740                              Fnth (make_fixnum (4), x_dnd_unsupported_drop_data),
 12741                              Fnth (make_fixnum (2), x_dnd_unsupported_drop_data),
 12742                              make_uint (x_dnd_unsupported_drop_window),
 12743                              frame, make_uint (x_dnd_unsupported_drop_time),
 12744                              Fcopy_sequence (XCAR (x_dnd_unsupported_drop_data)));
 12745               else
 12746                 val = Qnil;
 12747 
 12748               if (NILP (val))
 12749                 x_dnd_do_unsupported_drop (FRAME_DISPLAY_INFO (f),
 12750                                            frame, XCAR (x_dnd_unsupported_drop_data),
 12751                                            XCAR (XCDR (x_dnd_unsupported_drop_data)),
 12752                                            x_dnd_unsupported_drop_window,
 12753                                            XFIXNUM (Fnth (make_fixnum (3),
 12754                                                           x_dnd_unsupported_drop_data)),
 12755                                            XFIXNUM (Fnth (make_fixnum (4),
 12756                                                           x_dnd_unsupported_drop_data)),
 12757                                            x_dnd_unsupported_drop_time);
 12758               else if (SYMBOLP (val))
 12759                 x_dnd_action_symbol = val;
 12760 
 12761               x_dnd_unwind_flag = false;
 12762               unbind_to (ref, Qnil);
 12763 
 12764               /* Break out of the loop now, since DND has
 12765                  completed.  */
 12766               break;
 12767             }
 12768 
 12769 #ifdef USE_GTK
 12770           if (xg_pending_quit_event.kind != NO_EVENT)
 12771             {
 12772               xg_pending_quit_event.kind = NO_EVENT;
 12773               current_hold_quit = NULL;
 12774 
 12775               x_dnd_process_quit (f, FRAME_DISPLAY_INFO (f)->last_user_time);
 12776               x_restore_events_after_dnd (f, &root_window_attrs);
 12777               quit ();
 12778             }
 12779 #else
 12780         }
 12781       else
 12782         {
 12783           if (x_dnd_movement_frame)
 12784             x_dnd_movement_frame = NULL;
 12785 
 12786           if (x_dnd_wheel_frame)
 12787             x_dnd_wheel_frame = NULL;
 12788 
 12789           if (hold_quit.kind != NO_EVENT)
 12790             EVENT_INIT (hold_quit);
 12791         }
 12792 #endif
 12793     }
 12794 
 12795   x_dnd_waiting_for_finish = false;
 12796 
 12797 #ifdef USE_GTK
 12798   current_hold_quit = NULL;
 12799 #endif
 12800   x_dnd_movement_frame = NULL;
 12801   x_dnd_wheel_frame = NULL;
 12802   x_restore_events_after_dnd (f, &root_window_attrs);
 12803 
 12804   if (x_dnd_return_frame == 3
 12805       && FRAME_LIVE_P (x_dnd_return_frame_object))
 12806     {
 12807       /* Deliberately preserve the last device if
 12808          x_dnd_return_frame_object is the drag source.  */
 12809 
 12810       if (x_dnd_return_frame_object != x_dnd_frame)
 12811         x_dnd_return_frame_object->last_mouse_device = Qnil;
 12812 
 12813       x_dnd_return_frame_object->mouse_moved = true;
 12814 
 12815       XSETFRAME (action, x_dnd_return_frame_object);
 12816       x_dnd_return_frame_object = NULL;
 12817 
 12818       return unbind_to (base, action);
 12819     }
 12820 
 12821   x_dnd_return_frame_object = NULL;
 12822   FRAME_DISPLAY_INFO (f)->grabbed = 0;
 12823 
 12824   if (!NILP (x_dnd_action_symbol))
 12825     return unbind_to (base, x_dnd_action_symbol);
 12826 
 12827   if (x_dnd_action != None)
 12828     {
 12829       block_input ();
 12830       x_catch_errors (FRAME_X_DISPLAY (f));
 12831       atom_name = x_get_atom_name (FRAME_DISPLAY_INFO (f),
 12832                                    x_dnd_action, &need_sync);
 12833 
 12834       if (need_sync)
 12835         x_uncatch_errors ();
 12836       else
 12837         /* No protocol request actually happened, so avoid the extra
 12838            sync by calling x_uncatch_errors_after_check instead.  */
 12839         x_uncatch_errors_after_check ();
 12840 
 12841       if (atom_name)
 12842         {
 12843           action = intern (atom_name);
 12844           xfree (atom_name);
 12845         }
 12846       else
 12847         action = Qnil;
 12848       unblock_input ();
 12849 
 12850       return unbind_to (base, action);
 12851     }
 12852 
 12853   return unbind_to (base, Qnil);
 12854 }
 12855 
 12856 #ifdef HAVE_XINPUT2
 12857 
 12858 /* Since the input extension assigns a keyboard focus to each master
 12859    device, there is no longer a 1:1 correspondence between the
 12860    selected frame and the focus frame immediately after the keyboard
 12861    focus is switched to a given frame.  This situation is handled by
 12862    keeping track of each master device's focus frame, the time of the
 12863    last interaction with that frame, and always keeping the focus on
 12864    the most recently selected frame.  We also use the pointer of the
 12865    device that is keeping the current frame focused in functions like
 12866    `mouse-position'.  */
 12867 
 12868 static void
 12869 xi_handle_focus_change (struct x_display_info *dpyinfo)
 12870 {
 12871   struct input_event ie;
 12872   struct frame *focus, *new;
 12873   struct xi_device_t *device, *source = NULL;
 12874   ptrdiff_t i;
 12875   Time time;
 12876 #ifdef USE_GTK
 12877   struct x_output *output;
 12878   GtkWidget *widget;
 12879 #endif
 12880 
 12881   focus = dpyinfo->x_focus_frame;
 12882   new = NULL;
 12883   time = 0;
 12884 
 12885   dpyinfo->client_pointer_device = -1;
 12886 
 12887   for (i = 0; i < dpyinfo->num_devices; ++i)
 12888     {
 12889       device = &dpyinfo->devices[i];
 12890 
 12891       if (device->focus_frame
 12892           && device->focus_frame_time > time)
 12893         {
 12894           new = device->focus_frame;
 12895           time = device->focus_frame_time;
 12896           source = device;
 12897 
 12898           /* Use this device for future calls to `mouse-position' etc.
 12899              If it is a keyboard, use its attached pointer.  */
 12900 
 12901           if (device->use == XIMasterKeyboard)
 12902             dpyinfo->client_pointer_device = device->attachment;
 12903           else
 12904             dpyinfo->client_pointer_device = device->device_id;
 12905         }
 12906       /* Even if the implicit focus was set after the explicit focus
 12907          on this specific device, the explicit focus is what really
 12908          matters.  So use it instead.  */
 12909       else if (device->focus_implicit_frame
 12910                && device->focus_implicit_time > time)
 12911         {
 12912           new = device->focus_implicit_frame;
 12913           time = device->focus_implicit_time;
 12914           source = device;
 12915 
 12916           /* Use this device for future calls to `mouse-position' etc.
 12917              If it is a keyboard, use its attached pointer.  */
 12918 
 12919           if (device->use == XIMasterKeyboard)
 12920             dpyinfo->client_pointer_device = device->attachment;
 12921           else
 12922             dpyinfo->client_pointer_device = device->device_id;
 12923         }
 12924     }
 12925 
 12926   if (new != focus && focus)
 12927     {
 12928 #ifdef HAVE_X_I18N
 12929       if (FRAME_XIC (focus))
 12930         XUnsetICFocus (FRAME_XIC (focus));
 12931 #endif
 12932 
 12933 #ifdef USE_GTK
 12934       output = FRAME_X_OUTPUT (focus);
 12935 
 12936       if (x_gtk_use_native_input)
 12937         {
 12938           gtk_im_context_focus_out (output->im_context);
 12939           gtk_im_context_set_client_window (output->im_context,
 12940                                             NULL);
 12941         }
 12942 #endif
 12943 
 12944       EVENT_INIT (ie);
 12945       ie.kind = FOCUS_OUT_EVENT;
 12946       XSETFRAME (ie.frame_or_window, focus);
 12947 
 12948       kbd_buffer_store_event (&ie);
 12949     }
 12950 
 12951   if (new != focus && new)
 12952     {
 12953 #ifdef HAVE_X_I18N
 12954       if (FRAME_XIC (new))
 12955         XSetICFocus (FRAME_XIC (new));
 12956 #endif
 12957 
 12958 #ifdef USE_GTK
 12959       output = FRAME_X_OUTPUT (new);
 12960 
 12961       if (x_gtk_use_native_input)
 12962         {
 12963           widget = FRAME_GTK_OUTER_WIDGET (new);
 12964 
 12965           gtk_im_context_focus_in (output->im_context);
 12966           gtk_im_context_set_client_window (output->im_context,
 12967                                             gtk_widget_get_window (widget));
 12968         }
 12969 #endif
 12970 
 12971       EVENT_INIT (ie);
 12972       ie.kind = FOCUS_IN_EVENT;
 12973       ie.device = source->name;
 12974       XSETFRAME (ie.frame_or_window, new);
 12975 
 12976       kbd_buffer_store_event (&ie);
 12977     }
 12978 
 12979   x_new_focus_frame (dpyinfo, new);
 12980 }
 12981 
 12982 static void
 12983 xi_focus_handle_for_device (struct x_display_info *dpyinfo,
 12984                             struct frame *mentioned_frame,
 12985                             XIEvent *base_event)
 12986 {
 12987   struct xi_device_t *device;
 12988   XIEnterEvent *event;
 12989 
 12990   /* XILeaveEvent, XIFocusInEvent, etc are just synonyms for
 12991      XIEnterEvent.  */
 12992   event = (XIEnterEvent *) base_event;
 12993   device = xi_device_from_id (dpyinfo, event->deviceid);
 12994 
 12995   if (!device)
 12996     return;
 12997 
 12998   switch (event->evtype)
 12999     {
 13000     case XI_FocusIn:
 13001       /* The last-focus-change time of the device changed, so update the
 13002          frame's user time.  */
 13003       x_display_set_last_user_time (dpyinfo, event->time,
 13004                                     event->send_event, true);
 13005 
 13006       device->focus_frame = mentioned_frame;
 13007       device->focus_frame_time = event->time;
 13008       break;
 13009 
 13010     case XI_FocusOut:
 13011       /* The last-focus-change time of the device changed, so update the
 13012          frame's user time.  */
 13013       x_display_set_last_user_time (dpyinfo, event->time,
 13014                                     event->send_event, false);
 13015 
 13016       device->focus_frame = NULL;
 13017 
 13018       /* So, unfortunately, the X Input Extension is implemented such
 13019          that means XI_Leave events will not have their focus field
 13020          set if the core focus is transferred to another window after
 13021          an entry event that pretends to (or really does) set the
 13022          implicit focus.  In addition, if the core focus is set, but
 13023          the extension focus on the client pointer is not, all
 13024          XI_Enter events will have their focus fields set, despite not
 13025          actually changing the effective focus window.  Combined with
 13026          almost all window managers not setting the focus on input
 13027          extension devices, this means that Emacs will continue to
 13028          think the implicit focus is set on one of its frames if the
 13029          actual (core) focus is transferred to another window while
 13030          the pointer remains inside a frame.  The only workaround in
 13031          this case is to clear the implicit focus along with
 13032          XI_FocusOut events, which is not correct at all, but better
 13033          than leaving frames in an incorrectly-focused state.
 13034          (bug#57468) */
 13035       device->focus_implicit_frame = NULL;
 13036       break;
 13037 
 13038     case XI_Enter:
 13039       if (!event->focus)
 13040         break;
 13041 
 13042       if (device->use == XIMasterPointer)
 13043         device = xi_device_from_id (dpyinfo, device->attachment);
 13044 
 13045       if (!device)
 13046         break;
 13047 
 13048       device->focus_implicit_frame = mentioned_frame;
 13049       device->focus_implicit_time = event->time;
 13050       break;
 13051 
 13052     case XI_Leave:
 13053       if (!event->focus)
 13054         break;
 13055 
 13056       if (device->use == XIMasterPointer)
 13057         device = xi_device_from_id (dpyinfo, device->attachment);
 13058 
 13059       if (!device)
 13060         break;
 13061 
 13062       device->focus_implicit_frame = NULL;
 13063       break;
 13064     }
 13065 
 13066   xi_handle_focus_change (dpyinfo);
 13067 }
 13068 
 13069 static void
 13070 xi_handle_delete_frame (struct x_display_info *dpyinfo,
 13071                         struct frame *f)
 13072 {
 13073   struct xi_device_t *device;
 13074   ptrdiff_t i;
 13075 
 13076   for (i = 0; i < dpyinfo->num_devices; ++i)
 13077     {
 13078       device = &dpyinfo->devices[i];
 13079 
 13080       if (device->focus_frame == f)
 13081         device->focus_frame = NULL;
 13082 
 13083       if (device->focus_implicit_frame == f)
 13084         device->focus_implicit_frame = NULL;
 13085     }
 13086 }
 13087 
 13088 /* Handle an interaction by DEVICE on frame F.  TIME is the time of
 13089    the interaction; if F isn't currently the global focus frame, but
 13090    is the focus of DEVICE, make it the focus frame.  */
 13091 
 13092 static void
 13093 xi_handle_interaction (struct x_display_info *dpyinfo,
 13094                        struct frame *f, struct xi_device_t *device,
 13095                        Time time)
 13096 {
 13097   bool change;
 13098 
 13099   /* If DEVICE is a pointer, use its attached keyboard device.  */
 13100   if (device->use == XIMasterPointer)
 13101     device = xi_device_from_id (dpyinfo, device->attachment);
 13102 
 13103   if (!device)
 13104     return;
 13105 
 13106   change = false;
 13107 
 13108   if (device->focus_frame == f)
 13109     {
 13110       device->focus_frame_time = time;
 13111       change = true;
 13112     }
 13113 
 13114   if (device->focus_implicit_frame == f)
 13115     {
 13116       device->focus_implicit_time = time;
 13117       change = true;
 13118     }
 13119 
 13120   /* If F isn't currently focused, update the focus state.  */
 13121   if (change && f != dpyinfo->x_focus_frame)
 13122     xi_handle_focus_change (dpyinfo);
 13123 }
 13124 
 13125 /* Return whether or not XEV actually represents a change in the
 13126    position of the pointer on DEVICE, with respect to the last event
 13127    received.  This is necessary because the input extension reports
 13128    motion events in very high resolution, while Emacs is only fast
 13129    enough to process motion events aligned to the pixel grid.  */
 13130 
 13131 static bool
 13132 xi_position_changed (struct xi_device_t *device, XIDeviceEvent *xev)
 13133 {
 13134   bool changed;
 13135 
 13136   changed = true;
 13137 
 13138   if (xev->event != device->last_motion_window)
 13139     goto out;
 13140 
 13141   if (lrint (xev->event_x) == device->last_motion_x
 13142       && lrint (xev->event_y) == device->last_motion_y)
 13143     {
 13144       changed = false;
 13145       goto out;
 13146     }
 13147 
 13148  out:
 13149   device->last_motion_x = lrint (xev->event_x);
 13150   device->last_motion_y = lrint (xev->event_y);
 13151   device->last_motion_window = xev->event;
 13152 
 13153   return changed;
 13154 }
 13155 
 13156 static void
 13157 xi_report_motion_window_clear (struct xi_device_t *device)
 13158 {
 13159   device->last_motion_window = None;
 13160 }
 13161 
 13162 #ifdef HAVE_XINPUT2_1
 13163 
 13164 /* Look up a scroll valuator in DEVICE by NUMBER.  */
 13165 
 13166 static struct xi_scroll_valuator_t *
 13167 xi_get_scroll_valuator (struct xi_device_t *device, int number)
 13168 {
 13169   int i;
 13170 
 13171   for (i = 0; i < device->scroll_valuator_count; ++i)
 13172     {
 13173       if (device->valuators[i].number == number)
 13174         return &device->valuators[i];
 13175     }
 13176 
 13177   return NULL;
 13178 }
 13179 
 13180 /* Check if EVENT, a DeviceChanged event, contains any scroll
 13181    valuators.  */
 13182 
 13183 static bool
 13184 xi_has_scroll_valuators (XIDeviceChangedEvent *event)
 13185 {
 13186   int i;
 13187 
 13188   for (i = 0; i < event->num_classes; ++i)
 13189     {
 13190       if (event->classes[i]->type == XIScrollClass)
 13191         return true;
 13192     }
 13193 
 13194   return false;
 13195 }
 13196 
 13197 /* Repopulate the information (touchpoint tracking information, scroll
 13198    valuators, etc) in DEVICE with the device classes provided in
 13199    CLASSES.  This is called upon receiving a DeviceChanged event.
 13200 
 13201    This function is not present on XI 2.0 as there are no worthwhile
 13202    classes there.  */
 13203 
 13204 static void
 13205 xi_handle_new_classes (struct x_display_info *dpyinfo, struct xi_device_t *device,
 13206                        XIAnyClassInfo **classes, int num_classes)
 13207 {
 13208   XIScrollClassInfo *scroll;
 13209   struct xi_scroll_valuator_t *valuator;
 13210   XIValuatorClassInfo *valuator_info;
 13211   int i;
 13212 #ifdef HAVE_XINPUT2_2
 13213   XITouchClassInfo *touch;
 13214 #endif
 13215 
 13216   if (dpyinfo->xi2_version < 1)
 13217     /* Emacs is connected to an XI 2.0 server, which reports no
 13218        classes of interest.  */
 13219     return;
 13220 
 13221   device->valuators = xnmalloc (num_classes,
 13222                                 sizeof *device->valuators);
 13223   device->scroll_valuator_count = 0;
 13224 #ifdef HAVE_XINPUT2_2
 13225   device->direct_p = false;
 13226 #endif
 13227 
 13228   for (i = 0; i < num_classes; ++i)
 13229     {
 13230       switch (classes[i]->type)
 13231         {
 13232         case XIScrollClass:
 13233           scroll = (XIScrollClassInfo *) classes[i];
 13234 
 13235           xi_populate_scroll_valuator (device,
 13236                                        device->scroll_valuator_count++,
 13237                                        scroll);
 13238           break;
 13239 
 13240 #ifdef HAVE_XINPUT2_2
 13241         case XITouchClass:
 13242           touch = (XITouchClassInfo *) classes[i];
 13243 
 13244           if (touch->mode == XIDirectTouch)
 13245             device->direct_p = true;
 13246           break;
 13247 #endif
 13248         }
 13249     }
 13250 
 13251   /* Restore the values of any scroll valuators that we already
 13252      know about.  */
 13253 
 13254   for (i = 0; i < num_classes; ++i)
 13255     {
 13256       if (classes[i]->type != XIValuatorClass)
 13257         continue;
 13258 
 13259       valuator_info = (XIValuatorClassInfo *) classes[i];
 13260 
 13261       /* Avoid restoring bogus values if some driver accidentally
 13262          specifies relative values in scroll valuator classes how the
 13263          input extension spec says they should be, but allow restoring
 13264          values when a value is set, which is how the input extension
 13265          actually behaves.  */
 13266 
 13267       if (valuator_info->value == 0.0
 13268           && valuator_info->mode != XIModeAbsolute)
 13269         continue;
 13270 
 13271       valuator = xi_get_scroll_valuator (device,
 13272                                          valuator_info->number);
 13273 
 13274       if (!valuator)
 13275         continue;
 13276 
 13277       valuator->invalid_p = false;
 13278       valuator->current_value = valuator_info->value;
 13279       valuator->emacs_value = 0;
 13280 
 13281       break;
 13282     }
 13283 }
 13284 
 13285 #endif
 13286 
 13287 /* Handle EVENT, a DeviceChanged event.  Look up the device that
 13288    changed, and update its information with the data in EVENT.  */
 13289 
 13290 static void
 13291 xi_handle_device_changed (struct x_display_info *dpyinfo,
 13292                           struct xi_device_t *device,
 13293                           XIDeviceChangedEvent *event)
 13294 {
 13295 #ifdef HAVE_XINPUT2_1
 13296   int ndevices;
 13297   XIDeviceInfo *info;
 13298 #endif
 13299 #ifdef HAVE_XINPUT2_2
 13300   struct xi_touch_point_t *tem, *last;
 13301 #endif
 13302 
 13303 #ifdef HAVE_XINPUT2_1
 13304   if (xi_has_scroll_valuators (event))
 13305     /* Scroll valuators are provided by this event.  Use the values
 13306        provided in this event to populate the device's new scroll
 13307        valuator list: if this event is a SlaveSwitch event caused by
 13308        wheel movement, then querying for the device info will probably
 13309        return the value after the wheel movement, leading to a delta
 13310        of 0 being computed upon handling the subsequent XI_Motion
 13311        event.  (bug#58980) */
 13312     xi_handle_new_classes (dpyinfo, device, event->classes,
 13313                            event->num_classes);
 13314   else
 13315     {
 13316       /* When a DeviceChange event is received for a master device,
 13317          the X server sometimes does not send any scroll valuators
 13318          along with it.  This is possibly an X server bug but I really
 13319          don't want to dig any further, so fetch the scroll valuators
 13320          manually.  (bug#57020) */
 13321 
 13322       x_catch_errors (dpyinfo->display);
 13323       info = XIQueryDevice (dpyinfo->display, event->deviceid,
 13324                             /* ndevices is always 1 if a deviceid is
 13325                                specified.  If the request fails, NULL will
 13326                                be returned.  */
 13327                             &ndevices);
 13328       x_uncatch_errors ();
 13329 
 13330       if (!info)
 13331         return;
 13332 
 13333       /* info contains the classes currently associated with the
 13334          event.  Apply them.  */
 13335       xi_handle_new_classes (dpyinfo, device, info->classes,
 13336                              info->num_classes);
 13337     }
 13338 #endif
 13339 
 13340 #ifdef HAVE_XINPUT2_2
 13341   /* The device is no longer a DirectTouch device, so remove any
 13342      touchpoints that we might have recorded.  */
 13343   if (!device->direct_p)
 13344     {
 13345       tem = device->touchpoints;
 13346 
 13347       while (tem)
 13348         {
 13349           last = tem;
 13350           tem = tem->next;
 13351           xfree (last);
 13352         }
 13353 
 13354       device->touchpoints = NULL;
 13355     }
 13356 #endif
 13357 }
 13358 
 13359 /* Remove the client-side record of every device in TO_DISABLE.
 13360    Called while processing XI_HierarchyChanged events.  We batch up
 13361    multiple disabled devices because it is more efficient to disable
 13362    them at once.  */
 13363 
 13364 static void
 13365 xi_disable_devices (struct x_display_info *dpyinfo,
 13366                     int *to_disable, int n_disabled)
 13367 {
 13368   struct xi_device_t *devices;
 13369   int ndevices, i, j;
 13370 #ifdef HAVE_XINPUT2_2
 13371   struct xi_touch_point_t *tem, *last;
 13372 #endif
 13373 
 13374   /* Don't pointlessly copy dpyinfo->devices if there are no devices
 13375      to disable.  */
 13376   if (!n_disabled)
 13377     return;
 13378 
 13379   ndevices = 0;
 13380   devices = xzalloc (sizeof *devices * dpyinfo->num_devices);
 13381 
 13382   /* Loop through every device currently in DPYINFO, and copy it to
 13383      DEVICES if it is not in TO_DISABLE.  Note that this function
 13384      should be called with input blocked, since xfree can otherwise
 13385      call GC, which will call mark_xterm with invalid state.  */
 13386   for (i = 0; i < dpyinfo->num_devices; ++i)
 13387     {
 13388       for (j = 0; j < n_disabled; ++j)
 13389         {
 13390           if (to_disable[j] == dpyinfo->devices[i].device_id)
 13391             {
 13392               if (x_dnd_in_progress
 13393                   /* If the drag-and-drop pointer device is being
 13394                      disabled, then cancel the drag and drop
 13395                      operation.  */
 13396                   && to_disable[j] == x_dnd_pointer_device)
 13397                 x_dnd_cancel_dnd_early ();
 13398 
 13399               /* Free any scroll valuators that might be on this
 13400                  device.  */
 13401 #ifdef HAVE_XINPUT2_1
 13402               xfree (dpyinfo->devices[i].valuators);
 13403 #endif
 13404 
 13405               /* Free any currently active touch points on this
 13406                  device.  */
 13407 #ifdef HAVE_XINPUT2_2
 13408               tem = dpyinfo->devices[i].touchpoints;
 13409               while (tem)
 13410                 {
 13411                   last = tem;
 13412                   tem = tem->next;
 13413                   xfree (last);
 13414                 }
 13415 #endif
 13416 
 13417               goto out;
 13418             }
 13419 
 13420           devices[ndevices++] = dpyinfo->devices[i];
 13421 
 13422         out:
 13423           continue;
 13424         }
 13425     }
 13426 
 13427   /* Free the old devices array and replace it with ndevices.  */
 13428   xfree (dpyinfo->devices);
 13429 
 13430   dpyinfo->devices = devices;
 13431   dpyinfo->num_devices = ndevices;
 13432 }
 13433 
 13434 #endif
 13435 
 13436 /* The focus may have changed.  Figure out if it is a real focus change,
 13437    by checking both FocusIn/Out and Enter/LeaveNotify events.
 13438 
 13439    Returns FOCUS_IN_EVENT event in *BUFP. */
 13440 
 13441 static void
 13442 x_detect_focus_change (struct x_display_info *dpyinfo, struct frame *frame,
 13443                        const XEvent *event, struct input_event *bufp)
 13444 {
 13445   if (!frame)
 13446     return;
 13447 
 13448   switch (event->type)
 13449     {
 13450     case EnterNotify:
 13451     case LeaveNotify:
 13452       {
 13453         struct frame *focus_frame = dpyinfo->x_focus_event_frame;
 13454         int focus_state
 13455           = focus_frame ? focus_frame->output_data.x->focus_state : 0;
 13456 
 13457         if (event->xcrossing.detail != NotifyInferior
 13458             && event->xcrossing.focus
 13459             && ! (focus_state & FOCUS_EXPLICIT))
 13460           x_focus_changed ((event->type == EnterNotify ? FocusIn : FocusOut),
 13461                            FOCUS_IMPLICIT,
 13462                            dpyinfo, frame, bufp);
 13463       }
 13464       break;
 13465 
 13466     case FocusIn:
 13467     case FocusOut:
 13468       /* Ignore transient focus events from hotkeys, window manager
 13469          gadgets, and other odd sources.  Some buggy window managers
 13470          (e.g., Muffin 4.2.4) send FocusIn events of this type without
 13471          corresponding FocusOut events even when some other window
 13472          really has focus, and these kinds of focus event don't
 13473          correspond to real user input changes.  GTK+ uses the same
 13474          filtering. */
 13475       if (event->xfocus.mode == NotifyGrab
 13476           || event->xfocus.mode == NotifyUngrab)
 13477         return;
 13478       x_focus_changed (event->type,
 13479                        (event->xfocus.detail == NotifyPointer ?
 13480                         FOCUS_IMPLICIT : FOCUS_EXPLICIT),
 13481                        dpyinfo, frame, bufp);
 13482       break;
 13483 
 13484     case ClientMessage:
 13485       if (event->xclient.message_type == dpyinfo->Xatom_XEMBED)
 13486         {
 13487           enum xembed_message msg = event->xclient.data.l[1];
 13488           x_focus_changed ((msg == XEMBED_FOCUS_IN ? FocusIn : FocusOut),
 13489                            FOCUS_EXPLICIT, dpyinfo, frame, bufp);
 13490         }
 13491       break;
 13492     }
 13493 }
 13494 
 13495 
 13496 #if (defined USE_LUCID && defined HAVE_XINPUT2) \
 13497   || (!defined USE_X_TOOLKIT && !defined USE_GTK)
 13498 /* Handle an event saying the mouse has moved out of an Emacs frame.  */
 13499 
 13500 void
 13501 x_mouse_leave (struct x_display_info *dpyinfo)
 13502 {
 13503 #if defined HAVE_XINPUT2 && !defined USE_X_TOOLKIT
 13504   struct xi_device_t *device;
 13505 #endif
 13506   Mouse_HLInfo *hlinfo;
 13507 
 13508   hlinfo = &dpyinfo->mouse_highlight;
 13509 
 13510   if (hlinfo->mouse_face_mouse_frame)
 13511     {
 13512       clear_mouse_face (hlinfo);
 13513       hlinfo->mouse_face_mouse_frame = NULL;
 13514     }
 13515 
 13516 #if defined HAVE_XINPUT2 && !defined USE_X_TOOLKIT
 13517   if (!dpyinfo->supports_xi2)
 13518     /* The call below is supposed to reset the implicit focus and
 13519        revert the focus back to the last explicitly focused frame.  It
 13520        doesn't work on input extension builds because focus tracking
 13521        does not set x_focus_event_frame, and proceeds on a per-device
 13522        basis.  On such builds, clear the implicit focus of the client
 13523        pointer instead.  */
 13524 #endif
 13525     x_new_focus_frame (dpyinfo, dpyinfo->x_focus_event_frame);
 13526 #if defined HAVE_XINPUT2 && !defined USE_X_TOOLKIT
 13527   else
 13528     {
 13529       if (dpyinfo->client_pointer_device == -1)
 13530         /* If there's no client pointer device, then no implicit focus
 13531            is currently set.  */
 13532         return;
 13533 
 13534       device = xi_device_from_id (dpyinfo, dpyinfo->client_pointer_device);
 13535 
 13536       if (device && device->focus_implicit_frame)
 13537         {
 13538           device->focus_implicit_frame = NULL;
 13539 
 13540           /* The focus might have changed; compute the new focus.  */
 13541           xi_handle_focus_change (dpyinfo);
 13542         }
 13543     }
 13544 #endif
 13545 }
 13546 #endif
 13547 
 13548 /* The focus has changed, or we have redirected a frame's focus to
 13549    another frame (this happens when a frame uses a surrogate
 13550    mini-buffer frame).  Shift the highlight as appropriate.
 13551 
 13552    The FRAME argument doesn't necessarily have anything to do with which
 13553    frame is being highlighted or un-highlighted; we only use it to find
 13554    the appropriate X display info.  */
 13555 
 13556 static void
 13557 XTframe_rehighlight (struct frame *frame)
 13558 {
 13559   x_frame_rehighlight (FRAME_DISPLAY_INFO (frame));
 13560 }
 13561 
 13562 static void
 13563 x_frame_rehighlight (struct x_display_info *dpyinfo)
 13564 {
 13565   struct frame *old_highlight = dpyinfo->highlight_frame;
 13566 
 13567   if (dpyinfo->x_focus_frame)
 13568     {
 13569       dpyinfo->highlight_frame
 13570         = ((FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame)))
 13571            ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame))
 13572            : dpyinfo->x_focus_frame);
 13573       if (! FRAME_LIVE_P (dpyinfo->highlight_frame))
 13574         {
 13575           fset_focus_frame (dpyinfo->x_focus_frame, Qnil);
 13576           dpyinfo->highlight_frame = dpyinfo->x_focus_frame;
 13577         }
 13578     }
 13579   else
 13580     dpyinfo->highlight_frame = 0;
 13581 
 13582   if (dpyinfo->highlight_frame != old_highlight)
 13583     {
 13584       if (old_highlight)
 13585         x_frame_unhighlight (old_highlight);
 13586       if (dpyinfo->highlight_frame)
 13587         x_frame_highlight (dpyinfo->highlight_frame);
 13588     }
 13589 }
 13590 
 13591 
 13592 
 13593 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc.  */
 13594 
 13595 /* Initialize mode_switch_bit and modifier_meaning.  */
 13596 static void
 13597 x_find_modifier_meanings (struct x_display_info *dpyinfo)
 13598 {
 13599   int min_code, max_code;
 13600   KeySym *syms;
 13601   int syms_per_code;
 13602   XModifierKeymap *mods;
 13603 #ifdef HAVE_XKB
 13604   int i;
 13605   int found_meta_p = false;
 13606   unsigned int vmodmask;
 13607 #endif
 13608 
 13609   dpyinfo->meta_mod_mask = 0;
 13610   dpyinfo->shift_lock_mask = 0;
 13611   dpyinfo->alt_mod_mask = 0;
 13612   dpyinfo->super_mod_mask = 0;
 13613   dpyinfo->hyper_mod_mask = 0;
 13614 
 13615 #ifdef HAVE_XKB
 13616   if (dpyinfo->xkb_desc
 13617       && dpyinfo->xkb_desc->server)
 13618     {
 13619       for (i = 0; i < XkbNumVirtualMods; i++)
 13620         {
 13621           vmodmask = dpyinfo->xkb_desc->server->vmods[i];
 13622 
 13623           if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_Meta)
 13624             {
 13625               dpyinfo->meta_mod_mask |= vmodmask;
 13626 
 13627               if (vmodmask)
 13628                 found_meta_p = true;
 13629             }
 13630           else if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_Alt)
 13631             dpyinfo->alt_mod_mask |= vmodmask;
 13632           else if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_Super)
 13633             dpyinfo->super_mod_mask |= vmodmask;
 13634           else if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_Hyper)
 13635             dpyinfo->hyper_mod_mask |= vmodmask;
 13636           else if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_ShiftLock)
 13637             dpyinfo->shift_lock_mask |= vmodmask;
 13638         }
 13639 
 13640       if (!found_meta_p)
 13641         {
 13642           dpyinfo->meta_mod_mask = dpyinfo->alt_mod_mask;
 13643           dpyinfo->alt_mod_mask = 0;
 13644         }
 13645 
 13646       if (dpyinfo->alt_mod_mask & dpyinfo->meta_mod_mask)
 13647         dpyinfo->alt_mod_mask &= ~dpyinfo->meta_mod_mask;
 13648 
 13649       if (dpyinfo->hyper_mod_mask & dpyinfo->super_mod_mask)
 13650         dpyinfo->hyper_mod_mask &= ~dpyinfo->super_mod_mask;
 13651 
 13652       return;
 13653     }
 13654 #endif
 13655 
 13656   XDisplayKeycodes (dpyinfo->display, &min_code, &max_code);
 13657 
 13658   syms = XGetKeyboardMapping (dpyinfo->display,
 13659                               min_code, max_code - min_code + 1,
 13660                               &syms_per_code);
 13661 
 13662   if (!syms)
 13663     {
 13664       dpyinfo->meta_mod_mask = Mod1Mask;
 13665       dpyinfo->super_mod_mask = Mod2Mask;
 13666       return;
 13667     }
 13668 
 13669   mods = XGetModifierMapping (dpyinfo->display);
 13670 
 13671   /* Scan the modifier table to see which modifier bits the Meta and
 13672      Alt keysyms are on.  */
 13673   {
 13674     int row, col;       /* The row and column in the modifier table.  */
 13675     bool found_alt_or_meta;
 13676 
 13677     for (row = 3; row < 8; row++)
 13678       {
 13679         found_alt_or_meta = false;
 13680         for (col = 0; col < mods->max_keypermod; col++)
 13681           {
 13682             KeyCode code = mods->modifiermap[(row * mods->max_keypermod) + col];
 13683 
 13684             /* Zeroes are used for filler.  Skip them.  */
 13685             if (code == 0)
 13686               continue;
 13687 
 13688             /* Are any of this keycode's keysyms a meta key?  */
 13689             {
 13690               int code_col;
 13691 
 13692               for (code_col = 0; code_col < syms_per_code; code_col++)
 13693                 {
 13694                   int sym = syms[((code - min_code) * syms_per_code) + code_col];
 13695 
 13696                   switch (sym)
 13697                     {
 13698                     case XK_Meta_L:
 13699                     case XK_Meta_R:
 13700                       found_alt_or_meta = true;
 13701                       dpyinfo->meta_mod_mask |= (1 << row);
 13702                       break;
 13703 
 13704                     case XK_Alt_L:
 13705                     case XK_Alt_R:
 13706                       found_alt_or_meta = true;
 13707                       dpyinfo->alt_mod_mask |= (1 << row);
 13708                       break;
 13709 
 13710                     case XK_Hyper_L:
 13711                     case XK_Hyper_R:
 13712                       if (!found_alt_or_meta)
 13713                         dpyinfo->hyper_mod_mask |= (1 << row);
 13714                       code_col = syms_per_code;
 13715                       col = mods->max_keypermod;
 13716                       break;
 13717 
 13718                     case XK_Super_L:
 13719                     case XK_Super_R:
 13720                       if (!found_alt_or_meta)
 13721                         dpyinfo->super_mod_mask |= (1 << row);
 13722                       code_col = syms_per_code;
 13723                       col = mods->max_keypermod;
 13724                       break;
 13725 
 13726                     case XK_Shift_Lock:
 13727                       /* Ignore this if it's not on the lock modifier.  */
 13728                       if (!found_alt_or_meta && ((1 << row) == LockMask))
 13729                         dpyinfo->shift_lock_mask = LockMask;
 13730                       code_col = syms_per_code;
 13731                       col = mods->max_keypermod;
 13732                       break;
 13733                     }
 13734                 }
 13735             }
 13736           }
 13737       }
 13738   }
 13739 
 13740   /* If we couldn't find any meta keys, accept any alt keys as meta keys.  */
 13741   if (! dpyinfo->meta_mod_mask)
 13742     {
 13743       dpyinfo->meta_mod_mask = dpyinfo->alt_mod_mask;
 13744       dpyinfo->alt_mod_mask = 0;
 13745     }
 13746 
 13747   /* If some keys are both alt and meta,
 13748      make them just meta, not alt.  */
 13749   if (dpyinfo->alt_mod_mask & dpyinfo->meta_mod_mask)
 13750     {
 13751       dpyinfo->alt_mod_mask &= ~dpyinfo->meta_mod_mask;
 13752     }
 13753 
 13754   /* If some keys are both super and hyper, make them just super.
 13755      Many X servers are misconfigured so that super and hyper are both
 13756      Mod4, but most users have no hyper key.  */
 13757   if (dpyinfo->hyper_mod_mask & dpyinfo->super_mod_mask)
 13758     dpyinfo->hyper_mod_mask &= ~dpyinfo->super_mod_mask;
 13759 
 13760   XFree (syms);
 13761 
 13762   if (dpyinfo->modmap)
 13763     XFreeModifiermap (dpyinfo->modmap);
 13764   dpyinfo->modmap = mods;
 13765 }
 13766 
 13767 /* Convert between the modifier bits X uses and the modifier bits
 13768    Emacs uses.  */
 13769 
 13770 int
 13771 x_x_to_emacs_modifiers (struct x_display_info *dpyinfo, int state)
 13772 {
 13773   int mod_ctrl = ctrl_modifier;
 13774   int mod_meta = meta_modifier;
 13775   int mod_alt  = alt_modifier;
 13776   int mod_hyper = hyper_modifier;
 13777   int mod_super = super_modifier;
 13778   Lisp_Object tem;
 13779 
 13780   tem = Fget (Vx_ctrl_keysym, Qmodifier_value);
 13781   if (FIXNUMP (tem)) mod_ctrl = XFIXNUM (tem) & INT_MAX;
 13782   tem = Fget (Vx_alt_keysym, Qmodifier_value);
 13783   if (FIXNUMP (tem)) mod_alt = XFIXNUM (tem) & INT_MAX;
 13784   tem = Fget (Vx_meta_keysym, Qmodifier_value);
 13785   if (FIXNUMP (tem)) mod_meta = XFIXNUM (tem) & INT_MAX;
 13786   tem = Fget (Vx_hyper_keysym, Qmodifier_value);
 13787   if (FIXNUMP (tem)) mod_hyper = XFIXNUM (tem) & INT_MAX;
 13788   tem = Fget (Vx_super_keysym, Qmodifier_value);
 13789   if (FIXNUMP (tem)) mod_super = XFIXNUM (tem) & INT_MAX;
 13790 
 13791   return (  ((state & (ShiftMask | dpyinfo->shift_lock_mask)) ? shift_modifier : 0)
 13792             | ((state & ControlMask)                    ? mod_ctrl      : 0)
 13793             | ((state & dpyinfo->meta_mod_mask)         ? mod_meta      : 0)
 13794             | ((state & dpyinfo->alt_mod_mask)          ? mod_alt       : 0)
 13795             | ((state & dpyinfo->super_mod_mask)        ? mod_super     : 0)
 13796             | ((state & dpyinfo->hyper_mod_mask)        ? mod_hyper     : 0));
 13797 }
 13798 
 13799 int
 13800 x_emacs_to_x_modifiers (struct x_display_info *dpyinfo, intmax_t state)
 13801 {
 13802   EMACS_INT mod_ctrl = ctrl_modifier;
 13803   EMACS_INT mod_meta = meta_modifier;
 13804   EMACS_INT mod_alt  = alt_modifier;
 13805   EMACS_INT mod_hyper = hyper_modifier;
 13806   EMACS_INT mod_super = super_modifier;
 13807 
 13808   Lisp_Object tem;
 13809 
 13810   tem = Fget (Vx_ctrl_keysym, Qmodifier_value);
 13811   if (FIXNUMP (tem)) mod_ctrl = XFIXNUM (tem);
 13812   tem = Fget (Vx_alt_keysym, Qmodifier_value);
 13813   if (FIXNUMP (tem)) mod_alt = XFIXNUM (tem);
 13814   tem = Fget (Vx_meta_keysym, Qmodifier_value);
 13815   if (FIXNUMP (tem)) mod_meta = XFIXNUM (tem);
 13816   tem = Fget (Vx_hyper_keysym, Qmodifier_value);
 13817   if (FIXNUMP (tem)) mod_hyper = XFIXNUM (tem);
 13818   tem = Fget (Vx_super_keysym, Qmodifier_value);
 13819   if (FIXNUMP (tem)) mod_super = XFIXNUM (tem);
 13820 
 13821 
 13822   return (  ((state & mod_alt)          ? dpyinfo->alt_mod_mask   : 0)
 13823             | ((state & mod_super)      ? dpyinfo->super_mod_mask : 0)
 13824             | ((state & mod_hyper)      ? dpyinfo->hyper_mod_mask : 0)
 13825             | ((state & shift_modifier) ? ShiftMask        : 0)
 13826             | ((state & mod_ctrl)       ? ControlMask      : 0)
 13827             | ((state & mod_meta)       ? dpyinfo->meta_mod_mask  : 0));
 13828 }
 13829 
 13830 /* Convert a keysym to its name.  */
 13831 
 13832 char *
 13833 get_keysym_name (int keysym)
 13834 {
 13835   char *value;
 13836 
 13837   block_input ();
 13838   value = XKeysymToString (keysym);
 13839   unblock_input ();
 13840 
 13841   return value;
 13842 }
 13843 
 13844 /* Given the root and event coordinates of an X event destined for F's
 13845    edit window, compute the offset between that window and F's root
 13846    window.  This information is then used as an optimization to avoid
 13847    synchronizing when converting coordinates from some other event to
 13848    F's edit window.  */
 13849 
 13850 static void
 13851 x_compute_root_window_offset (struct frame *f, int root_x, int root_y,
 13852                               int event_x, int event_y)
 13853 {
 13854   FRAME_X_OUTPUT (f)->window_offset_certain_p = true;
 13855   FRAME_X_OUTPUT (f)->root_x = root_x - event_x;
 13856   FRAME_X_OUTPUT (f)->root_y = root_y - event_y;
 13857 }
 13858 
 13859 /* Translate the given coordinates from the root window to the edit
 13860    window of FRAME, taking into account any cached root window
 13861    offsets.  This allows Emacs to avoid excessive calls to _XReply in
 13862    many cases while handling events, which would otherwise result in
 13863    slowdowns over slow network connections.  */
 13864 
 13865 void
 13866 x_translate_coordinates (struct frame *f, int root_x, int root_y,
 13867                          int *x_out, int *y_out)
 13868 {
 13869   struct x_output *output;
 13870   Window dummy;
 13871 
 13872   output = FRAME_X_OUTPUT (f);
 13873 
 13874   if (output->window_offset_certain_p)
 13875     {
 13876       /* Use the cached root window offset.  */
 13877       *x_out = root_x - output->root_x;
 13878       *y_out = root_y - output->root_y;
 13879 
 13880       return;
 13881     }
 13882 
 13883   /* Otherwise, do the transformation manually.  Then, cache the root
 13884      window position.  */
 13885   if (!XTranslateCoordinates (FRAME_X_DISPLAY (f),
 13886                               FRAME_DISPLAY_INFO (f)->root_window,
 13887                               FRAME_X_WINDOW (f), root_x, root_y,
 13888                               x_out, y_out, &dummy))
 13889     /* Use some dummy values.  This is not supposed to be called with
 13890        coordinates out of the screen.  */
 13891     *x_out = 0, *y_out = 0;
 13892   else
 13893     {
 13894       /* Cache the root window offset of the edit window.  */
 13895       output->window_offset_certain_p = true;
 13896       output->root_x = root_x - *x_out;
 13897       output->root_y = root_y - *y_out;
 13898     }
 13899 }
 13900 
 13901 /* Translate the given coordinates from the edit window of FRAME,
 13902    taking into account any cached root window offsets.  This is mainly
 13903    used from the popup menu code.  */
 13904 
 13905 void
 13906 x_translate_coordinates_to_root (struct frame *f, int x, int y,
 13907                                  int *x_out, int *y_out)
 13908 {
 13909   struct x_output *output;
 13910   Window dummy;
 13911 
 13912   output = FRAME_X_OUTPUT (f);
 13913 
 13914   if (output->window_offset_certain_p)
 13915     {
 13916       /* Use the cached root window offset.  */
 13917       *x_out = x + output->root_x;
 13918       *y_out = y + output->root_y;
 13919 
 13920       return;
 13921     }
 13922 
 13923   /* Otherwise, do the transform manually and compute and cache the
 13924      root window position.  */
 13925   if (!XTranslateCoordinates (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 13926                               FRAME_DISPLAY_INFO (f)->root_window,
 13927                               x, y, x_out, y_out, &dummy))
 13928     *x_out = 0, *y_out = 0;
 13929   else
 13930     {
 13931       /* Cache the root window offset of the edit window.  */
 13932       output->window_offset_certain_p = true;
 13933       output->root_x = *x_out - x;
 13934       output->root_y = *y_out - y;
 13935     }
 13936 }
 13937 
 13938 /* Do x-translate-coordinates, but try to avoid a roundtrip to the X
 13939    server at the cost of not returning `child', which most callers
 13940    have no reason to use.  */
 13941 
 13942 Lisp_Object
 13943 x_handle_translate_coordinates (struct frame *f, Lisp_Object dest_window,
 13944                                 int source_x, int source_y)
 13945 {
 13946   if (NILP (dest_window))
 13947     {
 13948       /* We are translating coordinates from a frame to the root
 13949          window.  Avoid a roundtrip if possible by using cached
 13950          coordinates.  */
 13951 
 13952       if (!FRAME_X_OUTPUT (f)->window_offset_certain_p)
 13953         return Qnil;
 13954 
 13955       return list3 (make_fixnum (source_x + FRAME_X_OUTPUT (f)->root_x),
 13956                     make_fixnum (source_y + FRAME_X_OUTPUT (f)->root_y),
 13957                     Qnil);
 13958     }
 13959 
 13960   return Qnil;
 13961 }
 13962 
 13963 /* The same, but for an XIDeviceEvent.  */
 13964 
 13965 #ifdef HAVE_XINPUT2
 13966 
 13967 static void
 13968 xi_compute_root_window_offset (struct frame *f, XIDeviceEvent *xev)
 13969 {
 13970   /* Truncate coordinates instead of rounding them, because that is
 13971      how the X server handles window hierarchy.  */
 13972   x_compute_root_window_offset (f, xev->root_x, xev->root_y,
 13973                                 xev->event_x, xev->event_y);
 13974 }
 13975 
 13976 static void
 13977 xi_compute_root_window_offset_enter (struct frame *f, XIEnterEvent *enter)
 13978 {
 13979   x_compute_root_window_offset (f, enter->root_x, enter->root_y,
 13980                                 enter->event_x, enter->event_y);
 13981 }
 13982 
 13983 #ifdef HAVE_XINPUT2_4
 13984 
 13985 static void
 13986 xi_compute_root_window_offset_pinch (struct frame *f, XIGesturePinchEvent *pev)
 13987 {
 13988   /* Truncate coordinates instead of rounding them, because that is
 13989      how the X server handles window hierarchy.  */
 13990   x_compute_root_window_offset (f, pev->root_x, pev->root_y,
 13991                                 pev->event_x, pev->event_y);
 13992 }
 13993 
 13994 #endif
 13995 
 13996 #endif
 13997 
 13998 static Bool
 13999 x_query_pointer_1 (struct x_display_info *dpyinfo,
 14000                    int client_pointer_device, Window w,
 14001                    Window *root_return, Window *child_return,
 14002                    int *root_x_return, int *root_y_return,
 14003                    int *win_x_return, int *win_y_return,
 14004                    unsigned int *mask_return)
 14005 {
 14006   Bool rc;
 14007   Display *dpy;
 14008 #ifdef HAVE_XINPUT2
 14009   bool had_errors;
 14010   XIModifierState modifiers;
 14011   XIButtonState buttons;
 14012   XIGroupState group; /* Unused.  */
 14013   double root_x, root_y, win_x, win_y;
 14014   unsigned int state;
 14015 #endif
 14016 
 14017   dpy = dpyinfo->display;
 14018 
 14019 #ifdef HAVE_XINPUT2
 14020   if (client_pointer_device != -1)
 14021     {
 14022       /* Catch errors caused by the device going away.  This is not
 14023          very expensive, since XIQueryPointer will sync anyway.  */
 14024       x_catch_errors (dpy);
 14025       rc = XIQueryPointer (dpyinfo->display,
 14026                            dpyinfo->client_pointer_device,
 14027                            w, root_return, child_return,
 14028                            &root_x, &root_y, &win_x, &win_y,
 14029                            &buttons, &modifiers, &group);
 14030       had_errors = x_had_errors_p (dpy);
 14031       x_uncatch_errors_after_check ();
 14032 
 14033       if (had_errors)
 14034         {
 14035           /* If the specified client pointer is the display's client
 14036              pointer, clear it now.  A new client pointer might not be
 14037              found before the next call to x_query_pointer_1 and
 14038              waiting for the error leads to excessive syncing.  */
 14039 
 14040           if (client_pointer_device == dpyinfo->client_pointer_device)
 14041             dpyinfo->client_pointer_device = -1;
 14042 
 14043           rc = XQueryPointer (dpyinfo->display, w, root_return,
 14044                               child_return, root_x_return,
 14045                               root_y_return, win_x_return,
 14046                               win_y_return, mask_return);
 14047         }
 14048       else
 14049         {
 14050           state = 0;
 14051 
 14052           xi_convert_button_state (&buttons, &state);
 14053           *mask_return = state | modifiers.effective;
 14054 
 14055           XFree (buttons.mask);
 14056 
 14057           *root_x_return = lrint (root_x);
 14058           *root_y_return = lrint (root_y);
 14059           *win_x_return = lrint (win_x);
 14060           *win_y_return = lrint (win_y);
 14061         }
 14062     }
 14063   else
 14064 #endif
 14065     rc = XQueryPointer (dpy, w, root_return, child_return,
 14066                         root_x_return, root_y_return, win_x_return,
 14067                         win_y_return, mask_return);
 14068 
 14069   return rc;
 14070 }
 14071 
 14072 Bool
 14073 x_query_pointer (Display *dpy, Window w, Window *root_return,
 14074                  Window *child_return, int *root_x_return,
 14075                  int *root_y_return, int *win_x_return,
 14076                  int *win_y_return, unsigned int *mask_return)
 14077 {
 14078   struct x_display_info *dpyinfo;
 14079 
 14080   dpyinfo = x_display_info_for_display (dpy);
 14081 
 14082   if (!dpyinfo)
 14083     emacs_abort ();
 14084 
 14085 #ifdef HAVE_XINPUT2
 14086   return x_query_pointer_1 (dpyinfo, dpyinfo->client_pointer_device,
 14087                             w, root_return, child_return, root_x_return,
 14088                             root_y_return, win_x_return, win_y_return,
 14089                             mask_return);
 14090 #else
 14091   return x_query_pointer_1 (dpyinfo, -1, w, root_return, child_return,
 14092                             root_x_return, root_y_return, win_x_return,
 14093                             win_y_return, mask_return);
 14094 #endif
 14095 }
 14096 
 14097 /* Mouse clicks and mouse movement.  Rah.
 14098 
 14099    Formerly, we used PointerMotionHintMask (in standard_event_mask)
 14100    so that we would have to call XQueryPointer after each MotionNotify
 14101    event to ask for another such event.  However, this made mouse tracking
 14102    slow, and there was a bug that made it eventually stop.
 14103 
 14104    Simply asking for MotionNotify all the time seems to work better.
 14105 
 14106    In order to avoid asking for motion events and then throwing most
 14107    of them away or busy-polling the server for mouse positions, we ask
 14108    the server for pointer motion hints.  This means that we get only
 14109    one event per group of mouse movements.  "Groups" are delimited by
 14110    other kinds of events (focus changes and button clicks, for
 14111    example), or by XQueryPointer calls; when one of these happens, we
 14112    get another MotionNotify event the next time the mouse moves.  This
 14113    is at least as efficient as getting motion events when mouse
 14114    tracking is on, and I suspect only negligibly worse when tracking
 14115    is off.  */
 14116 
 14117 /* Prepare a mouse-event in *RESULT for placement in the input queue.
 14118 
 14119    If the event is a button press, then note that we have grabbed
 14120    the mouse.
 14121 
 14122    The XButtonEvent structure passed as EVENT might not come from the
 14123    X server, and instead be artificially constructed from input
 14124    extension events.  In these special events, the only fields that
 14125    are initialized are `time', `button', `state', `type', `window' and
 14126    `x', `y', `x_root' and `y_root'.  This function should not access
 14127    any other fields in EVENT without also initializing the
 14128    corresponding fields in `bv' under the XI_ButtonPress and
 14129    XI_ButtonRelease labels inside `handle_one_xevent'.  */
 14130 
 14131 static Lisp_Object
 14132 x_construct_mouse_click (struct input_event *result,
 14133                          const XButtonEvent *event,
 14134                          struct frame *f)
 14135 {
 14136   int x = event->x;
 14137   int y = event->y;
 14138 
 14139   /* Make the event type NO_EVENT; we'll change that when we decide
 14140      otherwise.  */
 14141   result->kind = MOUSE_CLICK_EVENT;
 14142   result->code = event->button - Button1;
 14143   result->timestamp = event->time;
 14144   result->modifiers = (x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO (f),
 14145                                                event->state)
 14146                        | (event->type == ButtonRelease
 14147                           ? up_modifier
 14148                           : down_modifier));
 14149 
 14150   /* If result->window is not the frame's edit widget (which can
 14151      happen with GTK+ scroll bars, for example), translate the
 14152      coordinates so they appear at the correct position.  */
 14153   if (event->window != FRAME_X_WINDOW (f))
 14154     x_translate_coordinates (f, event->x_root, event->y_root,
 14155                              &x, &y);
 14156 
 14157   XSETINT (result->x, x);
 14158   XSETINT (result->y, y);
 14159   XSETFRAME (result->frame_or_window, f);
 14160   result->arg = Qnil;
 14161   return Qnil;
 14162 }
 14163 
 14164 /* Function to report a mouse movement to the mainstream Emacs code.
 14165    The input handler calls this.
 14166 
 14167    We have received a mouse movement event, which is given in *event.
 14168    If the mouse is over a different glyph than it was last time, tell
 14169    the mainstream emacs code by setting mouse_moved.  If not, ask for
 14170    another motion event, so we can check again the next time it moves.
 14171 
 14172    The XMotionEvent structure passed as EVENT might not come from the
 14173    X server, and instead be artificially constructed from input
 14174    extension events.  In these special events, the only fields that
 14175    are initialized are `time', `window', `send_event', `x' and `y'.
 14176    This function should not access any other fields in EVENT without
 14177    also initializing the corresponding fields in `ev' under the
 14178    XI_Motion, XI_Enter and XI_Leave labels inside
 14179    `handle_one_xevent'.  */
 14180 
 14181 static bool
 14182 x_note_mouse_movement (struct frame *frame, const XMotionEvent *event,
 14183                        Lisp_Object device)
 14184 {
 14185   XRectangle *r;
 14186   struct x_display_info *dpyinfo;
 14187 
 14188   if (!FRAME_X_OUTPUT (frame))
 14189     return false;
 14190 
 14191   dpyinfo = FRAME_DISPLAY_INFO (frame);
 14192   dpyinfo->last_mouse_movement_time = event->time;
 14193   dpyinfo->last_mouse_movement_time_send_event = event->send_event;
 14194   dpyinfo->last_mouse_motion_frame = frame;
 14195   dpyinfo->last_mouse_motion_x = event->x;
 14196   dpyinfo->last_mouse_motion_y = event->y;
 14197 
 14198   if (event->window != FRAME_X_WINDOW (frame))
 14199     {
 14200       frame->mouse_moved = true;
 14201       frame->last_mouse_device = device;
 14202       dpyinfo->last_mouse_scroll_bar = NULL;
 14203       note_mouse_highlight (frame, -1, -1);
 14204       dpyinfo->last_mouse_glyph_frame = NULL;
 14205       return true;
 14206     }
 14207 
 14208 
 14209   /* Has the mouse moved off the glyph it was on at the last sighting?  */
 14210   r = &dpyinfo->last_mouse_glyph;
 14211   if (frame != dpyinfo->last_mouse_glyph_frame
 14212       || event->x < r->x || event->x >= r->x + r->width
 14213       || event->y < r->y || event->y >= r->y + r->height)
 14214     {
 14215       frame->mouse_moved = true;
 14216       frame->last_mouse_device = device;
 14217       dpyinfo->last_mouse_scroll_bar = NULL;
 14218       note_mouse_highlight (frame, event->x, event->y);
 14219       /* Remember which glyph we're now on.  */
 14220       remember_mouse_glyph (frame, event->x, event->y, r);
 14221       dpyinfo->last_mouse_glyph_frame = frame;
 14222       return true;
 14223     }
 14224 
 14225   return false;
 14226 }
 14227 
 14228 /* Get a sibling below WINDOW on DPY at PARENT_X and PARENT_Y.  */
 14229 static Window
 14230 x_get_window_below (Display *dpy, Window window,
 14231                     int parent_x, int parent_y,
 14232                     int *inner_x, int *inner_y)
 14233 {
 14234   int rc, i, cx, cy;
 14235   XWindowAttributes attrs;
 14236   unsigned int nchildren;
 14237   Window root, parent, *children, value;
 14238   bool window_seen;
 14239 
 14240   /* TODO: rewrite to have less dependencies.  */
 14241 
 14242   children = NULL;
 14243   window_seen = false;
 14244   value = None;
 14245 
 14246   rc = XQueryTree (dpy, window, &root, &parent,
 14247                    &children, &nchildren);
 14248 
 14249   if (rc)
 14250     {
 14251       if (children)
 14252         XFree (children);
 14253 
 14254       rc = XQueryTree (dpy, parent, &root,
 14255                        &parent, &children, &nchildren);
 14256     }
 14257 
 14258   if (rc)
 14259     {
 14260       for (i = nchildren - 1; i >= 0; --i)
 14261         {
 14262           if (children[i] == window)
 14263             {
 14264               window_seen = true;
 14265               continue;
 14266             }
 14267 
 14268           if (!window_seen)
 14269             continue;
 14270 
 14271           rc = XGetWindowAttributes (dpy, children[i], &attrs);
 14272 
 14273           if (rc && attrs.map_state != IsViewable)
 14274             continue;
 14275 
 14276           if (rc && parent_x >= attrs.x
 14277               && parent_y >= attrs.y
 14278               && parent_x < attrs.x + attrs.width
 14279               && parent_y < attrs.y + attrs.height)
 14280             {
 14281               value = children[i];
 14282               cx = parent_x - attrs.x;
 14283               cy = parent_y - attrs.y;
 14284 
 14285               break;
 14286             }
 14287         }
 14288     }
 14289 
 14290   if (children)
 14291     XFree (children);
 14292 
 14293   if (value)
 14294     {
 14295       *inner_x = cx;
 14296       *inner_y = cy;
 14297     }
 14298 
 14299   return value;
 14300 }
 14301 
 14302 /* Like XTmouse_position, but much faster.  */
 14303 
 14304 static void
 14305 x_fast_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
 14306                        enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y,
 14307                        Time *timestamp)
 14308 {
 14309   int root_x, root_y, win_x, win_y;
 14310   unsigned int mask;
 14311   Window dummy;
 14312   struct scroll_bar *bar;
 14313   struct x_display_info *dpyinfo;
 14314   Lisp_Object tail, frame;
 14315   struct frame *f1;
 14316 
 14317   dpyinfo = FRAME_DISPLAY_INFO (*fp);
 14318 
 14319   if (dpyinfo->last_mouse_scroll_bar && !insist)
 14320     {
 14321       bar = dpyinfo->last_mouse_scroll_bar;
 14322 
 14323       if (bar->horizontal)
 14324         x_horizontal_scroll_bar_report_motion (fp, bar_window, part,
 14325                                                x, y, timestamp);
 14326       else
 14327         x_scroll_bar_report_motion (fp, bar_window, part,
 14328                                     x, y, timestamp);
 14329 
 14330       return;
 14331     }
 14332 
 14333   if (!EQ (Vx_use_fast_mouse_position, Qreally_fast))
 14334     {
 14335       /* This means that Emacs should select a frame and report the
 14336          mouse position relative to it.  The approach used here avoids
 14337          making multiple roundtrips to the X server querying for the
 14338          window beneath the pointer, and was borrowed from
 14339          haiku_mouse_position in haikuterm.c.  */
 14340 
 14341       FOR_EACH_FRAME (tail, frame)
 14342         {
 14343           if (FRAME_X_P (XFRAME (frame))
 14344               && (FRAME_DISPLAY_INFO (XFRAME (frame))
 14345                   == dpyinfo))
 14346             XFRAME (frame)->mouse_moved = false;
 14347         }
 14348 
 14349       if (gui_mouse_grabbed (dpyinfo)
 14350           && !EQ (track_mouse, Qdropping)
 14351           && !EQ (track_mouse, Qdrag_source))
 14352         /* Pick the last mouse frame if dropping.  */
 14353         f1 = dpyinfo->last_mouse_frame;
 14354       else
 14355         /* Otherwise, pick the last mouse motion frame.  */
 14356         f1 = dpyinfo->last_mouse_motion_frame;
 14357 
 14358       if (!f1 && (FRAME_X_P (SELECTED_FRAME ())
 14359                   && (FRAME_DISPLAY_INFO (SELECTED_FRAME ())
 14360                       == dpyinfo)))
 14361         f1 = SELECTED_FRAME ();
 14362 
 14363       if (!f1 || (!FRAME_X_P (f1) && (insist > 0)))
 14364         FOR_EACH_FRAME (tail, frame)
 14365           if (FRAME_X_P (XFRAME (frame))
 14366               && (FRAME_DISPLAY_INFO (XFRAME (frame))
 14367                   == dpyinfo)
 14368               && !FRAME_TOOLTIP_P (XFRAME (frame)))
 14369             f1 = XFRAME (frame);
 14370 
 14371       if (f1 && FRAME_TOOLTIP_P (f1))
 14372         f1 = NULL;
 14373 
 14374       if (f1 && FRAME_X_P (f1) && FRAME_X_WINDOW (f1))
 14375         {
 14376           if (!x_query_pointer (dpyinfo->display, FRAME_X_WINDOW (f1),
 14377                                 &dummy, &dummy, &root_x, &root_y,
 14378                                 &win_x, &win_y, &mask))
 14379             /* The pointer is out of the screen.  */
 14380             return;
 14381 
 14382           remember_mouse_glyph (f1, win_x, win_y,
 14383                                 &dpyinfo->last_mouse_glyph);
 14384           dpyinfo->last_mouse_glyph_frame = f1;
 14385 
 14386           *bar_window = Qnil;
 14387           *part = scroll_bar_nowhere;
 14388 
 14389           /* If track-mouse is `drag-source' and the mouse pointer is
 14390              certain to not be actually under the chosen frame, return
 14391              NULL in FP.  */
 14392           if (EQ (track_mouse, Qdrag_source)
 14393               && (win_x < 0 || win_y < 0
 14394                   || win_x >= FRAME_PIXEL_WIDTH (f1)
 14395                   || win_y >= FRAME_PIXEL_HEIGHT (f1)))
 14396             *fp = NULL;
 14397           else
 14398             *fp = f1;
 14399 
 14400           *timestamp = dpyinfo->last_mouse_movement_time;
 14401           XSETINT (*x, win_x);
 14402           XSETINT (*y, win_y);
 14403         }
 14404     }
 14405   else
 14406     {
 14407       /* This means Emacs should only report the coordinates of the
 14408          last mouse motion.  */
 14409 
 14410       if (dpyinfo->last_mouse_motion_frame)
 14411         {
 14412           *fp = dpyinfo->last_mouse_motion_frame;
 14413           *timestamp = dpyinfo->last_mouse_movement_time;
 14414           *x = make_fixnum (dpyinfo->last_mouse_motion_x);
 14415           *y = make_fixnum (dpyinfo->last_mouse_motion_y);
 14416           *bar_window = Qnil;
 14417           *part = scroll_bar_nowhere;
 14418 
 14419           FOR_EACH_FRAME (tail, frame)
 14420             {
 14421               if (FRAME_X_P (XFRAME (frame))
 14422                   && (FRAME_DISPLAY_INFO (XFRAME (frame))
 14423                       == dpyinfo))
 14424                 XFRAME (frame)->mouse_moved = false;
 14425             }
 14426 
 14427           dpyinfo->last_mouse_motion_frame->mouse_moved = false;
 14428         }
 14429     }
 14430 }
 14431 
 14432 /* Return the current position of the mouse.
 14433    *FP should be a frame which indicates which display to ask about.
 14434 
 14435    If the mouse movement started in a scroll bar, set *FP, *BAR_WINDOW,
 14436    and *PART to the frame, window, and scroll bar part that the mouse
 14437    is over.  Set *X and *Y to the portion and whole of the mouse's
 14438    position on the scroll bar.
 14439 
 14440    If the mouse movement started elsewhere, set *FP to the frame the
 14441    mouse is on, *BAR_WINDOW to nil, and *X and *Y to the character cell
 14442    the mouse is over.
 14443 
 14444    Set *TIMESTAMP to the server time-stamp for the time at which the mouse
 14445    was at this position.
 14446 
 14447    Don't store anything if we don't have a valid set of values to report.
 14448 
 14449    This clears the mouse_moved flag, so we can wait for the next mouse
 14450    movement.  */
 14451 
 14452 static void
 14453 XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
 14454                   enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y,
 14455                   Time *timestamp)
 14456 {
 14457   struct frame *f1, *maybe_tooltip;
 14458   struct x_display_info *dpyinfo;
 14459   bool unrelated_tooltip;
 14460 
 14461   dpyinfo = FRAME_DISPLAY_INFO (*fp);
 14462 
 14463   if (!NILP (Vx_use_fast_mouse_position))
 14464     {
 14465       /* The user says that Emacs is running over the network, and a
 14466          fast approximation of `mouse-position' should be used.
 14467 
 14468          Depending on what the value of `x-use-fast-mouse-position'
 14469          is, do one of two things: only perform the XQueryPointer to
 14470          obtain the coordinates from the last mouse frame, or only
 14471          return the last mouse motion frame and the
 14472          last_mouse_motion_x and Y.  */
 14473 
 14474       x_fast_mouse_position (fp, insist, bar_window, part, x,
 14475                              y, timestamp);
 14476       return;
 14477     }
 14478 
 14479   block_input ();
 14480 
 14481   if (dpyinfo->last_mouse_scroll_bar && insist == 0)
 14482     {
 14483       struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar;
 14484 
 14485       if (bar->horizontal)
 14486         x_horizontal_scroll_bar_report_motion (fp, bar_window, part, x, y, timestamp);
 14487       else
 14488         x_scroll_bar_report_motion (fp, bar_window, part, x, y, timestamp);
 14489     }
 14490   else
 14491     {
 14492       Window root;
 14493       int root_x, root_y;
 14494 
 14495       Window dummy_window;
 14496       int dummy;
 14497 
 14498       Lisp_Object frame, tail;
 14499 
 14500       /* Clear the mouse-moved flag for every frame on this display.  */
 14501       FOR_EACH_FRAME (tail, frame)
 14502         if (FRAME_X_P (XFRAME (frame))
 14503             && FRAME_X_DISPLAY (XFRAME (frame)) == FRAME_X_DISPLAY (*fp))
 14504           XFRAME (frame)->mouse_moved = false;
 14505 
 14506       dpyinfo->last_mouse_scroll_bar = NULL;
 14507 
 14508       /* Figure out which root window we're on.  */
 14509       x_query_pointer (FRAME_X_DISPLAY (*fp),
 14510                        DefaultRootWindow (FRAME_X_DISPLAY (*fp)),
 14511                        /* The root window which contains the pointer.  */
 14512                        &root,
 14513                        /* Trash which we can't trust if the pointer is on
 14514                           a different screen.  */
 14515                        &dummy_window,
 14516                        /* The position on that root window.  */
 14517                        &root_x, &root_y,
 14518                        /* More trash we can't trust.  */
 14519                        &dummy, &dummy,
 14520                        /* Modifier keys and pointer buttons, about which
 14521                           we don't care.  */
 14522                        (unsigned int *) &dummy);
 14523 
 14524       /* Now we have a position on the root; find the innermost window
 14525          containing the pointer.  */
 14526       {
 14527         Window win, child;
 14528 #ifdef USE_GTK
 14529         Window first_win = 0;
 14530 #endif
 14531         int win_x, win_y;
 14532         int parent_x, parent_y;
 14533 
 14534         win = root;
 14535         parent_x = root_x;
 14536         parent_y = root_y;
 14537 
 14538         /* XTranslateCoordinates can get errors if the window
 14539            structure is changing at the same time this function
 14540            is running.  So at least we must not crash from them.  */
 14541 
 14542         x_catch_errors (FRAME_X_DISPLAY (*fp));
 14543 
 14544         if (gui_mouse_grabbed (dpyinfo) && !EQ (track_mouse, Qdropping)
 14545             && !EQ (track_mouse, Qdrag_source))
 14546           {
 14547             /* If mouse was grabbed on a frame, give coords for that frame
 14548                even if the mouse is now outside it.  */
 14549             XTranslateCoordinates (FRAME_X_DISPLAY (*fp),
 14550                                    /* From-window.  */
 14551                                    root,
 14552                                    /* To-window.  */
 14553                                    FRAME_X_WINDOW (dpyinfo->last_mouse_frame),
 14554                                    /* From-position, to-position.  */
 14555                                    root_x, root_y, &win_x, &win_y,
 14556                                    /* Child of win.  */
 14557                                    &child);
 14558             f1 = dpyinfo->last_mouse_frame;
 14559           }
 14560         else
 14561           {
 14562             while (true)
 14563               {
 14564                 XTranslateCoordinates (FRAME_X_DISPLAY (*fp),
 14565                                        /* From-window, to-window.  */
 14566                                        root, win,
 14567                                        /* From-position, to-position.  */
 14568                                        root_x, root_y, &win_x, &win_y,
 14569                                        /* Child of win.  */
 14570                                        &child);
 14571 
 14572                 /* If CHILD is a tooltip frame, look below it if
 14573                    track-mouse is drag-source.  */
 14574                 if (child != None
 14575                     && (EQ (track_mouse, Qdrag_source)
 14576                         || EQ (track_mouse, Qdropping)))
 14577                   {
 14578                     maybe_tooltip = x_tooltip_window_to_frame (dpyinfo, child,
 14579                                                                &unrelated_tooltip);
 14580 
 14581                     if (maybe_tooltip || unrelated_tooltip)
 14582                       child = x_get_window_below (dpyinfo->display, child,
 14583                                                   parent_x, parent_y, &win_x,
 14584                                                   &win_y);
 14585                   }
 14586 
 14587                 if (child == None || child == win)
 14588                   {
 14589 #ifdef USE_GTK
 14590                     /* On GTK we have not inspected WIN yet.  If it has
 14591                        a frame and that frame has a parent, use it.  */
 14592                     struct frame *f = x_window_to_frame (dpyinfo, win);
 14593 
 14594                     if (f && FRAME_PARENT_FRAME (f))
 14595                       first_win = win;
 14596 #endif
 14597                     break;
 14598                   }
 14599 #ifdef USE_GTK
 14600                 /* We don't want to know the innermost window.  We
 14601                    want the edit window.  For non-Gtk+ the innermost
 14602                    window is the edit window.  For Gtk+ it might not
 14603                    be.  It might be the tool bar for example.  */
 14604                 if (x_window_to_frame (dpyinfo, win))
 14605                   /* But don't hurry.  We might find a child frame
 14606                      beneath.  */
 14607                   first_win = win;
 14608 #endif
 14609                 win = child;
 14610                 parent_x = win_x;
 14611                 parent_y = win_y;
 14612               }
 14613 
 14614 #ifdef USE_GTK
 14615             if (first_win)
 14616               win = first_win;
 14617 #endif
 14618 
 14619             /* Now we know that:
 14620                win is the innermost window containing the pointer
 14621                (XTC says it has no child containing the pointer),
 14622                win_x and win_y are the pointer's position in it
 14623                (XTC did this the last time through), and
 14624                parent_x and parent_y are the pointer's position in win's parent.
 14625                (They are what win_x and win_y were when win was child.
 14626                If win is the root window, it has no parent, and
 14627                parent_{x,y} are invalid, but that's okay, because we'll
 14628                never use them in that case.)  */
 14629 
 14630 #ifdef USE_GTK
 14631             /* We don't want to know the innermost window.  We
 14632                want the edit window.  */
 14633             f1 = x_window_to_frame (dpyinfo, win);
 14634 #else
 14635             /* Is win one of our frames?  */
 14636             f1 = x_any_window_to_frame (dpyinfo, win);
 14637 #endif
 14638 
 14639 #ifdef USE_X_TOOLKIT
 14640             /* If we end up with the menu bar window, say it's not
 14641                on the frame.  */
 14642             if (f1 != NULL
 14643                 && f1->output_data.x->menubar_widget
 14644                 && win == XtWindow (f1->output_data.x->menubar_widget))
 14645               f1 = NULL;
 14646 #endif /* USE_X_TOOLKIT */
 14647           }
 14648 
 14649         /* Set last user time to avoid confusing some window managers
 14650            about the tooltip displayed during drag-and-drop.  */
 14651 
 14652         if ((EQ (track_mouse, Qdrag_source)
 14653              || EQ (track_mouse, Qdropping))
 14654             && (dpyinfo->last_user_time
 14655                 < dpyinfo->last_mouse_movement_time))
 14656           x_display_set_last_user_time (dpyinfo,
 14657                                         dpyinfo->last_mouse_movement_time,
 14658                                         dpyinfo->last_mouse_movement_time_send_event,
 14659                                         true);
 14660 
 14661         if ((!f1 || FRAME_TOOLTIP_P (f1))
 14662             && (EQ (track_mouse, Qdropping)
 14663                 || EQ (track_mouse, Qdrag_source))
 14664             && gui_mouse_grabbed (dpyinfo))
 14665           {
 14666             /* When dropping then if we didn't get a frame or only a
 14667                tooltip frame and the mouse was grabbed on a frame,
 14668                give coords for that frame even if the mouse is now
 14669                outside it.  */
 14670             XTranslateCoordinates (FRAME_X_DISPLAY (*fp),
 14671                                    /* From-window.  */
 14672                                    root,
 14673                                    /* To-window.  */
 14674                                    FRAME_X_WINDOW (dpyinfo->last_mouse_frame),
 14675                                    /* From-position, to-position.  */
 14676                                    root_x, root_y, &win_x, &win_y,
 14677                                    /* Child of win.  */
 14678                                    &child);
 14679 
 14680             if (!EQ (track_mouse, Qdrag_source)
 14681                 /* Don't let tooltips interfere.  */
 14682                 || (f1 && FRAME_TOOLTIP_P (f1)))
 14683               f1 = dpyinfo->last_mouse_frame;
 14684             else
 14685               {
 14686                 /* Don't set FP but do set WIN_X and WIN_Y in this
 14687                    case, so make_lispy_movement knows which
 14688                    coordinates to report.  */
 14689                 *bar_window = Qnil;
 14690                 *part = 0;
 14691                 *fp = NULL;
 14692                 XSETINT (*x, win_x);
 14693                 XSETINT (*y, win_y);
 14694                 *timestamp = dpyinfo->last_mouse_movement_time;
 14695               }
 14696           }
 14697         else if (f1 && FRAME_TOOLTIP_P (f1))
 14698           f1 = NULL;
 14699 
 14700         if (x_had_errors_p (dpyinfo->display))
 14701           f1 = NULL;
 14702 
 14703         x_uncatch_errors_after_check ();
 14704 
 14705         /* If not, is it one of our scroll bars?  */
 14706         if (!f1)
 14707           {
 14708             struct scroll_bar *bar;
 14709 
 14710             bar = x_window_to_scroll_bar (dpyinfo->display, win, 2);
 14711 
 14712             if (bar)
 14713               {
 14714                 f1 = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 14715                 win_x = parent_x;
 14716                 win_y = parent_y;
 14717               }
 14718           }
 14719 
 14720         if (!f1 && insist > 0)
 14721           f1 = SELECTED_FRAME ();
 14722 
 14723         if (f1 && FRAME_X_P (f1))
 14724           {
 14725             /* Ok, we found a frame.  Store all the values.
 14726                last_mouse_glyph is a rectangle used to reduce the
 14727                generation of mouse events.  To not miss any motion
 14728                events, we must divide the frame into rectangles of the
 14729                size of the smallest character that could be displayed
 14730                on it, i.e. into the same rectangles that matrices on
 14731                the frame are divided into.  */
 14732 
 14733             dpyinfo = FRAME_DISPLAY_INFO (f1);
 14734             remember_mouse_glyph (f1, win_x, win_y, &dpyinfo->last_mouse_glyph);
 14735             dpyinfo->last_mouse_glyph_frame = f1;
 14736 
 14737             *bar_window = Qnil;
 14738             *part = 0;
 14739             *fp = f1;
 14740             XSETINT (*x, win_x);
 14741             XSETINT (*y, win_y);
 14742             *timestamp = dpyinfo->last_mouse_movement_time;
 14743           }
 14744       }
 14745     }
 14746 
 14747   unblock_input ();
 14748 }
 14749 
 14750 
 14751 
 14752 /***********************************************************************
 14753                                Scroll bars
 14754  ***********************************************************************/
 14755 
 14756 /* Scroll bar support.  */
 14757 
 14758 #if defined HAVE_XINPUT2
 14759 
 14760 /* Select for input extension events used by scroll bars.  This will
 14761    result in the corresponding core events not being generated for
 14762    SCROLL_BAR.  */
 14763 
 14764 MAYBE_UNUSED static void
 14765 xi_select_scroll_bar_events (struct x_display_info *dpyinfo,
 14766                              Window scroll_bar)
 14767 {
 14768   XIEventMask mask;
 14769   unsigned char *m;
 14770   ptrdiff_t length;
 14771 
 14772   length = XIMaskLen (XI_LASTEVENT);
 14773   mask.mask = m = alloca (length);
 14774   memset (m, 0, length);
 14775   mask.mask_len = length;
 14776 
 14777   mask.deviceid = XIAllMasterDevices;
 14778   XISetMask (m, XI_ButtonPress);
 14779   XISetMask (m, XI_ButtonRelease);
 14780   XISetMask (m, XI_Motion);
 14781   XISetMask (m, XI_Enter);
 14782   XISetMask (m, XI_Leave);
 14783 
 14784   XISelectEvents (dpyinfo->display, scroll_bar, &mask, 1);
 14785 }
 14786 
 14787 #endif
 14788 
 14789 /* Given an X window ID and a DISPLAY, find the struct scroll_bar which
 14790    manages it.
 14791    This can be called in GC, so we have to make sure to strip off mark
 14792    bits.  */
 14793 
 14794 static struct scroll_bar *
 14795 x_window_to_scroll_bar (Display *display, Window window_id, int type)
 14796 {
 14797   Lisp_Object tail, frame;
 14798 
 14799 #if defined (USE_GTK) && !defined (HAVE_GTK3) && defined (USE_TOOLKIT_SCROLL_BARS)
 14800   window_id = (Window) xg_get_scroll_id_for_window (display, window_id);
 14801 #endif /* USE_GTK && !HAVE_GTK3  && USE_TOOLKIT_SCROLL_BARS */
 14802 
 14803   FOR_EACH_FRAME (tail, frame)
 14804     {
 14805       Lisp_Object bar, condemned;
 14806 
 14807       if (! FRAME_X_P (XFRAME (frame)))
 14808         continue;
 14809 
 14810       /* Scan this frame's scroll bar list for a scroll bar with the
 14811          right window ID.  */
 14812       condemned = FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame));
 14813       for (bar = FRAME_SCROLL_BARS (XFRAME (frame));
 14814            /* This trick allows us to search both the ordinary and
 14815               condemned scroll bar lists with one loop.  */
 14816            ! NILP (bar) || (bar = condemned,
 14817                                condemned = Qnil,
 14818                                ! NILP (bar));
 14819            bar = XSCROLL_BAR (bar)->next)
 14820         if (XSCROLL_BAR (bar)->x_window == window_id
 14821             && FRAME_X_DISPLAY (XFRAME (frame)) == display
 14822             && (type == 2
 14823                 || (type == 1 && XSCROLL_BAR (bar)->horizontal)
 14824                 || (type == 0 && !XSCROLL_BAR (bar)->horizontal)))
 14825           return XSCROLL_BAR (bar);
 14826     }
 14827 
 14828   return NULL;
 14829 }
 14830 
 14831 
 14832 #if defined USE_LUCID
 14833 
 14834 /* Return the Lucid menu bar WINDOW is part of.  Return null
 14835    if WINDOW is not part of a menu bar.  */
 14836 
 14837 static Widget
 14838 x_window_to_menu_bar (Window window)
 14839 {
 14840   Lisp_Object tail, frame;
 14841 
 14842   FOR_EACH_FRAME (tail, frame)
 14843     if (FRAME_X_P (XFRAME (frame)))
 14844       {
 14845         Widget menu_bar = XFRAME (frame)->output_data.x->menubar_widget;
 14846 
 14847         if (menu_bar && xlwmenu_window_p (menu_bar, window))
 14848           return menu_bar;
 14849       }
 14850   return NULL;
 14851 }
 14852 
 14853 #endif /* USE_LUCID */
 14854 
 14855 
 14856 /************************************************************************
 14857                          Toolkit scroll bars
 14858  ************************************************************************/
 14859 
 14860 #ifdef USE_TOOLKIT_SCROLL_BARS
 14861 
 14862 static void x_send_scroll_bar_event (Lisp_Object, enum scroll_bar_part,
 14863                                      int, int, bool);
 14864 
 14865 /* Lisp window being scrolled.  Set when starting to interact with
 14866    a toolkit scroll bar, reset to nil when ending the interaction.  */
 14867 
 14868 static Lisp_Object window_being_scrolled;
 14869 
 14870 static Time
 14871 x_get_last_toolkit_time (struct x_display_info *dpyinfo)
 14872 {
 14873 #ifdef USE_X_TOOLKIT
 14874   return XtLastTimestampProcessed (dpyinfo->display);
 14875 #else
 14876   return dpyinfo->last_user_time;
 14877 #endif
 14878 }
 14879 
 14880 #ifndef USE_GTK
 14881 /* Id of action hook installed for scroll bars and horizontal scroll
 14882    bars.  */
 14883 
 14884 static XtActionHookId action_hook_id;
 14885 static XtActionHookId horizontal_action_hook_id;
 14886 
 14887 /* Whether this is an Xaw with arrow-scrollbars.  This should imply
 14888    that movements of 1/20 of the screen size are mapped to up/down.  */
 14889 
 14890 static Boolean xaw3d_arrow_scroll;
 14891 
 14892 /* Whether the drag scrolling maintains the mouse at the top of the
 14893    thumb.  If not, resizing the thumb needs to be done more carefully
 14894    to avoid jerkiness.  */
 14895 
 14896 static Boolean xaw3d_pick_top;
 14897 
 14898 /* Action hook installed via XtAppAddActionHook when toolkit scroll
 14899    bars are used..  The hook is responsible for detecting when
 14900    the user ends an interaction with the scroll bar, and generates
 14901    a `end-scroll' SCROLL_BAR_CLICK_EVENT' event if so.  */
 14902 
 14903 static void
 14904 xt_action_hook (Widget widget, XtPointer client_data, String action_name,
 14905                 XEvent *event, String *params, Cardinal *num_params)
 14906 {
 14907   bool scroll_bar_p;
 14908   const char *end_action;
 14909 
 14910 #ifdef USE_MOTIF
 14911   scroll_bar_p = XmIsScrollBar (widget);
 14912   end_action = "Release";
 14913 #else /* !USE_MOTIF i.e. use Xaw */
 14914   scroll_bar_p = XtIsSubclass (widget, scrollbarWidgetClass);
 14915   end_action = "EndScroll";
 14916 #endif /* USE_MOTIF */
 14917 
 14918   if (scroll_bar_p
 14919       && strcmp (action_name, end_action) == 0
 14920       && WINDOWP (window_being_scrolled))
 14921     {
 14922       struct window *w;
 14923       struct scroll_bar *bar;
 14924 
 14925       x_send_scroll_bar_event (window_being_scrolled,
 14926                                scroll_bar_end_scroll, 0, 0, false);
 14927       w = XWINDOW (window_being_scrolled);
 14928       bar = XSCROLL_BAR (w->vertical_scroll_bar);
 14929 
 14930       if (bar->dragging != -1)
 14931         {
 14932           bar->dragging = -1;
 14933           /* The thumb size is incorrect while dragging: fix it.  */
 14934           set_vertical_scroll_bar (w);
 14935         }
 14936       window_being_scrolled = Qnil;
 14937 #if defined (USE_LUCID)
 14938       bar->last_seen_part = scroll_bar_nowhere;
 14939 #endif
 14940       /* Xt timeouts no longer needed.  */
 14941       toolkit_scroll_bar_interaction = false;
 14942     }
 14943 }
 14944 
 14945 
 14946 static void
 14947 xt_horizontal_action_hook (Widget widget, XtPointer client_data, String action_name,
 14948                            XEvent *event, String *params, Cardinal *num_params)
 14949 {
 14950   bool scroll_bar_p;
 14951   const char *end_action;
 14952 
 14953 #ifdef USE_MOTIF
 14954   scroll_bar_p = XmIsScrollBar (widget);
 14955   end_action = "Release";
 14956 #else /* !USE_MOTIF i.e. use Xaw */
 14957   scroll_bar_p = XtIsSubclass (widget, scrollbarWidgetClass);
 14958   end_action = "EndScroll";
 14959 #endif /* USE_MOTIF */
 14960 
 14961   if (scroll_bar_p
 14962       && strcmp (action_name, end_action) == 0
 14963       && WINDOWP (window_being_scrolled))
 14964     {
 14965       struct window *w;
 14966       struct scroll_bar *bar;
 14967 
 14968       x_send_scroll_bar_event (window_being_scrolled,
 14969                                scroll_bar_end_scroll, 0, 0, true);
 14970       w = XWINDOW (window_being_scrolled);
 14971       if (!NILP (w->horizontal_scroll_bar))
 14972         {
 14973           bar = XSCROLL_BAR (w->horizontal_scroll_bar);
 14974           if (bar->dragging != -1)
 14975             {
 14976               bar->dragging = -1;
 14977               /* The thumb size is incorrect while dragging: fix it.  */
 14978               set_horizontal_scroll_bar (w);
 14979             }
 14980           window_being_scrolled = Qnil;
 14981 #if defined (USE_LUCID)
 14982           bar->last_seen_part = scroll_bar_nowhere;
 14983 #endif
 14984           /* Xt timeouts no longer needed.  */
 14985           toolkit_scroll_bar_interaction = false;
 14986         }
 14987     }
 14988 }
 14989 #endif /* not USE_GTK */
 14990 
 14991 /* Protect WINDOW from garbage collection until a matching scroll bar
 14992    message is received.  Return whether or not protection
 14993    succeeded.  */
 14994 static bool
 14995 x_protect_window_for_callback (struct x_display_info *dpyinfo,
 14996                                Lisp_Object window)
 14997 {
 14998   if (dpyinfo->n_protected_windows + 1
 14999       >= dpyinfo->protected_windows_max)
 15000     return false;
 15001 
 15002   dpyinfo->protected_windows[dpyinfo->n_protected_windows++]
 15003     = window;
 15004   return true;
 15005 }
 15006 
 15007 static Lisp_Object
 15008 x_unprotect_window_for_callback (struct x_display_info *dpyinfo)
 15009 {
 15010   Lisp_Object window;
 15011 
 15012   if (!dpyinfo->n_protected_windows)
 15013     return Qnil;
 15014 
 15015   window = dpyinfo->protected_windows[0];
 15016 
 15017   dpyinfo->n_protected_windows--;
 15018 
 15019   if (dpyinfo->n_protected_windows)
 15020     memmove (dpyinfo->protected_windows, &dpyinfo->protected_windows[1],
 15021              sizeof (Lisp_Object) * dpyinfo->n_protected_windows);
 15022 
 15023   return window;
 15024 }
 15025 
 15026 /* Send a client message with message type Xatom_Scrollbar for a
 15027    scroll action to the frame of WINDOW.  PART is a value identifying
 15028    the part of the scroll bar that was clicked on.  PORTION is the
 15029    amount to scroll of a whole of WHOLE.  */
 15030 
 15031 static void
 15032 x_send_scroll_bar_event (Lisp_Object window, enum scroll_bar_part part,
 15033                          int portion, int whole, bool horizontal)
 15034 {
 15035   XEvent event;
 15036   XClientMessageEvent *ev = &event.xclient;
 15037   struct window *w = XWINDOW (window);
 15038   struct frame *f = XFRAME (w->frame);
 15039   intptr_t iw = (intptr_t) w;
 15040   verify (INTPTR_WIDTH <= 64);
 15041   int sign_shift = INTPTR_WIDTH - 32;
 15042 
 15043   /* Don't do anything if too many scroll bar events have been
 15044      sent but not received.  */
 15045   if (!x_protect_window_for_callback (FRAME_DISPLAY_INFO (f), window))
 15046     return;
 15047 
 15048   block_input ();
 15049   /* Construct a ClientMessage event to send to the frame.  */
 15050   ev->type = ClientMessage;
 15051   ev->message_type = (horizontal
 15052                       ? FRAME_DISPLAY_INFO (f)->Xatom_Horizontal_Scrollbar
 15053                       : FRAME_DISPLAY_INFO (f)->Xatom_Scrollbar);
 15054   ev->display = FRAME_X_DISPLAY (f);
 15055   ev->window = FRAME_X_WINDOW (f);
 15056   ev->format = 32;
 15057 
 15058   /* A 32-bit X client can pass a window pointer through the X server
 15059      as-is.
 15060 
 15061      A 64-bit client is in trouble because a pointer does not fit in
 15062      the 32 bits given for ClientMessage data and will be truncated by
 15063      Xlib.  So use two slots and hope that X12 will resolve such
 15064      issues someday.  */
 15065   ev->data.l[0] = iw >> 31 >> 1;
 15066   ev->data.l[1] = sign_shift <= 0 ? iw : iw << sign_shift >> sign_shift;
 15067   ev->data.l[2] = part;
 15068   ev->data.l[3] = portion;
 15069   ev->data.l[4] = whole;
 15070 
 15071   /* Make Xt timeouts work while the scroll bar is active.  */
 15072 #ifdef USE_X_TOOLKIT
 15073   toolkit_scroll_bar_interaction = true;
 15074   x_activate_timeout_atimer ();
 15075 #endif
 15076 
 15077   /* Setting the event mask to zero means that the message will
 15078      be sent to the client that created the window, and if that
 15079      window no longer exists, no event will be sent.  */
 15080   XSendEvent (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), False,
 15081               NoEventMask, &event);
 15082   unblock_input ();
 15083 }
 15084 
 15085 
 15086 /* Transform a scroll bar ClientMessage EVENT to an Emacs input event
 15087    in *IEVENT.  */
 15088 
 15089 static void
 15090 x_scroll_bar_to_input_event (struct x_display_info *dpyinfo,
 15091                              const XEvent *event,
 15092                              struct input_event *ievent)
 15093 {
 15094   Lisp_Object window;
 15095 
 15096   /* Every time a scroll bar ClientMessage event is sent, the window
 15097      is pushed onto a queue that is traced for garbage collection.
 15098      Every time we need a window for a read scroll bar event, we
 15099      simply read from the other side of the queue.  */
 15100   window = x_unprotect_window_for_callback (dpyinfo);
 15101 
 15102   if (NILP (window))
 15103     {
 15104       /* This means we are getting extra scroll bar events for some
 15105          reason, and shouldn't be possible in practice.  */
 15106       EVENT_INIT (*ievent);
 15107       return;
 15108     }
 15109 
 15110   ievent->kind = SCROLL_BAR_CLICK_EVENT;
 15111   ievent->frame_or_window = window;
 15112   ievent->arg = Qnil;
 15113   ievent->timestamp = x_get_last_toolkit_time (dpyinfo);
 15114   ievent->code = 0;
 15115   ievent->part = event->xclient.data.l[2];
 15116   ievent->x = make_fixnum (event->xclient.data.l[3]);
 15117   ievent->y = make_fixnum (event->xclient.data.l[4]);
 15118   ievent->modifiers = 0;
 15119 }
 15120 
 15121 /* Transform a horizontal scroll bar ClientMessage EVENT to an Emacs
 15122    input event in *IEVENT.  */
 15123 
 15124 static void
 15125 x_horizontal_scroll_bar_to_input_event (struct x_display_info *dpyinfo,
 15126                                         const XEvent *event,
 15127                                         struct input_event *ievent)
 15128 {
 15129   Lisp_Object window;
 15130 
 15131   /* Every time a scroll bar ClientMessage event is sent, the window
 15132      is pushed onto a queue that is traced for garbage collection.
 15133      Every time we need a window for a read scroll bar event, we
 15134      simply read from the other side of the queue.  */
 15135   window = x_unprotect_window_for_callback (dpyinfo);
 15136 
 15137   if (NILP (window))
 15138     {
 15139       /* This means we are getting extra scroll bar events for some
 15140          reason, and shouldn't be possible in practice.  */
 15141       EVENT_INIT (*ievent);
 15142       return;
 15143     }
 15144 
 15145   ievent->kind = HORIZONTAL_SCROLL_BAR_CLICK_EVENT;
 15146   ievent->frame_or_window = window;
 15147   ievent->arg = Qnil;
 15148   ievent->timestamp = x_get_last_toolkit_time (dpyinfo);
 15149   ievent->code = 0;
 15150   ievent->part = event->xclient.data.l[2];
 15151   ievent->x = make_fixnum (event->xclient.data.l[3]);
 15152   ievent->y = make_fixnum (event->xclient.data.l[4]);
 15153   ievent->modifiers = 0;
 15154 }
 15155 
 15156 
 15157 #ifdef USE_MOTIF
 15158 
 15159 /* Minimum and maximum values used for Motif scroll bars.  */
 15160 
 15161 #define XM_SB_MAX 10000000
 15162 
 15163 /* Scroll bar callback for Motif scroll bars.  WIDGET is the scroll
 15164    bar widget.  CLIENT_DATA is a pointer to the scroll_bar structure.
 15165    CALL_DATA is a pointer to a XmScrollBarCallbackStruct.  */
 15166 
 15167 static void
 15168 xm_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data)
 15169 {
 15170   struct scroll_bar *bar = client_data;
 15171   XmScrollBarCallbackStruct *cs = call_data;
 15172   enum scroll_bar_part part = scroll_bar_nowhere;
 15173   bool horizontal = bar->horizontal;
 15174   int whole = 0, portion = 0;
 15175 
 15176   switch (cs->reason)
 15177     {
 15178     case XmCR_DECREMENT:
 15179       bar->dragging = -1;
 15180       part = horizontal ? scroll_bar_left_arrow : scroll_bar_up_arrow;
 15181       break;
 15182 
 15183     case XmCR_INCREMENT:
 15184       bar->dragging = -1;
 15185       part = horizontal ? scroll_bar_right_arrow : scroll_bar_down_arrow;
 15186       break;
 15187 
 15188     case XmCR_PAGE_DECREMENT:
 15189       bar->dragging = -1;
 15190       part = horizontal ? scroll_bar_before_handle : scroll_bar_above_handle;
 15191       break;
 15192 
 15193     case XmCR_PAGE_INCREMENT:
 15194       bar->dragging = -1;
 15195       part = horizontal ? scroll_bar_after_handle : scroll_bar_below_handle;
 15196       break;
 15197 
 15198     case XmCR_TO_TOP:
 15199       bar->dragging = -1;
 15200       part = horizontal ? scroll_bar_to_leftmost : scroll_bar_to_top;
 15201       break;
 15202 
 15203     case XmCR_TO_BOTTOM:
 15204       bar->dragging = -1;
 15205       part = horizontal ? scroll_bar_to_rightmost : scroll_bar_to_bottom;
 15206       break;
 15207 
 15208     case XmCR_DRAG:
 15209       {
 15210         int slider_size;
 15211 
 15212         block_input ();
 15213         XtVaGetValues (widget, XmNsliderSize, &slider_size, NULL);
 15214         unblock_input ();
 15215 
 15216         if (horizontal)
 15217           {
 15218             portion = bar->whole * ((float)cs->value / XM_SB_MAX);
 15219             whole = bar->whole * ((float)(XM_SB_MAX - slider_size) / XM_SB_MAX);
 15220             portion = min (portion, whole);
 15221             part = scroll_bar_horizontal_handle;
 15222           }
 15223         else
 15224           {
 15225             whole = XM_SB_MAX - slider_size;
 15226             portion = min (cs->value, whole);
 15227             part = scroll_bar_handle;
 15228           }
 15229 
 15230         bar->dragging = cs->value;
 15231       }
 15232       break;
 15233 
 15234     case XmCR_VALUE_CHANGED:
 15235       break;
 15236     };
 15237 
 15238   if (part != scroll_bar_nowhere)
 15239     {
 15240       window_being_scrolled = bar->window;
 15241       x_send_scroll_bar_event (bar->window, part, portion, whole,
 15242                                bar->horizontal);
 15243     }
 15244 }
 15245 
 15246 #elif defined USE_GTK
 15247 
 15248 /* Scroll bar callback for GTK scroll bars.  WIDGET is the scroll
 15249    bar widget.  DATA is a pointer to the scroll_bar structure. */
 15250 
 15251 static gboolean
 15252 xg_scroll_callback (GtkRange *range, GtkScrollType scroll,
 15253                     gdouble value, gpointer user_data)
 15254 {
 15255   int whole, portion;
 15256   struct scroll_bar *bar;
 15257   enum scroll_bar_part part;
 15258   GtkAdjustment *adj;
 15259   struct frame *f;
 15260   guint32 time;
 15261   struct x_display_info *dpyinfo;
 15262 
 15263   if (xg_ignore_gtk_scrollbar) return false;
 15264 
 15265   whole = 0;
 15266   portion = 0;
 15267   bar = user_data;
 15268   part = scroll_bar_nowhere;
 15269   adj = GTK_ADJUSTMENT (gtk_range_get_adjustment (range));
 15270   f = g_object_get_data (G_OBJECT (range), XG_FRAME_DATA);
 15271   time = gtk_get_current_event_time ();
 15272   dpyinfo = FRAME_DISPLAY_INFO (f);
 15273 
 15274   if (time != GDK_CURRENT_TIME)
 15275     x_display_set_last_user_time (dpyinfo, time, true,
 15276                                   true);
 15277 
 15278   switch (scroll)
 15279     {
 15280     case GTK_SCROLL_JUMP:
 15281       /* Buttons 1 2 or 3 must be grabbed.  */
 15282       if (FRAME_DISPLAY_INFO (f)->grabbed != 0
 15283           && FRAME_DISPLAY_INFO (f)->grabbed < (1 << 4))
 15284         {
 15285           if (bar->horizontal)
 15286             {
 15287               part = scroll_bar_horizontal_handle;
 15288               whole = (int)(gtk_adjustment_get_upper (adj) -
 15289                             gtk_adjustment_get_page_size (adj));
 15290               portion = min ((int)value, whole);
 15291               bar->dragging = portion;
 15292             }
 15293           else
 15294             {
 15295               part = scroll_bar_handle;
 15296               whole = gtk_adjustment_get_upper (adj) -
 15297                 gtk_adjustment_get_page_size (adj);
 15298               portion = min ((int)value, whole);
 15299               bar->dragging = portion;
 15300             }
 15301         }
 15302       break;
 15303     case GTK_SCROLL_STEP_BACKWARD:
 15304       part = (bar->horizontal
 15305               ? scroll_bar_left_arrow : scroll_bar_up_arrow);
 15306       bar->dragging = -1;
 15307       break;
 15308     case GTK_SCROLL_STEP_FORWARD:
 15309       part = (bar->horizontal
 15310               ? scroll_bar_right_arrow : scroll_bar_down_arrow);
 15311       bar->dragging = -1;
 15312       break;
 15313     case GTK_SCROLL_PAGE_BACKWARD:
 15314       part = (bar->horizontal
 15315               ? scroll_bar_before_handle : scroll_bar_above_handle);
 15316       bar->dragging = -1;
 15317       break;
 15318     case GTK_SCROLL_PAGE_FORWARD:
 15319       part = (bar->horizontal
 15320               ? scroll_bar_after_handle : scroll_bar_below_handle);
 15321       bar->dragging = -1;
 15322       break;
 15323     default:
 15324       break;
 15325     }
 15326 
 15327   if (part != scroll_bar_nowhere)
 15328     {
 15329       window_being_scrolled = bar->window;
 15330       x_send_scroll_bar_event (bar->window, part, portion, whole,
 15331                                bar->horizontal);
 15332     }
 15333 
 15334   return false;
 15335 }
 15336 
 15337 /* Callback for button release. Sets dragging to -1 when dragging is done.  */
 15338 
 15339 static gboolean
 15340 xg_end_scroll_callback (GtkWidget *widget,
 15341                         GdkEventButton *event,
 15342                         gpointer user_data)
 15343 {
 15344   struct scroll_bar *bar;
 15345 
 15346   bar = user_data;
 15347   bar->dragging = -1;
 15348 
 15349   if (WINDOWP (window_being_scrolled))
 15350     {
 15351       x_send_scroll_bar_event (window_being_scrolled,
 15352                                scroll_bar_end_scroll, 0, 0, bar->horizontal);
 15353       window_being_scrolled = Qnil;
 15354     }
 15355 
 15356   return false;
 15357 }
 15358 
 15359 
 15360 #else /* not USE_GTK and not USE_MOTIF */
 15361 
 15362 /* Xaw scroll bar callback.  Invoked when the thumb is dragged.
 15363    WIDGET is the scroll bar widget.  CLIENT_DATA is a pointer to the
 15364    scroll bar struct.  CALL_DATA is a pointer to a float saying where
 15365    the thumb is.  */
 15366 
 15367 static void
 15368 xaw_jump_callback (Widget widget, XtPointer client_data, XtPointer call_data)
 15369 {
 15370   struct scroll_bar *bar = client_data;
 15371   float *top_addr = call_data;
 15372   float top = *top_addr;
 15373   float shown;
 15374   int whole, portion, height, width;
 15375   enum scroll_bar_part part;
 15376   bool horizontal = bar->horizontal;
 15377 
 15378   if (horizontal)
 15379     {
 15380       /* Get the size of the thumb, a value between 0 and 1.  */
 15381       block_input ();
 15382       XtVaGetValues (widget, XtNshown, &shown, XtNwidth, &width, NULL);
 15383       unblock_input ();
 15384 
 15385       if (shown < 1)
 15386         {
 15387           whole = bar->whole - (shown * bar->whole);
 15388           portion = min (top * bar->whole, whole);
 15389         }
 15390       else
 15391         {
 15392           whole = bar->whole;
 15393           portion = 0;
 15394         }
 15395 
 15396       part = scroll_bar_horizontal_handle;
 15397     }
 15398   else
 15399     {
 15400       /* Get the size of the thumb, a value between 0 and 1.  */
 15401       block_input ();
 15402       XtVaGetValues (widget, XtNshown, &shown, XtNheight, &height, NULL);
 15403       unblock_input ();
 15404 
 15405       whole = 10000000;
 15406       portion = shown < 1 ? top * whole : 0;
 15407 
 15408       if (shown < 1 && (eabs (top + shown - 1) < 1.0f / height))
 15409         /* Some derivatives of Xaw refuse to shrink the thumb when you reach
 15410            the bottom, so we force the scrolling whenever we see that we're
 15411            too close to the bottom (in x_set_toolkit_scroll_bar_thumb
 15412            we try to ensure that we always stay two pixels away from the
 15413            bottom).  */
 15414         part = scroll_bar_down_arrow;
 15415       else
 15416         part = scroll_bar_handle;
 15417     }
 15418 
 15419   window_being_scrolled = bar->window;
 15420   bar->dragging = portion;
 15421   bar->last_seen_part = part;
 15422   x_send_scroll_bar_event (bar->window, part, portion, whole, bar->horizontal);
 15423 }
 15424 
 15425 
 15426 /* Xaw scroll bar callback.  Invoked for incremental scrolling.,
 15427    i.e. line or page up or down.  WIDGET is the Xaw scroll bar
 15428    widget.  CLIENT_DATA is a pointer to the scroll_bar structure for
 15429    the scroll bar.  CALL_DATA is an integer specifying the action that
 15430    has taken place.  Its magnitude is in the range 0..height of the
 15431    scroll bar.  Negative values mean scroll towards buffer start.
 15432    Values < height of scroll bar mean line-wise movement.  */
 15433 
 15434 static void
 15435 xaw_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data)
 15436 {
 15437   struct scroll_bar *bar = client_data;
 15438   /* The position really is stored cast to a pointer.  */
 15439   int position = (intptr_t) call_data;
 15440   Dimension height, width;
 15441   enum scroll_bar_part part;
 15442 
 15443   if (bar->horizontal)
 15444     {
 15445       /* Get the width of the scroll bar.  */
 15446       block_input ();
 15447       XtVaGetValues (widget, XtNwidth, &width, NULL);
 15448       unblock_input ();
 15449 
 15450       if (eabs (position) >= width)
 15451         part = (position < 0) ? scroll_bar_before_handle : scroll_bar_after_handle;
 15452 
 15453       /* If Xaw3d was compiled with ARROW_SCROLLBAR,
 15454          it maps line-movement to call_data = max(5, height/20).  */
 15455       else if (xaw3d_arrow_scroll && eabs (position) <= max (5, width / 20))
 15456         part = (position < 0) ? scroll_bar_left_arrow : scroll_bar_right_arrow;
 15457       else
 15458         part = scroll_bar_move_ratio;
 15459 
 15460       window_being_scrolled = bar->window;
 15461       bar->dragging = -1;
 15462       bar->last_seen_part = part;
 15463       x_send_scroll_bar_event (bar->window, part, position, width,
 15464                                bar->horizontal);
 15465     }
 15466   else
 15467     {
 15468 
 15469       /* Get the height of the scroll bar.  */
 15470       block_input ();
 15471       XtVaGetValues (widget, XtNheight, &height, NULL);
 15472       unblock_input ();
 15473 
 15474       if (eabs (position) >= height)
 15475         part = (position < 0) ? scroll_bar_above_handle : scroll_bar_below_handle;
 15476 
 15477       /* If Xaw3d was compiled with ARROW_SCROLLBAR,
 15478          it maps line-movement to call_data = max(5, height/20).  */
 15479       else if (xaw3d_arrow_scroll && eabs (position) <= max (5, height / 20))
 15480         part = (position < 0) ? scroll_bar_up_arrow : scroll_bar_down_arrow;
 15481       else
 15482         part = scroll_bar_move_ratio;
 15483 
 15484       window_being_scrolled = bar->window;
 15485       bar->dragging = -1;
 15486       bar->last_seen_part = part;
 15487       x_send_scroll_bar_event (bar->window, part, position, height,
 15488                                bar->horizontal);
 15489     }
 15490 }
 15491 
 15492 #endif /* not USE_GTK and not USE_MOTIF */
 15493 
 15494 #define SCROLL_BAR_NAME "verticalScrollBar"
 15495 #define SCROLL_BAR_HORIZONTAL_NAME "horizontalScrollBar"
 15496 
 15497 /* Create the widget for scroll bar BAR on frame F.  Record the widget
 15498    and X window of the scroll bar in BAR.  */
 15499 
 15500 #ifdef USE_GTK
 15501 static void
 15502 x_create_toolkit_scroll_bar (struct frame *f, struct scroll_bar *bar)
 15503 {
 15504   const char *scroll_bar_name = SCROLL_BAR_NAME;
 15505 
 15506   block_input ();
 15507   xg_create_scroll_bar (f, bar, G_CALLBACK (xg_scroll_callback),
 15508                         G_CALLBACK (xg_end_scroll_callback),
 15509                         scroll_bar_name);
 15510   unblock_input ();
 15511 }
 15512 
 15513 static void
 15514 x_create_horizontal_toolkit_scroll_bar (struct frame *f, struct scroll_bar *bar)
 15515 {
 15516   const char *scroll_bar_name = SCROLL_BAR_HORIZONTAL_NAME;
 15517 
 15518   block_input ();
 15519   xg_create_horizontal_scroll_bar (f, bar, G_CALLBACK (xg_scroll_callback),
 15520                                    G_CALLBACK (xg_end_scroll_callback),
 15521                                    scroll_bar_name);
 15522   unblock_input ();
 15523 }
 15524 
 15525 #else /* not USE_GTK */
 15526 
 15527 static void
 15528 x_create_toolkit_scroll_bar (struct frame *f, struct scroll_bar *bar)
 15529 {
 15530   Window xwindow;
 15531   Widget widget;
 15532   Arg av[20];
 15533   int ac = 0;
 15534   const char *scroll_bar_name = SCROLL_BAR_NAME;
 15535   unsigned long pixel;
 15536 
 15537   block_input ();
 15538 
 15539 #ifdef USE_MOTIF
 15540   /* Set resources.  Create the widget.  */
 15541   XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac;
 15542   XtSetArg (av[ac], XmNminimum, 0); ++ac;
 15543   XtSetArg (av[ac], XmNmaximum, XM_SB_MAX); ++ac;
 15544   XtSetArg (av[ac], XmNorientation, XmVERTICAL); ++ac;
 15545   XtSetArg (av[ac], XmNprocessingDirection, XmMAX_ON_BOTTOM), ++ac;
 15546   XtSetArg (av[ac], XmNincrement, 1); ++ac;
 15547   XtSetArg (av[ac], XmNpageIncrement, 1); ++ac;
 15548 
 15549   /* Note: "background" is the thumb color, and "trough" is the color behind
 15550      everything. */
 15551   pixel = f->output_data.x->scroll_bar_foreground_pixel;
 15552   if (pixel != -1)
 15553     {
 15554       XtSetArg (av[ac], XmNbackground, pixel);
 15555       ++ac;
 15556     }
 15557 
 15558   pixel = f->output_data.x->scroll_bar_background_pixel;
 15559   if (pixel != -1)
 15560     {
 15561       XtSetArg (av[ac], XmNtroughColor, pixel);
 15562       ++ac;
 15563     }
 15564 
 15565   widget = XmCreateScrollBar (f->output_data.x->edit_widget,
 15566                               (char *) scroll_bar_name, av, ac);
 15567 
 15568   /* Add one callback for everything that can happen.  */
 15569   XtAddCallback (widget, XmNdecrementCallback, xm_scroll_callback,
 15570                  (XtPointer) bar);
 15571   XtAddCallback (widget, XmNdragCallback, xm_scroll_callback,
 15572                  (XtPointer) bar);
 15573   XtAddCallback (widget, XmNincrementCallback, xm_scroll_callback,
 15574                  (XtPointer) bar);
 15575   XtAddCallback (widget, XmNpageDecrementCallback, xm_scroll_callback,
 15576                  (XtPointer) bar);
 15577   XtAddCallback (widget, XmNpageIncrementCallback, xm_scroll_callback,
 15578                  (XtPointer) bar);
 15579   XtAddCallback (widget, XmNtoBottomCallback, xm_scroll_callback,
 15580                  (XtPointer) bar);
 15581   XtAddCallback (widget, XmNtoTopCallback, xm_scroll_callback,
 15582                  (XtPointer) bar);
 15583 
 15584   /* Realize the widget.  Only after that is the X window created.  */
 15585   XtRealizeWidget (widget);
 15586 
 15587   /* Set the cursor to an arrow.  I didn't find a resource to do that.
 15588      And I'm wondering why it hasn't an arrow cursor by default.  */
 15589   XDefineCursor (XtDisplay (widget), XtWindow (widget),
 15590                  f->output_data.x->nontext_cursor);
 15591 
 15592 #ifdef HAVE_XINPUT2
 15593   /* Ask for input extension button and motion events.  This lets us
 15594      send the proper `wheel-up' or `wheel-down' events to Emacs.  */
 15595   if (FRAME_DISPLAY_INFO (f)->supports_xi2)
 15596     xi_select_scroll_bar_events (FRAME_DISPLAY_INFO (f),
 15597                                  XtWindow (widget));
 15598 #endif
 15599 #else /* !USE_MOTIF i.e. use Xaw */
 15600 
 15601   /* Set resources.  Create the widget.  The background of the
 15602      Xaw3d scroll bar widget is a little bit light for my taste.
 15603      We don't alter it here to let users change it according
 15604      to their taste with `emacs*verticalScrollBar.background: xxx'.  */
 15605   XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac;
 15606   XtSetArg (av[ac], XtNorientation, XtorientVertical); ++ac;
 15607   /* For smoother scrolling with Xaw3d   -sm */
 15608   /* XtSetArg (av[ac], XtNpickTop, True); ++ac; */
 15609 
 15610   pixel = f->output_data.x->scroll_bar_foreground_pixel;
 15611   if (pixel != -1)
 15612     {
 15613       XtSetArg (av[ac], XtNforeground, pixel);
 15614       ++ac;
 15615     }
 15616 
 15617   pixel = f->output_data.x->scroll_bar_background_pixel;
 15618   if (pixel != -1)
 15619     {
 15620       XtSetArg (av[ac], XtNbackground, pixel);
 15621       ++ac;
 15622     }
 15623 
 15624   /* Top/bottom shadow colors.  */
 15625 
 15626   /* Allocate them, if necessary.  */
 15627   if (f->output_data.x->scroll_bar_top_shadow_pixel == -1)
 15628     {
 15629       pixel = f->output_data.x->scroll_bar_background_pixel;
 15630       if (pixel != -1)
 15631         {
 15632           if (!x_alloc_lighter_color (f, FRAME_X_DISPLAY (f),
 15633                                       FRAME_X_COLORMAP (f),
 15634                                       &pixel, 1.2, 0x8000))
 15635             pixel = -1;
 15636           f->output_data.x->scroll_bar_top_shadow_pixel = pixel;
 15637         }
 15638     }
 15639   if (f->output_data.x->scroll_bar_bottom_shadow_pixel == -1)
 15640     {
 15641       pixel = f->output_data.x->scroll_bar_background_pixel;
 15642       if (pixel != -1)
 15643         {
 15644           if (!x_alloc_lighter_color (f, FRAME_X_DISPLAY (f),
 15645                                       FRAME_X_COLORMAP (f),
 15646                                       &pixel, 0.6, 0x4000))
 15647             pixel = -1;
 15648           f->output_data.x->scroll_bar_bottom_shadow_pixel = pixel;
 15649         }
 15650     }
 15651 
 15652 #ifdef XtNbeNiceToColormap
 15653   /* Tell the toolkit about them.  */
 15654   if (f->output_data.x->scroll_bar_top_shadow_pixel == -1
 15655       || f->output_data.x->scroll_bar_bottom_shadow_pixel == -1)
 15656     /* We tried to allocate a color for the top/bottom shadow, and
 15657        failed, so tell Xaw3d to use dithering instead.   */
 15658     /* But only if we have a small colormap.  Xaw3d can allocate nice
 15659        colors itself.  */
 15660     {
 15661       XtSetArg (av[ac], (String) XtNbeNiceToColormap,
 15662                 DefaultDepthOfScreen (FRAME_X_SCREEN (f)) < 16);
 15663       ++ac;
 15664     }
 15665   else
 15666     /* Tell what colors Xaw3d should use for the top/bottom shadow, to
 15667        be more consistent with other emacs 3d colors, and since Xaw3d is
 15668        not good at dealing with allocation failure.  */
 15669     {
 15670       /* This tells Xaw3d to use real colors instead of dithering for
 15671          the shadows.  */
 15672       XtSetArg (av[ac], (String) XtNbeNiceToColormap, False);
 15673       ++ac;
 15674 
 15675       /* Specify the colors.  */
 15676       pixel = f->output_data.x->scroll_bar_top_shadow_pixel;
 15677       if (pixel != -1)
 15678         {
 15679           XtSetArg (av[ac], (String) XtNtopShadowPixel, pixel);
 15680           ++ac;
 15681         }
 15682       pixel = f->output_data.x->scroll_bar_bottom_shadow_pixel;
 15683       if (pixel != -1)
 15684         {
 15685           XtSetArg (av[ac], (String) XtNbottomShadowPixel, pixel);
 15686           ++ac;
 15687         }
 15688     }
 15689 #endif
 15690 
 15691   widget = XtCreateWidget (scroll_bar_name, scrollbarWidgetClass,
 15692                            f->output_data.x->edit_widget, av, ac);
 15693 
 15694   {
 15695     char const *initial = "";
 15696     char const *val = initial;
 15697     XtVaGetValues (widget, XtNscrollVCursor, (XtPointer) &val,
 15698 #ifdef XtNarrowScrollbars
 15699                    XtNarrowScrollbars, (XtPointer) &xaw3d_arrow_scroll,
 15700 #endif
 15701                    XtNpickTop, (XtPointer) &xaw3d_pick_top, NULL);
 15702     if (xaw3d_arrow_scroll || val == initial)
 15703       { /* ARROW_SCROLL */
 15704         xaw3d_arrow_scroll = True;
 15705         /* Isn't that just a personal preference ?   --Stef */
 15706         XtVaSetValues (widget, XtNcursorName, "top_left_arrow", NULL);
 15707       }
 15708   }
 15709 
 15710   /* Define callbacks.  */
 15711   XtAddCallback (widget, XtNjumpProc, xaw_jump_callback, (XtPointer) bar);
 15712   XtAddCallback (widget, XtNscrollProc, xaw_scroll_callback,
 15713                  (XtPointer) bar);
 15714 
 15715   /* Realize the widget.  Only after that is the X window created.  */
 15716   XtRealizeWidget (widget);
 15717 
 15718 #endif /* !USE_MOTIF */
 15719 
 15720   /* Install an action hook that lets us detect when the user
 15721      finishes interacting with a scroll bar.  */
 15722   if (action_hook_id == 0)
 15723     action_hook_id = XtAppAddActionHook (Xt_app_con, xt_action_hook, 0);
 15724 
 15725   /* Remember X window and widget in the scroll bar vector.  */
 15726   SET_SCROLL_BAR_X_WIDGET (bar, widget);
 15727   xwindow = XtWindow (widget);
 15728   bar->x_window = xwindow;
 15729   bar->whole = 1;
 15730   bar->horizontal = false;
 15731 
 15732   unblock_input ();
 15733 }
 15734 
 15735 static void
 15736 x_create_horizontal_toolkit_scroll_bar (struct frame *f, struct scroll_bar *bar)
 15737 {
 15738   Window xwindow;
 15739   Widget widget;
 15740   Arg av[20];
 15741   int ac = 0;
 15742   const char *scroll_bar_name = SCROLL_BAR_HORIZONTAL_NAME;
 15743   unsigned long pixel;
 15744 
 15745   block_input ();
 15746 
 15747 #ifdef USE_MOTIF
 15748   /* Set resources.  Create the widget.  */
 15749   XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac;
 15750   XtSetArg (av[ac], XmNminimum, 0); ++ac;
 15751   XtSetArg (av[ac], XmNmaximum, XM_SB_MAX); ++ac;
 15752   XtSetArg (av[ac], XmNorientation, XmHORIZONTAL); ++ac;
 15753   XtSetArg (av[ac], XmNprocessingDirection, XmMAX_ON_RIGHT), ++ac;
 15754   XtSetArg (av[ac], XmNincrement, 1); ++ac;
 15755   XtSetArg (av[ac], XmNpageIncrement, 1); ++ac;
 15756 
 15757   /* Note: "background" is the thumb color, and "trough" is the color behind
 15758      everything. */
 15759   pixel = f->output_data.x->scroll_bar_foreground_pixel;
 15760   if (pixel != -1)
 15761     {
 15762       XtSetArg (av[ac], XmNbackground, pixel);
 15763       ++ac;
 15764     }
 15765 
 15766   pixel = f->output_data.x->scroll_bar_background_pixel;
 15767   if (pixel != -1)
 15768     {
 15769       XtSetArg (av[ac], XmNtroughColor, pixel);
 15770       ++ac;
 15771     }
 15772 
 15773   widget = XmCreateScrollBar (f->output_data.x->edit_widget,
 15774                               (char *) scroll_bar_name, av, ac);
 15775 
 15776   /* Add one callback for everything that can happen.  */
 15777   XtAddCallback (widget, XmNdecrementCallback, xm_scroll_callback,
 15778                  (XtPointer) bar);
 15779   XtAddCallback (widget, XmNdragCallback, xm_scroll_callback,
 15780                  (XtPointer) bar);
 15781   XtAddCallback (widget, XmNincrementCallback, xm_scroll_callback,
 15782                  (XtPointer) bar);
 15783   XtAddCallback (widget, XmNpageDecrementCallback, xm_scroll_callback,
 15784                  (XtPointer) bar);
 15785   XtAddCallback (widget, XmNpageIncrementCallback, xm_scroll_callback,
 15786                  (XtPointer) bar);
 15787   XtAddCallback (widget, XmNtoBottomCallback, xm_scroll_callback,
 15788                  (XtPointer) bar);
 15789   XtAddCallback (widget, XmNtoTopCallback, xm_scroll_callback,
 15790                  (XtPointer) bar);
 15791 
 15792   /* Realize the widget.  Only after that is the X window created.  */
 15793   XtRealizeWidget (widget);
 15794 
 15795   /* Set the cursor to an arrow.  I didn't find a resource to do that.
 15796      And I'm wondering why it hasn't an arrow cursor by default.  */
 15797   XDefineCursor (XtDisplay (widget), XtWindow (widget),
 15798                  f->output_data.x->nontext_cursor);
 15799 
 15800 #ifdef HAVE_XINPUT2
 15801   /* Ask for input extension button and motion events.  This lets us
 15802      send the proper `wheel-up' or `wheel-down' events to Emacs.  */
 15803   if (FRAME_DISPLAY_INFO (f)->supports_xi2)
 15804     xi_select_scroll_bar_events (FRAME_DISPLAY_INFO (f),
 15805                                  XtWindow (widget));
 15806 #endif
 15807 #else /* !USE_MOTIF i.e. use Xaw */
 15808 
 15809   /* Set resources.  Create the widget.  The background of the
 15810      Xaw3d scroll bar widget is a little bit light for my taste.
 15811      We don't alter it here to let users change it according
 15812      to their taste with `emacs*verticalScrollBar.background: xxx'.  */
 15813   XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac;
 15814   XtSetArg (av[ac], XtNorientation, XtorientHorizontal); ++ac;
 15815   /* For smoother scrolling with Xaw3d   -sm */
 15816   /* XtSetArg (av[ac], XtNpickTop, True); ++ac; */
 15817 
 15818   pixel = f->output_data.x->scroll_bar_foreground_pixel;
 15819   if (pixel != -1)
 15820     {
 15821       XtSetArg (av[ac], XtNforeground, pixel);
 15822       ++ac;
 15823     }
 15824 
 15825   pixel = f->output_data.x->scroll_bar_background_pixel;
 15826   if (pixel != -1)
 15827     {
 15828       XtSetArg (av[ac], XtNbackground, pixel);
 15829       ++ac;
 15830     }
 15831 
 15832   /* Top/bottom shadow colors.  */
 15833 
 15834   /* Allocate them, if necessary.  */
 15835   if (f->output_data.x->scroll_bar_top_shadow_pixel == -1)
 15836     {
 15837       pixel = f->output_data.x->scroll_bar_background_pixel;
 15838       if (pixel != -1)
 15839         {
 15840           if (!x_alloc_lighter_color (f, FRAME_X_DISPLAY (f),
 15841                                       FRAME_X_COLORMAP (f),
 15842                                       &pixel, 1.2, 0x8000))
 15843             pixel = -1;
 15844           f->output_data.x->scroll_bar_top_shadow_pixel = pixel;
 15845         }
 15846     }
 15847   if (f->output_data.x->scroll_bar_bottom_shadow_pixel == -1)
 15848     {
 15849       pixel = f->output_data.x->scroll_bar_background_pixel;
 15850       if (pixel != -1)
 15851         {
 15852           if (!x_alloc_lighter_color (f, FRAME_X_DISPLAY (f),
 15853                                       FRAME_X_COLORMAP (f),
 15854                                       &pixel, 0.6, 0x4000))
 15855             pixel = -1;
 15856           f->output_data.x->scroll_bar_bottom_shadow_pixel = pixel;
 15857         }
 15858     }
 15859 
 15860 #ifdef XtNbeNiceToColormap
 15861   /* Tell the toolkit about them.  */
 15862   if (f->output_data.x->scroll_bar_top_shadow_pixel == -1
 15863       || f->output_data.x->scroll_bar_bottom_shadow_pixel == -1)
 15864     /* We tried to allocate a color for the top/bottom shadow, and
 15865        failed, so tell Xaw3d to use dithering instead.   */
 15866     /* But only if we have a small colormap.  Xaw3d can allocate nice
 15867        colors itself.  */
 15868     {
 15869       XtSetArg (av[ac], (String) XtNbeNiceToColormap,
 15870                 DefaultDepthOfScreen (FRAME_X_SCREEN (f)) < 16);
 15871       ++ac;
 15872     }
 15873   else
 15874     /* Tell what colors Xaw3d should use for the top/bottom shadow, to
 15875        be more consistent with other emacs 3d colors, and since Xaw3d is
 15876        not good at dealing with allocation failure.  */
 15877     {
 15878       /* This tells Xaw3d to use real colors instead of dithering for
 15879          the shadows.  */
 15880       XtSetArg (av[ac], (String) XtNbeNiceToColormap, False);
 15881       ++ac;
 15882 
 15883       /* Specify the colors.  */
 15884       pixel = f->output_data.x->scroll_bar_top_shadow_pixel;
 15885       if (pixel != -1)
 15886         {
 15887           XtSetArg (av[ac], (String) XtNtopShadowPixel, pixel);
 15888           ++ac;
 15889         }
 15890       pixel = f->output_data.x->scroll_bar_bottom_shadow_pixel;
 15891       if (pixel != -1)
 15892         {
 15893           XtSetArg (av[ac], (String) XtNbottomShadowPixel, pixel);
 15894           ++ac;
 15895         }
 15896     }
 15897 #endif
 15898 
 15899   widget = XtCreateWidget (scroll_bar_name, scrollbarWidgetClass,
 15900                            f->output_data.x->edit_widget, av, ac);
 15901 
 15902   {
 15903     char const *initial = "";
 15904     char const *val = initial;
 15905     XtVaGetValues (widget, XtNscrollVCursor, (XtPointer) &val,
 15906 #ifdef XtNarrowScrollbars
 15907                    XtNarrowScrollbars, (XtPointer) &xaw3d_arrow_scroll,
 15908 #endif
 15909                    XtNpickTop, (XtPointer) &xaw3d_pick_top, NULL);
 15910     if (xaw3d_arrow_scroll || val == initial)
 15911       { /* ARROW_SCROLL */
 15912         xaw3d_arrow_scroll = True;
 15913         /* Isn't that just a personal preference ?   --Stef */
 15914         XtVaSetValues (widget, XtNcursorName, "top_left_arrow", NULL);
 15915       }
 15916   }
 15917 
 15918   /* Define callbacks.  */
 15919   XtAddCallback (widget, XtNjumpProc, xaw_jump_callback, (XtPointer) bar);
 15920   XtAddCallback (widget, XtNscrollProc, xaw_scroll_callback,
 15921                  (XtPointer) bar);
 15922 
 15923   /* Realize the widget.  Only after that is the X window created.  */
 15924   XtRealizeWidget (widget);
 15925 
 15926 #endif /* !USE_MOTIF */
 15927 
 15928   /* Install an action hook that lets us detect when the user
 15929      finishes interacting with a scroll bar.  */
 15930   if (horizontal_action_hook_id == 0)
 15931    horizontal_action_hook_id
 15932      = XtAppAddActionHook (Xt_app_con, xt_horizontal_action_hook, 0);
 15933 
 15934   /* Remember X window and widget in the scroll bar vector.  */
 15935   SET_SCROLL_BAR_X_WIDGET (bar, widget);
 15936   xwindow = XtWindow (widget);
 15937   bar->x_window = xwindow;
 15938   bar->whole = 1;
 15939   bar->horizontal = true;
 15940 
 15941   unblock_input ();
 15942 }
 15943 #endif /* not USE_GTK */
 15944 
 15945 
 15946 /* Set the thumb size and position of scroll bar BAR.  We are currently
 15947    displaying PORTION out of a whole WHOLE, and our position POSITION.  */
 15948 
 15949 #ifdef USE_GTK
 15950 static void
 15951 x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int position, int whole)
 15952 {
 15953   xg_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
 15954 }
 15955 
 15956 static void
 15957 x_set_toolkit_horizontal_scroll_bar_thumb (struct scroll_bar *bar, int portion, int position, int whole)
 15958 {
 15959   xg_set_toolkit_horizontal_scroll_bar_thumb (bar, portion, position, whole);
 15960 }
 15961 
 15962 #else /* not USE_GTK */
 15963 static void
 15964 x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int position,
 15965                                 int whole)
 15966 {
 15967   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 15968   Widget widget = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
 15969   float top, shown;
 15970 
 15971   block_input ();
 15972 
 15973 #ifdef USE_MOTIF
 15974 
 15975   if (scroll_bar_adjust_thumb_portion_p)
 15976     {
 15977       /* We use an estimate of 30 chars per line rather than the real
 15978          `portion' value.  This has the disadvantage that the thumb size
 15979          is not very representative, but it makes our life a lot easier.
 15980          Otherwise, we have to constantly adjust the thumb size, which
 15981          we can't always do quickly enough: while dragging, the size of
 15982          the thumb might prevent the user from dragging the thumb all the
 15983          way to the end.  but Motif and some versions of Xaw3d don't allow
 15984          updating the thumb size while dragging.  Also, even if we can update
 15985          its size, the update will often happen too late.
 15986          If you don't believe it, check out revision 1.650 of xterm.c to see
 15987          what hoops we were going through and the still poor behavior we got.  */
 15988       portion = WINDOW_TOTAL_LINES (XWINDOW (bar->window)) * 30;
 15989       /* When the thumb is at the bottom, position == whole.
 15990          So we need to increase `whole' to make space for the thumb.  */
 15991       whole += portion;
 15992     }
 15993 
 15994   if (whole <= 0)
 15995     top = 0, shown = 1;
 15996   else
 15997     {
 15998       top = (float) position / whole;
 15999       shown = (float) portion / whole;
 16000     }
 16001 
 16002   if (bar->dragging == -1)
 16003     {
 16004       int size, value;
 16005 
 16006       /* Slider size.  Must be in the range [1 .. MAX - MIN] where MAX
 16007          is the scroll bar's maximum and MIN is the scroll bar's minimum
 16008          value.  */
 16009       size = clip_to_bounds (1, shown * XM_SB_MAX, XM_SB_MAX);
 16010 
 16011       /* Position.  Must be in the range [MIN .. MAX - SLIDER_SIZE].  */
 16012       value = top * XM_SB_MAX;
 16013       value = min (value, XM_SB_MAX - size);
 16014 
 16015       XmScrollBarSetValues (widget, value, size, 0, 0, False);
 16016     }
 16017 #else /* !USE_MOTIF i.e. use Xaw */
 16018 
 16019   if (whole == 0)
 16020     top = 0, shown = 1;
 16021   else
 16022     {
 16023       top = (float) position / whole;
 16024       shown = (float) portion / whole;
 16025     }
 16026 
 16027   {
 16028     float old_top, old_shown;
 16029     Dimension height;
 16030     XtVaGetValues (widget,
 16031                    XtNtopOfThumb, &old_top,
 16032                    XtNshown, &old_shown,
 16033                    XtNheight, &height,
 16034                    NULL);
 16035 
 16036     /* Massage the top+shown values.  */
 16037     if (bar->dragging == -1 || bar->last_seen_part == scroll_bar_down_arrow)
 16038       top = max (0, min (1, top));
 16039     else
 16040       top = old_top;
 16041 #if ! defined (HAVE_XAW3D)
 16042     /* With Xaw, 'top' values too closer to 1.0 may
 16043        cause the thumb to disappear.  Fix that.  */
 16044     top = min (top, 0.99f);
 16045 #endif
 16046     /* Keep two pixels available for moving the thumb down.  */
 16047     shown = max (0, min (1 - top - (2.0f / height), shown));
 16048 #if ! defined (HAVE_XAW3D)
 16049     /* Likewise with too small 'shown'.  */
 16050     shown = max (shown, 0.01f);
 16051 #endif
 16052 
 16053     /* If the call to XawScrollbarSetThumb below doesn't seem to
 16054        work, check that 'NARROWPROTO' is defined in src/config.h.
 16055        If this is not so, most likely you need to fix configure.  */
 16056     if (top != old_top || shown != old_shown)
 16057       {
 16058         if (bar->dragging == -1)
 16059           XawScrollbarSetThumb (widget, top, shown);
 16060         else
 16061           {
 16062             /* Try to make the scrolling a tad smoother.  */
 16063             if (!xaw3d_pick_top)
 16064               shown = min (shown, old_shown);
 16065 
 16066             XawScrollbarSetThumb (widget, top, shown);
 16067           }
 16068       }
 16069   }
 16070 #endif /* !USE_MOTIF */
 16071 
 16072   unblock_input ();
 16073 }
 16074 
 16075 static void
 16076 x_set_toolkit_horizontal_scroll_bar_thumb (struct scroll_bar *bar, int portion, int position,
 16077                                 int whole)
 16078 {
 16079   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 16080   Widget widget = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
 16081   float top, shown;
 16082 
 16083   block_input ();
 16084 
 16085 #ifdef USE_MOTIF
 16086   bar->whole = whole;
 16087   shown = (float) portion / whole;
 16088   top = (float) position / (whole - portion);
 16089   {
 16090     int size = clip_to_bounds (1, shown * XM_SB_MAX, XM_SB_MAX);
 16091     int value = clip_to_bounds (0, top * (XM_SB_MAX - size), XM_SB_MAX - size);
 16092 
 16093     XmScrollBarSetValues (widget, value, size, 0, 0, False);
 16094   }
 16095 #else /* !USE_MOTIF i.e. use Xaw */
 16096   bar->whole = whole;
 16097   if (whole == 0)
 16098     top = 0, shown = 1;
 16099   else
 16100     {
 16101       top = (float) position / whole;
 16102       shown = (float) portion / whole;
 16103     }
 16104 
 16105   {
 16106     float old_top, old_shown;
 16107     Dimension height;
 16108     XtVaGetValues (widget,
 16109                    XtNtopOfThumb, &old_top,
 16110                    XtNshown, &old_shown,
 16111                    XtNheight, &height,
 16112                    NULL);
 16113 
 16114 #if false
 16115     /* Massage the top+shown values.  */
 16116     if (bar->dragging == -1 || bar->last_seen_part == scroll_bar_down_arrow)
 16117       top = max (0, min (1, top));
 16118     else
 16119       top = old_top;
 16120 #if ! defined (HAVE_XAW3D)
 16121     /* With Xaw, 'top' values too closer to 1.0 may
 16122        cause the thumb to disappear.  Fix that.  */
 16123     top = min (top, 0.99f);
 16124 #endif
 16125     /* Keep two pixels available for moving the thumb down.  */
 16126     shown = max (0, min (1 - top - (2.0f / height), shown));
 16127 #if ! defined (HAVE_XAW3D)
 16128     /* Likewise with too small 'shown'.  */
 16129     shown = max (shown, 0.01f);
 16130 #endif
 16131 #endif
 16132 
 16133     /* If the call to XawScrollbarSetThumb below doesn't seem to
 16134        work, check that 'NARROWPROTO' is defined in src/config.h.
 16135        If this is not so, most likely you need to fix configure.  */
 16136     XawScrollbarSetThumb (widget, top, shown);
 16137 #if false
 16138     if (top != old_top || shown != old_shown)
 16139       {
 16140         if (bar->dragging == -1)
 16141           XawScrollbarSetThumb (widget, top, shown);
 16142         else
 16143           {
 16144             /* Try to make the scrolling a tad smoother.  */
 16145             if (!xaw3d_pick_top)
 16146               shown = min (shown, old_shown);
 16147 
 16148             XawScrollbarSetThumb (widget, top, shown);
 16149           }
 16150       }
 16151 #endif
 16152   }
 16153 #endif /* !USE_MOTIF */
 16154 
 16155   unblock_input ();
 16156 }
 16157 #endif /* not USE_GTK */
 16158 
 16159 #endif /* USE_TOOLKIT_SCROLL_BARS */
 16160 
 16161 
 16162 
 16163 /************************************************************************
 16164                          Scroll bars, general
 16165  ************************************************************************/
 16166 
 16167 /* Create a scroll bar and return the scroll bar vector for it.  W is
 16168    the Emacs window on which to create the scroll bar. TOP, LEFT,
 16169    WIDTH and HEIGHT are the pixel coordinates and dimensions of the
 16170    scroll bar. */
 16171 
 16172 static struct scroll_bar *
 16173 x_scroll_bar_create (struct window *w, int top, int left,
 16174                      int width, int height, bool horizontal)
 16175 {
 16176   struct frame *f = XFRAME (w->frame);
 16177   struct scroll_bar *bar = ALLOCATE_PSEUDOVECTOR (struct scroll_bar, prev,
 16178                                                   PVEC_OTHER);
 16179   Lisp_Object barobj;
 16180 
 16181   block_input ();
 16182 
 16183 #ifdef USE_TOOLKIT_SCROLL_BARS
 16184   if (horizontal)
 16185     x_create_horizontal_toolkit_scroll_bar (f, bar);
 16186   else
 16187     x_create_toolkit_scroll_bar (f, bar);
 16188 #else /* not USE_TOOLKIT_SCROLL_BARS */
 16189   {
 16190     XSetWindowAttributes a;
 16191     unsigned long mask;
 16192     Window window;
 16193 
 16194     a.event_mask = (ButtonPressMask | ButtonReleaseMask
 16195                     | ButtonMotionMask | PointerMotionHintMask);
 16196     a.cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
 16197 
 16198     mask = (CWEventMask | CWCursor);
 16199 
 16200     /* Clear the area of W that will serve as a scroll bar.  This is
 16201        for the case that a window has been split horizontally.  In
 16202        this case, no clear_frame is generated to reduce flickering.  */
 16203     if (width > 0 && window_box_height (w) > 0)
 16204       x_clear_area (f, left, top, width, window_box_height (w));
 16205 
 16206     /* Create an input only window.  Scroll bar contents are drawn to
 16207        the frame window itself, so they can be double buffered and
 16208        synchronized using the same mechanism as the frame.  */
 16209     window = XCreateWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 16210                             /* Position and size of scroll bar.  */
 16211                             left, top, width, height,
 16212                             /* Border width.  */
 16213                             0,
 16214                             /* Depth.  */
 16215                             CopyFromParent,
 16216                             /* Class.  */
 16217                             InputOnly,
 16218                             /* Visual class.  */
 16219                             CopyFromParent,
 16220                              /* Attributes.  */
 16221                             mask, &a);
 16222 
 16223 #ifdef HAVE_XINPUT2
 16224   /* Ask for input extension button and motion events.  This lets us
 16225      send the proper `wheel-up' or `wheel-down' events to Emacs.  */
 16226   if (FRAME_DISPLAY_INFO (f)->supports_xi2)
 16227     xi_select_scroll_bar_events (FRAME_DISPLAY_INFO (f),
 16228                                  window);
 16229 #endif
 16230 
 16231     bar->x_window = window;
 16232   }
 16233 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 16234 
 16235   XSETWINDOW (bar->window, w);
 16236   bar->top = top;
 16237   bar->left = left;
 16238   bar->width = width;
 16239   bar->height = height;
 16240   bar->start = 0;
 16241   bar->end = 0;
 16242   bar->dragging = -1;
 16243   bar->horizontal = horizontal;
 16244 #if defined (USE_TOOLKIT_SCROLL_BARS) && defined (USE_LUCID)
 16245   bar->last_seen_part = scroll_bar_nowhere;
 16246 #endif
 16247 
 16248   /* Add bar to its frame's list of scroll bars.  */
 16249   bar->next = FRAME_SCROLL_BARS (f);
 16250   bar->prev = Qnil;
 16251   XSETVECTOR (barobj, bar);
 16252   fset_scroll_bars (f, barobj);
 16253   if (!NILP (bar->next))
 16254     XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
 16255 
 16256   /* Map the window/widget.  */
 16257 #ifdef USE_TOOLKIT_SCROLL_BARS
 16258   {
 16259 #ifdef USE_GTK
 16260     if (horizontal)
 16261       xg_update_horizontal_scrollbar_pos (f, bar->x_window, top,
 16262                                           left, width, max (height, 1));
 16263     else
 16264       xg_update_scrollbar_pos (f, bar->x_window, top,
 16265                                left, width, max (height, 1));
 16266 #else /* not USE_GTK */
 16267     Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
 16268     XtConfigureWidget (scroll_bar, left, top, width, max (height, 1), 0);
 16269     XtMapWidget (scroll_bar);
 16270     /* Don't obscure any child frames.  */
 16271     XLowerWindow (FRAME_X_DISPLAY (f), bar->x_window);
 16272 #endif /* not USE_GTK */
 16273     }
 16274 #else /* not USE_TOOLKIT_SCROLL_BARS */
 16275   XMapWindow (FRAME_X_DISPLAY (f), bar->x_window);
 16276   /* Don't obscure any child frames.  */
 16277   XLowerWindow (FRAME_X_DISPLAY (f), bar->x_window);
 16278 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 16279 
 16280   unblock_input ();
 16281   return bar;
 16282 }
 16283 
 16284 
 16285 #ifndef USE_TOOLKIT_SCROLL_BARS
 16286 
 16287 /* Draw BAR's handle in the proper position.
 16288 
 16289    If the handle is already drawn from START to END, don't bother
 16290    redrawing it, unless REBUILD; in that case, always
 16291    redraw it.  (REBUILD is handy for drawing the handle after expose
 16292    events.)
 16293 
 16294    Normally, we want to constrain the start and end of the handle to
 16295    fit inside its rectangle, but if the user is dragging the scroll
 16296    bar handle, we want to let them drag it down all the way, so that
 16297    the bar's top is as far down as it goes; otherwise, there's no way
 16298    to move to the very end of the buffer.  */
 16299 
 16300 static void
 16301 x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end,
 16302                          bool rebuild)
 16303 {
 16304   bool dragging;
 16305   struct frame *f;
 16306   Drawable w;
 16307   GC gc;
 16308   int inside_width, inside_height, top_range, length;
 16309 
 16310   /* If the display is already accurate, do nothing.  */
 16311   if (! rebuild
 16312       && start == bar->start
 16313       && end == bar->end)
 16314     return;
 16315 
 16316   f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 16317   dragging = bar->dragging != -1;
 16318   gc = f->output_data.x->normal_gc;
 16319   w = FRAME_X_DRAWABLE (f);
 16320 
 16321   block_input ();
 16322 
 16323   inside_width = VERTICAL_SCROLL_BAR_INSIDE_WIDTH (f, bar->width);
 16324   inside_height = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f, bar->height);
 16325   top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height);
 16326 
 16327   /* Make sure the values are reasonable, and try to preserve
 16328      the distance between start and end.  */
 16329   length = end - start;
 16330 
 16331   if (start < 0)
 16332     start = 0;
 16333   else if (start > top_range)
 16334     start = top_range;
 16335   end = start + length;
 16336 
 16337   if (end < start)
 16338     end = start;
 16339   else if (end > top_range && ! dragging)
 16340     end = top_range;
 16341 
 16342   /* Store the adjusted setting in the scroll bar.  */
 16343   bar->start = start;
 16344   bar->end = end;
 16345 
 16346   /* Clip the end position, just for display.  */
 16347   if (end > top_range)
 16348     end = top_range;
 16349 
 16350   /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels
 16351      below top positions, to make sure the handle is always at least
 16352      that many pixels tall.  */
 16353   end += VERTICAL_SCROLL_BAR_MIN_HANDLE;
 16354 
 16355   /* Draw the empty space above the handle.  Note that we can't clear
 16356      zero-height areas; that means "clear to end of window."  */
 16357   if ((inside_width > 0) && (start > 0))
 16358     {
 16359       if (f->output_data.x->scroll_bar_background_pixel != -1)
 16360         XSetForeground (FRAME_X_DISPLAY (f), gc,
 16361                         f->output_data.x->scroll_bar_background_pixel);
 16362       else
 16363         XSetForeground (FRAME_X_DISPLAY (f), gc,
 16364                         FRAME_BACKGROUND_PIXEL (f));
 16365 
 16366       XFillRectangle (FRAME_X_DISPLAY (f), w, gc,
 16367                       bar->left + VERTICAL_SCROLL_BAR_LEFT_BORDER,
 16368                       bar->top + VERTICAL_SCROLL_BAR_TOP_BORDER,
 16369                       inside_width, start);
 16370 
 16371       XSetForeground (FRAME_X_DISPLAY (f), gc,
 16372                       FRAME_FOREGROUND_PIXEL (f));
 16373     }
 16374 
 16375   /* Change to proper foreground color if one is specified.  */
 16376   if (f->output_data.x->scroll_bar_foreground_pixel != -1)
 16377     XSetForeground (FRAME_X_DISPLAY (f), gc,
 16378                     f->output_data.x->scroll_bar_foreground_pixel);
 16379 
 16380   /* Draw the handle itself.  */
 16381   XFillRectangle (FRAME_X_DISPLAY (f), w, gc,
 16382                   /* x, y, width, height */
 16383                   bar->left + VERTICAL_SCROLL_BAR_LEFT_BORDER,
 16384                   bar->top + VERTICAL_SCROLL_BAR_TOP_BORDER + start,
 16385                   inside_width, end - start);
 16386 
 16387 
 16388   /* Draw the empty space below the handle.  Note that we can't
 16389      clear zero-height areas; that means "clear to end of window." */
 16390   if ((inside_width > 0) && (end < inside_height))
 16391     {
 16392       if (f->output_data.x->scroll_bar_background_pixel != -1)
 16393         XSetForeground (FRAME_X_DISPLAY (f), gc,
 16394                         f->output_data.x->scroll_bar_background_pixel);
 16395       else
 16396         XSetForeground (FRAME_X_DISPLAY (f), gc,
 16397                         FRAME_BACKGROUND_PIXEL (f));
 16398 
 16399       XFillRectangle (FRAME_X_DISPLAY (f), w, gc,
 16400                       bar->left + VERTICAL_SCROLL_BAR_LEFT_BORDER,
 16401                       bar->top + VERTICAL_SCROLL_BAR_TOP_BORDER + end,
 16402                       inside_width, inside_height - end);
 16403 
 16404       XSetForeground (FRAME_X_DISPLAY (f), gc,
 16405                       FRAME_FOREGROUND_PIXEL (f));
 16406     }
 16407 
 16408   /* Restore the foreground color of the GC if we changed it above.  */
 16409   if (f->output_data.x->scroll_bar_foreground_pixel != -1)
 16410     XSetForeground (FRAME_X_DISPLAY (f), gc,
 16411                     FRAME_FOREGROUND_PIXEL (f));
 16412 
 16413   unblock_input ();
 16414 }
 16415 
 16416 #endif /* !USE_TOOLKIT_SCROLL_BARS */
 16417 
 16418 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
 16419    nil.  */
 16420 
 16421 static void
 16422 x_scroll_bar_remove (struct scroll_bar *bar)
 16423 {
 16424   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 16425   block_input ();
 16426 
 16427 #ifdef USE_TOOLKIT_SCROLL_BARS
 16428 #ifdef USE_GTK
 16429   xg_remove_scroll_bar (f, bar->x_window);
 16430 #else /* not USE_GTK */
 16431   XtDestroyWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar));
 16432 #endif /* not USE_GTK */
 16433 #else
 16434   XDestroyWindow (FRAME_X_DISPLAY (f), bar->x_window);
 16435 #endif
 16436 
 16437   /* Dissociate this scroll bar from its window.  */
 16438   if (bar->horizontal)
 16439     wset_horizontal_scroll_bar (XWINDOW (bar->window), Qnil);
 16440   else
 16441     wset_vertical_scroll_bar (XWINDOW (bar->window), Qnil);
 16442 
 16443   unblock_input ();
 16444 }
 16445 
 16446 
 16447 /* Set the handle of the vertical scroll bar for WINDOW to indicate
 16448    that we are displaying PORTION characters out of a total of WHOLE
 16449    characters, starting at POSITION.  If WINDOW has no scroll bar,
 16450    create one.  */
 16451 
 16452 static void
 16453 XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int position)
 16454 {
 16455   struct frame *f = XFRAME (w->frame);
 16456   Lisp_Object barobj;
 16457   struct scroll_bar *bar;
 16458   int top, height, left, width;
 16459   int window_y, window_height;
 16460 
 16461   /* Get window dimensions.  */
 16462   window_box (w, ANY_AREA, 0, &window_y, 0, &window_height);
 16463   top = window_y;
 16464   height = window_height;
 16465   left = WINDOW_SCROLL_BAR_AREA_X (w);
 16466   width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
 16467 
 16468   /* Does the scroll bar exist yet?  */
 16469   if (NILP (w->vertical_scroll_bar))
 16470     {
 16471       if (width > 0 && height > 0)
 16472         {
 16473           block_input ();
 16474           x_clear_area (f, left, top, width, height);
 16475           unblock_input ();
 16476         }
 16477 
 16478       bar = x_scroll_bar_create (w, top, left, width, max (height, 1), false);
 16479 #ifndef USE_TOOLKIT_SCROLL_BARS
 16480       /* Since non-toolkit scroll bars don't display their contents to
 16481          a dedicated window, no expose event will be generated.
 16482          Redraw the scroll bar manually.  */
 16483       x_scroll_bar_redraw (bar);
 16484 #endif
 16485     }
 16486   else
 16487     {
 16488       /* It may just need to be moved and resized.  */
 16489       unsigned int mask = 0;
 16490 
 16491       bar = XSCROLL_BAR (w->vertical_scroll_bar);
 16492 
 16493       block_input ();
 16494 
 16495       if (left != bar->left)
 16496         mask |= CWX;
 16497       if (top != bar->top)
 16498         mask |= CWY;
 16499       if (width != bar->width)
 16500         mask |= CWWidth;
 16501       if (height != bar->height)
 16502         mask |= CWHeight;
 16503 
 16504 #ifdef USE_TOOLKIT_SCROLL_BARS
 16505 
 16506       /* Move/size the scroll bar widget.  */
 16507       if (mask)
 16508         {
 16509           /* Since toolkit scroll bars are smaller than the space reserved
 16510              for them on the frame, we have to clear "under" them.  */
 16511           if (width > 0 && height > 0)
 16512             x_clear_area (f, left, top, width, height);
 16513 #ifdef USE_GTK
 16514           xg_update_scrollbar_pos (f, bar->x_window, top,
 16515                                    left, width, max (height, 1));
 16516 #else /* not USE_GTK */
 16517           XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar),
 16518                              left, top, width, max (height, 1), 0);
 16519 #endif /* not USE_GTK */
 16520         }
 16521 #else /* not USE_TOOLKIT_SCROLL_BARS */
 16522 
 16523       /* Move/size the scroll bar window.  */
 16524       if (mask)
 16525         {
 16526           XWindowChanges wc;
 16527 
 16528           wc.x = left;
 16529           wc.y = top;
 16530           wc.width = width;
 16531           wc.height = height;
 16532           XConfigureWindow (FRAME_X_DISPLAY (f), bar->x_window,
 16533                             mask, &wc);
 16534         }
 16535 
 16536 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 16537 
 16538       /* Remember new settings.  */
 16539       bar->left = left;
 16540       bar->top = top;
 16541       bar->width = width;
 16542       bar->height = height;
 16543 
 16544 #ifndef USE_TOOLKIT_SCROLL_BARS
 16545       /* Redraw the scroll bar.  */
 16546       x_scroll_bar_redraw (bar);
 16547 #endif
 16548 
 16549       unblock_input ();
 16550     }
 16551 
 16552 #ifdef USE_TOOLKIT_SCROLL_BARS
 16553   x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
 16554 #else /* not USE_TOOLKIT_SCROLL_BARS */
 16555   /* Set the scroll bar's current state, unless we're currently being
 16556      dragged.  */
 16557   if (bar->dragging == -1)
 16558     {
 16559       int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height);
 16560 
 16561       if (whole == 0)
 16562         x_scroll_bar_set_handle (bar, 0, top_range, false);
 16563       else
 16564         {
 16565           int start = ((double) position * top_range) / whole;
 16566           int end = ((double) (position + portion) * top_range) / whole;
 16567           x_scroll_bar_set_handle (bar, start, end, false);
 16568         }
 16569     }
 16570 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 16571 
 16572   XSETVECTOR (barobj, bar);
 16573   wset_vertical_scroll_bar (w, barobj);
 16574 }
 16575 
 16576 
 16577 static void
 16578 XTset_horizontal_scroll_bar (struct window *w, int portion, int whole, int position)
 16579 {
 16580   struct frame *f = XFRAME (w->frame);
 16581   Lisp_Object barobj;
 16582   struct scroll_bar *bar;
 16583   int top, height, left, width;
 16584   int window_x, window_width;
 16585   int pixel_width = WINDOW_PIXEL_WIDTH (w);
 16586 
 16587   /* Get window dimensions.  */
 16588   window_box (w, ANY_AREA, &window_x, 0, &window_width, 0);
 16589   left = window_x;
 16590   width = window_width;
 16591   top = WINDOW_SCROLL_BAR_AREA_Y (w);
 16592   height = WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
 16593 
 16594   /* Does the scroll bar exist yet?  */
 16595   if (NILP (w->horizontal_scroll_bar))
 16596     {
 16597       if (width > 0 && height > 0)
 16598         {
 16599           block_input ();
 16600 
 16601           /* Clear also part between window_width and
 16602              WINDOW_PIXEL_WIDTH.  */
 16603           x_clear_area (f, left, top, pixel_width, height);
 16604           unblock_input ();
 16605         }
 16606 
 16607       bar = x_scroll_bar_create (w, top, left, width, height, true);
 16608     }
 16609   else
 16610     {
 16611       /* It may just need to be moved and resized.  */
 16612       unsigned int mask = 0;
 16613 
 16614       bar = XSCROLL_BAR (w->horizontal_scroll_bar);
 16615 
 16616       block_input ();
 16617 
 16618       if (left != bar->left)
 16619         mask |= CWX;
 16620       if (top != bar->top)
 16621         mask |= CWY;
 16622       if (width != bar->width)
 16623         mask |= CWWidth;
 16624       if (height != bar->height)
 16625         mask |= CWHeight;
 16626 
 16627 #ifdef USE_TOOLKIT_SCROLL_BARS
 16628       /* Move/size the scroll bar widget.  */
 16629       if (mask)
 16630         {
 16631           /* Since toolkit scroll bars are smaller than the space reserved
 16632              for them on the frame, we have to clear "under" them.  */
 16633           if (width > 0 && height > 0)
 16634             x_clear_area (f,
 16635                           WINDOW_LEFT_EDGE_X (w), top,
 16636                           pixel_width - WINDOW_RIGHT_DIVIDER_WIDTH (w), height);
 16637 #ifdef USE_GTK
 16638           xg_update_horizontal_scrollbar_pos (f, bar->x_window, top, left,
 16639                                               width, height);
 16640 #else /* not USE_GTK */
 16641           XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar),
 16642                              left, top, width, height, 0);
 16643 #endif /* not USE_GTK */
 16644         }
 16645 #else /* not USE_TOOLKIT_SCROLL_BARS */
 16646 
 16647       /* Clear areas not covered by the scroll bar because it's not as
 16648          wide as the area reserved for it.  This makes sure a
 16649          previous mode line display is cleared after C-x 2 C-x 1, for
 16650          example.  */
 16651       {
 16652         int area_height = WINDOW_CONFIG_SCROLL_BAR_HEIGHT (w);
 16653         int rest = area_height - height;
 16654         if (rest > 0 && width > 0)
 16655           x_clear_area (f, left, top, width, rest);
 16656       }
 16657 
 16658       /* Move/size the scroll bar window.  */
 16659       if (mask)
 16660         {
 16661           XWindowChanges wc;
 16662 
 16663           wc.x = left;
 16664           wc.y = top;
 16665           wc.width = width;
 16666           wc.height = height;
 16667           XConfigureWindow (FRAME_X_DISPLAY (f), bar->x_window,
 16668                             mask, &wc);
 16669         }
 16670 
 16671 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 16672 
 16673       /* Remember new settings.  */
 16674       bar->left = left;
 16675       bar->top = top;
 16676       bar->width = width;
 16677       bar->height = height;
 16678 
 16679       unblock_input ();
 16680     }
 16681 
 16682 #ifdef USE_TOOLKIT_SCROLL_BARS
 16683   x_set_toolkit_horizontal_scroll_bar_thumb (bar, portion, position, whole);
 16684 #else /* not USE_TOOLKIT_SCROLL_BARS */
 16685   /* Set the scroll bar's current state, unless we're currently being
 16686      dragged.  */
 16687   if (bar->dragging == -1)
 16688     {
 16689       int left_range = HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, width);
 16690 
 16691       if (whole == 0)
 16692         x_scroll_bar_set_handle (bar, 0, left_range, false);
 16693       else
 16694         {
 16695           int start = ((double) position * left_range) / whole;
 16696           int end = ((double) (position + portion) * left_range) / whole;
 16697           x_scroll_bar_set_handle (bar, start, end, false);
 16698         }
 16699     }
 16700 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 16701 
 16702   XSETVECTOR (barobj, bar);
 16703   wset_horizontal_scroll_bar (w, barobj);
 16704 }
 16705 
 16706 
 16707 /* The following three hooks are used when we're doing a thorough
 16708    redisplay of the frame.  We don't explicitly know which scroll bars
 16709    are going to be deleted, because keeping track of when windows go
 16710    away is a real pain - "Can you say set-window-configuration, boys
 16711    and girls?"  Instead, we just assert at the beginning of redisplay
 16712    that *all* scroll bars are to be removed, and then save a scroll bar
 16713    from the fiery pit when we actually redisplay its window.  */
 16714 
 16715 /* Arrange for all scroll bars on FRAME to be removed at the next call
 16716    to `*judge_scroll_bars_hook'.  A scroll bar may be spared if
 16717    `*redeem_scroll_bar_hook' is applied to its window before the judgment.  */
 16718 
 16719 static void
 16720 XTcondemn_scroll_bars (struct frame *frame)
 16721 {
 16722   if (!NILP (FRAME_SCROLL_BARS (frame)))
 16723     {
 16724       if (!NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
 16725         {
 16726           /* Prepend scrollbars to already condemned ones.  */
 16727           Lisp_Object last = FRAME_SCROLL_BARS (frame);
 16728 
 16729           while (!NILP (XSCROLL_BAR (last)->next))
 16730             last = XSCROLL_BAR (last)->next;
 16731 
 16732           XSCROLL_BAR (last)->next = FRAME_CONDEMNED_SCROLL_BARS (frame);
 16733           XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = last;
 16734         }
 16735 
 16736       fset_condemned_scroll_bars (frame, FRAME_SCROLL_BARS (frame));
 16737       fset_scroll_bars (frame, Qnil);
 16738     }
 16739 }
 16740 
 16741 
 16742 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
 16743    Note that WINDOW isn't necessarily condemned at all.  */
 16744 
 16745 static void
 16746 XTredeem_scroll_bar (struct window *w)
 16747 {
 16748   struct scroll_bar *bar;
 16749   Lisp_Object barobj;
 16750   struct frame *f;
 16751 
 16752   /* We can't redeem this window's scroll bar if it doesn't have one.  */
 16753   if (NILP (w->vertical_scroll_bar) && NILP (w->horizontal_scroll_bar))
 16754     emacs_abort ();
 16755 
 16756   if (!NILP (w->vertical_scroll_bar) && WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
 16757     {
 16758       bar = XSCROLL_BAR (w->vertical_scroll_bar);
 16759       /* Unlink it from the condemned list.  */
 16760       f = XFRAME (WINDOW_FRAME (w));
 16761       if (NILP (bar->prev))
 16762         {
 16763           /* If the prev pointer is nil, it must be the first in one of
 16764              the lists.  */
 16765           if (EQ (FRAME_SCROLL_BARS (f), w->vertical_scroll_bar))
 16766             /* It's not condemned.  Everything's fine.  */
 16767             goto horizontal;
 16768           else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
 16769                        w->vertical_scroll_bar))
 16770             fset_condemned_scroll_bars (f, bar->next);
 16771           else
 16772             /* If its prev pointer is nil, it must be at the front of
 16773                one or the other!  */
 16774             emacs_abort ();
 16775         }
 16776       else
 16777         XSCROLL_BAR (bar->prev)->next = bar->next;
 16778 
 16779       if (! NILP (bar->next))
 16780         XSCROLL_BAR (bar->next)->prev = bar->prev;
 16781 
 16782       bar->next = FRAME_SCROLL_BARS (f);
 16783       bar->prev = Qnil;
 16784       XSETVECTOR (barobj, bar);
 16785       fset_scroll_bars (f, barobj);
 16786       if (! NILP (bar->next))
 16787         XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
 16788     }
 16789 
 16790  horizontal:
 16791   if (!NILP (w->horizontal_scroll_bar) && WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
 16792     {
 16793       bar = XSCROLL_BAR (w->horizontal_scroll_bar);
 16794       /* Unlink it from the condemned list.  */
 16795       f = XFRAME (WINDOW_FRAME (w));
 16796       if (NILP (bar->prev))
 16797         {
 16798           /* If the prev pointer is nil, it must be the first in one of
 16799              the lists.  */
 16800           if (EQ (FRAME_SCROLL_BARS (f), w->horizontal_scroll_bar))
 16801             /* It's not condemned.  Everything's fine.  */
 16802             return;
 16803           else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
 16804                        w->horizontal_scroll_bar))
 16805             fset_condemned_scroll_bars (f, bar->next);
 16806           else
 16807             /* If its prev pointer is nil, it must be at the front of
 16808                one or the other!  */
 16809             emacs_abort ();
 16810         }
 16811       else
 16812         XSCROLL_BAR (bar->prev)->next = bar->next;
 16813 
 16814       if (! NILP (bar->next))
 16815         XSCROLL_BAR (bar->next)->prev = bar->prev;
 16816 
 16817       bar->next = FRAME_SCROLL_BARS (f);
 16818       bar->prev = Qnil;
 16819       XSETVECTOR (barobj, bar);
 16820       fset_scroll_bars (f, barobj);
 16821       if (! NILP (bar->next))
 16822         XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
 16823     }
 16824 }
 16825 
 16826 /* Remove all scroll bars on FRAME that haven't been saved since the
 16827    last call to `*condemn_scroll_bars_hook'.  */
 16828 
 16829 static void
 16830 XTjudge_scroll_bars (struct frame *f)
 16831 {
 16832   Lisp_Object bar, next;
 16833 
 16834   bar = FRAME_CONDEMNED_SCROLL_BARS (f);
 16835 
 16836   /* Clear out the condemned list now so we won't try to process any
 16837      more events on the hapless scroll bars.  */
 16838   fset_condemned_scroll_bars (f, Qnil);
 16839 
 16840   for (; ! NILP (bar); bar = next)
 16841     {
 16842       struct scroll_bar *b = XSCROLL_BAR (bar);
 16843 
 16844       x_scroll_bar_remove (b);
 16845 
 16846       next = b->next;
 16847       b->next = b->prev = Qnil;
 16848     }
 16849 
 16850   /* Now there should be no references to the condemned scroll bars,
 16851      and they should get garbage-collected.  */
 16852 }
 16853 
 16854 
 16855 #ifndef USE_TOOLKIT_SCROLL_BARS
 16856 /* Handle exposure event EVENT generated for F, by redrawing all
 16857    intersecting scroll bars.  */
 16858 
 16859 static void
 16860 x_scroll_bar_handle_exposure (struct frame *f, XEvent *event)
 16861 {
 16862   int x, y, width, height;
 16863   XRectangle rect, scroll_bar_rect, intersection;
 16864   Lisp_Object bar, condemned;
 16865   struct scroll_bar *b;
 16866 
 16867   if (event->type == GraphicsExpose)
 16868     {
 16869       x = event->xgraphicsexpose.x;
 16870       y = event->xgraphicsexpose.y;
 16871       width = event->xgraphicsexpose.width;
 16872       height = event->xgraphicsexpose.height;
 16873     }
 16874   else
 16875     {
 16876       x = event->xexpose.x;
 16877       y = event->xexpose.y;
 16878       width = event->xexpose.width;
 16879       height = event->xexpose.height;
 16880     }
 16881 
 16882   rect.x = x;
 16883   rect.y = y;
 16884   rect.width = width;
 16885   rect.height = height;
 16886 
 16887   /* Scan this frame's scroll bar list for intersecting scroll
 16888      bars.  */
 16889   condemned = FRAME_CONDEMNED_SCROLL_BARS (f);
 16890   for (bar = FRAME_SCROLL_BARS (f);
 16891        /* This trick allows us to search both the ordinary and
 16892           condemned scroll bar lists with one loop.  */
 16893        !NILP (bar) || (bar = condemned,
 16894                        condemned = Qnil,
 16895                        !NILP (bar));
 16896        bar = XSCROLL_BAR (bar)->next)
 16897     {
 16898       b = XSCROLL_BAR (bar);
 16899 
 16900       scroll_bar_rect.x = b->left;
 16901       scroll_bar_rect.y = b->top;
 16902       scroll_bar_rect.width = b->width;
 16903       scroll_bar_rect.height = b->height;
 16904 
 16905       if (gui_intersect_rectangles (&rect,
 16906                                     &scroll_bar_rect,
 16907                                     &intersection))
 16908         x_scroll_bar_redraw (b);
 16909     }
 16910 }
 16911 
 16912 /* Redraw the scroll bar BAR.  Draw its border and set its thumb.
 16913    This is usually called from x_clear_frame, but is also used to
 16914    handle exposure events that overlap scroll bars.  */
 16915 
 16916 static void
 16917 x_scroll_bar_redraw (struct scroll_bar *bar)
 16918 {
 16919   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 16920   GC gc = f->output_data.x->normal_gc;
 16921 
 16922   if (f->output_data.x->scroll_bar_background_pixel != -1)
 16923     XSetForeground (FRAME_X_DISPLAY (f), gc,
 16924                     f->output_data.x->scroll_bar_background_pixel);
 16925   else
 16926     XSetForeground (FRAME_X_DISPLAY (f), gc,
 16927                     FRAME_BACKGROUND_PIXEL (f));
 16928 
 16929   XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), gc,
 16930                   bar->left, bar->top, bar->width, bar->height);
 16931 
 16932   XSetForeground (FRAME_X_DISPLAY (f), gc,
 16933                   FRAME_FOREGROUND_PIXEL (f));
 16934 
 16935   x_scroll_bar_set_handle (bar, bar->start, bar->end, true);
 16936 
 16937   /* Switch to scroll bar foreground color.  */
 16938   if (f->output_data.x->scroll_bar_foreground_pixel != -1)
 16939     XSetForeground (FRAME_X_DISPLAY (f), gc,
 16940                     f->output_data.x->scroll_bar_foreground_pixel);
 16941 
 16942   /* Draw a one-pixel border just inside the edges of the scroll bar.  */
 16943   XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), gc,
 16944                   bar->left, bar->top, bar->width - 1, bar->height - 1);
 16945 
 16946   /* Restore the foreground color of the GC if we changed it above.  */
 16947   if (f->output_data.x->scroll_bar_foreground_pixel != -1)
 16948     XSetForeground (FRAME_X_DISPLAY (f), gc,
 16949                     FRAME_FOREGROUND_PIXEL (f));
 16950 }
 16951 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 16952 
 16953 /* Handle a mouse click on the scroll bar BAR.  If *EMACS_EVENT's kind
 16954    is set to something other than NO_EVENT, it is enqueued.
 16955 
 16956    This may be called from a signal handler, so we have to ignore GC
 16957    mark bits.  */
 16958 
 16959 
 16960 static void
 16961 x_scroll_bar_handle_click (struct scroll_bar *bar,
 16962                            const XEvent *event,
 16963                            struct input_event *emacs_event,
 16964                            Lisp_Object device)
 16965 {
 16966   int left_range, x, top_range, y;
 16967 #ifndef USE_TOOLKIT_SCROLL_BARS
 16968   int new_start, new_end;
 16969 #endif
 16970 
 16971   if (! WINDOWP (bar->window))
 16972     emacs_abort ();
 16973 
 16974   emacs_event->kind = (bar->horizontal
 16975                        ? HORIZONTAL_SCROLL_BAR_CLICK_EVENT
 16976                        : SCROLL_BAR_CLICK_EVENT);
 16977   emacs_event->code = event->xbutton.button - Button1;
 16978   emacs_event->modifiers
 16979     = (x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO
 16980                                (XFRAME (WINDOW_FRAME (XWINDOW (bar->window)))),
 16981                                event->xbutton.state)
 16982        | (event->type == ButtonRelease
 16983           ? up_modifier
 16984           : down_modifier));
 16985   emacs_event->frame_or_window = bar->window;
 16986   emacs_event->arg = Qnil;
 16987   emacs_event->timestamp = event->xbutton.time;
 16988 
 16989   if (!NILP (device))
 16990     emacs_event->device = device;
 16991 
 16992   if (bar->horizontal)
 16993     {
 16994 
 16995       left_range = HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, bar->width);
 16996       x = event->xbutton.x - HORIZONTAL_SCROLL_BAR_LEFT_BORDER;
 16997 
 16998       if (x < 0) x = 0;
 16999       if (x > left_range) x = left_range;
 17000 
 17001       if (x < bar->start)
 17002         emacs_event->part = scroll_bar_before_handle;
 17003       else if (x < bar->end + HORIZONTAL_SCROLL_BAR_MIN_HANDLE)
 17004         emacs_event->part = scroll_bar_horizontal_handle;
 17005       else
 17006         emacs_event->part = scroll_bar_after_handle;
 17007 
 17008 #ifndef USE_TOOLKIT_SCROLL_BARS
 17009       /* If the user has released the handle, set it to its final position.  */
 17010       if (event->type == ButtonRelease && bar->dragging != -1)
 17011         {
 17012           new_start = - bar->dragging;
 17013           new_end = new_start + bar->end - bar->start;
 17014 
 17015           x_scroll_bar_set_handle (bar, new_start, new_end, false);
 17016           bar->dragging = -1;
 17017         }
 17018 #endif
 17019 
 17020       XSETINT (emacs_event->x, left_range);
 17021       XSETINT (emacs_event->y, x);
 17022     }
 17023   else
 17024     {
 17025       top_range
 17026         = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height);
 17027       y = event->xbutton.y - VERTICAL_SCROLL_BAR_TOP_BORDER;
 17028 
 17029       if (y < 0) y = 0;
 17030       if (y > top_range) y = top_range;
 17031 
 17032       if (y < bar->start)
 17033         emacs_event->part = scroll_bar_above_handle;
 17034       else if (y < bar->end + VERTICAL_SCROLL_BAR_MIN_HANDLE)
 17035         emacs_event->part = scroll_bar_handle;
 17036       else
 17037         emacs_event->part = scroll_bar_below_handle;
 17038 
 17039 #ifndef USE_TOOLKIT_SCROLL_BARS
 17040       /* If the user has released the handle, set it to its final position.  */
 17041       if (event->type == ButtonRelease && bar->dragging != -1)
 17042         {
 17043           new_start = y - bar->dragging;
 17044           new_end = new_start + bar->end - bar->start;
 17045 
 17046           x_scroll_bar_set_handle (bar, new_start, new_end, false);
 17047           bar->dragging = -1;
 17048         }
 17049 #endif
 17050 
 17051       XSETINT (emacs_event->x, y);
 17052       XSETINT (emacs_event->y, top_range);
 17053     }
 17054 }
 17055 
 17056 #ifndef USE_TOOLKIT_SCROLL_BARS
 17057 
 17058 /* Handle some mouse motion while someone is dragging the scroll bar.
 17059 
 17060    This may be called from a signal handler, so we have to ignore GC
 17061    mark bits.  */
 17062 
 17063 static void
 17064 x_scroll_bar_note_movement (struct scroll_bar *bar,
 17065                             const XMotionEvent *event)
 17066 {
 17067   struct frame *f = XFRAME (XWINDOW (bar->window)->frame);
 17068   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 17069 
 17070   dpyinfo->last_mouse_movement_time = event->time;
 17071   dpyinfo->last_mouse_movement_time_send_event = event->send_event;
 17072   dpyinfo->last_mouse_scroll_bar = bar;
 17073   f->mouse_moved = true;
 17074 
 17075   /* If we're dragging the bar, display it.  */
 17076   if (bar->dragging != -1)
 17077     {
 17078       /* Where should the handle be now?  */
 17079       int new_start = event->y - bar->dragging;
 17080 
 17081       if (new_start != bar->start)
 17082         {
 17083           int new_end = new_start + bar->end - bar->start;
 17084 
 17085           x_scroll_bar_set_handle (bar, new_start, new_end, false);
 17086         }
 17087     }
 17088 }
 17089 
 17090 #endif /* !USE_TOOLKIT_SCROLL_BARS */
 17091 
 17092 /* Return information to the user about the current position of the mouse
 17093    on the scroll bar.  */
 17094 
 17095 static void
 17096 x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
 17097                             enum scroll_bar_part *part, Lisp_Object *x,
 17098                             Lisp_Object *y, Time *timestamp)
 17099 {
 17100   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
 17101   struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar;
 17102   Window w = bar->x_window;
 17103   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 17104   int win_x, win_y;
 17105   Window dummy_window;
 17106   int dummy_coord;
 17107   unsigned int dummy_mask;
 17108 
 17109   block_input ();
 17110 
 17111   /* Get the mouse's position relative to the scroll bar window, and
 17112      report that.  */
 17113   if (x_query_pointer (FRAME_X_DISPLAY (f), w,
 17114 
 17115                        /* Root, child, root x and root y.  */
 17116                        &dummy_window, &dummy_window,
 17117                        &dummy_coord, &dummy_coord,
 17118 
 17119                        /* Position relative to scroll bar.  */
 17120                        &win_x, &win_y,
 17121 
 17122                        /* Mouse buttons and modifier keys.  */
 17123                        &dummy_mask))
 17124     {
 17125       int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height);
 17126 
 17127       win_y -= VERTICAL_SCROLL_BAR_TOP_BORDER;
 17128 
 17129       if (bar->dragging != -1)
 17130         win_y -= bar->dragging;
 17131 
 17132       if (win_y < 0)
 17133         win_y = 0;
 17134       if (win_y > top_range)
 17135         win_y = top_range;
 17136 
 17137       *fp = f;
 17138       *bar_window = bar->window;
 17139 
 17140       if (bar->dragging != -1)
 17141         *part = scroll_bar_handle;
 17142       else if (win_y < bar->start)
 17143         *part = scroll_bar_above_handle;
 17144       else if (win_y < bar->end + VERTICAL_SCROLL_BAR_MIN_HANDLE)
 17145         *part = scroll_bar_handle;
 17146       else
 17147         *part = scroll_bar_below_handle;
 17148 
 17149       XSETINT (*x, win_y);
 17150       XSETINT (*y, top_range);
 17151 
 17152       f->mouse_moved = false;
 17153       dpyinfo->last_mouse_scroll_bar = NULL;
 17154       *timestamp = dpyinfo->last_mouse_movement_time;
 17155     }
 17156 
 17157   unblock_input ();
 17158 }
 17159 
 17160 
 17161 /* Return information to the user about the current position of the mouse
 17162    on the scroll bar.  */
 17163 
 17164 static void
 17165 x_horizontal_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
 17166                                        enum scroll_bar_part *part, Lisp_Object *x,
 17167                                        Lisp_Object *y, Time *timestamp)
 17168 {
 17169   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
 17170   struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar;
 17171   Window w = bar->x_window;
 17172   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 17173   int win_x, win_y;
 17174   Window dummy_window;
 17175   int dummy_coord;
 17176   unsigned int dummy_mask;
 17177 
 17178   block_input ();
 17179 
 17180   /* Get the mouse's position relative to the scroll bar window, and
 17181      report that.  */
 17182   if (x_query_pointer (FRAME_X_DISPLAY (f), w,
 17183 
 17184                        /* Root, child, root x and root y.  */
 17185                        &dummy_window, &dummy_window,
 17186                        &dummy_coord, &dummy_coord,
 17187 
 17188                        /* Position relative to scroll bar.  */
 17189                        &win_x, &win_y,
 17190 
 17191                        /* Mouse buttons and modifier keys.  */
 17192                        &dummy_mask))
 17193     {
 17194       int left_range = HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, bar->width);
 17195 
 17196       win_x -= HORIZONTAL_SCROLL_BAR_LEFT_BORDER;
 17197 
 17198       if (bar->dragging != -1)
 17199         win_x -= bar->dragging;
 17200 
 17201       if (win_x < 0)
 17202         win_x = 0;
 17203       if (win_x > left_range)
 17204         win_x = left_range;
 17205 
 17206       *fp = f;
 17207       *bar_window = bar->window;
 17208 
 17209       if (bar->dragging != -1)
 17210         *part = scroll_bar_horizontal_handle;
 17211       else if (win_x < bar->start)
 17212         *part = scroll_bar_before_handle;
 17213       else if (win_x < bar->end + HORIZONTAL_SCROLL_BAR_MIN_HANDLE)
 17214         *part = scroll_bar_handle;
 17215       else
 17216         *part = scroll_bar_after_handle;
 17217 
 17218       XSETINT (*y, win_x);
 17219       XSETINT (*x, left_range);
 17220 
 17221       f->mouse_moved = false;
 17222       dpyinfo->last_mouse_scroll_bar = NULL;
 17223       *timestamp = dpyinfo->last_mouse_movement_time;
 17224     }
 17225 
 17226   unblock_input ();
 17227 }
 17228 
 17229 
 17230 /* The screen has been cleared and foreground or background colors may
 17231    have changed, so the scroll bars need to be redrawn.  Clear the
 17232    scroll bars and redraw them.  */
 17233 
 17234 static void
 17235 x_scroll_bar_clear (struct frame *f)
 17236 {
 17237 #ifndef USE_TOOLKIT_SCROLL_BARS
 17238   Lisp_Object bar, condemned;
 17239   GC gc = f->output_data.x->normal_gc;
 17240 
 17241   if (f->output_data.x->scroll_bar_background_pixel != -1)
 17242     XSetForeground (FRAME_X_DISPLAY (f), gc,
 17243                     f->output_data.x->scroll_bar_background_pixel);
 17244   else
 17245     XSetForeground (FRAME_X_DISPLAY (f), gc,
 17246                     FRAME_BACKGROUND_PIXEL (f));
 17247 
 17248   /* We can have scroll bars even if this is 0,
 17249      if we just turned off scroll bar mode.
 17250      But in that case we should not clear them.  */
 17251   if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
 17252     {
 17253       condemned = FRAME_CONDEMNED_SCROLL_BARS (f);
 17254       for (bar = FRAME_SCROLL_BARS (f);
 17255            /* This trick allows us to search both the ordinary and
 17256               condemned scroll bar lists with one loop.  */
 17257            !NILP (bar) || (bar = condemned,
 17258                            condemned = Qnil,
 17259                            !NILP (bar));
 17260            bar = XSCROLL_BAR (bar)->next)
 17261         x_scroll_bar_redraw (XSCROLL_BAR (bar));
 17262     }
 17263 
 17264   XSetForeground (FRAME_X_DISPLAY (f), gc,
 17265                   FRAME_FOREGROUND_PIXEL (f));
 17266 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 17267 }
 17268 
 17269 #ifdef ENABLE_CHECKING
 17270 
 17271 /* Record the last 100 characters stored
 17272    to help debug the loss-of-chars-during-GC problem.  */
 17273 
 17274 static int temp_index;
 17275 static short temp_buffer[100];
 17276 
 17277 #define STORE_KEYSYM_FOR_DEBUG(keysym)                          \
 17278   if (temp_index == ARRAYELTS (temp_buffer))                    \
 17279     temp_index = 0;                                             \
 17280   temp_buffer[temp_index++] = (keysym)
 17281 
 17282 #else /* not ENABLE_CHECKING */
 17283 
 17284 #define STORE_KEYSYM_FOR_DEBUG(keysym) ((void)0)
 17285 
 17286 #endif /* ENABLE_CHECKING */
 17287 
 17288 /* Set this to nonzero to fake an "X I/O error"
 17289    on a particular display.  */
 17290 
 17291 static struct x_display_info *XTread_socket_fake_io_error;
 17292 
 17293 /* When we find no input here, we occasionally do a no-op command
 17294    to verify that the X server is still running and we can still talk with it.
 17295    We try all the open displays, one by one.
 17296    This variable is used for cycling thru the displays.  */
 17297 
 17298 static struct x_display_info *next_noop_dpyinfo;
 17299 
 17300 /* Filter events for the current X input method.
 17301    DPYINFO is the display this event is for.
 17302    EVENT is the X event to filter.
 17303 
 17304    Returns non-zero if the event was filtered, caller shall not process
 17305    this event further.
 17306    Returns zero if event is wasn't filtered.  */
 17307 
 17308 #ifdef HAVE_X_I18N
 17309 static int
 17310 x_filter_event (struct x_display_info *dpyinfo, XEvent *event)
 17311 {
 17312   /* XFilterEvent returns non-zero if the input method has
 17313    consumed the event.  We pass the frame's X window to
 17314    XFilterEvent because that's the one for which the IC
 17315    was created.  */
 17316 
 17317   struct frame *f1;
 17318 
 17319 #if defined HAVE_XINPUT2 && defined USE_GTK
 17320   bool xinput_event = false;
 17321   if (dpyinfo->supports_xi2
 17322       && event->type == GenericEvent
 17323       && (event->xgeneric.extension
 17324           == dpyinfo->xi2_opcode)
 17325       && ((event->xgeneric.evtype
 17326            == XI_KeyPress)
 17327           || (event->xgeneric.evtype
 17328               == XI_KeyRelease)))
 17329     {
 17330       f1 = x_any_window_to_frame (dpyinfo,
 17331                                   ((XIDeviceEvent *)
 17332                                    event->xcookie.data)->event);
 17333       xinput_event = true;
 17334     }
 17335   else
 17336 #endif
 17337     f1 = x_any_window_to_frame (dpyinfo,
 17338                                 event->xclient.window);
 17339 
 17340 #ifdef USE_GTK
 17341   if (!x_gtk_use_native_input
 17342       && !dpyinfo->prefer_native_input)
 17343     {
 17344 #endif
 17345       return XFilterEvent (event, f1 ? FRAME_X_WINDOW (f1) : None);
 17346 #ifdef USE_GTK
 17347     }
 17348   else if (f1 && (event->type == KeyPress
 17349                   || event->type == KeyRelease
 17350 #ifdef HAVE_XINPUT2
 17351                   || xinput_event
 17352 #endif
 17353                   ))
 17354     {
 17355       bool result;
 17356 
 17357       block_input ();
 17358       result = xg_filter_key (f1, event);
 17359       unblock_input ();
 17360 
 17361       /* Clear `xg_pending_quit_event' so we don't end up reacting to quit
 17362          events sent outside the main event loop (i.e. those sent from
 17363          inside a popup menu event loop).  */
 17364 
 17365       if (popup_activated ())
 17366         xg_pending_quit_event.kind = NO_EVENT;
 17367 
 17368       if (result && f1)
 17369         /* There will probably be a GDK event generated soon, so
 17370            exercise the wire to make pselect return.  */
 17371         XNoOp (FRAME_X_DISPLAY (f1));
 17372 
 17373       return result;
 17374     }
 17375 
 17376   return 0;
 17377 #endif
 17378 }
 17379 #endif
 17380 
 17381 #ifdef USE_GTK
 17382 /* This is the filter function invoked by the GTK event loop.
 17383    It is invoked before the XEvent is translated to a GdkEvent,
 17384    so we have a chance to act on the event before GTK.  */
 17385 static GdkFilterReturn
 17386 event_handler_gdk (GdkXEvent *gxev, GdkEvent *ev, gpointer data)
 17387 {
 17388   XEvent *xev = (XEvent *) gxev;
 17389 
 17390   block_input ();
 17391   if (current_count >= 0)
 17392     {
 17393       struct x_display_info *dpyinfo;
 17394 
 17395       dpyinfo = x_display_info_for_display (xev->xany.display);
 17396 
 17397 #ifdef HAVE_X_I18N
 17398       /* Filter events for the current X input method.
 17399          GTK calls XFilterEvent but not for key press and release,
 17400          so we do it here.  */
 17401       if ((xev->type == KeyPress || xev->type == KeyRelease)
 17402           && dpyinfo
 17403           && x_filter_event (dpyinfo, xev))
 17404         {
 17405           unblock_input ();
 17406           return GDK_FILTER_REMOVE;
 17407         }
 17408 #elif USE_GTK
 17409       if (dpyinfo && (dpyinfo->prefer_native_input
 17410                       || x_gtk_use_native_input)
 17411           && (xev->type == KeyPress
 17412 #ifdef HAVE_XINPUT2
 17413               /* GTK claims cookies for us, so we don't have to claim
 17414                  them here.  */
 17415               || (dpyinfo->supports_xi2
 17416                   && xev->type == GenericEvent
 17417                   && (xev->xgeneric.extension
 17418                       == dpyinfo->xi2_opcode)
 17419                   && ((xev->xgeneric.evtype
 17420                        == XI_KeyPress)
 17421                       || (xev->xgeneric.evtype
 17422                           == XI_KeyRelease)))
 17423 #endif
 17424               ))
 17425         {
 17426           struct frame *f;
 17427 
 17428 #ifdef HAVE_XINPUT2
 17429           if (xev->type == GenericEvent)
 17430             f = x_any_window_to_frame (dpyinfo,
 17431                                        ((XIDeviceEvent *) xev->xcookie.data)->event);
 17432           else
 17433 #endif
 17434             f = x_any_window_to_frame (dpyinfo, xev->xany.window);
 17435 
 17436           if (f && xg_filter_key (f, xev))
 17437             {
 17438               unblock_input ();
 17439               return GDK_FILTER_REMOVE;
 17440             }
 17441         }
 17442 #endif
 17443 
 17444       if (! dpyinfo)
 17445         current_finish = X_EVENT_NORMAL;
 17446       else
 17447         current_count
 17448           += handle_one_xevent (dpyinfo, xev, &current_finish,
 17449                                 current_hold_quit);
 17450     }
 17451   else
 17452     current_finish = x_dispatch_event (xev, xev->xany.display);
 17453 
 17454   unblock_input ();
 17455 
 17456   if (current_finish == X_EVENT_GOTO_OUT || current_finish == X_EVENT_DROP)
 17457     return GDK_FILTER_REMOVE;
 17458 
 17459   return GDK_FILTER_CONTINUE;
 17460 }
 17461 #endif /* USE_GTK */
 17462 
 17463 
 17464 static void xembed_send_message (struct frame *f, Time,
 17465                                  enum xembed_message,
 17466                                  long detail, long data1, long data2);
 17467 
 17468 static void
 17469 x_net_wm_state (struct frame *f, Window window)
 17470 {
 17471   int value = FULLSCREEN_NONE;
 17472   Lisp_Object lval = Qnil;
 17473   bool sticky = false, shaded = false;
 17474 
 17475   x_get_current_wm_state (f, window, &value, &sticky, &shaded);
 17476 
 17477   switch (value)
 17478     {
 17479     case FULLSCREEN_WIDTH:
 17480       lval = Qfullwidth;
 17481       break;
 17482     case FULLSCREEN_HEIGHT:
 17483       lval = Qfullheight;
 17484       break;
 17485     case FULLSCREEN_BOTH:
 17486       lval = Qfullboth;
 17487       break;
 17488     case FULLSCREEN_MAXIMIZED:
 17489       lval = Qmaximized;
 17490       break;
 17491     }
 17492 
 17493   store_frame_param (f, Qfullscreen, lval);
 17494   store_frame_param (f, Qsticky, sticky ? Qt : Qnil);
 17495   store_frame_param (f, Qshaded, shaded ? Qt : Qnil);
 17496 }
 17497 
 17498 /* Flip back buffers on F if it has undrawn content.  */
 17499 
 17500 static void
 17501 x_flush_dirty_back_buffer_on (struct frame *f)
 17502 {
 17503 #ifdef HAVE_XDBE
 17504   if (FRAME_GARBAGED_P (f)
 17505       || buffer_flipping_blocked_p ()
 17506       /* If the frame is not already up to date, do not flush buffers
 17507          on input, as that will result in flicker.  */
 17508       || !FRAME_X_COMPLETE_P (f)
 17509       || !FRAME_X_NEED_BUFFER_FLIP (f))
 17510     return;
 17511 
 17512   show_back_buffer (f);
 17513 #endif
 17514 }
 17515 
 17516 #ifdef HAVE_GTK3
 17517 void
 17518 x_scroll_bar_configure (GdkEvent *event)
 17519 {
 17520   XEvent configure;
 17521   GdkDisplay *gdpy;
 17522   Display *dpy;
 17523 
 17524   configure.xconfigure.type = ConfigureNotify;
 17525   configure.xconfigure.serial = 0;
 17526   configure.xconfigure.send_event = event->configure.send_event;
 17527   configure.xconfigure.x = event->configure.x;
 17528   configure.xconfigure.y = event->configure.y;
 17529   configure.xconfigure.width = event->configure.width;
 17530   configure.xconfigure.height = event->configure.height;
 17531   configure.xconfigure.border_width = 0;
 17532   configure.xconfigure.event = GDK_WINDOW_XID (event->configure.window);
 17533   configure.xconfigure.window = GDK_WINDOW_XID (event->configure.window);
 17534   configure.xconfigure.above = None;
 17535   configure.xconfigure.override_redirect = False;
 17536 
 17537   gdpy = gdk_window_get_display (event->configure.window);
 17538   dpy = gdk_x11_display_get_xdisplay (gdpy);
 17539 
 17540   x_dispatch_event (&configure, dpy);
 17541 }
 17542 #endif
 17543 
 17544 /**
 17545   mouse_or_wdesc_frame: When not dropping and the mouse was grabbed
 17546   for DPYINFO, return the frame where the mouse was seen last.  If
 17547   there's no such frame, return the frame according to WDESC.  When
 17548   dropping, return the frame according to WDESC.  If there's no such
 17549   frame and the mouse was grabbed for DPYINFO, return the frame where
 17550   the mouse was seen last.  In either case, never return a tooltip
 17551   frame.  */
 17552 static struct frame *
 17553 mouse_or_wdesc_frame (struct x_display_info *dpyinfo, int wdesc)
 17554 {
 17555   struct frame *lm_f = (gui_mouse_grabbed (dpyinfo)
 17556                         ? dpyinfo->last_mouse_frame
 17557                         : NULL);
 17558 
 17559   if (lm_f && !EQ (track_mouse, Qdropping)
 17560       && !EQ (track_mouse, Qdrag_source))
 17561     return lm_f;
 17562   else
 17563     {
 17564       struct frame *w_f = x_window_to_frame (dpyinfo, wdesc);
 17565 
 17566       /* Do not return a tooltip frame.  */
 17567       if (!w_f || FRAME_TOOLTIP_P (w_f))
 17568         return EQ (track_mouse, Qdropping) ? lm_f : NULL;
 17569       else
 17570         /* When dropping it would be probably nice to raise w_f
 17571            here.  */
 17572         return w_f;
 17573     }
 17574 }
 17575 
 17576 static void
 17577 x_dnd_compute_tip_xy (int *root_x, int *root_y, Lisp_Object attributes)
 17578 {
 17579   Lisp_Object monitor, geometry;
 17580   int min_x, min_y, max_x, max_y;
 17581   int width, height;
 17582 
 17583   width = FRAME_PIXEL_WIDTH (XFRAME (tip_frame));
 17584   height = FRAME_PIXEL_HEIGHT (XFRAME (tip_frame));
 17585 
 17586   max_y = -1;
 17587 
 17588   /* Try to determine the monitor where the mouse pointer is and
 17589      its geometry.  See bug#22549.  */
 17590   while (CONSP (attributes))
 17591     {
 17592       monitor = XCAR (attributes);
 17593       geometry = assq_no_quit (Qgeometry, monitor);
 17594 
 17595       if (CONSP (geometry))
 17596         {
 17597           min_x = XFIXNUM (Fnth (make_fixnum (1), geometry));
 17598           min_y = XFIXNUM (Fnth (make_fixnum (2), geometry));
 17599           max_x = min_x + XFIXNUM (Fnth (make_fixnum (3), geometry));
 17600           max_y = min_y + XFIXNUM (Fnth (make_fixnum (4), geometry));
 17601 
 17602           if (min_x <= *root_x && *root_x < max_x
 17603               && min_y <= *root_y && *root_y < max_y)
 17604             break;
 17605 
 17606           max_y = -1;
 17607         }
 17608 
 17609       attributes = XCDR (attributes);
 17610     }
 17611 
 17612   /* It was not possible to determine the monitor's geometry, so we
 17613      assign some sane defaults here: */
 17614   if (max_y < 0)
 17615     {
 17616       min_x = 0;
 17617       min_y = 0;
 17618       max_x = x_display_pixel_width (FRAME_DISPLAY_INFO (x_dnd_frame));
 17619       max_y = x_display_pixel_height (FRAME_DISPLAY_INFO (x_dnd_frame));
 17620     }
 17621 
 17622   if (*root_y + XFIXNUM (tip_dy) <= min_y)
 17623     *root_y = min_y; /* Can happen for negative dy */
 17624   else if (*root_y + XFIXNUM (tip_dy) + height <= max_y)
 17625     /* It fits below the pointer */
 17626     *root_y += XFIXNUM (tip_dy);
 17627   else if (height + XFIXNUM (tip_dy) + min_y <= *root_y)
 17628     /* It fits above the pointer.  */
 17629     *root_y -= height + XFIXNUM (tip_dy);
 17630   else
 17631     /* Put it on the top.  */
 17632     *root_y = min_y;
 17633 
 17634   if (*root_x + XFIXNUM (tip_dx) <= min_x)
 17635     *root_x = 0; /* Can happen for negative dx */
 17636   else if (*root_x + XFIXNUM (tip_dx) + width <= max_x)
 17637     /* It fits to the right of the pointer.  */
 17638     *root_x += XFIXNUM (tip_dx);
 17639   else if (width + XFIXNUM (tip_dx) + min_x <= *root_x)
 17640     /* It fits to the left of the pointer.  */
 17641     *root_x -= width + XFIXNUM (tip_dx);
 17642   else
 17643     /* Put it left justified on the screen -- it ought to fit that way.  */
 17644     *root_x = min_x;
 17645 }
 17646 
 17647 static void
 17648 x_dnd_update_tooltip_position (int root_x, int root_y)
 17649 {
 17650   struct frame *tip_f;
 17651 
 17652   if (!x_dnd_in_progress || !x_dnd_update_tooltip)
 17653     return;
 17654 
 17655   if (!FRAMEP (tip_frame))
 17656     return;
 17657 
 17658   tip_f = XFRAME (tip_frame);
 17659 
 17660   if (!FRAME_LIVE_P (tip_f)
 17661       || !FRAME_VISIBLE_P (tip_f)
 17662       || (FRAME_X_DISPLAY (tip_f)
 17663           != FRAME_X_DISPLAY (x_dnd_frame)))
 17664     return;
 17665 
 17666   if (tip_window != None
 17667       && FIXNUMP (tip_dx) && FIXNUMP (tip_dy))
 17668     {
 17669       x_dnd_compute_tip_xy (&root_x, &root_y,
 17670                             x_dnd_monitors);
 17671 
 17672       if (x_dnd_last_tooltip_valid
 17673           && root_x == x_dnd_last_tooltip_x
 17674           && root_y == x_dnd_last_tooltip_y)
 17675         return;
 17676 
 17677       x_dnd_last_tooltip_x = root_x;
 17678       x_dnd_last_tooltip_y = root_y;
 17679       x_dnd_last_tooltip_valid = true;
 17680 
 17681       XMoveWindow (FRAME_X_DISPLAY (x_dnd_frame),
 17682                    tip_window, root_x, root_y);
 17683     }
 17684 }
 17685 
 17686 static void
 17687 x_dnd_update_tooltip_now (void)
 17688 {
 17689   int root_x, root_y;
 17690   Window root, child;
 17691   int win_x, win_y;
 17692   unsigned int mask;
 17693   Bool rc;
 17694   struct x_display_info *dpyinfo;
 17695 
 17696   if (!x_dnd_in_progress || !x_dnd_update_tooltip)
 17697     return;
 17698 
 17699   dpyinfo = FRAME_DISPLAY_INFO (x_dnd_frame);
 17700 
 17701 #ifndef HAVE_XINPUT2
 17702   rc = XQueryPointer (dpyinfo->display,
 17703                       dpyinfo->root_window,
 17704                       &root, &child, &root_x,
 17705                       &root_y, &win_x, &win_y,
 17706                       &mask);
 17707 #else
 17708   rc = x_query_pointer_1 (dpyinfo, x_dnd_pointer_device,
 17709                           dpyinfo->root_window,
 17710                           &root, &child, &root_x,
 17711                           &root_y, &win_x, &win_y,
 17712                           &mask);
 17713 #endif
 17714 
 17715   if (rc)
 17716     x_dnd_update_tooltip_position (root_x, root_y);
 17717 }
 17718 
 17719 /* Get the window underneath the pointer, see if it moved, and update
 17720    the DND state accordingly.  */
 17721 static void
 17722 x_dnd_update_state (struct x_display_info *dpyinfo, Time timestamp)
 17723 {
 17724   int root_x, root_y, dummy_x, dummy_y, target_proto, motif_style;
 17725   unsigned int dummy_mask;
 17726   Window dummy, dummy_child, target, toplevel;
 17727   xm_top_level_leave_message lmsg;
 17728   xm_top_level_enter_message emsg;
 17729   xm_drag_motion_message dmsg;
 17730   xm_drop_start_message dsmsg;
 17731   bool was_frame;
 17732 
 17733   if (x_query_pointer_1 (dpyinfo,
 17734 #ifdef HAVE_XINPUT2
 17735                          x_dnd_pointer_device,
 17736 #else
 17737                          -1,
 17738 #endif
 17739                          dpyinfo->root_window,
 17740                          &dummy, &dummy_child,
 17741                          &root_x, &root_y,
 17742                          &dummy_x, &dummy_y,
 17743                          &dummy_mask))
 17744     {
 17745       target = x_dnd_get_target_window (dpyinfo, root_x,
 17746                                         root_y, &target_proto,
 17747                                         &motif_style, &toplevel,
 17748                                         &was_frame);
 17749 
 17750       if (toplevel != x_dnd_last_seen_toplevel)
 17751         {
 17752           if (toplevel != FRAME_OUTER_WINDOW (x_dnd_frame)
 17753               && x_dnd_return_frame == 1)
 17754             x_dnd_return_frame = 2;
 17755 
 17756           if (x_dnd_return_frame == 2
 17757               && x_any_window_to_frame (dpyinfo, toplevel))
 17758             {
 17759               if (x_dnd_last_seen_window != None
 17760                   && x_dnd_last_protocol_version != -1
 17761                   && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 17762                 x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window,
 17763                                   x_dnd_last_seen_toplevel);
 17764               else if (x_dnd_last_seen_window != None
 17765                        && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)
 17766                        && !x_dnd_disable_motif_drag
 17767                        && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 17768                 {
 17769                   if (!x_dnd_motif_setup_p)
 17770                     xm_setup_drag_info (dpyinfo, x_dnd_frame);
 17771 
 17772                   lmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 17773                                                 XM_DRAG_REASON_TOP_LEVEL_LEAVE);
 17774                   lmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 17775                   lmsg.zero = 0;
 17776                   lmsg.timestamp = timestamp;
 17777                   lmsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 17778 
 17779                   if (x_dnd_motif_setup_p)
 17780                     xm_send_top_level_leave_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 17781                                                      x_dnd_last_seen_window, &lmsg);
 17782                 }
 17783 
 17784               x_dnd_end_window = x_dnd_last_seen_window;
 17785               x_dnd_last_seen_window = None;
 17786               x_dnd_last_seen_toplevel = None;
 17787               x_dnd_in_progress = false;
 17788               x_dnd_return_frame_object
 17789                 = x_any_window_to_frame (dpyinfo, toplevel);
 17790               x_dnd_return_frame = 3;
 17791               x_dnd_waiting_for_finish = false;
 17792               target = None;
 17793             }
 17794         }
 17795 
 17796       if (target != x_dnd_last_seen_window)
 17797         {
 17798           if (x_dnd_last_seen_window != None
 17799               && x_dnd_last_protocol_version != -1
 17800               && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 17801             x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window,
 17802                               x_dnd_last_seen_toplevel);
 17803           else if (x_dnd_last_seen_window != None
 17804                    && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)
 17805                    && !x_dnd_disable_motif_drag
 17806                    && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 17807             {
 17808               if (!x_dnd_motif_setup_p)
 17809                 xm_setup_drag_info (dpyinfo, x_dnd_frame);
 17810 
 17811               lmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 17812                                             XM_DRAG_REASON_TOP_LEVEL_LEAVE);
 17813               lmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 17814               lmsg.zero = 0;
 17815               lmsg.timestamp = timestamp;
 17816               lmsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 17817 
 17818               if (x_dnd_motif_setup_p)
 17819                 xm_send_top_level_leave_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 17820                                                  x_dnd_last_seen_window, &lmsg);
 17821             }
 17822 
 17823           x_dnd_action = None;
 17824           x_dnd_last_seen_toplevel = toplevel;
 17825           x_dnd_last_seen_window = target;
 17826           x_dnd_last_protocol_version = target_proto;
 17827           x_dnd_last_motif_style = motif_style;
 17828           x_dnd_last_window_is_frame = was_frame;
 17829 
 17830           if (target != None && x_dnd_last_protocol_version != -1)
 17831             x_dnd_send_enter (x_dnd_frame, target, x_dnd_last_seen_toplevel,
 17832                               x_dnd_last_protocol_version);
 17833           else if (target != None && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)
 17834                    && !x_dnd_disable_motif_drag)
 17835             {
 17836               if (!x_dnd_motif_setup_p)
 17837                 xm_setup_drag_info (dpyinfo, x_dnd_frame);
 17838 
 17839               emsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 17840                                             XM_DRAG_REASON_TOP_LEVEL_ENTER);
 17841               emsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 17842               emsg.zero = 0;
 17843               emsg.timestamp = timestamp;
 17844               emsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 17845               emsg.index_atom = x_dnd_motif_atom;
 17846 
 17847               if (x_dnd_motif_setup_p)
 17848                 xm_send_top_level_enter_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 17849                                                  target, &emsg);
 17850             }
 17851         }
 17852       else
 17853         x_dnd_last_seen_toplevel = toplevel;
 17854 
 17855       if (x_dnd_last_window_is_frame && target != None)
 17856         x_dnd_note_self_position (dpyinfo, target, root_x, root_y);
 17857       else if (x_dnd_last_protocol_version != -1 && target != None)
 17858         x_dnd_send_position (x_dnd_frame, target,
 17859                              x_dnd_last_seen_toplevel,
 17860                              x_dnd_last_protocol_version,
 17861                              root_x, root_y,
 17862                              x_dnd_selection_timestamp,
 17863                              x_dnd_wanted_action, 0,
 17864 #ifdef HAVE_XKB
 17865                              x_dnd_keyboard_state
 17866 #else
 17867                              0
 17868 #endif
 17869                              );
 17870       else if (XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) && target != None
 17871                && !x_dnd_disable_motif_drag)
 17872         {
 17873           if (!x_dnd_motif_setup_p)
 17874             xm_setup_drag_info (dpyinfo, x_dnd_frame);
 17875 
 17876           dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 17877                                         XM_DRAG_REASON_DRAG_MOTION);
 17878           dmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 17879           dmsg.side_effects
 17880             = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo,
 17881                                                                x_dnd_wanted_action),
 17882                                    XM_DROP_SITE_VALID, x_dnd_motif_operations,
 17883                                    (!x_dnd_xm_use_help
 17884                                     ? XM_DROP_ACTION_DROP
 17885                                     : XM_DROP_ACTION_DROP_HELP));
 17886           dmsg.timestamp = timestamp;
 17887           dmsg.x = root_x;
 17888           dmsg.y = root_y;
 17889 
 17890           if (x_dnd_motif_setup_p)
 17891             xm_send_drag_motion_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 17892                                          target, &dmsg);
 17893         }
 17894 
 17895       x_dnd_update_tooltip_position (root_x, root_y);
 17896     }
 17897   /* The pointer moved out of the screen.  */
 17898   else if (x_dnd_last_protocol_version != -1)
 17899     {
 17900       if (x_dnd_last_seen_window != None
 17901           && x_dnd_last_protocol_version != -1)
 17902         x_dnd_send_leave (x_dnd_frame,
 17903                           x_dnd_last_seen_window,
 17904                           x_dnd_last_seen_toplevel);
 17905       else if (x_dnd_last_seen_window != None
 17906                && !XM_DRAG_STYLE_IS_DROP_ONLY (x_dnd_last_motif_style)
 17907                && x_dnd_last_motif_style != XM_DRAG_STYLE_NONE
 17908                && x_dnd_motif_setup_p)
 17909         {
 17910           dsmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 17911                                          XM_DRAG_REASON_DROP_START);
 17912           dmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 17913           dsmsg.timestamp = timestamp;
 17914           dsmsg.side_effects
 17915             = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo,
 17916                                                                x_dnd_wanted_action),
 17917                                    XM_DROP_SITE_VALID, x_dnd_motif_operations,
 17918                                    XM_DROP_ACTION_DROP_CANCEL);
 17919           dsmsg.x = 0;
 17920           dsmsg.y = 0;
 17921           dsmsg.index_atom = x_dnd_motif_atom;
 17922           dsmsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 17923 
 17924           x_dnd_send_xm_leave_for_drop (dpyinfo, x_dnd_frame,
 17925                                         x_dnd_last_seen_window, timestamp);
 17926           xm_send_drop_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 17927                                 x_dnd_last_seen_window, &dsmsg);
 17928         }
 17929 
 17930       x_dnd_end_window = x_dnd_last_seen_window;
 17931       x_dnd_last_seen_window = None;
 17932       x_dnd_last_seen_toplevel = None;
 17933       x_dnd_in_progress = false;
 17934       x_dnd_waiting_for_finish = false;
 17935       x_dnd_frame = NULL;
 17936     }
 17937 }
 17938 
 17939 int
 17940 x_display_pixel_height (struct x_display_info *dpyinfo)
 17941 {
 17942   if (dpyinfo->screen_height)
 17943     return dpyinfo->screen_height;
 17944 
 17945   return HeightOfScreen (dpyinfo->screen);
 17946 }
 17947 
 17948 int
 17949 x_display_pixel_width (struct x_display_info *dpyinfo)
 17950 {
 17951   if (dpyinfo->screen_width)
 17952     return dpyinfo->screen_width;
 17953 
 17954   return WidthOfScreen (dpyinfo->screen);
 17955 }
 17956 
 17957 /* Handle events from each display until CELL's car becomes non-nil,
 17958    or TIMEOUT elapses.  */
 17959 void
 17960 x_wait_for_cell_change (Lisp_Object cell, struct timespec timeout)
 17961 {
 17962   struct x_display_info *dpyinfo;
 17963   fd_set fds;
 17964   int fd, maxfd;
 17965 #ifndef USE_GTK
 17966   int finish, rc;
 17967   XEvent event;
 17968   fd_set rfds;
 17969 #endif
 17970   struct input_event hold_quit;
 17971   struct timespec current, at;
 17972 
 17973   at = timespec_add (current_timespec (), timeout);
 17974 
 17975 #ifndef USE_GTK
 17976   FD_ZERO (&rfds);
 17977   rc = -1;
 17978 #endif
 17979 
 17980   while (true)
 17981     {
 17982       FD_ZERO (&fds);
 17983       maxfd = -1;
 17984 
 17985       for (dpyinfo = x_display_list; dpyinfo;
 17986            dpyinfo = dpyinfo->next)
 17987         {
 17988           fd = ConnectionNumber (dpyinfo->display);
 17989 
 17990 #ifndef USE_GTK
 17991           if ((rc < 0 || FD_ISSET (fd, &rfds))
 17992               /* If pselect failed, the erroring display's IO error
 17993                  handler will eventually be called.  */
 17994               && XPending (dpyinfo->display))
 17995             {
 17996               while (XPending (dpyinfo->display))
 17997                 {
 17998                   EVENT_INIT (hold_quit);
 17999 
 18000                   XNextEvent (dpyinfo->display, &event);
 18001                   handle_one_xevent (dpyinfo, &event,
 18002                                      &finish, &hold_quit);
 18003 
 18004                   if (!NILP (XCAR (cell)))
 18005                     return;
 18006 
 18007                   if (finish == X_EVENT_GOTO_OUT)
 18008                     break;
 18009 
 18010                   /* Make us quit now.  */
 18011                   if (hold_quit.kind != NO_EVENT)
 18012                     kbd_buffer_store_event (&hold_quit);
 18013                 }
 18014             }
 18015 #endif
 18016 
 18017           if (fd > maxfd)
 18018             maxfd = fd;
 18019 
 18020           eassert (fd < FD_SETSIZE);
 18021           FD_SET (fd, &fds);
 18022         }
 18023 
 18024       /* Prevent events from being lost (from GTK's point of view) by
 18025          using GDK to run the event loop.  */
 18026 #ifdef USE_GTK
 18027       while (gtk_events_pending ())
 18028         {
 18029           EVENT_INIT (hold_quit);
 18030           current_count = 0;
 18031           current_hold_quit = &hold_quit;
 18032           current_finish = X_EVENT_NORMAL;
 18033 
 18034           gtk_main_iteration ();
 18035 
 18036           current_count = -1;
 18037           current_hold_quit = NULL;
 18038 
 18039           /* Make us quit now.  */
 18040           if (hold_quit.kind != NO_EVENT)
 18041             kbd_buffer_store_event (&hold_quit);
 18042 
 18043           if (!NILP (XCAR (cell)))
 18044             return;
 18045 
 18046           if (current_finish == X_EVENT_GOTO_OUT)
 18047             break;
 18048         }
 18049 #endif
 18050 
 18051       eassert (maxfd >= 0);
 18052 
 18053       current = current_timespec ();
 18054 
 18055       if (timespec_cmp (at, current) < 0
 18056           || !NILP (XCAR (cell)))
 18057         return;
 18058 
 18059       timeout = timespec_sub (at, current);
 18060 
 18061 #ifndef USE_GTK
 18062       rc = pselect (maxfd + 1, &fds, NULL, NULL, &timeout, NULL);
 18063 
 18064       if (rc >= 0)
 18065         rfds = fds;
 18066 #else
 18067       pselect (maxfd + 1, &fds, NULL, NULL, &timeout, NULL);
 18068 #endif
 18069     }
 18070 }
 18071 
 18072 /* Find whether or not an undelivered MONITORS_CHANGED_EVENT is
 18073    already on the event queue.  DPYINFO is the display any such event
 18074    must apply to.  */
 18075 
 18076 static bool
 18077 x_find_monitors_changed_event (struct x_display_info *dpyinfo)
 18078 {
 18079   union buffered_input_event *event;
 18080 
 18081   event = kbd_fetch_ptr;
 18082 
 18083   while (event != kbd_store_ptr)
 18084     {
 18085       if (event->ie.kind == MONITORS_CHANGED_EVENT
 18086           && XTERMINAL (event->ie.arg) == dpyinfo->terminal)
 18087         return true;
 18088 
 18089       event = X_NEXT_KBD_EVENT (event);
 18090     }
 18091 
 18092   return false;
 18093 }
 18094 
 18095 #ifdef USE_GTK
 18096 static void
 18097 x_monitors_changed_cb (GdkScreen *gscr, gpointer user_data)
 18098 {
 18099   struct x_display_info *dpyinfo;
 18100   struct input_event ie;
 18101   Lisp_Object current_monitors, terminal;
 18102   GdkDisplay *gdpy;
 18103   Display *dpy;
 18104 
 18105   gdpy = gdk_screen_get_display (gscr);
 18106   dpy = gdk_x11_display_get_xdisplay (gdpy);
 18107   dpyinfo = x_display_info_for_display (dpy);
 18108 
 18109   if (!dpyinfo)
 18110     return;
 18111 
 18112   if (x_find_monitors_changed_event (dpyinfo))
 18113     return;
 18114 
 18115   XSETTERMINAL (terminal, dpyinfo->terminal);
 18116 
 18117   current_monitors
 18118     = Fx_display_monitor_attributes_list (terminal);
 18119 
 18120   if (NILP (Fequal (current_monitors,
 18121                     dpyinfo->last_monitor_attributes_list)))
 18122     {
 18123       EVENT_INIT (ie);
 18124       ie.kind = MONITORS_CHANGED_EVENT;
 18125       ie.arg = terminal;
 18126 
 18127       kbd_buffer_store_event (&ie);
 18128 
 18129       if (x_dnd_in_progress && x_dnd_update_tooltip)
 18130         x_dnd_monitors = current_monitors;
 18131 
 18132       x_dnd_update_tooltip_now ();
 18133     }
 18134 
 18135   dpyinfo->last_monitor_attributes_list = current_monitors;
 18136 }
 18137 #endif
 18138 
 18139 /* Extract the root window coordinates from the client message EVENT
 18140    if it is a message that we already understand.  Return false if the
 18141    event was not understood.  */
 18142 static bool
 18143 x_coords_from_dnd_message (struct x_display_info *dpyinfo,
 18144                            XEvent *event, int *x_out, int *y_out)
 18145 {
 18146   xm_drag_motion_message dmsg;
 18147   xm_drag_motion_reply dreply;
 18148   xm_drop_start_message smsg;
 18149   xm_drop_start_reply reply;
 18150   unsigned long kde_data;
 18151 
 18152   if (event->type != ClientMessage)
 18153     return false;
 18154 
 18155   if (event->xclient.message_type == dpyinfo->Xatom_XdndPosition)
 18156     {
 18157       if (event->xclient.format != 32)
 18158         return false;
 18159 
 18160       *x_out = (((unsigned long) event->xclient.data.l[2]) >> 16
 18161                 & 0xffff);
 18162       *y_out = (event->xclient.data.l[2] & 0xffff);
 18163 
 18164       return true;
 18165     }
 18166 
 18167   if ((event->xclient.message_type
 18168        == dpyinfo->Xatom_MOTIF_DRAG_AND_DROP_MESSAGE)
 18169       && event->xclient.format == 8)
 18170     {
 18171       if (!xm_read_drag_motion_message (event, &dmsg))
 18172         {
 18173           *x_out = dmsg.x;
 18174           *y_out = dmsg.y;
 18175 
 18176           return true;
 18177         }
 18178       else if (!xm_read_drag_motion_reply (event, &dreply))
 18179         {
 18180           *x_out = dreply.better_x;
 18181           *y_out = dreply.better_y;
 18182 
 18183           return true;
 18184         }
 18185       else if (!xm_read_drop_start_message (event, &smsg))
 18186         {
 18187           *x_out = smsg.x;
 18188           *y_out = smsg.y;
 18189 
 18190           return true;
 18191         }
 18192       else if (!xm_read_drop_start_reply (event, &reply))
 18193         {
 18194           *x_out = reply.better_x;
 18195           *y_out = reply.better_y;
 18196 
 18197           return true;
 18198         }
 18199     }
 18200 
 18201   if (((event->xclient.message_type
 18202         == dpyinfo->Xatom_DndProtocol)
 18203        || (event->xclient.message_type
 18204            == dpyinfo->Xatom_DND_PROTOCOL))
 18205       && event->xclient.format == 32
 18206       /* Check that the version of the old KDE protocol is new
 18207          enough to include coordinates.  */
 18208       && event->xclient.data.l[4])
 18209     {
 18210       kde_data = (unsigned long) event->xclient.data.l[3];
 18211 
 18212       *x_out = (kde_data & 0xffff);
 18213       *y_out = (kde_data >> 16 & 0xffff);
 18214 
 18215       return true;
 18216     }
 18217 
 18218   return false;
 18219 }
 18220 
 18221 static void
 18222 x_handle_wm_state (struct frame *f, struct input_event *ie)
 18223 {
 18224   struct x_display_info *dpyinfo;
 18225   Atom type;
 18226   int format;
 18227   unsigned long nitems, bytes_after;
 18228   unsigned char *data;
 18229   unsigned long *state;
 18230 
 18231   data = NULL;
 18232   dpyinfo = FRAME_DISPLAY_INFO (f);
 18233 
 18234   if (XGetWindowProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 18235                           dpyinfo->Xatom_wm_state, 0, 2, False,
 18236                           AnyPropertyType, &type, &format, &nitems,
 18237                           &bytes_after, &data) != Success)
 18238     return;
 18239 
 18240   if (!data || nitems != 2 || format != 32)
 18241     {
 18242       if (data)
 18243         XFree (data);
 18244 
 18245       return;
 18246     }
 18247 
 18248   state = (unsigned long *) data;
 18249 
 18250   if (state[0] == NormalState && FRAME_ICONIFIED_P (f))
 18251     {
 18252       /* The frame has been deiconified.  It has not been withdrawn
 18253          and is now visible.  */
 18254       SET_FRAME_VISIBLE (f, 1);
 18255       SET_FRAME_ICONIFIED (f, false);
 18256       f->output_data.x->has_been_visible = true;
 18257 
 18258       ie->kind = DEICONIFY_EVENT;
 18259       XSETFRAME (ie->frame_or_window, f);
 18260     }
 18261   else if (state[0] == IconicState
 18262            /* _NET_WM_STATE_HIDDEN should be used if the window
 18263               manager supports that.  */
 18264            && !x_wm_supports (f, dpyinfo->Xatom_net_wm_state_hidden))
 18265     {
 18266       /* The frame is actually iconified right now.  Mark it as
 18267          such.  */
 18268 
 18269       SET_FRAME_VISIBLE (f, 0);
 18270       SET_FRAME_ICONIFIED (f, true);
 18271 
 18272       ie->kind = ICONIFY_EVENT;
 18273       XSETFRAME (ie->frame_or_window, f);
 18274     }
 18275 
 18276   /* state[0] can also be WithdrawnState, meaning that the window has
 18277      been withdrawn and is no longer iconified.  However, Emacs sets
 18278      the correct flags upon withdrawing the window, so there is no
 18279      need to do anything here.  */
 18280 
 18281   XFree (data);
 18282 }
 18283 
 18284 #ifdef HAVE_XFIXES
 18285 
 18286 static bool
 18287 x_handle_selection_monitor_event (struct x_display_info *dpyinfo,
 18288                                   const XEvent *event)
 18289 {
 18290   XFixesSelectionNotifyEvent *notify;
 18291   int i;
 18292 
 18293   notify = (XFixesSelectionNotifyEvent *) event;
 18294 
 18295   if (notify->window != dpyinfo->selection_tracking_window)
 18296     return false;
 18297 
 18298   for (i = 0; i < dpyinfo->n_monitored_selections; ++i)
 18299     {
 18300       /* We don't have to keep track of timestamps here.  */
 18301       if (notify->selection == dpyinfo->monitored_selections[i].name)
 18302         dpyinfo->monitored_selections[i].owner = notify->owner;
 18303     }
 18304 
 18305   return true;
 18306 }
 18307 
 18308 Window
 18309 x_find_selection_owner (struct x_display_info *dpyinfo, Atom selection)
 18310 {
 18311   int i;
 18312 
 18313   for (i = 0; i < dpyinfo->n_monitored_selections; ++i)
 18314     {
 18315       if (selection == dpyinfo->monitored_selections[i].name)
 18316         return dpyinfo->monitored_selections[i].owner;
 18317     }
 18318 
 18319   return X_INVALID_WINDOW;
 18320 }
 18321 
 18322 #endif
 18323 
 18324 /* Handles the XEvent EVENT on display DPYINFO.
 18325 
 18326    *FINISH is X_EVENT_GOTO_OUT if caller should stop reading events.
 18327    *FINISH is zero if caller should continue reading events.
 18328    *FINISH is X_EVENT_DROP if event should not be passed to the toolkit.
 18329    *EVENT is unchanged unless we're processing KeyPress event.
 18330 
 18331    We return the number of characters stored into the buffer.  */
 18332 
 18333 static int
 18334 handle_one_xevent (struct x_display_info *dpyinfo,
 18335 #ifndef HAVE_XINPUT2
 18336                    const XEvent *event,
 18337 #else
 18338                    XEvent *event,
 18339 #endif
 18340                    int *finish, struct input_event *hold_quit)
 18341 {
 18342   union buffered_input_event inev;
 18343   int count = 0;
 18344   int do_help = 0;
 18345 #ifdef HAVE_XINPUT2
 18346   struct xi_device_t *gen_help_device;
 18347   Time gen_help_time UNINIT;
 18348 #endif
 18349   ptrdiff_t nbytes = 0;
 18350   struct frame *any, *f = NULL, *mouse_frame;
 18351   Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
 18352   /* This holds the state XLookupString needs to implement dead keys
 18353      and other tricks known as "compose processing".  _X Window System_
 18354      says that a portable program can't use this, but Stephen Gildea assures
 18355      me that letting the compiler initialize it to zeros will work okay.  */
 18356   static XComposeStatus compose_status;
 18357   XEvent configureEvent;
 18358   XEvent next_event;
 18359   Lisp_Object coding;
 18360 #if defined USE_X_TOOLKIT && defined HAVE_XINPUT2
 18361   /* Some XInput 2 events are important for Motif and Lucid menu bars
 18362      to work correctly, so they must be translated into core events
 18363      before being passed to XtDispatchEvent.  */
 18364   bool use_copy = false;
 18365   XEvent copy;
 18366 #elif defined USE_GTK && !defined HAVE_GTK3 && defined HAVE_XINPUT2
 18367   GdkEvent *copy = NULL;
 18368   GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display);
 18369 #endif
 18370   int dx, dy;
 18371 
 18372   /* Avoid warnings when SAFE_ALLOCA is not actually used.  */
 18373 #if defined HAVE_XINPUT2 || defined HAVE_XKB || defined HAVE_X_I18N
 18374   USE_SAFE_ALLOCA;
 18375 #endif
 18376 
 18377   /* This function is not reentrant, so input should be blocked before
 18378      it is called.  */
 18379 
 18380   if (!input_blocked_p ())
 18381     emacs_abort ();
 18382 
 18383   *finish = X_EVENT_NORMAL;
 18384 
 18385   EVENT_INIT (inev.ie);
 18386   inev.ie.kind = NO_EVENT;
 18387   inev.ie.arg = Qnil;
 18388 #ifdef HAVE_XINPUT2
 18389   gen_help_device = NULL;
 18390 #endif
 18391 
 18392   /* Ignore events coming from various extensions, such as XFIXES and
 18393      XKB.  */
 18394   if (event->type < LASTEvent)
 18395     {
 18396 #ifdef HAVE_XINPUT2
 18397       if (event->type != GenericEvent)
 18398 #endif
 18399         any = x_any_window_to_frame (dpyinfo, event->xany.window);
 18400 #ifdef HAVE_XINPUT2
 18401       else
 18402         any = NULL;
 18403 #endif
 18404     }
 18405   else
 18406     any = NULL;
 18407 
 18408   if (any && any->wait_event_type == event->type)
 18409     any->wait_event_type = 0; /* Indicates we got it.  */
 18410 
 18411   switch (event->type)
 18412     {
 18413     case ClientMessage:
 18414       {
 18415         int rc;
 18416 
 18417         if (((x_dnd_in_progress
 18418               && FRAME_DISPLAY_INFO (x_dnd_frame) == dpyinfo)
 18419              || (x_dnd_waiting_for_finish
 18420                  && FRAME_DISPLAY_INFO (x_dnd_finish_frame) == dpyinfo))
 18421             && event->xclient.message_type == dpyinfo->Xatom_XdndStatus)
 18422           {
 18423             Window target;
 18424             unsigned long r1, r2;
 18425             int root_x, root_y;
 18426             bool button;
 18427 
 18428             target = event->xclient.data.l[0];
 18429 
 18430             if (x_dnd_last_protocol_version != -1
 18431                 && x_dnd_in_progress
 18432                 && target == x_dnd_last_seen_toplevel
 18433                 /* The XDND documentation is not very clearly worded.
 18434                    But this should be the correct behavior, since
 18435                    "kDNDStatusSendHereFlag" in the reference
 18436                    implementation is 2, and means the mouse rect
 18437                    should be ignored.  */
 18438                 && !(event->xclient.data.l[1] & 2))
 18439               {
 18440                 r1 = event->xclient.data.l[2];
 18441                 r2 = event->xclient.data.l[3];
 18442 
 18443                 x_dnd_mouse_rect_target = target;
 18444                 x_dnd_mouse_rect.x = (r1 & 0xffff0000) >> 16;
 18445                 x_dnd_mouse_rect.y = (r1 & 0xffff);
 18446                 x_dnd_mouse_rect.width = (r2 & 0xffff0000) >> 16;
 18447                 x_dnd_mouse_rect.height = (r2 & 0xffff);
 18448               }
 18449             else
 18450               x_dnd_mouse_rect_target = None;
 18451 
 18452             if (x_dnd_last_protocol_version != -1
 18453                 && (x_dnd_in_progress
 18454                     && target == x_dnd_last_seen_window))
 18455               {
 18456                 if (event->xclient.data.l[1] & 1)
 18457                   {
 18458                     if (x_dnd_last_protocol_version >= 2)
 18459                       x_dnd_action = event->xclient.data.l[4];
 18460                     else
 18461                       x_dnd_action = dpyinfo->Xatom_XdndActionCopy;
 18462                   }
 18463                 else
 18464                   x_dnd_action = None;
 18465               }
 18466 
 18467             /* Send any pending XdndPosition message.  */
 18468             if (x_dnd_waiting_for_status_window == target)
 18469               {
 18470                 if (x_dnd_pending_send_position.type != 0)
 18471                   {
 18472                     /* If the last XdndStatus specified a mouse
 18473                        rectangle and this event falls inside, don't
 18474                        send the event, but clear
 18475                        x_dnd_waiting_for_status_window instead.  */
 18476 
 18477                     root_x = x_dnd_pending_send_position_root_x;
 18478                     root_y = x_dnd_pending_send_position_root_y;
 18479                     button = x_dnd_pending_send_position_button;
 18480 
 18481                     if (target == x_dnd_mouse_rect_target
 18482                         && x_dnd_mouse_rect.width
 18483                         && x_dnd_mouse_rect.height
 18484                         /* Ignore the mouse rectangle if we're
 18485                            supposed to be sending a button press
 18486                            instead.  */
 18487                         && !button
 18488                         && (root_x >= x_dnd_mouse_rect.x
 18489                             && root_x < (x_dnd_mouse_rect.x
 18490                                          + x_dnd_mouse_rect.width)
 18491                             && root_y >= x_dnd_mouse_rect.y
 18492                             && root_y < (x_dnd_mouse_rect.y
 18493                                          + x_dnd_mouse_rect.height)))
 18494                       x_dnd_waiting_for_status_window = None;
 18495                     else
 18496                       {
 18497                         x_ignore_errors_for_next_request (dpyinfo);
 18498                         XSendEvent (dpyinfo->display, target,
 18499                                     False, NoEventMask,
 18500                                     &x_dnd_pending_send_position);
 18501                         x_stop_ignoring_errors (dpyinfo);
 18502                         x_dnd_pending_send_position.type = 0;
 18503 
 18504                         /* Since we sent another XdndPosition message, we
 18505                            have to wait for another one in reply, so don't
 18506                            reset `x_dnd_waiting_for_status_window'
 18507                            here.  */
 18508                       }
 18509                   }
 18510                 else
 18511                   x_dnd_waiting_for_status_window = None;
 18512 
 18513                 /* Send any pending drop if warranted.  */
 18514                 if (x_dnd_waiting_for_finish && x_dnd_need_send_drop
 18515                     && x_dnd_waiting_for_status_window == None)
 18516                   {
 18517                     if (event->xclient.data.l[1] & 1)
 18518                       {
 18519                         if (x_dnd_send_drop_proto >= 2)
 18520                           x_dnd_action = event->xclient.data.l[4];
 18521                         else
 18522                           x_dnd_action = dpyinfo->Xatom_XdndActionCopy;
 18523                       }
 18524                     else
 18525                       x_dnd_action = None;
 18526 
 18527                     x_dnd_waiting_for_finish
 18528                       = x_dnd_send_drop (x_dnd_finish_frame,
 18529                                          target,
 18530                                          x_dnd_last_seen_toplevel,
 18531                                          x_dnd_selection_timestamp,
 18532                                          x_dnd_send_drop_proto);
 18533                   }
 18534               }
 18535 
 18536             goto done;
 18537           }
 18538 
 18539         if (event->xclient.message_type == dpyinfo->Xatom_XdndFinished
 18540             && (x_dnd_waiting_for_finish && !x_dnd_waiting_for_motif_finish)
 18541             /* Also check that the display is correct, since
 18542                `x_dnd_pending_finish_target' could still be valid on
 18543                another X server.  */
 18544             && dpyinfo->display == x_dnd_finish_display
 18545             && event->xclient.data.l[0] == x_dnd_pending_finish_target)
 18546           {
 18547             x_dnd_waiting_for_finish = false;
 18548 
 18549             if (x_dnd_waiting_for_finish_proto >= 5)
 18550               x_dnd_action = event->xclient.data.l[2];
 18551 
 18552             if (x_dnd_waiting_for_finish_proto >= 5
 18553                 && !(event->xclient.data.l[1] & 1))
 18554               x_dnd_action = None;
 18555 
 18556             goto done;
 18557           }
 18558 
 18559         if ((event->xclient.message_type
 18560              == dpyinfo->Xatom_MOTIF_DRAG_AND_DROP_MESSAGE)
 18561             && x_dnd_waiting_for_finish
 18562             && x_dnd_waiting_for_motif_finish == 1
 18563             && dpyinfo == x_dnd_waiting_for_motif_finish_display)
 18564           {
 18565             xm_drop_start_reply reply;
 18566             uint16_t operation, status, action;
 18567 
 18568             if (!xm_read_drop_start_reply (event, &reply))
 18569               {
 18570                 operation = XM_DRAG_SIDE_EFFECT_OPERATION (reply.side_effects);
 18571                 status = XM_DRAG_SIDE_EFFECT_SITE_STATUS (reply.side_effects);
 18572                 action = XM_DRAG_SIDE_EFFECT_DROP_ACTION (reply.side_effects);
 18573 
 18574                 if (operation != XM_DRAG_MOVE
 18575                     && operation != XM_DRAG_COPY
 18576                     && XM_DRAG_OPERATION_IS_LINK (operation))
 18577                   {
 18578                     x_dnd_waiting_for_finish = false;
 18579                     goto done;
 18580                   }
 18581 
 18582                 if (status != XM_DROP_SITE_VALID
 18583                     || (action == XM_DROP_ACTION_DROP_CANCEL
 18584                         || action == XM_DROP_ACTION_DROP_HELP))
 18585                   {
 18586                     x_dnd_waiting_for_finish = false;
 18587                     goto done;
 18588                   }
 18589 
 18590                 switch (operation)
 18591                   {
 18592                   case XM_DRAG_MOVE:
 18593                     x_dnd_action_symbol = QXdndActionMove;
 18594                     break;
 18595 
 18596                   case XM_DRAG_COPY:
 18597                     x_dnd_action_symbol = QXdndActionCopy;
 18598                     break;
 18599 
 18600                     /* This means XM_DRAG_OPERATION_IS_LINK (operation).  */
 18601                   default:
 18602                     x_dnd_action_symbol = QXdndActionLink;
 18603                     break;
 18604                   }
 18605 
 18606                 x_dnd_waiting_for_motif_finish = 2;
 18607                 goto done;
 18608               }
 18609           }
 18610 
 18611         if (event->xclient.message_type == dpyinfo->Xatom_wm_protocols
 18612             && event->xclient.format == 32)
 18613           {
 18614             if (event->xclient.data.l[0] == dpyinfo->Xatom_wm_take_focus)
 18615               {
 18616                 /* Use the value returned by x_any_window_to_frame
 18617                    because this could be the shell widget window
 18618                    if the frame has no title bar.  */
 18619                 f = any;
 18620 #ifdef HAVE_X_I18N
 18621                 /* Not quite sure this is needed -pd */
 18622                 if (f && FRAME_XIC (f))
 18623                   XSetICFocus (FRAME_XIC (f));
 18624 #endif
 18625 #if false
 18626       /* Emacs sets WM hints whose `input' field is `true'.  This
 18627          instructs the WM to set the input focus automatically for
 18628          Emacs with a call to XSetInputFocus.  Setting WM_TAKE_FOCUS
 18629          tells the WM to send us a ClientMessage WM_TAKE_FOCUS after
 18630          it has set the focus.  So, XSetInputFocus below is not
 18631          needed.
 18632 
 18633          The call to XSetInputFocus below has also caused trouble.  In
 18634          cases where the XSetInputFocus done by the WM and the one
 18635          below are temporally close (on a fast machine), the call
 18636          below can generate additional FocusIn events which confuse
 18637          Emacs.  */
 18638 
 18639                 /* Since we set WM_TAKE_FOCUS, we must call
 18640                    XSetInputFocus explicitly.  But not if f is null,
 18641                    since that might be an event for a deleted frame.  */
 18642                 if (f)
 18643                   {
 18644                     Display *d = event->xclient.display;
 18645                     /* Catch and ignore errors, in case window has been
 18646                        iconified by a window manager such as GWM.  */
 18647                     x_catch_errors (d);
 18648                     XSetInputFocus (d, event->xclient.window,
 18649                                     /* The ICCCM says this is
 18650                                        the only valid choice.  */
 18651                                     RevertToParent,
 18652                                     event->xclient.data.l[1]);
 18653                     x_uncatch_errors ();
 18654                   }
 18655                 /* Not certain about handling scroll bars here */
 18656 #endif
 18657                 /* Set the provided time as the user time, which is
 18658                    required for SetInputFocus to work correctly after
 18659                    taking the input focus.  */
 18660 
 18661                 /* Time can be sign extended if retrieved from a client message.
 18662                    Make sure it is always 32 bits, or systems with 64-bit longs
 18663                    will crash after 24 days of X server uptime.  (bug#59480) */
 18664                 x_display_set_last_user_time (dpyinfo, (event->xclient.data.l[1]
 18665                                                         & 0xffffffff),
 18666                                               true, true);
 18667                 goto done;
 18668               }
 18669 
 18670             if (event->xclient.data.l[0] == dpyinfo->Xatom_wm_save_yourself)
 18671               {
 18672                 /* Save state modify the WM_COMMAND property to
 18673                    something which can reinstate us.  This notifies
 18674                    the session manager, who's looking for such a
 18675                    PropertyNotify.  Can restart processing when
 18676                    a keyboard or mouse event arrives.  */
 18677                 /* If we have a session manager, don't set this.
 18678                    KDE will then start two Emacsen, one for the
 18679                    session manager and one for this. */
 18680 #ifdef HAVE_X_SM
 18681                 if (! x_session_have_connection ())
 18682 #endif
 18683                   {
 18684                     f = x_top_window_to_frame (dpyinfo,
 18685                                                event->xclient.window);
 18686                     /* This is just so we only give real data once
 18687                        for a single Emacs process.  */
 18688                     if (f == SELECTED_FRAME ())
 18689                       XSetCommand (FRAME_X_DISPLAY (f),
 18690                                    event->xclient.window,
 18691                                    initial_argv, initial_argc);
 18692                     else if (f)
 18693                       XSetCommand (FRAME_X_DISPLAY (f),
 18694                                    event->xclient.window,
 18695                                    0, 0);
 18696                   }
 18697                 goto done;
 18698               }
 18699 
 18700             if (event->xclient.data.l[0] == dpyinfo->Xatom_wm_delete_window)
 18701               {
 18702                 f = x_top_window_to_frame (dpyinfo,
 18703                                            event->xclient.window);
 18704 
 18705                 if (!f)
 18706                   goto OTHER; /* May be a dialog that is to be removed  */
 18707 
 18708                 inev.ie.kind = DELETE_WINDOW_EVENT;
 18709                 inev.ie.timestamp = event->xclient.data.l[1];
 18710                 XSETFRAME (inev.ie.frame_or_window, f);
 18711                 goto done;
 18712               }
 18713 
 18714 
 18715             if (event->xclient.data.l[0] == dpyinfo->Xatom_net_wm_ping
 18716                 /* Handling window stacking changes during
 18717                    drag-and-drop requires Emacs to select for
 18718                    SubstructureNotifyMask, which in turn causes the
 18719                    message to be sent to Emacs itself using the event
 18720                    mask specified by the EWMH.  To avoid an infinite
 18721                    loop, make sure the client message's window is not
 18722                    the root window if DND is in progress.  */
 18723                 && (!(x_dnd_in_progress
 18724                       || x_dnd_waiting_for_finish)
 18725                     || event->xclient.window != dpyinfo->root_window)
 18726                 && event->xclient.format == 32)
 18727               {
 18728                 XEvent send_event = *event;
 18729 
 18730                 send_event.xclient.window = dpyinfo->root_window;
 18731                 XSendEvent (dpyinfo->display, dpyinfo->root_window, False,
 18732                             SubstructureRedirectMask | SubstructureNotifyMask,
 18733                             &send_event);
 18734 
 18735                 *finish = X_EVENT_DROP;
 18736                 goto done;
 18737               }
 18738 
 18739 #if defined HAVE_XSYNC
 18740             if (event->xclient.data.l[0] == dpyinfo->Xatom_net_wm_sync_request
 18741                 && event->xclient.format == 32
 18742                 && dpyinfo->xsync_supported_p)
 18743               {
 18744                 struct frame *f
 18745                   = x_top_window_to_frame (dpyinfo,
 18746                                            event->xclient.window);
 18747 #if defined HAVE_GTK3
 18748                 GtkWidget *widget;
 18749                 GdkWindow *window;
 18750                 GdkFrameClock *frame_clock;
 18751 #endif
 18752 
 18753                 if (f)
 18754                   {
 18755 #ifndef HAVE_GTK3
 18756                     if (event->xclient.data.l[4] == 0)
 18757                       {
 18758                         XSyncIntsToValue (&FRAME_X_OUTPUT (f)->pending_basic_counter_value,
 18759                                           event->xclient.data.l[2], event->xclient.data.l[3]);
 18760                         FRAME_X_OUTPUT (f)->sync_end_pending_p = true;
 18761                       }
 18762                     else if (event->xclient.data.l[4] == 1)
 18763                       {
 18764                         XSyncIntsToValue (&FRAME_X_OUTPUT (f)->resize_counter_value,
 18765                                           event->xclient.data.l[2],
 18766                                           event->xclient.data.l[3]);
 18767 
 18768                         FRAME_X_OUTPUT (f)->ext_sync_end_pending_p = true;
 18769                       }
 18770 
 18771                     *finish = X_EVENT_DROP;
 18772 #else
 18773                     widget = FRAME_GTK_OUTER_WIDGET (f);
 18774                     window = gtk_widget_get_window (widget);
 18775                     eassert (window);
 18776 
 18777                     /* This could be a (former) child frame for which
 18778                        frame synchronization was disabled.  Enable it
 18779                        now.  */
 18780                     gdk_x11_window_set_frame_sync_enabled (window, TRUE);
 18781 
 18782                     if (widget && !FRAME_X_OUTPUT (f)->xg_sync_end_pending_p)
 18783                       {
 18784                         frame_clock = gdk_window_get_frame_clock (window);
 18785                         eassert (frame_clock);
 18786 
 18787                         gdk_frame_clock_request_phase (frame_clock,
 18788                                                        GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT);
 18789                         FRAME_X_OUTPUT (f)->xg_sync_end_pending_p = true;
 18790                       }
 18791 #endif
 18792                     goto done;
 18793                   }
 18794               }
 18795 #endif
 18796 
 18797             goto done;
 18798           }
 18799 
 18800         if (event->xclient.message_type == dpyinfo->Xatom_wm_configure_denied)
 18801           goto done;
 18802 
 18803         if (event->xclient.message_type == dpyinfo->Xatom_wm_window_moved)
 18804           {
 18805             int new_x, new_y;
 18806             f = x_window_to_frame (dpyinfo, event->xclient.window);
 18807 
 18808             new_x = event->xclient.data.s[0];
 18809             new_y = event->xclient.data.s[1];
 18810 
 18811             if (f)
 18812               {
 18813                 f->left_pos = new_x;
 18814                 f->top_pos = new_y;
 18815               }
 18816             goto done;
 18817           }
 18818 
 18819 #ifdef X_TOOLKIT_EDITRES
 18820         if (event->xclient.message_type == dpyinfo->Xatom_editres)
 18821           {
 18822             f = any;
 18823             if (f)
 18824               {
 18825                 _XEditResCheckMessages (f->output_data.x->widget,
 18826                                         NULL, (XEvent *) event, NULL);
 18827                 goto done;
 18828               }
 18829 
 18830             goto OTHER;
 18831           }
 18832 #endif /* X_TOOLKIT_EDITRES */
 18833 
 18834         if (event->xclient.message_type == dpyinfo->Xatom_DONE
 18835             || event->xclient.message_type == dpyinfo->Xatom_PAGE)
 18836           {
 18837             /* Ghostview job completed.  Kill it.  We could
 18838                reply with "Next" if we received "Page", but we
 18839                currently never do because we are interested in
 18840                images, only, which should have 1 page.  */
 18841             f = x_window_to_frame (dpyinfo, event->xclient.window);
 18842             if (!f)
 18843               goto OTHER;
 18844 #ifndef USE_CAIRO
 18845             Pixmap pixmap = (Pixmap) event->xclient.data.l[1];
 18846             /* FIXME: why does this sometimes generate a BadMatch
 18847                error?  */
 18848             x_catch_errors (dpyinfo->display);
 18849             x_kill_gs_process (pixmap, f);
 18850             x_uncatch_errors ();
 18851             expose_frame (f, 0, 0, 0, 0);
 18852 #endif  /* !USE_CAIRO */
 18853             goto done;
 18854           }
 18855 
 18856 #ifdef USE_TOOLKIT_SCROLL_BARS
 18857         /* Scroll bar callbacks send a ClientMessage from which
 18858            we construct an input_event.  */
 18859         if (event->xclient.message_type == dpyinfo->Xatom_Scrollbar)
 18860           {
 18861             /* Convert the scroll bar event to an input event using
 18862                the first window entered into the scroll bar event
 18863                queue. */
 18864             x_scroll_bar_to_input_event (dpyinfo, event, &inev.ie);
 18865 
 18866             *finish = X_EVENT_GOTO_OUT;
 18867             goto done;
 18868           }
 18869         else if (event->xclient.message_type == dpyinfo->Xatom_Horizontal_Scrollbar)
 18870           {
 18871             /* Convert the horizontal scroll bar event to an input
 18872                event using the first window entered into the scroll
 18873                bar event queue. */
 18874             x_horizontal_scroll_bar_to_input_event (dpyinfo, event,
 18875                                                     &inev.ie);
 18876 
 18877             *finish = X_EVENT_GOTO_OUT;
 18878             goto done;
 18879           }
 18880 #endif /* USE_TOOLKIT_SCROLL_BARS */
 18881 
 18882         /* XEmbed messages from the embedder (if any).  */
 18883         if (event->xclient.message_type == dpyinfo->Xatom_XEMBED)
 18884           {
 18885             enum xembed_message msg = event->xclient.data.l[1];
 18886             if (msg == XEMBED_FOCUS_IN || msg == XEMBED_FOCUS_OUT)
 18887               x_detect_focus_change (dpyinfo, any, event, &inev.ie);
 18888 
 18889             *finish = X_EVENT_GOTO_OUT;
 18890             goto done;
 18891           }
 18892 
 18893 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
 18894         /* These messages are sent by the compositing manager after a
 18895            frame is drawn under extended synchronization.  */
 18896         if (event->xclient.message_type
 18897             == dpyinfo->Xatom_net_wm_frame_drawn)
 18898           {
 18899             if (any)
 18900               x_sync_handle_frame_drawn (dpyinfo, (XEvent *) event, any);
 18901 
 18902             goto done;
 18903           }
 18904 
 18905         if (event->xclient.message_type
 18906             == dpyinfo->Xatom_net_wm_frame_timings)
 18907           goto done;
 18908 #endif
 18909 
 18910         if (xft_settings_event (dpyinfo, event))
 18911           goto done;
 18912 
 18913         f = any;
 18914         /* We don't want to ever leak tooltip frames to Lisp code.  */
 18915         if (!f || FRAME_TOOLTIP_P (f))
 18916           goto OTHER;
 18917 
 18918         /* These values are always used initialized, but GCC doesn't
 18919            know that.  */
 18920         dx = 0;
 18921         dy = 0;
 18922 
 18923         rc = x_coords_from_dnd_message (dpyinfo, (XEvent *) event,
 18924                                         &dx, &dy);
 18925 
 18926         if (x_handle_dnd_message (f, &event->xclient, dpyinfo, &inev.ie,
 18927                                   rc, dx, dy))
 18928           *finish = X_EVENT_DROP;
 18929       }
 18930       break;
 18931 
 18932     case SelectionNotify:
 18933 #if defined USE_X_TOOLKIT || defined USE_GTK
 18934       if (!x_window_to_frame (dpyinfo, event->xselection.requestor))
 18935         goto OTHER;
 18936 #endif /* not USE_X_TOOLKIT and not USE_GTK */
 18937 #ifdef HAVE_GTK3
 18938       /* GTK 3 apparently chokes on these events since they have no
 18939          associated device.  (bug#56869, another bug as well that I
 18940          can't find) */
 18941       *finish = X_EVENT_DROP;
 18942 #endif
 18943       x_handle_selection_notify (&event->xselection);
 18944       break;
 18945 
 18946     case SelectionClear:        /* Someone has grabbed ownership.  */
 18947 #if defined USE_X_TOOLKIT || defined USE_GTK
 18948       if (!x_window_to_frame (dpyinfo, event->xselectionclear.window))
 18949         goto OTHER;
 18950 #endif /* not USE_X_TOOLKIT and not USE_GTK */
 18951 #ifdef HAVE_GTK3
 18952       *finish = X_EVENT_DROP;
 18953 #endif
 18954       {
 18955         const XSelectionClearEvent *eventp = &event->xselectionclear;
 18956 
 18957         if (eventp->selection == dpyinfo->motif_drag_atom
 18958             && (eventp->time == CurrentTime
 18959                 || dpyinfo->motif_drag_atom_time <= eventp->time))
 18960           dpyinfo->motif_drag_atom = None;
 18961 
 18962         inev.sie.kind = SELECTION_CLEAR_EVENT;
 18963         SELECTION_EVENT_DPYINFO (&inev.sie) = dpyinfo;
 18964         SELECTION_EVENT_SELECTION (&inev.sie) = eventp->selection;
 18965         SELECTION_EVENT_TIME (&inev.sie) = eventp->time;
 18966 
 18967         if (x_use_pending_selection_requests)
 18968           {
 18969             x_push_selection_request (&inev.sie);
 18970             EVENT_INIT (inev.ie);
 18971           }
 18972       }
 18973       break;
 18974 
 18975     case SelectionRequest:      /* Someone wants our selection.  */
 18976 #ifdef USE_X_TOOLKIT
 18977       if (!x_window_to_frame (dpyinfo, event->xselectionrequest.owner))
 18978         goto OTHER;
 18979 #endif /* USE_X_TOOLKIT */
 18980 #ifdef HAVE_GTK3
 18981       *finish = X_EVENT_DROP;
 18982 #endif
 18983       {
 18984         const XSelectionRequestEvent *eventp = &event->xselectionrequest;
 18985 
 18986         inev.sie.kind = SELECTION_REQUEST_EVENT;
 18987         SELECTION_EVENT_DPYINFO (&inev.sie) = dpyinfo;
 18988         SELECTION_EVENT_REQUESTOR (&inev.sie) = eventp->requestor;
 18989         SELECTION_EVENT_SELECTION (&inev.sie) = eventp->selection;
 18990         SELECTION_EVENT_TARGET (&inev.sie) = eventp->target;
 18991         SELECTION_EVENT_PROPERTY (&inev.sie) = eventp->property;
 18992         SELECTION_EVENT_TIME (&inev.sie) = eventp->time;
 18993 
 18994         /* If drag-and-drop or another modal dialog/menu is in
 18995            progress, handle SelectionRequest events immediately, by
 18996            pushing it onto the selection queue.  */
 18997 
 18998         if (x_use_pending_selection_requests)
 18999           {
 19000             x_push_selection_request (&inev.sie);
 19001             EVENT_INIT (inev.ie);
 19002           }
 19003 
 19004         if (x_dnd_waiting_for_finish
 19005             && x_dnd_waiting_for_motif_finish == 2
 19006             && dpyinfo == x_dnd_waiting_for_motif_finish_display
 19007             && eventp->selection == x_dnd_motif_atom
 19008             && (eventp->target == dpyinfo->Xatom_XmTRANSFER_SUCCESS
 19009                 || eventp->target == dpyinfo->Xatom_XmTRANSFER_FAILURE))
 19010           {
 19011             x_dnd_waiting_for_finish = false;
 19012 
 19013             /* If the transfer failed, then return nil from
 19014                `x-begin-drag'.  */
 19015             if (eventp->target == dpyinfo->Xatom_XmTRANSFER_FAILURE)
 19016               x_dnd_action = None;
 19017           }
 19018       }
 19019       break;
 19020 
 19021     case PropertyNotify:
 19022       if (x_dnd_in_progress && x_dnd_use_toplevels
 19023           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame)
 19024           && event->xproperty.atom == dpyinfo->Xatom_wm_state)
 19025         {
 19026           struct x_client_list_window *tem, *last;
 19027 
 19028           for (last = NULL, tem = x_dnd_toplevels; tem;
 19029                last = tem, tem = tem->next)
 19030             {
 19031               if (tem->window == event->xproperty.window)
 19032                 {
 19033                   Atom actual_type;
 19034                   int actual_format, rc;
 19035                   unsigned long nitems, bytesafter;
 19036                   unsigned char *data = NULL;
 19037 
 19038                   if (event->xproperty.state == PropertyDelete)
 19039                     {
 19040                       if (!last)
 19041                         x_dnd_toplevels = tem->next;
 19042                       else
 19043                         last->next = tem->next;
 19044 
 19045 #ifdef HAVE_XSHAPE
 19046                       if (tem->n_input_rects != -1)
 19047                         xfree (tem->input_rects);
 19048                       if (tem->n_bounding_rects != -1)
 19049                         xfree (tem->bounding_rects);
 19050 #endif
 19051                       xfree (tem);
 19052                     }
 19053                   else
 19054                     {
 19055                       x_catch_errors (dpyinfo->display);
 19056                       rc = XGetWindowProperty (dpyinfo->display,
 19057                                                event->xproperty.window,
 19058                                                dpyinfo->Xatom_wm_state,
 19059                                                0, 2, False, AnyPropertyType,
 19060                                                &actual_type, &actual_format,
 19061                                                &nitems, &bytesafter, &data);
 19062 
 19063                       if (!x_had_errors_p (dpyinfo->display) && rc == Success && data
 19064                           && nitems == 2 && actual_format == 32)
 19065                         tem->wm_state = ((unsigned long *) data)[0];
 19066                       else
 19067                         tem->wm_state = WithdrawnState;
 19068 
 19069                       if (data)
 19070                         XFree (data);
 19071                       x_uncatch_errors_after_check ();
 19072                     }
 19073 
 19074                   x_dnd_update_state (dpyinfo, event->xproperty.time);
 19075                   break;
 19076                 }
 19077             }
 19078         }
 19079 
 19080       f = x_top_window_to_frame (dpyinfo, event->xproperty.window);
 19081       if (f && event->xproperty.atom == dpyinfo->Xatom_net_wm_state
 19082           /* This should never happen with embedded windows.  */
 19083           && !FRAME_X_EMBEDDED_P (f))
 19084         {
 19085           bool not_hidden = x_handle_net_wm_state (f, &event->xproperty);
 19086 
 19087           if (not_hidden && FRAME_ICONIFIED_P (f))
 19088             {
 19089               if (CONSP (frame_size_history))
 19090                 frame_size_history_plain
 19091                   (f, build_string ("PropertyNotify, not hidden & iconified"));
 19092 
 19093               /* Gnome shell does not iconify us when C-z is pressed.
 19094                  It hides the frame.  So if our state says we aren't
 19095                  hidden anymore, treat it as deiconified.  */
 19096               SET_FRAME_VISIBLE (f, 1);
 19097               SET_FRAME_ICONIFIED (f, false);
 19098 
 19099               f->output_data.x->has_been_visible = true;
 19100               inev.ie.kind = DEICONIFY_EVENT;
 19101 #if defined USE_GTK && defined HAVE_GTK3
 19102               /* If GTK3 wants to impose some old size here (Bug#24526),
 19103                  tell it that the current size is what we want.  */
 19104               if (f->was_invisible)
 19105                 {
 19106                   xg_frame_set_char_size
 19107                     (f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
 19108                   f->was_invisible = false;
 19109                 }
 19110 #endif
 19111               XSETFRAME (inev.ie.frame_or_window, f);
 19112             }
 19113           else if (!not_hidden && !FRAME_ICONIFIED_P (f))
 19114             {
 19115               if (CONSP (frame_size_history))
 19116                 frame_size_history_plain
 19117                   (f, build_string ("PropertyNotify, hidden & not iconified"));
 19118 
 19119               SET_FRAME_VISIBLE (f, 0);
 19120               SET_FRAME_ICONIFIED (f, true);
 19121               inev.ie.kind = ICONIFY_EVENT;
 19122               XSETFRAME (inev.ie.frame_or_window, f);
 19123             }
 19124         }
 19125 
 19126       if (f && event->xproperty.atom == dpyinfo->Xatom_wm_state
 19127           && !FRAME_X_EMBEDDED_P (f) && !FRAME_PARENT_FRAME (f))
 19128         /* Handle WM_STATE.  We use this to clear the iconified flag
 19129            on a frame if it is set.
 19130 
 19131            GTK builds ignore deiconifying frames on FocusIn or Expose
 19132            by default, and cannot wait for the window manager to
 19133            remove _NET_WM_STATE_HIDDEN, as it is ambiguous when not
 19134            set.  Handling UnmapNotify also checks for
 19135            _NET_WM_STATE_HIDDEN, and thus suffers from the same
 19136            problem.  */
 19137         x_handle_wm_state (f, &inev.ie);
 19138 
 19139       if (f && FRAME_X_OUTPUT (f)->alpha_identical_p
 19140           && (event->xproperty.atom
 19141               == dpyinfo->Xatom_net_wm_window_opacity))
 19142         {
 19143 #ifndef USE_XCB
 19144           int rc, actual_format;
 19145           Atom actual;
 19146           unsigned char *tmp_data;
 19147           unsigned long n, left, opacity;
 19148 
 19149           tmp_data = NULL;
 19150 #else
 19151           xcb_get_property_cookie_t opacity_cookie;
 19152           xcb_get_property_reply_t *opacity_reply;
 19153           xcb_generic_error_t *error;
 19154           bool rc;
 19155           uint32_t value;
 19156 #endif
 19157 
 19158           if (event->xproperty.state == PropertyDelete)
 19159             {
 19160               f->alpha[0] = 1.0;
 19161               f->alpha[1] = 1.0;
 19162 
 19163               store_frame_param (f, Qalpha, Qnil);
 19164             }
 19165           else
 19166             {
 19167 #ifndef USE_XCB
 19168               rc = XGetWindowProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
 19169                                        dpyinfo->Xatom_net_wm_window_opacity,
 19170                                        0, 1, False, AnyPropertyType, &actual,
 19171                                        &actual_format, &n, &left, &tmp_data);
 19172 
 19173               if (rc == Success && actual_format == 32
 19174                   && (actual == XA_CARDINAL
 19175                       /* Some broken programs set the opacity property
 19176                          to those types, but window managers accept
 19177                          them anyway.  */
 19178                       || actual == XA_ATOM
 19179                       || actual == XA_WINDOW) && n)
 19180                 {
 19181                   opacity = *(unsigned long *) tmp_data & OPAQUE;
 19182                   f->alpha[0] = (double) opacity / (double) OPAQUE;
 19183                   f->alpha[1] = (double) opacity / (double) OPAQUE;
 19184 
 19185                   store_frame_param (f, Qalpha, make_float (f->alpha[0]));
 19186                 }
 19187               else
 19188                 {
 19189                   f->alpha[0] = 1.0;
 19190                   f->alpha[1] = 1.0;
 19191 
 19192                   store_frame_param (f, Qalpha, Qnil);
 19193                 }
 19194 #else
 19195               opacity_cookie
 19196                 = xcb_get_property (dpyinfo->xcb_connection, 0,
 19197                                     (xcb_window_t) FRAME_OUTER_WINDOW (f),
 19198                                     (xcb_atom_t) dpyinfo->Xatom_net_wm_window_opacity,
 19199                                     XCB_ATOM_CARDINAL, 0, 1);
 19200               opacity_reply
 19201                 = xcb_get_property_reply (dpyinfo->xcb_connection,
 19202                                           opacity_cookie, &error);
 19203 
 19204               if (!opacity_reply)
 19205                 free (error), rc = false;
 19206               else
 19207                 rc = (opacity_reply->format == 32
 19208                       && (opacity_reply->type == XCB_ATOM_CARDINAL
 19209                           || opacity_reply->type == XCB_ATOM_ATOM
 19210                           || opacity_reply->type == XCB_ATOM_WINDOW)
 19211                       && (xcb_get_property_value_length (opacity_reply) >= 4));
 19212 
 19213               if (rc)
 19214                 {
 19215                   value = *(uint32_t *) xcb_get_property_value (opacity_reply);
 19216 
 19217                   f->alpha[0] = (double) value / (double) OPAQUE;
 19218                   f->alpha[1] = (double) value / (double) OPAQUE;
 19219                   store_frame_param (f, Qalpha, make_float (f->alpha[0]));
 19220                 }
 19221               else
 19222                 {
 19223                   f->alpha[0] = 1.0;
 19224                   f->alpha[1] = 1.0;
 19225 
 19226                   store_frame_param (f, Qalpha, Qnil);
 19227                 }
 19228 
 19229               if (opacity_reply)
 19230                 free (opacity_reply);
 19231 #endif
 19232             }
 19233 
 19234 #ifndef USE_XCB
 19235           if (tmp_data)
 19236             XFree (tmp_data);
 19237 #endif
 19238         }
 19239 
 19240       if (event->xproperty.window == dpyinfo->root_window
 19241           && (event->xproperty.atom == dpyinfo->Xatom_net_client_list_stacking
 19242               || event->xproperty.atom == dpyinfo->Xatom_net_current_desktop)
 19243           && x_dnd_in_progress
 19244           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 19245         {
 19246           if (x_dnd_use_toplevels)
 19247             {
 19248               x_dnd_free_toplevels (true);
 19249 
 19250               if (x_dnd_compute_toplevels (dpyinfo))
 19251                 {
 19252                   x_dnd_free_toplevels (true);
 19253                   x_dnd_use_toplevels = false;
 19254                 }
 19255             }
 19256 
 19257           x_dnd_update_state (dpyinfo, event->xproperty.time);
 19258         }
 19259 
 19260       x_handle_property_notify (&event->xproperty);
 19261       xft_settings_event (dpyinfo, event);
 19262       goto OTHER;
 19263 
 19264     case ReparentNotify:
 19265       f = x_top_window_to_frame (dpyinfo, event->xreparent.window);
 19266       if (f)
 19267         {
 19268 #ifndef USE_GTK
 19269           if (FRAME_OUTPUT_DATA (f)->parent_desc
 19270               && FRAME_X_EMBEDDED_P (f))
 19271             {
 19272               /* The frame's embedder was destroyed; mark the frame as
 19273                  no longer embedded, and map the frame.  An
 19274                  UnmapNotify event must have previously been received
 19275                  during the start of save-set processing.  */
 19276 
 19277               FRAME_X_OUTPUT (f)->explicit_parent = false;
 19278 
 19279               /* Remove the leftover XEMBED_INFO property.  */
 19280               XDeleteProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
 19281                                dpyinfo->Xatom_XEMBED_INFO);
 19282               x_make_frame_visible (f);
 19283             }
 19284 #endif
 19285 
 19286           /* Maybe we shouldn't set this for child frames ??  */
 19287           f->output_data.x->parent_desc = event->xreparent.parent;
 19288 
 19289           if (!FRAME_PARENT_FRAME (f))
 19290             {
 19291               x_real_positions (f, &f->left_pos, &f->top_pos);
 19292 
 19293               /* Perhaps reparented due to a WM restart.  Reset this.  */
 19294               dpyinfo->wm_type = X_WMTYPE_UNKNOWN;
 19295               dpyinfo->net_supported_window = 0;
 19296 
 19297 #ifndef USE_GTK
 19298               /* The window manager could have restarted and the new
 19299                  window manager might not support user time windows,
 19300                  so update what is used accordingly.
 19301 
 19302                  Note that this doesn't handle changes between
 19303                  non-reparenting window managers.  */
 19304               if (FRAME_X_OUTPUT (f)->has_been_visible)
 19305                 x_update_frame_user_time_window (f);
 19306 #endif
 19307             }
 19308           else
 19309             {
 19310               Window root;
 19311               unsigned int dummy_uint;
 19312 
 19313               XGetGeometry (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 19314                             &root, &f->left_pos, &f->top_pos,
 19315                             &dummy_uint, &dummy_uint, &dummy_uint, &dummy_uint);
 19316             }
 19317 
 19318           x_set_frame_alpha (f);
 19319         }
 19320       goto OTHER;
 19321 
 19322     case Expose:
 19323 
 19324 #ifdef HAVE_XWIDGETS
 19325       {
 19326         struct xwidget_view *xv;
 19327 
 19328         xv = xwidget_view_from_window (event->xexpose.window);
 19329 
 19330         if (xv)
 19331           {
 19332             xwidget_expose (xv);
 19333             goto OTHER;
 19334           }
 19335       }
 19336 #endif
 19337 
 19338       f = x_window_to_frame (dpyinfo, event->xexpose.window);
 19339       if (f)
 19340         {
 19341           if (!FRAME_VISIBLE_P (f))
 19342             {
 19343               /* By default, do not set the frame's visibility here, see
 19344                  https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html.
 19345                  The default behavior can be overridden by setting
 19346                  'x-set-frame-visibility-more-laxly' (Bug#49955,
 19347                  Bug#53298).  */
 19348               if (EQ (x_set_frame_visibility_more_laxly, Qexpose)
 19349                   || EQ (x_set_frame_visibility_more_laxly, Qt))
 19350                 {
 19351                   SET_FRAME_VISIBLE (f, 1);
 19352                   SET_FRAME_ICONIFIED (f, false);
 19353                 }
 19354 
 19355 #ifdef HAVE_XDBE
 19356               if (FRAME_X_DOUBLE_BUFFERED_P (f))
 19357                 x_drop_xrender_surfaces (f);
 19358 #endif
 19359               f->output_data.x->has_been_visible = true;
 19360               SET_FRAME_GARBAGED (f);
 19361             }
 19362           else if (FRAME_GARBAGED_P (f))
 19363             {
 19364 #ifdef USE_GTK
 19365               /* Go around the back buffer and manually clear the
 19366                  window the first time we show it.  This way, we avoid
 19367                  showing users the sanity-defying horror of whatever
 19368                  GtkWindow is rendering beneath us.  We've garbaged
 19369                  the frame, so we'll redraw the whole thing on next
 19370                  redisplay anyway.  Yuck.  */
 19371               x_clear_area1 (FRAME_X_DISPLAY (f),
 19372                              FRAME_X_WINDOW (f),
 19373                              event->xexpose.x, event->xexpose.y,
 19374                              event->xexpose.width, event->xexpose.height,
 19375                              0);
 19376               x_clear_under_internal_border (f);
 19377 #endif
 19378             }
 19379 
 19380           if (!FRAME_GARBAGED_P (f))
 19381             {
 19382 #if defined USE_X_TOOLKIT && defined USE_TOOLKIT_SCROLL_BARS
 19383               if (f->output_data.x->edit_widget)
 19384                 /* The widget's expose proc will be run in this
 19385                    case.  */
 19386                 goto OTHER;
 19387 #endif
 19388 #ifdef USE_GTK
 19389               /* This seems to be needed for GTK 2.6 and later, see
 19390                  https://debbugs.gnu.org/cgi/bugreport.cgi?bug=15398.  */
 19391               x_clear_area (f,
 19392                             event->xexpose.x, event->xexpose.y,
 19393                             event->xexpose.width, event->xexpose.height);
 19394 #endif
 19395               expose_frame (f, event->xexpose.x, event->xexpose.y,
 19396                             event->xexpose.width, event->xexpose.height);
 19397 #ifndef USE_TOOLKIT_SCROLL_BARS
 19398               x_scroll_bar_handle_exposure (f, (XEvent *) event);
 19399 #endif
 19400 #ifdef USE_GTK
 19401               x_clear_under_internal_border (f);
 19402 #endif
 19403             }
 19404 #ifndef USE_TOOLKIT_SCROLL_BARS
 19405           else
 19406             x_scroll_bar_handle_exposure (f, (XEvent *) event);
 19407 #endif
 19408 
 19409 #ifdef HAVE_XDBE
 19410           if (!FRAME_GARBAGED_P (f))
 19411             show_back_buffer (f);
 19412 #endif
 19413         }
 19414       else
 19415         {
 19416 #if defined USE_LUCID
 19417           /* Submenus of the Lucid menu bar aren't widgets
 19418              themselves, so there's no way to dispatch events
 19419              to them.  Recognize this case separately.  */
 19420           {
 19421             Widget widget = x_window_to_menu_bar (event->xexpose.window);
 19422             if (widget)
 19423               xlwmenu_redisplay (widget);
 19424           }
 19425 #endif /* USE_LUCID */
 19426 
 19427           /* Dispatch event to the widget.  */
 19428           goto OTHER;
 19429         }
 19430       break;
 19431 
 19432     case GraphicsExpose:        /* This occurs when an XCopyArea's
 19433                                    source area was obscured or not
 19434                                    available.  */
 19435       f = x_window_to_frame (dpyinfo, event->xgraphicsexpose.drawable);
 19436       if (f)
 19437         {
 19438           expose_frame (f, event->xgraphicsexpose.x,
 19439                         event->xgraphicsexpose.y,
 19440                         event->xgraphicsexpose.width,
 19441                         event->xgraphicsexpose.height);
 19442 #ifndef USE_TOOLKIT_SCROLL_BARS
 19443           x_scroll_bar_handle_exposure (f, (XEvent *) event);
 19444 #endif
 19445 #ifdef USE_GTK
 19446           x_clear_under_internal_border (f);
 19447 #endif
 19448 #ifdef HAVE_XDBE
 19449           show_back_buffer (f);
 19450 #endif
 19451         }
 19452 #ifdef USE_X_TOOLKIT
 19453       else
 19454         goto OTHER;
 19455 #endif /* USE_X_TOOLKIT */
 19456       break;
 19457 
 19458     case NoExpose:              /* This occurs when an XCopyArea's
 19459                                    source area was completely
 19460                                    available.  */
 19461 #ifdef USE_X_TOOLKIT
 19462       *finish = X_EVENT_DROP;
 19463 #endif
 19464       break;
 19465 
 19466     case UnmapNotify:
 19467       if (x_dnd_in_progress && x_dnd_use_toplevels
 19468           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 19469         {
 19470           for (struct x_client_list_window *tem = x_dnd_toplevels; tem;
 19471                tem = tem->next)
 19472             {
 19473               if (tem->window == event->xunmap.window)
 19474                 {
 19475                   tem->mapped_p = false;
 19476                   break;
 19477                 }
 19478             }
 19479         }
 19480 
 19481       /* Redo the mouse-highlight after the tooltip has gone.  */
 19482       if (event->xunmap.window == tip_window)
 19483         {
 19484           tip_window = None;
 19485           gui_redo_mouse_highlight (dpyinfo);
 19486         }
 19487 
 19488       f = x_top_window_to_frame (dpyinfo, event->xunmap.window);
 19489       if (f)            /* F may no longer exist if
 19490                            the frame was deleted.  */
 19491         {
 19492           bool visible = FRAME_VISIBLE_P (f);
 19493 
 19494 #ifdef USE_LUCID
 19495           /* Bloodcurdling hack alert: The Lucid menu bar widget's
 19496              redisplay procedure is not called when a tip frame over
 19497              menu items is unmapped.  Redisplay the menu manually...  */
 19498           if (FRAME_TOOLTIP_P (f) && popup_activated ())
 19499             {
 19500               Widget w;
 19501               Lisp_Object tail, frame;
 19502               struct frame *f1;
 19503 
 19504               FOR_EACH_FRAME (tail, frame)
 19505                 {
 19506                   if (!FRAME_X_P (XFRAME (frame)))
 19507                     continue;
 19508 
 19509                   f1 = XFRAME (frame);
 19510 
 19511                   if (FRAME_LIVE_P (f1))
 19512                     {
 19513                       w = FRAME_X_OUTPUT (f1)->menubar_widget;
 19514 
 19515                       if (w && !DoesSaveUnders (FRAME_DISPLAY_INFO (f1)->screen))
 19516                         xlwmenu_redisplay (w);
 19517                     }
 19518                 }
 19519             }
 19520 #endif /* USE_LUCID */
 19521 
 19522           /* While a frame is unmapped, display generation is
 19523              disabled; you don't want to spend time updating a
 19524              display that won't ever be seen.  */
 19525           SET_FRAME_VISIBLE (f, 0);
 19526           /* We can't distinguish, from the event, whether the window
 19527              has become iconified or invisible.  So assume, if it
 19528              was previously visible, than now it is iconified.
 19529              But x_make_frame_invisible clears both
 19530              the visible flag and the iconified flag;
 19531              and that way, we know the window is not iconified now.  */
 19532           if (visible || FRAME_ICONIFIED_P (f))
 19533             {
 19534               if (CONSP (frame_size_history))
 19535                 frame_size_history_plain
 19536                   (f, build_string ("UnmapNotify, visible | iconified"));
 19537 
 19538               SET_FRAME_ICONIFIED (f, true);
 19539               inev.ie.kind = ICONIFY_EVENT;
 19540               XSETFRAME (inev.ie.frame_or_window, f);
 19541             }
 19542           else if (CONSP (frame_size_history))
 19543             frame_size_history_plain
 19544               (f, build_string ("UnmapNotify, not visible & not iconified"));
 19545         }
 19546       goto OTHER;
 19547 
 19548     case MapNotify:
 19549 #if defined HAVE_XINPUT2 && defined HAVE_GTK3
 19550       if (xg_is_menu_window (dpyinfo->display, event->xmap.window))
 19551         popup_activated_flag = 1;
 19552 #endif
 19553 
 19554       if (x_dnd_in_progress
 19555           /* When _NET_WM_CLIENT_LIST stacking is being used, changes
 19556              in that property are watched for, and it's not necessary
 19557              to update the state in response to ordinary window
 19558              substructure events.  */
 19559           && !x_dnd_use_toplevels
 19560           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 19561         x_dnd_update_state (dpyinfo, dpyinfo->last_user_time);
 19562 
 19563       if (x_dnd_in_progress && x_dnd_use_toplevels
 19564           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 19565         {
 19566           for (struct x_client_list_window *tem = x_dnd_toplevels; tem;
 19567                tem = tem->next)
 19568             {
 19569               if (tem->window == event->xmap.window)
 19570                 {
 19571                   tem->mapped_p = true;
 19572                   break;
 19573                 }
 19574             }
 19575         }
 19576 
 19577       /* We use x_top_window_to_frame because map events can
 19578          come for sub-windows and they don't mean that the
 19579          frame is visible.  */
 19580       f = x_top_window_to_frame (dpyinfo, event->xmap.window);
 19581       if (f)
 19582         {
 19583           bool iconified = FRAME_ICONIFIED_P (f);
 19584           int value;
 19585           bool sticky, shaded;
 19586           bool not_hidden = x_get_current_wm_state (f, event->xmap.window, &value, &sticky,
 19587                                                     &shaded);
 19588 
 19589           if (CONSP (frame_size_history))
 19590             frame_size_history_extra
 19591               (f,
 19592                iconified
 19593                ? (not_hidden
 19594                   ? build_string ("MapNotify, not hidden & iconified")
 19595                   : build_string ("MapNotify, hidden & iconified"))
 19596                : (not_hidden
 19597                   ? build_string ("MapNotify, not hidden & not iconified")
 19598                   : build_string ("MapNotify, hidden & not iconified")),
 19599                FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
 19600                -1, -1, f->new_width, f->new_height);
 19601 
 19602           /* Check if fullscreen was specified before we where mapped the
 19603              first time, i.e. from the command line.  */
 19604           if (!f->output_data.x->has_been_visible)
 19605             {
 19606 
 19607               x_check_fullscreen (f);
 19608 #ifndef USE_GTK
 19609               /* For systems that cannot synthesize `skip_taskbar' for
 19610                  unmapped windows do the following.  */
 19611               if (FRAME_SKIP_TASKBAR (f))
 19612                 x_set_skip_taskbar (f, Qt, Qnil);
 19613 #endif /* Not USE_GTK */
 19614             }
 19615 
 19616           if (!iconified)
 19617             {
 19618               /* The `z-group' is reset every time a frame becomes
 19619                  invisible.  Handle this here.  */
 19620               if (FRAME_Z_GROUP (f) == z_group_above)
 19621                 x_set_z_group (f, Qabove, Qnil);
 19622               else if (FRAME_Z_GROUP (f) == z_group_below)
 19623                 x_set_z_group (f, Qbelow, Qnil);
 19624             }
 19625 
 19626           /* Embedded frames might have NET_WM_STATE left over, but
 19627              are always visible once mapped.  */
 19628           if (not_hidden || FRAME_X_EMBEDDED_P (f))
 19629             {
 19630               SET_FRAME_VISIBLE (f, 1);
 19631               SET_FRAME_ICONIFIED (f, false);
 19632 #if defined USE_GTK && defined HAVE_GTK3
 19633               /* If GTK3 wants to impose some old size here (Bug#24526),
 19634                  tell it that the current size is what we want.  */
 19635               if (f->was_invisible)
 19636                 {
 19637                   xg_frame_set_char_size
 19638                     (f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
 19639                   f->was_invisible = false;
 19640                 }
 19641 #endif
 19642               f->output_data.x->has_been_visible = true;
 19643             }
 19644 
 19645           x_update_opaque_region (f, NULL);
 19646 
 19647           if ((not_hidden || FRAME_X_EMBEDDED_P (f)) && iconified)
 19648             {
 19649               inev.ie.kind = DEICONIFY_EVENT;
 19650               XSETFRAME (inev.ie.frame_or_window, f);
 19651             }
 19652         }
 19653       goto OTHER;
 19654 
 19655     case KeyPress:
 19656       x_display_set_last_user_time (dpyinfo, event->xkey.time,
 19657                                     event->xkey.send_event,
 19658                                     true);
 19659       ignore_next_mouse_click_timeout = 0;
 19660 
 19661       coding = Qlatin_1;
 19662 
 19663 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
 19664       /* Dispatch KeyPress events when in menu.  */
 19665       if (popup_activated ())
 19666         goto OTHER;
 19667 #endif
 19668 
 19669       f = any;
 19670 
 19671 #ifdef USE_GTK
 19672       if (f)
 19673         x_set_gtk_user_time (f, event->xkey.time);
 19674 #endif
 19675 
 19676       /* If mouse-highlight is an integer, input clears out
 19677          mouse highlighting.  */
 19678       if (!hlinfo->mouse_face_hidden && FIXNUMP (Vmouse_highlight)
 19679           && (f == 0
 19680 #if ! defined (USE_GTK)
 19681               || !EQ (f->tool_bar_window, hlinfo->mouse_face_window)
 19682 #endif
 19683               || !EQ (f->tab_bar_window, hlinfo->mouse_face_window))
 19684           )
 19685         {
 19686           mouse_frame = hlinfo->mouse_face_mouse_frame;
 19687 
 19688           clear_mouse_face (hlinfo);
 19689           hlinfo->mouse_face_hidden = true;
 19690 
 19691           if (mouse_frame)
 19692             x_flush_dirty_back_buffer_on (mouse_frame);
 19693         }
 19694 
 19695 #if defined USE_MOTIF && defined USE_TOOLKIT_SCROLL_BARS
 19696       if (f == 0)
 19697         {
 19698           /* Scroll bars consume key events, but we want
 19699              the keys to go to the scroll bar's frame.  */
 19700           Widget widget = XtWindowToWidget (dpyinfo->display,
 19701                                             event->xkey.window);
 19702           if (widget && XmIsScrollBar (widget))
 19703             {
 19704               widget = XtParent (widget);
 19705               f = x_any_window_to_frame (dpyinfo, XtWindow (widget));
 19706             }
 19707         }
 19708 #endif /* USE_MOTIF and USE_TOOLKIT_SCROLL_BARS */
 19709 
 19710       if (f != 0)
 19711         {
 19712           KeySym keysym, orig_keysym;
 19713           /* al%imercury@uunet.uu.net says that making this 81
 19714              instead of 80 fixed a bug whereby meta chars made
 19715              his Emacs hang.
 19716 
 19717              It seems that some version of XmbLookupString has
 19718              a bug of not returning XBufferOverflow in
 19719              status_return even if the input is too long to
 19720              fit in 81 bytes.  So, we must prepare sufficient
 19721              bytes for copy_buffer.  513 bytes (256 chars for
 19722              two-byte character set) seems to be a fairly good
 19723              approximation.  -- 2000.8.10 handa@gnu.org  */
 19724           unsigned char copy_buffer[513];
 19725           unsigned char *copy_bufptr = copy_buffer;
 19726           int copy_bufsiz = sizeof (copy_buffer);
 19727           int modifiers;
 19728           Lisp_Object c;
 19729           /* `xkey' will be modified, but it's not important to modify
 19730              `event' itself.  */
 19731           XKeyEvent xkey = event->xkey;
 19732 
 19733           if (event->xkey.window == FRAME_X_WINDOW (f))
 19734             /* See the comment above x_compute_root_window_offset for
 19735                why this optimization is performed.  */
 19736             x_compute_root_window_offset (f, event->xkey.x_root,
 19737                                           event->xkey.y_root,
 19738                                           event->xkey.x, event->xkey.y);
 19739 
 19740 #ifdef HAVE_XINPUT2
 19741           Time pending_keystroke_time;
 19742           struct xi_device_t *source;
 19743 
 19744           pending_keystroke_time = dpyinfo->pending_keystroke_time;
 19745 
 19746           if (event->xkey.time >= pending_keystroke_time)
 19747             {
 19748 #if defined USE_GTK && !defined HAVE_GTK3
 19749               if (!dpyinfo->pending_keystroke_time_special_p)
 19750 #endif
 19751                 dpyinfo->pending_keystroke_time = 0;
 19752 #if defined USE_GTK && !defined HAVE_GTK3
 19753               else
 19754                 dpyinfo->pending_keystroke_time_special_p = false;
 19755 #endif
 19756             }
 19757 #endif
 19758 
 19759 #ifdef USE_GTK
 19760           /* Don't pass keys to GTK.  A Tab will shift focus to the
 19761              tool bar in GTK 2.4.  Keys will still go to menus and
 19762              dialogs because in that case popup_activated is nonzero
 19763              (see above).  */
 19764           *finish = X_EVENT_DROP;
 19765 #endif
 19766 
 19767           xkey.state |= x_emacs_to_x_modifiers (dpyinfo,
 19768                                                 extra_keyboard_modifiers);
 19769           modifiers = xkey.state;
 19770 
 19771           /* This will have to go some day...  */
 19772 
 19773           /* make_lispy_event turns chars into control chars.
 19774              Don't do it here because XLookupString is too eager.  */
 19775           xkey.state &= ~ControlMask;
 19776           xkey.state &= ~(dpyinfo->meta_mod_mask
 19777                           | dpyinfo->super_mod_mask
 19778                           | dpyinfo->hyper_mod_mask
 19779                           | dpyinfo->alt_mod_mask);
 19780 
 19781           /* In case Meta is ComposeCharacter,
 19782              clear its status.  According to Markus Ehrnsperger
 19783              Markus.Ehrnsperger@lehrstuhl-bross.physik.uni-muenchen.de
 19784              this enables ComposeCharacter to work whether or
 19785              not it is combined with Meta.  */
 19786           if (modifiers & dpyinfo->meta_mod_mask)
 19787             memset (&compose_status, 0, sizeof (compose_status));
 19788 
 19789 #ifdef HAVE_X_I18N
 19790           if (FRAME_XIC (f))
 19791             {
 19792               Status status_return;
 19793 
 19794               nbytes = XmbLookupString (FRAME_XIC (f),
 19795                                         &xkey, (char *) copy_bufptr,
 19796                                         copy_bufsiz, &keysym,
 19797                                         &status_return);
 19798               coding = FRAME_X_XIM_CODING (f);
 19799               if (status_return == XBufferOverflow)
 19800                 {
 19801                   copy_bufsiz = nbytes + 1;
 19802                   copy_bufptr = SAFE_ALLOCA (copy_bufsiz);
 19803                   nbytes = XmbLookupString (FRAME_XIC (f),
 19804                                             &xkey, (char *) copy_bufptr,
 19805                                             copy_bufsiz, &keysym,
 19806                                             &status_return);
 19807                 }
 19808               /* Xutf8LookupString is a new but already deprecated interface.  -stef  */
 19809               if (status_return == XLookupNone)
 19810                 break;
 19811               else if (status_return == XLookupChars)
 19812                 {
 19813                   keysym = NoSymbol;
 19814                   modifiers = 0;
 19815                 }
 19816               else if (status_return != XLookupKeySym
 19817                        && status_return != XLookupBoth)
 19818                 emacs_abort ();
 19819             }
 19820           else
 19821 #endif
 19822             {
 19823 #ifdef HAVE_XKB
 19824               int overflow;
 19825               unsigned int consumed;
 19826 
 19827               if (dpyinfo->xkb_desc)
 19828                 {
 19829                   if (!XkbTranslateKeyCode (dpyinfo->xkb_desc,
 19830                                             xkey.keycode, xkey.state,
 19831                                             &consumed, &keysym))
 19832                     goto done_keysym;
 19833 
 19834                   overflow = 0;
 19835 
 19836                   nbytes = XkbTranslateKeySym (dpyinfo->display, &keysym,
 19837                                                xkey.state & ~consumed,
 19838                                                (char *) copy_bufptr,
 19839                                                copy_bufsiz, &overflow);
 19840 
 19841                   if (overflow)
 19842                     {
 19843                       copy_bufptr = SAFE_ALLOCA ((copy_bufsiz += overflow)
 19844                                                  * sizeof *copy_bufptr);
 19845                       overflow = 0;
 19846                       nbytes = XkbTranslateKeySym (dpyinfo->display, &keysym,
 19847                                                    xkey.state & ~consumed,
 19848                                                    (char *) copy_bufptr,
 19849                                                    copy_bufsiz, &overflow);
 19850 
 19851                       if (overflow)
 19852                         nbytes = 0;
 19853                     }
 19854 
 19855                   if (nbytes)
 19856                     coding = Qnil;
 19857                 }
 19858               else
 19859 #endif
 19860                 nbytes = XLookupString (&xkey, (char *) copy_bufptr,
 19861                                         copy_bufsiz, &keysym,
 19862                                         &compose_status);
 19863             }
 19864 
 19865 #ifdef XK_F1
 19866           if (x_dnd_in_progress && keysym == XK_F1)
 19867             {
 19868               x_dnd_xm_use_help = true;
 19869               goto done_keysym;
 19870             }
 19871 #endif
 19872 
 19873           /* If not using XIM/XIC, and a compose sequence is in progress,
 19874              we break here.  Otherwise, chars_matched is always 0.  */
 19875           if (compose_status.chars_matched > 0 && nbytes == 0)
 19876             break;
 19877 
 19878           memset (&compose_status, 0, sizeof (compose_status));
 19879           orig_keysym = keysym;
 19880 
 19881           /* Common for all keysym input events.  */
 19882           XSETFRAME (inev.ie.frame_or_window, f);
 19883           inev.ie.modifiers
 19884             = x_x_to_emacs_modifiers (dpyinfo, modifiers);
 19885           inev.ie.timestamp = xkey.time;
 19886 
 19887           /* First deal with keysyms which have defined
 19888              translations to characters.  */
 19889           if (keysym >= 32 && keysym < 128)
 19890             /* Avoid explicitly decoding each ASCII character.  */
 19891             {
 19892               inev.ie.kind = ASCII_KEYSTROKE_EVENT;
 19893               inev.ie.code = keysym;
 19894 
 19895 #ifdef HAVE_XINPUT2
 19896               if (event->xkey.time == pending_keystroke_time)
 19897                 {
 19898                   source = xi_device_from_id (dpyinfo,
 19899                                               dpyinfo->pending_keystroke_source);
 19900 
 19901                   if (source)
 19902                     inev.ie.device = source->name;
 19903                 }
 19904 #endif
 19905 
 19906               goto done_keysym;
 19907             }
 19908 
 19909           /* Keysyms directly mapped to Unicode characters.  */
 19910           if (keysym >= 0x01000000 && keysym <= 0x0110FFFF)
 19911             {
 19912               if (keysym < 0x01000080)
 19913                 inev.ie.kind = ASCII_KEYSTROKE_EVENT;
 19914               else
 19915                 inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
 19916               inev.ie.code = keysym & 0xFFFFFF;
 19917 
 19918 #ifdef HAVE_XINPUT2
 19919               if (event->xkey.time == pending_keystroke_time)
 19920                 {
 19921                   source = xi_device_from_id (dpyinfo,
 19922                                               dpyinfo->pending_keystroke_source);
 19923 
 19924                   if (source)
 19925                     inev.ie.device = source->name;
 19926                 }
 19927 #endif
 19928 
 19929               goto done_keysym;
 19930             }
 19931 
 19932           /* Now non-ASCII.  */
 19933           if (HASH_TABLE_P (Vx_keysym_table)
 19934               && (c = Fgethash (make_fixnum (keysym),
 19935                                 Vx_keysym_table,
 19936                                 Qnil),
 19937                   FIXNATP (c)))
 19938             {
 19939               inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFIXNAT (c))
 19940                               ? ASCII_KEYSTROKE_EVENT
 19941                               : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
 19942               inev.ie.code = XFIXNAT (c);
 19943 
 19944 #ifdef HAVE_XINPUT2
 19945               if (event->xkey.time == pending_keystroke_time)
 19946                 {
 19947                   source = xi_device_from_id (dpyinfo,
 19948                                               dpyinfo->pending_keystroke_source);
 19949 
 19950                   if (source)
 19951                     inev.ie.device = source->name;
 19952                 }
 19953 #endif
 19954 
 19955               goto done_keysym;
 19956             }
 19957 
 19958           /* Random non-modifier sorts of keysyms.  */
 19959           if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
 19960                || keysym == XK_Delete
 19961 #ifdef XK_ISO_Left_Tab
 19962                || (keysym >= XK_ISO_Left_Tab
 19963                    && keysym <= XK_ISO_Enter)
 19964 #endif
 19965                || IsCursorKey (keysym) /* 0xff50 <= x < 0xff60 */
 19966                || IsMiscFunctionKey (keysym) /* 0xff60 <= x < VARIES */
 19967 #ifdef HPUX
 19968                /* This recognizes the "extended function
 19969                   keys".  It seems there's no cleaner way.
 19970                   Test IsModifierKey to avoid handling
 19971                   mode_switch incorrectly.  */
 19972                || (XK_Select <= keysym && keysym < XK_KP_Space)
 19973 #endif
 19974 #ifdef XK_dead_circumflex
 19975                || orig_keysym == XK_dead_circumflex
 19976 #endif
 19977 #ifdef XK_dead_grave
 19978                || orig_keysym == XK_dead_grave
 19979 #endif
 19980 #ifdef XK_dead_tilde
 19981                || orig_keysym == XK_dead_tilde
 19982 #endif
 19983 #ifdef XK_dead_diaeresis
 19984                || orig_keysym == XK_dead_diaeresis
 19985 #endif
 19986 #ifdef XK_dead_macron
 19987                || orig_keysym == XK_dead_macron
 19988 #endif
 19989 #ifdef XK_dead_degree
 19990                || orig_keysym == XK_dead_degree
 19991 #endif
 19992 #ifdef XK_dead_acute
 19993                || orig_keysym == XK_dead_acute
 19994 #endif
 19995 #ifdef XK_dead_cedilla
 19996                || orig_keysym == XK_dead_cedilla
 19997 #endif
 19998 #ifdef XK_dead_breve
 19999                || orig_keysym == XK_dead_breve
 20000 #endif
 20001 #ifdef XK_dead_ogonek
 20002                || orig_keysym == XK_dead_ogonek
 20003 #endif
 20004 #ifdef XK_dead_caron
 20005                || orig_keysym == XK_dead_caron
 20006 #endif
 20007 #ifdef XK_dead_doubleacute
 20008                || orig_keysym == XK_dead_doubleacute
 20009 #endif
 20010 #ifdef XK_dead_abovedot
 20011                || orig_keysym == XK_dead_abovedot
 20012 #endif
 20013 #ifdef XK_dead_abovering
 20014                || orig_keysym == XK_dead_abovering
 20015 #endif
 20016 #ifdef XK_dead_belowdot
 20017                || orig_keysym == XK_dead_belowdot
 20018 #endif
 20019 #ifdef XK_dead_voiced_sound
 20020                || orig_keysym == XK_dead_voiced_sound
 20021 #endif
 20022 #ifdef XK_dead_semivoiced_sound
 20023                || orig_keysym == XK_dead_semivoiced_sound
 20024 #endif
 20025 #ifdef XK_dead_hook
 20026                || orig_keysym == XK_dead_hook
 20027 #endif
 20028 #ifdef XK_dead_horn
 20029                || orig_keysym == XK_dead_horn
 20030 #endif
 20031 #ifdef XK_dead_stroke
 20032                || orig_keysym == XK_dead_stroke
 20033 #endif
 20034 #ifdef XK_dead_abovecomma
 20035                || orig_keysym == XK_dead_abovecomma
 20036 #endif
 20037                || IsKeypadKey (keysym) /* 0xff80 <= x < 0xffbe */
 20038                || IsFunctionKey (keysym) /* 0xffbe <= x < 0xffe1 */
 20039                /* Any "vendor-specific" key is ok.  */
 20040                || (orig_keysym & (1 << 28))
 20041                || (keysym != NoSymbol && nbytes == 0))
 20042               && ! (IsModifierKey (orig_keysym)
 20043                     /* The symbols from XK_ISO_Lock
 20044                        to XK_ISO_Last_Group_Lock
 20045                        don't have real modifiers but
 20046                        should be treated similarly to
 20047                        Mode_switch by Emacs. */
 20048 #if defined XK_ISO_Lock && defined XK_ISO_Last_Group_Lock
 20049                     || (XK_ISO_Lock <= orig_keysym
 20050                         && orig_keysym <= XK_ISO_Last_Group_Lock)
 20051 #endif
 20052                     ))
 20053             {
 20054               STORE_KEYSYM_FOR_DEBUG (keysym);
 20055               /* make_lispy_event will convert this to a symbolic
 20056                  key.  */
 20057               inev.ie.kind = NON_ASCII_KEYSTROKE_EVENT;
 20058               inev.ie.code = keysym;
 20059 
 20060 #ifdef HAVE_XINPUT2
 20061               if (event->xkey.time == pending_keystroke_time)
 20062                 {
 20063                   source = xi_device_from_id (dpyinfo,
 20064                                               dpyinfo->pending_keystroke_source);
 20065 
 20066                   if (source)
 20067                     inev.ie.device = source->name;
 20068                 }
 20069 #endif
 20070 
 20071               goto done_keysym;
 20072             }
 20073 
 20074           {     /* Raw bytes, not keysym.  */
 20075             ptrdiff_t i;
 20076 
 20077             for (i = 0; i < nbytes; i++)
 20078               {
 20079                 STORE_KEYSYM_FOR_DEBUG (copy_bufptr[i]);
 20080               }
 20081 
 20082             if (nbytes)
 20083               {
 20084                 inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
 20085                 inev.ie.arg = make_unibyte_string ((char *) copy_bufptr, nbytes);
 20086 
 20087                 Fput_text_property (make_fixnum (0), make_fixnum (nbytes),
 20088                                     Qcoding, coding, inev.ie.arg);
 20089 
 20090 #ifdef HAVE_XINPUT2
 20091                 if (event->xkey.time == pending_keystroke_time
 20092                     /* I-Bus sometimes sends events generated from
 20093                        multiple filtered keystrokes with a time of 0,
 20094                        so just use the recorded source device if it
 20095                        exists.  */
 20096                     || (pending_keystroke_time && !event->xkey.time))
 20097                   {
 20098                     source = xi_device_from_id (dpyinfo,
 20099                                                 dpyinfo->pending_keystroke_source);
 20100 
 20101                     if (source)
 20102                       inev.ie.device = source->name;
 20103                   }
 20104 #endif
 20105               }
 20106 
 20107             if (keysym == NoSymbol)
 20108               break;
 20109           }
 20110         }
 20111     done_keysym:
 20112 #ifdef HAVE_X_I18N
 20113       if (f)
 20114         {
 20115           struct window *w = XWINDOW (f->selected_window);
 20116           xic_set_preeditarea (w, w->cursor.x, w->cursor.y);
 20117 
 20118           if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea))
 20119             xic_set_statusarea (f);
 20120         }
 20121 
 20122       /* Don't dispatch this event since XtDispatchEvent calls
 20123          XFilterEvent, and two calls in a row may freeze the
 20124          client.  */
 20125       break;
 20126 #else
 20127       goto OTHER;
 20128 #endif
 20129 
 20130     case KeyRelease:
 20131 #ifdef HAVE_X_I18N
 20132       /* Don't dispatch this event since XtDispatchEvent calls
 20133          XFilterEvent, and two calls in a row may freeze the
 20134          client.  */
 20135       break;
 20136 #else
 20137       goto OTHER;
 20138 #endif
 20139 
 20140     case EnterNotify:
 20141       x_display_set_last_user_time (dpyinfo, event->xcrossing.time,
 20142                                     event->xcrossing.send_event,
 20143                                     false);
 20144 
 20145 #ifdef HAVE_XWIDGETS
 20146       {
 20147         struct xwidget_view *xvw;
 20148         Mouse_HLInfo *hlinfo;
 20149 
 20150         xvw = xwidget_view_from_window (event->xcrossing.window);
 20151 
 20152         if (xvw)
 20153           {
 20154             xwidget_motion_or_crossing (xvw, event);
 20155             hlinfo = MOUSE_HL_INFO (xvw->frame);
 20156 
 20157             if (xvw->frame == hlinfo->mouse_face_mouse_frame)
 20158               {
 20159                 clear_mouse_face (hlinfo);
 20160                 hlinfo->mouse_face_mouse_frame = 0;
 20161                 x_flush_dirty_back_buffer_on (xvw->frame);
 20162               }
 20163 
 20164             if (any_help_event_p)
 20165               do_help = -1;
 20166 
 20167             goto OTHER;
 20168           }
 20169       }
 20170 #endif
 20171 
 20172 #ifdef HAVE_XINPUT2
 20173       /* For whatever reason, the X server continues to deliver
 20174          EnterNotify and LeaveNotify events despite us selecting for
 20175          related XI_Enter and XI_Leave events.  It's not just our
 20176          problem, since windows created by "xinput test-xi2" suffer
 20177          from the same defect.  Simply ignore all such events while
 20178          the input extension is enabled.  (bug#57468) */
 20179 
 20180       if (dpyinfo->supports_xi2)
 20181         goto OTHER;
 20182 #endif
 20183 
 20184       if (x_top_window_to_frame (dpyinfo, event->xcrossing.window))
 20185         x_detect_focus_change (dpyinfo, any, event, &inev.ie);
 20186 
 20187       f = any;
 20188 
 20189       if (f && event->xcrossing.window == FRAME_X_WINDOW (f))
 20190         x_compute_root_window_offset (f, event->xcrossing.x_root,
 20191                                       event->xcrossing.y_root,
 20192                                       event->xcrossing.x,
 20193                                       event->xcrossing.y);
 20194 
 20195       /* The code below relies on the first several fields of
 20196          XCrossingEvent being laid out the same way as
 20197          XMotionEvent.  */
 20198 
 20199       if (f && x_mouse_click_focus_ignore_position)
 20200         {
 20201           ignore_next_mouse_click_timeout = (event->xmotion.time
 20202                                              + x_mouse_click_focus_ignore_time);
 20203           mouse_click_timeout_display = dpyinfo;
 20204         }
 20205 
 20206       /* EnterNotify counts as mouse movement,
 20207          so update things that depend on mouse position.  */
 20208       if (f && !f->output_data.x->hourglass_p)
 20209         x_note_mouse_movement (f, &event->xmotion, Qnil);
 20210 #ifdef USE_GTK
 20211       /* We may get an EnterNotify on the buttons in the toolbar.  In that
 20212          case we moved out of any highlighted area and need to note this.  */
 20213       if (!f && dpyinfo->last_mouse_glyph_frame)
 20214         x_note_mouse_movement (dpyinfo->last_mouse_glyph_frame, &event->xmotion,
 20215                                Qnil);
 20216 #endif
 20217       goto OTHER;
 20218 
 20219     case FocusIn:
 20220 #if defined HAVE_XINPUT2                                                \
 20221   && (defined HAVE_GTK3 || (!defined USE_GTK && !defined USE_X_TOOLKIT))
 20222       /* If a FocusIn event is received (because the window manager
 20223          sent us one), don't set the core focus if XInput 2 is
 20224          enabled, since that would mess up the device-specific focus
 20225          tracking.
 20226 
 20227          The long looking preprocessor conditional only enables this
 20228          code on GTK 3 and no toolkit builds, since those are the only
 20229          builds where focus is tracked specific to each master device.
 20230          Other builds use core events and the client pointer to handle
 20231          focus, much like on a build without XInput 2.  */
 20232       if (dpyinfo->supports_xi2)
 20233         goto OTHER;
 20234 #endif
 20235 #ifdef USE_GTK
 20236       /* Some WMs (e.g. Mutter in Gnome Shell), don't unmap
 20237          minimized/iconified windows; thus, for those WMs we won't get
 20238          a MapNotify when unminimizing/deiconifying.  Check here if we
 20239          are deiconizing a window (Bug42655).
 20240 
 20241          But don't do that by default on GTK since it may cause a plain
 20242          invisible frame get reported as iconified, compare
 20243          https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html.
 20244          That is fixed above but bites us here again.
 20245 
 20246          The option x_set_frame_visibility_more_laxly allows to override
 20247          the default behavior (Bug#49955, Bug#53298).  */
 20248       if (EQ (x_set_frame_visibility_more_laxly, Qfocus_in)
 20249           || EQ (x_set_frame_visibility_more_laxly, Qt))
 20250 #endif /* USE_GTK */
 20251         {
 20252           f = any;
 20253           if (f && FRAME_ICONIFIED_P (f))
 20254             {
 20255               SET_FRAME_VISIBLE (f, 1);
 20256               SET_FRAME_ICONIFIED (f, false);
 20257               f->output_data.x->has_been_visible = true;
 20258               inev.ie.kind = DEICONIFY_EVENT;
 20259               XSETFRAME (inev.ie.frame_or_window, f);
 20260             }
 20261         }
 20262 
 20263       x_detect_focus_change (dpyinfo, any, event, &inev.ie);
 20264       goto OTHER;
 20265 
 20266     case LeaveNotify:
 20267       x_display_set_last_user_time (dpyinfo, event->xcrossing.time,
 20268                                     event->xcrossing.send_event, false);
 20269 
 20270 #ifdef HAVE_XINPUT2
 20271       /* For whatever reason, the X server continues to deliver
 20272          EnterNotify and LeaveNotify events despite us selecting for
 20273          related XI_Enter and XI_Leave events.  It's not just our
 20274          problem, since windows created by "xinput test-xi2" suffer
 20275          from the same defect.  Simply ignore all such events while
 20276          the input extension is enabled.  (bug#57468) */
 20277 
 20278       if (dpyinfo->supports_xi2)
 20279         {
 20280 #if !defined USE_X_TOOLKIT && (!defined USE_GTK || defined HAVE_GTK3)
 20281           goto OTHER;
 20282 #else
 20283           /* Unfortunately, X toolkit popups generate LeaveNotify
 20284              events due to the core grabs they acquire (and our
 20285              releasing of the device grab).  This leads to the mouse
 20286              face persisting if a popup is activated by clicking on a
 20287              button, and then dismissed by releasing the mouse button
 20288              outside the frame, in which case no XI_Enter event is
 20289              generated for the grab.  */
 20290           goto just_clear_mouse_face;
 20291 #endif
 20292         }
 20293 #endif
 20294 
 20295 #ifdef HAVE_XWIDGETS
 20296       {
 20297         struct xwidget_view *xvw;
 20298 
 20299         xvw = xwidget_view_from_window (event->xcrossing.window);
 20300 
 20301         if (xvw)
 20302           {
 20303             xwidget_motion_or_crossing (xvw, event);
 20304             goto OTHER;
 20305           }
 20306       }
 20307 #endif
 20308 
 20309       if (x_top_window_to_frame (dpyinfo, event->xcrossing.window))
 20310         x_detect_focus_change (dpyinfo, any, event, &inev.ie);
 20311 
 20312 #if defined HAVE_XINPUT2                                                \
 20313   && (defined USE_X_TOOLKIT || (defined USE_GTK && !defined HAVE_GTK3))
 20314     just_clear_mouse_face:
 20315 #endif
 20316 
 20317 #if defined USE_X_TOOLKIT
 20318       /* If the mouse leaves the edit widget, then any mouse highlight
 20319          should be cleared.  */
 20320       f = x_window_to_frame (dpyinfo, event->xcrossing.window);
 20321 
 20322       if (!f)
 20323         f = x_top_window_to_frame (dpyinfo, event->xcrossing.window);
 20324 #else
 20325       f = x_top_window_to_frame (dpyinfo, event->xcrossing.window);
 20326 #endif
 20327 
 20328       if (f)
 20329         {
 20330           /* Now clear dpyinfo->last_mouse_motion_frame, or
 20331              gui_redo_mouse_highlight will end up highlighting the
 20332              last known position of the mouse if a tooltip frame is
 20333              later unmapped.  */
 20334 
 20335           if (f == dpyinfo->last_mouse_motion_frame)
 20336             dpyinfo->last_mouse_motion_frame = NULL;
 20337 
 20338           /* Something similar applies to
 20339              dpyinfo->last_mouse_glyph_frame.  */
 20340           if (f == dpyinfo->last_mouse_glyph_frame)
 20341             dpyinfo->last_mouse_glyph_frame = NULL;
 20342 
 20343           if (f == hlinfo->mouse_face_mouse_frame)
 20344             {
 20345               /* If we move outside the frame, then we're
 20346                  certainly no longer on any text in the frame.  */
 20347               clear_mouse_face (hlinfo);
 20348               hlinfo->mouse_face_mouse_frame = 0;
 20349               x_flush_dirty_back_buffer_on (f);
 20350             }
 20351 
 20352           /* Generate a nil HELP_EVENT to cancel a help-echo.
 20353              Do it only if there's something to cancel.
 20354              Otherwise, the startup message is cleared when
 20355              the mouse leaves the frame.  */
 20356           if (any_help_event_p
 20357               /* But never if `mouse-drag-and-drop-region' is in
 20358                  progress, since that results in the tooltip being
 20359                  dismissed when the mouse moves on top.  */
 20360               && !((EQ (track_mouse, Qdrag_source)
 20361                     || EQ (track_mouse, Qdropping))
 20362                    && gui_mouse_grabbed (dpyinfo)))
 20363             do_help = -1;
 20364 
 20365           if (event->xcrossing.window == FRAME_X_WINDOW (f))
 20366             x_compute_root_window_offset (f, event->xcrossing.x_root,
 20367                                           event->xcrossing.y_root,
 20368                                           event->xcrossing.x,
 20369                                           event->xcrossing.y);
 20370 
 20371         }
 20372 #ifdef USE_GTK
 20373       /* See comment in EnterNotify above */
 20374       else if (dpyinfo->last_mouse_glyph_frame)
 20375         x_note_mouse_movement (dpyinfo->last_mouse_glyph_frame,
 20376                                &event->xmotion, Qnil);
 20377 #endif
 20378       goto OTHER;
 20379 
 20380     case FocusOut:
 20381 #if defined HAVE_XINPUT2                                                \
 20382   && (defined HAVE_GTK3 || (!defined USE_GTK && !defined USE_X_TOOLKIT))
 20383       /* If a FocusIn event is received (because the window manager
 20384          sent us one), don't set the core focus if XInput 2 is
 20385          enabled, since that would mess up the device-specific focus
 20386          tracking.
 20387 
 20388          The long looking preprocessor conditional only enables this
 20389          code on GTK 3 and no toolkit builds, since those are the only
 20390          builds where focus is tracked specific to each master device.
 20391          Other builds use core events and the client pointer to handle
 20392          focus, much like on a build without XInput 2.  */
 20393       if (dpyinfo->supports_xi2)
 20394         goto OTHER;
 20395 #endif
 20396       x_detect_focus_change (dpyinfo, any, event, &inev.ie);
 20397       goto OTHER;
 20398 
 20399     case MotionNotify:
 20400       {
 20401         XMotionEvent xmotion = event->xmotion;
 20402 
 20403         previous_help_echo_string = help_echo_string;
 20404         help_echo_string = Qnil;
 20405 
 20406         if (hlinfo->mouse_face_hidden)
 20407           {
 20408             hlinfo->mouse_face_hidden = false;
 20409             clear_mouse_face (hlinfo);
 20410           }
 20411 
 20412         f = mouse_or_wdesc_frame (dpyinfo, event->xmotion.window);
 20413 
 20414         if (f && event->xmotion.window == FRAME_X_WINDOW (f))
 20415           /* See the comment above x_compute_root_window_offset for
 20416              why this optimization is performed.  */
 20417           x_compute_root_window_offset (f, event->xmotion.x_root,
 20418                                         event->xmotion.y_root,
 20419                                         event->xmotion.x,
 20420                                         event->xmotion.y);
 20421 
 20422         if (x_dnd_in_progress
 20423             /* Handle these events normally if the recursion
 20424                level is higher than when the drag-and-drop
 20425                operation was initiated.  This is so that mouse
 20426                input works while we're in the debugger for, say,
 20427                `x-dnd-movement-function`.  */
 20428             && (command_loop_level + minibuf_level
 20429                 <= x_dnd_recursion_depth)
 20430             && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 20431           {
 20432             Window target, toplevel;
 20433             int target_proto, motif_style;
 20434             xm_top_level_leave_message lmsg;
 20435             xm_top_level_enter_message emsg;
 20436             xm_drag_motion_message dmsg;
 20437             XRectangle *r;
 20438             bool was_frame;
 20439 
 20440             /* Always clear mouse face.  */
 20441             clear_mouse_face (hlinfo);
 20442             hlinfo->mouse_face_hidden = true;
 20443 
 20444             /* Sometimes the drag-and-drop operation starts with the
 20445                pointer of a frame invisible due to input.  Since
 20446                motion events are ignored during that, make the pointer
 20447                visible manually.  */
 20448 
 20449             if (f)
 20450               {
 20451                 XTtoggle_invisible_pointer (f, false);
 20452 
 20453                 r = &dpyinfo->last_mouse_glyph;
 20454 
 20455                 /* Also remember the mouse glyph and set
 20456                    mouse_moved.  */
 20457                 if (f != dpyinfo->last_mouse_glyph_frame
 20458                     || event->xmotion.x < r->x
 20459                     || event->xmotion.x >= r->x + r->width
 20460                     || event->xmotion.y < r->y
 20461                     || event->xmotion.y >= r->y + r->height)
 20462                   {
 20463                     f->mouse_moved = true;
 20464                     f->last_mouse_device = Qnil;
 20465                     dpyinfo->last_mouse_scroll_bar = NULL;
 20466 
 20467                     remember_mouse_glyph (f, event->xmotion.x,
 20468                                           event->xmotion.y, r);
 20469                     dpyinfo->last_mouse_glyph_frame = f;
 20470                   }
 20471               }
 20472 
 20473             if (event->xmotion.same_screen)
 20474               target = x_dnd_get_target_window (dpyinfo,
 20475                                                 event->xmotion.x_root,
 20476                                                 event->xmotion.y_root,
 20477                                                 &target_proto,
 20478                                                 &motif_style, &toplevel,
 20479                                                 &was_frame);
 20480             else
 20481               target = x_dnd_fill_empty_target (&target_proto, &motif_style,
 20482                                                 &toplevel, &was_frame);
 20483 
 20484             if (toplevel != x_dnd_last_seen_toplevel)
 20485               {
 20486                 if (toplevel != FRAME_OUTER_WINDOW (x_dnd_frame)
 20487                     && x_dnd_return_frame == 1)
 20488                   x_dnd_return_frame = 2;
 20489 
 20490                 if (x_dnd_return_frame == 2
 20491                     && x_any_window_to_frame (dpyinfo, toplevel))
 20492                   {
 20493                     if (x_dnd_last_seen_window != None
 20494                         && x_dnd_last_protocol_version != -1
 20495                         && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 20496                       x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window,
 20497                                         x_dnd_last_seen_toplevel);
 20498                     else if (x_dnd_last_seen_window != None
 20499                              && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)
 20500                              && !x_dnd_disable_motif_drag
 20501                              && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 20502                       {
 20503                         if (!x_dnd_motif_setup_p)
 20504                           xm_setup_drag_info (dpyinfo, x_dnd_frame);
 20505 
 20506                         lmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 20507                                                       XM_DRAG_REASON_TOP_LEVEL_LEAVE);
 20508                         lmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 20509                         lmsg.zero = 0;
 20510                         lmsg.timestamp = event->xmotion.time;
 20511                         lmsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 20512 
 20513                         if (x_dnd_motif_setup_p)
 20514                           xm_send_top_level_leave_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 20515                                                            x_dnd_last_seen_window, &lmsg);
 20516                       }
 20517 
 20518                     x_dnd_end_window = x_dnd_last_seen_window;
 20519                     x_dnd_last_seen_window = None;
 20520                     x_dnd_last_seen_toplevel = None;
 20521                     x_dnd_in_progress = false;
 20522                     x_dnd_return_frame_object
 20523                       = x_any_window_to_frame (dpyinfo, toplevel);
 20524                     x_dnd_return_frame = 3;
 20525                     x_dnd_waiting_for_finish = false;
 20526                     target = None;
 20527                   }
 20528               }
 20529 
 20530             if (target != x_dnd_last_seen_window)
 20531               {
 20532                 if (x_dnd_last_seen_window != None
 20533                     && x_dnd_last_protocol_version != -1
 20534                     && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 20535                   x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window,
 20536                                     x_dnd_last_seen_toplevel);
 20537                 else if (x_dnd_last_seen_window != None
 20538                          && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)
 20539                          && x_dnd_disable_motif_drag
 20540                          && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 20541                   {
 20542                     if (!x_dnd_motif_setup_p)
 20543                       xm_setup_drag_info (dpyinfo, x_dnd_frame);
 20544 
 20545                     /* This is apparently required.  If we don't send
 20546                        a motion event with the current root window
 20547                        coordinates of the pointer before the top level
 20548                        leave, then Motif displays an ugly black border
 20549                        around the previous drop site.  */
 20550 
 20551                     dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 20552                                                   XM_DRAG_REASON_DRAG_MOTION);
 20553                     dmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 20554                     dmsg.side_effects = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo,
 20555                                                                                          x_dnd_wanted_action),
 20556                                                              XM_DROP_SITE_NONE, x_dnd_motif_operations,
 20557                                                              XM_DROP_ACTION_DROP_CANCEL);
 20558                     dmsg.timestamp = event->xmotion.time;
 20559                     dmsg.x = event->xmotion.x_root;
 20560                     dmsg.y = event->xmotion.y_root;
 20561 
 20562                     lmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 20563                                                   XM_DRAG_REASON_TOP_LEVEL_LEAVE);
 20564                     lmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 20565                     lmsg.zero = 0;
 20566                     lmsg.timestamp = event->xbutton.time;
 20567                     lmsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 20568 
 20569                     if (x_dnd_motif_setup_p)
 20570                       {
 20571                         xm_send_drag_motion_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 20572                                                      x_dnd_last_seen_window, &dmsg);
 20573                         xm_send_top_level_leave_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 20574                                                          x_dnd_last_seen_window, &lmsg);
 20575                       }
 20576                   }
 20577 
 20578                 x_dnd_action = None;
 20579                 x_dnd_last_seen_toplevel = toplevel;
 20580                 x_dnd_last_seen_window = target;
 20581                 x_dnd_last_protocol_version = target_proto;
 20582                 x_dnd_last_motif_style = motif_style;
 20583                 x_dnd_last_window_is_frame = was_frame;
 20584 
 20585                 if (target != None && x_dnd_last_protocol_version != -1)
 20586                   x_dnd_send_enter (x_dnd_frame, target,
 20587                                     x_dnd_last_seen_toplevel,
 20588                                     x_dnd_last_protocol_version);
 20589                 else if (target != None && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)
 20590                          && !x_dnd_disable_motif_drag)
 20591                   {
 20592                     if (!x_dnd_motif_setup_p)
 20593                       xm_setup_drag_info (dpyinfo, x_dnd_frame);
 20594 
 20595                     emsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 20596                                                   XM_DRAG_REASON_TOP_LEVEL_ENTER);
 20597                     emsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 20598                     emsg.zero = 0;
 20599                     emsg.timestamp = event->xbutton.time;
 20600                     emsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 20601                     emsg.index_atom = x_dnd_motif_atom;
 20602 
 20603                     if (x_dnd_motif_setup_p)
 20604                       xm_send_top_level_enter_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 20605                                                        target, &emsg);
 20606                   }
 20607               }
 20608             else
 20609               x_dnd_last_seen_toplevel = toplevel;
 20610 
 20611             if (x_dnd_last_window_is_frame && target != None)
 20612               x_dnd_note_self_position (dpyinfo, target,
 20613                                         event->xbutton.x_root,
 20614                                         event->xbutton.y_root);
 20615             else if (x_dnd_last_protocol_version != -1 && target != None)
 20616               x_dnd_send_position (x_dnd_frame, target,
 20617                                    x_dnd_last_seen_toplevel,
 20618                                    x_dnd_last_protocol_version,
 20619                                    event->xmotion.x_root,
 20620                                    event->xmotion.y_root,
 20621                                    x_dnd_selection_timestamp,
 20622                                    x_dnd_wanted_action, 0,
 20623                                    event->xmotion.state);
 20624             else if (XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) && target != None
 20625                      && !x_dnd_disable_motif_drag)
 20626               {
 20627                 if (!x_dnd_motif_setup_p)
 20628                   xm_setup_drag_info (dpyinfo, x_dnd_frame);
 20629 
 20630                 dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 20631                                               XM_DRAG_REASON_DRAG_MOTION);
 20632                 dmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 20633                 dmsg.side_effects = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo,
 20634                                                                                      x_dnd_wanted_action),
 20635                                                          XM_DROP_SITE_VALID, x_dnd_motif_operations,
 20636                                                          (!x_dnd_xm_use_help
 20637                                                           ? XM_DROP_ACTION_DROP
 20638                                                           : XM_DROP_ACTION_DROP_HELP));
 20639                 dmsg.timestamp = event->xbutton.time;
 20640                 dmsg.x = event->xmotion.x_root;
 20641                 dmsg.y = event->xmotion.y_root;
 20642 
 20643                 if (x_dnd_motif_setup_p)
 20644                   xm_send_drag_motion_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 20645                                                target, &dmsg);
 20646               }
 20647 
 20648             x_dnd_update_tooltip_position (event->xmotion.x_root,
 20649                                            event->xmotion.y_root);
 20650 
 20651             goto OTHER;
 20652           }
 20653 
 20654 #ifdef USE_GTK
 20655         if (f && xg_event_is_for_scrollbar (f, event, false))
 20656           f = 0;
 20657 #endif
 20658 #ifdef HAVE_XWIDGETS
 20659         struct xwidget_view *xvw;
 20660 
 20661         xvw = xwidget_view_from_window (event->xmotion.window);
 20662 
 20663         if (xvw)
 20664           xwidget_motion_or_crossing (xvw, event);
 20665 #endif
 20666         if (f)
 20667           {
 20668             /* Maybe generate a SELECT_WINDOW_EVENT for
 20669                `mouse-autoselect-window' but don't let popup menus
 20670                interfere with this (Bug#1261).  */
 20671             if (!NILP (Vmouse_autoselect_window)
 20672                 && !popup_activated ()
 20673                 /* Don't switch if we're currently in the minibuffer.
 20674                    This tries to work around problems where the
 20675                    minibuffer gets unselected unexpectedly, and where
 20676                    you then have to move your mouse all the way down to
 20677                    the minibuffer to select it.  */
 20678                 && !MINI_WINDOW_P (XWINDOW (selected_window))
 20679                 /* With `focus-follows-mouse' non-nil create an event
 20680                    also when the target window is on another frame.  */
 20681                 && (f == XFRAME (selected_frame)
 20682                     || !NILP (focus_follows_mouse)))
 20683               {
 20684                 static Lisp_Object last_mouse_window;
 20685 
 20686                 if (xmotion.window != FRAME_X_WINDOW (f))
 20687                   {
 20688                     x_translate_coordinates (f, xmotion.x_root, xmotion.y_root,
 20689                                              &xmotion.x, &xmotion.y);
 20690                     xmotion.window = FRAME_X_WINDOW (f);
 20691                   }
 20692 
 20693                 Lisp_Object window = window_from_coordinates
 20694                   (f, xmotion.x, xmotion.y, 0, false, false);
 20695 
 20696                 /* A window will be autoselected only when it is not
 20697                    selected now and the last mouse movement event was
 20698                    not in it.  The remainder of the code is a bit vague
 20699                    wrt what a "window" is.  For immediate autoselection,
 20700                    the window is usually the entire window but for GTK
 20701                    where the scroll bars don't count.  For delayed
 20702                    autoselection the window is usually the window's text
 20703                    area including the margins.  */
 20704                 if (WINDOWP (window)
 20705                     && !EQ (window, last_mouse_window)
 20706                     && !EQ (window, selected_window))
 20707                   {
 20708                     inev.ie.kind = SELECT_WINDOW_EVENT;
 20709                     inev.ie.frame_or_window = window;
 20710                   }
 20711 
 20712                 /* Remember the last window where we saw the mouse.  */
 20713                 last_mouse_window = window;
 20714               }
 20715 
 20716             if (!x_note_mouse_movement (f, &xmotion, Qnil))
 20717               help_echo_string = previous_help_echo_string;
 20718           }
 20719         else
 20720           {
 20721 #ifndef USE_TOOLKIT_SCROLL_BARS
 20722             struct scroll_bar *bar
 20723               = x_window_to_scroll_bar (event->xmotion.display,
 20724                                         event->xmotion.window, 2);
 20725 
 20726             if (bar)
 20727               x_scroll_bar_note_movement (bar, &event->xmotion);
 20728 #endif /* USE_TOOLKIT_SCROLL_BARS */
 20729 
 20730             /* If we move outside the frame, then we're
 20731                certainly no longer on any text in the frame.  */
 20732             clear_mouse_face (hlinfo);
 20733           }
 20734 
 20735         /* If the contents of the global variable help_echo_string
 20736            has changed, generate a HELP_EVENT.  */
 20737         if (!NILP (help_echo_string)
 20738             || !NILP (previous_help_echo_string))
 20739           do_help = 1;
 20740 
 20741         if (f)
 20742           x_flush_dirty_back_buffer_on (f);
 20743         goto OTHER;
 20744       }
 20745 
 20746     case ConfigureNotify:
 20747       /* An opaque move can generate a stream of events as the window
 20748          is dragged around.  If the connection round trip time isn't
 20749          really short, they may come faster than we can respond to
 20750          them, given the multiple queries we can do to check window
 20751          manager state, translate coordinates, etc.
 20752 
 20753          So if this ConfigureNotify is immediately followed by another
 20754          for the same window, use the info from the latest update, and
 20755          consider the events all handled.  */
 20756 
 20757       /* Opaque resize may be trickier; ConfigureNotify events are
 20758          mixed with Expose events for multiple windows.  */
 20759       configureEvent = *event;
 20760       while (XPending (dpyinfo->display))
 20761         {
 20762           XNextEvent (dpyinfo->display, &next_event);
 20763           if (next_event.type != ConfigureNotify
 20764               || next_event.xconfigure.window != event->xconfigure.window
 20765               /* Skipping events with different sizes can lead to a
 20766                  mispositioned mode line at initial window creation.
 20767                  Only drop window motion events for now.  */
 20768               || next_event.xconfigure.width != event->xconfigure.width
 20769               || next_event.xconfigure.height != event->xconfigure.height)
 20770             {
 20771               XPutBackEvent (dpyinfo->display, &next_event);
 20772               break;
 20773             }
 20774           else
 20775             configureEvent = next_event;
 20776         }
 20777 
 20778       /* If we get a ConfigureNotify for the root window, this means
 20779          the dimensions of the screen it's on changed.  */
 20780 
 20781       if (configureEvent.xconfigure.window == dpyinfo->root_window)
 20782         {
 20783 #ifdef HAVE_XRANDR
 20784           /* This function is OK to call even if the X server doesn't
 20785              support RandR.  */
 20786           XRRUpdateConfiguration (&configureEvent);
 20787 #elif !defined USE_GTK
 20788           /* Catch screen size changes even if RandR is not available
 20789              on the client.  GTK does this internally.  */
 20790 
 20791           if (configureEvent.xconfigure.width != dpyinfo->screen_width
 20792               || configureEvent.xconfigure.height != dpyinfo->screen_height)
 20793             {
 20794               /* Also avoid storing duplicate events here, since
 20795                  Fx_display_monitor_attributes_list will return the
 20796                  same information for both invocations of the
 20797                  hook.  */
 20798               if (!x_find_monitors_changed_event (dpyinfo))
 20799                 {
 20800                   inev.ie.kind = MONITORS_CHANGED_EVENT;
 20801                   XSETTERMINAL (inev.ie.arg, dpyinfo->terminal);
 20802 
 20803                   /* Store this event now since inev.ie.type could be set to
 20804                      MOVE_FRAME_EVENT later.  */
 20805                   kbd_buffer_store_event (&inev.ie);
 20806                   inev.ie.kind = NO_EVENT;
 20807                 }
 20808 
 20809               /* Also update the position of the drag-and-drop
 20810                  tooltip.  */
 20811               x_dnd_update_tooltip_now ();
 20812             }
 20813 #endif
 20814 
 20815           dpyinfo->screen_width = configureEvent.xconfigure.width;
 20816           dpyinfo->screen_height = configureEvent.xconfigure.height;
 20817         }
 20818 
 20819       if (x_dnd_in_progress && x_dnd_use_toplevels
 20820           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 20821         {
 20822           int rc, dest_x, dest_y;
 20823           Window child;
 20824           struct x_client_list_window *tem, *last = NULL;
 20825 
 20826           for (tem = x_dnd_toplevels; tem; last = tem, tem = tem->next)
 20827             {
 20828               /* Not completely right, since the parent could be
 20829                  unmapped, but good enough.  */
 20830 
 20831               if (tem->window == configureEvent.xconfigure.window)
 20832                 {
 20833                   x_catch_errors (dpyinfo->display);
 20834                   rc = (XTranslateCoordinates (dpyinfo->display,
 20835                                                configureEvent.xconfigure.window,
 20836                                                dpyinfo->root_window,
 20837                                                -configureEvent.xconfigure.border_width,
 20838                                                -configureEvent.xconfigure.border_width,
 20839                                                &dest_x, &dest_y, &child)
 20840                         && !x_had_errors_p (dpyinfo->display));
 20841                   x_uncatch_errors_after_check ();
 20842 
 20843                   if (rc)
 20844                     {
 20845                       tem->x = dest_x;
 20846                       tem->y = dest_y;
 20847                       tem->width = (configureEvent.xconfigure.width
 20848                                     + configureEvent.xconfigure.border_width);
 20849                       tem->height = (configureEvent.xconfigure.height
 20850                                      + configureEvent.xconfigure.border_width);
 20851                     }
 20852                   else
 20853                     {
 20854                       /* The window was probably destroyed, so get rid
 20855                          of it.  */
 20856 
 20857                       if (!last)
 20858                         x_dnd_toplevels = tem->next;
 20859                       else
 20860                         last->next = tem->next;
 20861 
 20862 #ifdef HAVE_XSHAPE
 20863                       if (tem->n_input_rects != -1)
 20864                         xfree (tem->input_rects);
 20865                       if (tem->n_bounding_rects != -1)
 20866                         xfree (tem->bounding_rects);
 20867 #endif
 20868                       xfree (tem);
 20869                     }
 20870 
 20871                   break;
 20872                 }
 20873             }
 20874         }
 20875 
 20876 #if defined HAVE_GTK3 && defined USE_TOOLKIT_SCROLL_BARS
 20877           struct scroll_bar *bar = x_window_to_scroll_bar (dpyinfo->display,
 20878                                                            configureEvent.xconfigure.window, 2);
 20879 
 20880           /* There is really no other way to make GTK scroll bars fit
 20881              in the dimensions we want them to.  */
 20882           if (bar)
 20883             {
 20884               /* Skip all the pending configure events, not just the
 20885                  ones where window motion occurred.  */
 20886               while (XPending (dpyinfo->display))
 20887                 {
 20888                   XNextEvent (dpyinfo->display, &next_event);
 20889                   if (next_event.type != ConfigureNotify
 20890                       || next_event.xconfigure.window != event->xconfigure.window)
 20891                     {
 20892                       XPutBackEvent (dpyinfo->display, &next_event);
 20893                       break;
 20894                     }
 20895                   else
 20896                     configureEvent = next_event;
 20897                 }
 20898 
 20899               if (configureEvent.xconfigure.width != max (bar->width, 1)
 20900                   || configureEvent.xconfigure.height != max (bar->height, 1))
 20901                 {
 20902                   XResizeWindow (dpyinfo->display, bar->x_window,
 20903                                  max (bar->width, 1), max (bar->height, 1));
 20904                   x_flush (WINDOW_XFRAME (XWINDOW (bar->window)));
 20905                 }
 20906 
 20907 #ifdef HAVE_XDBE
 20908               if (f && FRAME_X_DOUBLE_BUFFERED_P (f))
 20909                 x_drop_xrender_surfaces (f);
 20910 #endif
 20911 
 20912               goto OTHER;
 20913             }
 20914 #endif
 20915 
 20916       f = x_top_window_to_frame (dpyinfo, configureEvent.xconfigure.window);
 20917 
 20918       /* This means we can no longer be certain of the root window
 20919          coordinates of any's edit window.  */
 20920       if (any)
 20921         FRAME_X_OUTPUT (any)->window_offset_certain_p = false;
 20922 
 20923       /* Unfortunately, we need to call x_drop_xrender_surfaces for
 20924          _all_ ConfigureNotify events, otherwise we miss some and
 20925          flicker.  Don't try to optimize these calls by looking only
 20926          for size changes: that's not sufficient.  We miss some
 20927          surface invalidations and flicker.  */
 20928 #ifdef HAVE_XDBE
 20929       if (f && FRAME_X_DOUBLE_BUFFERED_P (f))
 20930         x_drop_xrender_surfaces (f);
 20931 #endif
 20932 #if defined USE_CAIRO && !defined USE_GTK
 20933       if (f)
 20934         x_cr_update_surface_desired_size (f, configureEvent.xconfigure.width,
 20935                                           configureEvent.xconfigure.height);
 20936       else if (any && configureEvent.xconfigure.window == FRAME_X_WINDOW (any))
 20937         x_cr_update_surface_desired_size (any,
 20938                                           configureEvent.xconfigure.width,
 20939                                           configureEvent.xconfigure.height);
 20940       if (f || (any && configureEvent.xconfigure.window == FRAME_X_WINDOW (any)))
 20941         x_update_opaque_region (f ? f : any, &configureEvent);
 20942 #endif
 20943 #ifdef USE_GTK
 20944       if (!f
 20945           && (f = any)
 20946           && configureEvent.xconfigure.window == FRAME_X_WINDOW (f)
 20947           && (FRAME_VISIBLE_P(f)
 20948               || !(configureEvent.xconfigure.width <= 1
 20949                    && configureEvent.xconfigure.height <= 1)))
 20950         {
 20951 
 20952           if (CONSP (frame_size_history))
 20953             frame_size_history_extra
 20954               (f, build_string ("ConfigureNotify"),
 20955                FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
 20956                configureEvent.xconfigure.width,
 20957                configureEvent.xconfigure.height,
 20958                f->new_width, f->new_height);
 20959 
 20960 #ifdef HAVE_XDBE
 20961           if (FRAME_X_DOUBLE_BUFFERED_P (f))
 20962             x_drop_xrender_surfaces (f);
 20963 #endif
 20964           xg_frame_resized (f, configureEvent.xconfigure.width,
 20965                             configureEvent.xconfigure.height);
 20966 #ifdef USE_CAIRO
 20967           x_cr_update_surface_desired_size (f, configureEvent.xconfigure.width,
 20968                                             configureEvent.xconfigure.height);
 20969 #endif
 20970           x_update_opaque_region (f, &configureEvent);
 20971           f = 0;
 20972         }
 20973 #endif
 20974       if (f
 20975           && (FRAME_VISIBLE_P(f)
 20976               || !(configureEvent.xconfigure.width <= 1
 20977                    && configureEvent.xconfigure.height <= 1)))
 20978         {
 20979 #ifdef USE_GTK
 20980           /* For GTK+ don't call x_net_wm_state for the scroll bar
 20981              window.  (Bug#24963, Bug#25887) */
 20982           if (configureEvent.xconfigure.window == FRAME_X_WINDOW (f))
 20983 #endif
 20984             x_net_wm_state (f, configureEvent.xconfigure.window);
 20985 
 20986 #if defined USE_X_TOOLKIT || defined USE_GTK
 20987           /* Tip frames are pure X window, set size for them.  */
 20988           if (FRAME_TOOLTIP_P (f))
 20989             {
 20990               if (FRAME_PIXEL_HEIGHT (f) != configureEvent.xconfigure.height
 20991                   || FRAME_PIXEL_WIDTH (f) != configureEvent.xconfigure.width)
 20992                 SET_FRAME_GARBAGED (f);
 20993 
 20994               FRAME_PIXEL_HEIGHT (f) = configureEvent.xconfigure.height;
 20995               FRAME_PIXEL_WIDTH (f) = configureEvent.xconfigure.width;
 20996             }
 20997 #endif
 20998 
 20999 #ifndef USE_X_TOOLKIT
 21000 #ifndef USE_GTK
 21001           int width = configureEvent.xconfigure.width;
 21002           int height = configureEvent.xconfigure.height;
 21003 
 21004           if (CONSP (frame_size_history))
 21005             frame_size_history_extra
 21006               (f, build_string ("ConfigureNotify"),
 21007                FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
 21008                width, height, f->new_width, f->new_height);
 21009 
 21010           /* In the toolkit version, change_frame_size
 21011              is called by the code that handles resizing
 21012              of the EmacsFrame widget.  */
 21013 
 21014           /* Even if the number of character rows and columns has
 21015              not changed, the font size may have changed, so we need
 21016              to check the pixel dimensions as well.  */
 21017 
 21018           if (width != FRAME_PIXEL_WIDTH (f)
 21019               || height != FRAME_PIXEL_HEIGHT (f)
 21020               || (f->new_size_p
 21021                   && ((f->new_width >= 0 && width != f->new_width)
 21022                       || (f->new_height >= 0 && height != f->new_height))))
 21023             {
 21024               change_frame_size (f, width, height, false, true, false);
 21025               x_clear_under_internal_border (f);
 21026               SET_FRAME_GARBAGED (f);
 21027               cancel_mouse_face (f);
 21028             }
 21029 #endif /* not USE_GTK */
 21030 #endif
 21031 
 21032 #ifdef USE_GTK
 21033           /* GTK creates windows but doesn't map them.
 21034              Only get real positions when mapped.  */
 21035           if (FRAME_GTK_OUTER_WIDGET (f)
 21036               && gtk_widget_get_mapped (FRAME_GTK_OUTER_WIDGET (f)))
 21037 #endif
 21038             {
 21039               int old_left = f->left_pos;
 21040               int old_top = f->top_pos;
 21041               Lisp_Object frame;
 21042 
 21043               XSETFRAME (frame, f);
 21044 
 21045               if (!FRAME_PARENT_FRAME (f))
 21046                 x_real_positions (f, &f->left_pos, &f->top_pos);
 21047               else
 21048                 {
 21049                   Window root;
 21050                   unsigned int dummy_uint;
 21051 
 21052                   XGetGeometry (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 21053                                 &root, &f->left_pos, &f->top_pos,
 21054                                 &dummy_uint, &dummy_uint, &dummy_uint, &dummy_uint);
 21055                 }
 21056 
 21057               if (!FRAME_TOOLTIP_P (f)
 21058                   && (old_left != f->left_pos || old_top != f->top_pos))
 21059                 {
 21060                   inev.ie.kind = MOVE_FRAME_EVENT;
 21061                   XSETFRAME (inev.ie.frame_or_window, f);
 21062                 }
 21063             }
 21064 
 21065 
 21066 #ifdef HAVE_X_I18N
 21067           if (f)
 21068             {
 21069               if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea))
 21070                 xic_set_statusarea (f);
 21071 
 21072               struct window *w = XWINDOW (f->selected_window);
 21073               xic_set_preeditarea (w, w->cursor.x, w->cursor.y);
 21074             }
 21075 #endif
 21076 
 21077 #ifdef HAVE_XINPUT2
 21078           if (f && dpyinfo->supports_xi2)
 21079             {
 21080               Mouse_HLInfo *hlinfo;
 21081 
 21082               /* The input extension doesn't report motion events when
 21083                  the part of the window below the pointer changes.  To
 21084                  avoid outdated information from keeping
 21085                  i.e. mouse-highlight at the wrong position after the
 21086                  frame is moved or resized, reset the mouse highlight
 21087                  and last_mouse_motion_frame.  */
 21088 
 21089               if (dpyinfo->last_mouse_motion_frame == f)
 21090                 dpyinfo->last_mouse_motion_frame = NULL;
 21091 
 21092               hlinfo = MOUSE_HL_INFO (f);
 21093 
 21094               if (hlinfo->mouse_face_mouse_frame == f)
 21095                 reset_mouse_highlight (hlinfo);
 21096             }
 21097 #endif
 21098 
 21099         }
 21100 
 21101       if (x_dnd_in_progress
 21102           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 21103         x_dnd_update_state (dpyinfo, dpyinfo->last_user_time);
 21104       goto OTHER;
 21105 
 21106     case ButtonRelease:
 21107     case ButtonPress:
 21108       {
 21109         if (event->xbutton.type == ButtonPress)
 21110           x_display_set_last_user_time (dpyinfo, event->xbutton.time,
 21111                                         event->xbutton.send_event, true);
 21112 
 21113 #ifdef HAVE_XWIDGETS
 21114         struct xwidget_view *xvw;
 21115 
 21116         xvw = xwidget_view_from_window (event->xbutton.window);
 21117 
 21118         if (xvw)
 21119           {
 21120             xwidget_button (xvw, event->type == ButtonPress,
 21121                             event->xbutton.x, event->xbutton.y,
 21122                             event->xbutton.button, event->xbutton.state,
 21123                             event->xbutton.time);
 21124 
 21125             if (!EQ (selected_window, xvw->w) && (event->xbutton.button < 4))
 21126               {
 21127                 inev.ie.kind = SELECT_WINDOW_EVENT;
 21128                 inev.ie.frame_or_window = xvw->w;
 21129               }
 21130 
 21131             *finish = X_EVENT_DROP;
 21132             goto OTHER;
 21133           }
 21134 #endif
 21135         /* If we decide we want to generate an event to be seen
 21136            by the rest of Emacs, we put it here.  */
 21137         Lisp_Object tab_bar_arg = Qnil;
 21138         bool tab_bar_p = false;
 21139         bool tool_bar_p = false;
 21140         bool dnd_grab = false;
 21141 
 21142         if (x_dnd_in_progress
 21143             /* Handle these events normally if the recursion
 21144                level is higher than when the drag-and-drop
 21145                operation was initiated.  This is so that mouse
 21146                input works while we're in the debugger for, say,
 21147                `x-dnd-movement-function`.  */
 21148             && (command_loop_level + minibuf_level
 21149                 <= x_dnd_recursion_depth)
 21150             && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 21151           {
 21152             f = mouse_or_wdesc_frame (dpyinfo, event->xbutton.window);
 21153 
 21154             if (f && event->xbutton.window == FRAME_X_WINDOW (f))
 21155               /* See the comment above x_compute_root_window_offset
 21156                  for why this optimization is performed.  */
 21157               x_compute_root_window_offset (f, event->xbutton.x_root,
 21158                                             event->xbutton.y_root,
 21159                                             event->xbutton.x,
 21160                                             event->xbutton.y);
 21161 
 21162             if (event->type == ButtonPress)
 21163               {
 21164                 x_display_set_last_user_time (dpyinfo, event->xbutton.time,
 21165                                               event->xbutton.send_event, true);
 21166 
 21167                 dpyinfo->grabbed |= (1 << event->xbutton.button);
 21168                 dpyinfo->last_mouse_frame = f;
 21169 
 21170                 if (f)
 21171                   f->last_tab_bar_item = -1;
 21172 #if ! defined (USE_GTK)
 21173                 if (f)
 21174                   f->last_tool_bar_item = -1;
 21175 #endif /* not USE_GTK */
 21176               }
 21177             else
 21178               dpyinfo->grabbed &= ~(1 << event->xbutton.button);
 21179 
 21180             if (event->xbutton.type == ButtonPress
 21181                 && x_dnd_last_seen_window != None)
 21182               {
 21183                 if (x_dnd_last_window_is_frame)
 21184                   x_dnd_note_self_wheel (dpyinfo,
 21185                                          x_dnd_last_seen_window,
 21186                                          event->xbutton.x_root,
 21187                                          event->xbutton.y_root,
 21188                                          event->xbutton.button,
 21189                                          event->xbutton.state,
 21190                                          event->xbutton.time);
 21191                 else if (x_dnd_last_protocol_version != -1)
 21192                   x_dnd_send_position (x_dnd_frame,
 21193                                        x_dnd_last_seen_window,
 21194                                        x_dnd_last_seen_toplevel,
 21195                                        x_dnd_last_protocol_version,
 21196                                        event->xbutton.x_root,
 21197                                        event->xbutton.y_root,
 21198                                        event->xbutton.time,
 21199                                        x_dnd_wanted_action,
 21200                                        event->xbutton.button,
 21201                                        event->xbutton.state);
 21202 
 21203                 goto OTHER;
 21204               }
 21205 
 21206             if (event->xbutton.type == ButtonRelease)
 21207               {
 21208                 for (int i = 1; i < 8; ++i)
 21209                   {
 21210                     if (i != event->xbutton.button
 21211                         && event->xbutton.state & (Button1Mask << (i - 1)))
 21212                       dnd_grab = true;
 21213                   }
 21214 
 21215                 if (!dnd_grab)
 21216                   {
 21217                     x_dnd_end_window = x_dnd_last_seen_window;
 21218                     x_dnd_in_progress = false;
 21219 
 21220                     if (x_dnd_update_tooltip
 21221                         && FRAMEP (tip_frame)
 21222                         && FRAME_LIVE_P (XFRAME (tip_frame))
 21223                         && (FRAME_X_DISPLAY (XFRAME (tip_frame))
 21224                             == FRAME_X_DISPLAY (x_dnd_frame)))
 21225                       Fx_hide_tip ();
 21226 
 21227                     x_dnd_finish_frame = x_dnd_frame;
 21228 
 21229                     if (x_dnd_last_seen_window != None
 21230                         && x_dnd_last_window_is_frame)
 21231                       {
 21232                         x_dnd_waiting_for_finish = false;
 21233                         x_dnd_note_self_drop (dpyinfo,
 21234                                               x_dnd_last_seen_window,
 21235                                               event->xbutton.x_root,
 21236                                               event->xbutton.y_root,
 21237                                               event->xbutton.time);
 21238                       }
 21239                     else if (x_dnd_last_seen_window != None
 21240                              && x_dnd_last_protocol_version != -1)
 21241                       {
 21242                         x_dnd_pending_finish_target = x_dnd_last_seen_toplevel;
 21243                         x_dnd_waiting_for_finish_proto = x_dnd_last_protocol_version;
 21244 
 21245                         x_dnd_waiting_for_finish
 21246                           = x_dnd_do_drop (x_dnd_last_seen_window,
 21247                                            x_dnd_last_seen_toplevel,
 21248                                            x_dnd_last_protocol_version);
 21249                         x_dnd_finish_display = dpyinfo->display;
 21250                       }
 21251                     else if (x_dnd_last_seen_window != None)
 21252                       {
 21253                         xm_drop_start_message dmsg;
 21254                         xm_drag_receiver_info drag_receiver_info;
 21255 
 21256                         if (!xm_read_drag_receiver_info (dpyinfo, x_dnd_last_seen_window,
 21257                                                          &drag_receiver_info)
 21258                             && !x_dnd_disable_motif_protocol
 21259                             && drag_receiver_info.protocol_style != XM_DRAG_STYLE_NONE
 21260                             && (x_dnd_allow_current_frame
 21261                                 || x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame)))
 21262                           {
 21263                             if (!x_dnd_motif_setup_p)
 21264                               xm_setup_drag_info (dpyinfo, x_dnd_frame);
 21265 
 21266                             if (x_dnd_motif_setup_p)
 21267                               {
 21268                                 memset (&dmsg, 0, sizeof dmsg);
 21269 
 21270                                 dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 21271                                                               XM_DRAG_REASON_DROP_START);
 21272                                 dmsg.byte_order = XM_BYTE_ORDER_CUR_FIRST;
 21273                                 dmsg.side_effects
 21274                                   = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo,
 21275                                                                                      x_dnd_wanted_action),
 21276                                                          XM_DROP_SITE_VALID, x_dnd_motif_operations,
 21277                                                          (!x_dnd_xm_use_help
 21278                                                           ? XM_DROP_ACTION_DROP
 21279                                                           : XM_DROP_ACTION_DROP_HELP));
 21280                                 dmsg.timestamp = event->xbutton.time;
 21281                                 dmsg.x = event->xbutton.x_root;
 21282                                 dmsg.y = event->xbutton.y_root;
 21283                                 dmsg.index_atom = x_dnd_motif_atom;
 21284                                 dmsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 21285 
 21286                                 if (!XM_DRAG_STYLE_IS_DROP_ONLY (drag_receiver_info.protocol_style))
 21287                                   x_dnd_send_xm_leave_for_drop (FRAME_DISPLAY_INFO (x_dnd_frame),
 21288                                                                 x_dnd_frame, x_dnd_last_seen_window,
 21289                                                                 event->xbutton.time);
 21290 
 21291                                 xm_send_drop_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 21292                                                       x_dnd_last_seen_window, &dmsg);
 21293 
 21294                                 x_dnd_waiting_for_finish = true;
 21295                                 x_dnd_waiting_for_motif_finish_display = dpyinfo;
 21296                                 x_dnd_waiting_for_motif_finish = 1;
 21297                                 x_dnd_finish_display = dpyinfo->display;
 21298                               }
 21299                           }
 21300                         else
 21301                           x_dnd_send_unsupported_drop (dpyinfo, (x_dnd_last_seen_toplevel != None
 21302                                                                  ? x_dnd_last_seen_toplevel
 21303                                                                  : x_dnd_last_seen_window),
 21304                                                        event->xbutton.x_root, event->xbutton.y_root,
 21305                                                        event->xbutton.time);
 21306                       }
 21307                     else if (x_dnd_last_seen_toplevel != None)
 21308                       x_dnd_send_unsupported_drop (dpyinfo, x_dnd_last_seen_toplevel,
 21309                                                    event->xbutton.x_root,
 21310                                                    event->xbutton.y_root,
 21311                                                    event->xbutton.time);
 21312 
 21313 
 21314                     x_dnd_last_protocol_version = -1;
 21315                     x_dnd_last_motif_style = XM_DRAG_STYLE_NONE;
 21316                     x_dnd_last_seen_window = None;
 21317                     x_dnd_last_seen_toplevel = None;
 21318                     x_dnd_last_window_is_frame = false;
 21319                     x_dnd_frame = NULL;
 21320                   }
 21321               }
 21322 
 21323             goto OTHER;
 21324           }
 21325 
 21326         if (x_dnd_in_progress
 21327             && (command_loop_level + minibuf_level
 21328                 <= x_dnd_recursion_depth))
 21329           goto OTHER;
 21330 
 21331         memset (&compose_status, 0, sizeof (compose_status));
 21332         dpyinfo->last_mouse_glyph_frame = NULL;
 21333 
 21334         f = mouse_or_wdesc_frame (dpyinfo, event->xbutton.window);
 21335 
 21336         if (f && event->xbutton.window == FRAME_X_WINDOW (f))
 21337           /* See the comment above x_compute_root_window_offset
 21338              for why this optimization is performed.  */
 21339           x_compute_root_window_offset (f, event->xbutton.x_root,
 21340                                         event->xbutton.y_root,
 21341                                         event->xbutton.x,
 21342                                         event->xbutton.y);
 21343 
 21344         if (f && event->xbutton.type == ButtonPress
 21345             && !popup_activated ()
 21346             && !x_window_to_scroll_bar (event->xbutton.display,
 21347                                         event->xbutton.window, 2)
 21348             && !FRAME_NO_ACCEPT_FOCUS (f))
 21349           {
 21350             /* When clicking into a child frame or when clicking
 21351                into a parent frame with the child frame selected and
 21352                `no-accept-focus' is not set, select the clicked
 21353                frame.  */
 21354             struct frame *hf = dpyinfo->highlight_frame;
 21355 
 21356             if (FRAME_PARENT_FRAME (f) || (hf && frame_ancestor_p (f, hf)))
 21357               {
 21358                 x_ignore_errors_for_next_request (dpyinfo);
 21359                 XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 21360                                 RevertToParent, event->xbutton.time);
 21361                 x_stop_ignoring_errors (dpyinfo);
 21362 
 21363                 if (FRAME_PARENT_FRAME (f))
 21364                   XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f));
 21365               }
 21366           }
 21367 
 21368 #ifdef USE_GTK
 21369         if (!f)
 21370           {
 21371             f = x_any_window_to_frame (dpyinfo, event->xbutton.window);
 21372 
 21373             if (event->xbutton.button > 3
 21374                 && event->xbutton.button < 8
 21375                 && f)
 21376               {
 21377                 if (ignore_next_mouse_click_timeout
 21378                     && dpyinfo == mouse_click_timeout_display)
 21379                   {
 21380                     if (event->type == ButtonPress
 21381                         && event->xbutton.time > ignore_next_mouse_click_timeout)
 21382                       {
 21383                         ignore_next_mouse_click_timeout = 0;
 21384                         x_construct_mouse_click (&inev.ie, &event->xbutton, f);
 21385                       }
 21386                     if (event->type == ButtonRelease)
 21387                       ignore_next_mouse_click_timeout = 0;
 21388                   }
 21389                 else
 21390                   x_construct_mouse_click (&inev.ie, &event->xbutton, f);
 21391 
 21392                 *finish = X_EVENT_DROP;
 21393                 goto OTHER;
 21394               }
 21395             else
 21396               f = NULL;
 21397           }
 21398 
 21399         if (f && xg_event_is_for_scrollbar (f, event, false))
 21400           f = 0;
 21401 #endif
 21402         if (f)
 21403           {
 21404             /* Is this in the tab-bar?  */
 21405             if (WINDOWP (f->tab_bar_window)
 21406                 && WINDOW_TOTAL_LINES (XWINDOW (f->tab_bar_window)))
 21407               {
 21408                 Lisp_Object window;
 21409                 int x = event->xbutton.x;
 21410                 int y = event->xbutton.y;
 21411 
 21412                 window = window_from_coordinates (f, x, y, 0, true, true);
 21413                 tab_bar_p = EQ (window, f->tab_bar_window);
 21414 
 21415                 if (tab_bar_p)
 21416                   {
 21417                     tab_bar_arg = handle_tab_bar_click
 21418                       (f, x, y, event->xbutton.type == ButtonPress,
 21419                        x_x_to_emacs_modifiers (dpyinfo, event->xbutton.state));
 21420                     x_flush_dirty_back_buffer_on (f);
 21421                   }
 21422               }
 21423 
 21424 #if ! defined (USE_GTK)
 21425             /* Is this in the tool-bar?  */
 21426             if (WINDOWP (f->tool_bar_window)
 21427                 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)))
 21428               {
 21429                 Lisp_Object window;
 21430                 int x = event->xbutton.x;
 21431                 int y = event->xbutton.y;
 21432 
 21433                 window = window_from_coordinates (f, x, y, 0, true, true);
 21434                 tool_bar_p = (EQ (window, f->tool_bar_window)
 21435                               && (event->xbutton.type != ButtonRelease
 21436                                   || f->last_tool_bar_item != -1));
 21437 
 21438                 if (tool_bar_p && event->xbutton.button < 4)
 21439                   {
 21440                     handle_tool_bar_click
 21441                       (f, x, y, event->xbutton.type == ButtonPress,
 21442                        x_x_to_emacs_modifiers (dpyinfo, event->xbutton.state));
 21443                     x_flush_dirty_back_buffer_on (f);
 21444                   }
 21445               }
 21446 #endif /* !USE_GTK */
 21447 
 21448             if (!(tab_bar_p && NILP (tab_bar_arg)) && !tool_bar_p)
 21449 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
 21450               if (! popup_activated ())
 21451 #endif
 21452                 {
 21453                   if (ignore_next_mouse_click_timeout
 21454                       && dpyinfo == mouse_click_timeout_display)
 21455                     {
 21456                       if (event->type == ButtonPress
 21457                           && event->xbutton.time > ignore_next_mouse_click_timeout)
 21458                         {
 21459                           ignore_next_mouse_click_timeout = 0;
 21460                           x_construct_mouse_click (&inev.ie, &event->xbutton, f);
 21461                         }
 21462                       if (event->type == ButtonRelease)
 21463                         ignore_next_mouse_click_timeout = 0;
 21464                     }
 21465                   else
 21466                     x_construct_mouse_click (&inev.ie, &event->xbutton, f);
 21467 
 21468                   if (!NILP (tab_bar_arg))
 21469                     inev.ie.arg = tab_bar_arg;
 21470                 }
 21471 
 21472             if (FRAME_X_EMBEDDED_P (f)
 21473                 && !FRAME_NO_ACCEPT_FOCUS (f))
 21474               xembed_send_message (f, event->xbutton.time,
 21475                                    XEMBED_REQUEST_FOCUS, 0, 0, 0);
 21476           }
 21477         else
 21478           {
 21479             struct scroll_bar *bar
 21480               = x_window_to_scroll_bar (event->xbutton.display,
 21481                                         event->xbutton.window, 2);
 21482 
 21483 #ifdef USE_TOOLKIT_SCROLL_BARS
 21484             /* Make the "Ctrl-Mouse-2 splits window" work for toolkit
 21485                scroll bars.  */
 21486             if (bar && event->xbutton.state & ControlMask)
 21487               {
 21488                 x_scroll_bar_handle_click (bar, event, &inev.ie, Qnil);
 21489                 *finish = X_EVENT_DROP;
 21490               }
 21491 #else /* not USE_TOOLKIT_SCROLL_BARS */
 21492             if (bar)
 21493               x_scroll_bar_handle_click (bar, event, &inev.ie, Qnil);
 21494 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 21495           }
 21496 
 21497         if (event->type == ButtonPress)
 21498           {
 21499             dpyinfo->grabbed |= (1 << event->xbutton.button);
 21500             dpyinfo->last_mouse_frame = f;
 21501             if (f && !tab_bar_p)
 21502               f->last_tab_bar_item = -1;
 21503 #if ! defined (USE_GTK)
 21504             if (f && !tool_bar_p)
 21505               f->last_tool_bar_item = -1;
 21506 #endif /* not USE_GTK */
 21507           }
 21508         else
 21509           dpyinfo->grabbed &= ~(1 << event->xbutton.button);
 21510 
 21511         /* Ignore any mouse motion that happened before this event;
 21512            any subsequent mouse-movement Emacs events should reflect
 21513            only motion after the ButtonPress/Release.  */
 21514         if (f != 0)
 21515           f->mouse_moved = false;
 21516 
 21517 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
 21518         f = x_menubar_window_to_frame (dpyinfo, event);
 21519         /* For a down-event in the menu bar, don't pass it to Xt or
 21520            GTK right away.  Instead, save it and pass it to Xt or GTK
 21521            from kbd_buffer_get_event.  That way, we can run some Lisp
 21522            code first.  */
 21523         if (! popup_activated ()
 21524 #ifdef USE_GTK
 21525             /* Gtk+ menus only react to the first three buttons. */
 21526             && event->xbutton.button < 3
 21527 #endif
 21528             && f && event->type == ButtonPress
 21529             /* Verify the event is really within the menu bar
 21530                and not just sent to it due to grabbing.  */
 21531             && event->xbutton.x >= 0
 21532             && event->xbutton.x < FRAME_PIXEL_WIDTH (f)
 21533             && event->xbutton.y >= 0
 21534             && event->xbutton.y < FRAME_MENUBAR_HEIGHT (f)
 21535             && event->xbutton.same_screen)
 21536           {
 21537 #ifdef USE_MOTIF
 21538             Widget widget;
 21539 
 21540             widget = XtWindowToWidget (dpyinfo->display,
 21541                                        event->xbutton.window);
 21542 
 21543             if (widget && XmIsCascadeButton (widget)
 21544                 && XtIsSensitive (widget))
 21545               {
 21546 #endif
 21547                 if (!f->output_data.x->saved_menu_event)
 21548                   f->output_data.x->saved_menu_event = xmalloc (sizeof *event);
 21549                 *f->output_data.x->saved_menu_event = *event;
 21550                 inev.ie.kind = MENU_BAR_ACTIVATE_EVENT;
 21551                 XSETFRAME (inev.ie.frame_or_window, f);
 21552                 *finish = X_EVENT_DROP;
 21553 #ifdef USE_MOTIF
 21554               }
 21555 #endif
 21556           }
 21557         else
 21558           goto OTHER;
 21559 #endif /* USE_X_TOOLKIT || USE_GTK */
 21560       }
 21561       break;
 21562 
 21563     case CirculateNotify:
 21564       if (x_dnd_in_progress
 21565           /* When _NET_WM_CLIENT_LIST stacking is being used, changes
 21566              in that property are watched for, and it's not necessary
 21567              to update the state in response to ordinary window
 21568              substructure events.  */
 21569           && !x_dnd_use_toplevels
 21570           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 21571         x_dnd_update_state (dpyinfo, dpyinfo->last_user_time);
 21572       goto OTHER;
 21573 
 21574     case CirculateRequest:
 21575       goto OTHER;
 21576 
 21577     case VisibilityNotify:
 21578       f = x_top_window_to_frame (dpyinfo, event->xvisibility.window);
 21579       if (f && (event->xvisibility.state == VisibilityUnobscured
 21580                 || event->xvisibility.state == VisibilityPartiallyObscured))
 21581         SET_FRAME_VISIBLE (f, 1);
 21582 
 21583       goto OTHER;
 21584 
 21585     case MappingNotify:
 21586       /* Someone has changed the keyboard mapping - update the
 21587          local cache.  */
 21588       switch (event->xmapping.request)
 21589         {
 21590         case MappingModifier:
 21591           x_find_modifier_meanings (dpyinfo);
 21592           FALLTHROUGH;
 21593         case MappingKeyboard:
 21594           XRefreshKeyboardMapping ((XMappingEvent *) &event->xmapping);
 21595         }
 21596       goto OTHER;
 21597 
 21598     case DestroyNotify:
 21599       if (event->xdestroywindow.window
 21600           == dpyinfo->net_supported_window)
 21601         dpyinfo->net_supported_window = None;
 21602 
 21603       if (event->xdestroywindow.window
 21604           == dpyinfo->motif_drag_window)
 21605         /* We get DestroyNotify events for the drag window because
 21606            x_special_window_exists_p selects for structure
 21607            notification.  The drag window is not supposed to go away
 21608            but not all clients obey that requirement when setting the
 21609            drag window property.  */
 21610         dpyinfo->motif_drag_window = None;
 21611 
 21612       xft_settings_event (dpyinfo, event);
 21613       break;
 21614 
 21615 #ifdef HAVE_XINPUT2
 21616     case GenericEvent:
 21617       {
 21618         if (!dpyinfo->supports_xi2)
 21619           goto OTHER;
 21620 
 21621         if (event->xgeneric.extension != dpyinfo->xi2_opcode)
 21622           /* Not an XI2 event. */
 21623           goto OTHER;
 21624 
 21625         bool must_free_data = false;
 21626         XIEvent *xi_event = (XIEvent *) event->xcookie.data;
 21627 
 21628         /* Sometimes the event is already claimed by GTK, which
 21629            will free its data in due course. */
 21630         if (!xi_event)
 21631           {
 21632             if (XGetEventData (dpyinfo->display, &event->xcookie))
 21633               must_free_data = true;
 21634 
 21635             xi_event = (XIEvent *) event->xcookie.data;
 21636           }
 21637 
 21638         XIDeviceEvent *xev = (XIDeviceEvent *) xi_event;
 21639 
 21640         if (!xi_event)
 21641           {
 21642             /* It may turn out that the event data has already been
 21643                implicitly freed for various reasons up to and
 21644                including XMenuActivate pushing some other event onto
 21645                the foreign-event queue, or x_menu_wait_for_events
 21646                calling XNextEvent through a timer that tries to wait
 21647                for input.
 21648 
 21649                In that case, XGetEventData will return True, but
 21650                cookie->data will be NULL.  Since handling such input
 21651                events is not really important, we can afford to
 21652                discard them.
 21653 
 21654                The way Xlib is currently implemented makes calling
 21655                XFreeEventData unnecessary in this case, but call it
 21656                anyway, since not doing so may lead to a memory leak in
 21657                the future.  */
 21658 
 21659             if (must_free_data)
 21660               XFreeEventData (dpyinfo->display, &event->xcookie);
 21661             goto OTHER;
 21662           }
 21663 
 21664         switch (event->xcookie.evtype)
 21665           {
 21666           case XI_FocusIn:
 21667             {
 21668               XIFocusInEvent *focusin;
 21669 
 21670               focusin = (XIFocusInEvent *) xi_event;
 21671               any = x_any_window_to_frame (dpyinfo, focusin->event);
 21672 
 21673 #ifdef USE_GTK
 21674               /* Some WMs (e.g. Mutter in Gnome Shell), don't unmap
 21675                  minimized/iconified windows; thus, for those WMs we won't get
 21676                  a MapNotify when unminimizing/deiconifying.  Check here if we
 21677                  are deiconizing a window (Bug42655).
 21678 
 21679                  But don't do that by default on GTK since it may cause a plain
 21680                  invisible frame get reported as iconified, compare
 21681                  https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html.
 21682                  That is fixed above but bites us here again.
 21683 
 21684                  The option x_set_frame_visibility_more_laxly allows to override
 21685                  the default behavior (Bug#49955, Bug#53298).  */
 21686               if (EQ (x_set_frame_visibility_more_laxly, Qfocus_in)
 21687                   || EQ (x_set_frame_visibility_more_laxly, Qt))
 21688 #endif /* USE_GTK */
 21689                 {
 21690                   f = any;
 21691                   if (f && FRAME_ICONIFIED_P (f))
 21692                     {
 21693                       SET_FRAME_VISIBLE (f, 1);
 21694                       SET_FRAME_ICONIFIED (f, false);
 21695                       f->output_data.x->has_been_visible = true;
 21696                       inev.ie.kind = DEICONIFY_EVENT;
 21697                       XSETFRAME (inev.ie.frame_or_window, f);
 21698                     }
 21699                 }
 21700 
 21701               xi_focus_handle_for_device (dpyinfo, any, xi_event);
 21702 
 21703               goto XI_OTHER;
 21704             }
 21705 
 21706           case XI_FocusOut:
 21707             {
 21708               XIFocusOutEvent *focusout;
 21709 
 21710               focusout = (XIFocusOutEvent *) xi_event;
 21711               any = x_any_window_to_frame (dpyinfo, focusout->event);
 21712               xi_focus_handle_for_device (dpyinfo, any, xi_event);
 21713 
 21714               goto XI_OTHER;
 21715             }
 21716 
 21717           case XI_Enter:
 21718             {
 21719               XIEnterEvent *enter = (XIEnterEvent *) xi_event;
 21720               XMotionEvent ev;
 21721               struct xi_device_t *source;
 21722 
 21723               any = x_top_window_to_frame (dpyinfo, enter->event);
 21724               source = xi_device_from_id (dpyinfo, enter->sourceid);
 21725 
 21726               ev.x = lrint (enter->event_x);
 21727               ev.y = lrint (enter->event_y);
 21728               ev.window = enter->event;
 21729               ev.time = enter->time;
 21730               ev.send_event = enter->send_event;
 21731 
 21732               x_display_set_last_user_time (dpyinfo, enter->time,
 21733                                             enter->send_event, false);
 21734 
 21735 #ifdef USE_MOTIF
 21736               use_copy = true;
 21737 
 21738               copy.xcrossing.type = EnterNotify;
 21739               copy.xcrossing.serial = enter->serial;
 21740               copy.xcrossing.send_event = enter->send_event;
 21741               copy.xcrossing.display = dpyinfo->display;
 21742               copy.xcrossing.window = enter->event;
 21743               copy.xcrossing.root = enter->root;
 21744               copy.xcrossing.subwindow = enter->child;
 21745               copy.xcrossing.time = enter->time;
 21746               copy.xcrossing.x = lrint (enter->event_x);
 21747               copy.xcrossing.y = lrint (enter->event_y);
 21748               copy.xcrossing.x_root = lrint (enter->root_x);
 21749               copy.xcrossing.y_root = lrint (enter->root_y);
 21750               copy.xcrossing.mode = enter->mode;
 21751               copy.xcrossing.detail = enter->detail;
 21752               copy.xcrossing.focus = enter->focus;
 21753               copy.xcrossing.state = 0;
 21754               copy.xcrossing.same_screen = True;
 21755 #endif
 21756 
 21757               /* There is no need to handle entry/exit events for
 21758                  passive focus from non-top windows at all, since they
 21759                  are an inferiors of the frame's top window, which will
 21760                  get virtual events.  */
 21761               if (any)
 21762                 xi_focus_handle_for_device (dpyinfo, any, xi_event);
 21763 
 21764               if (!any)
 21765                 any = x_any_window_to_frame (dpyinfo, enter->event);
 21766 
 21767 #ifdef HAVE_XINPUT2_1
 21768               /* xfwm4 selects for button events on the frame window,
 21769                  resulting in passive grabs being generated along with
 21770                  the delivery of emulated button events; this then
 21771                  interferes with scrolling, since device valuators
 21772                  will constantly be reset as the crossing events
 21773                  related to those grabs arrive.  The only way to
 21774                  remedy this is to never reset scroll valuators on a
 21775                  grab-related crossing event.  (bug#57476) */
 21776 
 21777               if (enter->mode != XINotifyUngrab
 21778                   && enter->mode != XINotifyGrab
 21779                   && enter->mode != XINotifyPassiveGrab
 21780                   && enter->mode != XINotifyPassiveUngrab)
 21781                 xi_reset_scroll_valuators_for_device_id (dpyinfo,
 21782                                                          enter->deviceid);
 21783 #endif
 21784 
 21785               {
 21786 #ifdef HAVE_XWIDGETS
 21787                 struct xwidget_view *xwidget_view;
 21788 
 21789                 xwidget_view = xwidget_view_from_window (enter->event);
 21790 
 21791                 if (xwidget_view)
 21792                   {
 21793                     xwidget_motion_or_crossing (xwidget_view, event);
 21794 
 21795                     goto XI_OTHER;
 21796                   }
 21797 #endif
 21798               }
 21799 
 21800               f = any;
 21801 
 21802               if (f && enter->event == FRAME_X_WINDOW (f))
 21803                 xi_compute_root_window_offset_enter (f, enter);
 21804 
 21805               if (f && x_mouse_click_focus_ignore_position)
 21806                 {
 21807                   ignore_next_mouse_click_timeout = (enter->time
 21808                                                      + x_mouse_click_focus_ignore_time);
 21809                   mouse_click_timeout_display = dpyinfo;
 21810                 }
 21811 
 21812               /* EnterNotify counts as mouse movement,
 21813                  so update things that depend on mouse position.  */
 21814               if (f && !f->output_data.x->hourglass_p)
 21815                 x_note_mouse_movement (f, &ev, source ? source->name : Qnil);
 21816 #ifdef USE_GTK
 21817               /* We may get an EnterNotify on the buttons in the toolbar.  In that
 21818                  case we moved out of any highlighted area and need to note this.  */
 21819               if (!f && dpyinfo->last_mouse_glyph_frame)
 21820                 x_note_mouse_movement (dpyinfo->last_mouse_glyph_frame, &ev,
 21821                                        source ? source->name : Qnil);
 21822 #endif
 21823               goto XI_OTHER;
 21824             }
 21825 
 21826           case XI_Leave:
 21827             {
 21828               XILeaveEvent *leave;
 21829               struct xi_device_t *device;
 21830 
 21831               leave = (XILeaveEvent *) xi_event;
 21832 #ifdef USE_GTK
 21833               struct xi_device_t *source;
 21834               XMotionEvent ev;
 21835 
 21836               ev.x = lrint (leave->event_x);
 21837               ev.y = lrint (leave->event_y);
 21838               ev.window = leave->event;
 21839               ev.time = leave->time;
 21840               ev.send_event = leave->send_event;
 21841 #endif
 21842 
 21843               any = x_top_window_to_frame (dpyinfo, leave->event);
 21844 
 21845 #ifdef USE_GTK
 21846               source = xi_device_from_id (dpyinfo, leave->sourceid);
 21847 #endif
 21848               device = xi_device_from_id (dpyinfo, leave->deviceid);
 21849 
 21850               if (device)
 21851                 xi_report_motion_window_clear (device);
 21852 
 21853               /* This allows us to catch LeaveNotify events generated by
 21854                  popup menu grabs.  FIXME: this is right when there is a
 21855                  focus menu, but implicit focus tracking can get screwed
 21856                  up if we get this and no XI_Enter event later.   */
 21857 
 21858 #ifdef USE_X_TOOLKIT
 21859               if (popup_activated ()
 21860                   && (leave->mode == XINotifyPassiveUngrab
 21861                       || leave->mode == XINotifyUngrab))
 21862                 any = x_any_window_to_frame (dpyinfo, leave->event);
 21863 #endif
 21864 
 21865 #ifdef USE_MOTIF
 21866               use_copy = true;
 21867 
 21868               copy.xcrossing.type = LeaveNotify;
 21869               copy.xcrossing.serial = leave->serial;
 21870               copy.xcrossing.send_event = leave->send_event;
 21871               copy.xcrossing.display = dpyinfo->display;
 21872               copy.xcrossing.window = leave->event;
 21873               copy.xcrossing.root = leave->root;
 21874               copy.xcrossing.subwindow = leave->child;
 21875               copy.xcrossing.time = leave->time;
 21876               copy.xcrossing.x = lrint (leave->event_x);
 21877               copy.xcrossing.y = lrint (leave->event_y);
 21878               copy.xcrossing.x_root = lrint (leave->root_x);
 21879               copy.xcrossing.y_root = lrint (leave->root_y);
 21880               copy.xcrossing.mode = leave->mode;
 21881               copy.xcrossing.detail = leave->detail;
 21882               copy.xcrossing.focus = leave->focus;
 21883               copy.xcrossing.state = 0;
 21884               copy.xcrossing.same_screen = True;
 21885 #endif
 21886 
 21887               /* One problem behind the design of XInput 2 scrolling is
 21888                  that valuators are not unique to each window, but only
 21889                  the window that has grabbed the valuator's device or
 21890                  the window that the device's pointer is on top of can
 21891                  receive motion events.  There is also no way to
 21892                  retrieve the value of a valuator outside of each motion
 21893                  event.
 21894 
 21895                  As such, to prevent wildly inaccurate results when
 21896                  the valuators have changed outside Emacs, we reset
 21897                  our records of each valuator's value whenever the
 21898                  pointer moves out of a frame.  Ideally, this would
 21899                  ignore events with a detail of XINotifyInferior, as
 21900                  the window the pointer moved to would be one known to
 21901                  Emacs, but the code to keep track of which valuators
 21902                  had to be reset upon the corresponding XI_Enter event
 21903                  was very complicated and kept running into server
 21904                  bugs.  */
 21905 #ifdef HAVE_XINPUT2_1
 21906               /* xfwm4 selects for button events on the frame window,
 21907                  resulting in passive grabs being generated along with
 21908                  the delivery of emulated button events; this then
 21909                  interferes with scrolling, since device valuators
 21910                  will constantly be reset as the crossing events
 21911                  related to those grabs arrive.  The only way to
 21912                  remedy this is to never reset scroll valuators on a
 21913                  grab-related crossing event.  (bug#57476) */
 21914 
 21915               if (leave->mode != XINotifyUngrab
 21916                   && leave->mode != XINotifyGrab
 21917                   && leave->mode != XINotifyPassiveUngrab
 21918                   && leave->mode != XINotifyPassiveGrab)
 21919                 xi_reset_scroll_valuators_for_device_id (dpyinfo,
 21920                                                          leave->deviceid);
 21921 #endif
 21922 
 21923               x_display_set_last_user_time (dpyinfo, leave->time,
 21924                                             leave->send_event, false);
 21925 
 21926 #ifdef HAVE_XWIDGETS
 21927               {
 21928                 struct xwidget_view *xvw;
 21929 
 21930                 xvw = xwidget_view_from_window (leave->event);
 21931 
 21932                 if (xvw)
 21933                   {
 21934                     *finish = X_EVENT_DROP;
 21935                     xwidget_motion_or_crossing (xvw, event);
 21936 
 21937                     goto XI_OTHER;
 21938                   }
 21939               }
 21940 #endif
 21941 
 21942               if (any)
 21943                 xi_focus_handle_for_device (dpyinfo, any, xi_event);
 21944 
 21945 #ifndef USE_X_TOOLKIT
 21946               f = x_top_window_to_frame (dpyinfo, leave->event);
 21947 #else
 21948               /* On Xt builds that have XI2, the enter and leave event
 21949                  masks are set on the frame widget's window.  */
 21950               f = x_window_to_frame (dpyinfo, leave->event);
 21951 
 21952               if (!f)
 21953                 f = x_top_window_to_frame (dpyinfo, leave->event);
 21954 #endif
 21955 
 21956               if (f)
 21957                 {
 21958                   /* Now clear dpyinfo->last_mouse_motion_frame, or
 21959                      gui_redo_mouse_highlight will end up highlighting
 21960                      the last known position of the mouse if a
 21961                      tooltip frame is later unmapped.  */
 21962 
 21963                   if (f == dpyinfo->last_mouse_motion_frame)
 21964                     dpyinfo->last_mouse_motion_frame = NULL;
 21965 
 21966                   /* Something similar applies to
 21967                      dpyinfo->last_mouse_glyph_frame.  */
 21968                   if (f == dpyinfo->last_mouse_glyph_frame)
 21969                     dpyinfo->last_mouse_glyph_frame = NULL;
 21970 
 21971                   if (f == hlinfo->mouse_face_mouse_frame)
 21972                     {
 21973                       /* If we move outside the frame, then we're
 21974                          certainly no longer on any text in the frame.  */
 21975                       clear_mouse_face (hlinfo);
 21976                       hlinfo->mouse_face_mouse_frame = 0;
 21977                       x_flush_dirty_back_buffer_on (f);
 21978                     }
 21979 
 21980                   /* Generate a nil HELP_EVENT to cancel a help-echo.
 21981                      Do it only if there's something to cancel.
 21982                      Otherwise, the startup message is cleared when
 21983                      the mouse leaves the frame.  */
 21984                   if (any_help_event_p
 21985                       /* But never if `mouse-drag-and-drop-region' is
 21986                          in progress, since that results in the
 21987                          tooltip being dismissed when the mouse moves
 21988                          on top.  */
 21989                       && !((EQ (track_mouse, Qdrag_source)
 21990                             || EQ (track_mouse, Qdropping))
 21991                            && gui_mouse_grabbed (dpyinfo)))
 21992                     do_help = -1;
 21993 
 21994                   if (f && leave->event == FRAME_X_WINDOW (f))
 21995                     xi_compute_root_window_offset_enter (f, leave);
 21996                 }
 21997 #ifdef USE_GTK
 21998               /* See comment in EnterNotify above */
 21999               else if (dpyinfo->last_mouse_glyph_frame)
 22000                 x_note_mouse_movement (dpyinfo->last_mouse_glyph_frame, &ev,
 22001                                        source ? source->name : Qnil);
 22002 #endif
 22003               goto XI_OTHER;
 22004             }
 22005 
 22006           case XI_Motion:
 22007             {
 22008               struct xi_device_t *device, *source;
 22009 #ifdef HAVE_XINPUT2_1
 22010               XIValuatorState *states;
 22011               double *values;
 22012               bool found_valuator = false;
 22013               bool other_valuators_found = false;
 22014 #endif
 22015               /* A fake XMotionEvent for x_note_mouse_movement. */
 22016               XMotionEvent ev;
 22017               xm_top_level_leave_message lmsg;
 22018               xm_top_level_enter_message emsg;
 22019               xm_drag_motion_message dmsg;
 22020               unsigned int dnd_state;
 22021 
 22022               source = xi_device_from_id (dpyinfo, xev->sourceid);
 22023 
 22024 #ifdef HAVE_XINPUT2_1
 22025               states = &xev->valuators;
 22026               values = states->values;
 22027 #endif
 22028 
 22029               device = xi_device_from_id (dpyinfo, xev->deviceid);
 22030 
 22031               if (!device)
 22032                 goto XI_OTHER;
 22033 
 22034 #ifdef HAVE_XINPUT2_2
 22035               if (xev->flags & XIPointerEmulated)
 22036                 goto XI_OTHER;
 22037 #endif
 22038 
 22039 #ifdef HAVE_XINPUT2_1
 22040 #ifdef HAVE_XWIDGETS
 22041               struct xwidget_view *xv = xwidget_view_from_window (xev->event);
 22042               double xv_total_x = 0.0;
 22043               double xv_total_y = 0.0;
 22044 #endif
 22045               double total_x = 0.0;
 22046               double total_y = 0.0;
 22047 
 22048               int real_x, real_y;
 22049 
 22050               for (int i = 0; i < states->mask_len * 8; i++)
 22051                 {
 22052                   if (XIMaskIsSet (states->mask, i))
 22053                     {
 22054                       struct xi_scroll_valuator_t *val;
 22055                       double delta, scroll_unit;
 22056                       int scroll_height;
 22057                       Lisp_Object window;
 22058                       struct scroll_bar *bar;
 22059 
 22060                       bar = NULL;
 22061 
 22062                       /* See the comment on top of x_cache_xi_devices
 22063                          for more details on how scroll wheel movement
 22064                          is reported on XInput 2.  */
 22065                       delta = x_get_scroll_valuator_delta (dpyinfo, device,
 22066                                                            i, *values, &val);
 22067                       values++;
 22068 
 22069                       if (!val)
 22070                         {
 22071                           other_valuators_found = true;
 22072                           continue;
 22073                         }
 22074 
 22075                       if (delta != DBL_MAX)
 22076                         {
 22077                           if (!f)
 22078                             {
 22079                               f = x_any_window_to_frame (dpyinfo, xev->event);
 22080 
 22081                               if (!f)
 22082                                 {
 22083 #if defined USE_MOTIF || !defined USE_TOOLKIT_SCROLL_BARS
 22084                                   bar = x_window_to_scroll_bar (dpyinfo->display,
 22085                                                                 xev->event, 2);
 22086 
 22087                                   if (bar)
 22088                                     f = WINDOW_XFRAME (XWINDOW (bar->window));
 22089 
 22090                                   if (!f)
 22091 #endif
 22092                                     goto XI_OTHER;
 22093                                 }
 22094                             }
 22095 
 22096 #ifdef USE_GTK
 22097                           if (f && xg_event_is_for_scrollbar (f, event, true))
 22098                             *finish = X_EVENT_DROP;
 22099 #endif
 22100 
 22101                           if (FRAME_X_WINDOW (f) != xev->event)
 22102                             {
 22103                               if (!bar)
 22104                                 bar = x_window_to_scroll_bar (dpyinfo->display, xev->event, 2);
 22105 
 22106                               /* If this is a scroll bar, compute the
 22107                                  actual position directly to avoid an
 22108                                  extra roundtrip.  */
 22109 
 22110                               if (bar)
 22111                                 {
 22112                                   real_x = lrint (xev->event_x + bar->left);
 22113                                   real_y = lrint (xev->event_y + bar->top);
 22114                                 }
 22115                               else
 22116                                 x_translate_coordinates (f,
 22117                                                          lrint (xev->root_x),
 22118                                                          lrint (xev->root_y),
 22119                                                          &real_x, &real_y);
 22120                             }
 22121                           else
 22122                             {
 22123                               real_x = lrint (xev->event_x);
 22124                               real_y = lrint (xev->event_y);
 22125                             }
 22126 
 22127 #ifdef HAVE_XWIDGETS
 22128                           if (xv)
 22129                             {
 22130                               if (val->horizontal)
 22131                                 xv_total_x += delta;
 22132                               else
 22133                                 xv_total_y += delta;
 22134 
 22135                               found_valuator = true;
 22136                               continue;
 22137                             }
 22138 #endif
 22139 
 22140                           if (delta == 0.0)
 22141                             found_valuator = true;
 22142 
 22143                           if (signbit (delta) != signbit (val->emacs_value))
 22144                             val->emacs_value = 0;
 22145 
 22146                           val->emacs_value += delta;
 22147 
 22148                           if (mwheel_coalesce_scroll_events
 22149                               && (fabs (val->emacs_value) < 1)
 22150                               && (fabs (delta) > 0))
 22151                             continue;
 22152 
 22153                           window = window_from_coordinates (f, real_x, real_y, NULL,
 22154                                                             false, false);
 22155 
 22156                           if (WINDOWP (window))
 22157                             scroll_height = XWINDOW (window)->pixel_height;
 22158                           else
 22159                             /* EVENT_X and EVENT_Y can be outside the
 22160                                frame if F holds the input grab, so fall
 22161                                back to the height of the frame instead.  */
 22162                             scroll_height = FRAME_PIXEL_HEIGHT (f);
 22163 
 22164                           scroll_unit = pow (scroll_height, 2.0 / 3.0);
 22165 
 22166                           if (NUMBERP (Vx_scroll_event_delta_factor))
 22167                             scroll_unit *= XFLOATINT (Vx_scroll_event_delta_factor);
 22168 
 22169                           if (val->horizontal)
 22170                             total_x += val->emacs_value * scroll_unit;
 22171                           else
 22172                             total_y += val->emacs_value * scroll_unit;
 22173 
 22174                           found_valuator = true;
 22175                           val->emacs_value = 0;
 22176                         }
 22177                     }
 22178                 }
 22179 
 22180 #ifdef HAVE_XWIDGETS
 22181               if (xv)
 22182                 {
 22183                   unsigned int state;
 22184 
 22185                   state = xi_convert_event_state (xev);
 22186                   x_display_set_last_user_time (dpyinfo, xev->time,
 22187                                                 xev->send_event, true);
 22188 
 22189                   if (found_valuator)
 22190                     xwidget_scroll (xv, xev->event_x, xev->event_y,
 22191                                     -xv_total_x, -xv_total_y, state,
 22192                                     xev->time, (xv_total_x == 0.0
 22193                                                 && xv_total_y == 0.0));
 22194                   else
 22195                     xwidget_motion_notify (xv, xev->event_x, xev->event_y,
 22196                                            xev->root_x, xev->root_y, state,
 22197                                            xev->time);
 22198 
 22199                   goto XI_OTHER;
 22200                 }
 22201               else
 22202                 {
 22203 #endif
 22204                   if (found_valuator)
 22205                     {
 22206                       x_display_set_last_user_time (dpyinfo, xev->time,
 22207                                                     xev->send_event, true);
 22208 
 22209 
 22210 #if defined USE_GTK && !defined HAVE_GTK3
 22211                       /* Unlike on Motif, we can't select for XI
 22212                          events on the scroll bar window under GTK+ 2.
 22213                          So instead of that, just ignore XI wheel
 22214                          events which land on a scroll bar.
 22215 
 22216                          Here we assume anything which isn't the edit
 22217                          widget window is a scroll bar.  */
 22218 
 22219                       if (xev->child != None
 22220                           && xev->child != FRAME_X_WINDOW (f))
 22221                         goto XI_OTHER;
 22222 #endif
 22223 
 22224                       /* If this happened during a drag-and-drop
 22225                          operation, don't send an event.  We only have
 22226                          to set the user time.  */
 22227                       if (x_dnd_in_progress
 22228                           /* If another master device moved the
 22229                              pointer, we should put a wheel event on
 22230                              the keyboard buffer as usual.  It will be
 22231                              run once the drag-and-drop operation
 22232                              completes.  */
 22233                           && xev->deviceid == x_dnd_pointer_device
 22234                           && (command_loop_level + minibuf_level
 22235                               <= x_dnd_recursion_depth)
 22236                           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 22237                         goto XI_OTHER;
 22238 
 22239                       if (fabs (total_x) > 0 || fabs (total_y) > 0)
 22240                         {
 22241                           inev.ie.kind = (fabs (total_y) >= fabs (total_x)
 22242                                           ? WHEEL_EVENT : HORIZ_WHEEL_EVENT);
 22243                           inev.ie.timestamp = xev->time;
 22244 
 22245                           XSETINT (inev.ie.x, lrint (real_x));
 22246                           XSETINT (inev.ie.y, lrint (real_y));
 22247                           XSETFRAME (inev.ie.frame_or_window, f);
 22248 
 22249                           inev.ie.modifiers = (signbit (fabs (total_y) >= fabs (total_x)
 22250                                                         ? total_y : total_x)
 22251                                                ? down_modifier : up_modifier);
 22252                           inev.ie.modifiers
 22253                             |= x_x_to_emacs_modifiers (dpyinfo,
 22254                                                        xev->mods.effective);
 22255                           inev.ie.arg = list3 (Qnil,
 22256                                                make_float (total_x),
 22257                                                make_float (total_y));
 22258                         }
 22259                       else
 22260                         {
 22261                           inev.ie.kind = TOUCH_END_EVENT;
 22262                           inev.ie.timestamp = xev->time;
 22263 
 22264                           XSETINT (inev.ie.x, lrint (real_x));
 22265                           XSETINT (inev.ie.y, lrint (real_y));
 22266                           XSETFRAME (inev.ie.frame_or_window, f);
 22267                         }
 22268 
 22269                       if (source && !NILP (source->name))
 22270                         inev.ie.device = source->name;
 22271 
 22272                       if (!other_valuators_found)
 22273                         goto XI_OTHER;
 22274                     }
 22275 #ifdef HAVE_XWIDGETS
 22276                 }
 22277 #endif
 22278 #endif /* HAVE_XINPUT2_1 */
 22279 
 22280               if (!xi_position_changed (device, xev))
 22281                 goto XI_OTHER;
 22282 
 22283               ev.x = lrint (xev->event_x);
 22284               ev.y = lrint (xev->event_y);
 22285               ev.window = xev->event;
 22286               ev.time = xev->time;
 22287               ev.send_event = xev->send_event;
 22288 
 22289 #ifdef USE_MOTIF
 22290               use_copy = true;
 22291 
 22292               copy.xmotion.type = MotionNotify;
 22293               copy.xmotion.serial = xev->serial;
 22294               copy.xmotion.send_event = xev->send_event;
 22295               copy.xmotion.display = dpyinfo->display;
 22296               copy.xmotion.window = xev->event;
 22297               copy.xmotion.root = xev->root;
 22298               copy.xmotion.subwindow = xev->child;
 22299               copy.xmotion.time = xev->time;
 22300               copy.xmotion.x = lrint (xev->event_x);
 22301               copy.xmotion.y = lrint (xev->event_y);
 22302               copy.xmotion.x_root = lrint (xev->root_x);
 22303               copy.xmotion.y_root = lrint (xev->root_y);
 22304               copy.xmotion.state = xi_convert_event_state (xev);
 22305 
 22306               copy.xmotion.is_hint = False;
 22307               copy.xmotion.same_screen = True;
 22308 #endif
 22309 
 22310               previous_help_echo_string = help_echo_string;
 22311               help_echo_string = Qnil;
 22312 
 22313               if (hlinfo->mouse_face_hidden)
 22314                 {
 22315                   hlinfo->mouse_face_hidden = false;
 22316                   clear_mouse_face (hlinfo);
 22317                 }
 22318 
 22319               f = mouse_or_wdesc_frame (dpyinfo, xev->event);
 22320 
 22321               if (f && xev->event == FRAME_X_WINDOW (f))
 22322                 /* See the comment above x_compute_root_window_offset
 22323                    for why this optimization is performed.  */
 22324                 xi_compute_root_window_offset (f, xev);
 22325 
 22326               if (x_dnd_in_progress
 22327                   /* Handle these events normally if the recursion
 22328                      level is higher than when the drag-and-drop
 22329                      operation was initiated.  This is so that mouse
 22330                      input works while we're in the debugger for, say,
 22331                      `x-dnd-movement-function`.  */
 22332                   && (command_loop_level + minibuf_level
 22333                       <= x_dnd_recursion_depth)
 22334                   && xev->deviceid == x_dnd_pointer_device
 22335                   && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 22336                 {
 22337                   Window target, toplevel;
 22338                   int target_proto, motif_style;
 22339                   XRectangle *r;
 22340                   bool was_frame;
 22341 
 22342                   /* Always clear mouse face.  */
 22343                   clear_mouse_face (hlinfo);
 22344                   hlinfo->mouse_face_hidden = true;
 22345 
 22346                   /* Sometimes the drag-and-drop operation starts with the
 22347                      pointer of a frame invisible due to input.  Since
 22348                      motion events are ignored during that, make the pointer
 22349                      visible manually.  */
 22350 
 22351                   if (f)
 22352                     {
 22353                       XTtoggle_invisible_pointer (f, false);
 22354 
 22355                       r = &dpyinfo->last_mouse_glyph;
 22356 
 22357                       /* Also remember the mouse glyph and set
 22358                          mouse_moved.  */
 22359                       if (f != dpyinfo->last_mouse_glyph_frame
 22360                           || lrint (xev->event_x) < r->x
 22361                           || lrint (xev->event_x) >= r->x + r->width
 22362                           || lrint (xev->event_y) < r->y
 22363                           || lrint (xev->event_y) >= r->y + r->height)
 22364                         {
 22365                           f->mouse_moved = true;
 22366                           f->last_mouse_device = (source ? source->name
 22367                                                   : Qnil);
 22368                           dpyinfo->last_mouse_scroll_bar = NULL;
 22369 
 22370                           remember_mouse_glyph (f, lrint (xev->event_x),
 22371                                                 lrint (xev->event_y), r);
 22372                           dpyinfo->last_mouse_glyph_frame = f;
 22373                         }
 22374                     }
 22375 
 22376                   if (xev->root == dpyinfo->root_window)
 22377                     target = x_dnd_get_target_window (dpyinfo,
 22378                                                       lrint (xev->root_x),
 22379                                                       lrint (xev->root_y),
 22380                                                       &target_proto,
 22381                                                       &motif_style,
 22382                                                       &toplevel,
 22383                                                       &was_frame);
 22384                   else
 22385                     target = x_dnd_fill_empty_target (&target_proto,
 22386                                                       &motif_style,
 22387                                                       &toplevel,
 22388                                                       &was_frame);
 22389 
 22390                   if (toplevel != x_dnd_last_seen_toplevel)
 22391                     {
 22392                       if (toplevel != FRAME_OUTER_WINDOW (x_dnd_frame)
 22393                           && x_dnd_return_frame == 1)
 22394                         x_dnd_return_frame = 2;
 22395 
 22396                       if (x_dnd_return_frame == 2
 22397                           && x_any_window_to_frame (dpyinfo, toplevel))
 22398                         {
 22399                           if (x_dnd_last_seen_window != None
 22400                               && x_dnd_last_protocol_version != -1
 22401                               && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 22402                             x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window,
 22403                                               x_dnd_last_seen_toplevel);
 22404                           else if (x_dnd_last_seen_window != None
 22405                                    && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)
 22406                                    && !x_dnd_disable_motif_drag
 22407                                    && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 22408                             {
 22409                               if (!x_dnd_motif_setup_p)
 22410                                 xm_setup_drag_info (dpyinfo, x_dnd_frame);
 22411 
 22412                               lmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 22413                                                             XM_DRAG_REASON_TOP_LEVEL_LEAVE);
 22414                               lmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 22415                               lmsg.zero = 0;
 22416                               lmsg.timestamp = xev->time;
 22417                               lmsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 22418 
 22419                               if (x_dnd_motif_setup_p)
 22420                                 xm_send_top_level_leave_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 22421                                                                  x_dnd_last_seen_window, &lmsg);
 22422                             }
 22423 
 22424                           x_dnd_end_window = x_dnd_last_seen_window;
 22425                           x_dnd_last_seen_window = None;
 22426                           x_dnd_last_seen_toplevel = None;
 22427                           x_dnd_in_progress = false;
 22428                           x_dnd_return_frame_object
 22429                             = x_any_window_to_frame (dpyinfo, toplevel);
 22430                           x_dnd_return_frame = 3;
 22431                           x_dnd_waiting_for_finish = false;
 22432                           target = None;
 22433                         }
 22434                     }
 22435 
 22436                   if (target != x_dnd_last_seen_window)
 22437                     {
 22438                       if (x_dnd_last_seen_window != None
 22439                           && x_dnd_last_protocol_version != -1
 22440                           && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 22441                         x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window,
 22442                                           x_dnd_last_seen_toplevel);
 22443                       else if (x_dnd_last_seen_window != None
 22444                                && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)
 22445                                && !x_dnd_disable_motif_drag
 22446                                && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 22447                         {
 22448                           if (!x_dnd_motif_setup_p)
 22449                             xm_setup_drag_info (dpyinfo, x_dnd_frame);
 22450 
 22451                           /* This is apparently required.  If we don't
 22452                              send a motion event with the current root
 22453                              window coordinates of the pointer before
 22454                              the top level leave, then Motif displays
 22455                              an ugly black border around the previous
 22456                              drop site.  */
 22457 
 22458                           dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 22459                                                         XM_DRAG_REASON_DRAG_MOTION);
 22460                           dmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 22461                           dmsg.side_effects
 22462                             = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo,
 22463                                                                                x_dnd_wanted_action),
 22464                                                    XM_DROP_SITE_NONE, x_dnd_motif_operations,
 22465                                                    XM_DROP_ACTION_DROP_CANCEL);
 22466                           dmsg.timestamp = xev->time;
 22467                           dmsg.x = lrint (xev->root_x);
 22468                           dmsg.y = lrint (xev->root_y);
 22469 
 22470                           lmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 22471                                                         XM_DRAG_REASON_TOP_LEVEL_LEAVE);
 22472                           lmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 22473                           lmsg.zero = 0;
 22474                           lmsg.timestamp = xev->time;
 22475                           lmsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 22476 
 22477                           if (x_dnd_motif_setup_p)
 22478                             {
 22479                               xm_send_drag_motion_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 22480                                                            x_dnd_last_seen_window, &dmsg);
 22481                               xm_send_top_level_leave_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 22482                                                                x_dnd_last_seen_window, &lmsg);
 22483                             }
 22484                         }
 22485 
 22486                       x_dnd_action = None;
 22487                       x_dnd_last_seen_toplevel = toplevel;
 22488                       x_dnd_last_seen_window = target;
 22489                       x_dnd_last_protocol_version = target_proto;
 22490                       x_dnd_last_motif_style = motif_style;
 22491                       x_dnd_last_window_is_frame = was_frame;
 22492 
 22493                       if (target != None && x_dnd_last_protocol_version != -1)
 22494                         x_dnd_send_enter (x_dnd_frame, target,
 22495                                           x_dnd_last_seen_toplevel,
 22496                                           x_dnd_last_protocol_version);
 22497                       else if (target != None && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)
 22498                                && !x_dnd_disable_motif_drag)
 22499                         {
 22500                           if (!x_dnd_motif_setup_p)
 22501                             xm_setup_drag_info (dpyinfo, x_dnd_frame);
 22502 
 22503                           emsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 22504                                                         XM_DRAG_REASON_TOP_LEVEL_ENTER);
 22505                           emsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 22506                           emsg.zero = 0;
 22507                           emsg.timestamp = xev->time;
 22508                           emsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 22509                           emsg.index_atom = x_dnd_motif_atom;
 22510 
 22511                           if (x_dnd_motif_setup_p)
 22512                             xm_send_top_level_enter_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 22513                                                              target, &emsg);
 22514                         }
 22515                     }
 22516                   else
 22517                     x_dnd_last_seen_toplevel = toplevel;
 22518 
 22519                   if (x_dnd_last_window_is_frame && target != None)
 22520                     x_dnd_note_self_position (dpyinfo, target,
 22521                                               lrint (xev->root_x),
 22522                                               lrint (xev->root_y));
 22523                   else if (x_dnd_last_protocol_version != -1 && target != None)
 22524                     {
 22525                       dnd_state = xi_convert_event_state (xev);
 22526 
 22527                       x_dnd_send_position (x_dnd_frame, target,
 22528                                            x_dnd_last_seen_toplevel,
 22529                                            x_dnd_last_protocol_version,
 22530                                            lrint (xev->root_x),
 22531                                            lrint (xev->root_y),
 22532                                            x_dnd_selection_timestamp,
 22533                                            x_dnd_wanted_action, 0,
 22534                                            dnd_state);
 22535                     }
 22536                   else if (XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) && target != None
 22537                            && !x_dnd_disable_motif_drag)
 22538                     {
 22539                       if (!x_dnd_motif_setup_p)
 22540                         xm_setup_drag_info (dpyinfo, x_dnd_frame);
 22541 
 22542                       dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 22543                                                     XM_DRAG_REASON_DRAG_MOTION);
 22544                       dmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 22545                       dmsg.side_effects
 22546                         = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo,
 22547                                                                            x_dnd_wanted_action),
 22548                                                XM_DROP_SITE_VALID, x_dnd_motif_operations,
 22549                                                (!x_dnd_xm_use_help
 22550                                                 ? XM_DROP_ACTION_DROP
 22551                                                 : XM_DROP_ACTION_DROP_HELP));
 22552                       dmsg.timestamp = xev->time;
 22553                       dmsg.x = lrint (xev->root_x);
 22554                       dmsg.y = lrint (xev->root_y);
 22555 
 22556                       if (x_dnd_motif_setup_p)
 22557                         xm_send_drag_motion_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 22558                                                      target, &dmsg);
 22559                     }
 22560 
 22561                   x_dnd_update_tooltip_position (xev->root_x, xev->root_y);
 22562 
 22563                   goto XI_OTHER;
 22564                 }
 22565 
 22566 #ifdef USE_GTK
 22567               if (f && xg_event_is_for_scrollbar (f, event, false))
 22568                 f = 0;
 22569 #endif
 22570               if (f)
 22571                 {
 22572                   if (xev->event != FRAME_X_WINDOW (f))
 22573                     {
 22574                       x_translate_coordinates (f, lrint (xev->root_x),
 22575                                                lrint (xev->root_y),
 22576                                                &ev.x, &ev.y);
 22577                       ev.window = FRAME_X_WINDOW (f);
 22578                     }
 22579 
 22580                   /* Maybe generate a SELECT_WINDOW_EVENT for
 22581                      `mouse-autoselect-window' but don't let popup menus
 22582                      interfere with this (Bug#1261).  */
 22583                   if (!NILP (Vmouse_autoselect_window)
 22584                       && !popup_activated ()
 22585                       /* Don't switch if we're currently in the minibuffer.
 22586                          This tries to work around problems where the
 22587                          minibuffer gets unselected unexpectedly, and where
 22588                          you then have to move your mouse all the way down to
 22589                          the minibuffer to select it.  */
 22590                       && !MINI_WINDOW_P (XWINDOW (selected_window))
 22591                       /* With `focus-follows-mouse' non-nil create an event
 22592                          also when the target window is on another frame.  */
 22593                       && (f == XFRAME (selected_frame)
 22594                           || !NILP (focus_follows_mouse)))
 22595                     {
 22596                       static Lisp_Object last_mouse_window;
 22597                       Lisp_Object window = window_from_coordinates (f, ev.x, ev.y, 0, false, false);
 22598 
 22599                       /* A window will be autoselected only when it is not
 22600                          selected now and the last mouse movement event was
 22601                          not in it.  The remainder of the code is a bit vague
 22602                          wrt what a "window" is.  For immediate autoselection,
 22603                          the window is usually the entire window but for GTK
 22604                          where the scroll bars don't count.  For delayed
 22605                          autoselection the window is usually the window's text
 22606                          area including the margins.  */
 22607                       if (WINDOWP (window)
 22608                           && !EQ (window, last_mouse_window)
 22609                           && !EQ (window, selected_window))
 22610                         {
 22611                           inev.ie.kind = SELECT_WINDOW_EVENT;
 22612                           inev.ie.frame_or_window = window;
 22613 
 22614                           if (source)
 22615                             inev.ie.device = source->name;
 22616                         }
 22617 
 22618                       /* Remember the last window where we saw the mouse.  */
 22619                       last_mouse_window = window;
 22620                     }
 22621 
 22622                   if (!x_note_mouse_movement (f, &ev, source ? source->name : Qnil))
 22623                     help_echo_string = previous_help_echo_string;
 22624                 }
 22625               else
 22626                 {
 22627 #ifndef USE_TOOLKIT_SCROLL_BARS
 22628                   struct scroll_bar *bar
 22629                     = x_window_to_scroll_bar (dpyinfo->display, xev->event, 2);
 22630 
 22631                   if (bar)
 22632                     x_scroll_bar_note_movement (bar, &ev);
 22633 #endif /* USE_TOOLKIT_SCROLL_BARS */
 22634 
 22635                   /* If we move outside the frame, then we're
 22636                      certainly no longer on any text in the frame.  */
 22637                   clear_mouse_face (hlinfo);
 22638                 }
 22639 
 22640               /* If the contents of the global variable help_echo_string
 22641                  has changed, generate a HELP_EVENT.  */
 22642               if (!NILP (help_echo_string)
 22643                   || !NILP (previous_help_echo_string))
 22644                 {
 22645                   /* Also allow the focus and client pointer to be
 22646                      adjusted accordingly, in case a help tooltip is
 22647                      shown.  */
 22648                   gen_help_device = device;
 22649                   gen_help_time = xev->time;
 22650 
 22651                   do_help = 1;
 22652                 }
 22653 
 22654               if (f)
 22655                 x_flush_dirty_back_buffer_on (f);
 22656               goto XI_OTHER;
 22657             }
 22658 
 22659           case XI_ButtonRelease:
 22660           case XI_ButtonPress:
 22661             {
 22662               /* If we decide we want to generate an event to be seen
 22663                  by the rest of Emacs, we put it here.  */
 22664               Lisp_Object tab_bar_arg = Qnil;
 22665               bool tab_bar_p = false;
 22666               bool tool_bar_p = false;
 22667               struct xi_device_t *device, *source;
 22668 #ifdef HAVE_XWIDGETS
 22669               struct xwidget_view *xvw;
 22670 #endif
 22671               /* A fake XButtonEvent for x_construct_mouse_click. */
 22672               XButtonEvent bv;
 22673               bool dnd_grab = false;
 22674               int dnd_state;
 22675 
 22676               if (x_dnd_in_progress
 22677                   && (command_loop_level + minibuf_level
 22678                       <= x_dnd_recursion_depth)
 22679                   && xev->deviceid == x_dnd_pointer_device
 22680                   && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 22681                 {
 22682                   f = mouse_or_wdesc_frame (dpyinfo, xev->event);
 22683                   device = xi_device_from_id (dpyinfo, xev->deviceid);
 22684 
 22685                   if (f && xev->event == FRAME_X_WINDOW (f))
 22686                     /* See the comment above
 22687                        x_compute_root_window_offset for why this
 22688                        optimization is performed.  */
 22689                     xi_compute_root_window_offset (f, xev);
 22690 
 22691                   /* Don't track grab status for emulated pointer
 22692                      events, because they are ignored by the regular
 22693                      mouse click processing code.  */
 22694 #ifdef XIPointerEmulated
 22695                   if (!(xev->flags & XIPointerEmulated))
 22696                     {
 22697 #endif
 22698                       if (xev->evtype == XI_ButtonPress)
 22699                         {
 22700                           x_display_set_last_user_time (dpyinfo, xev->time,
 22701                                                         xev->send_event, true);
 22702 
 22703                           dpyinfo->grabbed |= (1 << xev->detail);
 22704                           dpyinfo->last_mouse_frame = f;
 22705 
 22706                           if (device)
 22707                             device->grab |= (1 << xev->detail);
 22708 
 22709                           if (f)
 22710                             f->last_tab_bar_item = -1;
 22711 #if ! defined (USE_GTK)
 22712                           if (f)
 22713                             f->last_tool_bar_item = -1;
 22714 #endif /* not USE_GTK */
 22715                         }
 22716                       else
 22717                         {
 22718                           dpyinfo->grabbed &= ~(1 << xev->detail);
 22719                           if (device)
 22720                             device->grab &= ~(1 << xev->detail);
 22721                         }
 22722 #ifdef XIPointerEmulated
 22723                     }
 22724 #endif
 22725 
 22726                   if (f && device)
 22727                     xi_handle_interaction (dpyinfo, f, device,
 22728                                            xev->time);
 22729 
 22730                   if (xev->evtype == XI_ButtonPress
 22731                       && x_dnd_last_seen_window != None)
 22732                     {
 22733                       dnd_state = xi_convert_event_state (xev);
 22734 
 22735                       if (x_dnd_last_window_is_frame)
 22736                         {
 22737 #ifdef XI_PointerEmulated
 22738                           /* Set the last user time here even if this
 22739                              is an emulated button event, since
 22740                              something happened in response.  */
 22741 
 22742                           if (xev->flags & XIPointerEmulated)
 22743                             x_display_set_last_user_time (dpyinfo, xev->time,
 22744                                                           xev->send_event, true);
 22745 #endif
 22746                           x_dnd_note_self_wheel (dpyinfo,
 22747                                                  x_dnd_last_seen_window,
 22748                                                  lrint (xev->root_x),
 22749                                                  lrint (xev->root_y),
 22750                                                  xev->detail, dnd_state,
 22751                                                  xev->time);
 22752                         }
 22753                       else
 22754                         x_dnd_send_position (x_dnd_frame,
 22755                                              x_dnd_last_seen_window,
 22756                                              x_dnd_last_seen_toplevel,
 22757                                              x_dnd_last_protocol_version,
 22758                                              lrint (xev->root_x),
 22759                                              lrint (xev->root_y),
 22760                                              xev->time, x_dnd_wanted_action,
 22761                                              xev->detail, dnd_state);
 22762 
 22763                       goto OTHER;
 22764                     }
 22765 
 22766                   if (xev->evtype == XI_ButtonRelease)
 22767                     {
 22768                       for (int i = 0; i < xev->buttons.mask_len * 8; ++i)
 22769                         {
 22770                           if (i != xev->detail && XIMaskIsSet (xev->buttons.mask, i))
 22771                             dnd_grab = true;
 22772                         }
 22773 
 22774                       if (!dnd_grab)
 22775                         {
 22776                           x_dnd_end_window = x_dnd_last_seen_window;
 22777                           x_dnd_in_progress = false;
 22778 
 22779                           /* If a tooltip that we're following is
 22780                              displayed, hide it now.  */
 22781 
 22782                           if (x_dnd_update_tooltip
 22783                               && FRAMEP (tip_frame)
 22784                               && FRAME_LIVE_P (XFRAME (tip_frame))
 22785                               && (FRAME_X_DISPLAY (XFRAME (tip_frame))
 22786                                   == FRAME_X_DISPLAY (x_dnd_frame)))
 22787                             Fx_hide_tip ();
 22788 
 22789                           /* This doesn't have to be marked since it
 22790                              is only accessed if
 22791                              x_dnd_waiting_for_finish is true, which
 22792                              is only possible inside the DND event
 22793                              loop where that frame is on the
 22794                              stack.  */
 22795                           x_dnd_finish_frame = x_dnd_frame;
 22796 
 22797                           if (x_dnd_last_seen_window != None
 22798                               && x_dnd_last_window_is_frame)
 22799                             {
 22800                               x_dnd_waiting_for_finish = false;
 22801                               x_dnd_note_self_drop (dpyinfo, x_dnd_last_seen_window,
 22802                                                     lrint (xev->root_x),
 22803                                                     lrint (xev->root_y), xev->time);
 22804                             }
 22805                           else if (x_dnd_last_seen_window != None
 22806                                    && x_dnd_last_protocol_version != -1)
 22807                             {
 22808                               x_dnd_pending_finish_target = x_dnd_last_seen_toplevel;
 22809                               x_dnd_waiting_for_finish_proto = x_dnd_last_protocol_version;
 22810 
 22811                               x_dnd_waiting_for_finish
 22812                                 = x_dnd_do_drop (x_dnd_last_seen_window,
 22813                                                  x_dnd_last_seen_toplevel,
 22814                                                  x_dnd_last_protocol_version);
 22815                               x_dnd_finish_display = dpyinfo->display;
 22816                             }
 22817                           else if (x_dnd_last_seen_window != None)
 22818                             {
 22819                               xm_drop_start_message dmsg;
 22820                               xm_drag_receiver_info drag_receiver_info;
 22821 
 22822                               if (!xm_read_drag_receiver_info (dpyinfo, x_dnd_last_seen_window,
 22823                                                                &drag_receiver_info)
 22824                                   && !x_dnd_disable_motif_protocol
 22825                                   && drag_receiver_info.protocol_style != XM_DRAG_STYLE_NONE
 22826                                   && (x_dnd_allow_current_frame
 22827                                       || x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame)))
 22828                                 {
 22829                                   if (!x_dnd_motif_setup_p)
 22830                                     xm_setup_drag_info (dpyinfo, x_dnd_frame);
 22831 
 22832                                   if (x_dnd_motif_setup_p)
 22833                                     {
 22834                                       memset (&dmsg, 0, sizeof dmsg);
 22835 
 22836                                       dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 22837                                                                     XM_DRAG_REASON_DROP_START);
 22838                                       dmsg.byte_order = XM_BYTE_ORDER_CUR_FIRST;
 22839                                       dmsg.side_effects
 22840                                         = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo,
 22841                                                                                            x_dnd_wanted_action),
 22842                                                                XM_DROP_SITE_VALID, x_dnd_motif_operations,
 22843                                                                (!x_dnd_xm_use_help
 22844                                                                 ? XM_DROP_ACTION_DROP
 22845                                                                 : XM_DROP_ACTION_DROP_HELP));
 22846                                       dmsg.timestamp = xev->time;
 22847                                       dmsg.x = lrint (xev->root_x);
 22848                                       dmsg.y = lrint (xev->root_y);
 22849                                       /* This atom technically has to be
 22850                                          unique to each drag-and-drop
 22851                                          operation, but that isn't easy to
 22852                                          accomplish, since we cannot
 22853                                          randomly move data around between
 22854                                          selections.  Let's hope no two
 22855                                          instances of Emacs try to drag
 22856                                          into the same window at the same
 22857                                          time.  */
 22858                                       dmsg.index_atom = x_dnd_motif_atom;
 22859                                       dmsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 22860 
 22861                                       if (!XM_DRAG_STYLE_IS_DROP_ONLY (drag_receiver_info.protocol_style))
 22862                                         x_dnd_send_xm_leave_for_drop (FRAME_DISPLAY_INFO (x_dnd_frame),
 22863                                                                       x_dnd_frame, x_dnd_last_seen_window,
 22864                                                                       xev->time);
 22865 
 22866                                       xm_send_drop_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 22867                                                             x_dnd_last_seen_window, &dmsg);
 22868 
 22869                                       x_dnd_waiting_for_finish = true;
 22870                                       x_dnd_waiting_for_motif_finish_display = dpyinfo;
 22871                                       x_dnd_waiting_for_motif_finish = 1;
 22872                                       x_dnd_finish_display = dpyinfo->display;
 22873                                     }
 22874                                 }
 22875                               else
 22876                                 x_dnd_send_unsupported_drop (dpyinfo, (x_dnd_last_seen_toplevel != None
 22877                                                                        ? x_dnd_last_seen_toplevel
 22878                                                                        : x_dnd_last_seen_window),
 22879                                                              lrint (xev->root_x),
 22880                                                              lrint (xev->root_y), xev->time);
 22881                             }
 22882                           else if (x_dnd_last_seen_toplevel != None)
 22883                             x_dnd_send_unsupported_drop (dpyinfo,
 22884                                                          x_dnd_last_seen_toplevel,
 22885                                                          lrint (xev->root_x),
 22886                                                          lrint (xev->root_y),
 22887                                                          xev->time);
 22888 
 22889                           x_dnd_last_protocol_version = -1;
 22890                           x_dnd_last_motif_style = XM_DRAG_STYLE_NONE;
 22891                           x_dnd_last_seen_window = None;
 22892                           x_dnd_last_seen_toplevel = None;
 22893                           x_dnd_last_window_is_frame = false;
 22894                           x_dnd_frame = NULL;
 22895 
 22896                           goto XI_OTHER;
 22897                         }
 22898                     }
 22899                 }
 22900 
 22901               if (x_dnd_in_progress
 22902                   && (command_loop_level + minibuf_level
 22903                       <= x_dnd_recursion_depth))
 22904                 goto XI_OTHER;
 22905 
 22906 #ifdef USE_MOTIF
 22907 #ifdef USE_TOOLKIT_SCROLL_BARS
 22908               struct scroll_bar *bar
 22909                 = x_window_to_scroll_bar (dpyinfo->display,
 22910                                           xev->event, 2);
 22911 #endif
 22912 
 22913               use_copy = true;
 22914               copy.xbutton.type = (xev->evtype == XI_ButtonPress
 22915                                    ? ButtonPress : ButtonRelease);
 22916               copy.xbutton.serial = xev->serial;
 22917               copy.xbutton.send_event = xev->send_event;
 22918               copy.xbutton.display = dpyinfo->display;
 22919               copy.xbutton.window = xev->event;
 22920               copy.xbutton.root = xev->root;
 22921               copy.xbutton.subwindow = xev->child;
 22922               copy.xbutton.time = xev->time;
 22923               copy.xbutton.x = lrint (xev->event_x);
 22924               copy.xbutton.y = lrint (xev->event_y);
 22925               copy.xbutton.x_root = lrint (xev->root_x);
 22926               copy.xbutton.y_root = lrint (xev->root_y);
 22927               copy.xbutton.state = xi_convert_event_state (xev);
 22928               copy.xbutton.button = xev->detail;
 22929               copy.xbutton.same_screen = True;
 22930 
 22931 #elif defined USE_GTK && !defined HAVE_GTK3
 22932               copy = gdk_event_new (xev->evtype == XI_ButtonPress
 22933                                     ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE);
 22934 
 22935               copy->button.window = gdk_x11_window_lookup_for_display (gdpy, xev->event);
 22936               copy->button.send_event = xev->send_event;
 22937               copy->button.time = xev->time;
 22938               copy->button.x = xev->event_x;
 22939               copy->button.y = xev->event_y;
 22940               copy->button.x_root = xev->root_x;
 22941               copy->button.y_root = xev->root_y;
 22942               copy->button.state = xi_convert_event_state (xev);
 22943               copy->button.button = xev->detail;
 22944 
 22945               if (!copy->button.window)
 22946                 emacs_abort ();
 22947 
 22948               g_object_ref (copy->button.window);
 22949 
 22950               if (popup_activated ())
 22951                 {
 22952                   /* GTK+ popup menus don't respond to core buttons
 22953                      after Button3, so don't dismiss popup menus upon
 22954                      wheel movement here either.  */
 22955                   if (xev->detail > 3)
 22956                     *finish = X_EVENT_DROP;
 22957 
 22958                   if (xev->evtype == XI_ButtonRelease)
 22959                     goto XI_OTHER;
 22960                 }
 22961 #endif
 22962 
 22963 #ifdef HAVE_XINPUT2_1
 22964               /* Ignore emulated scroll events when XI2 native
 22965                  scroll events are present.  */
 22966               if (xev->flags & XIPointerEmulated)
 22967                 {
 22968 #if !defined USE_MOTIF || !defined USE_TOOLKIT_SCROLL_BARS
 22969                   *finish = X_EVENT_DROP;
 22970 #else
 22971                   if (bar)
 22972                     *finish = X_EVENT_DROP;
 22973 #endif
 22974                   goto XI_OTHER;
 22975                 }
 22976 #endif
 22977 
 22978               if (xev->evtype == XI_ButtonPress)
 22979                 x_display_set_last_user_time (dpyinfo, xev->time,
 22980                                               xev->send_event, true);
 22981 
 22982               source = xi_device_from_id (dpyinfo, xev->sourceid);
 22983               device = xi_device_from_id (dpyinfo, xev->deviceid);
 22984 
 22985 #ifdef HAVE_XWIDGETS
 22986               xvw = xwidget_view_from_window (xev->event);
 22987               if (xvw)
 22988                 {
 22989                   /* If the user interacts with a frame that's focused
 22990                      on another device, but not the current focus
 22991                      frame, make it the focus frame.  */
 22992                   if (device)
 22993                     xi_handle_interaction (dpyinfo, xvw->frame,
 22994                                            device, xev->time);
 22995 
 22996                   xwidget_button (xvw, xev->evtype == XI_ButtonPress,
 22997                                   lrint (xev->event_x), lrint (xev->event_y),
 22998                                   xev->detail, xi_convert_event_state (xev),
 22999                                   xev->time);
 23000 
 23001                   if (!EQ (selected_window, xvw->w) && (xev->detail < 4))
 23002                     {
 23003                       inev.ie.kind = SELECT_WINDOW_EVENT;
 23004                       inev.ie.frame_or_window = xvw->w;
 23005 
 23006                       if (source)
 23007                         inev.ie.device = source->name;
 23008                     }
 23009 
 23010                   *finish = X_EVENT_DROP;
 23011                   goto XI_OTHER;
 23012                 }
 23013 #endif
 23014 
 23015               if (!device)
 23016                 goto XI_OTHER;
 23017 
 23018               bv.button = xev->detail;
 23019               bv.type = xev->evtype == XI_ButtonPress ? ButtonPress : ButtonRelease;
 23020               bv.x = lrint (xev->event_x);
 23021               bv.y = lrint (xev->event_y);
 23022               bv.x_root = lrint (xev->root_x);
 23023               bv.y_root = lrint (xev->root_y);
 23024               bv.window = xev->event;
 23025               bv.state = xi_convert_event_state (xev);
 23026               bv.time = xev->time;
 23027 
 23028               dpyinfo->last_mouse_glyph_frame = NULL;
 23029 
 23030               f = mouse_or_wdesc_frame (dpyinfo, xev->event);
 23031 
 23032               if (f && xev->event == FRAME_X_WINDOW (f))
 23033                 /* See the comment above x_compute_root_window_offset
 23034                    for why this optimization is performed.  */
 23035                 xi_compute_root_window_offset (f, xev);
 23036 
 23037               if (f && xev->evtype == XI_ButtonPress
 23038                   && !popup_activated ()
 23039                   && !x_window_to_scroll_bar (dpyinfo->display, xev->event, 2)
 23040                   && !FRAME_NO_ACCEPT_FOCUS (f))
 23041                 {
 23042                   /* When clicking into a child frame or when clicking
 23043                      into a parent frame with the child frame selected and
 23044                      `no-accept-focus' is not set, select the clicked
 23045                      frame.  */
 23046                   struct frame *hf = dpyinfo->highlight_frame;
 23047 
 23048                   if (FRAME_PARENT_FRAME (f) || (hf && frame_ancestor_p (f, hf)))
 23049                     {
 23050 #if defined HAVE_GTK3 || (!defined USE_GTK && !defined USE_X_TOOLKIT)
 23051                       if (device)
 23052                         {
 23053                           /* This can generate XI_BadDevice if the
 23054                              device's attachment was destroyed
 23055                              server-side.  */
 23056                           x_ignore_errors_for_next_request (dpyinfo);
 23057                           XISetFocus (dpyinfo->display, device->attachment,
 23058                                       /* Note that the input extension
 23059                                          only supports RevertToParent-type
 23060                                          behavior.  */
 23061                                       FRAME_OUTER_WINDOW (f), xev->time);
 23062                           x_stop_ignoring_errors (dpyinfo);
 23063                         }
 23064 #else
 23065                       /* Non-no toolkit builds without GTK 3 use core
 23066                          events to handle focus.  Errors are still
 23067                          caught here in case the window is not
 23068                          viewable.  */
 23069                       x_ignore_errors_for_next_request (dpyinfo);
 23070                       XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 23071                                       RevertToParent, xev->time);
 23072                       x_stop_ignoring_errors (dpyinfo);
 23073 #endif
 23074                       if (FRAME_PARENT_FRAME (f))
 23075                         XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f));
 23076                     }
 23077                 }
 23078 
 23079               if (f)
 23080                 {
 23081                   /* If the user interacts with a frame that's focused
 23082                      on another device, but not the current focus
 23083                      frame, make it the focus frame.  */
 23084                   if (device)
 23085                     xi_handle_interaction (dpyinfo, f, device,
 23086                                            xev->time);
 23087                 }
 23088 
 23089 #ifdef USE_GTK
 23090               if (!f)
 23091                 {
 23092                   int real_x = lrint (xev->root_x);
 23093                   int real_y = lrint (xev->root_y);
 23094 
 23095                   f = x_any_window_to_frame (dpyinfo, xev->event);
 23096 
 23097                   if (xev->detail > 3 && xev->detail < 8 && f)
 23098                     {
 23099                       if (xev->evtype == XI_ButtonRelease)
 23100                         {
 23101                           if (FRAME_X_WINDOW (f) != xev->event)
 23102                             x_translate_coordinates (f, real_x, real_y,
 23103                                                      &real_x, &real_y);
 23104 
 23105                           if (xev->detail <= 5)
 23106                             inev.ie.kind = WHEEL_EVENT;
 23107                           else
 23108                             inev.ie.kind = HORIZ_WHEEL_EVENT;
 23109 
 23110                           if (source)
 23111                             inev.ie.device = source->name;
 23112 
 23113                           inev.ie.timestamp = xev->time;
 23114 
 23115                           XSETINT (inev.ie.x, real_x);
 23116                           XSETINT (inev.ie.y, real_y);
 23117                           XSETFRAME (inev.ie.frame_or_window, f);
 23118 
 23119                           inev.ie.modifiers
 23120                             |= x_x_to_emacs_modifiers (dpyinfo,
 23121                                                        xev->mods.effective);
 23122 
 23123                           inev.ie.modifiers |= xev->detail % 2 ? down_modifier : up_modifier;
 23124                         }
 23125 
 23126                       *finish = X_EVENT_DROP;
 23127                       goto XI_OTHER;
 23128                     }
 23129                   else
 23130                     f = NULL;
 23131                 }
 23132 
 23133               if (f && xg_event_is_for_scrollbar (f, event, false))
 23134                 f = 0;
 23135 #endif
 23136 
 23137               if (f)
 23138                 {
 23139                   if (xev->detail >= 4 && xev->detail < 8)
 23140                     {
 23141                       if (xev->evtype == XI_ButtonRelease)
 23142                         {
 23143                           if (xev->detail <= 5)
 23144                             inev.ie.kind = WHEEL_EVENT;
 23145                           else
 23146                             inev.ie.kind = HORIZ_WHEEL_EVENT;
 23147 
 23148                           if (source)
 23149                             inev.ie.device = source->name;
 23150 
 23151                           inev.ie.timestamp = xev->time;
 23152 
 23153                           XSETINT (inev.ie.x, lrint (xev->event_x));
 23154                           XSETINT (inev.ie.y, lrint (xev->event_y));
 23155                           XSETFRAME (inev.ie.frame_or_window, f);
 23156 
 23157                           inev.ie.modifiers
 23158                             |= x_x_to_emacs_modifiers (dpyinfo,
 23159                                                        xev->mods.effective);
 23160 
 23161                           inev.ie.modifiers |= xev->detail % 2 ? down_modifier : up_modifier;
 23162                         }
 23163 
 23164                       goto XI_OTHER;
 23165                     }
 23166 
 23167                   /* Is this in the tab-bar?  */
 23168                   if (WINDOWP (f->tab_bar_window)
 23169                       && WINDOW_TOTAL_LINES (XWINDOW (f->tab_bar_window)))
 23170                     {
 23171                       Lisp_Object window;
 23172                       int x = bv.x;
 23173                       int y = bv.y;
 23174 
 23175                       window = window_from_coordinates (f, x, y, 0, true, true);
 23176                       tab_bar_p = EQ (window, f->tab_bar_window);
 23177 
 23178                       if (tab_bar_p)
 23179                         {
 23180                           tab_bar_arg = handle_tab_bar_click
 23181                             (f, x, y, xev->evtype == XI_ButtonPress,
 23182                              x_x_to_emacs_modifiers (dpyinfo, bv.state));
 23183                           x_flush_dirty_back_buffer_on (f);
 23184                         }
 23185                     }
 23186 
 23187 #if ! defined (USE_GTK)
 23188                   /* Is this in the tool-bar?  */
 23189                   if (WINDOWP (f->tool_bar_window)
 23190                       && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)))
 23191                     {
 23192                       Lisp_Object window;
 23193                       int x = bv.x;
 23194                       int y = bv.y;
 23195 
 23196                       window = window_from_coordinates (f, x, y, 0, true, true);
 23197                       /* Ignore button release events if the mouse
 23198                          wasn't previously pressed on the tool bar.
 23199                          We do this because otherwise selecting some
 23200                          text with the mouse and then releasing it on
 23201                          the tool bar doesn't stop selecting text,
 23202                          since the tool bar eats the button up
 23203                          event.  */
 23204                       tool_bar_p = (EQ (window, f->tool_bar_window)
 23205                                     && (xev->evtype != XI_ButtonRelease
 23206                                         || f->last_tool_bar_item != -1));
 23207 
 23208                       if (tool_bar_p && xev->detail < 4)
 23209                         {
 23210                           handle_tool_bar_click_with_device
 23211                             (f, x, y, xev->evtype == XI_ButtonPress,
 23212                              x_x_to_emacs_modifiers (dpyinfo, bv.state),
 23213                              source ? source->name : Qt);
 23214                           x_flush_dirty_back_buffer_on (f);
 23215                         }
 23216                     }
 23217 #endif /* !USE_GTK */
 23218 
 23219                   if (!(tab_bar_p && NILP (tab_bar_arg)) && !tool_bar_p)
 23220 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
 23221                     if (! popup_activated ())
 23222 #endif
 23223                       {
 23224                         if (ignore_next_mouse_click_timeout)
 23225                           {
 23226                             if (xev->evtype == XI_ButtonPress
 23227                                 && xev->time > ignore_next_mouse_click_timeout)
 23228                               {
 23229                                 ignore_next_mouse_click_timeout = 0;
 23230                                 x_construct_mouse_click (&inev.ie, &bv, f);
 23231                               }
 23232                             if (xev->evtype == XI_ButtonRelease)
 23233                               ignore_next_mouse_click_timeout = 0;
 23234                           }
 23235                         else
 23236                           x_construct_mouse_click (&inev.ie, &bv, f);
 23237 
 23238                         if (!NILP (tab_bar_arg))
 23239                           inev.ie.arg = tab_bar_arg;
 23240                       }
 23241 
 23242                   if (FRAME_X_EMBEDDED_P (f)
 23243                       && !FRAME_NO_ACCEPT_FOCUS (f))
 23244                     xembed_send_message (f, xev->time,
 23245                                          XEMBED_REQUEST_FOCUS, 0, 0, 0);
 23246                 }
 23247               else
 23248                 {
 23249                   struct scroll_bar *bar
 23250                     = x_window_to_scroll_bar (dpyinfo->display,
 23251                                               xev->event, 2);
 23252 
 23253 #ifndef USE_TOOLKIT_SCROLL_BARS
 23254                   if (bar)
 23255                     x_scroll_bar_handle_click (bar, (XEvent *) &bv, &inev.ie,
 23256                                                source ? source->name : Qnil);
 23257 #else
 23258                   /* Make the "Ctrl-Mouse-2 splits window" work for toolkit
 23259                      scroll bars.  */
 23260                   if (bar && xev->mods.effective & ControlMask)
 23261                     {
 23262                       x_scroll_bar_handle_click (bar, (XEvent *) &bv, &inev.ie,
 23263                                                  source ? source->name : Qnil);
 23264                       *finish = X_EVENT_DROP;
 23265                     }
 23266 #endif
 23267                 }
 23268 
 23269               if (xev->evtype == XI_ButtonPress)
 23270                 {
 23271                   dpyinfo->grabbed |= (1 << xev->detail);
 23272                   device->grab |= (1 << xev->detail);
 23273                   dpyinfo->last_mouse_frame = f;
 23274                   if (f && !tab_bar_p)
 23275                     f->last_tab_bar_item = -1;
 23276 #if ! defined (USE_GTK)
 23277                   if (f && !tool_bar_p)
 23278                     f->last_tool_bar_item = -1;
 23279 #endif /* not USE_GTK */
 23280 
 23281                 }
 23282               else
 23283                 {
 23284                   dpyinfo->grabbed &= ~(1 << xev->detail);
 23285                   device->grab &= ~(1 << xev->detail);
 23286                 }
 23287 
 23288               if (source && inev.ie.kind != NO_EVENT)
 23289                 inev.ie.device = source->name;
 23290 
 23291               if (f)
 23292                 f->mouse_moved = false;
 23293 
 23294 #if defined (USE_GTK)
 23295               /* No Xt toolkit currently available has support for XI2.
 23296                  So the code here assumes use of GTK.  */
 23297               f = x_menubar_window_to_frame (dpyinfo, event);
 23298               if (f /* Gtk+ menus only react to the first three buttons. */
 23299                   && xev->detail < 3)
 23300                 {
 23301                   /* What is done with Core Input ButtonPressed is not
 23302                      possible here, because GenericEvents cannot be saved.  */
 23303                   bool was_waiting_for_input = waiting_for_input;
 23304                   /* This hack was adopted from the NS port.  Whether
 23305                      or not it is actually safe is a different story
 23306                      altogether.  */
 23307                   if (waiting_for_input)
 23308                     waiting_for_input = 0;
 23309                   set_frame_menubar (f, true);
 23310                   waiting_for_input = was_waiting_for_input;
 23311                 }
 23312 #endif
 23313               goto XI_OTHER;
 23314             }
 23315 
 23316           case XI_KeyPress:
 23317             {
 23318               int state = xev->mods.effective;
 23319               Lisp_Object c;
 23320 #ifdef HAVE_XKB
 23321               unsigned int mods_rtrn;
 23322 #endif
 23323               int keycode = xev->detail;
 23324               KeySym keysym;
 23325               char copy_buffer[81];
 23326               char *copy_bufptr = copy_buffer;
 23327               int copy_bufsiz = sizeof (copy_buffer);
 23328               ptrdiff_t i;
 23329               unsigned int old_state;
 23330               struct xi_device_t *device, *source;
 23331 
 23332               coding = Qlatin_1;
 23333 
 23334               device = xi_device_from_id (dpyinfo, xev->deviceid);
 23335               source = xi_device_from_id (dpyinfo, xev->sourceid);
 23336 
 23337               if (!device)
 23338                 goto XI_OTHER;
 23339 
 23340 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
 23341               /* Dispatch XI_KeyPress events when in menu.  */
 23342               if (popup_activated ())
 23343                 {
 23344 #ifdef USE_LUCID
 23345                   /* This makes key navigation work inside menus.  */
 23346                   use_copy = true;
 23347                   copy.xkey.type = KeyPress;
 23348                   copy.xkey.serial = xev->serial;
 23349                   copy.xkey.send_event = xev->send_event;
 23350                   copy.xkey.display = dpyinfo->display;
 23351                   copy.xkey.window = xev->event;
 23352                   copy.xkey.root = xev->root;
 23353                   copy.xkey.subwindow = xev->child;
 23354                   copy.xkey.time = xev->time;
 23355                   copy.xkey.state = xi_convert_event_keyboard_state (xev);
 23356                   xi_convert_button_state (&xev->buttons, &copy.xkey.state);
 23357 
 23358                   copy.xkey.x = lrint (xev->event_x);
 23359                   copy.xkey.y = lrint (xev->event_y);
 23360                   copy.xkey.x_root = lrint (xev->root_x);
 23361                   copy.xkey.y_root = lrint (xev->root_y);
 23362                   copy.xkey.keycode = xev->detail;
 23363                   copy.xkey.same_screen = True;
 23364 #endif
 23365                   goto XI_OTHER;
 23366                 }
 23367 #endif
 23368 
 23369               x_display_set_last_user_time (dpyinfo, xev->time,
 23370                                             xev->send_event, true);
 23371               ignore_next_mouse_click_timeout = 0;
 23372 
 23373               f = x_any_window_to_frame (dpyinfo, xev->event);
 23374 
 23375               if (f && xev->event == FRAME_X_WINDOW (f))
 23376                 /* See the comment above x_compute_root_window_offset
 23377                    for why this optimization is performed.  */
 23378                 xi_compute_root_window_offset (f, xev);
 23379 
 23380               /* GTK handles TAB events in an undesirable manner, so
 23381                  keyboard events are always dropped.  But as a side
 23382                  effect, the user time will no longer be set by GDK,
 23383                  so do that manually.  */
 23384 #ifdef USE_GTK
 23385               if (f)
 23386                 x_set_gtk_user_time (f, xev->time);
 23387 #endif
 23388 
 23389               if (f)
 23390                 {
 23391                   /* If the user interacts with a frame that's focused
 23392                      on another device, but not the current focus
 23393                      frame, make it the focus frame.  */
 23394                   if (device)
 23395                     xi_handle_interaction (dpyinfo, f, device,
 23396                                            xev->time);
 23397                 }
 23398 
 23399               XKeyPressedEvent xkey;
 23400 
 23401               memset (&xkey, 0, sizeof xkey);
 23402 
 23403               xkey.type = KeyPress;
 23404               xkey.serial = xev->serial;
 23405               xkey.send_event = xev->send_event;
 23406               xkey.display = dpyinfo->display;
 23407               xkey.window = xev->event;
 23408               xkey.root = xev->root;
 23409               xkey.subwindow = xev->child;
 23410               xkey.time = xev->time;
 23411               xkey.state = xi_convert_event_keyboard_state (xev);
 23412 
 23413               xkey.x = lrint (xev->event_x);
 23414               xkey.y = lrint (xev->event_y);
 23415               xkey.x_root = lrint (xev->root_x);
 23416               xkey.y_root = lrint (xev->root_y);
 23417 
 23418               /* Some input methods react differently depending on the
 23419                  buttons that are pressed.  */
 23420               xi_convert_button_state (&xev->buttons, &xkey.state);
 23421 
 23422               xkey.keycode = xev->detail;
 23423               xkey.same_screen = True;
 23424 
 23425 #ifdef HAVE_X_I18N
 23426 #ifdef USE_GTK
 23427               if ((!x_gtk_use_native_input
 23428                    && x_filter_event (dpyinfo, (XEvent *) &xkey))
 23429                   || (x_gtk_use_native_input
 23430                       && x_filter_event (dpyinfo, event)))
 23431                 {
 23432                   /* Try to attribute core key events from the input
 23433                      method to the input extension event that caused
 23434                      them.  */
 23435                   dpyinfo->pending_keystroke_time = xev->time;
 23436                   dpyinfo->pending_keystroke_source = xev->sourceid;
 23437 
 23438                   *finish = X_EVENT_DROP;
 23439                   goto XI_OTHER;
 23440                 }
 23441 #else
 23442               if (x_filter_event (dpyinfo, (XEvent *) &xkey))
 23443                 {
 23444                   /* Try to attribute core key events from the input
 23445                      method to the input extension event that caused
 23446                      them.  */
 23447                   dpyinfo->pending_keystroke_time = xev->time;
 23448                   dpyinfo->pending_keystroke_source = xev->sourceid;
 23449 
 23450                   *finish = X_EVENT_DROP;
 23451                   goto XI_OTHER;
 23452                 }
 23453 #endif
 23454 #elif USE_GTK
 23455               if ((x_gtk_use_native_input
 23456                    || dpyinfo->prefer_native_input)
 23457                   && xg_filter_key (any, event))
 23458                 {
 23459                   /* Try to attribute core key events from the input
 23460                      method to the input extension event that caused
 23461                      them.  */
 23462                   dpyinfo->pending_keystroke_time = xev->time;
 23463                   dpyinfo->pending_keystroke_source = xev->sourceid;
 23464 
 23465                   *finish = X_EVENT_DROP;
 23466                   goto XI_OTHER;
 23467                 }
 23468 #endif
 23469 
 23470               state |= x_emacs_to_x_modifiers (dpyinfo, extra_keyboard_modifiers);
 23471 
 23472 #ifdef HAVE_XKB
 23473               if (dpyinfo->xkb_desc)
 23474                 {
 23475                   unsigned int xkb_state;
 23476 
 23477                   xkb_state = state & ~(1 << 13 | 1 << 14);
 23478                   xkb_state |= xev->group.effective << 13;
 23479 
 23480                   if (!XkbTranslateKeyCode (dpyinfo->xkb_desc, keycode,
 23481                                             xkb_state, &mods_rtrn, &keysym))
 23482                     goto XI_OTHER;
 23483                 }
 23484               else
 23485                 {
 23486 #endif
 23487                   int keysyms_per_keycode_return;
 23488                   KeySym *ksms = XGetKeyboardMapping (dpyinfo->display, keycode, 1,
 23489                                                       &keysyms_per_keycode_return);
 23490                   if (!(keysym = ksms[0]))
 23491                     {
 23492                       XFree (ksms);
 23493                       goto XI_OTHER;
 23494                     }
 23495                   XFree (ksms);
 23496 #ifdef HAVE_XKB
 23497                 }
 23498 #endif
 23499 
 23500               if (keysym == NoSymbol)
 23501                 goto XI_OTHER;
 23502 
 23503               /* If mouse-highlight is an integer, input clears out
 23504                  mouse highlighting.  */
 23505               if (!hlinfo->mouse_face_hidden && FIXNUMP (Vmouse_highlight)
 23506                   && (f == 0
 23507 #if ! defined (USE_GTK)
 23508                       || !EQ (f->tool_bar_window, hlinfo->mouse_face_window)
 23509 #endif
 23510                       || !EQ (f->tab_bar_window, hlinfo->mouse_face_window))
 23511                   )
 23512                 {
 23513                   mouse_frame = hlinfo->mouse_face_mouse_frame;
 23514 
 23515                   clear_mouse_face (hlinfo);
 23516                   hlinfo->mouse_face_hidden = true;
 23517 
 23518                   if (mouse_frame)
 23519                     x_flush_dirty_back_buffer_on (mouse_frame);
 23520                 }
 23521 
 23522               if (f != 0)
 23523                 {
 23524 #ifdef USE_GTK
 23525                   /* Don't pass keys to GTK.  A Tab will shift focus to the
 23526                      tool bar in GTK 2.4.  Keys will still go to menus and
 23527                      dialogs because in that case popup_activated is nonzero
 23528                      (see above).  */
 23529                   *finish = X_EVENT_DROP;
 23530 #endif
 23531 
 23532                   XSETFRAME (inev.ie.frame_or_window, f);
 23533                   inev.ie.timestamp = xev->time;
 23534 
 23535 #ifdef HAVE_X_I18N
 23536                   if (FRAME_XIC (f))
 23537                     {
 23538                       Status status_return;
 23539                       nbytes = XmbLookupString (FRAME_XIC (f),
 23540                                                 &xkey, (char *) copy_bufptr,
 23541                                                 copy_bufsiz, &keysym,
 23542                                                 &status_return);
 23543                       coding = FRAME_X_XIM_CODING (f);
 23544 
 23545                       if (status_return == XBufferOverflow)
 23546                         {
 23547                           copy_bufsiz = nbytes + 1;
 23548                           copy_bufptr = SAFE_ALLOCA (copy_bufsiz);
 23549                           nbytes = XmbLookupString (FRAME_XIC (f),
 23550                                                     &xkey, (char *) copy_bufptr,
 23551                                                     copy_bufsiz, &keysym,
 23552                                                     &status_return);
 23553                         }
 23554 
 23555                       if (status_return == XLookupNone)
 23556                         goto xi_done_keysym;
 23557                       else if (status_return == XLookupChars)
 23558                         {
 23559                           keysym = NoSymbol;
 23560                           state = 0;
 23561                         }
 23562                       else if (status_return != XLookupKeySym
 23563                                && status_return != XLookupBoth)
 23564                         emacs_abort ();
 23565                     }
 23566                   else
 23567 #endif
 23568                     {
 23569 #ifdef HAVE_XKB
 23570                       int overflow = 0;
 23571                       KeySym sym = keysym;
 23572 
 23573                       if (dpyinfo->xkb_desc)
 23574                         {
 23575                           nbytes = XkbTranslateKeySym (dpyinfo->display, &sym,
 23576                                                        state & ~mods_rtrn, copy_bufptr,
 23577                                                        copy_bufsiz, &overflow);
 23578                           if (overflow)
 23579                             {
 23580                               copy_bufptr = SAFE_ALLOCA ((copy_bufsiz += overflow)
 23581                                                          * sizeof *copy_bufptr);
 23582                               overflow = 0;
 23583                               nbytes = XkbTranslateKeySym (dpyinfo->display, &sym,
 23584                                                            state & ~mods_rtrn, copy_bufptr,
 23585                                                            copy_bufsiz, &overflow);
 23586 
 23587                               if (overflow)
 23588                                 nbytes = 0;
 23589                             }
 23590 
 23591                           coding = Qnil;
 23592                         }
 23593                       else
 23594 #endif
 23595                         {
 23596                           old_state = xkey.state;
 23597                           xkey.state &= ~ControlMask;
 23598                           xkey.state &= ~(dpyinfo->meta_mod_mask
 23599                                           | dpyinfo->super_mod_mask
 23600                                           | dpyinfo->hyper_mod_mask
 23601                                           | dpyinfo->alt_mod_mask);
 23602 
 23603                           nbytes = XLookupString (&xkey, copy_bufptr,
 23604                                                   copy_bufsiz, &keysym,
 23605                                                   NULL);
 23606 
 23607                           xkey.state = old_state;
 23608                         }
 23609                     }
 23610 
 23611                   inev.ie.modifiers = x_x_to_emacs_modifiers (dpyinfo, state);
 23612 
 23613 #ifdef XK_F1
 23614                   if (x_dnd_in_progress
 23615                       && xev->deviceid == x_dnd_keyboard_device
 23616                       && keysym == XK_F1)
 23617                     {
 23618                       x_dnd_xm_use_help = true;
 23619                       goto xi_done_keysym;
 23620                     }
 23621 #endif
 23622 
 23623                   /* First deal with keysyms which have defined
 23624                      translations to characters.  */
 23625                   if (keysym >= 32 && keysym < 128)
 23626                     /* Avoid explicitly decoding each ASCII character.  */
 23627                     {
 23628                       inev.ie.kind = ASCII_KEYSTROKE_EVENT;
 23629                       inev.ie.code = keysym;
 23630 
 23631                       if (source)
 23632                         inev.ie.device = source->name;
 23633 
 23634                       goto xi_done_keysym;
 23635                     }
 23636 
 23637                   /* Keysyms directly mapped to Unicode characters.  */
 23638                   if (keysym >= 0x01000000 && keysym <= 0x0110FFFF)
 23639                     {
 23640                       if (keysym < 0x01000080)
 23641                         inev.ie.kind = ASCII_KEYSTROKE_EVENT;
 23642                       else
 23643                         inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
 23644 
 23645                       if (source)
 23646                         inev.ie.device = source->name;
 23647 
 23648                       inev.ie.code = keysym & 0xFFFFFF;
 23649                       goto xi_done_keysym;
 23650                     }
 23651 
 23652                   /* Now non-ASCII.  */
 23653                   if (HASH_TABLE_P (Vx_keysym_table)
 23654                       && (c = Fgethash (make_fixnum (keysym),
 23655                                         Vx_keysym_table,
 23656                                         Qnil),
 23657                           FIXNATP (c)))
 23658                     {
 23659                       inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFIXNAT (c))
 23660                                       ? ASCII_KEYSTROKE_EVENT
 23661                                       : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
 23662                       inev.ie.code = XFIXNAT (c);
 23663 
 23664                       if (source)
 23665                         inev.ie.device = source->name;
 23666 
 23667                       goto xi_done_keysym;
 23668                     }
 23669 
 23670                   /* Random non-modifier sorts of keysyms.  */
 23671                   if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
 23672                        || keysym == XK_Delete
 23673 #ifdef XK_ISO_Left_Tab
 23674                        || (keysym >= XK_ISO_Left_Tab
 23675                            && keysym <= XK_ISO_Enter)
 23676 #endif
 23677                        || IsCursorKey (keysym) /* 0xff50 <= x < 0xff60 */
 23678                        || IsMiscFunctionKey (keysym) /* 0xff60 <= x < VARIES */
 23679 #ifdef HPUX
 23680                        /* This recognizes the "extended function
 23681                           keys".  It seems there's no cleaner way.
 23682                           Test IsModifierKey to avoid handling
 23683                           mode_switch incorrectly.  */
 23684                        || (XK_Select <= keysym && keysym < XK_KP_Space)
 23685 #endif
 23686 #ifdef XK_dead_circumflex
 23687                        || keysym == XK_dead_circumflex
 23688 #endif
 23689 #ifdef XK_dead_grave
 23690                        || keysym == XK_dead_grave
 23691 #endif
 23692 #ifdef XK_dead_tilde
 23693                        || keysym == XK_dead_tilde
 23694 #endif
 23695 #ifdef XK_dead_diaeresis
 23696                        || keysym == XK_dead_diaeresis
 23697 #endif
 23698 #ifdef XK_dead_macron
 23699                        || keysym == XK_dead_macron
 23700 #endif
 23701 #ifdef XK_dead_degree
 23702                        || keysym == XK_dead_degree
 23703 #endif
 23704 #ifdef XK_dead_acute
 23705                        || keysym == XK_dead_acute
 23706 #endif
 23707 #ifdef XK_dead_cedilla
 23708                        || keysym == XK_dead_cedilla
 23709 #endif
 23710 #ifdef XK_dead_breve
 23711                        || keysym == XK_dead_breve
 23712 #endif
 23713 #ifdef XK_dead_ogonek
 23714                        || keysym == XK_dead_ogonek
 23715 #endif
 23716 #ifdef XK_dead_caron
 23717                        || keysym == XK_dead_caron
 23718 #endif
 23719 #ifdef XK_dead_doubleacute
 23720                        || keysym == XK_dead_doubleacute
 23721 #endif
 23722 #ifdef XK_dead_abovedot
 23723                        || keysym == XK_dead_abovedot
 23724 #endif
 23725 #ifdef XK_dead_abovering
 23726                        || keysym == XK_dead_abovering
 23727 #endif
 23728 #ifdef XK_dead_belowdot
 23729                        || keysym == XK_dead_belowdot
 23730 #endif
 23731 #ifdef XK_dead_voiced_sound
 23732                        || keysym == XK_dead_voiced_sound
 23733 #endif
 23734 #ifdef XK_dead_semivoiced_sound
 23735                        || keysym == XK_dead_semivoiced_sound
 23736 #endif
 23737 #ifdef XK_dead_hook
 23738                        || keysym == XK_dead_hook
 23739 #endif
 23740 #ifdef XK_dead_horn
 23741                        || keysym == XK_dead_horn
 23742 #endif
 23743 #ifdef XK_dead_stroke
 23744                        || keysym == XK_dead_stroke
 23745 #endif
 23746 #ifdef XK_dead_abovecomma
 23747                        || keysym == XK_dead_abovecomma
 23748 #endif
 23749                        || IsKeypadKey (keysym) /* 0xff80 <= x < 0xffbe */
 23750                        || IsFunctionKey (keysym) /* 0xffbe <= x < 0xffe1 */
 23751                        /* Any "vendor-specific" key is ok.  */
 23752                        || (keysym & (1 << 28))
 23753                        || (keysym != NoSymbol && nbytes == 0))
 23754                       && ! (IsModifierKey (keysym)
 23755                             /* The symbols from XK_ISO_Lock
 23756                                to XK_ISO_Last_Group_Lock
 23757                                don't have real modifiers but
 23758                                should be treated similarly to
 23759                                Mode_switch by Emacs. */
 23760 #if defined XK_ISO_Lock && defined XK_ISO_Last_Group_Lock
 23761                             || (XK_ISO_Lock <= keysym
 23762                                 && keysym <= XK_ISO_Last_Group_Lock)
 23763 #endif
 23764                             ))
 23765                     {
 23766                       STORE_KEYSYM_FOR_DEBUG (keysym);
 23767                       /* make_lispy_event will convert this to a symbolic
 23768                          key.  */
 23769                       inev.ie.kind = NON_ASCII_KEYSTROKE_EVENT;
 23770                       inev.ie.code = keysym;
 23771 
 23772                       if (source)
 23773                         inev.ie.device = source->name;
 23774 
 23775                       goto xi_done_keysym;
 23776                     }
 23777 
 23778                   for (i = 0; i < nbytes; i++)
 23779                     {
 23780                       STORE_KEYSYM_FOR_DEBUG (copy_bufptr[i]);
 23781                     }
 23782 
 23783                   if (nbytes)
 23784                     {
 23785                       inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
 23786                       inev.ie.arg = make_unibyte_string (copy_bufptr, nbytes);
 23787 
 23788                       Fput_text_property (make_fixnum (0), make_fixnum (nbytes),
 23789                                           Qcoding, coding, inev.ie.arg);
 23790 
 23791                       if (source)
 23792                         inev.ie.device = source->name;
 23793                     }
 23794                   goto xi_done_keysym;
 23795                 }
 23796 
 23797               goto XI_OTHER;
 23798             }
 23799 
 23800 #if defined USE_GTK && !defined HAVE_GTK3
 23801           case XI_RawKeyPress:
 23802             {
 23803               XIRawEvent *raw_event = (XIRawEvent *) xi_event;
 23804 
 23805               /* This is the only way to attribute core keyboard
 23806                  events generated on GTK+ 2.x to the extension device
 23807                  that generated them.  */
 23808               dpyinfo->pending_keystroke_time = raw_event->time;
 23809               dpyinfo->pending_keystroke_source = raw_event->sourceid;
 23810               dpyinfo->pending_keystroke_time_special_p = true;
 23811               goto XI_OTHER;
 23812             }
 23813 #endif
 23814 
 23815           case XI_KeyRelease:
 23816 #if defined HAVE_X_I18N || defined USE_GTK || defined USE_LUCID
 23817             {
 23818               XKeyPressedEvent xkey;
 23819 
 23820               memset (&xkey, 0, sizeof xkey);
 23821 
 23822               xkey.type = KeyRelease;
 23823               xkey.serial = xev->serial;
 23824               xkey.send_event = xev->send_event;
 23825               xkey.display = dpyinfo->display;
 23826               xkey.window = xev->event;
 23827               xkey.root = xev->root;
 23828               xkey.subwindow = xev->child;
 23829               xkey.time = xev->time;
 23830               xkey.state = xi_convert_event_keyboard_state (xev);
 23831               xkey.x = lrint (xev->event_x);
 23832               xkey.y = lrint (xev->event_y);
 23833               xkey.x_root = lrint (xev->root_x);
 23834               xkey.y_root = lrint (xev->root_y);
 23835 
 23836               /* Some input methods react differently depending on the
 23837                  buttons that are pressed.  */
 23838               xi_convert_button_state (&xev->buttons, &xkey.state);
 23839 
 23840               xkey.keycode = xev->detail;
 23841               xkey.same_screen = True;
 23842 
 23843 #ifdef USE_LUCID
 23844               if (!popup_activated ())
 23845                 {
 23846 #endif
 23847 #ifdef HAVE_X_I18N
 23848                   if (x_filter_event (dpyinfo, (XEvent *) &xkey))
 23849                     *finish = X_EVENT_DROP;
 23850 #elif defined USE_GTK
 23851                   f = x_any_window_to_frame (xkey->event);
 23852 
 23853                   if (f && xg_filter_key (f, event))
 23854                     *finish = X_EVENT_DROP;
 23855 #endif
 23856 #ifdef USE_LUCID
 23857                 }
 23858               else
 23859                 {
 23860                   /* FIXME: the Lucid menu bar pops down upon any key
 23861                      release event, so we don't dispatch these events
 23862                      at all, which doesn't seem to be the right
 23863                      solution.
 23864 
 23865                      use_copy = true;
 23866                      copy.xkey = xkey; */
 23867                 }
 23868 #endif
 23869             }
 23870 #endif
 23871 
 23872             goto XI_OTHER;
 23873 
 23874           case XI_PropertyEvent:
 23875             goto XI_OTHER;
 23876 
 23877           case XI_HierarchyChanged:
 23878             {
 23879               XIHierarchyEvent *hev;
 23880               XIDeviceInfo *info;
 23881               int i, ndevices, n_disabled, *disabled;
 23882               struct xi_device_t *device;
 23883               bool any_changed;
 23884 
 23885               any_changed = false;
 23886               hev = (XIHierarchyEvent *) xi_event;
 23887               disabled = SAFE_ALLOCA (sizeof *disabled * hev->num_info);
 23888               n_disabled = 0;
 23889 
 23890               for (i = 0; i < hev->num_info; ++i)
 23891                 {
 23892                   if (hev->info[i].flags & XIDeviceEnabled)
 23893                     {
 23894                       /* Handle all disabled devices now, to prevent
 23895                          things happening out-of-order later.  */
 23896 
 23897                       if (n_disabled)
 23898                         {
 23899                           xi_disable_devices (dpyinfo, disabled, n_disabled);
 23900                           n_disabled = 0;
 23901 
 23902                           /* This flag really just means that disabled
 23903                              devices were handled early and should be
 23904                              used in conjunction with n_disabled.  */
 23905                           any_changed = true;
 23906                         }
 23907 
 23908                       /* Under unknown circumstances, multiple
 23909                          XIDeviceEnabled events are sent at once,
 23910                          causing the device to be duplicated.  Check
 23911                          that the device doesn't exist before adding
 23912                          it.  */
 23913 
 23914                       if (!xi_device_from_id (dpyinfo,
 23915                                               hev->info[i].deviceid))
 23916                         {
 23917                           x_catch_errors (dpyinfo->display);
 23918                           info = XIQueryDevice (dpyinfo->display,
 23919                                                 hev->info[i].deviceid,
 23920                                                 &ndevices);
 23921                           x_uncatch_errors ();
 23922 
 23923                           if (info && info->enabled)
 23924                             {
 23925                               dpyinfo->devices
 23926                                 = xrealloc (dpyinfo->devices,
 23927                                             (sizeof *dpyinfo->devices
 23928                                              * ++dpyinfo->num_devices));
 23929                               memset (dpyinfo->devices + dpyinfo->num_devices - 1,
 23930                                       0, sizeof *dpyinfo->devices);
 23931                               device = &dpyinfo->devices[dpyinfo->num_devices - 1];
 23932                               xi_populate_device_from_info (dpyinfo, device, info);
 23933                             }
 23934 
 23935                           if (info)
 23936                             XIFreeDeviceInfo (info);
 23937                         }
 23938                     }
 23939                   else if (hev->info[i].flags & XIDeviceDisabled)
 23940                     disabled[n_disabled++] = hev->info[i].deviceid;
 23941                   else if (hev->info[i].flags & XISlaveDetached
 23942                            || hev->info[i].flags & XISlaveAttached)
 23943                     {
 23944                       device = xi_device_from_id (dpyinfo, hev->info[i].deviceid);
 23945                       x_catch_errors (dpyinfo->display);
 23946                       info = XIQueryDevice (dpyinfo->display, hev->info[i].deviceid,
 23947                                             &ndevices);
 23948                       x_uncatch_errors ();
 23949 
 23950                       if (info)
 23951                         {
 23952                           if (device)
 23953                             {
 23954                               device->use = info->use;
 23955                               device->attachment = info->attachment;
 23956                             }
 23957 
 23958                           /* device could have been disabled by now.
 23959                              But instead of removing it immediately,
 23960                              wait for XIDeviceDisabled, or internal
 23961                              state could be left inconsistent.  */
 23962 
 23963                           XIFreeDeviceInfo (info);
 23964                         }
 23965                     }
 23966                 }
 23967 
 23968               /* Delete all devices that were disabled by this
 23969                  event.  */
 23970               xi_disable_devices (dpyinfo, disabled, n_disabled);
 23971 
 23972               /* If the device hierarchy has been changed, recompute
 23973                  focus.  This might seem like a micro-optimization but
 23974                  it actually keeps the focus from changing in some
 23975                  cases where it would be undesierable.  */
 23976               if (any_changed || n_disabled)
 23977                 xi_handle_focus_change (dpyinfo);
 23978 
 23979               goto XI_OTHER;
 23980             }
 23981 
 23982           case XI_DeviceChanged:
 23983             {
 23984               XIDeviceChangedEvent *device_changed;
 23985               struct xi_device_t *device;
 23986 
 23987               device_changed = (XIDeviceChangedEvent *) xi_event;
 23988               device = xi_device_from_id (dpyinfo, device_changed->deviceid);
 23989 
 23990               /* If the device isn't enabled, then stop handling this
 23991                  event.  A HierarchyChanged event will be sent if it
 23992                  is enabled afterwards.  */
 23993               if (!device)
 23994                 goto XI_OTHER;
 23995 
 23996               /* Now handle the event by retrieving scroll valuators
 23997                  and touch info.  */
 23998               xi_handle_device_changed (dpyinfo, device, device_changed);
 23999               goto XI_OTHER;
 24000             }
 24001 
 24002 #ifdef HAVE_XINPUT2_2
 24003           case XI_TouchBegin:
 24004             {
 24005               struct xi_device_t *device, *source;
 24006               bool menu_bar_p = false, tool_bar_p = false;
 24007 #ifdef HAVE_GTK3
 24008               GdkRectangle test_rect;
 24009 #endif
 24010               device = xi_device_from_id (dpyinfo, xev->deviceid);
 24011               source = xi_device_from_id (dpyinfo, xev->sourceid);
 24012               x_display_set_last_user_time (dpyinfo, xev->time,
 24013                                             xev->send_event, true);
 24014 
 24015               if (!device)
 24016                 goto XI_OTHER;
 24017 
 24018               if (xi_find_touch_point (device, xev->detail))
 24019                 emacs_abort ();
 24020 
 24021               f = x_window_to_frame (dpyinfo, xev->event);
 24022 
 24023               if (f)
 24024                 /* See the comment above x_compute_root_window_offset
 24025                    for why this optimization is performed.  */
 24026                 xi_compute_root_window_offset (f, xev);
 24027 
 24028 #ifdef HAVE_GTK3
 24029               menu_bar_p = (f && FRAME_X_OUTPUT (f)->menubar_widget
 24030                             && xg_event_is_for_menubar (f, event));
 24031               if (f && FRAME_X_OUTPUT (f)->toolbar_widget)
 24032                 {
 24033                   int scale = xg_get_scale (f);
 24034 
 24035                   test_rect.x = xev->event_x / scale;
 24036                   test_rect.y = xev->event_y / scale;
 24037                   test_rect.width = 1;
 24038                   test_rect.height = 1;
 24039 
 24040                   tool_bar_p = gtk_widget_intersect (FRAME_X_OUTPUT (f)->toolbar_widget,
 24041                                                      &test_rect, NULL);
 24042                 }
 24043 #endif
 24044 
 24045               if (!menu_bar_p && !tool_bar_p)
 24046                 {
 24047                   if (f && device->direct_p)
 24048                     {
 24049                       *finish = X_EVENT_DROP;
 24050 
 24051                       x_catch_errors (dpyinfo->display);
 24052 
 24053                       if (x_input_grab_touch_events)
 24054                         XIAllowTouchEvents (dpyinfo->display, xev->deviceid,
 24055                                             xev->detail, xev->event, XIAcceptTouch);
 24056 
 24057                       if (!x_had_errors_p (dpyinfo->display))
 24058                         {
 24059                           xi_link_touch_point (device, xev->detail, xev->event_x,
 24060                                                xev->event_y);
 24061 
 24062                           inev.ie.kind = TOUCHSCREEN_BEGIN_EVENT;
 24063                           inev.ie.timestamp = xev->time;
 24064                           XSETFRAME (inev.ie.frame_or_window, f);
 24065                           XSETINT (inev.ie.x, lrint (xev->event_x));
 24066                           XSETINT (inev.ie.y, lrint (xev->event_y));
 24067                           XSETINT (inev.ie.arg, xev->detail);
 24068 
 24069                           if (source)
 24070                             inev.ie.device = source->name;
 24071                         }
 24072 
 24073                       x_uncatch_errors ();
 24074                     }
 24075 #ifndef HAVE_GTK3
 24076                   else if (x_input_grab_touch_events)
 24077                     {
 24078                       x_ignore_errors_for_next_request (dpyinfo);
 24079                       XIAllowTouchEvents (dpyinfo->display, xev->deviceid,
 24080                                           xev->detail, xev->event, XIRejectTouch);
 24081                       x_stop_ignoring_errors (dpyinfo);
 24082                     }
 24083 #endif
 24084                 }
 24085               else
 24086                 {
 24087 #ifdef HAVE_GTK3
 24088                   bool was_waiting_for_input = waiting_for_input;
 24089                   /* This hack was adopted from the NS port.  Whether
 24090                      or not it is actually safe is a different story
 24091                      altogether.  */
 24092                   if (waiting_for_input)
 24093                     waiting_for_input = 0;
 24094                   set_frame_menubar (f, true);
 24095                   waiting_for_input = was_waiting_for_input;
 24096 #endif
 24097                 }
 24098 
 24099               goto XI_OTHER;
 24100             }
 24101 
 24102           case XI_TouchUpdate:
 24103             {
 24104               struct xi_device_t *device, *source;
 24105               struct xi_touch_point_t *touchpoint;
 24106               Lisp_Object arg = Qnil;
 24107 
 24108               device = xi_device_from_id (dpyinfo, xev->deviceid);
 24109               source = xi_device_from_id (dpyinfo, xev->sourceid);
 24110               x_display_set_last_user_time (dpyinfo, xev->time,
 24111                                             xev->send_event, true);
 24112 
 24113               if (!device)
 24114                 goto XI_OTHER;
 24115 
 24116               touchpoint = xi_find_touch_point (device, xev->detail);
 24117 
 24118               if (!touchpoint)
 24119                 goto XI_OTHER;
 24120 
 24121               touchpoint->x = xev->event_x;
 24122               touchpoint->y = xev->event_y;
 24123 
 24124               f = x_window_to_frame (dpyinfo, xev->event);
 24125 
 24126               if (f && device->direct_p)
 24127                 {
 24128                   inev.ie.kind = TOUCHSCREEN_UPDATE_EVENT;
 24129                   inev.ie.timestamp = xev->time;
 24130                   XSETFRAME (inev.ie.frame_or_window, f);
 24131 
 24132                   for (touchpoint = device->touchpoints;
 24133                        touchpoint; touchpoint = touchpoint->next)
 24134                     {
 24135                       arg = Fcons (list3i (lrint (touchpoint->x),
 24136                                            lrint (touchpoint->y),
 24137                                            lrint (touchpoint->number)),
 24138                                    arg);
 24139                     }
 24140 
 24141                   if (source)
 24142                     inev.ie.device = source->name;
 24143 
 24144                   inev.ie.arg = arg;
 24145                 }
 24146 
 24147               goto XI_OTHER;
 24148             }
 24149 
 24150           case XI_TouchEnd:
 24151             {
 24152               struct xi_device_t *device, *source;
 24153               bool unlinked_p;
 24154 
 24155               device = xi_device_from_id (dpyinfo, xev->deviceid);
 24156               source = xi_device_from_id (dpyinfo, xev->sourceid);
 24157               x_display_set_last_user_time (dpyinfo, xev->time,
 24158                                             xev->send_event, true);
 24159 
 24160               if (!device)
 24161                 goto XI_OTHER;
 24162 
 24163               unlinked_p = xi_unlink_touch_point (xev->detail, device);
 24164 
 24165               if (unlinked_p)
 24166                 {
 24167                   f = x_window_to_frame (dpyinfo, xev->event);
 24168 
 24169                   if (f && device->direct_p)
 24170                     {
 24171                       inev.ie.kind = TOUCHSCREEN_END_EVENT;
 24172                       inev.ie.timestamp = xev->time;
 24173 
 24174                       XSETFRAME (inev.ie.frame_or_window, f);
 24175                       XSETINT (inev.ie.x, lrint (xev->event_x));
 24176                       XSETINT (inev.ie.y, lrint (xev->event_y));
 24177                       XSETINT (inev.ie.arg, xev->detail);
 24178 
 24179                       if (source)
 24180                         inev.ie.device = source->name;
 24181                     }
 24182                 }
 24183 
 24184               goto XI_OTHER;
 24185             }
 24186 
 24187 #endif
 24188 
 24189 #ifdef HAVE_XINPUT2_4
 24190           case XI_GesturePinchBegin:
 24191           case XI_GesturePinchUpdate:
 24192             {
 24193               XIGesturePinchEvent *pev = (XIGesturePinchEvent *) xi_event;
 24194               struct xi_device_t *device, *source;
 24195 
 24196               device = xi_device_from_id (dpyinfo, pev->deviceid);
 24197               source = xi_device_from_id (dpyinfo, pev->sourceid);
 24198               x_display_set_last_user_time (dpyinfo, pev->time,
 24199                                             pev->send_event, true);
 24200 
 24201               if (!device)
 24202                 goto XI_OTHER;
 24203 
 24204 #ifdef HAVE_XWIDGETS
 24205               struct xwidget_view *xvw = xwidget_view_from_window (pev->event);
 24206 
 24207               if (xvw)
 24208                 {
 24209                   *finish = X_EVENT_DROP;
 24210                   xwidget_pinch (xvw, pev);
 24211                   goto XI_OTHER;
 24212                 }
 24213 #endif
 24214 
 24215               any = x_window_to_frame (dpyinfo, pev->event);
 24216 
 24217               if (any)
 24218                 {
 24219                   if (pev->event == FRAME_X_WINDOW (any))
 24220                     xi_compute_root_window_offset_pinch (any, pev);
 24221 
 24222                   inev.ie.kind = PINCH_EVENT;
 24223                   inev.ie.modifiers
 24224                     = x_x_to_emacs_modifiers (dpyinfo, pev->mods.effective);
 24225 
 24226                   XSETINT (inev.ie.x, lrint (pev->event_x));
 24227                   XSETINT (inev.ie.y, lrint (pev->event_y));
 24228                   XSETFRAME (inev.ie.frame_or_window, any);
 24229                   inev.ie.arg = list4 (make_float (pev->delta_x),
 24230                                        make_float (pev->delta_y),
 24231                                        make_float (pev->scale),
 24232                                        make_float (pev->delta_angle));
 24233 
 24234                   if (source)
 24235                     inev.ie.device = source->name;
 24236                 }
 24237 
 24238               /* Once again GTK seems to crash when confronted by
 24239                  events it doesn't understand.  */
 24240               *finish = X_EVENT_DROP;
 24241               goto XI_OTHER;
 24242             }
 24243 
 24244           case XI_GesturePinchEnd:
 24245             {
 24246 #if defined HAVE_XWIDGETS
 24247               XIGesturePinchEvent *pev = (XIGesturePinchEvent *) xi_event;
 24248               struct xwidget_view *xvw = xwidget_view_from_window (pev->event);
 24249 
 24250               if (xvw)
 24251                 xwidget_pinch (xvw, pev);
 24252 #endif
 24253               *finish = X_EVENT_DROP;
 24254               goto XI_OTHER;
 24255             }
 24256 #endif
 24257           default:
 24258             goto XI_OTHER;
 24259           }
 24260 
 24261       xi_done_keysym:
 24262 #ifdef HAVE_X_I18N
 24263       if (f)
 24264         {
 24265           struct window *w = XWINDOW (f->selected_window);
 24266           xic_set_preeditarea (w, w->cursor.x, w->cursor.y);
 24267 
 24268           if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea))
 24269             xic_set_statusarea (f);
 24270         }
 24271 #endif
 24272         if (must_free_data)
 24273           XFreeEventData (dpyinfo->display, &event->xcookie);
 24274         goto done_keysym;
 24275 
 24276       XI_OTHER:
 24277         if (must_free_data)
 24278           XFreeEventData (dpyinfo->display, &event->xcookie);
 24279         goto OTHER;
 24280       }
 24281 #endif
 24282 
 24283     default:
 24284 #ifdef HAVE_XKB
 24285       if (dpyinfo->supports_xkb
 24286           && event->type == dpyinfo->xkb_event_type)
 24287         {
 24288           XkbEvent *xkbevent = (XkbEvent *) event;
 24289 
 24290           if (xkbevent->any.xkb_type == XkbNewKeyboardNotify
 24291               || xkbevent->any.xkb_type == XkbMapNotify)
 24292             {
 24293               XkbRefreshKeyboardMapping (&xkbevent->map);
 24294 
 24295               if (dpyinfo->xkb_desc)
 24296                 {
 24297                   if (XkbGetUpdatedMap (dpyinfo->display,
 24298                                         (XkbKeySymsMask
 24299                                          | XkbKeyTypesMask
 24300                                          | XkbModifierMapMask
 24301                                          | XkbVirtualModsMask),
 24302                                         dpyinfo->xkb_desc) == Success)
 24303                     XkbGetNames (dpyinfo->display, XkbAllNamesMask,
 24304                                  dpyinfo->xkb_desc);
 24305                   else
 24306                     {
 24307                       XkbFreeKeyboard (dpyinfo->xkb_desc,
 24308                                        XkbAllComponentsMask, True);
 24309                       dpyinfo->xkb_desc = NULL;
 24310                     }
 24311                 }
 24312               else
 24313                 {
 24314                   dpyinfo->xkb_desc = XkbGetMap (dpyinfo->display,
 24315                                                  (XkbKeySymsMask
 24316                                                   | XkbKeyTypesMask
 24317                                                   | XkbModifierMapMask
 24318                                                   | XkbVirtualModsMask),
 24319                                                  XkbUseCoreKbd);
 24320 
 24321                   if (dpyinfo->xkb_desc)
 24322                     XkbGetNames (dpyinfo->display, XkbAllNamesMask,
 24323                                  dpyinfo->xkb_desc);
 24324                 }
 24325 
 24326               x_find_modifier_meanings (dpyinfo);
 24327             }
 24328           else if (x_dnd_in_progress
 24329                    && xkbevent->any.xkb_type == XkbStateNotify)
 24330             x_dnd_keyboard_state = (xkbevent->state.mods
 24331                                     | xkbevent->state.ptr_buttons);
 24332         }
 24333 #endif
 24334 #ifdef HAVE_XSHAPE
 24335       if (dpyinfo->xshape_supported_p
 24336           && event->type == dpyinfo->xshape_event_base + ShapeNotify
 24337           && x_dnd_in_progress && x_dnd_use_toplevels
 24338           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 24339         {
 24340 #ifndef USE_GTK
 24341           XEvent xevent;
 24342 #endif
 24343           XShapeEvent *xse = (XShapeEvent *) event;
 24344 #if defined HAVE_XCB_SHAPE && defined HAVE_XCB_SHAPE_INPUT_RECTS
 24345           xcb_shape_get_rectangles_cookie_t bounding_rect_cookie;
 24346           xcb_shape_get_rectangles_reply_t *bounding_rect_reply;
 24347           xcb_rectangle_iterator_t bounding_rect_iterator;
 24348 
 24349           xcb_shape_get_rectangles_cookie_t input_rect_cookie;
 24350           xcb_shape_get_rectangles_reply_t *input_rect_reply;
 24351           xcb_rectangle_iterator_t input_rect_iterator;
 24352 
 24353           xcb_generic_error_t *error;
 24354 #else
 24355           XRectangle *rects;
 24356           int rc, ordering;
 24357 #endif
 24358 
 24359           /* Somehow this really interferes with GTK's own processing
 24360              of ShapeNotify events.  Not sure what GTK uses them for,
 24361              but we cannot skip any of them here.  */
 24362 #ifndef USE_GTK
 24363           while (XPending (dpyinfo->display))
 24364             {
 24365               XNextEvent (dpyinfo->display, &xevent);
 24366 
 24367               if (xevent.type == dpyinfo->xshape_event_base + ShapeNotify
 24368                   && ((XShapeEvent *) &xevent)->window == xse->window)
 24369                 xse = (XShapeEvent *) &xevent;
 24370               else
 24371                 {
 24372                   XPutBackEvent (dpyinfo->display, &xevent);
 24373                   break;
 24374                 }
 24375             }
 24376 #endif
 24377 
 24378           for (struct x_client_list_window *tem = x_dnd_toplevels; tem;
 24379                tem = tem->next)
 24380             {
 24381               if (tem->window == xse->window)
 24382                 {
 24383                   if (tem->n_input_rects != -1)
 24384                     xfree (tem->input_rects);
 24385                   if (tem->n_bounding_rects != -1)
 24386                     xfree (tem->bounding_rects);
 24387 
 24388                   tem->n_input_rects = -1;
 24389                   tem->n_bounding_rects = -1;
 24390 
 24391 #if defined HAVE_XCB_SHAPE && defined HAVE_XCB_SHAPE_INPUT_RECTS
 24392                   bounding_rect_cookie = xcb_shape_get_rectangles (dpyinfo->xcb_connection,
 24393                                                                    (xcb_window_t) xse->window,
 24394                                                                    XCB_SHAPE_SK_BOUNDING);
 24395                   if (dpyinfo->xshape_major > 1
 24396                       || (dpyinfo->xshape_major == 1
 24397                           && dpyinfo->xshape_minor >= 1))
 24398                     input_rect_cookie
 24399                       = xcb_shape_get_rectangles (dpyinfo->xcb_connection,
 24400                                                   (xcb_window_t) xse->window,
 24401                                                   XCB_SHAPE_SK_INPUT);
 24402 
 24403                   bounding_rect_reply = xcb_shape_get_rectangles_reply (dpyinfo->xcb_connection,
 24404                                                                         bounding_rect_cookie,
 24405                                                                         &error);
 24406 
 24407                   if (bounding_rect_reply)
 24408                     {
 24409                       bounding_rect_iterator
 24410                         = xcb_shape_get_rectangles_rectangles_iterator (bounding_rect_reply);
 24411                       tem->n_bounding_rects = bounding_rect_iterator.rem + 1;
 24412                       tem->bounding_rects = xmalloc (tem->n_bounding_rects
 24413                                                      * sizeof *tem->bounding_rects);
 24414                       tem->n_bounding_rects = 0;
 24415 
 24416                       for (; bounding_rect_iterator.rem; xcb_rectangle_next (&bounding_rect_iterator))
 24417                         {
 24418                           tem->bounding_rects[tem->n_bounding_rects].x
 24419                             = bounding_rect_iterator.data->x;
 24420                           tem->bounding_rects[tem->n_bounding_rects].y
 24421                             = bounding_rect_iterator.data->y;
 24422                           tem->bounding_rects[tem->n_bounding_rects].width
 24423                             = bounding_rect_iterator.data->width;
 24424                           tem->bounding_rects[tem->n_bounding_rects].height
 24425                             = bounding_rect_iterator.data->height;
 24426 
 24427                           tem->n_bounding_rects++;
 24428                         }
 24429 
 24430                       free (bounding_rect_reply);
 24431                     }
 24432                   else
 24433                     free (error);
 24434 
 24435                   if (dpyinfo->xshape_major > 1
 24436                       || (dpyinfo->xshape_major == 1
 24437                           && dpyinfo->xshape_minor >= 1))
 24438                     {
 24439                       input_rect_reply = xcb_shape_get_rectangles_reply (dpyinfo->xcb_connection,
 24440                                                                          input_rect_cookie, &error);
 24441 
 24442                       if (input_rect_reply)
 24443                         {
 24444                           input_rect_iterator
 24445                             = xcb_shape_get_rectangles_rectangles_iterator (input_rect_reply);
 24446                           tem->n_input_rects = input_rect_iterator.rem + 1;
 24447                           tem->input_rects = xmalloc (tem->n_input_rects
 24448                                                       * sizeof *tem->input_rects);
 24449                           tem->n_input_rects = 0;
 24450 
 24451                           for (; input_rect_iterator.rem; xcb_rectangle_next (&input_rect_iterator))
 24452                             {
 24453                               tem->input_rects[tem->n_input_rects].x
 24454                                 = input_rect_iterator.data->x;
 24455                               tem->input_rects[tem->n_input_rects].y
 24456                                 = input_rect_iterator.data->y;
 24457                               tem->input_rects[tem->n_input_rects].width
 24458                                 = input_rect_iterator.data->width;
 24459                               tem->input_rects[tem->n_input_rects].height
 24460                                 = input_rect_iterator.data->height;
 24461 
 24462                               tem->n_input_rects++;
 24463                             }
 24464 
 24465                           free (input_rect_reply);
 24466                         }
 24467                       else
 24468                         free (error);
 24469                     }
 24470 #else
 24471                   x_catch_errors (dpyinfo->display);
 24472                   rects = XShapeGetRectangles (dpyinfo->display,
 24473                                                xse->window,
 24474                                                ShapeBounding,
 24475                                                &count, &ordering);
 24476                   rc = x_had_errors_p (dpyinfo->display);
 24477                   x_uncatch_errors_after_check ();
 24478 
 24479                   /* Does XShapeGetRectangles allocate anything upon an
 24480                      error?  */
 24481                   if (!rc)
 24482                     {
 24483                       tem->n_bounding_rects = count;
 24484                       tem->bounding_rects
 24485                         = xmalloc (sizeof *tem->bounding_rects * count);
 24486                       memcpy (tem->bounding_rects, rects,
 24487                               sizeof *tem->bounding_rects * count);
 24488 
 24489                       XFree (rects);
 24490                     }
 24491 
 24492 #ifdef ShapeInput
 24493                   if (dpyinfo->xshape_major > 1
 24494                       || (dpyinfo->xshape_major == 1
 24495                           && dpyinfo->xshape_minor >= 1))
 24496                     {
 24497                       x_catch_errors (dpyinfo->display);
 24498                       rects = XShapeGetRectangles (dpyinfo->display,
 24499                                                    xse->window, ShapeInput,
 24500                                                    &count, &ordering);
 24501                       rc = x_had_errors_p (dpyinfo->display);
 24502                       x_uncatch_errors_after_check ();
 24503 
 24504                       /* Does XShapeGetRectangles allocate anything upon
 24505                          an error?  */
 24506                       if (!rc)
 24507                         {
 24508                           tem->n_input_rects = count;
 24509                           tem->input_rects
 24510                             = xmalloc (sizeof *tem->input_rects * count);
 24511                           memcpy (tem->input_rects, rects,
 24512                                   sizeof *tem->input_rects * count);
 24513 
 24514                           XFree (rects);
 24515                         }
 24516                     }
 24517 #endif
 24518 #endif
 24519 
 24520                   /* Handle the common case where the input shape equals the
 24521                      bounding shape.  */
 24522 
 24523                   if (tem->n_input_rects != -1
 24524                       && tem->n_bounding_rects == tem->n_input_rects
 24525                       && !memcmp (tem->bounding_rects, tem->input_rects,
 24526                                   tem->n_input_rects * sizeof *tem->input_rects))
 24527                     {
 24528                       xfree (tem->input_rects);
 24529                       tem->n_input_rects = -1;
 24530                     }
 24531 
 24532                   /* And the common case where there is no input rect and the
 24533                      bounding rect equals the window dimensions.  */
 24534 
 24535                   if (tem->n_input_rects == -1
 24536                       && tem->n_bounding_rects == 1
 24537                       && tem->bounding_rects[0].width == tem->width
 24538                       && tem->bounding_rects[0].height == tem->height
 24539                       && tem->bounding_rects[0].x == -tem->border_width
 24540                       && tem->bounding_rects[0].y == -tem->border_width)
 24541                     {
 24542                       xfree (tem->bounding_rects);
 24543                       tem->n_bounding_rects = -1;
 24544                     }
 24545 
 24546                   break;
 24547                 }
 24548             }
 24549         }
 24550 #endif
 24551 #if defined HAVE_XRANDR && !defined USE_GTK
 24552       if (dpyinfo->xrandr_supported_p
 24553           && (event->type == (dpyinfo->xrandr_event_base
 24554                               + RRScreenChangeNotify)
 24555               || event->type == (dpyinfo->xrandr_event_base
 24556                                  + RRNotify)))
 24557         {
 24558           Time timestamp;
 24559           Lisp_Object current_monitors;
 24560           XRRScreenChangeNotifyEvent *notify;
 24561 
 24562           if (event->type == (dpyinfo->xrandr_event_base
 24563                               + RRScreenChangeNotify))
 24564             XRRUpdateConfiguration ((XEvent *) event);
 24565 
 24566           if (event->type == (dpyinfo->xrandr_event_base
 24567                               + RRScreenChangeNotify))
 24568             {
 24569               notify = ((XRRScreenChangeNotifyEvent *) event);
 24570               timestamp = notify->timestamp;
 24571 
 24572               /* Don't set screen dimensions if the notification is
 24573                  for a different screen.  */
 24574               if (notify->root == dpyinfo->root_window)
 24575                 {
 24576                   dpyinfo->screen_width = notify->width;
 24577                   dpyinfo->screen_height = notify->height;
 24578                   dpyinfo->screen_mm_width = notify->mwidth;
 24579                   dpyinfo->screen_mm_height = notify->mheight;
 24580                 }
 24581             }
 24582           else
 24583             timestamp = 0;
 24584 
 24585           if (x_find_monitors_changed_event (dpyinfo))
 24586             /* Don't store a MONITORS_CHANGED_EVENT if there is
 24587                already an undelivered event on the queue.  */
 24588             goto OTHER;
 24589 
 24590           inev.ie.kind = MONITORS_CHANGED_EVENT;
 24591           inev.ie.timestamp = timestamp;
 24592           XSETTERMINAL (inev.ie.arg, dpyinfo->terminal);
 24593 
 24594           /* Also don't do anything if the monitor configuration
 24595              didn't really change.  */
 24596 
 24597           current_monitors
 24598             = Fx_display_monitor_attributes_list (inev.ie.arg);
 24599 
 24600           if (!NILP (Fequal (current_monitors,
 24601                              dpyinfo->last_monitor_attributes_list)))
 24602             inev.ie.kind = NO_EVENT;
 24603 
 24604           dpyinfo->last_monitor_attributes_list = current_monitors;
 24605 
 24606           if (x_dnd_in_progress && x_dnd_update_tooltip)
 24607             x_dnd_monitors = current_monitors;
 24608 
 24609           if (inev.ie.kind != NO_EVENT)
 24610             x_dnd_update_tooltip_now ();
 24611         }
 24612 #endif
 24613 #ifdef HAVE_XFIXES
 24614       if (dpyinfo->xfixes_supported_p
 24615           && event->type == (dpyinfo->xfixes_event_base
 24616                              + XFixesSelectionNotify)
 24617           && x_handle_selection_monitor_event (dpyinfo, event))
 24618         /* GTK 3 crashes if an XFixesSelectionNotify arrives with a
 24619            window other than the root window, because it wants to know
 24620            the screen in order to determine the compositing manager
 24621            selection name.  (bug#58584) */
 24622         *finish = X_EVENT_DROP;
 24623 #endif
 24624     OTHER:
 24625 #ifdef USE_X_TOOLKIT
 24626       if (*finish != X_EVENT_DROP)
 24627         {
 24628           /* Ignore some obviously bogus ConfigureNotify events that
 24629              other clients have been known to send Emacs.
 24630              (bug#54051) */
 24631           if (event->type != ConfigureNotify
 24632               || (event->xconfigure.width != 0
 24633                   && event->xconfigure.height != 0))
 24634             {
 24635 #if defined USE_X_TOOLKIT && defined HAVE_XINPUT2
 24636               XtDispatchEvent (use_copy ? &copy : (XEvent *) event);
 24637 #else
 24638               XtDispatchEvent ((XEvent *) event);
 24639 #endif
 24640             }
 24641         }
 24642 #endif /* USE_X_TOOLKIT */
 24643 #if defined USE_GTK && !defined HAVE_GTK3 && defined HAVE_XINPUT2
 24644       if (*finish != X_EVENT_DROP && copy)
 24645         {
 24646           gtk_main_do_event (copy);
 24647           *finish = X_EVENT_DROP;
 24648         }
 24649 
 24650       if (copy)
 24651         gdk_event_free (copy);
 24652 #endif
 24653     break;
 24654     }
 24655 
 24656  done:
 24657   if (inev.ie.kind != NO_EVENT)
 24658     {
 24659       kbd_buffer_store_buffered_event (&inev, hold_quit);
 24660       count++;
 24661     }
 24662 
 24663   if (do_help
 24664       && !(hold_quit && hold_quit->kind != NO_EVENT))
 24665     {
 24666       Lisp_Object frame;
 24667 
 24668       if (f)
 24669         XSETFRAME (frame, f);
 24670       else
 24671         frame = Qnil;
 24672 
 24673       if (do_help > 0)
 24674         {
 24675           any_help_event_p = true;
 24676 #ifdef HAVE_XINPUT2
 24677           if (gen_help_device)
 24678             xi_handle_interaction (dpyinfo, f,
 24679                                    gen_help_device,
 24680                                    gen_help_time);
 24681 #endif
 24682           gen_help_event (help_echo_string, frame, help_echo_window,
 24683                           help_echo_object, help_echo_pos);
 24684         }
 24685       else
 24686         {
 24687           help_echo_string = Qnil;
 24688           gen_help_event (Qnil, frame, Qnil, Qnil, 0);
 24689         }
 24690       count++;
 24691     }
 24692 
 24693 #if defined HAVE_XINPUT2 || defined HAVE_XKB || defined HAVE_X_I18N
 24694   SAFE_FREE ();
 24695 #endif
 24696 
 24697   return count;
 24698 }
 24699 
 24700 /* Handles the XEvent EVENT on display DISPLAY.
 24701    This is used for event loops outside the normal event handling,
 24702    i.e. looping while a popup menu or a dialog is posted.
 24703 
 24704    Returns the value handle_one_xevent sets in the finish argument.  */
 24705 
 24706 #ifdef USE_GTK
 24707 static int
 24708 #else
 24709 int
 24710 #endif
 24711 x_dispatch_event (XEvent *event, Display *display)
 24712 {
 24713   struct x_display_info *dpyinfo;
 24714   int finish = X_EVENT_NORMAL;
 24715 
 24716   dpyinfo = x_display_info_for_display (display);
 24717 
 24718   if (dpyinfo)
 24719     {
 24720       /* Block input before calling x_dispatch_event.  */
 24721       block_input ();
 24722       handle_one_xevent (dpyinfo, event, &finish, 0);
 24723       unblock_input ();
 24724     }
 24725 
 24726   return finish;
 24727 }
 24728 
 24729 /* Read events coming from the X server.
 24730    Return as soon as there are no more events to be read.
 24731 
 24732    Return the number of characters stored into the buffer,
 24733    thus pretending to be `read' (except the characters we store
 24734    in the keyboard buffer can be multibyte, so are not necessarily
 24735    C chars).  */
 24736 
 24737 static int
 24738 XTread_socket (struct terminal *terminal, struct input_event *hold_quit)
 24739 {
 24740   int count = 0;
 24741   bool event_found = false;
 24742   struct x_display_info *dpyinfo = terminal->display_info.x;
 24743 
 24744   /* Don't allow XTread_socket to do anything if drag-and-drop is in
 24745      progress.  If unblock_input causes XTread_socket to be called and
 24746      read X events while the drag-and-drop event loop is in progress,
 24747      things can go wrong very quick.
 24748 
 24749      When x_dnd_unwind_flag is true, the above doesn't apply, since
 24750      the surrounding code takes special precautions to keep it safe.
 24751 
 24752      That doesn't matter for events from displays other than the
 24753      display of the drag-and-drop operation, though.  */
 24754   if (!x_dnd_unwind_flag
 24755       && ((x_dnd_in_progress
 24756            && dpyinfo->display == FRAME_X_DISPLAY (x_dnd_frame))
 24757           || (x_dnd_waiting_for_finish
 24758               && dpyinfo->display == x_dnd_finish_display)))
 24759     return 0;
 24760 
 24761   x_clean_failable_requests (dpyinfo);
 24762 
 24763   block_input ();
 24764 
 24765   /* For debugging, this gives a way to fake an I/O error.  */
 24766   if (dpyinfo == XTread_socket_fake_io_error)
 24767     {
 24768       XTread_socket_fake_io_error = 0;
 24769       x_io_error_quitter (dpyinfo->display);
 24770     }
 24771 
 24772 #ifndef USE_GTK
 24773   while (XPending (dpyinfo->display))
 24774     {
 24775       int finish;
 24776       XEvent event;
 24777 
 24778       XNextEvent (dpyinfo->display, &event);
 24779 
 24780 #ifdef HAVE_X_I18N
 24781       /* Filter events for the current X input method.  */
 24782 #ifdef HAVE_XINPUT2
 24783       if (event.type != GenericEvent
 24784           || !dpyinfo->supports_xi2
 24785           || event.xgeneric.extension != dpyinfo->xi2_opcode)
 24786         {
 24787           /* Input extension key events are filtered inside
 24788              handle_one_xevent.  */
 24789 #endif
 24790           if (x_filter_event (dpyinfo, &event))
 24791             continue;
 24792 #ifdef HAVE_XINPUT2
 24793         }
 24794 #endif
 24795 #endif
 24796       event_found = true;
 24797 
 24798       count += handle_one_xevent (dpyinfo, &event, &finish, hold_quit);
 24799 
 24800       if (finish == X_EVENT_GOTO_OUT)
 24801         break;
 24802     }
 24803 
 24804 #else /* USE_GTK */
 24805 
 24806   /* For GTK we must use the GTK event loop.  But XEvents gets passed
 24807      to our filter function above, and then to the big event switch.
 24808      We use a bunch of globals to communicate with our filter function,
 24809      that is kind of ugly, but it works.
 24810 
 24811      There is no way to do one display at the time, GTK just does events
 24812      from all displays.  */
 24813 
 24814   while (gtk_events_pending ())
 24815     {
 24816       current_count = count;
 24817       current_hold_quit = hold_quit;
 24818 
 24819       gtk_main_iteration ();
 24820 
 24821       count = current_count;
 24822       current_count = -1;
 24823       current_hold_quit = 0;
 24824 
 24825       if (current_finish == X_EVENT_GOTO_OUT)
 24826         break;
 24827     }
 24828 
 24829   /* Now see if `xg_pending_quit_event' was set.  */
 24830   if (xg_pending_quit_event.kind != NO_EVENT)
 24831     {
 24832       /* Check that the frame is still valid.  It could have been
 24833          deleted between now and the time the event was recorded.  */
 24834       if (FRAME_LIVE_P (XFRAME (xg_pending_quit_event.frame_or_window)))
 24835         /* Store that event into hold_quit and clear the pending quit
 24836            event.  */
 24837         *hold_quit = xg_pending_quit_event;
 24838 
 24839       /* If the frame is invalid, just clear the event as well.  */
 24840       xg_pending_quit_event.kind = NO_EVENT;
 24841     }
 24842 #endif /* USE_GTK */
 24843 
 24844   /* On some systems, an X bug causes Emacs to get no more events
 24845      when the window is destroyed.  Detect that.  (1994.)  */
 24846   if (! event_found)
 24847     {
 24848       /* Emacs and the X Server eats up CPU time if XNoOp is done every time.
 24849          One XNOOP in 100 loops will make Emacs terminate.
 24850          B. Bretthauer, 1994 */
 24851       x_noop_count++;
 24852       if (x_noop_count >= 100)
 24853         {
 24854           x_noop_count=0;
 24855 
 24856           if (next_noop_dpyinfo == 0)
 24857             next_noop_dpyinfo = x_display_list;
 24858 
 24859           XNoOp (next_noop_dpyinfo->display);
 24860 
 24861           /* Each time we get here, cycle through the displays now open.  */
 24862           next_noop_dpyinfo = next_noop_dpyinfo->next;
 24863         }
 24864     }
 24865 
 24866   /* If the focus was just given to an auto-raising frame,
 24867      raise it now.  FIXME: handle more than one such frame.  */
 24868   if (dpyinfo->x_pending_autoraise_frame)
 24869     {
 24870       x_raise_frame (dpyinfo->x_pending_autoraise_frame);
 24871       dpyinfo->x_pending_autoraise_frame = NULL;
 24872     }
 24873 
 24874   unblock_input ();
 24875 
 24876   return count;
 24877 }
 24878 
 24879 
 24880 
 24881 
 24882 /***********************************************************************
 24883                              Text Cursor
 24884  ***********************************************************************/
 24885 
 24886 /* Set clipping for output in glyph row ROW.  W is the window in which
 24887    we operate.  GC is the graphics context to set clipping in.
 24888 
 24889    ROW may be a text row or, e.g., a mode line.  Text rows must be
 24890    clipped to the interior of the window dedicated to text display,
 24891    mode lines must be clipped to the whole window.  */
 24892 
 24893 static void
 24894 x_clip_to_row (struct window *w, struct glyph_row *row,
 24895                enum glyph_row_area area, GC gc)
 24896 {
 24897   struct frame *f = XFRAME (WINDOW_FRAME (w));
 24898   XRectangle clip_rect;
 24899   int window_x, window_y, window_width;
 24900 
 24901   window_box (w, area, &window_x, &window_y, &window_width, 0);
 24902 
 24903   clip_rect.x = window_x;
 24904   clip_rect.y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, row->y));
 24905   clip_rect.y = max (clip_rect.y, window_y);
 24906   clip_rect.width = window_width;
 24907   clip_rect.height = row->visible_height;
 24908 
 24909   x_set_clip_rectangles (f, gc, &clip_rect, 1);
 24910 }
 24911 
 24912 
 24913 /* Draw a hollow box cursor on window W in glyph row ROW.  */
 24914 
 24915 static void
 24916 x_draw_hollow_cursor (struct window *w, struct glyph_row *row)
 24917 {
 24918   struct frame *f = XFRAME (WINDOW_FRAME (w));
 24919   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 24920   Display *dpy = FRAME_X_DISPLAY (f);
 24921   int x, y, wd, h;
 24922   XGCValues xgcv;
 24923   struct glyph *cursor_glyph;
 24924   GC gc;
 24925 
 24926   /* Get the glyph the cursor is on.  If we can't tell because
 24927      the current matrix is invalid or such, give up.  */
 24928   cursor_glyph = get_phys_cursor_glyph (w);
 24929   if (cursor_glyph == NULL)
 24930     return;
 24931 
 24932   /* Compute frame-relative coordinates for phys cursor.  */
 24933   get_phys_cursor_geometry (w, row, cursor_glyph, &x, &y, &h);
 24934   wd = w->phys_cursor_width - 1;
 24935 
 24936   /* The foreground of cursor_gc is typically the same as the normal
 24937      background color, which can cause the cursor box to be invisible.  */
 24938   xgcv.foreground = f->output_data.x->cursor_pixel;
 24939   xgcv.line_width = 1;
 24940   if (dpyinfo->scratch_cursor_gc)
 24941     XChangeGC (dpy, dpyinfo->scratch_cursor_gc, GCForeground | GCLineWidth, &xgcv);
 24942   else
 24943     dpyinfo->scratch_cursor_gc = XCreateGC (dpy, FRAME_X_DRAWABLE (f),
 24944                                             GCForeground | GCLineWidth, &xgcv);
 24945   gc = dpyinfo->scratch_cursor_gc;
 24946 
 24947   /* When on R2L character, show cursor at the right edge of the
 24948      glyph, unless the cursor box is as wide as the glyph or wider
 24949      (the latter happens when x-stretch-cursor is non-nil).  */
 24950   if ((cursor_glyph->resolved_level & 1) != 0
 24951       && cursor_glyph->pixel_width > wd)
 24952     {
 24953       x += cursor_glyph->pixel_width - wd;
 24954       if (wd > 0)
 24955         wd -= 1;
 24956     }
 24957   /* Set clipping, draw the rectangle, and reset clipping again.  */
 24958   x_clip_to_row (w, row, TEXT_AREA, gc);
 24959   x_draw_rectangle (f, gc, x, y, wd, h - 1);
 24960   x_reset_clip_rectangles (f, gc);
 24961 }
 24962 
 24963 
 24964 /* Draw a bar cursor on window W in glyph row ROW.
 24965 
 24966    Implementation note: One would like to draw a bar cursor with an
 24967    angle equal to the one given by the font property XA_ITALIC_ANGLE.
 24968    Unfortunately, I didn't find a font yet that has this property set.
 24969    --gerd.  */
 24970 
 24971 static void
 24972 x_draw_bar_cursor (struct window *w, struct glyph_row *row, int width, enum text_cursor_kinds kind)
 24973 {
 24974   struct frame *f = XFRAME (w->frame);
 24975   struct glyph *cursor_glyph;
 24976 
 24977   /* If cursor is out of bounds, don't draw garbage.  This can happen
 24978      in mini-buffer windows when switching between echo area glyphs
 24979      and mini-buffer.  */
 24980   cursor_glyph = get_phys_cursor_glyph (w);
 24981   if (cursor_glyph == NULL)
 24982     return;
 24983 
 24984   /* Experimental avoidance of cursor on xwidget.  */
 24985   if (cursor_glyph->type == XWIDGET_GLYPH)
 24986     return;
 24987 
 24988   /* If on an image, draw like a normal cursor.  That's usually better
 24989      visible than drawing a bar, esp. if the image is large so that
 24990      the bar might not be in the window.  */
 24991   if (cursor_glyph->type == IMAGE_GLYPH)
 24992     {
 24993       struct glyph_row *r;
 24994       r = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
 24995       draw_phys_cursor_glyph (w, r, DRAW_CURSOR);
 24996     }
 24997   else
 24998     {
 24999       Display *dpy = FRAME_X_DISPLAY (f);
 25000       Drawable drawable = FRAME_X_DRAWABLE (f);
 25001       GC gc = FRAME_DISPLAY_INFO (f)->scratch_cursor_gc;
 25002       unsigned long mask = GCForeground | GCBackground | GCGraphicsExposures;
 25003       struct face *face = FACE_FROM_ID (f, cursor_glyph->face_id);
 25004       XGCValues xgcv;
 25005 
 25006       /* If the glyph's background equals the color we normally draw
 25007          the bars cursor in, the bar cursor in its normal color is
 25008          invisible.  Use the glyph's foreground color instead in this
 25009          case, on the assumption that the glyph's colors are chosen so
 25010          that the glyph is legible.  */
 25011       if (face->background == f->output_data.x->cursor_pixel)
 25012         xgcv.background = xgcv.foreground = face->foreground;
 25013       else
 25014         xgcv.background = xgcv.foreground = f->output_data.x->cursor_pixel;
 25015       xgcv.graphics_exposures = False;
 25016       xgcv.line_width = 1;
 25017 
 25018       mask |= GCLineWidth;
 25019 
 25020       if (gc)
 25021         XChangeGC (dpy, gc, mask, &xgcv);
 25022       else
 25023         {
 25024           gc = XCreateGC (dpy, drawable, mask, &xgcv);
 25025           FRAME_DISPLAY_INFO (f)->scratch_cursor_gc = gc;
 25026         }
 25027 
 25028       x_clip_to_row (w, row, TEXT_AREA, gc);
 25029 
 25030       if (kind == BAR_CURSOR)
 25031         {
 25032           int x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
 25033 
 25034           if (width < 0)
 25035             width = FRAME_CURSOR_WIDTH (f);
 25036           width = min (cursor_glyph->pixel_width, width);
 25037 
 25038           w->phys_cursor_width = width;
 25039 
 25040           /* If the character under cursor is R2L, draw the bar cursor
 25041              on the right of its glyph, rather than on the left.  */
 25042           if ((cursor_glyph->resolved_level & 1) != 0)
 25043             x += cursor_glyph->pixel_width - width;
 25044 
 25045           x_fill_rectangle (f, gc, x,
 25046                             WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
 25047                             width, row->height, false);
 25048         }
 25049       else /* HBAR_CURSOR */
 25050         {
 25051           int dummy_x, dummy_y, dummy_h;
 25052           int x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
 25053 
 25054           if (width < 0)
 25055             width = row->height;
 25056 
 25057           width = min (row->height, width);
 25058 
 25059           get_phys_cursor_geometry (w, row, cursor_glyph, &dummy_x,
 25060                                     &dummy_y, &dummy_h);
 25061 
 25062           if ((cursor_glyph->resolved_level & 1) != 0
 25063               && cursor_glyph->pixel_width > w->phys_cursor_width - 1)
 25064             x += cursor_glyph->pixel_width - w->phys_cursor_width + 1;
 25065           x_fill_rectangle (f, gc, x,
 25066                             WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
 25067                                                      row->height - width),
 25068                             w->phys_cursor_width - 1, width, false);
 25069         }
 25070 
 25071       x_reset_clip_rectangles (f, gc);
 25072     }
 25073 }
 25074 
 25075 
 25076 /* RIF: Define cursor CURSOR on frame F.  */
 25077 
 25078 static void
 25079 x_define_frame_cursor (struct frame *f, Emacs_Cursor cursor)
 25080 {
 25081   if (!f->pointer_invisible
 25082       && f->output_data.x->current_cursor != cursor)
 25083     XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), cursor);
 25084   f->output_data.x->current_cursor = cursor;
 25085 }
 25086 
 25087 
 25088 /* RIF: Clear area on frame F.  */
 25089 
 25090 static void
 25091 x_clear_frame_area (struct frame *f, int x, int y, int width, int height)
 25092 {
 25093   x_clear_area (f, x, y, width, height);
 25094 }
 25095 
 25096 
 25097 /* RIF: Draw cursor on window W.  */
 25098 
 25099 static void
 25100 x_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, int x,
 25101                       int y, enum text_cursor_kinds cursor_type,
 25102                       int cursor_width, bool on_p, bool active_p)
 25103 {
 25104 #ifdef HAVE_X_I18N
 25105   struct frame *f = XFRAME (WINDOW_FRAME (w));
 25106 #endif
 25107 
 25108   if (on_p)
 25109     {
 25110       w->phys_cursor_type = cursor_type;
 25111       w->phys_cursor_on_p = true;
 25112 
 25113       if (glyph_row->exact_window_width_line_p
 25114           && (glyph_row->reversed_p
 25115               ? (w->phys_cursor.hpos < 0)
 25116               : (w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])))
 25117         {
 25118           glyph_row->cursor_in_fringe_p = true;
 25119           draw_fringe_bitmap (w, glyph_row, glyph_row->reversed_p);
 25120         }
 25121       else
 25122         {
 25123           switch (cursor_type)
 25124             {
 25125             case HOLLOW_BOX_CURSOR:
 25126               x_draw_hollow_cursor (w, glyph_row);
 25127               break;
 25128 
 25129             case FILLED_BOX_CURSOR:
 25130               draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
 25131               break;
 25132 
 25133             case BAR_CURSOR:
 25134               x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
 25135               break;
 25136 
 25137             case HBAR_CURSOR:
 25138               x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
 25139               break;
 25140 
 25141             case NO_CURSOR:
 25142               w->phys_cursor_width = 0;
 25143               break;
 25144 
 25145             default:
 25146               emacs_abort ();
 25147             }
 25148         }
 25149 
 25150 #ifdef HAVE_X_I18N
 25151       if (w == XWINDOW (f->selected_window))
 25152         xic_set_preeditarea (w, x, y);
 25153 #endif
 25154     }
 25155 }
 25156 
 25157 
 25158 /* Icons.  */
 25159 
 25160 /* Make the x-window of frame F use the gnu icon bitmap.  */
 25161 
 25162 static bool
 25163 x_bitmap_icon (struct frame *f, Lisp_Object file)
 25164 {
 25165   ptrdiff_t bitmap_id;
 25166 
 25167   if (FRAME_X_WINDOW (f) == 0)
 25168     return true;
 25169 
 25170   /* Free up our existing icon bitmap and mask if any.  */
 25171   if (f->output_data.x->icon_bitmap > 0)
 25172     image_destroy_bitmap (f, f->output_data.x->icon_bitmap);
 25173   f->output_data.x->icon_bitmap = 0;
 25174 
 25175   if (STRINGP (file))
 25176     {
 25177 #ifdef USE_GTK
 25178       /* Use gtk_window_set_icon_from_file () if available,
 25179          It's not restricted to bitmaps */
 25180       if (xg_set_icon (f, file))
 25181         return false;
 25182 #endif /* USE_GTK */
 25183       bitmap_id = image_create_bitmap_from_file (f, file);
 25184       x_create_bitmap_mask (f, bitmap_id);
 25185     }
 25186   else
 25187     {
 25188       /* Create the GNU bitmap and mask if necessary.  */
 25189       if (FRAME_DISPLAY_INFO (f)->icon_bitmap_id < 0)
 25190         {
 25191           ptrdiff_t rc = -1;
 25192 
 25193 #ifdef USE_GTK
 25194 
 25195           if (xg_set_icon (f, xg_default_icon_file)
 25196               || xg_set_icon_from_xpm_data (f, gnu_xpm_bits))
 25197             {
 25198               FRAME_DISPLAY_INFO (f)->icon_bitmap_id = -2;
 25199               return false;
 25200             }
 25201 
 25202 #elif defined (HAVE_XPM) && defined (HAVE_X_WINDOWS)
 25203           /* This allocates too many colors.  */
 25204           if ((FRAME_X_VISUAL_INFO (f)->class == TrueColor
 25205                || FRAME_X_VISUAL_INFO (f)->class == StaticColor
 25206                || FRAME_X_VISUAL_INFO (f)->class == StaticGray)
 25207               /* That pixmap needs about 240 colors, and we should
 25208                  also leave some more space for other colors as
 25209                  well.  */
 25210               || FRAME_X_VISUAL_INFO (f)->colormap_size >= (240 * 4))
 25211             {
 25212               rc = x_create_bitmap_from_xpm_data (f, gnu_xpm_bits);
 25213               if (rc != -1)
 25214                 FRAME_DISPLAY_INFO (f)->icon_bitmap_id = rc;
 25215             }
 25216 #endif
 25217 
 25218           /* If all else fails, use the (black and white) xbm image. */
 25219           if (rc == -1)
 25220             {
 25221               rc = image_create_bitmap_from_data (f,
 25222                                                   (char *) gnu_xbm_bits,
 25223                                                   gnu_xbm_width,
 25224                                                   gnu_xbm_height);
 25225               if (rc == -1)
 25226                 return true;
 25227 
 25228               FRAME_DISPLAY_INFO (f)->icon_bitmap_id = rc;
 25229               x_create_bitmap_mask (f, FRAME_DISPLAY_INFO (f)->icon_bitmap_id);
 25230             }
 25231         }
 25232 
 25233       /* The first time we create the GNU bitmap and mask,
 25234          this increments the ref-count one extra time.
 25235          As a result, the GNU bitmap and mask are never freed.
 25236          That way, we don't have to worry about allocating it again.  */
 25237       image_reference_bitmap (f, FRAME_DISPLAY_INFO (f)->icon_bitmap_id);
 25238 
 25239       bitmap_id = FRAME_DISPLAY_INFO (f)->icon_bitmap_id;
 25240     }
 25241 
 25242   x_wm_set_icon_pixmap (f, bitmap_id);
 25243   f->output_data.x->icon_bitmap = bitmap_id;
 25244 
 25245   return false;
 25246 }
 25247 
 25248 
 25249 /* Make the x-window of frame F use a rectangle with text.
 25250    Use ICON_NAME as the text.  */
 25251 
 25252 bool
 25253 x_text_icon (struct frame *f, const char *icon_name)
 25254 {
 25255   if (FRAME_X_WINDOW (f) == 0)
 25256     return true;
 25257 
 25258   {
 25259     XTextProperty text;
 25260     text.value = (unsigned char *) icon_name;
 25261     text.encoding = XA_STRING;
 25262     text.format = 8;
 25263     text.nitems = strlen (icon_name);
 25264     XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
 25265   }
 25266 
 25267   if (f->output_data.x->icon_bitmap > 0)
 25268     image_destroy_bitmap (f, f->output_data.x->icon_bitmap);
 25269   f->output_data.x->icon_bitmap = 0;
 25270   x_wm_set_icon_pixmap (f, 0);
 25271 
 25272   return false;
 25273 }
 25274 
 25275 
 25276 struct x_error_message_stack
 25277 {
 25278   /* Pointer to the error message of any error that was generated, or
 25279      NULL.  */
 25280   char *string;
 25281 
 25282   /* The display this error handler applies to.  */
 25283   Display *dpy;
 25284 
 25285   /* A function to call upon an error if non-NULL.  */
 25286   x_special_error_handler handler;
 25287 
 25288   /* Some data to pass to that handler function.  */
 25289   void *handler_data;
 25290 
 25291   /* The previous handler in this stack.  */
 25292   struct x_error_message_stack *prev;
 25293 
 25294   /* The first request that this error handler applies to.  Keeping
 25295      track of this allows us to avoid an XSync yet still have errors
 25296      for previously made requests be handled correctly.  */
 25297   unsigned long first_request;
 25298 };
 25299 
 25300 /* Stack of X error message handlers.  Whenever an error is generated
 25301    on a display, look in this stack for an appropriate error handler,
 25302    set its `string' to the error message and call its `handler' with
 25303    `handler_data'.  If no handler applies to the error, don't catch
 25304    it, and let it crash Emacs instead.
 25305 
 25306    This used to be a pointer to a string in which any error would be
 25307    placed before 2006.  */
 25308 static struct x_error_message_stack *x_error_message;
 25309 
 25310 /* The amount of items (depth) in that stack.  */
 25311 int x_error_message_count;
 25312 
 25313 /* Compare various request serials while handling wraparound.  Treat a
 25314    difference of more than X_ULONG_MAX / 2 as wraparound.
 25315 
 25316    Note that these functions truncate serials to 32 bits before
 25317    comparison.  */
 25318 
 25319 static bool
 25320 x_is_serial_more_than (unsigned int a, unsigned int b)
 25321 {
 25322   if (a > b)
 25323     return true;
 25324 
 25325   return (b - a > X_ULONG_MAX / 2);
 25326 }
 25327 
 25328 static bool
 25329 x_is_serial_more_than_or_equal_to (unsigned int a, unsigned int b)
 25330 {
 25331   if (a >= b)
 25332     return true;
 25333 
 25334   return (b - a > X_ULONG_MAX / 2);
 25335 }
 25336 
 25337 static bool
 25338 x_is_serial_less_than (unsigned int a, unsigned int b)
 25339 {
 25340   if (a < b)
 25341     return true;
 25342 
 25343   return (a - b > X_ULONG_MAX / 2);
 25344 }
 25345 
 25346 static bool
 25347 x_is_serial_less_than_or_equal_to (unsigned int a, unsigned int b)
 25348 {
 25349   if (a <= b)
 25350     return true;
 25351 
 25352   return (a - b > X_ULONG_MAX / 2);
 25353 }
 25354 
 25355 static struct x_error_message_stack *
 25356 x_find_error_handler (Display *dpy, XErrorEvent *event)
 25357 {
 25358   struct x_error_message_stack *stack;
 25359 
 25360   stack = x_error_message;
 25361 
 25362   while (stack)
 25363     {
 25364       if (x_is_serial_more_than_or_equal_to (event->serial,
 25365                                              stack->first_request)
 25366           && dpy == stack->dpy)
 25367         return stack;
 25368 
 25369       stack = stack->prev;
 25370     }
 25371 
 25372   return NULL;
 25373 }
 25374 
 25375 void
 25376 x_unwind_errors_to (int depth)
 25377 {
 25378   while (x_error_message_count > depth)
 25379     /* This is safe to call because we check whether or not
 25380        x_error_message->dpy is still alive before calling XSync.  */
 25381     x_uncatch_errors ();
 25382 }
 25383 
 25384 #define X_ERROR_MESSAGE_SIZE 200
 25385 
 25386 /* An X error handler which stores the error message in the first
 25387    applicable handler in the x_error_message stack.  This is called
 25388    from *x_error_handler if an x_catch_errors for DISPLAY is in
 25389    effect.  */
 25390 
 25391 static void
 25392 x_error_catcher (Display *display, XErrorEvent *event,
 25393                  struct x_error_message_stack *stack)
 25394 {
 25395   char buf[X_ERROR_MESSAGE_SIZE];
 25396 
 25397   XGetErrorText (display, event->error_code,
 25398                  buf, X_ERROR_MESSAGE_SIZE);
 25399 
 25400   if (stack->string)
 25401     xfree (stack->string);
 25402 
 25403   stack->string = xstrdup (buf);
 25404 
 25405   if (stack->handler)
 25406     stack->handler (display, event, stack->string,
 25407                     stack->handler_data);
 25408 }
 25409 
 25410 /* Begin trapping X errors for display DPY.
 25411 
 25412    After calling this function, X protocol errors generated on DPY no
 25413    longer cause Emacs to exit; instead, they are recorded in an error
 25414    handler pushed onto the stack `x_error_message'.
 25415 
 25416    Calling x_check_errors signals an Emacs error if an X error has
 25417    occurred since the last call to x_catch_errors or x_check_errors.
 25418 
 25419    Calling x_uncatch_errors resumes the normal error handling,
 25420    skipping an XSync if the last request made is known to have been
 25421    processed.  Calling x_uncatch_errors_after_check is similar, but
 25422    always skips an XSync to the server, and should be used only
 25423    immediately after x_had_errors_p or x_check_errors, or when it is
 25424    known that no requests have been made since the last x_catch_errors
 25425    call for DPY.
 25426 
 25427    There is no need to use this mechanism for ignoring errors from
 25428    single asynchronous requests, such as sending a ClientMessage to a
 25429    window that might no longer exist.  Use
 25430    x_ignore_errors_for_next_request (paired with
 25431    x_stop_ignoring_errors) instead.  */
 25432 
 25433 void
 25434 x_catch_errors_with_handler (Display *dpy, x_special_error_handler handler,
 25435                              void *handler_data)
 25436 {
 25437   struct x_error_message_stack *data;
 25438 
 25439   data = xzalloc (sizeof *data);
 25440   data->dpy = dpy;
 25441   data->handler = handler;
 25442   data->handler_data = handler_data;
 25443   data->prev = x_error_message;
 25444   data->first_request = XNextRequest (dpy);
 25445   x_error_message = data;
 25446 
 25447   ++x_error_message_count;
 25448 }
 25449 
 25450 void
 25451 x_catch_errors (Display *dpy)
 25452 {
 25453   x_catch_errors_with_handler (dpy, NULL, NULL);
 25454 }
 25455 
 25456 /* Return if errors for REQUEST should be ignored even if there is no
 25457    error handler applied.  */
 25458 static struct x_failable_request *
 25459 x_request_can_fail (struct x_display_info *dpyinfo,
 25460                     unsigned long request)
 25461 {
 25462   struct x_failable_request *failable_requests;
 25463 
 25464   for (failable_requests = dpyinfo->failable_requests;
 25465        failable_requests < dpyinfo->next_failable_request;
 25466        failable_requests++)
 25467     {
 25468       if (x_is_serial_more_than_or_equal_to (request,
 25469                                              failable_requests->start)
 25470           && (!failable_requests->end
 25471               || x_is_serial_less_than_or_equal_to (request,
 25472                                                     failable_requests->end)))
 25473         return failable_requests;
 25474     }
 25475 
 25476   return NULL;
 25477 }
 25478 
 25479 /* Remove outdated request serials from
 25480    dpyinfo->failable_requests.  */
 25481 static void
 25482 x_clean_failable_requests (struct x_display_info *dpyinfo)
 25483 {
 25484   struct x_failable_request *first, *last;
 25485 
 25486   last = dpyinfo->next_failable_request;
 25487 
 25488   for (first = dpyinfo->failable_requests; first < last; first++)
 25489     {
 25490       if (x_is_serial_more_than (first->start,
 25491                                  LastKnownRequestProcessed (dpyinfo->display))
 25492           || !first->end
 25493           || x_is_serial_more_than (first->end,
 25494                                     LastKnownRequestProcessed (dpyinfo->display)))
 25495         break;
 25496     }
 25497 
 25498   if (first != last)
 25499     memmove (&dpyinfo->failable_requests, first,
 25500              sizeof *first * (last - first));
 25501 
 25502   dpyinfo->next_failable_request = (dpyinfo->failable_requests
 25503                                     + (last - first));
 25504 }
 25505 
 25506 /* Protect a section of X requests: ignore errors generated by X
 25507    requests made from now until `x_stop_ignoring_errors'.  Each call
 25508    must be paired with a call to `x_stop_ignoring_errors', and
 25509    recursive calls inside the protected section are not allowed.
 25510 
 25511    The advantage over x_catch_errors followed by
 25512    x_uncatch_errors_after_check is that this function does not sync to
 25513    catch errors if requests were made.  It should be used instead of
 25514    those two functions for catching errors around requests that do not
 25515    require a reply.  */
 25516 
 25517 void
 25518 x_ignore_errors_for_next_request (struct x_display_info *dpyinfo)
 25519 {
 25520   struct x_failable_request *request, *max;
 25521   unsigned long next_request;
 25522 #ifdef HAVE_GTK3
 25523   GdkDisplay *gdpy;
 25524 #endif
 25525 
 25526   /* This code is not reentrant, so be sure nothing calls it
 25527      recursively in response to input.  */
 25528   block_input ();
 25529 
 25530 #ifdef HAVE_GTK3
 25531   /* GTK 3 tends to override our own error handler inside certain
 25532      callbacks, which this can be called from.  Instead of trying to
 25533      restore our own, add a trap for the following requests with
 25534      GDK as well.  */
 25535 
 25536   gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display);
 25537 
 25538   if (gdpy)
 25539     gdk_x11_display_error_trap_push (gdpy);
 25540 #endif
 25541 
 25542   if ((dpyinfo->next_failable_request
 25543        != dpyinfo->failable_requests)
 25544       && (dpyinfo->next_failable_request - 1)->end == 0)
 25545     /* A new sequence should never be started before an old one
 25546        finishes.  Use `x_catch_errors' to nest error handlers.  */
 25547     emacs_abort ();
 25548 
 25549   request = dpyinfo->next_failable_request;
 25550   max = dpyinfo->failable_requests + N_FAILABLE_REQUESTS;
 25551   next_request = XNextRequest (dpyinfo->display);
 25552 
 25553   if (request >= max)
 25554     {
 25555       /* There is no point in making this extra sync if all requests
 25556          are known to have been fully processed.  */
 25557       if ((LastKnownRequestProcessed (dpyinfo->display)
 25558            != next_request - 1))
 25559         XSync (dpyinfo->display, False);
 25560 
 25561       x_clean_failable_requests (dpyinfo);
 25562       request = dpyinfo->next_failable_request;
 25563     }
 25564 
 25565   if (request >= max)
 25566     /* A request should always be made immediately after calling this
 25567        function.  */
 25568     emacs_abort ();
 25569 
 25570   request->start = next_request;
 25571   request->end = 0;
 25572 
 25573   dpyinfo->next_failable_request++;
 25574 }
 25575 
 25576 void
 25577 x_stop_ignoring_errors (struct x_display_info *dpyinfo)
 25578 {
 25579   struct x_failable_request *range;
 25580 #ifdef HAVE_GTK3
 25581   GdkDisplay *gdpy;
 25582 #endif
 25583 
 25584   range = dpyinfo->next_failable_request - 1;
 25585   range->end = XNextRequest (dpyinfo->display) - 1;
 25586 
 25587   /* Abort if no request was made since
 25588      `x_ignore_errors_for_next_request'.  */
 25589 
 25590   if (x_is_serial_less_than (range->end, range->start))
 25591     emacs_abort ();
 25592 
 25593 #ifdef HAVE_GTK3
 25594   gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display);
 25595 
 25596   if (gdpy)
 25597     gdk_x11_display_error_trap_pop_ignored (gdpy);
 25598 #endif
 25599 
 25600   unblock_input ();
 25601 }
 25602 
 25603 /* Undo the last x_catch_errors call.
 25604    DPY should be the display that was passed to x_catch_errors.
 25605 
 25606    This version should be used only if the immediately preceding
 25607    X-protocol-related thing was x_check_errors or x_had_error_p, both
 25608    of which issue XSync calls, so we don't need to re-sync here.  */
 25609 
 25610 void
 25611 x_uncatch_errors_after_check (void)
 25612 {
 25613   struct x_error_message_stack *tmp;
 25614 
 25615   block_input ();
 25616   tmp = x_error_message;
 25617   x_error_message = x_error_message->prev;
 25618   --x_error_message_count;
 25619   if (tmp->string)
 25620     xfree (tmp->string);
 25621   xfree (tmp);
 25622   unblock_input ();
 25623 }
 25624 
 25625 /* Undo the last x_catch_errors call.  */
 25626 
 25627 void
 25628 x_uncatch_errors (void)
 25629 {
 25630   struct x_error_message_stack *tmp;
 25631   struct x_display_info *dpyinfo;
 25632 
 25633   /* In rare situations when running Emacs run in daemon mode,
 25634      shutting down an emacsclient via delete-frame can cause
 25635      x_uncatch_errors to be called when x_error_message is set to
 25636      NULL.  */
 25637   if (x_error_message == NULL)
 25638     return;
 25639 
 25640   block_input ();
 25641 
 25642   dpyinfo = x_display_info_for_display (x_error_message->dpy);
 25643 
 25644   /* The display may have been closed before this function is called.
 25645      Check if it is still open before calling XSync.  */
 25646   if (dpyinfo != 0
 25647       /* There is no point in making this extra sync if all requests
 25648          are known to have been fully processed.  */
 25649       && (LastKnownRequestProcessed (x_error_message->dpy)
 25650           != XNextRequest (x_error_message->dpy) - 1)
 25651       /* Likewise if no request was made since the trap was
 25652          installed.  */
 25653       && (NextRequest (x_error_message->dpy)
 25654           > x_error_message->first_request))
 25655     {
 25656       XSync (x_error_message->dpy, False);
 25657       x_clean_failable_requests (dpyinfo);
 25658     }
 25659 
 25660   tmp = x_error_message;
 25661   x_error_message = x_error_message->prev;
 25662   --x_error_message_count;
 25663   if (tmp->string)
 25664     xfree (tmp->string);
 25665   xfree (tmp);
 25666   unblock_input ();
 25667 }
 25668 
 25669 /* If any X protocol errors have arrived since the last call to
 25670    x_catch_errors or x_check_errors, signal an Emacs error using
 25671    sprintf (a buffer, FORMAT, the x error message text) as the text.  */
 25672 
 25673 void
 25674 x_check_errors (Display *dpy, const char *format)
 25675 {
 25676   struct x_display_info *dpyinfo;
 25677   char *string;
 25678 
 25679   /* This shouldn't happen, since x_check_errors should be called
 25680      immediately inside an x_catch_errors block.  */
 25681   if (dpy != x_error_message->dpy)
 25682     emacs_abort ();
 25683 
 25684   /* There is no point in making this extra sync if all requests
 25685      are known to have been fully processed.  */
 25686   if ((LastKnownRequestProcessed (dpy)
 25687        != XNextRequest (dpy) - 1)
 25688       && (NextRequest (dpy)
 25689           > x_error_message->first_request))
 25690     XSync (dpy, False);
 25691 
 25692   dpyinfo = x_display_info_for_display (dpy);
 25693 
 25694   /* Clean the array of failable requests, since a sync happened.  */
 25695   if (dpyinfo)
 25696     x_clean_failable_requests (dpyinfo);
 25697 
 25698   if (x_error_message->string)
 25699     {
 25700       string = alloca (strlen (x_error_message->string) + 1);
 25701       strcpy (string, x_error_message->string);
 25702 
 25703       error (format, string);
 25704     }
 25705 }
 25706 
 25707 /* Nonzero if any X protocol errors were generated since the last call
 25708    to x_catch_errors on DPY.  */
 25709 
 25710 bool
 25711 x_had_errors_p (Display *dpy)
 25712 {
 25713   struct x_display_info *dpyinfo;
 25714 
 25715   /* This shouldn't happen, since x_check_errors should be called
 25716      immediately inside an x_catch_errors block.  */
 25717   if (dpy != x_error_message->dpy)
 25718     emacs_abort ();
 25719 
 25720   /* Make sure to catch any errors incurred so far.  */
 25721   if ((LastKnownRequestProcessed (dpy)
 25722        != XNextRequest (dpy) - 1)
 25723       && (NextRequest (dpy)
 25724           > x_error_message->first_request))
 25725     XSync (dpy, False);
 25726 
 25727   dpyinfo = x_display_info_for_display (dpy);
 25728 
 25729   /* Clean the array of failable requests, since a sync happened.  */
 25730   if (dpyinfo)
 25731     x_clean_failable_requests (dpyinfo);
 25732 
 25733   return !!x_error_message->string;
 25734 }
 25735 
 25736 /* Forget about any errors we have had, since we did x_catch_errors on
 25737    DPY.  */
 25738 
 25739 void
 25740 x_clear_errors (Display *dpy)
 25741 {
 25742   /* This shouldn't happen, since x_check_errors should be called
 25743      immediately inside an x_catch_errors block.  */
 25744   if (dpy != x_error_message->dpy)
 25745     emacs_abort ();
 25746 
 25747   xfree (x_error_message->string);
 25748   x_error_message->string = NULL;
 25749 }
 25750 
 25751 #if false
 25752       /* See comment in unwind_to_catch why calling this is a bad
 25753        * idea.  --lorentey   */
 25754 /* Close off all unclosed x_catch_errors calls.  */
 25755 
 25756 void
 25757 x_fully_uncatch_errors (void)
 25758 {
 25759   while (x_error_message)
 25760     x_uncatch_errors ();
 25761 }
 25762 #endif
 25763 
 25764 #if false
 25765 static unsigned int x_wire_count;
 25766 
 25767 static int
 25768 x_trace_wire (Display *dpy)
 25769 {
 25770   fprintf (stderr, "Lib call: %u\n", ++x_wire_count);
 25771   return 0;
 25772 }
 25773 #endif
 25774 
 25775 
 25776 /************************************************************************
 25777                           Handling X errors
 25778  ************************************************************************/
 25779 
 25780 /* Error message passed to x_connection_closed.  */
 25781 
 25782 static char *error_msg;
 25783 
 25784 /* Try to find a frame in Vframe_list, and make it the selected frame.
 25785    `delete_frame' sometimes misses the initial frame for an unknown
 25786    reason when Emacs is running as a background daemon.  */
 25787 
 25788 static void
 25789 x_try_restore_frame (void)
 25790 {
 25791   Lisp_Object tail, frame;
 25792 
 25793   FOR_EACH_FRAME (tail, frame)
 25794     {
 25795       if (!NILP (do_switch_frame (frame, 0, 1, Qnil)))
 25796         return;
 25797     }
 25798 }
 25799 
 25800 /* Handle the loss of connection to display DPY.  ERROR_MESSAGE is
 25801    the text of an error message that lead to the connection loss.  */
 25802 
 25803 static void
 25804 x_connection_closed (Display *dpy, const char *error_message, bool ioerror)
 25805 {
 25806   struct x_display_info *dpyinfo;
 25807   Lisp_Object frame, tail;
 25808   specpdl_ref idx = SPECPDL_INDEX ();
 25809   Emacs_XIOErrorHandler io_error_handler;
 25810   xm_drop_start_message dmsg;
 25811   struct frame *f;
 25812   Lisp_Object minibuf_frame, tmp;
 25813   struct x_failable_request *failable;
 25814   struct x_error_message_stack *stack;
 25815   static Display *current_display;
 25816 
 25817   /* Prevent recursive calls of this function for the same display.
 25818      This is because destroying a frame might still cause an IO error
 25819      in some cases.  (bug#56528) */
 25820   if (current_display == dpy)
 25821     return;
 25822 
 25823   current_display = dpy;
 25824 
 25825   dpyinfo = x_display_info_for_display (dpy);
 25826   error_msg = alloca (strlen (error_message) + 1);
 25827   strcpy (error_msg, error_message);
 25828 
 25829   /* Inhibit redisplay while frames are being deleted. */
 25830   specbind (Qinhibit_redisplay, Qt);
 25831 
 25832   /* If drag-and-drop is in progress, cancel drag-and-drop.  If DND
 25833      frame's display is DPY, don't reset event masks or try to send
 25834      responses to other programs because the display is going
 25835      away.  */
 25836 
 25837   if (x_dnd_in_progress || x_dnd_waiting_for_finish)
 25838     {
 25839       if (!ioerror)
 25840         {
 25841           /* Handle display disconnect errors here because this function
 25842              is not reentrant at this particular spot.  */
 25843           io_error_handler = XSetIOErrorHandler (x_dnd_io_error_handler);
 25844 
 25845           if (!!sigsetjmp (x_dnd_disconnect_handler, 1)
 25846               && x_dnd_in_progress
 25847               && dpy == (x_dnd_waiting_for_finish
 25848                          ? x_dnd_finish_display
 25849                          : FRAME_X_DISPLAY (x_dnd_frame)))
 25850             {
 25851               /* Clean up drag and drop if the drag frame's display isn't
 25852                  the one being disconnected.  */
 25853               f = x_dnd_frame;
 25854 
 25855               if (x_dnd_last_seen_window != None
 25856                   && x_dnd_last_protocol_version != -1)
 25857                 x_dnd_send_leave (x_dnd_frame,
 25858                                   x_dnd_last_seen_window,
 25859                                   x_dnd_last_seen_toplevel);
 25860               else if (x_dnd_last_seen_window != None
 25861                        && !XM_DRAG_STYLE_IS_DROP_ONLY (x_dnd_last_motif_style)
 25862                        && x_dnd_last_motif_style != XM_DRAG_STYLE_NONE
 25863                        && x_dnd_motif_setup_p)
 25864                 {
 25865                   dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 25866                                                 XM_DRAG_REASON_DROP_START);
 25867                   dmsg.byte_order = XM_BYTE_ORDER_CUR_FIRST;
 25868                   dmsg.timestamp = FRAME_DISPLAY_INFO (f)->last_user_time;
 25869                   dmsg.side_effects
 25870                     = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (FRAME_DISPLAY_INFO (f),
 25871                                                                        x_dnd_wanted_action),
 25872                                            XM_DROP_SITE_VALID, x_dnd_motif_operations,
 25873                                            XM_DROP_ACTION_DROP_CANCEL);
 25874                   dmsg.x = 0;
 25875                   dmsg.y = 0;
 25876                   dmsg.index_atom = x_dnd_motif_atom;
 25877                   dmsg.source_window = FRAME_X_WINDOW (f);
 25878 
 25879                   x_dnd_send_xm_leave_for_drop (FRAME_DISPLAY_INFO (f), f,
 25880                                                 x_dnd_last_seen_window, 0);
 25881                   xm_send_drop_message (FRAME_DISPLAY_INFO (f), FRAME_X_WINDOW (f),
 25882                                         x_dnd_last_seen_window, &dmsg);
 25883                 }
 25884             }
 25885 
 25886           XSetIOErrorHandler (io_error_handler);
 25887         }
 25888 
 25889       dpyinfo = x_display_info_for_display (dpy);
 25890 
 25891       x_dnd_last_seen_window = None;
 25892       x_dnd_last_seen_toplevel = None;
 25893       x_dnd_in_progress = false;
 25894       x_dnd_waiting_for_finish = false;
 25895 
 25896       if (x_dnd_use_toplevels)
 25897         x_dnd_free_toplevels (!ioerror);
 25898 
 25899       x_dnd_return_frame_object = NULL;
 25900       x_dnd_movement_frame = NULL;
 25901       x_dnd_wheel_frame = NULL;
 25902       x_dnd_frame = NULL;
 25903     }
 25904 
 25905   if (dpyinfo)
 25906     {
 25907       /* Protect display from being closed when we delete the last
 25908          frame on it. */
 25909       dpyinfo->reference_count++;
 25910       dpyinfo->terminal->reference_count++;
 25911       if (ioerror)
 25912         dpyinfo->display = 0;
 25913     }
 25914 
 25915   /* delete_frame can still try to read async input (even though we
 25916      tell pass `noelisp'), because looking up the `delete-before'
 25917      parameter calls Fassq which then calls maybe_quit.  So block
 25918      input while deleting frames.  */
 25919   block_input ();
 25920 
 25921   /* First delete frames whose mini-buffers are on frames
 25922      that are on the dead display.  */
 25923   FOR_EACH_FRAME (tail, frame)
 25924     {
 25925       /* Tooltip frames don't have these, so avoid crashing.  */
 25926 
 25927       if (FRAME_TOOLTIP_P (XFRAME (frame)))
 25928         continue;
 25929 
 25930       minibuf_frame
 25931         = WINDOW_FRAME (XWINDOW (FRAME_MINIBUF_WINDOW (XFRAME (frame))));
 25932 
 25933       if (FRAME_X_P (XFRAME (frame))
 25934           && FRAME_X_P (XFRAME (minibuf_frame))
 25935           && ! EQ (frame, minibuf_frame)
 25936           && FRAME_DISPLAY_INFO (XFRAME (minibuf_frame)) == dpyinfo)
 25937         delete_frame (frame, Qnoelisp);
 25938     }
 25939 
 25940   /* Now delete all remaining frames on the dead display.
 25941      We are now sure none of these is used as the mini-buffer
 25942      for another frame that we need to delete.  */
 25943   FOR_EACH_FRAME (tail, frame)
 25944     if (FRAME_X_P (XFRAME (frame))
 25945         && FRAME_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
 25946       {
 25947         /* Set this to t so that delete_frame won't get confused
 25948            trying to find a replacement.  */
 25949         kset_default_minibuffer_frame (FRAME_KBOARD (XFRAME (frame)), Qt);
 25950         delete_frame (frame, Qnoelisp);
 25951       }
 25952 
 25953   /* If DPYINFO is null, this means we didn't open the display in the
 25954      first place, so don't try to close it.  */
 25955   if (dpyinfo)
 25956     {
 25957       /* We can not call XtCloseDisplay here because it calls XSync.
 25958          XSync inside the error handler apparently hangs Emacs.  On
 25959          current Xt versions, this isn't needed either.  */
 25960 #ifdef USE_GTK
 25961       /* A long-standing GTK bug prevents proper disconnect handling
 25962          <https://gitlab.gnome.org/GNOME/gtk/issues/221>.  Once,
 25963          the resulting Glib error message loop filled a user's disk.
 25964          To avoid this, kill Emacs unconditionally on disconnect.  */
 25965       shut_down_emacs (0, Qnil);
 25966       fprintf (stderr, "%s\n\
 25967 When compiled with GTK, Emacs cannot recover from X disconnects.\n\
 25968 This is a GTK bug: https://gitlab.gnome.org/GNOME/gtk/issues/221\n\
 25969 For details, see etc/PROBLEMS.\n",
 25970                error_msg);
 25971       emacs_abort ();
 25972 #endif /* USE_GTK */
 25973 
 25974       /* Indicate that this display is dead.  */
 25975       dpyinfo->display = 0;
 25976 
 25977       dpyinfo->reference_count--;
 25978       dpyinfo->terminal->reference_count--;
 25979       if (dpyinfo->reference_count != 0)
 25980         /* We have just closed all frames on this display. */
 25981         emacs_abort ();
 25982 
 25983       /* This was the last terminal remaining, so print the error
 25984          message and associated error handlers and kill Emacs.  */
 25985       if (dpyinfo->terminal == terminal_list
 25986           && !terminal_list->next_terminal)
 25987         {
 25988           fprintf (stderr, "%s\n", error_msg);
 25989 
 25990           if (!ioerror && dpyinfo)
 25991             {
 25992               /* Dump the list of error handlers for debugging
 25993                  purposes.  */
 25994 
 25995               fprintf (stderr, "X error handlers currently installed:\n");
 25996 
 25997               for (failable = dpyinfo->failable_requests;
 25998                    failable < dpyinfo->next_failable_request;
 25999                    ++failable)
 26000                 {
 26001                   if (failable->end)
 26002                     fprintf (stderr, "Ignoring errors between %lu to %lu\n",
 26003                              failable->start, failable->end);
 26004                   else
 26005                     fprintf (stderr, "Ignoring errors from %lu onwards\n",
 26006                              failable->start);
 26007                 }
 26008 
 26009               for (stack = x_error_message; stack; stack = stack->prev)
 26010                 fprintf (stderr, "Trapping errors from %lu\n",
 26011                          stack->first_request);
 26012             }
 26013         }
 26014 
 26015       XSETTERMINAL (tmp, dpyinfo->terminal);
 26016       Fdelete_terminal (tmp, Qnoelisp);
 26017     }
 26018 
 26019   /* The initial "daemon" frame is sometimes not selected by
 26020      `delete_frame' when Emacs is a background daemon.  */
 26021   if (NILP (selected_frame))
 26022     x_try_restore_frame ();
 26023 
 26024   unblock_input ();
 26025 
 26026   /* Sometimes another terminal is still alive, but deleting this
 26027      terminal caused all frames to vanish.  In that case, simply kill
 26028      Emacs, since the next redisplay will abort as there is no more
 26029      selected frame.  (bug#56528) */
 26030   if (terminal_list == 0 || NILP (selected_frame))
 26031     Fkill_emacs (make_fixnum (70), Qnil);
 26032 
 26033   totally_unblock_input ();
 26034 
 26035   unbind_to (idx, Qnil);
 26036   clear_waiting_for_input ();
 26037 
 26038   /* Here, we absolutely have to use a non-local exit (e.g. signal, throw,
 26039      longjmp), because returning from this function would get us back into
 26040      Xlib's code which will directly call `exit'.  */
 26041   current_display = NULL;
 26042   error ("%s", error_msg);
 26043 }
 26044 
 26045 static void x_error_quitter (Display *, XErrorEvent *);
 26046 
 26047 /* This is the first-level handler for X protocol errors.
 26048    It calls x_error_quitter or x_error_catcher.  */
 26049 
 26050 static int
 26051 x_error_handler (Display *display, XErrorEvent *event)
 26052 {
 26053   struct x_error_message_stack *stack;
 26054   struct x_display_info *dpyinfo;
 26055   struct x_failable_request *fail, *last;
 26056 
 26057 #if defined USE_GTK && defined HAVE_GTK3
 26058   if ((event->error_code == BadMatch
 26059        || event->error_code == BadWindow)
 26060       && event->request_code == X_SetInputFocus)
 26061     return 0;
 26062 #endif
 26063 
 26064   dpyinfo = x_display_info_for_display (display);
 26065 
 26066   if (dpyinfo)
 26067     {
 26068       fail = x_request_can_fail (dpyinfo, event->serial);
 26069 
 26070       if (fail)
 26071         {
 26072           /* Now that this request sequence has been fully handled,
 26073              remove it from the list of requests that can fail.  */
 26074 
 26075           if (event->serial == fail->end)
 26076             {
 26077               last = dpyinfo->next_failable_request;
 26078               memmove (&dpyinfo->failable_requests, fail,
 26079                        sizeof *fail * (last - fail));
 26080               dpyinfo->next_failable_request = (dpyinfo->failable_requests
 26081                                                 + (last - fail));
 26082             }
 26083 
 26084           return 0;
 26085         }
 26086     }
 26087 
 26088   /* If we try to ungrab or grab a device that doesn't exist anymore
 26089      (that happens a lot in xmenu.c), just ignore the error.  */
 26090 
 26091 #ifdef HAVE_XINPUT2
 26092   /* Handle errors from some specific XI2 requests here to avoid a
 26093      sync in handle_one_xevent.  */
 26094   if (dpyinfo && dpyinfo->supports_xi2
 26095       && event->request_code == dpyinfo->xi2_opcode
 26096       && (event->minor_code == X_XIGrabDevice
 26097           || event->minor_code == X_XIUngrabDevice
 26098           || event->minor_code == X_XIAllowEvents))
 26099     return 0;
 26100 #endif
 26101 
 26102   stack = x_find_error_handler (display, event);
 26103 
 26104   if (stack)
 26105     x_error_catcher (display, event, stack);
 26106   else
 26107     x_error_quitter (display, event);
 26108   return 0;
 26109 }
 26110 
 26111 /* This is the usual handler for X protocol errors.
 26112    It kills all frames on the display that we got the error for.
 26113    If that was the only one, it prints an error message and kills Emacs.  */
 26114 
 26115 /* .gdbinit puts a breakpoint here, so make sure it is not inlined.  */
 26116 
 26117 static void NO_INLINE
 26118 x_error_quitter (Display *display, XErrorEvent *event)
 26119 {
 26120   char buf[256], buf1[400 + INT_STRLEN_BOUND (int)
 26121                       + INT_STRLEN_BOUND (unsigned long)];
 26122 
 26123   /* Ignore BadName errors.  They can happen because of fonts
 26124      or colors that are not defined.  */
 26125 
 26126   if (event->error_code == BadName)
 26127     return;
 26128 
 26129   /* Note that there is no real way portable across R3/R4 to get the
 26130      original error handler.  */
 26131 
 26132   XGetErrorText (display, event->error_code, buf, sizeof (buf));
 26133   sprintf (buf1, "X protocol error: %s on protocol request %d\n"
 26134            "Serial no: %lu\n", buf, event->request_code,
 26135            event->serial);
 26136   x_connection_closed (display, buf1, false);
 26137 }
 26138 
 26139 
 26140 /* This is the handler for X IO errors, always.
 26141    It kills all frames on the display that we lost touch with.
 26142    If that was the only one, it prints an error message and kills Emacs.  */
 26143 
 26144 static int NO_INLINE
 26145 x_io_error_quitter (Display *display)
 26146 {
 26147   char buf[256];
 26148 
 26149   snprintf (buf, sizeof buf, "Connection lost to X server '%s'",
 26150             DisplayString (display));
 26151   x_connection_closed (display, buf, true);
 26152 
 26153   return 0;
 26154 }
 26155 
 26156 
 26157 /* Changing the font of the frame.  */
 26158 
 26159 /* Give frame F the font FONT-OBJECT as its default font.  The return
 26160    value is FONT-OBJECT.  FONTSET is an ID of the fontset for the
 26161    frame.  If it is negative, generate a new fontset from
 26162    FONT-OBJECT.  */
 26163 
 26164 static Lisp_Object
 26165 x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
 26166 {
 26167   struct font *font = XFONT_OBJECT (font_object);
 26168   int unit, font_ascent, font_descent;
 26169 
 26170   if (fontset < 0)
 26171     fontset = fontset_from_font (font_object);
 26172   FRAME_FONTSET (f) = fontset;
 26173   if (FRAME_FONT (f) == font)
 26174     /* This font is already set in frame F.  There's nothing more to
 26175        do.  */
 26176     return font_object;
 26177 
 26178   FRAME_FONT (f) = font;
 26179   FRAME_BASELINE_OFFSET (f) = font->baseline_offset;
 26180   FRAME_COLUMN_WIDTH (f) = font->average_width;
 26181   get_font_ascent_descent (font, &font_ascent, &font_descent);
 26182   FRAME_LINE_HEIGHT (f) = font_ascent + font_descent;
 26183 
 26184 #ifndef USE_X_TOOLKIT
 26185   FRAME_MENU_BAR_HEIGHT (f) = FRAME_MENU_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
 26186 #endif
 26187   /* We could use a more elaborate calculation here.  */
 26188   FRAME_TAB_BAR_HEIGHT (f) = FRAME_TAB_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
 26189 
 26190   /* Compute character columns occupied by scrollbar.
 26191 
 26192      Don't do things differently for non-toolkit scrollbars
 26193      (Bug#17163).  */
 26194   unit = FRAME_COLUMN_WIDTH (f);
 26195   if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
 26196     FRAME_CONFIG_SCROLL_BAR_COLS (f)
 26197       = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + unit - 1) / unit;
 26198   else
 26199     FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + unit - 1) / unit;
 26200 
 26201 
 26202   /* Don't change the size of a tip frame; there's no point in doing it
 26203      because it's done in Fx_show_tip, and it leads to problems because
 26204      the tip frame has no widget.  */
 26205   if (FRAME_X_WINDOW (f) != 0 && !FRAME_TOOLTIP_P (f))
 26206     adjust_frame_size
 26207       (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
 26208        FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3, false, Qfont);
 26209 
 26210 #ifdef HAVE_X_I18N
 26211   if (FRAME_XIC (f)
 26212       && (FRAME_XIC_STYLE (f) & (XIMPreeditPosition | XIMStatusArea)))
 26213     {
 26214       block_input ();
 26215       xic_set_xfontset (f, SSDATA (fontset_ascii (fontset)));
 26216       unblock_input ();
 26217     }
 26218 #endif
 26219 
 26220   return font_object;
 26221 }
 26222 
 26223 
 26224 /***********************************************************************
 26225                            X Input Methods
 26226  ***********************************************************************/
 26227 
 26228 #ifdef HAVE_X_I18N
 26229 
 26230 #ifdef HAVE_X11R6
 26231 
 26232 /* HAVE_X11R6 means Xlib conforms to the R6 specification or later.
 26233    HAVE_X11R6_XIM, OTOH, means that Emacs should try to use R6-style
 26234    callback driven input method initialization.  They are separate
 26235    because Sun apparently ships buggy Xlib with some versions of
 26236    Solaris... */
 26237 
 26238 #ifdef HAVE_X11R6_XIM
 26239 
 26240 /* If preedit text is set on F, cancel preedit, free the text, and
 26241    generate the appropriate events to cancel the preedit display.
 26242 
 26243    This is mainly useful when the connection to the IM server is
 26244    dropped during preconversion.  */
 26245 
 26246 static void
 26247 x_maybe_clear_preedit (struct frame *f)
 26248 {
 26249   struct x_output *output;
 26250   struct input_event ie;
 26251 
 26252   output = FRAME_X_OUTPUT (f);
 26253 
 26254   if (!output->preedit_chars)
 26255     return;
 26256 
 26257   EVENT_INIT (ie);
 26258   ie.kind = PREEDIT_TEXT_EVENT;
 26259   ie.arg = Qnil;
 26260   XSETFRAME (ie.frame_or_window, f);
 26261   XSETINT (ie.x, 0);
 26262   XSETINT (ie.y, 0);
 26263   kbd_buffer_store_event (&ie);
 26264 
 26265   xfree (output->preedit_chars);
 26266 
 26267   output->preedit_size = 0;
 26268   output->preedit_active = false;
 26269   output->preedit_chars = NULL;
 26270   output->preedit_caret = 0;
 26271 }
 26272 
 26273 /* XIM destroy callback function, which is called whenever the
 26274    connection to input method XIM dies.  CLIENT_DATA contains a
 26275    pointer to the x_display_info structure corresponding to XIM.  */
 26276 
 26277 static void
 26278 xim_destroy_callback (XIM xim, XPointer client_data, XPointer call_data)
 26279 {
 26280   struct x_display_info *dpyinfo = (struct x_display_info *) client_data;
 26281   Lisp_Object frame, tail;
 26282 
 26283   block_input ();
 26284 
 26285   /* No need to call XDestroyIC.. */
 26286   FOR_EACH_FRAME (tail, frame)
 26287     {
 26288       struct frame *f = XFRAME (frame);
 26289       if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo)
 26290         {
 26291           FRAME_XIC (f) = NULL;
 26292           xic_free_xfontset (f);
 26293 
 26294           /* Free the preedit text if necessary.  */
 26295           x_maybe_clear_preedit (f);
 26296         }
 26297     }
 26298 
 26299   /* No need to call XCloseIM.  */
 26300   dpyinfo->xim = NULL;
 26301   XFree (dpyinfo->xim_styles);
 26302   unblock_input ();
 26303 }
 26304 
 26305 #endif
 26306 
 26307 #endif /* HAVE_X11R6 */
 26308 
 26309 /* Open the connection to the XIM server on display DPYINFO.
 26310    RESOURCE_NAME is the resource name Emacs uses.  */
 26311 
 26312 static void
 26313 xim_open_dpy (struct x_display_info *dpyinfo, char *resource_name)
 26314 {
 26315 #ifdef HAVE_XIM
 26316   XIM xim;
 26317   const char *locale;
 26318 
 26319   if (use_xim)
 26320     {
 26321       if (dpyinfo->xim)
 26322         XCloseIM (dpyinfo->xim);
 26323       xim = XOpenIM (dpyinfo->display, dpyinfo->rdb, resource_name,
 26324                      emacs_class);
 26325       dpyinfo->xim = xim;
 26326 
 26327       if (xim)
 26328         {
 26329 #ifdef HAVE_X11R6_XIM
 26330           XIMCallback destroy;
 26331 #endif
 26332 
 26333           /* Get supported styles and XIM values.  */
 26334           XGetIMValues (xim, XNQueryInputStyle, &dpyinfo->xim_styles, NULL);
 26335 
 26336 #ifdef HAVE_X11R6_XIM
 26337           destroy.callback = xim_destroy_callback;
 26338           destroy.client_data = (XPointer)dpyinfo;
 26339           XSetIMValues (xim, XNDestroyCallback, &destroy, NULL);
 26340 #endif
 26341 
 26342           locale = XLocaleOfIM (xim);
 26343 
 26344           /* Now try to determine the coding system that should be
 26345              used.  locale is in Host Portable Character Encoding, and
 26346              as such can be passed to build_string as is.  */
 26347           dpyinfo->xim_coding = safe_call1 (Vx_input_coding_function,
 26348                                             build_string (locale));
 26349         }
 26350     }
 26351 
 26352   else
 26353 #endif /* HAVE_XIM */
 26354     dpyinfo->xim = NULL;
 26355 }
 26356 
 26357 
 26358 #ifdef HAVE_X11R6_XIM
 26359 
 26360 /* XIM instantiate callback function, which is called whenever an XIM
 26361    server is available.  DISPLAY is the display of the XIM.
 26362    CLIENT_DATA contains a pointer to an xim_inst_t structure created
 26363    when the callback was registered.  */
 26364 
 26365 static void
 26366 xim_instantiate_callback (Display *display, XPointer client_data, XPointer call_data)
 26367 {
 26368   struct xim_inst_t *xim_inst = (struct xim_inst_t *) client_data;
 26369   struct x_display_info *dpyinfo = xim_inst->dpyinfo;
 26370 
 26371   if (x_dnd_in_progress)
 26372     return;
 26373 
 26374   /* We don't support multiple XIM connections. */
 26375   if (dpyinfo->xim)
 26376     return;
 26377 
 26378   xim_open_dpy (dpyinfo, xim_inst->resource_name);
 26379 
 26380   /* Create XIC for the existing frames on the same display, as long
 26381      as they have no XIC.  */
 26382   if (dpyinfo->xim && dpyinfo->reference_count > 0)
 26383     {
 26384       Lisp_Object tail, frame;
 26385 
 26386       block_input ();
 26387       FOR_EACH_FRAME (tail, frame)
 26388         {
 26389           struct frame *f = XFRAME (frame);
 26390 
 26391           if (FRAME_X_P (f)
 26392               && FRAME_DISPLAY_INFO (f) == xim_inst->dpyinfo)
 26393             if (FRAME_XIC (f) == NULL)
 26394               {
 26395                 create_frame_xic (f);
 26396                 if (FRAME_XIC_STYLE (f) & XIMStatusArea)
 26397                   xic_set_statusarea (f);
 26398                 struct window *w = XWINDOW (f->selected_window);
 26399                 xic_set_preeditarea (w, w->cursor.x, w->cursor.y);
 26400               }
 26401         }
 26402 
 26403       unblock_input ();
 26404     }
 26405 }
 26406 
 26407 #endif /* HAVE_X11R6_XIM */
 26408 
 26409 
 26410 /* Open a connection to the XIM server on display DPYINFO.
 26411    RESOURCE_NAME is the resource name for Emacs.  On X11R5, open the
 26412    connection only at the first time.  On X11R6, open the connection
 26413    in the XIM instantiate callback function.  */
 26414 
 26415 static void
 26416 xim_initialize (struct x_display_info *dpyinfo, char *resource_name)
 26417 {
 26418   dpyinfo->xim = NULL;
 26419 #ifdef HAVE_XIM
 26420   if (use_xim)
 26421     {
 26422 #ifdef HAVE_X11R6_XIM
 26423       struct xim_inst_t *xim_inst = xmalloc (sizeof *xim_inst);
 26424       Bool ret;
 26425 
 26426       dpyinfo->xim_callback_data = xim_inst;
 26427       xim_inst->dpyinfo = dpyinfo;
 26428       xim_inst->resource_name = xstrdup (resource_name);
 26429       ret = XRegisterIMInstantiateCallback
 26430         (dpyinfo->display, dpyinfo->rdb, xim_inst->resource_name,
 26431          emacs_class, xim_instantiate_callback,
 26432          /* This is XPointer in XFree86 but (XPointer *) on Tru64, at
 26433             least, but the configure test doesn't work because
 26434             xim_instantiate_callback can either be XIMProc or
 26435             XIDProc, so just cast to void *.  */
 26436          (void *) xim_inst);
 26437       eassert (ret == True);
 26438 #else /* not HAVE_X11R6_XIM */
 26439       xim_open_dpy (dpyinfo, resource_name);
 26440 #endif /* not HAVE_X11R6_XIM */
 26441     }
 26442 #endif /* HAVE_XIM */
 26443 }
 26444 
 26445 
 26446 /* Close the connection to the XIM server on display DPYINFO. */
 26447 
 26448 static void
 26449 xim_close_dpy (struct x_display_info *dpyinfo)
 26450 {
 26451 #ifdef HAVE_XIM
 26452   if (use_xim)
 26453     {
 26454 #ifdef HAVE_X11R6_XIM
 26455       struct xim_inst_t *xim_inst = dpyinfo->xim_callback_data;
 26456 
 26457       if (dpyinfo->display)
 26458         {
 26459           Bool ret = XUnregisterIMInstantiateCallback
 26460             (dpyinfo->display, dpyinfo->rdb, xim_inst->resource_name,
 26461              emacs_class, xim_instantiate_callback, (void *) xim_inst);
 26462           eassert (ret == True);
 26463         }
 26464       xfree (xim_inst->resource_name);
 26465       xfree (xim_inst);
 26466 #endif /* HAVE_X11R6_XIM */
 26467       if (dpyinfo->display)
 26468         XCloseIM (dpyinfo->xim);
 26469       dpyinfo->xim = NULL;
 26470       XFree (dpyinfo->xim_styles);
 26471     }
 26472 #endif /* HAVE_XIM */
 26473 }
 26474 
 26475 #endif /* not HAVE_X11R6_XIM */
 26476 
 26477 
 26478 
 26479 /* Calculate the absolute position in frame F
 26480    from its current recorded position values and gravity.  */
 26481 
 26482 static void
 26483 x_calc_absolute_position (struct frame *f)
 26484 {
 26485   int flags = f->size_hint_flags;
 26486   struct frame *p = FRAME_PARENT_FRAME (f);
 26487 
 26488   /* We have nothing to do if the current position
 26489      is already for the top-left corner.  */
 26490   if (! ((flags & XNegative) || (flags & YNegative)))
 26491     return;
 26492 
 26493   /* Treat negative positions as relative to the leftmost bottommost
 26494      position that fits on the screen.  */
 26495   if ((flags & XNegative) && (f->left_pos <= 0))
 26496     {
 26497       int width = FRAME_PIXEL_WIDTH (f);
 26498 
 26499       /* A frame that has been visible at least once should have outer
 26500          edges.  */
 26501       if (f->output_data.x->has_been_visible && !p)
 26502         {
 26503           Lisp_Object frame;
 26504           Lisp_Object edges = Qnil;
 26505 
 26506           XSETFRAME (frame, f);
 26507           edges = Fx_frame_edges (frame, Qouter_edges);
 26508           if (!NILP (edges))
 26509             width = (XFIXNUM (Fnth (make_fixnum (2), edges))
 26510                      - XFIXNUM (Fnth (make_fixnum (0), edges)));
 26511         }
 26512 
 26513       if (p)
 26514         f->left_pos = (FRAME_PIXEL_WIDTH (p) - width - 2 * f->border_width
 26515                        + f->left_pos);
 26516       else
 26517         f->left_pos = (x_display_pixel_width (FRAME_DISPLAY_INFO (f))
 26518                        - width + f->left_pos);
 26519 
 26520     }
 26521 
 26522   if ((flags & YNegative) && (f->top_pos <= 0))
 26523     {
 26524       int height = FRAME_PIXEL_HEIGHT (f);
 26525 
 26526 #if defined USE_X_TOOLKIT && defined USE_MOTIF
 26527       /* Something is fishy here.  When using Motif, starting Emacs with
 26528          `-g -0-0', the frame appears too low by a few pixels.
 26529 
 26530          This seems to be so because initially, while Emacs is starting,
 26531          the column widget's height and the frame's pixel height are
 26532          different.  The column widget's height is the right one.  In
 26533          later invocations, when Emacs is up, the frame's pixel height
 26534          is right, though.
 26535 
 26536          It's not obvious where the initial small difference comes from.
 26537          2000-12-01, gerd.  */
 26538 
 26539       XtVaGetValues (f->output_data.x->column_widget, XtNheight, &height, NULL);
 26540 #endif
 26541 
 26542       if (f->output_data.x->has_been_visible && !p)
 26543         {
 26544           Lisp_Object frame;
 26545           Lisp_Object edges = Qnil;
 26546 
 26547           XSETFRAME (frame, f);
 26548           if (NILP (edges))
 26549             edges = Fx_frame_edges (frame, Qouter_edges);
 26550           if (!NILP (edges))
 26551             height = (XFIXNUM (Fnth (make_fixnum (3), edges))
 26552                       - XFIXNUM (Fnth (make_fixnum (1), edges)));
 26553         }
 26554 
 26555       if (p)
 26556         f->top_pos = (FRAME_PIXEL_HEIGHT (p) - height - 2 * f->border_width
 26557                        + f->top_pos);
 26558       else
 26559         f->top_pos = (x_display_pixel_height (FRAME_DISPLAY_INFO (f))
 26560                       - height + f->top_pos);
 26561   }
 26562 
 26563   /* The left_pos and top_pos
 26564      are now relative to the top and left screen edges,
 26565      so the flags should correspond.  */
 26566   f->size_hint_flags &= ~ (XNegative | YNegative);
 26567 }
 26568 
 26569 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
 26570    to really change the position, and 0 when calling from
 26571    x_make_frame_visible (in that case, XOFF and YOFF are the current
 26572    position values).  It is -1 when calling from gui_set_frame_parameters,
 26573    which means, do adjust for borders but don't change the gravity.  */
 26574 
 26575 static void
 26576 x_set_offset (struct frame *f, int xoff, int yoff, int change_gravity)
 26577 {
 26578   int modified_top, modified_left;
 26579 #ifdef USE_GTK
 26580   int scale = xg_get_scale (f);
 26581 #endif
 26582 
 26583   if (change_gravity > 0)
 26584     {
 26585       f->top_pos = yoff;
 26586       f->left_pos = xoff;
 26587       f->size_hint_flags &= ~ (XNegative | YNegative);
 26588       if (xoff < 0)
 26589         f->size_hint_flags |= XNegative;
 26590       if (yoff < 0)
 26591         f->size_hint_flags |= YNegative;
 26592       f->win_gravity = NorthWestGravity;
 26593     }
 26594 
 26595   x_calc_absolute_position (f);
 26596 
 26597   block_input ();
 26598   x_wm_set_size_hint (f, 0, false);
 26599 
 26600 #ifdef USE_GTK
 26601   if (x_gtk_use_window_move)
 26602     {
 26603       /* When a position change was requested and the outer GTK widget
 26604          has been realized already, leave it to gtk_window_move to
 26605          DTRT and return.  Used for Bug#25851 and Bug#25943.  Convert
 26606          from X pixels to GTK scaled pixels.  */
 26607       if (change_gravity != 0 && FRAME_GTK_OUTER_WIDGET (f))
 26608         gtk_window_move (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
 26609                          f->left_pos / scale, f->top_pos / scale);
 26610       unblock_input ();
 26611       return;
 26612     }
 26613 #endif /* USE_GTK */
 26614 
 26615   modified_left = f->left_pos;
 26616   modified_top = f->top_pos;
 26617 
 26618   if (change_gravity != 0 && FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A)
 26619     {
 26620       /* Some WMs (twm, wmaker at least) has an offset that is smaller
 26621          than the WM decorations.  So we use the calculated offset instead
 26622          of the WM decoration sizes here (x/y_pixels_outer_diff).  */
 26623       modified_left += FRAME_X_OUTPUT (f)->move_offset_left;
 26624       modified_top += FRAME_X_OUTPUT (f)->move_offset_top;
 26625     }
 26626 
 26627 #ifdef USE_GTK
 26628   /* Make sure we adjust for possible scaling.  */
 26629   gtk_window_move (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
 26630                    modified_left / scale, modified_top / scale);
 26631 #else
 26632   XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 26633                modified_left, modified_top);
 26634 #endif
 26635 
 26636   /* 'x_sync_with_move' is too costly for dragging child frames.  */
 26637   if (!FRAME_PARENT_FRAME (f)
 26638       /* If no window manager exists, just calling XSync will be
 26639          sufficient to ensure that the window geometry has been
 26640          updated.  */
 26641       && NILP (Vx_no_window_manager))
 26642     {
 26643       x_sync_with_move (f, f->left_pos, f->top_pos,
 26644                         FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN);
 26645 
 26646       /* change_gravity is non-zero when this function is called from Lisp to
 26647          programmatically move a frame.  In that case, we call
 26648          x_check_expected_move to discover if we have a "Type A" or "Type B"
 26649          window manager, and, for a "Type A" window manager, adjust the position
 26650          of the frame.
 26651 
 26652          We call x_check_expected_move if a programmatic move occurred, and
 26653          either the window manager type (A/B) is unknown or it is Type A but we
 26654          need to compute the top/left offset adjustment for this frame.  */
 26655 
 26656       if (change_gravity != 0
 26657           && (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN
 26658               || (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A
 26659                   && (FRAME_X_OUTPUT (f)->move_offset_left == 0
 26660                       && FRAME_X_OUTPUT (f)->move_offset_top == 0))))
 26661         x_check_expected_move (f, modified_left, modified_top);
 26662     }
 26663   /* Instead, just wait for the last ConfigureWindow request to
 26664      complete.  No window manager is involved when moving child
 26665      frames.  */
 26666   else
 26667     XSync (FRAME_X_DISPLAY (f), False);
 26668 
 26669   unblock_input ();
 26670 }
 26671 
 26672 static Window
 26673 x_get_wm_check_window (struct x_display_info *dpyinfo)
 26674 {
 26675   Window result;
 26676   unsigned char *tmp_data = NULL;
 26677   int rc, actual_format;
 26678   unsigned long actual_size, bytes_remaining;
 26679   Atom actual_type;
 26680 
 26681   rc = XGetWindowProperty (dpyinfo->display, dpyinfo->root_window,
 26682                            dpyinfo->Xatom_net_supporting_wm_check,
 26683                            0, 1, False, XA_WINDOW, &actual_type,
 26684                            &actual_format, &actual_size,
 26685                            &bytes_remaining, &tmp_data);
 26686 
 26687   if (rc != Success || actual_type != XA_WINDOW
 26688       || actual_format != 32 || actual_size != 1)
 26689     {
 26690       if (tmp_data)
 26691         XFree (tmp_data);
 26692 
 26693       return None;
 26694     }
 26695 
 26696   result = *(Window *) tmp_data;
 26697   XFree (tmp_data);
 26698 
 26699   return result;
 26700 }
 26701 
 26702 /* Return true if _NET_SUPPORTING_WM_CHECK window exists and _NET_SUPPORTED
 26703    on the root window for frame F contains ATOMNAME.
 26704    This is how a WM check shall be done according to the Window Manager
 26705    Specification/Extended Window Manager Hints at
 26706    https://freedesktop.org/wiki/Specifications/wm-spec/.  */
 26707 
 26708 bool
 26709 x_wm_supports_1 (struct x_display_info *dpyinfo, Atom want_atom)
 26710 {
 26711   Atom actual_type;
 26712   unsigned long actual_size, bytes_remaining;
 26713   int i, rc, actual_format;
 26714   bool ret;
 26715   Window wmcheck_window;
 26716   Window target_window = dpyinfo->root_window;
 26717   int max_len = 65536;
 26718   Display *dpy = dpyinfo->display;
 26719   unsigned char *tmp_data = NULL;
 26720   Atom target_type = XA_WINDOW;
 26721 
 26722   /* The user says there's no window manager, so take him up on
 26723      it.  */
 26724   if (!NILP (Vx_no_window_manager))
 26725     return false;
 26726 
 26727   block_input ();
 26728 
 26729   x_catch_errors (dpy);
 26730 
 26731   wmcheck_window = dpyinfo->net_supported_window;
 26732 
 26733   if (wmcheck_window == None)
 26734     wmcheck_window = x_get_wm_check_window (dpyinfo);
 26735 
 26736   if (!x_special_window_exists_p (dpyinfo, wmcheck_window))
 26737     {
 26738       if (dpyinfo->net_supported_window != None)
 26739         {
 26740           dpyinfo->net_supported_window = None;
 26741           wmcheck_window = x_get_wm_check_window (dpyinfo);
 26742 
 26743           if (!x_special_window_exists_p (dpyinfo, wmcheck_window))
 26744             {
 26745               x_uncatch_errors ();
 26746               unblock_input ();
 26747               return false;
 26748             }
 26749         }
 26750       else
 26751         {
 26752           x_uncatch_errors ();
 26753           unblock_input ();
 26754           return false;
 26755         }
 26756     }
 26757 
 26758   if (dpyinfo->net_supported_window != wmcheck_window)
 26759     {
 26760       /* Window changed, reload atoms */
 26761       if (dpyinfo->net_supported_atoms != NULL)
 26762         XFree (dpyinfo->net_supported_atoms);
 26763       dpyinfo->net_supported_atoms = NULL;
 26764       dpyinfo->nr_net_supported_atoms = 0;
 26765       dpyinfo->net_supported_window = 0;
 26766 
 26767       target_type = XA_ATOM;
 26768       tmp_data = NULL;
 26769       rc = XGetWindowProperty (dpy, target_window,
 26770                                dpyinfo->Xatom_net_supported,
 26771                                0, max_len, False, target_type,
 26772                                &actual_type, &actual_format, &actual_size,
 26773                                &bytes_remaining, &tmp_data);
 26774 
 26775       if (rc != Success || actual_type != XA_ATOM || x_had_errors_p (dpy))
 26776         {
 26777           if (tmp_data)
 26778             XFree (tmp_data);
 26779           x_uncatch_errors ();
 26780           unblock_input ();
 26781           return false;
 26782         }
 26783 
 26784       dpyinfo->net_supported_atoms = (Atom *) tmp_data;
 26785       dpyinfo->nr_net_supported_atoms = actual_size;
 26786       dpyinfo->net_supported_window = wmcheck_window;
 26787     }
 26788 
 26789   ret = false;
 26790 
 26791   for (i = 0; !ret && i < dpyinfo->nr_net_supported_atoms; ++i)
 26792     ret = dpyinfo->net_supported_atoms[i] == want_atom;
 26793 
 26794   x_uncatch_errors ();
 26795   unblock_input ();
 26796 
 26797   return ret;
 26798 }
 26799 
 26800 bool
 26801 x_wm_supports (struct frame *f, Atom want_atom)
 26802 {
 26803   return x_wm_supports_1 (FRAME_DISPLAY_INFO (f),
 26804                           want_atom);
 26805 }
 26806 
 26807 static void
 26808 set_wm_state (Lisp_Object frame, bool add, Atom atom, Atom value)
 26809 {
 26810   struct x_display_info *dpyinfo;
 26811   XEvent msg;
 26812 
 26813   dpyinfo = FRAME_DISPLAY_INFO (XFRAME (frame));
 26814   msg.xclient.type = ClientMessage;
 26815   msg.xclient.window = FRAME_OUTER_WINDOW (XFRAME (frame));
 26816   msg.xclient.message_type = dpyinfo->Xatom_net_wm_state;
 26817   msg.xclient.format = 32;
 26818 
 26819   msg.xclient.data.l[0] = add ? 1 : 0;
 26820   msg.xclient.data.l[1] = atom;
 26821   msg.xclient.data.l[2] = value;
 26822   msg.xclient.data.l[3] = 1; /* Source indication.  */
 26823   msg.xclient.data.l[4] = 0;
 26824 
 26825   block_input ();
 26826   XSendEvent (dpyinfo->display, dpyinfo->root_window,
 26827               False, (SubstructureRedirectMask
 26828                       | SubstructureNotifyMask), &msg);
 26829   unblock_input ();
 26830 }
 26831 
 26832 void
 26833 x_set_sticky (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
 26834 {
 26835   Lisp_Object frame;
 26836   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 26837 
 26838   XSETFRAME (frame, f);
 26839 
 26840   set_wm_state (frame, !NILP (new_value),
 26841                 dpyinfo->Xatom_net_wm_state_sticky, None);
 26842 }
 26843 
 26844 void
 26845 x_set_shaded (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
 26846 {
 26847   Lisp_Object frame;
 26848   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 26849 
 26850   XSETFRAME (frame, f);
 26851 
 26852   set_wm_state (frame, !NILP (new_value),
 26853                 dpyinfo->Xatom_net_wm_state_shaded, None);
 26854 }
 26855 
 26856 /**
 26857  * x_set_skip_taskbar:
 26858  *
 26859  * Set frame F's `skip-taskbar' parameter.  If non-nil, this should
 26860  * remove F's icon from the taskbar associated with the display of F's
 26861  * window-system window and inhibit switching to F's window via
 26862  * <Alt>-<TAB>.  If nil, lift these restrictions.
 26863  *
 26864  * Some window managers may not honor this parameter.
 26865  */
 26866 void
 26867 x_set_skip_taskbar (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
 26868 {
 26869   if (!EQ (new_value, old_value))
 26870     {
 26871 #ifdef USE_GTK
 26872       xg_set_skip_taskbar (f, new_value);
 26873 #else
 26874       Lisp_Object frame;
 26875       struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 26876 
 26877       XSETFRAME (frame, f);
 26878       set_wm_state (frame, !NILP (new_value),
 26879                     dpyinfo->Xatom_net_wm_state_skip_taskbar, None);
 26880 #endif /* USE_GTK */
 26881       FRAME_SKIP_TASKBAR (f) = !NILP (new_value);
 26882     }
 26883 }
 26884 
 26885 /**
 26886  * x_set_z_group:
 26887  *
 26888  * Set frame F's `z-group' parameter.  If `above', F's window-system
 26889  * window is displayed above all windows that do not have the `above'
 26890  * property set.  If nil, F's window is shown below all windows that
 26891  * have the `above' property set and above all windows that have the
 26892  * `below' property set.  If `below', F's window is displayed below all
 26893  * windows that do not have the `below' property set.
 26894  *
 26895  * Some window managers may not honor this parameter.
 26896  *
 26897  * Internally, this function also handles a value 'above-suspended'.
 26898  * That value is used to temporarily remove F from the 'above' group
 26899  * to make sure that it does not obscure a menu currently popped up.
 26900  */
 26901 void
 26902 x_set_z_group (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
 26903 {
 26904   /* We don't care about old_value.  The window manager might have
 26905      reset the value without telling us.  */
 26906   Lisp_Object frame;
 26907   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 26908 
 26909   XSETFRAME (frame, f);
 26910 
 26911   if (NILP (new_value))
 26912     {
 26913       set_wm_state (frame, false,
 26914                     dpyinfo->Xatom_net_wm_state_above, None);
 26915       set_wm_state (frame, false,
 26916                     dpyinfo->Xatom_net_wm_state_below, None);
 26917       FRAME_Z_GROUP (f) = z_group_none;
 26918     }
 26919   else if (EQ (new_value, Qabove))
 26920     {
 26921       set_wm_state (frame, true,
 26922                     dpyinfo->Xatom_net_wm_state_above, None);
 26923       set_wm_state (frame, false,
 26924                     dpyinfo->Xatom_net_wm_state_below, None);
 26925       FRAME_Z_GROUP (f) = z_group_above;
 26926     }
 26927   else if (EQ (new_value, Qbelow))
 26928     {
 26929       set_wm_state (frame, false,
 26930                     dpyinfo->Xatom_net_wm_state_above, None);
 26931       set_wm_state (frame, true,
 26932                     dpyinfo->Xatom_net_wm_state_below, None);
 26933       FRAME_Z_GROUP (f) = z_group_below;
 26934     }
 26935   else if (EQ (new_value, Qabove_suspended))
 26936     {
 26937       set_wm_state (frame, false,
 26938                     dpyinfo->Xatom_net_wm_state_above, None);
 26939       FRAME_Z_GROUP (f) = z_group_above_suspended;
 26940     }
 26941   else
 26942     error ("Invalid z-group specification");
 26943 }
 26944 
 26945 
 26946 /* Return the current _NET_WM_STATE.
 26947    SIZE_STATE is set to one of the FULLSCREEN_* values.
 26948    Set *STICKY to the sticky state.
 26949 
 26950    Return true iff we are not hidden.  */
 26951 
 26952 static bool
 26953 x_get_current_wm_state (struct frame *f,
 26954                         Window window,
 26955                         int *size_state,
 26956                         bool *sticky,
 26957                         bool *shaded)
 26958 {
 26959   unsigned long actual_size;
 26960   int i;
 26961   bool is_hidden = false;
 26962   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 26963   long max_len = 65536;
 26964   Atom target_type = XA_ATOM;
 26965   /* If XCB is available, we can avoid three XSync calls.  */
 26966 #ifdef USE_XCB
 26967   xcb_get_property_cookie_t prop_cookie;
 26968   xcb_get_property_reply_t *prop;
 26969   typedef xcb_atom_t reply_data_object;
 26970 #else
 26971   Display *dpy = FRAME_X_DISPLAY (f);
 26972   unsigned long bytes_remaining;
 26973   int rc, actual_format;
 26974   Atom actual_type;
 26975   unsigned char *tmp_data = NULL;
 26976   typedef Atom reply_data_object;
 26977 #endif
 26978   reply_data_object *reply_data;
 26979 # if defined GCC_LINT || defined lint
 26980   reply_data_object reply_data_dummy;
 26981   reply_data = &reply_data_dummy;
 26982 # endif
 26983 
 26984   *sticky = false;
 26985   *size_state = FULLSCREEN_NONE;
 26986   *shaded = false;
 26987 
 26988   block_input ();
 26989 
 26990 #ifdef USE_XCB
 26991   prop_cookie = xcb_get_property (dpyinfo->xcb_connection, 0, window,
 26992                                   dpyinfo->Xatom_net_wm_state,
 26993                                   target_type, 0, max_len);
 26994   prop = xcb_get_property_reply (dpyinfo->xcb_connection, prop_cookie, NULL);
 26995   if (prop && prop->type == target_type)
 26996     {
 26997       int actual_bytes = xcb_get_property_value_length (prop);
 26998       eassume (0 <= actual_bytes);
 26999       actual_size = actual_bytes / sizeof *reply_data;
 27000       reply_data = xcb_get_property_value (prop);
 27001     }
 27002   else
 27003     {
 27004       actual_size = 0;
 27005       is_hidden = FRAME_ICONIFIED_P (f);
 27006     }
 27007 #else
 27008   x_catch_errors (dpy);
 27009   rc = XGetWindowProperty (dpy, window, dpyinfo->Xatom_net_wm_state,
 27010                            0, max_len, False, target_type,
 27011                            &actual_type, &actual_format, &actual_size,
 27012                            &bytes_remaining, &tmp_data);
 27013 
 27014   if (rc == Success && actual_type == target_type && ! x_had_errors_p (dpy))
 27015     reply_data = (Atom *) tmp_data;
 27016   else
 27017     {
 27018       actual_size = 0;
 27019       is_hidden = FRAME_ICONIFIED_P (f);
 27020     }
 27021 
 27022   x_uncatch_errors ();
 27023 #endif
 27024 
 27025   for (i = 0; i < actual_size; ++i)
 27026     {
 27027       Atom a = reply_data[i];
 27028       if (a == dpyinfo->Xatom_net_wm_state_hidden)
 27029         is_hidden = true;
 27030       else if (a == dpyinfo->Xatom_net_wm_state_maximized_horz)
 27031         {
 27032           if (*size_state == FULLSCREEN_HEIGHT)
 27033             *size_state = FULLSCREEN_MAXIMIZED;
 27034           else
 27035             *size_state = FULLSCREEN_WIDTH;
 27036         }
 27037       else if (a == dpyinfo->Xatom_net_wm_state_maximized_vert)
 27038         {
 27039           if (*size_state == FULLSCREEN_WIDTH)
 27040             *size_state = FULLSCREEN_MAXIMIZED;
 27041           else
 27042             *size_state = FULLSCREEN_HEIGHT;
 27043         }
 27044       else if (a == dpyinfo->Xatom_net_wm_state_fullscreen)
 27045         *size_state = FULLSCREEN_BOTH;
 27046       else if (a == dpyinfo->Xatom_net_wm_state_sticky)
 27047         *sticky = true;
 27048       else if (a == dpyinfo->Xatom_net_wm_state_shaded)
 27049         *shaded = true;
 27050     }
 27051 
 27052 #ifdef USE_XCB
 27053   free (prop);
 27054 #else
 27055   if (tmp_data) XFree (tmp_data);
 27056 #endif
 27057 
 27058   unblock_input ();
 27059   return ! is_hidden;
 27060 }
 27061 
 27062 /* Do fullscreen as specified in extended window manager hints */
 27063 
 27064 static bool
 27065 do_ewmh_fullscreen (struct frame *f)
 27066 {
 27067   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 27068   bool have_net_atom = x_wm_supports (f, dpyinfo->Xatom_net_wm_state);
 27069   int cur;
 27070   bool dummy;
 27071 
 27072   x_get_current_wm_state (f, FRAME_OUTER_WINDOW (f), &cur, &dummy, &dummy);
 27073 
 27074   /* Some window managers don't say they support _NET_WM_STATE, but they do say
 27075      they support _NET_WM_STATE_FULLSCREEN.  Try that also.  */
 27076   if (!have_net_atom)
 27077     have_net_atom = x_wm_supports (f, dpyinfo->Xatom_net_wm_state_fullscreen);
 27078 
 27079   if (have_net_atom && cur != f->want_fullscreen)
 27080     {
 27081       Lisp_Object frame;
 27082 
 27083       XSETFRAME (frame, f);
 27084 
 27085       /* Keep number of calls to set_wm_state as low as possible.
 27086          Some window managers, or possible Gtk+, hangs when too many
 27087          are sent at once.  */
 27088       switch (f->want_fullscreen)
 27089         {
 27090         case FULLSCREEN_BOTH:
 27091           if (cur != FULLSCREEN_BOTH)
 27092             set_wm_state (frame, true, dpyinfo->Xatom_net_wm_state_fullscreen,
 27093                           None);
 27094           break;
 27095         case FULLSCREEN_WIDTH:
 27096           if (x_frame_normalize_before_maximize && cur == FULLSCREEN_MAXIMIZED)
 27097             {
 27098               set_wm_state (frame, false,
 27099                             dpyinfo->Xatom_net_wm_state_maximized_horz,
 27100                             dpyinfo->Xatom_net_wm_state_maximized_vert);
 27101               set_wm_state (frame, true,
 27102                             dpyinfo->Xatom_net_wm_state_maximized_horz, None);
 27103             }
 27104           else
 27105             {
 27106               if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_HEIGHT
 27107                   || cur == FULLSCREEN_MAXIMIZED)
 27108                 set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen,
 27109                               dpyinfo->Xatom_net_wm_state_maximized_vert);
 27110               if (cur != FULLSCREEN_MAXIMIZED || x_frame_normalize_before_maximize)
 27111                 set_wm_state (frame, true,
 27112                               dpyinfo->Xatom_net_wm_state_maximized_horz, None);
 27113             }
 27114           break;
 27115         case FULLSCREEN_HEIGHT:
 27116           if (x_frame_normalize_before_maximize && cur == FULLSCREEN_MAXIMIZED)
 27117             {
 27118               set_wm_state (frame, false,
 27119                             dpyinfo->Xatom_net_wm_state_maximized_horz,
 27120                             dpyinfo->Xatom_net_wm_state_maximized_vert);
 27121               set_wm_state (frame, true,
 27122                             dpyinfo->Xatom_net_wm_state_maximized_vert, None);
 27123             }
 27124           else
 27125             {
 27126               if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_WIDTH
 27127                   || cur == FULLSCREEN_MAXIMIZED)
 27128                 set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen,
 27129                               dpyinfo->Xatom_net_wm_state_maximized_horz);
 27130               if (cur != FULLSCREEN_MAXIMIZED || x_frame_normalize_before_maximize)
 27131                 set_wm_state (frame, true,
 27132                               dpyinfo->Xatom_net_wm_state_maximized_vert, None);
 27133             }
 27134           break;
 27135         case FULLSCREEN_MAXIMIZED:
 27136           if (x_frame_normalize_before_maximize && cur == FULLSCREEN_BOTH)
 27137             {
 27138               set_wm_state (frame, false,
 27139                             dpyinfo->Xatom_net_wm_state_fullscreen, None);
 27140               set_wm_state (frame, true,
 27141                             dpyinfo->Xatom_net_wm_state_maximized_horz,
 27142                             dpyinfo->Xatom_net_wm_state_maximized_vert);
 27143             }
 27144           else if (x_frame_normalize_before_maximize && cur == FULLSCREEN_WIDTH)
 27145             {
 27146               set_wm_state (frame, false,
 27147                             dpyinfo->Xatom_net_wm_state_maximized_horz, None);
 27148               set_wm_state (frame, true,
 27149                             dpyinfo->Xatom_net_wm_state_maximized_horz,
 27150                             dpyinfo->Xatom_net_wm_state_maximized_vert);
 27151             }
 27152           else if (x_frame_normalize_before_maximize && cur == FULLSCREEN_HEIGHT)
 27153             {
 27154               set_wm_state (frame, false,
 27155                             dpyinfo->Xatom_net_wm_state_maximized_vert, None);
 27156               set_wm_state (frame, true,
 27157                             dpyinfo->Xatom_net_wm_state_maximized_horz,
 27158                             dpyinfo->Xatom_net_wm_state_maximized_vert);
 27159             }
 27160           else
 27161             {
 27162               if (cur == FULLSCREEN_BOTH)
 27163                 set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen,
 27164                               None);
 27165               else if (cur == FULLSCREEN_HEIGHT)
 27166                 set_wm_state (frame, true,
 27167                               dpyinfo->Xatom_net_wm_state_maximized_horz, None);
 27168               else if (cur == FULLSCREEN_WIDTH)
 27169                 set_wm_state (frame, true, None,
 27170                               dpyinfo->Xatom_net_wm_state_maximized_vert);
 27171               else
 27172                 set_wm_state (frame, true,
 27173                               dpyinfo->Xatom_net_wm_state_maximized_horz,
 27174                               dpyinfo->Xatom_net_wm_state_maximized_vert);
 27175             }
 27176           break;
 27177         case FULLSCREEN_NONE:
 27178           if (cur == FULLSCREEN_BOTH)
 27179             set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen,
 27180                           None);
 27181           else
 27182             set_wm_state (frame, false,
 27183                           dpyinfo->Xatom_net_wm_state_maximized_horz,
 27184                           dpyinfo->Xatom_net_wm_state_maximized_vert);
 27185         }
 27186 
 27187       f->want_fullscreen = FULLSCREEN_NONE;
 27188 
 27189     }
 27190 
 27191   return have_net_atom;
 27192 }
 27193 
 27194 static void
 27195 XTfullscreen_hook (struct frame *f)
 27196 {
 27197   if (FRAME_VISIBLE_P (f))
 27198     {
 27199       block_input ();
 27200       x_check_fullscreen (f);
 27201       x_sync (f);
 27202       unblock_input ();
 27203     }
 27204 }
 27205 
 27206 
 27207 static bool
 27208 x_handle_net_wm_state (struct frame *f, const XPropertyEvent *event)
 27209 {
 27210   int value = FULLSCREEN_NONE;
 27211   Lisp_Object lval;
 27212   bool sticky = false, shaded = false;
 27213   bool not_hidden = x_get_current_wm_state (f, event->window,
 27214                                             &value, &sticky,
 27215                                             &shaded);
 27216 
 27217   lval = Qnil;
 27218   switch (value)
 27219     {
 27220     case FULLSCREEN_WIDTH:
 27221       lval = Qfullwidth;
 27222       break;
 27223     case FULLSCREEN_HEIGHT:
 27224       lval = Qfullheight;
 27225       break;
 27226     case FULLSCREEN_BOTH:
 27227       lval = Qfullboth;
 27228       break;
 27229     case FULLSCREEN_MAXIMIZED:
 27230       lval = Qmaximized;
 27231       break;
 27232     }
 27233 
 27234   store_frame_param (f, Qfullscreen, lval);
 27235   store_frame_param (f, Qsticky, sticky ? Qt : Qnil);
 27236   store_frame_param (f, Qshaded, shaded ? Qt : Qnil);
 27237 
 27238   return not_hidden;
 27239 }
 27240 
 27241 /* Check if we need to resize the frame due to a fullscreen request.
 27242    If so needed, resize the frame. */
 27243 static void
 27244 x_check_fullscreen (struct frame *f)
 27245 {
 27246   Lisp_Object lval = Qnil;
 27247 
 27248   if (do_ewmh_fullscreen (f))
 27249     return;
 27250 
 27251   if (f->output_data.x->parent_desc != FRAME_DISPLAY_INFO (f)->root_window)
 27252     return; /* Only fullscreen without WM or with EWM hints (above). */
 27253 
 27254   /* Setting fullscreen to nil doesn't do anything.  We could save the
 27255      last non-fullscreen size and restore it, but it seems like a
 27256      lot of work for this unusual case (no window manager running).  */
 27257 
 27258   if (f->want_fullscreen != FULLSCREEN_NONE)
 27259     {
 27260       int width = FRAME_PIXEL_WIDTH (f), height = FRAME_PIXEL_HEIGHT (f);
 27261       struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 27262 
 27263       switch (f->want_fullscreen)
 27264         {
 27265           /* No difference between these two when there is no WM */
 27266         case FULLSCREEN_MAXIMIZED:
 27267           lval = Qmaximized;
 27268           width = x_display_pixel_width (dpyinfo);
 27269           height = x_display_pixel_height (dpyinfo);
 27270           break;
 27271         case FULLSCREEN_BOTH:
 27272           lval = Qfullboth;
 27273           width = x_display_pixel_width (dpyinfo);
 27274           height = x_display_pixel_height (dpyinfo);
 27275           break;
 27276         case FULLSCREEN_WIDTH:
 27277           lval = Qfullwidth;
 27278           width = x_display_pixel_width (dpyinfo);
 27279           height = height + FRAME_MENUBAR_HEIGHT (f);
 27280           break;
 27281         case FULLSCREEN_HEIGHT:
 27282           lval = Qfullheight;
 27283           height = x_display_pixel_height (dpyinfo);
 27284           break;
 27285         default:
 27286           emacs_abort ();
 27287         }
 27288 
 27289       x_wm_set_size_hint (f, 0, false);
 27290 
 27291       XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 27292                      width, height);
 27293 
 27294       if (FRAME_VISIBLE_P (f))
 27295         x_wait_for_event (f, ConfigureNotify);
 27296       else
 27297         {
 27298           change_frame_size (f, width, height, false, true, false);
 27299           x_sync (f);
 27300         }
 27301     }
 27302 
 27303   /* `x_net_wm_state' might have reset the fullscreen frame parameter,
 27304      restore it. */
 27305   store_frame_param (f, Qfullscreen, lval);
 27306 }
 27307 
 27308 /* This function is called by x_set_offset to determine whether the window
 27309    manager interfered with the positioning of the frame.  Type A window
 27310    managers position the surrounding window manager decorations a small
 27311    amount above and left of the user-supplied position.  Type B window
 27312    managers position the surrounding window manager decorations at the
 27313    user-specified position.  If we detect a Type A window manager, we
 27314    compensate by moving the window right and down by the proper amount.  */
 27315 
 27316 static void
 27317 x_check_expected_move (struct frame *f, int expected_left, int expected_top)
 27318 {
 27319   int current_left = 0, current_top = 0;
 27320 
 27321   /* x_real_positions returns the left and top offsets of the outermost
 27322      window manager window around the frame.  */
 27323 
 27324   x_real_positions (f, &current_left, &current_top);
 27325 
 27326   if (current_left != expected_left || current_top != expected_top)
 27327     {
 27328       /* It's a "Type A" window manager. */
 27329 
 27330       int adjusted_left;
 27331       int adjusted_top;
 27332 
 27333       FRAME_DISPLAY_INFO (f)->wm_type = X_WMTYPE_A;
 27334       FRAME_X_OUTPUT (f)->move_offset_left = expected_left - current_left;
 27335       FRAME_X_OUTPUT (f)->move_offset_top = expected_top - current_top;
 27336 
 27337       /* Now fix the mispositioned frame's location. */
 27338 
 27339       adjusted_left = expected_left + FRAME_X_OUTPUT (f)->move_offset_left;
 27340       adjusted_top = expected_top + FRAME_X_OUTPUT (f)->move_offset_top;
 27341 
 27342       XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 27343                    adjusted_left, adjusted_top);
 27344 
 27345       x_sync_with_move (f, expected_left, expected_top, false);
 27346     }
 27347   else
 27348     /* It's a "Type B" window manager.  We don't have to adjust the
 27349        frame's position. */
 27350       FRAME_DISPLAY_INFO (f)->wm_type = X_WMTYPE_B;
 27351 }
 27352 
 27353 
 27354 /* Wait for XGetGeometry to return up-to-date position information for a
 27355    recently-moved frame.  Call this immediately after calling XMoveWindow.
 27356    If FUZZY is non-zero, then LEFT and TOP are just estimates of where the
 27357    frame has been moved to, so we use a fuzzy position comparison instead
 27358    of an exact comparison.  */
 27359 
 27360 static void
 27361 x_sync_with_move (struct frame *f, int left, int top, bool fuzzy)
 27362 {
 27363   sigset_t emptyset;
 27364   int count, current_left, current_top;
 27365   struct timespec fallback;
 27366 
 27367   sigemptyset (&emptyset);
 27368   count = 0;
 27369 
 27370   while (count++ < 50)
 27371     {
 27372       current_left = 0;
 27373       current_top = 0;
 27374 
 27375       /* There is no need to call XSync (even when no window manager
 27376          is present) because x_real_positions already does that
 27377          implicitly.  */
 27378       x_real_positions (f, &current_left, &current_top);
 27379 
 27380       if (fuzzy)
 27381         {
 27382           /* The left fuzz-factor is 10 pixels.  The top fuzz-factor is 40
 27383              pixels.  */
 27384 
 27385           if (eabs (current_left - left) <= 10
 27386               && eabs (current_top - top) <= 40)
 27387             return;
 27388         }
 27389       else if (current_left == left && current_top == top)
 27390         return;
 27391     }
 27392 
 27393   /* As a last resort, just wait 0.5 seconds and hope that XGetGeometry
 27394      will then return up-to-date position info. */
 27395 
 27396   fallback = dtotimespec (0.5);
 27397 
 27398   /* This will hang if input is blocked, so use pselect to wait
 27399      instead.  */
 27400   if (input_blocked_p ())
 27401     pselect (0, NULL, NULL, NULL, &fallback, &emptyset);
 27402   else
 27403     wait_reading_process_output (0, 500000000, 0, false, Qnil, NULL, 0);
 27404 }
 27405 
 27406 /* Wait for an event on frame F matching EVENTTYPE.  */
 27407 void
 27408 x_wait_for_event (struct frame *f, int eventtype)
 27409 {
 27410   if (!FLOATP (Vx_wait_for_event_timeout))
 27411     return;
 27412 
 27413   int level = interrupt_input_blocked;
 27414   fd_set fds;
 27415   struct timespec tmo, tmo_at, time_now;
 27416   int fd = ConnectionNumber (FRAME_X_DISPLAY (f));
 27417 
 27418   f->wait_event_type = eventtype;
 27419 
 27420   /* Default timeout is 0.1 second.  Hopefully not noticeable.  */
 27421   double timeout = XFLOAT_DATA (Vx_wait_for_event_timeout);
 27422   time_t timeout_seconds = (time_t) timeout;
 27423   tmo = make_timespec
 27424     (timeout_seconds, (long int) ((timeout - timeout_seconds)
 27425                                   * 1000 * 1000 * 1000));
 27426   tmo_at = timespec_add (current_timespec (), tmo);
 27427 
 27428   while (f->wait_event_type)
 27429     {
 27430       pending_signals = true;
 27431       totally_unblock_input ();
 27432       /* XTread_socket is called after unblock.  */
 27433       block_input ();
 27434       interrupt_input_blocked = level;
 27435 
 27436       FD_ZERO (&fds);
 27437       FD_SET (fd, &fds);
 27438 
 27439       time_now = current_timespec ();
 27440       if (timespec_cmp (tmo_at, time_now) < 0)
 27441         break;
 27442 
 27443       tmo = timespec_sub (tmo_at, time_now);
 27444       if (pselect (fd + 1, &fds, NULL, NULL, &tmo, NULL) == 0)
 27445         break; /* Timeout */
 27446     }
 27447 
 27448   f->wait_event_type = 0;
 27449 }
 27450 
 27451 
 27452 /* Change the size of frame F's X window to WIDTH/HEIGHT in the case F
 27453    doesn't have a widget.  If CHANGE_GRAVITY, change to
 27454    top-left-corner window gravity for this size change and subsequent
 27455    size changes.  Otherwise leave the window gravity unchanged.  */
 27456 
 27457 static void
 27458 x_set_window_size_1 (struct frame *f, bool change_gravity,
 27459                      int width, int height)
 27460 {
 27461   if (change_gravity)
 27462     f->win_gravity = NorthWestGravity;
 27463   x_wm_set_size_hint (f, 0, false);
 27464 
 27465   XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 27466                  width, height + FRAME_MENUBAR_HEIGHT (f));
 27467 
 27468   /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
 27469      receive in the ConfigureNotify event; if we get what we asked
 27470      for, then the event won't cause the screen to become garbaged, so
 27471      we have to make sure to do it here.  */
 27472   SET_FRAME_GARBAGED (f);
 27473 
 27474   /* Now, strictly speaking, we can't be sure that this is accurate,
 27475      but the window manager will get around to dealing with the size
 27476      change request eventually, and we'll hear how it went when the
 27477      ConfigureNotify event gets here.
 27478 
 27479      We could just not bother storing any of this information here,
 27480      and let the ConfigureNotify event set everything up, but that
 27481      might be kind of confusing to the Lisp code, since size changes
 27482      wouldn't be reported in the frame parameters until some random
 27483      point in the future when the ConfigureNotify event arrives.
 27484 
 27485      Pass true for DELAY since we can't run Lisp code inside of
 27486      a BLOCK_INPUT.  */
 27487 
 27488   /* But the ConfigureNotify may in fact never arrive, and then this is
 27489      not right if the frame is visible.  Instead wait (with timeout)
 27490      for the ConfigureNotify.  */
 27491   if (FRAME_VISIBLE_P (f))
 27492     {
 27493       x_wait_for_event (f, ConfigureNotify);
 27494 
 27495       if (CONSP (frame_size_history))
 27496         frame_size_history_extra
 27497           (f, build_string ("x_set_window_size_1, visible"),
 27498            FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f), width, height,
 27499            f->new_width, f->new_height);
 27500     }
 27501   else
 27502     {
 27503       if (CONSP (frame_size_history))
 27504         frame_size_history_extra
 27505           (f, build_string ("x_set_window_size_1, invisible"),
 27506            FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f), width, height,
 27507            f->new_width, f->new_height);
 27508 
 27509       /* Call adjust_frame_size right away as with GTK.  It might be
 27510          tempting to clear out f->new_width and f->new_height here.  */
 27511       adjust_frame_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, width),
 27512                          FRAME_PIXEL_TO_TEXT_HEIGHT (f, height),
 27513                          5, 0, Qx_set_window_size_1);
 27514 
 27515       x_sync (f);
 27516     }
 27517 }
 27518 
 27519 
 27520 /* Change the size of frame F's X window to WIDTH and HEIGHT pixels.  If
 27521    CHANGE_GRAVITY, change to top-left-corner window gravity for this
 27522    size change and subsequent size changes.  Otherwise we leave the
 27523    window gravity unchanged.  */
 27524 
 27525 void
 27526 x_set_window_size (struct frame *f, bool change_gravity,
 27527                    int width, int height)
 27528 {
 27529   block_input ();
 27530 
 27531 #ifdef USE_GTK
 27532   if (FRAME_GTK_WIDGET (f))
 27533     xg_frame_set_char_size (f, width, height);
 27534   else
 27535     x_set_window_size_1 (f, change_gravity, width, height);
 27536 #else /* not USE_GTK */
 27537   x_set_window_size_1 (f, change_gravity, width, height);
 27538   x_clear_under_internal_border (f);
 27539 #endif /* not USE_GTK */
 27540 
 27541   /* If cursor was outside the new size, mark it as off.  */
 27542   mark_window_cursors_off (XWINDOW (f->root_window));
 27543 
 27544   /* Clear out any recollection of where the mouse highlighting was,
 27545      since it might be in a place that's outside the new frame size.
 27546      Actually checking whether it is outside is a pain in the neck,
 27547      so don't try--just let the highlighting be done afresh with new size.  */
 27548   cancel_mouse_face (f);
 27549 
 27550   unblock_input ();
 27551 
 27552   do_pending_window_change (false);
 27553 }
 27554 
 27555 /* Move the mouse to position pixel PIX_X, PIX_Y relative to frame F.  */
 27556 
 27557 void
 27558 frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y)
 27559 {
 27560 #ifdef HAVE_XINPUT2
 27561   int deviceid;
 27562 
 27563   deviceid = FRAME_DISPLAY_INFO (f)->client_pointer_device;
 27564 
 27565   if (FRAME_DISPLAY_INFO (f)->supports_xi2
 27566       && deviceid != -1)
 27567     {
 27568       block_input ();
 27569       x_ignore_errors_for_next_request (FRAME_DISPLAY_INFO (f));
 27570       XIWarpPointer (FRAME_X_DISPLAY (f), deviceid, None,
 27571                      FRAME_X_WINDOW (f), 0, 0, 0, 0, pix_x, pix_y);
 27572       x_stop_ignoring_errors (FRAME_DISPLAY_INFO (f));
 27573       unblock_input ();
 27574     }
 27575   else
 27576 #endif
 27577     XWarpPointer (FRAME_X_DISPLAY (f), None, FRAME_X_WINDOW (f),
 27578                   0, 0, 0, 0, pix_x, pix_y);
 27579 }
 27580 
 27581 /* Raise frame F.  */
 27582 
 27583 static void
 27584 x_raise_frame (struct frame *f)
 27585 {
 27586   block_input ();
 27587 
 27588   if (FRAME_VISIBLE_P (f))
 27589     {
 27590       XRaiseWindow (FRAME_X_DISPLAY (f),
 27591                     FRAME_OUTER_WINDOW (f));
 27592       XFlush (FRAME_X_DISPLAY (f));
 27593     }
 27594 
 27595   unblock_input ();
 27596 }
 27597 
 27598 static void
 27599 x_lower_frame_1 (struct frame *f)
 27600 {
 27601   Window *windows;
 27602   Lisp_Object frame, tail;
 27603   struct frame *sibling;
 27604 
 27605   windows = alloca (2 * sizeof *windows);
 27606 
 27607   /* Lowering a child frame leads to the window being put below any
 27608      scroll bars on the parent.  To avoid that, restack the child
 27609      frame below all of its siblings instead of just lowering it.  */
 27610 
 27611   FOR_EACH_FRAME (tail, frame)
 27612     {
 27613       sibling = XFRAME (frame);
 27614 
 27615       if (sibling == f)
 27616         continue;
 27617 
 27618       if (FRAME_PARENT_FRAME (sibling)
 27619           != FRAME_PARENT_FRAME (f))
 27620         continue;
 27621 
 27622       windows[0] = FRAME_OUTER_WINDOW (sibling);
 27623       windows[1] = FRAME_OUTER_WINDOW (f);
 27624 
 27625       XRestackWindows (FRAME_X_DISPLAY (f), windows, 2);
 27626     }
 27627 }
 27628 
 27629 /* Lower frame F.  */
 27630 
 27631 static void
 27632 x_lower_frame (struct frame *f)
 27633 {
 27634   if (FRAME_PARENT_FRAME (f)
 27635       && (FRAME_HAS_VERTICAL_SCROLL_BARS (FRAME_PARENT_FRAME (f))
 27636           || FRAME_HAS_HORIZONTAL_SCROLL_BARS (FRAME_PARENT_FRAME (f))))
 27637     x_lower_frame_1 (f);
 27638   else
 27639     XLowerWindow (FRAME_X_DISPLAY (f),
 27640                   FRAME_OUTER_WINDOW (f));
 27641 
 27642 #ifdef HAVE_XWIDGETS
 27643   /* Make sure any X windows owned by xwidget views of the parent
 27644      still display below the lowered frame.  */
 27645 
 27646   if (FRAME_PARENT_FRAME (f))
 27647     lower_frame_xwidget_views (FRAME_PARENT_FRAME (f));
 27648 #endif
 27649 
 27650   XFlush (FRAME_X_DISPLAY (f));
 27651 }
 27652 
 27653 static void
 27654 XTframe_raise_lower (struct frame *f, bool raise_flag)
 27655 {
 27656   if (raise_flag)
 27657     x_raise_frame (f);
 27658   else
 27659     x_lower_frame (f);
 27660 }
 27661 
 27662 /* Request focus with XEmbed */
 27663 
 27664 static void
 27665 xembed_request_focus (struct frame *f)
 27666 {
 27667   /* See XEmbed Protocol Specification at
 27668      https://freedesktop.org/wiki/Specifications/xembed-spec/  */
 27669   if (FRAME_VISIBLE_P (f))
 27670     xembed_send_message (f, CurrentTime,
 27671                          XEMBED_REQUEST_FOCUS, 0, 0, 0);
 27672 }
 27673 
 27674 static Bool
 27675 server_timestamp_predicate (Display *display, XEvent *xevent,
 27676                             XPointer arg)
 27677 {
 27678   XID *args = (XID *) arg;
 27679 
 27680   if (xevent->type == PropertyNotify
 27681       && xevent->xproperty.window == args[0]
 27682       && xevent->xproperty.atom == args[1])
 27683     return True;
 27684 
 27685   return False;
 27686 }
 27687 
 27688 /* Get the server time.  The X server is guaranteed to deliver the
 27689    PropertyNotify event, so there is no reason to use x_if_event.  */
 27690 
 27691 static Time
 27692 x_get_server_time (struct frame *f)
 27693 {
 27694   Atom property_atom;
 27695   XEvent property_dummy;
 27696   struct x_display_info *dpyinfo;
 27697   XID client_data[2];
 27698 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
 27699   uint_fast64_t current_monotonic_time;
 27700 #endif
 27701 
 27702   /* If the server time is the same as the monotonic time, avoid a
 27703      roundtrip by using that instead.  */
 27704 
 27705 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
 27706   if (FRAME_DISPLAY_INFO (f)->server_time_monotonic_p)
 27707     {
 27708       current_monotonic_time = x_sync_current_monotonic_time ();
 27709 
 27710       if (current_monotonic_time)
 27711         /* Truncate the time to CARD32.  */
 27712         return (current_monotonic_time / 1000) & X_ULONG_MAX;
 27713     }
 27714 #endif
 27715 
 27716   dpyinfo = FRAME_DISPLAY_INFO (f);
 27717   property_atom = dpyinfo->Xatom_EMACS_SERVER_TIME_PROP;
 27718   client_data[0] = FRAME_OUTER_WINDOW (f);
 27719   client_data[1] = property_atom;
 27720 
 27721   XChangeProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
 27722                    property_atom, XA_ATOM, 32,
 27723                    PropModeReplace,
 27724                    (unsigned char *) &property_atom, 1);
 27725 
 27726   XIfEvent (dpyinfo->display, &property_dummy,
 27727             server_timestamp_predicate, (XPointer) client_data);
 27728 
 27729   return property_dummy.xproperty.time;
 27730 }
 27731 
 27732 /* Activate frame with Extended Window Manager Hints */
 27733 
 27734 static void
 27735 x_ewmh_activate_frame (struct frame *f)
 27736 {
 27737   XEvent msg;
 27738   struct x_display_info *dpyinfo;
 27739   Time time;
 27740 
 27741   dpyinfo = FRAME_DISPLAY_INFO (f);
 27742 
 27743   if (FRAME_VISIBLE_P (f))
 27744     {
 27745       /* See the documentation at
 27746          https://specifications.freedesktop.org/wm-spec/wm-spec-latest.html
 27747          for more details on the format of this message.  */
 27748       msg.xclient.type = ClientMessage;
 27749       msg.xclient.window = FRAME_OUTER_WINDOW (f);
 27750       msg.xclient.message_type = dpyinfo->Xatom_net_active_window;
 27751       msg.xclient.format = 32;
 27752       msg.xclient.data.l[0] = 1;
 27753       msg.xclient.data.l[1] = dpyinfo->last_user_time;
 27754       msg.xclient.data.l[2] = (!dpyinfo->x_focus_frame
 27755                                ? None
 27756                                : FRAME_OUTER_WINDOW (dpyinfo->x_focus_frame));
 27757       msg.xclient.data.l[3] = 0;
 27758       msg.xclient.data.l[4] = 0;
 27759 
 27760       /* No frame is currently focused on that display, so apply any
 27761          bypass for focus stealing prevention that the user has
 27762          specified.  */
 27763       if (!dpyinfo->x_focus_frame)
 27764         {
 27765           if (EQ (Vx_allow_focus_stealing, Qimitate_pager))
 27766             msg.xclient.data.l[0] = 2;
 27767           else if (EQ (Vx_allow_focus_stealing, Qnewer_time))
 27768             {
 27769               block_input ();
 27770               time = x_get_server_time (f);
 27771 #ifdef USE_GTK
 27772               x_set_gtk_user_time (f, time);
 27773 #endif
 27774               /* Temporarily override dpyinfo->x_focus_frame so the
 27775                  user time property is set on the right window.  */
 27776               dpyinfo->x_focus_frame = f;
 27777               x_display_set_last_user_time (dpyinfo, time, true, true);
 27778               dpyinfo->x_focus_frame = NULL;
 27779               unblock_input ();
 27780 
 27781               msg.xclient.data.l[1] = time;
 27782             }
 27783           else if (EQ (Vx_allow_focus_stealing, Qraise_and_focus))
 27784             {
 27785               time = x_get_server_time (f);
 27786 
 27787               x_set_input_focus (FRAME_DISPLAY_INFO (f),
 27788                                  FRAME_OUTER_WINDOW (f),
 27789                                  time);
 27790               XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f));
 27791 
 27792               return;
 27793             }
 27794         }
 27795 
 27796       XSendEvent (dpyinfo->display, dpyinfo->root_window,
 27797                   False, (SubstructureRedirectMask
 27798                           | SubstructureNotifyMask), &msg);
 27799     }
 27800 }
 27801 
 27802 static Lisp_Object
 27803 x_get_focus_frame (struct frame *f)
 27804 {
 27805   Lisp_Object lisp_focus;
 27806 
 27807   struct frame *focus =  FRAME_DISPLAY_INFO (f)->x_focus_frame;
 27808 
 27809   if (!focus)
 27810     return Qnil;
 27811 
 27812   XSETFRAME (lisp_focus, focus);
 27813   return lisp_focus;
 27814 }
 27815 
 27816 /* Return the toplevel parent of F, if it is a child frame.
 27817    Otherwise, return NULL.  */
 27818 
 27819 static struct frame *
 27820 x_get_toplevel_parent (struct frame *f)
 27821 {
 27822   struct frame *parent;
 27823 
 27824   if (!FRAME_PARENT_FRAME (f))
 27825     return NULL;
 27826 
 27827   parent = FRAME_PARENT_FRAME (f);
 27828 
 27829   while (FRAME_PARENT_FRAME (parent))
 27830     parent = FRAME_PARENT_FRAME (parent);
 27831 
 27832   return parent;
 27833 }
 27834 
 27835 static void
 27836 x_set_input_focus (struct x_display_info *dpyinfo, Window window,
 27837                    Time time)
 27838 {
 27839 #ifdef HAVE_XINPUT2
 27840   struct xi_device_t *device;
 27841 #endif
 27842 
 27843   /* Do the equivalent of XSetInputFocus with the specified window and
 27844      time, but use the attachment to the device that Emacs has
 27845      designated the client pointer on X Input Extension builds.
 27846      Asynchronously trap errors around the generated XI_SetFocus or
 27847      SetInputFocus request, in case the device has been destroyed or
 27848      the window obscured.
 27849 
 27850      The revert_to will be set to RevertToParent for generated
 27851      SetInputFocus requests.  */
 27852 
 27853 #ifdef HAVE_XINPUT2
 27854   if (dpyinfo->supports_xi2
 27855       && dpyinfo->client_pointer_device != -1)
 27856     {
 27857       device = xi_device_from_id (dpyinfo, dpyinfo->client_pointer_device);
 27858 
 27859       /* The device is a master pointer.  Use its attachment, which
 27860          should be the master keyboard.  */
 27861 
 27862       if (device)
 27863         {
 27864           eassert (device->use == XIMasterPointer);
 27865 
 27866           x_ignore_errors_for_next_request (dpyinfo);
 27867           XISetFocus (dpyinfo->display, device->attachment,
 27868                       /* Note that the input extension
 27869                          only supports RevertToParent-type
 27870                          behavior.  */
 27871                       window, time);
 27872           x_stop_ignoring_errors (dpyinfo);
 27873 
 27874           return;
 27875         }
 27876     }
 27877 #endif
 27878 
 27879   /* Otherwise, use the pointer device that the X server says is the
 27880      client pointer.  */
 27881   x_ignore_errors_for_next_request (dpyinfo);
 27882   XSetInputFocus (dpyinfo->display, window, RevertToParent, time);
 27883   x_stop_ignoring_errors (dpyinfo);
 27884 }
 27885 
 27886 /* In certain situations, when the window manager follows a
 27887    click-to-focus policy, there seems to be no way around calling
 27888    XSetInputFocus to give another frame the input focus.
 27889 
 27890    In an ideal world, XSetInputFocus should generally be avoided so
 27891    that applications don't interfere with the window manager's focus
 27892    policy.  But I think it's okay to use when it's clearly done
 27893    following a user-command.  */
 27894 
 27895 static void
 27896 x_focus_frame (struct frame *f, bool noactivate)
 27897 {
 27898   struct x_display_info *dpyinfo;
 27899   Time time;
 27900 
 27901   /* The code below is not reentrant wrt to dpyinfo->x_focus_frame and
 27902      friends being set.  */
 27903   block_input ();
 27904 
 27905   dpyinfo = FRAME_DISPLAY_INFO (f);
 27906 
 27907   if (FRAME_X_EMBEDDED_P (f))
 27908     /* For Xembedded frames, normally the embedder forwards key
 27909        events.  See XEmbed Protocol Specification at
 27910        https://freedesktop.org/wiki/Specifications/xembed-spec/  */
 27911     xembed_request_focus (f);
 27912   else
 27913     {
 27914       if (!noactivate
 27915           /* If F is override-redirect, use SetInputFocus instead.
 27916              Override-redirect frames are not subject to window
 27917              management.  */
 27918           && !FRAME_OVERRIDE_REDIRECT (f)
 27919           /* If F is a child frame, use SetInputFocus instead.  This
 27920              may not work if its parent is not activated.  */
 27921           && !FRAME_PARENT_FRAME (f)
 27922           /* If the focus is being transferred from a child frame to
 27923              its toplevel parent, also use SetInputFocus.  */
 27924           && (!dpyinfo->x_focus_frame
 27925               || (x_get_toplevel_parent (dpyinfo->x_focus_frame)
 27926                   != f))
 27927           && x_wm_supports (f, dpyinfo->Xatom_net_active_window))
 27928         {
 27929           /* When window manager activation is possible, use it
 27930              instead.  The window manager is expected to perform any
 27931              necessary actions such as raising the frame, moving it to
 27932              the current workspace, and mapping it, etc, before moving
 27933              input focus to the frame.  */
 27934           x_ewmh_activate_frame (f);
 27935           goto out;
 27936         }
 27937 
 27938       if (NILP (Vx_no_window_manager))
 27939         {
 27940           /* Use the last user time.  It is invalid to use CurrentTime
 27941              according to the ICCCM:
 27942 
 27943                Clients that use a SetInputFocus request must set the
 27944                time field to the timestamp of the event that caused
 27945                them to make the attempt. [...] Note that clients must
 27946                not use CurrentTime in the time field.  */
 27947           time = dpyinfo->last_user_time;
 27948 
 27949           /* Unless the focus doesn't belong to Emacs anymore and
 27950              `x-allow-focus-stealing' is set to Qnewer_time.  */
 27951           if (EQ (Vx_allow_focus_stealing, Qnewer_time)
 27952               && !dpyinfo->x_focus_frame)
 27953             time = x_get_server_time (f);
 27954 
 27955           /* Ignore any BadMatch error this request might result in.
 27956              A BadMatch error can occur if the window was obscured
 27957              after the time of the last user interaction without
 27958              changing the last-focus-change-time.  */
 27959           x_set_input_focus (FRAME_DISPLAY_INFO (f), FRAME_OUTER_WINDOW (f),
 27960                              time);
 27961         }
 27962       else
 27963         x_set_input_focus (FRAME_DISPLAY_INFO (f), FRAME_OUTER_WINDOW (f),
 27964                            /* But when no window manager is in use,
 27965                               respecting the ICCCM doesn't really
 27966                               matter.  */
 27967                            CurrentTime);
 27968     }
 27969 
 27970  out:
 27971   unblock_input ();
 27972 }
 27973 
 27974 
 27975 /* XEmbed implementation.  */
 27976 
 27977 #if defined USE_X_TOOLKIT || ! defined USE_GTK
 27978 
 27979 /* XEmbed implementation.  */
 27980 
 27981 #define XEMBED_VERSION 0
 27982 
 27983 static void
 27984 xembed_set_info (struct frame *f, enum xembed_info flags)
 27985 {
 27986   unsigned long data[2];
 27987   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 27988 
 27989   data[0] = XEMBED_VERSION;
 27990   data[1] = flags;
 27991 
 27992   XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 27993                    dpyinfo->Xatom_XEMBED_INFO, dpyinfo->Xatom_XEMBED_INFO,
 27994                    32, PropModeReplace, (unsigned char *) data, 2);
 27995 }
 27996 #endif /* defined USE_X_TOOLKIT || ! defined USE_GTK */
 27997 
 27998 static void
 27999 xembed_send_message (struct frame *f, Time t, enum xembed_message msg,
 28000                      long int detail, long int data1, long int data2)
 28001 {
 28002   XEvent event;
 28003 
 28004   event.xclient.type = ClientMessage;
 28005   event.xclient.window = FRAME_X_OUTPUT (f)->parent_desc;
 28006   event.xclient.message_type = FRAME_DISPLAY_INFO (f)->Xatom_XEMBED;
 28007   event.xclient.format = 32;
 28008   event.xclient.data.l[0] = t;
 28009   event.xclient.data.l[1] = msg;
 28010   event.xclient.data.l[2] = detail;
 28011   event.xclient.data.l[3] = data1;
 28012   event.xclient.data.l[4] = data2;
 28013 
 28014   /* XXX: the XEmbed spec tells us to trap errors around this request,
 28015      but I don't understand why: there is no way for clients to
 28016      survive the death of the parent anyway.  */
 28017 
 28018   x_ignore_errors_for_next_request (FRAME_DISPLAY_INFO (f));
 28019   XSendEvent (FRAME_X_DISPLAY (f), FRAME_X_OUTPUT (f)->parent_desc,
 28020               False, NoEventMask, &event);
 28021   x_stop_ignoring_errors (FRAME_DISPLAY_INFO (f));
 28022 }
 28023 
 28024 /* Change of visibility.  */
 28025 
 28026 /* This tries to wait until the frame is really visible, depending on
 28027    the value of Vx_wait_for_event_timeout.
 28028    However, if the window manager asks the user where to position
 28029    the frame, this will return before the user finishes doing that.
 28030    The frame will not actually be visible at that time,
 28031    but it will become visible later when the window manager
 28032    finishes with it.  */
 28033 
 28034 void
 28035 x_make_frame_visible (struct frame *f)
 28036 {
 28037 #ifndef USE_GTK
 28038   struct x_display_info *dpyinfo;
 28039   struct x_output *output;
 28040 #endif
 28041   bool output_flushed;
 28042 
 28043   if (FRAME_PARENT_FRAME (f))
 28044     {
 28045       if (!FRAME_VISIBLE_P (f))
 28046         {
 28047           block_input ();
 28048 #ifdef USE_GTK
 28049           gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
 28050           XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 28051                        f->left_pos, f->top_pos);
 28052 #else
 28053           XMapRaised (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f));
 28054 #endif
 28055           unblock_input ();
 28056 
 28057           SET_FRAME_VISIBLE (f, true);
 28058           SET_FRAME_ICONIFIED (f, false);
 28059         }
 28060       return;
 28061     }
 28062 
 28063   block_input ();
 28064 
 28065   gui_set_bitmap_icon (f);
 28066 
 28067 #ifndef USE_GTK
 28068   dpyinfo = FRAME_DISPLAY_INFO (f);
 28069 #endif
 28070 
 28071   if (! FRAME_VISIBLE_P (f))
 28072     {
 28073       /* We test asked_for_visible here to make sure we don't
 28074          call x_set_offset a second time
 28075          if we get to x_make_frame_visible a second time
 28076          before the window gets really visible.  */
 28077       if (! FRAME_ICONIFIED_P (f)
 28078           && ! FRAME_X_EMBEDDED_P (f)
 28079           && ! f->output_data.x->asked_for_visible)
 28080         x_set_offset (f, f->left_pos, f->top_pos, 0);
 28081 
 28082 #ifndef USE_GTK
 28083       output = FRAME_X_OUTPUT (f);
 28084       x_update_frame_user_time_window (f);
 28085 
 28086       /* It's been a while since I wrote that code...  I don't
 28087          remember if it can leave `user_time_window' unset or not.  */
 28088       if (output->user_time_window != None)
 28089         {
 28090           if (dpyinfo->last_user_time)
 28091             XChangeProperty (dpyinfo->display, output->user_time_window,
 28092                              dpyinfo->Xatom_net_wm_user_time,
 28093                              XA_CARDINAL, 32, PropModeReplace,
 28094                              (unsigned char *) &dpyinfo->last_user_time, 1);
 28095           else
 28096             XDeleteProperty (dpyinfo->display, output->user_time_window,
 28097                              dpyinfo->Xatom_net_wm_user_time);
 28098         }
 28099 #endif
 28100 
 28101       f->output_data.x->asked_for_visible = true;
 28102 
 28103       if (! EQ (Vx_no_window_manager, Qt))
 28104         x_wm_set_window_state (f, NormalState);
 28105 #ifdef USE_X_TOOLKIT
 28106       if (FRAME_X_EMBEDDED_P (f))
 28107         xembed_set_info (f, XEMBED_MAPPED);
 28108       else
 28109         {
 28110           /* This was XtPopup, but that did nothing for an iconified frame.  */
 28111           XtMapWidget (f->output_data.x->widget);
 28112         }
 28113 #else /* not USE_X_TOOLKIT */
 28114 #ifdef USE_GTK
 28115       gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
 28116       gtk_window_deiconify (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
 28117 #else
 28118       if (FRAME_X_EMBEDDED_P (f))
 28119         xembed_set_info (f, XEMBED_MAPPED);
 28120       else
 28121         XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
 28122 #endif /* not USE_GTK */
 28123 #endif /* not USE_X_TOOLKIT */
 28124 
 28125       if (FRAME_X_EMBEDDED_P (f))
 28126         {
 28127           SET_FRAME_VISIBLE (f, true);
 28128           SET_FRAME_ICONIFIED (f, false);
 28129         }
 28130     }
 28131 
 28132   /* Synchronize to ensure Emacs knows the frame is visible
 28133      before we do anything else.  We do this loop with input not blocked
 28134      so that incoming events are handled.  */
 28135   {
 28136     Lisp_Object frame;
 28137     /* This must be before UNBLOCK_INPUT
 28138        since events that arrive in response to the actions above
 28139        will set it when they are handled.  */
 28140     bool previously_visible = f->output_data.x->has_been_visible;
 28141 
 28142     XSETFRAME (frame, f);
 28143 
 28144     int original_left = f->left_pos;
 28145     int original_top = f->top_pos;
 28146 
 28147     /* This must come after we set COUNT.  */
 28148     unblock_input ();
 28149 
 28150     /* Keep track of whether or not the output buffer was flushed, to
 28151        avoid any extra flushes.  */
 28152     output_flushed = false;
 28153 
 28154     /* We unblock here so that arriving X events are processed.  */
 28155 
 28156     /* Now move the window back to where it was "supposed to be".
 28157        But don't do it if the gravity is negative.
 28158        When the gravity is negative, this uses a position
 28159        that is 3 pixels too low.  Perhaps that's really the border width.
 28160 
 28161        Don't do this if the window has never been visible before,
 28162        because the window manager may choose the position
 28163        and we don't want to override it.  */
 28164 
 28165     if (!FRAME_VISIBLE_P (f)
 28166         && !FRAME_ICONIFIED_P (f)
 28167         && !FRAME_X_EMBEDDED_P (f)
 28168         && !FRAME_PARENT_FRAME (f)
 28169         && f->win_gravity == NorthWestGravity
 28170         && previously_visible)
 28171       {
 28172         Drawable rootw;
 28173         int x, y;
 28174         unsigned int width, height, border, depth;
 28175 
 28176         block_input ();
 28177 
 28178         /* On some window managers (such as FVWM) moving an existing
 28179            window, even to the same place, causes the window manager
 28180            to introduce an offset.  This can cause the window to move
 28181            to an unexpected location.  Check the geometry (a little
 28182            slow here) and then verify that the window is in the right
 28183            place.  If the window is not in the right place, move it
 28184            there, and take the potential window manager hit.  */
 28185         XGetGeometry (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 28186                       &rootw, &x, &y, &width, &height, &border, &depth);
 28187         output_flushed = true;
 28188 
 28189         if (original_left != x || original_top != y)
 28190           XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 28191                        original_left, original_top);
 28192 
 28193         unblock_input ();
 28194       }
 28195 
 28196     /* Try to wait for a MapNotify event (that is what tells us when a
 28197        frame becomes visible).  */
 28198 
 28199 #ifdef CYGWIN
 28200     /* On Cygwin, which uses input polling, we need to force input to
 28201        be read.  See
 28202        https://lists.gnu.org/r/emacs-devel/2013-12/msg00351.html
 28203        and https://debbugs.gnu.org/cgi/bugreport.cgi?bug=24091#131.
 28204        Fake an alarm signal to let the handler know that there's
 28205        something to be read.
 28206 
 28207        It could be confusing if a real alarm arrives while processing
 28208        the fake one.  Turn it off and let the handler reset it.  */
 28209     int old_poll_suppress_count = poll_suppress_count;
 28210     poll_suppress_count = 1;
 28211     poll_for_input_1 ();
 28212     poll_suppress_count = old_poll_suppress_count;
 28213 #endif
 28214 
 28215     if (!FRAME_VISIBLE_P (f))
 28216       {
 28217         if (CONSP (frame_size_history))
 28218           frame_size_history_plain
 28219             (f, build_string ("x_make_frame_visible"));
 28220 
 28221         x_wait_for_event (f, MapNotify);
 28222         output_flushed = true;
 28223       }
 28224 
 28225     if (!output_flushed)
 28226       x_flush (f);
 28227   }
 28228 }
 28229 
 28230 /* Change from mapped state to withdrawn state.  */
 28231 
 28232 /* Make the frame visible (mapped and not iconified).  */
 28233 
 28234 void
 28235 x_make_frame_invisible (struct frame *f)
 28236 {
 28237   Window window;
 28238 
 28239   /* Use the frame's outermost window, not the one we normally draw on.  */
 28240   window = FRAME_OUTER_WINDOW (f);
 28241 
 28242   /* Don't keep the highlight on an invisible frame.  */
 28243   if (FRAME_DISPLAY_INFO (f)->highlight_frame == f)
 28244     FRAME_DISPLAY_INFO (f)->highlight_frame = 0;
 28245 
 28246   block_input ();
 28247 
 28248   /* Before unmapping the window, update the WM_SIZE_HINTS property to claim
 28249      that the current position of the window is user-specified, rather than
 28250      program-specified, so that when the window is mapped again, it will be
 28251      placed at the same location, without forcing the user to position it
 28252      by hand again (they have already done that once for this window.)  */
 28253   x_wm_set_size_hint (f, 0, true);
 28254 
 28255 #ifdef USE_GTK
 28256   if (FRAME_GTK_OUTER_WIDGET (f))
 28257     gtk_widget_hide (FRAME_GTK_OUTER_WIDGET (f));
 28258   else
 28259 #else
 28260   if (FRAME_X_EMBEDDED_P (f))
 28261     xembed_set_info (f, 0);
 28262   else
 28263 #endif
 28264 
 28265     if (! XWithdrawWindow (FRAME_X_DISPLAY (f), window,
 28266                            DefaultScreen (FRAME_X_DISPLAY (f))))
 28267       {
 28268         unblock_input ();
 28269         error ("Can't notify window manager of window withdrawal");
 28270       }
 28271 
 28272   x_sync (f);
 28273 
 28274   /* We can't distinguish this from iconification
 28275      just by the event that we get from the server.
 28276      So we can't win using the usual strategy of letting
 28277      FRAME_SAMPLE_VISIBILITY set this.  So do it by hand,
 28278      and synchronize with the server to make sure we agree.  */
 28279   SET_FRAME_VISIBLE (f, 0);
 28280   SET_FRAME_ICONIFIED (f, false);
 28281 
 28282   if (CONSP (frame_size_history))
 28283     frame_size_history_plain
 28284       (f, build_string ("x_make_frame_invisible"));
 28285 
 28286   unblock_input ();
 28287 }
 28288 
 28289 static void
 28290 x_make_frame_visible_invisible (struct frame *f, bool visible)
 28291 {
 28292   if (visible)
 28293     x_make_frame_visible (f);
 28294   else
 28295     x_make_frame_invisible (f);
 28296 }
 28297 
 28298 Cursor
 28299 x_create_font_cursor (struct x_display_info *dpyinfo, int glyph)
 28300 {
 28301   if (glyph <= 65535)
 28302     return XCreateFontCursor (dpyinfo->display, glyph);
 28303 
 28304   /* x-pointer-invisible cannot fit in CARD16, and thus cannot be any
 28305      existing cursor.  */
 28306   return make_invisible_cursor (dpyinfo);
 28307 }
 28308 
 28309 
 28310 /* Change window state from mapped to iconified.  */
 28311 
 28312 void
 28313 x_iconify_frame (struct frame *f)
 28314 {
 28315 #ifdef USE_X_TOOLKIT
 28316   int result;
 28317 #endif
 28318 
 28319   /* Don't keep the highlight on an invisible frame.  */
 28320   if (FRAME_DISPLAY_INFO (f)->highlight_frame == f)
 28321     FRAME_DISPLAY_INFO (f)->highlight_frame = 0;
 28322 
 28323   if (FRAME_ICONIFIED_P (f))
 28324     return;
 28325 
 28326   block_input ();
 28327 
 28328   gui_set_bitmap_icon (f);
 28329 
 28330 #if defined (USE_GTK)
 28331   if (FRAME_GTK_OUTER_WIDGET (f))
 28332     {
 28333       if (! FRAME_VISIBLE_P (f))
 28334         gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
 28335 
 28336       gtk_window_iconify (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
 28337       SET_FRAME_VISIBLE (f, 0);
 28338       SET_FRAME_ICONIFIED (f, true);
 28339       unblock_input ();
 28340       return;
 28341     }
 28342 #endif
 28343 
 28344 #ifdef USE_X_TOOLKIT
 28345 
 28346   if (! FRAME_VISIBLE_P (f))
 28347     {
 28348       if (! EQ (Vx_no_window_manager, Qt))
 28349         x_wm_set_window_state (f, IconicState);
 28350       /* This was XtPopup, but that did nothing for an iconified frame.  */
 28351       XtMapWidget (f->output_data.x->widget);
 28352       /* The server won't give us any event to indicate
 28353          that an invisible frame was changed to an icon,
 28354          so we have to record it here.  */
 28355       SET_FRAME_VISIBLE (f, 0);
 28356       SET_FRAME_ICONIFIED (f, true);
 28357       unblock_input ();
 28358       return;
 28359     }
 28360 
 28361   result = XIconifyWindow (FRAME_X_DISPLAY (f),
 28362                            XtWindow (f->output_data.x->widget),
 28363                            DefaultScreen (FRAME_X_DISPLAY (f)));
 28364   unblock_input ();
 28365 
 28366   if (!result)
 28367     error ("Can't notify window manager of iconification");
 28368 
 28369   SET_FRAME_ICONIFIED (f, true);
 28370   SET_FRAME_VISIBLE (f, 0);
 28371 
 28372   block_input ();
 28373   XFlush (FRAME_X_DISPLAY (f));
 28374   unblock_input ();
 28375 #else /* not USE_X_TOOLKIT */
 28376 
 28377   /* Make sure the X server knows where the window should be positioned,
 28378      in case the user deiconifies with the window manager.  */
 28379   if (! FRAME_VISIBLE_P (f)
 28380       && ! FRAME_ICONIFIED_P (f)
 28381       && ! FRAME_X_EMBEDDED_P (f))
 28382     x_set_offset (f, f->left_pos, f->top_pos, 0);
 28383 
 28384   /* Since we don't know which revision of X we're running, we'll use both
 28385      the X11R3 and X11R4 techniques.  I don't know if this is a good idea.  */
 28386 
 28387   /* X11R4: send a ClientMessage to the window manager using the
 28388      WM_CHANGE_STATE type.  */
 28389   {
 28390     XEvent msg;
 28391 
 28392     msg.xclient.window = FRAME_X_WINDOW (f);
 28393     msg.xclient.type = ClientMessage;
 28394     msg.xclient.message_type = FRAME_DISPLAY_INFO (f)->Xatom_wm_change_state;
 28395     msg.xclient.format = 32;
 28396     msg.xclient.data.l[0] = IconicState;
 28397     msg.xclient.data.l[1] = 0;
 28398     msg.xclient.data.l[2] = 0;
 28399     msg.xclient.data.l[3] = 0;
 28400     msg.xclient.data.l[4] = 0;
 28401 
 28402     if (! XSendEvent (FRAME_X_DISPLAY (f),
 28403                       FRAME_DISPLAY_INFO (f)->root_window,
 28404                       False,
 28405                       SubstructureRedirectMask | SubstructureNotifyMask,
 28406                       &msg))
 28407       {
 28408         unblock_input ();
 28409         error ("Can't notify window manager of iconification");
 28410       }
 28411   }
 28412 
 28413   /* X11R3: set the initial_state field of the window manager hints to
 28414      IconicState.  */
 28415   x_wm_set_window_state (f, IconicState);
 28416 
 28417   if (!FRAME_VISIBLE_P (f))
 28418     {
 28419       /* If the frame was withdrawn, before, we must map it.  */
 28420       XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
 28421     }
 28422 
 28423   SET_FRAME_ICONIFIED (f, true);
 28424   SET_FRAME_VISIBLE (f, 0);
 28425 
 28426   XFlush (FRAME_X_DISPLAY (f));
 28427   unblock_input ();
 28428 #endif /* not USE_X_TOOLKIT */
 28429 }
 28430 
 28431 
 28432 /* Free X resources of frame F.  */
 28433 
 28434 void
 28435 x_free_frame_resources (struct frame *f)
 28436 {
 28437   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 28438   Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
 28439 #ifdef USE_X_TOOLKIT
 28440   Lisp_Object bar;
 28441   struct scroll_bar *b;
 28442 #endif
 28443 
 28444   block_input ();
 28445 
 28446 #ifdef HAVE_XINPUT2
 28447   /* Remove any record of this frame being focused.  */
 28448   xi_handle_delete_frame (dpyinfo, f);
 28449 #endif
 28450 
 28451   /* If a display connection is dead, don't try sending more
 28452      commands to the X server.  */
 28453   if (dpyinfo->display)
 28454     {
 28455       /* Always exit with visible pointer to avoid weird issue
 28456          with Xfixes (Bug#17609).  */
 28457       if (f->pointer_invisible)
 28458         XTtoggle_invisible_pointer (f, 0);
 28459 
 28460       /* We must free faces before destroying windows because some
 28461          font-driver (e.g. xft) access a window while finishing a
 28462          face.  */
 28463       free_frame_faces (f);
 28464       tear_down_x_back_buffer (f);
 28465 
 28466       if (f->output_data.x->icon_desc)
 28467         XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->icon_desc);
 28468 
 28469 #ifdef USE_X_TOOLKIT
 28470       /* Explicitly destroy the scroll bars of the frame.  Without
 28471          this, we get "BadDrawable" errors from the toolkit later on,
 28472          presumably from expose events generated for the disappearing
 28473          toolkit scroll bars.  */
 28474       for (bar = FRAME_SCROLL_BARS (f); !NILP (bar); bar = b->next)
 28475         {
 28476           b = XSCROLL_BAR (bar);
 28477           x_scroll_bar_remove (b);
 28478         }
 28479 #endif
 28480 
 28481 #ifdef HAVE_X_I18N
 28482       if (FRAME_XIC (f))
 28483         free_frame_xic (f);
 28484 #endif
 28485 
 28486 #ifdef USE_CAIRO
 28487       x_cr_destroy_frame_context (f);
 28488 #endif
 28489 #ifdef USE_X_TOOLKIT
 28490       if (f->output_data.x->widget)
 28491         {
 28492           XtDestroyWidget (f->output_data.x->widget);
 28493           f->output_data.x->widget = NULL;
 28494         }
 28495       /* Tooltips don't have widgets, only a simple X window, even if
 28496          we are using a toolkit.  */
 28497       else if (FRAME_X_WINDOW (f))
 28498         XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
 28499 
 28500       free_frame_menubar (f);
 28501 
 28502       if (f->shell_position)
 28503         xfree (f->shell_position);
 28504 #else  /* !USE_X_TOOLKIT */
 28505 
 28506 #ifdef HAVE_XWIDGETS
 28507       kill_frame_xwidget_views (f);
 28508 #endif
 28509 
 28510 #ifdef USE_GTK
 28511       xg_free_frame_widgets (f);
 28512 #endif /* USE_GTK */
 28513 
 28514       tear_down_x_back_buffer (f);
 28515       if (FRAME_X_WINDOW (f))
 28516         XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
 28517 #endif /* !USE_X_TOOLKIT */
 28518 
 28519 #ifdef HAVE_XSYNC
 28520       if (FRAME_X_BASIC_COUNTER (f) != None)
 28521         XSyncDestroyCounter (FRAME_X_DISPLAY (f),
 28522                              FRAME_X_BASIC_COUNTER (f));
 28523 
 28524       if (FRAME_X_EXTENDED_COUNTER (f) != None)
 28525         XSyncDestroyCounter (FRAME_X_DISPLAY (f),
 28526                              FRAME_X_EXTENDED_COUNTER (f));
 28527 #endif
 28528 
 28529       unload_color (f, FRAME_FOREGROUND_PIXEL (f));
 28530       unload_color (f, FRAME_BACKGROUND_PIXEL (f));
 28531       unload_color (f, f->output_data.x->cursor_pixel);
 28532       unload_color (f, f->output_data.x->cursor_foreground_pixel);
 28533       unload_color (f, f->output_data.x->border_pixel);
 28534       unload_color (f, f->output_data.x->mouse_pixel);
 28535 
 28536       if (f->output_data.x->scroll_bar_background_pixel != -1)
 28537         unload_color (f, f->output_data.x->scroll_bar_background_pixel);
 28538       if (f->output_data.x->scroll_bar_foreground_pixel != -1)
 28539         unload_color (f, f->output_data.x->scroll_bar_foreground_pixel);
 28540 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
 28541       /* Scrollbar shadow colors.  */
 28542       if (f->output_data.x->scroll_bar_top_shadow_pixel != -1)
 28543         unload_color (f, f->output_data.x->scroll_bar_top_shadow_pixel);
 28544       if (f->output_data.x->scroll_bar_bottom_shadow_pixel != -1)
 28545         unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
 28546 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
 28547       if (f->output_data.x->white_relief.pixel != -1)
 28548         unload_color (f, f->output_data.x->white_relief.pixel);
 28549       if (f->output_data.x->black_relief.pixel != -1)
 28550         unload_color (f, f->output_data.x->black_relief.pixel);
 28551 
 28552       x_free_gcs (f);
 28553 
 28554       /* Free extra GCs allocated by x_setup_relief_colors.  */
 28555       if (f->output_data.x->white_relief.gc)
 28556         {
 28557           XFreeGC (dpyinfo->display, f->output_data.x->white_relief.gc);
 28558           f->output_data.x->white_relief.gc = 0;
 28559         }
 28560       if (f->output_data.x->black_relief.gc)
 28561         {
 28562           XFreeGC (dpyinfo->display, f->output_data.x->black_relief.gc);
 28563           f->output_data.x->black_relief.gc = 0;
 28564         }
 28565 
 28566       /* Free cursors.  */
 28567       if (f->output_data.x->text_cursor != 0)
 28568         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->text_cursor);
 28569       if (f->output_data.x->nontext_cursor != 0)
 28570         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->nontext_cursor);
 28571       if (f->output_data.x->modeline_cursor != 0)
 28572         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->modeline_cursor);
 28573       if (f->output_data.x->hand_cursor != 0)
 28574         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->hand_cursor);
 28575       if (f->output_data.x->hourglass_cursor != 0)
 28576         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->hourglass_cursor);
 28577       if (f->output_data.x->horizontal_drag_cursor != 0)
 28578         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->horizontal_drag_cursor);
 28579       if (f->output_data.x->vertical_drag_cursor != 0)
 28580         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->vertical_drag_cursor);
 28581       if (f->output_data.x->left_edge_cursor != 0)
 28582         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->left_edge_cursor);
 28583       if (f->output_data.x->top_left_corner_cursor != 0)
 28584         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->top_left_corner_cursor);
 28585       if (f->output_data.x->top_edge_cursor != 0)
 28586         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->top_edge_cursor);
 28587       if (f->output_data.x->top_right_corner_cursor != 0)
 28588         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->top_right_corner_cursor);
 28589       if (f->output_data.x->right_edge_cursor != 0)
 28590         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->right_edge_cursor);
 28591       if (f->output_data.x->bottom_right_corner_cursor != 0)
 28592         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->bottom_right_corner_cursor);
 28593       if (f->output_data.x->bottom_edge_cursor != 0)
 28594         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->bottom_edge_cursor);
 28595       if (f->output_data.x->bottom_left_corner_cursor != 0)
 28596         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->bottom_left_corner_cursor);
 28597 
 28598       /* Free sync fences.  */
 28599 #if defined HAVE_XSYNCTRIGGERFENCE && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
 28600       x_sync_free_fences (f);
 28601 #endif
 28602 
 28603 #ifdef USE_TOOLKIT_SCROLL_BARS
 28604       /* Since the frame was destroyed, we can no longer guarantee
 28605          that scroll bar events will be received.  Clear
 28606          protected_windows.  */
 28607       dpyinfo->n_protected_windows = 0;
 28608 #endif
 28609     }
 28610 
 28611 #ifdef HAVE_GTK3
 28612   if (FRAME_OUTPUT_DATA (f)->scrollbar_background_css_provider)
 28613     g_object_unref (FRAME_OUTPUT_DATA (f)->scrollbar_background_css_provider);
 28614 
 28615   if (FRAME_OUTPUT_DATA (f)->scrollbar_foreground_css_provider)
 28616     g_object_unref (FRAME_OUTPUT_DATA (f)->scrollbar_foreground_css_provider);
 28617 #endif
 28618 
 28619   if (f == dpyinfo->motif_drag_atom_owner)
 28620     {
 28621       dpyinfo->motif_drag_atom_owner = NULL;
 28622       dpyinfo->motif_drag_atom = None;
 28623     }
 28624 
 28625   if (f == dpyinfo->x_focus_frame)
 28626     dpyinfo->x_focus_frame = 0;
 28627   if (f == dpyinfo->x_focus_event_frame)
 28628     dpyinfo->x_focus_event_frame = 0;
 28629   if (f == dpyinfo->highlight_frame)
 28630     dpyinfo->highlight_frame = 0;
 28631   if (f == hlinfo->mouse_face_mouse_frame)
 28632     reset_mouse_highlight (hlinfo);
 28633 
 28634 #ifdef HAVE_XINPUT2
 28635   /* Consider a frame being unfocused with no following FocusIn event
 28636      while an older focus from another seat exists.  The client
 28637      pointer should then revert to the other seat, so handle potential
 28638      focus changes.  */
 28639 
 28640   if (dpyinfo->supports_xi2)
 28641     xi_handle_focus_change (dpyinfo);
 28642 #endif
 28643 
 28644   unblock_input ();
 28645 }
 28646 
 28647 
 28648 /* Destroy the X window of frame F.  */
 28649 
 28650 static void
 28651 x_destroy_window (struct frame *f)
 28652 {
 28653   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 28654 
 28655   /* If a display connection is dead, don't try sending more
 28656      commands to the X server.  */
 28657   if (dpyinfo->display != 0)
 28658     x_free_frame_resources (f);
 28659 
 28660   xfree (f->output_data.x->saved_menu_event);
 28661 
 28662 #ifdef HAVE_X_I18N
 28663   if (f->output_data.x->preedit_chars)
 28664     xfree (f->output_data.x->preedit_chars);
 28665 #endif
 28666 
 28667 #ifdef HAVE_XINPUT2
 28668 #ifdef HAVE_XINPUT2_1
 28669   if (f->output_data.x->xi_masks)
 28670     XFree (f->output_data.x->xi_masks);
 28671 #else
 28672   /* This is allocated by us under very old versions of libXi; see
 28673      `setup_xi_event_mask'.  */
 28674   if (f->output_data.x->xi_masks)
 28675     xfree (f->output_data.x->xi_masks);
 28676 #endif
 28677 #endif
 28678 
 28679   xfree (f->output_data.x);
 28680   f->output_data.x = NULL;
 28681 
 28682   dpyinfo->reference_count--;
 28683 }
 28684 
 28685 /* Intern NAME in DPYINFO, but check to see if the atom was already
 28686    interned when the X connection was opened, and use that instead.
 28687 
 28688    If PREDEFINED_ONLY, return None if the atom was not interned during
 28689    connection setup or is predefined.  */
 28690 Atom
 28691 x_intern_cached_atom (struct x_display_info *dpyinfo,
 28692                       const char *name, bool predefined_only)
 28693 {
 28694   int i;
 28695   char *ptr;
 28696   Atom *atom;
 28697 
 28698   /* Special atoms that depend on the screen number.  */
 28699   char xsettings_atom_name[sizeof "_XSETTINGS_S%d" - 2
 28700                            + INT_STRLEN_BOUND (int)];
 28701   char cm_atom_name[sizeof "_NET_WM_CM_S%d" - 2
 28702                     + INT_STRLEN_BOUND (int)];
 28703 
 28704   sprintf (xsettings_atom_name, "_XSETTINGS_S%d",
 28705            XScreenNumberOfScreen (dpyinfo->screen));
 28706   sprintf (cm_atom_name, "_NET_WM_CM_S%d",
 28707            XScreenNumberOfScreen (dpyinfo->screen));
 28708 
 28709   if (!strcmp (name, xsettings_atom_name))
 28710     return dpyinfo->Xatom_xsettings_sel;
 28711 
 28712   if (!strcmp (name, cm_atom_name))
 28713     return dpyinfo->Xatom_NET_WM_CM_Sn;
 28714 
 28715   /* Now do some common predefined atoms.  */
 28716   if (!strcmp (name, "PRIMARY"))
 28717     return XA_PRIMARY;
 28718 
 28719   if (!strcmp (name, "SECONDARY"))
 28720     return XA_SECONDARY;
 28721 
 28722   if (!strcmp (name, "STRING"))
 28723     return XA_STRING;
 28724 
 28725   if (!strcmp (name, "INTEGER"))
 28726     return XA_INTEGER;
 28727 
 28728   if (!strcmp (name, "ATOM"))
 28729     return XA_ATOM;
 28730 
 28731   if (!strcmp (name, "WINDOW"))
 28732     return XA_WINDOW;
 28733 
 28734   if (!strcmp (name, "DRAWABLE"))
 28735     return XA_DRAWABLE;
 28736 
 28737   if (!strcmp (name, "BITMAP"))
 28738     return XA_BITMAP;
 28739 
 28740   if (!strcmp (name, "CARDINAL"))
 28741     return XA_CARDINAL;
 28742 
 28743   if (!strcmp (name, "COLORMAP"))
 28744     return XA_COLORMAP;
 28745 
 28746   if (!strcmp (name, "CURSOR"))
 28747     return XA_CURSOR;
 28748 
 28749   if (!strcmp (name, "FONT"))
 28750     return XA_FONT;
 28751 
 28752   if (dpyinfo->motif_drag_atom != None
 28753       && !strcmp (name, dpyinfo->motif_drag_atom_name))
 28754     return dpyinfo->motif_drag_atom;
 28755 
 28756   for (i = 0; i < ARRAYELTS (x_atom_refs); ++i)
 28757     {
 28758       ptr = (char *) dpyinfo;
 28759 
 28760       if (!strcmp (x_atom_refs[i].name, name))
 28761         {
 28762           atom = (Atom *) (ptr + x_atom_refs[i].offset);
 28763 
 28764           return *atom;
 28765         }
 28766     }
 28767 
 28768   if (predefined_only)
 28769     return None;
 28770 
 28771   return XInternAtom (dpyinfo->display, name, False);
 28772 }
 28773 
 28774 /* Get the name of ATOM, but try not to make a request to the X
 28775    server.  Whether or not a request to the X server happened is
 28776    placed in NEED_SYNC.  */
 28777 char *
 28778 x_get_atom_name (struct x_display_info *dpyinfo, Atom atom,
 28779                  bool *need_sync)
 28780 {
 28781   char *dpyinfo_pointer, *name, *value, *buffer;
 28782   int i;
 28783   Atom ref_atom;
 28784 
 28785   dpyinfo_pointer = (char *) dpyinfo;
 28786   value = NULL;
 28787 
 28788   if (need_sync)
 28789     *need_sync = false;
 28790 
 28791   buffer = alloca (45 + INT_STRLEN_BOUND (int));
 28792 
 28793   switch (atom)
 28794     {
 28795     case XA_PRIMARY:
 28796       return xstrdup ("PRIMARY");
 28797 
 28798     case XA_SECONDARY:
 28799       return xstrdup ("SECONDARY");
 28800 
 28801     case XA_INTEGER:
 28802       return xstrdup ("INTEGER");
 28803 
 28804     case XA_ATOM:
 28805       return xstrdup ("ATOM");
 28806 
 28807     case XA_CARDINAL:
 28808       return xstrdup ("CARDINAL");
 28809 
 28810     case XA_WINDOW:
 28811       return xstrdup ("WINDOW");
 28812 
 28813     case XA_DRAWABLE:
 28814       return xstrdup ("DRAWABLE");
 28815 
 28816     case XA_BITMAP:
 28817       return xstrdup ("BITMAP");
 28818 
 28819     case XA_COLORMAP:
 28820       return xstrdup ("COLORMAP");
 28821 
 28822     case XA_FONT:
 28823       return xstrdup ("FONT");
 28824 
 28825     default:
 28826       if (dpyinfo->motif_drag_atom
 28827           && atom == dpyinfo->motif_drag_atom)
 28828         return xstrdup (dpyinfo->motif_drag_atom_name);
 28829 
 28830       if (atom == dpyinfo->Xatom_xsettings_sel)
 28831         {
 28832           sprintf (buffer, "_XSETTINGS_S%d",
 28833                    XScreenNumberOfScreen (dpyinfo->screen));
 28834           return xstrdup (buffer);
 28835         }
 28836 
 28837       if (atom == dpyinfo->Xatom_NET_WM_CM_Sn)
 28838         {
 28839           sprintf (buffer, "_NET_WM_CM_S%d",
 28840                    XScreenNumberOfScreen (dpyinfo->screen));
 28841           return xstrdup (buffer);
 28842         }
 28843 
 28844       for (i = 0; i < ARRAYELTS (x_atom_refs); ++i)
 28845         {
 28846           ref_atom = *(Atom *) (dpyinfo_pointer
 28847                                 + x_atom_refs[i].offset);
 28848 
 28849           if (atom == ref_atom)
 28850             return xstrdup (x_atom_refs[i].name);
 28851         }
 28852 
 28853       name = XGetAtomName (dpyinfo->display, atom);
 28854 
 28855       if (need_sync)
 28856         *need_sync = true;
 28857 
 28858       if (name)
 28859         {
 28860           value = xstrdup (name);
 28861           XFree (name);
 28862         }
 28863 
 28864       break;
 28865     }
 28866 
 28867   return value;
 28868 }
 28869 
 28870 #ifndef USE_GTK
 28871 
 28872 /* Set up XEmbed for F, and change its save set to handle the parent
 28873    being destroyed.  */
 28874 
 28875 bool
 28876 x_embed_frame (struct x_display_info *dpyinfo, struct frame *f)
 28877 {
 28878   bool rc;
 28879 
 28880   x_catch_errors (dpyinfo->display);
 28881   /* Catch errors; the target window might no longer exist.  */
 28882   XReparentWindow (dpyinfo->display, FRAME_OUTER_WINDOW (f),
 28883                    FRAME_OUTPUT_DATA (f)->parent_desc, 0, 0);
 28884   rc = x_had_errors_p (dpyinfo->display);
 28885   x_uncatch_errors_after_check ();
 28886 
 28887   if (rc)
 28888     return false;
 28889 
 28890   return true;
 28891 }
 28892 
 28893 #endif
 28894 
 28895 
 28896 /* Setting window manager hints.  */
 28897 
 28898 /* Set the normal size hints for the window manager, for frame F.
 28899    FLAGS is the flags word to use--or 0 meaning preserve the flags
 28900    that the window now has.
 28901    If USER_POSITION, set the USPosition
 28902    flag (this is useful when FLAGS is 0).
 28903    The GTK version is in gtkutils.c.  */
 28904 
 28905 void
 28906 x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
 28907 {
 28908 #ifndef USE_GTK
 28909   XSizeHints size_hints;
 28910   Window window = FRAME_OUTER_WINDOW (f);
 28911 #ifdef USE_X_TOOLKIT
 28912   WMShellWidget shell;
 28913 #ifndef USE_MOTIF
 28914   bool hints_changed;
 28915 #endif
 28916 #endif
 28917 
 28918   if (!window)
 28919     return;
 28920 
 28921 #ifdef USE_X_TOOLKIT
 28922   if (f->output_data.x->widget)
 28923     {
 28924       /* Do this dance in xterm.c because some stuff is not as easily
 28925          available in widget.c.  */
 28926 
 28927       eassert (XtIsWMShell (f->output_data.x->widget));
 28928       shell = (WMShellWidget) f->output_data.x->widget;
 28929 
 28930       if (flags)
 28931         {
 28932           shell->wm.size_hints.flags &= ~(PPosition | USPosition);
 28933           shell->wm.size_hints.flags |= flags & (PPosition | USPosition);
 28934         }
 28935 
 28936       if (user_position)
 28937         {
 28938           shell->wm.size_hints.flags &= ~PPosition;
 28939           shell->wm.size_hints.flags |= USPosition;
 28940         }
 28941 
 28942 #ifndef USE_MOTIF
 28943       hints_changed
 28944         = widget_update_wm_size_hints (f->output_data.x->widget,
 28945                                        f->output_data.x->edit_widget);
 28946 #else
 28947       widget_update_wm_size_hints (f->output_data.x->widget,
 28948                                    f->output_data.x->edit_widget);
 28949 
 28950       /* Do this all over again for the benefit of Motif, which always
 28951          knows better than the programmer.  */
 28952       shell->wm.size_hints.flags &= ~(PPosition | USPosition);
 28953       shell->wm.size_hints.flags |= flags & (PPosition | USPosition);
 28954 
 28955       if (user_position)
 28956         {
 28957           shell->wm.size_hints.flags &= ~PPosition;
 28958           shell->wm.size_hints.flags |= USPosition;
 28959         }
 28960 #endif
 28961 
 28962       /* Drill hints into Motif, since it keeps setting its own.  */
 28963       size_hints.flags = shell->wm.size_hints.flags;
 28964       size_hints.x = shell->wm.size_hints.x;
 28965       size_hints.y = shell->wm.size_hints.y;
 28966       size_hints.width = shell->wm.size_hints.width;
 28967       size_hints.height = shell->wm.size_hints.height;
 28968       size_hints.min_width = shell->wm.size_hints.min_width;
 28969       size_hints.min_height = shell->wm.size_hints.min_height;
 28970       size_hints.max_width = shell->wm.size_hints.max_width;
 28971       size_hints.max_height = shell->wm.size_hints.max_height;
 28972       size_hints.width_inc = shell->wm.size_hints.width_inc;
 28973       size_hints.height_inc = shell->wm.size_hints.height_inc;
 28974       size_hints.min_aspect.x = shell->wm.size_hints.min_aspect.x;
 28975       size_hints.min_aspect.y = shell->wm.size_hints.min_aspect.y;
 28976       size_hints.max_aspect.x = shell->wm.size_hints.max_aspect.x;
 28977       size_hints.max_aspect.y = shell->wm.size_hints.max_aspect.y;
 28978       size_hints.base_width = shell->wm.base_width;
 28979       size_hints.base_height = shell->wm.base_height;
 28980       size_hints.win_gravity = shell->wm.win_gravity;
 28981 
 28982 #ifdef USE_MOTIF
 28983       XSetWMNormalHints (XtDisplay (f->output_data.x->widget),
 28984                          XtWindow (f->output_data.x->widget),
 28985                          &size_hints);
 28986 #else
 28987       /* In many cases, widget_update_wm_size_hints will not have
 28988          updated the size hints if only flags changed.  When that
 28989          happens, set the WM hints manually.  */
 28990 
 28991       if (!hints_changed)
 28992         XSetWMNormalHints (XtDisplay (f->output_data.x->widget),
 28993                            XtWindow (f->output_data.x->widget),
 28994                            &size_hints);
 28995 #endif
 28996 
 28997       return;
 28998     }
 28999 #endif
 29000 
 29001   /* Setting PMaxSize caused various problems.  */
 29002   size_hints.flags = PResizeInc | PMinSize /* | PMaxSize */;
 29003 
 29004   size_hints.x = f->left_pos;
 29005   size_hints.y = f->top_pos;
 29006 
 29007   size_hints.width = FRAME_PIXEL_WIDTH (f);
 29008   size_hints.height = FRAME_PIXEL_HEIGHT (f);
 29009 
 29010   size_hints.width_inc = frame_resize_pixelwise ? 1 : FRAME_COLUMN_WIDTH (f);
 29011   size_hints.height_inc = frame_resize_pixelwise ? 1 : FRAME_LINE_HEIGHT (f);
 29012 
 29013   size_hints.max_width = x_display_pixel_width (FRAME_DISPLAY_INFO (f))
 29014     - FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
 29015   size_hints.max_height = x_display_pixel_height (FRAME_DISPLAY_INFO (f))
 29016     - FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0);
 29017 
 29018   /* Calculate the base and minimum sizes.  */
 29019   {
 29020     int base_width, base_height;
 29021 
 29022     base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
 29023     base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0);
 29024 
 29025     /* The window manager uses the base width hints to calculate the
 29026        current number of rows and columns in the frame while
 29027        resizing; min_width and min_height aren't useful for this
 29028        purpose, since they might not give the dimensions for a
 29029        zero-row, zero-column frame.  */
 29030 
 29031     size_hints.flags |= PBaseSize;
 29032     size_hints.base_width = base_width;
 29033     size_hints.base_height = base_height + FRAME_MENUBAR_HEIGHT (f);
 29034     size_hints.min_width  = base_width;
 29035     size_hints.min_height = base_height;
 29036   }
 29037 
 29038   /* If we don't need the old flags, we don't need the old hint at all.  */
 29039   if (flags)
 29040     {
 29041       size_hints.flags |= flags;
 29042       goto no_read;
 29043     }
 29044 
 29045   {
 29046     XSizeHints hints;           /* Sometimes I hate X Windows... */
 29047     long supplied_return;
 29048     int value;
 29049 
 29050     value = XGetWMNormalHints (FRAME_X_DISPLAY (f), window, &hints,
 29051                                &supplied_return);
 29052 
 29053     if (flags)
 29054       size_hints.flags |= flags;
 29055     else
 29056       {
 29057         if (value == 0)
 29058           hints.flags = 0;
 29059         if (hints.flags & PSize)
 29060           size_hints.flags |= PSize;
 29061         if (hints.flags & PPosition)
 29062           size_hints.flags |= PPosition;
 29063         if (hints.flags & USPosition)
 29064           size_hints.flags |= USPosition;
 29065         if (hints.flags & USSize)
 29066           size_hints.flags |= USSize;
 29067       }
 29068   }
 29069 
 29070  no_read:
 29071 
 29072 #ifdef PWinGravity
 29073   size_hints.win_gravity = f->win_gravity;
 29074   size_hints.flags |= PWinGravity;
 29075 
 29076   if (user_position)
 29077     {
 29078       size_hints.flags &= ~ PPosition;
 29079       size_hints.flags |= USPosition;
 29080     }
 29081 #endif /* PWinGravity */
 29082 
 29083   XSetWMNormalHints (FRAME_X_DISPLAY (f), window, &size_hints);
 29084 #else
 29085   xg_wm_set_size_hint (f, flags, user_position);
 29086 #endif /* USE_GTK */
 29087 }
 29088 
 29089 /* Used for IconicState or NormalState */
 29090 
 29091 static void
 29092 x_wm_set_window_state (struct frame *f, int state)
 29093 {
 29094 #ifdef USE_X_TOOLKIT
 29095   Arg al[1];
 29096 
 29097   XtSetArg (al[0], XtNinitialState, state);
 29098   XtSetValues (f->output_data.x->widget, al, 1);
 29099 #else /* not USE_X_TOOLKIT */
 29100   Window window = FRAME_X_WINDOW (f);
 29101 
 29102   f->output_data.x->wm_hints.flags |= StateHint;
 29103   f->output_data.x->wm_hints.initial_state = state;
 29104 
 29105   XSetWMHints (FRAME_X_DISPLAY (f), window, &f->output_data.x->wm_hints);
 29106 #endif /* not USE_X_TOOLKIT */
 29107 }
 29108 
 29109 static void
 29110 x_wm_set_icon_pixmap (struct frame *f, ptrdiff_t pixmap_id)
 29111 {
 29112   Pixmap icon_pixmap, icon_mask;
 29113 
 29114 #if !defined USE_X_TOOLKIT && !defined USE_GTK
 29115   Window window = FRAME_OUTER_WINDOW (f);
 29116 #endif
 29117 
 29118   if (pixmap_id > 0)
 29119     {
 29120       icon_pixmap = image_bitmap_pixmap (f, pixmap_id);
 29121       f->output_data.x->wm_hints.icon_pixmap = icon_pixmap;
 29122       icon_mask = x_bitmap_mask (f, pixmap_id);
 29123       f->output_data.x->wm_hints.icon_mask = icon_mask;
 29124     }
 29125   else
 29126     {
 29127       /* It seems there is no way to turn off use of an icon
 29128          pixmap.  */
 29129       return;
 29130     }
 29131 
 29132 
 29133 #ifdef USE_GTK
 29134   {
 29135     xg_set_frame_icon (f, icon_pixmap, icon_mask);
 29136     return;
 29137   }
 29138 
 29139 #elif defined (USE_X_TOOLKIT) /* same as in x_wm_set_window_state.  */
 29140 
 29141   {
 29142     Arg al[1];
 29143     XtSetArg (al[0], XtNiconPixmap, icon_pixmap);
 29144     XtSetValues (f->output_data.x->widget, al, 1);
 29145     XtSetArg (al[0], XtNiconMask, icon_mask);
 29146     XtSetValues (f->output_data.x->widget, al, 1);
 29147   }
 29148 
 29149 #else /* not USE_X_TOOLKIT && not USE_GTK */
 29150 
 29151   f->output_data.x->wm_hints.flags |= (IconPixmapHint | IconMaskHint);
 29152   XSetWMHints (FRAME_X_DISPLAY (f), window, &f->output_data.x->wm_hints);
 29153 
 29154 #endif /* not USE_X_TOOLKIT && not USE_GTK */
 29155 }
 29156 
 29157 void
 29158 x_wm_set_icon_position (struct frame *f, int icon_x, int icon_y)
 29159 {
 29160   Window window = FRAME_OUTER_WINDOW (f);
 29161 
 29162   f->output_data.x->wm_hints.flags |= IconPositionHint;
 29163   f->output_data.x->wm_hints.icon_x = icon_x;
 29164   f->output_data.x->wm_hints.icon_y = icon_y;
 29165 
 29166   XSetWMHints (FRAME_X_DISPLAY (f), window, &f->output_data.x->wm_hints);
 29167 }
 29168 
 29169 
 29170 /***********************************************************************
 29171                                 Fonts
 29172  ***********************************************************************/
 29173 
 29174 #ifdef GLYPH_DEBUG
 29175 
 29176 /* Check that FONT is valid on frame F.  It is if it can be found in F's
 29177    font table.  */
 29178 
 29179 static void
 29180 x_check_font (struct frame *f, struct font *font)
 29181 {
 29182   eassert (font != NULL && ! NILP (font->props[FONT_TYPE_INDEX]));
 29183   if (font->driver->check)
 29184     eassert (font->driver->check (f, font) == 0);
 29185 }
 29186 
 29187 #endif /* GLYPH_DEBUG */
 29188 
 29189 
 29190 /***********************************************************************
 29191                              Image Hooks
 29192  ***********************************************************************/
 29193 
 29194 static void
 29195 x_free_pixmap (struct frame *f, Emacs_Pixmap pixmap)
 29196 {
 29197 #ifdef USE_CAIRO
 29198   if (pixmap)
 29199     {
 29200       xfree (pixmap->data);
 29201       xfree (pixmap);
 29202     }
 29203 #else
 29204   XFreePixmap (FRAME_X_DISPLAY (f), pixmap);
 29205 #endif
 29206 }
 29207 
 29208 
 29209 /***********************************************************************
 29210                             Initialization
 29211  ***********************************************************************/
 29212 
 29213 #ifdef USE_X_TOOLKIT
 29214 static XrmOptionDescRec emacs_options[] = {
 29215   {(char *) "-geometry", (char *) ".geometry", XrmoptionSepArg, NULL},
 29216   {(char *) "-iconic", (char *) ".iconic", XrmoptionNoArg, (XtPointer) "yes"},
 29217 
 29218   {(char *) "-internal-border-width",
 29219    (char *) "*EmacsScreen.internalBorderWidth", XrmoptionSepArg, NULL},
 29220   {(char *) "-ib", (char *) "*EmacsScreen.internalBorderWidth",
 29221    XrmoptionSepArg, NULL},
 29222   {(char *) "-T", (char *) "*EmacsShell.title", XrmoptionSepArg, NULL},
 29223   {(char *) "-wn", (char *) "*EmacsShell.title", XrmoptionSepArg, NULL},
 29224   {(char *) "-title", (char *) "*EmacsShell.title", XrmoptionSepArg, NULL},
 29225   {(char *) "-iconname", (char *) "*EmacsShell.iconName",
 29226    XrmoptionSepArg, NULL},
 29227   {(char *) "-in", (char *) "*EmacsShell.iconName", XrmoptionSepArg, NULL},
 29228   {(char *) "-mc", (char *) "*pointerColor", XrmoptionSepArg, NULL},
 29229   {(char *) "-cr", (char *) "*cursorColor", XrmoptionSepArg, NULL}
 29230 };
 29231 
 29232 /* Whether atimer for Xt timeouts is activated or not.  */
 29233 
 29234 static bool x_timeout_atimer_activated_flag;
 29235 
 29236 #endif /* USE_X_TOOLKIT */
 29237 
 29238 static int x_initialized;
 29239 
 29240 /* Test whether two display-name strings agree up to the dot that separates
 29241    the screen number from the server number.  */
 29242 static bool
 29243 same_x_server (const char *name1, const char *name2)
 29244 {
 29245   bool seen_colon = false;
 29246   Lisp_Object sysname = Fsystem_name ();
 29247   if (! STRINGP (sysname))
 29248     sysname = empty_unibyte_string;
 29249   const char *system_name = SSDATA (sysname);
 29250   ptrdiff_t system_name_length = SBYTES (sysname);
 29251   ptrdiff_t length_until_period = 0;
 29252 
 29253   while (system_name[length_until_period] != 0
 29254          && system_name[length_until_period] != '.')
 29255     length_until_period++;
 29256 
 29257   /* Treat `unix' like an empty host name.  */
 29258   if (! strncmp (name1, "unix:", 5))
 29259     name1 += 4;
 29260   if (! strncmp (name2, "unix:", 5))
 29261     name2 += 4;
 29262   /* Treat this host's name like an empty host name.  */
 29263   if (! strncmp (name1, system_name, system_name_length)
 29264       && name1[system_name_length] == ':')
 29265     name1 += system_name_length;
 29266   if (! strncmp (name2, system_name, system_name_length)
 29267       && name2[system_name_length] == ':')
 29268     name2 += system_name_length;
 29269   /* Treat this host's domainless name like an empty host name.  */
 29270   if (! strncmp (name1, system_name, length_until_period)
 29271       && name1[length_until_period] == ':')
 29272     name1 += length_until_period;
 29273   if (! strncmp (name2, system_name, length_until_period)
 29274       && name2[length_until_period] == ':')
 29275     name2 += length_until_period;
 29276 
 29277   for (; *name1 != '\0' && *name1 == *name2; name1++, name2++)
 29278     {
 29279       if (*name1 == ':')
 29280         seen_colon = true;
 29281       if (seen_colon && *name1 == '.')
 29282         return true;
 29283     }
 29284   return (seen_colon
 29285           && (*name1 == '.' || *name1 == '\0')
 29286           && (*name2 == '.' || *name2 == '\0'));
 29287 }
 29288 
 29289 /* Count number of set bits in mask and number of bits to shift to
 29290    get to the first bit.  With MASK 0x7e0, *BITS is set to 6, and *OFFSET
 29291    to 5.  */
 29292 static void
 29293 get_bits_and_offset (unsigned long mask, int *bits, int *offset)
 29294 {
 29295   int nr = 0;
 29296   int off = 0;
 29297 
 29298   while (!(mask & 1))
 29299     {
 29300       off++;
 29301       mask >>= 1;
 29302     }
 29303 
 29304   while (mask & 1)
 29305     {
 29306       nr++;
 29307       mask >>= 1;
 29308     }
 29309 
 29310   *offset = off;
 29311   *bits = nr;
 29312 }
 29313 
 29314 /* Return true iff display DISPLAY is available for use.
 29315    But don't permanently open it, just test its availability.  */
 29316 
 29317 bool
 29318 x_display_ok (const char *display)
 29319 {
 29320   /* XOpenDisplay fails if it gets a signal.  Block SIGIO which may arrive.  */
 29321   unrequest_sigio ();
 29322   Display *dpy = XOpenDisplay (display);
 29323   request_sigio ();
 29324   if (!dpy)
 29325     return false;
 29326   XCloseDisplay (dpy);
 29327   return true;
 29328 }
 29329 
 29330 #ifdef USE_GTK
 29331 static void
 29332 my_log_handler (const gchar *log_domain, GLogLevelFlags log_level,
 29333                 const gchar *msg, gpointer user_data)
 29334 {
 29335   if (!strstr (msg, "g_set_prgname"))
 29336       fprintf (stderr, "%s-WARNING **: %s\n", log_domain, msg);
 29337 }
 29338 #endif
 29339 
 29340 /* Current X display connection identifier.  Incremented for each next
 29341    connection established.  */
 29342 static unsigned x_display_id;
 29343 
 29344 #if defined HAVE_XINPUT2 && !defined HAVE_GTK3
 29345 
 29346 /* Select for device change events on the root window of DPYINFO.
 29347    These include device change and hierarchy change notifications.  */
 29348 
 29349 static void
 29350 xi_select_hierarchy_events (struct x_display_info *dpyinfo)
 29351 {
 29352   XIEventMask mask;
 29353   ptrdiff_t l;
 29354   unsigned char *m;
 29355 
 29356   l = XIMaskLen (XI_LASTEVENT);
 29357   mask.mask = m = alloca (l);
 29358   memset (m, 0, l);
 29359   mask.mask_len = l;
 29360 
 29361   mask.deviceid = XIAllDevices;
 29362 
 29363   XISetMask (m, XI_PropertyEvent);
 29364   XISetMask (m, XI_HierarchyChanged);
 29365   XISetMask (m, XI_DeviceChanged);
 29366 
 29367   XISelectEvents (dpyinfo->display, dpyinfo->root_window,
 29368                   &mask, 1);
 29369 }
 29370 
 29371 #endif
 29372 
 29373 #if defined HAVE_XINPUT2 && defined HAVE_GTK3
 29374 
 29375 /* Look up whether or not GTK already initialized the X input
 29376    extension.
 29377 
 29378    Value is 0 if GTK was not built with the input extension, or if it
 29379    was explicitly disabled, 1 if GTK enabled the input extension and
 29380    the version was successfully determined, and 2 if that information
 29381    could not be determined.  */
 29382 
 29383 static int
 29384 xi_check_toolkit (Display *display)
 29385 {
 29386   GdkDisplay *gdpy;
 29387   GdkDeviceManager *manager;
 29388 
 29389   gdpy = gdk_x11_lookup_xdisplay (display);
 29390   eassume (gdpy);
 29391   manager = gdk_display_get_device_manager (gdpy);
 29392 
 29393   if (!strcmp (G_OBJECT_TYPE_NAME (manager),
 29394                "GdkX11DeviceManagerXI2"))
 29395     return 1;
 29396 
 29397   if (!strcmp (G_OBJECT_TYPE_NAME (manager),
 29398                "GdkX11DeviceManagerCore"))
 29399     return 0;
 29400 
 29401   /* Something changed in GDK so this information is no longer
 29402      available.  */
 29403 
 29404   return 2;
 29405 }
 29406 
 29407 #endif
 29408 
 29409 /* Open a connection to X display DISPLAY_NAME, and return the
 29410    structure that describes the open display.  If obtaining the XCB
 29411    connection or toolkit-specific display fails, return NULL.  Signal
 29412    an error if opening the display itself failed.  */
 29413 
 29414 struct x_display_info *
 29415 x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
 29416 {
 29417   Display *dpy;
 29418   struct terminal *terminal;
 29419   struct x_display_info *dpyinfo;
 29420   XrmDatabase xrdb;
 29421 #ifdef USE_XCB
 29422   xcb_connection_t *xcb_conn;
 29423 #endif
 29424   static char const cm_atom_fmt[] = "_NET_WM_CM_S%d";
 29425   char cm_atom_sprintf[sizeof cm_atom_fmt - 2 + INT_STRLEN_BOUND (int)];
 29426 #ifdef USE_GTK
 29427   GdkDisplay *gdpy;
 29428   GdkScreen *gscr;
 29429 #endif
 29430 #ifdef HAVE_XFIXES
 29431   Lisp_Object tem, lisp_name;
 29432   int num_fast_selections;
 29433   Atom selection_name;
 29434 #ifdef USE_XCB
 29435   xcb_get_selection_owner_cookie_t *selection_cookies;
 29436   xcb_get_selection_owner_reply_t *selection_reply;
 29437   xcb_generic_error_t *selection_error;
 29438 #endif
 29439 #endif
 29440   int i;
 29441 
 29442 #if defined HAVE_XFIXES && defined USE_XCB
 29443   USE_SAFE_ALLOCA;
 29444 #endif
 29445 
 29446   block_input ();
 29447 
 29448   if (!x_initialized)
 29449     {
 29450       x_initialize ();
 29451       ++x_initialized;
 29452     }
 29453 
 29454 #if defined USE_X_TOOLKIT || defined USE_GTK
 29455 
 29456   if (!x_display_ok (SSDATA (display_name)))
 29457     error ("Display %s can't be opened", SSDATA (display_name));
 29458 
 29459 #endif
 29460 
 29461 #ifdef USE_GTK
 29462   {
 29463 #define NUM_ARGV 10
 29464     int argc;
 29465     char *argv[NUM_ARGV];
 29466     char **argv2 = argv;
 29467     guint id;
 29468 
 29469     if (x_initialized++ > 1)
 29470       {
 29471         xg_display_open (SSDATA (display_name), &dpy);
 29472       }
 29473     else
 29474       {
 29475         static char display_opt[] = "--display";
 29476         static char name_opt[] = "--name";
 29477 
 29478         for (argc = 0; argc < NUM_ARGV; ++argc)
 29479           argv[argc] = 0;
 29480 
 29481         argc = 0;
 29482         argv[argc++] = initial_argv[0];
 29483 
 29484         if (! NILP (display_name))
 29485           {
 29486             argv[argc++] = display_opt;
 29487             argv[argc++] = SSDATA (display_name);
 29488           }
 29489 
 29490         argv[argc++] = name_opt;
 29491         argv[argc++] = resource_name;
 29492 
 29493         XSetLocaleModifiers ("");
 29494 
 29495         /* Work around GLib bug that outputs a faulty warning. See
 29496            https://bugzilla.gnome.org/show_bug.cgi?id=563627.  */
 29497         id = g_log_set_handler ("GLib", G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL
 29498                                   | G_LOG_FLAG_RECURSION, my_log_handler, NULL);
 29499 
 29500         /* NULL window -> events for all windows go to our function.
 29501            Call before gtk_init so Gtk+ event filters comes after our.  */
 29502         gdk_window_add_filter (NULL, event_handler_gdk, NULL);
 29503 
 29504         /* gtk_init does set_locale.  Fix locale before and after.  */
 29505         fixup_locale ();
 29506         unrequest_sigio (); /* See comment in x_display_ok.  */
 29507         gtk_init (&argc, &argv2);
 29508         request_sigio ();
 29509 
 29510         g_log_remove_handler ("GLib", id);
 29511 
 29512         xg_initialize ();
 29513 
 29514         /* Do this after the call to xg_initialize, because when
 29515            Fontconfig is used, xg_initialize calls its initialization
 29516            function which in some versions of Fontconfig calls setlocale.  */
 29517         fixup_locale ();
 29518 
 29519         dpy = DEFAULT_GDK_DISPLAY ();
 29520 
 29521 #ifndef HAVE_GTK3
 29522         /* Load our own gtkrc if it exists.  */
 29523         {
 29524           const char *file = "~/.emacs.d/gtkrc";
 29525           Lisp_Object s, abs_file;
 29526 
 29527           s = build_string (file);
 29528           abs_file = Fexpand_file_name (s, Qnil);
 29529 
 29530           if (! NILP (abs_file) && !NILP (Ffile_readable_p (abs_file)))
 29531             gtk_rc_parse (SSDATA (abs_file));
 29532         }
 29533 #endif
 29534 
 29535         XSetErrorHandler (x_error_handler);
 29536         XSetIOErrorHandler (x_io_error_quitter);
 29537       }
 29538   }
 29539 #else /* not USE_GTK */
 29540 #ifdef USE_X_TOOLKIT
 29541   /* weiner@footloose.sps.mot.com reports that this causes
 29542      errors with X11R5:
 29543            X protocol error: BadAtom (invalid Atom parameter)
 29544            on protocol request 18skiloaf.
 29545      So let's not use it until R6.  */
 29546 #ifdef HAVE_X11XTR6
 29547   XtSetLanguageProc (NULL, NULL, NULL);
 29548 #endif
 29549 
 29550   {
 29551     int argc = 0;
 29552     char *argv[3];
 29553 
 29554     argv[0] = (char *) "";
 29555     argc = 1;
 29556     if (xrm_option)
 29557       {
 29558         argv[argc++] = (char *) "-xrm";
 29559         argv[argc++] = xrm_option;
 29560       }
 29561     turn_on_atimers (false);
 29562     unrequest_sigio ();  /* See comment in x_display_ok.  */
 29563     dpy = XtOpenDisplay (Xt_app_con, SSDATA (display_name),
 29564                          resource_name, EMACS_CLASS,
 29565                          emacs_options, XtNumber (emacs_options),
 29566                          &argc, argv);
 29567     request_sigio ();
 29568     turn_on_atimers (true);
 29569 
 29570 #ifdef HAVE_X11XTR6
 29571     /* I think this is to compensate for XtSetLanguageProc.  */
 29572     fixup_locale ();
 29573 #endif
 29574   }
 29575 
 29576 #else /* not USE_X_TOOLKIT */
 29577   XSetLocaleModifiers ("");
 29578   unrequest_sigio ();  /* See comment in x_display_ok.  */
 29579   dpy = XOpenDisplay (SSDATA (display_name));
 29580   request_sigio ();
 29581 #endif /* not USE_X_TOOLKIT */
 29582 #endif /* not USE_GTK*/
 29583 
 29584   /* Detect failure.  */
 29585   if (dpy == 0)
 29586     {
 29587 #if !defined USE_X_TOOLKIT && !defined USE_GTK
 29588       /* Avoid opening a display three times (once in dispextern.c
 29589          upon startup, once in x_display_ok, and once above) to
 29590          determine whether or not the display is alive on no toolkit
 29591          builds, where no toolkit initialization happens at all.  */
 29592 
 29593       error ("Display %s can't be opened", SSDATA (display_name));
 29594 #endif
 29595 
 29596       unblock_input ();
 29597 
 29598 #if defined HAVE_XFIXES && defined USE_XCB
 29599       SAFE_FREE ();
 29600 #endif
 29601       return 0;
 29602     }
 29603 
 29604 #ifdef USE_XCB
 29605   xcb_conn = XGetXCBConnection (dpy);
 29606   if (!xcb_conn)
 29607     {
 29608 #ifdef USE_GTK
 29609       xg_display_close (dpy);
 29610 #else
 29611 #ifdef USE_X_TOOLKIT
 29612       XtCloseDisplay (dpy);
 29613 #else
 29614       XCloseDisplay (dpy);
 29615 #endif
 29616 #endif /* ! USE_GTK */
 29617 
 29618       unblock_input ();
 29619 
 29620 #if defined HAVE_XFIXES && defined USE_XCB
 29621       SAFE_FREE ();
 29622 #endif
 29623       return 0;
 29624     }
 29625 #endif
 29626 
 29627   /* Select for structure events on the root window, since this allows
 29628      us to record changes to the size of the screen.  */
 29629 
 29630   XSelectInput (dpy, DefaultRootWindow (dpy), StructureNotifyMask);
 29631 
 29632   /* We have definitely succeeded.  Record the new connection.  */
 29633 
 29634   dpyinfo = xzalloc (sizeof *dpyinfo);
 29635   terminal = x_create_terminal (dpyinfo);
 29636 
 29637   dpyinfo->next_failable_request = dpyinfo->failable_requests;
 29638 
 29639   {
 29640     struct x_display_info *share;
 29641 
 29642     for (share = x_display_list; share; share = share->next)
 29643       if (same_x_server (SSDATA (XCAR (share->name_list_element)),
 29644                          SSDATA (display_name)))
 29645         break;
 29646     if (share)
 29647       terminal->kboard = share->terminal->kboard;
 29648     else
 29649       {
 29650         terminal->kboard = allocate_kboard (Qx);
 29651 
 29652         if (!BASE_EQ (XSYMBOL (Qvendor_specific_keysyms)->u.s.function,
 29653                       Qunbound))
 29654           {
 29655             char *vendor = ServerVendor (dpy);
 29656 
 29657             /* Temporarily hide the partially initialized terminal.  */
 29658             terminal_list = terminal->next_terminal;
 29659             unblock_input ();
 29660             kset_system_key_alist
 29661               (terminal->kboard,
 29662                call1 (Qvendor_specific_keysyms,
 29663                       vendor ? build_string (vendor) : empty_unibyte_string));
 29664             block_input ();
 29665             terminal->next_terminal = terminal_list;
 29666             terminal_list = terminal;
 29667           }
 29668 
 29669         /* Don't let the initial kboard remain current longer than necessary.
 29670            That would cause problems if a file loaded on startup tries to
 29671            prompt in the mini-buffer.  */
 29672         if (current_kboard == initial_kboard)
 29673           current_kboard = terminal->kboard;
 29674       }
 29675     terminal->kboard->reference_count++;
 29676   }
 29677 
 29678   /* Put this display on the chain.  */
 29679   dpyinfo->next = x_display_list;
 29680   x_display_list = dpyinfo;
 29681 
 29682   dpyinfo->name_list_element = Fcons (display_name, Qnil);
 29683   dpyinfo->display = dpy;
 29684   dpyinfo->connection = ConnectionNumber (dpyinfo->display);
 29685 #ifdef USE_XCB
 29686   dpyinfo->xcb_connection = xcb_conn;
 29687 #endif
 29688 
 29689   /* https://lists.gnu.org/r/emacs-devel/2015-11/msg00194.html  */
 29690   dpyinfo->smallest_font_height = 1;
 29691   dpyinfo->smallest_char_width = 1;
 29692 
 29693   dpyinfo->color_names_size = 256;
 29694   dpyinfo->color_names = xzalloc (dpyinfo->color_names_size
 29695                                   * sizeof *dpyinfo->color_names);
 29696   dpyinfo->color_names_length = xzalloc (dpyinfo->color_names_size
 29697                                          * sizeof *dpyinfo->color_names_length);
 29698 
 29699   /* Set the name of the terminal. */
 29700   terminal->name = xlispstrdup (display_name);
 29701 
 29702 #if false
 29703   XSetAfterFunction (dpyinfo->display, x_trace_wire);
 29704 #endif
 29705 
 29706   Lisp_Object system_name = Fsystem_name ();
 29707   static char const title[] = "GNU Emacs";
 29708   if (STRINGP (system_name))
 29709     {
 29710       static char const at[] = " at ";
 29711       ptrdiff_t nbytes = sizeof (title) + sizeof (at);
 29712       if (INT_ADD_WRAPV (nbytes, SBYTES (system_name), &nbytes))
 29713         memory_full (SIZE_MAX);
 29714       dpyinfo->x_id_name = xmalloc (nbytes);
 29715       sprintf (dpyinfo->x_id_name, "%s%s%s", title, at, SDATA (system_name));
 29716     }
 29717   else
 29718     {
 29719       dpyinfo->x_id_name = xmalloc (sizeof (title));
 29720       strcpy (dpyinfo->x_id_name, title);
 29721     }
 29722 
 29723   dpyinfo->x_id = ++x_display_id;
 29724 
 29725 #ifndef HAVE_XKB
 29726   /* Figure out which modifier bits mean what.  */
 29727   x_find_modifier_meanings (dpyinfo);
 29728 #endif
 29729 
 29730   /* Get the scroll bar cursor.  */
 29731 #ifdef USE_GTK
 29732   /* We must create a GTK cursor, it is required for GTK widgets.  */
 29733   dpyinfo->xg_cursor = xg_create_default_cursor (dpyinfo->display);
 29734 #endif /* USE_GTK */
 29735 
 29736   dpyinfo->vertical_scroll_bar_cursor
 29737     = XCreateFontCursor (dpyinfo->display, XC_sb_v_double_arrow);
 29738 
 29739   dpyinfo->horizontal_scroll_bar_cursor
 29740     = XCreateFontCursor (dpyinfo->display, XC_sb_h_double_arrow);
 29741 
 29742   xrdb = x_load_resources (dpyinfo->display, xrm_option,
 29743                            resource_name, EMACS_CLASS);
 29744 #ifdef HAVE_XRMSETDATABASE
 29745   XrmSetDatabase (dpyinfo->display, xrdb);
 29746 #else
 29747   dpyinfo->display->db = xrdb;
 29748 #endif
 29749 
 29750 #ifdef HAVE_XRENDER
 29751   int event_base, error_base;
 29752   dpyinfo->xrender_supported_p
 29753     = XRenderQueryExtension (dpyinfo->display, &event_base, &error_base);
 29754 
 29755   if (dpyinfo->xrender_supported_p)
 29756     dpyinfo->xrender_supported_p
 29757       = XRenderQueryVersion (dpyinfo->display, &dpyinfo->xrender_major,
 29758                              &dpyinfo->xrender_minor);
 29759 #endif
 29760 
 29761   /* This must come after XRenderQueryVersion! */
 29762 #ifdef HAVE_XCOMPOSITE
 29763   int composite_event_base, composite_error_base;
 29764   dpyinfo->composite_supported_p = XCompositeQueryExtension (dpyinfo->display,
 29765                                                              &composite_event_base,
 29766                                                              &composite_error_base);
 29767 
 29768   if (dpyinfo->composite_supported_p)
 29769     dpyinfo->composite_supported_p
 29770       = XCompositeQueryVersion (dpyinfo->display,
 29771                                 &dpyinfo->composite_major,
 29772                                 &dpyinfo->composite_minor);
 29773 #endif
 29774 
 29775 #ifdef HAVE_XSHAPE
 29776   dpyinfo->xshape_supported_p
 29777     = XShapeQueryExtension (dpyinfo->display,
 29778                             &dpyinfo->xshape_event_base,
 29779                             &dpyinfo->xshape_error_base);
 29780 
 29781   if (dpyinfo->xshape_supported_p)
 29782     dpyinfo->xshape_supported_p
 29783       = XShapeQueryVersion (dpyinfo->display,
 29784                             &dpyinfo->xshape_major,
 29785                             &dpyinfo->xshape_minor);
 29786 #endif
 29787 
 29788   /* Put the rdb where we can find it in a way that works on
 29789      all versions.  */
 29790   dpyinfo->rdb = xrdb;
 29791 
 29792   dpyinfo->screen = ScreenOfDisplay (dpyinfo->display,
 29793                                      DefaultScreen (dpyinfo->display));
 29794   select_visual (dpyinfo);
 29795   dpyinfo->cmap = DefaultColormapOfScreen (dpyinfo->screen);
 29796   dpyinfo->root_window = RootWindowOfScreen (dpyinfo->screen);
 29797   dpyinfo->icon_bitmap_id = -1;
 29798   dpyinfo->wm_type = X_WMTYPE_UNKNOWN;
 29799 
 29800   reset_mouse_highlight (&dpyinfo->mouse_highlight);
 29801 
 29802 #ifdef HAVE_XRENDER
 29803   if (dpyinfo->xrender_supported_p
 29804       /* This could already have been initialized by
 29805          `select_visual'.  */
 29806       && !dpyinfo->pict_format)
 29807     dpyinfo->pict_format = XRenderFindVisualFormat (dpyinfo->display,
 29808                                                     dpyinfo->visual);
 29809 #endif
 29810 
 29811 #ifdef HAVE_XSYNC
 29812   int xsync_event_base, xsync_error_base;
 29813   dpyinfo->xsync_supported_p
 29814     = XSyncQueryExtension (dpyinfo->display,
 29815                            &xsync_event_base,
 29816                            &xsync_error_base);
 29817 
 29818   if (dpyinfo->xsync_supported_p)
 29819     dpyinfo->xsync_supported_p = XSyncInitialize (dpyinfo->display,
 29820                                                   &dpyinfo->xsync_major,
 29821                                                   &dpyinfo->xsync_minor);
 29822 
 29823   {
 29824     AUTO_STRING (synchronizeResize, "synchronizeResize");
 29825     AUTO_STRING (SynchronizeResize, "SynchronizeResize");
 29826 
 29827     Lisp_Object value = gui_display_get_resource (dpyinfo,
 29828                                                   synchronizeResize,
 29829                                                   SynchronizeResize,
 29830                                                   Qnil, Qnil);
 29831 
 29832     if (STRINGP (value)
 29833         && (!strcmp (SSDATA (value), "false")
 29834             || !strcmp (SSDATA (value), "off")))
 29835       dpyinfo->xsync_supported_p = false;
 29836   }
 29837 #endif
 29838 
 29839 #ifdef HAVE_XINERAMA
 29840   int xin_event_base, xin_error_base;
 29841   dpyinfo->xinerama_supported_p
 29842     = XineramaQueryExtension (dpy, &xin_event_base, &xin_error_base);
 29843 #endif
 29844 
 29845   /* See if a private colormap is requested.  */
 29846   if (dpyinfo->visual == DefaultVisualOfScreen (dpyinfo->screen))
 29847     {
 29848       if (dpyinfo->visual_info.class == PseudoColor)
 29849         {
 29850           AUTO_STRING (privateColormap, "privateColormap");
 29851           AUTO_STRING (PrivateColormap, "PrivateColormap");
 29852           Lisp_Object value
 29853             = gui_display_get_resource (dpyinfo, privateColormap,
 29854                                         PrivateColormap, Qnil, Qnil);
 29855           if (STRINGP (value)
 29856               && (!strcmp (SSDATA (value), "true")
 29857                   || !strcmp (SSDATA (value), "on")))
 29858             dpyinfo->cmap = XCopyColormapAndFree (dpyinfo->display, dpyinfo->cmap);
 29859         }
 29860     }
 29861   else
 29862     dpyinfo->cmap = XCreateColormap (dpyinfo->display, dpyinfo->root_window,
 29863                                      dpyinfo->visual, AllocNone);
 29864 
 29865   /* See if we can construct pixel values from RGB values.  */
 29866   if (dpyinfo->visual_info.class == TrueColor)
 29867     {
 29868       get_bits_and_offset (dpyinfo->visual_info.red_mask,
 29869                            &dpyinfo->red_bits, &dpyinfo->red_offset);
 29870       get_bits_and_offset (dpyinfo->visual_info.blue_mask,
 29871                            &dpyinfo->blue_bits, &dpyinfo->blue_offset);
 29872       get_bits_and_offset (dpyinfo->visual_info.green_mask,
 29873                            &dpyinfo->green_bits, &dpyinfo->green_offset);
 29874 
 29875 #ifdef HAVE_XRENDER
 29876       if (dpyinfo->pict_format)
 29877         {
 29878           unsigned long channel_mask
 29879             = ((unsigned long) dpyinfo->pict_format->direct.alphaMask
 29880                << dpyinfo->pict_format->direct.alpha);
 29881 
 29882           if (channel_mask)
 29883             get_bits_and_offset (channel_mask, &dpyinfo->alpha_bits,
 29884                                  &dpyinfo->alpha_offset);
 29885           dpyinfo->alpha_mask = channel_mask;
 29886         }
 29887       else
 29888 #endif
 29889         {
 29890           XColor xc;
 29891           unsigned long alpha_mask;
 29892           xc.red = 65535;
 29893           xc.green = 65535;
 29894           xc.blue = 65535;
 29895 
 29896           if (XAllocColor (dpyinfo->display,
 29897                            dpyinfo->cmap, &xc) != 0)
 29898             {
 29899               alpha_mask = xc.pixel & ~(dpyinfo->visual_info.red_mask
 29900                                         | dpyinfo->visual_info.blue_mask
 29901                                         | dpyinfo->visual_info.green_mask);
 29902 
 29903               if (alpha_mask)
 29904                 get_bits_and_offset (alpha_mask, &dpyinfo->alpha_bits,
 29905                                      &dpyinfo->alpha_offset);
 29906               dpyinfo->alpha_mask = alpha_mask;
 29907             }
 29908         }
 29909     }
 29910 
 29911 #ifdef HAVE_XDBE
 29912   dpyinfo->supports_xdbe = false;
 29913   int xdbe_major;
 29914   int xdbe_minor;
 29915   if (XdbeQueryExtension (dpyinfo->display, &xdbe_major, &xdbe_minor))
 29916     dpyinfo->supports_xdbe = true;
 29917 #endif
 29918 
 29919 #ifdef USE_XCB
 29920   xcb_screen_t *xcb_screen = NULL;
 29921   xcb_screen_iterator_t iter;
 29922   xcb_visualid_t wanted = { XVisualIDFromVisual (dpyinfo->visual) };
 29923   xcb_depth_iterator_t depth_iter;
 29924   xcb_visualtype_iterator_t visual_iter;
 29925 
 29926   int screen = DefaultScreen (dpyinfo->display);
 29927 
 29928   iter = xcb_setup_roots_iterator (xcb_get_setup (dpyinfo->xcb_connection));
 29929   for (; iter.rem; --screen, xcb_screen_next (&iter))
 29930     {
 29931       if (!screen)
 29932         xcb_screen = iter.data;
 29933     }
 29934 
 29935   if (xcb_screen)
 29936     {
 29937       depth_iter = xcb_screen_allowed_depths_iterator (xcb_screen);
 29938       for (; depth_iter.rem; xcb_depth_next (&depth_iter))
 29939         {
 29940           visual_iter = xcb_depth_visuals_iterator (depth_iter.data);
 29941           for (; visual_iter.rem; xcb_visualtype_next (&visual_iter))
 29942             {
 29943               if (wanted == visual_iter.data->visual_id)
 29944                 {
 29945                   dpyinfo->xcb_visual = visual_iter.data;
 29946                   break;
 29947                 }
 29948             }
 29949         }
 29950     }
 29951 #endif
 29952 
 29953 #ifdef HAVE_XINPUT2
 29954   dpyinfo->supports_xi2 = false;
 29955   int rc;
 29956   int major = 2;
 29957   int xi_first_event, xi_first_error;
 29958 
 29959 #ifndef HAVE_GTK3
 29960   {
 29961     AUTO_STRING (disableInputExtension, "disableInputExtension");
 29962     AUTO_STRING (DisableInputExtension, "DisableInputExtension");
 29963 
 29964     Lisp_Object value = gui_display_get_resource (dpyinfo,
 29965                                                   disableInputExtension,
 29966                                                   DisableInputExtension,
 29967                                                   Qnil, Qnil);
 29968 
 29969     if (STRINGP (value)
 29970         && (!strcmp (SSDATA (value), "on")
 29971             || !strcmp (SSDATA (value), "true")))
 29972       goto skip_xi_setup;
 29973   }
 29974 #endif
 29975 
 29976 #ifdef HAVE_XINPUT2_4
 29977   int minor = 4;
 29978 #elif defined HAVE_XINPUT2_3 /* XInput 2.3 */
 29979   int minor = 3;
 29980 #elif defined HAVE_XINPUT2_2 /* XInput 2.2 */
 29981   int minor = 2;
 29982 #elif defined HAVE_XINPUT2_1 /* XInput 2.1 */
 29983   int minor = 1;
 29984 #else /* Some old version of XI2 we're not interested in. */
 29985   int minor = 0;
 29986 #endif
 29987 
 29988   dpyinfo->client_pointer_device = -1;
 29989 
 29990 #ifdef HAVE_GTK3
 29991   /* GTK gets a chance to request use of the input extension first.
 29992      If we later try to enable it if GDK did not, then GTK will not
 29993      get the resulting extension events.  */
 29994 
 29995   rc = xi_check_toolkit (dpyinfo->display);
 29996 
 29997   if (!rc)
 29998     goto skip_xi_setup;
 29999 #endif
 30000 
 30001   if (XQueryExtension (dpyinfo->display, "XInputExtension",
 30002                        &dpyinfo->xi2_opcode, &xi_first_event,
 30003                        &xi_first_error))
 30004     {
 30005 #ifdef HAVE_GTK3
 30006       bool move_backwards = false;
 30007       int original_minor = minor;
 30008 
 30009     query:
 30010 
 30011       /* Catch errors caused by GTK requesting a different version of
 30012          XInput 2 than what Emacs was built with.  Usually, the X
 30013          server tolerates these mistakes, but a BadValue error can
 30014          result if only one of GTK or Emacs wasn't built with support
 30015          for XInput 2.2.
 30016 
 30017          To work around the first, it suffices to increase the minor
 30018          version until the X server is happy if the XIQueryVersion
 30019          request results in an error.  If that doesn't work, however,
 30020          then it's the latter, so decrease the minor until the version
 30021          that GTK requested is found.  */
 30022 #endif
 30023 
 30024       x_catch_errors (dpyinfo->display);
 30025 
 30026       rc = XIQueryVersion (dpyinfo->display, &major, &minor);
 30027 
 30028 #ifdef HAVE_GTK3
 30029       /* Increase the minor version until we find one the X
 30030          server agrees with.  If that didn't work, then
 30031          decrease the version until it either hits zero or
 30032          becomes agreeable to the X server.  */
 30033 
 30034       if (x_had_errors_p (dpyinfo->display))
 30035         {
 30036           x_uncatch_errors_after_check ();
 30037 
 30038           /* Since BadValue errors can't be generated if both the
 30039              prior and current requests specify a version of 2.2 or
 30040              later, this means the prior request specified a version
 30041              of the input extension less than 2.2.  */
 30042           if (minor >= 2)
 30043             {
 30044               move_backwards = true;
 30045               minor = original_minor;
 30046 
 30047               if (--minor < 0)
 30048                 rc = BadRequest;
 30049               else
 30050                 goto query;
 30051             }
 30052           else
 30053             {
 30054               if (!move_backwards)
 30055                 {
 30056                   minor++;
 30057                   goto query;
 30058                 }
 30059 
 30060               if (--minor < 0)
 30061                 rc = BadRequest;
 30062               else
 30063                 goto query;
 30064 
 30065             }
 30066         }
 30067       else
 30068         x_uncatch_errors_after_check ();
 30069 
 30070       /* But don't delude ourselves into thinking that we can use
 30071          features provided by a version of the input extension that
 30072          libXi itself doesn't support.  */
 30073 
 30074       if (minor > original_minor)
 30075         minor = original_minor;
 30076 #else
 30077       if (x_had_errors_p (dpyinfo->display))
 30078         rc = BadRequest;
 30079 
 30080       x_uncatch_errors_after_check ();
 30081 #endif
 30082 
 30083       if (rc == Success)
 30084         {
 30085           dpyinfo->supports_xi2 = true;
 30086 #ifndef HAVE_GTK3
 30087           /* Select for hierarchy events on the root window.  GTK 3.x
 30088              does this itself.  */
 30089           xi_select_hierarchy_events (dpyinfo);
 30090 #endif
 30091 
 30092           dpyinfo->xi2_version = minor;
 30093           x_cache_xi_devices (dpyinfo);
 30094         }
 30095     }
 30096  skip_xi_setup:
 30097   ;
 30098 #endif
 30099 
 30100 #if defined HAVE_XRANDR || defined USE_GTK
 30101   Lisp_Object term;
 30102 
 30103   XSETTERMINAL (term, terminal);
 30104 #endif
 30105 
 30106 #ifdef HAVE_XRANDR
 30107   dpyinfo->xrandr_supported_p
 30108     = XRRQueryExtension (dpy, &dpyinfo->xrandr_event_base,
 30109                          &dpyinfo->xrandr_error_base);
 30110 
 30111 #ifndef USE_GTK
 30112   dpyinfo->last_monitor_attributes_list = Qnil;
 30113 #endif
 30114 
 30115   if (dpyinfo->xrandr_supported_p)
 30116     {
 30117       XRRQueryVersion (dpy, &dpyinfo->xrandr_major_version,
 30118                        &dpyinfo->xrandr_minor_version);
 30119 
 30120 #ifndef USE_GTK
 30121       if (dpyinfo->xrandr_major_version == 1
 30122           && dpyinfo->xrandr_minor_version >= 2)
 30123         {
 30124           XRRSelectInput (dpyinfo->display,
 30125                           dpyinfo->root_window,
 30126                           (RRScreenChangeNotifyMask
 30127                            | RRCrtcChangeNotifyMask
 30128                            | RROutputChangeNotifyMask
 30129 #ifdef USE_GTK
 30130                            /* Emacs doesn't actually need this, but
 30131                               GTK selects for it when the display is
 30132                               initialized.  */
 30133                            | RROutputPropertyNotifyMask
 30134 #endif
 30135                            ));
 30136 
 30137           dpyinfo->last_monitor_attributes_list
 30138             = Fx_display_monitor_attributes_list (term);
 30139         }
 30140 #endif
 30141     }
 30142 #endif
 30143 
 30144 #ifdef USE_GTK
 30145   dpyinfo->last_monitor_attributes_list
 30146     = Fx_display_monitor_attributes_list (term);
 30147 
 30148   gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display);
 30149   gscr = gdk_display_get_default_screen (gdpy);
 30150 
 30151   g_signal_connect (G_OBJECT (gscr), "monitors-changed",
 30152                     G_CALLBACK (x_monitors_changed_cb),
 30153                     NULL);
 30154 #endif
 30155 
 30156 #ifdef HAVE_XKB
 30157   int xkb_major, xkb_minor, xkb_op, xkb_error_code;
 30158   xkb_major = XkbMajorVersion;
 30159   xkb_minor = XkbMinorVersion;
 30160 
 30161   if (XkbLibraryVersion (&xkb_major, &xkb_minor)
 30162       && XkbQueryExtension (dpyinfo->display, &xkb_op, &dpyinfo->xkb_event_type,
 30163                             &xkb_error_code, &xkb_major, &xkb_minor))
 30164     {
 30165       dpyinfo->supports_xkb = true;
 30166       dpyinfo->xkb_desc = XkbGetMap (dpyinfo->display,
 30167                                      (XkbKeySymsMask
 30168                                       | XkbKeyTypesMask
 30169                                       | XkbModifierMapMask
 30170                                       | XkbVirtualModsMask),
 30171                                      XkbUseCoreKbd);
 30172 
 30173       if (dpyinfo->xkb_desc)
 30174         XkbGetNames (dpyinfo->display, XkbAllNamesMask,
 30175                      dpyinfo->xkb_desc);
 30176 
 30177       XkbSelectEvents (dpyinfo->display, XkbUseCoreKbd,
 30178                        XkbNewKeyboardNotifyMask | XkbMapNotifyMask,
 30179                        XkbNewKeyboardNotifyMask | XkbMapNotifyMask);
 30180     }
 30181 #endif
 30182 
 30183 #ifdef HAVE_XFIXES
 30184   int xfixes_error_base;
 30185   dpyinfo->xfixes_supported_p
 30186     = XFixesQueryExtension (dpyinfo->display,
 30187                             &dpyinfo->xfixes_event_base,
 30188                             &xfixes_error_base);
 30189 
 30190   if (dpyinfo->xfixes_supported_p)
 30191     {
 30192       if (!XFixesQueryVersion (dpyinfo->display, &dpyinfo->xfixes_major,
 30193                                &dpyinfo->xfixes_minor))
 30194         dpyinfo->xfixes_supported_p = false;
 30195     }
 30196 #endif
 30197 
 30198 #if defined USE_CAIRO || defined HAVE_XFT
 30199   {
 30200     /* If we are using Xft, the following precautions should be made:
 30201 
 30202        1. Make sure that the Xrender extension is added before the Xft one.
 30203        Otherwise, the close-display hook set by Xft is called after the one
 30204        for Xrender, and the former tries to re-add the latter.  This results
 30205        in inconsistency of internal states and leads to X protocol error when
 30206        one reconnects to the same X server (Bug#1696).
 30207 
 30208        2. Check dpi value in X resources.  It is better we use it as well,
 30209        since Xft will use it, as will all Gnome applications.  If our real DPI
 30210        is smaller or larger than the one Xft uses, our font will look smaller
 30211        or larger than other for other applications, even if it is the same
 30212        font name (monospace-10 for example).  */
 30213 
 30214     char *v = XGetDefault (dpyinfo->display, "Xft", "dpi");
 30215     double d;
 30216     if (v != NULL && sscanf (v, "%lf", &d) == 1)
 30217       dpyinfo->resy = dpyinfo->resx = d;
 30218   }
 30219 #endif
 30220 
 30221   if (dpyinfo->resy < 1)
 30222     {
 30223       int screen_number = XScreenNumberOfScreen (dpyinfo->screen);
 30224       double pixels = DisplayHeight (dpyinfo->display, screen_number);
 30225       double mm = DisplayHeightMM (dpyinfo->display, screen_number);
 30226       /* Mac OS X 10.3's Xserver sometimes reports 0.0mm.  */
 30227       dpyinfo->resy = (mm < 1) ? 100 : pixels * 25.4 / mm;
 30228       pixels = DisplayWidth (dpyinfo->display, screen_number);
 30229       mm = DisplayWidthMM (dpyinfo->display, screen_number);
 30230       /* Mac OS X 10.3's Xserver sometimes reports 0.0mm.  */
 30231       dpyinfo->resx = (mm < 1) ? 100 : pixels * 25.4 / mm;
 30232     }
 30233 
 30234   sprintf (cm_atom_sprintf, cm_atom_fmt,
 30235            XScreenNumberOfScreen (dpyinfo->screen));
 30236 
 30237   {
 30238     enum { atom_count = ARRAYELTS (x_atom_refs) };
 30239     /* 1 for _XSETTINGS_SN.  */
 30240     enum { total_atom_count = 2 + atom_count };
 30241     Atom atoms_return[total_atom_count];
 30242     char *atom_names[total_atom_count];
 30243     static char const xsettings_fmt[] = "_XSETTINGS_S%d";
 30244     char xsettings_atom_name[sizeof xsettings_fmt - 2
 30245                              + INT_STRLEN_BOUND (int)];
 30246 
 30247     for (i = 0; i < atom_count; i++)
 30248       atom_names[i] = (char *) x_atom_refs[i].name;
 30249 
 30250     /* Build _XSETTINGS_SN atom name.  */
 30251     sprintf (xsettings_atom_name, xsettings_fmt,
 30252              XScreenNumberOfScreen (dpyinfo->screen));
 30253     atom_names[i] = xsettings_atom_name;
 30254     atom_names[i + 1] = cm_atom_sprintf;
 30255 
 30256     XInternAtoms (dpyinfo->display, atom_names, total_atom_count,
 30257                   False, atoms_return);
 30258 
 30259     for (i = 0; i < atom_count; i++)
 30260       *(Atom *) ((char *) dpyinfo + x_atom_refs[i].offset) = atoms_return[i];
 30261 
 30262     /* Manually copy last two atoms.  */
 30263     dpyinfo->Xatom_xsettings_sel = atoms_return[i];
 30264     dpyinfo->Xatom_NET_WM_CM_Sn = atoms_return[i + 1];
 30265   }
 30266 
 30267 #ifdef HAVE_XKB
 30268   /* Figure out which modifier bits mean what.  */
 30269   x_find_modifier_meanings (dpyinfo);
 30270 #endif
 30271 
 30272   dpyinfo->x_dnd_atoms_size = 16;
 30273   dpyinfo->x_dnd_atoms = xmalloc (sizeof *dpyinfo->x_dnd_atoms
 30274                                   * dpyinfo->x_dnd_atoms_size);
 30275   dpyinfo->gray
 30276     = XCreatePixmapFromBitmapData (dpyinfo->display, dpyinfo->root_window,
 30277                                    gray_bits, gray_width, gray_height,
 30278                                    1, 0, 1);
 30279 
 30280   dpyinfo->invisible_cursor = make_invisible_cursor (dpyinfo);
 30281 #ifdef HAVE_XFIXES
 30282   dpyinfo->fixes_pointer_blanking = egetenv ("EMACS_XFIXES");
 30283 #endif
 30284 
 30285 #ifdef HAVE_X_I18N
 30286   /* Avoid initializing input methods if the X library does not
 30287      support Emacs's locale.  When the current locale is not
 30288      supported, decoding input method strings becomes undefined.  */
 30289   if (XSupportsLocale ())
 30290     xim_initialize (dpyinfo, resource_name);
 30291 #endif
 30292 
 30293   xsettings_initialize (dpyinfo);
 30294 
 30295   /* This is only needed for distinguishing keyboard and process input.  */
 30296   if (dpyinfo->connection != 0)
 30297     add_keyboard_wait_descriptor (dpyinfo->connection);
 30298 
 30299 #ifdef F_SETOWN
 30300   fcntl (dpyinfo->connection, F_SETOWN, getpid ());
 30301 #endif /* ! defined (F_SETOWN) */
 30302 
 30303   if (interrupt_input)
 30304     init_sigio (dpyinfo->connection);
 30305 
 30306 #ifdef USE_LUCID
 30307   {
 30308     XrmValue d, fr, to;
 30309     Font font;
 30310     XFontStruct *query_result;
 30311 
 30312     dpy = dpyinfo->display;
 30313     d.addr = (XPointer) &dpy;
 30314     d.size = sizeof (Display *);
 30315     fr.addr = (char *) XtDefaultFont;
 30316     fr.size = sizeof (XtDefaultFont);
 30317     to.size = sizeof (Font *);
 30318     to.addr = (XPointer) &font;
 30319     x_catch_errors (dpy);
 30320     if (!XtCallConverter (dpy, XtCvtStringToFont, &d, 1, &fr, &to, NULL))
 30321       emacs_abort ();
 30322     query_result = XQueryFont (dpy, font);
 30323 
 30324     /* Set the dialog font to some fallback (here, 9x15) if the font
 30325        specified is invalid.  */
 30326     if (x_had_errors_p (dpy) || !font)
 30327       XrmPutLineResource (&xrdb, "Emacs.dialog.*.font: 9x15");
 30328 
 30329     /* Do not destroy the font struct returned above with XFreeFont;
 30330        that also destroys the font, leading to X protocol errors at
 30331        XtCloseDisplay.  Just free the font info structure.
 30332        (Bug#18403) */
 30333     XFreeFontInfo (NULL, query_result, 1);
 30334     x_uncatch_errors ();
 30335   }
 30336 #endif
 30337 
 30338   /* See if we should run in synchronous mode.  This is useful
 30339      for debugging X code.  */
 30340   {
 30341     AUTO_STRING (synchronous, "synchronous");
 30342     AUTO_STRING (Synchronous, "Synchronous");
 30343     Lisp_Object value = gui_display_get_resource (dpyinfo, synchronous,
 30344                                                   Synchronous, Qnil, Qnil);
 30345     if (STRINGP (value)
 30346         && (!strcmp (SSDATA (value), "true")
 30347             || !strcmp (SSDATA (value), "on")))
 30348       XSynchronize (dpyinfo->display, True);
 30349   }
 30350 
 30351   {
 30352     AUTO_STRING (useXIM, "useXIM");
 30353     AUTO_STRING (UseXIM, "UseXIM");
 30354     Lisp_Object value = gui_display_get_resource (dpyinfo, useXIM, UseXIM,
 30355                                                   Qnil, Qnil);
 30356 #ifdef USE_XIM
 30357     if (STRINGP (value)
 30358         && (!strcmp (SSDATA (value), "false")
 30359             || !strcmp (SSDATA (value), "off")))
 30360       use_xim = false;
 30361 #else
 30362     if (STRINGP (value)
 30363         && (!strcmp (SSDATA (value), "true")
 30364             || !strcmp (SSDATA (value), "on")))
 30365       use_xim = true;
 30366 #endif
 30367   }
 30368 
 30369 #ifdef HAVE_X_I18N
 30370   {
 30371     AUTO_STRING (inputStyle, "inputStyle");
 30372     AUTO_STRING (InputStyle, "InputStyle");
 30373     Lisp_Object value = gui_display_get_resource (dpyinfo, inputStyle, InputStyle,
 30374                                                   Qnil, Qnil);
 30375 
 30376     if (STRINGP (value))
 30377       {
 30378         if (!strcmp (SSDATA (value), "callback"))
 30379           dpyinfo->preferred_xim_style = STYLE_CALLBACK;
 30380         else if (!strcmp (SSDATA (value), "none"))
 30381           dpyinfo->preferred_xim_style = STYLE_NONE;
 30382         else if (!strcmp (SSDATA (value), "overthespot"))
 30383           dpyinfo->preferred_xim_style = STYLE_OVERTHESPOT;
 30384         else if (!strcmp (SSDATA (value), "offthespot"))
 30385           dpyinfo->preferred_xim_style = STYLE_OFFTHESPOT;
 30386         else if (!strcmp (SSDATA (value), "root"))
 30387           dpyinfo->preferred_xim_style = STYLE_ROOT;
 30388 #ifdef USE_GTK
 30389         else if (!strcmp (SSDATA (value), "native"))
 30390           dpyinfo->prefer_native_input = true;
 30391 #endif
 30392       }
 30393   }
 30394 #endif
 30395 
 30396 #ifdef HAVE_X_SM
 30397   /* Only do this for the very first display in the Emacs session.
 30398      Ignore X session management when Emacs was first started on a
 30399      tty or started as a daemon.  */
 30400   if (!dpyinfo->next && ! IS_DAEMON)
 30401     x_session_initialize (dpyinfo);
 30402 #endif
 30403 
 30404 #if defined USE_CAIRO || defined HAVE_XRENDER
 30405   x_extension_initialize (dpyinfo);
 30406 #endif
 30407 
 30408 #ifdef USE_TOOLKIT_SCROLL_BARS
 30409   dpyinfo->protected_windows = xmalloc (sizeof (Lisp_Object) * 256);
 30410   dpyinfo->n_protected_windows = 0;
 30411   dpyinfo->protected_windows_max = 256;
 30412 #endif
 30413 
 30414 #ifdef HAVE_XFIXES
 30415   /* Initialize selection tracking for the selections in
 30416      x-fast-selection-list.  */
 30417 
 30418   if (CONSP (Vx_fast_selection_list)
 30419       && dpyinfo->xfixes_supported_p
 30420       && dpyinfo->xfixes_major >= 1)
 30421     {
 30422       num_fast_selections = 0;
 30423       tem = Vx_fast_selection_list;
 30424 
 30425       FOR_EACH_TAIL_SAFE (tem)
 30426         {
 30427           if (!SYMBOLP (XCAR (tem)))
 30428             continue;
 30429 
 30430           num_fast_selections++;
 30431         }
 30432 
 30433       dpyinfo->n_monitored_selections = num_fast_selections;
 30434       dpyinfo->selection_tracking_window
 30435         = x_create_special_window (dpyinfo, dpyinfo->root_window);
 30436       dpyinfo->monitored_selections
 30437         = xmalloc (num_fast_selections
 30438                    * sizeof *dpyinfo->monitored_selections);
 30439 
 30440       num_fast_selections = 0;
 30441       tem = Vx_fast_selection_list;
 30442 
 30443       FOR_EACH_TAIL_SAFE (tem)
 30444         {
 30445           lisp_name = XCAR (tem);
 30446 
 30447           if (!SYMBOLP (lisp_name))
 30448             continue;
 30449 
 30450           selection_name = symbol_to_x_atom (dpyinfo, lisp_name);
 30451           dpyinfo->monitored_selections[num_fast_selections++].name
 30452             = selection_name;
 30453           dpyinfo->monitored_selections[num_fast_selections - 1].owner
 30454             = X_INVALID_WINDOW;
 30455 
 30456           /* Select for selection input.  */
 30457           XFixesSelectSelectionInput (dpyinfo->display,
 30458                                       dpyinfo->selection_tracking_window,
 30459                                       selection_name,
 30460                                       (XFixesSetSelectionOwnerNotifyMask
 30461                                        | XFixesSetSelectionOwnerNotifyMask
 30462                                        | XFixesSelectionClientCloseNotifyMask));
 30463         }
 30464 
 30465 #ifdef USE_XCB
 30466       selection_cookies = SAFE_ALLOCA (sizeof *selection_cookies
 30467                                        * num_fast_selections);
 30468 #endif
 30469 
 30470       /* Now, ask for the current owners of all those selections.  */
 30471       for (i = 0; i < num_fast_selections; ++i)
 30472         {
 30473 #ifdef USE_XCB
 30474           selection_cookies[i]
 30475             = xcb_get_selection_owner (dpyinfo->xcb_connection,
 30476                                        dpyinfo->monitored_selections[i].name);
 30477 #else
 30478           dpyinfo->monitored_selections[i].owner
 30479             = XGetSelectionOwner (dpyinfo->display,
 30480                                   dpyinfo->monitored_selections[i].name);
 30481 #endif
 30482         }
 30483 
 30484 #ifdef USE_XCB
 30485       for (i = 0; i < num_fast_selections; ++i)
 30486         {
 30487           selection_reply
 30488             = xcb_get_selection_owner_reply (dpyinfo->xcb_connection,
 30489                                              selection_cookies[i],
 30490                                              &selection_error);
 30491 
 30492           if (selection_reply)
 30493             {
 30494               dpyinfo->monitored_selections[i].owner
 30495                 = selection_reply->owner;
 30496               free (selection_reply);
 30497             }
 30498           else if (selection_error)
 30499             free (selection_error);
 30500         }
 30501 #endif
 30502     }
 30503 #endif
 30504 
 30505   unblock_input ();
 30506 
 30507 #if defined HAVE_XFIXES && defined USE_XCB
 30508   SAFE_FREE ();
 30509 #endif
 30510   return dpyinfo;
 30511 }
 30512 
 30513 
 30514 
 30515 /* Remove all the selection input events on the keyboard buffer
 30516    intended for DPYINFO.  */
 30517 
 30518 static void
 30519 x_delete_selection_requests (struct x_display_info *dpyinfo)
 30520 {
 30521   union buffered_input_event *event;
 30522   int moved_events;
 30523 
 30524   for (event = kbd_fetch_ptr; event != kbd_store_ptr;
 30525        event = X_NEXT_KBD_EVENT (event))
 30526     {
 30527       if (event->kind == SELECTION_REQUEST_EVENT
 30528           || event->kind == SELECTION_CLEAR_EVENT)
 30529         {
 30530           if (SELECTION_EVENT_DPYINFO (&event->sie) != dpyinfo)
 30531             continue;
 30532 
 30533           /* Remove the event from the fifo buffer before processing;
 30534              otherwise swallow_events called recursively could see it
 30535              and process it again.  To do this, we move the events
 30536              between kbd_fetch_ptr and EVENT one slot to the right,
 30537              cyclically.  */
 30538 
 30539           if (event < kbd_fetch_ptr)
 30540             {
 30541               memmove (kbd_buffer + 1, kbd_buffer,
 30542                        (event - kbd_buffer) * sizeof *kbd_buffer);
 30543               kbd_buffer[0] = kbd_buffer[KBD_BUFFER_SIZE - 1];
 30544               moved_events = kbd_buffer + KBD_BUFFER_SIZE - 1 - kbd_fetch_ptr;
 30545             }
 30546           else
 30547             moved_events = event - kbd_fetch_ptr;
 30548 
 30549           memmove (kbd_fetch_ptr + 1, kbd_fetch_ptr,
 30550                    moved_events * sizeof *kbd_fetch_ptr);
 30551           kbd_fetch_ptr = X_NEXT_KBD_EVENT (kbd_fetch_ptr);
 30552 
 30553           /* `detect_input_pending' will then recompute whether or not
 30554              pending input events exist.  */
 30555           input_pending = false;
 30556         }
 30557     }
 30558 }
 30559 
 30560 /* Get rid of display DPYINFO, deleting all frames on it,
 30561    and without sending any more commands to the X server.  */
 30562 
 30563 static void
 30564 x_delete_display (struct x_display_info *dpyinfo)
 30565 {
 30566   struct terminal *t;
 30567   struct color_name_cache_entry *color_entry, *next_color_entry;
 30568   int i;
 30569   struct x_selection_request_event *ie, *last, *temp;
 30570 
 30571   /* Close all frames and delete the generic struct terminal for this
 30572      X display.  */
 30573   for (t = terminal_list; t; t = t->next_terminal)
 30574     if (t->type == output_x_window && t->display_info.x == dpyinfo)
 30575       {
 30576 #ifdef HAVE_X_SM
 30577         /* Close X session management when we close its display.  */
 30578         if (t->id == 1 && x_session_have_connection ())
 30579           x_session_close ();
 30580 #endif
 30581         delete_terminal (t);
 30582         break;
 30583       }
 30584 
 30585   /* Find any pending selection requests for this display and unchain
 30586      them.  */
 30587 
 30588   last = NULL;
 30589 
 30590   for (ie = pending_selection_requests; ie; ie = ie->next)
 30591     {
 30592     again:
 30593 
 30594       if (SELECTION_EVENT_DPYINFO (&ie->se) == dpyinfo)
 30595         {
 30596           if (last)
 30597             last->next = ie->next;
 30598 
 30599           temp = ie;
 30600           ie = ie->next;
 30601           xfree (temp);
 30602 
 30603           goto again;
 30604         }
 30605 
 30606       last = ie;
 30607     }
 30608 
 30609   x_delete_selection_requests (dpyinfo);
 30610 
 30611   if (next_noop_dpyinfo == dpyinfo)
 30612     next_noop_dpyinfo = dpyinfo->next;
 30613 
 30614   if (mouse_click_timeout_display == dpyinfo)
 30615     mouse_click_timeout_display = NULL;
 30616 
 30617   if (x_display_list == dpyinfo)
 30618     x_display_list = dpyinfo->next;
 30619   else
 30620     {
 30621       struct x_display_info *tail;
 30622 
 30623       for (tail = x_display_list; tail; tail = tail->next)
 30624         if (tail->next == dpyinfo)
 30625           tail->next = tail->next->next;
 30626     }
 30627 
 30628   for (i = 0; i < dpyinfo->color_names_size; ++i)
 30629     {
 30630       for (color_entry = dpyinfo->color_names[i];
 30631            color_entry; color_entry = next_color_entry)
 30632         {
 30633           next_color_entry = color_entry->next;
 30634 
 30635           xfree (color_entry->name);
 30636           xfree (color_entry);
 30637         }
 30638     }
 30639 
 30640   if (dpyinfo->net_supported_atoms)
 30641     XFree (dpyinfo->net_supported_atoms);
 30642 
 30643   xfree (dpyinfo->color_names);
 30644   xfree (dpyinfo->color_names_length);
 30645   xfree (dpyinfo->x_id_name);
 30646   xfree (dpyinfo->x_dnd_atoms);
 30647   xfree (dpyinfo->color_cells);
 30648 #ifdef HAVE_XFIXES
 30649   if (dpyinfo->monitored_selections)
 30650     xfree (dpyinfo->monitored_selections);
 30651 #endif
 30652 #ifdef USE_TOOLKIT_SCROLL_BARS
 30653   xfree (dpyinfo->protected_windows);
 30654 #endif
 30655 #ifdef HAVE_XINPUT2
 30656   if (dpyinfo->supports_xi2)
 30657     x_free_xi_devices (dpyinfo);
 30658 #endif
 30659   xfree (dpyinfo);
 30660 }
 30661 
 30662 #ifdef USE_X_TOOLKIT
 30663 
 30664 /* Atimer callback function for TIMER.  Called every 0.1s to process
 30665    Xt timeouts, if needed.  We must avoid calling XtAppPending as
 30666    much as possible because that function does an implicit XFlush
 30667    that slows us down.  */
 30668 
 30669 static void
 30670 x_process_timeouts (struct atimer *timer)
 30671 {
 30672   block_input ();
 30673   x_timeout_atimer_activated_flag = false;
 30674   if (toolkit_scroll_bar_interaction || popup_activated ())
 30675     {
 30676       while (XtAppPending (Xt_app_con) & XtIMTimer)
 30677         XtAppProcessEvent (Xt_app_con, XtIMTimer);
 30678       /* Reactivate the atimer for next time.  */
 30679       x_activate_timeout_atimer ();
 30680     }
 30681   unblock_input ();
 30682 }
 30683 
 30684 /* Install an asynchronous timer that processes Xt timeout events
 30685    every 0.1s as long as either `toolkit_scroll_bar_interaction' or
 30686    `popup_activated_flag' (in xmenu.c) is set.  Make sure to call this
 30687    function whenever these variables are set.  This is necessary
 30688    because some widget sets use timeouts internally, for example the
 30689    LessTif menu bar, or the Xaw3d scroll bar.  When Xt timeouts aren't
 30690    processed, these widgets don't behave normally.  */
 30691 
 30692 void
 30693 x_activate_timeout_atimer (void)
 30694 {
 30695   block_input ();
 30696   if (!x_timeout_atimer_activated_flag)
 30697     {
 30698       struct timespec interval = make_timespec (0, 100 * 1000 * 1000);
 30699       start_atimer (ATIMER_RELATIVE, interval, x_process_timeouts, 0);
 30700       x_timeout_atimer_activated_flag = true;
 30701     }
 30702   unblock_input ();
 30703 }
 30704 
 30705 #endif /* USE_X_TOOLKIT */
 30706 
 30707 
 30708 /* Set up use of X before we make the first connection.  */
 30709 
 30710 extern frame_parm_handler x_frame_parm_handlers[];
 30711 
 30712 static struct redisplay_interface x_redisplay_interface =
 30713   {
 30714     x_frame_parm_handlers,
 30715     gui_produce_glyphs,
 30716     gui_write_glyphs,
 30717     gui_insert_glyphs,
 30718     gui_clear_end_of_line,
 30719     x_scroll_run,
 30720     x_after_update_window_line,
 30721     NULL, /* update_window_begin */
 30722     NULL, /* update_window_end   */
 30723     x_flip_and_flush,
 30724     gui_clear_window_mouse_face,
 30725     gui_get_glyph_overhangs,
 30726     gui_fix_overlapping_area,
 30727     x_draw_fringe_bitmap,
 30728 #ifdef USE_CAIRO
 30729     x_cr_define_fringe_bitmap,
 30730     x_cr_destroy_fringe_bitmap,
 30731 #else
 30732     0, /* define_fringe_bitmap */
 30733     0, /* destroy_fringe_bitmap */
 30734 #endif
 30735     x_compute_glyph_string_overhangs,
 30736     x_draw_glyph_string,
 30737     x_define_frame_cursor,
 30738     x_clear_frame_area,
 30739     x_clear_under_internal_border,
 30740     x_draw_window_cursor,
 30741     x_draw_vertical_window_border,
 30742     x_draw_window_divider,
 30743     x_shift_glyphs_for_insert, /* Never called; see comment in function.  */
 30744     x_show_hourglass,
 30745     x_hide_hourglass,
 30746     x_default_font_parameter
 30747   };
 30748 
 30749 
 30750 /* This function is called when the last frame on a display is deleted. */
 30751 void
 30752 x_delete_terminal (struct terminal *terminal)
 30753 {
 30754   struct x_display_info *dpyinfo;
 30755   struct frame *f;
 30756   Lisp_Object tail, frame;
 30757 
 30758   dpyinfo = terminal->display_info.x;
 30759 
 30760   /* Protect against recursive calls.  delete_frame in
 30761      delete_terminal calls us back when it deletes our last frame.  */
 30762   if (!terminal->name)
 30763     return;
 30764 
 30765   block_input ();
 30766 
 30767   /* Delete all remaining frames on the display that is going away.
 30768      Otherwise, font backends assume the display is still up, and
 30769      xftfont_end_for_frame crashes.  */
 30770   FOR_EACH_FRAME (tail, frame)
 30771     {
 30772       f = XFRAME (frame);
 30773 
 30774       if (FRAME_LIVE_P (f) && f->terminal == terminal)
 30775         /* Pass Qnoelisp rather than Qt.  */
 30776         delete_frame (frame, Qnoelisp);
 30777     }
 30778 
 30779 #ifdef HAVE_X_I18N
 30780   /* We must close our connection to the XIM server before closing the
 30781      X display.  */
 30782   if (dpyinfo->xim)
 30783     xim_close_dpy (dpyinfo);
 30784 #endif
 30785 
 30786   /* Normally, the display is available...  */
 30787   if (dpyinfo->display)
 30788     {
 30789       image_destroy_all_bitmaps (dpyinfo);
 30790       XSetCloseDownMode (dpyinfo->display, DestroyAll);
 30791 
 30792       /* Delete the scratch cursor GC, should it exist.  */
 30793       if (dpyinfo->scratch_cursor_gc)
 30794         XFreeGC (dpyinfo->display, dpyinfo->scratch_cursor_gc);
 30795 
 30796       /* Get rid of any drag-and-drop operation that might be in
 30797          progress as well.  */
 30798       if ((x_dnd_in_progress || x_dnd_waiting_for_finish)
 30799           && dpyinfo->display == (x_dnd_waiting_for_finish
 30800                                   ? x_dnd_finish_display
 30801                                   : FRAME_X_DISPLAY (x_dnd_frame)))
 30802         {
 30803           x_dnd_last_seen_window = None;
 30804           x_dnd_last_seen_toplevel = None;
 30805           x_dnd_in_progress = false;
 30806           x_dnd_waiting_for_finish = false;
 30807 
 30808           /* The display is going away, so there's no point in
 30809              de-selecting for input on the DND toplevels.  */
 30810           if (x_dnd_use_toplevels)
 30811             x_dnd_free_toplevels (false);
 30812 
 30813           x_dnd_return_frame_object = NULL;
 30814           x_dnd_movement_frame = NULL;
 30815           x_dnd_wheel_frame = NULL;
 30816           x_dnd_frame = NULL;
 30817         }
 30818 
 30819       /* Whether or not XCloseDisplay destroys the associated resource
 30820          database depends on the version of libX11.  To avoid both
 30821          crash and memory leak, we dissociate the database from the
 30822          display and then destroy dpyinfo->rdb ourselves.
 30823 
 30824          Unfortunately, the above strategy does not work in some
 30825          situations due to a bug in newer versions of libX11: because
 30826          XrmSetDatabase doesn't clear the flag XlibDisplayDfltRMDB if
 30827          dpy->db is NULL, XCloseDisplay destroys the associated
 30828          database whereas it has not been created by XGetDefault
 30829          (Bug#21974 in freedesktop.org Bugzilla).  As a workaround, we
 30830          don't destroy the database here in order to avoid the crash
 30831          in the above situations for now, though that may cause memory
 30832          leaks in other situations.  */
 30833 #if false
 30834 #ifdef HAVE_XRMSETDATABASE
 30835       XrmSetDatabase (dpyinfo->display, NULL);
 30836 #else
 30837       dpyinfo->display->db = NULL;
 30838 #endif
 30839       /* We used to call XrmDestroyDatabase from x_delete_display, but
 30840          some older versions of libX11 crash if we call it after
 30841          closing all the displays.  */
 30842       XrmDestroyDatabase (dpyinfo->rdb);
 30843 #endif
 30844 #ifdef USE_GTK
 30845       xg_display_close (dpyinfo->display);
 30846 #else
 30847 #ifdef USE_X_TOOLKIT
 30848       XtCloseDisplay (dpyinfo->display);
 30849 #else
 30850       XCloseDisplay (dpyinfo->display);
 30851 #endif
 30852 #endif /* ! USE_GTK */
 30853       /* Do not close the connection here because it's already closed
 30854          by X(t)CloseDisplay (Bug#18403).  */
 30855       dpyinfo->display = NULL;
 30856     }
 30857 
 30858   /* ...but if called from x_connection_closed, the display may already
 30859      be closed and dpyinfo->display was set to 0 to indicate that.  Since
 30860      X server is most likely gone, explicit close is the only reliable
 30861      way to continue and avoid Bug#19147.  */
 30862   else if (dpyinfo->connection >= 0)
 30863     emacs_close (dpyinfo->connection);
 30864 
 30865   /* Free the keyboard and modifier maps here; that is safe to do
 30866      without a display, and not doing so leads to a lot of data being
 30867      leaked upon IO error.  */
 30868 
 30869 #ifdef HAVE_XKB
 30870   if (dpyinfo->xkb_desc)
 30871     XkbFreeKeyboard (dpyinfo->xkb_desc, XkbAllComponentsMask, True);
 30872 #endif
 30873 
 30874   if (dpyinfo->modmap)
 30875     XFreeModifiermap (dpyinfo->modmap);
 30876 
 30877   /* No more input on this descriptor.  */
 30878   delete_keyboard_wait_descriptor (dpyinfo->connection);
 30879   /* Mark as dead. */
 30880   dpyinfo->connection = -1;
 30881 
 30882   x_delete_display (dpyinfo);
 30883   unblock_input ();
 30884 }
 30885 
 30886 #ifdef HAVE_XINPUT2
 30887 static bool
 30888 x_have_any_grab (struct x_display_info *dpyinfo)
 30889 {
 30890   int i;
 30891 
 30892   if (!dpyinfo->supports_xi2)
 30893     return false;
 30894 
 30895   for (i = 0; i < dpyinfo->num_devices; ++i)
 30896     {
 30897       if (dpyinfo->devices[i].grab)
 30898         return true;
 30899     }
 30900 
 30901   return false;
 30902 }
 30903 #endif
 30904 
 30905 /* Create a struct terminal, initialize it with the X11 specific
 30906    functions and make DISPLAY->TERMINAL point to it.  */
 30907 
 30908 static struct terminal *
 30909 x_create_terminal (struct x_display_info *dpyinfo)
 30910 {
 30911   struct terminal *terminal;
 30912 
 30913   terminal = create_terminal (output_x_window, &x_redisplay_interface);
 30914 
 30915   terminal->display_info.x = dpyinfo;
 30916   dpyinfo->terminal = terminal;
 30917 
 30918   /* kboard is initialized in x_term_init. */
 30919 
 30920   terminal->clear_frame_hook = x_clear_frame;
 30921   terminal->ins_del_lines_hook = x_ins_del_lines;
 30922   terminal->delete_glyphs_hook = x_delete_glyphs;
 30923   terminal->ring_bell_hook = XTring_bell;
 30924   terminal->toggle_invisible_pointer_hook = XTtoggle_invisible_pointer;
 30925   terminal->update_begin_hook = x_update_begin;
 30926   terminal->update_end_hook = x_update_end;
 30927   terminal->read_socket_hook = XTread_socket;
 30928   terminal->frame_up_to_date_hook = XTframe_up_to_date;
 30929 #ifdef HAVE_XDBE
 30930   terminal->buffer_flipping_unblocked_hook = XTbuffer_flipping_unblocked_hook;
 30931 #endif
 30932   terminal->defined_color_hook = x_defined_color;
 30933   terminal->query_frame_background_color = x_query_frame_background_color;
 30934   terminal->query_colors = x_query_colors;
 30935   terminal->mouse_position_hook = XTmouse_position;
 30936   terminal->get_focus_frame = x_get_focus_frame;
 30937   terminal->focus_frame_hook = x_focus_frame;
 30938   terminal->frame_rehighlight_hook = XTframe_rehighlight;
 30939   terminal->frame_raise_lower_hook = XTframe_raise_lower;
 30940   terminal->frame_visible_invisible_hook = x_make_frame_visible_invisible;
 30941   terminal->fullscreen_hook = XTfullscreen_hook;
 30942   terminal->iconify_frame_hook = x_iconify_frame;
 30943   terminal->set_window_size_hook = x_set_window_size;
 30944   terminal->set_frame_offset_hook = x_set_offset;
 30945   terminal->set_frame_alpha_hook = x_set_frame_alpha;
 30946   terminal->set_new_font_hook = x_new_font;
 30947   terminal->set_bitmap_icon_hook = x_bitmap_icon;
 30948   terminal->implicit_set_name_hook = x_implicitly_set_name;
 30949   terminal->menu_show_hook = x_menu_show;
 30950 #ifdef HAVE_EXT_MENU_BAR
 30951   terminal->activate_menubar_hook = x_activate_menubar;
 30952 #endif
 30953 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
 30954   terminal->popup_dialog_hook = xw_popup_dialog;
 30955 #endif
 30956   terminal->change_tab_bar_height_hook = x_change_tab_bar_height;
 30957 #ifndef HAVE_EXT_TOOL_BAR
 30958   terminal->change_tool_bar_height_hook = x_change_tool_bar_height;
 30959 #endif
 30960   terminal->set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
 30961   terminal->set_horizontal_scroll_bar_hook = XTset_horizontal_scroll_bar;
 30962   terminal->set_scroll_bar_default_width_hook = x_set_scroll_bar_default_width;
 30963   terminal->set_scroll_bar_default_height_hook = x_set_scroll_bar_default_height;
 30964   terminal->condemn_scroll_bars_hook = XTcondemn_scroll_bars;
 30965   terminal->redeem_scroll_bar_hook = XTredeem_scroll_bar;
 30966   terminal->judge_scroll_bars_hook = XTjudge_scroll_bars;
 30967   terminal->get_string_resource_hook = x_get_string_resource;
 30968   terminal->free_pixmap = x_free_pixmap;
 30969   terminal->delete_frame_hook = x_destroy_window;
 30970   terminal->delete_terminal_hook = x_delete_terminal;
 30971   terminal->toolkit_position_hook = x_toolkit_position;
 30972 #ifdef HAVE_XINPUT2
 30973   terminal->any_grab_hook = x_have_any_grab;
 30974 #endif
 30975   /* Other hooks are NULL by default.  */
 30976 
 30977   return terminal;
 30978 }
 30979 
 30980 static void
 30981 x_initialize (void)
 30982 {
 30983   baud_rate = 19200;
 30984 
 30985   x_noop_count = 0;
 30986   any_help_event_p = false;
 30987   ignore_next_mouse_click_timeout = 0;
 30988   mouse_click_timeout_display = NULL;
 30989 
 30990 #ifdef USE_GTK
 30991   current_count = -1;
 30992 #endif
 30993 
 30994   /* Try to use interrupt input; if we can't, then start polling.  */
 30995   Fset_input_interrupt_mode (Qt);
 30996 
 30997 #if THREADS_ENABLED
 30998   /* This must be called before any other Xlib routines.  */
 30999   if (XInitThreads () == 0)
 31000     fputs ("Warning: An error occurred initializing X11 thread support!\n",
 31001            stderr);
 31002 #endif
 31003 
 31004 #ifdef USE_X_TOOLKIT
 31005   XtToolkitInitialize ();
 31006 
 31007   Xt_app_con = XtCreateApplicationContext ();
 31008 
 31009   /* Register a converter from strings to pixels, which uses
 31010      Emacs' color allocation infrastructure.  */
 31011   XtAppSetTypeConverter (Xt_app_con,
 31012                          XtRString, XtRPixel, cvt_string_to_pixel,
 31013                          cvt_string_to_pixel_args,
 31014                          XtNumber (cvt_string_to_pixel_args),
 31015                          XtCacheByDisplay, cvt_pixel_dtor);
 31016 
 31017   XtAppSetFallbackResources (Xt_app_con, Xt_default_resources);
 31018 #endif
 31019 
 31020 #ifdef USE_TOOLKIT_SCROLL_BARS
 31021 #ifndef USE_GTK
 31022   xaw3d_arrow_scroll = False;
 31023   xaw3d_pick_top = True;
 31024 #endif
 31025 #endif
 31026 
 31027 #ifdef USE_CAIRO
 31028   gui_init_fringe (&x_redisplay_interface);
 31029 #endif
 31030 
 31031   /* Note that there is no real way portable across R3/R4 to get the
 31032      original error handler.  */
 31033   XSetErrorHandler (x_error_handler);
 31034   XSetIOErrorHandler (x_io_error_quitter);
 31035 }
 31036 
 31037 #ifdef USE_GTK
 31038 void
 31039 init_xterm (void)
 31040 {
 31041 #ifndef HAVE_XINPUT2
 31042   /* Emacs can handle only core input events when built without XI2
 31043      support, so make sure Gtk doesn't use Xinput or Xinput2
 31044      extensions.  */
 31045 #ifndef HAVE_GTK3
 31046   xputenv ("GDK_CORE_DEVICE_EVENTS=1");
 31047 #else
 31048   gdk_disable_multidevice ();
 31049 #endif
 31050 #endif
 31051 }
 31052 #endif
 31053 
 31054 void
 31055 mark_xterm (void)
 31056 {
 31057   Lisp_Object val;
 31058 #if defined HAVE_XINPUT2 || defined USE_TOOLKIT_SCROLL_BARS \
 31059   || defined HAVE_XRANDR || defined USE_GTK || defined HAVE_X_I18N
 31060   struct x_display_info *dpyinfo;
 31061 #if defined HAVE_XINPUT2 || defined USE_TOOLKIT_SCROLL_BARS
 31062   int i;
 31063 #endif
 31064 #endif
 31065 
 31066   if (x_dnd_return_frame_object)
 31067     {
 31068       XSETFRAME (val, x_dnd_return_frame_object);
 31069       mark_object (val);
 31070     }
 31071 
 31072   if (x_dnd_movement_frame)
 31073     {
 31074       XSETFRAME (val, x_dnd_movement_frame);
 31075       mark_object (val);
 31076     }
 31077 
 31078   if (x_dnd_wheel_frame)
 31079     {
 31080       XSETFRAME (val, x_dnd_wheel_frame);
 31081       mark_object (val);
 31082     }
 31083 
 31084 #if defined HAVE_XINPUT2 || defined USE_TOOLKIT_SCROLL_BARS \
 31085   || defined HAVE_XRANDR || defined USE_GTK || defined HAVE_X_I18N
 31086   for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
 31087     {
 31088 #ifdef HAVE_XINPUT2
 31089       for (i = 0; i < dpyinfo->num_devices; ++i)
 31090         mark_object (dpyinfo->devices[i].name);
 31091 #endif
 31092 #ifdef USE_TOOLKIT_SCROLL_BARS
 31093       for (i = 0; i < dpyinfo->n_protected_windows; ++i)
 31094         mark_object (dpyinfo->protected_windows[i]);
 31095 #endif
 31096 #if defined HAVE_XRANDR || defined USE_GTK
 31097       mark_object (dpyinfo->last_monitor_attributes_list);
 31098 #endif
 31099 #if defined HAVE_X_I18N
 31100       mark_object (dpyinfo->xim_coding);
 31101 #endif
 31102     }
 31103 #endif
 31104 }
 31105 
 31106 /* Error handling functions for Lisp functions that expose X protocol
 31107    requests.  They are mostly like `x_catch_errors' and friends, but
 31108    respect `x-fast-protocol-requests'.  */
 31109 
 31110 void
 31111 x_catch_errors_for_lisp (struct x_display_info *dpyinfo)
 31112 {
 31113   if (!x_fast_protocol_requests)
 31114     x_catch_errors (dpyinfo->display);
 31115   else
 31116     x_ignore_errors_for_next_request (dpyinfo);
 31117 }
 31118 
 31119 void
 31120 x_check_errors_for_lisp (struct x_display_info *dpyinfo,
 31121                          const char *format)
 31122 {
 31123   if (!x_fast_protocol_requests)
 31124     x_check_errors (dpyinfo->display, format);
 31125 }
 31126 
 31127 void
 31128 x_uncatch_errors_for_lisp (struct x_display_info *dpyinfo)
 31129 {
 31130   if (!x_fast_protocol_requests)
 31131     x_uncatch_errors ();
 31132   else
 31133     x_stop_ignoring_errors (dpyinfo);
 31134 }
 31135 
 31136 /* Preserve the selections in LOST in another frame on DPYINFO.  LOST
 31137    is a list of local selections that were lost, due to their frame
 31138    being deleted.  */
 31139 
 31140 void
 31141 x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost,
 31142                        Lisp_Object current_owner)
 31143 {
 31144   Lisp_Object tail, frame, new_owner;
 31145   Time timestamp;
 31146   Window *owners;
 31147   Atom *names;
 31148   ptrdiff_t nowners, counter;
 31149   struct selection_input_event clear;
 31150 #ifdef USE_XCB
 31151   xcb_get_selection_owner_cookie_t *cookies;
 31152   xcb_generic_error_t *error;
 31153   xcb_get_selection_owner_reply_t *reply;
 31154 #endif
 31155 
 31156   new_owner = Qnil;
 31157 
 31158   FOR_EACH_FRAME (tail, frame)
 31159     {
 31160       if (FRAME_X_P (XFRAME (frame))
 31161           && !EQ (frame, current_owner)
 31162           && FRAME_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
 31163         {
 31164           new_owner = frame;
 31165           break;
 31166         }
 31167     }
 31168 
 31169   tail = lost;
 31170   nowners = 0;
 31171 
 31172   FOR_EACH_TAIL_SAFE (tail)
 31173     {
 31174       Lisp_Object tem = XCAR (tail);
 31175       ++nowners;
 31176 
 31177       /* The selection is really lost (since we cannot find a new
 31178          owner), so run the appropriate hooks.  */
 31179       if (NILP (new_owner))
 31180         CALLN (Frun_hook_with_args, Qx_lost_selection_functions,
 31181                XCAR (tem));
 31182       else
 31183         {
 31184           CONS_TO_INTEGER (XCAR (XCDR (XCDR (tem))), Time, timestamp);
 31185 
 31186           /* This shouldn't be able to signal any errors, despite the
 31187              call to `x_check_errors' inside.  */
 31188           x_own_selection (XCAR (tem), XCAR (XCDR (tem)),
 31189                            new_owner, XCAR (XCDR (XCDR (XCDR (XCDR (tem))))),
 31190                            timestamp);
 31191         }
 31192     }
 31193 
 31194   if (!NILP (new_owner))
 31195     {
 31196       owners = alloca (sizeof *owners * nowners);
 31197       names = alloca (sizeof *names * nowners);
 31198 #ifdef USE_XCB
 31199       cookies = alloca (sizeof *cookies * nowners);
 31200 #endif
 31201 
 31202       tail = lost;
 31203       nowners = 0;
 31204       counter = 0;
 31205 
 31206       FOR_EACH_TAIL_SAFE (tail)
 31207         {
 31208           Lisp_Object tem = XCAR (tail);
 31209 
 31210           /* Now check if we still don't own that selection, which can
 31211              happen if another program set itself as the owner.  */
 31212           names[counter++] = symbol_to_x_atom (dpyinfo, XCAR (tem));
 31213 
 31214 #ifndef USE_XCB
 31215           owners[nowners++] = XGetSelectionOwner (dpyinfo->display,
 31216                                                   names[counter - 1]);
 31217 #else
 31218           cookies[nowners++]
 31219             = xcb_get_selection_owner (dpyinfo->xcb_connection,
 31220                                        names[counter - 1]);
 31221         }
 31222 
 31223       nowners = 0;
 31224       tail = lost;
 31225 
 31226       FOR_EACH_TAIL_SAFE (tail)
 31227         {
 31228           Lisp_Object tem = XCAR (tail);
 31229 
 31230           reply = xcb_get_selection_owner_reply (dpyinfo->xcb_connection,
 31231                                                  cookies[nowners++], &error);
 31232           if (reply)
 31233             owners[nowners - 1] = reply->owner;
 31234           else
 31235             owners[nowners - 1] = None;
 31236 
 31237           free (reply ? (void *) reply : (void *) error);
 31238 #endif
 31239 
 31240           if (owners[nowners - 1] != FRAME_X_WINDOW (XFRAME (new_owner)))
 31241             {
 31242               /* Clear the local selection, since we know we don't own
 31243                  it any longer.  */
 31244               CONS_TO_INTEGER (XCAR (XCDR (XCDR (tem))), Time, timestamp);
 31245 
 31246               clear.kind = SELECTION_CLEAR_EVENT;
 31247 
 31248               SELECTION_EVENT_DPYINFO (&clear) = dpyinfo;
 31249               SELECTION_EVENT_SELECTION (&clear) = names[nowners - 1];
 31250               SELECTION_EVENT_TIME (&clear) = timestamp;
 31251 
 31252               x_handle_selection_event (&clear);
 31253             }
 31254         }
 31255 
 31256       tail = lost;
 31257       nowners = 0;
 31258 
 31259       FOR_EACH_TAIL_SAFE (tail)
 31260         {
 31261           Lisp_Object tem = XCAR (tail);
 31262 
 31263           /* If the selection isn't owned by us anymore, note that the
 31264              selection was lost.  */
 31265           if (owners[nowners++] != FRAME_X_WINDOW (XFRAME (new_owner)))
 31266             CALLN (Frun_hook_with_args, Qx_lost_selection_functions,
 31267                    XCAR (tem));
 31268         }
 31269     }
 31270 }
 31271 
 31272 /* Return a list of the keyboard modifier masks in DPYINFO.
 31273 
 31274    Value is a list of (HYPER SUPER ALT SHIFT-LOCK META), each element
 31275    being the appropriate modifier mask.  */
 31276 
 31277 Lisp_Object
 31278 x_get_keyboard_modifiers (struct x_display_info *dpyinfo)
 31279 {
 31280   /* This sometimes happens when the function is called during display
 31281      initialization, which can happen while obtaining vendor specific
 31282      keysyms.  */
 31283 
 31284 #ifdef HAVE_XKB
 31285   if (!dpyinfo->xkb_desc && !dpyinfo->modmap)
 31286     x_find_modifier_meanings (dpyinfo);
 31287 #else
 31288   if (!dpyinfo->modmap)
 31289     x_find_modifier_meanings (dpyinfo);
 31290 #endif
 31291 
 31292   return list5 (make_uint (dpyinfo->hyper_mod_mask),
 31293                 make_uint (dpyinfo->super_mod_mask),
 31294                 make_uint (dpyinfo->alt_mod_mask),
 31295                 make_uint (dpyinfo->shift_lock_mask),
 31296                 make_uint (dpyinfo->meta_mod_mask));
 31297 }
 31298 
 31299 void
 31300 syms_of_xterm (void)
 31301 {
 31302   x_error_message = NULL;
 31303   PDUMPER_IGNORE (x_error_message);
 31304 
 31305   x_dnd_monitors = Qnil;
 31306   staticpro (&x_dnd_monitors);
 31307 
 31308   x_dnd_action_symbol = Qnil;
 31309   staticpro (&x_dnd_action_symbol);
 31310 
 31311   x_dnd_selection_alias_cell = Fcons (Qnil, Qnil);
 31312   staticpro (&x_dnd_selection_alias_cell);
 31313 
 31314   x_dnd_unsupported_drop_data = Qnil;
 31315   staticpro (&x_dnd_unsupported_drop_data);
 31316 
 31317   /* Used by x_cr_export_frames.  */
 31318   DEFSYM (Qconcat, "concat");
 31319 
 31320   DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms");
 31321   DEFSYM (Qlatin_1, "latin-1");
 31322   DEFSYM (Qnow, "now");
 31323   DEFSYM (Qx_dnd_targets_list, "x-dnd-targets-list");
 31324   DEFSYM (Qx_auto_preserve_selections, "x-auto-preserve-selections");
 31325 
 31326 #ifdef USE_GTK
 31327   xg_default_icon_file = build_pure_c_string ("icons/hicolor/scalable/apps/emacs.svg");
 31328   staticpro (&xg_default_icon_file);
 31329 
 31330   DEFSYM (Qx_gtk_map_stock, "x-gtk-map-stock");
 31331 #endif
 31332 
 31333   DEFVAR_BOOL ("x-use-underline-position-properties",
 31334                x_use_underline_position_properties,
 31335      doc: /* Non-nil means make use of UNDERLINE_POSITION font properties.
 31336 A value of nil means ignore them.  If you encounter fonts with bogus
 31337 UNDERLINE_POSITION font properties, set this to nil.  You can also use
 31338 `underline-minimum-offset' to override the font's UNDERLINE_POSITION for
 31339 small font display sizes.  */);
 31340   x_use_underline_position_properties = true;
 31341   DEFSYM (Qx_use_underline_position_properties,
 31342           "x-use-underline-position-properties");
 31343 
 31344   DEFVAR_BOOL ("x-underline-at-descent-line",
 31345                x_underline_at_descent_line,
 31346      doc: /* Non-nil means to draw the underline at the same place as the descent line.
 31347 (If `line-spacing' is in effect, that moves the underline lower by
 31348 that many pixels.)
 31349 A value of nil means to draw the underline according to the value of the
 31350 variable `x-use-underline-position-properties', which is usually at the
 31351 baseline level.  The default value is nil.  */);
 31352   x_underline_at_descent_line = false;
 31353   DEFSYM (Qx_underline_at_descent_line, "x-underline-at-descent-line");
 31354 
 31355   DEFVAR_BOOL ("x-mouse-click-focus-ignore-position",
 31356                x_mouse_click_focus_ignore_position,
 31357     doc: /* Non-nil means that a mouse click to focus a frame does not move point.
 31358 This variable is used only when the window manager requires that you
 31359 click on a frame to select it (give it focus).  In that case, a value
 31360 of nil, means that the selected window and cursor position changes to
 31361 reflect the mouse click position, while a non-nil value means that the
 31362 selected window or cursor position is preserved.
 31363 
 31364 This option works by ignoring button press events for a given amount
 31365 of time after a frame might've been focused.  If it does not work for
 31366 you, try increasing the value of
 31367 `x-mouse-click-focus-ignore-time'.  */);
 31368   x_mouse_click_focus_ignore_position = false;
 31369 
 31370   DEFVAR_INT ("x-mouse-click-focus-ignore-time", x_mouse_click_focus_ignore_time,
 31371     doc: /* Number of milliseconds for which to ignore buttons after focus change.
 31372 This variable only takes effect if
 31373 `x-mouse-click-focus-ignore-position' is non-nil, and should be
 31374 adjusted if the default value does not work for whatever reason.  */);
 31375   x_mouse_click_focus_ignore_time = 200;
 31376 
 31377   DEFVAR_LISP ("x-toolkit-scroll-bars", Vx_toolkit_scroll_bars,
 31378     doc: /* Which toolkit scroll bars Emacs uses, if any.
 31379 A value of nil means Emacs doesn't use toolkit scroll bars.
 31380 With the X Window system, the value is a symbol describing the
 31381 X toolkit.  Possible values are: gtk, motif, xaw, or xaw3d.
 31382 With MS Windows, Haiku windowing or Nextstep, the value is t.  */);
 31383 #ifdef USE_TOOLKIT_SCROLL_BARS
 31384 #ifdef USE_MOTIF
 31385   Vx_toolkit_scroll_bars = intern_c_string ("motif");
 31386 #elif defined HAVE_XAW3D
 31387   Vx_toolkit_scroll_bars = intern_c_string ("xaw3d");
 31388 #elif USE_GTK
 31389   Vx_toolkit_scroll_bars = intern_c_string ("gtk");
 31390 #else
 31391   Vx_toolkit_scroll_bars = intern_c_string ("xaw");
 31392 #endif
 31393 #else
 31394   Vx_toolkit_scroll_bars = Qnil;
 31395 #endif
 31396 
 31397   DEFSYM (Qmodifier_value, "modifier-value");
 31398   DEFSYM (Qctrl, "ctrl");
 31399   Fput (Qctrl, Qmodifier_value, make_fixnum (ctrl_modifier));
 31400   DEFSYM (Qalt, "alt");
 31401   Fput (Qalt, Qmodifier_value, make_fixnum (alt_modifier));
 31402   DEFSYM (Qhyper, "hyper");
 31403   Fput (Qhyper, Qmodifier_value, make_fixnum (hyper_modifier));
 31404   DEFSYM (Qmeta, "meta");
 31405   Fput (Qmeta, Qmodifier_value, make_fixnum (meta_modifier));
 31406   DEFSYM (Qsuper, "super");
 31407   Fput (Qsuper, Qmodifier_value, make_fixnum (super_modifier));
 31408   DEFSYM (QXdndSelection, "XdndSelection");
 31409   DEFSYM (Qx_selection_alias_alist, "x-selection-alias-alist");
 31410   DEFSYM (Qimitate_pager, "imitate-pager");
 31411   DEFSYM (Qnewer_time, "newer-time");
 31412   DEFSYM (Qraise_and_focus, "raise-and-focus");
 31413   DEFSYM (Qreally_fast, "really-fast");
 31414 
 31415   DEFVAR_LISP ("x-ctrl-keysym", Vx_ctrl_keysym,
 31416     doc: /* Which keys Emacs uses for the ctrl modifier.
 31417 This should be one of the symbols `ctrl', `alt', `hyper', `meta',
 31418 `super'.  For example, `ctrl' means use the Ctrl_L and Ctrl_R keysyms.
 31419 The default is nil, which is the same as `ctrl'.  */);
 31420   Vx_ctrl_keysym = Qnil;
 31421 
 31422   DEFVAR_LISP ("x-alt-keysym", Vx_alt_keysym,
 31423     doc: /* Which keys Emacs uses for the alt modifier.
 31424 This should be one of the symbols `ctrl', `alt', `hyper', `meta',
 31425 `super'.  For example, `alt' means use the Alt_L and Alt_R keysyms.
 31426 The default is nil, which is the same as `alt'.  */);
 31427   Vx_alt_keysym = Qnil;
 31428 
 31429   DEFVAR_LISP ("x-hyper-keysym", Vx_hyper_keysym,
 31430     doc: /* Which keys Emacs uses for the hyper modifier.
 31431 This should be one of the symbols `ctrl', `alt', `hyper', `meta',
 31432 `super'.  For example, `hyper' means use the Hyper_L and Hyper_R
 31433 keysyms.  The default is nil, which is the same as `hyper'.  */);
 31434   Vx_hyper_keysym = Qnil;
 31435 
 31436   DEFVAR_LISP ("x-meta-keysym", Vx_meta_keysym,
 31437     doc: /* Which keys Emacs uses for the meta modifier.
 31438 This should be one of the symbols `ctrl', `alt', `hyper', `meta',
 31439 `super'.  For example, `meta' means use the Meta_L and Meta_R keysyms.
 31440 The default is nil, which is the same as `meta'.  */);
 31441   Vx_meta_keysym = Qnil;
 31442 
 31443   DEFVAR_LISP ("x-super-keysym", Vx_super_keysym,
 31444     doc: /* Which keys Emacs uses for the super modifier.
 31445 This should be one of the symbols `ctrl', `alt', `hyper', `meta',
 31446 `super'.  For example, `super' means use the Super_L and Super_R
 31447 keysyms.  The default is nil, which is the same as `super'.  */);
 31448   Vx_super_keysym = Qnil;
 31449 
 31450   DEFVAR_LISP ("x-wait-for-event-timeout", Vx_wait_for_event_timeout,
 31451     doc: /* How long to wait for X events.
 31452 
 31453 Emacs will wait up to this many seconds to receive X events after
 31454 making changes which affect the state of the graphical interface.
 31455 Under some window managers this can take an indefinite amount of time,
 31456 so it is important to limit the wait.
 31457 
 31458 If set to a non-float value, there will be no wait at all.  */);
 31459   Vx_wait_for_event_timeout = make_float (0.1);
 31460 
 31461   DEFVAR_LISP ("x-keysym-table", Vx_keysym_table,
 31462     doc: /* Hash table of character codes indexed by X keysym codes.  */);
 31463   Vx_keysym_table = make_hash_table (hashtest_eql, 900,
 31464                                      DEFAULT_REHASH_SIZE,
 31465                                      DEFAULT_REHASH_THRESHOLD,
 31466                                      Qnil, false);
 31467 
 31468   DEFVAR_BOOL ("x-frame-normalize-before-maximize",
 31469                x_frame_normalize_before_maximize,
 31470     doc: /* Non-nil means normalize frame before maximizing.
 31471 If this variable is t, Emacs first asks the window manager to give the
 31472 frame its normal size, and only then the final state, whenever changing
 31473 from a full-height, full-width or full-both state to the maximized one
 31474 or when changing from the maximized to the full-height or full-width
 31475 state.
 31476 
 31477 Set this variable only if your window manager cannot handle the
 31478 transition between the various maximization states.  */);
 31479   x_frame_normalize_before_maximize = false;
 31480 
 31481   DEFVAR_BOOL ("x-gtk-use-window-move", x_gtk_use_window_move,
 31482     doc: /* Non-nil means rely on gtk_window_move to set frame positions.
 31483 If this variable is t (the default), the GTK build uses the function
 31484 gtk_window_move to set or store frame positions and disables some time
 31485 consuming frame position adjustments.  In newer versions of GTK, Emacs
 31486 always uses gtk_window_move and ignores the value of this variable.  */);
 31487   x_gtk_use_window_move = true;
 31488 
 31489   DEFVAR_LISP ("x-scroll-event-delta-factor", Vx_scroll_event_delta_factor,
 31490                doc: /* A scale to apply to pixel deltas reported in scroll events.
 31491 This option is only effective when Emacs is built with XInput 2
 31492 support. */);
 31493   Vx_scroll_event_delta_factor = make_float (1.0);
 31494   DEFSYM (Qexpose, "expose");
 31495 
 31496   DEFVAR_BOOL ("x-gtk-use-native-input", x_gtk_use_native_input,
 31497                doc: /* Non-nil means to use GTK for input method support.
 31498 This provides better support for some modern input methods, and is
 31499 only effective when Emacs is built with GTK.  */);
 31500   x_gtk_use_native_input = false;
 31501 
 31502   DEFVAR_LISP ("x-set-frame-visibility-more-laxly",
 31503                x_set_frame_visibility_more_laxly,
 31504     doc: /* Non-nil means set frame visibility more laxly.
 31505 If this is nil, Emacs is more strict when marking a frame as visible.
 31506 Since this may cause problems on some window managers, this variable can
 31507 be also set as follows: The value `focus-in' means to mark a frame as
 31508 visible also when a FocusIn event is received for it on GTK builds.  The
 31509 value `expose' means to mark a frame as visible also when an Expose
 31510 event is received for it on any X build.  The value `t' means to mark a
 31511 frame as visible in either of these two cases.
 31512 
 31513 Note that any non-nil setting may cause invisible frames get erroneously
 31514 reported as iconified.  */);
 31515   x_set_frame_visibility_more_laxly = Qnil;
 31516 
 31517   DEFVAR_BOOL ("x-input-grab-touch-events", x_input_grab_touch_events,
 31518                doc: /* Non-nil means to actively grab touch events.
 31519 This means touch sequences that started on an Emacs frame will
 31520 reliably continue to receive updates even if the finger moves off the
 31521 frame, but may cause crashes with some window managers and/or external
 31522 programs.  */);
 31523   x_input_grab_touch_events = true;
 31524 
 31525   DEFVAR_BOOL ("x-dnd-fix-motif-leave", x_dnd_fix_motif_leave,
 31526                doc: /* Work around Motif bug during drag-and-drop.
 31527 When non-nil, Emacs will send a motion event containing impossible
 31528 coordinates to a Motif drop receiver when the mouse moves outside it
 31529 during a drag-and-drop session, to work around broken implementations
 31530 of Motif.  */);
 31531   x_dnd_fix_motif_leave = true;
 31532 
 31533   DEFVAR_BOOL ("x-dnd-disable-motif-drag", x_dnd_disable_motif_drag,
 31534                doc: /* Disable the Motif drag protocol during DND.
 31535 This reduces network usage, but also means you can no longer scroll
 31536 around inside the Motif window underneath the cursor during
 31537 drag-and-drop.  */);
 31538   x_dnd_disable_motif_drag = false;
 31539 
 31540   DEFVAR_LISP ("x-dnd-movement-function", Vx_dnd_movement_function,
 31541     doc: /* Function called upon mouse movement on a frame during drag-and-drop.
 31542 It should either be nil, or accept two arguments FRAME and POSITION,
 31543 where FRAME is the frame the mouse is on top of, and POSITION is a
 31544 mouse position list.  */);
 31545   Vx_dnd_movement_function = Qnil;
 31546 
 31547   DEFVAR_LISP ("x-dnd-wheel-function", Vx_dnd_wheel_function,
 31548     doc: /* Function called upon wheel movement on a frame during drag-and-drop.
 31549 It should either be nil, or accept four arguments POSITION, BUTTON,
 31550 STATE and TIME, where POSITION is a mouse position list describing
 31551 where the wheel moved, BUTTON is the wheel button that was pressed,
 31552 STATE is the X modifier state at the time of the wheel movement, and
 31553 TIME is the X server time at which the wheel moved.  */);
 31554   Vx_dnd_wheel_function = Qnil;
 31555 
 31556   DEFVAR_LISP ("x-dnd-unsupported-drop-function", Vx_dnd_unsupported_drop_function,
 31557     doc: /* Function called when trying to drop on an unsupported window.
 31558 This function is called whenever the user tries to drop something on a
 31559 window that does not support either the XDND or Motif protocols for
 31560 drag-and-drop.  It should return a non-nil value if the drop was
 31561 handled by the function, and nil if it was not.  It should accept
 31562 several arguments TARGETS, X, Y, ACTION, WINDOW-ID, FRAME, TIME and
 31563 LOCAL-SELECTION, where TARGETS is the list of targets that was passed
 31564 to `x-begin-drag', WINDOW-ID is the numeric XID of the window that is
 31565 being dropped on, X and Y are the root window-relative coordinates
 31566 where the drop happened, ACTION is the action that was passed to
 31567 `x-begin-drag', FRAME is the frame which initiated the drag-and-drop
 31568 operation, TIME is the X server time when the drop happened, and
 31569 LOCAL-SELECTION is the contents of the `XdndSelection' when
 31570 `x-begin-drag' was run; its contents can be retrieved by calling the
 31571 function `x-get-local-selection'.
 31572 
 31573 If a symbol is returned, then it will be used as the return value of
 31574 `x-begin-drag'.  */);
 31575   Vx_dnd_unsupported_drop_function = Qnil;
 31576 
 31577   DEFVAR_INT ("x-color-cache-bucket-size", x_color_cache_bucket_size,
 31578     doc: /* Max number of buckets allowed per display in the internal color cache.
 31579 Values less than 1 mean 128.  This option is for debugging only.  */);
 31580   x_color_cache_bucket_size = 128;
 31581 
 31582   DEFVAR_LISP ("x-dnd-targets-list", Vx_dnd_targets_list,
 31583     doc: /* List of drag-and-drop targets.
 31584 This variable contains the list of drag-and-drop selection targets
 31585 during a drag-and-drop operation, in the same format as the TARGET
 31586 argument to `x-begin-drag'.  */);
 31587   Vx_dnd_targets_list = Qnil;
 31588 
 31589   DEFVAR_LISP ("x-dnd-native-test-function", Vx_dnd_native_test_function,
 31590     doc: /* Function that determines return value of drag-and-drop on Emacs frames.
 31591 If the value is a function, `x-begin-drag' will call it with two
 31592 arguments, POS and ACTION, where POS is a mouse position list
 31593 that specifies the location of the drop, and ACTION is the
 31594 action specified by the caller of `x-begin-drag'.  The function
 31595 should return a symbol describing what to return from
 31596 `x-begin-drag' if the drop happens on an Emacs frame.
 31597 
 31598 If the value is nil, or the function returns a value that is not
 31599 a symbol, a drop on an Emacs frame will be canceled.  */);
 31600   Vx_dnd_native_test_function = Qnil;
 31601 
 31602   DEFVAR_BOOL ("x-dnd-preserve-selection-data", x_dnd_preserve_selection_data,
 31603     doc: /* Preserve selection data after `x-begin-drag' returns.
 31604 This lets you inspect the contents of `XdndSelection' after a
 31605 drag-and-drop operation, which is useful when writing tests for
 31606 drag-and-drop code.  */);
 31607   x_dnd_preserve_selection_data = false;
 31608 
 31609   DEFVAR_BOOL ("x-dnd-disable-motif-protocol", x_dnd_disable_motif_protocol,
 31610     doc: /* Disable the Motif drag-and-drop protocols.
 31611 When non-nil, `x-begin-drag' will not drop onto any window that only
 31612 supports the Motif drag-and-drop protocols.  */);
 31613   x_dnd_disable_motif_protocol = false;
 31614 
 31615   DEFVAR_BOOL ("x-dnd-use-unsupported-drop", x_dnd_use_unsupported_drop,
 31616     doc: /* Enable the emulation of drag-and-drop based on the primary selection.
 31617 When nil, do not use the primary selection and synthetic mouse clicks
 31618 to emulate the drag-and-drop of `STRING', `UTF8_STRING',
 31619 `COMPOUND_TEXT' or `TEXT'.  */);
 31620   x_dnd_use_unsupported_drop = true;
 31621 
 31622   DEFVAR_BOOL ("x-fast-protocol-requests", x_fast_protocol_requests,
 31623     doc: /* Whether or not X protocol-related functions should wait for errors.
 31624 When this is nil, functions such as `x-delete-window-property',
 31625 `x-change-window-property' and `x-send-client-message' will wait for a
 31626 reply from the X server, and signal any errors that occurred while
 31627 executing the protocol request.  Otherwise, errors will be silently
 31628 ignored without waiting, which is generally faster.  */);
 31629   x_fast_protocol_requests = false;
 31630 
 31631   DEFVAR_LISP ("x-auto-preserve-selections", Vx_auto_preserve_selections,
 31632     doc: /* Whether or not to transfer selection ownership when deleting a frame.
 31633 When non-nil, deleting a frame that is currently the owner of a
 31634 selection will cause its ownership to be transferred to another frame
 31635 on the same display.
 31636 
 31637 In addition, when this variable is a list, only preserve the
 31638 selections whose names are contained within.  */);
 31639   Vx_auto_preserve_selections = list2 (QCLIPBOARD, QPRIMARY);
 31640 
 31641   DEFVAR_LISP ("x-input-coding-system", Vx_input_coding_system,
 31642     doc: /* Coding system used for input from X input methods.
 31643 If a symbol and non-nil, this is the coding system that will be used
 31644 to decode input from X input methods.  It does not affect input from
 31645 GTK native input methods enabled through `x-gtk-use-native-input'.  */);
 31646   Vx_input_coding_system = Qnil;
 31647 
 31648   DEFVAR_LISP ("x-input-coding-function", Vx_input_coding_function,
 31649     doc: /* Function used to determine the coding system used by input methods.
 31650 It should accept a single argument, a string describing the locale of
 31651 the input method, and return a coding system that can decode keyboard
 31652 input generated by said input method.  */);
 31653   Vx_input_coding_function = Qnil;
 31654 
 31655   DEFVAR_LISP ("x-fast-selection-list", Vx_fast_selection_list,
 31656     doc: /* List of selections for which `x-selection-exists-p' should be fast.
 31657 
 31658 List of selection names as atoms that will be monitored by Emacs for
 31659 ownership changes when the X server supports the XFIXES extension.
 31660 The result of the monitoring is then used by `x-selection-exists-p' to
 31661 avoid a server round trip, which is important as it is called while
 31662 updating the tool bar.  The value of this variable is only read upon
 31663 connection setup.  */);
 31664   /* The default value of this variable is chosen so that updating the
 31665      tool bar does not require a call to _XReply.  */
 31666   Vx_fast_selection_list = list1 (QCLIPBOARD);
 31667 
 31668   DEFVAR_LISP ("x-allow-focus-stealing", Vx_allow_focus_stealing,
 31669     doc: /* How to bypass window manager focus stealing prevention.
 31670 
 31671 Some window managers prevent `x-focus-frame' from activating the given
 31672 frame when Emacs is in the background, which is especially prone to
 31673 cause problems when the Emacs server wants to activate itself.
 31674 
 31675 In addition, when an old-fashioned (pre-EWMH) window manager is being
 31676 run and `x-no-window-manager' is nil, the X server will not let Emacs
 31677 focus itself if another program was focused after the last time Emacs
 31678 obtained the input focus.
 31679 
 31680 This variable specifies the strategy used to activate frames when that
 31681 is the case, and has several valid values (any other value means to
 31682 not bypass window manager focus stealing prevention):
 31683 
 31684   - The symbol `imitate-pager', which means to pretend that Emacs is a
 31685     pager.
 31686 
 31687   - The symbol `newer-time', which means to fetch the current time
 31688     from the X server and use it to activate the frame.
 31689 
 31690   - The symbol `raise-and-focus', which means to raise the window and
 31691     focus it manually.  */);
 31692   Vx_allow_focus_stealing = Qnewer_time;
 31693 
 31694   DEFVAR_LISP ("x-use-fast-mouse-position", Vx_use_fast_mouse_position,
 31695     doc: /* How to make `mouse-position' faster.
 31696 
 31697 `mouse-position' and `mouse-pixel-position' default to querying the X
 31698 server for the window under the mouse pointer.  This results in
 31699 accurate results, but is also very slow when the X connection has
 31700 moderate to high latency.  Setting this variable to a non-nil value
 31701 makes Emacs query only for the position of the pointer, which is
 31702 usually faster.  Doing so improves the performance of dragging to
 31703 select text over slow X connections.
 31704 
 31705 If that is still too slow, setting this variable to the symbol
 31706 `really-fast' will make Emacs return only cached values.  */);
 31707   Vx_use_fast_mouse_position = Qnil;
 31708 }

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