diff options
Diffstat (limited to 'src/window.c')
| -rw-r--r-- | src/window.c | 213 |
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 | ||
| 1901 | DEFUN ("window-lines-pixel-dimensions", Fwindow_lines_pixel_dimensions, Swindow_lines_pixel_dimensions, 0, 6, 0, | ||
| 1902 | doc: /* Return pixel dimensions of WINDOW's lines. | ||
| 1903 | The return value is a list of the x- and y-coordinates of the lower | ||
| 1904 | right corner of the last character of each line. Return nil if the | ||
| 1905 | current glyph matrix of WINDOW is not up-to-date. | ||
| 1906 | |||
| 1907 | Optional argument WINDOW specifies the window whose lines' dimensions | ||
| 1908 | shall be returned. Nil or omitted means to return the dimensions for | ||
| 1909 | the selected window. | ||
| 1910 | |||
| 1911 | FIRST, if non-nil, specifies the index of the first line whose | ||
| 1912 | dimensions shall be returned. If FIRST is nil and BODY is non-nil, | ||
| 1913 | start with the first text line of WINDOW. Otherwise, start with the | ||
| 1914 | first line of WINDOW. | ||
| 1915 | |||
| 1916 | LAST, if non-nil, specifies the last line whose dimensions shall be | ||
| 1917 | returned. If LAST is nil and BODY is non-nil, the last line is the last | ||
| 1918 | line of the body (text area) of WINDOW. Otherwise, last is the last | ||
| 1919 | line of WINDOW. | ||
| 1920 | |||
| 1921 | INVERSE, if nil, means that the y-pixel value returned for a specific | ||
| 1922 | line specifies the distance in pixels from the left edge (body edge if | ||
| 1923 | BODY is non-nil) of WINDOW to the right edge of the last glyph of that | ||
| 1924 | line. INVERSE non-nil means that the y-pixel value returned for a | ||
| 1925 | specific line specifies the distance in pixels from the right edge of | ||
| 1926 | the last glyph of that line to the right edge (body edge if BODY is | ||
| 1927 | non-nil) of WINDOW. | ||
| 1928 | |||
| 1929 | LEFT non-nil means to return the x- and y-coordinates of the lower left | ||
| 1930 | corner of the leftmost character on each line. This is the value that | ||
| 1931 | should be used for buffers that mostly display text from right to left. | ||
| 1932 | |||
| 1933 | If LEFT is non-nil and INVERSE is nil, this means that the y-pixel value | ||
| 1934 | returned for a specific line specifies the distance in pixels from the | ||
| 1935 | left 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 | ||
| 1937 | non-nil, the y-pixel value returned for a specific line specifies the | ||
| 1938 | distance in pixels from the left edge (body edge if BODY is non-nil) of | ||
| 1939 | WINDOW to the left edge of the last (leftmost) glyph of that line. | ||
| 1940 | |||
| 1941 | Normally, the value of this function is not available while Emacs is | ||
| 1942 | busy, for example, when processing a command. It should be retrievable | ||
| 1943 | though 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 | |||
| 1901 | DEFUN ("window-dedicated-p", Fwindow_dedicated_p, Swindow_dedicated_p, | 2024 | DEFUN ("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 | ||
| 2129 | Lisp_Object | ||
| 2130 | window_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 | |||
| 2006 | DEFUN ("window-parameter", Fwindow_parameter, Swindow_parameter, | 2138 | DEFUN ("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. |
| 2009 | WINDOW can be any window and defaults to the selected one. */) | 2141 | WINDOW 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 | ||
| 2018 | DEFUN ("set-window-parameter", Fset_window_parameter, | 2149 | DEFUN ("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 | */ | ||
| 4886 | bool | ||
| 4887 | window_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 | */ | ||
| 4917 | bool | ||
| 4918 | window_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 | ||
| 4745 | int | 4939 | int |
| @@ -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); |