changeset 53127:bc14fd4782c3

(buffer_posn_from_coords): Return actual row/column for glyph clicked on, rather than (unused) pixel positions. (mode_line_string, marginal_area_string): Change X and Y args to pointers for returning actual row/column for glyph clicked on. Simplify and optimize loops.
author Kim F. Storm <storm@cua.dk>
date Sun, 23 Nov 2003 00:09:19 +0000
parents c93af1a0546a
children c9aeaeb38318
files src/dispnew.c
diffstat 1 files changed, 46 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/src/dispnew.c	Sun Nov 23 00:09:00 2003 +0000
+++ b/src/dispnew.c	Sun Nov 23 00:09:19 2003 +0000
@@ -5689,7 +5689,7 @@
 /* Determine what's under window-relative pixel position (*X, *Y).
    Return in *OBJECT the object (string or buffer) that's there.
    Return in *POS the position in that object. Adjust *X and *Y
-   to character boundaries.  */
+   to character positions.  */
 
 void
 buffer_posn_from_coords (w, x, y, object, pos)
@@ -5701,7 +5701,8 @@
   struct it it;
   struct buffer *old_current_buffer = current_buffer;
   struct text_pos startp;
-  int left_area_width;
+  struct glyph_row *row;
+  int x0, x1;
 
   current_buffer = XBUFFER (w->buffer);
   SET_TEXT_POS_FROM_MARKER (startp, w->start);
@@ -5709,16 +5710,21 @@
   BYTEPOS (startp) = min (ZV_BYTE, max (BEGV_BYTE, BYTEPOS (startp)));
   start_display (&it, w, startp);
 
-  left_area_width = WINDOW_LEFT_MARGIN_WIDTH (w);
-  move_it_to (&it, -1, *x + it.first_visible_x - left_area_width, *y, -1,
+  x0 = *x - WINDOW_LEFT_MARGIN_WIDTH (w);
+  move_it_to (&it, -1, x0 + it.first_visible_x, *y, -1,
 	      MOVE_TO_X | MOVE_TO_Y);
 
-  *x = it.current_x - it.first_visible_x + left_area_width;
-  *y = it.current_y;
+  /* Add extra (default width) columns if clicked after EOL. */
+  x1 = max(0, it.current_x + it.pixel_width - it.first_visible_x);
+  if (x0 > x1)
+    it.hpos += (x0 - x1) / WINDOW_FRAME_COLUMN_WIDTH (w);
+
   current_buffer = old_current_buffer;
 
   *object = STRINGP (it.string) ? it.string : w->buffer;
   *pos = it.current;
+  *x = it.hpos;
+  *y = it.vpos;
 }
 
 
@@ -5730,7 +5736,7 @@
 Lisp_Object
 mode_line_string (w, x, y, part, charpos)
      struct window *w;
-     int x, y;
+     int *x, *y;
      enum window_part part;
      int *charpos;
 {
@@ -5744,20 +5750,28 @@
   else
     row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
 
+  *y = row - MATRIX_FIRST_TEXT_ROW (w->current_matrix);
+
   if (row->mode_line_p && row->enabled_p)
     {
       /* Find the glyph under X.  If we find one with a string object,
          it's the one we were looking for.  */
       glyph = row->glyphs[TEXT_AREA];
       end = glyph + row->used[TEXT_AREA];
-      for (x0 = 0; glyph < end; x0 += glyph->pixel_width, ++glyph)
-	if (x >= x0 && x < x0 + glyph->pixel_width)
-	  {
-	    string = glyph->object;
-	    *charpos = glyph->charpos;
-	    break;
-	  }
+      for (x0 = *x; glyph < end && x0 > glyph->pixel_width; ++glyph)
+	x0 -= glyph->pixel_width;
+      *x = glyph - row->glyphs[TEXT_AREA];
+      if (glyph < end)
+	{
+	  string = glyph->object;
+	  *charpos = glyph->charpos;
+	}
+      else
+	/* Add extra (default width) columns if clicked after EOL. */
+	*x += x0 / WINDOW_FRAME_COLUMN_WIDTH (w);
     }
+  else
+    *x = 0;
 
   return string;
 }
@@ -5770,13 +5784,13 @@
 Lisp_Object
 marginal_area_string (w, x, y, part, charpos)
      struct window *w;
-     int x, y;
+     int *x, *y;
      enum window_part part;
      int *charpos;
 {
   struct glyph_row *row = w->current_matrix->rows;
   struct glyph *glyph, *end;
-  int x0, i, wy = y;
+  int x0, i, wy = *y;
   int area;
   Lisp_Object string = Qnil;
 
@@ -5790,14 +5804,12 @@
   for (i = 0; row->enabled_p && i < w->current_matrix->nrows; ++i, ++row)
     if (wy >= row->y && wy < MATRIX_ROW_BOTTOM_Y (row))
       break;
+  *y = row - MATRIX_FIRST_TEXT_ROW (w->current_matrix);
 
   if (row->enabled_p)
     {
       /* Find the glyph under X.  If we find one with a string object,
 	 it's the one we were looking for.  */
-      glyph = row->glyphs[area];
-      end = glyph + row->used[area];
-
       if (area == RIGHT_MARGIN_AREA)
 	x0 = ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
 	       ? WINDOW_LEFT_FRINGE_WIDTH (w) 
@@ -5809,14 +5821,22 @@
 	      ? WINDOW_LEFT_FRINGE_WIDTH (w) 
 	      : 0);
 
-      for (; glyph < end; x0 += glyph->pixel_width, ++glyph)
-	if (x >= x0 && x < x0 + glyph->pixel_width)
-	  {
-	    string = glyph->object;
-	    *charpos = glyph->charpos;
-	    break;
-	  }
+      glyph = row->glyphs[area];
+      end = glyph + row->used[area];
+      for (x0 = *x - x0; glyph < end && x0 > glyph->pixel_width; ++glyph)
+	x0 -= glyph->pixel_width;
+      *x = glyph - row->glyphs[area];
+      if (glyph < end)
+	{
+	  string = glyph->object;
+	  *charpos = glyph->charpos;
+	}
+      else
+	/* Add extra (default width) columns if clicked after EOL. */
+	*x += x0 / WINDOW_FRAME_COLUMN_WIDTH (w);
     }
+  else
+    *x = 0;
 
   return string;
 }