From ba922d0c08796dc9730229a3bb090851cac81409 Mon Sep 17 00:00:00 2001 From: "Kim F. Storm" Date: Sun, 23 Nov 2003 00:09:19 +0000 Subject: [PATCH] (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. --- src/dispnew.c | 72 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 26 deletions(-) diff --git a/src/dispnew.c b/src/dispnew.c index 3bce256f2db..35e03eff9c6 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -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; } -- 2.39.2