From xemacs-m  Sat May 17 07:12: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 HAA05389
	for <xemacs-beta@xemacs.org>; Sat, 17 May 1997 07:12:28 -0500 (CDT)
Received: (from hniksic@localhost)
          by jagor.srce.hr (8.8.5/8.8.4)
	  id OAA23600; Sat, 17 May 1997 14:12:28 +0200 (MET DST)
To: XEmacs Developers <xemacs-beta@xemacs.org>
Subject: [patch] Multiple frames on TTY-s
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: 17 May 1997 14:12:27 +0200
Message-ID: <kig67wi5mc4.fsf@jagor.srce.hr>
Lines: 358
X-Mailer: Gnus v5.4.52/XEmacs 19.15

Here is a slightly modified implementation of multiple frames on
TTY-s.  The advantages are:

1) doesn't meddle with frame names; the default frame name is now
   "emacs" again;

2) modeline identification solved cleanly; the default modeline
   identification is now "XEmacs%N", where `%N' will be empty on
   non-tty frames, and on the first TTY frame, and "-%d" on subsequent
   TTY frames.  The count is no longer console-local;

3) simpler than the previous patch, and ready for inclusion to 20.3 (I
   hope);

This is my absolutely first time to dare change anything in
redisplay*.c.  Although, I'm cheating, since I didn't touch the
redisplay routines.  But still.

--- src/ChangeLog.orig	Wed May 14 17:20:01 1997
+++ src/ChangeLog	Sat May 17 14:11:00 1997
@@ -1,3 +1,9 @@
+Sat May 17 14:10:27 1997  Hrvoje Niksic  <hniksic@srce.hr>
+
+	* redisplay.c (decode_mode_spec): New specification `%N'.
+
+	* frame-tty.c: Enable multiple frames.
+
 Sun May 11 23:36:08 1997  Steven L Baur  <steve@altair.xemacs.org>
 
 	* buffer.c: Rename Vdelete_auto_save_files to coding standards.
--- src/frame-tty.c.orig	Sun Mar  9 00:27:47 1997
+++ src/frame-tty.c	Sat May 17 13:59:47 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,47 @@
 #include "console-tty.h"
 #include "frame.h"
 
+
+/* Default properties to use when creating frames.  */
 Lisp_Object Vdefault_tty_frame_plist;
 
+/* The count of frame number. */
+static int tty_frame_count;
+
+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");
 
-  f->name = build_string ("emacs");
+  ++tty_frame_count;
+  f->order_count = tty_frame_count;
   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 +79,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 +91,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 +168,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.h.orig	Thu May 15 12:27:33 1997
+++ src/frame.h	Thu May 15 12:28:08 1997
@@ -59,6 +59,11 @@
   int pixheight;
   int pixwidth;
 
+#ifdef HAVE_TTY
+  /* The count of frame number.  This applies to TTY frames only. */
+  int order_count;
+#endif
+
   /* Width of the internal border.  This is a line of background color
      just inside the window's border.  It is normally only non-zero on
      X frames, but we put it here to avoid introducing window system
--- src/frame.c.orig	Wed May 14 04:01:56 1997
+++ src/frame.c	Thu May 15 11:41:24 1997
@@ -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;
 
 	}
--- src/redisplay.c.orig	Thu May 15 12:24:01 1997
+++ src/redisplay.c	Thu May 15 12:29:40 1997
@@ -61,6 +61,10 @@
 #include "mule-coding.h"
 #endif
 
+#ifdef HAVE_TTY
+#include "console-tty.h"
+#endif
+
 /* Note: We have to be careful throughout this code to properly handle
    and differentiate between Bufbytes and Emchars.
 
@@ -5765,6 +5769,20 @@
       /* print value of mode-name (obsolete) */
     case 'm':
       obj = b->mode_name;
+      break;
+
+      /* print hyphen and frame number, if != 1 */
+    case 'N':
+#ifdef HAVE_TTY
+      {
+	struct frame *f = XFRAME (w->frame);
+	if (FRAME_TTY_P (f) && f->order_count > 1)
+	  {
+	    str = alloca (10);
+	    sprintf (str, "-%d", f->order_count);
+	  }
+      }
+#endif
       break;
 
       /* print Narrow if appropriate */
--- lisp/prim/modeline.el.orig	Thu Apr 10 07:55:46 1997
+++ lisp/prim/modeline.el	Thu May 15 11:05:51 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 "XEmacs%N:"))
+					; 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
--------------------------------+--------------------------------
I'm sure they'll listen to reason! -- Neal Stevenson, _Snow Crash_

