Don't globally add to change-major-mode-hook.
[bpt/emacs.git] / src / dispnew.c
index 388bae2..ad7ed32 100644 (file)
@@ -34,6 +34,7 @@ Boston, MA 02111-1307, USA.  */
 #include "dispextern.h"
 #include "cm.h"
 #include "buffer.h"
+#include "charset.h"
 #include "frame.h"
 #include "window.h"
 #include "commands.h"
@@ -42,7 +43,9 @@ Boston, MA 02111-1307, USA.  */
 #include "intervals.h"
 #include "blockinput.h"
 
-#include "systty.h"
+/* I don't know why DEC Alpha OSF1 fail to compile this file if we
+   include the following file.  */
+/* #include "systty.h" */
 #include "syssignal.h"
 
 #ifdef HAVE_X_WINDOWS
@@ -346,7 +349,7 @@ remake_frame_glyphs (frame)
 
       FRAME_MESSAGE_BUF (frame)
        = (char *) xrealloc (FRAME_MESSAGE_BUF (frame),
-                            FRAME_WIDTH (frame) + 1);
+                            FRAME_MESSAGE_BUF_SIZE (frame) + 1);
 
       if (echo_area_glyphs == old_message_buf)
        echo_area_glyphs = FRAME_MESSAGE_BUF (frame);
@@ -355,7 +358,7 @@ remake_frame_glyphs (frame)
     }
   else
     FRAME_MESSAGE_BUF (frame)
-      = (char *) xmalloc (FRAME_WIDTH (frame) + 1);
+      = (char *) xmalloc (FRAME_MESSAGE_BUF_SIZE (frame) + 1);
 
   FRAME_CURRENT_GLYPHS (frame) = make_frame_glyphs (frame, 0);
   FRAME_DESIRED_GLYPHS (frame) = make_frame_glyphs (frame, 0);
@@ -1114,18 +1117,29 @@ direct_output_forward_char (n)
   register FRAME_PTR frame = selected_frame;
   register struct window *w = XWINDOW (selected_window);
   Lisp_Object position;
+  /* This check is redundant.  It's checked at "losing cursor" below.  */
+#if 0
   int hpos = FRAME_CURSOR_X (frame);
 
   /* Give up if in truncated text at end of line.  */
   if (hpos >= WINDOW_LEFT_MARGIN (w) + window_internal_width (w) - 1)
     return 0;
+#endif /* 0 */
+
+  /* Give up if the buffer's direction is reversed (i.e. right-to-left).  */
+  if (!NILP (XBUFFER(w->buffer)->direction_reversed))
+    return 0;
 
   /* Avoid losing if cursor is in invisible text off left margin
      or about to go off either side of window.  */
   if ((FRAME_CURSOR_X (frame) == WINDOW_LEFT_MARGIN (w)
        && (XINT (w->hscroll) || n < 0))
       || (n > 0
-         && (FRAME_CURSOR_X (frame) + 1 >= window_internal_width (w) - 1))
+         && (FRAME_CURSOR_X (frame) + 1 
+             >= XFASTINT (w->left) + window_internal_width (w) - 1))
+      /* BUG FIX: Added "XFASTINT (w->left)".  Without this,
+        direct_output_forward_char() always fails on "the right"
+        window.  */
       || cursor_in_echo_area)
     return 0;
 
@@ -1414,9 +1428,17 @@ scrolling (frame)
        return 0;
       old_hash[i] = line_hash_code (current_frame, i);
       if (! desired_frame->enable[i])
-       new_hash[i] = old_hash[i];
+       {
+         /* This line cannot be redrawn, so don't let scrolling mess it.  */
+         new_hash[i] = old_hash[i];
+#define INFINITY 1000000       /* Taken from scroll.c */
+         draw_cost[i] = INFINITY;
+       }
       else
-       new_hash[i] = line_hash_code (desired_frame, i);
+       {
+         new_hash[i] = line_hash_code (desired_frame, i);
+         draw_cost[i] = line_draw_cost (desired_frame, i);
+       }
 
       if (old_hash[i] != new_hash[i])
        {
@@ -1425,7 +1447,6 @@ scrolling (frame)
        }
       else if (i == unchanged_at_top)
        unchanged_at_top++;
-      draw_cost[i] = line_draw_cost (desired_frame, i);
       old_draw_cost[i] = line_draw_cost (current_frame, i);
     }
 
@@ -1547,7 +1568,7 @@ update_line (frame, vpos)
   int *temp1;
   int tem;
   int osp, nsp, begmatch, endmatch, olen, nlen;
-  int save;
+  GLYPH save;
   register struct frame_glyphs *current_frame
     = FRAME_CURRENT_GLYPHS (frame);
   register struct frame_glyphs *desired_frame
@@ -1663,8 +1684,10 @@ update_line (frame, vpos)
          if (i >= olen || nbody[i] != obody[i])    /* A non-matching char. */
            {
              cursor_to (vpos, i);
-             for (j = 1; (i + j < nlen &&
-                          (i + j >= olen || nbody[i+j] != obody[i+j]));
+             for (j = 1;
+                  (i + j < nlen
+                   && (i + j >= olen || nbody[i + j] != obody[i + j]
+                       || (nbody[i + j] & GLYPH_MASK_PADDING)));
                   j++);
 
              /* Output this run of non-matching chars.  */ 
@@ -1851,8 +1874,24 @@ update_line (frame, vpos)
        }
       else if (nlen > olen)
        {
-         write_glyphs (nbody + nsp + begmatch, olen - tem);
-         insert_glyphs (nbody + nsp + begmatch + olen - tem, nlen - olen);
+         /* Here, we used to have the following simple code:
+            ----------------------------------------
+            write_glyphs (nbody + nsp + begmatch, olen - tem);
+            insert_glyphs (nbody + nsp + begmatch + olen - tem, nlen - olen);
+            ----------------------------------------
+            but it doesn't work if nbody[nsp + begmatch + olen - tem]
+            is a padding glyph.  */
+         int out = olen - tem; /* Columns to be overwritten originally.  */
+         int del;
+
+         /* Calculate columns we can actually overwrite.  */
+         while (nbody[nsp + begmatch + out] & GLYPH_MASK_PADDING) out--;
+         write_glyphs (nbody + nsp + begmatch, out);
+         /* If we left columns to be overwritten. we must delete them.  */
+         del = olen - tem - out;
+         if (del > 0) delete_glyphs (del);
+         /* At last, we insert columns not yet written out.  */
+         insert_glyphs (nbody + nsp + begmatch + out, nlen - olen + del);
          olen = nlen;
        }
       else if (olen > nlen)
@@ -1929,7 +1968,7 @@ the current state.\n")
        goto changed;
     }
   /* Detect deletion of a buffer at the end of the list.  */
-  if (*vecp == Qlambda)
+  if (EQ (*vecp, Qlambda))
     return Qnil;
  changed:
   /* Start with 1 so there is room for at least one lambda at the end.  */
@@ -2067,6 +2106,7 @@ change_frame_size (f, newheight, newwidth, pretend, delay)
      int newheight, newwidth, pretend;
 {
   Lisp_Object tail, frame;
+
   if (! FRAME_WINDOW_P (f))
     {
       /* When using termcap, or on MS-DOS, all frames use
@@ -2086,6 +2126,8 @@ change_frame_size_1 (frame, newheight, newwidth, pretend, delay)
      int newheight, newwidth, pretend, delay;
 {
   int new_frame_window_width;
+  unsigned int total_glyphs;
+
   /* If we can't deal with the change now, queue it for later.  */
   if (delay)
     {
@@ -2106,6 +2148,13 @@ change_frame_size_1 (frame, newheight, newwidth, pretend, delay)
     newwidth  = FRAME_WIDTH  (frame);
   new_frame_window_width = FRAME_WINDOW_WIDTH_ARG (frame, newwidth);
 
+  total_glyphs = newheight * (newwidth + 2) * sizeof (GLYPH);
+
+  /* If these sizes are so big they cause overflow,
+     just ignore the change.  It's not clear what better we could do.  */
+  if (total_glyphs / sizeof (GLYPH) / newheight != newwidth + 2)
+    return;
+
   /* Round up to the smallest acceptable size.  */
   check_frame_size (frame, &newheight, &newwidth);
 
@@ -2183,6 +2232,10 @@ change_frame_size_1 (frame, newheight, newwidth, pretend, delay)
   calculate_costs (frame);
 
   UNBLOCK_INPUT;
+
+  /* This isn't quite a no-op: it runs window-configuration-change-hook.  */
+  Fset_window_buffer (FRAME_SELECTED_WINDOW (frame),
+                     XWINDOW (FRAME_SELECTED_WINDOW (frame))->buffer);
 }
 \f
 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal,
@@ -2335,8 +2388,8 @@ Emacs was built without floating point support.\n\
    waiting for input as well.  */
 
 Lisp_Object
-sit_for (sec, usec, reading, display)
-     int sec, usec, reading, display;
+sit_for (sec, usec, reading, display, initial_display)
+     int sec, usec, reading, display, initial_display;
 {
   Lisp_Object read_kbd;
 
@@ -2345,7 +2398,7 @@ sit_for (sec, usec, reading, display)
   if (detect_input_pending_run_timers (display))
     return Qnil;
 
-  if (display)
+  if (initial_display)
     redisplay_preserve_echo_area ();
 
   if (sec == 0 && usec == 0)
@@ -2358,32 +2411,6 @@ sit_for (sec, usec, reading, display)
   XSETINT (read_kbd, reading ? -1 : 1);
   wait_reading_process_input (sec, usec, read_kbd, display);
 
-
-  /* wait_reading_process_input should always be available now; it is
-     simulated in a simple way on systems that don't support
-     subprocesses.  */
-#if 0
-  /* No wait_reading_process_input available.  */
-  immediate_quit = 1;
-  QUIT;
-
-  waitchannels = 1;
-#ifdef VMS
-  input_wait_timeout (XINT (arg));
-#else                          /* not VMS */
-#ifndef HAVE_TIMEVAL
-  timeout_sec = sec;
-  select (1, &waitchannels, 0, 0, &timeout_sec);
-#else /* HAVE_TIMEVAL */
-  timeout.tv_sec = sec;  
-  timeout.tv_usec = usec;
-  select (1, &waitchannels, 0, 0, &timeout);
-#endif /* HAVE_TIMEVAL */
-#endif /* not VMS */
-
-  immediate_quit = 0;
-#endif 
-
   return detect_input_pending () ? Qnil : Qt;
 }
 
@@ -2425,7 +2452,7 @@ Value is t if waited the full time with no input arriving.")
     error ("millisecond `sit-for' not supported on %s", SYSTEM_TYPE);
 #endif
 
-  return sit_for (sec, usec, 0, NILP (nodisp));
+  return sit_for (sec, usec, 0, NILP (nodisp), NILP (nodisp));
 }
 \f
 char *terminal_type;
@@ -2501,7 +2528,7 @@ init_display ()
   /* If no window system has been specified, try to use the terminal.  */
   if (! isatty (0))
     {
-      fprintf (stderr, "emacs: standard input is not a tty\n");
+      fatal ("standard input is not a tty");
       exit (1);
     }
 
@@ -2539,6 +2566,18 @@ For types not defined in VMS, use  define emacs_term \"TYPE\".\n\
 
   term_init (terminal_type);
 
+  {
+    int width = FRAME_WINDOW_WIDTH (selected_frame);
+    int height = FRAME_HEIGHT (selected_frame);
+
+    unsigned int total_glyphs = height * (width + 2) * sizeof (GLYPH);
+
+    /* If these sizes are so big they cause overflow,
+       just ignore the change.  It's not clear what better we could do.  */
+    if (total_glyphs / sizeof (GLYPH) / height != width + 2)
+      fatal ("screen size %dx%d too big", width, height);
+  }
+
   remake_frame_glyphs (selected_frame);
   calculate_costs (selected_frame);