changeset 47099:4a9df8aa130c

(x_display_and_set_cursor): Use FRAME_BLINK_OFF_CURSOR and FRAME_BLINK_OFF_CURSOR_WIDTH for blinking cursor off. (x_display_and_set_cursor): Check FRAME_CURSOR_WIDTH for bar cursor. (expose_overlaps): New function. (expose_window): Use it to fix the display of overlapping rows.
author Richard M. Stallman <rms@gnu.org>
date Thu, 29 Aug 2002 14:38:12 +0000
parents 7746b52cf1c9
children c7ddac695d06
files src/w32term.c
diffstat 1 files changed, 109 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- a/src/w32term.c	Thu Aug 29 14:37:51 2002 +0000
+++ b/src/w32term.c	Thu Aug 29 14:38:12 2002 +0000
@@ -401,6 +401,8 @@
 				   enum text_cursor_kinds));
 static void expose_frame P_ ((struct frame *, int, int, int, int));
 static int expose_window_tree P_ ((struct window *, RECT *));
+static void expose_overlaps P_ ((struct window *, struct glyph_row *,
+				 struct glyph_row *));
 static int expose_window P_ ((struct window *, RECT *));
 static void expose_area P_ ((struct window *, struct glyph_row *,
 			     RECT *, enum glyph_row_area));
@@ -5771,6 +5773,39 @@
 }
 
 
+/* Redraw those parts of glyphs rows during expose event handling that
+   overlap other rows.  Redrawing of an exposed line writes over parts
+   of lines overlapping that exposed line; this function fixes that.
+
+   W is the window being exposed.  FIRST_OVERLAPPING_ROW is the first
+   row in W's current matrix that is exposed and overlaps other rows.
+   LAST_OVERLAPPING_ROW is the last such row.  */
+
+static void
+expose_overlaps (w, first_overlapping_row, last_overlapping_row)
+     struct window *w;
+     struct glyph_row *first_overlapping_row;
+     struct glyph_row *last_overlapping_row;
+{
+  struct glyph_row *row;
+  
+  for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
+    if (row->overlapping_p)
+      {
+	xassert (row->enabled_p && !row->mode_line_p);
+	  
+	if (row->used[LEFT_MARGIN_AREA])
+	  x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
+  
+	if (row->used[TEXT_AREA])
+	  x_fix_overlapping_area (w, row, TEXT_AREA);
+  
+	if (row->used[RIGHT_MARGIN_AREA])
+	  x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
+      }
+}
+
+
 /* Redraw the part of window W intersection rectagle FR.  Pixel
    coordinates in FR are frame relative.  Call this function with
    input blocked.  Value is non-zero if the exposure overwrites
@@ -5812,6 +5847,7 @@
       int yb = window_text_bottom_y (w);
       struct glyph_row *row;
       int cursor_cleared_p;
+      struct glyph_row *first_overlapping_row, *last_overlapping_row;
 
       TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
 	      r.left, r.top, r.right, r.bottom));
@@ -5832,7 +5868,8 @@
       else
 	cursor_cleared_p = 0;
 
-      /* Find the first row intersecting the rectangle R.  */
+      /* Update lines intersecting rectangle R.  */
+      first_overlapping_row = last_overlapping_row = NULL;
       for (row = w->current_matrix->rows;
 	   row->enabled_p;
 	   ++row)
@@ -5845,6 +5882,13 @@
 	      || (r.top >= y0 && r.top < y1)
 	      || (r.bottom > y0 && r.bottom < y1))
 	    {
+	      if (row->overlapping_p)
+		{
+		  if (first_overlapping_row == NULL)
+		    first_overlapping_row = row;
+		  last_overlapping_row = row;
+		}
+	      
 	      if (expose_line (w, row, &r))
 		mouse_face_overwritten_p = 1;
 	    }
@@ -5865,6 +5909,10 @@
 
       if (!w->pseudo_window_p)
 	{
+	  /* Fix the display of overlapping rows.  */
+	  if (first_overlapping_row)
+	    expose_overlaps (w, first_overlapping_row, last_overlapping_row);
+          
 	  /* Draw border between windows.  */
 	  x_draw_vertical_border (w);
 
@@ -9617,7 +9665,7 @@
      cursor glyph at hand.  */
   if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
     goto mark_cursor_off;
-	 
+
   /* If the cursor is in the mouse face area, redisplay that when
      we clear the cursor.  */
   if (! NILP (dpyinfo->mouse_face_window)
@@ -9711,6 +9759,7 @@
   struct frame *f = XFRAME (w->frame);
   int new_cursor_type;
   int new_cursor_width;
+  int cursor_off_state = 0;
   struct glyph_matrix *current_glyphs;
   struct glyph_row *glyph_row;
   struct glyph *glyph;
@@ -9751,59 +9800,69 @@
      the cursor type given by the frame parameter.  If explicitly
      marked off, draw no cursor.  In all other cases, we want a hollow
      box cursor.  */
-  cursor_non_selected 
-    = !NILP (Fbuffer_local_value (Qcursor_in_non_selected_windows,
-				  w->buffer));
   new_cursor_width = -1;
+  new_cursor_type = -2;
+
+  /* Echo area */
   if (cursor_in_echo_area
       && FRAME_HAS_MINIBUF_P (f)
       && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
     {
       if (w == XWINDOW (echo_area_window))
 	new_cursor_type = FRAME_DESIRED_CURSOR (f);
+      else if (NILP (Fbuffer_local_value (Qcursor_in_non_selected_windows,
+					  w->buffer)))
+	new_cursor_type = NO_CURSOR;
       else
+	cursor_off_state = 1;
+    }
+
+  /* Nonselected window or nonselected frame.  */
+  else if (f != FRAME_X_DISPLAY_INFO (f)->w32_highlight_frame
+	   || w != XWINDOW (f->selected_window))
+    {
+      if ((MINI_WINDOW_P (w) && minibuf_level == 0)
+	  || NILP (Fbuffer_local_value (Qcursor_in_non_selected_windows,
+					w->buffer))
+	  || NILP (XBUFFER (w->buffer)->cursor_type))
+	new_cursor_type = NO_CURSOR;
+      else
+	cursor_off_state = 1;
+    }
+
+  /* If new_cursor_type isn't decided yet, decide it now.  */
+  if (new_cursor_type == -2)
+    {
+      struct buffer *b = XBUFFER (w->buffer);
+
+      if (EQ (b->cursor_type, Qt))
 	{
-	  if (cursor_non_selected)
-	    new_cursor_type = HOLLOW_BOX_CURSOR;
-	  else
-	    new_cursor_type = NO_CURSOR;
-	  active_cursor = 0;
+	  new_cursor_type = FRAME_DESIRED_CURSOR (f);
+	  new_cursor_width = FRAME_CURSOR_WIDTH (f);
 	}
-    }
-  else
-    {
-      if (f != FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame
-          || w != XWINDOW (f->selected_window))
-        {
-	  active_cursor = 0;
-
-          if (MINI_WINDOW_P (w) 
-              || !cursor_non_selected
-              || NILP (XBUFFER (w->buffer)->cursor_type))
-            new_cursor_type = NO_CURSOR;
-          else
-            new_cursor_type = HOLLOW_BOX_CURSOR;
-        }
       else
-        {
-	  struct buffer *b = XBUFFER (w->buffer);
-
-	  if (EQ (b->cursor_type, Qt))
-            new_cursor_type = FRAME_DESIRED_CURSOR (f);
-	  else
-	    new_cursor_type = x_specified_cursor_type (b->cursor_type, 
-						       &new_cursor_width);
-	  if (w->cursor_off_p)
-	    {
-	      if (new_cursor_type == FILLED_BOX_CURSOR)
-		new_cursor_type = HOLLOW_BOX_CURSOR;
-	      else if (new_cursor_type == BAR_CURSOR && new_cursor_width > 1)
-		new_cursor_width = 1;
-	      else
-		new_cursor_type = NO_CURSOR;
-	    }
-	}
-    }
+	new_cursor_type = x_specified_cursor_type (b->cursor_type, 
+						   &new_cursor_width);
+    }
+
+  /* If cursor has blinked off, use the other specified state.  */
+  if (w->cursor_off_p)
+    {
+      new_cursor_type = FRAME_BLINK_OFF_CURSOR (f);
+      new_cursor_width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
+    }
+  /* Dim out or hollow out the cursor for nonselected windows.  */
+  if (cursor_off_state)
+    {
+      if (new_cursor_type == FILLED_BOX_CURSOR)
+	new_cursor_type = HOLLOW_BOX_CURSOR;
+      else if (new_cursor_type == BAR_CURSOR && new_cursor_width > 1)
+	new_cursor_width = 1;
+      else
+	new_cursor_type = NO_CURSOR;
+    }
+
+  /* Now new_cursor_type is correct.  */
 
   /* If cursor is currently being shown and we don't want it to be or
      it is in the wrong place, or the cursor type is not what we want,
@@ -9817,9 +9876,12 @@
 	      && new_cursor_width != w->phys_cursor_width)))
     x_erase_phys_cursor (w);
 
-  /* If the cursor is now invisible and we want it to be visible,
-     display it.  */
-  if (on && !w->phys_cursor_on_p)
+  /* Don't check phys_cursor_on_p here because that flag is only set
+     to zero in some cases where we know that the cursor has been
+     completely erased, to avoid the extra work of erasing the cursor
+     twice.  In other words, phys_cursor_on_p can be 1 and the cursor
+     still not be visible, or it has only been partly erased.  */
+  if (on)
     {
       w->phys_cursor_ascent = glyph_row->ascent;
       w->phys_cursor_height = glyph_row->height;