*** empty log message ***
[bpt/emacs.git] / src / window.c
index 7685c0d..b1876a2 100644 (file)
@@ -1,12 +1,12 @@
 /* Window creation, deletion and examination for GNU Emacs.
    Does not include redisplay.
-   Copyright (C) 1985, 1986, 1987 Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1987, 1992 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 1, or (at your option)
+the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
@@ -27,6 +27,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "indent.h"
 #include "termchar.h"
 #include "disptab.h"
+#include "keyboard.h"
 
 Lisp_Object Qwindowp;
 
@@ -46,14 +47,6 @@ static struct window *decode_window();
 
 Lisp_Object selected_window;
 
-#ifndef MULTI_SCREEN
-
-/* The root window for the screen.
-   This is accessed via SCREEN_ROOT_WINDOW (selected_screen).  */
-Lisp_Object root_window;
-
-#endif
-
 /* The minibuffer window of the selected screen.
    Note that you cannot test for minibufferness of an arbitrary window
    by comparing against this; but you can test for minibufferness of
@@ -153,20 +146,7 @@ DEFUN ("minibuffer-window", Fminibuffer_window, Sminibuffer_window, 0, 0, 0,
   ()
 {
 #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;
 }
@@ -195,7 +175,7 @@ POS defaults to point; WINDOW, to the selected window.")
   register struct buffer *buf;
   struct position posval;
 
-  if (NULL (pos))
+  if (NILP (pos))
     posint = point;
   else
     {
@@ -203,7 +183,7 @@ POS defaults to point; WINDOW, to the selected window.")
       posint = XINT (pos);
     }
 
-  if (NULL (window))
+  if (NILP (window))
     window = selected_window;
   else
     CHECK_WINDOW (window, 1);
@@ -234,7 +214,7 @@ POS defaults to point; WINDOW, to the selected window.")
       posval = *compute_motion (top, 0, 0, posint, height, 0,
                                XFASTINT (w->width) - 1
                                - (XFASTINT (w->width) + XFASTINT (w->left)
-                                  != XSCREEN (w->screen)->width),
+                                  != SCREEN_WIDTH (XSCREEN (w->screen))),
                                XINT (w->hscroll), 0);
 
       return posval.vpos < height ? Qt : Qnil;
@@ -245,7 +225,7 @@ static struct window *
 decode_window (window)
      register Lisp_Object window;
 {
-  if (NULL (window))
+  if (NILP (window))
     return XWINDOW (selected_window);
 
   CHECK_WINDOW (window, 0);
@@ -328,55 +308,136 @@ and BOTTOM is one more than the bottommost row used by WINDOW\n\
                         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 distances\n\
+measured in characters from the upper-left corner of the screen.\n\
+(0 .  0) denotes the character in the upper left corner of the\n\
+screen.\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-line' 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_line;
+
+    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\
-which are relative to 0,0 at the top left corner of the screen.")
-  (screen, coordinates)
-      Lisp_Object screen, coordinates;
+DEFUN ("window-at", Fwindow_at, Swindow_at, 2, 3, 0,
+  "Return window containing row ROW, column COLUMN on SCREEN.\n\
+If omitted, SCREEN defaults to the currently selected screen.\n\
+The top left corner of the screen is considered to be row 0,\n\
+column 0.")
+  (row, column, screen)
+      Lisp_Object row, column, screen;
 {
   int part;
 
-  CHECK_SCREEN (screen, 0);
-  CHECK_CONS (coordinates, 1);
+  if (NILP (screen))
+    XSET (screen, Lisp_Screen, selected_screen);
+  else
+    CHECK_LIVE_SCREEN (screen, 2);
+  CHECK_NUMBER (row, 0);
+  CHECK_NUMBER (column, 1);
 
   return window_from_coordinates (XSCREEN (screen),
-                                 XINT (Fcar (coordinates)),
-                                 XINT (Fcar (Fcdr (coordinates))),
+                                 XINT (row), XINT (column),
                                  &part);
 }
 
@@ -452,7 +513,7 @@ from overriding motion of point in order to display at this exact start.")
   set_marker_restricted (w->start, pos, w->buffer);
   /* this is not right, but much easier than doing what is right. */
   w->start_at_line_beg = Qnil;
-  if (NULL (noforce))
+  if (NILP (noforce))
     w->force_start = Qt;
   w->update_mode_line = Qt;
   XFASTINT (w->last_modified) = 0;
@@ -471,24 +532,22 @@ See also `set-window-buffer-dedicated'.")
   return decode_window (window)->dedicated;
 }
 
-DEFUN ("set-window-buffer-dedicated", Fset_window_buffer_dedicated,
-       Sset_window_buffer_dedicated, 2, 2, 0,
-  "Make WINDOW display BUFFER and be dedicated to that buffer.\n\
-Then Emacs will not automatically change which buffer appears in WINDOW.\n\
-If BUFFER is nil, make WINDOW not be dedicated (but don't change which\n\
-buffer appears in it currently).")
+DEFUN ("set-window-dedicated-p", Fset_window_dedicated_p,
+       Sset_window_dedicated_p, 2, 2, 0,
+  "Control whether WINDOW is dedicated to the buffer it displays.\n\
+If it is dedicated, Emacs will not automatically change\n\
+which buffer appears in it.\n\
+The second argument is the new value for the dedication flag;\n\
+non-nil means yes.")
   (window, arg)
        Lisp_Object window, arg;
 {
   register struct window *w = decode_window (window);
 
-  if (NULL (arg))
+  if (NILP (arg))
     w->dedicated = Qnil;
   else
-    {
-      Fset_window_buffer (window, Fget_buffer_create (arg));
-      w->dedicated = Qt;
-    }
+    w->dedicated = Qt;
 
   return w->dedicated;
 }
@@ -524,8 +583,7 @@ window_display_table (w)
   return 0;
 }
 
-DEFUN ("set-window-display-table",
-       Fset_window_display_table, Sset_window_display_table, 2, 2, 0,
+DEFUN ("set-window-display-table", Fset_window_display_table, Sset_window_display_table, 2, 2, 0,
   "Set WINDOW's display-table to TABLE.")
   (window, table)
      register Lisp_Object window, table;
@@ -576,8 +634,8 @@ replace_window (old, replacement)
   /* If OLD is its screen's root_window, then replacement is the new
      root_window for that screen.  */
 
-  if (old == XSCREEN (o->screen)->root_window)
-    XSCREEN (o->screen)->root_window = replacement;
+  if (old == SCREEN_ROOT_WINDOW (XSCREEN (o->screen)))
+    SCREEN_ROOT_WINDOW (XSCREEN (o->screen)) = replacement;
 
   p->left = o->left;
   p->top = o->top;
@@ -585,15 +643,15 @@ replace_window (old, replacement)
   p->height = o->height;
 
   p->next = tem = o->next;
-  if (!NULL (tem))
+  if (!NILP (tem))
     XWINDOW (tem)->prev = replacement;
 
   p->prev = tem = o->prev;
-  if (!NULL (tem))
+  if (!NILP (tem))
     XWINDOW (tem)->next = replacement;
 
   p->parent = tem = o->parent;
-  if (!NULL (tem))
+  if (!NILP (tem))
     {
       if (EQ (XWINDOW (tem)->vchild, old))
        XWINDOW (tem)->vchild = replacement;
@@ -615,14 +673,14 @@ DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "",
   register struct window *p;
   register struct window *par;
 
-  if (NULL (window))
+  if (NILP (window))
     window = selected_window;
   else
     CHECK_WINDOW (window, 0);
 
   p = XWINDOW (window);
   parent = p->parent;
-  if (NULL (parent))
+  if (NILP (parent))
     error ("Attempt to delete minibuffer or sole ordinary window");
   par = XWINDOW (parent);
 
@@ -634,7 +692,7 @@ DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "",
   tem = p->buffer;
   /* tem is null for dummy parent windows
      (which have inferiors but not any contents themselves) */
-  if (!NULL (tem))
+  if (!NILP (tem))
     {
       unshow_buffer (p);
       unchain_marker (p->pointm);
@@ -643,11 +701,11 @@ DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "",
     }
 
   tem = p->next;
-  if (!NULL (tem))
+  if (!NILP (tem))
     XWINDOW (tem)->prev = p->prev;
 
   tem = p->prev;
-  if (!NULL (tem))
+  if (!NILP (tem))
     XWINDOW (tem)->next = p->next;
 
   if (EQ (window, par->hchild))
@@ -657,7 +715,7 @@ DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "",
 
   /* Find one of our siblings to give our space to.  */
   sib = p->prev;
-  if (NULL (sib))
+  if (NILP (sib))
     {
       /* If p gives its space to its next sibling, that sibling needs
         to have its top/left side pulled back to where p's is.
@@ -669,11 +727,11 @@ DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "",
     }
 
   /* Stretch that sibling.  */
-  if (!NULL (par->vchild))
+  if (!NILP (par->vchild))
     set_window_height (sib,
                       XFASTINT (XWINDOW (sib)->height) + XFASTINT (p->height),
                       1);
-  if (!NULL (par->hchild))
+  if (!NILP (par->hchild))
     set_window_width (sib,
                      XFASTINT (XWINDOW (sib)->width) + XFASTINT (p->width),
                      1);
@@ -682,93 +740,63 @@ DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "",
      put the child into the parent's place.  */
 
   tem = par->hchild;
-  if (NULL (tem))
+  if (NILP (tem))
     tem = par->vchild;
-  if (NULL (XWINDOW (tem)->next))
+  if (NILP (XWINDOW (tem)->next))
     replace_window (parent, tem);
   return Qnil;
 }
 \f
-#ifdef MULTI_SCREEN
-Lisp_Object
-next_screen_window (screen, window, mini)
-     SCREEN_PTR screen;
-     Lisp_Object window, mini;
-{
-  Lisp_Object tem;
-
-  if (NULL (window))
-    window = SCREEN_SELECTED_WINDOW (screen);
-  
-  /* 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, we have found
-            the minibuffer window of this screen.  */
-         {
-           tem = SCREEN_ROOT_WINDOW (screen);
-           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)
-       {
-         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.  */
-  while (MINI_WINDOW_P (XWINDOW (window))
-        && !EQ (mini, Qt)
-        && (!NULL (mini) || !minibuf_level));
-
-  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;
+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;
 {
   register Lisp_Object tem;
+  Lisp_Object start_window;
 
-  if (NULL (window))
+  if (NILP (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;
+
+  /* minibuf == nil may or may not include minibuffers.
+     Decide if it does.  */
+  if (NILP (minibuf))
+    minibuf = (minibuf_level ? Qt : Qlambda);
+
+  /* all_screens == nil doesn't specify which screens to include.
+     Decide which screens it includes.  */
+  if (NILP (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.  */
@@ -776,75 +804,96 @@ global minibuffer screen is in use and MINIBUF is t, all screens are used.")
     {
       /* 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))
+      while (tem = XWINDOW (window)->next, NILP (tem))
+       if (tem = XWINDOW (window)->parent, !NILP (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.  */
+       else
          {
+           /* 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, NULL (mini) ? 0 : 1);
+           if (! NILP (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)
        {
-         if (!NULL (XWINDOW (window)->hchild))
+         if (!NILP (XWINDOW (window)->hchild))
            window = XWINDOW (window)->hchild;
-         else if (!NULL (XWINDOW (window)->vchild))
+         else if (!NILP (XWINDOW (window)->vchild))
            window = XWINDOW (window)->vchild;
          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, 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;
 }
 
 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;
+  "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))
+  if (NILP (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;
+
+  /* minibuf == nil may or may not include minibuffers.
+     Decide if it does.  */
+  if (NILP (minibuf))
+    minibuf = (minibuf_level ? Qt : Qlambda);
+
+  /* all_screens == nil doesn't specify which screens to include.
+     Decide which screens it includes.  */
+  if (NILP (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.  */
@@ -852,20 +901,20 @@ global minibuffer screen is in use and MINIBUF is t, all screens are used.")
     {
       /* Find a window that actually has a previous one.  This loop
         climbs up the tree.  */
-      while (tem = XWINDOW (window)->prev, NULL (tem))
-       if (tem = XWINDOW (window)->parent, !NULL (tem))
+      while (tem = XWINDOW (window)->prev, NILP (tem))
+       if (tem = XWINDOW (window)->parent, !NILP (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);
+           if (! NILP (all_screens))
+             tem = next_screen (tem, all_screens);
 #endif
            tem = SCREEN_ROOT_WINDOW (XSCREEN (tem));
+
            break;
          }
 
@@ -874,25 +923,23 @@ global minibuffer screen is in use and MINIBUF is t, all screens are used.")
         recurse on that.  Otherwise, we've found the window we want.  */
       while (1)
        {
-         if (!NULL (XWINDOW (window)->hchild))
+         if (!NILP (XWINDOW (window)->hchild))
            window = XWINDOW (window)->hchild;
-         else if (!NULL (XWINDOW (window)->vchild))
+         else if (!NILP (XWINDOW (window)->vchild))
            window = XWINDOW (window)->vchild;
          else break;
-         while (tem = XWINDOW (window)->next, !NULL (tem))
+         while (tem = XWINDOW (window)->next, !NILP (tem))
            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;
 }
@@ -962,7 +1009,7 @@ window_loop (type, obj, mini, screens)
      on all screens, screen is 0.  */
   if (SCREENP (screens))
     screen = XSCREEN (screens);
-  else if (NULL (screens))
+  else if (NILP (screens))
     screen = selected_screen;
   else
     screen = 0;
@@ -983,7 +1030,7 @@ window_loop (type, obj, mini, screens)
         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.
@@ -1007,7 +1054,8 @@ window_loop (type, obj, mini, screens)
 
          case GET_LRU_WINDOW:
            /* t as arg means consider only full-width windows */
-           if (!NULL (obj) && XFASTINT (XWINDOW (w)->width) != screen->width)
+           if (!NILP (obj) && XFASTINT (XWINDOW (w)->width)
+               != SCREEN_WIDTH (screen))
              break;
 #if 0
            /* Ignore invisible and iconified screens.  */
@@ -1017,9 +1065,9 @@ window_loop (type, obj, mini, screens)
 #endif
            /* Ignore dedicated windows and minibuffers.  */
            if (MINI_WINDOW_P (XWINDOW (w))
-               || !NULL (XWINDOW (w)->dedicated))
+               || !NILP (XWINDOW (w)->dedicated))
              break;
-           if (NULL (best_window)
+           if (NILP (best_window)
                || (XFASTINT (XWINDOW (best_window)->use_time)
                    > XFASTINT (XWINDOW (w)->use_time)))
              best_window = w;
@@ -1035,10 +1083,10 @@ window_loop (type, obj, mini, screens)
              {
                /* If we're deleting the buffer displayed in the only window
                   on the screen, find a new buffer to display there.  */
-               if (NULL (XWINDOW (w)->parent))
+               if (NILP (XWINDOW (w)->parent))
                  {
                    Lisp_Object new_buffer = Fother_buffer (obj);
-                   if (NULL (new_buffer))
+                   if (NILP (new_buffer))
                      new_buffer
                        = Fget_buffer_create (build_string ("*scratch*"));
                    Fset_window_buffer (w, new_buffer);
@@ -1058,12 +1106,12 @@ window_loop (type, obj, mini, screens)
 #endif
            /* Ignore dedicated windows and minibuffers.  */
            if (MINI_WINDOW_P (XWINDOW (w))
-               || !NULL (XWINDOW (w)->dedicated))
+               || !NILP (XWINDOW (w)->dedicated))
              break;
            {
              struct window *best_window_ptr = XWINDOW (best_window);
              struct window *w_ptr = XWINDOW (w);
-             if (NULL (best_window) ||
+             if (NILP (best_window) ||
                  (XFASTINT (w_ptr->height) * XFASTINT (w_ptr->width))
                  > (XFASTINT (best_window_ptr->height)
                     * XFASTINT (best_window_ptr->width)))
@@ -1076,7 +1124,7 @@ window_loop (type, obj, mini, screens)
              {
                /* Find another buffer to show in this window.  */
                Lisp_Object another_buffer = Fother_buffer (obj);
-               if (NULL (another_buffer))
+               if (NILP (another_buffer))
                  another_buffer
                    = Fget_buffer_create (build_string ("*scratch*"));
                Fset_window_buffer (w, another_buffer);
@@ -1102,7 +1150,7 @@ screen, search only that screen.\n")
   register Lisp_Object w;
   /* First try for a window that is full-width */
   w = window_loop (GET_LRU_WINDOW, Qt, 0, screens);
-  if (!NULL (w) && !EQ (w, selected_window))
+  if (!NILP (w) && !EQ (w, selected_window))
     return w;
   /* If none of them, try the rest */
   return window_loop (GET_LRU_WINDOW, Qnil, 0, screens);
@@ -1145,7 +1193,7 @@ Only the screen WINDOW is on is affected.")
   struct buffer *obuf = current_buffer;
   int top;
 
-  if (NULL (window))
+  if (NILP (window))
     window = selected_window;
   else
     CHECK_WINDOW (window, 0);
@@ -1170,7 +1218,7 @@ DEFUN ("delete-windows-on", Fdelete_windows_on, Sdelete_windows_on,
   (buffer)
      Lisp_Object buffer;
 {
-  if (!NULL (buffer))
+  if (!NILP (buffer))
     {
       buffer = Fget_buffer (buffer);
       CHECK_BUFFER (buffer, 0);
@@ -1186,7 +1234,7 @@ DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows,
   (buffer)
      Lisp_Object buffer;
 {
-  if (!NULL (buffer))
+  if (!NILP (buffer))
     {
       buffer = Fget_buffer (buffer);
       CHECK_BUFFER (buffer, 0);
@@ -1212,7 +1260,7 @@ set_window_height (window, height, nodelete)
   Lisp_Object child;
 
   if (!nodelete
-      && ! NULL (w->parent)
+      && ! NILP (w->parent)
       && height < window_min_height)
     {
       Fdelete_window (window);
@@ -1222,19 +1270,19 @@ set_window_height (window, height, nodelete)
   XFASTINT (w->last_modified) = 0;
   windows_or_buffers_changed++;
   XFASTINT (w->height) = height;
-  if (!NULL (w->hchild))
+  if (!NILP (w->hchild))
     {
-      for (child = w->hchild; !NULL (child); child = XWINDOW (child)->next)
+      for (child = w->hchild; !NILP (child); child = XWINDOW (child)->next)
        {
          XWINDOW (child)->top = w->top;
          set_window_height (child, height, nodelete);
        }
     }
-  else if (!NULL (w->vchild))
+  else if (!NILP (w->vchild))
     {
       lastbot = top = XFASTINT (w->top);
       lastobot = 0;
-      for (child = w->vchild; !NULL (child); child = c->next)
+      for (child = w->vchild; !NILP (child); child = c->next)
        {
          c = XWINDOW (child);
 
@@ -1254,7 +1302,7 @@ set_window_height (window, height, nodelete)
        }
       /* Now delete any children that became too small.  */
       if (!nodelete)
-       for (child = w->vchild; !NULL (child); child = XWINDOW (child)->next)
+       for (child = w->vchild; !NILP (child); child = XWINDOW (child)->next)
          {
            set_window_height (child, XINT (XWINDOW (child)->height), 0);
          }
@@ -1283,19 +1331,19 @@ set_window_width (window, width, nodelete)
   XFASTINT (w->last_modified) = 0;
   windows_or_buffers_changed++;
   XFASTINT (w->width) = width;
-  if (!NULL (w->vchild))
+  if (!NILP (w->vchild))
     {
-      for (child = w->vchild; !NULL (child); child = XWINDOW (child)->next)
+      for (child = w->vchild; !NILP (child); child = XWINDOW (child)->next)
        {
          XWINDOW (child)->left = w->left;
          set_window_width (child, width, nodelete);
        }
     }
-  else if (!NULL (w->hchild))
+  else if (!NILP (w->hchild))
     {
       lastright = left = XFASTINT (w->left);
       lastoright = 0;
-      for (child = w->hchild; !NULL (child); child = c->next)
+      for (child = w->hchild; !NILP (child); child = c->next)
        {
          c = XWINDOW (child);
 
@@ -1314,14 +1362,14 @@ set_window_width (window, width, nodelete)
        }
       /* Delete children that became too small */
       if (!nodelete)
-       for (child = w->hchild; !NULL (child); child = XWINDOW (child)->next)
+       for (child = w->hchild; !NILP (child); child = XWINDOW (child)->next)
          {
            set_window_width (child, XINT (XWINDOW (child)->width), 0);
          }
     }
 }
 \f
-static int window_select_count;
+int window_select_count;
 
 DEFUN ("set-window-buffer", Fset_window_buffer, Sset_window_buffer, 2, 2, 0,
   "Make WINDOW display BUFFER as its contents.\n\
@@ -1335,16 +1383,16 @@ BUFFER can be a buffer or buffer name.")
   buffer = Fget_buffer (buffer);
   CHECK_BUFFER (buffer, 1);
 
-  if (NULL (XBUFFER (buffer)->name))
+  if (NILP (XBUFFER (buffer)->name))
     error ("Attempt to display deleted buffer");
 
   tem = w->buffer;
-  if (NULL (tem))
+  if (NILP (tem))
     error ("Window is deleted");
   else if (! EQ (tem, Qt))     /* w->buffer is t when the window
                                   is first being set up.  */
     {
-      if (!NULL (w->dedicated) && !EQ (tem, buffer))
+      if (!NILP (w->dedicated) && !EQ (tem, buffer))
        error ("Window is dedicated to %s\n", tem);
 
       unshow_buffer (w);
@@ -1380,7 +1428,7 @@ before each command.")
 
   w = XWINDOW (window);
 
-  if (NULL (w->buffer))
+  if (NILP (w->buffer))
     error ("Trying to select deleted window or non-leaf window");
 
   XFASTINT (w->use_time) = ++window_select_count;
@@ -1438,16 +1486,16 @@ Returns the window displaying BUFFER.")
   buffer = Fget_buffer (buffer);
   CHECK_BUFFER (buffer, 0);
 
-  if (!NULL (Vdisplay_buffer_function))
+  if (!NILP (Vdisplay_buffer_function))
     return call2 (Vdisplay_buffer_function, buffer, not_this_window);
 
-  if (NULL (not_this_window)
+  if (NILP (not_this_window)
       && XBUFFER (XWINDOW (selected_window)->buffer) == XBUFFER (buffer))
     return selected_window;
 
   window = Fget_buffer_window (buffer, Qnil);
-  if (!NULL (window)
-      && (NULL (not_this_window) || !EQ (window, selected_window)))
+  if (!NILP (window)
+      && (NILP (not_this_window) || !EQ (window, selected_window)))
     return window;
 
 #ifdef MULTI_SCREEN
@@ -1467,16 +1515,14 @@ Returns the window displaying BUFFER.")
 
   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 */
@@ -1485,7 +1531,7 @@ Returns the window displaying BUFFER.")
 
       window = Fget_largest_window (screens);
 
-      if (!NULL (window)
+      if (!NILP (window)
          && window_height (window) >= split_height_threshold
          &&
          (XFASTINT (XWINDOW (window)->width)
@@ -1583,16 +1629,16 @@ and put SIZE columns in the first of the pair.")
   register struct window *o, *p;
   register int size;
 
-  if (NULL (window))
+  if (NILP (window))
     window = selected_window;
   else
     CHECK_WINDOW (window, 0);
 
   o = XWINDOW (window);
 
-  if (NULL (chsize))
+  if (NILP (chsize))
     {
-      if (!NULL (horflag))
+      if (!NILP (horflag))
        /* Round odd size up, since this is for the left-hand window,
           and it will lose a column for the separators.  */
        size = ((XFASTINT (o->width) + 1) & -2) >> 1;
@@ -1616,13 +1662,13 @@ and put SIZE columns in the first of the pair.")
   if (window_min_height < 2)
     window_min_height = 2;
 
-  if (NULL (horflag))
+  if (NILP (horflag))
     {
       if (size < window_min_height
          || size + window_min_height > XFASTINT (o->height))
        args_out_of_range_3 (window, chsize, horflag);
-      if (NULL (o->parent)
-         || NULL (XWINDOW (o->parent)->vchild))
+      if (NILP (o->parent)
+         || NILP (XWINDOW (o->parent)->vchild))
        {
          make_dummy_parent (window);
          new = o->parent;
@@ -1634,8 +1680,8 @@ and put SIZE columns in the first of the pair.")
       if (size < window_min_width
          || size + window_min_width > XFASTINT (o->width))
        args_out_of_range_3 (window, chsize, horflag);
-      if (NULL (o->parent)
-         || NULL (XWINDOW (o->parent)->hchild))
+      if (NILP (o->parent)
+         || NILP (XWINDOW (o->parent)->hchild))
        {
          make_dummy_parent (window);
          new = o->parent;
@@ -1653,7 +1699,7 @@ and put SIZE columns in the first of the pair.")
 
   p->screen = o->screen;
   p->next = o->next;
-  if (!NULL (p->next))
+  if (!NILP (p->next))
     XWINDOW (p->next)->prev = new;
   p->prev = window;
   o->next = new;
@@ -1664,7 +1710,7 @@ and put SIZE columns in the first of the pair.")
 
   /* Apportion the available screen space among the two new windows */
 
-  if (!NULL (horflag))
+  if (!NILP (horflag))
     {
       p->height = o->height;
       p->top = o->top;
@@ -1691,7 +1737,7 @@ From program, optional second arg non-nil means grow sideways ARG columns.")
      register Lisp_Object n, side;
 {
   CHECK_NUMBER (n, 0);
-  change_window_height (XINT (n), !NULL (side));
+  change_window_height (XINT (n), !NILP (side));
   return Qnil;
 }
 
@@ -1702,7 +1748,7 @@ From program, optional second arg non-nil means shrink sideways ARG columns.")
      register Lisp_Object n, side;
 {
   CHECK_NUMBER (n, 0);
-  change_window_height (-XINT (n), !NULL (side));
+  change_window_height (-XINT (n), !NILP (side));
   return Qnil;
 }
 
@@ -1759,14 +1805,14 @@ change_window_height (delta, widthflag)
     {
       p = XWINDOW (window);
       parent = p->parent;
-      if (NULL (parent))
+      if (NILP (parent))
        {
          if (widthflag)
            error ("No other window to side of this one");
          break;
        }
-      if (widthflag ? !NULL (XWINDOW (parent)->hchild)
-         : !NULL (XWINDOW (parent)->vchild))
+      if (widthflag ? !NILP (XWINDOW (parent)->hchild)
+         : !NILP (XWINDOW (parent)->vchild))
        break;
       window = parent;
     }
@@ -1774,7 +1820,7 @@ change_window_height (delta, widthflag)
   sizep = &CURSIZE (p);
 
   if (*sizep + delta < MINSIZE (p)
-      && !NULL (XWINDOW (window)->parent))
+      && !NILP (XWINDOW (window)->parent))
     {
       Fdelete_window (window);
       return;
@@ -1782,20 +1828,25 @@ change_window_height (delta, widthflag)
 
   {
     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)));
+    maxdelta = (!NILP (parent) ? (*sizefun) (parent) - *sizep
+               : !NILP (p->next) ? (*sizefun) (p->next) - MINSIZE (p->next)
+               : !NILP (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) &&
+  if (!NILP (p->next) &&
       (*sizefun) (p->next) - delta >= MINSIZE (p->next))
     {
       (*setsizefun) (p->next, (*sizefun) (p->next) - delta, 0);
@@ -1805,7 +1856,7 @@ change_window_height (delta, widthflag)
         but it propagates the new top edge to its children */
       (*setsizefun) (p->next, (*sizefun) (p->next), 0);
     }
-  else if (!NULL (p->prev) &&
+  else if (!NILP (p->prev) &&
           (*sizefun) (p->prev) - delta >= MINSIZE (p->prev))
     {
       (*setsizefun) (p->prev, (*sizefun) (p->prev) - delta, 0);
@@ -1860,8 +1911,8 @@ window_internal_height (w)
   if (MINI_WINDOW_P (w))
     return ht;
 
-  if (!NULL (w->parent) || !NULL (w->vchild) || !NULL (w->hchild)
-      || !NULL (w->next) || !NULL (w->prev)
+  if (!NILP (w->parent) || !NILP (w->vchild) || !NILP (w->hchild)
+      || !NILP (w->next) || !NILP (w->prev)
       || SCREEN_WANTS_MODELINE_P (XSCREEN (WINDOW_SCREEN (w))))
     return ht - 1;
 
@@ -1871,9 +1922,10 @@ window_internal_height (w)
 /* Scroll contents of window WINDOW up N lines.  */
 
 void
-window_scroll (window, n)
+window_scroll (window, n, noerror)
      Lisp_Object window;
      int n;
+     int noerror;
 {
   register struct window *w = XWINDOW (window);
   register int opoint = point;
@@ -1886,7 +1938,7 @@ window_scroll (window, n)
   XFASTINT (tem) = point;
   tem = Fpos_visible_in_window_p (tem, window);
 
-  if (NULL (tem))
+  if (NILP (tem))
     {
       Fvertical_motion (make_number (- ht / 2));
       XFASTINT (tem) = point;
@@ -1902,14 +1954,14 @@ window_scroll (window, n)
   SET_PT (opoint);
 
   if (lose)
-    Fsignal (Qbeginning_of_buffer, Qnil);
+    {
+      if (noerror)
+       return;
+      else
+       Fsignal (Qbeginning_of_buffer, Qnil);
+    }
 
   if (pos < ZV)
-#if 0
-      /* Allow scrolling to an empty screen (end of buffer)
-        if that is exactly how far we wanted to go.  */
-      || XINT (nmoved) == n)
-#endif
     {
       set_marker_restricted (w->start, make_number (pos), w->buffer);
       w->start_at_line_beg = bolp;
@@ -1928,7 +1980,12 @@ window_scroll (window, n)
        }
     }
   else
-    Fsignal (Qend_of_buffer, Qnil);
+    {
+      if (noerror)
+       return;
+      else
+       Fsignal (Qend_of_buffer, Qnil);
+    }
 }
 \f
 /* This is the guts of Fscroll_up and Fscroll_down.  */
@@ -1953,14 +2010,14 @@ scroll_command (n, direction)
            - next_screen_context_lines);
   defalt = direction * (defalt < 1 ? 1 : defalt);
 
-  if (NULL (n))
-    window_scroll (selected_window, defalt);
+  if (NILP (n))
+    window_scroll (selected_window, defalt, 0);
   else if (EQ (n, Qminus))
-    window_scroll (selected_window, - defalt);
+    window_scroll (selected_window, - defalt, 0);
   else
     {
       n = Fprefix_numeric_value (n);
-      window_scroll (selected_window, XINT (n) * direction);
+      window_scroll (selected_window, XINT (n) * direction, 0);
     }
 
   unbind_to (count, Qnil);
@@ -2007,13 +2064,13 @@ showing that buffer, popping the buffer up if necessary.")
   register int count = specpdl_ptr - specpdl;
 
   if (MINI_WINDOW_P (XWINDOW (selected_window))
-      && !NULL (Vminibuf_scroll_window))
+      && !NILP (Vminibuf_scroll_window))
     window = Vminibuf_scroll_window;
   /* If buffer is specified, scroll that buffer.  */
-  else if (!NULL (Vother_window_scroll_buffer))
+  else if (!NILP (Vother_window_scroll_buffer))
     {
       window = Fget_buffer_window (Vother_window_scroll_buffer, Qnil);
-      if (NULL (window))
+      if (NILP (window))
        window = Fdisplay_buffer (Vother_window_scroll_buffer, Qt);
     }
   else
@@ -2033,16 +2090,16 @@ showing that buffer, popping the buffer up if necessary.")
   Fset_buffer (w->buffer);
   SET_PT (marker_position (w->pointm));
 
-  if (NULL (n))
-    window_scroll (window, ht - next_screen_context_lines);
+  if (NILP (n))
+    window_scroll (window, ht - next_screen_context_lines, 1);
   else if (EQ (n, Qminus))
-    window_scroll (window, next_screen_context_lines - ht);
+    window_scroll (window, next_screen_context_lines - ht, 1);
   else
     {
       if (XTYPE (n) == Lisp_Cons)
        n = Fcar (n);
       CHECK_NUMBER (n, 0);
-      window_scroll (window, XINT (n));
+      window_scroll (window, XINT (n), 1);
     }
 
   Fset_marker (w->pointm, make_number (point), Qnil);
@@ -2058,7 +2115,7 @@ Default for ARG is window width minus 2.")
      register Lisp_Object arg;
 {
 
-  if (NULL (arg))
+  if (NILP (arg))
     XFASTINT (arg) = XFASTINT (XWINDOW (selected_window)->width) - 2;
   else
     arg = Fprefix_numeric_value (arg);
@@ -2075,7 +2132,7 @@ Default for ARG is window width minus 2.")
   (arg)
      register Lisp_Object arg;
 {
-  if (NULL (arg))
+  if (NILP (arg))
     XFASTINT (arg) = XFASTINT (XWINDOW (selected_window)->width) - 2;
   else
     arg = Fprefix_numeric_value (arg);
@@ -2099,7 +2156,7 @@ redraws with point in the center.")
   register int ht = window_internal_height (w);
   register int opoint = point;
 
-  if (NULL (n))
+  if (NILP (n))
     {
       extern int screen_garbaged;
 
@@ -2144,7 +2201,7 @@ negative means relative to bottom of window.")
   register int height = window_internal_height (w);
   register int start;
 
-  if (NULL (arg))
+  if (NILP (arg))
     XFASTINT (arg) = height / 2;
   else
     {
@@ -2251,7 +2308,7 @@ by `current-window-configuration' (which see).")
 
   windows_or_buffers_changed++;
   new_current_buffer = data->current_buffer;
-  if (NULL (XBUFFER (new_current_buffer)->name))
+  if (NILP (XBUFFER (new_current_buffer)->name))
     new_current_buffer = Qnil;
 
   /* Mark all windows now on screen as "deleted".
@@ -2269,12 +2326,12 @@ by `current-window-configuration' (which see).")
       w = XWINDOW (p->window);
       w->next = Qnil;
 
-      if (!NULL (p->parent))
+      if (!NILP (p->parent))
        w->parent = SAVED_WINDOW_N (saved_windows, XFASTINT (p->parent))->window;
       else
        w->parent = Qnil;
 
-      if (!NULL (p->prev))
+      if (!NILP (p->prev))
        {
          w->prev = SAVED_WINDOW_N (saved_windows, XFASTINT (p->prev))->window;
 #ifdef MULTI_SCREEN
@@ -2288,7 +2345,7 @@ by `current-window-configuration' (which see).")
       else
        {
          w->prev = Qnil;
-         if (!NULL (w->parent))
+         if (!NILP (w->parent))
            {
              if (EQ (p->width, XWINDOW (w->parent)->width))
                {
@@ -2311,11 +2368,11 @@ by `current-window-configuration' (which see).")
       XFASTINT (w->last_modified) = 0;
 
       /* Reinstall the saved buffer and pointers into it.  */
-      if (NULL (p->buffer))
+      if (NILP (p->buffer))
        w->buffer = p->buffer;
       else
        {
-         if (!NULL (XBUFFER (p->buffer)->name))
+         if (!NILP (XBUFFER (p->buffer)->name))
            /* If saved buffer is alive, install it.  */
            {
              w->buffer = p->buffer;
@@ -2329,7 +2386,7 @@ by `current-window-configuration' (which see).")
                  XBUFFER (p->buffer) == current_buffer)
                Fgoto_char (w->pointm);
            }
-         else if (NULL (XBUFFER (w->buffer)->name))
+         else if (NILP (XBUFFER (w->buffer)->name))
            /* Else if window's old buffer is dead too, get a live one.  */
            {
              w->buffer = Fcdr (Fcar (Vbuffer_alist));
@@ -2364,7 +2421,7 @@ by `current-window-configuration' (which see).")
   if (s == selected_screen)
     {
       Fselect_window (data->current_window);
-      if (!NULL (new_current_buffer))
+      if (!NILP (new_current_buffer))
        Fset_buffer (new_current_buffer);
       else
        Fset_buffer (XWINDOW (selected_window)->buffer);
@@ -2383,11 +2440,11 @@ delete_all_subwindows (w)
 {
   register int count = 1;
   w->buffer = Qnil;
-  if (!NULL (w->next))
+  if (!NILP (w->next))
     delete_all_subwindows (XWINDOW (w->next));
-  if (!NULL (w->vchild))
+  if (!NILP (w->vchild))
     delete_all_subwindows (XWINDOW (w->vchild));
-  if (!NULL (w->hchild))
+  if (!NILP (w->hchild))
     delete_all_subwindows (XWINDOW (w->hchild));
 }
 \f
@@ -2396,11 +2453,11 @@ count_windows (window)
      register struct window *window;
 {
   register int count = 1;
-  if (!NULL (window->next))
+  if (!NILP (window->next))
     count += count_windows (XWINDOW (window->next));
-  if (!NULL (window->vchild))
+  if (!NILP (window->vchild))
     count += count_windows (XWINDOW (window->vchild));
-  if (!NULL (window->hchild))
+  if (!NILP (window->hchild))
     count += count_windows (XWINDOW (window->hchild));
   return count;
 }
@@ -2415,7 +2472,7 @@ save_window_save (window, vector, i)
   register struct window *w;
   register Lisp_Object tem;
 
-  for (;!NULL (window); window = w->next)
+  for (;!NILP (window); window = w->next)
     {
       p = SAVED_WINDOW_N (vector, i);
       w = XWINDOW (window);
@@ -2429,7 +2486,7 @@ save_window_save (window, vector, i)
       p->height = w->height;
       p->hscroll = w->hscroll;
       p->display_table = w->display_table;
-      if (!NULL (w->buffer))
+      if (!NILP (w->buffer))
        {
          /* Save w's value of point in the window configuration.
             If w is the selected window, then get the value of point
@@ -2457,19 +2514,19 @@ save_window_save (window, vector, i)
          p->start_at_line_beg = Qnil;
        }
 
-      if (NULL (w->parent))
+      if (NILP (w->parent))
        p->parent = Qnil;
       else
        p->parent = XWINDOW (w->parent)->temslot;
 
-      if (NULL (w->prev))
+      if (NILP (w->prev))
        p->prev = Qnil;
       else
        p->prev = XWINDOW (w->prev)->temslot;
 
-      if (!NULL (w->vchild))
+      if (!NILP (w->vchild))
        i = save_window_save (w->vchild, vector, i);
-      if (!NULL (w->hchild))
+      if (!NILP (w->hchild))
        i = save_window_save (w->hchild, vector, i);
     }
 
@@ -2493,11 +2550,11 @@ its value is -not- saved.")
   register int i;
   SCREEN_PTR s;
 
-  if (NULL (screen))
+  if (NILP (screen))
     s = selected_screen;
   else
     {
-      CHECK_SCREEN (screen, 0);
+      CHECK_LIVE_SCREEN (screen, 0);
       s = XSCREEN (screen);
     }
 
@@ -2546,35 +2603,42 @@ init_window_once ()
   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 ();
 
-  root_window = make_window (0);
-  minibuf_window = make_window (0);
+  SCREEN_ROOT_WINDOW (selected_screen) = make_window ();
+  minibuf_window = make_window ();
 
-  XWINDOW (root_window)->next = minibuf_window;
-  XWINDOW (minibuf_window)->prev = root_window;
+  XWINDOW (SCREEN_ROOT_WINDOW (selected_screen))->next = minibuf_window;
+  XWINDOW (minibuf_window)->prev = SCREEN_ROOT_WINDOW (selected_screen);
 
   /* These values 9 and 10 are arbitrary,
      just so that there is "something there."
      Correct values are put in in init_xdisp */
 
-  XFASTINT (XWINDOW (root_window)->width) = 10;
+  XFASTINT (XWINDOW (SCREEN_ROOT_WINDOW (selected_screen))->width) = 10;
   XFASTINT (XWINDOW (minibuf_window)->width) = 10;
 
-  XFASTINT (XWINDOW (root_window)->height) = 9;
+  XFASTINT (XWINDOW (SCREEN_ROOT_WINDOW (selected_screen))->height) = 9;
   XFASTINT (XWINDOW (minibuf_window)->top) = 9;
   XFASTINT (XWINDOW (minibuf_window)->height) = 1;
 
   /* Prevent error in Fset_window_buffer.  */
-  XWINDOW (root_window)->buffer = Qt;
+  XWINDOW (SCREEN_ROOT_WINDOW (selected_screen))->buffer = Qt;
   XWINDOW (minibuf_window)->buffer = Qt;
 
   /* Now set them up for real.  */
-  Fset_window_buffer (root_window, Fcurrent_buffer ());
+  Fset_window_buffer (SCREEN_ROOT_WINDOW (selected_screen),
+                     Fcurrent_buffer ());
   Fset_window_buffer (minibuf_window, get_minibuffer (0));
 
-  selected_window = root_window;
+  selected_window = SCREEN_ROOT_WINDOW (selected_screen);
+  /* Make sure this window seems more recently used than
+     a newly-created, never-selected window.  Increment
+     window_select_count so the first selection ever will get
+     something newer than this.  */
+  XFASTINT (XWINDOW (selected_window)->use_time) = ++window_select_count;
 #endif /* not MULTI_SCREEN */
 }
 
@@ -2672,14 +2736,15 @@ If there is only one window, it is split regardless of this value.");
   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);
   defsubr (&Sset_window_point);
   defsubr (&Sset_window_start);
   defsubr (&Swindow_dedicated_p);
-  defsubr (&Sset_window_buffer_dedicated);
+  defsubr (&Sset_window_dedicated_p);
   defsubr (&Swindow_display_table);
   defsubr (&Sset_window_display_table);
   defsubr (&Snext_window);