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