#endif
#include "lisp.h"
-#include "systty.h" /* For emacs_tty in termchar.h */
#include "termchar.h"
#include "termopts.h"
-#include "termhooks.h"
/* cm.h must come after dispextern.h on Windows. */
#include "dispextern.h"
#include "cm.h"
#include "charset.h"
#include "keyboard.h"
#include "frame.h"
+#include "termhooks.h"
#include "window.h"
#include "commands.h"
#include "disptab.h"
EMACS_INT baud_rate;
/* Either nil or a symbol naming the window system under which Emacs
- is running. */
+ creates the first frame. */
-Lisp_Object Vwindow_system;
+Lisp_Object Vinitial_window_system;
/* Version number of X windows: 10, 11 or nil. */
static struct frame *frame_matrix_frame;
-/* Current interface for window-based redisplay. Set from init_xterm.
- A null value means we are not using window-based redisplay. */
-
-struct redisplay_interface *rif;
-
/* Non-zero means that fonts have been loaded since the last glyph
matrix adjustments. Redisplay must stop, and glyph matrices must
be adjusted when this flag becomes non-zero during display. The
{
int c = glyph->u.ch;
int face_id = glyph->face_id;
- if (TTY_MUST_WRITE_SPACES (CURTTY ()))
+ if (FRAME_MUST_WRITE_SPACES (SELECTED_FRAME ())) /* XXX Is SELECTED_FRAME OK here? */
c -= SPACEGLYPH;
hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + c;
hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + face_id;
int glyph_table_len = GLYPH_TABLE_LENGTH;
/* Ignore trailing and leading spaces if we can. */
- if (!TTY_MUST_WRITE_SPACES (CURTTY ()))
+ if (!FRAME_MUST_WRITE_SPACES (SELECTED_FRAME ())) /* XXX Is SELECTED_FRAME OK here? */
{
/* Skip from the end over trailing spaces. */
while (end > beg && CHAR_GLYPH_SPACE_P (*(end - 1)))
return Qnil;
update_begin (f);
+#ifdef MSDOS
if (FRAME_MSDOS_P (f))
- set_terminal_modes ();
+ set_terminal_modes (FRAME_DISPLAY (f));
+#endif
clear_frame ();
clear_current_matrices (f);
update_end (f);
- fflush (TTY_OUTPUT (FRAME_TTY (f)));
+ if (FRAME_TERMCAP_P (f))
+ fflush (TTY_OUTPUT (FRAME_TTY (f)));
windows_or_buffers_changed++;
/* Mark all windows as inaccurate, so that every window will have
its redisplay done. */
/* If we can't insert glyphs, we can use this method only
at the end of a line. */
- if (!TTY_CHAR_INS_DEL_OK (FRAME_TTY (f)))
+ if (!FRAME_CHAR_INS_DEL_OK (f))
if (PT != ZV && FETCH_BYTE (PT_BYTE) != '\n')
return 0;
updated_row = glyph_row;
updated_area = TEXT_AREA;
update_begin (f);
- if (rif)
+ if (FRAME_RIF (f))
{
- rif->update_window_begin_hook (w);
+ FRAME_RIF (f)->update_window_begin_hook (w);
if (glyphs == end - n
/* In front of a space added by append_space. */
|| (glyphs == end - n - 1
&& (end - n)->charpos <= 0))
- rif->write_glyphs (glyphs, n);
+ FRAME_RIF (f)->write_glyphs (glyphs, n);
else
- rif->insert_glyphs (glyphs, n);
+ FRAME_RIF (f)->insert_glyphs (glyphs, n);
}
else
{
a frame matrix is used, cursor_to expects frame coordinates,
and the X and Y parameters are not used. */
if (window_redisplay_p)
- rif->cursor_to (w->cursor.vpos, w->cursor.hpos,
- w->cursor.y, w->cursor.x);
+ FRAME_RIF (f)->cursor_to (w->cursor.vpos, w->cursor.hpos,
+ w->cursor.y, w->cursor.x);
else
{
int x, y;
cursor_to (y, x);
}
- if (rif)
- rif->update_window_end_hook (w, 1, 0);
+ if (FRAME_RIF (f))
+ FRAME_RIF (f)->update_window_end_hook (w, 1, 0);
update_end (f);
updated_row = NULL;
- fflush (TTY_OUTPUT (CURTTY ()));
+ if (FRAME_TERMCAP_P (f))
+ fflush (TTY_OUTPUT (FRAME_TTY (f)));
TRACE ((stderr, "direct output for insert\n"));
mark_window_display_accurate (it.window, 1);
&& w->cursor.hpos < w->desired_matrix->matrix_w);
if (FRAME_WINDOW_P (f))
- rif->cursor_to (w->cursor.vpos, w->cursor.hpos,
- w->cursor.y, w->cursor.x);
+ FRAME_RIF (f)->cursor_to (w->cursor.vpos, w->cursor.hpos,
+ w->cursor.y, w->cursor.x);
else
{
int x, y;
cursor_to (y, x);
}
- fflush (TTY_OUTPUT (CURTTY ()));
+ if (FRAME_TERMCAP_P (f))
+ fflush (TTY_OUTPUT (FRAME_TTY (f)));
redisplay_performed_directly_p = 1;
return 1;
}
#if 0 /* This flush is a performance bottleneck under X,
and it doesn't seem to be necessary anyway. */
- rif->flush_display (f);
+ FRAME_RIF (f)->flush_display (f);
#endif
}
else
paused_p = update_frame_1 (f, force_p, inhibit_hairy_id_p);
update_end (f);
- if (TTY_TERMSCRIPT (FRAME_TTY (f)))
- fflush (TTY_TERMSCRIPT (FRAME_TTY (f)));
- fflush (TTY_OUTPUT (FRAME_TTY (f)));
+ if (FRAME_TERMCAP_P (f))
+ {
+ if (TTY_TERMSCRIPT (FRAME_TTY (f)))
+ fflush (TTY_TERMSCRIPT (FRAME_TTY (f)));
+ fflush (TTY_OUTPUT (FRAME_TTY (f)));
+ }
/* Check window matrices for lost pointers. */
#if GLYPH_DEBUG
int yb;
{
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
{
updated_row = row;
updated_area = area;
- rif->cursor_to (i, 0, row->y, area == TEXT_AREA ? row->x : 0);
+ FRAME_RIF (f)->cursor_to (i, 0, row->y,
+ area == TEXT_AREA ? row->x : 0);
if (row->used[area])
- rif->write_glyphs (row->glyphs[area], row->used[area]);
- rif->clear_end_of_line (-1);
+ FRAME_RIF (f)->write_glyphs (row->glyphs[area],
+ row->used[area]);
+ FRAME_RIF (f)->clear_end_of_line (-1);
}
row->overlapped_p = 0;
{
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;
#if GLYPH_DEBUG
struct frame *f = XFRAME (WINDOW_FRAME (w));
#endif
+ struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
/* Check that W's frame doesn't have glyph matrices. */
xassert (FRAME_WINDOW_P (f));
int area, vpos;
{
struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
+ struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
/* Let functions in xterm.c know what area subsequent X positions
will be relative to. */
{
struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
+ struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
int changed_p = 0;
/* Let functions in xterm.c know what area subsequent X positions
{
struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
+ struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
int changed_p = 0;
/* Set the row being updated. This is important to let xterm.c
struct window *w;
{
struct frame *f = XFRAME (w->frame);
+ struct redisplay_interface *rif = FRAME_RIF (f);
int cx, cy, vpos, hpos;
/* Not intended for frame matrix updates. */
int i, j, first_old, first_new, last_old, last_new;
int nruns, nbytes, n, run_idx;
struct row_entry *entry;
+ struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
/* Skip over rows equal at the start. */
for (i = header_line_p ? 1 : 0; i < current_matrix->nrows - 1; ++i)
}
/* If we cannot insert/delete lines, it's no use trying it. */
- if (!TTY_LINE_INS_DEL_OK (FRAME_TTY (f)))
+ if (!FRAME_LINE_INS_DEL_OK (f))
inhibit_id_p = 1;
/* See if any of the desired lines are enabled; don't compute for
}
/* If changed lines are few, don't allow preemption, don't scroll. */
- if ((!TTY_SCROLL_REGION_OK (FRAME_TTY (frame))
+ if ((!FRAME_SCROLL_REGION_OK (frame)
&& changed_lines < baud_rate / 2400)
|| unchanged_at_bottom == FRAME_LINES (frame))
return 1;
window_size = (FRAME_LINES (frame) - unchanged_at_top
- unchanged_at_bottom);
- if (TTY_SCROLL_REGION_OK (FRAME_TTY (frame)))
+ if (FRAME_SCROLL_REGION_OK (frame))
free_at_end_vpos -= unchanged_at_bottom;
- else if (TTY_MEMORY_BELOW_FRAME (FRAME_TTY (frame)))
+ else if (FRAME_MEMORY_BELOW_FRAME (frame))
free_at_end_vpos = -1;
/* If large window, fast terminal and few lines in common between
current frame and desired frame, don't bother with i/d calc. */
- if (!TTY_SCROLL_REGION_OK (FRAME_TTY (frame))
+ if (!FRAME_SCROLL_REGION_OK (frame)
&& window_size >= 18 && baud_rate > 2400
&& (window_size >=
10 * scrolling_max_lines_saved (unchanged_at_top,
struct glyph_row *current_row = MATRIX_ROW (current_matrix, vpos);
struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, vpos);
int must_write_whole_line_p;
- int write_spaces_p = TTY_MUST_WRITE_SPACES (FRAME_TTY (f));
+ int write_spaces_p = FRAME_MUST_WRITE_SPACES (f);
int colored_spaces_p = (FACE_FROM_ID (f, DEFAULT_FACE_ID)->background
!= FACE_TTY_DEFAULT_BG_COLOR);
nlen--;
/* If there's no i/d char, quickly do the best we can without it. */
- if (!TTY_CHAR_INS_DEL_OK (FRAME_TTY (f)))
+ if (!FRAME_CHAR_INS_DEL_OK (f))
{
int i, j;
tem = (nlen - nsp) - (olen - osp);
if (endmatch && tem
- && (!TTY_CHAR_INS_DEL_OK (FRAME_TTY (f))
+ && (!FRAME_CHAR_INS_DEL_OK (f)
|| endmatch <= char_ins_del_cost (f)[tem]))
endmatch = 0;
Is it worth it? */
if (nsp != osp
- && (!TTY_CHAR_INS_DEL_OK (FRAME_TTY (f))
+ && (!FRAME_CHAR_INS_DEL_OK (f)
|| begmatch + endmatch <= char_ins_del_cost (f)[nsp - osp]))
{
begmatch = 0;
***********************************************************************/
/* Determine what's under window-relative pixel position (*X, *Y).
- Return in *OBJECT the object (string or buffer) that's there.
- Return in *POS the position in that object. Adjust *X and *Y
- to character positions. */
+ Return the object (string or buffer) that's there.
+ Return in *POS the position in that object.
+ Adjust *X and *Y to character positions. */
-void
-buffer_posn_from_coords (w, x, y, dx, dy, object, pos)
+Lisp_Object
+buffer_posn_from_coords (w, x, y, pos, object, dx, dy, width, height)
struct window *w;
int *x, *y;
- int *dx, *dy;
- Lisp_Object *object;
struct display_pos *pos;
+ Lisp_Object *object;
+ int *dx, *dy;
+ int *width, *height;
{
struct it it;
struct buffer *old_current_buffer = current_buffer;
struct text_pos startp;
+ Lisp_Object string;
+ struct glyph_row *row;
int x0, x1;
current_buffer = XBUFFER (w->buffer);
*dx = x0 + it.first_visible_x - it.current_x;
*dy = *y - it.current_y;
- *object = w->buffer;
+ string = w->buffer;
+ if (STRINGP (it.string))
+ string = it.string;
+ *pos = it.current;
#ifdef HAVE_WINDOW_SYSTEM
if (it.what == IT_IMAGE)
struct image *img;
if ((img = IMAGE_FROM_ID (it.f, it.image_id)) != NULL
&& !NILP (img->spec))
- {
- struct glyph_row *row = MATRIX_ROW (w->current_matrix, it.vpos);
- struct glyph *glyph;
+ *object = img->spec;
+ }
+#endif
- if (it.hpos < row->used[TEXT_AREA]
- && (glyph = row->glyphs[TEXT_AREA] + it.hpos,
- glyph->type == IMAGE_GLYPH))
- {
- *dy -= row->ascent - glyph->ascent;
- *object = img->spec;
- }
+ row = MATRIX_ROW (w->current_matrix, it.vpos);
+ if (row->enabled_p)
+ {
+ if (it.hpos < row->used[TEXT_AREA])
+ {
+ struct glyph *glyph = row->glyphs[TEXT_AREA] + it.hpos;
+ *width = glyph->pixel_width;
+ *height = glyph->ascent + glyph->descent;
+#ifdef HAVE_WINDOW_SYSTEM
+ if (glyph->type == IMAGE_GLYPH)
+ *dy -= row->ascent - glyph->ascent;
+#endif
+ }
+ else
+ {
+ *width = 0;
+ *height = row->height;
}
}
else
-#endif
- if (STRINGP (it.string))
- *object = it.string;
-
- *pos = it.current;
+ {
+ *width = *height = 0;
+ }
/* Add extra (default width) columns if clicked after EOL. */
x1 = max(0, it.current_x + it.pixel_width - it.first_visible_x);
*x = it.hpos;
*y = it.vpos;
+
+ return string;
}
/* Value is the string under window-relative coordinates X/Y in the
- mode or header line of window W, or nil if none. MODE_LINE_P non-zero
- means look at the mode line. *CHARPOS is set to the position in
- the string returned. */
+ mode line or header line (PART says which) of window W, or nil if none.
+ *CHARPOS is set to the position in the string returned. */
Lisp_Object
-mode_line_string (w, x, y, dx, dy, part, charpos)
+mode_line_string (w, part, x, y, charpos, object, dx, dy, width, height)
struct window *w;
- int *x, *y;
- int *dx, *dy;
enum window_part part;
+ int *x, *y;
int *charpos;
+ Lisp_Object *object;
+ int *dx, *dy;
+ int *width, *height;
{
struct glyph_row *row;
struct glyph *glyph, *end;
{
string = glyph->object;
*charpos = glyph->charpos;
+ *width = glyph->pixel_width;
+ *height = glyph->ascent + glyph->descent;
+#ifdef HAVE_WINDOW_SYSTEM
+ if (glyph->type == IMAGE_GLYPH)
+ {
+ struct image *img;
+ img = IMAGE_FROM_ID (WINDOW_XFRAME (w), glyph->u.img_id);
+ if (img != NULL)
+ *object = img->spec;
+ y0 -= row->ascent - glyph->ascent;
+ }
+#endif
}
else
- /* Add extra (default width) columns if clicked after EOL. */
- *x += x0 / WINDOW_FRAME_COLUMN_WIDTH (w);
+ {
+ /* Add extra (default width) columns if clicked after EOL. */
+ *x += x0 / WINDOW_FRAME_COLUMN_WIDTH (w);
+ *width = 0;
+ *height = row->height;
+ }
}
else
{
*x = 0;
x0 = 0;
+ *width = *height = 0;
}
- if (dx)
- {
- *dx = x0;
- *dy = y0;
- }
+ *dx = x0;
+ *dy = y0;
return string;
}
the string returned. */
Lisp_Object
-marginal_area_string (w, x, y, dx, dy, part, charpos)
+marginal_area_string (w, part, x, y, charpos, object, dx, dy, width, height)
struct window *w;
- int *x, *y;
- int *dx, *dy;
enum window_part part;
+ int *x, *y;
int *charpos;
+ Lisp_Object *object;
+ int *dx, *dy;
+ int *width, *height;
{
struct glyph_row *row = w->current_matrix->rows;
struct glyph *glyph, *end;
{
string = glyph->object;
*charpos = glyph->charpos;
+ *width = glyph->pixel_width;
+ *height = glyph->ascent + glyph->descent;
#ifdef HAVE_WINDOW_SYSTEM
if (glyph->type == IMAGE_GLYPH)
{
struct image *img;
img = IMAGE_FROM_ID (WINDOW_XFRAME (w), glyph->u.img_id);
if (img != NULL)
- string = img->spec;
+ *object = img->spec;
y0 -= row->ascent - glyph->ascent;
}
#endif
}
else
- /* Add extra (default width) columns if clicked after EOL. */
- *x += x0 / WINDOW_FRAME_COLUMN_WIDTH (w);
+ {
+ /* Add extra (default width) columns if clicked after EOL. */
+ *x += x0 / WINDOW_FRAME_COLUMN_WIDTH (w);
+ *width = 0;
+ *height = row->height;
+ }
}
else
{
x0 = 0;
*x = 0;
+ *width = *height = 0;
}
- if (dx)
- {
- *dx = x0;
- *dy = y0;
- }
+ *dx = x0;
+ *dy = y0;
return string;
}
#endif
int old_errno = errno;
- struct tty_output *tty;
-
+ struct tty_display_info *tty;
+
/* The frame size change obviously applies to a single
termcap-controlled terminal, but we can't decide which.
Therefore, we resize the frames corresponding to each tty.
if (! tty->term_initted)
continue;
-
- get_tty_size (tty, &width, &height);
+
+ get_tty_size (fileno (TTY_INPUT (tty)), &width, &height);
{
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 structures
- now. Let that be done later outside of the signal handler. */
- change_frame_size (XFRAME (frame), height, width, 0, 1, 0);
- break;
- }
- }
+ if (FRAME_TERMCAP_P (XFRAME (frame)) && FRAME_TTY (XFRAME (frame)) == tty)
+ /* Record the new sizes, but don't reallocate the data
+ structures now. Let that be done later outside of the
+ signal handler. */
+ change_frame_size (XFRAME (frame), height, width, 0, 1, 0);
}
}
{
/* ??? Perhaps we should do something special for multibyte strings here. */
CHECK_STRING (string);
+ if (! FRAME_TERMCAP_P (SELECTED_FRAME ()))
+ error ("Current frame is not on a tty device");
+
if (TTY_TERMSCRIPT (CURTTY ()))
{
fwrite (SDATA (string), 1, SBYTES (string),
putchar (07);
else
ring_bell ();
- fflush (TTY_OUTPUT (CURTTY ()));
+ if (FRAME_TERMCAP_P (XFRAME (selected_frame)))
+ fflush (TTY_OUTPUT (CURTTY ()));
}
else
bitch_at_user ();
error ("Keyboard macro terminated by a command ringing the bell");
else
ring_bell ();
- fflush (TTY_OUTPUT (CURTTY ()));
+ if (FRAME_TERMCAP_P (XFRAME (selected_frame)))
+ fflush (TTY_OUTPUT (CURTTY ()));
}
/* Now is the time to initialize this; it's used by init_sys_modes
during startup. */
- Vwindow_system = Qnil;
+ Vinitial_window_system = Qnil;
/* If the user wants to use a window system, we shouldn't bother
initializing the terminal. This is especially important when the
#endif
)
{
- Vwindow_system = intern ("x");
+ Vinitial_window_system = intern ("x");
#ifdef HAVE_X11
Vwindow_system_version = make_number (11);
#else
#ifdef HAVE_NTGUI
if (!inhibit_window_system)
{
- Vwindow_system = intern ("w32");
+ Vinitial_window_system = intern ("w32");
Vwindow_system_version = make_number (1);
adjust_frame_glyphs_initially ();
return;
#ifdef MAC_OS
if (!inhibit_window_system)
{
- Vwindow_system = intern ("mac");
+ Vinitial_window_system = intern ("mac");
Vwindow_system_version = make_number (1);
adjust_frame_glyphs_initially ();
return;
#endif /* VMS */
{
- struct tty_output *tty;
-
- tty = term_init (selected_frame, 0, terminal_type);
- change_frame_size (XFRAME (selected_frame), FrameRows (tty), FrameCols (tty), 0, 0, 0);
+ struct display *d;
+ struct frame *f = XFRAME (selected_frame);
+
+ /* Open a display on the controlling tty. */
+ d = term_init (0, terminal_type, 1); /* Errors are fatal. */
+
+ /* Convert the initial frame to use the new display. */
+ if (! f->output_method == output_initial)
+ abort ();
+ f->output_method = d->type;
+ f->display = d;
+
+ d->reference_count++;
+ d->display_info.tty->top_frame = selected_frame;
+ change_frame_size (XFRAME (selected_frame), FrameRows (d->display_info.tty), FrameCols (d->display_info.tty), 0, 0, 1);
+
+ /* Delete the initial display. */
+ if (--initial_display->reference_count == 0
+ && initial_display->delete_display_hook)
+ (*initial_display->delete_display_hook) (initial_display);
}
{
and internal_terminal_init. */
&& (strcmp (terminal_type, "internal") != 0 || inhibit_window_system)
#endif
- && NILP (Vwindow_system))
+ && NILP (Vinitial_window_system))
{
/* For the initial frame, we don't have any way of knowing what
are the foreground and background colors of the terminal. */
Emacs's frame display when you reenter Emacs.
It is up to you to set this variable if your terminal can do that. */);
- DEFVAR_LISP ("window-system", &Vwindow_system,
- doc: /* Name of window system that Emacs is displaying through.
+ DEFVAR_LISP ("initial-window-system", &Vinitial_window_system,
+ doc: /* Name of the window system that Emacs uses for the first frame.
The value is a symbol--for instance, `x' for X windows.
The value is nil if Emacs is using a text-only terminal. */);
if (noninteractive)
#endif
{
- Vwindow_system = Qnil;
+ Vinitial_window_system = Qnil;
Vwindow_system_version = Qnil;
}
}