aboutsummaryrefslogtreecommitdiffstats
path: root/src/window.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/window.c')
-rw-r--r--src/window.c213
1 files changed, 205 insertions, 8 deletions
diff --git a/src/window.c b/src/window.c
index bf89f0e488b..4816bd69909 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1208,13 +1208,13 @@ coordinates_in_window (register struct window *w, int x, int y)
1208 - WINDOW_BOTTOM_DIVIDER_WIDTH (w)))) 1208 - WINDOW_BOTTOM_DIVIDER_WIDTH (w))))
1209 return ON_HORIZONTAL_SCROLL_BAR; 1209 return ON_HORIZONTAL_SCROLL_BAR;
1210 /* On the mode or header line? */ 1210 /* On the mode or header line? */
1211 else if ((WINDOW_WANTS_MODELINE_P (w) 1211 else if ((window_wants_mode_line (w)
1212 && y >= (bottom_y 1212 && y >= (bottom_y
1213 - CURRENT_MODE_LINE_HEIGHT (w) 1213 - CURRENT_MODE_LINE_HEIGHT (w)
1214 - WINDOW_BOTTOM_DIVIDER_WIDTH (w)) 1214 - WINDOW_BOTTOM_DIVIDER_WIDTH (w))
1215 && y <= bottom_y - WINDOW_BOTTOM_DIVIDER_WIDTH (w) 1215 && y <= bottom_y - WINDOW_BOTTOM_DIVIDER_WIDTH (w)
1216 && (part = ON_MODE_LINE)) 1216 && (part = ON_MODE_LINE))
1217 || (WINDOW_WANTS_HEADER_LINE_P (w) 1217 || (window_wants_header_line (w)
1218 && y < top_y + CURRENT_HEADER_LINE_HEIGHT (w) 1218 && y < top_y + CURRENT_HEADER_LINE_HEIGHT (w)
1219 && (part = ON_HEADER_LINE))) 1219 && (part = ON_HEADER_LINE)))
1220 { 1220 {
@@ -1851,7 +1851,7 @@ Return nil if window display is not up-to-date. In that case, use
1851 1851
1852 if (EQ (line, Qheader_line)) 1852 if (EQ (line, Qheader_line))
1853 { 1853 {
1854 if (!WINDOW_WANTS_HEADER_LINE_P (w)) 1854 if (!window_wants_header_line (w))
1855 return Qnil; 1855 return Qnil;
1856 row = MATRIX_HEADER_LINE_ROW (w->current_matrix); 1856 row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
1857 return row->enabled_p ? list4i (row->height, 0, 0, 0) : Qnil; 1857 return row->enabled_p ? list4i (row->height, 0, 0, 0) : Qnil;
@@ -1898,6 +1898,129 @@ Return nil if window display is not up-to-date. In that case, use
1898 return list4i (row->height + min (0, row->y) - crop, i, row->y, crop); 1898 return list4i (row->height + min (0, row->y) - crop, i, row->y, crop);
1899} 1899}
1900 1900
1901DEFUN ("window-lines-pixel-dimensions", Fwindow_lines_pixel_dimensions, Swindow_lines_pixel_dimensions, 0, 6, 0,
1902 doc: /* Return pixel dimensions of WINDOW's lines.
1903The return value is a list of the x- and y-coordinates of the lower
1904right corner of the last character of each line. Return nil if the
1905current glyph matrix of WINDOW is not up-to-date.
1906
1907Optional argument WINDOW specifies the window whose lines' dimensions
1908shall be returned. Nil or omitted means to return the dimensions for
1909the selected window.
1910
1911FIRST, if non-nil, specifies the index of the first line whose
1912dimensions shall be returned. If FIRST is nil and BODY is non-nil,
1913start with the first text line of WINDOW. Otherwise, start with the
1914first line of WINDOW.
1915
1916LAST, if non-nil, specifies the last line whose dimensions shall be
1917returned. If LAST is nil and BODY is non-nil, the last line is the last
1918line of the body (text area) of WINDOW. Otherwise, last is the last
1919line of WINDOW.
1920
1921INVERSE, if nil, means that the y-pixel value returned for a specific
1922line specifies the distance in pixels from the left edge (body edge if
1923BODY is non-nil) of WINDOW to the right edge of the last glyph of that
1924line. INVERSE non-nil means that the y-pixel value returned for a
1925specific line specifies the distance in pixels from the right edge of
1926the last glyph of that line to the right edge (body edge if BODY is
1927non-nil) of WINDOW.
1928
1929LEFT non-nil means to return the x- and y-coordinates of the lower left
1930corner of the leftmost character on each line. This is the value that
1931should be used for buffers that mostly display text from right to left.
1932
1933If LEFT is non-nil and INVERSE is nil, this means that the y-pixel value
1934returned for a specific line specifies the distance in pixels from the
1935left edge of the last (leftmost) glyph of that line to the right edge
1936(body edge if BODY is non-nil) of WINDOW. If LEFT and INVERSE are both
1937non-nil, the y-pixel value returned for a specific line specifies the
1938distance in pixels from the left edge (body edge if BODY is non-nil) of
1939WINDOW to the left edge of the last (leftmost) glyph of that line.
1940
1941Normally, the value of this function is not available while Emacs is
1942busy, for example, when processing a command. It should be retrievable
1943though when run from an idle timer with a delay of zero seconds. */)
1944 (Lisp_Object window, Lisp_Object first, Lisp_Object last, Lisp_Object body, Lisp_Object inverse, Lisp_Object left)
1945{
1946 struct window *w = decode_live_window (window);
1947 struct buffer *b;
1948 struct glyph_row *row, *end_row;
1949 int max_y = NILP (body) ? WINDOW_PIXEL_HEIGHT (w) : window_text_bottom_y (w);
1950 Lisp_Object rows = Qnil;
1951 int window_width = NILP (body) ? w->pixel_width : window_body_width (w, true);
1952 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
1953 int subtract = NILP (body) ? 0 : header_line_height;
1954 bool invert = !NILP (inverse);
1955 bool left_flag = !NILP (left);
1956
1957 if (noninteractive || w->pseudo_window_p)
1958 return Qnil;
1959
1960 CHECK_BUFFER (w->contents);
1961 b = XBUFFER (w->contents);
1962
1963 /* Fail if current matrix is not up-to-date. */
1964 if (!w->window_end_valid
1965 || windows_or_buffers_changed
1966 || b->clip_changed
1967 || b->prevent_redisplay_optimizations_p
1968 || window_outdated (w))
1969 return Qnil;
1970
1971 if (NILP (first))
1972 row = (NILP (body)
1973 ? MATRIX_ROW (w->current_matrix, 0)
1974 : MATRIX_FIRST_TEXT_ROW (w->current_matrix));
1975 else if (NUMBERP (first))
1976 {
1977 CHECK_RANGED_INTEGER (first, 0, w->current_matrix->nrows);
1978 row = MATRIX_ROW (w->current_matrix, XINT (first));
1979 }
1980 else
1981 error ("Invalid specification of first line");
1982
1983 if (NILP (last))
1984
1985 end_row = (NILP (body)
1986 ? MATRIX_ROW (w->current_matrix, w->current_matrix->nrows)
1987 : MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w));
1988 else if (NUMBERP (last))
1989 {
1990 CHECK_RANGED_INTEGER (last, 0, w->current_matrix->nrows);
1991 end_row = MATRIX_ROW (w->current_matrix, XINT (last));
1992 }
1993 else
1994 error ("Invalid specification of last line");
1995
1996 while (row <= end_row && row->enabled_p
1997 && row->y + row->height < max_y)
1998 {
1999
2000 if (left_flag)
2001 {
2002 struct glyph *glyph = row->glyphs[TEXT_AREA];
2003
2004 rows = Fcons (Fcons (make_number
2005 (invert
2006 ? glyph->pixel_width
2007 : window_width - glyph->pixel_width),
2008 make_number (row->y + row->height - subtract)),
2009 rows);
2010 }
2011 else
2012 rows = Fcons (Fcons (make_number
2013 (invert
2014 ? window_width - row->pixel_width
2015 : row->pixel_width),
2016 make_number (row->y + row->height - subtract)),
2017 rows);
2018 row++;
2019 }
2020
2021 return Fnreverse (rows);
2022}
2023
1901DEFUN ("window-dedicated-p", Fwindow_dedicated_p, Swindow_dedicated_p, 2024DEFUN ("window-dedicated-p", Fwindow_dedicated_p, Swindow_dedicated_p,
1902 0, 1, 0, 2025 0, 1, 0,
1903 doc: /* Return non-nil when WINDOW is dedicated to its buffer. 2026 doc: /* Return non-nil when WINDOW is dedicated to its buffer.
@@ -2003,16 +2126,24 @@ return value is a list of elements of the form (PARAMETER . VALUE). */)
2003 return Fcopy_alist (decode_valid_window (window)->window_parameters); 2126 return Fcopy_alist (decode_valid_window (window)->window_parameters);
2004} 2127}
2005 2128
2129Lisp_Object
2130window_parameter (struct window *w, Lisp_Object parameter)
2131{
2132 Lisp_Object result = Fassq (parameter, w->window_parameters);
2133
2134 return CDR_SAFE (result);
2135}
2136
2137
2006DEFUN ("window-parameter", Fwindow_parameter, Swindow_parameter, 2138DEFUN ("window-parameter", Fwindow_parameter, Swindow_parameter,
2007 2, 2, 0, 2139 2, 2, 0,
2008 doc: /* Return WINDOW's value for PARAMETER. 2140 doc: /* Return WINDOW's value for PARAMETER.
2009WINDOW can be any window and defaults to the selected one. */) 2141WINDOW can be any window and defaults to the selected one. */)
2010 (Lisp_Object window, Lisp_Object parameter) 2142 (Lisp_Object window, Lisp_Object parameter)
2011{ 2143{
2012 Lisp_Object result; 2144 struct window *w = decode_any_window (window);
2013 2145
2014 result = Fassq (parameter, decode_any_window (window)->window_parameters); 2146 return window_parameter (w, parameter);
2015 return CDR_SAFE (result);
2016} 2147}
2017 2148
2018DEFUN ("set-window-parameter", Fset_window_parameter, 2149DEFUN ("set-window-parameter", Fset_window_parameter,
@@ -4740,6 +4871,69 @@ mark_window_cursors_off (struct window *w)
4740} 4871}
4741 4872
4742 4873
4874/**
4875 * window_wants_mode_line:
4876 *
4877 * Return 1 if window W wants a mode line and is high enough to
4878 * accomodate it, 0 otherwise.
4879 *
4880 * W wants a mode line if it's a leaf window and neither a minibuffer
4881 * nor a pseudo window. Moreover, its 'window-mode-line-format'
4882 * parameter must not be 'none' and either that parameter or W's
4883 * buffer's 'mode-line-format' value must be non-nil. Finally, W must
4884 * be higher than its frame's canonical character height.
4885 */
4886bool
4887window_wants_mode_line (struct window *w)
4888{
4889 Lisp_Object window_mode_line_format =
4890 window_parameter (w, Qmode_line_format);
4891
4892 return ((WINDOW_LEAF_P (w)
4893 && !MINI_WINDOW_P (w)
4894 && !WINDOW_PSEUDO_P (w)
4895 && !EQ (window_mode_line_format, Qnone)
4896 && (!NILP (window_mode_line_format)
4897 || !NILP (BVAR (XBUFFER (WINDOW_BUFFER (w)), mode_line_format)))
4898 && WINDOW_PIXEL_HEIGHT (w) > WINDOW_FRAME_LINE_HEIGHT (w))
4899 ? 1
4900 : 0);
4901}
4902
4903
4904/**
4905 * window_wants_header_line:
4906 *
4907 * Return 1 if window W wants a header line and is high enough to
4908 * accomodate it, 0 otherwise.
4909 *
4910 * W wants a header line if it's a leaf window and neither a minibuffer
4911 * nor a pseudo window. Moreover, its 'window-mode-line-format'
4912 * parameter must not be 'none' and either that parameter or W's
4913 * buffer's 'mode-line-format' value must be non-nil. Finally, W must
4914 * be higher than its frame's canonical character height and be able to
4915 * accomodate a mode line too if necessary (the mode line prevails).
4916 */
4917bool
4918window_wants_header_line (struct window *w)
4919{
4920 Lisp_Object window_header_line_format =
4921 window_parameter (w, Qheader_line_format);
4922
4923 return ((WINDOW_LEAF_P (w)
4924 && !MINI_WINDOW_P (w)
4925 && !WINDOW_PSEUDO_P (w)
4926 && !EQ (window_header_line_format, Qnone)
4927 && (!NILP (window_header_line_format)
4928 || !NILP (BVAR (XBUFFER (WINDOW_BUFFER (w)), header_line_format)))
4929 && (WINDOW_PIXEL_HEIGHT (w)
4930 > (window_wants_mode_line (w)
4931 ? 2 * WINDOW_FRAME_LINE_HEIGHT (w)
4932 : WINDOW_FRAME_LINE_HEIGHT (w))))
4933 ? 1
4934 : 0);
4935}
4936
4743/* Return number of lines of text (not counting mode lines) in W. */ 4937/* Return number of lines of text (not counting mode lines) in W. */
4744 4938
4745int 4939int
@@ -4753,10 +4947,10 @@ window_internal_height (struct window *w)
4753 || WINDOWP (w->contents) 4947 || WINDOWP (w->contents)
4754 || !NILP (w->next) 4948 || !NILP (w->next)
4755 || !NILP (w->prev) 4949 || !NILP (w->prev)
4756 || WINDOW_WANTS_MODELINE_P (w)) 4950 || window_wants_mode_line (w))
4757 --ht; 4951 --ht;
4758 4952
4759 if (WINDOW_WANTS_HEADER_LINE_P (w)) 4953 if (window_wants_header_line (w))
4760 --ht; 4954 --ht;
4761 } 4955 }
4762 4956
@@ -7354,6 +7548,8 @@ syms_of_window (void)
7354 DEFSYM (Qfloor, "floor"); 7548 DEFSYM (Qfloor, "floor");
7355 DEFSYM (Qceiling, "ceiling"); 7549 DEFSYM (Qceiling, "ceiling");
7356 DEFSYM (Qmark_for_redisplay, "mark-for-redisplay"); 7550 DEFSYM (Qmark_for_redisplay, "mark-for-redisplay");
7551 DEFSYM (Qmode_line_format, "mode-line-format");
7552 DEFSYM (Qheader_line_format, "header-line-format");
7357 7553
7358 staticpro (&Vwindow_list); 7554 staticpro (&Vwindow_list);
7359 7555
@@ -7603,6 +7799,7 @@ displayed after a scrolling operation to be somewhat inaccurate. */);
7603 defsubr (&Sset_window_point); 7799 defsubr (&Sset_window_point);
7604 defsubr (&Sset_window_start); 7800 defsubr (&Sset_window_start);
7605 defsubr (&Swindow_dedicated_p); 7801 defsubr (&Swindow_dedicated_p);
7802 defsubr (&Swindow_lines_pixel_dimensions);
7606 defsubr (&Sset_window_dedicated_p); 7803 defsubr (&Sset_window_dedicated_p);
7607 defsubr (&Swindow_display_table); 7804 defsubr (&Swindow_display_table);
7608 defsubr (&Sset_window_display_table); 7805 defsubr (&Sset_window_display_table);