/* Updating of data structures for redisplay.
- Copyright (C) 1985, 1986, 1987, 1988, 1990,
- 1992, 1993 Free Software Foundation, Inc.
+ Copyright (C) 1985, 86, 87, 88, 93, 94 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <signal.h>
-
-#include "config.h"
#include <stdio.h>
+
+#include <config.h>
#include <ctype.h>
+#include "lisp.h"
#include "termchar.h"
#include "termopts.h"
#include "termhooks.h"
#include "cm.h"
-#include "lisp.h"
#include "dispextern.h"
#include "buffer.h"
#include "frame.h"
#include "commands.h"
#include "disptab.h"
#include "indent.h"
+#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__
+/* 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
/* Nonzero upon entry to redisplay means do not assume anything about
current contents of actual terminal frame; clear and redraw it. */
exist inside frame objects lives in the following structure instead.
NOTE: the_only_frame is not checked for garbage collection; don't
- store collectable objects in any of its fields!
+ store collectible objects in any of its fields!
You're not/The only frame in town/... */
#else
-DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, "",
+DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, 0,
"Clear frame FRAME and output again what is supposed to appear on it.")
(frame)
Lisp_Object frame;
Lisp_Object tail, frame;
FOR_EACH_FRAME (tail, frame)
- /* If we simply redrew all visible frames, whether or not they
- were garbaged, then this would make all frames clear and
- nredraw whenever a new frame is created or an existing frame
- is de-iconified; those events set the global frame_garbaged
- flag, to which redisplay responds by calling this function.
-
- This used to redraw all visible frames; the only advantage of
- that approach is that if a frame changes from invisible to
- visible without setting its garbaged flag, it still gets
- redisplayed. But that should never happen; since invisible
- frames are not updated, they should always be marked as
- garbaged when they become visible again. If that doesn't
- happen, it's a bug in the visibility code, not a bug here. */
- if (FRAME_VISIBLE_P (XFRAME (frame))
- && FRAME_GARBAGED_P (XFRAME (frame)))
+ if (FRAME_VISIBLE_P (XFRAME (frame)))
Fredraw_frame (frame);
return Qnil;
}
+/* This is used when frame_garbaged is set.
+ Redraw the individual frames marked as garbaged. */
+
+void
+redraw_garbaged_frames ()
+{
+ Lisp_Object tail, frame;
+
+ FOR_EACH_FRAME (tail, frame)
+ if (FRAME_VISIBLE_P (XFRAME (frame))
+ && FRAME_GARBAGED_P (XFRAME (frame)))
+ Fredraw_frame (frame);
+}
+
\f
static struct frame_glyphs *
make_frame_glyphs (frame, empty)
register int i;
register width = FRAME_WIDTH (frame);
register height = FRAME_HEIGHT (frame);
- register struct frame_glyphs *new =
- (struct frame_glyphs *) xmalloc (sizeof (struct frame_glyphs));
+ register struct frame_glyphs *new
+ = (struct frame_glyphs *) xmalloc (sizeof (struct frame_glyphs));
SET_GLYPHS_FRAME (new, frame);
new->height = height;
new->width = width;
new->used = (int *) xmalloc (height * sizeof (int));
new->glyphs = (GLYPH **) xmalloc (height * sizeof (GLYPH *));
+ new->charstarts = (int **) xmalloc (height * sizeof (int *));
new->highlight = (char *) xmalloc (height * sizeof (char));
new->enable = (char *) xmalloc (height * sizeof (char));
bzero (new->enable, height * sizeof (char));
/* Make the buffer used by decode_mode_spec. This buffer is also
used as temporary storage when updating the frame. See scroll.c. */
unsigned int total_glyphs = (width + 2) * sizeof (GLYPH);
+ unsigned int total_charstarts = (width + 2) * sizeof (int);
new->total_contents = (GLYPH *) xmalloc (total_glyphs);
bzero (new->total_contents, total_glyphs);
+
+ new->total_charstarts = (int *) xmalloc (total_charstarts);
+ bzero (new->total_charstarts, total_glyphs);
}
else
{
bzero (new->total_contents, total_glyphs);
for (i = 0; i < height; i++)
new->glyphs[i] = new->total_contents + i * (width + 2) + 1;
+
+ if (!FRAME_TERMCAP_P (frame))
+ {
+ unsigned int total_charstarts = height * (width + 2) * sizeof (int);
+
+ new->total_charstarts = (int *) xmalloc (total_charstarts);
+ bzero (new->total_charstarts, total_charstarts);
+ for (i = 0; i < height; i++)
+ new->charstarts[i] = new->total_charstarts + i * (width + 2) + 1;
+ }
+ else
+ {
+ /* Without a window system, we don't really need charstarts.
+ So use a small amount of space to make enough data structure
+ to prevent crashes in display_text_line. */
+ new->total_charstarts = (int *) xmalloc ((width + 2) * sizeof (int));
+ for (i = 0; i < height; i++)
+ new->charstarts[i] = new->total_charstarts;
+ }
}
return new;
struct frame_glyphs *glyphs;
{
if (glyphs->total_contents)
- free (glyphs->total_contents);
-
- free (glyphs->used);
- free (glyphs->glyphs);
- free (glyphs->highlight);
- free (glyphs->enable);
- free (glyphs->bufp);
+ xfree (glyphs->total_contents);
+ if (glyphs->total_charstarts)
+ xfree (glyphs->total_charstarts);
+
+ xfree (glyphs->used);
+ xfree (glyphs->glyphs);
+ xfree (glyphs->highlight);
+ xfree (glyphs->enable);
+ xfree (glyphs->bufp);
+ if (glyphs->charstarts)
+ xfree (glyphs->charstarts);
#ifdef HAVE_X_WINDOWS
if (FRAME_X_P (frame))
{
- free (glyphs->top_left_x);
- free (glyphs->top_left_y);
- free (glyphs->pix_width);
- free (glyphs->pix_height);
- free (glyphs->max_ascent);
+ xfree (glyphs->top_left_x);
+ xfree (glyphs->top_left_y);
+ xfree (glyphs->pix_width);
+ xfree (glyphs->pix_height);
+ xfree (glyphs->max_ascent);
}
#endif
- free (glyphs);
+ xfree (glyphs);
}
static void
Returns nonzero if done, zero if terminal cannot scroll them. */
int
-scroll_frame_lines (frame, from, end, amount)
+scroll_frame_lines (frame, from, end, amount, newpos)
register FRAME_PTR frame;
- int from, end, amount;
+ int from, end, amount, newpos;
{
register int i;
register struct frame_glyphs *current_frame
= FRAME_CURRENT_GLYPHS (frame);
+ int pos_adjust;
+ int width = FRAME_WIDTH (frame);
if (!line_ins_del_ok)
return 0;
sizeof (GLYPH *) * (end + amount - from),
amount * sizeof (GLYPH *));
+ rotate_vector (current_frame->charstarts + from,
+ sizeof (int *) * (end + amount - from),
+ amount * sizeof (int *));
+
safe_bcopy (current_frame->used + from,
current_frame->used + from + amount,
(end - from) * sizeof current_frame->used[0]);
current_frame->enable + from + amount,
(end - from) * sizeof current_frame->enable[0]);
+ /* Adjust the lines by an amount
+ that puts the first of them at NEWPOS. */
+ pos_adjust = newpos - current_frame->charstarts[from + amount][0];
+
+ /* Offset each char position in the charstarts lines we moved
+ by pos_adjust. */
+ for (i = from + amount; i < end + amount; i++)
+ {
+ int *line = current_frame->charstarts[i];
+ int col;
+ for (col = 0; col < width; col++)
+ if (line[col] > 0)
+ line[col] += pos_adjust;
+ }
+ for (i = from; i < from + amount; i++)
+ {
+ int *line = current_frame->charstarts[i];
+ int col;
+ line[0] = -1;
+ for (col = 0; col < width; col++)
+ line[col] = 0;
+ }
+
/* Mark the lines made empty by scrolling as enabled, empty and
normal video. */
bzero (current_frame->used + from,
for (i = from; i < from + amount; i++)
{
current_frame->glyphs[i][0] = '\0';
+ current_frame->charstarts[i][0] = -1;
current_frame->enable[i] = 1;
}
sizeof (GLYPH *) * (end - from - amount),
amount * sizeof (GLYPH *));
+ rotate_vector (current_frame->charstarts + from + amount,
+ sizeof (int *) * (end - from - amount),
+ amount * sizeof (int *));
+
safe_bcopy (current_frame->used + from,
current_frame->used + from + amount,
(end - from) * sizeof current_frame->used[0]);
current_frame->enable + from + amount,
(end - from) * sizeof current_frame->enable[0]);
+ /* Adjust the lines by an amount
+ that puts the first of them at NEWPOS. */
+ pos_adjust = newpos - current_frame->charstarts[from + amount][0];
+
+ /* Offset each char position in the charstarts lines we moved
+ by pos_adjust. */
+ for (i = from + amount; i < end + amount; i++)
+ {
+ int *line = current_frame->charstarts[i];
+ int col;
+ for (col = 0; col < width; col++)
+ if (line[col] > 0)
+ line[col] += pos_adjust;
+ }
+ for (i = end + amount; i < end; i++)
+ {
+ int *line = current_frame->charstarts[i];
+ int col;
+ line[0] = -1;
+ for (col = 0; col < width; col++)
+ line[col] = 0;
+ }
+
/* Mark the lines made empty by scrolling as enabled, empty and
normal video. */
bzero (current_frame->used + end + amount,
for (i = end + amount; i < end; i++)
{
current_frame->glyphs[i][0] = '\0';
+ current_frame->charstarts[i][0] = 0;
current_frame->enable[i] = 1;
}
int len;
bcopy (current_frame->glyphs[vpos],
- desired_frame->glyphs[vpos], start);
+ desired_frame->glyphs[vpos],
+ start * sizeof (current_frame->glyphs[vpos]));
+ bcopy (current_frame->charstarts[vpos],
+ desired_frame->charstarts[vpos],
+ start * sizeof (current_frame->charstarts[vpos]));
len = min (start, current_frame->used[vpos]);
if (desired_frame->used[vpos] < len)
desired_frame->used[vpos] = len;
&& desired_frame->used[vpos] < current_frame->used[vpos])
{
while (desired_frame->used[vpos] < end)
- desired_frame->glyphs[vpos][desired_frame->used[vpos]++]
- = SPACEGLYPH;
+ {
+ int used = desired_frame->used[vpos]++;
+ desired_frame->glyphs[vpos][used] = SPACEGLYPH;
+ desired_frame->glyphs[vpos][used] = 0;
+ }
bcopy (current_frame->glyphs[vpos] + end,
desired_frame->glyphs[vpos] + end,
- current_frame->used[vpos] - end);
+ ((current_frame->used[vpos] - end)
+ * sizeof (current_frame->glyphs[vpos])));
+ bcopy (current_frame->charstarts[vpos] + end,
+ desired_frame->charstarts[vpos] + end,
+ ((current_frame->used[vpos] - end)
+ * sizeof (current_frame->charstarts[vpos])));
desired_frame->used[vpos] = current_frame->used[vpos];
}
}
#endif
\f
+/* Adjust by ADJUST the charstart values in window W
+ after vpos VPOS, which counts relative to the frame
+ (not relative to W itself). */
+
+void
+adjust_window_charstarts (w, vpos, adjust)
+ struct window *w;
+ int vpos;
+ int adjust;
+{
+ int left = XFASTINT (w->left);
+ int top = XFASTINT (w->top);
+ int right = left + window_internal_width (w);
+ int bottom = top + window_internal_height (w);
+ int i;
+
+ for (i = vpos + 1; i < bottom; i++)
+ {
+ int *charstart
+ = FRAME_CURRENT_GLYPHS (XFRAME (WINDOW_FRAME (w)))->charstarts[i];
+ int j;
+ for (j = left; j < right; j++)
+ if (charstart[j] > 0)
+ charstart[j] += adjust;
+ }
+}
+
+/* Check the charstarts values in the area of window W
+ for internal consistency. We cannot check that they are "right";
+ we can only look for something nonsensical. */
+
+verify_charstarts (w)
+ struct window *w;
+{
+ FRAME_PTR f = XFRAME (WINDOW_FRAME (w));
+ int i;
+ int top = XFASTINT (w->top);
+ int bottom = top + window_internal_height (w);
+ int left = XFASTINT (w->left);
+ int right = left + window_internal_width (w);
+ int next_line;
+ int truncate = (XINT (w->hscroll)
+ || (truncate_partial_width_windows
+ && (XFASTINT (w->width) < FRAME_WIDTH (f)))
+ || !NILP (XBUFFER (w->buffer)->truncate_lines));
+
+ for (i = top; i < bottom; i++)
+ {
+ int j;
+ int last;
+ int *charstart = FRAME_CURRENT_GLYPHS (f)->charstarts[i];
+
+ if (i != top)
+ {
+ if (truncate)
+ {
+ /* If we are truncating lines, allow a jump
+ in charstarts from one line to the next. */
+ if (charstart[left] < next_line)
+ abort ();
+ }
+ else
+ {
+ if (charstart[left] != next_line)
+ abort ();
+ }
+ }
+
+ for (j = left; j < right; j++)
+ if (charstart[j] > 0)
+ last = charstart[j];
+ /* Record where the next line should start. */
+ next_line = last;
+ if (BUF_ZV (XBUFFER (w->buffer)) != last)
+ {
+ /* If there's a newline between the two lines, count that. */
+ int endchar = *BUF_CHAR_ADDRESS (XBUFFER (w->buffer), last);
+ if (endchar == '\n')
+ next_line++;
+ }
+ }
+}
+\f
/* On discovering that the redisplay for a window was no good,
cancel the columns of that window, so that when the window is
displayed over again get_display_line will not complain. */
struct window *w;
{
register int vpos;
- register struct frame_glyphs *desired_glyphs =
- FRAME_DESIRED_GLYPHS (XFRAME (w->frame));
+ register struct frame_glyphs *desired_glyphs
+ = FRAME_DESIRED_GLYPHS (XFRAME (w->frame));
register int start = XFASTINT (w->left);
register int bot = XFASTINT (w->top) + XFASTINT (w->height);
/* Give up if buffer appears in two places. */
|| buffer_shared > 1
+#ifdef USE_TEXT_PROPERTIES
+ /* Intervals have already been adjusted, point is after the
+ character that was just inserted. */
+ /* Give up if character is invisible. */
+ /* Give up if character has a face property.
+ 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))
+#endif
+
/* Give up if w is minibuffer and a message is being displayed there */
|| (MINI_WINDOW_P (w) && echo_area_glyphs))
return 0;
- current_frame->glyphs[vpos][hpos] = g;
+ {
+#ifdef HAVE_X_WINDOWS
+ int dummy;
+ int face = compute_char_face (frame, w, point - 1, -1, -1, &dummy, point);
+#endif
+ current_frame->glyphs[vpos][hpos] = MAKE_GLYPH (frame, g, face);
+ current_frame->charstarts[vpos][hpos] = point - 1;
+ /* Record the entry for after the newly inserted character. */
+ current_frame->charstarts[vpos][hpos + 1] = point;
+ adjust_window_charstarts (w, vpos, 1);
+ }
unchanged_modified = MODIFF;
beg_unchanged = GPT - BEG;
XFASTINT (w->last_point) = point;
{
register FRAME_PTR frame = selected_frame;
register struct window *w = XWINDOW (selected_window);
+ int position;
+ int hpos = FRAME_CURSOR_X (frame);
+
+ /* Give up if in truncated text at end of line. */
+ if (hpos >= XFASTINT (w->left) + window_internal_width (w) - 1)
+ return 0;
/* Avoid losing if cursor is in invisible text off left margin
or about to go off either side of window. */
&& (FRAME_CURSOR_X (frame) + 1 >= window_internal_width (w) - 1))
|| cursor_in_echo_area)
return 0;
+
+ /* Can't use direct output if highlighting a region. */
+ if (!NILP (Vtransient_mark_mode) && !NILP (current_buffer->mark_active))
+ return 0;
+
+#ifdef USE_TEXT_PROPERTIES
+ /* Don't use direct output next to an invisible character
+ since we might need to do something special. */
+
+ XFASTINT (position) = point;
+ if (XFASTINT (position) < ZV
+ && ! NILP (Fget_char_property (position,
+ Qinvisible,
+ selected_window)))
+ return 0;
+
+ XFASTINT (position) = point - 1;
+ if (XFASTINT (position) >= BEGV
+ && ! NILP (Fget_char_property (position,
+ Qinvisible,
+ selected_window)))
+ return 0;
+#endif
FRAME_CURSOR_X (frame) += n;
XFASTINT (w->last_point_x) = FRAME_CURSOR_X (frame);
XFASTINT (w->last_point) = point;
cursor_to (FRAME_CURSOR_Y (frame), FRAME_CURSOR_X (frame));
fflush (stdout);
+
return 1;
}
\f
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;
register int downto, leftmost;
#endif
+ if (preempt_count <= 0)
+ preempt_count = 1;
+
if (FRAME_HEIGHT (f) == 0) abort (); /* Some bug zeros some core */
detect_input_pending ();
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++)
outq = PENDING_OUTPUT_COUNT (stdout);
#endif
outq *= 10;
- sleep (outq / baud_rate);
+ if (baud_rate <= outq && baud_rate > 0)
+ sleep (outq / baud_rate);
}
}
if ((i - 1) % preempt_count == 0)
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;
}
struct window *window;
int col, line;
{
+ int hscroll = XINT (window->hscroll);
int window_left = XFASTINT (window->left);
/* The actual width of the window is window->width less one for the
sure I will keep it. */
posn = compute_motion (startp, 0,
(window == XWINDOW (minibuf_window) && startp == 1
- ? minibuf_prompt_width : 0),
- ZV, line, col - window_left,
- window_width, XINT (window->hscroll), 0);
+ ? minibuf_prompt_width : 0)
+ + (hscroll ? 1 - hscroll : 0),
+ ZV, line, col,
+ window_width, hscroll, 0, window);
current_buffer = old_current_buffer;
int vpos;
{
register GLYPH *obody, *nbody, *op1, *op2, *np1, *temp;
+ int *temp1;
int tem;
int osp, nsp, begmatch, endmatch, olen, nlen;
int save;
= current_frame->used[vpos]
* FONT_WIDTH (frame->display.x->font);
current_frame->pix_height[vpos]
- = FONT_HEIGHT (frame->display.x->font);
+ = frame->display.x->line_height;
}
#endif /* HAVE_X_WINDOWS */
{
int i,j;
+#if 0
+ if (FRAME_X_P (frame))
+ {
+ /* Under X, erase everything we are going to rewrite,
+ and rewrite everything from the first char that's changed.
+ This is part of supporting fonts like Courier
+ whose chars can overlap outside the char width. */
+ for (i = 0; i < nlen; i++)
+ if (i >= olen || nbody[i] != obody[i])
+ break;
+
+ cursor_to (vpos, i);
+ if (i != olen)
+ clear_end_of_line (olen);
+ write_glyphs (nbody + i, nlen - i);
+ }
+ else
+ {}
+#endif /* 0 */
for (i = 0; i < nlen; i++)
{
if (i >= olen || nbody[i] != obody[i]) /* A non-matching char. */
desired_frame->glyphs[vpos] = current_frame->glyphs[vpos];
current_frame->glyphs[vpos] = temp;
+ /* Exchange charstarts between current_frame and new_frame. */
+ temp1 = desired_frame->charstarts[vpos];
+ desired_frame->charstarts[vpos] = current_frame->charstarts[vpos];
+ current_frame->charstarts[vpos] = temp1;
+
return;
}
desired_frame->glyphs[vpos] = current_frame->glyphs[vpos];
current_frame->glyphs[vpos] = temp;
+ /* Exchange charstarts between current_frame and new_frame. */
+ temp1 = desired_frame->charstarts[vpos];
+ desired_frame->charstarts[vpos] = current_frame->charstarts[vpos];
+ current_frame->charstarts[vpos] = temp1;
+
return;
}
temp = desired_frame->glyphs[vpos];
desired_frame->glyphs[vpos] = current_frame->glyphs[vpos];
current_frame->glyphs[vpos] = temp;
+
+ /* Exchange charstarts between current_frame and new_frame. */
+ temp1 = desired_frame->charstarts[vpos];
+ desired_frame->charstarts[vpos] = current_frame->charstarts[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,
int height = FRAME_NEW_HEIGHT (f);
int width = FRAME_NEW_WIDTH (f);
-
- FRAME_NEW_HEIGHT (f) = 0;
- FRAME_NEW_WIDTH (f) = 0;
- if (height != 0)
+ if (height != 0 || width != 0)
change_frame_size (f, height, width, 0, 0);
}
}
FRAME_NEW_HEIGHT (frame) = 0;
FRAME_NEW_WIDTH (frame) = 0;
- /* If an arguments is zero, set it to the current value. */
+ /* If an argument is zero, set it to the current value. */
newheight || (newheight = FRAME_HEIGHT (frame));
newwidth || (newwidth = FRAME_WIDTH (frame));
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);
}
DEFUN ("sleep-for", Fsleep_for, Ssleep_for, 1, 2, 0,
"Pause, without updating display, for SECONDS seconds.\n\
-Optional second arg MILLISECONDS specifies an additional wait period,\n\
-in milliseconds.\n\
-\(Not all operating systems support milliseconds.)")
+SECONDS may be a floating-point value, meaning that you can wait for a\n\
+fraction of a second. Optional second arg MILLISECONDS specifies an\n\
+additional wait period, in milliseconds; this may be useful if your\n\
+Emacs was built without floating point support.\n\
+\(Not all operating systems support waiting for a fraction of a second.)")
(seconds, milliseconds)
Lisp_Object seconds, milliseconds;
{
int sec, usec;
- CHECK_NUMBER (seconds, 0);
- sec = XINT (seconds);
-
if (NILP (milliseconds))
XSET (milliseconds, Lisp_Int, 0);
else
CHECK_NUMBER (milliseconds, 1);
- usec = XINT (milliseconds);
+ usec = XINT (milliseconds) * 1000;
+
+#ifdef LISP_FLOAT_TYPE
+ {
+ double duration = extract_float (seconds);
+ sec = (int) duration;
+ usec += (duration - sec) * 1000000;
+ }
+#else
+ CHECK_NUMBER (seconds, 0);
+ sec = XINT (seconds);
+#endif
#ifndef EMACS_HAS_USECS
if (sec == 0 && usec != 0)
/* This is just like wait_reading_process_input, except that
it does the redisplay.
- It's also just like Fsit_for, except that it can be used for
- waiting for input as well. */
+ It's also much like Fsit_for, except that it can be used for
+ waiting for input as well. One differnce is that sit_for
+ does not call prepare_menu_bars; Fsit_for does call that. */
Lisp_Object
sit_for (sec, usec, reading, display)
DEFUN ("sit-for", Fsit_for, Ssit_for, 1, 3, 0,
"Perform redisplay, then wait for SECONDS seconds or until input is available.\n\
-Optional second arg MILLISECONDS specifies an additional wait period, in\n\
-milliseconds.\n\
+SECONDS may be a floating-point value, meaning that you can wait for a\n\
+fraction of a second. Optional second arg MILLISECONDS specifies an\n\
+additional wait period, in milliseconds; this may be useful if your\n\
+Emacs was built without floating point support.\n\
+\(Not all operating systems support waiting for a fraction of a second.)\n\
Optional third arg non-nil means don't redisplay, just wait for input.\n\
Redisplay is preempted as always if input arrives, and does not happen\n\
if input is available before it starts.\n\
{
int sec, usec;
- CHECK_NUMBER (seconds, 0);
- sec = XINT (seconds);
-
if (NILP (milliseconds))
XSET (milliseconds, Lisp_Int, 0);
else
CHECK_NUMBER (milliseconds, 1);
- usec = XINT (milliseconds);
+ usec = XINT (milliseconds) * 1000;
+
+#ifdef LISP_FLOAT_TYPE
+ {
+ double duration = extract_float (seconds);
+ sec = (int) duration;
+ usec += (duration - sec) * 1000000;
+ }
+#else
+ CHECK_NUMBER (seconds, 0);
+ sec = XINT (seconds);
+#endif
#ifndef EMACS_HAS_USECS
if (usec != 0 && sec == 0)
error ("millisecond `sit-for' not supported on %s", SYSTEM_TYPE);
#endif
+ if (NILP (nodisp))
+ prepare_menu_bars ();
return sit_for (sec, usec, 0, NILP (nodisp));
}
\f
cursor_in_echo_area = 0;
terminal_type = (char *) 0;
- /* If the DISPLAY environment variable is set, try to use X, and
- die with an error message if that doesn't work. */
+ /* Now is the time to initialize this; it's used by init_sys_modes
+ during startup. */
+ Vwindow_system = Qnil;
- /* Check if we're using a window system here before trying to
- initialize the terminal. If we check the terminal first,
+ /* 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
+ using the window system.
- If someone has indicated that they want
- 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 using the window
- system. */
+ If the DISPLAY environment variable is set, try to use X, and die
+ with an error message if that doesn't work. */
#ifdef HAVE_X_WINDOWS
- if (!inhibit_window_system && (display_arg || getenv ("DISPLAY")))
+ if (! display_arg)
+ {
+#ifdef VMS
+ display_arg = (getenv ("DECW$DISPLAY") != 0);
+#else
+ display_arg = (getenv ("DISPLAY") != 0);
+#endif
+ }
+
+ if (!inhibit_window_system && display_arg)
{
Vwindow_system = intern ("x");
#ifdef HAVE_X11
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\
On most systems, changing this value will affect the amount of padding\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,
Vwindow_system_version = Qnil;
}
}
-