diff src/frame.c @ 371:cc15677e0335 r21-2b1

Import from CVS: tag r21-2b1
author cvs
date Mon, 13 Aug 2007 11:03:08 +0200
parents a4f53d9b3154
children 8626e4521993
line wrap: on
line diff
--- a/src/frame.c	Mon Aug 13 11:01:58 2007 +0200
+++ b/src/frame.c	Mon Aug 13 11:03:08 2007 +0200
@@ -1006,10 +1006,13 @@
 }
 
 int
-device_matches_console_spec (Lisp_Object device, Lisp_Object console)
+device_matches_console_spec (Lisp_Object frame, Lisp_Object device,
+			     Lisp_Object console)
 {
   if (EQ (console, Qwindow_system))
     return DEVICE_WIN_P (XDEVICE (device));
+  if (NILP (console))
+    console = (DEVICE_CONSOLE (XDEVICE (FRAME_DEVICE (XFRAME (frame)))));
   if (DEVICEP (console))
     return EQ (device, console);
   if (CONSOLEP (console))
@@ -1023,60 +1026,78 @@
    FRAMETYPE and CONSOLE control which frames and devices
    are considered; see `next-frame'. */
 
-Lisp_Object
-next_frame (Lisp_Object frame, Lisp_Object frametype, Lisp_Object console)
+static Lisp_Object
+next_frame_internal (Lisp_Object frame, Lisp_Object frametype,
+		     Lisp_Object console, int called_from_delete_device)
 {
-  Lisp_Object first = Qnil;
-  Lisp_Object devcons, concons;
   int passed = 0;
-
+  int started_over = 0;
+
+  /* If this frame is dead, it won't be in frame_list, and we'll loop
+     forever.  Forestall that.  */
   CHECK_LIVE_FRAME (frame);
 
+  while (1)
+    {
+      Lisp_Object devcons, concons;
+
       DEVICE_LOOP_NO_BREAK (devcons, concons)
 	{
 	  Lisp_Object device = XCAR (devcons);
 	  Lisp_Object frmcons;
 
-      if (!device_matches_console_spec (device, console))
-	    {
-	      if (EQ (device, FRAME_DEVICE (XFRAME (frame))))
-		passed = 1;
+	  if (!device_matches_console_spec (frame, device, console))
 	    continue;
-	    }
 
 	  DEVICE_FRAME_LOOP (frmcons, XDEVICE (device))
 	    {
 	      Lisp_Object f = XCAR (frmcons);
-
 	      if (passed)
 		{
+		  /* #### Doing this here is bad and is now
+                     unnecessary.  The real bug was that f->iconified
+                     was never, ever updated unless a user explicitly
+                     called frame-iconified-p.  That has now been
+                     fixed.  With this change removed all of the other
+                     changes made to support this routine having the
+                     called_from_delete_device arg could be removed.
+                     But it is too close to release to do that now. */
+#if 0
+		  /* Make sure the visibility and iconified flags are
+                     up-to-date unless we're being deleted. */
+		  if (!called_from_delete_device)
+		    {
+		      Fframe_iconified_p (f);
+		      Fframe_visible_p (f);
+		    }
+#endif
+
+		  /* Decide whether this frame is eligible to be returned.  */
+
+		  /* If we've looped all the way around without finding any
+		     eligible frames, return the original frame.  */
+		  if (EQ (f, frame))
+		    return f;
+
 		  if (frame_matches_frametype (f, frametype))
 		    return f;
 		}
-	  else
-	    {
+
 	      if (EQ (frame, f))
-		{
-		passed = 1;
+		passed++;
 	    }
-	      else
-		{
-		  if (NILP (first) && frame_matches_frametype (f, frametype))
-		    first = f;
-		}
 	}
+      /* We hit the end of the list, and need to start over again. */
+      if (started_over)
+	return Qnil;
+      started_over++;
     }
 }
 
-  if (NILP (first))
-    /* We went through the whole frame list without finding a single
-       acceptable frame.  Return the original frame.  */
-    return frame;
-  else
-    /* There were no acceptable frames in the list after FRAME; otherwise,
-       we would have returned directly from the loop.  Since FIRST is the last
-       acceptable frame in the list, return it.  */
-    return first;
+Lisp_Object
+next_frame (Lisp_Object frame, Lisp_Object frametype, Lisp_Object console)
+{
+  return next_frame_internal (frame, frametype, console, 0);
 }
 
 /* Return the previous frame in the frame list before FRAME.
@@ -1084,52 +1105,50 @@
    are considered; see `next-frame'. */
 
 Lisp_Object
-previous_frame (Lisp_Object frame, Lisp_Object frametype, Lisp_Object console)
+prev_frame (Lisp_Object frame, Lisp_Object frametype, Lisp_Object console)
 {
   Lisp_Object devcons, concons;
-  Lisp_Object last = Qnil;
-
+  Lisp_Object prev;
+
+  /* If this frame is dead, it won't be in frame_list, and we'll loop
+     forever.  Forestall that.  */
   CHECK_LIVE_FRAME (frame);
 
+  prev = Qnil;
   DEVICE_LOOP_NO_BREAK (devcons, concons)
     {
       Lisp_Object device = XCAR (devcons);
       Lisp_Object frmcons;
 
-      if (!device_matches_console_spec (device, console))
-	{
-	  if (EQ (device, FRAME_DEVICE (XFRAME (frame)))
-	      && !NILP (last))
-	    return last;
+      if (!device_matches_console_spec (frame, device, console))
 	continue;
-	}
 
       DEVICE_FRAME_LOOP (frmcons, XDEVICE (device))
 	{
 	  Lisp_Object f = XCAR (frmcons);
 
-	  if (EQ (frame, f))
-	    {
-	      if (!NILP (last))
-		return last;
-	    }
-	  else
-	    {
+	  if (EQ (frame, f) && !NILP (prev))
+	    return prev;
+
+	  /* Decide whether this frame is eligible to be returned,
+	     according to frametype.  */
+
 	  if (frame_matches_frametype (f, frametype))
-		last = f;
+	    prev = f;
+
 	}
     }
-    }
-
-  if (NILP (last))
+
+  /* We've scanned the entire list.  */
+  if (NILP (prev))
     /* We went through the whole frame list without finding a single
        acceptable frame.  Return the original frame.  */
     return frame;
   else
     /* There were no acceptable frames in the list before FRAME; otherwise,
-       we would have returned directly from the loop.  Since LAST is the last
+       we would have returned directly from the loop.  Since PREV is the last
        acceptable frame in the list, return it.  */
-    return last;
+    return prev;
 }
 
 DEFUN ("next-frame", Fnext_frame, 0, 3, 0, /*
@@ -1194,7 +1213,7 @@
 {
   XSETFRAME (frame, decode_frame (frame));
 
-  return previous_frame (frame, frametype, console);
+  return prev_frame (frame, frametype, console);
 }
 
 /* Return any frame for which PREDICATE is non-zero, or return Qnil
@@ -1226,15 +1245,23 @@
    (Exception: if F is a stream frame, it's OK to delete if
    any other frames exist.) */
 
-int
-other_visible_frames (struct frame *f)
+static int
+other_visible_frames_internal (struct frame *f, int called_from_delete_device)
 {
   Lisp_Object frame;
 
   XSETFRAME (frame, f);
   if (FRAME_STREAM_P (f))
-    return !EQ (frame, next_frame (frame, Qt, Qt));
-  return !EQ (frame, next_frame (frame, Qvisible_iconic_nomini, Qt));
+    return !EQ (frame, next_frame_internal (frame, Qt, Qt,
+					    called_from_delete_device));
+  return !EQ (frame, next_frame_internal (frame, Qvisible_iconic_nomini, Qt,
+					  called_from_delete_device));
+}
+
+int
+other_visible_frames (struct frame *f)
+{
+  return other_visible_frames_internal (f, 0);
 }
 
 /* Delete frame F.
@@ -1295,7 +1322,7 @@
      losing any way of communicating with the still running XEmacs process.
      So we put it back.  */
   if (!force && !allow_deletion_of_last_visible_frame &&
-      !other_visible_frames (f))
+      !other_visible_frames_internal (f, called_from_delete_device))
     error ("Attempt to delete the sole visible or iconified frame");
 
   /* Does this frame have a minibuffer, and is it the surrogate
@@ -1421,17 +1448,22 @@
 
       next = DEVMETH_OR_GIVEN (d, get_frame_parent, (f), Qnil);
       if (NILP (next) || EQ (next, frame) || ! FRAME_LIVE_P (XFRAME (next)))
-	next = next_frame (frame, Qvisible, device);
+	next = next_frame_internal (frame, Qvisible, device,
+				    called_from_delete_device);
       if (NILP (next) || EQ (next, frame))
-	next = next_frame (frame, Qvisible, console);
-      if (NILP (next) || EQ (next, frame))
-	next = next_frame (frame, Qvisible, Qt);
+	next = next_frame_internal (frame, Qvisible, console,
+				    called_from_delete_device);
       if (NILP (next) || EQ (next, frame))
-	next = next_frame (frame, Qt, device);
+	next = next_frame_internal (frame, Qvisible, Qt,
+				    called_from_delete_device);
       if (NILP (next) || EQ (next, frame))
-	next = next_frame (frame, Qt, console);
+	next = next_frame_internal (frame, Qt, device,
+				    called_from_delete_device);
       if (NILP (next) || EQ (next, frame))
-	next = next_frame (frame, Qt, Qt);
+	next = next_frame_internal (frame, Qt, console,
+				    called_from_delete_device);
+      if (NILP (next) || EQ (next, frame))
+	next = next_frame_internal (frame, Qt, Qt, called_from_delete_device);
 
       /* if we haven't found another frame at this point
 	 then there aren't any. */
@@ -1453,7 +1485,9 @@
 	   */
 	  if (!EQ (device, FRAME_DEVICE(XFRAME(next))))
 	    {
-		Lisp_Object next_f = next_frame (frame, Qt, device);
+		Lisp_Object next_f =
+		    next_frame_internal (frame, Qt, device,
+					 called_from_delete_device);
 		if (NILP (next_f) || EQ (next_f, frame))
 		  ;
 		else
@@ -1795,7 +1829,7 @@
   struct window *w;
   int pix_x, pix_y;
 
-  CHECK_LIVE_WINDOW (window);
+  CHECK_WINDOW (window);
   CHECK_INT (x);
   CHECK_INT (y);
 
@@ -1819,7 +1853,7 @@
 {
   struct window *w;
 
-  CHECK_LIVE_WINDOW (window);
+  CHECK_WINDOW (window);
   CHECK_INT (x);
   CHECK_INT (y);