]> git.eshelyaron.com Git - emacs.git/commitdiff
(buffer_posn_from_coords): Return actual row/column
authorKim F. Storm <storm@cua.dk>
Sun, 23 Nov 2003 00:09:19 +0000 (00:09 +0000)
committerKim F. Storm <storm@cua.dk>
Sun, 23 Nov 2003 00:09:19 +0000 (00:09 +0000)
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.

src/dispnew.c

index 3bce256f2dbbe0bbdf0c36518cce526618a51633..35e03eff9c65de30ef4eb7394ac30f14aa70dfcd 100644 (file)
@@ -5689,7 +5689,7 @@ update_frame_line (f, vpos)
 /* 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 @@ buffer_posn_from_coords (w, x, y, object, pos)
   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 @@ buffer_posn_from_coords (w, x, y, object, pos)
   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 @@ buffer_posn_from_coords (w, x, y, object, pos)
 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 @@ mode_line_string (w, x, y, part, charpos)
   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 @@ mode_line_string (w, x, y, part, charpos)
 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 @@ marginal_area_string (w, x, y, part, charpos)
   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 @@ marginal_area_string (w, x, y, part, charpos)
              ? 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;
 }