aboutsummaryrefslogtreecommitdiffstats
path: root/src/term.c
diff options
context:
space:
mode:
authorGerd Möllmann2024-10-05 18:55:18 +0200
committerGerd Möllmann2024-10-05 18:55:18 +0200
commitbeb5b77123619758c1def6b9f227fa7568516775 (patch)
tree809e025df6a48b10f3022558f23840a8def6cbec /src/term.c
parent069ecc9c4c3709246a6ff50d09af418444d427c3 (diff)
downloademacs-tty-child-frames.tar.gz
emacs-tty-child-frames.zip
Preview from my branch on githubtty-child-frames
Diffstat (limited to 'src/term.c')
-rw-r--r--src/term.c253
1 files changed, 227 insertions, 26 deletions
diff --git a/src/term.c b/src/term.c
index 1f524880054..37c0780b555 100644
--- a/src/term.c
+++ b/src/term.c
@@ -65,8 +65,8 @@ static int been_here = -1;
65#ifndef HAVE_ANDROID 65#ifndef HAVE_ANDROID
66 66
67static void tty_set_scroll_region (struct frame *f, int start, int stop); 67static void tty_set_scroll_region (struct frame *f, int start, int stop);
68static void turn_on_face (struct frame *, int face_id); 68static void turn_on_face (struct frame *f, struct face *face);
69static void turn_off_face (struct frame *, int face_id); 69static void turn_off_face (struct frame *f, struct face *face);
70static void tty_turn_off_highlight (struct tty_display_info *); 70static void tty_turn_off_highlight (struct tty_display_info *);
71static void tty_show_cursor (struct tty_display_info *); 71static void tty_show_cursor (struct tty_display_info *);
72static void tty_hide_cursor (struct tty_display_info *); 72static void tty_hide_cursor (struct tty_display_info *);
@@ -788,13 +788,20 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len)
788 /* Identify a run of glyphs with the same face. */ 788 /* Identify a run of glyphs with the same face. */
789 int face_id = string->face_id; 789 int face_id = string->face_id;
790 790
791 /* FIXME/tty: it happens that a single glyph's frame is NULL. It
792 might depend on a tab bar line being present, then switching
793 from a buffer without header line to one with header line and
794 opening a child frame. */
795 struct frame *face_id_frame = string->frame ? string->frame : f;
796
791 for (n = 1; n < stringlen; ++n) 797 for (n = 1; n < stringlen; ++n)
792 if (string[n].face_id != face_id) 798 if (string[n].face_id != face_id || string[n].frame != face_id_frame)
793 break; 799 break;
794 800
795 /* Turn appearance modes of the face of the run on. */ 801 /* Turn appearance modes of the face of the run on. */
796 tty_highlight_if_desired (tty); 802 tty_highlight_if_desired (tty);
797 turn_on_face (f, face_id); 803 struct face *face = FACE_FROM_ID (face_id_frame, face_id);
804 turn_on_face (f, face);
798 805
799 if (n == stringlen) 806 if (n == stringlen)
800 /* This is the last run. */ 807 /* This is the last run. */
@@ -812,7 +819,7 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len)
812 string += n; 819 string += n;
813 820
814 /* Turn appearance modes off. */ 821 /* Turn appearance modes off. */
815 turn_off_face (f, face_id); 822 turn_off_face (f, face);
816 tty_turn_off_highlight (tty); 823 tty_turn_off_highlight (tty);
817 } 824 }
818 825
@@ -822,8 +829,8 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len)
822#ifndef DOS_NT 829#ifndef DOS_NT
823 830
824static void 831static void
825tty_write_glyphs_with_face (register struct frame *f, register struct glyph *string, 832tty_write_glyphs_with_face (struct frame *f, struct glyph *string,
826 register int len, register int face_id) 833 int len, struct face *face)
827{ 834{
828 unsigned char *conversion_buffer; 835 unsigned char *conversion_buffer;
829 struct coding_system *coding; 836 struct coding_system *coding;
@@ -856,7 +863,7 @@ tty_write_glyphs_with_face (register struct frame *f, register struct glyph *str
856 863
857 /* Turn appearance modes of the face. */ 864 /* Turn appearance modes of the face. */
858 tty_highlight_if_desired (tty); 865 tty_highlight_if_desired (tty);
859 turn_on_face (f, face_id); 866 turn_on_face (f, face);
860 867
861 coding->mode |= CODING_MODE_LAST_BLOCK; 868 coding->mode |= CODING_MODE_LAST_BLOCK;
862 conversion_buffer = encode_terminal_code (string, len, coding); 869 conversion_buffer = encode_terminal_code (string, len, coding);
@@ -871,7 +878,7 @@ tty_write_glyphs_with_face (register struct frame *f, register struct glyph *str
871 } 878 }
872 879
873 /* Turn appearance modes off. */ 880 /* Turn appearance modes off. */
874 turn_off_face (f, face_id); 881 turn_off_face (f, face);
875 tty_turn_off_highlight (tty); 882 tty_turn_off_highlight (tty);
876 883
877 cmcheckmagic (tty); 884 cmcheckmagic (tty);
@@ -919,6 +926,7 @@ tty_insert_glyphs (struct frame *f, struct glyph *start, int len)
919 926
920 while (len-- > 0) 927 while (len-- > 0)
921 { 928 {
929 struct face *face = NULL;
922 OUTPUT1_IF (tty, tty->TS_ins_char); 930 OUTPUT1_IF (tty, tty->TS_ins_char);
923 if (!start) 931 if (!start)
924 { 932 {
@@ -928,7 +936,10 @@ tty_insert_glyphs (struct frame *f, struct glyph *start, int len)
928 else 936 else
929 { 937 {
930 tty_highlight_if_desired (tty); 938 tty_highlight_if_desired (tty);
931 turn_on_face (f, start->face_id); 939 int face_id = start->face_id;
940 struct frame *face_id_frame = start->frame;
941 face = FACE_FROM_ID (face_id_frame, face_id);
942 turn_on_face (f, face);
932 glyph = start; 943 glyph = start;
933 ++start; 944 ++start;
934 /* We must open sufficient space for a character which 945 /* We must open sufficient space for a character which
@@ -957,9 +968,9 @@ tty_insert_glyphs (struct frame *f, struct glyph *start, int len)
957 } 968 }
958 969
959 OUTPUT1_IF (tty, tty->TS_pad_inserted_char); 970 OUTPUT1_IF (tty, tty->TS_pad_inserted_char);
960 if (start) 971 if (face)
961 { 972 {
962 turn_off_face (f, glyph->face_id); 973 turn_off_face (f, face);
963 tty_turn_off_highlight (tty); 974 tty_turn_off_highlight (tty);
964 } 975 }
965 } 976 }
@@ -1542,6 +1553,7 @@ append_glyph (struct it *it)
1542 glyph->type = CHAR_GLYPH; 1553 glyph->type = CHAR_GLYPH;
1543 glyph->pixel_width = 1; 1554 glyph->pixel_width = 1;
1544 glyph->u.ch = it->char_to_display; 1555 glyph->u.ch = it->char_to_display;
1556 glyph->frame = it->f;
1545 glyph->face_id = it->face_id; 1557 glyph->face_id = it->face_id;
1546 glyph->avoid_cursor_p = it->avoid_cursor_p; 1558 glyph->avoid_cursor_p = it->avoid_cursor_p;
1547 glyph->multibyte_p = it->multibyte_p; 1559 glyph->multibyte_p = it->multibyte_p;
@@ -1769,6 +1781,7 @@ append_composite_glyph (struct it *it)
1769 1781
1770 glyph->avoid_cursor_p = it->avoid_cursor_p; 1782 glyph->avoid_cursor_p = it->avoid_cursor_p;
1771 glyph->multibyte_p = it->multibyte_p; 1783 glyph->multibyte_p = it->multibyte_p;
1784 glyph->frame = it->f;
1772 glyph->face_id = it->face_id; 1785 glyph->face_id = it->face_id;
1773 glyph->padding_p = false; 1786 glyph->padding_p = false;
1774 glyph->charpos = CHARPOS (it->position); 1787 glyph->charpos = CHARPOS (it->position);
@@ -1855,6 +1868,7 @@ append_glyphless_glyph (struct it *it, int face_id, const char *str)
1855 glyph->pixel_width = 1; 1868 glyph->pixel_width = 1;
1856 glyph->avoid_cursor_p = it->avoid_cursor_p; 1869 glyph->avoid_cursor_p = it->avoid_cursor_p;
1857 glyph->multibyte_p = it->multibyte_p; 1870 glyph->multibyte_p = it->multibyte_p;
1871 glyph->frame = it->f;
1858 glyph->face_id = face_id; 1872 glyph->face_id = face_id;
1859 glyph->padding_p = false; 1873 glyph->padding_p = false;
1860 glyph->charpos = CHARPOS (it->position); 1874 glyph->charpos = CHARPOS (it->position);
@@ -1981,9 +1995,8 @@ produce_glyphless_glyph (struct it *it, Lisp_Object acronym)
1981 FACE_ID is a realized face ID number, in the face cache. */ 1995 FACE_ID is a realized face ID number, in the face cache. */
1982 1996
1983static void 1997static void
1984turn_on_face (struct frame *f, int face_id) 1998turn_on_face (struct frame *f, struct face *face)
1985{ 1999{
1986 struct face *face = FACE_FROM_ID (f, face_id);
1987 unsigned long fg = face->foreground; 2000 unsigned long fg = face->foreground;
1988 unsigned long bg = face->background; 2001 unsigned long bg = face->background;
1989 struct tty_display_info *tty = FRAME_TTY (f); 2002 struct tty_display_info *tty = FRAME_TTY (f);
@@ -2064,9 +2077,8 @@ turn_on_face (struct frame *f, int face_id)
2064/* Turn off appearances of face FACE_ID on tty frame F. */ 2077/* Turn off appearances of face FACE_ID on tty frame F. */
2065 2078
2066static void 2079static void
2067turn_off_face (struct frame *f, int face_id) 2080turn_off_face (struct frame *f, struct face *face)
2068{ 2081{
2069 struct face *face = FACE_FROM_ID (f, face_id);
2070 struct tty_display_info *tty = FRAME_TTY (f); 2082 struct tty_display_info *tty = FRAME_TTY (f);
2071 2083
2072 if (tty->TS_exit_attribute_mode) 2084 if (tty->TS_exit_attribute_mode)
@@ -2399,7 +2411,7 @@ A suspended tty may be resumed by calling `resume-tty' on it. */)
2399 t->display_info.tty->output = 0; 2411 t->display_info.tty->output = 0;
2400 2412
2401 if (FRAMEP (t->display_info.tty->top_frame)) 2413 if (FRAMEP (t->display_info.tty->top_frame))
2402 SET_FRAME_VISIBLE (XFRAME (t->display_info.tty->top_frame), 0); 2414 SET_FRAME_VISIBLE (XFRAME (t->display_info.tty->top_frame), false);
2403 2415
2404 } 2416 }
2405 2417
@@ -2482,7 +2494,7 @@ frame's terminal). */)
2482 get_tty_size (fileno (t->display_info.tty->input), &width, &height); 2494 get_tty_size (fileno (t->display_info.tty->input), &width, &height);
2483 if (width != old_width || height != old_height) 2495 if (width != old_width || height != old_height)
2484 change_frame_size (f, width, height, false, false, false); 2496 change_frame_size (f, width, height, false, false, false);
2485 SET_FRAME_VISIBLE (XFRAME (t->display_info.tty->top_frame), 1); 2497 SET_FRAME_VISIBLE (XFRAME (t->display_info.tty->top_frame), true);
2486 } 2498 }
2487 2499
2488 set_tty_hooks (t); 2500 set_tty_hooks (t);
@@ -2563,22 +2575,24 @@ tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row,
2563 struct frame *f = XFRAME (WINDOW_FRAME (w)); 2575 struct frame *f = XFRAME (WINDOW_FRAME (w));
2564 struct tty_display_info *tty = FRAME_TTY (f); 2576 struct tty_display_info *tty = FRAME_TTY (f);
2565 int face_id = tty->mouse_highlight.mouse_face_face_id; 2577 int face_id = tty->mouse_highlight.mouse_face_face_id;
2566 int save_x, save_y, pos_x, pos_y;
2567 2578
2568 if (end_hpos >= row->used[TEXT_AREA]) 2579 if (end_hpos >= row->used[TEXT_AREA])
2569 nglyphs = row->used[TEXT_AREA] - start_hpos; 2580 nglyphs = row->used[TEXT_AREA] - start_hpos;
2570 2581
2571 pos_y = row->y + WINDOW_TOP_EDGE_Y (w); 2582 int pos_y = row->y + WINDOW_TOP_EDGE_Y (w);
2572 pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos + WINDOW_LEFT_EDGE_X (w); 2583 int pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos + WINDOW_LEFT_EDGE_X (w);
2573 2584
2574 /* Save current cursor coordinates. */ 2585 /* Save current cursor coordinates. */
2575 save_y = curY (tty); 2586 int save_y = curY (tty);
2576 save_x = curX (tty); 2587 int save_x = curX (tty);
2577 cursor_to (f, pos_y, pos_x); 2588 cursor_to (f, pos_y, pos_x);
2578 2589
2579 if (draw == DRAW_MOUSE_FACE) 2590 if (draw == DRAW_MOUSE_FACE)
2580 tty_write_glyphs_with_face (f, row->glyphs[TEXT_AREA] + start_hpos, 2591 {
2581 nglyphs, face_id); 2592 struct glyph *glyph = row->glyphs[TEXT_AREA] + start_hpos;
2593 struct face *face = FACE_FROM_ID (glyph->frame, face_id);
2594 tty_write_glyphs_with_face (f, glyph, nglyphs, face);
2595 }
2582 else if (draw == DRAW_NORMAL_TEXT) 2596 else if (draw == DRAW_NORMAL_TEXT)
2583 write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs); 2597 write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs);
2584 2598
@@ -3969,7 +3983,7 @@ tty_free_frame_resources (struct frame *f)
3969 3983
3970#endif 3984#endif
3971 3985
3972 3986
3973 3987
3974#ifndef HAVE_ANDROID 3988#ifndef HAVE_ANDROID
3975 3989
@@ -4044,6 +4058,8 @@ set_tty_hooks (struct terminal *terminal)
4044 terminal->read_socket_hook = &tty_read_avail_input; /* keyboard.c */ 4058 terminal->read_socket_hook = &tty_read_avail_input; /* keyboard.c */
4045 terminal->delete_frame_hook = &tty_free_frame_resources; 4059 terminal->delete_frame_hook = &tty_free_frame_resources;
4046 terminal->delete_terminal_hook = &delete_tty; 4060 terminal->delete_terminal_hook = &delete_tty;
4061
4062 terminal->frame_raise_lower_hook = tty_raise_lower_frame;
4047 /* Other hooks are NULL by default. */ 4063 /* Other hooks are NULL by default. */
4048} 4064}
4049 4065
@@ -4714,6 +4730,184 @@ delete_tty (struct terminal *terminal)
4714 4730
4715#endif 4731#endif
4716 4732
4733/* Return geometric attributes of FRAME. According to the value of
4734 ATTRIBUTES return the outer edges of FRAME (Qouter_edges), the
4735 native edges of FRAME (Qnative_edges), or the inner edges of frame
4736 (Qinner_edges). Any other value means to return the geometry as
4737 returned by Fx_frame_geometry. */
4738
4739static Lisp_Object
4740tty_frame_geometry (Lisp_Object frame, Lisp_Object attribute)
4741{
4742 struct frame *f = decode_live_frame (frame);
4743 if (FRAME_INITIAL_P (f) || !FRAME_TTY (f))
4744 return Qnil;
4745
4746 int native_width = f->pixel_width;
4747 int native_height = f->pixel_height;
4748
4749 eassert (FRAME_PARENT_FRAME (f) || (f->left_pos == 0 && f->top_pos == 0));
4750 int outer_left = f->left_pos;
4751 int outer_top = f->top_pos;
4752 int outer_right = outer_left + native_width;
4753 int outer_bottom = outer_top + native_height;
4754
4755 int native_left = outer_left;
4756 int native_top = outer_top;
4757 int native_right = outer_right;
4758 int native_bottom = outer_bottom;
4759
4760 int internal_border_width = FRAME_INTERNAL_BORDER_WIDTH (f);
4761 int inner_left = native_left + internal_border_width;
4762 int inner_top = native_top + internal_border_width;
4763 int inner_right = native_right - internal_border_width;
4764 int inner_bottom = native_bottom - internal_border_width;
4765
4766 int menu_bar_height = FRAME_MENU_BAR_HEIGHT (f);
4767 inner_top += menu_bar_height;
4768 int menu_bar_width = menu_bar_height ? native_width : 0;
4769
4770 int tab_bar_height = FRAME_TAB_BAR_HEIGHT (f);
4771 int tab_bar_width = (tab_bar_height
4772 ? native_width - 2 * internal_border_width
4773 : 0);
4774 inner_top += tab_bar_height;
4775
4776 int tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f);
4777 int tool_bar_width = (tool_bar_height
4778 ? native_width - 2 * internal_border_width
4779 : 0);
4780
4781 /* Subtract or add to the inner dimensions based on the tool bar
4782 position. */
4783 if (EQ (FRAME_TOOL_BAR_POSITION (f), Qtop))
4784 inner_top += tool_bar_height;
4785 else
4786 inner_bottom -= tool_bar_height;
4787
4788 /* Construct list. */
4789 if (EQ (attribute, Qouter_edges))
4790 return list4i (outer_left, outer_top, outer_right, outer_bottom);
4791 else if (EQ (attribute, Qnative_edges))
4792 return list4i (native_left, native_top, native_right, native_bottom);
4793 else if (EQ (attribute, Qinner_edges))
4794 return list4i (inner_left, inner_top, inner_right, inner_bottom);
4795 else
4796 return list (Fcons (Qouter_position, Fcons (make_fixnum (outer_left),
4797 make_fixnum (outer_top))),
4798 Fcons (Qouter_size,
4799 Fcons (make_fixnum (outer_right - outer_left),
4800 make_fixnum (outer_bottom - outer_top))),
4801 Fcons (Qouter_border_width, make_fixnum (0)),
4802 Fcons (Qexternal_border_size,
4803 Fcons (make_fixnum (0), make_fixnum (0))),
4804 Fcons (Qtitle_bar_size,
4805 Fcons (make_fixnum (0), make_fixnum (0))),
4806 Fcons (Qmenu_bar_external, Qnil),
4807 Fcons (Qmenu_bar_size,
4808 Fcons (make_fixnum (menu_bar_width),
4809 make_fixnum (menu_bar_height))),
4810 Fcons (Qtab_bar_size,
4811 Fcons (make_fixnum (tab_bar_width),
4812 make_fixnum (tab_bar_height))),
4813 Fcons (Qtool_bar_external, Qnil),
4814 Fcons (Qtool_bar_position, FRAME_TOOL_BAR_POSITION (f)),
4815 Fcons (Qtool_bar_size,
4816 Fcons (make_fixnum (tool_bar_width),
4817 make_fixnum (tool_bar_height))),
4818 Fcons (Qinternal_border_width,
4819 make_fixnum (internal_border_width)));
4820}
4821
4822DEFUN ("tty-frame-geometry", Ftty_frame_geometry, Stty_frame_geometry, 0, 1, 0,
4823 doc: /* Return geometric attributes of terminal frame FRAME.
4824 See also `frame-geometry'. */)
4825 (Lisp_Object frame)
4826{
4827 return tty_frame_geometry (frame, Qnil);
4828}
4829
4830DEFUN ("tty-frame-edges", Ftty_frame_edges, Stty_frame_edges, 0, 2, 0,
4831 doc: /* Return coordinates of FRAME's edges.
4832 See also `frame-edges'. */)
4833 (Lisp_Object frame, Lisp_Object type)
4834{
4835 if (!EQ (type, Qouter_edges) && !EQ (type, Qinner_edges))
4836 type = Qnative_edges;
4837 return tty_frame_geometry (frame, type);
4838}
4839
4840DEFUN ("tty-frame-list-z-order", Ftty_frame_list_z_order,
4841 Stty_frame_list_z_order, 0, 1, 0,
4842 doc: /* Return list of Emacs's frames, in Z (stacking) order.
4843 See also `frame-list-z-order'. */)
4844 (Lisp_Object frame)
4845{
4846 struct frame *f = decode_tty_frame (frame);
4847 Lisp_Object frames = frames_in_reverse_z_order (f, true);
4848 return Fnreverse (frames);
4849}
4850
4851DEFUN ("tty-frame-restack", Ftty_frame_restack,
4852 Stty_frame_restack, 2, 3, 0,
4853 doc: /* Restack FRAME1 below FRAME2 on terminals.
4854. See also `frame-restack'. */)
4855 (Lisp_Object frame1, Lisp_Object frame2, Lisp_Object above)
4856{
4857 /* FIXME/tty: implementation. */
4858 return Qnil;
4859}
4860
4861static void
4862tty_display_dimension (Lisp_Object frame, int *width, int *height)
4863{
4864 if (!FRAMEP (frame))
4865 frame = Fselected_frame ();
4866 struct frame *f = XFRAME (frame);
4867 switch (f->output_method)
4868 {
4869 case output_initial:
4870 *width = 80;
4871 *height = 25;
4872 break;
4873 case output_termcap:
4874 *width = FrameCols (FRAME_TTY (f));
4875 *height = FrameRows (FRAME_TTY (f));
4876 break;
4877 case output_x_window:
4878 case output_msdos_raw:
4879 case output_w32:
4880 case output_ns:
4881 case output_pgtk:
4882 case output_haiku:
4883 case output_android:
4884 emacs_abort ();
4885 break;
4886 }
4887}
4888
4889DEFUN ("tty-display-pixel-width", Ftty_display_pixel_width,
4890 Stty_display_pixel_width, 0, 1, 0,
4891 doc: /* Return the width of DISPLAY's screen in pixels.
4892. See also `display-pixel-width'. */)
4893 (Lisp_Object display)
4894{
4895 int width, height;
4896 tty_display_dimension (display, &width, &height);
4897 return make_fixnum (width);
4898}
4899
4900DEFUN ("tty-display-pixel-height", Ftty_display_pixel_height,
4901 Stty_display_pixel_height, 0, 1, 0,
4902 doc: /* Return the height of DISPLAY's screen in pixels.
4903 See also `display-pixel-height'. */)
4904 (Lisp_Object display)
4905{
4906 int width, height;
4907 tty_display_dimension (display, &width, &height);
4908 return make_fixnum (height);
4909}
4910
4717void 4911void
4718syms_of_term (void) 4912syms_of_term (void)
4719{ 4913{
@@ -4770,6 +4964,13 @@ trigger redisplay. */);
4770 defsubr (&Sgpm_mouse_stop); 4964 defsubr (&Sgpm_mouse_stop);
4771#endif /* HAVE_GPM */ 4965#endif /* HAVE_GPM */
4772 4966
4967 defsubr (&Stty_frame_geometry);
4968 defsubr (&Stty_frame_edges);
4969 defsubr (&Stty_frame_list_z_order);
4970 defsubr (&Stty_frame_restack);
4971 defsubr (&Stty_display_pixel_width);
4972 defsubr (&Stty_display_pixel_height);
4973
4773#if !defined DOS_NT && !defined HAVE_ANDROID 4974#if !defined DOS_NT && !defined HAVE_ANDROID
4774 default_orig_pair = NULL; 4975 default_orig_pair = NULL;
4775 default_set_foreground = NULL; 4976 default_set_foreground = NULL;