Mercurial > emacs
changeset 432:4d44159f7481
*** empty log message ***
author | Jim Blandy <jimb@redhat.com> |
---|---|
date | Fri, 15 Nov 1991 22:14:20 +0000 |
parents | 504d7cdfd311 |
children | 1c6c6382f1d7 |
files | src/window.c |
diffstat | 1 files changed, 232 insertions(+), 171 deletions(-) [+] |
line wrap: on
line diff
--- a/src/window.c Thu Nov 14 21:40:03 1991 +0000 +++ b/src/window.c Fri Nov 15 22:14:20 1991 +0000 @@ -153,20 +153,7 @@ () { #ifdef MULTI_SCREEN - if (minibuf_level == 0 - && !EQ (minibuf_window, selected_screen->minibuffer_window) - && !EQ (Qnil, selected_screen->minibuffer_window)) - { - Fset_window_buffer (selected_screen->minibuffer_window, - XWINDOW (minibuf_window)->buffer); - minibuf_window = selected_screen->minibuffer_window; - } - - if (SCREENP (Vglobal_minibuffer_screen)) - minibuf_window = XSCREEN (Vglobal_minibuffer_screen)->minibuffer_window; - else - minibuf_window = selected_screen->minibuffer_window; - + choose_minibuf_screen (); #endif /* MULTI_SCREEN */ return minibuf_window; } @@ -328,55 +315,135 @@ Qnil)))); } +/* Test if the character at column *x, row *y is within window *w. + If it is not, return 0; + if it is in the window's text area, + set *x and *y to its location relative to the upper left corner + of the window, and + return 1; + if it is on the window's modeline, return 2; + if it is on the border between the window and its right sibling, + return 3. */ +static int +coordinates_in_window (w, x, y) + register struct window *w; + register int *x, *y; +{ + register int left = XINT (w->left); + register int width = XINT (w->width); + register int window_height = XINT (w->height); + register int top = XFASTINT (w->top); + + if ( *x < left || *x >= left + width + || *y < top || *y >= top + window_height) + return 0; + + /* Is the character is the mode line? */ + if (*y == top + window_height - 1 + && window_height > 1) /* 1 line => minibuffer */ + return 2; + + /* Is the character in the right border? */ + if (*x == left + width - 1 + && left + width != SCREEN_WIDTH (XSCREEN (w->screen))) + return 3; + + *x -= left; + *y -= top; + return 1; +} + +DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p, + Scoordinates_in_window_p, 2, 2, 0, + "Return non-nil if COORDINATES are in WINDOW.\n\ +COORDINATES is a cons of the form (X . Y), X and Y being screen-relative.\n\ +If COORDINATES are in the text portion of WINDOW,\n\ + the coordinates relative to the window are returned.\n\ +If they are in the mode line of WINDOW, 'mode-line is returned.\n\ +If they are on the border between WINDOW and its right sibling,\n\ + 'vertical-split is returned.") + (coordinates, window) + register Lisp_Object coordinates, window; +{ + int x, y; + + CHECK_WINDOW (window, 0); + CHECK_CONS (coordinates, 1); + x = XINT (Fcar (coordinates)); + y = XINT (Fcdr (coordinates)); + + switch (coordinates_in_window (XWINDOW (window), &x, &y)) + { + case 0: /* NOT in window at all. */ + return Qnil; + + case 1: /* In text part of window. */ + return Fcons (x, y); + + case 2: /* In mode line of window. */ + return Qmode_line; + + case 3: /* On right border of window. */ + return Qvertical_split; + + default: + abort (); + } +} + /* Find the window containing column x, row y, and return it as a - Lisp_Object. If x, y is on the window's modeline, set *modeline_p - to 1; otherwise set it to 0. If there is no window under x, y - return nil and leave *modeline_p unmodified. */ + Lisp_Object. If x, y is on the window's modeline, set *part + to 1; if it is on the separating line between the window and its + right sibling, set it to 2; otherwise set it to 0. If there is no + window under x, y return nil and leave *part unmodified. */ Lisp_Object -window_from_coordinates (screen, x, y, modeline_p) +window_from_coordinates (screen, x, y, part) SCREEN_PTR screen; int x, y; - int *modeline_p; + int *part; { register Lisp_Object tem, first; - first = SCREEN_SELECTED_WINDOW (screen); - tem = next_screen_window (screen, first, Qt); + tem = first = SCREEN_SELECTED_WINDOW (screen); - while (1) + do { int found = coordinates_in_window (XWINDOW (tem), &x, &y); if (found) { - *modeline_p = (found == -1); + *part = found - 1; return tem; } - if (EQ (tem, first)) - return Qnil; - - tem = next_screen_window (screen, tem, Qt); + tem = Fnext_window (tem, Qt, Qlambda); } + while (! EQ (tem, first)); + + return Qnil; } -DEFUN ("locate-window-from-coordinates", - Flocate_window_from_coordinates, Slocate_window_from_coordinates, - 2, 2, 0, - "Return window on SCREEN containing position COORDINATES.\n\ -COORDINATES is a list (SCREEN-X SCREEN-Y) of coordinates\n\ +DEFUN ("window-at", Fwindow_at, Swindow_at, 1, 2, 0, + "Return window containing position COORDINATES on SCREEN.\n\ +If omitted, SCREEN defaults to the currently selected screen.\n\ +COORDINATES is a pair (SCREEN-X . SCREEN-Y) of coordinates\n\ which are relative to 0,0 at the top left corner of the screen.") - (screen, coordinates) - Lisp_Object screen, coordinates; + (coordinates, screen) + Lisp_Object coordinates, screen; { int part; - CHECK_SCREEN (screen, 0); + if (NULL (screen)) + XSET (screen, Lisp_Screen, selected_screen); + else + CHECK_LIVE_SCREEN (screen, 0); CHECK_CONS (coordinates, 1); + CHECK_NUMBER (XCONS (coordinates)->car, 1); + CHECK_NUMBER (XCONS (coordinates)->cdr, 1); return window_from_coordinates (XSCREEN (screen), XINT (Fcar (coordinates)), - XINT (Fcar (Fcdr (coordinates))), + XINT (Fcdr (coordinates)), &part); } @@ -689,17 +756,57 @@ return Qnil; } -#ifdef MULTI_SCREEN -Lisp_Object -next_screen_window (screen, window, mini) - SCREEN_PTR screen; - Lisp_Object window, mini; + +extern Lisp_Object next_screen (), prev_screen (); + +DEFUN ("next-window", Fnext_window, Snext_window, 0, 3, 0, + "Return next window after WINDOW in canonical ordering of windows.\n\ +If omitted, WINDOW defaults to the selected window.\n\ +\n\ +Optional second arg MINIBUF t means count the minibuffer window even\n\ +if not active. MINIBUF nil or omitted means count the minibuffer iff\n\ +it is active. MINIBUF neither t nor nil means not to count the\n\ +minibuffer even if it is active.\n\ +\n\ +Several screens may share a single minibuffer; if the minibuffer\n\ +counts, all windows on all screens that share that minibuffer count\n\ +too. This means that next-window may be used to iterate through the\n\ +set of windows even when the minibuffer is on another screen. If the\n\ +minibuffer does not count, only windows from WINDOW's screen count.\n\ +\n\ +Optional third arg ALL-SCREENS t means include windows on all screens.\n\ +ALL-SCREENS nil or omitted means cycle within the screens as specified\n\ +above. If neither nil nor t, restrict to WINDOW's screen.") + (window, minibuf, all_screens) + register Lisp_Object window, minibuf, all_screens; { - Lisp_Object tem; + register Lisp_Object tem; + Lisp_Object start_window; if (NULL (window)) - window = SCREEN_SELECTED_WINDOW (screen); - + window = selected_window; + else + CHECK_WINDOW (window, 0); + + start_window = window; + + /* minibuf == nil may or may not include minibuffers. + Decide if it does. */ + if (NULL (minibuf)) + minibuf = (minibuf_level ? Qt : Qlambda); + + /* all_screens == nil doesn't specify which screens to include. + Decide which screens it includes. */ + if (NULL (all_screens)) + all_screens = (EQ (minibuf, Qt) + ? (SCREEN_MINIBUF_WINDOW + (XSCREEN + (WINDOW_SCREEN + (XWINDOW (window))))) + : Qnil); + else if (! EQ (all_screens, Qt)) + all_screens = Qnil; + /* Do this loop at least once, to get the next window, and perhaps again, if we hit the minibuffer and that is not acceptable. */ do @@ -709,15 +816,22 @@ while (tem = XWINDOW (window)->next, NULL (tem)) if (tem = XWINDOW (window)->parent, !NULL (tem)) window = tem; - else - /* Since window's next and parent are nil, we have found - the minibuffer window of this screen. */ + else { - tem = SCREEN_ROOT_WINDOW (screen); + /* We've reached the end of this screen. + Which other screens are acceptable? */ + tem = WINDOW_SCREEN (XWINDOW (window)); +#ifdef MULTI_SCREEN + if (! NULL (all_screens)) + tem = next_screen (tem, all_screens); +#endif + tem = SCREEN_ROOT_WINDOW (XSCREEN (tem)); + break; } window = tem; + /* If we're in a combination window, find its first child and recurse on that. Otherwise, we've found the window we want. */ while (1) @@ -729,122 +843,66 @@ else break; } } - /* Exit the loop if + /* Which windows are acceptible? + Exit the loop and accept this window if this isn't a minibuffer window, or - we're accepting all minibuffer windows, even when inactive, or - we're accepting active minibuffer windows and this one is. */ + we're accepting minibuffer windows, or + we've come all the way around and we're back at the original window. */ while (MINI_WINDOW_P (XWINDOW (window)) - && !EQ (mini, Qt) - && (!NULL (mini) || !minibuf_level)); + && ! EQ (minibuf, Qt) + && window != start_window); return window; } -#endif -extern Lisp_Object next_screen (), prev_screen (); - -DEFUN ("next-window", Fnext_window, Snext_window, 0, 3, 0, - "Return next window after WINDOW in canonical ordering of windows.\n\ -Optional second arg MINIBUF t means count the minibuffer window\n\ -even if not active. If MINIBUF is neither t nor nil it means\n\ -not to count the minibuffer even if it is active.\n\ -Optional third arg ALL-SCREENS t means include all windows in all screens;\n\ -otherwise cycle within the selected screen, with the exception that if a\n\ -global minibuffer screen is in use and MINIBUF is t, all screens are used.") - (window, mini, all_screens) - register Lisp_Object window, mini, all_screens; +DEFUN ("previous-window", Fprevious_window, Sprevious_window, 0, 3, 0, + "Return the window preceeding WINDOW in canonical ordering of windows.\n\ +If omitted, WINDOW defaults to the selected window.\n\ +\n\ +Optional second arg MINIBUF t means count the minibuffer window even\n\ +if not active. MINIBUF nil or omitted means count the minibuffer iff\n\ +it is active. MINIBUF neither t nor nil means not to count the\n\ +minibuffer even if it is active.\n\ +\n\ +Several screens may share a single minibuffer; if the minibuffer\n\ +counts, all windows on all screens that share that minibuffer count\n\ +too. This means that previous-window may be used to iterate through\n\ +the set of windows even when the minibuffer is on another screen. If\n\ +the minibuffer does not count, only windows from WINDOW's screen\n\ +count.\n\ +\n\ +Optional third arg ALL-SCREENS t means include windows on all screens.\n\ +ALL-SCREENS nil or omitted means cycle within the screens as specified\n\ +above. If neither nil nor t, restrict to WINDOW's screen.") + (window, minibuf, all_screens) + register Lisp_Object window, minibuf, all_screens; { register Lisp_Object tem; + Lisp_Object start_window; if (NULL (window)) window = selected_window; else CHECK_WINDOW (window, 0); -#ifdef MULTI_SCREEN - if (EQ (mini, Qt) - || (! NULL (mini) && minibuf_level)) - { - if (SCREENP (Vglobal_minibuffer_screen)) - all_screens = Qt; - } -#endif + start_window = window; - /* Do this loop at least once, to get the next window, and perhaps - again, if we hit the minibuffer and that is not acceptable. */ - do - { - /* Find a window that actually has a next one. This loop - climbs up the tree. */ - while (tem = XWINDOW (window)->next, NULL (tem)) - if (tem = XWINDOW (window)->parent, !NULL (tem)) - window = tem; - else - /* Since window's next and parent are nil, it must be - the minibuffer window of this screen. If all_screens, - jump to the next screen. */ - { - tem = WINDOW_SCREEN (XWINDOW (window)); -#ifdef MULTI_SCREEN - if (! NULL (all_screens)) - tem = next_screen (tem, NULL (mini) ? 0 : 1); -#endif - tem = SCREEN_ROOT_WINDOW (XSCREEN (tem)); - break; - } + /* minibuf == nil may or may not include minibuffers. + Decide if it does. */ + if (NULL (minibuf)) + minibuf = (minibuf_level ? Qt : Qlambda); - window = tem; - /* If we're in a combination window, find its first child and - recurse on that. Otherwise, we've found the window we want. */ - while (1) - { - if (!NULL (XWINDOW (window)->hchild)) - window = XWINDOW (window)->hchild; - else if (!NULL (XWINDOW (window)->vchild)) - window = XWINDOW (window)->vchild; - else break; - } - } - /* Exit the loop if - this isn't a minibuffer window, or - we're accepting all minibuffer windows, even when inactive, or - we're accepting active minibuffer windows and this one is, or - this is a screen whose only window is a minibuffer window. */ - while (MINI_WINDOW_P (XWINDOW (window)) - && !EQ (mini, Qt) - && (!NULL (mini) || !minibuf_level) - && !EQ (SCREEN_ROOT_WINDOW (XSCREEN (XWINDOW (window)->screen)), - SCREEN_MINIBUF_WINDOW (XSCREEN (XWINDOW (window)->screen)))); - - return window; -} - -DEFUN ("previous-window", Fprevious_window, Sprevious_window, 0, 3, 0, - "Return previous window before WINDOW in canonical ordering of windows.\n\ -Optional second arg MINIBUF t means count the minibuffer window\n\ -even if not active. If MINIBUF is neither t nor nil it means\n\ -not to count the minibuffer even if it is active.\n\ -Optional third arg ALL-SCREENS t means include all windows in all screens;\n\ -otherwise cycle within the selected screen, with the exception that if a\n\ -global minibuffer screen is in use and MINIBUF is t, all screens are used.") - (window, mini, all_screens) - register Lisp_Object window, mini, all_screens; -{ - register Lisp_Object tem; - - if (NULL (window)) - window = selected_window; - else - CHECK_WINDOW (window, 0); - -#ifdef MULTI_SCREEN - if (EQ (mini, Qt) - || (! NULL (mini) && minibuf_level)) - { - if (SCREENP (Vglobal_minibuffer_screen)) - all_screens = Qt; - } -#endif + /* all_screens == nil doesn't specify which screens to include. + Decide which screens it includes. */ + if (NULL (all_screens)) + all_screens = (EQ (minibuf, Qt) + ? (SCREEN_MINIBUF_WINDOW + (XSCREEN + (WINDOW_SCREEN + (XWINDOW (window))))) + : Qnil); + else if (! EQ (all_screens, Qt)) + all_screens = Qnil; /* Do this loop at least once, to get the previous window, and perhaps again, if we hit the minibuffer and that is not acceptable. */ @@ -855,17 +913,17 @@ while (tem = XWINDOW (window)->prev, NULL (tem)) if (tem = XWINDOW (window)->parent, !NULL (tem)) window = tem; - else - /* Since window's prev and parent are nil, we have found - the root window of this screen. If all_screens, jump - to the previous screen. */ + else { + /* We have found the top window on the screen. + Which screens are acceptable? */ tem = WINDOW_SCREEN (XWINDOW (window)); #ifdef MULTI_SCREEN if (! NULL (all_screens)) - tem = prev_screen (tem, NULL (mini) ? 0 : 1); + tem = next_screen (tem, all_screens); #endif tem = SCREEN_ROOT_WINDOW (XSCREEN (tem)); + break; } @@ -883,16 +941,14 @@ window = tem; } } - /* Exit the loop if + /* Which windows are acceptable? + Exit the loop and accept this window if this isn't a minibuffer window, or - we're accepting all minibuffer windows, even when inactive, or - we're accepting active minibuffer windows and this one is, or - this is a screen whose only window is a minibuffer window. */ + we're accepting minibuffer windows, or + we've come all the way around and we're back at the original window. */ while (MINI_WINDOW_P (XWINDOW (window)) - && !EQ (mini, Qt) - && (!NULL (mini) || !minibuf_level) - && !EQ (SCREEN_ROOT_WINDOW (XSCREEN (XWINDOW (window)->screen)), - SCREEN_MINIBUF_WINDOW (XSCREEN (XWINDOW (window)->screen)))); + && !EQ (minibuf, Qt) + && window != start_window); return window; } @@ -983,7 +1039,7 @@ the current window. */ #ifdef MULTI_SCREEN if (screen) - next_window = next_screen_window (screen, w, mini ? Qt : Qnil); + next_window = Fnext_window (w, (mini ? Qt : Qnil), Qlambda); else #endif /* MULTI_SCREEN */ /* We know screen is 0, so we're looping through all screens. @@ -1467,16 +1523,14 @@ if (pop_up_windows #ifdef MULTI_SCREEN - || EQ (SCREEN_ROOT_WINDOW (selected_screen), - SCREEN_MINIBUF_WINDOW (selected_screen)) + || SCREEN_MINIBUF_ONLY_P (selected_screen) #endif ) { Lisp_Object screens = Qnil; #ifdef MULTI_SCREEN - if (EQ (SCREEN_ROOT_WINDOW (selected_screen), - SCREEN_MINIBUF_WINDOW (selected_screen))) + if (SCREEN_MINIBUF_ONLY_P (selected_screen)) XSET (screens, Lisp_Screen, last_nonminibuf_screen); #endif /* Don't try to create a window if would get an error */ @@ -1782,17 +1836,22 @@ { register int maxdelta; - register Lisp_Object tem; maxdelta = (!NULL (parent) ? (*sizefun) (parent) - *sizep - : (tem = (!NULL (p->next) ? p->next : p->prev), - (*sizefun) (tem) - MINSIZE (tem))); + : !NULL (p->next) ? (*sizefun) (p->next) - MINSIZE (p->next) + : !NULL (p->prev) ? (*sizefun) (p->prev) - MINSIZE (p->prev) + /* This is a screen with only one window, a minibuffer-only + or a minibufferless screen. */ + : (delta = 0)); if (delta > maxdelta) /* This case traps trying to make the minibuffer the full screen, or make the only window aside from the minibuffer the full screen. */ delta = maxdelta; + + if (delta == 0) + return; } if (!NULL (p->next) && @@ -2497,7 +2556,7 @@ s = selected_screen; else { - CHECK_SCREEN (screen, 0); + CHECK_LIVE_SCREEN (screen, 0); s = XSCREEN (screen); } @@ -2546,6 +2605,7 @@ selected_screen = make_terminal_screen (); minibuf_window = selected_screen->minibuffer_window; selected_window = selected_screen->selected_window; + last_nonminibuf_screen = selected_screen; #else /* not MULTI_SCREEN */ extern Lisp_Object get_minibuffer (); @@ -2677,7 +2737,8 @@ defsubr (&Swindow_hscroll); defsubr (&Sset_window_hscroll); defsubr (&Swindow_edges); - defsubr (&Slocate_window_from_coordinates); + defsubr (&Scoordinates_in_window_p); + defsubr (&Swindow_at); defsubr (&Swindow_point); defsubr (&Swindow_start); defsubr (&Swindow_end);