Mercurial > emacs
comparison src/dispnew.c @ 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 | 4cb0d5b004e9 |
children | b246aabe1c49 |
comparison
equal
deleted
inserted
replaced
53126:c93af1a0546a | 53127:bc14fd4782c3 |
---|---|
5687 ***********************************************************************/ | 5687 ***********************************************************************/ |
5688 | 5688 |
5689 /* Determine what's under window-relative pixel position (*X, *Y). | 5689 /* Determine what's under window-relative pixel position (*X, *Y). |
5690 Return in *OBJECT the object (string or buffer) that's there. | 5690 Return in *OBJECT the object (string or buffer) that's there. |
5691 Return in *POS the position in that object. Adjust *X and *Y | 5691 Return in *POS the position in that object. Adjust *X and *Y |
5692 to character boundaries. */ | 5692 to character positions. */ |
5693 | 5693 |
5694 void | 5694 void |
5695 buffer_posn_from_coords (w, x, y, object, pos) | 5695 buffer_posn_from_coords (w, x, y, object, pos) |
5696 struct window *w; | 5696 struct window *w; |
5697 int *x, *y; | 5697 int *x, *y; |
5699 struct display_pos *pos; | 5699 struct display_pos *pos; |
5700 { | 5700 { |
5701 struct it it; | 5701 struct it it; |
5702 struct buffer *old_current_buffer = current_buffer; | 5702 struct buffer *old_current_buffer = current_buffer; |
5703 struct text_pos startp; | 5703 struct text_pos startp; |
5704 int left_area_width; | 5704 struct glyph_row *row; |
5705 int x0, x1; | |
5705 | 5706 |
5706 current_buffer = XBUFFER (w->buffer); | 5707 current_buffer = XBUFFER (w->buffer); |
5707 SET_TEXT_POS_FROM_MARKER (startp, w->start); | 5708 SET_TEXT_POS_FROM_MARKER (startp, w->start); |
5708 CHARPOS (startp) = min (ZV, max (BEGV, CHARPOS (startp))); | 5709 CHARPOS (startp) = min (ZV, max (BEGV, CHARPOS (startp))); |
5709 BYTEPOS (startp) = min (ZV_BYTE, max (BEGV_BYTE, BYTEPOS (startp))); | 5710 BYTEPOS (startp) = min (ZV_BYTE, max (BEGV_BYTE, BYTEPOS (startp))); |
5710 start_display (&it, w, startp); | 5711 start_display (&it, w, startp); |
5711 | 5712 |
5712 left_area_width = WINDOW_LEFT_MARGIN_WIDTH (w); | 5713 x0 = *x - WINDOW_LEFT_MARGIN_WIDTH (w); |
5713 move_it_to (&it, -1, *x + it.first_visible_x - left_area_width, *y, -1, | 5714 move_it_to (&it, -1, x0 + it.first_visible_x, *y, -1, |
5714 MOVE_TO_X | MOVE_TO_Y); | 5715 MOVE_TO_X | MOVE_TO_Y); |
5715 | 5716 |
5716 *x = it.current_x - it.first_visible_x + left_area_width; | 5717 /* Add extra (default width) columns if clicked after EOL. */ |
5717 *y = it.current_y; | 5718 x1 = max(0, it.current_x + it.pixel_width - it.first_visible_x); |
5719 if (x0 > x1) | |
5720 it.hpos += (x0 - x1) / WINDOW_FRAME_COLUMN_WIDTH (w); | |
5721 | |
5718 current_buffer = old_current_buffer; | 5722 current_buffer = old_current_buffer; |
5719 | 5723 |
5720 *object = STRINGP (it.string) ? it.string : w->buffer; | 5724 *object = STRINGP (it.string) ? it.string : w->buffer; |
5721 *pos = it.current; | 5725 *pos = it.current; |
5726 *x = it.hpos; | |
5727 *y = it.vpos; | |
5722 } | 5728 } |
5723 | 5729 |
5724 | 5730 |
5725 /* Value is the string under window-relative coordinates X/Y in the | 5731 /* Value is the string under window-relative coordinates X/Y in the |
5726 mode or header line of window W, or nil if none. MODE_LINE_P non-zero | 5732 mode or header line of window W, or nil if none. MODE_LINE_P non-zero |
5728 the string returned. */ | 5734 the string returned. */ |
5729 | 5735 |
5730 Lisp_Object | 5736 Lisp_Object |
5731 mode_line_string (w, x, y, part, charpos) | 5737 mode_line_string (w, x, y, part, charpos) |
5732 struct window *w; | 5738 struct window *w; |
5733 int x, y; | 5739 int *x, *y; |
5734 enum window_part part; | 5740 enum window_part part; |
5735 int *charpos; | 5741 int *charpos; |
5736 { | 5742 { |
5737 struct glyph_row *row; | 5743 struct glyph_row *row; |
5738 struct glyph *glyph, *end; | 5744 struct glyph *glyph, *end; |
5742 if (part == ON_MODE_LINE) | 5748 if (part == ON_MODE_LINE) |
5743 row = MATRIX_MODE_LINE_ROW (w->current_matrix); | 5749 row = MATRIX_MODE_LINE_ROW (w->current_matrix); |
5744 else | 5750 else |
5745 row = MATRIX_HEADER_LINE_ROW (w->current_matrix); | 5751 row = MATRIX_HEADER_LINE_ROW (w->current_matrix); |
5746 | 5752 |
5753 *y = row - MATRIX_FIRST_TEXT_ROW (w->current_matrix); | |
5754 | |
5747 if (row->mode_line_p && row->enabled_p) | 5755 if (row->mode_line_p && row->enabled_p) |
5748 { | 5756 { |
5749 /* Find the glyph under X. If we find one with a string object, | 5757 /* Find the glyph under X. If we find one with a string object, |
5750 it's the one we were looking for. */ | 5758 it's the one we were looking for. */ |
5751 glyph = row->glyphs[TEXT_AREA]; | 5759 glyph = row->glyphs[TEXT_AREA]; |
5752 end = glyph + row->used[TEXT_AREA]; | 5760 end = glyph + row->used[TEXT_AREA]; |
5753 for (x0 = 0; glyph < end; x0 += glyph->pixel_width, ++glyph) | 5761 for (x0 = *x; glyph < end && x0 > glyph->pixel_width; ++glyph) |
5754 if (x >= x0 && x < x0 + glyph->pixel_width) | 5762 x0 -= glyph->pixel_width; |
5755 { | 5763 *x = glyph - row->glyphs[TEXT_AREA]; |
5756 string = glyph->object; | 5764 if (glyph < end) |
5757 *charpos = glyph->charpos; | 5765 { |
5758 break; | 5766 string = glyph->object; |
5759 } | 5767 *charpos = glyph->charpos; |
5760 } | 5768 } |
5769 else | |
5770 /* Add extra (default width) columns if clicked after EOL. */ | |
5771 *x += x0 / WINDOW_FRAME_COLUMN_WIDTH (w); | |
5772 } | |
5773 else | |
5774 *x = 0; | |
5761 | 5775 |
5762 return string; | 5776 return string; |
5763 } | 5777 } |
5764 | 5778 |
5765 | 5779 |
5768 the string returned. */ | 5782 the string returned. */ |
5769 | 5783 |
5770 Lisp_Object | 5784 Lisp_Object |
5771 marginal_area_string (w, x, y, part, charpos) | 5785 marginal_area_string (w, x, y, part, charpos) |
5772 struct window *w; | 5786 struct window *w; |
5773 int x, y; | 5787 int *x, *y; |
5774 enum window_part part; | 5788 enum window_part part; |
5775 int *charpos; | 5789 int *charpos; |
5776 { | 5790 { |
5777 struct glyph_row *row = w->current_matrix->rows; | 5791 struct glyph_row *row = w->current_matrix->rows; |
5778 struct glyph *glyph, *end; | 5792 struct glyph *glyph, *end; |
5779 int x0, i, wy = y; | 5793 int x0, i, wy = *y; |
5780 int area; | 5794 int area; |
5781 Lisp_Object string = Qnil; | 5795 Lisp_Object string = Qnil; |
5782 | 5796 |
5783 if (part == ON_LEFT_MARGIN) | 5797 if (part == ON_LEFT_MARGIN) |
5784 area = LEFT_MARGIN_AREA; | 5798 area = LEFT_MARGIN_AREA; |
5788 abort (); | 5802 abort (); |
5789 | 5803 |
5790 for (i = 0; row->enabled_p && i < w->current_matrix->nrows; ++i, ++row) | 5804 for (i = 0; row->enabled_p && i < w->current_matrix->nrows; ++i, ++row) |
5791 if (wy >= row->y && wy < MATRIX_ROW_BOTTOM_Y (row)) | 5805 if (wy >= row->y && wy < MATRIX_ROW_BOTTOM_Y (row)) |
5792 break; | 5806 break; |
5807 *y = row - MATRIX_FIRST_TEXT_ROW (w->current_matrix); | |
5793 | 5808 |
5794 if (row->enabled_p) | 5809 if (row->enabled_p) |
5795 { | 5810 { |
5796 /* Find the glyph under X. If we find one with a string object, | 5811 /* Find the glyph under X. If we find one with a string object, |
5797 it's the one we were looking for. */ | 5812 it's the one we were looking for. */ |
5798 glyph = row->glyphs[area]; | |
5799 end = glyph + row->used[area]; | |
5800 | |
5801 if (area == RIGHT_MARGIN_AREA) | 5813 if (area == RIGHT_MARGIN_AREA) |
5802 x0 = ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) | 5814 x0 = ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) |
5803 ? WINDOW_LEFT_FRINGE_WIDTH (w) | 5815 ? WINDOW_LEFT_FRINGE_WIDTH (w) |
5804 : WINDOW_TOTAL_FRINGE_WIDTH (w)) | 5816 : WINDOW_TOTAL_FRINGE_WIDTH (w)) |
5805 + window_box_width (w, LEFT_MARGIN_AREA) | 5817 + window_box_width (w, LEFT_MARGIN_AREA) |
5807 else | 5819 else |
5808 x0 = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) | 5820 x0 = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) |
5809 ? WINDOW_LEFT_FRINGE_WIDTH (w) | 5821 ? WINDOW_LEFT_FRINGE_WIDTH (w) |
5810 : 0); | 5822 : 0); |
5811 | 5823 |
5812 for (; glyph < end; x0 += glyph->pixel_width, ++glyph) | 5824 glyph = row->glyphs[area]; |
5813 if (x >= x0 && x < x0 + glyph->pixel_width) | 5825 end = glyph + row->used[area]; |
5814 { | 5826 for (x0 = *x - x0; glyph < end && x0 > glyph->pixel_width; ++glyph) |
5815 string = glyph->object; | 5827 x0 -= glyph->pixel_width; |
5816 *charpos = glyph->charpos; | 5828 *x = glyph - row->glyphs[area]; |
5817 break; | 5829 if (glyph < end) |
5818 } | 5830 { |
5819 } | 5831 string = glyph->object; |
5832 *charpos = glyph->charpos; | |
5833 } | |
5834 else | |
5835 /* Add extra (default width) columns if clicked after EOL. */ | |
5836 *x += x0 / WINDOW_FRAME_COLUMN_WIDTH (w); | |
5837 } | |
5838 else | |
5839 *x = 0; | |
5820 | 5840 |
5821 return string; | 5841 return string; |
5822 } | 5842 } |
5823 | 5843 |
5824 | 5844 |