root/src/pgtkterm.c

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

DEFINITIONS

This source file includes following definitions.
  1. pgtk_device_added_or_removal_cb
  2. pgtk_seat_added_cb
  3. pgtk_seat_removed_cb
  4. pgtk_enumerate_devices
  5. pgtk_free_devices
  6. pgtk_regenerate_devices
  7. pgtk_toolkit_position
  8. pgtk_get_device_for_event
  9. flip_cr_context
  10. evq_enqueue
  11. evq_flush
  12. mark_pgtkterm
  13. get_keysym_name
  14. frame_set_mouse_pixel_position
  15. pgtk_raise_frame
  16. pgtk_lower_frame
  17. pgtk_frame_raise_lower
  18. pgtk_free_frame_resources
  19. pgtk_destroy_window
  20. pgtk_calc_absolute_position
  21. pgtk_set_offset
  22. pgtk_set_window_size
  23. pgtk_iconify_frame
  24. pgtk_make_frame_visible_wait_for_map_event_cb
  25. pgtk_make_frame_visible_wait_for_map_event_timeout
  26. pgtk_wait_for_map_event
  27. pgtk_make_frame_visible
  28. pgtk_make_frame_invisible
  29. pgtk_make_frame_visible_invisible
  30. pgtk_new_font
  31. pgtk_display_pixel_height
  32. pgtk_display_pixel_width
  33. pgtk_set_parent_frame
  34. pgtk_set_no_focus_on_map
  35. pgtk_set_no_accept_focus
  36. pgtk_set_z_group
  37. pgtk_initialize_display_info
  38. pgtk_set_cursor_gc
  39. pgtk_set_mouse_face_gc
  40. pgtk_set_mode_line_face_gc
  41. pgtk_set_glyph_string_gc
  42. pgtk_set_glyph_string_clipping
  43. pgtk_set_glyph_string_clipping_exactly
  44. pgtk_compute_glyph_string_overhangs
  45. pgtk_clear_glyph_string_rect
  46. fill_background_by_face
  47. fill_background
  48. pgtk_draw_glyph_string_background
  49. pgtk_draw_rectangle
  50. pgtk_draw_glyph_string_foreground
  51. pgtk_draw_composite_glyph_string_foreground
  52. pgtk_draw_glyphless_glyph_string_foreground
  53. pgtk_compute_lighter_color
  54. pgtk_fill_trapezoid_for_relief
  55. pgtk_erase_corners_for_relief
  56. pgtk_setup_relief_color
  57. pgtk_setup_relief_colors
  58. pgtk_set_clip_rectangles
  59. pgtk_draw_relief_rect
  60. pgtk_draw_box_rect
  61. pgtk_draw_glyph_string_box
  62. pgtk_draw_horizontal_wave
  63. pgtk_draw_underwave
  64. pgtk_draw_image_relief
  65. pgtk_draw_glyph_string_bg_rect
  66. pgtk_cr_draw_image
  67. pgtk_draw_image_foreground
  68. pgtk_draw_image_glyph_string
  69. pgtk_draw_stretch_glyph_string
  70. pgtk_draw_glyph_string
  71. pgtk_define_frame_cursor
  72. pgtk_after_update_window_line
  73. pgtk_clear_frame_area
  74. pgtk_draw_hollow_cursor
  75. pgtk_draw_bar_cursor
  76. pgtk_draw_window_cursor
  77. pgtk_copy_bits
  78. pgtk_scroll_run
  79. pgtk_bitmap_icon
  80. pgtk_text_icon
  81. pgtk_update_begin
  82. pgtk_draw_vertical_window_border
  83. pgtk_draw_window_divider
  84. pgtk_update_end
  85. pgtk_frame_up_to_date
  86. pgtk_mouse_position
  87. pgtk_define_fringe_bitmap
  88. pgtk_destroy_fringe_bitmap
  89. pgtk_clip_to_row
  90. pgtk_draw_fringe_bitmap
  91. hourglass_cb
  92. pgtk_show_hourglass
  93. pgtk_hide_hourglass
  94. pgtk_flush_display
  95. pgtk_clear_frame
  96. recover_from_visible_bell
  97. pgtk_flash
  98. pgtk_ring_bell
  99. pgtk_read_socket
  100. pgtk_send_scroll_bar_event
  101. xg_scroll_callback
  102. xg_end_scroll_callback
  103. pgtk_create_toolkit_scroll_bar
  104. pgtk_create_horizontal_toolkit_scroll_bar
  105. pgtk_set_toolkit_scroll_bar_thumb
  106. pgtk_set_toolkit_horizontal_scroll_bar_thumb
  107. pgtk_scroll_bar_create
  108. pgtk_scroll_bar_remove
  109. pgtk_set_vertical_scroll_bar
  110. pgtk_set_horizontal_scroll_bar
  111. pgtk_condemn_scroll_bars
  112. pgtk_redeem_scroll_bar
  113. pgtk_judge_scroll_bars
  114. set_fullscreen_state
  115. pgtk_fullscreen_hook
  116. pgtk_delete_terminal
  117. pgtk_query_frame_background_color
  118. pgtk_free_pixmap
  119. pgtk_focus_frame
  120. set_opacity_recursively
  121. pgtk_set_frame_alpha
  122. frame_highlight
  123. frame_unhighlight
  124. pgtk_frame_rehighlight
  125. pgtk_frame_rehighlight_hook
  126. pgtk_toggle_invisible_pointer
  127. pgtk_new_focus_frame
  128. pgtk_buffer_flipping_unblocked_hook
  129. pgtk_create_terminal
  130. pgtk_window_is_of_frame_recursive
  131. pgtk_window_is_of_frame
  132. pgtk_any_window_to_frame
  133. pgtk_handle_event
  134. pgtk_fill_rectangle
  135. pgtk_clear_under_internal_border
  136. pgtk_handle_draw
  137. size_allocate
  138. get_modifier_values
  139. pgtk_gtk_to_emacs_modifiers
  140. pgtk_emacs_to_gtk_modifiers
  141. pgtk_enqueue_string
  142. pgtk_enqueue_preedit
  143. key_press_event
  144. pgtk_display_info_for_display
  145. key_release_event
  146. configure_event
  147. map_event
  148. window_state_event
  149. delete_event
  150. pgtk_focus_changed
  151. enter_notify_event
  152. leave_notify_event
  153. focus_in_event
  154. focus_out_event
  155. note_mouse_movement
  156. motion_notify_event
  157. construct_mouse_click
  158. button_event
  159. scroll_event
  160. symbol_to_drag_action
  161. drag_action_to_symbol
  162. pgtk_update_drop_status
  163. pgtk_finish_drop
  164. drag_leave
  165. drag_motion
  166. drag_drop
  167. pgtk_monitors_changed_cb
  168. pgtk_set_event_handler
  169. my_log_handler
  170. same_x_server
  171. pgtk_find_selection_owner
  172. pgtk_selection_event
  173. pgtk_display_x_warning
  174. pgtk_term_init
  175. pgtk_delete_display
  176. pgtk_xlfd_to_fontname
  177. pgtk_defined_color
  178. pgtk_parse_color
  179. pgtk_query_colors
  180. pgtk_query_color
  181. pgtk_clear_area
  182. syms_of_pgtkterm
  183. pgtk_cr_update_surface_desired_size
  184. pgtk_begin_cr_clip
  185. pgtk_end_cr_clip
  186. pgtk_set_cr_source_with_gc_foreground
  187. pgtk_set_cr_source_with_gc_background
  188. pgtk_set_cr_source_with_color
  189. pgtk_cr_draw_frame
  190. pgtk_cr_accumulate_data
  191. pgtk_cr_destroy_frame_context
  192. pgtk_cr_destroy
  193. pgtk_cr_export_frames

     1 /* Communication module for window systems using GTK.
     2 
     3 Copyright (C) 1989, 1993-1994, 2005-2006, 2008-2023 Free Software
     4 Foundation, Inc.
     5 
     6 This file is part of GNU Emacs.
     7 
     8 GNU Emacs is free software: you can redistribute it and/or modify
     9 it under the terms of the GNU General Public License as published by
    10 the Free Software Foundation, either version 3 of the License, or (at
    11 your option) any later version.
    12 
    13 GNU Emacs is distributed in the hope that it will be useful,
    14 but WITHOUT ANY WARRANTY; without even the implied warranty of
    15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16 GNU General Public License for more details.
    17 
    18 You should have received a copy of the GNU General Public License
    19 along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
    20 
    21 /* This should be the first include, as it may set up #defines affecting
    22    interpretation of even the system includes. */
    23 #include <config.h>
    24 
    25 #include <cairo.h>
    26 #include <fcntl.h>
    27 #include <math.h>
    28 #include <pthread.h>
    29 #include <sys/types.h>
    30 #include <time.h>
    31 #include <signal.h>
    32 #include <unistd.h>
    33 #include <errno.h>
    34 
    35 #include <c-ctype.h>
    36 #include <c-strcase.h>
    37 #include <ftoastr.h>
    38 
    39 #include <dlfcn.h>
    40 
    41 #include "lisp.h"
    42 #include "blockinput.h"
    43 #include "frame.h"
    44 #include "sysselect.h"
    45 #include "gtkutil.h"
    46 #include "systime.h"
    47 #include "character.h"
    48 #include "xwidget.h"
    49 #include "fontset.h"
    50 #include "composite.h"
    51 #include "ccl.h"
    52 
    53 #include "termhooks.h"
    54 #include "termopts.h"
    55 #include "termchar.h"
    56 #include "emacs-icon.h"
    57 #include "menu.h"
    58 #include "window.h"
    59 #include "keyboard.h"
    60 #include "atimer.h"
    61 #include "buffer.h"
    62 #include "font.h"
    63 #include "xsettings.h"
    64 #include "emacsgtkfixed.h"
    65 
    66 #ifdef GDK_WINDOWING_WAYLAND
    67 #include <gdk/gdkwayland.h>
    68 #endif
    69 
    70 #define FRAME_CR_CONTEXT(f)             ((f)->output_data.pgtk->cr_context)
    71 #define FRAME_CR_ACTIVE_CONTEXT(f)      ((f)->output_data.pgtk->cr_active)
    72 #define FRAME_CR_SURFACE(f)             (cairo_get_target (FRAME_CR_CONTEXT (f)))
    73 
    74 /* Non-zero means that a HELP_EVENT has been generated since Emacs
    75    start.  */
    76 
    77 static bool any_help_event_p;
    78 
    79 /* Chain of existing displays */
    80 struct pgtk_display_info *x_display_list;
    81 
    82 struct event_queue_t
    83 {
    84   union buffered_input_event *q;
    85   int nr, cap;
    86 };
    87 
    88 /* A queue of events that will be read by the read_socket_hook.  */
    89 static struct event_queue_t event_q;
    90 
    91 /* Non-zero timeout value means ignore next mouse click if it arrives
    92    before that timeout elapses (i.e. as part of the same sequence of
    93    events resulting from clicking on a frame to select it).  */
    94 static Time ignore_next_mouse_click_timeout;
    95 
    96 /* The default Emacs icon .  */
    97 static Lisp_Object xg_default_icon_file;
    98 
    99 /* The current GdkDragContext of a drop.  */
   100 static GdkDragContext *current_drop_context;
   101 
   102 /* Whether or not current_drop_context was set from a drop
   103    handler.  */
   104 static bool current_drop_context_drop;
   105 
   106 /* The time of the last drop.  */
   107 static guint32 current_drop_time;
   108 
   109 static void pgtk_delete_display (struct pgtk_display_info *);
   110 static void pgtk_clear_frame_area (struct frame *, int, int, int, int);
   111 static void pgtk_fill_rectangle (struct frame *, unsigned long, int, int,
   112                                  int, int, bool);
   113 static void pgtk_clip_to_row (struct window *, struct glyph_row *,
   114                               enum glyph_row_area, cairo_t *);
   115 static struct frame *pgtk_any_window_to_frame (GdkWindow *);
   116 static void pgtk_regenerate_devices (struct pgtk_display_info *);
   117 
   118 static void
   119 pgtk_device_added_or_removal_cb (GdkSeat *seat, GdkDevice *device,
   120                                  gpointer user_data)
   121 {
   122   pgtk_regenerate_devices (user_data);
   123 }
   124 
   125 static void
   126 pgtk_seat_added_cb (GdkDisplay *dpy, GdkSeat *seat,
   127                     gpointer user_data)
   128 {
   129   pgtk_regenerate_devices (user_data);
   130 
   131   g_signal_connect (G_OBJECT (seat), "device-added",
   132                     G_CALLBACK (pgtk_device_added_or_removal_cb),
   133                     user_data);
   134   g_signal_connect (G_OBJECT (seat), "device-removed",
   135                     G_CALLBACK (pgtk_device_added_or_removal_cb),
   136                     user_data);
   137 }
   138 
   139 static void
   140 pgtk_seat_removed_cb (GdkDisplay *dpy, GdkSeat *seat,
   141                       gpointer user_data)
   142 {
   143   pgtk_regenerate_devices (user_data);
   144 
   145   g_signal_handlers_disconnect_by_func (G_OBJECT (seat),
   146                                         G_CALLBACK (pgtk_device_added_or_removal_cb),
   147                                         user_data);
   148 }
   149 
   150 static void
   151 pgtk_enumerate_devices (struct pgtk_display_info *dpyinfo,
   152                         bool initial_p)
   153 {
   154   struct pgtk_device_t *rec;
   155   GList *all_seats, *devices_on_seat, *tem, *t1;
   156   GdkSeat *seat;
   157   char printbuf[1026]; /* Believe it or not, some device names are
   158                           actually almost this long.  */
   159 
   160   block_input ();
   161   all_seats = gdk_display_list_seats (dpyinfo->gdpy);
   162 
   163   for (tem = all_seats; tem; tem = tem->next)
   164     {
   165       seat = GDK_SEAT (tem->data);
   166 
   167       if (initial_p)
   168         {
   169           g_signal_connect (G_OBJECT (seat), "device-added",
   170                             G_CALLBACK (pgtk_device_added_or_removal_cb),
   171                             dpyinfo);
   172           g_signal_connect (G_OBJECT (seat), "device-removed",
   173                             G_CALLBACK (pgtk_device_added_or_removal_cb),
   174                             dpyinfo);
   175         }
   176 
   177       /* We only want slaves, not master devices.  */
   178       devices_on_seat = gdk_seat_get_slaves (seat,
   179                                              GDK_SEAT_CAPABILITY_ALL);
   180 
   181       for (t1 = devices_on_seat; t1; t1 = t1->next)
   182         {
   183           rec = xmalloc (sizeof *rec);
   184           rec->seat = g_object_ref (seat);
   185           rec->device = GDK_DEVICE (t1->data);
   186 
   187           snprintf (printbuf, 1026, "%u:%s",
   188                     gdk_device_get_source (rec->device),
   189                     gdk_device_get_name (rec->device));
   190 
   191           rec->name = build_string (printbuf);
   192           rec->next = dpyinfo->devices;
   193           dpyinfo->devices = rec;
   194         }
   195 
   196       g_list_free (devices_on_seat);
   197     }
   198 
   199   g_list_free (all_seats);
   200   unblock_input ();
   201 }
   202 
   203 static void
   204 pgtk_free_devices (struct pgtk_display_info *dpyinfo)
   205 {
   206   struct pgtk_device_t *last, *tem;
   207 
   208   tem = dpyinfo->devices;
   209   while (tem)
   210     {
   211       last = tem;
   212       tem = tem->next;
   213 
   214       g_object_unref (last->seat);
   215       xfree (last);
   216     }
   217 
   218   dpyinfo->devices = NULL;
   219 }
   220 
   221 static void
   222 pgtk_regenerate_devices (struct pgtk_display_info *dpyinfo)
   223 {
   224   pgtk_free_devices (dpyinfo);
   225   pgtk_enumerate_devices (dpyinfo, false);
   226 }
   227 
   228 static void
   229 pgtk_toolkit_position (struct frame *f, int x, int y,
   230                        bool *menu_bar_p, bool *tool_bar_p)
   231 {
   232   GdkRectangle test_rect;
   233   int scale;
   234 
   235   y += (FRAME_MENUBAR_HEIGHT (f)
   236         + FRAME_TOOLBAR_TOP_HEIGHT (f));
   237   x += FRAME_TOOLBAR_LEFT_WIDTH (f);
   238 
   239   if (FRAME_EXTERNAL_MENU_BAR (f))
   240     *menu_bar_p = (x >= 0 && x < FRAME_PIXEL_WIDTH (f)
   241                    && y >= 0 && y < FRAME_MENUBAR_HEIGHT (f));
   242 
   243   if (FRAME_X_OUTPUT (f)->toolbar_widget)
   244     {
   245       scale = xg_get_scale (f);
   246       test_rect.x = x / scale;
   247       test_rect.y = y / scale;
   248       test_rect.width = 1;
   249       test_rect.height = 1;
   250 
   251       *tool_bar_p = gtk_widget_intersect (FRAME_X_OUTPUT (f)->toolbar_widget,
   252                                           &test_rect, NULL);
   253     }
   254 }
   255 
   256 static Lisp_Object
   257 pgtk_get_device_for_event (struct pgtk_display_info *dpyinfo,
   258                            GdkEvent *event)
   259 {
   260   struct pgtk_device_t *tem;
   261   GdkDevice *device;
   262 
   263   device = gdk_event_get_source_device (event);
   264 
   265   if (!device)
   266     return Qt;
   267 
   268   for (tem = dpyinfo->devices; tem; tem = tem->next)
   269     {
   270       if (tem->device == device)
   271         return tem->name;
   272     }
   273 
   274   return Qt;
   275 }
   276 
   277 /* This is not a flip context in the same sense as gpu rendering
   278    scenes, it only occurs when a new context was required due to a
   279    resize or other fundamental change.  This is called when that
   280    context's surface has completed drawing.  */
   281 
   282 static void
   283 flip_cr_context (struct frame *f)
   284 {
   285   cairo_t *cr = FRAME_CR_ACTIVE_CONTEXT (f);
   286 
   287   block_input ();
   288   if (cr != FRAME_CR_CONTEXT (f))
   289     {
   290       cairo_destroy (cr);
   291 
   292       FRAME_CR_ACTIVE_CONTEXT (f)
   293         = cairo_reference (FRAME_CR_CONTEXT (f));
   294     }
   295   unblock_input ();
   296 }
   297 
   298 
   299 static void
   300 evq_enqueue (union buffered_input_event *ev)
   301 {
   302   struct event_queue_t *evq = &event_q;
   303   struct frame *frame;
   304   struct pgtk_display_info *dpyinfo;
   305 
   306   if (evq->cap == 0)
   307     {
   308       evq->cap = 4;
   309       evq->q = xmalloc (sizeof *evq->q * evq->cap);
   310     }
   311 
   312   if (evq->nr >= evq->cap)
   313     {
   314       evq->cap += evq->cap / 2;
   315       evq->q = xrealloc (evq->q, sizeof *evq->q * evq->cap);
   316     }
   317 
   318   evq->q[evq->nr++] = *ev;
   319 
   320   if (ev->ie.kind != SELECTION_REQUEST_EVENT
   321       && ev->ie.kind != SELECTION_CLEAR_EVENT)
   322     {
   323       frame = NULL;
   324 
   325       if (WINDOWP (ev->ie.frame_or_window))
   326         frame = WINDOW_XFRAME (XWINDOW (ev->ie.frame_or_window));
   327 
   328       if (FRAMEP (ev->ie.frame_or_window))
   329         frame = XFRAME (ev->ie.frame_or_window);
   330 
   331       if (frame)
   332         {
   333           dpyinfo = FRAME_DISPLAY_INFO (frame);
   334 
   335           if (dpyinfo->last_user_time < ev->ie.timestamp)
   336             dpyinfo->last_user_time = ev->ie.timestamp;
   337         }
   338     }
   339 
   340   raise (SIGIO);
   341 }
   342 
   343 static int
   344 evq_flush (struct input_event *hold_quit)
   345 {
   346   struct event_queue_t *evq = &event_q;
   347   int n = 0;
   348 
   349   while (evq->nr > 0)
   350     {
   351       /* kbd_buffer_store_buffered_event may do longjmp, so
   352          we need to shift event queue first and pass the event
   353          to kbd_buffer_store_buffered_event so that events in
   354          queue are not processed twice.  Bug#52941 */
   355       union buffered_input_event ev = evq->q[0];
   356       int i;
   357       for (i = 1; i < evq->nr; i++)
   358         evq->q[i - 1] = evq->q[i];
   359       evq->nr--;
   360 
   361       kbd_buffer_store_buffered_event (&ev, hold_quit);
   362       n++;
   363     }
   364 
   365   return n;
   366 }
   367 
   368 void
   369 mark_pgtkterm (void)
   370 {
   371   struct pgtk_display_info *dpyinfo;
   372   struct pgtk_device_t *device;
   373   struct event_queue_t *evq = &event_q;
   374   int i, n = evq->nr;
   375 
   376   for (i = 0; i < n; i++)
   377     {
   378       union buffered_input_event *ev = &evq->q[i];
   379 
   380       /* Selection requests don't have Lisp object members.  */
   381 
   382       if (ev->ie.kind == SELECTION_REQUEST_EVENT
   383           || ev->ie.kind == SELECTION_CLEAR_EVENT)
   384         continue;
   385 
   386       mark_object (ev->ie.x);
   387       mark_object (ev->ie.y);
   388       mark_object (ev->ie.frame_or_window);
   389       mark_object (ev->ie.arg);
   390       mark_object (ev->ie.device);
   391     }
   392 
   393   for (dpyinfo = x_display_list; dpyinfo;
   394        dpyinfo = dpyinfo->next)
   395     {
   396       for (device = dpyinfo->devices; device;
   397            device = device->next)
   398         mark_object (device->name);
   399     }
   400 }
   401 
   402 char *
   403 get_keysym_name (int keysym)
   404 {
   405   return gdk_keyval_name (keysym);
   406 }
   407 
   408 void
   409 frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y)
   410 /* --------------------------------------------------------------------------
   411      Programmatically reposition mouse pointer in pixel coordinates
   412    -------------------------------------------------------------------------- */
   413 {
   414 }
   415 
   416 /* Raise frame F.  */
   417 
   418 static void
   419 pgtk_raise_frame (struct frame *f)
   420 {
   421   /* This works only for non-child frames on X.
   422      It does not work for child frames on X, and it does not work
   423      on Wayland too. */
   424   block_input ();
   425   if (FRAME_VISIBLE_P (f))
   426     gdk_window_raise (gtk_widget_get_window (FRAME_WIDGET (f)));
   427   unblock_input ();
   428 }
   429 
   430 /* Lower frame F.  */
   431 
   432 static void
   433 pgtk_lower_frame (struct frame *f)
   434 {
   435   if (FRAME_VISIBLE_P (f))
   436     {
   437       block_input ();
   438       gdk_window_lower (gtk_widget_get_window (FRAME_WIDGET (f)));
   439       unblock_input ();
   440     }
   441 }
   442 
   443 static void
   444 pgtk_frame_raise_lower (struct frame *f, bool raise_flag)
   445 {
   446   if (raise_flag)
   447     pgtk_raise_frame (f);
   448   else
   449     pgtk_lower_frame (f);
   450 }
   451 
   452 /* Free X resources of frame F.  */
   453 
   454 void
   455 pgtk_free_frame_resources (struct frame *f)
   456 {
   457   struct pgtk_display_info *dpyinfo;
   458   Mouse_HLInfo *hlinfo;
   459 
   460   check_window_system (f);
   461   dpyinfo = FRAME_DISPLAY_INFO (f);
   462   hlinfo = MOUSE_HL_INFO (f);
   463 
   464   block_input ();
   465 
   466 #ifdef HAVE_XWIDGETS
   467   kill_frame_xwidget_views (f);
   468 #endif
   469   free_frame_faces (f);
   470 
   471   if (FRAME_X_OUTPUT (f)->scale_factor_atimer != NULL)
   472     {
   473       cancel_atimer (FRAME_X_OUTPUT (f)->scale_factor_atimer);
   474       FRAME_X_OUTPUT (f)->scale_factor_atimer = NULL;
   475     }
   476 
   477 #define CLEAR_IF_EQ(FIELD)      \
   478   do { if (f == dpyinfo->FIELD) dpyinfo->FIELD = 0; } while (false)
   479 
   480   CLEAR_IF_EQ (x_focus_frame);
   481   CLEAR_IF_EQ (highlight_frame);
   482   CLEAR_IF_EQ (x_focus_event_frame);
   483   CLEAR_IF_EQ (last_mouse_frame);
   484   CLEAR_IF_EQ (last_mouse_motion_frame);
   485   CLEAR_IF_EQ (last_mouse_glyph_frame);
   486   CLEAR_IF_EQ (im.focused_frame);
   487 
   488 #undef CLEAR_IF_EQ
   489 
   490   if (f == hlinfo->mouse_face_mouse_frame)
   491     reset_mouse_highlight (hlinfo);
   492 
   493   g_clear_object (&FRAME_X_OUTPUT (f)->text_cursor);
   494   g_clear_object (&FRAME_X_OUTPUT (f)->nontext_cursor);
   495   g_clear_object (&FRAME_X_OUTPUT (f)->modeline_cursor);
   496   g_clear_object (&FRAME_X_OUTPUT (f)->hand_cursor);
   497   g_clear_object (&FRAME_X_OUTPUT (f)->hourglass_cursor);
   498   g_clear_object (&FRAME_X_OUTPUT (f)->horizontal_drag_cursor);
   499   g_clear_object (&FRAME_X_OUTPUT (f)->vertical_drag_cursor);
   500   g_clear_object (&FRAME_X_OUTPUT (f)->left_edge_cursor);
   501   g_clear_object (&FRAME_X_OUTPUT (f)->right_edge_cursor);
   502   g_clear_object (&FRAME_X_OUTPUT (f)->top_edge_cursor);
   503   g_clear_object (&FRAME_X_OUTPUT (f)->bottom_edge_cursor);
   504   g_clear_object (&FRAME_X_OUTPUT (f)->top_left_corner_cursor);
   505   g_clear_object (&FRAME_X_OUTPUT (f)->top_right_corner_cursor);
   506   g_clear_object (&FRAME_X_OUTPUT (f)->bottom_right_corner_cursor);
   507   g_clear_object (&FRAME_X_OUTPUT (f)->bottom_left_corner_cursor);
   508 
   509 
   510   if (FRAME_X_OUTPUT (f)->border_color_css_provider != NULL)
   511     {
   512       GtkStyleContext *ctxt = gtk_widget_get_style_context (FRAME_WIDGET (f));
   513       GtkCssProvider *old = FRAME_X_OUTPUT (f)->border_color_css_provider;
   514       gtk_style_context_remove_provider (ctxt, GTK_STYLE_PROVIDER (old));
   515       g_object_unref (old);
   516       FRAME_X_OUTPUT (f)->border_color_css_provider = NULL;
   517     }
   518 
   519   if (FRAME_X_OUTPUT (f)->scrollbar_foreground_css_provider != NULL)
   520     {
   521       GtkCssProvider *old
   522         = FRAME_X_OUTPUT (f)->scrollbar_foreground_css_provider;
   523       g_object_unref (old);
   524       FRAME_X_OUTPUT (f)->scrollbar_foreground_css_provider = NULL;
   525     }
   526 
   527   if (FRAME_X_OUTPUT (f)->scrollbar_background_css_provider != NULL)
   528     {
   529       GtkCssProvider *old
   530         = FRAME_X_OUTPUT (f)->scrollbar_background_css_provider;
   531       g_object_unref (old);
   532       FRAME_X_OUTPUT (f)->scrollbar_background_css_provider = NULL;
   533     }
   534 
   535   gtk_widget_destroy (FRAME_WIDGET (f));
   536 
   537   if (FRAME_X_OUTPUT (f)->cr_surface_visible_bell != NULL)
   538     {
   539       cairo_surface_destroy (FRAME_X_OUTPUT (f)->cr_surface_visible_bell);
   540       FRAME_X_OUTPUT (f)->cr_surface_visible_bell = NULL;
   541     }
   542 
   543   if (FRAME_X_OUTPUT (f)->atimer_visible_bell != NULL)
   544     {
   545       cancel_atimer (FRAME_X_OUTPUT (f)->atimer_visible_bell);
   546       FRAME_X_OUTPUT (f)->atimer_visible_bell = NULL;
   547     }
   548 
   549   xfree (f->output_data.pgtk);
   550   f->output_data.pgtk = NULL;
   551 
   552   unblock_input ();
   553 }
   554 
   555 void
   556 pgtk_destroy_window (struct frame *f)
   557 /* --------------------------------------------------------------------------
   558      External: Delete the window
   559    -------------------------------------------------------------------------- */
   560 {
   561   struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
   562 
   563   check_window_system (f);
   564   if (dpyinfo->gdpy != NULL)
   565     pgtk_free_frame_resources (f);
   566 
   567   dpyinfo->reference_count--;
   568 }
   569 
   570 /* Calculate the absolute position in frame F
   571    from its current recorded position values and gravity.  */
   572 
   573 static void
   574 pgtk_calc_absolute_position (struct frame *f)
   575 {
   576   int flags = f->size_hint_flags;
   577   struct frame *p = FRAME_PARENT_FRAME (f);
   578 
   579   /* We have nothing to do if the current position
   580      is already for the top-left corner.  */
   581   if (! ((flags & XNegative) || (flags & YNegative)))
   582     return;
   583 
   584   /* Treat negative positions as relative to the leftmost bottommost
   585      position that fits on the screen.  */
   586   if ((flags & XNegative) && (f->left_pos <= 0))
   587     {
   588       int width = FRAME_PIXEL_WIDTH (f);
   589 
   590       /* A frame that has been visible at least once should have outer
   591          edges.  */
   592       if (f->output_data.pgtk->has_been_visible && !p)
   593         {
   594           Lisp_Object frame;
   595           Lisp_Object edges = Qnil;
   596 
   597           XSETFRAME (frame, f);
   598           edges = Fpgtk_frame_edges (frame, Qouter_edges);
   599           if (!NILP (edges))
   600             width = (XFIXNUM (Fnth (make_fixnum (2), edges))
   601                      - XFIXNUM (Fnth (make_fixnum (0), edges)));
   602         }
   603 
   604       if (p)
   605         f->left_pos = (FRAME_PIXEL_WIDTH (p) - width - 2 * f->border_width
   606                        + f->left_pos);
   607       else
   608         f->left_pos = (pgtk_display_pixel_width (FRAME_DISPLAY_INFO (f))
   609                        - width + f->left_pos);
   610 
   611     }
   612 
   613   if ((flags & YNegative) && (f->top_pos <= 0))
   614     {
   615       int height = FRAME_PIXEL_HEIGHT (f);
   616 
   617       if (f->output_data.pgtk->has_been_visible && !p)
   618         {
   619           Lisp_Object frame;
   620           Lisp_Object edges = Qnil;
   621 
   622           XSETFRAME (frame, f);
   623           if (NILP (edges))
   624             edges = Fpgtk_frame_edges (frame, Qouter_edges);
   625           if (!NILP (edges))
   626             height = (XFIXNUM (Fnth (make_fixnum (3), edges))
   627                       - XFIXNUM (Fnth (make_fixnum (1), edges)));
   628         }
   629 
   630       if (p)
   631         f->top_pos = (FRAME_PIXEL_HEIGHT (p) - height - 2 * f->border_width
   632                        + f->top_pos);
   633       else
   634         f->top_pos = (pgtk_display_pixel_height (FRAME_DISPLAY_INFO (f))
   635                       - height + f->top_pos);
   636   }
   637 
   638   /* The left_pos and top_pos
   639      are now relative to the top and left screen edges,
   640      so the flags should correspond.  */
   641   f->size_hint_flags &= ~ (XNegative | YNegative);
   642 }
   643 
   644 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
   645    to really change the position, and 0 when calling from
   646    x_make_frame_visible (in that case, XOFF and YOFF are the current
   647    position values).  It is -1 when calling from x_set_frame_parameters,
   648    which means, do adjust for borders but don't change the gravity.  */
   649 
   650 static void
   651 pgtk_set_offset (struct frame *f, int xoff, int yoff, int change_gravity)
   652 {
   653   if (change_gravity > 0)
   654     {
   655       f->top_pos = yoff;
   656       f->left_pos = xoff;
   657       f->size_hint_flags &= ~ (XNegative | YNegative);
   658       if (xoff < 0)
   659         f->size_hint_flags |= XNegative;
   660       if (yoff < 0)
   661         f->size_hint_flags |= YNegative;
   662       f->win_gravity = NorthWestGravity;
   663     }
   664 
   665   pgtk_calc_absolute_position (f);
   666 
   667   block_input ();
   668   xg_wm_set_size_hint (f, 0, false);
   669 
   670   if (change_gravity != 0)
   671     {
   672       if (FRAME_GTK_OUTER_WIDGET (f))
   673         gtk_window_move (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
   674                          f->left_pos, f->top_pos);
   675       else
   676         {
   677           GtkWidget *fixed = FRAME_GTK_WIDGET (f);
   678           GtkWidget *parent = gtk_widget_get_parent (fixed);
   679           gtk_fixed_move (GTK_FIXED (parent), fixed,
   680                           f->left_pos, f->top_pos);
   681         }
   682     }
   683   unblock_input ();
   684   return;
   685 }
   686 
   687 static void
   688 pgtk_set_window_size (struct frame *f, bool change_gravity,
   689                       int width, int height)
   690 /* --------------------------------------------------------------------------
   691      Adjust window pixel size based on given character grid size
   692      Impl is a bit more complex than other terms, need to do some
   693      internal clipping.
   694    -------------------------------------------------------------------------- */
   695 {
   696   int pixelwidth, pixelheight;
   697 
   698   block_input ();
   699 
   700   gtk_widget_get_size_request (FRAME_GTK_WIDGET (f), &pixelwidth,
   701                                &pixelheight);
   702 
   703   pixelwidth = width;
   704   pixelheight = height;
   705 
   706   for (GtkWidget * w = FRAME_GTK_WIDGET (f); w != NULL;
   707        w = gtk_widget_get_parent (w))
   708     {
   709       gint wd, hi;
   710       gtk_widget_get_size_request (w, &wd, &hi);
   711     }
   712 
   713   f->output_data.pgtk->preferred_width = pixelwidth;
   714   f->output_data.pgtk->preferred_height = pixelheight;
   715   xg_wm_set_size_hint (f, 0, 0);
   716   xg_frame_set_char_size (f, pixelwidth, pixelheight);
   717   gtk_widget_queue_resize (FRAME_WIDGET (f));
   718 
   719   unblock_input ();
   720 }
   721 
   722 void
   723 pgtk_iconify_frame (struct frame *f)
   724 {
   725   GtkWindow *window;
   726 
   727   /* Don't keep the highlight on an invisible frame.  */
   728 
   729   if (FRAME_DISPLAY_INFO (f)->highlight_frame == f)
   730     FRAME_DISPLAY_INFO (f)->highlight_frame = NULL;
   731 
   732   /* If the frame is already iconified, return.  */
   733 
   734   if (FRAME_ICONIFIED_P (f))
   735     return;
   736 
   737   /* Child frames on PGTK have no outer widgets.  In that case, simply
   738      refuse to iconify the frame.  */
   739 
   740   if (FRAME_GTK_OUTER_WIDGET (f))
   741     {
   742       if (!FRAME_VISIBLE_P (f))
   743         gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
   744 
   745       window = GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f));
   746 
   747       gtk_window_iconify (window);
   748 
   749       /* Don't make the frame iconified here.  Doing so will cause it
   750          to be skipped by redisplay, until GDK says it is deiconified
   751          (see window_state_event for more details).  However, if the
   752          window server rejects the iconification request, GDK will
   753          never tell Emacs about the iconification not happening,
   754          leading to the frame not being redisplayed until the next
   755          window state change.  */
   756 
   757       /* SET_FRAME_VISIBLE (f, 0);
   758          SET_FRAME_ICONIFIED (f, true); */
   759     }
   760 }
   761 
   762 static gboolean
   763 pgtk_make_frame_visible_wait_for_map_event_cb (GtkWidget *widget,
   764                                                GdkEventAny *event,
   765                                                gpointer user_data)
   766 {
   767   int *foundptr = user_data;
   768   *foundptr = 1;
   769   return FALSE;
   770 }
   771 
   772 static gboolean
   773 pgtk_make_frame_visible_wait_for_map_event_timeout (gpointer user_data)
   774 {
   775   int *timedoutptr = user_data;
   776   *timedoutptr = 1;
   777   return FALSE;
   778 }
   779 
   780 static void
   781 pgtk_wait_for_map_event (struct frame *f, bool multiple_times)
   782 {
   783   if (FLOATP (Vpgtk_wait_for_event_timeout))
   784     {
   785       guint msec
   786         = (guint) (XFLOAT_DATA (Vpgtk_wait_for_event_timeout) * 1000);
   787       int found = 0;
   788       int timed_out = 0;
   789       gulong id
   790         = g_signal_connect (FRAME_WIDGET (f), "map-event",
   791                             G_CALLBACK
   792                             (pgtk_make_frame_visible_wait_for_map_event_cb),
   793                             &found);
   794       guint src
   795         = g_timeout_add (msec,
   796                          pgtk_make_frame_visible_wait_for_map_event_timeout,
   797                          &timed_out);
   798 
   799       if (!multiple_times)
   800         {
   801           while (!found && !timed_out)
   802             gtk_main_iteration ();
   803         }
   804       else
   805         {
   806           while (!timed_out)
   807             gtk_main_iteration ();
   808         }
   809 
   810       g_signal_handler_disconnect (FRAME_WIDGET (f), id);
   811 
   812       if (!timed_out)
   813         g_source_remove (src);
   814     }
   815 }
   816 
   817 void
   818 pgtk_make_frame_visible (struct frame *f)
   819 {
   820   GtkWidget *win = FRAME_GTK_OUTER_WIDGET (f);
   821 
   822   if (!FRAME_VISIBLE_P (f))
   823     {
   824       gtk_widget_show (FRAME_WIDGET (f));
   825       if (win)
   826         gtk_window_deiconify (GTK_WINDOW (win));
   827 
   828       pgtk_wait_for_map_event (f, false);
   829     }
   830 }
   831 
   832 
   833 void
   834 pgtk_make_frame_invisible (struct frame *f)
   835 {
   836   gtk_widget_hide (FRAME_WIDGET (f));
   837 
   838   /* Handle any pending map event(s), then make the frame visible
   839      manually, to avoid race conditions.  */
   840   pgtk_wait_for_map_event (f, true);
   841 
   842   SET_FRAME_VISIBLE (f, 0);
   843   SET_FRAME_ICONIFIED (f, false);
   844 }
   845 
   846 static void
   847 pgtk_make_frame_visible_invisible (struct frame *f, bool visible)
   848 {
   849   if (visible)
   850     pgtk_make_frame_visible (f);
   851   else
   852     pgtk_make_frame_invisible (f);
   853 }
   854 
   855 static Lisp_Object
   856 pgtk_new_font (struct frame *f, Lisp_Object font_object, int fontset)
   857 {
   858   struct font *font = XFONT_OBJECT (font_object);
   859   int font_ascent, font_descent;
   860 
   861   if (fontset < 0)
   862     fontset = fontset_from_font (font_object);
   863   FRAME_FONTSET (f) = fontset;
   864 
   865   if (FRAME_FONT (f) == font)
   866     {
   867       /* This font is already set in frame F.  There's nothing more to
   868          do.  */
   869       return font_object;
   870     }
   871 
   872   FRAME_FONT (f) = font;
   873 
   874   FRAME_BASELINE_OFFSET (f) = font->baseline_offset;
   875   FRAME_COLUMN_WIDTH (f) = font->average_width;
   876   get_font_ascent_descent (font, &font_ascent, &font_descent);
   877   FRAME_LINE_HEIGHT (f) = font_ascent + font_descent;
   878 
   879   /* We could use a more elaborate calculation here.  */
   880   FRAME_TAB_BAR_HEIGHT (f) = FRAME_TAB_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
   881 
   882   /* Compute the scroll bar width in character columns.  */
   883   if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
   884     {
   885       int wid = FRAME_COLUMN_WIDTH (f);
   886       FRAME_CONFIG_SCROLL_BAR_COLS (f)
   887         = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + wid - 1) / wid;
   888     }
   889   else
   890     {
   891       int wid = FRAME_COLUMN_WIDTH (f);
   892       FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
   893     }
   894 
   895   /* Compute the scroll bar height in character lines.  */
   896   if (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) > 0)
   897     {
   898       int height = FRAME_LINE_HEIGHT (f);
   899       FRAME_CONFIG_SCROLL_BAR_LINES (f)
   900         = (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) + height - 1) / height;
   901     }
   902   else
   903     {
   904       int height = FRAME_LINE_HEIGHT (f);
   905       FRAME_CONFIG_SCROLL_BAR_LINES (f) = (14 + height - 1) / height;
   906     }
   907 
   908   /* Now make the frame display the given font.  */
   909   if (FRAME_GTK_WIDGET (f) != NULL)
   910     adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
   911                        FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3,
   912                        false, Qfont);
   913 
   914   return font_object;
   915 }
   916 
   917 int
   918 pgtk_display_pixel_height (struct pgtk_display_info *dpyinfo)
   919 {
   920   GdkDisplay *gdpy = dpyinfo->gdpy;
   921   GdkScreen *gscr = gdk_display_get_default_screen (gdpy);
   922 
   923   return gdk_screen_get_height (gscr);
   924 }
   925 
   926 int
   927 pgtk_display_pixel_width (struct pgtk_display_info *dpyinfo)
   928 {
   929   GdkDisplay *gdpy = dpyinfo->gdpy;
   930   GdkScreen *gscr = gdk_display_get_default_screen (gdpy);
   931 
   932   return gdk_screen_get_width (gscr);
   933 }
   934 
   935 void
   936 pgtk_set_parent_frame (struct frame *f, Lisp_Object new_value,
   937                        Lisp_Object old_value)
   938 {
   939   struct frame *p = NULL;
   940 
   941   if (!NILP (new_value)
   942       && (!FRAMEP (new_value)
   943           || !FRAME_LIVE_P (p = XFRAME (new_value))
   944           || !FRAME_PGTK_P (p)))
   945     {
   946       store_frame_param (f, Qparent_frame, old_value);
   947       error ("Invalid specification of `parent-frame'");
   948     }
   949 
   950   if (p != FRAME_PARENT_FRAME (f))
   951     {
   952       block_input ();
   953 
   954       if (p != NULL)
   955         {
   956           if (FRAME_DISPLAY_INFO (f) != FRAME_DISPLAY_INFO (p))
   957             error ("Cross display reparent.");
   958         }
   959 
   960       GtkWidget *fixed = FRAME_GTK_WIDGET (f);
   961 
   962       GtkAllocation alloc;
   963       gtk_widget_get_allocation (fixed, &alloc);
   964       g_object_ref (fixed);
   965 
   966       /* Remember the css provider, and restore it later. */
   967       GtkCssProvider *provider = FRAME_X_OUTPUT (f)->border_color_css_provider;
   968       FRAME_X_OUTPUT (f)->border_color_css_provider = NULL;
   969       {
   970         GtkStyleContext *ctxt = gtk_widget_get_style_context (FRAME_WIDGET (f));
   971         if (provider != NULL)
   972           gtk_style_context_remove_provider (ctxt, GTK_STYLE_PROVIDER (provider));
   973       }
   974 
   975       {
   976         GtkWidget *whbox_of_f = gtk_widget_get_parent (fixed);
   977         /* Here, unhighlight can be called and may change
   978            border_color_css_provider.  */
   979         gtk_container_remove (GTK_CONTAINER (whbox_of_f), fixed);
   980 
   981         if (FRAME_GTK_OUTER_WIDGET (f))
   982           {
   983             gtk_widget_destroy (FRAME_GTK_OUTER_WIDGET (f));
   984             FRAME_GTK_OUTER_WIDGET (f) = NULL;
   985             FRAME_OUTPUT_DATA (f)->vbox_widget = NULL;
   986             FRAME_OUTPUT_DATA (f)->hbox_widget = NULL;
   987             FRAME_OUTPUT_DATA (f)->menubar_widget = NULL;
   988             FRAME_OUTPUT_DATA (f)->toolbar_widget = NULL;
   989             FRAME_OUTPUT_DATA (f)->ttip_widget = NULL;
   990             FRAME_OUTPUT_DATA (f)->ttip_lbl = NULL;
   991             FRAME_OUTPUT_DATA (f)->ttip_window = NULL;
   992           }
   993       }
   994 
   995       if (p == NULL)
   996         {
   997           xg_create_frame_outer_widgets (f);
   998           pgtk_set_event_handler (f);
   999           gtk_box_pack_start (GTK_BOX (f->output_data.pgtk->hbox_widget),
  1000                               fixed, TRUE, TRUE, 0);
  1001           f->output_data.pgtk->preferred_width = alloc.width;
  1002           f->output_data.pgtk->preferred_height = alloc.height;
  1003           xg_wm_set_size_hint (f, 0, 0);
  1004           xg_frame_set_char_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, alloc.width),
  1005                                   FRAME_PIXEL_TO_TEXT_HEIGHT (f, alloc.height));
  1006           gtk_widget_queue_resize (FRAME_WIDGET (f));
  1007           gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
  1008         }
  1009       else
  1010         {
  1011           GtkWidget *fixed_of_p = FRAME_GTK_WIDGET (p);
  1012           gtk_fixed_put (GTK_FIXED (fixed_of_p), fixed, f->left_pos, f->top_pos);
  1013           gtk_widget_set_size_request (fixed, alloc.width, alloc.height);
  1014           gtk_widget_show_all (fixed);
  1015         }
  1016 
  1017       /* Restore css provider. */
  1018       GtkStyleContext *ctxt = gtk_widget_get_style_context (FRAME_WIDGET (f));
  1019       GtkCssProvider *old = FRAME_X_OUTPUT (f)->border_color_css_provider;
  1020       FRAME_X_OUTPUT (f)->border_color_css_provider = provider;
  1021       if (provider != NULL)
  1022         {
  1023           gtk_style_context_add_provider (ctxt, GTK_STYLE_PROVIDER (provider),
  1024                                           GTK_STYLE_PROVIDER_PRIORITY_USER);
  1025         }
  1026       if (old != NULL)
  1027         {
  1028           gtk_style_context_remove_provider (ctxt, GTK_STYLE_PROVIDER (old));
  1029           g_object_unref(old);
  1030         }
  1031 
  1032       g_object_unref (fixed);
  1033 
  1034       unblock_input ();
  1035 
  1036       fset_parent_frame (f, new_value);
  1037     }
  1038 }
  1039 
  1040 /* Doesn't work on wayland.  */
  1041 void
  1042 pgtk_set_no_focus_on_map (struct frame *f, Lisp_Object new_value,
  1043                           Lisp_Object old_value)
  1044 {
  1045   if (!EQ (new_value, old_value))
  1046     {
  1047       xg_set_no_focus_on_map (f, new_value);
  1048       FRAME_NO_FOCUS_ON_MAP (f) = !NILP (new_value);
  1049     }
  1050 }
  1051 
  1052 void
  1053 pgtk_set_no_accept_focus (struct frame *f, Lisp_Object new_value,
  1054                           Lisp_Object old_value)
  1055 {
  1056   xg_set_no_accept_focus (f, new_value);
  1057   FRAME_NO_ACCEPT_FOCUS (f) = !NILP (new_value);
  1058 }
  1059 
  1060 void
  1061 pgtk_set_z_group (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
  1062 {
  1063   if (!FRAME_GTK_OUTER_WIDGET (f))
  1064     return;
  1065 
  1066   if (NILP (new_value))
  1067     {
  1068       gtk_window_set_keep_above (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
  1069                                  FALSE);
  1070       gtk_window_set_keep_below (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
  1071                                  FALSE);
  1072       FRAME_Z_GROUP (f) = z_group_none;
  1073     }
  1074   else if (EQ (new_value, Qabove))
  1075     {
  1076       gtk_window_set_keep_above (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
  1077                                  TRUE);
  1078       gtk_window_set_keep_below (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
  1079                                  FALSE);
  1080       FRAME_Z_GROUP (f) = z_group_above;
  1081     }
  1082   else if (EQ (new_value, Qabove_suspended))
  1083     {
  1084       gtk_window_set_keep_above (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
  1085                                  FALSE);
  1086       FRAME_Z_GROUP (f) = z_group_above_suspended;
  1087     }
  1088   else if (EQ (new_value, Qbelow))
  1089     {
  1090       gtk_window_set_keep_above (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
  1091                                  FALSE);
  1092       gtk_window_set_keep_below (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
  1093                                  TRUE);
  1094       FRAME_Z_GROUP (f) = z_group_below;
  1095     }
  1096   else
  1097     error ("Invalid z-group specification");
  1098 }
  1099 
  1100 static void
  1101 pgtk_initialize_display_info (struct pgtk_display_info *dpyinfo)
  1102 /* --------------------------------------------------------------------------
  1103       Initialize global info and storage for display.
  1104    -------------------------------------------------------------------------- */
  1105 {
  1106   dpyinfo->resx = 96;
  1107   dpyinfo->resy = 96;
  1108   dpyinfo->color_p = 1;
  1109   dpyinfo->n_planes = 32;
  1110   dpyinfo->root_window = 42;    /* a placeholder.. */
  1111   dpyinfo->highlight_frame = dpyinfo->x_focus_frame = NULL;
  1112   dpyinfo->n_fonts = 0;
  1113   dpyinfo->smallest_font_height = 1;
  1114   dpyinfo->smallest_char_width = 1;
  1115 
  1116   reset_mouse_highlight (&dpyinfo->mouse_highlight);
  1117 }
  1118 
  1119 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
  1120    face.  */
  1121 
  1122 static void
  1123 pgtk_set_cursor_gc (struct glyph_string *s)
  1124 {
  1125   if (s->font == FRAME_FONT (s->f)
  1126       && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
  1127       && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f) && !s->cmp)
  1128       s->xgcv = FRAME_X_OUTPUT (s->f)->cursor_xgcv;
  1129   else
  1130     {
  1131       /* Cursor on non-default face: must merge.  */
  1132       Emacs_GC xgcv;
  1133 
  1134       xgcv.background = FRAME_X_OUTPUT (s->f)->cursor_color;
  1135       xgcv.foreground = s->face->background;
  1136 
  1137       /* If the glyph would be invisible, try a different foreground.  */
  1138       if (xgcv.foreground == xgcv.background)
  1139         xgcv.foreground = s->face->foreground;
  1140       if (xgcv.foreground == xgcv.background)
  1141         xgcv.foreground = FRAME_X_OUTPUT (s->f)->cursor_foreground_color;
  1142       if (xgcv.foreground == xgcv.background)
  1143         xgcv.foreground = s->face->foreground;
  1144 
  1145       /* Make sure the cursor is distinct from text in this face.  */
  1146       if (xgcv.background == s->face->background
  1147           && xgcv.foreground == s->face->foreground)
  1148         {
  1149           xgcv.background = s->face->foreground;
  1150           xgcv.foreground = s->face->background;
  1151         }
  1152 
  1153       s->xgcv = xgcv;
  1154     }
  1155 }
  1156 
  1157 
  1158 /* Set up S->gc of glyph string S for drawing text in mouse face.  */
  1159 
  1160 static void
  1161 pgtk_set_mouse_face_gc (struct glyph_string *s)
  1162 {
  1163   prepare_face_for_display (s->f, s->face);
  1164 
  1165   if (s->font == s->face->font)
  1166     {
  1167       s->xgcv.foreground = s->face->foreground;
  1168       s->xgcv.background = s->face->background;
  1169     }
  1170   else
  1171     {
  1172       /* Otherwise construct scratch_cursor_gc with values from FACE
  1173          except for FONT.  */
  1174       Emacs_GC xgcv;
  1175 
  1176       xgcv.background = s->face->background;
  1177       xgcv.foreground = s->face->foreground;
  1178 
  1179       s->xgcv = xgcv;
  1180 
  1181     }
  1182 }
  1183 
  1184 
  1185 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
  1186    Faces to use in the mode line have already been computed when the
  1187    matrix was built, so there isn't much to do, here.  */
  1188 
  1189 static void
  1190 pgtk_set_mode_line_face_gc (struct glyph_string *s)
  1191 {
  1192   s->xgcv.foreground = s->face->foreground;
  1193   s->xgcv.background = s->face->background;
  1194 }
  1195 
  1196 
  1197 /* Set S->gc of glyph string S for drawing that glyph string.  Set
  1198    S->stippled_p to a non-zero value if the face of S has a stipple
  1199    pattern.  */
  1200 
  1201 static void
  1202 pgtk_set_glyph_string_gc (struct glyph_string *s)
  1203 {
  1204   prepare_face_for_display (s->f, s->face);
  1205 
  1206   if (s->hl == DRAW_NORMAL_TEXT)
  1207     {
  1208       s->xgcv.foreground = s->face->foreground;
  1209       s->xgcv.background = s->face->background;
  1210       s->stippled_p = s->face->stipple != 0;
  1211     }
  1212   else if (s->hl == DRAW_INVERSE_VIDEO)
  1213     {
  1214       pgtk_set_mode_line_face_gc (s);
  1215       s->stippled_p = s->face->stipple != 0;
  1216     }
  1217   else if (s->hl == DRAW_CURSOR)
  1218     {
  1219       pgtk_set_cursor_gc (s);
  1220       s->stippled_p = false;
  1221     }
  1222   else if (s->hl == DRAW_MOUSE_FACE)
  1223     {
  1224       pgtk_set_mouse_face_gc (s);
  1225       s->stippled_p = s->face->stipple != 0;
  1226     }
  1227   else if (s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
  1228     {
  1229       s->xgcv.foreground = s->face->foreground;
  1230       s->xgcv.background = s->face->background;
  1231       s->stippled_p = s->face->stipple != 0;
  1232     }
  1233   else
  1234     emacs_abort ();
  1235 }
  1236 
  1237 
  1238 /* Set clipping for output of glyph string S.  S may be part of a mode
  1239    line or menu if we don't have X toolkit support.  */
  1240 
  1241 static void
  1242 pgtk_set_glyph_string_clipping (struct glyph_string *s, cairo_t * cr)
  1243 {
  1244   XRectangle r[2];
  1245   int n = get_glyph_string_clip_rects (s, r, 2);
  1246 
  1247   if (n > 0)
  1248     {
  1249       for (int i = 0; i < n; i++)
  1250         {
  1251           cairo_rectangle (cr, r[i].x, r[i].y, r[i].width, r[i].height);
  1252         }
  1253       cairo_clip (cr);
  1254     }
  1255 }
  1256 
  1257 /* Set SRC's clipping for output of glyph string DST.  This is called
  1258    when we are drawing DST's left_overhang or right_overhang only in
  1259    the area of SRC.  */
  1260 
  1261 static void
  1262 pgtk_set_glyph_string_clipping_exactly (struct glyph_string *src,
  1263                                         struct glyph_string *dst, cairo_t * cr)
  1264 {
  1265   dst->clip[0].x = src->x;
  1266   dst->clip[0].y = src->y;
  1267   dst->clip[0].width = src->width;
  1268   dst->clip[0].height = src->height;
  1269   dst->num_clips = 1;
  1270 
  1271   cairo_rectangle (cr, src->x, src->y, src->width, src->height);
  1272   cairo_clip (cr);
  1273 }
  1274 
  1275 /* RIF:
  1276    Compute left and right overhang of glyph string S.  */
  1277 
  1278 static void
  1279 pgtk_compute_glyph_string_overhangs (struct glyph_string *s)
  1280 {
  1281   if (s->cmp == NULL
  1282       && (s->first_glyph->type == CHAR_GLYPH
  1283           || s->first_glyph->type == COMPOSITE_GLYPH))
  1284     {
  1285       struct font_metrics metrics;
  1286 
  1287       if (s->first_glyph->type == CHAR_GLYPH)
  1288         {
  1289           unsigned *code = alloca (sizeof (unsigned) * s->nchars);
  1290           struct font *font = s->font;
  1291           int i;
  1292 
  1293           for (i = 0; i < s->nchars; i++)
  1294             code[i] = s->char2b[i];
  1295           font->driver->text_extents (font, code, s->nchars, &metrics);
  1296         }
  1297       else
  1298         {
  1299           Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
  1300 
  1301           composition_gstring_width (gstring, s->cmp_from, s->cmp_to,
  1302                                      &metrics);
  1303         }
  1304       s->right_overhang = (metrics.rbearing > metrics.width
  1305                            ? metrics.rbearing - metrics.width : 0);
  1306       s->left_overhang = metrics.lbearing < 0 ? -metrics.lbearing : 0;
  1307     }
  1308   else if (s->cmp)
  1309     {
  1310       s->right_overhang = s->cmp->rbearing - s->cmp->pixel_width;
  1311       s->left_overhang = -s->cmp->lbearing;
  1312     }
  1313 }
  1314 
  1315 /* Fill rectangle X, Y, W, H with background color of glyph string
  1316    S.  */
  1317 static void
  1318 pgtk_clear_glyph_string_rect (struct glyph_string *s, int x, int y,
  1319                               int w, int h)
  1320 {
  1321   pgtk_fill_rectangle (s->f, s->xgcv.background, x, y, w, h,
  1322                        (s->first_glyph->type != STRETCH_GLYPH
  1323                         || s->hl != DRAW_CURSOR));
  1324 }
  1325 
  1326 static void
  1327 fill_background_by_face (struct frame *f, struct face *face, int x, int y,
  1328                          int width, int height)
  1329 {
  1330   cairo_t *cr = pgtk_begin_cr_clip (f);
  1331 
  1332   cairo_rectangle (cr, x, y, width, height);
  1333   cairo_clip (cr);
  1334 
  1335   double r = ((face->background >> 16) & 0xff) / 255.0;
  1336   double g = ((face->background >> 8) & 0xff) / 255.0;
  1337   double b = ((face->background >> 0) & 0xff) / 255.0;
  1338   cairo_set_source_rgb (cr, r, g, b);
  1339   cairo_paint (cr);
  1340 
  1341   if (face->stipple != 0)
  1342     {
  1343       cairo_pattern_t *mask
  1344         = FRAME_DISPLAY_INFO (f)->bitmaps[face->stipple - 1].pattern;
  1345 
  1346       double r = ((face->foreground >> 16) & 0xff) / 255.0;
  1347       double g = ((face->foreground >> 8) & 0xff) / 255.0;
  1348       double b = ((face->foreground >> 0) & 0xff) / 255.0;
  1349       cairo_set_source_rgb (cr, r, g, b);
  1350       cairo_mask (cr, mask);
  1351     }
  1352 
  1353   pgtk_end_cr_clip (f);
  1354 }
  1355 
  1356 static void
  1357 fill_background (struct glyph_string *s, int x, int y, int width, int height)
  1358 {
  1359   fill_background_by_face (s->f, s->face, x, y, width, height);
  1360 }
  1361 
  1362 /* Draw the background of glyph_string S.  If S->background_filled_p
  1363    is non-zero don't draw it.  FORCE_P non-zero means draw the
  1364    background even if it wouldn't be drawn normally.  This is used
  1365    when a string preceding S draws into the background of S, or S
  1366    contains the first component of a composition.  */
  1367 static void
  1368 pgtk_draw_glyph_string_background (struct glyph_string *s, bool force_p)
  1369 {
  1370   /* Nothing to do if background has already been drawn or if it
  1371      shouldn't be drawn in the first place.  */
  1372   if (!s->background_filled_p)
  1373     {
  1374       int box_line_width = max (s->face->box_horizontal_line_width, 0);
  1375 
  1376       if (s->stippled_p)
  1377         {
  1378           /* Fill background with a stipple pattern.  */
  1379           fill_background (s, s->x, s->y + box_line_width,
  1380                            s->background_width,
  1381                            s->height - 2 * box_line_width);
  1382           s->background_filled_p = true;
  1383         }
  1384       else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
  1385                /* When xdisp.c ignores FONT_HEIGHT, we cannot trust
  1386                   font dimensions, since the actual glyphs might be
  1387                   much smaller.  So in that case we always clear the
  1388                   rectangle with background color.  */
  1389                || FONT_TOO_HIGH (s->font)
  1390                || s->font_not_found_p
  1391                || s->extends_to_end_of_line_p || force_p)
  1392         {
  1393           pgtk_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
  1394                                         s->background_width,
  1395                                         s->height - 2 * box_line_width);
  1396           s->background_filled_p = true;
  1397         }
  1398     }
  1399 }
  1400 
  1401 
  1402 static void
  1403 pgtk_draw_rectangle (struct frame *f, unsigned long color, int x, int y,
  1404                      int width, int height, bool respect_alpha_background)
  1405 {
  1406   cairo_t *cr;
  1407 
  1408   cr = pgtk_begin_cr_clip (f);
  1409   pgtk_set_cr_source_with_color (f, color, respect_alpha_background);
  1410   cairo_rectangle (cr, x + 0.5, y + 0.5, width, height);
  1411   cairo_set_line_width (cr, 1);
  1412   cairo_stroke (cr);
  1413   pgtk_end_cr_clip (f);
  1414 }
  1415 
  1416 /* Draw the foreground of glyph string S.  */
  1417 static void
  1418 pgtk_draw_glyph_string_foreground (struct glyph_string *s)
  1419 {
  1420   int i, x;
  1421 
  1422   /* If first glyph of S has a left box line, start drawing the text
  1423      of S to the right of that box line.  */
  1424   if (s->face->box != FACE_NO_BOX && s->first_glyph->left_box_line_p)
  1425     x = s->x + max (s->face->box_vertical_line_width, 0);
  1426   else
  1427     x = s->x;
  1428 
  1429   /* Draw characters of S as rectangles if S's font could not be
  1430      loaded.  */
  1431   if (s->font_not_found_p)
  1432     {
  1433       for (i = 0; i < s->nchars; ++i)
  1434         {
  1435           struct glyph *g = s->first_glyph + i;
  1436           pgtk_draw_rectangle (s->f,
  1437                                s->face->foreground, x, s->y,
  1438                                g->pixel_width - 1, s->height - 1,
  1439                                false);
  1440           x += g->pixel_width;
  1441         }
  1442     }
  1443   else
  1444     {
  1445       struct font *font = s->font;
  1446       int boff = font->baseline_offset;
  1447       int y;
  1448 
  1449       if (font->vertical_centering)
  1450         boff = VCENTER_BASELINE_OFFSET (font, s->f) - boff;
  1451 
  1452       y = s->ybase - boff;
  1453       if (s->for_overlaps || (s->background_filled_p && s->hl != DRAW_CURSOR))
  1454         font->driver->draw (s, 0, s->nchars, x, y, false);
  1455       else
  1456         font->driver->draw (s, 0, s->nchars, x, y, true);
  1457       if (s->face->overstrike)
  1458         font->driver->draw (s, 0, s->nchars, x + 1, y, false);
  1459     }
  1460 }
  1461 
  1462 /* Draw the foreground of composite glyph string S.  */
  1463 static void
  1464 pgtk_draw_composite_glyph_string_foreground (struct glyph_string *s)
  1465 {
  1466   int i, j, x;
  1467   struct font *font = s->font;
  1468 
  1469   /* If first glyph of S has a left box line, start drawing the text
  1470      of S to the right of that box line.  */
  1471   if (s->face && s->face->box != FACE_NO_BOX
  1472       && s->first_glyph->left_box_line_p)
  1473     x = s->x + max (s->face->box_vertical_line_width, 0);
  1474   else
  1475     x = s->x;
  1476 
  1477   /* S is a glyph string for a composition.  S->cmp_from is the index
  1478      of the first character drawn for glyphs of this composition.
  1479      S->cmp_from == 0 means we are drawing the very first character of
  1480      this composition.  */
  1481 
  1482   /* Draw a rectangle for the composition if the font for the very
  1483      first character of the composition could not be loaded.  */
  1484   if (s->font_not_found_p)
  1485     {
  1486       if (s->cmp_from == 0)
  1487         pgtk_draw_rectangle (s->f, s->face->foreground, x, s->y,
  1488                              s->width - 1, s->height - 1, false);
  1489     }
  1490   else if (!s->first_glyph->u.cmp.automatic)
  1491     {
  1492       int y = s->ybase;
  1493 
  1494       for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++)
  1495         /* TAB in a composition means display glyphs with padding
  1496            space on the left or right.  */
  1497         if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
  1498           {
  1499             int xx = x + s->cmp->offsets[j * 2];
  1500             int yy = y - s->cmp->offsets[j * 2 + 1];
  1501 
  1502             font->driver->draw (s, j, j + 1, xx, yy, false);
  1503             if (s->face->overstrike)
  1504               font->driver->draw (s, j, j + 1, xx + 1, yy, false);
  1505           }
  1506     }
  1507   else
  1508     {
  1509       Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
  1510       Lisp_Object glyph;
  1511       int y = s->ybase;
  1512       int width = 0;
  1513 
  1514       for (i = j = s->cmp_from; i < s->cmp_to; i++)
  1515         {
  1516           glyph = LGSTRING_GLYPH (gstring, i);
  1517           if (NILP (LGLYPH_ADJUSTMENT (glyph)))
  1518             width += LGLYPH_WIDTH (glyph);
  1519           else
  1520             {
  1521               int xoff, yoff, wadjust;
  1522 
  1523               if (j < i)
  1524                 {
  1525                   font->driver->draw (s, j, i, x, y, false);
  1526                   if (s->face->overstrike)
  1527                     font->driver->draw (s, j, i, x + 1, y, false);
  1528                   x += width;
  1529                 }
  1530               xoff = LGLYPH_XOFF (glyph);
  1531               yoff = LGLYPH_YOFF (glyph);
  1532               wadjust = LGLYPH_WADJUST (glyph);
  1533               font->driver->draw (s, i, i + 1, x + xoff, y + yoff, false);
  1534               if (s->face->overstrike)
  1535                 font->driver->draw (s, i, i + 1, x + xoff + 1, y + yoff,
  1536                                     false);
  1537               x += wadjust;
  1538               j = i + 1;
  1539               width = 0;
  1540             }
  1541         }
  1542       if (j < i)
  1543         {
  1544           font->driver->draw (s, j, i, x, y, false);
  1545           if (s->face->overstrike)
  1546             font->driver->draw (s, j, i, x + 1, y, false);
  1547         }
  1548     }
  1549 }
  1550 
  1551 
  1552 /* Draw the foreground of glyph string S for glyphless characters.  */
  1553 static void
  1554 pgtk_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
  1555 {
  1556   struct glyph *glyph = s->first_glyph;
  1557   unsigned char2b[8];
  1558   int x, i, j;
  1559 
  1560   /* If first glyph of S has a left box line, start drawing the text
  1561      of S to the right of that box line.  */
  1562   if (s->face && s->face->box != FACE_NO_BOX
  1563       && s->first_glyph->left_box_line_p)
  1564     x = s->x + max (s->face->box_vertical_line_width, 0);
  1565   else
  1566     x = s->x;
  1567 
  1568   s->char2b = char2b;
  1569 
  1570   for (i = 0; i < s->nchars; i++, glyph++)
  1571     {
  1572 #ifdef GCC_LINT
  1573       enum
  1574       { PACIFY_GCC_BUG_81401 = 1 };
  1575 #else
  1576       enum
  1577       { PACIFY_GCC_BUG_81401 = 0 };
  1578 #endif
  1579       char buf[7 + PACIFY_GCC_BUG_81401];
  1580       char *str = NULL;
  1581       int len = glyph->u.glyphless.len;
  1582 
  1583       if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM)
  1584         {
  1585           if (len > 0
  1586               && CHAR_TABLE_P (Vglyphless_char_display)
  1587               &&
  1588               (CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display))
  1589                >= 1))
  1590             {
  1591               Lisp_Object acronym
  1592                 = (!glyph->u.glyphless.for_no_font
  1593                    ? CHAR_TABLE_REF (Vglyphless_char_display,
  1594                                      glyph->u.glyphless.ch)
  1595                    : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
  1596               if (CONSP (acronym))
  1597                 acronym = XCAR (acronym);
  1598               if (STRINGP (acronym))
  1599                 str = SSDATA (acronym);
  1600             }
  1601         }
  1602       else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE)
  1603         {
  1604           unsigned int ch = glyph->u.glyphless.ch;
  1605           eassume (ch <= MAX_CHAR);
  1606           sprintf (buf, "%0*X", ch < 0x10000 ? 4 : 6, ch);
  1607           str = buf;
  1608         }
  1609 
  1610       if (str)
  1611         {
  1612           int upper_len = (len + 1) / 2;
  1613 
  1614           /* It is assured that all LEN characters in STR is ASCII.  */
  1615           for (j = 0; j < len; j++)
  1616             char2b[j]
  1617               = s->font->driver->encode_char (s->font, str[j]) & 0xFFFF;
  1618           s->font->driver->draw (s, 0, upper_len,
  1619                                  x + glyph->slice.glyphless.upper_xoff,
  1620                                  s->ybase + glyph->slice.glyphless.upper_yoff,
  1621                                  false);
  1622           s->font->driver->draw (s, upper_len, len,
  1623                                  x + glyph->slice.glyphless.lower_xoff,
  1624                                  s->ybase + glyph->slice.glyphless.lower_yoff,
  1625                                  false);
  1626         }
  1627       if (glyph->u.glyphless.method != GLYPHLESS_DISPLAY_THIN_SPACE)
  1628         pgtk_draw_rectangle (s->f, s->face->foreground,
  1629                              x, s->ybase - glyph->ascent,
  1630                              glyph->pixel_width - 1,
  1631                              glyph->ascent + glyph->descent - 1,
  1632                              false);
  1633       x += glyph->pixel_width;
  1634     }
  1635 
  1636   /* Pacify GCC 12 even though s->char2b is not used after this
  1637      function returns.  */
  1638   s->char2b = NULL;
  1639 }
  1640 
  1641 /* Brightness beyond which a color won't have its highlight brightness
  1642    boosted.
  1643 
  1644    Nominally, highlight colors for `3d' faces are calculated by
  1645    brightening an object's color by a constant scale factor, but this
  1646    doesn't yield good results for dark colors, so for colors who's
  1647    brightness is less than this value (on a scale of 0-65535) have an
  1648    use an additional additive factor.
  1649 
  1650    The value here is set so that the default menu-bar/mode-line color
  1651    (grey75) will not have its highlights changed at all.  */
  1652 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 48000
  1653 
  1654 
  1655 /* Compute a color which is lighter or darker than *PIXEL by FACTOR or
  1656    DELTA.  Try a color with RGB values multiplied by FACTOR first.  If
  1657    this produces the same color as PIXEL, try a color where all RGB
  1658    values have DELTA added.  Return the computed color in *PIXEL.  F
  1659    is the frame to act on.  */
  1660 
  1661 static void
  1662 pgtk_compute_lighter_color (struct frame *f, unsigned long *pixel,
  1663                             double factor, int delta)
  1664 {
  1665   Emacs_Color color, new;
  1666   long bright;
  1667 
  1668   /* Get RGB color values.  */
  1669   color.pixel = *pixel;
  1670   pgtk_query_color (f, &color);
  1671 
  1672   /* Change RGB values by specified FACTOR.  Avoid overflow!  */
  1673   eassert (factor >= 0);
  1674   new.red = min (0xffff, factor * color.red);
  1675   new.green = min (0xffff, factor * color.green);
  1676   new.blue = min (0xffff, factor * color.blue);
  1677 
  1678   /* Calculate brightness of COLOR.  */
  1679   bright = (2 * color.red + 3 * color.green + color.blue) / 6;
  1680 
  1681   /* We only boost colors that are darker than
  1682      HIGHLIGHT_COLOR_DARK_BOOST_LIMIT.  */
  1683   if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
  1684     /* Make an additive adjustment to NEW, because it's dark enough so
  1685        that scaling by FACTOR alone isn't enough.  */
  1686     {
  1687       /* How far below the limit this color is (0 - 1, 1 being darker).  */
  1688       double dimness = 1 - (double) bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
  1689       /* The additive adjustment.  */
  1690       int min_delta = delta * dimness * factor / 2;
  1691 
  1692       if (factor < 1)
  1693         {
  1694           new.red = max (0, new.red - min_delta);
  1695           new.green = max (0, new.green - min_delta);
  1696           new.blue = max (0, new.blue - min_delta);
  1697         }
  1698       else
  1699         {
  1700           new.red = min (0xffff, min_delta + new.red);
  1701           new.green = min (0xffff, min_delta + new.green);
  1702           new.blue = min (0xffff, min_delta + new.blue);
  1703         }
  1704     }
  1705 
  1706   new.pixel = (new.red >> 8 << 16
  1707                | new.green >> 8 << 8
  1708                | new.blue >> 8);
  1709 
  1710   if (new.pixel == *pixel)
  1711     {
  1712       /* If we end up with the same color as before, try adding
  1713          delta to the RGB values.  */
  1714       new.red = min (0xffff, delta + color.red);
  1715       new.green = min (0xffff, delta + color.green);
  1716       new.blue = min (0xffff, delta + color.blue);
  1717       new.pixel = (new.red >> 8 << 16
  1718                    | new.green >> 8 << 8
  1719                    | new.blue >> 8);
  1720     }
  1721 
  1722   *pixel = new.pixel;
  1723 }
  1724 
  1725 static void
  1726 pgtk_fill_trapezoid_for_relief (struct frame *f, unsigned long color, int x,
  1727                                 int y, int width, int height, int top_p)
  1728 {
  1729   cairo_t *cr;
  1730 
  1731   cr = pgtk_begin_cr_clip (f);
  1732   pgtk_set_cr_source_with_color (f, color, false);
  1733   cairo_move_to (cr, top_p ? x : x + height, y);
  1734   cairo_line_to (cr, x, y + height);
  1735   cairo_line_to (cr, top_p ? x + width - height : x + width, y + height);
  1736   cairo_line_to (cr, x + width, y);
  1737   cairo_fill (cr);
  1738   pgtk_end_cr_clip (f);
  1739 }
  1740 
  1741 enum corners
  1742 {
  1743   CORNER_BOTTOM_RIGHT,          /* 0 -> pi/2 */
  1744   CORNER_BOTTOM_LEFT,           /* pi/2 -> pi */
  1745   CORNER_TOP_LEFT,              /* pi -> 3pi/2 */
  1746   CORNER_TOP_RIGHT,             /* 3pi/2 -> 2pi */
  1747   CORNER_LAST
  1748 };
  1749 
  1750 static void
  1751 pgtk_erase_corners_for_relief (struct frame *f, unsigned long color, int x,
  1752                                int y, int width, int height, double radius,
  1753                                double margin, int corners)
  1754 {
  1755   cairo_t *cr;
  1756   int i;
  1757 
  1758   cr = pgtk_begin_cr_clip (f);
  1759   pgtk_set_cr_source_with_color (f, color, false);
  1760   for (i = 0; i < CORNER_LAST; i++)
  1761     if (corners & (1 << i))
  1762       {
  1763         double xm, ym, xc, yc;
  1764 
  1765         if (i == CORNER_TOP_LEFT || i == CORNER_BOTTOM_LEFT)
  1766           xm = x - margin, xc = xm + radius;
  1767         else
  1768           xm = x + width + margin, xc = xm - radius;
  1769         if (i == CORNER_TOP_LEFT || i == CORNER_TOP_RIGHT)
  1770           ym = y - margin, yc = ym + radius;
  1771         else
  1772           ym = y + height + margin, yc = ym - radius;
  1773 
  1774         cairo_move_to (cr, xm, ym);
  1775         cairo_arc (cr, xc, yc, radius, i * M_PI_2, (i + 1) * M_PI_2);
  1776       }
  1777   cairo_clip (cr);
  1778   cairo_rectangle (cr, x, y, width, height);
  1779   cairo_fill (cr);
  1780   pgtk_end_cr_clip (f);
  1781 }
  1782 
  1783 static void
  1784 pgtk_setup_relief_color (struct frame *f, struct relief *relief, double factor,
  1785                          int delta, unsigned long default_pixel)
  1786 {
  1787   Emacs_GC xgcv;
  1788   struct pgtk_output *di = FRAME_X_OUTPUT (f);
  1789   unsigned long pixel;
  1790   unsigned long background = di->relief_background;
  1791 
  1792   /* Allocate new color.  */
  1793   xgcv.foreground = default_pixel;
  1794   pixel = background;
  1795   pgtk_compute_lighter_color (f, &pixel, factor, delta);
  1796   xgcv.foreground = relief->pixel = pixel;
  1797 
  1798   relief->xgcv = xgcv;
  1799 }
  1800 
  1801 /* Set up colors for the relief lines around glyph string S.  */
  1802 static void
  1803 pgtk_setup_relief_colors (struct glyph_string *s)
  1804 {
  1805   struct pgtk_output *di = FRAME_X_OUTPUT (s->f);
  1806   unsigned long color;
  1807 
  1808   if (s->face->use_box_color_for_shadows_p)
  1809     color = s->face->box_color;
  1810   else if (s->first_glyph->type == IMAGE_GLYPH
  1811            && s->img->pixmap
  1812            && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
  1813     color = IMAGE_BACKGROUND (s->img, s->f, 0);
  1814   else
  1815     {
  1816       /* Get the background color of the face.  */
  1817       color = s->xgcv.background;
  1818     }
  1819 
  1820   if (!di->relief_background_valid_p
  1821       || di->relief_background != color)
  1822     {
  1823       di->relief_background_valid_p = true;
  1824       di->relief_background = color;
  1825       pgtk_setup_relief_color (s->f, &di->white_relief, 1.2, 0x8000,
  1826                                WHITE_PIX_DEFAULT (s->f));
  1827       pgtk_setup_relief_color (s->f, &di->black_relief, 0.6, 0x4000,
  1828                                BLACK_PIX_DEFAULT (s->f));
  1829     }
  1830 }
  1831 
  1832 static void
  1833 pgtk_set_clip_rectangles (struct frame *f, cairo_t *cr,
  1834                           XRectangle *rectangles, int n)
  1835 {
  1836   if (n > 0)
  1837     {
  1838       for (int i = 0; i < n; i++)
  1839         cairo_rectangle (cr, rectangles[i].x, rectangles[i].y,
  1840                          rectangles[i].width, rectangles[i].height);
  1841       cairo_clip (cr);
  1842     }
  1843 }
  1844 
  1845 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
  1846    TOP_Y, RIGHT_X, and BOTTOM_Y.  WIDTH is the thickness of the relief
  1847    to draw, it must be >= 0.  RAISED_P means draw a raised
  1848    relief.  LEFT_P means draw a relief on the left side of
  1849    the rectangle.  RIGHT_P means draw a relief on the right
  1850    side of the rectangle.  CLIP_RECT is the clipping rectangle to use
  1851    when drawing.  */
  1852 
  1853 static void
  1854 pgtk_draw_relief_rect (struct frame *f,
  1855                        int left_x, int top_y, int right_x, int bottom_y,
  1856                        int hwidth, int vwidth, bool raised_p, bool top_p,
  1857                        bool bot_p, bool left_p, bool right_p,
  1858                        XRectangle *clip_rect)
  1859 {
  1860   unsigned long top_left_color, bottom_right_color;
  1861   int corners = 0;
  1862 
  1863   cairo_t *cr = pgtk_begin_cr_clip (f);
  1864 
  1865   if (raised_p)
  1866     {
  1867       top_left_color = FRAME_X_OUTPUT (f)->white_relief.xgcv.foreground;
  1868       bottom_right_color = FRAME_X_OUTPUT (f)->black_relief.xgcv.foreground;
  1869     }
  1870   else
  1871     {
  1872       top_left_color = FRAME_X_OUTPUT (f)->black_relief.xgcv.foreground;
  1873       bottom_right_color = FRAME_X_OUTPUT (f)->white_relief.xgcv.foreground;
  1874     }
  1875 
  1876   pgtk_set_clip_rectangles (f, cr, clip_rect, 1);
  1877 
  1878   if (left_p)
  1879     {
  1880       pgtk_fill_rectangle (f, top_left_color, left_x, top_y,
  1881                            vwidth, bottom_y + 1 - top_y, false);
  1882       if (top_p)
  1883         corners |= 1 << CORNER_TOP_LEFT;
  1884       if (bot_p)
  1885         corners |= 1 << CORNER_BOTTOM_LEFT;
  1886     }
  1887   if (right_p)
  1888     {
  1889       pgtk_fill_rectangle (f, bottom_right_color, right_x + 1 - vwidth, top_y,
  1890                            vwidth, bottom_y + 1 - top_y, false);
  1891       if (top_p)
  1892         corners |= 1 << CORNER_TOP_RIGHT;
  1893       if (bot_p)
  1894         corners |= 1 << CORNER_BOTTOM_RIGHT;
  1895     }
  1896   if (top_p)
  1897     {
  1898       if (!right_p)
  1899         pgtk_fill_rectangle (f, top_left_color, left_x, top_y,
  1900                              right_x + 1 - left_x, hwidth, false);
  1901       else
  1902         pgtk_fill_trapezoid_for_relief (f, top_left_color, left_x, top_y,
  1903                                         right_x + 1 - left_x, hwidth, 1);
  1904     }
  1905   if (bot_p)
  1906     {
  1907       if (!left_p)
  1908         pgtk_fill_rectangle (f, bottom_right_color, left_x,
  1909                              bottom_y + 1 - hwidth, right_x + 1 - left_x,
  1910                              hwidth, false);
  1911       else
  1912         pgtk_fill_trapezoid_for_relief (f, bottom_right_color,
  1913                                         left_x, bottom_y + 1 - hwidth,
  1914                                         right_x + 1 - left_x, hwidth, 0);
  1915     }
  1916   if (left_p && vwidth > 1)
  1917     pgtk_fill_rectangle (f, bottom_right_color, left_x, top_y,
  1918                          1, bottom_y + 1 - top_y, false);
  1919   if (top_p && hwidth > 1)
  1920     pgtk_fill_rectangle (f, bottom_right_color, left_x, top_y,
  1921                          right_x + 1 - left_x, 1, false);
  1922   if (corners)
  1923     pgtk_erase_corners_for_relief (f, FRAME_BACKGROUND_PIXEL (f), left_x,
  1924                                    top_y, right_x - left_x + 1,
  1925                                    bottom_y - top_y + 1, 6, 1, corners);
  1926 
  1927   pgtk_end_cr_clip (f);
  1928 }
  1929 
  1930 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
  1931    RIGHT_X, and BOTTOM_Y.  WIDTH is the thickness of the lines to
  1932    draw, it must be >= 0.  LEFT_P means draw a line on the
  1933    left side of the rectangle.  RIGHT_P means draw a line
  1934    on the right side of the rectangle.  CLIP_RECT is the clipping
  1935    rectangle to use when drawing.  */
  1936 
  1937 static void
  1938 pgtk_draw_box_rect (struct glyph_string *s, int left_x,
  1939                     int top_y, int right_x, int bottom_y, int hwidth,
  1940                     int vwidth, bool left_p, bool right_p,
  1941                     XRectangle * clip_rect)
  1942 {
  1943   unsigned long foreground_backup;
  1944 
  1945   cairo_t *cr = pgtk_begin_cr_clip (s->f);
  1946 
  1947   foreground_backup = s->xgcv.foreground;
  1948   s->xgcv.foreground = s->face->box_color;
  1949 
  1950   pgtk_set_clip_rectangles (s->f, cr, clip_rect, 1);
  1951 
  1952   /* Top.  */
  1953   pgtk_fill_rectangle (s->f, s->xgcv.foreground,
  1954                        left_x, top_y, right_x - left_x + 1, hwidth,
  1955                        false);
  1956 
  1957   /* Left.  */
  1958   if (left_p)
  1959     pgtk_fill_rectangle (s->f, s->xgcv.foreground,
  1960                          left_x, top_y, vwidth, bottom_y - top_y + 1,
  1961                          false);
  1962 
  1963   /* Bottom.  */
  1964   pgtk_fill_rectangle (s->f, s->xgcv.foreground,
  1965                        left_x, bottom_y - hwidth + 1, right_x - left_x + 1,
  1966                        hwidth, false);
  1967 
  1968   /* Right.  */
  1969   if (right_p)
  1970     pgtk_fill_rectangle (s->f, s->xgcv.foreground,
  1971                          right_x - vwidth + 1, top_y, vwidth,
  1972                          bottom_y - top_y + 1, false);
  1973 
  1974   s->xgcv.foreground = foreground_backup;
  1975 
  1976   pgtk_end_cr_clip (s->f);
  1977 }
  1978 
  1979 
  1980 /* Draw a box around glyph string S.  */
  1981 
  1982 static void
  1983 pgtk_draw_glyph_string_box (struct glyph_string *s)
  1984 {
  1985   int hwidth, vwidth, left_x, right_x, top_y, bottom_y, last_x;
  1986   bool raised_p, left_p, right_p;
  1987   struct glyph *last_glyph;
  1988   XRectangle clip_rect;
  1989 
  1990   last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
  1991             ? WINDOW_RIGHT_EDGE_X (s->w) : window_box_right (s->w, s->area));
  1992 
  1993   /* The glyph that may have a right box line.  */
  1994   last_glyph = (s->cmp || s->img
  1995                 ? s->first_glyph : s->first_glyph + s->nchars - 1);
  1996 
  1997   vwidth = eabs (s->face->box_vertical_line_width);
  1998   hwidth = eabs (s->face->box_horizontal_line_width);
  1999   raised_p = s->face->box == FACE_RAISED_BOX;
  2000   left_x = s->x;
  2001   right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
  2002              ? last_x - 1 : min (last_x, s->x + s->background_width) - 1);
  2003   top_y = s->y;
  2004   bottom_y = top_y + s->height - 1;
  2005 
  2006   left_p = (s->first_glyph->left_box_line_p
  2007             || (s->hl == DRAW_MOUSE_FACE
  2008                 && (s->prev == NULL || s->prev->hl != s->hl)));
  2009   right_p = (last_glyph->right_box_line_p
  2010              || (s->hl == DRAW_MOUSE_FACE
  2011                  && (s->next == NULL || s->next->hl != s->hl)));
  2012 
  2013   get_glyph_string_clip_rect (s, &clip_rect);
  2014 
  2015   if (s->face->box == FACE_SIMPLE_BOX)
  2016     pgtk_draw_box_rect (s, left_x, top_y, right_x, bottom_y, hwidth,
  2017                         vwidth, left_p, right_p, &clip_rect);
  2018   else
  2019     {
  2020       pgtk_setup_relief_colors (s);
  2021       pgtk_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y, hwidth,
  2022                              vwidth, raised_p, true, true, left_p, right_p,
  2023                              &clip_rect);
  2024     }
  2025 }
  2026 
  2027 static void
  2028 pgtk_draw_horizontal_wave (struct frame *f, unsigned long color, int x, int y,
  2029                            int width, int height, int wave_length)
  2030 {
  2031   cairo_t *cr;
  2032   double dx = wave_length, dy = height - 1;
  2033   int xoffset, n;
  2034 
  2035   cr = pgtk_begin_cr_clip (f);
  2036   pgtk_set_cr_source_with_color (f, color, false);
  2037   cairo_rectangle (cr, x, y, width, height);
  2038   cairo_clip (cr);
  2039 
  2040   if (x >= 0)
  2041     {
  2042       xoffset = x % (wave_length * 2);
  2043       if (xoffset == 0)
  2044         xoffset = wave_length * 2;
  2045     }
  2046   else
  2047     xoffset = x % (wave_length * 2) + wave_length * 2;
  2048   n = (width + xoffset) / wave_length + 1;
  2049   if (xoffset > wave_length)
  2050     {
  2051       xoffset -= wave_length;
  2052       --n;
  2053       y += height - 1;
  2054       dy = -dy;
  2055     }
  2056 
  2057   cairo_move_to (cr, x - xoffset + 0.5, y + 0.5);
  2058   while (--n >= 0)
  2059     {
  2060       cairo_rel_line_to (cr, dx, dy);
  2061       dy = -dy;
  2062     }
  2063   cairo_set_line_width (cr, 1);
  2064   cairo_stroke (cr);
  2065   pgtk_end_cr_clip (f);
  2066 }
  2067 
  2068 static void
  2069 pgtk_draw_underwave (struct glyph_string *s, unsigned long color)
  2070 {
  2071   int wave_height = 3, wave_length = 2;
  2072 
  2073   pgtk_draw_horizontal_wave (s->f, color, s->x, s->ybase - wave_height + 3,
  2074                              s->width, wave_height, wave_length);
  2075 }
  2076 
  2077 /* Draw a relief around the image glyph string S.  */
  2078 
  2079 static void
  2080 pgtk_draw_image_relief (struct glyph_string *s)
  2081 {
  2082   int x1, y1, thick;
  2083   bool raised_p, top_p, bot_p, left_p, right_p;
  2084   int extra_x, extra_y;
  2085   XRectangle r;
  2086   int x = s->x;
  2087   int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
  2088 
  2089   /* If first glyph of S has a left box line, start drawing it to the
  2090      right of that line.  */
  2091   if (s->face->box != FACE_NO_BOX
  2092       && s->first_glyph->left_box_line_p
  2093       && s->slice.x == 0)
  2094     x += max (s->face->box_vertical_line_width, 0);
  2095 
  2096   /* If there is a margin around the image, adjust x- and y-position
  2097      by that margin.  */
  2098   if (s->slice.x == 0)
  2099     x += s->img->hmargin;
  2100   if (s->slice.y == 0)
  2101     y += s->img->vmargin;
  2102 
  2103   if (s->hl == DRAW_IMAGE_SUNKEN
  2104       || s->hl == DRAW_IMAGE_RAISED)
  2105     {
  2106       if (s->face->id == TAB_BAR_FACE_ID)
  2107         thick = (tab_bar_button_relief < 0
  2108                  ? DEFAULT_TAB_BAR_BUTTON_RELIEF
  2109                  : min (tab_bar_button_relief, 1000000));
  2110       else
  2111         thick = (tool_bar_button_relief < 0
  2112                  ? DEFAULT_TOOL_BAR_BUTTON_RELIEF
  2113                  : min (tool_bar_button_relief, 1000000));
  2114       raised_p = s->hl == DRAW_IMAGE_RAISED;
  2115     }
  2116   else
  2117     {
  2118       thick = eabs (s->img->relief);
  2119       raised_p = s->img->relief > 0;
  2120     }
  2121 
  2122   x1 = x + s->slice.width - 1;
  2123   y1 = y + s->slice.height - 1;
  2124 
  2125   extra_x = extra_y = 0;
  2126   if (s->face->id == TAB_BAR_FACE_ID)
  2127     {
  2128       if (CONSP (Vtab_bar_button_margin)
  2129           && FIXNUMP (XCAR (Vtab_bar_button_margin))
  2130           && FIXNUMP (XCDR (Vtab_bar_button_margin)))
  2131         {
  2132           extra_x = XFIXNUM (XCAR (Vtab_bar_button_margin)) - thick;
  2133           extra_y = XFIXNUM (XCDR (Vtab_bar_button_margin)) - thick;
  2134         }
  2135       else if (FIXNUMP (Vtab_bar_button_margin))
  2136         extra_x = extra_y = XFIXNUM (Vtab_bar_button_margin) - thick;
  2137     }
  2138 
  2139   if (s->face->id == TOOL_BAR_FACE_ID)
  2140     {
  2141       if (CONSP (Vtool_bar_button_margin)
  2142           && FIXNUMP (XCAR (Vtool_bar_button_margin))
  2143           && FIXNUMP (XCDR (Vtool_bar_button_margin)))
  2144         {
  2145           extra_x = XFIXNUM (XCAR (Vtool_bar_button_margin));
  2146           extra_y = XFIXNUM (XCDR (Vtool_bar_button_margin));
  2147         }
  2148       else if (FIXNUMP (Vtool_bar_button_margin))
  2149         extra_x = extra_y = XFIXNUM (Vtool_bar_button_margin);
  2150     }
  2151 
  2152   top_p = bot_p = left_p = right_p = false;
  2153 
  2154   if (s->slice.x == 0)
  2155     x -= thick + extra_x, left_p = true;
  2156   if (s->slice.y == 0)
  2157     y -= thick + extra_y, top_p = true;
  2158   if (s->slice.x + s->slice.width == s->img->width)
  2159     x1 += thick + extra_x, right_p = true;
  2160   if (s->slice.y + s->slice.height == s->img->height)
  2161     y1 += thick + extra_y, bot_p = true;
  2162 
  2163   pgtk_setup_relief_colors (s);
  2164   get_glyph_string_clip_rect (s, &r);
  2165   pgtk_draw_relief_rect (s->f, x, y, x1, y1, thick, thick, raised_p,
  2166                          top_p, bot_p, left_p, right_p, &r);
  2167 }
  2168 
  2169 /* Draw part of the background of glyph string S.  X, Y, W, and H
  2170    give the rectangle to draw.  */
  2171 
  2172 static void
  2173 pgtk_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w,
  2174                                 int h)
  2175 {
  2176   if (s->stippled_p)
  2177     fill_background (s, x, y, w, h);
  2178   else
  2179     pgtk_clear_glyph_string_rect (s, x, y, w, h);
  2180 }
  2181 
  2182 static void
  2183 pgtk_cr_draw_image (struct frame *f, Emacs_GC *gc, cairo_pattern_t *image,
  2184                     int src_x, int src_y, int width, int height,
  2185                     int dest_x, int dest_y, bool overlay_p)
  2186 {
  2187   cairo_t *cr = pgtk_begin_cr_clip (f);
  2188 
  2189   if (overlay_p)
  2190     cairo_rectangle (cr, dest_x, dest_y, width, height);
  2191   else
  2192     {
  2193       pgtk_set_cr_source_with_gc_background (f, gc, false);
  2194       cairo_rectangle (cr, dest_x, dest_y, width, height);
  2195       cairo_fill_preserve (cr);
  2196     }
  2197 
  2198   cairo_translate (cr, dest_x - src_x, dest_y - src_y);
  2199 
  2200   cairo_surface_t *surface;
  2201   cairo_pattern_get_surface (image, &surface);
  2202   cairo_format_t format = cairo_image_surface_get_format (surface);
  2203   if (format != CAIRO_FORMAT_A8 && format != CAIRO_FORMAT_A1)
  2204     {
  2205       cairo_set_source (cr, image);
  2206       cairo_fill (cr);
  2207     }
  2208   else
  2209     {
  2210       pgtk_set_cr_source_with_gc_foreground (f, gc, false);
  2211       cairo_clip (cr);
  2212       cairo_mask (cr, image);
  2213     }
  2214 
  2215   pgtk_end_cr_clip (f);
  2216 }
  2217 
  2218 /* Draw foreground of image glyph string S.  */
  2219 
  2220 static void
  2221 pgtk_draw_image_foreground (struct glyph_string *s)
  2222 {
  2223   int x = s->x;
  2224   int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
  2225 
  2226   /* If first glyph of S has a left box line, start drawing it to the
  2227      right of that line.  */
  2228   if (s->face->box != FACE_NO_BOX
  2229       && s->first_glyph->left_box_line_p
  2230       && s->slice.x == 0)
  2231     x += max (s->face->box_vertical_line_width, 0);
  2232 
  2233   /* If there is a margin around the image, adjust x- and y-position
  2234      by that margin.  */
  2235   if (s->slice.x == 0)
  2236     x += s->img->hmargin;
  2237   if (s->slice.y == 0)
  2238     y += s->img->vmargin;
  2239 
  2240   if (s->img->cr_data)
  2241     {
  2242       cairo_t *cr = pgtk_begin_cr_clip (s->f);
  2243       pgtk_set_glyph_string_clipping (s, cr);
  2244       pgtk_cr_draw_image (s->f, &s->xgcv, s->img->cr_data,
  2245                           s->slice.x, s->slice.y, s->slice.width, s->slice.height,
  2246                           x, y, true);
  2247       if (!s->img->mask)
  2248         {
  2249           /* When the image has a mask, we can expect that at
  2250              least part of a mouse highlight or a block cursor will
  2251              be visible.  If the image doesn't have a mask, make
  2252              a block cursor visible by drawing a rectangle around
  2253              the image.  I believe it's looking better if we do
  2254              nothing here for mouse-face.  */
  2255           if (s->hl == DRAW_CURSOR)
  2256             {
  2257               int relief = eabs (s->img->relief);
  2258               pgtk_draw_rectangle (s->f, s->xgcv.foreground, x - relief,
  2259                                    y - relief, s->slice.width + relief * 2 - 1,
  2260                                    s->slice.height + relief * 2 - 1, false);
  2261             }
  2262         }
  2263       pgtk_end_cr_clip (s->f);
  2264     }
  2265   else
  2266     /* Draw a rectangle if image could not be loaded.  */
  2267     pgtk_draw_rectangle (s->f, s->xgcv.foreground, x, y,
  2268                          s->slice.width - 1, s->slice.height - 1, false);
  2269 }
  2270 
  2271 /* Draw image glyph string S.
  2272 
  2273             s->y
  2274    s->x      +-------------------------
  2275              |   s->face->box
  2276              |
  2277              |     +-------------------------
  2278              |     |  s->img->margin
  2279              |     |
  2280              |     |       +-------------------
  2281              |     |       |  the image
  2282 
  2283  */
  2284 
  2285 static void
  2286 pgtk_draw_image_glyph_string (struct glyph_string *s)
  2287 {
  2288   int box_line_hwidth = max (s->face->box_vertical_line_width, 0);
  2289   int box_line_vwidth = max (s->face->box_horizontal_line_width, 0);
  2290   int height;
  2291 
  2292   height = s->height;
  2293   if (s->slice.y == 0)
  2294     height -= box_line_vwidth;
  2295   if (s->slice.y + s->slice.height >= s->img->height)
  2296     height -= box_line_vwidth;
  2297 
  2298   /* Fill background with face under the image.  Do it only if row is
  2299      taller than image or if image has a clip mask to reduce
  2300      flickering.  */
  2301   s->stippled_p = s->face->stipple != 0;
  2302   if (height > s->slice.height
  2303       || s->img->hmargin
  2304       || s->img->vmargin
  2305       || s->img->mask
  2306       || s->img->pixmap == 0
  2307       || s->width != s->background_width)
  2308     {
  2309       int x = s->x;
  2310       int y = s->y;
  2311       int width = s->background_width;
  2312 
  2313       if (s->first_glyph->left_box_line_p
  2314           && s->slice.x == 0)
  2315         {
  2316           x += box_line_hwidth;
  2317           width -= box_line_hwidth;
  2318         }
  2319 
  2320       if (s->slice.y == 0)
  2321         y += box_line_vwidth;
  2322 
  2323       pgtk_draw_glyph_string_bg_rect (s, x, y, width, height);
  2324 
  2325       s->background_filled_p = true;
  2326     }
  2327 
  2328   /* Draw the foreground.  */
  2329   pgtk_draw_image_foreground (s);
  2330 
  2331   /* If we must draw a relief around the image, do it.  */
  2332   if (s->img->relief
  2333       || s->hl == DRAW_IMAGE_RAISED
  2334       || s->hl == DRAW_IMAGE_SUNKEN)
  2335     pgtk_draw_image_relief (s);
  2336 }
  2337 
  2338 /* Draw stretch glyph string S.  */
  2339 
  2340 static void
  2341 pgtk_draw_stretch_glyph_string (struct glyph_string *s)
  2342 {
  2343   eassert (s->first_glyph->type == STRETCH_GLYPH);
  2344 
  2345   if (s->hl == DRAW_CURSOR && !x_stretch_cursor_p)
  2346     {
  2347       /* If `x-stretch-cursor' is nil, don't draw a block cursor as
  2348          wide as the stretch glyph.  */
  2349       int width, background_width = s->background_width;
  2350       int x = s->x;
  2351 
  2352       if (!s->row->reversed_p)
  2353         {
  2354           int left_x = window_box_left_offset (s->w, TEXT_AREA);
  2355 
  2356           if (x < left_x)
  2357             {
  2358               background_width -= left_x - x;
  2359               x = left_x;
  2360             }
  2361         }
  2362       else
  2363         {
  2364           /* In R2L rows, draw the cursor on the right edge of the
  2365              stretch glyph.  */
  2366           int right_x = window_box_right (s->w, TEXT_AREA);
  2367 
  2368           if (x + background_width > right_x)
  2369             background_width -= x - right_x;
  2370           x += background_width;
  2371         }
  2372       width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
  2373       if (s->row->reversed_p)
  2374         x -= width;
  2375 
  2376       /* Draw cursor.  */
  2377       pgtk_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
  2378 
  2379       /* Clear rest using the GC of the original non-cursor face.  */
  2380       if (width < background_width)
  2381         {
  2382           int y = s->y;
  2383           int w = background_width - width, h = s->height;
  2384           XRectangle r;
  2385           unsigned long color;
  2386 
  2387           if (!s->row->reversed_p)
  2388             x += width;
  2389           else
  2390             x = s->x;
  2391           if (s->row->mouse_face_p && cursor_in_mouse_face_p (s->w))
  2392             {
  2393               pgtk_set_mouse_face_gc (s);
  2394               color = s->xgcv.foreground;
  2395             }
  2396           else
  2397             color = s->face->background;
  2398 
  2399           cairo_t *cr = pgtk_begin_cr_clip (s->f);
  2400 
  2401           get_glyph_string_clip_rect (s, &r);
  2402           pgtk_set_clip_rectangles (s->f, cr, &r, 1);
  2403 
  2404           if (s->face->stipple)
  2405             fill_background (s, x, y, w, h);
  2406           else
  2407             pgtk_fill_rectangle (s->f, color, x, y, w, h,
  2408                                  true);
  2409 
  2410           pgtk_end_cr_clip (s->f);
  2411         }
  2412     }
  2413   else if (!s->background_filled_p)
  2414     {
  2415       int background_width = s->background_width;
  2416       int x = s->x, text_left_x = window_box_left (s->w, TEXT_AREA);
  2417 
  2418       /* Don't draw into left fringe or scrollbar area except for
  2419          header line and mode line.  */
  2420       if (s->area == TEXT_AREA
  2421           && x < text_left_x && !s->row->mode_line_p)
  2422         {
  2423           background_width -= text_left_x - x;
  2424           x = text_left_x;
  2425         }
  2426 
  2427       if (background_width > 0)
  2428         pgtk_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
  2429     }
  2430 
  2431   s->background_filled_p = true;
  2432 }
  2433 
  2434 static void
  2435 pgtk_draw_glyph_string (struct glyph_string *s)
  2436 {
  2437   bool relief_drawn_p = false;
  2438 
  2439   /* If S draws into the background of its successors, draw the
  2440      background of the successors first so that S can draw into it.
  2441      This makes S->next use XDrawString instead of XDrawImageString.  */
  2442   if (s->next && s->right_overhang && !s->for_overlaps)
  2443     {
  2444       int width;
  2445       struct glyph_string *next;
  2446 
  2447       for (width = 0, next = s->next;
  2448            next && width < s->right_overhang;
  2449            width += next->width, next = next->next)
  2450         if (next->first_glyph->type != IMAGE_GLYPH)
  2451           {
  2452             cairo_t *cr = pgtk_begin_cr_clip (next->f);
  2453             pgtk_set_glyph_string_gc (next);
  2454             pgtk_set_glyph_string_clipping (next, cr);
  2455             if (next->first_glyph->type == STRETCH_GLYPH)
  2456               pgtk_draw_stretch_glyph_string (next);
  2457             else
  2458               pgtk_draw_glyph_string_background (next, true);
  2459             next->num_clips = 0;
  2460             pgtk_end_cr_clip (next->f);
  2461           }
  2462     }
  2463 
  2464   /* Set up S->gc, set clipping and draw S.  */
  2465   pgtk_set_glyph_string_gc (s);
  2466 
  2467   cairo_t *cr = pgtk_begin_cr_clip (s->f);
  2468 
  2469   /* Draw relief (if any) in advance for char/composition so that the
  2470      glyph string can be drawn over it.  */
  2471   if (!s->for_overlaps
  2472       && s->face->box != FACE_NO_BOX
  2473       && (s->first_glyph->type == CHAR_GLYPH
  2474           || s->first_glyph->type == COMPOSITE_GLYPH))
  2475 
  2476     {
  2477       pgtk_set_glyph_string_clipping (s, cr);
  2478       pgtk_draw_glyph_string_background (s, true);
  2479       pgtk_draw_glyph_string_box (s);
  2480       pgtk_set_glyph_string_clipping (s, cr);
  2481       relief_drawn_p = true;
  2482     }
  2483   else if (!s->clip_head        /* draw_glyphs didn't specify a clip mask. */
  2484            && !s->clip_tail
  2485            && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
  2486                || (s->next && s->next->hl != s->hl && s->right_overhang)))
  2487     /* We must clip just this glyph.  left_overhang part has already
  2488        drawn when s->prev was drawn, and right_overhang part will be
  2489        drawn later when s->next is drawn. */
  2490     pgtk_set_glyph_string_clipping_exactly (s, s, cr);
  2491   else
  2492     pgtk_set_glyph_string_clipping (s, cr);
  2493 
  2494   switch (s->first_glyph->type)
  2495     {
  2496     case IMAGE_GLYPH:
  2497       pgtk_draw_image_glyph_string (s);
  2498       break;
  2499 
  2500     case XWIDGET_GLYPH:
  2501       x_draw_xwidget_glyph_string (s);
  2502       break;
  2503 
  2504     case STRETCH_GLYPH:
  2505       pgtk_draw_stretch_glyph_string (s);
  2506       break;
  2507 
  2508     case CHAR_GLYPH:
  2509       if (s->for_overlaps)
  2510         s->background_filled_p = true;
  2511       else
  2512         pgtk_draw_glyph_string_background (s, false);
  2513       pgtk_draw_glyph_string_foreground (s);
  2514       break;
  2515 
  2516     case COMPOSITE_GLYPH:
  2517       if (s->for_overlaps || (s->cmp_from > 0
  2518                               && !s->first_glyph->u.cmp.automatic))
  2519         s->background_filled_p = true;
  2520       else
  2521         pgtk_draw_glyph_string_background (s, true);
  2522       pgtk_draw_composite_glyph_string_foreground (s);
  2523       break;
  2524 
  2525     case GLYPHLESS_GLYPH:
  2526       if (s->for_overlaps)
  2527         s->background_filled_p = true;
  2528       else
  2529         pgtk_draw_glyph_string_background (s, true);
  2530       pgtk_draw_glyphless_glyph_string_foreground (s);
  2531       break;
  2532 
  2533     default:
  2534       emacs_abort ();
  2535     }
  2536 
  2537   if (!s->for_overlaps)
  2538     {
  2539       /* Draw relief if not yet drawn.  */
  2540       if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
  2541         pgtk_draw_glyph_string_box (s);
  2542 
  2543       /* Draw underline.  */
  2544       if (s->face->underline)
  2545         {
  2546           if (s->face->underline == FACE_UNDER_WAVE)
  2547             {
  2548               if (s->face->underline_defaulted_p)
  2549                 pgtk_draw_underwave (s, s->xgcv.foreground);
  2550               else
  2551                 pgtk_draw_underwave (s, s->face->underline_color);
  2552             }
  2553           else if (s->face->underline == FACE_UNDER_LINE)
  2554             {
  2555               unsigned long thickness, position;
  2556               int y;
  2557 
  2558               if (s->prev
  2559                   && s->prev->face->underline == FACE_UNDER_LINE
  2560                   && (s->prev->face->underline_at_descent_line_p
  2561                       == s->face->underline_at_descent_line_p)
  2562                   && (s->prev->face->underline_pixels_above_descent_line
  2563                       == s->face->underline_pixels_above_descent_line))
  2564                 {
  2565                   /* We use the same underline style as the previous one.  */
  2566                   thickness = s->prev->underline_thickness;
  2567                   position = s->prev->underline_position;
  2568                 }
  2569               else
  2570                 {
  2571                   struct font *font = font_for_underline_metrics (s);
  2572 
  2573                   /* Get the underline thickness.  Default is 1 pixel.  */
  2574                   if (font && font->underline_thickness > 0)
  2575                     thickness = font->underline_thickness;
  2576                   else
  2577                     thickness = 1;
  2578                   if ((x_underline_at_descent_line
  2579                        || s->face->underline_at_descent_line_p))
  2580                     position = ((s->height - thickness)
  2581                                 - (s->ybase - s->y)
  2582                                 - s->face->underline_pixels_above_descent_line);
  2583                   else
  2584                     {
  2585                       /* Get the underline position.  This is the recommended
  2586                          vertical offset in pixels from the baseline to the top of
  2587                          the underline.  This is a signed value according to the
  2588                          specs, and its default is
  2589 
  2590                          ROUND ((maximum descent) / 2), with
  2591                          ROUND(x) = floor (x + 0.5)  */
  2592 
  2593                       if (x_use_underline_position_properties
  2594                           && font && font->underline_position >= 0)
  2595                         position = font->underline_position;
  2596                       else if (font)
  2597                         position = (font->descent + 1) / 2;
  2598                       else
  2599                         position = underline_minimum_offset;
  2600                     }
  2601 
  2602                   /* Ignore minimum_offset if the amount of pixels was
  2603                      explicitly specified.  */
  2604                   if (!s->face->underline_pixels_above_descent_line)
  2605                     position = max (position, underline_minimum_offset);
  2606                 }
  2607               /* Check the sanity of thickness and position.  We should
  2608                  avoid drawing underline out of the current line area.  */
  2609               if (s->y + s->height <= s->ybase + position)
  2610                 position = (s->height - 1) - (s->ybase - s->y);
  2611               if (s->y + s->height < s->ybase + position + thickness)
  2612                 thickness = (s->y + s->height) - (s->ybase + position);
  2613               s->underline_thickness = thickness;
  2614               s->underline_position = position;
  2615               y = s->ybase + position;
  2616               if (s->face->underline_defaulted_p)
  2617                 pgtk_fill_rectangle (s->f, s->xgcv.foreground,
  2618                                      s->x, y, s->width, thickness,
  2619                                      false);
  2620               else
  2621                 {
  2622                   pgtk_fill_rectangle (s->f, s->face->underline_color,
  2623                                        s->x, y, s->width, thickness,
  2624                                        false);
  2625                 }
  2626             }
  2627         }
  2628       /* Draw overline.  */
  2629       if (s->face->overline_p)
  2630         {
  2631           unsigned long dy = 0, h = 1;
  2632 
  2633           if (s->face->overline_color_defaulted_p)
  2634             pgtk_fill_rectangle (s->f, s->xgcv.foreground, s->x, s->y + dy,
  2635                                  s->width, h, false);
  2636           else
  2637             pgtk_fill_rectangle (s->f, s->face->overline_color, s->x,
  2638                                  s->y + dy, s->width, h, false);
  2639         }
  2640 
  2641       /* Draw strike-through.  */
  2642       if (s->face->strike_through_p)
  2643         {
  2644           /* Y-coordinate and height of the glyph string's first
  2645              glyph.  We cannot use s->y and s->height because those
  2646              could be larger if there are taller display elements
  2647              (e.g., characters displayed with a larger font) in the
  2648              same glyph row.  */
  2649           int glyph_y = s->ybase - s->first_glyph->ascent;
  2650           int glyph_height = s->first_glyph->ascent + s->first_glyph->descent;
  2651           /* Strike-through width and offset from the glyph string's
  2652              top edge.  */
  2653           unsigned long h = 1;
  2654           unsigned long dy = (glyph_height - h) / 2;
  2655 
  2656           if (s->face->strike_through_color_defaulted_p)
  2657             pgtk_fill_rectangle (s->f, s->xgcv.foreground, s->x, glyph_y + dy,
  2658                                  s->width, h, false);
  2659           else
  2660             pgtk_fill_rectangle (s->f, s->face->strike_through_color, s->x,
  2661                                  glyph_y + dy, s->width, h, false);
  2662         }
  2663 
  2664       if (s->prev)
  2665         {
  2666           struct glyph_string *prev;
  2667 
  2668           for (prev = s->prev; prev; prev = prev->prev)
  2669             if (prev->hl != s->hl
  2670                 && prev->x + prev->width + prev->right_overhang > s->x)
  2671               {
  2672                 /* As prev was drawn while clipped to its own area, we
  2673                    must draw the right_overhang part using s->hl now.  */
  2674                 enum draw_glyphs_face save = prev->hl;
  2675 
  2676                 prev->hl = s->hl;
  2677                 pgtk_set_glyph_string_gc (prev);
  2678                 cairo_save (cr);
  2679                 pgtk_set_glyph_string_clipping_exactly (s, prev, cr);
  2680                 if (prev->first_glyph->type == CHAR_GLYPH)
  2681                   pgtk_draw_glyph_string_foreground (prev);
  2682                 else
  2683                   pgtk_draw_composite_glyph_string_foreground (prev);
  2684                 prev->hl = save;
  2685                 prev->num_clips = 0;
  2686                 cairo_restore (cr);
  2687               }
  2688         }
  2689 
  2690       if (s->next)
  2691         {
  2692           struct glyph_string *next;
  2693 
  2694           for (next = s->next; next; next = next->next)
  2695             if (next->hl != s->hl
  2696                 && next->x - next->left_overhang < s->x + s->width)
  2697               {
  2698                 /* As next will be drawn while clipped to its own area,
  2699                    we must draw the left_overhang part using s->hl now.  */
  2700                 enum draw_glyphs_face save = next->hl;
  2701 
  2702                 next->hl = s->hl;
  2703                 pgtk_set_glyph_string_gc (next);
  2704                 cairo_save (cr);
  2705                 pgtk_set_glyph_string_clipping_exactly (s, next, cr);
  2706                 if (next->first_glyph->type == CHAR_GLYPH)
  2707                   pgtk_draw_glyph_string_foreground (next);
  2708                 else
  2709                   pgtk_draw_composite_glyph_string_foreground (next);
  2710                 cairo_restore (cr);
  2711                 next->hl = save;
  2712                 next->num_clips = 0;
  2713                 next->clip_head = s->next;
  2714               }
  2715         }
  2716     }
  2717 
  2718   /* TODO: figure out in which cases the stipple is actually drawn on
  2719      PGTK.  */
  2720   if (!s->row->stipple_p)
  2721     s->row->stipple_p = s->face->stipple;
  2722 
  2723   /* Reset clipping.  */
  2724   pgtk_end_cr_clip (s->f);
  2725   s->num_clips = 0;
  2726 }
  2727 
  2728 /* RIF: Define cursor CURSOR on frame F.  */
  2729 
  2730 static void
  2731 pgtk_define_frame_cursor (struct frame *f, Emacs_Cursor cursor)
  2732 {
  2733   if (!f->pointer_invisible && FRAME_X_OUTPUT (f)->current_cursor != cursor)
  2734     gdk_window_set_cursor (gtk_widget_get_window (FRAME_GTK_WIDGET (f)),
  2735                            cursor);
  2736   FRAME_X_OUTPUT (f)->current_cursor = cursor;
  2737 }
  2738 
  2739 static void
  2740 pgtk_after_update_window_line (struct window *w,
  2741                                struct glyph_row *desired_row)
  2742 {
  2743   struct frame *f;
  2744   int width, height;
  2745 
  2746   /* begin copy from other terms */
  2747   eassert (w);
  2748 
  2749   if (!desired_row->mode_line_p && !w->pseudo_window_p)
  2750     desired_row->redraw_fringe_bitmaps_p = 1;
  2751 
  2752   /* When a window has disappeared, make sure that no rest of
  2753      full-width rows stays visible in the internal border.  */
  2754   if (windows_or_buffers_changed
  2755       && desired_row->full_width_p
  2756       && (f = XFRAME (w->frame),
  2757           width = FRAME_INTERNAL_BORDER_WIDTH (f),
  2758           width != 0) && (height = desired_row->visible_height, height > 0))
  2759     {
  2760       int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
  2761 
  2762       block_input ();
  2763       pgtk_clear_frame_area (f, 0, y, width, height);
  2764       pgtk_clear_frame_area (f,
  2765                              FRAME_PIXEL_WIDTH (f) - width, y, width, height);
  2766       unblock_input ();
  2767     }
  2768 }
  2769 
  2770 static void
  2771 pgtk_clear_frame_area (struct frame *f, int x, int y, int width, int height)
  2772 {
  2773   pgtk_clear_area (f, x, y, width, height);
  2774 }
  2775 
  2776 /* Draw a hollow box cursor on window W in glyph row ROW.  */
  2777 
  2778 static void
  2779 pgtk_draw_hollow_cursor (struct window *w, struct glyph_row *row)
  2780 {
  2781   struct frame *f = XFRAME (WINDOW_FRAME (w));
  2782   int x, y, wd, h;
  2783   struct glyph *cursor_glyph;
  2784 
  2785   /* Get the glyph the cursor is on.  If we can't tell because
  2786      the current matrix is invalid or such, give up.  */
  2787   cursor_glyph = get_phys_cursor_glyph (w);
  2788   if (cursor_glyph == NULL)
  2789     return;
  2790 
  2791   /* Compute frame-relative coordinates for phys cursor.  */
  2792   get_phys_cursor_geometry (w, row, cursor_glyph, &x, &y, &h);
  2793   wd = w->phys_cursor_width - 1;
  2794 
  2795   /* The foreground of cursor_gc is typically the same as the normal
  2796      background color, which can cause the cursor box to be invisible.  */
  2797   cairo_t *cr = pgtk_begin_cr_clip (f);
  2798   pgtk_set_cr_source_with_color (f, FRAME_X_OUTPUT (f)->cursor_color, false);
  2799 
  2800   /* When on R2L character, show cursor at the right edge of the
  2801      glyph, unless the cursor box is as wide as the glyph or wider
  2802      (the latter happens when x-stretch-cursor is non-nil).  */
  2803   if ((cursor_glyph->resolved_level & 1) != 0
  2804       && cursor_glyph->pixel_width > wd)
  2805     {
  2806       x += cursor_glyph->pixel_width - wd;
  2807       if (wd > 0)
  2808         wd -= 1;
  2809     }
  2810   /* Set clipping, draw the rectangle, and reset clipping again.  */
  2811   pgtk_clip_to_row (w, row, TEXT_AREA, cr);
  2812   pgtk_draw_rectangle (f, FRAME_X_OUTPUT (f)->cursor_color,
  2813                        x, y, wd, h - 1, false);
  2814   pgtk_end_cr_clip (f);
  2815 }
  2816 
  2817 /* Draw a bar cursor on window W in glyph row ROW.
  2818 
  2819    Implementation note: One would like to draw a bar cursor with an
  2820    angle equal to the one given by the font property XA_ITALIC_ANGLE.
  2821    Unfortunately, I didn't find a font yet that has this property set.
  2822    --gerd.  */
  2823 
  2824 static void
  2825 pgtk_draw_bar_cursor (struct window *w, struct glyph_row *row, int width,
  2826                    enum text_cursor_kinds kind)
  2827 {
  2828   struct frame *f = XFRAME (w->frame);
  2829   struct glyph *cursor_glyph;
  2830 
  2831   /* If cursor is out of bounds, don't draw garbage.  This can happen
  2832      in mini-buffer windows when switching between echo area glyphs
  2833      and mini-buffer.  */
  2834   cursor_glyph = get_phys_cursor_glyph (w);
  2835   if (cursor_glyph == NULL)
  2836     return;
  2837 
  2838   /* Experimental avoidance of cursor on xwidget.  */
  2839   if (cursor_glyph->type == XWIDGET_GLYPH)
  2840     return;
  2841 
  2842   /* If on an image, draw like a normal cursor.  That's usually better
  2843      visible than drawing a bar, esp. if the image is large so that
  2844      the bar might not be in the window.  */
  2845   if (cursor_glyph->type == IMAGE_GLYPH)
  2846     {
  2847       struct glyph_row *r;
  2848       r = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
  2849       draw_phys_cursor_glyph (w, r, DRAW_CURSOR);
  2850     }
  2851   else
  2852     {
  2853       struct face *face = FACE_FROM_ID (f, cursor_glyph->face_id);
  2854       unsigned long color;
  2855 
  2856       cairo_t *cr = pgtk_begin_cr_clip (f);
  2857 
  2858       /* If the glyph's background equals the color we normally draw
  2859          the bars cursor in, the bar cursor in its normal color is
  2860          invisible.  Use the glyph's foreground color instead in this
  2861          case, on the assumption that the glyph's colors are chosen so
  2862          that the glyph is legible.  */
  2863       if (face->background == FRAME_X_OUTPUT (f)->cursor_color)
  2864         color = face->foreground;
  2865       else
  2866         color = FRAME_X_OUTPUT (f)->cursor_color;
  2867 
  2868       pgtk_clip_to_row (w, row, TEXT_AREA, cr);
  2869 
  2870       if (kind == BAR_CURSOR)
  2871         {
  2872           int x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
  2873 
  2874           if (width < 0)
  2875             width = FRAME_CURSOR_WIDTH (f);
  2876           width = min (cursor_glyph->pixel_width, width);
  2877 
  2878           w->phys_cursor_width = width;
  2879 
  2880           /* If the character under cursor is R2L, draw the bar cursor
  2881              on the right of its glyph, rather than on the left.  */
  2882           if ((cursor_glyph->resolved_level & 1) != 0)
  2883             x += cursor_glyph->pixel_width - width;
  2884 
  2885           pgtk_fill_rectangle (f, color, x,
  2886                                WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
  2887                                width, row->height, false);
  2888         }
  2889       else                      /* HBAR_CURSOR */
  2890         {
  2891           int dummy_x, dummy_y, dummy_h;
  2892           int x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
  2893 
  2894           if (width < 0)
  2895             width = row->height;
  2896 
  2897           width = min (row->height, width);
  2898 
  2899           get_phys_cursor_geometry (w, row, cursor_glyph, &dummy_x,
  2900                                     &dummy_y, &dummy_h);
  2901 
  2902           if ((cursor_glyph->resolved_level & 1) != 0
  2903               && cursor_glyph->pixel_width > w->phys_cursor_width - 1)
  2904             x += cursor_glyph->pixel_width - w->phys_cursor_width + 1;
  2905           pgtk_fill_rectangle (f, color, x,
  2906                                WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
  2907                                                         row->height - width),
  2908                                w->phys_cursor_width - 1, width, false);
  2909         }
  2910 
  2911       pgtk_end_cr_clip (f);
  2912     }
  2913 }
  2914 
  2915 /* RIF: Draw cursor on window W.  */
  2916 
  2917 static void
  2918 pgtk_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, int x,
  2919                          int y, enum text_cursor_kinds cursor_type,
  2920                          int cursor_width, bool on_p, bool active_p)
  2921 {
  2922   struct frame *f = XFRAME (w->frame);
  2923 
  2924   if (on_p)
  2925     {
  2926       w->phys_cursor_type = cursor_type;
  2927       w->phys_cursor_on_p = true;
  2928 
  2929       if (glyph_row->exact_window_width_line_p
  2930           && (glyph_row->reversed_p
  2931               ? (w->phys_cursor.hpos < 0)
  2932               : (w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])))
  2933         {
  2934           glyph_row->cursor_in_fringe_p = true;
  2935           draw_fringe_bitmap (w, glyph_row, glyph_row->reversed_p);
  2936         }
  2937       else
  2938         {
  2939           switch (cursor_type)
  2940             {
  2941             case HOLLOW_BOX_CURSOR:
  2942               pgtk_draw_hollow_cursor (w, glyph_row);
  2943               break;
  2944 
  2945             case FILLED_BOX_CURSOR:
  2946               draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
  2947               break;
  2948 
  2949             case BAR_CURSOR:
  2950               pgtk_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
  2951               break;
  2952 
  2953             case HBAR_CURSOR:
  2954               pgtk_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
  2955               break;
  2956 
  2957             case NO_CURSOR:
  2958               w->phys_cursor_width = 0;
  2959               break;
  2960 
  2961             default:
  2962               emacs_abort ();
  2963             }
  2964         }
  2965 
  2966       if (w == XWINDOW (f->selected_window))
  2967         {
  2968           int frame_x = (WINDOW_TO_FRAME_PIXEL_X (w, x)
  2969                          + WINDOW_LEFT_FRINGE_WIDTH (w)
  2970                          + WINDOW_LEFT_MARGIN_WIDTH (w));
  2971           int frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, y);
  2972           pgtk_im_set_cursor_location (f, frame_x, frame_y,
  2973                                        w->phys_cursor_width,
  2974                                        w->phys_cursor_height);
  2975         }
  2976     }
  2977 
  2978 }
  2979 
  2980 static void
  2981 pgtk_copy_bits (struct frame *f, cairo_rectangle_t *src_rect,
  2982                 cairo_rectangle_t *dst_rect)
  2983 {
  2984   cairo_t *cr;
  2985   cairo_surface_t *surface;     /* temporary surface */
  2986 
  2987   surface
  2988     = cairo_surface_create_similar (FRAME_CR_SURFACE (f),
  2989                                     CAIRO_CONTENT_COLOR_ALPHA,
  2990                                     (int) src_rect->width,
  2991                                     (int) src_rect->height);
  2992 
  2993   cr = cairo_create (surface);
  2994   cairo_set_source_surface (cr, FRAME_CR_SURFACE (f), -src_rect->x,
  2995                             -src_rect->y);
  2996   cairo_rectangle (cr, 0, 0, src_rect->width, src_rect->height);
  2997   cairo_clip (cr);
  2998   cairo_paint (cr);
  2999   cairo_destroy (cr);
  3000 
  3001   cr = pgtk_begin_cr_clip (f);
  3002   cairo_set_source_surface (cr, surface, dst_rect->x, dst_rect->y);
  3003   cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
  3004   cairo_rectangle (cr, dst_rect->x, dst_rect->y, dst_rect->width,
  3005                    dst_rect->height);
  3006   cairo_clip (cr);
  3007   cairo_paint (cr);
  3008   pgtk_end_cr_clip (f);
  3009 
  3010   cairo_surface_destroy (surface);
  3011 }
  3012 
  3013 /* Scroll part of the display as described by RUN.  */
  3014 
  3015 static void
  3016 pgtk_scroll_run (struct window *w, struct run *run)
  3017 {
  3018   struct frame *f = XFRAME (w->frame);
  3019   int x, y, width, height, from_y, to_y, bottom_y;
  3020 
  3021   /* Get frame-relative bounding box of the text display area of W,
  3022      without mode lines.  Include in this box the left and right
  3023      fringe of W.  */
  3024   window_box (w, ANY_AREA, &x, &y, &width, &height);
  3025 
  3026   from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
  3027   to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
  3028   bottom_y = y + height;
  3029 
  3030   if (to_y < from_y)
  3031     {
  3032       /* Scrolling up.  Make sure we don't copy part of the mode
  3033          line at the bottom.  */
  3034       if (from_y + run->height > bottom_y)
  3035         height = bottom_y - from_y;
  3036       else
  3037         height = run->height;
  3038     }
  3039   else
  3040     {
  3041       /* Scrolling down.  Make sure we don't copy over the mode line.
  3042          at the bottom.  */
  3043       if (to_y + run->height > bottom_y)
  3044         height = bottom_y - to_y;
  3045       else
  3046         height = run->height;
  3047     }
  3048 
  3049   block_input ();
  3050 
  3051 #ifdef HAVE_XWIDGETS
  3052   /* "Copy" xwidget views in the area that will be scrolled.  */
  3053   GtkWidget *tem, *parent = FRAME_GTK_WIDGET (f);
  3054   GList *children = gtk_container_get_children (GTK_CONTAINER (parent));
  3055   GList *iter;
  3056   struct xwidget_view *view;
  3057 
  3058   for (iter = children; iter; iter = iter->next)
  3059     {
  3060       tem = iter->data;
  3061       view = g_object_get_data (G_OBJECT (tem), XG_XWIDGET_VIEW);
  3062 
  3063       if (view && !view->hidden)
  3064         {
  3065           int window_y = view->y + view->clip_top;
  3066           int window_height = view->clip_bottom - view->clip_top;
  3067 
  3068           Emacs_Rectangle r1, r2, result;
  3069           r1.x = w->pixel_left;
  3070           r1.y = from_y;
  3071           r1.width = w->pixel_width;
  3072           r1.height = height;
  3073           r2 = r1;
  3074           r2.y = window_y;
  3075           r2.height = window_height;
  3076 
  3077           /* The window is offscreen, just unmap it.  */
  3078           if (window_height == 0)
  3079             {
  3080               view->hidden = true;
  3081               gtk_widget_hide (tem);
  3082               continue;
  3083             }
  3084 
  3085           bool intersects_p =
  3086             gui_intersect_rectangles (&r1, &r2, &result);
  3087 
  3088           if (XWINDOW (view->w) == w && intersects_p)
  3089             {
  3090               int y = view->y + (to_y - from_y);
  3091               int text_area_x, text_area_y, text_area_width, text_area_height;
  3092               int clip_top, clip_bottom;
  3093 
  3094               window_box (w, view->area, &text_area_x, &text_area_y,
  3095                           &text_area_width, &text_area_height);
  3096 
  3097               view->y = y;
  3098 
  3099               clip_top = 0;
  3100               clip_bottom = XXWIDGET (view->model)->height;
  3101 
  3102               if (y < text_area_y)
  3103                 clip_top = text_area_y - y;
  3104 
  3105               if ((y + clip_bottom) > (text_area_y + text_area_height))
  3106                 {
  3107                   clip_bottom -= (y + clip_bottom) - (text_area_y + text_area_height);
  3108                 }
  3109 
  3110               view->clip_top = clip_top;
  3111               view->clip_bottom = clip_bottom;
  3112 
  3113               /* This means the view has moved offscreen.  Unmap
  3114                  it and hide it here.  */
  3115               if ((view->clip_bottom - view->clip_top) <= 0)
  3116                 {
  3117                   view->hidden = true;
  3118                   gtk_widget_hide (tem);
  3119                 }
  3120               else
  3121                 {
  3122                   gtk_fixed_move (GTK_FIXED (FRAME_GTK_WIDGET (f)),
  3123                                   tem, view->x + view->clip_left,
  3124                                   view->y + view->clip_top);
  3125                   gtk_widget_set_size_request (tem, view->clip_right - view->clip_left,
  3126                                                view->clip_bottom - view->clip_top);
  3127                   gtk_widget_queue_allocate (tem);
  3128                 }
  3129             }
  3130         }
  3131     }
  3132 
  3133   g_list_free (children);
  3134 #endif
  3135 
  3136   /* Cursor off.  Will be switched on again in x_update_window_end.  */
  3137   gui_clear_cursor (w);
  3138 
  3139   {
  3140     cairo_rectangle_t src_rect = { x, from_y, width, height };
  3141     cairo_rectangle_t dst_rect = { x, to_y, width, height };
  3142     pgtk_copy_bits (f, &src_rect, &dst_rect);
  3143   }
  3144 
  3145   unblock_input ();
  3146 }
  3147 
  3148 /* Icons.  */
  3149 
  3150 static bool
  3151 pgtk_bitmap_icon (struct frame *f, Lisp_Object file)
  3152 {
  3153   /* This code has never worked anyway for the reason that Wayland
  3154      uses icons set within desktop files, and has been disabled
  3155      because leaving it intact would require image.c to retain a
  3156      reference to a GdkPixbuf (which are no longer used) within new
  3157      bitmaps.  */
  3158 #if 0
  3159   ptrdiff_t bitmap_id;
  3160 
  3161   if (FRAME_GTK_WIDGET (f) == 0)
  3162     return true;
  3163 
  3164   /* Free up our existing icon bitmap and mask if any.  */
  3165   if (f->output_data.pgtk->icon_bitmap > 0)
  3166     image_destroy_bitmap (f, f->output_data.pgtk->icon_bitmap);
  3167   f->output_data.pgtk->icon_bitmap = 0;
  3168 
  3169   if (STRINGP (file))
  3170     {
  3171       /* Use gtk_window_set_icon_from_file () if available,
  3172          It's not restricted to bitmaps */
  3173       if (xg_set_icon (f, file))
  3174         return false;
  3175       bitmap_id = image_create_bitmap_from_file (f, file);
  3176     }
  3177   else
  3178     {
  3179       /* Create the GNU bitmap and mask if necessary.  */
  3180       if (FRAME_DISPLAY_INFO (f)->icon_bitmap_id < 0)
  3181         {
  3182           ptrdiff_t rc = -1;
  3183 
  3184           if (xg_set_icon (f, xg_default_icon_file)
  3185               || xg_set_icon_from_xpm_data (f, gnu_xpm_bits))
  3186             {
  3187               FRAME_DISPLAY_INFO (f)->icon_bitmap_id = -2;
  3188               return false;
  3189             }
  3190 
  3191           /* If all else fails, use the (black and white) xbm image. */
  3192           if (rc == -1)
  3193             {
  3194               rc = image_create_bitmap_from_data (f,
  3195                                                   (char *) gnu_xbm_bits,
  3196                                                   gnu_xbm_width,
  3197                                                   gnu_xbm_height);
  3198               if (rc == -1)
  3199                 return true;
  3200 
  3201               FRAME_DISPLAY_INFO (f)->icon_bitmap_id = rc;
  3202             }
  3203         }
  3204 
  3205       /* The first time we create the GNU bitmap and mask,
  3206          this increments the ref-count one extra time.
  3207          As a result, the GNU bitmap and mask are never freed.
  3208          That way, we don't have to worry about allocating it again.  */
  3209       image_reference_bitmap (f, FRAME_DISPLAY_INFO (f)->icon_bitmap_id);
  3210 
  3211       bitmap_id = FRAME_DISPLAY_INFO (f)->icon_bitmap_id;
  3212     }
  3213 
  3214   f->output_data.pgtk->icon_bitmap = bitmap_id;
  3215 #endif /* 0 */
  3216   return false;
  3217 }
  3218 
  3219 
  3220 /* Make the x-window of frame F use a rectangle with text.
  3221    Use ICON_NAME as the text.  */
  3222 
  3223 bool
  3224 pgtk_text_icon (struct frame *f, const char *icon_name)
  3225 {
  3226   if (FRAME_GTK_OUTER_WIDGET (f))
  3227     {
  3228       gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), NULL);
  3229       gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), icon_name);
  3230     }
  3231 
  3232   return false;
  3233 }
  3234 
  3235 /***********************************************************************
  3236                     Starting and ending an update
  3237  ***********************************************************************/
  3238 
  3239 /* Start an update of frame F.  This function is installed as a hook
  3240    for update_begin, i.e. it is called when update_begin is called.
  3241    This function is called prior to calls to x_update_window_begin for
  3242    each window being updated.  Currently, there is nothing to do here
  3243    because all interesting stuff is done on a window basis.  */
  3244 
  3245 static void
  3246 pgtk_update_begin (struct frame *f)
  3247 {
  3248   pgtk_clear_under_internal_border (f);
  3249 }
  3250 
  3251 /* Draw a vertical window border from (x,y0) to (x,y1)  */
  3252 
  3253 static void
  3254 pgtk_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
  3255 {
  3256   struct frame *f = XFRAME (WINDOW_FRAME (w));
  3257   struct face *face;
  3258   cairo_t *cr;
  3259 
  3260   cr = pgtk_begin_cr_clip (f);
  3261 
  3262   face = FACE_FROM_ID_OR_NULL (f, VERTICAL_BORDER_FACE_ID);
  3263   if (face)
  3264     pgtk_set_cr_source_with_color (f, face->foreground, false);
  3265 
  3266   cairo_rectangle (cr, x, y0, 1, y1 - y0);
  3267   cairo_fill (cr);
  3268 
  3269   pgtk_end_cr_clip (f);
  3270 }
  3271 
  3272 /* Draw a window divider from (x0,y0) to (x1,y1)  */
  3273 
  3274 static void
  3275 pgtk_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
  3276 {
  3277   struct frame *f = XFRAME (WINDOW_FRAME (w));
  3278   struct face *face = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FACE_ID);
  3279   struct face *face_first
  3280     = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID);
  3281   struct face *face_last
  3282     = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
  3283   unsigned long color = face ? face->foreground : FRAME_FOREGROUND_PIXEL (f);
  3284   unsigned long color_first = (face_first
  3285                                ? face_first->foreground
  3286                                : FRAME_FOREGROUND_PIXEL (f));
  3287   unsigned long color_last = (face_last
  3288                               ? face_last->foreground
  3289                               : FRAME_FOREGROUND_PIXEL (f));
  3290   cairo_t *cr = pgtk_begin_cr_clip (f);
  3291 
  3292   if (y1 - y0 > x1 - x0 && x1 - x0 > 2)
  3293     /* Vertical.  */
  3294     {
  3295       pgtk_set_cr_source_with_color (f, color_first, false);
  3296       cairo_rectangle (cr, x0, y0, 1, y1 - y0);
  3297       cairo_fill (cr);
  3298       pgtk_set_cr_source_with_color (f, color, false);
  3299       cairo_rectangle (cr, x0 + 1, y0, x1 - x0 - 2, y1 - y0);
  3300       cairo_fill (cr);
  3301       pgtk_set_cr_source_with_color (f, color_last, false);
  3302       cairo_rectangle (cr, x1 - 1, y0, 1, y1 - y0);
  3303       cairo_fill (cr);
  3304     }
  3305   else if (x1 - x0 > y1 - y0 && y1 - y0 > 3)
  3306     /* Horizontal.  */
  3307     {
  3308       pgtk_set_cr_source_with_color (f, color_first, false);
  3309       cairo_rectangle (cr, x0, y0, x1 - x0, 1);
  3310       cairo_fill (cr);
  3311       pgtk_set_cr_source_with_color (f, color, false);
  3312       cairo_rectangle (cr, x0, y0 + 1, x1 - x0, y1 - y0 - 2);
  3313       cairo_fill (cr);
  3314       pgtk_set_cr_source_with_color (f, color_last, false);
  3315       cairo_rectangle (cr, x0, y1 - 1, x1 - x0, 1);
  3316       cairo_fill (cr);
  3317     }
  3318   else
  3319     {
  3320       pgtk_set_cr_source_with_color (f, color, false);
  3321       cairo_rectangle (cr, x0, y0, x1 - x0, y1 - y0);
  3322       cairo_fill (cr);
  3323     }
  3324 
  3325   pgtk_end_cr_clip (f);
  3326 }
  3327 
  3328 /* End update of frame F.  This function is installed as a hook in
  3329    update_end.  */
  3330 
  3331 static void
  3332 pgtk_update_end (struct frame *f)
  3333 {
  3334   /* Mouse highlight may be displayed again.  */
  3335   MOUSE_HL_INFO (f)->mouse_face_defer = false;
  3336 }
  3337 
  3338 static void
  3339 pgtk_frame_up_to_date (struct frame *f)
  3340 {
  3341   block_input ();
  3342   FRAME_MOUSE_UPDATE (f);
  3343   if (!buffer_flipping_blocked_p ())
  3344     {
  3345       flip_cr_context (f);
  3346       gtk_widget_queue_draw (FRAME_GTK_WIDGET (f));
  3347     }
  3348   unblock_input ();
  3349 }
  3350 
  3351 /* Return the current position of the mouse.
  3352    *FP should be a frame which indicates which display to ask about.
  3353 
  3354    If the mouse movement started in a scroll bar, set *FP, *BAR_WINDOW,
  3355    and *PART to the frame, window, and scroll bar part that the mouse
  3356    is over.  Set *X and *Y to the portion and whole of the mouse's
  3357    position on the scroll bar.
  3358 
  3359    If the mouse movement started elsewhere, set *FP to the frame the
  3360    mouse is on, *BAR_WINDOW to nil, and *X and *Y to the character cell
  3361    the mouse is over.
  3362 
  3363    Set *TIMESTAMP to the server time-stamp for the time at which the mouse
  3364    was at this position.
  3365 
  3366    Don't store anything if we don't have a valid set of values to report.
  3367 
  3368    This clears the mouse_moved flag, so we can wait for the next mouse
  3369    movement.  */
  3370 
  3371 static void
  3372 pgtk_mouse_position (struct frame **fp, int insist, Lisp_Object * bar_window,
  3373                      enum scroll_bar_part *part, Lisp_Object *x,
  3374                      Lisp_Object *y, Time *timestamp)
  3375 {
  3376   struct frame *f1;
  3377   struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
  3378   int win_x, win_y;
  3379   GdkSeat *seat;
  3380   GdkDevice *device;
  3381   GdkModifierType mask;
  3382   GdkWindow *win;
  3383   bool return_frame_flag = false;
  3384 
  3385   block_input ();
  3386 
  3387   Lisp_Object frame, tail;
  3388 
  3389   /* Clear the mouse-moved flag for every frame on this display.  */
  3390   FOR_EACH_FRAME (tail, frame)
  3391     if (FRAME_PGTK_P (XFRAME (frame))
  3392         && FRAME_X_DISPLAY (XFRAME (frame)) == FRAME_X_DISPLAY (*fp))
  3393     XFRAME (frame)->mouse_moved = false;
  3394 
  3395   dpyinfo->last_mouse_scroll_bar = NULL;
  3396 
  3397   if (gui_mouse_grabbed (dpyinfo)
  3398       && (!EQ (track_mouse, Qdropping)
  3399           && !EQ (track_mouse, Qdrag_source)))
  3400     f1 = dpyinfo->last_mouse_frame;
  3401   else
  3402     {
  3403       f1 = *fp;
  3404       win = gtk_widget_get_window (FRAME_GTK_WIDGET (*fp));
  3405       seat = gdk_display_get_default_seat (dpyinfo->gdpy);
  3406       device = gdk_seat_get_pointer (seat);
  3407       win = gdk_window_get_device_position (win, device, &win_x,
  3408                                             &win_y, &mask);
  3409       if (win != NULL)
  3410         f1 = pgtk_any_window_to_frame (win);
  3411       else
  3412         {
  3413           f1 = SELECTED_FRAME ();
  3414 
  3415           if (!FRAME_PGTK_P (f1))
  3416             f1 = dpyinfo->last_mouse_frame;
  3417 
  3418           return_frame_flag = EQ (track_mouse, Qdrag_source);
  3419         }
  3420     }
  3421 
  3422   /* F1 can be a terminal frame.  (Bug#50322) */
  3423   if (f1 == NULL || !FRAME_PGTK_P (f1))
  3424     {
  3425       unblock_input ();
  3426       return;
  3427     }
  3428 
  3429   win = gtk_widget_get_window (FRAME_GTK_WIDGET (f1));
  3430   seat = gdk_display_get_default_seat (dpyinfo->gdpy);
  3431   device = gdk_seat_get_pointer (seat);
  3432 
  3433   win = gdk_window_get_device_position (win, device,
  3434                                         &win_x, &win_y, &mask);
  3435 
  3436   if (f1 != NULL)
  3437     {
  3438       remember_mouse_glyph (f1, win_x, win_y,
  3439                             &dpyinfo->last_mouse_glyph);
  3440       dpyinfo->last_mouse_glyph_frame = f1;
  3441 
  3442       *bar_window = Qnil;
  3443       *part = 0;
  3444       *fp = !return_frame_flag ? f1 : NULL;
  3445       XSETINT (*x, win_x);
  3446       XSETINT (*y, win_y);
  3447       *timestamp = dpyinfo->last_mouse_movement_time;
  3448     }
  3449 
  3450   unblock_input ();
  3451 }
  3452 
  3453 /* Fringe bitmaps.  */
  3454 
  3455 static int max_fringe_bmp = 0;
  3456 static cairo_pattern_t **fringe_bmp = 0;
  3457 
  3458 static void
  3459 pgtk_define_fringe_bitmap (int which, unsigned short *bits, int h, int wd)
  3460 {
  3461   int i, stride;
  3462   cairo_surface_t *surface;
  3463   unsigned char *data;
  3464   cairo_pattern_t *pattern;
  3465 
  3466   if (which >= max_fringe_bmp)
  3467     {
  3468       i = max_fringe_bmp;
  3469       max_fringe_bmp = which + 20;
  3470       fringe_bmp
  3471         = (cairo_pattern_t **) xrealloc (fringe_bmp,
  3472                                          max_fringe_bmp *
  3473                                          sizeof (cairo_pattern_t *));
  3474       while (i < max_fringe_bmp)
  3475         fringe_bmp[i++] = 0;
  3476     }
  3477 
  3478   block_input ();
  3479 
  3480   surface = cairo_image_surface_create (CAIRO_FORMAT_A1, wd, h);
  3481   stride = cairo_image_surface_get_stride (surface);
  3482   data = cairo_image_surface_get_data (surface);
  3483 
  3484   for (i = 0; i < h; i++)
  3485     {
  3486       *((unsigned short *) data) = bits[i];
  3487       data += stride;
  3488     }
  3489 
  3490   cairo_surface_mark_dirty (surface);
  3491   pattern = cairo_pattern_create_for_surface (surface);
  3492   cairo_surface_destroy (surface);
  3493 
  3494   unblock_input ();
  3495 
  3496   fringe_bmp[which] = pattern;
  3497 }
  3498 
  3499 static void
  3500 pgtk_destroy_fringe_bitmap (int which)
  3501 {
  3502   if (which >= max_fringe_bmp)
  3503     return;
  3504 
  3505   if (fringe_bmp[which])
  3506     {
  3507       block_input ();
  3508       cairo_pattern_destroy (fringe_bmp[which]);
  3509       unblock_input ();
  3510     }
  3511   fringe_bmp[which] = 0;
  3512 }
  3513 
  3514 static void
  3515 pgtk_clip_to_row (struct window *w, struct glyph_row *row,
  3516                   enum glyph_row_area area, cairo_t * cr)
  3517 {
  3518   int window_x, window_y, window_width;
  3519   cairo_rectangle_int_t rect;
  3520 
  3521   window_box (w, area, &window_x, &window_y, &window_width, 0);
  3522 
  3523   rect.x = window_x;
  3524   rect.y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, row->y));
  3525   rect.y = max (rect.y, window_y);
  3526   rect.width = window_width;
  3527   rect.height = row->visible_height;
  3528 
  3529   cairo_rectangle (cr, rect.x, rect.y, rect.width, rect.height);
  3530   cairo_clip (cr);
  3531 }
  3532 
  3533 static void
  3534 pgtk_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
  3535                          struct draw_fringe_bitmap_params *p)
  3536 {
  3537   struct frame *f = XFRAME (WINDOW_FRAME (w));
  3538   struct face *face = p->face;
  3539 
  3540   cairo_t *cr = pgtk_begin_cr_clip (f);
  3541 
  3542   /* Must clip because of partially visible lines.  */
  3543   pgtk_clip_to_row (w, row, ANY_AREA, cr);
  3544 
  3545   if (p->bx >= 0 && !p->overlay_p)
  3546     {
  3547       /* In case the same realized face is used for fringes and for
  3548          something displayed in the text (e.g. face `region' on
  3549          mono-displays, the fill style may have been changed to
  3550          FillSolid in pgtk_draw_glyph_string_background.  */
  3551       if (face->stipple)
  3552         fill_background_by_face (f, face, p->bx, p->by, p->nx, p->ny);
  3553       else
  3554         {
  3555           pgtk_set_cr_source_with_color (f, face->background, true);
  3556           cairo_rectangle (cr, p->bx, p->by, p->nx, p->ny);
  3557           cairo_fill (cr);
  3558         }
  3559     }
  3560 
  3561   if (p->which
  3562       && p->which < max_fringe_bmp
  3563       && p->which < max_used_fringe_bitmap)
  3564     {
  3565       Emacs_GC gcv;
  3566 
  3567       if (!fringe_bmp[p->which])
  3568         {
  3569           /* This fringe bitmap is known to fringe.c, but lacks the
  3570              cairo_pattern_t pattern which shadows that bitmap.  This
  3571              is typical to define-fringe-bitmap being called when the
  3572              selected frame was not a GUI frame, for example, when
  3573              packages that define fringe bitmaps are loaded by a
  3574              daemon Emacs.  Create the missing pattern now.  */
  3575           gui_define_fringe_bitmap (f, p->which);
  3576         }
  3577 
  3578       gcv.foreground = (p->cursor_p
  3579                         ? (p->overlay_p ? face->background
  3580                            : FRAME_X_OUTPUT (f)->cursor_color)
  3581                         : face->foreground);
  3582       gcv.background = face->background;
  3583       pgtk_cr_draw_image (f, &gcv, fringe_bmp[p->which], 0, p->dh,
  3584                           p->wd, p->h, p->x, p->y, p->overlay_p);
  3585     }
  3586 
  3587   pgtk_end_cr_clip (f);
  3588 }
  3589 
  3590 static struct atimer *hourglass_atimer = NULL;
  3591 static int hourglass_enter_count = 0;
  3592 
  3593 static void
  3594 hourglass_cb (struct atimer *timer)
  3595 {
  3596 
  3597 }
  3598 
  3599 static void
  3600 pgtk_show_hourglass (struct frame *f)
  3601 {
  3602   struct pgtk_output *x = FRAME_X_OUTPUT (f);
  3603   if (x->hourglass_widget != NULL)
  3604     gtk_widget_destroy (x->hourglass_widget);
  3605 
  3606   /* This creates a GDK_INPUT_ONLY window.  */
  3607   x->hourglass_widget = gtk_event_box_new ();
  3608   gtk_widget_set_has_window (x->hourglass_widget, true);
  3609   gtk_fixed_put (GTK_FIXED (FRAME_GTK_WIDGET (f)), x->hourglass_widget, 0, 0);
  3610   gtk_widget_show (x->hourglass_widget);
  3611   gtk_widget_set_size_request (x->hourglass_widget, 30000, 30000);
  3612   gdk_window_raise (gtk_widget_get_window (x->hourglass_widget));
  3613   gdk_window_set_cursor (gtk_widget_get_window (x->hourglass_widget),
  3614                          x->hourglass_cursor);
  3615 
  3616   /* For cursor animation, we receive signals, set pending_signals,
  3617      and wait for the signal handler to run.  */
  3618   if (hourglass_enter_count++ == 0)
  3619     {
  3620       struct timespec ts = make_timespec (0, 50 * 1000 * 1000);
  3621       if (hourglass_atimer != NULL)
  3622         cancel_atimer (hourglass_atimer);
  3623       hourglass_atimer
  3624         = start_atimer (ATIMER_CONTINUOUS, ts, hourglass_cb, NULL);
  3625     }
  3626 }
  3627 
  3628 static void
  3629 pgtk_hide_hourglass (struct frame *f)
  3630 {
  3631   struct pgtk_output *x = FRAME_X_OUTPUT (f);
  3632   if (--hourglass_enter_count == 0)
  3633     {
  3634       if (hourglass_atimer != NULL)
  3635         {
  3636           cancel_atimer (hourglass_atimer);
  3637           hourglass_atimer = NULL;
  3638         }
  3639     }
  3640   if (x->hourglass_widget != NULL)
  3641     {
  3642       gtk_widget_destroy (x->hourglass_widget);
  3643       x->hourglass_widget = NULL;
  3644     }
  3645 }
  3646 
  3647 /* Flushes changes to display.  */
  3648 static void
  3649 pgtk_flush_display (struct frame *f)
  3650 {
  3651 }
  3652 
  3653 extern frame_parm_handler pgtk_frame_parm_handlers[];
  3654 
  3655 static struct redisplay_interface pgtk_redisplay_interface = {
  3656   pgtk_frame_parm_handlers,
  3657   gui_produce_glyphs,
  3658   gui_write_glyphs,
  3659   gui_insert_glyphs,
  3660   gui_clear_end_of_line,
  3661   pgtk_scroll_run,
  3662   pgtk_after_update_window_line,
  3663   NULL, /* gui_update_window_begin, */
  3664   NULL, /* gui_update_window_end, */
  3665   pgtk_flush_display,
  3666   gui_clear_window_mouse_face,
  3667   gui_get_glyph_overhangs,
  3668   gui_fix_overlapping_area,
  3669   pgtk_draw_fringe_bitmap,
  3670   pgtk_define_fringe_bitmap,
  3671   pgtk_destroy_fringe_bitmap,
  3672   pgtk_compute_glyph_string_overhangs,
  3673   pgtk_draw_glyph_string,
  3674   pgtk_define_frame_cursor,
  3675   pgtk_clear_frame_area,
  3676   pgtk_clear_under_internal_border,
  3677   pgtk_draw_window_cursor,
  3678   pgtk_draw_vertical_window_border,
  3679   pgtk_draw_window_divider,
  3680   NULL,                         /* pgtk_shift_glyphs_for_insert, */
  3681   pgtk_show_hourglass,
  3682   pgtk_hide_hourglass,
  3683   pgtk_default_font_parameter,
  3684 };
  3685 
  3686 void
  3687 pgtk_clear_frame (struct frame *f)
  3688 {
  3689   if (!FRAME_DEFAULT_FACE (f))
  3690     return;
  3691 
  3692   mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
  3693 
  3694   block_input ();
  3695   pgtk_clear_area (f, 0, 0, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
  3696   unblock_input ();
  3697 }
  3698 
  3699 static void
  3700 recover_from_visible_bell (struct atimer *timer)
  3701 {
  3702   struct frame *f = timer->client_data;
  3703 
  3704   if (FRAME_X_OUTPUT (f)->cr_surface_visible_bell != NULL)
  3705     {
  3706       cairo_surface_destroy (FRAME_X_OUTPUT (f)->cr_surface_visible_bell);
  3707       FRAME_X_OUTPUT (f)->cr_surface_visible_bell = NULL;
  3708     }
  3709 
  3710   if (FRAME_X_OUTPUT (f)->atimer_visible_bell != NULL)
  3711     FRAME_X_OUTPUT (f)->atimer_visible_bell = NULL;
  3712 }
  3713 
  3714 /* Invert the middle quarter of the frame for .15 sec.  */
  3715 
  3716 static void
  3717 pgtk_flash (struct frame *f)
  3718 {
  3719   cairo_surface_t *surface_orig, *surface;
  3720   cairo_t *cr;
  3721   int width, height, flash_height, flash_left, flash_right;
  3722   struct timespec delay;
  3723 
  3724   if (!FRAME_CR_CONTEXT (f))
  3725     return;
  3726 
  3727   block_input ();
  3728 
  3729   surface_orig = FRAME_CR_SURFACE (f);
  3730 
  3731   width = FRAME_CR_SURFACE_DESIRED_WIDTH (f);
  3732   height = FRAME_CR_SURFACE_DESIRED_HEIGHT (f);
  3733   surface = cairo_surface_create_similar (surface_orig,
  3734                                           CAIRO_CONTENT_COLOR_ALPHA,
  3735                                           width, height);
  3736 
  3737   cr = cairo_create (surface);
  3738   cairo_set_source_surface (cr, surface_orig, 0, 0);
  3739   cairo_rectangle (cr, 0, 0, width, height);
  3740   cairo_clip (cr);
  3741   cairo_paint (cr);
  3742 
  3743   cairo_set_source_rgb (cr, 1, 1, 1);
  3744   cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE);
  3745 
  3746   /* Get the height not including a menu bar widget.  */
  3747   height = FRAME_PIXEL_HEIGHT (f);
  3748   /* Height of each line to flash.  */
  3749   flash_height = FRAME_LINE_HEIGHT (f);
  3750   /* These will be the left and right margins of the rectangles.  */
  3751   flash_left = FRAME_INTERNAL_BORDER_WIDTH (f);
  3752   flash_right = (FRAME_PIXEL_WIDTH (f)
  3753                  - FRAME_INTERNAL_BORDER_WIDTH (f));
  3754   width = flash_right - flash_left;
  3755 
  3756   /* If window is tall, flash top and bottom line.  */
  3757   if (height > 3 * FRAME_LINE_HEIGHT (f))
  3758     {
  3759       cairo_rectangle (cr,
  3760                        flash_left,
  3761                        (FRAME_INTERNAL_BORDER_WIDTH (f)
  3762                         + FRAME_TOP_MARGIN_HEIGHT (f)),
  3763                        width, flash_height);
  3764       cairo_fill (cr);
  3765 
  3766       cairo_rectangle (cr,
  3767                        flash_left,
  3768                        (height - flash_height
  3769                         - FRAME_INTERNAL_BORDER_WIDTH (f)
  3770                         - FRAME_BOTTOM_MARGIN_HEIGHT (f)),
  3771                        width, flash_height);
  3772       cairo_fill (cr);
  3773     }
  3774   else
  3775     {
  3776       /* If it is short, flash it all.  */
  3777       cairo_rectangle (cr,
  3778                        flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
  3779                        width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
  3780       cairo_fill (cr);
  3781     }
  3782 
  3783   FRAME_X_OUTPUT (f)->cr_surface_visible_bell = surface;
  3784 
  3785   delay = make_timespec (0, 50 * 1000 * 1000);
  3786 
  3787   if (FRAME_X_OUTPUT (f)->atimer_visible_bell != NULL)
  3788     {
  3789       cancel_atimer (FRAME_X_OUTPUT (f)->atimer_visible_bell);
  3790       FRAME_X_OUTPUT (f)->atimer_visible_bell = NULL;
  3791     }
  3792 
  3793   FRAME_X_OUTPUT (f)->atimer_visible_bell
  3794     = start_atimer (ATIMER_RELATIVE, delay, recover_from_visible_bell, f);
  3795 
  3796 
  3797   cairo_destroy (cr);
  3798   unblock_input ();
  3799 }
  3800 
  3801 /* Make audible bell.  */
  3802 
  3803 static void
  3804 pgtk_ring_bell (struct frame *f)
  3805 {
  3806   if (visible_bell)
  3807     {
  3808       pgtk_flash (f);
  3809     }
  3810   else
  3811     {
  3812       block_input ();
  3813       gtk_widget_error_bell (FRAME_GTK_WIDGET (f));
  3814       unblock_input ();
  3815     }
  3816 }
  3817 
  3818 /* Read events coming from the X server.
  3819    Return as soon as there are no more events to be read.
  3820 
  3821    Return the number of characters stored into the buffer,
  3822    thus pretending to be `read' (except the characters we store
  3823    in the keyboard buffer can be multibyte, so are not necessarily
  3824    C chars).  */
  3825 
  3826 static int
  3827 pgtk_read_socket (struct terminal *terminal, struct input_event *hold_quit)
  3828 {
  3829   GMainContext *context;
  3830   bool context_acquired = false;
  3831   int count;
  3832 
  3833   count = evq_flush (hold_quit);
  3834   if (count > 0)
  3835     {
  3836       return count;
  3837     }
  3838 
  3839   context = g_main_context_default ();
  3840   context_acquired = g_main_context_acquire (context);
  3841 
  3842   block_input ();
  3843 
  3844   if (context_acquired)
  3845     {
  3846       while (g_main_context_pending (context))
  3847         {
  3848           g_main_context_dispatch (context);
  3849         }
  3850     }
  3851 
  3852   unblock_input ();
  3853 
  3854   if (context_acquired)
  3855     g_main_context_release (context);
  3856 
  3857   count = evq_flush (hold_quit);
  3858   if (count > 0)
  3859     {
  3860       return count;
  3861     }
  3862 
  3863   return 0;
  3864 }
  3865 
  3866 /* Lisp window being scrolled.  Set when starting to interact with
  3867    a toolkit scroll bar, reset to nil when ending the interaction.  */
  3868 
  3869 static Lisp_Object window_being_scrolled;
  3870 
  3871 static void
  3872 pgtk_send_scroll_bar_event (Lisp_Object window, enum scroll_bar_part part,
  3873                             int portion, int whole, bool horizontal)
  3874 {
  3875   union buffered_input_event inev;
  3876 
  3877   EVENT_INIT (inev.ie);
  3878 
  3879   inev.ie.kind = (horizontal
  3880                   ? HORIZONTAL_SCROLL_BAR_CLICK_EVENT
  3881                   : SCROLL_BAR_CLICK_EVENT);
  3882   inev.ie.frame_or_window = window;
  3883   inev.ie.arg = Qnil;
  3884   inev.ie.timestamp = 0;
  3885   inev.ie.code = 0;
  3886   inev.ie.part = part;
  3887   inev.ie.x = make_fixnum (portion);
  3888   inev.ie.y = make_fixnum (whole);
  3889   inev.ie.modifiers = 0;
  3890 
  3891   evq_enqueue (&inev);
  3892 }
  3893 
  3894 
  3895 /* Scroll bar callback for GTK scroll bars.  WIDGET is the scroll
  3896    bar widget.  DATA is a pointer to the scroll_bar structure. */
  3897 
  3898 static gboolean
  3899 xg_scroll_callback (GtkRange * range,
  3900                     GtkScrollType scroll, gdouble value, gpointer user_data)
  3901 {
  3902   int whole = 0, portion = 0;
  3903   struct scroll_bar *bar = user_data;
  3904   enum scroll_bar_part part = scroll_bar_nowhere;
  3905   GtkAdjustment *adj = GTK_ADJUSTMENT (gtk_range_get_adjustment (range));
  3906 
  3907   if (xg_ignore_gtk_scrollbar)
  3908     return false;
  3909 
  3910   switch (scroll)
  3911     {
  3912     case GTK_SCROLL_JUMP:
  3913       if (bar->horizontal)
  3914         {
  3915           part = scroll_bar_horizontal_handle;
  3916           whole = (int) (gtk_adjustment_get_upper (adj) -
  3917                          gtk_adjustment_get_page_size (adj));
  3918           portion = min ((int) value, whole);
  3919           bar->dragging = portion;
  3920         }
  3921       else
  3922         {
  3923           part = scroll_bar_handle;
  3924           whole = gtk_adjustment_get_upper (adj) -
  3925             gtk_adjustment_get_page_size (adj);
  3926           portion = min ((int) value, whole);
  3927           bar->dragging = portion;
  3928         }
  3929       break;
  3930     case GTK_SCROLL_STEP_BACKWARD:
  3931       part = (bar->horizontal ? scroll_bar_left_arrow : scroll_bar_up_arrow);
  3932       bar->dragging = -1;
  3933       break;
  3934     case GTK_SCROLL_STEP_FORWARD:
  3935       part = (bar->horizontal
  3936               ? scroll_bar_right_arrow : scroll_bar_down_arrow);
  3937       bar->dragging = -1;
  3938       break;
  3939     case GTK_SCROLL_PAGE_BACKWARD:
  3940       part = (bar->horizontal
  3941               ? scroll_bar_before_handle : scroll_bar_above_handle);
  3942       bar->dragging = -1;
  3943       break;
  3944     case GTK_SCROLL_PAGE_FORWARD:
  3945       part = (bar->horizontal
  3946               ? scroll_bar_after_handle : scroll_bar_below_handle);
  3947       bar->dragging = -1;
  3948       break;
  3949     default:
  3950       break;
  3951     }
  3952 
  3953   if (part != scroll_bar_nowhere)
  3954     {
  3955       window_being_scrolled = bar->window;
  3956       pgtk_send_scroll_bar_event (bar->window, part, portion, whole,
  3957                                   bar->horizontal);
  3958     }
  3959 
  3960   return false;
  3961 }
  3962 
  3963 /* Callback for button release. Sets dragging to -1 when dragging is done.  */
  3964 
  3965 static gboolean
  3966 xg_end_scroll_callback (GtkWidget * widget,
  3967                         GdkEventButton * event, gpointer user_data)
  3968 {
  3969   struct scroll_bar *bar = user_data;
  3970   bar->dragging = -1;
  3971   if (WINDOWP (window_being_scrolled))
  3972     {
  3973       pgtk_send_scroll_bar_event (window_being_scrolled,
  3974                                   scroll_bar_end_scroll, 0, 0,
  3975                                   bar->horizontal);
  3976       window_being_scrolled = Qnil;
  3977     }
  3978 
  3979   return false;
  3980 }
  3981 
  3982 #define SCROLL_BAR_NAME "verticalScrollBar"
  3983 #define SCROLL_BAR_HORIZONTAL_NAME "horizontalScrollBar"
  3984 
  3985 /* Create the widget for scroll bar BAR on frame F.  Record the widget
  3986    and X window of the scroll bar in BAR.  */
  3987 
  3988 static void
  3989 pgtk_create_toolkit_scroll_bar (struct frame *f, struct scroll_bar *bar)
  3990 {
  3991   const char *scroll_bar_name = SCROLL_BAR_NAME;
  3992 
  3993   block_input ();
  3994   xg_create_scroll_bar (f, bar, G_CALLBACK (xg_scroll_callback),
  3995                         G_CALLBACK (xg_end_scroll_callback), scroll_bar_name);
  3996   unblock_input ();
  3997 }
  3998 
  3999 static void
  4000 pgtk_create_horizontal_toolkit_scroll_bar (struct frame *f,
  4001                                            struct scroll_bar *bar)
  4002 {
  4003   const char *scroll_bar_name = SCROLL_BAR_HORIZONTAL_NAME;
  4004 
  4005   block_input ();
  4006   xg_create_horizontal_scroll_bar (f, bar, G_CALLBACK (xg_scroll_callback),
  4007                                    G_CALLBACK (xg_end_scroll_callback),
  4008                                    scroll_bar_name);
  4009   unblock_input ();
  4010 }
  4011 
  4012 /* Set the thumb size and position of scroll bar BAR.  We are currently
  4013    displaying PORTION out of a whole WHOLE, and our position POSITION.  */
  4014 
  4015 static void
  4016 pgtk_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion,
  4017                                    int position, int whole)
  4018 {
  4019   xg_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
  4020 }
  4021 
  4022 static void
  4023 pgtk_set_toolkit_horizontal_scroll_bar_thumb (struct scroll_bar *bar,
  4024                                               int portion, int position,
  4025                                               int whole)
  4026 {
  4027   xg_set_toolkit_horizontal_scroll_bar_thumb (bar, portion, position, whole);
  4028 }
  4029 
  4030 /* Create a scroll bar and return the scroll bar vector for it.  W is
  4031    the Emacs window on which to create the scroll bar. TOP, LEFT,
  4032    WIDTH and HEIGHT are the pixel coordinates and dimensions of the
  4033    scroll bar. */
  4034 
  4035 static struct scroll_bar *
  4036 pgtk_scroll_bar_create (struct window *w, int top, int left,
  4037                         int width, int height, bool horizontal)
  4038 {
  4039   struct frame *f = XFRAME (w->frame);
  4040   struct scroll_bar *bar
  4041     = ALLOCATE_PSEUDOVECTOR (struct scroll_bar, prev, PVEC_OTHER);
  4042   Lisp_Object barobj;
  4043 
  4044   block_input ();
  4045 
  4046   if (horizontal)
  4047     pgtk_create_horizontal_toolkit_scroll_bar (f, bar);
  4048   else
  4049     pgtk_create_toolkit_scroll_bar (f, bar);
  4050 
  4051   XSETWINDOW (bar->window, w);
  4052   bar->top = top;
  4053   bar->left = left;
  4054   bar->width = width;
  4055   bar->height = height;
  4056   bar->start = 0;
  4057   bar->end = 0;
  4058   bar->dragging = -1;
  4059   bar->horizontal = horizontal;
  4060 
  4061   /* Add bar to its frame's list of scroll bars.  */
  4062   bar->next = FRAME_SCROLL_BARS (f);
  4063   bar->prev = Qnil;
  4064   XSETVECTOR (barobj, bar);
  4065   fset_scroll_bars (f, barobj);
  4066   if (!NILP (bar->next))
  4067     XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
  4068 
  4069   /* Map the window/widget.  */
  4070   {
  4071     if (horizontal)
  4072       xg_update_horizontal_scrollbar_pos (f, bar->x_window, top,
  4073                                           left, width, max (height, 1));
  4074     else
  4075       xg_update_scrollbar_pos (f, bar->x_window, top,
  4076                                left, width, max (height, 1));
  4077   }
  4078 
  4079   unblock_input ();
  4080   return bar;
  4081 }
  4082 
  4083 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
  4084    nil.  */
  4085 
  4086 static void
  4087 pgtk_scroll_bar_remove (struct scroll_bar *bar)
  4088 {
  4089   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
  4090   block_input ();
  4091 
  4092   xg_remove_scroll_bar (f, bar->x_window);
  4093 
  4094   /* Dissociate this scroll bar from its window.  */
  4095   if (bar->horizontal)
  4096     wset_horizontal_scroll_bar (XWINDOW (bar->window), Qnil);
  4097   else
  4098     wset_vertical_scroll_bar (XWINDOW (bar->window), Qnil);
  4099 
  4100   unblock_input ();
  4101 }
  4102 
  4103 /* Set the handle of the vertical scroll bar for WINDOW to indicate
  4104    that we are displaying PORTION characters out of a total of WHOLE
  4105    characters, starting at POSITION.  If WINDOW has no scroll bar,
  4106    create one.  */
  4107 
  4108 static void
  4109 pgtk_set_vertical_scroll_bar (struct window *w, int portion, int whole,
  4110                               int position)
  4111 {
  4112   struct frame *f = XFRAME (w->frame);
  4113   Lisp_Object barobj;
  4114   struct scroll_bar *bar;
  4115   int top, height, left, width;
  4116   int window_y, window_height;
  4117 
  4118   /* Get window dimensions.  */
  4119   window_box (w, ANY_AREA, 0, &window_y, 0, &window_height);
  4120   top = window_y;
  4121   height = window_height;
  4122   left = WINDOW_SCROLL_BAR_AREA_X (w);
  4123   width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
  4124 
  4125   /* Does the scroll bar exist yet?  */
  4126   if (NILP (w->vertical_scroll_bar))
  4127     {
  4128       if (width > 0 && height > 0)
  4129         {
  4130           block_input ();
  4131           pgtk_clear_area (f, left, top, width, height);
  4132           unblock_input ();
  4133         }
  4134 
  4135       bar = pgtk_scroll_bar_create (w, top, left, width, max (height, 1), false);
  4136     }
  4137   else
  4138     {
  4139       /* It may just need to be moved and resized.  */
  4140       unsigned int mask = 0;
  4141 
  4142       bar = XSCROLL_BAR (w->vertical_scroll_bar);
  4143 
  4144       block_input ();
  4145 
  4146       if (left != bar->left)
  4147         mask |= 1;
  4148       if (top != bar->top)
  4149         mask |= 1;
  4150       if (width != bar->width)
  4151         mask |= 1;
  4152       if (height != bar->height)
  4153         mask |= 1;
  4154 
  4155       /* Move/size the scroll bar widget.  */
  4156       if (mask)
  4157         {
  4158           /* Since toolkit scroll bars are smaller than the space reserved
  4159              for them on the frame, we have to clear "under" them.  */
  4160           if (width > 0 && height > 0)
  4161             pgtk_clear_area (f, left, top, width, height);
  4162           xg_update_scrollbar_pos (f, bar->x_window, top,
  4163                                    left, width, max (height, 1));
  4164         }
  4165 
  4166       /* Remember new settings.  */
  4167       bar->left = left;
  4168       bar->top = top;
  4169       bar->width = width;
  4170       bar->height = height;
  4171 
  4172       unblock_input ();
  4173     }
  4174 
  4175   pgtk_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
  4176 
  4177   XSETVECTOR (barobj, bar);
  4178   wset_vertical_scroll_bar (w, barobj);
  4179 }
  4180 
  4181 static void
  4182 pgtk_set_horizontal_scroll_bar (struct window *w, int portion, int whole,
  4183                                 int position)
  4184 {
  4185   struct frame *f = XFRAME (w->frame);
  4186   Lisp_Object barobj;
  4187   struct scroll_bar *bar;
  4188   int top, height, left, width;
  4189   int window_x, window_width;
  4190   int pixel_width = WINDOW_PIXEL_WIDTH (w);
  4191 
  4192   /* Get window dimensions.  */
  4193   window_box (w, ANY_AREA, &window_x, 0, &window_width, 0);
  4194   left = window_x;
  4195   width = window_width;
  4196   top = WINDOW_SCROLL_BAR_AREA_Y (w);
  4197   height = WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
  4198 
  4199   /* Does the scroll bar exist yet?  */
  4200   if (NILP (w->horizontal_scroll_bar))
  4201     {
  4202       if (width > 0 && height > 0)
  4203         {
  4204           block_input ();
  4205 
  4206           /* Clear also part between window_width and
  4207              WINDOW_PIXEL_WIDTH.  */
  4208           pgtk_clear_area (f, left, top, pixel_width, height);
  4209           unblock_input ();
  4210         }
  4211 
  4212       bar = pgtk_scroll_bar_create (w, top, left, width, height, true);
  4213     }
  4214   else
  4215     {
  4216       /* It may just need to be moved and resized.  */
  4217       unsigned int mask = 0;
  4218 
  4219       bar = XSCROLL_BAR (w->horizontal_scroll_bar);
  4220 
  4221       block_input ();
  4222 
  4223       if (left != bar->left)
  4224         mask |= 1;
  4225       if (top != bar->top)
  4226         mask |= 1;
  4227       if (width != bar->width)
  4228         mask |= 1;
  4229       if (height != bar->height)
  4230         mask |= 1;
  4231 
  4232       /* Move/size the scroll bar widget.  */
  4233       if (mask)
  4234         {
  4235           /* Since toolkit scroll bars are smaller than the space reserved
  4236              for them on the frame, we have to clear "under" them.  */
  4237           if (width > 0 && height > 0)
  4238             pgtk_clear_area (f,
  4239                              WINDOW_LEFT_EDGE_X (w), top,
  4240                              pixel_width - WINDOW_RIGHT_DIVIDER_WIDTH (w),
  4241                              height);
  4242           xg_update_horizontal_scrollbar_pos (f, bar->x_window, top, left,
  4243                                               width, height);
  4244         }
  4245 
  4246       /* Remember new settings.  */
  4247       bar->left = left;
  4248       bar->top = top;
  4249       bar->width = width;
  4250       bar->height = height;
  4251 
  4252       unblock_input ();
  4253     }
  4254 
  4255   pgtk_set_toolkit_horizontal_scroll_bar_thumb (bar, portion, position, whole);
  4256 
  4257   XSETVECTOR (barobj, bar);
  4258   wset_horizontal_scroll_bar (w, barobj);
  4259 }
  4260 
  4261 /* The following three hooks are used when we're doing a thorough
  4262    redisplay of the frame.  We don't explicitly know which scroll bars
  4263    are going to be deleted, because keeping track of when windows go
  4264    away is a real pain - "Can you say set-window-configuration, boys
  4265    and girls?"  Instead, we just assert at the beginning of redisplay
  4266    that *all* scroll bars are to be removed, and then save a scroll bar
  4267    from the fiery pit when we actually redisplay its window.  */
  4268 
  4269 /* Arrange for all scroll bars on FRAME to be removed at the next call
  4270    to `*judge_scroll_bars_hook'.  A scroll bar may be spared if
  4271    `*redeem_scroll_bar_hook' is applied to its window before the judgment.  */
  4272 
  4273 static void
  4274 pgtk_condemn_scroll_bars (struct frame *frame)
  4275 {
  4276   if (!NILP (FRAME_SCROLL_BARS (frame)))
  4277     {
  4278       if (!NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
  4279         {
  4280           /* Prepend scrollbars to already condemned ones.  */
  4281           Lisp_Object last = FRAME_SCROLL_BARS (frame);
  4282 
  4283           while (!NILP (XSCROLL_BAR (last)->next))
  4284             last = XSCROLL_BAR (last)->next;
  4285 
  4286           XSCROLL_BAR (last)->next = FRAME_CONDEMNED_SCROLL_BARS (frame);
  4287           XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = last;
  4288         }
  4289 
  4290       fset_condemned_scroll_bars (frame, FRAME_SCROLL_BARS (frame));
  4291       fset_scroll_bars (frame, Qnil);
  4292     }
  4293 }
  4294 
  4295 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
  4296    Note that WINDOW isn't necessarily condemned at all.  */
  4297 
  4298 static void
  4299 pgtk_redeem_scroll_bar (struct window *w)
  4300 {
  4301   struct scroll_bar *bar;
  4302   Lisp_Object barobj;
  4303   struct frame *f;
  4304 
  4305   /* We can't redeem this window's scroll bar if it doesn't have one.  */
  4306   if (NILP (w->vertical_scroll_bar) && NILP (w->horizontal_scroll_bar))
  4307     emacs_abort ();
  4308 
  4309   if (!NILP (w->vertical_scroll_bar) && WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
  4310     {
  4311       bar = XSCROLL_BAR (w->vertical_scroll_bar);
  4312       /* Unlink it from the condemned list.  */
  4313       f = XFRAME (WINDOW_FRAME (w));
  4314       if (NILP (bar->prev))
  4315         {
  4316           /* If the prev pointer is nil, it must be the first in one of
  4317              the lists.  */
  4318           if (EQ (FRAME_SCROLL_BARS (f), w->vertical_scroll_bar))
  4319             /* It's not condemned.  Everything's fine.  */
  4320             goto horizontal;
  4321           else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
  4322                        w->vertical_scroll_bar))
  4323             fset_condemned_scroll_bars (f, bar->next);
  4324           else
  4325             /* If its prev pointer is nil, it must be at the front of
  4326                one or the other!  */
  4327             emacs_abort ();
  4328         }
  4329       else
  4330         XSCROLL_BAR (bar->prev)->next = bar->next;
  4331 
  4332       if (!NILP (bar->next))
  4333         XSCROLL_BAR (bar->next)->prev = bar->prev;
  4334 
  4335       bar->next = FRAME_SCROLL_BARS (f);
  4336       bar->prev = Qnil;
  4337       XSETVECTOR (barobj, bar);
  4338       fset_scroll_bars (f, barobj);
  4339       if (!NILP (bar->next))
  4340         XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
  4341     }
  4342 
  4343 horizontal:
  4344   if (!NILP (w->horizontal_scroll_bar)
  4345       && WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
  4346     {
  4347       bar = XSCROLL_BAR (w->horizontal_scroll_bar);
  4348       /* Unlink it from the condemned list.  */
  4349       f = XFRAME (WINDOW_FRAME (w));
  4350       if (NILP (bar->prev))
  4351         {
  4352           /* If the prev pointer is nil, it must be the first in one of
  4353              the lists.  */
  4354           if (EQ (FRAME_SCROLL_BARS (f), w->horizontal_scroll_bar))
  4355             /* It's not condemned.  Everything's fine.  */
  4356             return;
  4357           else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
  4358                        w->horizontal_scroll_bar))
  4359             fset_condemned_scroll_bars (f, bar->next);
  4360           else
  4361             /* If its prev pointer is nil, it must be at the front of
  4362                one or the other!  */
  4363             emacs_abort ();
  4364         }
  4365       else
  4366         XSCROLL_BAR (bar->prev)->next = bar->next;
  4367 
  4368       if (!NILP (bar->next))
  4369         XSCROLL_BAR (bar->next)->prev = bar->prev;
  4370 
  4371       bar->next = FRAME_SCROLL_BARS (f);
  4372       bar->prev = Qnil;
  4373       XSETVECTOR (barobj, bar);
  4374       fset_scroll_bars (f, barobj);
  4375       if (!NILP (bar->next))
  4376         XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
  4377     }
  4378 }
  4379 
  4380 /* Remove all scroll bars on FRAME that haven't been saved since the
  4381    last call to `*condemn_scroll_bars_hook'.  */
  4382 
  4383 static void
  4384 pgtk_judge_scroll_bars (struct frame *f)
  4385 {
  4386   Lisp_Object bar, next;
  4387 
  4388   bar = FRAME_CONDEMNED_SCROLL_BARS (f);
  4389 
  4390   /* Clear out the condemned list now so we won't try to process any
  4391      more events on the hapless scroll bars.  */
  4392   fset_condemned_scroll_bars (f, Qnil);
  4393 
  4394   for (; !NILP (bar); bar = next)
  4395     {
  4396       struct scroll_bar *b = XSCROLL_BAR (bar);
  4397 
  4398       pgtk_scroll_bar_remove (b);
  4399 
  4400       next = b->next;
  4401       b->next = b->prev = Qnil;
  4402     }
  4403 
  4404   /* Now there should be no references to the condemned scroll bars,
  4405      and they should get garbage-collected.  */
  4406 }
  4407 
  4408 static void
  4409 set_fullscreen_state (struct frame *f)
  4410 {
  4411   if (!FRAME_GTK_OUTER_WIDGET (f))
  4412     return;
  4413 
  4414   GtkWindow *widget = GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f));
  4415   switch (f->want_fullscreen)
  4416     {
  4417     case FULLSCREEN_NONE:
  4418       gtk_window_unfullscreen (widget);
  4419       gtk_window_unmaximize (widget);
  4420       store_frame_param (f, Qfullscreen, Qnil);
  4421       break;
  4422 
  4423     case FULLSCREEN_BOTH:
  4424       gtk_window_unmaximize (widget);
  4425       gtk_window_fullscreen (widget);
  4426       store_frame_param (f, Qfullscreen, Qfullboth);
  4427       break;
  4428 
  4429     case FULLSCREEN_MAXIMIZED:
  4430       gtk_window_unfullscreen (widget);
  4431       gtk_window_maximize (widget);
  4432       store_frame_param (f, Qfullscreen, Qmaximized);
  4433       break;
  4434 
  4435     case FULLSCREEN_WIDTH:
  4436     case FULLSCREEN_HEIGHT:
  4437       /* Not supported by gtk. Ignore them. */
  4438       break;
  4439     }
  4440 
  4441   f->want_fullscreen = FULLSCREEN_NONE;
  4442 }
  4443 
  4444 static void
  4445 pgtk_fullscreen_hook (struct frame *f)
  4446 {
  4447   if (FRAME_VISIBLE_P (f))
  4448     {
  4449       block_input ();
  4450       set_fullscreen_state (f);
  4451       unblock_input ();
  4452     }
  4453 }
  4454 
  4455 /* This function is called when the last frame on a display is deleted. */
  4456 void
  4457 pgtk_delete_terminal (struct terminal *terminal)
  4458 {
  4459   struct pgtk_display_info *dpyinfo = terminal->display_info.pgtk;
  4460 
  4461   /* Protect against recursive calls.  delete_frame in
  4462      delete_terminal calls us back when it deletes our last frame.  */
  4463   if (!terminal->name)
  4464     return;
  4465 
  4466   block_input ();
  4467 
  4468   pgtk_im_finish (dpyinfo);
  4469 
  4470   /* Normally, the display is available...  */
  4471   if (dpyinfo->gdpy)
  4472     {
  4473       image_destroy_all_bitmaps (dpyinfo);
  4474 
  4475       g_clear_object (&dpyinfo->xg_cursor);
  4476       g_clear_object (&dpyinfo->vertical_scroll_bar_cursor);
  4477       g_clear_object (&dpyinfo->horizontal_scroll_bar_cursor);
  4478       g_clear_object (&dpyinfo->invisible_cursor);
  4479       if (dpyinfo->last_click_event != NULL)
  4480         {
  4481           gdk_event_free (dpyinfo->last_click_event);
  4482           dpyinfo->last_click_event = NULL;
  4483         }
  4484 
  4485       /* Disconnect these handlers before the display closes so
  4486          useless removal signals don't fire.  */
  4487       g_signal_handlers_disconnect_by_func (G_OBJECT (dpyinfo->gdpy),
  4488                                             G_CALLBACK (pgtk_seat_added_cb),
  4489                                             dpyinfo);
  4490       g_signal_handlers_disconnect_by_func (G_OBJECT (dpyinfo->gdpy),
  4491                                             G_CALLBACK (pgtk_seat_removed_cb),
  4492                                             dpyinfo);
  4493       xg_display_close (dpyinfo->gdpy);
  4494 
  4495       dpyinfo->gdpy = NULL;
  4496     }
  4497 
  4498   if (dpyinfo->connection >= 0)
  4499     emacs_close (dpyinfo->connection);
  4500 
  4501   dpyinfo->connection = -1;
  4502 
  4503   delete_keyboard_wait_descriptor (0);
  4504 
  4505   pgtk_delete_display (dpyinfo);
  4506   unblock_input ();
  4507 }
  4508 
  4509 /* Store F's background color into *BGCOLOR.  */
  4510 static void
  4511 pgtk_query_frame_background_color (struct frame *f, Emacs_Color * bgcolor)
  4512 {
  4513   bgcolor->pixel = FRAME_BACKGROUND_PIXEL (f);
  4514   pgtk_query_color (f, bgcolor);
  4515 }
  4516 
  4517 static void
  4518 pgtk_free_pixmap (struct frame *f, Emacs_Pixmap pixmap)
  4519 {
  4520   if (pixmap)
  4521     {
  4522       xfree (pixmap->data);
  4523       xfree (pixmap);
  4524     }
  4525 }
  4526 
  4527 void
  4528 pgtk_focus_frame (struct frame *f, bool noactivate)
  4529 {
  4530   struct pgtk_display_info *dpyinfo;
  4531   GtkWidget *widget;
  4532   GtkWindow *window;
  4533 
  4534   dpyinfo = FRAME_DISPLAY_INFO (f);
  4535 
  4536   if (FRAME_GTK_OUTER_WIDGET (f) && !noactivate)
  4537     {
  4538       /* The user says it is okay to activate the frame.  Call
  4539          gtk_window_present_with_time.  If the timestamp specified
  4540          (actually a display serial on Wayland) is new enough, then
  4541          any Wayland compositor supporting gtk_surface1_present will
  4542          cause the frame to be activated.  */
  4543 
  4544       window = GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f));
  4545       gtk_window_present_with_time (window, dpyinfo->last_user_time);
  4546       return;
  4547     }
  4548 
  4549   widget = FRAME_WIDGET (f);
  4550 
  4551   if (widget)
  4552     gtk_widget_grab_focus (widget);
  4553 }
  4554 
  4555 static void
  4556 set_opacity_recursively (GtkWidget *w, gpointer data)
  4557 {
  4558   gtk_widget_set_opacity (w, *(double *) data);
  4559 
  4560   if (GTK_IS_CONTAINER (w))
  4561     gtk_container_foreach (GTK_CONTAINER (w),
  4562                            set_opacity_recursively, data);
  4563 }
  4564 
  4565 static void
  4566 pgtk_set_frame_alpha (struct frame *f)
  4567 {
  4568   struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  4569   double alpha = 1.0;
  4570   double alpha_min = 1.0;
  4571 
  4572   if (dpyinfo->highlight_frame == f)
  4573     alpha = f->alpha[0];
  4574   else
  4575     alpha = f->alpha[1];
  4576 
  4577   if (alpha < 0.0)
  4578     return;
  4579 
  4580   if (FLOATP (Vframe_alpha_lower_limit))
  4581     alpha_min = XFLOAT_DATA (Vframe_alpha_lower_limit);
  4582   else if (FIXNUMP (Vframe_alpha_lower_limit))
  4583     alpha_min = (XFIXNUM (Vframe_alpha_lower_limit)) / 100.0;
  4584 
  4585   if (alpha > 1.0)
  4586     alpha = 1.0;
  4587   else if (alpha < alpha_min && alpha_min <= 1.0)
  4588     alpha = alpha_min;
  4589 
  4590   set_opacity_recursively (FRAME_WIDGET (f), &alpha);
  4591   /* without this, blending mode is strange on wayland. */
  4592   gtk_widget_queue_resize_no_redraw (FRAME_WIDGET (f));
  4593 }
  4594 
  4595 static void
  4596 frame_highlight (struct frame *f)
  4597 {
  4598   block_input ();
  4599   GtkWidget *w = FRAME_WIDGET (f);
  4600 
  4601   char *css = g_strdup_printf ("decoration { border: solid %dpx #%06x; }",
  4602                                f->border_width,
  4603                                ((unsigned int) FRAME_X_OUTPUT (f)->border_pixel
  4604                                 & 0x00ffffff));
  4605 
  4606   GtkStyleContext *ctxt = gtk_widget_get_style_context (w);
  4607   GtkCssProvider *css_provider = gtk_css_provider_new ();
  4608   gtk_css_provider_load_from_data (css_provider, css, -1, NULL);
  4609   gtk_style_context_add_provider (ctxt, GTK_STYLE_PROVIDER (css_provider),
  4610                                   GTK_STYLE_PROVIDER_PRIORITY_USER);
  4611   g_free (css);
  4612 
  4613   GtkCssProvider *old = FRAME_X_OUTPUT (f)->border_color_css_provider;
  4614   FRAME_X_OUTPUT (f)->border_color_css_provider = css_provider;
  4615   if (old != NULL)
  4616     {
  4617       gtk_style_context_remove_provider (ctxt, GTK_STYLE_PROVIDER (old));
  4618       g_object_unref (old);
  4619     }
  4620 
  4621   unblock_input ();
  4622   gui_update_cursor (f, true);
  4623   pgtk_set_frame_alpha (f);
  4624 }
  4625 
  4626 static void
  4627 frame_unhighlight (struct frame *f)
  4628 {
  4629   GtkWidget *w;
  4630   char *css;
  4631   GtkStyleContext *ctxt;
  4632   GtkCssProvider *css_provider, *old;
  4633 
  4634   block_input ();
  4635 
  4636   w = FRAME_WIDGET (f);
  4637 
  4638   css = g_strdup_printf ("decoration { border: dotted %dpx #ffffff; }",
  4639                          f->border_width);
  4640 
  4641   ctxt = gtk_widget_get_style_context (w);
  4642   css_provider = gtk_css_provider_new ();
  4643   gtk_css_provider_load_from_data (css_provider, css, -1, NULL);
  4644   gtk_style_context_add_provider (ctxt, GTK_STYLE_PROVIDER (css_provider),
  4645                                   GTK_STYLE_PROVIDER_PRIORITY_USER);
  4646   g_free (css);
  4647 
  4648   old = FRAME_X_OUTPUT (f)->border_color_css_provider;
  4649   FRAME_X_OUTPUT (f)->border_color_css_provider = css_provider;
  4650   if (old != NULL)
  4651     {
  4652       gtk_style_context_remove_provider (ctxt, GTK_STYLE_PROVIDER (old));
  4653       g_object_unref (old);
  4654     }
  4655 
  4656   unblock_input ();
  4657   gui_update_cursor (f, true);
  4658   pgtk_set_frame_alpha (f);
  4659 }
  4660 
  4661 
  4662 void
  4663 pgtk_frame_rehighlight (struct pgtk_display_info *dpyinfo)
  4664 {
  4665   struct frame *old_highlight = dpyinfo->highlight_frame;
  4666 
  4667   if (dpyinfo->x_focus_frame)
  4668     {
  4669       dpyinfo->highlight_frame
  4670         = ((FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame)))
  4671            ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame))
  4672            : dpyinfo->x_focus_frame);
  4673       if (!FRAME_LIVE_P (dpyinfo->highlight_frame))
  4674         {
  4675           fset_focus_frame (dpyinfo->x_focus_frame, Qnil);
  4676           dpyinfo->highlight_frame = dpyinfo->x_focus_frame;
  4677         }
  4678     }
  4679   else
  4680     dpyinfo->highlight_frame = 0;
  4681 
  4682   if (old_highlight)
  4683     frame_unhighlight (old_highlight);
  4684   if (dpyinfo->highlight_frame)
  4685     frame_highlight (dpyinfo->highlight_frame);
  4686 }
  4687 
  4688 /* The focus has changed, or we have redirected a frame's focus to
  4689    another frame (this happens when a frame uses a surrogate
  4690    mini-buffer frame).  Shift the highlight as appropriate.
  4691 
  4692    The FRAME argument doesn't necessarily have anything to do with which
  4693    frame is being highlighted or un-highlighted; we only use it to find
  4694    the appropriate X display info.  */
  4695 
  4696 static void
  4697 pgtk_frame_rehighlight_hook (struct frame *frame)
  4698 {
  4699   pgtk_frame_rehighlight (FRAME_DISPLAY_INFO (frame));
  4700 }
  4701 
  4702 /* Set whether or not the mouse pointer should be visible on frame
  4703    F.  */
  4704 static void
  4705 pgtk_toggle_invisible_pointer (struct frame *f, bool invisible)
  4706 {
  4707   Emacs_Cursor cursor;
  4708   if (invisible)
  4709     cursor = FRAME_DISPLAY_INFO (f)->invisible_cursor;
  4710   else
  4711     cursor = f->output_data.pgtk->current_cursor;
  4712   gdk_window_set_cursor (gtk_widget_get_window (FRAME_GTK_WIDGET (f)),
  4713                          cursor);
  4714   f->pointer_invisible = invisible;
  4715 
  4716   /* This is needed to make the pointer visible upon receiving a
  4717      motion notify event.  */
  4718   gdk_display_flush (FRAME_X_DISPLAY (f));
  4719 }
  4720 
  4721 /* The focus has changed.  Update the frames as necessary to reflect
  4722    the new situation.  Note that we can't change the selected frame
  4723    here, because the Lisp code we are interrupting might become confused.
  4724    Each event gets marked with the frame in which it occurred, so the
  4725    Lisp code can tell when the switch took place by examining the events.  */
  4726 
  4727 static void
  4728 pgtk_new_focus_frame (struct pgtk_display_info *dpyinfo, struct frame *frame)
  4729 {
  4730   struct frame *old_focus = dpyinfo->x_focus_frame;
  4731   /* doesn't work on wayland */
  4732 
  4733   if (frame != dpyinfo->x_focus_frame)
  4734     {
  4735       /* Set this before calling other routines, so that they see
  4736          the correct value of x_focus_frame.  */
  4737       dpyinfo->x_focus_frame = frame;
  4738 
  4739       if (old_focus && old_focus->auto_lower)
  4740         if (FRAME_GTK_OUTER_WIDGET (old_focus))
  4741           gdk_window_lower (gtk_widget_get_window
  4742                             (FRAME_GTK_OUTER_WIDGET (old_focus)));
  4743 
  4744       if (dpyinfo->x_focus_frame && dpyinfo->x_focus_frame->auto_raise)
  4745         if (FRAME_GTK_OUTER_WIDGET (dpyinfo->x_focus_frame))
  4746           gdk_window_raise (gtk_widget_get_window
  4747                             (FRAME_GTK_OUTER_WIDGET (dpyinfo->x_focus_frame)));
  4748     }
  4749 
  4750   pgtk_frame_rehighlight (dpyinfo);
  4751 }
  4752 
  4753 static void
  4754 pgtk_buffer_flipping_unblocked_hook (struct frame *f)
  4755 {
  4756   block_input ();
  4757   flip_cr_context (f);
  4758   gtk_widget_queue_draw (FRAME_GTK_WIDGET (f));
  4759   unblock_input ();
  4760 }
  4761 
  4762 static struct terminal *
  4763 pgtk_create_terminal (struct pgtk_display_info *dpyinfo)
  4764 {
  4765   struct terminal *terminal;
  4766 
  4767   terminal = create_terminal (output_pgtk, &pgtk_redisplay_interface);
  4768 
  4769   terminal->display_info.pgtk = dpyinfo;
  4770   dpyinfo->terminal = terminal;
  4771 
  4772   terminal->clear_frame_hook = pgtk_clear_frame;
  4773   terminal->ring_bell_hook = pgtk_ring_bell;
  4774   terminal->toggle_invisible_pointer_hook = pgtk_toggle_invisible_pointer;
  4775   terminal->update_begin_hook = pgtk_update_begin;
  4776   terminal->update_end_hook = pgtk_update_end;
  4777   terminal->read_socket_hook = pgtk_read_socket;
  4778   terminal->frame_up_to_date_hook = pgtk_frame_up_to_date;
  4779   terminal->mouse_position_hook = pgtk_mouse_position;
  4780   terminal->frame_rehighlight_hook = pgtk_frame_rehighlight_hook;
  4781   terminal->buffer_flipping_unblocked_hook = pgtk_buffer_flipping_unblocked_hook;
  4782   terminal->frame_raise_lower_hook = pgtk_frame_raise_lower;
  4783   terminal->frame_visible_invisible_hook = pgtk_make_frame_visible_invisible;
  4784   terminal->fullscreen_hook = pgtk_fullscreen_hook;
  4785   terminal->menu_show_hook = pgtk_menu_show;
  4786   terminal->activate_menubar_hook = pgtk_activate_menubar;
  4787   terminal->popup_dialog_hook = pgtk_popup_dialog;
  4788   terminal->change_tab_bar_height_hook = pgtk_change_tab_bar_height;
  4789   terminal->set_vertical_scroll_bar_hook = pgtk_set_vertical_scroll_bar;
  4790   terminal->set_horizontal_scroll_bar_hook = pgtk_set_horizontal_scroll_bar;
  4791   terminal->condemn_scroll_bars_hook = pgtk_condemn_scroll_bars;
  4792   terminal->redeem_scroll_bar_hook = pgtk_redeem_scroll_bar;
  4793   terminal->judge_scroll_bars_hook = pgtk_judge_scroll_bars;
  4794   terminal->get_string_resource_hook = pgtk_get_string_resource;
  4795   terminal->delete_frame_hook = pgtk_destroy_window;
  4796   terminal->delete_terminal_hook = pgtk_delete_terminal;
  4797   terminal->query_frame_background_color = pgtk_query_frame_background_color;
  4798   terminal->defined_color_hook = pgtk_defined_color;
  4799   terminal->set_new_font_hook = pgtk_new_font;
  4800   terminal->set_bitmap_icon_hook = pgtk_bitmap_icon;
  4801   terminal->implicit_set_name_hook = pgtk_implicitly_set_name;
  4802   terminal->iconify_frame_hook = pgtk_iconify_frame;
  4803   terminal->set_scroll_bar_default_width_hook
  4804     = pgtk_set_scroll_bar_default_width;
  4805   terminal->set_scroll_bar_default_height_hook
  4806     = pgtk_set_scroll_bar_default_height;
  4807   terminal->set_window_size_hook = pgtk_set_window_size;
  4808   terminal->query_colors = pgtk_query_colors;
  4809   terminal->get_focus_frame = pgtk_get_focus_frame;
  4810   terminal->focus_frame_hook = pgtk_focus_frame;
  4811   terminal->set_frame_offset_hook = pgtk_set_offset;
  4812   terminal->free_pixmap = pgtk_free_pixmap;
  4813   terminal->toolkit_position_hook = pgtk_toolkit_position;
  4814 
  4815   /* Other hooks are NULL by default.  */
  4816 
  4817   return terminal;
  4818 }
  4819 
  4820 struct pgtk_window_is_of_frame_recursive_t
  4821 {
  4822   GdkWindow *window;
  4823   bool result;
  4824   GtkWidget *emacs_gtk_fixed;   /* stop on emacsgtkfixed other than this. */
  4825 };
  4826 
  4827 static void
  4828 pgtk_window_is_of_frame_recursive (GtkWidget *widget, gpointer data)
  4829 {
  4830   struct pgtk_window_is_of_frame_recursive_t *datap = data;
  4831 
  4832   if (datap->result)
  4833     return;
  4834 
  4835   if (EMACS_IS_FIXED (widget) && widget != datap->emacs_gtk_fixed)
  4836     return;
  4837 
  4838   if (gtk_widget_get_window (widget) == datap->window)
  4839     {
  4840       datap->result = true;
  4841       return;
  4842     }
  4843 
  4844   if (GTK_IS_CONTAINER (widget))
  4845     gtk_container_foreach (GTK_CONTAINER (widget),
  4846                            pgtk_window_is_of_frame_recursive, datap);
  4847 }
  4848 
  4849 static bool
  4850 pgtk_window_is_of_frame (struct frame *f, GdkWindow *window)
  4851 {
  4852   struct pgtk_window_is_of_frame_recursive_t data;
  4853   data.window = window;
  4854   data.result = false;
  4855   data.emacs_gtk_fixed = FRAME_GTK_WIDGET (f);
  4856   pgtk_window_is_of_frame_recursive (FRAME_WIDGET (f), &data);
  4857   return data.result;
  4858 }
  4859 
  4860 /* Like x_window_to_frame but also compares the window with the widget's
  4861    windows.  */
  4862 static struct frame *
  4863 pgtk_any_window_to_frame (GdkWindow *window)
  4864 {
  4865   Lisp_Object tail, frame;
  4866   struct frame *f, *found = NULL;
  4867 
  4868   if (window == NULL)
  4869     return NULL;
  4870 
  4871   FOR_EACH_FRAME (tail, frame)
  4872     {
  4873       if (found)
  4874         break;
  4875       f = XFRAME (frame);
  4876       if (FRAME_PGTK_P (f))
  4877         {
  4878           if (pgtk_window_is_of_frame (f, window))
  4879             found = f;
  4880         }
  4881     }
  4882 
  4883   return found;
  4884 }
  4885 
  4886 static gboolean
  4887 pgtk_handle_event (GtkWidget *widget, GdkEvent *event, gpointer *data)
  4888 {
  4889   struct frame *f;
  4890   union buffered_input_event inev;
  4891   GtkWidget *frame_widget;
  4892   gint x, y;
  4893 
  4894   if (event->type == GDK_TOUCHPAD_PINCH
  4895       && (event->touchpad_pinch.phase
  4896           != GDK_TOUCHPAD_GESTURE_PHASE_END))
  4897     {
  4898       f = pgtk_any_window_to_frame (gtk_widget_get_window (widget));
  4899       frame_widget = FRAME_GTK_WIDGET (f);
  4900 
  4901       gtk_widget_translate_coordinates (widget, frame_widget,
  4902                                         lrint (event->touchpad_pinch.x),
  4903                                         lrint (event->touchpad_pinch.y),
  4904                                         &x, &y);
  4905       if (f)
  4906         {
  4907 
  4908           inev.ie.kind = PINCH_EVENT;
  4909           XSETFRAME (inev.ie.frame_or_window, f);
  4910           XSETINT (inev.ie.x, x);
  4911           XSETINT (inev.ie.y, y);
  4912           inev.ie.arg = list4 (make_float (event->touchpad_pinch.dx),
  4913                                make_float (event->touchpad_pinch.dy),
  4914                                make_float (event->touchpad_pinch.scale),
  4915                                make_float (event->touchpad_pinch.angle_delta));
  4916           inev.ie.modifiers = pgtk_gtk_to_emacs_modifiers (FRAME_DISPLAY_INFO (f),
  4917                                                            event->touchpad_pinch.state);
  4918           inev.ie.device
  4919             = pgtk_get_device_for_event (FRAME_DISPLAY_INFO (f), event);
  4920           evq_enqueue (&inev);
  4921         }
  4922 
  4923       return TRUE;
  4924     }
  4925   return FALSE;
  4926 }
  4927 
  4928 static void
  4929 pgtk_fill_rectangle (struct frame *f, unsigned long color, int x, int y,
  4930                      int width, int height, bool respect_alpha_background)
  4931 {
  4932   cairo_t *cr;
  4933   cr = pgtk_begin_cr_clip (f);
  4934   pgtk_set_cr_source_with_color (f, color, respect_alpha_background);
  4935   cairo_rectangle (cr, x, y, width, height);
  4936   cairo_fill (cr);
  4937   pgtk_end_cr_clip (f);
  4938 }
  4939 
  4940 void
  4941 pgtk_clear_under_internal_border (struct frame *f)
  4942 {
  4943   if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0
  4944       && (!FRAME_GTK_OUTER_WIDGET (f)
  4945           || gtk_widget_get_realized (FRAME_GTK_OUTER_WIDGET (f))))
  4946     {
  4947       int border = FRAME_INTERNAL_BORDER_WIDTH (f);
  4948       int width = FRAME_PIXEL_WIDTH (f);
  4949       int height = FRAME_PIXEL_HEIGHT (f);
  4950       int margin = FRAME_TOP_MARGIN_HEIGHT (f);
  4951       int bottom_margin = FRAME_BOTTOM_MARGIN_HEIGHT (f);
  4952       int face_id = (FRAME_PARENT_FRAME (f)
  4953                      ? (!NILP (Vface_remapping_alist)
  4954                         ? lookup_basic_face (NULL, f,
  4955                                              CHILD_FRAME_BORDER_FACE_ID)
  4956                         : CHILD_FRAME_BORDER_FACE_ID)
  4957                      : (!NILP (Vface_remapping_alist)
  4958                         ? lookup_basic_face (NULL, f,
  4959                                              INTERNAL_BORDER_FACE_ID)
  4960                         : INTERNAL_BORDER_FACE_ID));
  4961       struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
  4962 
  4963       block_input ();
  4964 
  4965       if (face)
  4966         {
  4967           fill_background_by_face (f, face, 0, margin, width, border);
  4968           fill_background_by_face (f, face, 0, 0, border, height);
  4969           fill_background_by_face (f, face, width - border, 0, border,
  4970                                    height);
  4971           fill_background_by_face (f, face, 0, (height
  4972                                                 - bottom_margin
  4973                                                 - border),
  4974                                    width, border);
  4975         }
  4976       else
  4977         {
  4978           pgtk_clear_area (f, 0, 0, border, height);
  4979           pgtk_clear_area (f, 0, margin, width, border);
  4980           pgtk_clear_area (f, width - border, 0, border, height);
  4981           pgtk_clear_area (f, 0, height - bottom_margin - border,
  4982                            width, border);
  4983         }
  4984 
  4985       unblock_input ();
  4986     }
  4987 }
  4988 
  4989 static gboolean
  4990 pgtk_handle_draw (GtkWidget *widget, cairo_t *cr, gpointer *data)
  4991 {
  4992   struct frame *f;
  4993 
  4994   GdkWindow *win = gtk_widget_get_window (widget);
  4995 
  4996   if (win != NULL)
  4997     {
  4998       cairo_surface_t *src = NULL;
  4999       f = pgtk_any_window_to_frame (win);
  5000       if (f != NULL)
  5001         {
  5002           src = FRAME_X_OUTPUT (f)->cr_surface_visible_bell;
  5003           if (src == NULL && FRAME_CR_ACTIVE_CONTEXT (f) != NULL)
  5004             src = cairo_get_target (FRAME_CR_ACTIVE_CONTEXT (f));
  5005         }
  5006       if (src != NULL)
  5007         {
  5008           cairo_set_source_surface (cr, src, 0, 0);
  5009           cairo_paint (cr);
  5010         }
  5011     }
  5012   return FALSE;
  5013 }
  5014 
  5015 static void
  5016 size_allocate (GtkWidget *widget, GtkAllocation *alloc,
  5017                gpointer user_data)
  5018 {
  5019   struct frame *f = pgtk_any_window_to_frame (gtk_widget_get_window (widget));
  5020 
  5021   if (!f)
  5022     f = user_data;
  5023 
  5024   if (f)
  5025     {
  5026       xg_frame_resized (f, alloc->width, alloc->height);
  5027       pgtk_cr_update_surface_desired_size (f, alloc->width, alloc->height, false);
  5028     }
  5029 }
  5030 
  5031 static void
  5032 get_modifier_values (int *mod_ctrl, int *mod_meta, int *mod_alt,
  5033                      int *mod_hyper, int *mod_super)
  5034 {
  5035   Lisp_Object tem;
  5036 
  5037   *mod_ctrl = ctrl_modifier;
  5038   *mod_meta = meta_modifier;
  5039   *mod_alt = alt_modifier;
  5040   *mod_hyper = hyper_modifier;
  5041   *mod_super = super_modifier;
  5042 
  5043   tem = Fget (Vx_ctrl_keysym, Qmodifier_value);
  5044   if (INTEGERP (tem))
  5045     *mod_ctrl = XFIXNUM (tem) & INT_MAX;
  5046   tem = Fget (Vx_alt_keysym, Qmodifier_value);
  5047   if (INTEGERP (tem))
  5048     *mod_alt = XFIXNUM (tem) & INT_MAX;
  5049   tem = Fget (Vx_meta_keysym, Qmodifier_value);
  5050   if (INTEGERP (tem))
  5051     *mod_meta = XFIXNUM (tem) & INT_MAX;
  5052   tem = Fget (Vx_hyper_keysym, Qmodifier_value);
  5053   if (INTEGERP (tem))
  5054     *mod_hyper = XFIXNUM (tem) & INT_MAX;
  5055   tem = Fget (Vx_super_keysym, Qmodifier_value);
  5056   if (INTEGERP (tem))
  5057     *mod_super = XFIXNUM (tem) & INT_MAX;
  5058 }
  5059 
  5060 int
  5061 pgtk_gtk_to_emacs_modifiers (struct pgtk_display_info *dpyinfo, int state)
  5062 {
  5063   int mod_ctrl;
  5064   int mod_meta;
  5065   int mod_alt;
  5066   int mod_hyper;
  5067   int mod_super;
  5068   int mod;
  5069 
  5070   get_modifier_values (&mod_ctrl, &mod_meta, &mod_alt, &mod_hyper,
  5071                        &mod_super);
  5072 
  5073   mod = 0;
  5074   if (state & GDK_SHIFT_MASK)
  5075     mod |= shift_modifier;
  5076   if (state & GDK_CONTROL_MASK)
  5077     mod |= mod_ctrl;
  5078   if (state & GDK_META_MASK || state & GDK_MOD1_MASK)
  5079     mod |= mod_meta;
  5080   if (state & GDK_SUPER_MASK)
  5081     mod |= mod_super;
  5082   if (state & GDK_HYPER_MASK)
  5083     mod |= mod_hyper;
  5084 
  5085   return mod;
  5086 }
  5087 
  5088 int
  5089 pgtk_emacs_to_gtk_modifiers (struct pgtk_display_info *dpyinfo, int state)
  5090 {
  5091   int mod_ctrl;
  5092   int mod_meta;
  5093   int mod_alt;
  5094   int mod_hyper;
  5095   int mod_super;
  5096   int mask;
  5097 
  5098   get_modifier_values (&mod_ctrl, &mod_meta, &mod_alt, &mod_hyper,
  5099                        &mod_super);
  5100 
  5101   mask = 0;
  5102   if (state & mod_super)
  5103     mask |= GDK_SUPER_MASK;
  5104   if (state & mod_hyper)
  5105     mask |= GDK_HYPER_MASK;
  5106   if (state & shift_modifier)
  5107     mask |= GDK_SHIFT_MASK;
  5108   if (state & mod_ctrl)
  5109     mask |= GDK_CONTROL_MASK;
  5110   if (state & mod_meta)
  5111     mask |= GDK_MOD1_MASK;
  5112   return mask;
  5113 }
  5114 
  5115 #define IsCursorKey(keysym)       (0xff50 <= (keysym) && (keysym) < 0xff60)
  5116 #define IsMiscFunctionKey(keysym) (0xff60 <= (keysym) && (keysym) < 0xff6c)
  5117 #define IsKeypadKey(keysym)       (0xff80 <= (keysym) && (keysym) < 0xffbe)
  5118 #define IsFunctionKey(keysym)     (0xffbe <= (keysym) && (keysym) < 0xffe1)
  5119 #define IsModifierKey(keysym)                                                   \
  5120   ((((keysym) >= GDK_KEY_Shift_L) && ((keysym) <= GDK_KEY_Hyper_R))             \
  5121    || (((keysym) >= GDK_KEY_ISO_Lock) && ((keysym) <= GDK_KEY_ISO_Level5_Lock)) \
  5122    || ((keysym) == GDK_KEY_Mode_switch)                                         \
  5123    || ((keysym) == GDK_KEY_Num_Lock))
  5124 
  5125 
  5126 void
  5127 pgtk_enqueue_string (struct frame *f, gchar *str)
  5128 {
  5129   gunichar *ustr, *uptr;
  5130 
  5131   uptr = ustr = g_utf8_to_ucs4 (str, -1, NULL, NULL, NULL);
  5132   if (ustr == NULL)
  5133     return;
  5134   for (; *ustr != 0; ustr++)
  5135     {
  5136       union buffered_input_event inev;
  5137       Lisp_Object c = make_fixnum (*ustr);
  5138       EVENT_INIT (inev.ie);
  5139       inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFIXNAT (c))
  5140                       ? ASCII_KEYSTROKE_EVENT
  5141                       : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
  5142       inev.ie.arg = Qnil;
  5143       inev.ie.code = XFIXNAT (c);
  5144       XSETFRAME (inev.ie.frame_or_window, f);
  5145       inev.ie.modifiers = 0;
  5146       inev.ie.timestamp = 0;
  5147       evq_enqueue (&inev);
  5148     }
  5149 
  5150   g_free (uptr);
  5151 }
  5152 
  5153 void
  5154 pgtk_enqueue_preedit (struct frame *f, Lisp_Object preedit)
  5155 {
  5156   union buffered_input_event inev;
  5157   EVENT_INIT (inev.ie);
  5158   inev.ie.kind = PREEDIT_TEXT_EVENT;
  5159   inev.ie.arg = preedit;
  5160   inev.ie.code = 0;
  5161   XSETFRAME (inev.ie.frame_or_window, f);
  5162   inev.ie.modifiers = 0;
  5163   inev.ie.timestamp = 0;
  5164   evq_enqueue (&inev);
  5165 }
  5166 
  5167 static gboolean
  5168 key_press_event (GtkWidget *widget, GdkEvent *event, gpointer *user_data)
  5169 {
  5170   union buffered_input_event inev;
  5171   ptrdiff_t nbytes;
  5172   Mouse_HLInfo *hlinfo;
  5173   struct frame *f;
  5174   struct pgtk_display_info *dpyinfo;
  5175 
  5176   f = pgtk_any_window_to_frame (gtk_widget_get_window (widget));
  5177   EVENT_INIT (inev.ie);
  5178   hlinfo = MOUSE_HL_INFO (f);
  5179   nbytes = 0;
  5180 
  5181   /* If mouse-highlight is an integer, input clears out
  5182      mouse highlighting.  */
  5183   if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
  5184     {
  5185       clear_mouse_face (hlinfo);
  5186       hlinfo->mouse_face_hidden = true;
  5187     }
  5188 
  5189   if (f != 0)
  5190     {
  5191       guint keysym, orig_keysym;
  5192       /* al%imercury@uunet.uu.net says that making this 81
  5193          instead of 80 fixed a bug whereby meta chars made
  5194          his Emacs hang.
  5195 
  5196          It seems that some version of XmbLookupString has
  5197          a bug of not returning XBufferOverflow in
  5198          status_return even if the input is too long to
  5199          fit in 81 bytes.  So, we must prepare sufficient
  5200          bytes for copy_buffer.  513 bytes (256 chars for
  5201          two-byte character set) seems to be a fairly good
  5202          approximation.  -- 2000.8.10 handa@etl.go.jp  */
  5203       unsigned char copy_buffer[513];
  5204       unsigned char *copy_bufptr = copy_buffer;
  5205       int copy_bufsiz = sizeof (copy_buffer);
  5206       int modifiers;
  5207       Lisp_Object c;
  5208       guint state;
  5209 
  5210       dpyinfo = FRAME_DISPLAY_INFO (f);
  5211 
  5212       /* Set the last user time for pgtk_focus_frame to work
  5213          correctly.  */
  5214       dpyinfo->last_user_time = event->key.time;
  5215 
  5216       state = event->key.state;
  5217 
  5218       /* While super is pressed, the input method will always always
  5219          resend the key events ignoring super.  As a workaround, don't
  5220          filter key events with super or hyper pressed.  */
  5221       if (!(event->key.state & (GDK_SUPER_MASK | GDK_HYPER_MASK)))
  5222         {
  5223           if (pgtk_im_filter_keypress (f, &event->key))
  5224             return TRUE;
  5225         }
  5226 
  5227       state |= pgtk_emacs_to_gtk_modifiers (FRAME_DISPLAY_INFO (f),
  5228                                             extra_keyboard_modifiers);
  5229       modifiers = state;
  5230 
  5231       /* This will have to go some day...  */
  5232 
  5233       /* make_lispy_event turns chars into control chars.
  5234          Don't do it here because XLookupString is too eager.  */
  5235       state &= ~GDK_CONTROL_MASK;
  5236       state &= ~(GDK_META_MASK
  5237                  | GDK_SUPER_MASK | GDK_HYPER_MASK | GDK_MOD1_MASK);
  5238 
  5239       nbytes = event->key.length;
  5240       if (nbytes > copy_bufsiz)
  5241         nbytes = copy_bufsiz;
  5242       memcpy (copy_bufptr, event->key.string, nbytes);
  5243 
  5244       keysym = event->key.keyval;
  5245       orig_keysym = keysym;
  5246 
  5247       /* Common for all keysym input events.  */
  5248       XSETFRAME (inev.ie.frame_or_window, f);
  5249       inev.ie.modifiers
  5250         = pgtk_gtk_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), modifiers);
  5251       inev.ie.timestamp = event->key.time;
  5252 
  5253       /* First deal with keysyms which have defined
  5254          translations to characters.  */
  5255       if (keysym >= 32 && keysym < 128)
  5256         /* Avoid explicitly decoding each ASCII character.  */
  5257         {
  5258           inev.ie.kind = ASCII_KEYSTROKE_EVENT;
  5259           inev.ie.code = keysym;
  5260 
  5261           inev.ie.device
  5262             = pgtk_get_device_for_event (FRAME_DISPLAY_INFO (f), event);
  5263           goto done;
  5264         }
  5265 
  5266       /* Keysyms directly mapped to Unicode characters.  */
  5267       if (keysym >= 0x01000000 && keysym <= 0x0110FFFF)
  5268         {
  5269           if (keysym < 0x01000080)
  5270             inev.ie.kind = ASCII_KEYSTROKE_EVENT;
  5271           else
  5272             inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
  5273           inev.ie.code = keysym & 0xFFFFFF;
  5274 
  5275           inev.ie.device
  5276             = pgtk_get_device_for_event (FRAME_DISPLAY_INFO (f), event);
  5277           goto done;
  5278         }
  5279 
  5280       /* Now non-ASCII.  */
  5281       if (HASH_TABLE_P (Vpgtk_keysym_table)
  5282           && (c = Fgethash (make_fixnum (keysym),
  5283                             Vpgtk_keysym_table, Qnil), FIXNATP (c)))
  5284         {
  5285           inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFIXNAT (c))
  5286                           ? ASCII_KEYSTROKE_EVENT
  5287                           : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
  5288           inev.ie.code = XFIXNAT (c);
  5289 
  5290           inev.ie.device
  5291             = pgtk_get_device_for_event (FRAME_DISPLAY_INFO (f), event);
  5292           goto done;
  5293         }
  5294 
  5295       /* Random non-modifier sorts of keysyms.  */
  5296       if (((keysym >= GDK_KEY_BackSpace && keysym <= GDK_KEY_Escape)
  5297            || keysym == GDK_KEY_Delete
  5298 #ifdef GDK_KEY_ISO_Left_Tab
  5299            || (keysym >= GDK_KEY_ISO_Left_Tab && keysym <= GDK_KEY_ISO_Enter)
  5300 #endif
  5301            || IsCursorKey (keysym)      /* 0xff50 <= x < 0xff60 */
  5302            || IsMiscFunctionKey (keysym)        /* 0xff60 <= x < VARIES */
  5303 #ifdef HPUX
  5304            /* This recognizes the "extended function
  5305               keys".  It seems there's no cleaner way.
  5306               Test IsModifierKey to avoid handling
  5307               mode_switch incorrectly.  */
  5308            || (GDK_KEY_Select <= keysym && keysym < GDK_KEY_KP_Space)
  5309 #endif
  5310 #ifdef GDK_KEY_dead_circumflex
  5311            || orig_keysym == GDK_KEY_dead_circumflex
  5312 #endif
  5313 #ifdef GDK_KEY_dead_grave
  5314            || orig_keysym == GDK_KEY_dead_grave
  5315 #endif
  5316 #ifdef GDK_KEY_dead_tilde
  5317            || orig_keysym == GDK_KEY_dead_tilde
  5318 #endif
  5319 #ifdef GDK_KEY_dead_diaeresis
  5320            || orig_keysym == GDK_KEY_dead_diaeresis
  5321 #endif
  5322 #ifdef GDK_KEY_dead_macron
  5323            || orig_keysym == GDK_KEY_dead_macron
  5324 #endif
  5325 #ifdef GDK_KEY_dead_degree
  5326            || orig_keysym == GDK_KEY_dead_degree
  5327 #endif
  5328 #ifdef GDK_KEY_dead_acute
  5329            || orig_keysym == GDK_KEY_dead_acute
  5330 #endif
  5331 #ifdef GDK_KEY_dead_cedilla
  5332            || orig_keysym == GDK_KEY_dead_cedilla
  5333 #endif
  5334 #ifdef GDK_KEY_dead_breve
  5335            || orig_keysym == GDK_KEY_dead_breve
  5336 #endif
  5337 #ifdef GDK_KEY_dead_ogonek
  5338            || orig_keysym == GDK_KEY_dead_ogonek
  5339 #endif
  5340 #ifdef GDK_KEY_dead_caron
  5341            || orig_keysym == GDK_KEY_dead_caron
  5342 #endif
  5343 #ifdef GDK_KEY_dead_doubleacute
  5344            || orig_keysym == GDK_KEY_dead_doubleacute
  5345 #endif
  5346 #ifdef GDK_KEY_dead_abovedot
  5347            || orig_keysym == GDK_KEY_dead_abovedot
  5348 #endif
  5349            || IsKeypadKey (keysym)      /* 0xff80 <= x < 0xffbe */
  5350            || IsFunctionKey (keysym)    /* 0xffbe <= x < 0xffe1 */
  5351            /* Any "vendor-specific" key is ok.  */
  5352            || (orig_keysym & (1 << 28))
  5353            || (keysym != GDK_KEY_VoidSymbol && nbytes == 0))
  5354           && !(event->key.is_modifier
  5355                || IsModifierKey (orig_keysym)
  5356                /* The symbols from GDK_KEY_ISO_Lock
  5357                   to GDK_KEY_ISO_Last_Group_Lock
  5358                   don't have real modifiers but
  5359                   should be treated similarly to
  5360                   Mode_switch by Emacs. */
  5361 #if defined GDK_KEY_ISO_Lock && defined GDK_KEY_ISO_Last_Group_Lock
  5362                || (GDK_KEY_ISO_Lock <= orig_keysym
  5363                    && orig_keysym <= GDK_KEY_ISO_Last_Group_Lock)
  5364 #endif
  5365           ))
  5366         {
  5367           /* make_lispy_event will convert this to a symbolic
  5368              key.  */
  5369           inev.ie.kind = NON_ASCII_KEYSTROKE_EVENT;
  5370           inev.ie.code = keysym;
  5371 
  5372           inev.ie.device
  5373             = pgtk_get_device_for_event (FRAME_DISPLAY_INFO (f), event);
  5374           goto done;
  5375         }
  5376 
  5377       {
  5378         inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
  5379         inev.ie.arg = make_unibyte_string ((char *) copy_bufptr, nbytes);
  5380         inev.ie.device
  5381           = pgtk_get_device_for_event (FRAME_DISPLAY_INFO (f), event);
  5382 
  5383         if (keysym == GDK_KEY_VoidSymbol)
  5384           goto done;
  5385       }
  5386     }
  5387 
  5388 done:
  5389   if (inev.ie.kind != NO_EVENT)
  5390     {
  5391       XSETFRAME (inev.ie.frame_or_window, f);
  5392       evq_enqueue (&inev);
  5393     }
  5394 
  5395   return TRUE;
  5396 }
  5397 
  5398 static struct pgtk_display_info *
  5399 pgtk_display_info_for_display (GdkDisplay *dpy)
  5400 {
  5401   struct pgtk_display_info *dpyinfo;
  5402 
  5403   for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
  5404     {
  5405       if (dpyinfo->display == dpy)
  5406         return dpyinfo;
  5407     }
  5408 
  5409   return NULL;
  5410 }
  5411 
  5412 static gboolean
  5413 key_release_event (GtkWidget *widget,
  5414                    GdkEvent *event,
  5415                    gpointer *user_data)
  5416 {
  5417   GdkDisplay *display;
  5418   struct pgtk_display_info *dpyinfo;
  5419 
  5420   display = gtk_widget_get_display (widget);
  5421   dpyinfo = pgtk_display_info_for_display (display);
  5422 
  5423   if (dpyinfo)
  5424     /* This is needed on Wayland because of some brain dead
  5425        compositors.  Without them, we would not have to keep track of
  5426        the serial of key release events.  */
  5427     dpyinfo->last_user_time = event->key.time;
  5428 
  5429   return TRUE;
  5430 }
  5431 
  5432 static gboolean
  5433 configure_event (GtkWidget *widget,
  5434                  GdkEvent *event,
  5435                  gpointer *user_data)
  5436 {
  5437   struct frame *f = pgtk_any_window_to_frame (event->configure.window);
  5438 
  5439   if (f && widget == FRAME_GTK_OUTER_WIDGET (f))
  5440     {
  5441       if (any_help_event_p)
  5442         {
  5443           Lisp_Object frame;
  5444           if (f)
  5445             XSETFRAME (frame, f);
  5446           else
  5447             frame = Qnil;
  5448           help_echo_string = Qnil;
  5449           gen_help_event (Qnil, frame, Qnil, Qnil, 0);
  5450         }
  5451 
  5452       if (f->win_gravity == NorthWestGravity)
  5453         gtk_window_get_position (GTK_WINDOW (widget),
  5454                                  &f->left_pos, &f->top_pos);
  5455       else
  5456         {
  5457           f->top_pos = event->configure.y;
  5458           f->left_pos = event->configure.x;
  5459         }
  5460     }
  5461   return FALSE;
  5462 }
  5463 
  5464 static gboolean
  5465 map_event (GtkWidget *widget,
  5466            GdkEvent *event,
  5467            gpointer *user_data)
  5468 {
  5469   struct frame *f = pgtk_any_window_to_frame (event->any.window);
  5470   union buffered_input_event inev;
  5471 
  5472   EVENT_INIT (inev.ie);
  5473   inev.ie.kind = NO_EVENT;
  5474   inev.ie.arg = Qnil;
  5475 
  5476   if (f)
  5477     {
  5478       bool iconified = FRAME_ICONIFIED_P (f);
  5479 
  5480       /* Check if fullscreen was specified before we where mapped the
  5481          first time, i.e. from the command line.  */
  5482       if (!FRAME_X_OUTPUT (f)->has_been_visible)
  5483         set_fullscreen_state (f);
  5484 
  5485       if (!iconified)
  5486         {
  5487           /* The `z-group' is reset every time a frame becomes
  5488              invisible.  Handle this here.  */
  5489           if (FRAME_Z_GROUP (f) == z_group_above)
  5490             pgtk_set_z_group (f, Qabove, Qnil);
  5491           else if (FRAME_Z_GROUP (f) == z_group_below)
  5492             pgtk_set_z_group (f, Qbelow, Qnil);
  5493         }
  5494 
  5495       SET_FRAME_VISIBLE (f, 1);
  5496       SET_FRAME_ICONIFIED (f, false);
  5497       FRAME_X_OUTPUT (f)->has_been_visible = true;
  5498 
  5499       if (iconified)
  5500         {
  5501           inev.ie.kind = DEICONIFY_EVENT;
  5502           XSETFRAME (inev.ie.frame_or_window, f);
  5503         }
  5504     }
  5505 
  5506   if (inev.ie.kind != NO_EVENT)
  5507     evq_enqueue (&inev);
  5508   return FALSE;
  5509 }
  5510 
  5511 static gboolean
  5512 window_state_event (GtkWidget *widget,
  5513                     GdkEvent *event,
  5514                     gpointer *user_data)
  5515 {
  5516   struct frame *f = pgtk_any_window_to_frame (event->window_state.window);
  5517   GdkWindowState new_state;
  5518   union buffered_input_event inev;
  5519 
  5520   new_state = event->window_state.new_window_state;
  5521 
  5522   EVENT_INIT (inev.ie);
  5523   inev.ie.kind = NO_EVENT;
  5524   inev.ie.arg = Qnil;
  5525 
  5526   if (new_state & GDK_WINDOW_STATE_FULLSCREEN)
  5527     store_frame_param (f, Qfullscreen, Qfullboth);
  5528   else if (new_state & GDK_WINDOW_STATE_MAXIMIZED)
  5529     store_frame_param (f, Qfullscreen, Qmaximized);
  5530   else if ((new_state & GDK_WINDOW_STATE_TOP_TILED)
  5531            && (new_state & GDK_WINDOW_STATE_BOTTOM_TILED)
  5532            && !(new_state & GDK_WINDOW_STATE_TOP_RESIZABLE)
  5533            && !(new_state & GDK_WINDOW_STATE_BOTTOM_RESIZABLE))
  5534     store_frame_param (f, Qfullscreen, Qfullheight);
  5535   else if ((new_state & GDK_WINDOW_STATE_LEFT_TILED)
  5536            && (new_state & GDK_WINDOW_STATE_RIGHT_TILED)
  5537            && !(new_state & GDK_WINDOW_STATE_LEFT_RESIZABLE)
  5538            && !(new_state & GDK_WINDOW_STATE_RIGHT_RESIZABLE))
  5539     store_frame_param (f, Qfullscreen, Qfullwidth);
  5540   else
  5541     store_frame_param (f, Qfullscreen, Qnil);
  5542 
  5543   /* The Wayland protocol provides no way for the client to know
  5544      whether or not one of its toplevels has actually been
  5545      deiconified.  It only provides a request for clients to iconify a
  5546      toplevel, without even the ability to determine whether or not
  5547      the iconification request was rejected by the display server.
  5548 
  5549      GDK computes the iconified state by sending a window state event
  5550      containing only GDK_WINDOW_STATE_ICONIFIED immediately after
  5551      gtk_window_iconify is called.  That is error-prone if the request
  5552      to iconify the frame was rejected by the display server, but is
  5553      not the main problem here, as Wayland compositors only rarely
  5554      reject such requests.  GDK also assumes that it can clear the
  5555      iconified state upon receiving the next toplevel configure event
  5556      from the display server.  Unfortunately, such events can be sent
  5557      by Wayland compositors while the frame is iconified, and may also
  5558      not be sent upon deiconification.  So, no matter what Emacs does,
  5559      the iconification state of a frame is likely to be wrong under
  5560      one situation or another.  */
  5561 
  5562   if (new_state & GDK_WINDOW_STATE_ICONIFIED)
  5563     {
  5564       SET_FRAME_ICONIFIED (f, true);
  5565       SET_FRAME_VISIBLE (f, false);
  5566     }
  5567   else
  5568     {
  5569       FRAME_X_OUTPUT (f)->has_been_visible = true;
  5570       inev.ie.kind = DEICONIFY_EVENT;
  5571       XSETFRAME (inev.ie.frame_or_window, f);
  5572       SET_FRAME_ICONIFIED (f, false);
  5573       SET_FRAME_VISIBLE (f, true);
  5574     }
  5575 
  5576   if (new_state & GDK_WINDOW_STATE_STICKY)
  5577     store_frame_param (f, Qsticky, Qt);
  5578   else
  5579     store_frame_param (f, Qsticky, Qnil);
  5580 
  5581   if (inev.ie.kind != NO_EVENT)
  5582     evq_enqueue (&inev);
  5583   return FALSE;
  5584 }
  5585 
  5586 static gboolean
  5587 delete_event (GtkWidget *widget,
  5588               GdkEvent *event, gpointer *user_data)
  5589 {
  5590   struct frame *f = pgtk_any_window_to_frame (event->any.window);
  5591   union buffered_input_event inev;
  5592 
  5593   EVENT_INIT (inev.ie);
  5594   inev.ie.kind = NO_EVENT;
  5595   inev.ie.arg = Qnil;
  5596 
  5597   if (f)
  5598     {
  5599       inev.ie.kind = DELETE_WINDOW_EVENT;
  5600       XSETFRAME (inev.ie.frame_or_window, f);
  5601     }
  5602 
  5603   if (inev.ie.kind != NO_EVENT)
  5604     evq_enqueue (&inev);
  5605   return TRUE;
  5606 }
  5607 
  5608 /* The focus may have changed.  Figure out if it is a real focus change,
  5609    by checking both FocusIn/Out and Enter/LeaveNotify events.
  5610 
  5611    Returns FOCUS_IN_EVENT event in *BUFP. */
  5612 
  5613 /* Handle FocusIn and FocusOut state changes for FRAME.
  5614    If FRAME has focus and there exists more than one frame, puts
  5615    a FOCUS_IN_EVENT into *BUFP.  */
  5616 
  5617 static void
  5618 pgtk_focus_changed (gboolean is_enter, int state,
  5619                     struct pgtk_display_info *dpyinfo, struct frame *frame,
  5620                     union buffered_input_event *bufp)
  5621 {
  5622   if (is_enter)
  5623     {
  5624       if (dpyinfo->x_focus_event_frame != frame)
  5625         {
  5626           pgtk_new_focus_frame (dpyinfo, frame);
  5627           dpyinfo->x_focus_event_frame = frame;
  5628 
  5629           /* Don't stop displaying the initial startup message
  5630              for a switch-frame event we don't need.  */
  5631           /* When run as a daemon, Vterminal_frame is always NIL.  */
  5632           bufp->ie.arg = (((NILP (Vterminal_frame)
  5633                             || !FRAME_PGTK_P (XFRAME (Vterminal_frame))
  5634                             || EQ (Fdaemonp (), Qt))
  5635                            && CONSP (Vframe_list)
  5636                            && !NILP (XCDR (Vframe_list))) ? Qt : Qnil);
  5637           bufp->ie.kind = FOCUS_IN_EVENT;
  5638           XSETFRAME (bufp->ie.frame_or_window, frame);
  5639         }
  5640 
  5641       frame->output_data.pgtk->focus_state |= state;
  5642 
  5643     }
  5644   else
  5645     {
  5646       frame->output_data.pgtk->focus_state &= ~state;
  5647 
  5648       if (dpyinfo->x_focus_event_frame == frame)
  5649         {
  5650           dpyinfo->x_focus_event_frame = 0;
  5651           pgtk_new_focus_frame (dpyinfo, NULL);
  5652 
  5653           bufp->ie.kind = FOCUS_OUT_EVENT;
  5654           XSETFRAME (bufp->ie.frame_or_window, frame);
  5655         }
  5656 
  5657       if (frame->pointer_invisible)
  5658         pgtk_toggle_invisible_pointer (frame, false);
  5659     }
  5660 }
  5661 
  5662 static gboolean
  5663 enter_notify_event (GtkWidget *widget, GdkEvent *event,
  5664                     gpointer *user_data)
  5665 {
  5666   union buffered_input_event inev;
  5667   struct frame *frame
  5668     = pgtk_any_window_to_frame (gtk_widget_get_window (widget));
  5669 
  5670   if (frame == NULL)
  5671     return FALSE;
  5672 
  5673   struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (frame);
  5674   struct frame *focus_frame = dpyinfo->x_focus_frame;
  5675   int focus_state
  5676     = focus_frame ? focus_frame->output_data.pgtk->focus_state : 0;
  5677 
  5678   EVENT_INIT (inev.ie);
  5679   inev.ie.kind = NO_EVENT;
  5680   inev.ie.arg = Qnil;
  5681 
  5682   if (event->crossing.detail != GDK_NOTIFY_INFERIOR
  5683       && event->crossing.focus && !(focus_state & FOCUS_EXPLICIT))
  5684     pgtk_focus_changed (TRUE, FOCUS_IMPLICIT, dpyinfo, frame, &inev);
  5685   if (inev.ie.kind != NO_EVENT)
  5686     evq_enqueue (&inev);
  5687   return TRUE;
  5688 }
  5689 
  5690 static gboolean
  5691 leave_notify_event (GtkWidget *widget, GdkEvent *event,
  5692                     gpointer *user_data)
  5693 {
  5694   union buffered_input_event inev;
  5695   struct frame *frame
  5696     = pgtk_any_window_to_frame (gtk_widget_get_window (widget));
  5697 
  5698   if (frame == NULL)
  5699     return FALSE;
  5700 
  5701   struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (frame);
  5702   struct frame *focus_frame = dpyinfo->x_focus_frame;
  5703   int focus_state
  5704     = focus_frame ? focus_frame->output_data.pgtk->focus_state : 0;
  5705   Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (frame);
  5706 
  5707   if (frame == hlinfo->mouse_face_mouse_frame)
  5708     {
  5709       /* If we move outside the frame, then we're
  5710          certainly no longer on any text in the frame.  */
  5711       clear_mouse_face (hlinfo);
  5712       hlinfo->mouse_face_mouse_frame = 0;
  5713     }
  5714 
  5715   EVENT_INIT (inev.ie);
  5716   inev.ie.kind = NO_EVENT;
  5717   inev.ie.arg = Qnil;
  5718 
  5719   if (event->crossing.detail != GDK_NOTIFY_INFERIOR
  5720       && event->crossing.focus && !(focus_state & FOCUS_EXPLICIT))
  5721     pgtk_focus_changed (FALSE, FOCUS_IMPLICIT, dpyinfo, frame, &inev);
  5722 
  5723   if (frame)
  5724     {
  5725       if (any_help_event_p)
  5726         {
  5727           Lisp_Object frame_obj;
  5728           XSETFRAME (frame_obj, frame);
  5729           help_echo_string = Qnil;
  5730           gen_help_event (Qnil, frame_obj, Qnil, Qnil, 0);
  5731         }
  5732     }
  5733 
  5734   if (inev.ie.kind != NO_EVENT)
  5735     evq_enqueue (&inev);
  5736   return TRUE;
  5737 }
  5738 
  5739 static gboolean
  5740 focus_in_event (GtkWidget *widget, GdkEvent *event, gpointer *user_data)
  5741 {
  5742   union buffered_input_event inev;
  5743   struct frame *frame
  5744     = pgtk_any_window_to_frame (gtk_widget_get_window (widget));
  5745 
  5746   if (frame == NULL)
  5747     return TRUE;
  5748 
  5749   EVENT_INIT (inev.ie);
  5750   inev.ie.kind = NO_EVENT;
  5751   inev.ie.arg = Qnil;
  5752 
  5753   pgtk_focus_changed (TRUE, FOCUS_EXPLICIT,
  5754                       FRAME_DISPLAY_INFO (frame), frame, &inev);
  5755   if (inev.ie.kind != NO_EVENT)
  5756     evq_enqueue (&inev);
  5757 
  5758   pgtk_im_focus_in (frame);
  5759 
  5760   return TRUE;
  5761 }
  5762 
  5763 static gboolean
  5764 focus_out_event (GtkWidget *widget, GdkEvent *event, gpointer *user_data)
  5765 {
  5766   union buffered_input_event inev;
  5767   struct frame *frame
  5768     = pgtk_any_window_to_frame (gtk_widget_get_window (widget));
  5769 
  5770   if (frame == NULL)
  5771     return TRUE;
  5772 
  5773   EVENT_INIT (inev.ie);
  5774   inev.ie.kind = NO_EVENT;
  5775   inev.ie.arg = Qnil;
  5776 
  5777   pgtk_focus_changed (FALSE, FOCUS_EXPLICIT,
  5778                       FRAME_DISPLAY_INFO (frame), frame, &inev);
  5779   if (inev.ie.kind != NO_EVENT)
  5780     evq_enqueue (&inev);
  5781 
  5782   pgtk_im_focus_out (frame);
  5783 
  5784   return TRUE;
  5785 }
  5786 
  5787 /* Function to report a mouse movement to the mainstream Emacs code.
  5788    The input handler calls this.
  5789 
  5790    We have received a mouse movement event, which is given in *event.
  5791    If the mouse is over a different glyph than it was last time, tell
  5792    the mainstream emacs code by setting mouse_moved.  If not, ask for
  5793    another motion event, so we can check again the next time it moves.  */
  5794 
  5795 static bool
  5796 note_mouse_movement (struct frame *frame,
  5797                      const GdkEventMotion *event)
  5798 {
  5799   XRectangle *r;
  5800   struct pgtk_display_info *dpyinfo;
  5801 
  5802   if (!FRAME_X_OUTPUT (frame))
  5803     return false;
  5804 
  5805   dpyinfo = FRAME_DISPLAY_INFO (frame);
  5806   dpyinfo->last_mouse_movement_time = event->time;
  5807   dpyinfo->last_mouse_motion_frame = frame;
  5808   dpyinfo->last_mouse_motion_x = event->x;
  5809   dpyinfo->last_mouse_motion_y = event->y;
  5810 
  5811   if (event->window != gtk_widget_get_window (FRAME_GTK_WIDGET (frame)))
  5812     {
  5813       frame->mouse_moved = true;
  5814       dpyinfo->last_mouse_scroll_bar = NULL;
  5815       note_mouse_highlight (frame, -1, -1);
  5816       dpyinfo->last_mouse_glyph_frame = NULL;
  5817       frame->last_mouse_device
  5818         = pgtk_get_device_for_event (FRAME_DISPLAY_INFO (frame),
  5819                                      (GdkEvent *) event);
  5820       return true;
  5821     }
  5822 
  5823 
  5824   /* Has the mouse moved off the glyph it was on at the last sighting?  */
  5825   r = &dpyinfo->last_mouse_glyph;
  5826   if (frame != dpyinfo->last_mouse_glyph_frame
  5827       || event->x < r->x || event->x >= r->x + r->width
  5828       || event->y < r->y || event->y >= r->y + r->height)
  5829     {
  5830       frame->mouse_moved = true;
  5831       dpyinfo->last_mouse_scroll_bar = NULL;
  5832       note_mouse_highlight (frame, event->x, event->y);
  5833       /* Remember which glyph we're now on.  */
  5834       remember_mouse_glyph (frame, event->x, event->y, r);
  5835       dpyinfo->last_mouse_glyph_frame = frame;
  5836       frame->last_mouse_device
  5837         = pgtk_get_device_for_event (FRAME_DISPLAY_INFO (frame),
  5838                                      (GdkEvent *) event);
  5839       return true;
  5840     }
  5841 
  5842   return false;
  5843 }
  5844 
  5845 static gboolean
  5846 motion_notify_event (GtkWidget *widget, GdkEvent *event,
  5847                      gpointer *user_data)
  5848 {
  5849   union buffered_input_event inev;
  5850   struct frame *f, *frame;
  5851   struct pgtk_display_info *dpyinfo;
  5852   Mouse_HLInfo *hlinfo;
  5853 
  5854   EVENT_INIT (inev.ie);
  5855   inev.ie.kind = NO_EVENT;
  5856   inev.ie.arg = Qnil;
  5857 
  5858   previous_help_echo_string = help_echo_string;
  5859   help_echo_string = Qnil;
  5860 
  5861   frame = pgtk_any_window_to_frame (gtk_widget_get_window (widget));
  5862   dpyinfo = FRAME_DISPLAY_INFO (frame);
  5863   f = (gui_mouse_grabbed (dpyinfo) ? dpyinfo->last_mouse_frame
  5864        : pgtk_any_window_to_frame (gtk_widget_get_window (widget)));
  5865   hlinfo = MOUSE_HL_INFO (f);
  5866 
  5867   if (hlinfo->mouse_face_hidden)
  5868     {
  5869       hlinfo->mouse_face_hidden = false;
  5870       clear_mouse_face (hlinfo);
  5871     }
  5872 
  5873   if (f && xg_event_is_for_scrollbar (f, event, false))
  5874     f = 0;
  5875 
  5876   if (f)
  5877     {
  5878       /* Maybe generate a SELECT_WINDOW_EVENT for
  5879          `mouse-autoselect-window' but don't let popup menus
  5880          interfere with this (Bug#1261).  */
  5881       if (!NILP (Vmouse_autoselect_window)
  5882           /* Don't switch if we're currently in the minibuffer.
  5883              This tries to work around problems where the
  5884              minibuffer gets unselected unexpectedly, and where
  5885              you then have to move your mouse all the way down to
  5886              the minibuffer to select it.  */
  5887           && !MINI_WINDOW_P (XWINDOW (selected_window))
  5888           /* With `focus-follows-mouse' non-nil create an event
  5889              also when the target window is on another frame.  */
  5890           && (f == XFRAME (selected_frame) || !NILP (focus_follows_mouse)))
  5891         {
  5892           static Lisp_Object last_mouse_window;
  5893           Lisp_Object window = window_from_coordinates
  5894             (f, event->motion.x, event->motion.y, 0, false, false);
  5895 
  5896           /* A window will be autoselected only when it is not
  5897              selected now and the last mouse movement event was
  5898              not in it.  The remainder of the code is a bit vague
  5899              wrt what a "window" is.  For immediate autoselection,
  5900              the window is usually the entire window but for GTK
  5901              where the scroll bars don't count.  For delayed
  5902              autoselection the window is usually the window's text
  5903              area including the margins.  */
  5904           if (WINDOWP (window)
  5905               && !EQ (window, last_mouse_window)
  5906               && !EQ (window, selected_window))
  5907             {
  5908               inev.ie.kind = SELECT_WINDOW_EVENT;
  5909               inev.ie.frame_or_window = window;
  5910             }
  5911 
  5912           /* Remember the last window where we saw the mouse.  */
  5913           last_mouse_window = window;
  5914         }
  5915 
  5916       if (!note_mouse_movement (f, &event->motion))
  5917         help_echo_string = previous_help_echo_string;
  5918     }
  5919   else
  5920     /* If we move outside the frame, then we're
  5921        certainly no longer on any text in the frame.  */
  5922     clear_mouse_face (hlinfo);
  5923 
  5924   /* If the contents of the global variable help_echo_string
  5925      has changed, generate a HELP_EVENT.  */
  5926   int do_help = 0;
  5927   if (!NILP (help_echo_string) || !NILP (previous_help_echo_string))
  5928     do_help = 1;
  5929 
  5930   if (inev.ie.kind != NO_EVENT)
  5931     evq_enqueue (&inev);
  5932 
  5933   if (do_help > 0)
  5934     {
  5935       Lisp_Object frame;
  5936 
  5937       if (f)
  5938         XSETFRAME (frame, f);
  5939       else
  5940         frame = Qnil;
  5941 
  5942       any_help_event_p = true;
  5943       gen_help_event (help_echo_string, frame, help_echo_window,
  5944                       help_echo_object, help_echo_pos);
  5945     }
  5946 
  5947   return TRUE;
  5948 }
  5949 
  5950 /* Prepare a mouse-event in *RESULT for placement in the input queue.
  5951 
  5952    If the event is a button press, then note that we have grabbed
  5953    the mouse.  */
  5954 
  5955 static Lisp_Object
  5956 construct_mouse_click (struct input_event *result,
  5957                        const GdkEventButton *event,
  5958                        struct frame *f)
  5959 {
  5960   /* Make the event type NO_EVENT; we'll change that when we decide
  5961      otherwise.  */
  5962   result->kind = MOUSE_CLICK_EVENT;
  5963   result->code = event->button - 1;
  5964   result->timestamp = event->time;
  5965   result->modifiers = (pgtk_gtk_to_emacs_modifiers (FRAME_DISPLAY_INFO (f),
  5966                                                     event->state)
  5967                        | (event->type == GDK_BUTTON_RELEASE
  5968                           ? up_modifier : down_modifier));
  5969 
  5970   XSETINT (result->x, event->x);
  5971   XSETINT (result->y, event->y);
  5972   XSETFRAME (result->frame_or_window, f);
  5973   result->arg = Qnil;
  5974   result->device = pgtk_get_device_for_event (FRAME_DISPLAY_INFO (f),
  5975                                               (GdkEvent *) event);
  5976   return Qnil;
  5977 }
  5978 
  5979 static gboolean
  5980 button_event (GtkWidget *widget, GdkEvent *event,
  5981               gpointer *user_data)
  5982 {
  5983   union buffered_input_event inev;
  5984   struct frame *f, *frame;
  5985   struct pgtk_display_info *dpyinfo;
  5986 
  5987   /* If we decide we want to generate an event to be seen
  5988      by the rest of Emacs, we put it here.  */
  5989   bool tab_bar_p = false;
  5990   bool tool_bar_p = false;
  5991   Lisp_Object tab_bar_arg = Qnil;
  5992 
  5993   EVENT_INIT (inev.ie);
  5994   inev.ie.kind = NO_EVENT;
  5995   inev.ie.arg = Qnil;
  5996 
  5997   /* ignore double click and triple click. */
  5998   if (event->type != GDK_BUTTON_PRESS && event->type != GDK_BUTTON_RELEASE)
  5999     return TRUE;
  6000 
  6001   frame = pgtk_any_window_to_frame (gtk_widget_get_window (widget));
  6002   dpyinfo = FRAME_DISPLAY_INFO (frame);
  6003 
  6004   dpyinfo->last_mouse_glyph_frame = NULL;
  6005 
  6006   if (gui_mouse_grabbed (dpyinfo))
  6007     f = dpyinfo->last_mouse_frame;
  6008   else
  6009     {
  6010       f = pgtk_any_window_to_frame (gtk_widget_get_window (widget));
  6011 
  6012       if (f && event->button.type == GDK_BUTTON_PRESS
  6013           && !FRAME_NO_ACCEPT_FOCUS (f))
  6014         {
  6015           /* When clicking into a child frame or when clicking
  6016              into a parent frame with the child frame selected and
  6017              `no-accept-focus' is not set, select the clicked
  6018              frame.  */
  6019           struct frame *hf = dpyinfo->highlight_frame;
  6020 
  6021           if (FRAME_PARENT_FRAME (f) || (hf && frame_ancestor_p (f, hf)))
  6022             {
  6023               block_input ();
  6024               gtk_widget_grab_focus (FRAME_GTK_WIDGET (f));
  6025 
  6026               if (FRAME_GTK_OUTER_WIDGET (f))
  6027                 gtk_window_present (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
  6028               unblock_input ();
  6029             }
  6030         }
  6031     }
  6032 
  6033   /* Set the last user time, used to activate the frame in
  6034      pgtk_focus_frame.  */
  6035   dpyinfo->last_user_time = event->button.time;
  6036 
  6037   if (f)
  6038     {
  6039       /* Is this in the tab-bar?  */
  6040       if (WINDOWP (f->tab_bar_window)
  6041           && WINDOW_TOTAL_LINES (XWINDOW (f->tab_bar_window)))
  6042         {
  6043           Lisp_Object window;
  6044           int x = event->button.x;
  6045           int y = event->button.y;
  6046 
  6047           window = window_from_coordinates (f, x, y, 0, true, true);
  6048           tab_bar_p = EQ (window, f->tab_bar_window);
  6049 
  6050           if (tab_bar_p)
  6051             tab_bar_arg = handle_tab_bar_click
  6052               (f, x, y, event->type == GDK_BUTTON_PRESS,
  6053                pgtk_gtk_to_emacs_modifiers (dpyinfo, event->button.state));
  6054         }
  6055 
  6056       if (!(tab_bar_p && NILP (tab_bar_arg)) && !tool_bar_p)
  6057         {
  6058           if (ignore_next_mouse_click_timeout)
  6059             {
  6060               if (event->type == GDK_BUTTON_PRESS
  6061                   && event->button.time > ignore_next_mouse_click_timeout)
  6062                 {
  6063                   ignore_next_mouse_click_timeout = 0;
  6064                   construct_mouse_click (&inev.ie, &event->button, f);
  6065                 }
  6066               if (event->type == GDK_BUTTON_RELEASE)
  6067                 ignore_next_mouse_click_timeout = 0;
  6068             }
  6069           else
  6070             construct_mouse_click (&inev.ie, &event->button, f);
  6071 
  6072           if (!NILP (tab_bar_arg))
  6073             inev.ie.arg = tab_bar_arg;
  6074         }
  6075     }
  6076 
  6077   if (event->type == GDK_BUTTON_PRESS)
  6078     {
  6079       dpyinfo->grabbed |= (1 << event->button.button);
  6080       dpyinfo->last_mouse_frame = f;
  6081 
  6082       if (dpyinfo->last_click_event != NULL)
  6083         gdk_event_free (dpyinfo->last_click_event);
  6084       dpyinfo->last_click_event = gdk_event_copy (event);
  6085     }
  6086   else
  6087     dpyinfo->grabbed &= ~(1 << event->button.button);
  6088 
  6089   /* Ignore any mouse motion that happened before this event;
  6090      any subsequent mouse-movement Emacs events should reflect
  6091      only motion after the ButtonPress/Release.  */
  6092   if (f != 0)
  6093     f->mouse_moved = false;
  6094 
  6095   if (inev.ie.kind != NO_EVENT)
  6096     evq_enqueue (&inev);
  6097   return TRUE;
  6098 }
  6099 
  6100 static gboolean
  6101 scroll_event (GtkWidget *widget, GdkEvent *event, gpointer *user_data)
  6102 {
  6103   union buffered_input_event inev;
  6104   struct frame *f, *frame;
  6105   struct pgtk_display_info *dpyinfo;
  6106   GdkScrollDirection dir;
  6107   double delta_x, delta_y;
  6108 
  6109   EVENT_INIT (inev.ie);
  6110   inev.ie.kind = NO_EVENT;
  6111   inev.ie.arg = Qnil;
  6112 
  6113   frame = pgtk_any_window_to_frame (gtk_widget_get_window (widget));
  6114   dpyinfo = FRAME_DISPLAY_INFO (frame);
  6115 
  6116   if (gui_mouse_grabbed (dpyinfo))
  6117     f = dpyinfo->last_mouse_frame;
  6118   else
  6119     f = pgtk_any_window_to_frame (gtk_widget_get_window (widget));
  6120 
  6121   inev.ie.kind = NO_EVENT;
  6122   inev.ie.timestamp = event->scroll.time;
  6123   inev.ie.modifiers
  6124     = pgtk_gtk_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), event->scroll.state);
  6125   XSETINT (inev.ie.x, event->scroll.x);
  6126   XSETINT (inev.ie.y, event->scroll.y);
  6127   XSETFRAME (inev.ie.frame_or_window, f);
  6128   inev.ie.arg = Qnil;
  6129 
  6130   if (gdk_event_is_scroll_stop_event (event))
  6131     {
  6132       inev.ie.kind = TOUCH_END_EVENT;
  6133       inev.ie.device
  6134         = pgtk_get_device_for_event (FRAME_DISPLAY_INFO (f), event);
  6135       evq_enqueue (&inev);
  6136       return TRUE;
  6137     }
  6138 
  6139   if (gdk_event_get_scroll_direction (event, &dir))
  6140     {
  6141       switch (dir)
  6142         {
  6143         case GDK_SCROLL_UP:
  6144           inev.ie.kind = WHEEL_EVENT;
  6145           inev.ie.modifiers |= up_modifier;
  6146           break;
  6147         case GDK_SCROLL_DOWN:
  6148           inev.ie.kind = WHEEL_EVENT;
  6149           inev.ie.modifiers |= down_modifier;
  6150           break;
  6151         case GDK_SCROLL_LEFT:
  6152           inev.ie.kind = HORIZ_WHEEL_EVENT;
  6153           inev.ie.modifiers |= up_modifier;
  6154           break;
  6155         case GDK_SCROLL_RIGHT:
  6156           inev.ie.kind = HORIZ_WHEEL_EVENT;
  6157           inev.ie.modifiers |= down_modifier;
  6158           break;
  6159         case GDK_SCROLL_SMOOTH:         /* shut up warning */
  6160           break;
  6161         }
  6162     }
  6163   else if (gdk_event_get_scroll_deltas (event, &delta_x, &delta_y))
  6164     {
  6165       if (!mwheel_coalesce_scroll_events)
  6166         {
  6167           inev.ie.kind = ((fabs (delta_x) > fabs (delta_y))
  6168                           ? HORIZ_WHEEL_EVENT
  6169                           : WHEEL_EVENT);
  6170           inev.ie.modifiers |= (inev.ie.kind == HORIZ_WHEEL_EVENT
  6171                                 ? (delta_x >= 0 ? up_modifier : down_modifier)
  6172                                 : (delta_y >= 0 ? down_modifier : up_modifier));
  6173           inev.ie.arg = list3 (Qnil, make_float (-delta_x * 100),
  6174                                make_float (-delta_y * 100));
  6175         }
  6176       else
  6177         {
  6178           dpyinfo->scroll.acc_x += delta_x;
  6179           dpyinfo->scroll.acc_y += delta_y;
  6180           if (dpyinfo->scroll.acc_y >= dpyinfo->scroll.y_per_line)
  6181             {
  6182               int nlines = dpyinfo->scroll.acc_y / dpyinfo->scroll.y_per_line;
  6183               inev.ie.kind = WHEEL_EVENT;
  6184               inev.ie.modifiers |= down_modifier;
  6185               inev.ie.arg = list3 (make_fixnum (nlines),
  6186                                    make_float (-dpyinfo->scroll.acc_x * 100),
  6187                                    make_float (-dpyinfo->scroll.acc_y * 100));
  6188               dpyinfo->scroll.acc_y -= dpyinfo->scroll.y_per_line * nlines;
  6189             }
  6190           else if (dpyinfo->scroll.acc_y <= -dpyinfo->scroll.y_per_line)
  6191             {
  6192               int nlines = -dpyinfo->scroll.acc_y / dpyinfo->scroll.y_per_line;
  6193               inev.ie.kind = WHEEL_EVENT;
  6194               inev.ie.modifiers |= up_modifier;
  6195               inev.ie.arg = list3 (make_fixnum (nlines),
  6196                                    make_float (-dpyinfo->scroll.acc_x * 100),
  6197                                    make_float (-dpyinfo->scroll.acc_y * 100));
  6198 
  6199               dpyinfo->scroll.acc_y -= -dpyinfo->scroll.y_per_line * nlines;
  6200             }
  6201           else if (dpyinfo->scroll.acc_x >= dpyinfo->scroll.x_per_char
  6202                    || !mwheel_coalesce_scroll_events)
  6203             {
  6204               int nchars = dpyinfo->scroll.acc_x / dpyinfo->scroll.x_per_char;
  6205               inev.ie.kind = HORIZ_WHEEL_EVENT;
  6206               inev.ie.modifiers |= up_modifier;
  6207               inev.ie.arg = list3 (make_fixnum (nchars),
  6208                                    make_float (-dpyinfo->scroll.acc_x * 100),
  6209                                    make_float (-dpyinfo->scroll.acc_y * 100));
  6210 
  6211               dpyinfo->scroll.acc_x -= dpyinfo->scroll.x_per_char * nchars;
  6212             }
  6213           else if (dpyinfo->scroll.acc_x <= -dpyinfo->scroll.x_per_char)
  6214             {
  6215               int nchars = -dpyinfo->scroll.acc_x / dpyinfo->scroll.x_per_char;
  6216               inev.ie.kind = HORIZ_WHEEL_EVENT;
  6217               inev.ie.modifiers |= down_modifier;
  6218               inev.ie.arg = list3 (make_fixnum (nchars),
  6219                                    make_float (-dpyinfo->scroll.acc_x * 100),
  6220                                    make_float (-dpyinfo->scroll.acc_y * 100));
  6221 
  6222               dpyinfo->scroll.acc_x -= -dpyinfo->scroll.x_per_char * nchars;
  6223             }
  6224         }
  6225     }
  6226 
  6227   if (inev.ie.kind != NO_EVENT)
  6228     {
  6229       inev.ie.device
  6230         = pgtk_get_device_for_event (FRAME_DISPLAY_INFO (f), event);
  6231       evq_enqueue (&inev);
  6232     }
  6233   return TRUE;
  6234 }
  6235 
  6236 
  6237 
  6238 /* C part of drop handling code.
  6239    The Lisp part is in pgtk-dnd.el.  */
  6240 
  6241 static GdkDragAction
  6242 symbol_to_drag_action (Lisp_Object act)
  6243 {
  6244   if (EQ (act, Qcopy))
  6245     return GDK_ACTION_COPY;
  6246 
  6247   if (EQ (act, Qmove))
  6248     return GDK_ACTION_MOVE;
  6249 
  6250   if (EQ (act, Qlink))
  6251     return GDK_ACTION_LINK;
  6252 
  6253   if (EQ (act, Qprivate))
  6254     return GDK_ACTION_PRIVATE;
  6255 
  6256   if (NILP (act))
  6257     return GDK_ACTION_DEFAULT;
  6258 
  6259   signal_error ("Invalid drag acction", act);
  6260 }
  6261 
  6262 static Lisp_Object
  6263 drag_action_to_symbol (GdkDragAction action)
  6264 {
  6265   switch (action)
  6266     {
  6267     case GDK_ACTION_COPY:
  6268       return Qcopy;
  6269 
  6270     case GDK_ACTION_MOVE:
  6271       return Qmove;
  6272 
  6273     case GDK_ACTION_LINK:
  6274       return Qlink;
  6275 
  6276     case GDK_ACTION_PRIVATE:
  6277       return Qprivate;
  6278 
  6279     case GDK_ACTION_DEFAULT:
  6280     default:
  6281       return Qnil;
  6282     }
  6283 }
  6284 
  6285 void
  6286 pgtk_update_drop_status (Lisp_Object action, Lisp_Object event_time)
  6287 {
  6288   guint32 time;
  6289 
  6290   CONS_TO_INTEGER (event_time, guint32, time);
  6291 
  6292   if (!current_drop_context || time < current_drop_time)
  6293     return;
  6294 
  6295   gdk_drag_status (current_drop_context,
  6296                    symbol_to_drag_action (action),
  6297                    time);
  6298 }
  6299 
  6300 void
  6301 pgtk_finish_drop (Lisp_Object success, Lisp_Object event_time,
  6302                   Lisp_Object del)
  6303 {
  6304   guint32 time;
  6305 
  6306   CONS_TO_INTEGER (event_time, guint32, time);
  6307 
  6308   if (!current_drop_context || time < current_drop_time)
  6309     return;
  6310 
  6311   gtk_drag_finish (current_drop_context, !NILP (success),
  6312                    !NILP (del), time);
  6313 
  6314   if (current_drop_context_drop)
  6315     g_clear_pointer (&current_drop_context,
  6316                      g_object_unref);
  6317 }
  6318 
  6319 static void
  6320 drag_leave (GtkWidget *widget, GdkDragContext *context,
  6321             guint time, gpointer user_data)
  6322 {
  6323   struct frame *f;
  6324   union buffered_input_event inev;
  6325 
  6326   f = pgtk_any_window_to_frame (gtk_widget_get_window (widget));
  6327 
  6328   if (current_drop_context)
  6329     {
  6330       if (current_drop_context_drop)
  6331         gtk_drag_finish (current_drop_context,
  6332                          FALSE, FALSE, current_drop_time);
  6333 
  6334       g_clear_pointer (&current_drop_context,
  6335                        g_object_unref);
  6336     }
  6337 
  6338   EVENT_INIT (inev.ie);
  6339 
  6340   inev.ie.kind = DRAG_N_DROP_EVENT;
  6341   inev.ie.modifiers = 0;
  6342   inev.ie.arg = Qnil;
  6343   inev.ie.timestamp = time;
  6344 
  6345   XSETINT (inev.ie.x, 0);
  6346   XSETINT (inev.ie.y, 0);
  6347   XSETFRAME (inev.ie.frame_or_window, f);
  6348 
  6349   evq_enqueue (&inev);
  6350 }
  6351 
  6352 static gboolean
  6353 drag_motion (GtkWidget *widget, GdkDragContext *context,
  6354              gint x, gint y, guint time)
  6355 
  6356 {
  6357   struct frame *f;
  6358   union buffered_input_event inev;
  6359   GdkAtom name;
  6360   GdkDragAction suggestion;
  6361 
  6362   f = pgtk_any_window_to_frame (gtk_widget_get_window (widget));
  6363 
  6364   if (!f)
  6365     return FALSE;
  6366 
  6367   if (current_drop_context)
  6368     {
  6369       if (current_drop_context_drop)
  6370         gtk_drag_finish (current_drop_context,
  6371                          FALSE, FALSE, current_drop_time);
  6372 
  6373       g_clear_pointer (&current_drop_context,
  6374                        g_object_unref);
  6375     }
  6376 
  6377   current_drop_context = g_object_ref (context);
  6378   current_drop_time = time;
  6379   current_drop_context_drop = false;
  6380 
  6381   name = gdk_drag_get_selection (context);
  6382   suggestion = gdk_drag_context_get_suggested_action (context);
  6383 
  6384   EVENT_INIT (inev.ie);
  6385 
  6386   inev.ie.kind = DRAG_N_DROP_EVENT;
  6387   inev.ie.modifiers = 0;
  6388   inev.ie.arg = list4 (Qlambda, intern (gdk_atom_name (name)),
  6389                        make_uint (time),
  6390                        drag_action_to_symbol (suggestion));
  6391   inev.ie.timestamp = time;
  6392 
  6393   XSETINT (inev.ie.x, x);
  6394   XSETINT (inev.ie.y, y);
  6395   XSETFRAME (inev.ie.frame_or_window, f);
  6396 
  6397   evq_enqueue (&inev);
  6398 
  6399   return TRUE;
  6400 }
  6401 
  6402 static gboolean
  6403 drag_drop (GtkWidget *widget, GdkDragContext *context,
  6404            int x, int y, guint time, gpointer user_data)
  6405 {
  6406   struct frame *f;
  6407   union buffered_input_event inev;
  6408   GdkAtom name;
  6409   GdkDragAction selected_action;
  6410 
  6411   f = pgtk_any_window_to_frame (gtk_widget_get_window (widget));
  6412 
  6413   if (!f)
  6414     return FALSE;
  6415 
  6416   if (current_drop_context)
  6417     {
  6418       if (current_drop_context_drop)
  6419         gtk_drag_finish (current_drop_context,
  6420                          FALSE, FALSE, current_drop_time);
  6421 
  6422       g_clear_pointer (&current_drop_context,
  6423                        g_object_unref);
  6424     }
  6425 
  6426   current_drop_context = g_object_ref (context);
  6427   current_drop_time = time;
  6428   current_drop_context_drop = true;
  6429 
  6430   name = gdk_drag_get_selection (context);
  6431   selected_action = gdk_drag_context_get_selected_action (context);
  6432 
  6433   EVENT_INIT (inev.ie);
  6434 
  6435   inev.ie.kind = DRAG_N_DROP_EVENT;
  6436   inev.ie.modifiers = 0;
  6437   inev.ie.arg = list4 (Qquote, intern (gdk_atom_name (name)),
  6438                        make_uint (time),
  6439                        drag_action_to_symbol (selected_action));
  6440   inev.ie.timestamp = time;
  6441 
  6442   XSETINT (inev.ie.x, x);
  6443   XSETINT (inev.ie.y, y);
  6444   XSETFRAME (inev.ie.frame_or_window, f);
  6445 
  6446   evq_enqueue (&inev);
  6447 
  6448   return TRUE;
  6449 }
  6450 
  6451 static void
  6452 pgtk_monitors_changed_cb (GdkScreen *screen, gpointer user_data)
  6453 {
  6454   struct terminal *terminal;
  6455   union buffered_input_event inev;
  6456 
  6457   EVENT_INIT (inev.ie);
  6458   terminal = user_data;
  6459   inev.ie.kind = MONITORS_CHANGED_EVENT;
  6460   XSETTERMINAL (inev.ie.arg, terminal);
  6461 
  6462   evq_enqueue (&inev);
  6463 }
  6464 
  6465 static gboolean pgtk_selection_event (GtkWidget *, GdkEvent *, gpointer);
  6466 
  6467 void
  6468 pgtk_set_event_handler (struct frame *f)
  6469 {
  6470   if (f->tooltip)
  6471     {
  6472       g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "draw",
  6473                         G_CALLBACK (pgtk_handle_draw), NULL);
  6474       return;
  6475     }
  6476 
  6477   gtk_drag_dest_set (FRAME_GTK_WIDGET (f), 0, NULL, 0,
  6478                      (GDK_ACTION_MOVE | GDK_ACTION_COPY
  6479                       | GDK_ACTION_LINK | GDK_ACTION_PRIVATE));
  6480 
  6481   if (FRAME_GTK_OUTER_WIDGET (f))
  6482     {
  6483       g_signal_connect (G_OBJECT (FRAME_GTK_OUTER_WIDGET (f)),
  6484                         "window-state-event", G_CALLBACK (window_state_event),
  6485                         NULL);
  6486       g_signal_connect (G_OBJECT (FRAME_GTK_OUTER_WIDGET (f)), "delete-event",
  6487                         G_CALLBACK (delete_event), NULL);
  6488       g_signal_connect (G_OBJECT (FRAME_GTK_OUTER_WIDGET (f)), "event",
  6489                         G_CALLBACK (pgtk_handle_event), NULL);
  6490       g_signal_connect (G_OBJECT (FRAME_GTK_OUTER_WIDGET (f)), "configure-event",
  6491                         G_CALLBACK (configure_event), NULL);
  6492     }
  6493 
  6494   g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "map-event",
  6495                     G_CALLBACK (map_event), NULL);
  6496   g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "size-allocate",
  6497                     G_CALLBACK (size_allocate), f);
  6498   g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "key-press-event",
  6499                     G_CALLBACK (key_press_event), NULL);
  6500   g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "key-release-event",
  6501                     G_CALLBACK (key_release_event), NULL);
  6502   g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "focus-in-event",
  6503                     G_CALLBACK (focus_in_event), NULL);
  6504   g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "focus-out-event",
  6505                     G_CALLBACK (focus_out_event), NULL);
  6506   g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "enter-notify-event",
  6507                     G_CALLBACK (enter_notify_event), NULL);
  6508   g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "leave-notify-event",
  6509                     G_CALLBACK (leave_notify_event), NULL);
  6510   g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "motion-notify-event",
  6511                     G_CALLBACK (motion_notify_event), NULL);
  6512   g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "button-press-event",
  6513                     G_CALLBACK (button_event), NULL);
  6514   g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "button-release-event",
  6515                     G_CALLBACK (button_event), NULL);
  6516   g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "scroll-event",
  6517                     G_CALLBACK (scroll_event), NULL);
  6518   g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "configure-event",
  6519                     G_CALLBACK (configure_event), NULL);
  6520   g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "drag-leave",
  6521                     G_CALLBACK (drag_leave), NULL);
  6522   g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "drag-motion",
  6523                     G_CALLBACK (drag_motion), NULL);
  6524   g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "drag-drop",
  6525                     G_CALLBACK (drag_drop), NULL);
  6526   g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "draw",
  6527                     G_CALLBACK (pgtk_handle_draw), NULL);
  6528   g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "property-notify-event",
  6529                     G_CALLBACK (pgtk_selection_event), NULL);
  6530   g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "selection-clear-event",
  6531                     G_CALLBACK (pgtk_selection_event), NULL);
  6532   g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "selection-request-event",
  6533                     G_CALLBACK (pgtk_selection_event), NULL);
  6534   g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "selection-notify-event",
  6535                     G_CALLBACK (pgtk_selection_event), NULL);
  6536   g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "event",
  6537                     G_CALLBACK (pgtk_handle_event), NULL);
  6538 }
  6539 
  6540 static void
  6541 my_log_handler (const gchar * log_domain, GLogLevelFlags log_level,
  6542                 const gchar * msg, gpointer user_data)
  6543 {
  6544   if (!strstr (msg, "g_set_prgname"))
  6545     fprintf (stderr, "%s-WARNING **: %s", log_domain, msg);
  6546 }
  6547 
  6548 /* Test whether two display-name strings agree up to the dot that separates
  6549    the screen number from the server number.  */
  6550 static bool
  6551 same_x_server (const char *name1, const char *name2)
  6552 {
  6553   bool seen_colon = false;
  6554   Lisp_Object sysname = Fsystem_name ();
  6555   const char *system_name = SSDATA (sysname);
  6556   ptrdiff_t system_name_length = SBYTES (sysname);
  6557   ptrdiff_t length_until_period = 0;
  6558 
  6559   while (system_name[length_until_period] != 0
  6560          && system_name[length_until_period] != '.')
  6561     length_until_period++;
  6562 
  6563   /* Treat `unix' like an empty host name.  */
  6564   if (!strncmp (name1, "unix:", 5))
  6565     name1 += 4;
  6566   if (!strncmp (name2, "unix:", 5))
  6567     name2 += 4;
  6568   /* Treat this host's name like an empty host name.  */
  6569   if (!strncmp (name1, system_name, system_name_length)
  6570       && name1[system_name_length] == ':')
  6571     name1 += system_name_length;
  6572   if (!strncmp (name2, system_name, system_name_length)
  6573       && name2[system_name_length] == ':')
  6574     name2 += system_name_length;
  6575   /* Treat this host's domainless name like an empty host name.  */
  6576   if (!strncmp (name1, system_name, length_until_period)
  6577       && name1[length_until_period] == ':')
  6578     name1 += length_until_period;
  6579   if (!strncmp (name2, system_name, length_until_period)
  6580       && name2[length_until_period] == ':')
  6581     name2 += length_until_period;
  6582 
  6583   for (; *name1 != '\0' && *name1 == *name2; name1++, name2++)
  6584     {
  6585       if (*name1 == ':')
  6586         seen_colon = true;
  6587       if (seen_colon && *name1 == '.')
  6588         return true;
  6589     }
  6590   return (seen_colon
  6591           && (*name1 == '.' || *name1 == '\0')
  6592           && (*name2 == '.' || *name2 == '\0'));
  6593 }
  6594 
  6595 static struct frame *
  6596 pgtk_find_selection_owner (GdkWindow *window)
  6597 {
  6598   Lisp_Object tail, tem;
  6599   struct frame *f;
  6600 
  6601   FOR_EACH_FRAME (tail, tem)
  6602     {
  6603       f = XFRAME (tem);
  6604 
  6605       if (FRAME_PGTK_P (f)
  6606           && (FRAME_GDK_WINDOW (f) == window))
  6607         return f;
  6608     }
  6609 
  6610   return NULL;
  6611 }
  6612 
  6613 static gboolean
  6614 pgtk_selection_event (GtkWidget *widget, GdkEvent *event,
  6615                       gpointer user_data)
  6616 {
  6617   struct frame *f;
  6618   union buffered_input_event inev;
  6619 
  6620   if (event->type == GDK_PROPERTY_NOTIFY)
  6621     pgtk_handle_property_notify (&event->property);
  6622   else if (event->type == GDK_SELECTION_CLEAR
  6623            || event->type == GDK_SELECTION_REQUEST)
  6624     {
  6625       f = pgtk_find_selection_owner (event->selection.window);
  6626 
  6627       if (f)
  6628         {
  6629           EVENT_INIT (inev.ie);
  6630 
  6631           inev.sie.kind = (event->type == GDK_SELECTION_CLEAR
  6632                            ? SELECTION_CLEAR_EVENT
  6633                            : SELECTION_REQUEST_EVENT);
  6634 
  6635           SELECTION_EVENT_DPYINFO (&inev.sie) = FRAME_DISPLAY_INFO (f);
  6636           SELECTION_EVENT_SELECTION (&inev.sie) = event->selection.selection;
  6637           SELECTION_EVENT_TIME (&inev.sie) = event->selection.time;
  6638 
  6639           if (event->type == GDK_SELECTION_REQUEST)
  6640             {
  6641               /* FIXME: when does GDK destroy the requestor GdkWindow
  6642                  object?
  6643 
  6644                  It would make sense to wait for the transfer to
  6645                  complete.  But I don't know if GDK actually does
  6646                  that.  */
  6647               SELECTION_EVENT_REQUESTOR (&inev.sie) = event->selection.requestor;
  6648               SELECTION_EVENT_TARGET (&inev.sie) = event->selection.target;
  6649               SELECTION_EVENT_PROPERTY (&inev.sie) = event->selection.property;
  6650             }
  6651 
  6652           evq_enqueue (&inev);
  6653           return TRUE;
  6654         }
  6655     }
  6656   else if (event->type == GDK_SELECTION_NOTIFY)
  6657     pgtk_handle_selection_notify (&event->selection);
  6658 
  6659   return FALSE;
  6660 }
  6661 
  6662 /* Display a warning message if the PGTK port is being used under X;
  6663    that is not supported.  */
  6664 
  6665 static void
  6666 pgtk_display_x_warning (GdkDisplay *display)
  6667 {
  6668   GtkWidget *dialog_widget, *label, *content_area;
  6669   GtkDialog *dialog;
  6670   GtkWindow *window;
  6671   GdkScreen *screen;
  6672 
  6673   /* Do this instead of GDK_IS_X11_DISPLAY because the GDK X header
  6674      pulls in Xlib, which conflicts with definitions in pgtkgui.h.  */
  6675   if (strcmp (G_OBJECT_TYPE_NAME (display),
  6676               "GdkX11Display"))
  6677     return;
  6678 
  6679   dialog_widget = gtk_dialog_new ();
  6680   dialog = GTK_DIALOG (dialog_widget);
  6681   window = GTK_WINDOW (dialog_widget);
  6682   screen = gdk_display_get_default_screen (display);
  6683   content_area = gtk_dialog_get_content_area (dialog);
  6684 
  6685   gtk_window_set_title (window, "Warning");
  6686   gtk_window_set_screen (window, screen);
  6687 
  6688   label = gtk_label_new ("You are trying to run Emacs configured with\n"
  6689                           " the \"pure-GTK\" interface under the X Window\n"
  6690                           " System.  That configuration is unsupported and\n"
  6691                           " will lead to sporadic crashes during transfer of\n"
  6692                           " large selection data.  It will also lead to\n"
  6693                           " various problems with keyboard input.\n");
  6694   gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
  6695   gtk_container_add (GTK_CONTAINER (content_area), label);
  6696   gtk_widget_show (label);
  6697   gtk_widget_show (dialog_widget);
  6698 }
  6699 
  6700 /* Open a connection to X display DISPLAY_NAME, and return
  6701    the structure that describes the open display.
  6702    If we cannot contact the display, return null.  */
  6703 
  6704 struct pgtk_display_info *
  6705 pgtk_term_init (Lisp_Object display_name, char *resource_name)
  6706 {
  6707   GdkDisplay *dpy;
  6708   struct terminal *terminal;
  6709   struct pgtk_display_info *dpyinfo;
  6710   static int x_initialized = 0;
  6711   static unsigned x_display_id = 0;
  6712   static char *initial_display = NULL;
  6713   char *dpy_name;
  6714   static void *handle = NULL;
  6715   Lisp_Object lisp_dpy_name = Qnil;
  6716   GdkScreen *gscr;
  6717   gdouble dpi;
  6718 
  6719   block_input ();
  6720 
  6721   if (!x_initialized)
  6722     {
  6723       any_help_event_p = false;
  6724 
  6725       Fset_input_interrupt_mode (Qt);
  6726       baud_rate = 19200;
  6727 
  6728 #ifdef USE_CAIRO
  6729       gui_init_fringe (&pgtk_redisplay_interface);
  6730 #endif
  6731 
  6732       ++x_initialized;
  6733     }
  6734 
  6735   dpy_name = SSDATA (display_name);
  6736   if (strlen (dpy_name) == 0 && initial_display != NULL)
  6737     dpy_name = initial_display;
  6738   lisp_dpy_name = build_string (dpy_name);
  6739 
  6740   {
  6741 #define NUM_ARGV 10
  6742     int argc;
  6743     char *argv[NUM_ARGV];
  6744     char **argv2 = argv;
  6745     guint id;
  6746 
  6747     if (x_initialized++ > 1)
  6748       {
  6749         xg_display_open (dpy_name, &dpy);
  6750       }
  6751     else
  6752       {
  6753         static char display_opt[] = "--display";
  6754         static char name_opt[] = "--name";
  6755 
  6756         for (argc = 0; argc < NUM_ARGV; ++argc)
  6757           argv[argc] = 0;
  6758 
  6759         argc = 0;
  6760         argv[argc++] = initial_argv[0];
  6761 
  6762         if (strlen (dpy_name) != 0)
  6763           {
  6764             argv[argc++] = display_opt;
  6765             argv[argc++] = dpy_name;
  6766           }
  6767 
  6768         argv[argc++] = name_opt;
  6769         argv[argc++] = resource_name;
  6770 
  6771         /* Work around GLib bug that outputs a faulty warning. See
  6772            https://bugzilla.gnome.org/show_bug.cgi?id=563627.  */
  6773         id = g_log_set_handler ("GLib", G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL
  6774                                 | G_LOG_FLAG_RECURSION, my_log_handler, NULL);
  6775 
  6776         /* gtk_init does set_locale.  Fix locale before and after.  */
  6777         fixup_locale ();
  6778         unrequest_sigio ();     /* See comment in x_display_ok.  */
  6779         gtk_init (&argc, &argv2);
  6780         request_sigio ();
  6781         fixup_locale ();
  6782 
  6783 
  6784         g_log_remove_handler ("GLib", id);
  6785 
  6786         xg_initialize ();
  6787 
  6788         dpy = DEFAULT_GDK_DISPLAY ();
  6789 
  6790         initial_display = g_strdup (gdk_display_get_name (dpy));
  6791         dpy_name = initial_display;
  6792         lisp_dpy_name = build_string (dpy_name);
  6793       }
  6794   }
  6795 
  6796   /* Detect failure.  */
  6797   if (dpy == 0)
  6798     {
  6799       unblock_input ();
  6800       return 0;
  6801     }
  6802 
  6803   /* If the PGTK port is being used under X, complain very loudly, as
  6804      that isn't supported.  */
  6805   pgtk_display_x_warning (dpy);
  6806 
  6807   dpyinfo = xzalloc (sizeof *dpyinfo);
  6808   pgtk_initialize_display_info (dpyinfo);
  6809   terminal = pgtk_create_terminal (dpyinfo);
  6810 
  6811   {
  6812     struct pgtk_display_info *share;
  6813 
  6814     for (share = x_display_list; share; share = share->next)
  6815       if (same_x_server (SSDATA (XCAR (share->name_list_element)), dpy_name))
  6816         break;
  6817     if (share)
  6818       terminal->kboard = share->terminal->kboard;
  6819     else
  6820       {
  6821         terminal->kboard = allocate_kboard (Qpgtk);
  6822 
  6823         /* Don't let the initial kboard remain current longer than necessary.
  6824            That would cause problems if a file loaded on startup tries to
  6825            prompt in the mini-buffer.  */
  6826         if (current_kboard == initial_kboard)
  6827           current_kboard = terminal->kboard;
  6828       }
  6829     terminal->kboard->reference_count++;
  6830   }
  6831 
  6832   /* Put this display on the chain.  */
  6833   dpyinfo->next = x_display_list;
  6834   x_display_list = dpyinfo;
  6835 
  6836   dpyinfo->name_list_element = Fcons (lisp_dpy_name, Qnil);
  6837   dpyinfo->gdpy = dpy;
  6838 
  6839   /* https://lists.gnu.org/r/emacs-devel/2015-11/msg00194.html  */
  6840   dpyinfo->smallest_font_height = 1;
  6841   dpyinfo->smallest_char_width = 1;
  6842 
  6843   /* Set the name of the terminal. */
  6844   terminal->name = xlispstrdup (lisp_dpy_name);
  6845 
  6846   Lisp_Object system_name = Fsystem_name ();
  6847   ptrdiff_t nbytes;
  6848   if (ckd_add (&nbytes, SBYTES (Vinvocation_name), SBYTES (system_name) + 2))
  6849     memory_full (SIZE_MAX);
  6850   dpyinfo->x_id = ++x_display_id;
  6851   dpyinfo->x_id_name = xmalloc (nbytes);
  6852   char *nametail = lispstpcpy (dpyinfo->x_id_name, Vinvocation_name);
  6853   *nametail++ = '@';
  6854   lispstpcpy (nametail, system_name);
  6855 
  6856   /* Get the scroll bar cursor.  */
  6857   /* We must create a GTK cursor, it is required for GTK widgets.  */
  6858   dpyinfo->xg_cursor = xg_create_default_cursor (dpyinfo->gdpy);
  6859 
  6860   dpyinfo->vertical_scroll_bar_cursor
  6861     = gdk_cursor_new_for_display (dpyinfo->gdpy, GDK_SB_V_DOUBLE_ARROW);
  6862 
  6863   dpyinfo->horizontal_scroll_bar_cursor
  6864     = gdk_cursor_new_for_display (dpyinfo->gdpy, GDK_SB_H_DOUBLE_ARROW);
  6865 
  6866   dpyinfo->icon_bitmap_id = -1;
  6867 
  6868   reset_mouse_highlight (&dpyinfo->mouse_highlight);
  6869 
  6870   gscr = gdk_display_get_default_screen (dpyinfo->gdpy);
  6871   dpi = gdk_screen_get_resolution (gscr);
  6872 
  6873   if (dpi < 0)
  6874     dpi = 96.0;
  6875 
  6876   dpyinfo->resx = dpi;
  6877   dpyinfo->resy = dpi;
  6878 
  6879   g_signal_connect (G_OBJECT (gscr), "monitors-changed",
  6880                     G_CALLBACK (pgtk_monitors_changed_cb),
  6881                     terminal);
  6882 
  6883   /* Set up scrolling increments.  */
  6884   dpyinfo->scroll.x_per_char = 1;
  6885   dpyinfo->scroll.y_per_line = 1;
  6886 
  6887   dpyinfo->connection = -1;
  6888 
  6889   if (!handle)
  6890     handle = dlopen (NULL, RTLD_LAZY);
  6891 
  6892 #ifdef GDK_WINDOWING_X11
  6893   if (!strcmp (G_OBJECT_TYPE_NAME (dpy), "GdkX11Display") && handle)
  6894     {
  6895       void *(*gdk_x11_display_get_xdisplay) (GdkDisplay *)
  6896         = dlsym (handle, "gdk_x11_display_get_xdisplay");
  6897       int (*x_connection_number) (void *)
  6898         = dlsym (handle, "XConnectionNumber");
  6899 
  6900       if (x_connection_number
  6901           && gdk_x11_display_get_xdisplay)
  6902         dpyinfo->connection
  6903           = x_connection_number (gdk_x11_display_get_xdisplay (dpy));
  6904     }
  6905 #endif
  6906 
  6907 #ifdef GDK_WINDOWING_WAYLAND
  6908   if (GDK_IS_WAYLAND_DISPLAY (dpy) && handle)
  6909     {
  6910       struct wl_display *wl_dpy = gdk_wayland_display_get_wl_display (dpy);
  6911       int (*display_get_fd) (struct wl_display *)
  6912         = dlsym (handle, "wl_display_get_fd");
  6913 
  6914       if (display_get_fd)
  6915         dpyinfo->connection = display_get_fd (wl_dpy);
  6916     }
  6917 #endif
  6918 
  6919   if (dpyinfo->connection >= 0)
  6920     {
  6921       add_keyboard_wait_descriptor (dpyinfo->connection);
  6922 #ifdef F_SETOWN
  6923       fcntl (dpyinfo->connection, F_SETOWN, getpid ());
  6924 #endif /* ! defined (F_SETOWN) */
  6925 
  6926       if (interrupt_input)
  6927         init_sigio (dpyinfo->connection);
  6928     }
  6929 
  6930   dpyinfo->invisible_cursor
  6931     = gdk_cursor_new_for_display (dpyinfo->gdpy, GDK_BLANK_CURSOR);
  6932 
  6933   xsettings_initialize (dpyinfo);
  6934 
  6935   pgtk_im_init (dpyinfo);
  6936 
  6937   g_signal_connect (G_OBJECT (dpyinfo->gdpy), "seat-added",
  6938                     G_CALLBACK (pgtk_seat_added_cb), dpyinfo);
  6939   g_signal_connect (G_OBJECT (dpyinfo->gdpy), "seat-removed",
  6940                     G_CALLBACK (pgtk_seat_removed_cb), dpyinfo);
  6941   pgtk_enumerate_devices (dpyinfo, true);
  6942 
  6943   unblock_input ();
  6944 
  6945   return dpyinfo;
  6946 }
  6947 
  6948 /* Get rid of display DPYINFO, deleting all frames on it,
  6949    and without sending any more commands to the X server.  */
  6950 
  6951 static void
  6952 pgtk_delete_display (struct pgtk_display_info *dpyinfo)
  6953 {
  6954   struct terminal *t;
  6955 
  6956   /* Close all frames and delete the generic struct terminal for this
  6957      X display.  */
  6958   for (t = terminal_list; t; t = t->next_terminal)
  6959     if (t->type == output_pgtk && t->display_info.pgtk == dpyinfo)
  6960       {
  6961         delete_terminal (t);
  6962         break;
  6963       }
  6964 
  6965   if (x_display_list == dpyinfo)
  6966     x_display_list = dpyinfo->next;
  6967   else
  6968     {
  6969       struct pgtk_display_info *tail;
  6970 
  6971       for (tail = x_display_list; tail; tail = tail->next)
  6972         if (tail->next == dpyinfo)
  6973           tail->next = tail->next->next;
  6974     }
  6975 
  6976   pgtk_free_devices (dpyinfo);
  6977   xfree (dpyinfo);
  6978 }
  6979 
  6980 char *
  6981 pgtk_xlfd_to_fontname (const char *xlfd)
  6982 /* --------------------------------------------------------------------------
  6983     Convert an X font name (XLFD) to an Gtk font name.
  6984     Only family is used.
  6985     The string returned is temporarily allocated.
  6986    -------------------------------------------------------------------------- */
  6987 {
  6988   char *name = xmalloc (180);
  6989 
  6990   if (!strncmp (xlfd, "--", 2))
  6991     {
  6992       if (sscanf (xlfd, "--%179[^-]-", name) != 1)
  6993         name[0] = '\0';
  6994     }
  6995   else
  6996     {
  6997       if (sscanf (xlfd, "-%*[^-]-%179[^-]-", name) != 1)
  6998         name[0] = '\0';
  6999     }
  7000 
  7001   /* stopgap for malformed XLFD input */
  7002   if (strlen (name) == 0)
  7003     strcpy (name, "Monospace");
  7004 
  7005   return name;
  7006 }
  7007 
  7008 bool
  7009 pgtk_defined_color (struct frame *f, const char *name,
  7010                     Emacs_Color *color_def, bool alloc,
  7011                     bool makeIndex)
  7012 /* --------------------------------------------------------------------------
  7013          Return true if named color found, and set color_def rgb accordingly.
  7014          If makeIndex and alloc are nonzero put the color in the color_table,
  7015          and set color_def pixel to the resulting index.
  7016          If makeIndex is zero, set color_def pixel to ARGB.
  7017          Return false if not found
  7018    -------------------------------------------------------------------------- */
  7019 {
  7020   int r;
  7021 
  7022   block_input ();
  7023   r = xg_check_special_colors (f, name, color_def);
  7024   if (!r)
  7025     r = pgtk_parse_color (f, name, color_def);
  7026   unblock_input ();
  7027   return r;
  7028 }
  7029 
  7030 /* On frame F, translate the color name to RGB values.  Use cached
  7031    information, if possible.
  7032 
  7033    Note that there is currently no way to clean old entries out of the
  7034    cache.  However, it is limited to names in the server's database,
  7035    and names we've actually looked up; list-colors-display is probably
  7036    the most color-intensive case we're likely to hit.  */
  7037 
  7038 int
  7039 pgtk_parse_color (struct frame *f, const char *color_name,
  7040                   Emacs_Color * color)
  7041 {
  7042   GdkRGBA rgba;
  7043   if (gdk_rgba_parse (&rgba, color_name))
  7044     {
  7045       color->red = rgba.red * 65535;
  7046       color->green = rgba.green * 65535;
  7047       color->blue = rgba.blue * 65535;
  7048       color->pixel = ((color->red >> 8) << 16
  7049                       | (color->green >> 8) << 8
  7050                       | (color->blue >> 8) << 0);
  7051       return 1;
  7052     }
  7053   return 0;
  7054 }
  7055 
  7056 /* On frame F, translate pixel colors to RGB values for the NCOLORS
  7057    colors in COLORS.  On W32, we no longer try to map colors to
  7058    a palette.  */
  7059 void
  7060 pgtk_query_colors (struct frame *f, Emacs_Color * colors, int ncolors)
  7061 {
  7062   int i;
  7063 
  7064   for (i = 0; i < ncolors; i++)
  7065     {
  7066       unsigned long pixel = colors[i].pixel;
  7067       /* Convert to a 16 bit value in range 0 - 0xffff. */
  7068 #define GetRValue(p) (((p) >> 16) & 0xff)
  7069 #define GetGValue(p) (((p) >> 8) & 0xff)
  7070 #define GetBValue(p) (((p) >> 0) & 0xff)
  7071       colors[i].red = GetRValue (pixel) * 257;
  7072       colors[i].green = GetGValue (pixel) * 257;
  7073       colors[i].blue = GetBValue (pixel) * 257;
  7074     }
  7075 }
  7076 
  7077 void
  7078 pgtk_query_color (struct frame *f, Emacs_Color * color)
  7079 {
  7080   pgtk_query_colors (f, color, 1);
  7081 }
  7082 
  7083 void
  7084 pgtk_clear_area (struct frame *f, int x, int y, int width, int height)
  7085 {
  7086   cairo_t *cr;
  7087 
  7088   eassert (width > 0 && height > 0);
  7089 
  7090   cr = pgtk_begin_cr_clip (f);
  7091   pgtk_set_cr_source_with_color (f, FRAME_X_OUTPUT (f)->background_color,
  7092                                  true);
  7093   cairo_rectangle (cr, x, y, width, height);
  7094   cairo_fill (cr);
  7095   pgtk_end_cr_clip (f);
  7096 }
  7097 
  7098 
  7099 void
  7100 syms_of_pgtkterm (void)
  7101 {
  7102   DEFSYM (Qmodifier_value, "modifier-value");
  7103   DEFSYM (Qalt, "alt");
  7104   DEFSYM (Qhyper, "hyper");
  7105   DEFSYM (Qmeta, "meta");
  7106   DEFSYM (Qsuper, "super");
  7107   DEFSYM (Qcontrol, "control");
  7108   DEFSYM (QUTF8_STRING, "UTF8_STRING");
  7109 
  7110   DEFSYM (Qfile, "file");
  7111   DEFSYM (Qurl, "url");
  7112 
  7113   DEFSYM (Qlatin_1, "latin-1");
  7114 
  7115   xg_default_icon_file
  7116     = build_pure_c_string ("icons/hicolor/scalable/apps/emacs.svg");
  7117   staticpro (&xg_default_icon_file);
  7118 
  7119   DEFSYM (Qx_gtk_map_stock, "x-gtk-map-stock");
  7120 
  7121   DEFSYM (Qcopy, "copy");
  7122   DEFSYM (Qmove, "move");
  7123   DEFSYM (Qlink, "link");
  7124   DEFSYM (Qprivate, "private");
  7125 
  7126 
  7127   Fput (Qalt, Qmodifier_value, make_fixnum (alt_modifier));
  7128   Fput (Qhyper, Qmodifier_value, make_fixnum (hyper_modifier));
  7129   Fput (Qmeta, Qmodifier_value, make_fixnum (meta_modifier));
  7130   Fput (Qsuper, Qmodifier_value, make_fixnum (super_modifier));
  7131   Fput (Qcontrol, Qmodifier_value, make_fixnum (ctrl_modifier));
  7132 
  7133   DEFVAR_LISP ("x-ctrl-keysym", Vx_ctrl_keysym,
  7134                doc: /* SKIP: real doc in xterm.c.  */);
  7135   Vx_ctrl_keysym = Qnil;
  7136 
  7137   DEFVAR_LISP ("x-alt-keysym", Vx_alt_keysym,
  7138                doc: /* SKIP: real doc in xterm.c.  */);
  7139   Vx_alt_keysym = Qnil;
  7140 
  7141   DEFVAR_LISP ("x-hyper-keysym", Vx_hyper_keysym,
  7142                doc: /* SKIP: real doc in xterm.c.  */);
  7143   Vx_hyper_keysym = Qnil;
  7144 
  7145   DEFVAR_LISP ("x-meta-keysym", Vx_meta_keysym,
  7146                doc: /* SKIP: real doc in xterm.c.  */);
  7147   Vx_meta_keysym = Qnil;
  7148 
  7149   DEFVAR_LISP ("x-super-keysym", Vx_super_keysym,
  7150                doc: /* SKIP: real doc in xterm.c.  */);
  7151   Vx_super_keysym = Qnil;
  7152 
  7153   DEFVAR_BOOL ("x-use-underline-position-properties",
  7154                x_use_underline_position_properties,
  7155      doc: /* SKIP: real doc in xterm.c.  */);
  7156   x_use_underline_position_properties = 1;
  7157 
  7158   DEFVAR_BOOL ("x-underline-at-descent-line",
  7159                x_underline_at_descent_line,
  7160      doc: /* SKIP: real doc in xterm.c.  */);
  7161   x_underline_at_descent_line = 0;
  7162 
  7163   DEFVAR_LISP ("x-toolkit-scroll-bars", Vx_toolkit_scroll_bars,
  7164      doc: /* SKIP: real doc in xterm.c.  */);
  7165   Vx_toolkit_scroll_bars = intern_c_string ("gtk");
  7166 
  7167   DEFVAR_LISP ("pgtk-wait-for-event-timeout", Vpgtk_wait_for_event_timeout,
  7168                doc: /* How long to wait for GTK events.
  7169 
  7170 Emacs will wait up to this many seconds to receive some GTK events
  7171 after making changes which affect the state of the graphical
  7172 interface.  Under some window managers this can take an indefinite
  7173 amount of time, so it is important to limit the wait.
  7174 
  7175 If set to a non-float value, there will be no wait at all.  */);
  7176   Vpgtk_wait_for_event_timeout = make_float (0.1);
  7177 
  7178   DEFVAR_LISP ("pgtk-keysym-table", Vpgtk_keysym_table,
  7179     doc: /* Hash table of character codes indexed by X keysym codes.  */);
  7180   Vpgtk_keysym_table = make_hash_table (hashtest_eql, 900, DEFAULT_REHASH_SIZE,
  7181                                         DEFAULT_REHASH_THRESHOLD, Qnil, false);
  7182 
  7183   window_being_scrolled = Qnil;
  7184   staticpro (&window_being_scrolled);
  7185 
  7186   /* Tell Emacs about this window system.  */
  7187   Fprovide (Qpgtk, Qnil);
  7188 }
  7189 
  7190 /* Cairo does not allow resizing a surface/context after it is
  7191    created, so we need to trash the old context, create a new context
  7192    on the next cr_clip_begin with the new dimensions and request a
  7193    re-draw.
  7194 
  7195    This will leave the active context available to present on screen
  7196    until a redrawn frame is completed.  */
  7197 void
  7198 pgtk_cr_update_surface_desired_size (struct frame *f, int width, int height, bool force)
  7199 {
  7200   if (FRAME_CR_SURFACE_DESIRED_WIDTH (f) != width
  7201       || FRAME_CR_SURFACE_DESIRED_HEIGHT (f) != height
  7202       || force)
  7203     {
  7204       pgtk_cr_destroy_frame_context (f);
  7205       FRAME_CR_SURFACE_DESIRED_WIDTH (f) = width;
  7206       FRAME_CR_SURFACE_DESIRED_HEIGHT (f) = height;
  7207       SET_FRAME_GARBAGED (f);
  7208     }
  7209 }
  7210 
  7211 
  7212 cairo_t *
  7213 pgtk_begin_cr_clip (struct frame *f)
  7214 {
  7215   cairo_t *cr = FRAME_CR_CONTEXT (f);
  7216 
  7217   if (!cr)
  7218     {
  7219       cairo_surface_t *surface
  7220         = gdk_window_create_similar_surface (gtk_widget_get_window
  7221                                              (FRAME_GTK_WIDGET (f)),
  7222                                              CAIRO_CONTENT_COLOR_ALPHA,
  7223                                              FRAME_CR_SURFACE_DESIRED_WIDTH (f),
  7224                                              FRAME_CR_SURFACE_DESIRED_HEIGHT
  7225                                              (f));
  7226 
  7227       cr = FRAME_CR_CONTEXT (f) = cairo_create (surface);
  7228       cairo_surface_destroy (surface);
  7229     }
  7230 
  7231   cairo_save (cr);
  7232 
  7233   return cr;
  7234 }
  7235 
  7236 void
  7237 pgtk_end_cr_clip (struct frame *f)
  7238 {
  7239   cairo_restore (FRAME_CR_CONTEXT (f));
  7240 }
  7241 
  7242 void
  7243 pgtk_set_cr_source_with_gc_foreground (struct frame *f, Emacs_GC *gc,
  7244                                        bool respects_alpha_background)
  7245 {
  7246   pgtk_set_cr_source_with_color (f, gc->foreground,
  7247                                  respects_alpha_background);
  7248 }
  7249 
  7250 void
  7251 pgtk_set_cr_source_with_gc_background (struct frame *f, Emacs_GC *gc,
  7252                                        bool respects_alpha_background)
  7253 {
  7254   pgtk_set_cr_source_with_color (f, gc->background,
  7255                                  respects_alpha_background);
  7256 }
  7257 
  7258 void
  7259 pgtk_set_cr_source_with_color (struct frame *f, unsigned long color,
  7260                                bool respects_alpha_background)
  7261 {
  7262   Emacs_Color col;
  7263   col.pixel = color;
  7264   pgtk_query_color (f, &col);
  7265 
  7266   if (!respects_alpha_background)
  7267     {
  7268       cairo_set_source_rgb (FRAME_CR_CONTEXT (f), col.red / 65535.0,
  7269                             col.green / 65535.0, col.blue / 65535.0);
  7270       cairo_set_operator (FRAME_CR_CONTEXT (f), CAIRO_OPERATOR_OVER);
  7271     }
  7272   else
  7273     {
  7274       cairo_set_source_rgba (FRAME_CR_CONTEXT (f), col.red / 65535.0,
  7275                              col.green / 65535.0, col.blue / 65535.0,
  7276                              f->alpha_background);
  7277       cairo_set_operator (FRAME_CR_CONTEXT (f), CAIRO_OPERATOR_SOURCE);
  7278     }
  7279 }
  7280 
  7281 void
  7282 pgtk_cr_draw_frame (cairo_t * cr, struct frame *f)
  7283 {
  7284   cairo_set_source_surface (cr, FRAME_CR_SURFACE (f), 0, 0);
  7285   cairo_paint (cr);
  7286 }
  7287 
  7288 static cairo_status_t
  7289 pgtk_cr_accumulate_data (void *closure, const unsigned char *data,
  7290                          unsigned int length)
  7291 {
  7292   Lisp_Object *acc = (Lisp_Object *) closure;
  7293 
  7294   *acc = Fcons (make_unibyte_string ((char const *) data, length), *acc);
  7295 
  7296   return CAIRO_STATUS_SUCCESS;
  7297 }
  7298 
  7299 void
  7300 pgtk_cr_destroy_frame_context (struct frame *f)
  7301 {
  7302   if (FRAME_CR_CONTEXT (f) != NULL)
  7303     {
  7304       cairo_destroy (FRAME_CR_CONTEXT (f));
  7305       FRAME_CR_CONTEXT (f) = NULL;
  7306     }
  7307 }
  7308 
  7309 static void
  7310 pgtk_cr_destroy (void *cr)
  7311 {
  7312   block_input ();
  7313   cairo_destroy (cr);
  7314   unblock_input ();
  7315 }
  7316 
  7317 Lisp_Object
  7318 pgtk_cr_export_frames (Lisp_Object frames, cairo_surface_type_t surface_type)
  7319 {
  7320   struct frame *f;
  7321   cairo_surface_t *surface;
  7322   cairo_t *cr;
  7323   int width, height;
  7324   void (*surface_set_size_func) (cairo_surface_t *, double, double) = NULL;
  7325   Lisp_Object acc = Qnil;
  7326   specpdl_ref count = SPECPDL_INDEX ();
  7327 
  7328   specbind (Qredisplay_dont_pause, Qt);
  7329   redisplay_preserve_echo_area (31);
  7330 
  7331   f = XFRAME (XCAR (frames));
  7332   frames = XCDR (frames);
  7333   width = FRAME_PIXEL_WIDTH (f);
  7334   height = FRAME_PIXEL_HEIGHT (f);
  7335 
  7336   block_input ();
  7337 #ifdef CAIRO_HAS_PDF_SURFACE
  7338   if (surface_type == CAIRO_SURFACE_TYPE_PDF)
  7339     {
  7340       surface = cairo_pdf_surface_create_for_stream (pgtk_cr_accumulate_data, &acc,
  7341                                                      width, height);
  7342       surface_set_size_func = cairo_pdf_surface_set_size;
  7343     }
  7344   else
  7345 #endif
  7346 #ifdef CAIRO_HAS_PNG_FUNCTIONS
  7347   if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
  7348     surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
  7349   else
  7350 #endif
  7351 #ifdef CAIRO_HAS_PS_SURFACE
  7352   if (surface_type == CAIRO_SURFACE_TYPE_PS)
  7353     {
  7354       surface = cairo_ps_surface_create_for_stream (pgtk_cr_accumulate_data, &acc,
  7355                                                     width, height);
  7356       surface_set_size_func = cairo_ps_surface_set_size;
  7357     }
  7358   else
  7359 #endif
  7360 #ifdef CAIRO_HAS_SVG_SURFACE
  7361   if (surface_type == CAIRO_SURFACE_TYPE_SVG)
  7362     surface = cairo_svg_surface_create_for_stream (pgtk_cr_accumulate_data, &acc,
  7363                                                    width, height);
  7364   else
  7365 #endif
  7366     abort ();
  7367 
  7368   cr = cairo_create (surface);
  7369   cairo_surface_destroy (surface);
  7370   record_unwind_protect_ptr (pgtk_cr_destroy, cr);
  7371 
  7372   while (1)
  7373     {
  7374       cairo_t *saved_cr = FRAME_CR_CONTEXT (f);
  7375       FRAME_CR_CONTEXT (f) = cr;
  7376       pgtk_clear_area (f, 0, 0, width, height);
  7377       expose_frame (f, 0, 0, width, height);
  7378       FRAME_CR_CONTEXT (f) = saved_cr;
  7379 
  7380       if (NILP (frames))
  7381         break;
  7382 
  7383       cairo_surface_show_page (surface);
  7384       f = XFRAME (XCAR (frames));
  7385       frames = XCDR (frames);
  7386       width = FRAME_PIXEL_WIDTH (f);
  7387       height = FRAME_PIXEL_HEIGHT (f);
  7388       if (surface_set_size_func)
  7389         (*surface_set_size_func) (surface, width, height);
  7390 
  7391       unblock_input ();
  7392       maybe_quit ();
  7393       block_input ();
  7394     }
  7395 
  7396 #ifdef CAIRO_HAS_PNG_FUNCTIONS
  7397   if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
  7398     {
  7399       cairo_surface_flush (surface);
  7400       cairo_surface_write_to_png_stream (surface, pgtk_cr_accumulate_data, &acc);
  7401     }
  7402 #endif
  7403   unblock_input ();
  7404 
  7405   unbind_to (count, Qnil);
  7406 
  7407   return CALLN (Fapply, intern ("concat"), Fnreverse (acc));
  7408 }

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