From xemacs-m  Mon May 12 11:19:29 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 LAA12213
	for <xemacs-beta@xemacs.org>; Mon, 12 May 1997 11:19:27 -0500 (CDT)
Received: (from hniksic@localhost)
          by jagor.srce.hr (8.8.5/8.8.4)
	  id SAA25651; Mon, 12 May 1997 18:19:26 +0200 (MET DST)
To: XEmacs Developers <xemacs-beta@xemacs.org>
Subject: Multiple frames on TTY-s: update
X-Save-Project-Gutenberg: <URL:http://www.promo.net/pg/nl/pgny_nov96.html>
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: 12 May 1997 18:19:26 +0200
Message-ID: <kigiv0o8xyp.fsf@jagor.srce.hr>
Lines: 336
X-Mailer: Gnus v5.4.52/XEmacs 19.15

Here is a better patch for that.  A condition has been handled (thanks
David!) and a Lisp_Object is now declared as extern.  This is stable
stuff, and you can all try applying it and tell me how fast your
XEmacs crashes.       (I'm just kidding.  It really is stable)

--- src/frame-tty.c.orig	Sun Mar  9 00:27:47 1997
+++ src/frame-tty.c	Mon May 12 18:16:02 1997
@@ -1,6 +1,7 @@
 /* TTY frame functions.
-   Copyright (C) 1995 Free Software Foundation, Inc.
+   Copyright (C) 1995  Free Software Foundation, Inc.
    Copyright (C) 1995, 1996 Ben Wing.
+   Copyright (C) 1997  Free Software Foundation, Inc.
 
 This file is part of XEmacs.
 
@@ -21,11 +22,8 @@
 
 /* Synched up with: Not in FSF. */
 
-/* Written by Ben Wing. */
-
-/* #### This file is just a stub.  It should be possible to have more
-   than one frame on a tty, with only one frame being "active" (displayed)
-   at a time. */
+/* Written by Ben Wing.
+   Multi-frame support added by Hrvoje Niksic. */
 
 #include <config.h>
 #include "lisp.h"
@@ -33,25 +31,67 @@
 #include "console-tty.h"
 #include "frame.h"
 
+
+/* Default properties to use when creating frames.  */
 Lisp_Object Vdefault_tty_frame_plist;
 
+static void tty_make_frame_visible (struct frame *);
+static void tty_make_frame_invisible (struct frame *);
+
+
 static void
 tty_init_frame_1 (struct frame *f, Lisp_Object props)
 {
   struct device *d = XDEVICE (FRAME_DEVICE (f));
   struct console *c = XCONSOLE (DEVICE_CONSOLE (d));
-  if (!NILP (DEVICE_FRAME_LIST (d)))
-    error ("Only one frame allowed on TTY devices");
+  Lisp_Object base_name = Qnil;
+  struct gcpro gcpro1;
+
+  /* Increment the frame count of this console. */
+  ++CONSOLE_TTY_DATA (c)->frame_count;
+
+  GCPRO1 (base_name);
+  /* Construct the frame name. */
+  base_name = Fplist_get (props, Qname, Vdefault_frame_name);
+  if (!NILP (base_name))
+    CHECK_STRING (base_name);
+  else
+    base_name = build_string ("XEmacs");
+
+  if (CONSOLE_TTY_DATA (c)->frame_count == 1)
+    f->name = base_name;
+  else
+    {
+      char *name = alloca (XSTRING_LENGTH (base_name) + 10);
+      sprintf (name, "%s-%d",
+	       XSTRING_DATA (base_name),
+	       CONSOLE_TTY_DATA (c)->frame_count);
+      f->name = build_string (name);
+    }
+  UNGCPRO;
 
-  f->name = build_string ("emacs");
   f->height = CONSOLE_TTY_DATA (c)->height;
   f->width = CONSOLE_TTY_DATA (c)->width;
-  f->visible = 1;
 #ifdef HAVE_SCROLLBARS
   f->scrollbar_on_left = 1;
   f->scrollbar_on_top = 0;
 #endif
+}
+
+static void
+tty_init_frame_3 (struct frame *f)
+{
+  struct device *d = XDEVICE (FRAME_DEVICE (f));
+  Lisp_Object tail = DEVICE_FRAME_LIST (d);
+
+  while (CONSP (tail))
+    {
+      tty_make_frame_invisible (decode_frame (XCAR (tail)));
+      tail = XCDR (tail);
+    }
+  select_frame_2 (make_frame (f));
   SET_FRAME_CLEAR (f);
+  tty_make_frame_visible (f);
 }
 
 static void
@@ -59,7 +99,7 @@
 		      int first_on_console)
 {
   if (first_on_console)
-      call1 (Qinit_post_tty_win, FRAME_CONSOLE (f));
+    call1 (Qinit_post_tty_win, FRAME_CONSOLE (f));
 }
 
 /* Change from withdrawn state to mapped state. */
@@ -71,20 +111,72 @@
       SET_FRAME_CLEAR(f);
       f->visible = 1;
     }
-  
 }
 
 /* Change from mapped state to withdrawn state. */
 static void
 tty_make_frame_invisible (struct frame *f)
 {
-    f->visible = 0;
+  f->visible = 0;
 }
 
 static int
 tty_frame_visible_p (struct frame *f)
 {
-  return FRAME_VISIBLE_P(f);
+  return FRAME_VISIBLE_P (f);
+}
+
+/* Raise the frame.  This means that it becomes visible, and all the
+   others become invisible.  */
+static void
+tty_raise_frame (struct frame *f)
+{
+  struct device *d = XDEVICE (FRAME_DEVICE (f));
+  Lisp_Object frame_list = DEVICE_FRAME_LIST (d);
+  Lisp_Object tail = frame_list;
+
+  while (CONSP (tail))
+    {
+      if (decode_frame (XCAR (tail)) != f)
+	tty_make_frame_invisible (XFRAME (XCAR (tail)));
+      tail = XCDR (tail);
+    }
+  select_frame_2 (make_frame (f));
+  tty_make_frame_visible (f);
+}
+
+/* Lower the frame.  This means that it becomes invisible, while the
+   one after it in the frame list becomes visible.  */
+static void
+tty_lower_frame (struct frame *f)
+{
+  struct device *d = XDEVICE (FRAME_DEVICE (f));
+  Lisp_Object frame_list = DEVICE_FRAME_LIST (d);
+  Lisp_Object tail;
+  Lisp_Object new;
+
+  if (!FRAME_VISIBLE_P (f))
+    return;
+
+  tail = frame_list;
+  while (CONSP (tail))
+    {
+      if (decode_frame (XCAR (tail)) == f)
+	break;
+      tail = XCDR (tail);
+    }
+  if (!CONSP (tail))
+    {
+      error ("Cannot find frame to lower");
+    }
+
+  tty_make_frame_invisible (f);
+  if (CONSP (XCDR (tail)))
+    new = XCAR (XCDR (tail));
+  else
+    new = XCAR (frame_list);
+  tty_make_frame_visible (XFRAME (new));
+  select_frame_2 (new);
 }
 
 
@@ -96,10 +188,13 @@
 console_type_create_frame_tty (void)
 {
   CONSOLE_HAS_METHOD (tty, init_frame_1);
+  CONSOLE_HAS_METHOD (tty, init_frame_3);
   CONSOLE_HAS_METHOD (tty, after_init_frame);
   CONSOLE_HAS_METHOD (tty, make_frame_visible);
   CONSOLE_HAS_METHOD (tty, make_frame_invisible);
   CONSOLE_HAS_METHOD (tty, frame_visible_p);
+  CONSOLE_HAS_METHOD (tty, raise_frame);
+  CONSOLE_HAS_METHOD (tty, lower_frame);
 }
 
 void
--- src/frame.c.orig	Fri May  9 05:28:24 1997
+++ src/frame.c	Sun May 11 09:06:21 1997
@@ -410,7 +410,7 @@
   else if (STRINGP (Vdefault_frame_name))
     name = Vdefault_frame_name;
   else
-    name = build_string ("emacs");
+    name = build_string ("XEmacs");
 
   if (!NILP (Fstring_match (make_string ((CONST Bufbyte *) "\\.", 2), name,
 			    Qnil, Qnil)))
@@ -639,8 +639,27 @@
 select_frame_1 (Lisp_Object frame)
 {
   struct frame *f = XFRAME (frame);
+
+  /* If on a TTY, selecting a frame must raise it.  */
+#ifdef HAVE_TTY
+  if (FRAME_TTY_P (f))
+    FRAMEMETH(f, raise_frame, (f));  /* tty_raise_frame will call
+					select_frame_2, so we can skip
+					it. */
+  else
+    select_frame_2 (frame);
+#else
+  select_frame_2 (frame);
+#endif
+}
+
+/* Called from tty_raise_frame. */
+void
+select_frame_2 (Lisp_Object frame)
+{
+  struct frame *f = XFRAME (frame);
   Lisp_Object old_selected_frame = Fselected_frame (Qnil);
-  
+
   if (EQ (frame, old_selected_frame))
     return;
 
@@ -966,6 +985,7 @@
 {
   int passed = 0;
   int started_over = 0;
+  Lisp_Object tmp_frametype;
 
   /* If this frame is dead, it won't be in frame_list, and we'll loop
      forever.  Forestall that.  */
@@ -1013,7 +1033,18 @@
 		  if (EQ (f, frame))
 		    return f;
 
-		  if (frame_matches_frametype (f, frametype))
+		  tmp_frametype = frametype;
+		  if (FRAME_TTY_P (XFRAME (f)))
+		    {
+		      /* Only one TTY frame is visible at a time, but
+                         next-frame and similar should still find
+                         them.  */
+		      if (EQ (frametype, Qvisible)
+			  || EQ (frametype, Qvisible_nomini)
+			  || EQ (frametype, Qvisible_iconic_nomini))
+			tmp_frametype = Qnil;
+		    }
+		  if (frame_matches_frametype (f, tmp_frametype))
 		    return f;
 		}
 	      
@@ -1043,6 +1074,7 @@
 {
   Lisp_Object devcons, concons;
   Lisp_Object prev;
+  Lisp_Object tmp_frametype;
 
   /* If this frame is dead, it won't be in frame_list, and we'll loop
      forever.  Forestall that.  */
@@ -1067,7 +1099,17 @@
 	  /* Decide whether this frame is eligible to be returned,
 	     according to frametype.  */
 
-	  if (frame_matches_frametype (f, frametype))
+	  tmp_frametype = frametype;
+	  if (FRAME_TTY_P (XFRAME (f)))
+	    {
+	      /* Only one TTY frame is visible at a time, but
+		 next-frame and similar should still find them.  */
+	      if (EQ (frametype, Qvisible)
+		  || EQ (frametype, Qvisible_nomini)
+		  || EQ (frametype, Qvisible_iconic_nomini))
+		tmp_frametype = Qnil;
+	    }
+	  if (frame_matches_frametype (f, tmp_frametype))
 	    prev = f;
 
 	}
@@ -3055,7 +3097,7 @@
 This can be overridden by arguments to `make-frame'.
 This must be a string.
 */ );
-  Vdefault_frame_name = Fpurecopy (build_string ("emacs"));
+  Vdefault_frame_name = Fpurecopy (build_string ("XEmacs"));
 
   DEFVAR_LISP ("default-frame-plist", &Vdefault_frame_plist /*
 Plist of default values for frame creation, other than the first one.
--- src/console-tty.h.orig	Fri Apr 11 04:10:31 1997
+++ src/console-tty.h	Sun May 11 09:06:21 1997
@@ -58,6 +58,9 @@
   int height;
   int width;
 
+  /* The count of frame number. */
+  int frame_count;
+
   /* flags indicating presence, absence or value of various features */
   struct
     {
--- lisp/prim/modeline.el.orig	Thu Apr 10 07:55:46 1997
+++ lisp/prim/modeline.el	Sun May 11 09:06:21 1997
@@ -389,7 +389,8 @@
 		     "button2 cycles to the next buffer")
 
 (defconst modeline-buffer-identification
-  (list (cons modeline-buffer-id-left-extent (purecopy "XEmacs:"))
+  (list (cons modeline-buffer-id-left-extent (purecopy "%S:"))
+					; this used to be "XEmacs:"
 	(cons modeline-buffer-id-right-extent (purecopy " %17b")))
   "Modeline control for identifying the buffer being displayed.
 Its default value is \"XEmacs: %17b\" (NOT!).  Major modes that edit things


-- 
Hrvoje Niksic <hniksic@srce.hr> | Student at FER Zagreb, Croatia
--------------------------------+--------------------------------
* Q: What is an experienced Emacs user?
* A: A person who wishes that the terminal had pedals.

