From xemacs-m  Tue Jun 10 08:22:46 1997
Received: from jagor.srce.hr (hniksic@jagor.srce.hr [161.53.2.130])
	by xemacs.org (8.8.5/8.8.5) with ESMTP id IAA15236
	for <xemacs-beta@xemacs.org>; Tue, 10 Jun 1997 08:22:44 -0500 (CDT)
Received: (from hniksic@localhost)
          by jagor.srce.hr (8.8.5/8.8.4)
	  id PAA27631; Tue, 10 Jun 1997 15:22:43 +0200 (MET DST)
To: XEmacs Developers <xemacs-beta@xemacs.org>
Subject: [PATCH] Set gc-pointer on all frames
X-Attribution: Hrv
X-Face: Mie8:rOV<\c/~z{s.X4A{!?vY7{drJ([U]0O=W/<W*SMo/Mv:58:*_y~ki>xDi&N7XG
        KV^$k0m3Oe/)'e%3=$PCR&3ITUXH,cK>]bci&<qQ>Ff%x_>1`T(+M2Gg/fgndU%k*ft
        [(7._6e0n-V%|%'[c|q:;}td$#INd+;?!-V=c8Pqf}3J
From: Hrvoje Niksic <hniksic@srce.hr>
Date: 10 Jun 1997 15:22:42 +0200
Message-ID: <kigbu5epp7h.fsf@jagor.srce.hr>
Lines: 143
X-Mailer: Gnus v5.4.52/XEmacs 20.3(beta4)

Before the garbage collection /per se/ begins, the pointer in the
selected frame is set to gc-pointer-glyph.  So when gc takes a
little-bit of time, moving to another frame leaves you with a plain
old ugly yucky pointer.

The correct thing is to set frame pointer to gc-pointer-glyph in all
the window-system frames.  It's not hard to implement, but it's
somewhat tricky.  The following patch does it; I've been running with
it for some time, and XEmacs has been stable.

--- src/alloc.c.orig	Tue Jun 10 14:14:27 1997
+++ src/alloc.c	Tue Jun 10 14:57:31 1997
@@ -3956,12 +3956,12 @@
   char stack_top_variable;
   extern char *stack_bottom;
   int i;
-  struct frame *f = selected_frame ();
   int speccount = specpdl_depth ();
   Lisp_Object pre_gc_cursor = Qnil;
+  Lisp_Object changed_frames = Qnil;
   struct gcpro gcpro1;
 
-  int cursor_changed = 0;
+  int cursor_changed_selected_frame = 0;
 
   if (gc_in_progress != 0)
     return;
@@ -3972,7 +3972,7 @@
   if (preparing_for_armageddon)
     return;
 
-  GCPRO1 (pre_gc_cursor);
+  GCPRO1 (changed_frames);
 
   /* Very important to prevent GC during any of the following
      stuff that might run Lisp code; otherwise, we'll likely
@@ -3987,36 +3987,55 @@
   /* Now show the GC cursor/message. */
   if (!noninteractive)
     {
-      if (FRAME_WIN_P (f))
+      /* No need to gcpro this; gc won't catch us now. */
+      Lisp_Object frmcons, devcons, concons;
+      Lisp_Object selframe = make_frame (selected_frame ());
+
+      FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
 	{
-	  Lisp_Object frame = make_frame (f);
-	  Lisp_Object cursor = glyph_image_instance (Vgc_pointer_glyph,
-						     FRAME_SELECTED_WINDOW (f),
-						     ERROR_ME_NOT, 1);
-	  pre_gc_cursor = f->pointer;
-	  if (POINTER_IMAGE_INSTANCEP (cursor)
-	      /* don't change if we don't know how to change back. */
-	      && POINTER_IMAGE_INSTANCEP (pre_gc_cursor))
+	  struct frame *f = XFRAME (XCAR (frmcons));
+	  int cursor_changed;
+
+	  if (FRAME_WIN_P (f))
 	    {
-	      cursor_changed = 1;
-	      Fset_frame_pointer (frame, cursor);
+	      Lisp_Object frame = XCAR (frmcons);
+	      Lisp_Object cursor =
+		glyph_image_instance (Vgc_pointer_glyph,
+				      FRAME_SELECTED_WINDOW (f),
+				      ERROR_ME_NOT, 1);
+	      pre_gc_cursor = f->pointer;
+	      if (POINTER_IMAGE_INSTANCEP (cursor)
+		  /* don't change if we don't know how to change back. */
+		  && POINTER_IMAGE_INSTANCEP (pre_gc_cursor))
+		{
+		  Fset_frame_pointer (frame, cursor);
+		  /* Add the frame to the list. */
+		  changed_frames = Fcons (pre_gc_cursor, changed_frames);
+		  changed_frames = Fcons (XCAR (frmcons), changed_frames);
+		  if (EQ (XCAR (frmcons), selframe))
+		    cursor_changed_selected_frame = 1;
+		}
 	    }
 	}
-
-      /* Don't print messages to the stream device. */
-      if (!cursor_changed && !FRAME_STREAM_P (f))
-	{
-	  char *msg = (STRINGP (Vgc_message)
-		       ? GETTEXT ((char *) XSTRING_DATA (Vgc_message))
-		       : 0);
-	  Lisp_Object args[2], whole_msg;
-	  args[0] = build_string (msg ? msg :
-				  GETTEXT ((CONST char *) gc_default_message));
-	  args[1] = build_string ("...");
-	  whole_msg = Fconcat (2, args);
-	  echo_area_message (f, (Bufbyte *) 0, whole_msg, 0, -1,
-			     Qgarbage_collecting);
-	}
+      /* Now handle the plain old message. */
+      {
+	struct frame *f = XFRAME (selframe);
+	/* Don't print messages to the stream device. */
+	if (!cursor_changed_selected_frame && !FRAME_STREAM_P (f))
+	  {
+	    char *msg = (STRINGP (Vgc_message)
+			 ? GETTEXT ((char *) XSTRING_DATA (Vgc_message))
+			 : 0);
+	    Lisp_Object args[2], whole_msg;
+	    args[0] =
+	      build_string (msg ? msg :
+			    GETTEXT ((CONST char *) gc_default_message));
+	    args[1] = build_string ("...");
+	    whole_msg = Fconcat (2, args);
+	    echo_area_message (f, (Bufbyte *) 0, whole_msg, 0, -1,
+			       Qgarbage_collecting);
+	  }
+      }
     }
 
   /***** Now we actually start the garbage collection. */
@@ -4152,9 +4171,13 @@
   /* Now remove the GC cursor/message */
   if (!noninteractive)
     {
-      if (cursor_changed)
-	Fset_frame_pointer (make_frame (f), pre_gc_cursor);
-      else if (!FRAME_STREAM_P (f))
+      Lisp_Object tail = changed_frames;
+      while (CONSP (tail) && CONSP (XCDR (tail)))
+	{
+	  Fset_frame_pointer (XCAR (tail), XCAR (XCDR (tail)));
+	  tail = XCDR (XCDR (tail));
+	}
+      if (!cursor_changed_selected_frame && !FRAME_STREAM_P (selected_frame ()))
 	{
 	  char *msg = (STRINGP (Vgc_message)
 		       ? GETTEXT ((char *) XSTRING_DATA (Vgc_message))


-- 
Hrvoje Niksic <hniksic@srce.hr> | Student at FER Zagreb, Croatia
--------------------------------+--------------------------------
WWW:  World-Wide-Waste.  Waste management corporation, which
      handles the billions of tons of garbage generated by just
      about everybody these days.

