/* 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 Free Software Foundation, Inc.
+ 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
This file is part of GNU Emacs.
-GNU Emacs is free software; you can redistribute it and/or modify
+GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA. */
+along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <signal.h>
#include "dispextern.h"
#include "cm.h"
#include "buffer.h"
-#include "charset.h"
+#include "character.h"
#include "keyboard.h"
#include "frame.h"
#include "termhooks.h"
#include "w32term.h"
#endif /* HAVE_NTGUI */
-#ifdef MAC_OS
-#include "macterm.h"
-#endif /* MAC_OS */
+#ifdef HAVE_NS
+#include "nsterm.h"
+#endif
/* Include systime.h after xterm.h to avoid double inclusion of time.h. */
matrix adjustments. Redisplay must stop, and glyph matrices must
be adjusted when this flag becomes non-zero during display. The
reason fonts can be loaded so late is that fonts of fontsets are
- loaded on demand. */
+ loaded on demand. Another reason is that a line contains many
+ characters displayed by zero width or very narrow glyphs of
+ variable-width fonts. */
int fonts_changed_p;
int header_line_changed_p = 0;
int header_line_p = 0;
int left = -1, right = -1;
- int window_width = -1, window_height;
+ int window_width = -1, window_height = -1;
/* See if W had a header line that has disappeared now, or vice versa.
Get W's size. */
len = 0;
while (beg < end)
{
- GLYPH g = GLYPH_FROM_CHAR_GLYPH (*beg);
+ GLYPH g;
+
+ SET_GLYPH_FROM_CHAR_GLYPH (g, *beg);
- if (g < 0
+ if (GLYPH_INVALID_P (g)
|| GLYPH_SIMPLE_P (glyph_table_base, glyph_table_len, g))
len += 1;
else
else if (!NILP (w->left_margin_cols)
|| !NILP (w->right_margin_cols))
return 1;
-
+
w = NILP (w->next) ? 0 : XWINDOW (w->next);
}
return 0;
struct glyph_matrix *window_matrix;
int window_y, frame_y;
/* If non-zero, a glyph to insert at the right border of W. */
- GLYPH right_border_glyph = 0;
+ GLYPH right_border_glyph;
+
+ SET_GLYPH_FROM_CHAR (right_border_glyph, 0);
/* Set window_matrix to the matrix we have to add to FRAME_MATRIX. */
if (w->must_be_updated_p)
if (!WINDOW_RIGHTMOST_P (w))
{
struct Lisp_Char_Table *dp = window_display_table (w);
+ Lisp_Object gc;
- right_border_glyph
- = ((dp && INTEGERP (DISP_BORDER_GLYPH (dp)))
- ? spec_glyph_lookup_face (w, XINT (DISP_BORDER_GLYPH (dp)))
- : '|');
+ SET_GLYPH_FROM_CHAR (right_border_glyph, '|');
+ if (dp
+ && (gc = DISP_BORDER_GLYPH (dp), GLYPH_CODE_P (gc))
+ && GLYPH_CODE_CHAR_VALID_P (gc))
+ {
+ SET_GLYPH_FROM_GLYPH_CODE (right_border_glyph, gc);
+ spec_glyph_lookup_face (w, &right_border_glyph);
+ }
- if (FAST_GLYPH_FACE (right_border_glyph) <= 0)
- right_border_glyph
- = FAST_MAKE_GLYPH (right_border_glyph, VERTICAL_BORDER_FACE_ID);
+ if (GLYPH_FACE (right_border_glyph) <= 0)
+ SET_GLYPH_FACE (right_border_glyph, VERTICAL_BORDER_FACE_ID);
}
}
else
/* Maybe insert a vertical border between horizontally adjacent
windows. */
- if (right_border_glyph)
+ if (GLYPH_CHAR (right_border_glyph) != 0)
{
struct glyph *border = window_row->glyphs[LAST_AREA] - 1;
SET_CHAR_GLYPH_FROM_GLYPH (*border, right_border_glyph);
This is used for glyphs displayed specially and not part of the text;
for instance, vertical separators, truncation markers, etc. */
-GLYPH
+void
spec_glyph_lookup_face (w, glyph)
struct window *w;
- GLYPH glyph;
+ GLYPH *glyph;
{
- int lface_id = FAST_GLYPH_FACE (glyph);
+ int lface_id = GLYPH_FACE (*glyph);
/* Convert the glyph's specified face to a realized (cache) face. */
if (lface_id > 0)
{
int face_id = merge_faces (XFRAME (w->frame),
Qt, lface_id, DEFAULT_FACE_ID);
- glyph
- = FAST_MAKE_GLYPH (FAST_GLYPH_CHAR (glyph), face_id);
+ SET_GLYPH_FACE (*glyph, face_id);
}
- return glyph;
}
/* Add spaces to a glyph row ROW in a window matrix.
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);
|| g == '\t'
|| g == '\n'
|| g == '\r'
+ || (g == ' ' && !NILP (current_buffer->word_wrap))
/* Give up if unable to display the cursor in the window. */
|| w->cursor.vpos < 0
/* Give up if we are showing a message or just cleared the message
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. */
{
int i;
struct frame *f = XFRAME (WINDOW_FRAME (w));
-
+
/* If rows overlapping others have been changed, the rows being
overlapped have to be redrawn. This won't draw lines that have
already been drawn in update_window_line because overlapped_p in
int i, bottom_y;
struct glyph_row *row;
struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
-
+
for (i = 0; i < w->current_matrix->nrows; ++i)
{
row = w->current_matrix->rows + i;
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,
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
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))
{
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);
}
}
Also flush out if likely to have more than 1k buffered
otherwise. I'm told that some telnet connections get
really screwed by more than 1k output at once. */
- int outq = PENDING_OUTPUT_COUNT (FRAME_TTY (f)->output);
- if (outq > 900
- || (outq > 20 && ((i - 1) % preempt_count == 0)))
+ FILE *display_output = FRAME_TTY (f)->output;
+ if (display_output)
{
- fflush (FRAME_TTY (f)->output);
- if (preempt_count == 1)
+ int outq = PENDING_OUTPUT_COUNT (display_output);
+ if (outq > 900
+ || (outq > 20 && ((i - 1) % preempt_count == 0)))
{
+ fflush (display_output);
+ if (preempt_count == 1)
+ {
#ifdef EMACS_OUTQSIZE
- if (EMACS_OUTQSIZE (0, &outq) < 0)
- /* Probably not a tty. Ignore the error and reset
- the outq count. */
- outq = PENDING_OUTPUT_COUNT (FRAME_TTY (f->output));
+ if (EMACS_OUTQSIZE (0, &outq) < 0)
+ /* Probably not a tty. Ignore the error and reset
+ the outq count. */
+ outq = PENDING_OUTPUT_COUNT (FRAME_TTY (f->output));
#endif
- outq *= 10;
- if (baud_rate <= outq && baud_rate > 0)
- sleep (outq / baud_rate);
+ outq *= 10;
+ if (baud_rate <= outq && baud_rate > 0)
+ sleep (outq / baud_rate);
+ }
}
}
}
continue;
get_tty_size (fileno (tty->input), &width, &height);
-
+
if (width > 5 && height > 2) {
Lisp_Object tail, frame;
-
+
FOR_EACH_FRAME (tail, frame)
if (FRAME_TERMCAP_P (XFRAME (frame)) && FRAME_TTY (XFRAME (frame)) == tty)
/* Record the new sizes, but don't reallocate the data
change_frame_size (XFRAME (frame), height, width, 0, 1, 0);
}
}
-
+
errno = old_errno;
}
#endif /* SIGWINCH */
(newheight
- 1
- FRAME_TOP_MARGIN (f)),
- 0);
+ 2);
XSETFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (f))->top_line,
newheight - 1);
set_window_height (FRAME_MINIBUF_WINDOW (f), 1, 0);
else
/* Frame has just one top-level window. */
set_window_height (FRAME_ROOT_WINDOW (f),
- newheight - FRAME_TOP_MARGIN (f), 0);
+ 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;
}
if (new_frame_total_cols != FRAME_TOTAL_COLS (f))
{
- set_window_width (FRAME_ROOT_WINDOW (f), new_frame_total_cols, 0);
+ set_window_width (FRAME_ROOT_WINDOW (f), new_frame_total_cols, 2);
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))
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 (f),
- XWINDOW (FRAME_SELECTED_WINDOW (f))->buffer, Qt);
+ run_window_configuration_change_hook (f);
unbind_to (count, Qnil);
}
{
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 ();
error ("Unknown terminal device");
tty = t->display_info.tty;
-
+
+ if (! tty->output)
+ error ("Terminal is currently suspended");
+
if (tty->termscript)
{
fwrite (SDATA (string), 1, SBYTES (string), tty->termscript);
/* Construct the space glyph. */
space_glyph.type = CHAR_GLYPH;
- SET_CHAR_GLYPH_FROM_GLYPH (space_glyph, ' ');
+ SET_CHAR_GLYPH (space_glyph, ' ', DEFAULT_FACE_ID, 0);
space_glyph.charpos = -1;
inverse_video = 0;
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
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))
Vinitial_window_system = intern ("x");
#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,
}
#endif /* HAVE_NTGUI */
-#ifdef MAC_OS
- if (!inhibit_window_system)
+#ifdef HAVE_NS
+ if (!inhibit_window_system
+#ifndef CANNOT_DUMP
+ && initialized
+#endif
+ )
{
- Vinitial_window_system = intern ("mac");
- Vwindow_system_version = make_number (1);
+ Vinitial_window_system = intern("ns");
+ Vwindow_system_version = make_number(10);
adjust_frame_glyphs_initially ();
return;
}
-#endif /* MAC_OS */
+#endif
/* If no window system has been specified, try to use the terminal. */
if (! isatty (0))
exit (1);
}
+#ifdef WINDOWSNT
+ terminal_type = "w32console";
+#else
/* Look at the TERM variable. */
terminal_type = (char *) getenv ("TERM");
+#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);
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));
}
-
+
{
struct frame *sf = SELECTED_FRAME ();
int width = FRAME_TOTAL_COLS (sf);
/* 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
return w->cursor_off_p ? Qnil : Qt;
}
+DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame,
+ Slast_nonminibuf_frame, 0, 0, 0,
+ doc: /* Value is last nonminibuffer frame. */)
+ ()
+{
+ Lisp_Object frame = Qnil;
+
+ if (last_nonminibuf_frame)
+ XSETFRAME (frame, last_nonminibuf_frame);
+
+ return frame;
+}
\f
/***********************************************************************
Initialization
defsubr (&Ssend_string_to_terminal);
defsubr (&Sinternal_show_cursor);
defsubr (&Sinternal_show_cursor_p);
+ defsubr (&Slast_nonminibuf_frame);
#if GLYPH_DEBUG
defsubr (&Sdump_redisplay_history);
DEFVAR_LISP ("window-system-version", &Vwindow_system_version,
doc: /* The version number of the window system in use.
-For X windows, this is 10 or 11. */);
+For X windows, this is 11. */);
DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area,
doc: /* Non-nil means put cursor in minibuffer, at end of any message there. */);