summaryrefslogtreecommitdiff
path: root/src/term.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/term.c')
-rw-r--r--src/term.c266
1 files changed, 234 insertions, 32 deletions
diff --git a/src/term.c b/src/term.c
index 1f524880054..330da251e18 100644
--- a/src/term.c
+++ b/src/term.c
@@ -65,11 +65,9 @@ static int been_here = -1;
#ifndef HAVE_ANDROID
static void tty_set_scroll_region (struct frame *f, int start, int stop);
-static void turn_on_face (struct frame *, int face_id);
-static void turn_off_face (struct frame *, int face_id);
+static void turn_on_face (struct frame *f, struct face *face);
+static void turn_off_face (struct frame *f, struct face *face);
static void tty_turn_off_highlight (struct tty_display_info *);
-static void tty_show_cursor (struct tty_display_info *);
-static void tty_hide_cursor (struct tty_display_info *);
static void tty_background_highlight (struct tty_display_info *tty);
static void clear_tty_hooks (struct terminal *terminal);
static void set_tty_hooks (struct terminal *terminal);
@@ -336,7 +334,7 @@ tty_toggle_highlight (struct tty_display_info *tty)
/* Make cursor invisible. */
-static void
+void
tty_hide_cursor (struct tty_display_info *tty)
{
if (tty->cursor_hidden == 0)
@@ -353,7 +351,7 @@ tty_hide_cursor (struct tty_display_info *tty)
/* Ensure that cursor is visible. */
-static void
+void
tty_show_cursor (struct tty_display_info *tty)
{
if (tty->cursor_hidden)
@@ -788,13 +786,20 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len)
/* Identify a run of glyphs with the same face. */
int face_id = string->face_id;
+ /* FIXME/tty: it happens that a single glyph's frame is NULL. It
+ might depend on a tab bar line being present, then switching
+ from a buffer without header line to one with header line and
+ opening a child frame. */
+ struct frame *face_id_frame = string->frame ? string->frame : f;
+
for (n = 1; n < stringlen; ++n)
- if (string[n].face_id != face_id)
+ if (string[n].face_id != face_id || string[n].frame != face_id_frame)
break;
/* Turn appearance modes of the face of the run on. */
tty_highlight_if_desired (tty);
- turn_on_face (f, face_id);
+ struct face *face = FACE_FROM_ID (face_id_frame, face_id);
+ turn_on_face (f, face);
if (n == stringlen)
/* This is the last run. */
@@ -812,7 +817,7 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len)
string += n;
/* Turn appearance modes off. */
- turn_off_face (f, face_id);
+ turn_off_face (f, face);
tty_turn_off_highlight (tty);
}
@@ -822,8 +827,8 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len)
#ifndef DOS_NT
static void
-tty_write_glyphs_with_face (register struct frame *f, register struct glyph *string,
- register int len, register int face_id)
+tty_write_glyphs_with_face (struct frame *f, struct glyph *string,
+ int len, struct face *face)
{
unsigned char *conversion_buffer;
struct coding_system *coding;
@@ -856,7 +861,7 @@ tty_write_glyphs_with_face (register struct frame *f, register struct glyph *str
/* Turn appearance modes of the face. */
tty_highlight_if_desired (tty);
- turn_on_face (f, face_id);
+ turn_on_face (f, face);
coding->mode |= CODING_MODE_LAST_BLOCK;
conversion_buffer = encode_terminal_code (string, len, coding);
@@ -871,7 +876,7 @@ tty_write_glyphs_with_face (register struct frame *f, register struct glyph *str
}
/* Turn appearance modes off. */
- turn_off_face (f, face_id);
+ turn_off_face (f, face);
tty_turn_off_highlight (tty);
cmcheckmagic (tty);
@@ -919,6 +924,7 @@ tty_insert_glyphs (struct frame *f, struct glyph *start, int len)
while (len-- > 0)
{
+ struct face *face = NULL;
OUTPUT1_IF (tty, tty->TS_ins_char);
if (!start)
{
@@ -928,7 +934,10 @@ tty_insert_glyphs (struct frame *f, struct glyph *start, int len)
else
{
tty_highlight_if_desired (tty);
- turn_on_face (f, start->face_id);
+ int face_id = start->face_id;
+ struct frame *face_id_frame = start->frame;
+ face = FACE_FROM_ID (face_id_frame, face_id);
+ turn_on_face (f, face);
glyph = start;
++start;
/* We must open sufficient space for a character which
@@ -957,9 +966,9 @@ tty_insert_glyphs (struct frame *f, struct glyph *start, int len)
}
OUTPUT1_IF (tty, tty->TS_pad_inserted_char);
- if (start)
+ if (face)
{
- turn_off_face (f, glyph->face_id);
+ turn_off_face (f, face);
tty_turn_off_highlight (tty);
}
}
@@ -1542,6 +1551,7 @@ append_glyph (struct it *it)
glyph->type = CHAR_GLYPH;
glyph->pixel_width = 1;
glyph->u.ch = it->char_to_display;
+ glyph->frame = it->f;
glyph->face_id = it->face_id;
glyph->avoid_cursor_p = it->avoid_cursor_p;
glyph->multibyte_p = it->multibyte_p;
@@ -1769,6 +1779,7 @@ append_composite_glyph (struct it *it)
glyph->avoid_cursor_p = it->avoid_cursor_p;
glyph->multibyte_p = it->multibyte_p;
+ glyph->frame = it->f;
glyph->face_id = it->face_id;
glyph->padding_p = false;
glyph->charpos = CHARPOS (it->position);
@@ -1855,6 +1866,7 @@ append_glyphless_glyph (struct it *it, int face_id, const char *str)
glyph->pixel_width = 1;
glyph->avoid_cursor_p = it->avoid_cursor_p;
glyph->multibyte_p = it->multibyte_p;
+ glyph->frame = it->f;
glyph->face_id = face_id;
glyph->padding_p = false;
glyph->charpos = CHARPOS (it->position);
@@ -1981,9 +1993,8 @@ produce_glyphless_glyph (struct it *it, Lisp_Object acronym)
FACE_ID is a realized face ID number, in the face cache. */
static void
-turn_on_face (struct frame *f, int face_id)
+turn_on_face (struct frame *f, struct face *face)
{
- struct face *face = FACE_FROM_ID (f, face_id);
unsigned long fg = face->foreground;
unsigned long bg = face->background;
struct tty_display_info *tty = FRAME_TTY (f);
@@ -2064,9 +2075,8 @@ turn_on_face (struct frame *f, int face_id)
/* Turn off appearances of face FACE_ID on tty frame F. */
static void
-turn_off_face (struct frame *f, int face_id)
+turn_off_face (struct frame *f, struct face *face)
{
- struct face *face = FACE_FROM_ID (f, face_id);
struct tty_display_info *tty = FRAME_TTY (f);
if (tty->TS_exit_attribute_mode)
@@ -2399,8 +2409,10 @@ A suspended tty may be resumed by calling `resume-tty' on it. */)
t->display_info.tty->output = 0;
if (FRAMEP (t->display_info.tty->top_frame))
- SET_FRAME_VISIBLE (XFRAME (t->display_info.tty->top_frame), 0);
-
+ {
+ struct frame *top = XFRAME (t->display_info.tty->top_frame);
+ SET_FRAME_VISIBLE (root_frame (top), false);
+ }
}
/* Clear display hooks to prevent further output. */
@@ -2472,7 +2484,8 @@ frame's terminal). */)
if (FRAMEP (t->display_info.tty->top_frame))
{
- struct frame *f = XFRAME (t->display_info.tty->top_frame);
+ struct frame *top = XFRAME (t->display_info.tty->top_frame);
+ struct frame *f = root_frame (top);
int width, height;
int old_height = FRAME_COLS (f);
int old_width = FRAME_TOTAL_LINES (f);
@@ -2482,7 +2495,7 @@ frame's terminal). */)
get_tty_size (fileno (t->display_info.tty->input), &width, &height);
if (width != old_width || height != old_height)
change_frame_size (f, width, height, false, false, false);
- SET_FRAME_VISIBLE (XFRAME (t->display_info.tty->top_frame), 1);
+ SET_FRAME_VISIBLE (f, true);
}
set_tty_hooks (t);
@@ -2563,22 +2576,24 @@ tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row,
struct frame *f = XFRAME (WINDOW_FRAME (w));
struct tty_display_info *tty = FRAME_TTY (f);
int face_id = tty->mouse_highlight.mouse_face_face_id;
- int save_x, save_y, pos_x, pos_y;
if (end_hpos >= row->used[TEXT_AREA])
nglyphs = row->used[TEXT_AREA] - start_hpos;
- pos_y = row->y + WINDOW_TOP_EDGE_Y (w);
- pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos + WINDOW_LEFT_EDGE_X (w);
+ int pos_y = row->y + WINDOW_TOP_EDGE_Y (w);
+ int pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos + WINDOW_LEFT_EDGE_X (w);
/* Save current cursor coordinates. */
- save_y = curY (tty);
- save_x = curX (tty);
+ int save_y = curY (tty);
+ int save_x = curX (tty);
cursor_to (f, pos_y, pos_x);
if (draw == DRAW_MOUSE_FACE)
- tty_write_glyphs_with_face (f, row->glyphs[TEXT_AREA] + start_hpos,
- nglyphs, face_id);
+ {
+ struct glyph *glyph = row->glyphs[TEXT_AREA] + start_hpos;
+ struct face *face = FACE_FROM_ID (f, face_id);
+ tty_write_glyphs_with_face (f, glyph, nglyphs, face);
+ }
else if (draw == DRAW_NORMAL_TEXT)
write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs);
@@ -3969,7 +3984,7 @@ tty_free_frame_resources (struct frame *f)
#endif
-
+
#ifndef HAVE_ANDROID
@@ -4044,6 +4059,8 @@ set_tty_hooks (struct terminal *terminal)
terminal->read_socket_hook = &tty_read_avail_input; /* keyboard.c */
terminal->delete_frame_hook = &tty_free_frame_resources;
terminal->delete_terminal_hook = &delete_tty;
+
+ terminal->frame_raise_lower_hook = tty_raise_lower_frame;
/* Other hooks are NULL by default. */
}
@@ -4714,6 +4731,184 @@ delete_tty (struct terminal *terminal)
#endif
+/* Return geometric attributes of FRAME. According to the value of
+ ATTRIBUTES return the outer edges of FRAME (Qouter_edges), the
+ native edges of FRAME (Qnative_edges), or the inner edges of frame
+ (Qinner_edges). Any other value means to return the geometry as
+ returned by Fx_frame_geometry. */
+
+static Lisp_Object
+tty_frame_geometry (Lisp_Object frame, Lisp_Object attribute)
+{
+ struct frame *f = decode_live_frame (frame);
+ if (FRAME_INITIAL_P (f) || !FRAME_TTY (f))
+ return Qnil;
+
+ int native_width = f->pixel_width;
+ int native_height = f->pixel_height;
+
+ eassert (FRAME_PARENT_FRAME (f) || (f->left_pos == 0 && f->top_pos == 0));
+ int outer_left = f->left_pos;
+ int outer_top = f->top_pos;
+ int outer_right = outer_left + native_width;
+ int outer_bottom = outer_top + native_height;
+
+ int native_left = outer_left;
+ int native_top = outer_top;
+ int native_right = outer_right;
+ int native_bottom = outer_bottom;
+
+ int internal_border_width = FRAME_INTERNAL_BORDER_WIDTH (f);
+ int inner_left = native_left + internal_border_width;
+ int inner_top = native_top + internal_border_width;
+ int inner_right = native_right - internal_border_width;
+ int inner_bottom = native_bottom - internal_border_width;
+
+ int menu_bar_height = FRAME_MENU_BAR_HEIGHT (f);
+ inner_top += menu_bar_height;
+ int menu_bar_width = menu_bar_height ? native_width : 0;
+
+ int tab_bar_height = FRAME_TAB_BAR_HEIGHT (f);
+ int tab_bar_width = (tab_bar_height
+ ? native_width - 2 * internal_border_width
+ : 0);
+ inner_top += tab_bar_height;
+
+ int tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f);
+ int tool_bar_width = (tool_bar_height
+ ? native_width - 2 * internal_border_width
+ : 0);
+
+ /* Subtract or add to the inner dimensions based on the tool bar
+ position. */
+ if (EQ (FRAME_TOOL_BAR_POSITION (f), Qtop))
+ inner_top += tool_bar_height;
+ else
+ inner_bottom -= tool_bar_height;
+
+ /* Construct list. */
+ if (EQ (attribute, Qouter_edges))
+ return list4i (outer_left, outer_top, outer_right, outer_bottom);
+ else if (EQ (attribute, Qnative_edges))
+ return list4i (native_left, native_top, native_right, native_bottom);
+ else if (EQ (attribute, Qinner_edges))
+ return list4i (inner_left, inner_top, inner_right, inner_bottom);
+ else
+ return list (Fcons (Qouter_position, Fcons (make_fixnum (outer_left),
+ make_fixnum (outer_top))),
+ Fcons (Qouter_size,
+ Fcons (make_fixnum (outer_right - outer_left),
+ make_fixnum (outer_bottom - outer_top))),
+ Fcons (Qouter_border_width, make_fixnum (0)),
+ Fcons (Qexternal_border_size,
+ Fcons (make_fixnum (0), make_fixnum (0))),
+ Fcons (Qtitle_bar_size,
+ Fcons (make_fixnum (0), make_fixnum (0))),
+ Fcons (Qmenu_bar_external, Qnil),
+ Fcons (Qmenu_bar_size,
+ Fcons (make_fixnum (menu_bar_width),
+ make_fixnum (menu_bar_height))),
+ Fcons (Qtab_bar_size,
+ Fcons (make_fixnum (tab_bar_width),
+ make_fixnum (tab_bar_height))),
+ Fcons (Qtool_bar_external, Qnil),
+ Fcons (Qtool_bar_position, FRAME_TOOL_BAR_POSITION (f)),
+ Fcons (Qtool_bar_size,
+ Fcons (make_fixnum (tool_bar_width),
+ make_fixnum (tool_bar_height))),
+ Fcons (Qinternal_border_width,
+ make_fixnum (internal_border_width)));
+}
+
+DEFUN ("tty-frame-geometry", Ftty_frame_geometry, Stty_frame_geometry, 0, 1, 0,
+ doc: /* Return geometric attributes of terminal frame FRAME.
+ See also `frame-geometry'. */)
+ (Lisp_Object frame)
+{
+ return tty_frame_geometry (frame, Qnil);
+}
+
+DEFUN ("tty-frame-edges", Ftty_frame_edges, Stty_frame_edges, 0, 2, 0,
+ doc: /* Return coordinates of FRAME's edges.
+ See also `frame-edges'. */)
+ (Lisp_Object frame, Lisp_Object type)
+{
+ if (!EQ (type, Qouter_edges) && !EQ (type, Qinner_edges))
+ type = Qnative_edges;
+ return tty_frame_geometry (frame, type);
+}
+
+DEFUN ("tty-frame-list-z-order", Ftty_frame_list_z_order,
+ Stty_frame_list_z_order, 0, 1, 0,
+ doc: /* Return list of Emacs's frames, in Z (stacking) order.
+ See also `frame-list-z-order'. */)
+ (Lisp_Object frame)
+{
+ struct frame *f = decode_tty_frame (frame);
+ Lisp_Object frames = frames_in_reverse_z_order (f, true);
+ return Fnreverse (frames);
+}
+
+DEFUN ("tty-frame-restack", Ftty_frame_restack,
+ Stty_frame_restack, 2, 3, 0,
+ doc: /* Restack FRAME1 below FRAME2 on terminals.
+. See also `frame-restack'. */)
+ (Lisp_Object frame1, Lisp_Object frame2, Lisp_Object above)
+{
+ /* FIXME/tty: tty-frame-restack implementation. */
+ return Qnil;
+}
+
+static void
+tty_display_dimension (Lisp_Object frame, int *width, int *height)
+{
+ if (!FRAMEP (frame))
+ frame = Fselected_frame ();
+ struct frame *f = XFRAME (frame);
+ switch (f->output_method)
+ {
+ case output_initial:
+ *width = 80;
+ *height = 25;
+ break;
+ case output_termcap:
+ *width = FrameCols (FRAME_TTY (f));
+ *height = FrameRows (FRAME_TTY (f));
+ break;
+ case output_x_window:
+ case output_msdos_raw:
+ case output_w32:
+ case output_ns:
+ case output_pgtk:
+ case output_haiku:
+ case output_android:
+ emacs_abort ();
+ break;
+ }
+}
+
+DEFUN ("tty-display-pixel-width", Ftty_display_pixel_width,
+ Stty_display_pixel_width, 0, 1, 0,
+ doc: /* Return the width of DISPLAY's screen in pixels.
+. See also `display-pixel-width'. */)
+ (Lisp_Object display)
+{
+ int width, height;
+ tty_display_dimension (display, &width, &height);
+ return make_fixnum (width);
+}
+
+DEFUN ("tty-display-pixel-height", Ftty_display_pixel_height,
+ Stty_display_pixel_height, 0, 1, 0,
+ doc: /* Return the height of DISPLAY's screen in pixels.
+ See also `display-pixel-height'. */)
+ (Lisp_Object display)
+{
+ int width, height;
+ tty_display_dimension (display, &width, &height);
+ return make_fixnum (height);
+}
+
void
syms_of_term (void)
{
@@ -4770,6 +4965,13 @@ trigger redisplay. */);
defsubr (&Sgpm_mouse_stop);
#endif /* HAVE_GPM */
+ defsubr (&Stty_frame_geometry);
+ defsubr (&Stty_frame_edges);
+ defsubr (&Stty_frame_list_z_order);
+ defsubr (&Stty_frame_restack);
+ defsubr (&Stty_display_pixel_width);
+ defsubr (&Stty_display_pixel_height);
+
#if !defined DOS_NT && !defined HAVE_ANDROID
default_orig_pair = NULL;
default_set_foreground = NULL;