]> code.delx.au - gnu-emacs/blobdiff - src/dispnew.c
(make_hdr): Undo June 16 change.
[gnu-emacs] / src / dispnew.c
index aa90d06cbb6f0f20cd6e8e9dee658be7b43abd42..c91354bad1a7a42d59b4e1b8d71a705362ccd547 100644 (file)
@@ -19,9 +19,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 
 #include <signal.h>
-#include <stdio.h>
 
 #include <config.h>
+
+#include <stdio.h>
 #include <ctype.h>
 
 #include "lisp.h"
@@ -39,22 +40,34 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "intervals.h"
 
 #include "systty.h"
-#include "systime.h"
 
 #ifdef HAVE_X_WINDOWS
 #include "xterm.h"
 #endif /* HAVE_X_WINDOWS */
 
+/* Include systime.h after xterm.h to avoid double inclusion of time.h. */
+#include "systime.h"
+
+#include <errno.h>
+
 #define max(a, b) ((a) > (b) ? (a) : (b))
 #define min(a, b) ((a) < (b) ? (a) : (b))
 
-#ifndef PENDING_OUTPUT_COUNT
 /* Get number of chars of output now in the buffer of a stdio stream.
    This ought to be built in in stdio, but it isn't.
    Some s- files override this because their stdio internals differ.  */
 #ifdef __GNU_LIBRARY__
-#define        PENDING_OUTPUT_COUNT(FILE) ((FILE)->__bufp - (FILE)->__buffer)
+/* The s- file might have overridden the definition with one that works for
+   the system's C library.  But we are using the GNU C library, so this is
+   the right definition for every system.  */
+#ifdef GNU_LIBRARY_PENDING_OUTPUT_COUNT
+#define PENDING_OUTPUT_COUNT GNU_LIBRARY_PENDING_OUTPUT_COUNT
 #else
+#undef PENDING_OUTPUT_COUNT
+#define        PENDING_OUTPUT_COUNT(FILE) ((FILE)->__bufp - (FILE)->__buffer)
+#endif
+#else /* not __GNU_LIBRARY__ */
+#ifndef PENDING_OUTPUT_COUNT
 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base)
 #endif
 #endif
@@ -173,7 +186,7 @@ redraw_frame (f)
      FRAME_PTR f;
 {
   Lisp_Object frame;
-  XSET (frame, Lisp_Frame, f);
+  XSETFRAME (frame, f);
   Fredraw_frame (frame);
 }
 
@@ -305,7 +318,7 @@ make_frame_glyphs (frame, empty)
   return new;
 }
 
-static void
+void
 free_frame_glyphs (frame, glyphs)
      FRAME_PTR frame;
      struct frame_glyphs *glyphs;
@@ -838,10 +851,10 @@ preserve_other_columns (w)
 
              bcopy (current_frame->glyphs[vpos],
                     desired_frame->glyphs[vpos],
-                    start * sizeof (current_frame->glyphs[vpos]));
+                    start * sizeof (current_frame->glyphs[vpos][0]));
              bcopy (current_frame->charstarts[vpos],
                     desired_frame->charstarts[vpos],
-                    start * sizeof (current_frame->charstarts[vpos]));
+                    start * sizeof (current_frame->charstarts[vpos][0]));
              len = min (start, current_frame->used[vpos]);
              if (desired_frame->used[vpos] < len)
                desired_frame->used[vpos] = len;
@@ -858,11 +871,11 @@ preserve_other_columns (w)
              bcopy (current_frame->glyphs[vpos] + end,
                     desired_frame->glyphs[vpos] + end,
                     ((current_frame->used[vpos] - end)
-                     * sizeof (current_frame->glyphs[vpos])));
+                     * sizeof (current_frame->glyphs[vpos][0])));
              bcopy (current_frame->charstarts[vpos] + end,
                     desired_frame->charstarts[vpos] + end,
                     ((current_frame->used[vpos] - end)
-                     * sizeof (current_frame->charstarts[vpos])));
+                     * sizeof (current_frame->charstarts[vpos][0])));
              desired_frame->used[vpos] = current_frame->used[vpos];
            }
        }
@@ -1064,7 +1077,7 @@ direct_output_for_insert (g)
      At the moment we only lose at end of line or end of buffer
      and only with faces that have some background */
   /* Instead of wasting time, give up if character has any text properties */
-      || ! NILP (Ftext_properties_at (XFASTINT (point - 1), Qnil))
+      || ! NILP (Ftext_properties_at (make_number (point - 1), Qnil))
 #endif
 
   /* Give up if w is minibuffer and a message is being displayed there */
@@ -1072,9 +1085,12 @@ direct_output_for_insert (g)
     return 0;
 
   {
+    int face = 0;
 #ifdef HAVE_X_WINDOWS
     int dummy;
-    int face = compute_char_face (frame, w, point - 1, -1, -1, &dummy, point);
+
+    if (FRAME_X_P (frame))
+      face = compute_char_face (frame, w, point - 1, -1, -1, &dummy, point, 0);
 #endif
     current_frame->glyphs[vpos][hpos] = MAKE_GLYPH (frame, g, face);
     current_frame->charstarts[vpos][hpos] = point - 1;
@@ -1084,9 +1100,9 @@ direct_output_for_insert (g)
   }
   unchanged_modified = MODIFF;
   beg_unchanged = GPT - BEG;
-  XFASTINT (w->last_point) = point;
-  XFASTINT (w->last_point_x) = hpos;
-  XFASTINT (w->last_modified) = MODIFF;
+  XSETFASTINT (w->last_point, point);
+  XSETFASTINT (w->last_point_x, hpos);
+  XSETFASTINT (w->last_modified, MODIFF);
 
   reassert_line_highlight (0, vpos);
   write_glyphs (&current_frame->glyphs[vpos][hpos], 1);
@@ -1107,7 +1123,7 @@ direct_output_forward_char (n)
 {
   register FRAME_PTR frame = selected_frame;
   register struct window *w = XWINDOW (selected_window);
-  int position;
+  Lisp_Object position;
   int hpos = FRAME_CURSOR_X (frame);
 
   /* Give up if in truncated text at end of line.  */
@@ -1131,14 +1147,14 @@ direct_output_forward_char (n)
   /* Don't use direct output next to an invisible character
      since we might need to do something special.  */
 
-  XFASTINT (position) = point;
+  XSETFASTINT (position, point);
   if (XFASTINT (position) < ZV
       && ! NILP (Fget_char_property (position,
                                     Qinvisible,
                                     selected_window)))
     return 0;
 
-  XFASTINT (position) = point - 1;
+  XSETFASTINT (position, point - 1);
   if (XFASTINT (position) >= BEGV
       && ! NILP (Fget_char_property (position,
                                     Qinvisible,
@@ -1147,8 +1163,8 @@ direct_output_forward_char (n)
 #endif
 
   FRAME_CURSOR_X (frame) += n;
-  XFASTINT (w->last_point_x) = FRAME_CURSOR_X (frame);
-  XFASTINT (w->last_point) = point;
+  XSETFASTINT (w->last_point_x, FRAME_CURSOR_X (frame));
+  XSETFASTINT (w->last_point, point);
   cursor_to (FRAME_CURSOR_Y (frame), FRAME_CURSOR_X (frame));
   fflush (stdout);
 
@@ -1167,8 +1183,8 @@ update_frame (f, force, inhibit_hairy_id)
      int force;
      int inhibit_hairy_id;
 {
-  register struct frame_glyphs *current_frame = FRAME_CURRENT_GLYPHS (f);
-  register struct frame_glyphs *desired_frame = FRAME_DESIRED_GLYPHS (f);
+  register struct frame_glyphs *current_frame;
+  register struct frame_glyphs *desired_frame = 0;
   register int i;
   int pause;
   int preempt_count = baud_rate / 2400 + 1;
@@ -1194,6 +1210,10 @@ update_frame (f, force, inhibit_hairy_id)
   if (!line_ins_del_ok)
     inhibit_hairy_id = 1;
 
+  /* These are separate to avoid a possible bug in the AIX C compiler.  */
+  current_frame = FRAME_CURRENT_GLYPHS (f);
+  desired_frame = FRAME_DESIRED_GLYPHS (f);
+
   /* See if any of the desired lines are enabled; don't compute for
      i/d line if just want cursor motion. */
   for (i = 0; i < FRAME_HEIGHT (f); i++)
@@ -1250,7 +1270,7 @@ update_frame (f, force, inhibit_hairy_id)
                        outq = PENDING_OUTPUT_COUNT (stdout);
 #endif
                      outq *= 10;
-                     if (baud_rate >= outq)
+                     if (baud_rate <= outq && baud_rate > 0)
                        sleep (outq / baud_rate);
                    }
                }
@@ -1331,7 +1351,7 @@ update_frame (f, force, inhibit_hairy_id)
   if (FRAME_HEIGHT (f) == 0) abort (); /* Some bug zeros some core */
   display_completed = !pause;
 
-  bzero (desired_frame->enable, FRAME_HEIGHT (f));
+  bzero (FRAME_DESIRED_GLYPHS (f)->enable, FRAME_HEIGHT (f));
   return pause;
 }
 
@@ -1842,6 +1862,65 @@ update_line (frame, vpos)
   current_frame->charstarts[vpos] = temp1;
 }
 \f
+/* A vector of size >= NFRAMES + 3 * NBUFFERS + 1, containing the session's
+   frames, buffers, buffer-read-only flags, and buffer-modified-flags,
+   and a trailing sentinel (so we don't need to add length checks).  */
+static Lisp_Object frame_and_buffer_state;
+
+DEFUN ("frame-or-buffer-changed-p", Fframe_or_buffer_changed_p,
+  Sframe_or_buffer_changed_p, 0, 0, 0,
+  "Return non-nil if the frame and buffer state appears to have changed.\n\
+The state variable is an internal vector containing all frames and buffers,\n\
+along with the buffers' read-only and modified flags, which allows a fast\n\
+check to see whether the menu bars might need to be recomputed.\n\
+If this function returns non-nil, it updates the internal vector to reflect\n\
+the current state.\n")
+  ()
+{
+  Lisp_Object tail, frame, buf;
+  Lisp_Object *vecp;
+  int n;
+  vecp = XVECTOR (frame_and_buffer_state)->contents;
+  FOR_EACH_FRAME (tail, frame)
+    if (!EQ (*vecp++, frame))
+      goto changed;
+  for (tail = Vbuffer_alist; CONSP (tail); tail = XCONS (tail)->cdr)
+    {
+      buf = XCONS (XCONS (tail)->car)->cdr;
+      if (!EQ (*vecp++, buf))
+       goto changed;
+      if (!EQ (*vecp++, XBUFFER (buf)->read_only))
+       goto changed;
+      if (!EQ (*vecp++, Fbuffer_modified_p (buf)))
+       goto changed;
+    }
+  return Qnil;
+ changed:
+  n = 1;
+  FOR_EACH_FRAME (tail, frame)
+    n++;
+  for (tail = Vbuffer_alist; CONSP (tail); tail = XCONS (tail)->cdr)
+    n += 3;
+  /* Reallocate the vector if it's grown, or if it's shrunk a lot.  */
+  if (n > XVECTOR (frame_and_buffer_state)->size
+      || n < XVECTOR (frame_and_buffer_state)->size / 2)
+    frame_and_buffer_state = Fmake_vector (make_number (n), Qlambda);
+  vecp = XVECTOR (frame_and_buffer_state)->contents;
+  FOR_EACH_FRAME (tail, frame)
+    *vecp++ = frame;
+  for (tail = Vbuffer_alist; CONSP (tail); tail = XCONS (tail)->cdr)
+    {
+      buf = XCONS (XCONS (tail)->car)->cdr;
+      *vecp++ = buf;
+      *vecp++ = XBUFFER (buf)->read_only;
+      *vecp++ = Fbuffer_modified_p (buf);
+    }
+  /* If we left any slack in the vector, fill it up now.  */
+  for (; n < XVECTOR (frame_and_buffer_state)->size; ++n)
+    *vecp++ = Qlambda;
+  return Qt;
+}
+\f
 DEFUN ("open-termscript", Fopen_termscript, Sopen_termscript,
   1, 1, "FOpen termscript file: ",
   "Start writing all terminal output to FILE as well as the terminal.\n\
@@ -1969,8 +2048,8 @@ change_frame_size (frame, newheight, newwidth, pretend, delay)
          /* Frame has both root and minibuffer.  */
          set_window_height (FRAME_ROOT_WINDOW (frame),
                             newheight - 1 - FRAME_MENU_BAR_LINES (frame), 0);
-         XFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (frame))->top)
-           = newheight - 1;
+         XSETFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (frame))->top,
+                      newheight - 1);
          set_window_height (FRAME_MINIBUF_WINDOW (frame), 1, 0);
        }
       else
@@ -2011,7 +2090,12 @@ change_frame_size (frame, newheight, newwidth, pretend, delay)
 
   FRAME_HEIGHT (frame) = newheight;
   FRAME_WIDTH (frame)  = newwidth;
-       
+
+  if (FRAME_CURSOR_X (frame) >= FRAME_WIDTH (frame))
+    FRAME_CURSOR_X (frame) = FRAME_WIDTH (frame) - 1;
+  if (FRAME_CURSOR_Y (frame) >= FRAME_HEIGHT (frame))
+    FRAME_CURSOR_Y (frame) = FRAME_HEIGHT (frame) - 1;
+
   remake_frame_glyphs (frame);
   calculate_costs (frame);
 }
@@ -2079,7 +2163,7 @@ Emacs was built without floating point support.\n\
   int sec, usec;
 
   if (NILP (milliseconds))
-    XSET (milliseconds, Lisp_Int, 0);
+    XSETINT (milliseconds, 0);
   else
     CHECK_NUMBER (milliseconds, 1);
   usec = XINT (milliseconds) * 1000;
@@ -2118,7 +2202,7 @@ Emacs was built without floating point support.\n\
   {
     Lisp_Object zero;
 
-    XFASTINT (zero) = 0;
+    XSETFASTINT (zero, 0);
     wait_reading_process_input (sec, usec, zero, 0);
   }
 
@@ -2185,7 +2269,7 @@ sit_for (sec, usec, reading, display)
   gobble_input (0);
 #endif
 
-  XSET (read_kbd, Lisp_Int, reading ? -1 : 1);
+  XSETINT (read_kbd, reading ? -1 : 1);
   wait_reading_process_input (sec, usec, read_kbd, display);
 
 
@@ -2234,7 +2318,7 @@ Value is t if waited the full time with no input arriving.")
   int sec, usec;
 
   if (NILP (milliseconds))
-    XSET (milliseconds, Lisp_Int, 0);
+    XSETINT (milliseconds, 0);
   else
     CHECK_NUMBER (milliseconds, 1);
   usec = XINT (milliseconds) * 1000;
@@ -2374,14 +2458,18 @@ syms_of_display ()
   defsubr (&Sredraw_frame);
 #endif
   defsubr (&Sredraw_display);
+  defsubr (&Sframe_or_buffer_changed_p);
   defsubr (&Sopen_termscript);
   defsubr (&Sding);
   defsubr (&Ssit_for);
   defsubr (&Ssleep_for);
   defsubr (&Ssend_string_to_terminal);
 
+  frame_and_buffer_state = Fmake_vector (make_number (1), Qlambda);
+  staticpro (&frame_and_buffer_state);
+
   DEFVAR_INT ("baud-rate", &baud_rate,
-    "The output baud rate of the terminal.\n\
+    "*The output baud rate of the terminal.\n\
 On most systems, changing this value will affect the amount of padding\n\
 and the other strategic decisions made during redisplay.");
   DEFVAR_BOOL ("inverse-video", &inverse_video,
@@ -2409,7 +2497,7 @@ Each element can be:\n\
  integer: a glyph code which this glyph is an alias for.\n\
  string: output this glyph using that string (not impl. in X windows).\n\
  nil: this glyph mod 256 is char code to output,\n\
-    and this glyph / 256 is face code for X windows (see `x-set-face').");
+    and this glyph / 256 is face code for X windows (see `face-id').");
   Vglyph_table = Qnil;
 
   DEFVAR_LISP ("standard-display-table", &Vstandard_display_table,