]> code.delx.au - gnu-emacs/blobdiff - src/xterm.c
* lisp/mail/rmailsum.el: Commas no longer separate regexps. (Bug#19026)
[gnu-emacs] / src / xterm.c
index 04d6c061892228f0ef6f11913b059e8d9beab6cd..4f5dfed9ae8f37483deebe6ead4cf78a57893abf 100644 (file)
@@ -22,6 +22,9 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include <stdio.h>
+#ifdef USE_CAIRO
+#include <math.h>
+#endif
 
 #include "lisp.h"
 #include "blockinput.h"
@@ -211,34 +214,16 @@ enum xembed_message
     XEMBED_ACTIVATE_ACCELERATOR   = 14
   };
 
+static void x_free_cr_resources (struct frame *);
 static bool x_alloc_nearest_color_1 (Display *, Colormap, XColor *);
-static void x_set_window_size_1 (struct frame *, bool, int, int);
 static void x_raise_frame (struct frame *);
 static void x_lower_frame (struct frame *);
-static const XColor *x_color_cells (Display *, int *);
 static int x_io_error_quitter (Display *);
 static struct terminal *x_create_terminal (struct x_display_info *);
-static void x_update_end (struct frame *);
-static void XTframe_up_to_date (struct frame *);
-static void x_clear_area1 (Display *, Window, int, int, int, int, int);
-static void x_clear_frame (struct frame *);
-static _Noreturn void x_ins_del_lines (struct frame *, int, int);
-static void frame_highlight (struct frame *);
-static void frame_unhighlight (struct frame *);
-static void x_new_focus_frame (struct x_display_info *, struct frame *);
-static void  x_focus_changed (int, int, struct x_display_info *,
-                              struct frame *, struct input_event *);
-static void XTframe_rehighlight (struct frame *);
 static void x_frame_rehighlight (struct x_display_info *);
-static void x_draw_hollow_cursor (struct window *, struct glyph_row *);
-static void x_draw_bar_cursor (struct window *, struct glyph_row *, int,
-                               enum text_cursor_kinds);
 
 static void x_clip_to_row (struct window *, struct glyph_row *,
                           enum glyph_row_area, GC);
-static void x_flush (struct frame *f);
-static void x_update_begin (struct frame *);
-static void x_update_window_begin (struct window *);
 static struct scroll_bar *x_window_to_scroll_bar (Display *, Window, int);
 static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *,
                                         enum scroll_bar_part *,
@@ -258,9 +243,6 @@ static int handle_one_xevent (struct x_display_info *,
 #if ! (defined USE_X_TOOLKIT || defined USE_MOTIF)
 static int x_dispatch_event (XEvent *, Display *);
 #endif
-/* Don't declare this _Noreturn because we want no
-   interference with debugging failing X calls.  */
-static void x_connection_closed (Display *, const char *);
 static void x_wm_set_window_state (struct frame *, int);
 static void x_wm_set_icon_pixmap (struct frame *, ptrdiff_t);
 static void x_initialize (void);
@@ -326,32 +308,13 @@ record_event (char *locus, int type)
 
 #endif
 
-static void x_prepare_for_xlibdraw (struct frame *);
-static void x_set_clip_rectangles (struct frame *, GC, XRectangle *, int);
-static void x_reset_clip_rectangles (struct frame *, GC);
-static void x_fill_rectangle (struct frame *, GC, int, int,
-                              unsigned int, unsigned int);
-static void x_draw_rectangle (struct frame *, GC, int, int,
-                              unsigned int, unsigned int);
-static void x_fill_trapezoid_for_relief (struct frame *, GC, int, int,
-                                         unsigned int, unsigned int, int);
-static void x_clear_window (struct frame *);
-
 #ifdef USE_CAIRO
-static struct x_gc_ext_data *x_gc_get_ext_data (struct frame *, GC, int);
-static void x_extension_initialize (struct x_display_info *);
-static cairo_status_t x_cr_accumulate_data (void *,
-                                            const unsigned char *,
-                                            unsigned int);
 
 #define FRAME_CR_CONTEXT(f)    ((f)->output_data.x->cr_context)
 #define FRAME_CR_SURFACE(f)    ((f)->output_data.x->cr_surface)
 
 static struct x_gc_ext_data *
-x_gc_get_ext_data (f, gc, create_if_not_found_p)
-     struct frame *f;
-     GC gc;
-     int create_if_not_found_p;
+x_gc_get_ext_data (struct frame *f, GC gc, int create_if_not_found_p)
 {
   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
   XEDataObject object;
@@ -376,8 +339,7 @@ x_gc_get_ext_data (f, gc, create_if_not_found_p)
 }
 
 static void
-x_extension_initialize (dpyinfo)
-     struct x_display_info *dpyinfo;
+x_extension_initialize (struct x_display_info *dpyinfo)
 {
   XExtCodes *ext_codes = XAddExtension (dpyinfo->display);
 
@@ -398,9 +360,7 @@ x_cr_destroy_surface (struct frame *f)
 }
 
 cairo_t *
-x_begin_cr_clip (f, gc)
-     struct frame *f;
-     GC gc;
+x_begin_cr_clip (struct frame *f, GC gc)
 {
   cairo_t *cr = FRAME_CR_CONTEXT (f);
 
@@ -445,16 +405,13 @@ x_begin_cr_clip (f, gc)
 }
 
 void
-x_end_cr_clip (f)
-     struct frame *f;
+x_end_cr_clip (struct frame *f)
 {
   cairo_restore (FRAME_CR_CONTEXT (f));
 }
 
 void
-x_set_cr_source_with_gc_foreground (f, gc)
-     struct frame *f;
-     GC gc;
+x_set_cr_source_with_gc_foreground (struct frame *f, GC gc)
 {
   XGCValues xgcv;
   XColor color;
@@ -467,9 +424,7 @@ x_set_cr_source_with_gc_foreground (f, gc)
 }
 
 void
-x_set_cr_source_with_gc_background (f, gc)
-     struct frame *f;
-     GC gc;
+x_set_cr_source_with_gc_background (struct frame *f, GC gc)
 {
   XGCValues xgcv;
   XColor color;
@@ -487,10 +442,7 @@ static int max_fringe_bmp = 0;
 static cairo_pattern_t **fringe_bmp = 0;
 
 static void
-x_cr_define_fringe_bitmap (which, bits, h, wd)
-     int which;
-     unsigned short *bits;
-     int h, wd;
+x_cr_define_fringe_bitmap (int which, unsigned short *bits, int h, int wd)
 {
   int i, stride;
   cairo_surface_t *surface;
@@ -528,8 +480,7 @@ x_cr_define_fringe_bitmap (which, bits, h, wd)
 }
 
 static void
-x_cr_destroy_fringe_bitmap (which)
-     int which;
+x_cr_destroy_fringe_bitmap (int which)
 {
   if (which >= max_fringe_bmp)
     return;
@@ -544,16 +495,9 @@ x_cr_destroy_fringe_bitmap (which)
 }
 
 static void
-x_cr_draw_image (struct frame *f,
-                 GC gc,
-                 cairo_pattern_t *image,
-                 int src_x,
-                 int src_y,
-                 unsigned int width,
-                 unsigned int height,
-                int dest_x,
-                 int dest_y,
-                 bool overlay_p)
+x_cr_draw_image (struct frame *f, GC gc, cairo_pattern_t *image,
+                int src_x, int src_y, int width, int height,
+                int dest_x, int dest_y, bool overlay_p)
 {
   cairo_t *cr;
   cairo_matrix_t matrix;
@@ -588,16 +532,14 @@ x_cr_draw_image (struct frame *f,
 }
 
 void
-x_cr_draw_frame (cr, f)
-     cairo_t *cr;
-     struct frame *f;
+x_cr_draw_frame (cairo_t *cr, struct frame *f)
 {
   int width, height;
 
   width = FRAME_PIXEL_WIDTH (f);
   height = FRAME_PIXEL_HEIGHT (f);
 
-  x_prepare_for_xlibdraw (f);
+  x_free_cr_resources (f);
   FRAME_CR_CONTEXT (f) = cr;
   x_clear_area (f, 0, 0, width, height);
   expose_frame (f, 0, 0, width, height);
@@ -605,10 +547,8 @@ x_cr_draw_frame (cr, f)
 }
 
 static cairo_status_t
-x_cr_accumulate_data (closure, data, length)
-     void *closure;
-     const unsigned char *data;
-     unsigned int length;
+x_cr_accumulate_data (void *closure, const unsigned char *data,
+                     unsigned int length)
 {
   Lisp_Object *acc = (Lisp_Object *) closure;
 
@@ -618,8 +558,7 @@ x_cr_accumulate_data (closure, data, length)
 }
 
 static void
-x_cr_destroy (arg)
-     Lisp_Object arg;
+x_cr_destroy (Lisp_Object arg)
 {
   cairo_t *cr = (cairo_t *) XSAVE_POINTER (arg, 0);
 
@@ -629,9 +568,7 @@ x_cr_destroy (arg)
 }
 
 Lisp_Object
-x_cr_export_frames (frames, surface_type)
-     Lisp_Object frames;
-     cairo_surface_type_t surface_type;
+x_cr_export_frames (Lisp_Object frames, cairo_surface_type_t surface_type)
 {
   struct frame *f;
   cairo_surface_t *surface;
@@ -690,7 +627,7 @@ x_cr_export_frames (frames, surface_type)
       QUIT;
 
       block_input ();
-      x_prepare_for_xlibdraw (f);
+      x_free_cr_resources (f);
       FRAME_CR_CONTEXT (f) = cr;
       x_clear_area (f, 0, 0, width, height);
       expose_frame (f, 0, 0, width, height);
@@ -730,8 +667,7 @@ x_cr_export_frames (frames, surface_type)
 #endif /* USE_CAIRO */
 
 static void
-x_prepare_for_xlibdraw (f)
-     struct frame *f;
+x_free_cr_resources (struct frame *f)
 {
 #ifdef USE_CAIRO
   if (f == NULL)
@@ -739,7 +675,7 @@ x_prepare_for_xlibdraw (f)
       Lisp_Object rest, frame;
       FOR_EACH_FRAME (rest, frame)
        if (FRAME_X_P (XFRAME (frame)))
-         x_prepare_for_xlibdraw (XFRAME (frame));
+         x_free_cr_resources (XFRAME (frame));
     }
   else
     {
@@ -760,11 +696,7 @@ x_prepare_for_xlibdraw (f)
 }
 
 static void
-x_set_clip_rectangles (f, gc, rectangles, n)
-     struct frame *f;
-     GC gc;
-     XRectangle *rectangles;
-     int n;
+x_set_clip_rectangles (struct frame *f, GC gc, XRectangle *rectangles, int n)
 {
   XSetClipRectangles (FRAME_X_DISPLAY (f), gc, 0, 0, rectangles, n, Unsorted);
 #ifdef USE_CAIRO
@@ -780,9 +712,7 @@ x_set_clip_rectangles (f, gc, rectangles, n)
 }
 
 static void
-x_reset_clip_rectangles (f, gc)
-     struct frame *f;
-     GC gc;
+x_reset_clip_rectangles (struct frame *f, GC gc)
 {
   XSetClipMask (FRAME_X_DISPLAY (f), gc, None);
 #ifdef USE_CAIRO
@@ -796,11 +726,7 @@ x_reset_clip_rectangles (f, gc)
 }
 
 static void
-x_fill_rectangle (f, gc, x, y, width, height)
-     struct frame *f;
-     GC gc;
-     int x, y;
-     unsigned int width, height;
+x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
 {
 #ifdef USE_CAIRO
   cairo_t *cr;
@@ -817,11 +743,7 @@ x_fill_rectangle (f, gc, x, y, width, height)
 }
 
 static void
-x_draw_rectangle (f, gc, x, y, width, height)
-     struct frame *f;
-     GC gc;
-     int x, y;
-     unsigned int width, height;
+x_draw_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
 {
 #ifdef USE_CAIRO
   cairo_t *cr;
@@ -839,8 +761,7 @@ x_draw_rectangle (f, gc, x, y, width, height)
 }
 
 static void
-x_clear_window (f)
-     struct frame *f;
+x_clear_window (struct frame *f)
 {
 #ifdef USE_CAIRO
   cairo_t *cr;
@@ -856,12 +777,8 @@ x_clear_window (f)
 
 #ifdef USE_CAIRO
 static void
-x_fill_trapezoid_for_relief (f, gc, x, y, width, height, top_p)
-     struct frame *f;
-     GC gc;
-     int x, y;
-     unsigned int width, height;
-     int top_p;
+x_fill_trapezoid_for_relief (struct frame *f, GC gc, int x, int y,
+                            int width, int height, int top_p)
 {
   cairo_t *cr;
 
@@ -871,10 +788,92 @@ x_fill_trapezoid_for_relief (f, gc, x, y, width, height, top_p)
   cairo_line_to (cr, x, y + height);
   cairo_line_to (cr, top_p ? x + width - height : x + width, y + height);
   cairo_line_to (cr, x + width, y);
-  cairo_close_path (cr);
   cairo_fill (cr);
   x_end_cr_clip (f);
 }
+
+enum corners
+  {
+    CORNER_BOTTOM_RIGHT,       /* 0 -> pi/2 */
+    CORNER_BOTTOM_LEFT,                /* pi/2 -> pi */
+    CORNER_TOP_LEFT,           /* pi -> 3pi/2 */
+    CORNER_TOP_RIGHT,          /* 3pi/2 -> 2pi */
+    CORNER_LAST
+  };
+
+static void
+x_erase_corners_for_relief (struct frame *f, GC gc, int x, int y,
+                           int width, int height,
+                           double radius, double margin, int corners)
+{
+  cairo_t *cr;
+  int i;
+
+  cr = x_begin_cr_clip (f, gc);
+  x_set_cr_source_with_gc_background (f, gc);
+  for (i = 0; i < CORNER_LAST; i++)
+    if (corners & (1 << i))
+      {
+       double xm, ym, xc, yc;
+
+       if (i == CORNER_TOP_LEFT || i == CORNER_BOTTOM_LEFT)
+         xm = x - margin, xc = xm + radius;
+       else
+         xm = x + width + margin, xc = xm - radius;
+       if (i == CORNER_TOP_LEFT || i == CORNER_TOP_RIGHT)
+         ym = y - margin, yc = ym + radius;
+       else
+         ym = y + height + margin, yc = ym - radius;
+
+       cairo_move_to (cr, xm, ym);
+       cairo_arc (cr, xc, yc, radius, i * M_PI_2, (i + 1) * M_PI_2);
+      }
+  cairo_clip (cr);
+  cairo_rectangle (cr, x, y, width, height);
+  cairo_fill (cr);
+  x_end_cr_clip (f);
+}
+
+static void
+x_draw_horizontal_wave (struct frame *f, GC gc, int x, int y,
+                       int width, int height, int wave_length)
+{
+  cairo_t *cr;
+  double dx = wave_length, dy = height - 1;
+  int xoffset, n;
+
+  cr = x_begin_cr_clip (f, gc);
+  x_set_cr_source_with_gc_foreground (f, gc);
+  cairo_rectangle (cr, x, y, width, height);
+  cairo_clip (cr);
+
+  if (x >= 0)
+    {
+      xoffset = x % (wave_length * 2);
+      if (xoffset == 0)
+       xoffset = wave_length * 2;
+    }
+  else
+    xoffset = x % (wave_length * 2) + wave_length * 2;
+  n = (width + xoffset) / wave_length + 1;
+  if (xoffset > wave_length)
+    {
+      xoffset -= wave_length;
+      --n;
+      y += height - 1;
+      dy = -dy;
+    }
+
+  cairo_move_to (cr, x - xoffset + 0.5, y + 0.5);
+  while (--n >= 0)
+    {
+      cairo_rel_line_to (cr, dx, dy);
+      dy = -dy;
+    }
+  cairo_set_line_width (cr, 1);
+  cairo_stroke (cr);
+  x_end_cr_clip (f);
+}
 #endif
 
 \f
@@ -1004,6 +1003,10 @@ static void
 x_update_begin (struct frame *f)
 {
 #ifdef USE_CAIRO
+  if (! NILP (tip_frame) && XFRAME (tip_frame) == f
+      && ! FRAME_VISIBLE_P (f))
+    return;
+
   if (! FRAME_CR_SURFACE (f))
     {
       int width, height;
@@ -1917,7 +1920,7 @@ x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
        {
          sprintf (buf, "%0*X",
                   glyph->u.glyphless.ch < 0x10000 ? 4 : 6,
-                  glyph->u.glyphless.ch);
+                  glyph->u.glyphless.ch + 0u);
          str = buf;
        }
 
@@ -2010,9 +2013,9 @@ x_alloc_lighter_color_for_widget (Widget widget, Display *display, Colormap cmap
 
 static XtConvertArgRec cvt_string_to_pixel_args[] =
   {
-    {XtWidgetBaseOffset, (XtPointer) XtOffset (Widget, core.screen),
+    {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.screen),
      sizeof (Screen *)},
-    {XtWidgetBaseOffset, (XtPointer) XtOffset (Widget, core.colormap),
+    {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.colormap),
      sizeof (Colormap)}
   };
 
@@ -2516,6 +2519,7 @@ x_draw_relief_rect (struct frame *f,
 {
 #ifdef USE_CAIRO
   GC top_left_gc, bottom_right_gc;
+  int corners = 0;
 
   if (raised_p)
     {
@@ -2532,11 +2536,23 @@ x_draw_relief_rect (struct frame *f,
   x_set_clip_rectangles (f, bottom_right_gc, clip_rect, 1);
 
   if (left_p)
-    x_fill_rectangle (f, top_left_gc, left_x, top_y,
-                     width, bottom_y + 1 - top_y);
+    {
+      x_fill_rectangle (f, top_left_gc, left_x, top_y,
+                       width, bottom_y + 1 - top_y);
+      if (top_p)
+       corners |= 1 << CORNER_TOP_LEFT;
+      if (bot_p)
+       corners |= 1 << CORNER_BOTTOM_LEFT;
+    }
   if (right_p)
-    x_fill_rectangle (f, bottom_right_gc, right_x + 1 - width, top_y,
-                     width, bottom_y + 1 - top_y);
+    {
+      x_fill_rectangle (f, bottom_right_gc, right_x + 1 - width, top_y,
+                       width, bottom_y + 1 - top_y);
+      if (top_p)
+       corners |= 1 << CORNER_TOP_RIGHT;
+      if (bot_p)
+       corners |= 1 << CORNER_BOTTOM_RIGHT;
+    }
   if (top_p)
     {
       if (!right_p)
@@ -2556,9 +2572,23 @@ x_draw_relief_rect (struct frame *f,
                                     left_x, bottom_y + 1 - width,
                                     right_x + 1 - left_x, width, 0);
     }
+  if (left_p && width != 1)
+    x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
+                     1, bottom_y + 1 - top_y);
+  if (top_p && width != 1)
+    x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
+                     right_x + 1 - left_x, 1);
+  if (corners)
+    {
+      XSetBackground (FRAME_X_DISPLAY (f), top_left_gc,
+                     FRAME_BACKGROUND_PIXEL (f));
+      x_erase_corners_for_relief (f, top_left_gc, left_x, top_y,
+                                 right_x - left_x + 1, bottom_y - top_y + 1,
+                                 6, 1, corners);
+    }
 
-  x_set_clip_rectangles (f, top_left_gc, clip_rect, 1);
-  x_set_clip_rectangles (f, bottom_right_gc, clip_rect, 1);
+  x_reset_clip_rectangles (f, top_left_gc);
+  x_reset_clip_rectangles (f, bottom_right_gc);
 #else
   Display *dpy = FRAME_X_DISPLAY (f);
   Window window = FRAME_X_WINDOW (f);
@@ -3102,6 +3132,7 @@ x_draw_image_glyph_string (struct glyph_string *s)
     }
 
   /* Draw the foreground.  */
+#ifdef USE_CAIRO
   if (s->img->cr_data)
     {
       cairo_t *cr = x_begin_cr_clip (s->f, s->gc);
@@ -3117,7 +3148,9 @@ x_draw_image_glyph_string (struct glyph_string *s)
       cairo_fill (cr);
       x_end_cr_clip (s->f);
     }
-  else if (pixmap != None)
+  else
+#endif
+    if (pixmap != None)
     {
       x_draw_image_foreground_1 (s, pixmap);
       x_set_glyph_string_clipping (s);
@@ -3218,7 +3251,7 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
              XSetForeground (s->display, gc, xgcv.foreground);
            }
 
-         XSetClipMask (s->display, gc, None);
+         x_reset_clip_rectangles (s->f, gc);
        }
     }
   else if (!s->background_filled_p)
@@ -3255,6 +3288,10 @@ static void
 x_draw_underwave (struct glyph_string *s)
 {
   int wave_height = 3, wave_length = 2;
+#ifdef USE_CAIRO
+  x_draw_horizontal_wave (s->f, s->gc, s->x, s->ybase - wave_height + 3,
+                         s->width, wave_height, wave_length);
+#else  /* not USE_CAIRO */
   int dx, dy, x0, y0, width, x1, y1, x2, y2, xmax;
   bool odd;
   XRectangle wave_clip, string_clip, final_clip;
@@ -3304,6 +3341,7 @@ x_draw_underwave (struct glyph_string *s)
 
   /* Restore previous clipping rectangle(s) */
   XSetClipRectangles (s->display, s->gc, 0, 0, s->clip, s->num_clips, Unsorted);
+#endif /* not USE_CAIRO */
 }
 
 
@@ -3591,7 +3629,9 @@ x_draw_glyph_string (struct glyph_string *s)
 static void
 x_shift_glyphs_for_insert (struct frame *f, int x, int y, int width, int height, int shift_by)
 {
-  x_prepare_for_xlibdraw (f);
+/* Never called on a GUI frame, see
+   http://lists.gnu.org/archive/html/emacs-devel/2015-05/msg00456.html
+*/
   XCopyArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), FRAME_X_WINDOW (f),
             f->output_data.x->normal_gc,
             x, y, width, height,
@@ -3621,10 +3661,7 @@ x_clear_area1 (Display *dpy, Window window,
 
 
 void
-x_clear_area (f, x, y, width, height)
-     struct frame *f;
-     int x, y;
-     int width, height;
+x_clear_area (struct frame *f, int x, int y, int width, int height)
 {
 #ifdef USE_CAIRO
   cairo_t *cr;
@@ -6364,7 +6401,7 @@ x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end,
       x_clear_area1 (FRAME_X_DISPLAY (f), w,
                    VERTICAL_SCROLL_BAR_LEFT_BORDER,
                    VERTICAL_SCROLL_BAR_TOP_BORDER,
-                   inside_width, start);
+                   inside_width, start, False);
 
     /* Change to proper foreground color if one is specified.  */
     if (f->output_data.x->scroll_bar_foreground_pixel != -1)
@@ -6389,7 +6426,7 @@ x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end,
       x_clear_area1 (FRAME_X_DISPLAY (f), w,
                    VERTICAL_SCROLL_BAR_LEFT_BORDER,
                    VERTICAL_SCROLL_BAR_TOP_BORDER + end,
-                   inside_width, inside_height - end);
+                   inside_width, inside_height - end, False);
   }
 
   unblock_input ();
@@ -6623,8 +6660,7 @@ XTset_horizontal_scroll_bar (struct window *w, int portion, int whole, int posit
        int area_height = WINDOW_CONFIG_SCROLL_BAR_HEIGHT (w);
        int rest = area_height - height;
        if (rest > 0 && width > 0)
-         x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                       left, top, width, rest);
+         x_clear_area (f, left, top, width, rest);
       }
 
       /* Move/size the scroll bar window.  */
@@ -7729,11 +7765,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       goto OTHER;
 
     case MapNotify:
-      if (event->xmap.window == tip_window)
-        /* The tooltip has been drawn already.  Avoid
-           the SET_FRAME_GARBAGED below.  */
-        goto OTHER;
-
       /* We use x_top_window_to_frame because map events can
          come for sub-windows and they don't mean that the
          frame is visible.  */
@@ -7780,17 +7811,18 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 
       f = any;
 
-#if ! defined (USE_GTK)
       /* If mouse-highlight is an integer, input clears out
         mouse highlighting.  */
       if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
+#if ! defined (USE_GTK)
          && (f == 0
-             || !EQ (f->tool_bar_window, hlinfo->mouse_face_window)))
+             || !EQ (f->tool_bar_window, hlinfo->mouse_face_window))
+#endif
+         )
         {
           clear_mouse_face (hlinfo);
           hlinfo->mouse_face_hidden = true;
         }
-#endif
 
 #if defined USE_MOTIF && defined USE_TOOLKIT_SCROLL_BARS
       if (f == 0)
@@ -8259,7 +8291,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
         {
           xg_frame_resized (f, event->xconfigure.width,
                             event->xconfigure.height);
+#ifdef USE_CAIRO
           x_cr_destroy_surface (f);
+#endif
           f = 0;
         }
 #endif
@@ -8267,6 +8301,18 @@ handle_one_xevent (struct x_display_info *dpyinfo,
         {
          x_net_wm_state (f, event->xconfigure.window);
 
+#ifdef USE_X_TOOLKIT
+          /* Tip frames are pure X window, set size for them.  */
+          if (! NILP (tip_frame) && XFRAME (tip_frame) == f)
+            {
+              if (FRAME_PIXEL_HEIGHT (f) != event->xconfigure.height
+                  || FRAME_PIXEL_WIDTH (f) != event->xconfigure.width)
+                SET_FRAME_GARBAGED (f);
+              FRAME_PIXEL_HEIGHT (f) = event->xconfigure.height;
+              FRAME_PIXEL_WIDTH (f) = event->xconfigure.width;
+            }
+#endif
+
 #ifndef USE_X_TOOLKIT
 #ifndef USE_GTK
           int width = FRAME_PIXEL_TO_TEXT_WIDTH (f, event->xconfigure.width);
@@ -9172,7 +9218,7 @@ static char *error_msg;
    the text of an error message that lead to the connection loss.  */
 
 static void
-x_connection_closed (Display *dpy, const char *error_message)
+x_connection_closed (Display *dpy, const char *error_message, bool ioerror)
 {
   struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
   Lisp_Object frame, tail;
@@ -9191,6 +9237,7 @@ x_connection_closed (Display *dpy, const char *error_message)
       dpyinfo->reference_count++;
       dpyinfo->terminal->reference_count++;
     }
+  if (ioerror) dpyinfo->display = 0;
 
   /* First delete frames whose mini-buffers are on frames
      that are on the dead display.  */
@@ -9328,7 +9375,7 @@ x_error_quitter (Display *display, XErrorEvent *event)
   XGetErrorText (display, event->error_code, buf, sizeof (buf));
   sprintf (buf1, "X protocol error: %s on protocol request %d",
           buf, event->request_code);
-  x_connection_closed (display, buf1);
+  x_connection_closed (display, buf1, false);
 }
 
 
@@ -9343,7 +9390,7 @@ x_io_error_quitter (Display *display)
 
   snprintf (buf, sizeof buf, "Connection lost to X server `%s'",
            DisplayString (display));
-  x_connection_closed (display, buf);
+  x_connection_closed (display, buf, true);
   return 0;
 }
 \f
@@ -10958,7 +11005,7 @@ x_free_frame_resources (struct frame *f)
        free_frame_xic (f);
 #endif
 
-      x_prepare_for_xlibdraw (f);
+      x_free_cr_resources (f);
 #ifdef USE_X_TOOLKIT
       if (f->output_data.x->widget)
        {
@@ -11408,7 +11455,10 @@ get_bits_and_offset (unsigned long mask, int *bits, int *offset)
 bool
 x_display_ok (const char *display)
 {
+  /* XOpenDisplay fails if it gets a signal.  Block SIGIO which may arrive.  */
+  unrequest_sigio ();
   Display *dpy = XOpenDisplay (display);
+  request_sigio ();
   if (!dpy)
     return false;
   XCloseDisplay (dpy);
@@ -11588,7 +11638,9 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
 
         /* gtk_init does set_locale.  Fix locale before and after.  */
         fixup_locale ();
+        unrequest_sigio (); /* See comment in x_display_ok.  */
         gtk_init (&argc, &argv2);
+        request_sigio ();
         fixup_locale ();
 
         g_log_remove_handler ("GLib", id);
@@ -11638,10 +11690,12 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
        argv[argc++] = xrm_option;
       }
     turn_on_atimers (false);
+    unrequest_sigio ();  /* See comment in x_display_ok.  */
     dpy = XtOpenDisplay (Xt_app_con, SSDATA (display_name),
                         resource_name, EMACS_CLASS,
                         emacs_options, XtNumber (emacs_options),
                         &argc, argv);
+    request_sigio ();
     turn_on_atimers (true);
 
 #ifdef HAVE_X11XTR6
@@ -11652,7 +11706,9 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
 
 #else /* not USE_X_TOOLKIT */
   XSetLocaleModifiers ("");
+  unrequest_sigio ();  // See comment in x_display_ok.
   dpy = XOpenDisplay (SSDATA (display_name));
+  request_sigio ();
 #endif /* not USE_X_TOOLKIT */
 #endif /* not USE_GTK*/
 
@@ -12165,7 +12221,7 @@ static struct redisplay_interface x_redisplay_interface =
     x_draw_window_cursor,
     x_draw_vertical_window_border,
     x_draw_window_divider,
-    x_shift_glyphs_for_insert,
+    x_shift_glyphs_for_insert, /* Never called; see comment in function.  */
     x_show_hourglass,
     x_hide_hourglass
   };
@@ -12466,9 +12522,11 @@ default is nil, which is the same as `super'.  */);
   DEFVAR_BOOL ("x-frame-normalize-before-maximize",
               x_frame_normalize_before_maximize,
     doc: /* Non-nil means normalize frame before maximizing.
-If this variable is t, Emacs asks the window manager to give the frame
-intermediately its normal size whenever changing from a full-height or
-full-width state to the fully maximized one and vice versa.
+If this variable is t, Emacs first asks the window manager to give the
+frame its normal size, and only then the final state, whenever changing
+from a full-height, full-width or full-both state to the maximized one
+or when changing from the maximized to the full-height or full-width
+state.
 
 Set this variable only if your window manager cannot handle the
 transition between the various maximization states.  */);