]> code.delx.au - gnu-emacs/blobdiff - src/window.c
*** empty log message ***
[gnu-emacs] / src / window.c
index 8c5d5fd7f26a1b8d0322237fa76efc353a395fc6..d53bd510c632c90dc7b3463e972177497bde7443 100644 (file)
@@ -18,8 +18,6 @@ You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
-#include <stdio.h>
-
 #include "config.h"
 #include "lisp.h"
 #include "buffer.h"
@@ -28,8 +26,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "commands.h"
 #include "indent.h"
 #include "termchar.h"
-#include "termhooks.h"
 #include "disptab.h"
+#include "keyboard.h"
 
 Lisp_Object Qwindowp;
 
@@ -87,10 +85,10 @@ int window_min_width;
 int pop_up_windows;
 
 /* Nonzero implies make new X screens for Fdisplay_buffer.  */
-int auto_new_screen;
+int pop_up_screens;
 
 /* Non-nil means use this function instead of default */
-Lisp_Object Vauto_new_screen_function;
+Lisp_Object Vpop_up_screen_function;
 
 /* Function to call to handle Fdisplay_buffer.  */
 Lisp_Object Vdisplay_buffer_function;
@@ -156,20 +154,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;
 }
@@ -198,7 +183,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
     {
@@ -206,7 +191,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);
@@ -248,7 +233,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);
@@ -331,55 +316,133 @@ 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 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\
-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, 1, 2, 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);
 }
 
@@ -455,7 +518,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;
@@ -485,7 +548,7 @@ buffer appears in it currently).")
 {
   register struct window *w = decode_window (window);
 
-  if (NULL (arg))
+  if (NILP (arg))
     w->dedicated = Qnil;
   else
     {
@@ -527,8 +590,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;
@@ -588,15 +650,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;
@@ -618,14 +680,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);
 
@@ -637,7 +699,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);
@@ -646,11 +708,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))
@@ -660,7 +722,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.
@@ -672,11 +734,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);
@@ -685,93 +747,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.  */
@@ -779,75 +811,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.  */
@@ -855,20 +908,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;
          }
 
@@ -877,25 +930,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;
 }
@@ -965,7 +1016,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;
@@ -986,7 +1037,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.
@@ -1010,7 +1061,7 @@ 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)
              break;
 #if 0
            /* Ignore invisible and iconified screens.  */
@@ -1020,9 +1071,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;
@@ -1038,10 +1089,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);
@@ -1061,12 +1112,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)))
@@ -1079,7 +1130,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);
@@ -1105,7 +1156,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);
@@ -1148,7 +1199,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);
@@ -1173,7 +1224,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);
@@ -1189,7 +1240,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);
@@ -1215,7 +1266,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);
@@ -1225,19 +1276,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);
 
@@ -1257,7 +1308,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);
          }
@@ -1286,19 +1337,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);
 
@@ -1317,14 +1368,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\
@@ -1338,16 +1389,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);
@@ -1383,7 +1434,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;
@@ -1395,24 +1446,13 @@ before each command.")
 
   selected_window = window;
 #ifdef MULTI_SCREEN
-  /* If we're selecting the minibuffer window of the selected screen,
-     don't change the selected screen, even if the minibuffer is on
-     a different screen.  */
-  if (XSCREEN (WINDOW_SCREEN (w)) != selected_screen
-      && ! EQ (SCREEN_MINIBUF_WINDOW (selected_screen), window))
+  if (XSCREEN (WINDOW_SCREEN (w)) != selected_screen)
     {
       XSCREEN (WINDOW_SCREEN (w))->selected_window = window;
       Fselect_screen (WINDOW_SCREEN (w), Qnil);
     }
   else
     selected_screen->selected_window = window;
-
-  /* When using the global minibuffer screen, we want the highlight to
-   go to the minibuffer's screen, and when we finish, we want the highlight
-   to return to the original screen.  Call the hook to put the highlight
-   where it belongs.  */
-  if (screen_rehighlight_hook)
-    (*screen_rehighlight_hook) ();
 #endif
 
   record_buffer (w->buffer);
@@ -1452,46 +1492,44 @@ 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
-  if (auto_new_screen)
+  /* If there are no screens open that have more than a minibuffer,
+     we need to create a new screen.  */
+  if (pop_up_screens || last_nonminibuf_screen == 0)
     {
       window
-       = Fscreen_selected_window (NULL (Vauto_new_screen_function)
-                                  ? Fx_create_screen (Qnil)
-                                  : call0 (Vauto_new_screen_function));
+       = Fscreen_selected_window (call0 (Vpop_up_screen_function));
       Fset_window_buffer (window, buffer);
 #if 0
-         Fselect_screen (XWINDOW (window)->screen, Qnil);
+      Fselect_screen (XWINDOW (window)->screen, Qnil);
 #endif
       return window;
     }
 #endif /* MULTI_SCREEN */
 
-  if (pop_up_windows)
+  if (pop_up_windows
+#ifdef MULTI_SCREEN
+      || SCREEN_MINIBUF_ONLY_P (selected_screen)
+#endif
+      )
     {
+      Lisp_Object screens = Qnil;
+      
 #ifdef MULTI_SCREEN
-      /* When minibuffer screen is used, this is the previous screen.
-        Declared in minibuffer.c */
-      extern struct screen *active_screen;
-      Lisp_Object screens;
-
-      if (active_screen)
-       XSET (screens, Lisp_Screen, active_screen);
-      else
-       screens = Qnil;
-
+      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 */
       if (split_height_threshold < window_min_height << 1)
@@ -1499,7 +1537,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)
@@ -1597,16 +1635,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;
@@ -1630,13 +1668,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;
@@ -1648,8 +1686,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;
@@ -1667,7 +1705,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;
@@ -1678,7 +1716,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;
@@ -1705,7 +1743,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;
 }
 
@@ -1716,7 +1754,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;
 }
 
@@ -1773,14 +1811,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;
     }
@@ -1788,7 +1826,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;
@@ -1796,20 +1834,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);
@@ -1819,7 +1862,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);
@@ -1874,8 +1917,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;
 
@@ -1885,9 +1928,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;
@@ -1900,7 +1944,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;
@@ -1916,14 +1960,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;
@@ -1942,7 +1986,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.  */
@@ -1967,14 +2016,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);
@@ -2021,13 +2070,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
@@ -2047,16 +2096,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);
@@ -2072,7 +2121,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);
@@ -2089,7 +2138,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);
@@ -2113,7 +2162,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;
 
@@ -2158,7 +2207,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
     {
@@ -2241,7 +2290,7 @@ by `current-window-configuration' (which see).")
   register Lisp_Object tem;
   Lisp_Object new_current_buffer;
   int k;
-  SCREEN_PTR s, screen_to_select;
+  SCREEN_PTR s;
 
   while (XTYPE (arg) != Lisp_Window_Configuration)
     {
@@ -2265,13 +2314,13 @@ 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".
      Restoring the new configuration "undeletes" any that are in it.  */
 
-  delete_all_subwindows (XWINDOW (s->root_window));
+  delete_all_subwindows (XWINDOW (SCREEN_ROOT_WINDOW (s)));
 #if 0
   /* This loses when the minibuf screen is not s. */
   delete_all_subwindows (XWINDOW (XWINDOW (minibuf_window)->prev));
@@ -2283,12 +2332,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
@@ -2302,7 +2351,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))
                {
@@ -2325,11 +2374,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;
@@ -2343,7 +2392,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));
@@ -2378,7 +2427,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);
@@ -2397,11 +2446,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
@@ -2410,11 +2459,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;
 }
@@ -2429,7 +2478,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);
@@ -2443,7 +2492,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
@@ -2471,19 +2520,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);
     }
 
@@ -2491,35 +2540,46 @@ save_window_save (window, vector, i)
 }
 
 DEFUN ("current-window-configuration",
-       Fcurrent_window_configuration, Scurrent_window_configuration, 0, 0, 0,
-       "Return an object representing Emacs' current window configuration.\n\
+       Fcurrent_window_configuration, Scurrent_window_configuration, 0, 1, 0,
+  "Return an object representing the current window configuration of SCREEN.\n\
+If SCREEN is nil or omitted, use the selected screen.\n\
 This describes the number of windows, their sizes and current buffers,\n\
 and for each displayed buffer, where display starts, and the positions of\n\
 point and mark.  An exception is made for point in the current buffer:\n\
 its value is -not- saved.")
-  ()
+  (screen)
+     Lisp_Object screen;
 {
   register Lisp_Object tem;
   register int n_windows;
   register struct save_window_data *data;
   register int i;
+  SCREEN_PTR s;
+
+  if (NILP (screen))
+    s = selected_screen;
+  else
+    {
+      CHECK_LIVE_SCREEN (screen, 0);
+      s = XSCREEN (screen);
+    }
 
-  n_windows = count_windows (XWINDOW (SCREEN_ROOT_WINDOW (selected_screen)));
+  n_windows = count_windows (XWINDOW (SCREEN_ROOT_WINDOW (s)));
   data = (struct save_window_data *)
            XVECTOR (Fmake_vector (make_number (SAVE_WINDOW_DATA_SIZE),
                                  Qnil));
-  XFASTINT (data->screen_width) = SCREEN_WIDTH (selected_screen);
-  XFASTINT (data->screen_height) = SCREEN_HEIGHT (selected_screen);
-  data->current_window = selected_window;
+  XFASTINT (data->screen_width) = SCREEN_WIDTH (s);
+  XFASTINT (data->screen_height) = SCREEN_HEIGHT (s);
+  data->current_window = SCREEN_SELECTED_WINDOW (s);
   XSET (data->current_buffer, Lisp_Buffer, current_buffer);
   data->minibuf_scroll_window = Vminibuf_scroll_window;
-  data->root_window = SCREEN_ROOT_WINDOW (selected_screen);
+  data->root_window = SCREEN_ROOT_WINDOW (s);
   tem = Fmake_vector (make_number (n_windows), Qnil);
   data->saved_windows = tem;
   for (i = 0; i < n_windows; i++)
     XVECTOR (tem)->contents[i]
       = Fmake_vector (make_number (SAVED_WINDOW_VECTOR_SIZE), Qnil);
-  save_window_save (SCREEN_ROOT_WINDOW (selected_screen),
+  save_window_save (SCREEN_ROOT_WINDOW (s),
                    XVECTOR (tem), 0);
   XSET (tem, Lisp_Window_Configuration, data);
   return (tem);
@@ -2538,7 +2598,7 @@ Does not restore the value of point in current buffer.")
   register int count = specpdl_ptr - specpdl;
 
   record_unwind_protect (Fset_window_configuration,
-                        Fcurrent_window_configuration ());
+                        Fcurrent_window_configuration (Qnil));
   val = Fprogn (args);
   return unbind_to (count, val);
 }
@@ -2549,11 +2609,12 @@ 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);
+  root_window = make_window ();
+  minibuf_window = make_window ();
 
   XWINDOW (root_window)->next = minibuf_window;
   XWINDOW (minibuf_window)->prev = root_window;
@@ -2578,6 +2639,11 @@ init_window_once ()
   Fset_window_buffer (minibuf_window, get_minibuffer (0));
 
   selected_window = root_window;
+  /* 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 */
 }
 
@@ -2630,18 +2696,17 @@ SCREEN-PART is one of the following symbols:\n\
   Vother_window_scroll_buffer = Qnil;
 
 #ifdef MULTI_SCREEN
-  DEFVAR_BOOL ("auto-new-screen", &auto_new_screen,
+  DEFVAR_BOOL ("pop-up-screens", &pop_up_screens,
     "*Non-nil means `display-buffer' should make a separate X-window.");
-  auto_new_screen = 0;
+  pop_up_screens = 0;
 
-  DEFVAR_LISP ("auto-new-screen-function", &Vauto_new_screen_function,
+  DEFVAR_LISP ("pop-up-screen-function", &Vpop_up_screen_function,
     "*If non-nil, function to call to handle automatic new screen creation.\n\
 It is called with no arguments and should return a newly created screen.\n\
-nil means call `x-create-screen' with a nil argument.\n\
 \n\
 A typical value might be `(lambda () (x-create-screen auto-screen-parms))'\n\
 where `auto-screen-parms' would hold the default screen parameters.");
-  Vauto_new_screen_function = Qnil;
+  Vpop_up_screen_function = Qnil;
 #endif
 
   DEFVAR_BOOL ("pop-up-windows", &pop_up_windows,
@@ -2676,7 +2741,8 @@ 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);