/* Updating of data structures for redisplay.
- Copyright (C) 1985, 86, 87, 88, 93, 94, 95 Free Software Foundation, Inc.
+ Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 97, 1998
+ Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <stdio.h>
#include <ctype.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
#include "lisp.h"
#include "termchar.h"
#include "termopts.h"
#include "dispextern.h"
#include "cm.h"
#include "buffer.h"
+#include "charset.h"
#include "frame.h"
#include "window.h"
#include "commands.h"
#include "indent.h"
#include "intervals.h"
#include "blockinput.h"
+#include "process.h"
+#include "keyboard.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
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
+#define minmax(floor, val, ceil) \
+ ((val) < (floor) ? (floor) : (val) > (ceil) ? (ceil) : (val))
/* 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.
return Qnil;
}
+void
redraw_frame (f)
FRAME_PTR f;
{
int empty;
{
register int i;
- register width = FRAME_WINDOW_WIDTH (frame);
- register height = FRAME_HEIGHT (frame);
+ register int width = FRAME_WINDOW_WIDTH (frame);
+ register int height = FRAME_HEIGHT (frame);
register struct frame_glyphs *new
= (struct frame_glyphs *) xmalloc (sizeof (struct frame_glyphs));
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);
}
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);
/* cancel_line eliminates any request to display a line at position `vpos' */
+void
cancel_line (vpos, frame)
int vpos;
register FRAME_PTR frame;
FRAME_DESIRED_GLYPHS (frame)->enable[vpos] = 0;
}
+void
clear_frame_records (frame)
register FRAME_PTR frame;
{
into the FRAME_DESIRED_GLYPHS (frame) from the FRAME_PHYS_GLYPHS (frame)
so that update_frame will not change those columns. */
+void
preserve_other_columns (w)
struct window *w;
{
for internal consistency. We cannot check that they are "right";
we can only look for something nonsensical. */
+void
verify_charstarts (w)
struct window *w;
{
cancel the columns of that window, so that when the window is
displayed over again get_display_line will not complain. */
+void
cancel_my_columns (w)
struct window *w;
{
unchanged_modified = MODIFF;
beg_unchanged = GPT - BEG;
XSETFASTINT (w->last_point, PT);
- XSETFASTINT (w->last_point_x, hpos);
+ XSETFASTINT (w->last_point_x, hpos + 1);
XSETFASTINT (w->last_modified, MODIFF);
XSETFASTINT (w->last_overlay_modified, OVERLAY_MODIFF);
int hpos = FRAME_CURSOR_X (frame);
/* Give up if in truncated text at end of line. */
+ /* This check is not redundant. */
if (hpos >= WINDOW_LEFT_MARGIN (w) + window_internal_width (w) - 1)
return 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;
register int i;
int pause;
int preempt_count = baud_rate / 2400 + 1;
- extern input_pending;
+ extern int input_pending;
#ifdef HAVE_WINDOW_SYSTEM
register int downto, leftmost;
#endif
}
while (row > top && col == 0);
- if (col >= FRAME_WINDOW_WIDTH (f))
+ /* Make sure COL is not out of range. */
+ if (col >= FRAME_CURSOR_X_LIMIT (f))
{
- col = 0;
+ /* If we have another row, advance cursor into it. */
if (row < FRAME_HEIGHT (f) - 1)
- row++;
+ {
+ col = FRAME_LEFT_SCROLL_BAR_WIDTH (f);
+ row++;
+ }
+ /* Otherwise move it back in range. */
+ else
+ col = FRAME_CURSOR_X_LIMIT (f) - 1;
}
}
}
else
cursor_to (FRAME_CURSOR_Y (f),
- max (min (FRAME_CURSOR_X (f),
- FRAME_WINDOW_WIDTH (f) - 1), 0));
+ minmax (0, FRAME_CURSOR_X (f),
+ FRAME_CURSOR_X_LIMIT (f) - 1));
}
update_end (f);
extern void scrolling_1 ();
+int
scrolling (frame)
FRAME_PTR 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])
{
}
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);
}
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
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. */
olen = nlen - (nsp - osp);
}
cursor_to (vpos, osp);
- insert_glyphs ((char *)0, nsp - osp);
+ insert_glyphs ((GLYPH *) 0, nsp - osp);
}
olen += nsp - osp;
}
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)
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. */
/* Do any change in frame size that was requested by a signal. */
+void
do_pending_window_change ()
{
/* If window_change_signal should have run before, run it now. */
redisplay. Since this tries to resize windows, we can't call it
from a signal handler. */
+void
change_frame_size (f, newheight, newwidth, pretend, delay)
register FRAME_PTR f;
- int newheight, newwidth, pretend;
+ int newheight, newwidth, pretend, delay;
{
Lisp_Object tail, frame;
{
int new_frame_window_width;
unsigned int total_glyphs;
+ int count = specpdl_ptr - specpdl;
/* If we can't deal with the change now, queue it for later. */
if (delay)
FRAME_HEIGHT (frame) = newheight;
SET_FRAME_WIDTH (frame, newwidth);
- if (FRAME_CURSOR_X (frame) >= FRAME_WINDOW_WIDTH (frame))
- FRAME_CURSOR_X (frame) = FRAME_WINDOW_WIDTH (frame) - 1;
+ if (FRAME_CURSOR_X (frame) >= FRAME_CURSOR_X_LIMIT (frame))
+ FRAME_CURSOR_X (frame) = FRAME_CURSOR_X_LIMIT (frame) - 1;
if (FRAME_CURSOR_Y (frame) >= FRAME_HEIGHT (frame))
FRAME_CURSOR_Y (frame) = FRAME_HEIGHT (frame) - 1;
calculate_costs (frame);
UNBLOCK_INPUT;
+
+ record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
+
+ /* 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);
+
+ unbind_to (count, Qnil);
}
\f
DEFUN ("send-string-to-terminal", Fsend_string_to_terminal,
(string)
Lisp_Object string;
{
+ /* ??? Perhaps we should do something special for multibyte strings here. */
CHECK_STRING (string, 0);
- fwrite (XSTRING (string)->data, 1, XSTRING (string)->size, stdout);
+ fwrite (XSTRING (string)->data, 1, STRING_BYTES (XSTRING (string)), stdout);
fflush (stdout);
if (termscript)
{
- fwrite (XSTRING (string)->data, 1, XSTRING (string)->size, termscript);
+ fwrite (XSTRING (string)->data, 1, STRING_BYTES (XSTRING (string)),
+ termscript);
fflush (termscript);
}
return Qnil;
return Qnil;
}
+void
bitch_at_user ()
{
if (noninteractive)
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;
if (detect_input_pending_run_timers (display))
return Qnil;
- if (display)
+ if (initial_display)
redisplay_preserve_echo_area ();
if (sec == 0 && usec == 0)
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;
}
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;
/* Then invoke its decoding routine to set up variables
in the terminal package */
+void
init_display ()
{
#ifdef HAVE_X_WINDOWS
display_arg = (display != 0 && *display != 0);
}
- if (!inhibit_window_system && display_arg && initialized)
+ if (!inhibit_window_system && display_arg
+#ifndef CANNOT_DUMP
+ && initialized
+#endif
+ )
{
Vwindow_system = intern ("x");
#ifdef HAVE_X11
/* 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);
}
/* 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)
- {
- fprintf (stderr, "emacs: screen size %dx%d too big\n,",
- width, height);
- exit (1);
- }
+ fatal ("screen size %dx%d too big", width, height);
}
remake_frame_glyphs (selected_frame);
#endif /* SIGWINCH */
}
\f
+void
syms_of_display ()
{
defsubr (&Sredraw_frame);