]> code.delx.au - gnu-emacs/blobdiff - src/dispnew.c
Reword header comment to prevent copyright.el wanting to update years.
[gnu-emacs] / src / dispnew.c
index d95ce7c39e7b752cc8a3094407b1ff96a851e0a9..ba50b001980c6220d8732d979590cb75dda2c56c 100644 (file)
@@ -1,7 +1,7 @@
 /* Updating of data structures for redisplay.
    Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
                  1997, 1998, 1999, 2000, 2001, 2002, 2003,
-                 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+                 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -22,6 +22,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <signal.h>
 #include <stdio.h>
 #include <ctype.h>
+#include <setjmp.h>
 
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
@@ -59,10 +60,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "w32term.h"
 #endif /* HAVE_NTGUI */
 
-#ifdef MAC_OS
-#include "macterm.h"
-#endif /* MAC_OS */
-
 #ifdef HAVE_NS
 #include "nsterm.h"
 #endif
@@ -3394,7 +3391,7 @@ DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, 0,
   update_begin (f);
 #ifdef MSDOS
   if (FRAME_MSDOS_P (f))
-    set_terminal_modes (FRAME_TERMINAL (f));
+    FRAME_TERMINAL (f)->set_terminal_modes_hook (FRAME_TERMINAL (f));
 #endif
   clear_frame (f);
   clear_current_matrices (f);
@@ -3958,11 +3955,12 @@ update_frame (f, force_p, inhibit_hairy_id_p)
       paused_p = update_frame_1 (f, force_p, inhibit_hairy_id_p);
       update_end (f);
 
-      if (FRAME_TERMCAP_P (f))
+      if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
         {
           if (FRAME_TTY (f)->termscript)
             fflush (FRAME_TTY (f)->termscript);
-          fflush (FRAME_TTY (f)->output);
+         if (FRAME_TERMCAP_P (f))
+           fflush (FRAME_TTY (f)->output);
         }
 
       /* Check window matrices for lost pointers.  */
@@ -4132,14 +4130,14 @@ redraw_overlapping_rows (w, yb)
 
       bottom_y = MATRIX_ROW_BOTTOM_Y (row);
 
-      if (row->overlapping_p && i > 0 && bottom_y < yb)
+      if (row->overlapping_p)
        {
          int overlaps = 0;
 
-         if (MATRIX_ROW_OVERLAPS_PRED_P (row)
+         if (MATRIX_ROW_OVERLAPS_PRED_P (row) && i > 0
              && !MATRIX_ROW (w->current_matrix, i - 1)->overlapped_p)
            overlaps |= OVERLAPS_PRED;
-         if (MATRIX_ROW_OVERLAPS_SUCC_P (row)
+         if (MATRIX_ROW_OVERLAPS_SUCC_P (row) && bottom_y < yb
              && !MATRIX_ROW (w->current_matrix, i + 1)->overlapped_p)
            overlaps |= OVERLAPS_SUCC;
 
@@ -4478,6 +4476,7 @@ update_text_area (w, vpos)
       struct glyph *desired_glyph = desired_row->glyphs[TEXT_AREA];
       int overlapping_glyphs_p = current_row->contains_overlapping_glyphs_p;
       int desired_stop_pos = desired_row->used[TEXT_AREA];
+      int abort_skipping = 0;
 
       /* If the desired row extends its face to the text area end, and
         unless the current row also does so at the same position,
@@ -4497,7 +4496,7 @@ update_text_area (w, vpos)
         in common.  */
       while (i < stop)
        {
-         int can_skip_p = 1;
+         int can_skip_p = !abort_skipping;
 
          /* Skip over glyphs that both rows have in common.  These
             don't have to be written.  We can't skip if the last
@@ -4514,11 +4513,13 @@ update_text_area (w, vpos)
 
              rif->get_glyph_overhangs (glyph, XFRAME (w->frame),
                                        &left, &right);
-             can_skip_p = right == 0;
+             can_skip_p = (right == 0 && !abort_skipping);
            }
 
          if (can_skip_p)
            {
+             int start_hpos = i;
+
              while (i < stop
                     && GLYPH_EQUAL_P (desired_glyph, current_glyph))
                {
@@ -4550,6 +4551,12 @@ update_text_area (w, vpos)
                      x -= desired_glyph->pixel_width;
                      left -= desired_glyph->pixel_width;
                    }
+
+                 /* Abort the skipping algorithm if we end up before
+                    our starting point, to avoid looping (bug#1070).
+                    This can happen when the lbearing is larger than
+                    the pixel width.  */
+                 abort_skipping = (i < start_hpos);
                }
            }
 
@@ -5927,7 +5934,7 @@ buffer_posn_from_coords (w, x, y, pos, object, dx, dy, width, height)
      int *width, *height;
 {
   struct it it;
-  struct buffer *old_current_buffer = current_buffer;
+  Lisp_Object old_current_buffer = Fcurrent_buffer ();
   struct text_pos startp;
   Lisp_Object string;
   struct glyph_row *row;
@@ -5936,7 +5943,9 @@ buffer_posn_from_coords (w, x, y, pos, object, dx, dy, width, height)
 #endif
   int x0, x1;
 
-  current_buffer = XBUFFER (w->buffer);
+  /* We used to set current_buffer directly here, but that does the
+     wrong thing with `face-remapping-alist' (bug#2044).  */
+  Fset_buffer (w->buffer);
   SET_TEXT_POS_FROM_MARKER (startp, w->start);
   CHARPOS (startp) = min (ZV, max (BEGV, CHARPOS (startp)));
   BYTEPOS (startp) = min (ZV_BYTE, max (BEGV_BYTE, BYTEPOS (startp)));
@@ -5946,7 +5955,7 @@ buffer_posn_from_coords (w, x, y, pos, object, dx, dy, width, height)
   move_it_to (&it, -1, x0 + it.first_visible_x, *y, -1,
              MOVE_TO_X | MOVE_TO_Y);
 
-  current_buffer = old_current_buffer;
+  Fset_buffer (old_current_buffer);
 
   *dx = x0 + it.first_visible_x - it.current_x;
   *dy = *y - it.current_y;
@@ -6210,6 +6219,11 @@ window_change_signal (signalnum) /* If we don't have an argument, */
     if (! tty->term_initted)
       continue;
 
+    /* Suspended tty frames have tty->input == NULL avoid trying to
+       use it.  */
+    if (!tty->input)
+      continue;
+
     get_tty_size (fileno (tty->input), &width, &height);
 
     if (width > 5 && height > 2) {
@@ -6360,7 +6374,9 @@ change_frame_size_1 (f, newheight, newwidth, pretend, delay, safe)
        set_window_height (FRAME_ROOT_WINDOW (f),
                           newheight - FRAME_TOP_MARGIN (f), 2);
 
-      if (FRAME_TERMCAP_P (f) && !pretend)
+      /* MSDOS frames cannot PRETEND, as they change frame size by
+        manipulating video hardware.  */
+      if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
        FrameRows (FRAME_TTY (f)) = newheight;
     }
 
@@ -6370,7 +6386,9 @@ change_frame_size_1 (f, newheight, newwidth, pretend, delay, safe)
       if (FRAME_HAS_MINIBUF_P (f))
        set_window_width (FRAME_MINIBUF_WINDOW (f), new_frame_total_cols, 0);
 
-      if (FRAME_TERMCAP_P (f) && !pretend)
+      /* MSDOS frames cannot PRETEND, as they change frame size by
+        manipulating video hardware.  */
+      if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
        FrameCols (FRAME_TTY (f)) = newwidth;
 
       if (WINDOWP (f->tool_bar_window))
@@ -6421,7 +6439,8 @@ FILE = nil means just close any termscript file currently open.  */)
 {
   struct tty_display_info *tty;
 
-  if (! FRAME_TERMCAP_P (SELECTED_FRAME ()))
+  if (! FRAME_TERMCAP_P (SELECTED_FRAME ())
+      && ! FRAME_MSDOS_P (SELECTED_FRAME ()))
     error ("Current frame is not on a tty device");
 
   tty = CURTTY ();
@@ -6451,14 +6470,15 @@ DEFUN ("send-string-to-terminal", Fsend_string_to_terminal,
 Control characters in STRING will have terminal-dependent effects.
 
 Optional parameter TERMINAL specifies the tty terminal device to use.
-It may be a terminal id, a frame, or nil for the terminal used by the
-currently selected frame.  */)
+It may be a terminal object, a frame, or nil for the terminal used by
+the currently selected frame.  In batch mode, STRING is sent to stdout
+when TERMINAL is nil.  */)
   (string, terminal)
      Lisp_Object string;
      Lisp_Object terminal;
 {
-  struct terminal *t = get_tty_terminal (terminal, 1);
-  struct tty_display_info *tty;
+  struct terminal *t = get_terminal (terminal, 1);
+  FILE *out;
 
   /* ??? Perhaps we should do something special for multibyte strings here.  */
   CHECK_STRING (string);
@@ -6467,15 +6487,26 @@ currently selected frame.  */)
   if (!t)
     error ("Unknown terminal device");
 
-  tty = t->display_info.tty;
-
-  if (tty->termscript)
+  if (t->type == output_initial)
+    out = stdout;
+  else if (t->type != output_termcap && t->type != output_msdos_raw)
+    error ("Device %d is not a termcap terminal device", t->id);
+  else
     {
-      fwrite (SDATA (string), 1, SBYTES (string), tty->termscript);
-      fflush (tty->termscript);
+      struct tty_display_info *tty = t->display_info.tty;
+
+      if (! tty->output)
+       error ("Terminal is currently suspended");
+
+      if (tty->termscript)
+       {
+         fwrite (SDATA (string), 1, SBYTES (string), tty->termscript);
+         fflush (tty->termscript);
+       }
+      out = tty->output;
     }
-  fwrite (SDATA (string), 1, SBYTES (string), tty->output);
-  fflush (tty->output);
+  fwrite (SDATA (string), 1, SBYTES (string), out);
+  fflush (out);
   UNBLOCK_INPUT;
   return Qnil;
 }
@@ -6828,6 +6859,10 @@ init_display ()
     signal (SIGWINCH, window_change_signal);
 #endif /* SIGWINCH */
 
+  /* If running as a daemon, no need to initialize any frames/terminal. */
+  if (IS_DAEMON)
+      return;
+
   /* If the user wants to use a window system, we shouldn't bother
      initializing the terminal.  This is especially important when the
      terminal is so dumb that emacs gives up before and doesn't bother
@@ -6840,12 +6875,7 @@ init_display ()
   if (! inhibit_window_system && ! display_arg)
     {
       char *display;
-#ifdef VMS
-      display = getenv ("DECW$DISPLAY");
-#else
       display = getenv ("DISPLAY");
-#endif
-
       display_arg = (display != 0 && *display != 0);
 
       if (display_arg && !x_display_ok (display))
@@ -6862,11 +6892,9 @@ init_display ()
 #endif
      )
     {
-      Vinitial_window_system = intern ("x");
+      Vinitial_window_system = Qx;
 #ifdef HAVE_X11
       Vwindow_system_version = make_number (11);
-#else
-      Vwindow_system_version = make_number (10);
 #endif
 #if defined (GNU_LINUX) && defined (HAVE_LIBNCURSES)
       /* In some versions of ncurses,
@@ -6882,23 +6910,13 @@ init_display ()
 #ifdef HAVE_NTGUI
   if (!inhibit_window_system)
     {
-      Vinitial_window_system = intern ("w32");
+      Vinitial_window_system = Qw32;
       Vwindow_system_version = make_number (1);
       adjust_frame_glyphs_initially ();
       return;
     }
 #endif /* HAVE_NTGUI */
 
-#ifdef MAC_OS
-  if (!inhibit_window_system)
-    {
-      Vinitial_window_system = intern ("mac");
-      Vwindow_system_version = make_number (1);
-      adjust_frame_glyphs_initially ();
-      return;
-    }
-#endif /* MAC_OS */
-
 #ifdef HAVE_NS
   if (!inhibit_window_system
 #ifndef CANNOT_DUMP
@@ -6906,7 +6924,7 @@ init_display ()
 #endif
       )
     {
-      Vinitial_window_system = intern("ns");
+      Vinitial_window_system = Qns;
       Vwindow_system_version = make_number(10);
       adjust_frame_glyphs_initially ();
       return;
@@ -6928,40 +6946,15 @@ init_display ()
 #endif
   if (!terminal_type)
     {
-#ifdef VMS
-      fprintf (stderr, "Please specify your terminal type.\n\
-For types defined in VMS, use  set term /device=TYPE.\n\
-For types not defined in VMS, use  define emacs_term \"TYPE\".\n\
-\(The quotation marks are necessary since terminal types are lower case.)\n");
-#else /* not VMS */
-
 #ifdef HAVE_WINDOW_SYSTEM
       if (! inhibit_window_system)
        fprintf (stderr, "Please set the environment variable DISPLAY or TERM (see `tset').\n");
       else
 #endif /* HAVE_WINDOW_SYSTEM */
        fprintf (stderr, "Please set the environment variable TERM; see `tset'.\n");
-#endif /* not VMS */
       exit (1);
     }
 
-#ifdef VMS
-  /* VMS DCL tends to up-case things, so down-case term type.
-     Hardly any uppercase letters in terminal types; should be none.  */
-  {
-    char *new = (char *) xmalloc (strlen (terminal_type) + 1);
-    char *p;
-
-    strcpy (new, terminal_type);
-
-    for (p = new; *p; p++)
-      if (isupper (*p))
-       *p = tolower (*p);
-
-    terminal_type = new;
-  }
-#endif /* VMS */
-
   {
     struct terminal *t;
     struct frame *f = XFRAME (selected_frame);
@@ -6990,7 +6983,13 @@ For types not defined in VMS, use  define emacs_term \"TYPE\".\n\
     Fmodify_frame_parameters
       (selected_frame, Fcons (Fcons (Qtty_type,
                                      Ftty_type (selected_frame)), Qnil));
-    Fmodify_frame_parameters (selected_frame, Fcons (Fcons (Qtty, Qnil), Qnil));
+    if (t->display_info.tty->name)
+      Fmodify_frame_parameters (selected_frame,
+                               Fcons (Fcons (Qtty, build_string (t->display_info.tty->name)),
+                                      Qnil));
+    else
+      Fmodify_frame_parameters (selected_frame, Fcons (Fcons (Qtty, Qnil),
+                                                      Qnil));
   }
 
   {
@@ -7012,13 +7011,6 @@ For types not defined in VMS, use  define emacs_term \"TYPE\".\n\
   /* Set up faces of the initial terminal frame of a dumped Emacs.  */
   if (initialized
       && !noninteractive
-#ifdef MSDOS
-      /* The MSDOS terminal turns on its ``window system'' relatively
-        late into the startup, so we cannot do the frame faces'
-        initialization just yet.  It will be done later by pc-win.el
-        and internal_terminal_init.  */
-      && (strcmp (terminal_type, "internal") != 0 || inhibit_window_system)
-#endif
       && NILP (Vinitial_window_system))
     {
       /* For the initial frame, we don't have any way of knowing what