]> code.delx.au - gnu-emacs/blobdiff - src/xterm.c
(XTread_socket) [!USE_X_TOOLKIT]: Compute the value of `dont_resize' only
[gnu-emacs] / src / xterm.c
index c6ff4e6d08ea6485731a23afc2fed6f912ee68c1..77860842d5733ac58ec4da5112af5254736ba8f8 100644 (file)
@@ -172,9 +172,17 @@ enum fringe_bitmap_type
    `indicate-empty-lines' is non-nil.  */
 
 #define zv_width 8
-#define zv_height 8
+#define zv_height 72
+#define zv_period 3
 static unsigned char zv_bits[] = {
-   0x00, 0x00, 0x1e, 0x1e, 0x1e, 0x1e, 0x00, 0x00};
+  0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
+  0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
+  0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
+  0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
+  0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
+  0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
+  0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
+  0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
 
 /* An arrow like this: `<-'.  */
 
@@ -462,13 +470,14 @@ static void x_update_window_cursor P_ ((struct window *, int));
 static void x_erase_phys_cursor P_ ((struct window *));
 void x_display_and_set_cursor P_ ((struct window *, int, int, int, int, int));
 static void x_draw_fringe_bitmap P_ ((struct window *, struct glyph_row *, 
-                                     enum fringe_bitmap_type));
+                                     enum fringe_bitmap_type, int left_p));
 
 static void x_clip_to_row P_ ((struct window *, struct glyph_row *,
                               GC, int));
 static int x_phys_cursor_in_rect_p P_ ((struct window *, XRectangle *));
 static void x_draw_row_fringe_bitmaps P_ ((struct window *, struct glyph_row *));
-static void notice_overwritten_cursor P_ ((struct window *, int, int));
+static void notice_overwritten_cursor P_ ((struct window *, enum glyph_row_area,
+                                          int, int, int, int));
 static void x_flush P_ ((struct frame *f));
 static void x_update_begin P_ ((struct frame *));
 static void x_update_window_begin P_ ((struct window *));
@@ -481,6 +490,8 @@ static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *,
                                            enum scroll_bar_part *,
                                            Lisp_Object *, Lisp_Object *,
                                            unsigned long *));
+static void x_check_fullscreen P_ ((struct frame *));
+static void x_check_fullscreen_move P_ ((struct frame *));
 
 /* Flush display of frame F, or of all frames if F is null.  */
 
@@ -817,15 +828,17 @@ x_after_update_window_line (desired_row)
    drawn.  */
 
 static void
-x_draw_fringe_bitmap (w, row, which)
+x_draw_fringe_bitmap (w, row, which, left_p)
      struct window *w;
      struct glyph_row *row;
      enum fringe_bitmap_type which;
+     int left_p;
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
   Display *display = FRAME_X_DISPLAY (f);
   Window window = FRAME_X_WINDOW (f);
   int x, y, wd, h, dy;
+  int b1, b2;
   unsigned char *bits;
   Pixmap pixmap;
   GC gc = f->output_data.x->normal_gc;
@@ -835,77 +848,137 @@ x_draw_fringe_bitmap (w, row, which)
   /* Must clip because of partially visible lines.  */
   x_clip_to_row (w, row, gc, 1);
 
+  /* Convert row to frame coordinates.  */
+  y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
+
   switch (which)
     {
+    case NO_FRINGE_BITMAP:
+      wd = 0;
+      h = 0;
+      break;
+
     case LEFT_TRUNCATION_BITMAP:
       wd = left_width;
       h = left_height;
       bits = left_bits;
-      x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
-          - wd
-          - (FRAME_X_LEFT_FRINGE_WIDTH (f) - wd) / 2);
       break;
       
     case OVERLAY_ARROW_BITMAP:
-      wd = left_width;
-      h = left_height;
+      wd = ov_width;
+      h = ov_height;
       bits = ov_bits;
-      x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
-          - wd
-          - (FRAME_X_LEFT_FRINGE_WIDTH (f) - wd) / 2);
       break;
       
     case RIGHT_TRUNCATION_BITMAP:
       wd = right_width;
       h = right_height;
       bits = right_bits;
-      x = window_box_right (w, -1);
-      x += (FRAME_X_RIGHT_FRINGE_WIDTH (f) - wd) / 2;
       break;
 
     case CONTINUED_LINE_BITMAP:
-      wd = right_width;
-      h = right_height;
+      wd = continued_width;
+      h = continued_height;
       bits = continued_bits;
-      x = window_box_right (w, -1);
-      x += (FRAME_X_RIGHT_FRINGE_WIDTH (f) - wd) / 2;
       break;
       
     case CONTINUATION_LINE_BITMAP:
       wd = continuation_width;
       h = continuation_height;
       bits = continuation_bits;
-      x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
-          - wd
-          - (FRAME_X_LEFT_FRINGE_WIDTH (f) - wd) / 2);
       break;
 
     case ZV_LINE_BITMAP:
       wd = zv_width;
-      h = zv_height;
-      bits = zv_bits;
-      x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
-          - wd
-          - (FRAME_X_LEFT_FRINGE_WIDTH (f) - wd) / 2);
+      h = zv_height - (y % zv_period);
+      bits = zv_bits + (y % zv_period);
       break;
 
     default:
       abort ();
     }
 
-  /* Convert to frame coordinates.  Set dy to the offset in the row to
-     start drawing the bitmap.  */
-  y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
+  /* Clip bitmap if too high.  */
+  if (h > row->height)
+    h = row->height;
+
+  /* Set dy to the offset in the row to start drawing the bitmap.  */
   dy = (row->height - h) / 2;
 
-  /* Draw the bitmap.  I believe these small pixmaps can be cached
-     by the server.  */
   face = FACE_FROM_ID (f, FRINGE_FACE_ID);
-  pixmap = XCreatePixmapFromBitmapData (display, window, bits, wd, h,
-                                       face->foreground,
-                                       face->background, depth);
-  XCopyArea (display, pixmap, window, gc, 0, 0, wd, h, x, y + dy);
-  XFreePixmap (display, pixmap);
+  PREPARE_FACE_FOR_DISPLAY (f, face);
+
+  /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
+     the fringe.  */
+  b1 = b2 = -1;
+  if (left_p)
+    {
+      if (wd > FRAME_X_LEFT_FRINGE_WIDTH (f))
+       wd = FRAME_X_LEFT_FRINGE_WIDTH (f);
+      x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
+          - wd
+          - (FRAME_X_LEFT_FRINGE_WIDTH (f) - wd) / 2);
+      if (wd < FRAME_X_LEFT_FRINGE_WIDTH (f) || row->height > h)
+       {
+         /* If W has a vertical border to its left, don't draw over it.  */
+         int border = ((XFASTINT (w->left) > 0
+                        && !FRAME_HAS_VERTICAL_SCROLL_BARS (f))
+                       ? 1 : 0);
+         b1 = (window_box_left (w, -1)
+               - FRAME_X_LEFT_FRINGE_WIDTH (f)
+               + border);
+         b2 = (FRAME_X_LEFT_FRINGE_WIDTH (f) - border);
+       }
+    }
+  else
+    {
+      if (wd > FRAME_X_RIGHT_FRINGE_WIDTH (f))
+       wd = FRAME_X_RIGHT_FRINGE_WIDTH (f);
+      x = (window_box_right (w, -1)
+          + (FRAME_X_RIGHT_FRINGE_WIDTH (f) - wd) / 2);
+      /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
+        the fringe.  */
+      if (wd < FRAME_X_RIGHT_FRINGE_WIDTH (f) || row->height > h)
+       {
+         b1 = window_box_right (w, -1);
+         b2 = FRAME_X_RIGHT_FRINGE_WIDTH (f);
+       }
+    }
+
+  if (b1 >= 0)
+    {
+      int header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
+      
+      /* In case the same realized face is used for fringes and
+        for something displayed in the text (e.g. face `region' on
+        mono-displays, the fill style may have been changed to
+        FillSolid in x_draw_glyph_string_background.  */
+      if (face->stipple)
+       XSetFillStyle (display, face->gc, FillOpaqueStippled);
+      else
+       XSetForeground (display, face->gc, face->background);
+      
+      XFillRectangle (display, window, face->gc,
+                     b1,
+                     WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
+                                                      row->y)),
+                     b2,
+                     row->visible_height);
+      if (!face->stipple)
+       XSetForeground (display, face->gc, face->foreground);
+    }
+
+  if (which != NO_FRINGE_BITMAP)
+    {
+      /* Draw the bitmap.  I believe these small pixmaps can be cached
+        by the server.  */
+      pixmap = XCreatePixmapFromBitmapData (display, window, bits, wd, h,
+                                           face->foreground,
+                                           face->background, depth);
+      XCopyArea (display, pixmap, window, gc, 0, 0, wd, h, x, y + dy);
+      XFreePixmap (display, pixmap);
+    }
+  
   XSetClipMask (display, gc, None);
 }
 
@@ -920,8 +993,6 @@ x_draw_row_fringe_bitmaps (w, row)
 {
   struct frame *f = XFRAME (w->frame);
   enum fringe_bitmap_type bitmap;
-  struct face *face;
-  int header_line_height = -1;
 
   xassert (interrupt_input_blocked);
 
@@ -930,103 +1001,37 @@ x_draw_row_fringe_bitmaps (w, row)
   if (row->visible_height <= 0)
     return;
 
-  face = FACE_FROM_ID (f, FRINGE_FACE_ID);
-  PREPARE_FACE_FOR_DISPLAY (f, face);
-
-  /* Decide which bitmap to draw in the left fringe.  */
-  if (row->overlay_arrow_p)
-    bitmap = OVERLAY_ARROW_BITMAP;
-  else if (row->truncated_on_left_p)
-    bitmap = LEFT_TRUNCATION_BITMAP;
-  else if (MATRIX_ROW_CONTINUATION_LINE_P (row))
-    bitmap = CONTINUATION_LINE_BITMAP;
-  else if (row->indicate_empty_line_p)
-    bitmap = ZV_LINE_BITMAP;
-  else
-    bitmap = NO_FRINGE_BITMAP;
-
-  /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
-     the fringe.  */
-  if (bitmap == NO_FRINGE_BITMAP
-      || FRAME_FRINGE_BITMAP_WIDTH (f) < FRAME_X_LEFT_FRINGE_WIDTH (f)
-      || row->height > FRAME_FRINGE_BITMAP_HEIGHT (f))
-    {
-      /* If W has a vertical border to its left, don't draw over it.  */
-      int border = ((XFASTINT (w->left) > 0
-                    && !FRAME_HAS_VERTICAL_SCROLL_BARS (f))
-                   ? 1 : 0);
-      int left = window_box_left (w, -1);
-
-      if (header_line_height < 0)
-       header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
-      
-      /* In case the same realized face is used for fringes and
-        for something displayed in the text (e.g. face `region' on
-        mono-displays, the fill style may have been changed to
-        FillSolid in x_draw_glyph_string_background.  */
-      if (face->stipple)
-       XSetFillStyle (FRAME_X_DISPLAY (f), face->gc, FillOpaqueStippled);
+  if (FRAME_X_LEFT_FRINGE_WIDTH (f) != 0)
+    {
+      /* Decide which bitmap to draw in the left fringe.  */
+      if (row->overlay_arrow_p)
+       bitmap = OVERLAY_ARROW_BITMAP;
+      else if (row->truncated_on_left_p)
+       bitmap = LEFT_TRUNCATION_BITMAP;
+      else if (MATRIX_ROW_CONTINUATION_LINE_P (row))
+       bitmap = CONTINUATION_LINE_BITMAP;
+      else if (row->indicate_empty_line_p)
+       bitmap = ZV_LINE_BITMAP;
       else
-       XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->background);
-      
-      XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                     face->gc,
-                     (left
-                      - FRAME_X_LEFT_FRINGE_WIDTH (f)
-                      + border),
-                     WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
-                                                      row->y)),
-                     FRAME_X_LEFT_FRINGE_WIDTH (f) - border,
-                     row->visible_height);
-      if (!face->stipple)
-       XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->foreground);
-    }
-
-  /* Draw the left bitmap.  */
-  if (bitmap != NO_FRINGE_BITMAP)
-    x_draw_fringe_bitmap (w, row, bitmap);
+       bitmap = NO_FRINGE_BITMAP;
 
-  /* Decide which bitmap to draw in the right fringe.  */
-  if (row->truncated_on_right_p)
-    bitmap = RIGHT_TRUNCATION_BITMAP;
-  else if (row->continued_p)
-    bitmap = CONTINUED_LINE_BITMAP;
-  else
-    bitmap = NO_FRINGE_BITMAP;
+      x_draw_fringe_bitmap (w, row, bitmap, 1);
+    }
 
-  /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
-     the fringe.  */
-  if (bitmap == NO_FRINGE_BITMAP
-      || FRAME_FRINGE_BITMAP_WIDTH (f) < FRAME_X_RIGHT_FRINGE_WIDTH (f)
-      || row->height > FRAME_FRINGE_BITMAP_HEIGHT (f))
+  if (FRAME_X_RIGHT_FRINGE_WIDTH (f) != 0)
     {
-      int right = window_box_right (w, -1);
-
-      if (header_line_height < 0)
-       header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
-
-      /* In case the same realized face is used for fringes and
-        for something displayed in the text (e.g. face `region' on
-        mono-displays, the fill style may have been changed to
-        FillSolid in x_draw_glyph_string_background.  */
-      if (face->stipple)
-       XSetFillStyle (FRAME_X_DISPLAY (f), face->gc, FillOpaqueStippled);
+      /* Decide which bitmap to draw in the right fringe.  */
+      if (row->truncated_on_right_p)
+       bitmap = RIGHT_TRUNCATION_BITMAP;
+      else if (row->continued_p)
+       bitmap = CONTINUED_LINE_BITMAP;
+      else if (row->indicate_empty_line_p && FRAME_X_LEFT_FRINGE_WIDTH (f) == 0)
+       bitmap = ZV_LINE_BITMAP;
       else
-       XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->background);
-      XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                     face->gc,
-                     right,
-                     WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
-                                                      row->y)),
-                     FRAME_X_RIGHT_FRINGE_WIDTH (f),
-                     row->visible_height);
-      if (!face->stipple)
-       XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->foreground);
-    }
+       bitmap = NO_FRINGE_BITMAP;
 
-  /* Draw the right bitmap.  */
-  if (bitmap != NO_FRINGE_BITMAP)
-    x_draw_fringe_bitmap (w, row, bitmap);
+      x_draw_fringe_bitmap (w, row, bitmap, 0);
+    }
 }
 
 \f
@@ -1605,7 +1610,7 @@ x_append_stretch_glyph (it, object, width, height, ascent)
    4. `:height HEIGHT' specifies that the height of the stretch produced
    should be HEIGHT, measured in canonical character units.
 
-   5. `:relative-height FACTOR' specifies that the height of the the
+   5. `:relative-height FACTOR' specifies that the height of the
    stretch should be FACTOR times the height of the characters having
    the glyph property.
 
@@ -3834,6 +3839,7 @@ x_setup_relief_colors (s)
   if (s->face->use_box_color_for_shadows_p)
     color = s->face->box_color;
   else if (s->first_glyph->type == IMAGE_GLYPH
+          && s->img->pixmap
           && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
     color = IMAGE_BACKGROUND (s->img, s->f, 0);
   else
@@ -4127,7 +4133,7 @@ x_draw_image_relief (s)
   if (s->hl == DRAW_IMAGE_SUNKEN
       || s->hl == DRAW_IMAGE_RAISED)
     {
-      thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : 3;
+      thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF;
       raised_p = s->hl == DRAW_IMAGE_RAISED;
     }
   else
@@ -5064,7 +5070,6 @@ x_draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
       /* X is relative to the left edge of W, without scroll bars
         or fringes.  */
       struct frame *f = XFRAME (w->frame);
-      /* int width = FRAME_FRINGE_WIDTH (f);  */
       int window_left_x = WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f);
 
       x += window_left_x;
@@ -5206,7 +5211,8 @@ x_draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
          x1 -= left_area_width;
        }
 
-      notice_overwritten_cursor (w, x0, x1);
+      notice_overwritten_cursor (w, area, x0, x1,
+                                row->y, MATRIX_ROW_BOTTOM_Y (row));
     }
 
   /* Value is the x-position up to which drawn, relative to AREA of W.
@@ -5428,7 +5434,10 @@ x_clear_end_of_line (to_x)
   
   /* Notice if the cursor will be cleared by this operation.  */
   if (!updated_row->full_width_p)
-    notice_overwritten_cursor (w, output_cursor.x, -1);
+    notice_overwritten_cursor (w, updated_area,
+                              output_cursor.x, -1,
+                              updated_row->y,
+                              MATRIX_ROW_BOTTOM_Y (updated_row));
 
   from_x = output_cursor.x;
      
@@ -7317,7 +7326,7 @@ x_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
 
 
 /* Handle mouse button event on the tool-bar of frame F, at
-   frame-relative coordinates X/Y.  EVENT_TYPE is either ButtionPress
+   frame-relative coordinates X/Y.  EVENT_TYPE is either ButtonPress
    or ButtonRelase.  */
 
 static void
@@ -7647,9 +7656,9 @@ fast_find_position (w, pos, hpos, vpos, x, y, stop)
 #endif /* not 0 */
 
 
-/* Find the position of the the glyph for position POS in OBJECT in
-   window W's current matrix, and return in *X/*Y the pixel
-   coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
+/* Find the position of the glyph for position POS in OBJECT in
+   window W's current matrix, and return in *X*Y the pixel
+   coordinates, and return in *HPOS*VPOS the column/row of the glyph.
 
    RIGHT_P non-zero means return the position of the right edge of the
    glyph, RIGHT_P zero means return the left edge position.
@@ -7779,7 +7788,8 @@ show_mouse_face (dpyinfo, draw)
              x_draw_glyphs (w, start_x, row, TEXT_AREA, 
                             start_hpos, end_hpos, draw, 0);
 
-             row->mouse_face_p = draw == DRAW_MOUSE_FACE || DRAW_IMAGE_RAISED;
+             row->mouse_face_p
+               = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
            }
        }
 
@@ -10235,6 +10245,8 @@ XTread_socket (sd, bufp, numchars, expected)
              f = x_window_to_frame (dpyinfo, event.xexpose.window);
              if (f)
                {
+                  x_check_fullscreen (f);
+
                  if (f->async_visible == 0)
                    {
                      f->async_visible = 1;
@@ -10407,7 +10419,7 @@ XTread_socket (sd, bufp, numchars, expected)
                     status_return even if the input is too long to
                     fit in 81 bytes.  So, we must prepare sufficient
                     bytes for copy_buffer.  513 bytes (256 chars for
-                    two-byte character set) seems to be a faily good
+                    two-byte character set) seems to be a fairly good
                     approximation.  -- 2000.8.10 handa@etl.go.jp  */
                  unsigned char copy_buffer[513];
                  unsigned char *copy_bufptr = copy_buffer;
@@ -10837,8 +10849,17 @@ XTread_socket (sd, bufp, numchars, expected)
              if (f)
                {
 #ifndef USE_X_TOOLKIT
+                  /* If there is a pending resize for fullscreen, don't
+                     do this one, the right one will come later.
+                    The toolkit version doesn't seem to need this, but we
+                    need to reset it below.  */
+                  int dont_resize =
+                    ((f->output_data.x->want_fullscreen & FULLSCREEN_WAIT)
+                     && FRAME_NEW_WIDTH (f) != 0);
                  int rows = PIXEL_TO_CHAR_HEIGHT (f, event.xconfigure.height);
                  int columns = PIXEL_TO_CHAR_WIDTH (f, event.xconfigure.width);
+                  if (dont_resize)
+                    goto OTHER;
                  
                  /* In the toolkit version, change_frame_size
                     is called by the code that handles resizing
@@ -10866,6 +10887,10 @@ XTread_socket (sd, bufp, numchars, expected)
                  x_real_positions (f, &f->output_data.x->left_pos,
                                    &f->output_data.x->top_pos);
 
+                  x_check_fullscreen_move(f);
+                  if (f->output_data.x->want_fullscreen & FULLSCREEN_WAIT)
+                    f->output_data.x->want_fullscreen &=
+                      ~(FULLSCREEN_WAIT|FULLSCREEN_BOTH);
 #ifdef HAVE_X_I18N
                  if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea))
                    xic_set_statusarea (f);
@@ -11097,22 +11122,25 @@ XTread_socket (sd, bufp, numchars, expected)
                             Text Cursor
  ***********************************************************************/
 
-/* Notice if the text cursor of window W has been overwritten by a
-   drawing operation that outputs N glyphs starting at START_X and
-   ending at END_X in the line given by output_cursor.vpos.
-   Coordinates are area-relative.  END_X < 0 means all the rest
-   of the line after START_X has been written.  */
+/* Notice when the text cursor of window W has been completely
+   overwritten by a drawing operation that outputs glyphs in AREA
+   starting at X0 and ending at X1 in the line starting at Y0 and
+   ending at Y1.  X coordinates are area-relative.  X1 < 0 means all
+   the rest of the line after X0 has been written.  Y coordinates
+   are window-relative.  */
 
 static void
-notice_overwritten_cursor (w, start_x, end_x)
+notice_overwritten_cursor (w, area, x0, x1, y0, y1)
      struct window *w;
-     int start_x, end_x;
+     enum glyph_row_area area;
+     int x0, y0, x1, y1;
 {
-  if (updated_area == TEXT_AREA
+  if (area == TEXT_AREA
       && w->phys_cursor_on_p
-      && output_cursor.vpos == w->phys_cursor.vpos
-      && start_x <= w->phys_cursor.x
-      && (end_x < 0 || end_x > w->phys_cursor.x))
+      && y0 <= w->phys_cursor.y
+      && y1 >= w->phys_cursor.y + w->phys_cursor_height
+      && x0 <= w->phys_cursor.x
+      && (x1 < 0 || x1 > w->phys_cursor.x))
     w->phys_cursor_on_p = 0;
 }
 
@@ -12099,7 +12127,9 @@ x_new_font (f, fontname)
   f->output_data.x->font = (XFontStruct *) (fontp->font);
   f->output_data.x->baseline_offset = fontp->baseline_offset;
   f->output_data.x->fontset = -1;
-  
+
+  x_compute_fringe_widths (f, 1);
+
   /* Compute the scroll bar width in character columns.  */
   if (f->scroll_bar_pixel_width > 0)
     {
@@ -12177,6 +12207,90 @@ x_new_fontset (f, fontsetname)
   return build_string (fontsetname);
 }
 
+/* Compute actual fringe widths */
+
+void
+x_compute_fringe_widths (f, redraw)
+     struct frame *f;
+     int redraw;
+{
+  int o_left = f->output_data.x->left_fringe_width;
+  int o_right = f->output_data.x->right_fringe_width;
+  int o_cols = f->output_data.x->fringe_cols;
+
+  Lisp_Object left_fringe = Fassq (Qleft_fringe, f->param_alist);
+  Lisp_Object right_fringe = Fassq (Qright_fringe, f->param_alist);
+  int left_fringe_width, right_fringe_width;
+
+  if (!NILP (left_fringe))
+    left_fringe = Fcdr (left_fringe);
+  if (!NILP (right_fringe))
+    right_fringe = Fcdr (right_fringe);
+
+  left_fringe_width = ((NILP (left_fringe) || !INTEGERP (left_fringe)) ? 8 :
+                      XINT (left_fringe));
+  right_fringe_width = ((NILP (right_fringe) || !INTEGERP (right_fringe)) ? 8 :
+                       XINT (right_fringe));
+
+  if (left_fringe_width || right_fringe_width)
+    {
+      int left_wid = left_fringe_width >= 0 ? left_fringe_width : -left_fringe_width;
+      int right_wid = right_fringe_width >= 0 ? right_fringe_width : -right_fringe_width;
+      int conf_wid = left_wid + right_wid;
+      int font_wid = FONT_WIDTH (f->output_data.x->font);
+      int cols = (left_wid + right_wid + font_wid-1) / font_wid;
+      int real_wid = cols * font_wid;
+      if (left_wid && right_wid)
+       {
+         if (left_fringe_width < 0)
+           {
+             /* Left fringe width is fixed, adjust right fringe if necessary */
+             f->output_data.x->left_fringe_width = left_wid;
+             f->output_data.x->right_fringe_width = real_wid - left_wid;
+           }
+         else if (right_fringe_width < 0)
+           {
+             /* Right fringe width is fixed, adjust left fringe if necessary */
+             f->output_data.x->left_fringe_width = real_wid - right_wid;
+             f->output_data.x->right_fringe_width = right_wid;
+           }
+         else
+           {
+             /* Adjust both fringes with an equal amount.
+                Note that we are doing integer arithmetic here, so don't
+                lose a pixel if the total width is an odd number.  */
+             int fill = real_wid - conf_wid;
+             f->output_data.x->left_fringe_width = left_wid + fill/2;
+             f->output_data.x->right_fringe_width = right_wid + fill - fill/2;
+           }
+       }
+      else if (left_fringe_width)
+       {
+         f->output_data.x->left_fringe_width = real_wid;
+         f->output_data.x->right_fringe_width = 0;
+       }
+      else
+       {
+         f->output_data.x->left_fringe_width = 0;
+         f->output_data.x->right_fringe_width = real_wid;
+       }
+      f->output_data.x->fringe_cols = cols;
+      f->output_data.x->fringes_extra = real_wid;
+    }
+  else
+    {
+      f->output_data.x->left_fringe_width = 0;
+      f->output_data.x->right_fringe_width = 0;
+      f->output_data.x->fringe_cols = 0;
+      f->output_data.x->fringes_extra = 0;
+    }
+
+  if (redraw && FRAME_VISIBLE_P (f))
+    if (o_left != f->output_data.x->left_fringe_width ||
+       o_right != f->output_data.x->right_fringe_width ||
+       o_cols != f->output_data.x->fringe_cols)
+      redraw_frame (f);
+}
 \f
 /***********************************************************************
                           X Input Methods
@@ -12546,6 +12660,114 @@ x_set_offset (f, xoff, yoff, change_gravity)
   UNBLOCK_INPUT;
 }
 
+/* Check if we need to resize the frame due to a fullscreen request.
+   If so needed, resize the frame. */
+static void
+x_check_fullscreen (f)
+     struct frame *f;
+{
+  if (f->output_data.x->want_fullscreen & FULLSCREEN_BOTH)
+    {
+      int width, height, ign;
+                      
+      x_real_positions (f, &f->output_data.x->left_pos,
+                        &f->output_data.x->top_pos);
+
+      x_fullscreen_adjust (f, &width, &height, &ign, &ign);
+                  
+      /* We do not need to move the window, it shall be taken care of
+         when setting WM manager hints.
+         If the frame is visible already, the position is checked by
+         x_check_fullscreen_move. */
+      if (f->width != width || f->height != height)
+        {
+          change_frame_size (f, height, width, 0, 1, 0);
+          SET_FRAME_GARBAGED (f);
+          cancel_mouse_face (f);
+
+          /* Wait for the change of frame size to occur */
+          f->output_data.x->want_fullscreen |= FULLSCREEN_WAIT;
+          
+        }
+    }
+}
+
+/* If frame parameters are set after the frame is mapped, we need to move
+   the window.  This is done in xfns.c.
+   Some window managers moves the window to the right position, some
+   moves the outer window manager window to the specified position.
+   Here we check that we are in the right spot.  If not, make a second
+   move, assuming we are dealing with the second kind of window manager. */
+static void
+x_check_fullscreen_move (f)
+     struct frame *f;
+{
+  if (f->output_data.x->want_fullscreen & FULLSCREEN_MOVE_WAIT)
+  {
+    int expect_top = f->output_data.x->top_pos;
+    int expect_left = f->output_data.x->left_pos;
+
+    if (f->output_data.x->want_fullscreen & FULLSCREEN_HEIGHT)
+      expect_top = 0;
+    if (f->output_data.x->want_fullscreen & FULLSCREEN_WIDTH)
+      expect_left = 0;
+    
+    if (expect_top != f->output_data.x->top_pos
+        || expect_left != f->output_data.x->left_pos)
+      x_set_offset (f, expect_left, expect_top, 1);
+
+    /* Just do this once */
+    f->output_data.x->want_fullscreen &= ~FULLSCREEN_MOVE_WAIT;
+  }
+}
+
+
+/* Calculate fullscreen size.  Return in *TOP_POS and *LEFT_POS the
+   wanted positions of the WM window (not emacs window).
+   Return in *WIDTH and *HEIGHT the wanted width and height of Emacs
+   window (FRAME_X_WINDOW).
+ */
+void
+x_fullscreen_adjust (f, width, height, top_pos, left_pos)
+     struct frame *f;
+     int *width;
+     int *height;
+     int *top_pos;
+     int *left_pos;
+{
+  int newwidth = f->width, newheight = f->height;
+
+  *top_pos = f->output_data.x->top_pos;
+  *left_pos = f->output_data.x->left_pos;
+  
+  if (f->output_data.x->want_fullscreen & FULLSCREEN_HEIGHT)
+    {
+      int ph;
+      
+      ph = FRAME_X_DISPLAY_INFO (f)->height;
+      newheight = PIXEL_TO_CHAR_HEIGHT (f, ph);
+      ph = CHAR_TO_PIXEL_HEIGHT (f, newheight)
+        - f->output_data.x->y_pixels_diff;
+      newheight = PIXEL_TO_CHAR_HEIGHT (f, ph);
+      *top_pos = 0;
+    }
+
+  if (f->output_data.x->want_fullscreen & FULLSCREEN_WIDTH)
+    {
+      int pw;
+      
+      pw = FRAME_X_DISPLAY_INFO (f)->width;
+      newwidth = PIXEL_TO_CHAR_WIDTH (f, pw);
+      pw = CHAR_TO_PIXEL_WIDTH (f, newwidth)
+        - f->output_data.x->x_pixels_diff;
+      newwidth = PIXEL_TO_CHAR_WIDTH (f, pw);
+      *left_pos = 0;
+    }
+
+  *width = newwidth;
+  *height = newheight;
+}
+
 
 /* Change the size of frame F's X window to COLS/ROWS in the case F
    doesn't have a widget.  If CHANGE_GRAVITY is 1, we change to
@@ -12567,8 +12789,9 @@ x_set_window_size_1 (f, change_gravity, cols, rows)
        : FRAME_SCROLL_BAR_PIXEL_WIDTH (f) > 0
        ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f)
        : (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->output_data.x->font)));
-  f->output_data.x->fringes_extra
-    = FRAME_FRINGE_WIDTH (f);
+
+  x_compute_fringe_widths (f, 0);
+
   pixelwidth = CHAR_TO_PIXEL_WIDTH (f, cols);
   pixelheight = CHAR_TO_PIXEL_HEIGHT (f, rows);
 
@@ -13131,6 +13354,8 @@ x_free_frame_resources (f)
      struct frame *f;
 {
   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  Lisp_Object bar;
+  struct scroll_bar *b;
 
   BLOCK_INPUT;
 
@@ -13140,23 +13365,40 @@ x_free_frame_resources (f)
     {
       if (f->output_data.x->icon_desc)
        XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->icon_desc);
-      
+
+#ifdef USE_X_TOOLKIT
+      /* Explicitly destroy the scroll bars of the frame.  Without
+        this, we get "BadDrawable" errors from the toolkit later on,
+        presumably from expose events generated for the disappearing
+        toolkit scroll bars.  */
+      for (bar = FRAME_SCROLL_BARS (f); !NILP (bar); bar = b->next)
+       {
+         b = XSCROLL_BAR (bar);
+         x_scroll_bar_remove (b);
+       }
+#endif
+
 #ifdef HAVE_X_I18N
       if (FRAME_XIC (f))
        free_frame_xic (f);
 #endif
-      
-      if (FRAME_X_WINDOW (f))
-       XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
-      
+
 #ifdef USE_X_TOOLKIT
       if (f->output_data.x->widget)
        {
          XtDestroyWidget (f->output_data.x->widget);
          f->output_data.x->widget = NULL;
        }
+      /* Tooltips don't have widgets, only a simple X window, even if
+        we are using a toolkit.  */
+      else if (FRAME_X_WINDOW (f))
+       XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
+
       free_frame_menubar (f);
-#endif /* USE_X_TOOLKIT */
+#else  /* !USE_X_TOOLKIT */
+      if (FRAME_X_WINDOW (f))
+       XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
+#endif /* !USE_X_TOOLKIT */
 
       unload_color (f, f->output_data.x->foreground_pixel);
       unload_color (f, f->output_data.x->background_pixel);
@@ -13164,7 +13406,7 @@ x_free_frame_resources (f)
       unload_color (f, f->output_data.x->cursor_foreground_pixel);
       unload_color (f, f->output_data.x->border_pixel);
       unload_color (f, f->output_data.x->mouse_pixel);
-      
+
       if (f->output_data.x->scroll_bar_background_pixel != -1)
        unload_color (f, f->output_data.x->scroll_bar_background_pixel);
       if (f->output_data.x->scroll_bar_foreground_pixel != -1)
@@ -14056,10 +14298,10 @@ x_load_font (f, fontname, size)
 
     /* Set global flag fonts_changed_p to non-zero if the font loaded
        has a character with a smaller width than any other character
-       before, or if the font loaded has a smalle>r height than any
+       before, or if the font loaded has a smaller height than any
        other font loaded before.  If this happens, it will make a
        glyph matrix reallocation necessary.  */
-    fonts_changed_p = x_compute_min_glyph_bounds (f);
+    fonts_changed_p |= x_compute_min_glyph_bounds (f);
     UNBLOCK_INPUT;
     return fontp;
   }
@@ -14764,7 +15006,7 @@ wide as that tab on the display.  */);
   DEFVAR_BOOL ("x-use-underline-position-properties",
               &x_use_underline_position_properties,
      doc: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
-Nil means ignore them.  If you encounter fonts with bogus
+nil means ignore them.  If you encounter fonts with bogus
 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
 to 4.1, set this to nil.  */);
   x_use_underline_position_properties = 1;