emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] Changes to emacs/src/frame.c,v


From: Miles Bader
Subject: [Emacs-diffs] Changes to emacs/src/frame.c,v
Date: Wed, 29 Aug 2007 05:28:21 +0000

CVSROOT:        /cvsroot/emacs
Module name:    emacs
Changes by:     Miles Bader <miles>     07/08/29 05:28:10

Index: src/frame.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/frame.c,v
retrieving revision 1.343
retrieving revision 1.344
diff -u -b -r1.343 -r1.344
--- src/frame.c 26 Jul 2007 05:27:52 -0000      1.343
+++ src/frame.c 29 Aug 2007 05:27:53 -0000      1.344
@@ -42,6 +42,7 @@
 #include "fontset.h"
 #endif
 #include "blockinput.h"
+#include "termchar.h"
 #include "termhooks.h"
 #include "dispextern.h"
 #include "window.h"
@@ -74,6 +75,8 @@
 
 Lisp_Object Qx_frame_parameter;
 Lisp_Object Qx_resource_name;
+Lisp_Object Qterminal;
+Lisp_Object Qterminal_live_p;
 
 /* Frame parameters (set or reported).  */
 
@@ -103,15 +106,19 @@
 Lisp_Object Qunsplittable;
 Lisp_Object Qmenu_bar_lines, Qtool_bar_lines;
 Lisp_Object Qleft_fringe, Qright_fringe;
-Lisp_Object Qbuffer_predicate, Qbuffer_list;
+Lisp_Object Qbuffer_predicate, Qbuffer_list, Qburied_buffer_list;
 Lisp_Object Qtty_color_mode;
+Lisp_Object Qtty, Qtty_type;
+Lisp_Object Qwindow_system;
+Lisp_Object Qenvironment;
+Lisp_Object Qterm_environment_variable;
+Lisp_Object Qdisplay_environment_variable;
 
 Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth;
 
 Lisp_Object Qinhibit_face_set_after_frame_default;
 Lisp_Object Qface_set_after_frame_default;
 
-
 Lisp_Object Vterminal_frame;
 Lisp_Object Vdefault_frame_alist;
 Lisp_Object Vdefault_frame_scroll_bars;
@@ -180,8 +187,6 @@
 Lisp_Object Vemacs_iconified;
 Lisp_Object Vframe_list;
 
-struct x_output tty_display;
-
 extern Lisp_Object Vminibuffer_list;
 extern Lisp_Object get_minibuffer ();
 extern Lisp_Object Fhandle_switch_frame ();
@@ -203,6 +208,7 @@
     return Qnil;
   switch (XFRAME (object)->output_method)
     {
+    case output_initial: /* The initial frame is like a termcap frame. */
     case output_termcap:
       return Qt;
     case output_x_window:
@@ -221,7 +227,7 @@
 DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
        doc: /* Return non-nil if OBJECT is a frame which has not been deleted.
 Value is nil if OBJECT is not a live frame.  If object is a live
-frame, the return value indicates what sort of output device it is
+frame, the return value indicates what sort of terminal device it is
 displayed on.  See the documentation of `framep' for possible
 return values.  */)
      (object)
@@ -233,6 +239,30 @@
          : Qnil);
 }
 
+DEFUN ("window-system", Fwindow_system, Swindow_system, 0, 1, 0,
+       doc: /* The name of the window system that FRAME is displaying through.
+The value is a symbol---for instance, 'x' for X windows.
+The value is nil if Emacs is using a text-only terminal.
+
+FRAME defaults to the currently selected frame.  */)
+  (frame)
+     Lisp_Object frame;
+{
+  Lisp_Object type;
+  if (NILP (frame))
+    frame = selected_frame;
+
+  type = Fframep (frame);
+
+  if (NILP (type))
+    wrong_type_argument (Qframep, frame);
+
+  if (EQ (type, Qt))
+    return Qnil;
+  else
+    return type;
+}      
+
 struct frame *
 make_frame (mini_p)
      int mini_p;
@@ -276,9 +306,7 @@
   f->menu_bar_items_used = 0;
   f->buffer_predicate = Qnil;
   f->buffer_list = Qnil;
-#ifdef MULTI_KBOARD
-  f->kboard = initial_kboard;
-#endif
+  f->buried_buffer_list = Qnil;
   f->namebuf = 0;
   f->title = Qnil;
   f->menu_bar_window = Qnil;
@@ -398,8 +426,8 @@
 
 #ifdef MULTI_KBOARD
   if (!NILP (mini_window)
-      && XFRAME (XWINDOW (mini_window)->frame)->kboard != kb)
-    error ("Frame and minibuffer must be on the same display");
+      && FRAME_KBOARD (XFRAME (XWINDOW (mini_window)->frame)) != kb)
+    error ("Frame and minibuffer must be on the same terminal");
 #endif
 
   /* Make a frame containing just a root window.  */
@@ -475,18 +503,19 @@
 }
 #endif /* HAVE_WINDOW_SYSTEM */
 
-/* Construct a frame that refers to the terminal (stdin and stdout).  */
+/* Construct a frame that refers to a terminal.  */
 
-static int terminal_frame_count;
+static int tty_frame_count;
 
 struct frame *
-make_terminal_frame ()
+make_initial_frame (void)
 {
-  register struct frame *f;
+  struct frame *f;
+  struct terminal *terminal;
   Lisp_Object frame;
-  char name[20];
 
 #ifdef MULTI_KBOARD
+  /* Create the initial keyboard. */
   if (!initial_kboard)
     {
       initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
@@ -500,13 +529,51 @@
   if (! (NILP (Vframe_list) || CONSP (Vframe_list)))
     Vframe_list = Qnil;
 
+  terminal = init_initial_terminal ();
+
+  f = make_frame (1);
+  XSETFRAME (frame, f);
+
+  Vframe_list = Fcons (frame, Vframe_list);
+
+  tty_frame_count = 1;
+  f->name = build_string ("F1");
+
+  f->visible = 1;
+  f->async_visible = 1;
+
+  f->output_method = terminal->type;
+  f->terminal = terminal;
+  f->terminal->reference_count++;
+  f->output_data.nothing = 0;
+  
+  FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
+  FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
+    
+  FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
+  FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
+
+  return f;
+}
+
+
+struct frame *
+make_terminal_frame (struct terminal *terminal)
+{
+  register struct frame *f;
+  Lisp_Object frame;
+  char name[20];
+
+  if (terminal->deleted)
+    error ("Terminal is being deleted, can't create new frames on it");
+
   f = make_frame (1);
 
   XSETFRAME (frame, f);
   Vframe_list = Fcons (frame, Vframe_list);
 
-  terminal_frame_count++;
-  sprintf (name, "F%d", terminal_frame_count);
+  tty_frame_count++;
+  sprintf (name, "F%d", tty_frame_count);
   f->name = build_string (name);
 
   f->visible = 1;              /* FRAME_SET_VISIBLE wd set frame_garbaged. */
@@ -526,11 +593,11 @@
         for the black color.  Other frames all inherit their pixels
         from what's already in the_only_x_display.  */
       if ((!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame)))
-         && f->output_data.x->background_pixel == 0
-         && f->output_data.x->foreground_pixel == 0)
+         && FRAME_BACKGROUND_PIXEL (f) == 0
+         && FRAME_FOREGROUND_PIXEL (f) == 0)
        {
-         f->output_data.x->background_pixel = FACE_TTY_DEFAULT_BG_COLOR;
-         f->output_data.x->foreground_pixel = FACE_TTY_DEFAULT_FG_COLOR;
+         FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
+         FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
        }
     }
   else
@@ -538,12 +605,33 @@
 #else
 #ifdef WINDOWSNT
   f->output_method = output_termcap;
-  f->output_data.x = &tty_display;
+  f->terminal = terminal;
+  f->terminal->reference_count++;
+  create_w32cons_output (f);
 #else
 #ifdef MAC_OS8
   make_mac_terminal_frame (f);
 #else
-  f->output_data.x = &tty_display;
+  {
+    f->output_method = output_termcap;
+    f->terminal = terminal;
+    f->terminal->reference_count++;
+    create_tty_output (f);
+    
+    FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
+    FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
+    
+    FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
+    FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
+
+    /* Set the top frame to the newly created frame. */
+    if (FRAME_TTY (f)->top_frame
+        && FRAME_LIVE_P (XFRAME (FRAME_TTY (f)->top_frame)))
+      XFRAME (FRAME_TTY (f)->top_frame)->async_visible = 2; /* obscured */
+    
+    FRAME_TTY (f)->top_frame = frame;
+  }
+  
 #ifdef CANNOT_DUMP
   FRAME_FOREGROUND_PIXEL(f) = FACE_TTY_DEFAULT_FG_COLOR;
   FRAME_BACKGROUND_PIXEL(f) = FACE_TTY_DEFAULT_BG_COLOR;
@@ -558,18 +646,55 @@
   return f;
 }
 
+/* Get a suitable value for frame parameter PARAMETER for a newly
+   created frame, based on (1) the user-supplied frame parameter
+   alist SUPPLIED_PARMS, (2) CURRENT_VALUE, and finally, if all else
+   fails, (3) Vdefault_frame_alist.  */
+
+static Lisp_Object
+get_future_frame_param (Lisp_Object parameter,
+                        Lisp_Object supplied_parms,
+                        char *current_value)
+{
+  Lisp_Object result;
+
+  result = Fassq (parameter, supplied_parms);
+  if (NILP (result))
+    result = Fassq (parameter, XFRAME (selected_frame)->param_alist);
+  if (NILP (result) && current_value != NULL)
+    result = build_string (current_value);
+  if (NILP (result))
+    result = Fassq (parameter, Vdefault_frame_alist);
+  if (!NILP (result) && !STRINGP (result))
+    result = XCDR (result);
+  if (NILP (result) || !STRINGP (result))
+    result = Qnil;
+
+  return result;
+}
+
 DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
        1, 1, 0,
-       doc: /* Create an additional terminal frame.
-You can create multiple frames on a text-only terminal in this way.
-Only the selected terminal frame is actually displayed.
+       doc: /* Create an additional terminal frame, possibly on another 
terminal.
 This function takes one argument, an alist specifying frame parameters.
-In practice, generally you don't need to specify any parameters.
-Note that changing the size of one terminal frame automatically affects all.  
*/)
+
+You can create multiple frames on a single text-only terminal, but
+only one of them (the selected terminal frame) is actually displayed.
+
+In practice, generally you don't need to specify any parameters,
+except when you want to create a new frame on another terminal.
+In that case, the `tty' parameter specifies the device file to open,
+and the `tty-type' parameter specifies the terminal type.  Example:
+
+   (make-terminal-frame '((tty . "/dev/pts/5") (tty-type . "xterm")))
+
+Note that changing the size of one terminal frame automatically
+affects all frames on the same terminal device.  */)
      (parms)
      Lisp_Object parms;
 {
   struct frame *f;
+  struct terminal *t = NULL;
   Lisp_Object frame, tem;
   struct frame *sf = SELECTED_FRAME ();
 
@@ -579,24 +704,83 @@
     abort ();
 #else /* not MSDOS */
 
-#ifdef MAC_OS
+#if 0 /* #ifdef MAC_OS */
+  /* This can happen for multi-tty when using both terminal frames and
+     Carbon frames. */
   if (sf->output_method != output_mac)
     error ("Not running on a Macintosh screen; cannot make a new Macintosh 
frame");
 #else
+#if 0                           /* This should work now! */
   if (sf->output_method != output_termcap)
     error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
 #endif
+#endif
 #endif /* not MSDOS */
 
-  f = make_terminal_frame ();
+  {
+    Lisp_Object terminal;
+
+    terminal = Fassq (Qterminal, parms);
+    if (!NILP (terminal))
+      {
+        terminal = XCDR (terminal);
+        t = get_terminal (terminal, 1);
+      }
+  }
+  
+  if (!t)
+    { 
+      char *name = 0, *type = 0;
+      Lisp_Object tty, tty_type;
+
+      tty = get_future_frame_param
+        (Qtty, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
+                       ? FRAME_TTY (XFRAME (selected_frame))->name
+                       : NULL));
+      if (!NILP (tty))
+        {
+          name = (char *) alloca (SBYTES (tty) + 1);
+          strncpy (name, SDATA (tty), SBYTES (tty));
+          name[SBYTES (tty)] = 0;
+        }
+      
+      tty_type = get_future_frame_param
+        (Qtty_type, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
+                            ? FRAME_TTY (XFRAME (selected_frame))->type
+                            : NULL));
+      if (!NILP (tty_type))
+        {
+          type = (char *) alloca (SBYTES (tty_type) + 1);
+          strncpy (type, SDATA (tty_type), SBYTES (tty_type));
+          type[SBYTES (tty_type)] = 0;
+        }
+
+      t = init_tty (name, type, 0); /* Errors are not fatal. */
+    }
+
+  f = make_terminal_frame (t);
+
+  {
+    int width, height;
+    get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
+    change_frame_size (f, height, width, 0, 0, 0);
+  }
 
-  change_frame_size (f, FRAME_LINES (sf),
-                    FRAME_COLS (sf), 0, 0, 0);
   adjust_glyphs (f);
   calculate_costs (f);
   XSETFRAME (frame, f);
   Fmodify_frame_parameters (frame, Vdefault_frame_alist);
   Fmodify_frame_parameters (frame, parms);
+  Fmodify_frame_parameters (frame, Fcons (Fcons (Qwindow_system, Qnil), Qnil));
+  Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty_type,
+                                                 build_string 
(t->display_info.tty->type)),
+                                          Qnil));
+  if (t->display_info.tty->name != NULL)
+    Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty,
+                                                   build_string 
(t->display_info.tty->name)),
+                                            Qnil));
+  else
+    Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty, Qnil), Qnil));
 
   /* Make the frame face alist be frame-specific, so that each
      frame could change its face definitions independently.  */
@@ -620,7 +804,7 @@
    frame's focus to FRAME instead.
 
    FOR_DELETION non-zero means that the selected frame is being
-   deleted, which includes the possibility that the frame's display
+   deleted, which includes the possibility that the frame's terminal
    is dead.  */
 
 Lisp_Object
@@ -695,6 +879,15 @@
   if (!for_deletion && FRAME_HAS_MINIBUF_P (sf))
     resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf)), 1);
 
+  if (FRAME_TERMCAP_P (XFRAME (selected_frame))
+      && FRAME_TERMCAP_P (XFRAME (frame))
+      && FRAME_TTY (XFRAME (selected_frame)) == FRAME_TTY (XFRAME (frame)))
+    {
+      XFRAME (selected_frame)->async_visible = 2; /* obscured */
+      XFRAME (frame)->async_visible = 1;
+      FRAME_TTY (XFRAME (frame))->top_frame = frame;
+    }
+
   selected_frame = frame;
   if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
     last_nonminibuf_frame = XFRAME (selected_frame);
@@ -879,6 +1072,7 @@
   return XFRAME (frame)->selected_window = window;
 }
 
+
 DEFUN ("frame-list", Fframe_list, Sframe_list,
        0, 0, 0,
        doc: /* Return a list of all frames.  */)
@@ -925,7 +1119,10 @@
        f = XCAR (tail);
 
        if (passed
+           && ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME 
(frame))
            && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
+                || (FRAME_TERMCAP_P (XFRAME (f)) && FRAME_TERMCAP_P (XFRAME 
(frame))
+                    && FRAME_TTY (XFRAME (f)) == FRAME_TTY (XFRAME (frame)))))
          {
            /* Decide whether this frame is eligible to be returned.  */
 
@@ -1002,7 +1199,10 @@
       if (EQ (frame, f) && !NILP (prev))
        return prev;
 
-      if (FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
+      if ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame))
+           && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
+          || (FRAME_TERMCAP_P (XFRAME (f)) && FRAME_TERMCAP_P (XFRAME (frame))
+              && FRAME_TTY (XFRAME (f)) == FRAME_TTY (XFRAME (frame))))
        {
          /* Decide whether this frame is eligible to be returned,
             according to minibuf.  */
@@ -1136,6 +1336,14 @@
   return 1;
 }
 
+/* Error handler for `delete-frame-functions'. */
+static Lisp_Object
+delete_frame_handler (Lisp_Object arg)
+{
+  add_to_log ("Error during `delete-frame': %s", arg, Qnil);
+  return Qnil;
+}
+
 DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
        doc: /* Delete FRAME, permanently eliminating it from use.
 If omitted, FRAME defaults to the selected frame.
@@ -1151,6 +1359,8 @@
 {
   struct frame *f;
   struct frame *sf = SELECTED_FRAME ();
+  struct kboard *kb;
+
   int minibuffer_selected;
 
   if (EQ (frame, Qnil))
@@ -1209,11 +1419,22 @@
       && NILP (Fframe_parameter (frame, intern ("tooltip"))))
     {
       Lisp_Object args[2];
+      struct gcpro gcpro1, gcpro2;
+
+      /* Don't let a rogue function in `delete-frame-functions'
+        prevent the frame deletion. */
+      GCPRO2 (args[0], args[1]);
       args[0] = intern ("delete-frame-functions");
       args[1] = frame;
-      Frun_hook_with_args (2, args);
+      internal_condition_case_2 (Frun_hook_with_args, 2, args,
+                                Qt, delete_frame_handler);
+      UNGCPRO;
     }
 
+  /* The hook may sometimes (indirectly) cause the frame to be deleted.  */
+  if (! FRAME_LIVE_P (f))
+    return Qnil;
+
   minibuffer_selected = EQ (minibuf_window, selected_window);
 
   /* Don't let the frame remain selected.  */
@@ -1229,7 +1450,7 @@
        {
          FOR_EACH_FRAME (tail, frame1)
            {
-             if (! EQ (frame, frame1))
+             if (! EQ (frame, frame1) && FRAME_LIVE_P (XFRAME (frame1)))
                break;
            }
        }
@@ -1255,6 +1476,24 @@
   if (EQ (f->minibuffer_window, echo_area_window))
     echo_area_window = sf->minibuffer_window;
 
+  /* Don't allow other frames to refer to a deleted frame in their
+     'environment parameter.  */
+  {
+    Lisp_Object tail, frame1;
+    Lisp_Object env = get_frame_param (XFRAME (frame), Qenvironment);
+    FOR_EACH_FRAME (tail, frame1)
+      {
+        if (EQ (frame, frame1) || !FRAME_LIVE_P (XFRAME (frame1)))
+          continue;
+        if (EQ (frame, get_frame_param (XFRAME (frame1), Qenvironment)))
+          {
+            store_frame_param (XFRAME (frame1), Qenvironment, env);
+            if (!FRAMEP (env))
+              env = frame1;
+          }
+      }
+  }
+  
   /* Clear any X selections for this frame.  */
 #ifdef HAVE_X_WINDOWS
   if (FRAME_X_P (f))
@@ -1295,18 +1534,36 @@
     xfree (FRAME_MESSAGE_BUF (f));
 
   /* Since some events are handled at the interrupt level, we may get
-     an event for f at any time; if we zero out the frame's display
+     an event for f at any time; if we zero out the frame's terminal
      now, then we may trip up the event-handling code.  Instead, we'll
-     promise that the display of the frame must be valid until we have
-     called the window-system-dependent frame destruction routine.  */
+     promise that the terminal of the frame must be valid until we
+     have called the window-system-dependent frame destruction
+     routine.  */
 
-  /* I think this should be done with a hook.  */
-#ifdef HAVE_WINDOW_SYSTEM
-  if (FRAME_WINDOW_P (f))
-    x_destroy_window (f);
-#endif
+  if (FRAME_TERMINAL (f)->delete_frame_hook)
+    (*FRAME_TERMINAL (f)->delete_frame_hook) (f);
 
+  {
+    struct terminal *terminal = FRAME_TERMINAL (f);
   f->output_data.nothing = 0;
+    f->terminal = 0;             /* Now the frame is dead. */
+
+    /* If needed, delete the terminal that this frame was on.
+       (This must be done after the frame is killed.) */
+    terminal->reference_count--;
+    if (terminal->reference_count == 0)
+      {
+        kb = NULL;
+        if (terminal->delete_terminal_hook)
+          (*terminal->delete_terminal_hook) (terminal);
+        else
+          delete_terminal (terminal);
+      }
+#ifdef MULTI_KBOARD
+    else
+      kb = terminal->kboard;
+#endif
+  }
 
   /* If we've deleted the last_nonminibuf_frame, then try to find
      another one.  */
@@ -1331,6 +1588,7 @@
 
   /* If there's no other frame on the same kboard, get out of
      single-kboard state if we're in it for this kboard.  */
+  if (kb != NULL)
   {
     Lisp_Object frames;
     /* Some frame we found on the same kboard, or nil if there are none.  */
@@ -1350,19 +1608,19 @@
          abort ();
        f1 = XFRAME (this);
 
-       if (FRAME_KBOARD (f) == FRAME_KBOARD (f1))
+         if (kb == FRAME_KBOARD (f1))
          frame_on_same_kboard = this;
       }
 
     if (NILP (frame_on_same_kboard))
-      not_single_kboard_state (FRAME_KBOARD (f));
+       not_single_kboard_state (kb);
   }
 
 
   /* If we've deleted this keyboard's default_minibuffer_frame, try to
      find another one.  Prefer minibuffer-only frames, but also notice
      frames with other windows.  */
-  if (EQ (frame, FRAME_KBOARD (f)->Vdefault_minibuffer_frame))
+  if (kb != NULL && EQ (frame, kb->Vdefault_minibuffer_frame))
     {
       Lisp_Object frames;
 
@@ -1388,7 +1646,7 @@
 
          /* Consider only frames on the same kboard
             and only those with minibuffers.  */
-         if (FRAME_KBOARD (f) == FRAME_KBOARD (f1)
+         if (kb == FRAME_KBOARD (f1)
              && FRAME_HAS_MINIBUF_P (f1))
            {
              frame_with_minibuf = this;
@@ -1396,7 +1654,7 @@
                break;
            }
 
-         if (FRAME_KBOARD (f) == FRAME_KBOARD (f1))
+         if (kb == FRAME_KBOARD (f1))
            frame_on_same_kboard = this;
        }
 
@@ -1411,11 +1669,11 @@
          if (NILP (frame_with_minibuf))
            abort ();
 
-         FRAME_KBOARD (f)->Vdefault_minibuffer_frame = frame_with_minibuf;
+         kb->Vdefault_minibuffer_frame = frame_with_minibuf;
        }
       else
        /* No frames left on this kboard--say no minibuffer either.  */
-       FRAME_KBOARD (f)->Vdefault_minibuffer_frame = Qnil;
+       kb->Vdefault_minibuffer_frame = Qnil;
     }
 
   /* Cause frame titles to update--necessary if we now have just one frame.  */
@@ -1452,8 +1710,8 @@
 
 #if defined (HAVE_MOUSE) || defined (HAVE_GPM)
   /* It's okay for the hook to refrain from storing anything.  */
-  if (mouse_position_hook)
-    (*mouse_position_hook) (&f, -1,
+  if (FRAME_TERMINAL (f)->mouse_position_hook)
+    (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, -1,
                            &lispy_dummy, &party_dummy,
                            &x, &y,
                            &long_dummy);
@@ -1496,8 +1754,8 @@
 
 #if defined (HAVE_MOUSE) || defined (HAVE_GPM)
   /* It's okay for the hook to refrain from storing anything.  */
-  if (mouse_position_hook)
-    (*mouse_position_hook) (&f, -1,
+  if (FRAME_TERMINAL (f)->mouse_position_hook)
+    (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, -1,
                            &lispy_dummy, &party_dummy,
                            &x, &y,
                            &long_dummy);
@@ -1787,16 +2045,19 @@
      (frame)
      Lisp_Object frame;
 {
+  struct frame *f;
   if (NILP (frame))
     frame = selected_frame;
 
   CHECK_LIVE_FRAME (frame);
 
+  f = XFRAME (frame);
+  
   /* Do like the documentation says. */
   Fmake_frame_visible (frame);
 
-  if (frame_raise_lower_hook)
-    (*frame_raise_lower_hook) (XFRAME (frame), 1);
+  if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
+    (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, 1);
 
   return Qnil;
 }
@@ -1810,13 +2071,17 @@
      (frame)
      Lisp_Object frame;
 {
+  struct frame *f;
+  
   if (NILP (frame))
     frame = selected_frame;
 
   CHECK_LIVE_FRAME (frame);
 
-  if (frame_raise_lower_hook)
-    (*frame_raise_lower_hook) (XFRAME (frame), 0);
+  f = XFRAME (frame);
+  
+  if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
+    (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, 0);
 
   return Qnil;
 }
@@ -1850,6 +2115,8 @@
      (frame, focus_frame)
      Lisp_Object frame, focus_frame;
 {
+  struct frame *f;
+  
   /* Note that we don't check for a live frame here.  It's reasonable
      to redirect the focus of a frame you're about to delete, if you
      know what other frame should receive those keystrokes.  */
@@ -1858,10 +2125,12 @@
   if (! NILP (focus_frame))
     CHECK_LIVE_FRAME (focus_frame);
 
-  XFRAME (frame)->focus_frame = focus_frame;
+  f = XFRAME (frame);
+  
+  f->focus_frame = focus_frame;
 
-  if (frame_rehighlight_hook)
-    (*frame_rehighlight_hook) (XFRAME (frame));
+  if (FRAME_TERMINAL (f)->frame_rehighlight_hook)
+    (*FRAME_TERMINAL (f)->frame_rehighlight_hook) (f);
 
   return Qnil;
 }
@@ -1923,7 +2192,7 @@
   XFRAME (frame)->buffer_list = list;
 }
 
-/* Discard BUFFER from the buffer-list of each frame.  */
+/* Discard BUFFER from the buffer-list and buried-buffer-list of each frame.  
*/
 
 void
 frames_discard_buffer (buffer)
@@ -1935,6 +2204,8 @@
     {
       XFRAME (frame)->buffer_list
        = Fdelq (buffer, XFRAME (frame)->buffer_list);
+      XFRAME (frame)->buried_buffer_list
+        = Fdelq (buffer, XFRAME (frame)->buried_buffer_list);
     }
 }
 
@@ -1993,8 +2264,8 @@
                            SBYTES (f->name)))
        return;
 
-      terminal_frame_count++;
-      sprintf (namebuf, "F%d", terminal_frame_count);
+      tty_frame_count++;
+      sprintf (namebuf, "F%d", tty_frame_count);
       name = build_string (namebuf);
     }
   else
@@ -2022,13 +2293,18 @@
 {
   register Lisp_Object old_alist_elt;
 
-  /* The buffer-alist parameter is stored in a special place and is
-     not in the alist.  */
+  /* The buffer-list parameters are stored in a special place and not
+     in the alist.  */
   if (EQ (prop, Qbuffer_list))
     {
       f->buffer_list = val;
       return;
     }
+  if (EQ (prop, Qburied_buffer_list))
+    {
+      f->buried_buffer_list = val;
+      return;
+    }
 
   /* If PROP is a symbol which is supposed to have frame-local values,
      and it is set up based on this frame, switch to the global
@@ -2041,6 +2317,7 @@
       if ((BUFFER_LOCAL_VALUEP (valcontents)
           || SOME_BUFFER_LOCAL_VALUEP (valcontents))
          && XBUFFER_LOCAL_VALUE (valcontents)->check_frame
+         && XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame
          && XFRAME (XBUFFER_LOCAL_VALUE (valcontents)->frame) == f)
        swap_in_global_binding (prop);
     }
@@ -2168,6 +2445,7 @@
                   : FRAME_MINIBUF_WINDOW (f)));
   store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
   store_in_alist (&alist, Qbuffer_list, frame_buffer_list (frame));
+  store_in_alist (&alist, Qburied_buffer_list, XFRAME 
(frame)->buried_buffer_list);
 
   /* I think this should be done with a hook.  */
 #ifdef HAVE_WINDOW_SYSTEM
@@ -2335,10 +2613,45 @@
            call1 (Qframe_set_background_mode, frame);
        }
     }
+}
 
-  return Qnil;
+DEFUN ("frame-with-environment", Fframe_with_environment, 
Sframe_with_environment, 0, 1, 0,
+       doc: /* Return the frame that has the environment variable list for 
FRAME.
+
+The frame-local environment variable list is normally shared between
+frames that were created in the same Emacsclient session.  The
+environment list is stored in a single frame's 'environment parameter;
+the other frames' 'environment parameter is set to this frame.  This
+function follows the chain of 'environment references to reach the
+frame that stores the actual local environment list, and returns that
+frame.  */)
+     (frame)
+     Lisp_Object frame;
+{
+  Lisp_Object hare, tortoise;
+
+  if (NILP (frame))
+    frame = selected_frame;
+  CHECK_FRAME (frame);
+
+  hare = tortoise = get_frame_param (XFRAME (frame), Qenvironment);
+  while (!NILP (hare) && FRAMEP (hare))
+    {
+      frame = hare;
+      hare = get_frame_param (XFRAME (hare), Qenvironment);
+      if (NILP (hare) || !FRAMEP (hare))
+        break;
+      frame = hare;
+      hare = get_frame_param (XFRAME (hare), Qenvironment);
+      tortoise = get_frame_param (XFRAME (tortoise), Qenvironment);
+      if (EQ (hare, tortoise))
+        error ("Cyclic frame-local environment indirection");
+    }
+
+  return frame;
 }
 
+
 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
        0, 1, 0,
        doc: /* Height in pixels of a line in the font in frame FRAME.
@@ -2754,9 +3067,8 @@
              if (NATNUMP (param_index)
                  && (XFASTINT (param_index)
                      < sizeof (frame_parms)/sizeof (frame_parms[0]))
-                 && rif->frame_parm_handlers[XINT (param_index)])
-               (*(rif->frame_parm_handlers[XINT (param_index)])) (f, val, 
old_value);
-
+                  && FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])
+                (*(FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])) 
(f, val, old_value);
              unbind_to (count, Qnil);
            }
        }
@@ -2800,8 +3112,8 @@
          if (NATNUMP (param_index)
              && (XFASTINT (param_index)
                  < sizeof (frame_parms)/sizeof (frame_parms[0]))
-             && rif->frame_parm_handlers[XINT (param_index)])
-           (*(rif->frame_parm_handlers[XINT (param_index)])) (f, val, 
old_value);
+             && FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])
+           (*(FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])) (f, 
val, old_value);
        }
     }
 
@@ -3039,8 +3351,8 @@
   else if (EQ (new_value, Qfullheight))
     f->want_fullscreen = FULLSCREEN_HEIGHT;
 
-  if (fullscreen_hook != NULL) 
-    fullscreen_hook (f);
+  if (FRAME_TERMINAL (f)->fullscreen_hook != NULL) 
+    FRAME_TERMINAL (f)->fullscreen_hook (f);
 }
 
 
@@ -3089,8 +3401,8 @@
       if (NATNUMP (index)
          && (XFASTINT (index)
              < sizeof (frame_parms)/sizeof (frame_parms[0]))
-         && rif->frame_parm_handlers[XFASTINT (index)])
-       (*(rif->frame_parm_handlers[XFASTINT (index)]))
+         && FRAME_RIF (f)->frame_parm_handlers[XFASTINT (index)])
+         (*FRAME_RIF (f)->frame_parm_handlers[XFASTINT (index)])
          (f, bgcolor, Qnil);
     }
 
@@ -4027,12 +4339,27 @@
   staticpro (&Qbuffer_predicate);
   Qbuffer_list = intern ("buffer-list");
   staticpro (&Qbuffer_list);
+  Qburied_buffer_list = intern ("buried-buffer-list");
+  staticpro (&Qburied_buffer_list);
   Qdisplay_type = intern ("display-type");
   staticpro (&Qdisplay_type);
   Qbackground_mode = intern ("background-mode");
   staticpro (&Qbackground_mode);
   Qtty_color_mode = intern ("tty-color-mode");
   staticpro (&Qtty_color_mode);
+  Qtty = intern ("tty");
+  staticpro (&Qtty);
+  Qtty_type = intern ("tty-type");
+  staticpro (&Qtty_type);
+  Qwindow_system = intern ("window-system");
+  staticpro (&Qwindow_system);
+  Qenvironment = intern ("environment");
+  staticpro (&Qenvironment);
+
+  Qterm_environment_variable = intern ("term-environment-variable");
+  staticpro (&Qterm_environment_variable);
+  Qdisplay_environment_variable = intern ("display-environment-variable");
+  staticpro (&Qdisplay_environment_variable);
 
   Qface_set_after_frame_default = intern ("face-set-after-frame-default");
   staticpro (&Qface_set_after_frame_default);
@@ -4053,6 +4380,11 @@
   Qx_frame_parameter = intern ("x-frame-parameter");
   staticpro (&Qx_frame_parameter);
 
+  Qterminal = intern ("terminal");
+  staticpro (&Qterminal);
+  Qterminal_live_p = intern ("terminal-live-p");
+  staticpro (&Qterminal_live_p);
+  
   {
     int i;
 
@@ -4101,6 +4433,7 @@
 These override values given in window system configuration data,
  including X Windows' defaults database.
 For values specific to the first Emacs frame, see `initial-frame-alist'.
+For window-system specific values, see `window-system-default-frame-alist'.
 For values specific to the separate minibuffer frame, see
  `minibuffer-frame-alist'.
 The `menu-bar-lines' element of the list controls whether new frames
@@ -4147,7 +4480,14 @@
   DEFVAR_LISP ("delete-frame-functions", &Vdelete_frame_functions,
               doc: /* Functions to be run before deleting a frame.
 The functions are run with one arg, the frame to be deleted.
-See `delete-frame'.  */);
+See `delete-frame'.
+
+Note that functions in this list may be called twice on the same
+frame.  In the second invocation, the frame is already deleted, and
+the function should do nothing.  (You can use `frame-live-p' to check
+for this.)  This wrinkle happens when an earlier function in
+`delete-frame-functions' (indirectly) calls delete-frame
+recursively.  */);
   Vdelete_frame_functions = Qnil;
 
   DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
@@ -4170,6 +4510,7 @@
   defsubr (&Sactive_minibuffer_window);
   defsubr (&Sframep);
   defsubr (&Sframe_live_p);
+  defsubr (&Swindow_system);
   defsubr (&Smake_terminal_frame);
   defsubr (&Shandle_switch_frame);
   defsubr (&Sselect_frame);
@@ -4203,6 +4544,7 @@
   defsubr (&Sframe_parameters);
   defsubr (&Sframe_parameter);
   defsubr (&Smodify_frame_parameters);
+  defsubr (&Sframe_with_environment);
   defsubr (&Sframe_char_height);
   defsubr (&Sframe_char_width);
   defsubr (&Sframe_pixel_height);




reply via email to

[Prev in Thread] Current Thread [Next in Thread]