aboutsummaryrefslogtreecommitdiffstats
path: root/src/term.c
diff options
context:
space:
mode:
authorEli Zaretskii2013-09-05 11:01:04 +0300
committerEli Zaretskii2013-09-05 11:01:04 +0300
commit41306318777a942420bc4feadbfacf662ea179dc (patch)
tree669e5cca02f95d6064ce73c0d3fbbf91b8c8b563 /src/term.c
parent141f1ff7a40cda10f0558e891dd196a943a5082e (diff)
parent257b3b03cb1cff917e0b3b7832ad3eab5b59f257 (diff)
downloademacs-41306318777a942420bc4feadbfacf662ea179dc.tar.gz
emacs-41306318777a942420bc4feadbfacf662ea179dc.zip
Merge from trunk after a lot of time.
Diffstat (limited to 'src/term.c')
-rw-r--r--src/term.c515
1 files changed, 195 insertions, 320 deletions
diff --git a/src/term.c b/src/term.c
index bed0e8b4d1f..73d7585e8f5 100644
--- a/src/term.c
+++ b/src/term.c
@@ -1,6 +1,6 @@
1/* Terminal control module for terminals described by TERMCAP 1/* Terminal control module for terminals described by TERMCAP
2 Copyright (C) 1985-1987, 1993-1995, 1998, 2000-2012 2 Copyright (C) 1985-1987, 1993-1995, 1998, 2000-2013 Free Software
3 Free Software Foundation, Inc. 3 Foundation, Inc.
4 4
5This file is part of GNU Emacs. 5This file is part of GNU Emacs.
6 6
@@ -20,20 +20,18 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20/* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>. */ 20/* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>. */
21 21
22#include <config.h> 22#include <config.h>
23#include <stdio.h>
24#include <ctype.h>
25#include <errno.h> 23#include <errno.h>
24#include <fcntl.h>
25#include <stdio.h>
26#include <sys/file.h> 26#include <sys/file.h>
27#include <sys/time.h>
27#include <unistd.h> 28#include <unistd.h>
28#include <signal.h>
29#include <setjmp.h>
30 29
31#include "lisp.h" 30#include "lisp.h"
32#include "termchar.h" 31#include "termchar.h"
33#include "termopts.h"
34#include "tparam.h" 32#include "tparam.h"
35#include "buffer.h"
36#include "character.h" 33#include "character.h"
34#include "buffer.h"
37#include "charset.h" 35#include "charset.h"
38#include "coding.h" 36#include "coding.h"
39#include "composite.h" 37#include "composite.h"
@@ -58,21 +56,12 @@ static int been_here = -1;
58#include "xterm.h" 56#include "xterm.h"
59#endif 57#endif
60 58
61#ifdef HAVE_MENUS
62#include "menu.h" 59#include "menu.h"
63#endif
64
65#ifndef O_RDWR
66#define O_RDWR 2
67#endif
68
69#ifndef O_NOCTTY
70#define O_NOCTTY 0
71#endif
72 60
73/* The name of the default console device. */ 61/* The name of the default console device. */
74#ifdef WINDOWSNT 62#ifdef WINDOWSNT
75#define DEV_TTY "CONOUT$" 63#define DEV_TTY "CONOUT$"
64#include "w32term.h"
76#else 65#else
77#define DEV_TTY "/dev/tty" 66#define DEV_TTY "/dev/tty"
78#endif 67#endif
@@ -84,22 +73,21 @@ static void tty_turn_off_highlight (struct tty_display_info *);
84static void tty_show_cursor (struct tty_display_info *); 73static void tty_show_cursor (struct tty_display_info *);
85static void tty_hide_cursor (struct tty_display_info *); 74static void tty_hide_cursor (struct tty_display_info *);
86static void tty_background_highlight (struct tty_display_info *tty); 75static void tty_background_highlight (struct tty_display_info *tty);
87static struct terminal *get_tty_terminal (Lisp_Object, int); 76static struct terminal *get_tty_terminal (Lisp_Object, bool);
88static void clear_tty_hooks (struct terminal *terminal); 77static void clear_tty_hooks (struct terminal *terminal);
89static void set_tty_hooks (struct terminal *terminal); 78static void set_tty_hooks (struct terminal *terminal);
90static void dissociate_if_controlling_tty (int fd); 79static void dissociate_if_controlling_tty (int fd);
91static void delete_tty (struct terminal *); 80static void delete_tty (struct terminal *);
92static void maybe_fatal (int must_succeed, struct terminal *terminal, 81static _Noreturn void maybe_fatal (bool, struct terminal *,
93 const char *str1, const char *str2, ...) 82 const char *, const char *, ...)
94 NO_RETURN ATTRIBUTE_FORMAT_PRINTF (3, 5) ATTRIBUTE_FORMAT_PRINTF (4, 5); 83 ATTRIBUTE_FORMAT_PRINTF (3, 5) ATTRIBUTE_FORMAT_PRINTF (4, 5);
95static void vfatal (const char *str, va_list ap) 84static _Noreturn void vfatal (const char *str, va_list ap)
96 NO_RETURN ATTRIBUTE_FORMAT_PRINTF (1, 0); 85 ATTRIBUTE_FORMAT_PRINTF (1, 0);
97 86
98 87
99#define OUTPUT(tty, a) \ 88#define OUTPUT(tty, a) \
100 emacs_tputs ((tty), a, \ 89 emacs_tputs ((tty), a, \
101 (int) (FRAME_LINES (XFRAME (selected_frame)) \ 90 FRAME_LINES (XFRAME (selected_frame)) - curY (tty), \
102 - curY (tty)), \
103 cmputc) 91 cmputc)
104 92
105#define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc) 93#define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc)
@@ -126,12 +114,11 @@ enum no_color_bit
126 NC_STANDOUT = 1 << 0, 114 NC_STANDOUT = 1 << 0,
127 NC_UNDERLINE = 1 << 1, 115 NC_UNDERLINE = 1 << 1,
128 NC_REVERSE = 1 << 2, 116 NC_REVERSE = 1 << 2,
129 NC_BLINK = 1 << 3, 117 NC_ITALIC = 1 << 3,
130 NC_DIM = 1 << 4, 118 NC_DIM = 1 << 4,
131 NC_BOLD = 1 << 5, 119 NC_BOLD = 1 << 5,
132 NC_INVIS = 1 << 6, 120 NC_INVIS = 1 << 6,
133 NC_PROTECT = 1 << 7, 121 NC_PROTECT = 1 << 7
134 NC_ALT_CHARSET = 1 << 8
135}; 122};
136 123
137/* internal state */ 124/* internal state */
@@ -140,10 +127,6 @@ enum no_color_bit
140 127
141static int max_frame_cols; 128static int max_frame_cols;
142 129
143/* Non-zero if we have dropped our controlling tty and therefore
144 should not open a frame on stdout. */
145static int no_controlling_tty;
146
147 130
148 131
149#ifdef HAVE_GPM 132#ifdef HAVE_GPM
@@ -713,7 +696,7 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len)
713{ 696{
714 unsigned char *conversion_buffer; 697 unsigned char *conversion_buffer;
715 struct coding_system *coding; 698 struct coding_system *coding;
716 size_t n, stringlen; 699 int n, stringlen;
717 700
718 struct tty_display_info *tty = FRAME_TTY (f); 701 struct tty_display_info *tty = FRAME_TTY (f);
719 702
@@ -760,13 +743,13 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len)
760 conversion_buffer = encode_terminal_code (string, n, coding); 743 conversion_buffer = encode_terminal_code (string, n, coding);
761 if (coding->produced > 0) 744 if (coding->produced > 0)
762 { 745 {
763 BLOCK_INPUT; 746 block_input ();
764 fwrite (conversion_buffer, 1, coding->produced, tty->output); 747 fwrite (conversion_buffer, 1, coding->produced, tty->output);
765 if (ferror (tty->output)) 748 if (ferror (tty->output))
766 clearerr (tty->output); 749 clearerr (tty->output);
767 if (tty->termscript) 750 if (tty->termscript)
768 fwrite (conversion_buffer, 1, coding->produced, tty->termscript); 751 fwrite (conversion_buffer, 1, coding->produced, tty->termscript);
769 UNBLOCK_INPUT; 752 unblock_input ();
770 } 753 }
771 string += n; 754 string += n;
772 755
@@ -821,13 +804,13 @@ tty_write_glyphs_with_face (register struct frame *f, register struct glyph *str
821 conversion_buffer = encode_terminal_code (string, len, coding); 804 conversion_buffer = encode_terminal_code (string, len, coding);
822 if (coding->produced > 0) 805 if (coding->produced > 0)
823 { 806 {
824 BLOCK_INPUT; 807 block_input ();
825 fwrite (conversion_buffer, 1, coding->produced, tty->output); 808 fwrite (conversion_buffer, 1, coding->produced, tty->output);
826 if (ferror (tty->output)) 809 if (ferror (tty->output))
827 clearerr (tty->output); 810 clearerr (tty->output);
828 if (tty->termscript) 811 if (tty->termscript)
829 fwrite (conversion_buffer, 1, coding->produced, tty->termscript); 812 fwrite (conversion_buffer, 1, coding->produced, tty->termscript);
830 UNBLOCK_INPUT; 813 unblock_input ();
831 } 814 }
832 815
833 /* Turn appearance modes off. */ 816 /* Turn appearance modes off. */
@@ -907,13 +890,13 @@ tty_insert_glyphs (struct frame *f, struct glyph *start, int len)
907 890
908 if (coding->produced > 0) 891 if (coding->produced > 0)
909 { 892 {
910 BLOCK_INPUT; 893 block_input ();
911 fwrite (conversion_buffer, 1, coding->produced, tty->output); 894 fwrite (conversion_buffer, 1, coding->produced, tty->output);
912 if (ferror (tty->output)) 895 if (ferror (tty->output))
913 clearerr (tty->output); 896 clearerr (tty->output);
914 if (tty->termscript) 897 if (tty->termscript)
915 fwrite (conversion_buffer, 1, coding->produced, tty->termscript); 898 fwrite (conversion_buffer, 1, coding->produced, tty->termscript);
916 UNBLOCK_INPUT; 899 unblock_input ();
917 } 900 }
918 901
919 OUTPUT1_IF (tty, tty->TS_pad_inserted_char); 902 OUTPUT1_IF (tty, tty->TS_pad_inserted_char);
@@ -971,8 +954,8 @@ tty_ins_del_lines (struct frame *f, int vpos, int n)
971 const char *single = n > 0 ? tty->TS_ins_line : tty->TS_del_line; 954 const char *single = n > 0 ? tty->TS_ins_line : tty->TS_del_line;
972 const char *scroll = n > 0 ? tty->TS_rev_scroll : tty->TS_fwd_scroll; 955 const char *scroll = n > 0 ? tty->TS_rev_scroll : tty->TS_fwd_scroll;
973 956
974 register int i = n > 0 ? n : -n; 957 int i = eabs (n);
975 register char *buf; 958 char *buf;
976 959
977 /* If the lines below the insertion are being pushed 960 /* If the lines below the insertion are being pushed
978 into the end of the window, this is the same as clearing; 961 into the end of the window, this is the same as clearing;
@@ -1337,9 +1320,9 @@ term_get_fkeys_1 (void)
1337 1320
1338 /* This can happen if CANNOT_DUMP or with strange options. */ 1321 /* This can happen if CANNOT_DUMP or with strange options. */
1339 if (!KEYMAPP (KVAR (kboard, Vinput_decode_map))) 1322 if (!KEYMAPP (KVAR (kboard, Vinput_decode_map)))
1340 KVAR (kboard, Vinput_decode_map) = Fmake_sparse_keymap (Qnil); 1323 kset_input_decode_map (kboard, Fmake_sparse_keymap (Qnil));
1341 1324
1342 for (i = 0; i < (sizeof (keys)/sizeof (keys[0])); i++) 1325 for (i = 0; i < (sizeof (keys) / sizeof (keys[0])); i++)
1343 { 1326 {
1344 char *sequence = tgetstr (keys[i].cap, address); 1327 char *sequence = tgetstr (keys[i].cap, address);
1345 if (sequence) 1328 if (sequence)
@@ -1449,7 +1432,7 @@ static void append_glyph (struct it *);
1449static void append_composite_glyph (struct it *); 1432static void append_composite_glyph (struct it *);
1450static void produce_composite_glyph (struct it *); 1433static void produce_composite_glyph (struct it *);
1451static void append_glyphless_glyph (struct it *, int, const char *); 1434static void append_glyphless_glyph (struct it *, int, const char *);
1452static void produce_glyphless_glyph (struct it *, int, Lisp_Object); 1435static void produce_glyphless_glyph (struct it *, Lisp_Object);
1453 1436
1454/* Append glyphs to IT's glyph_row. Called from produce_glyphs for 1437/* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1455 terminal frames if IT->glyph_row != NULL. IT->char_to_display is 1438 terminal frames if IT->glyph_row != NULL. IT->char_to_display is
@@ -1463,7 +1446,7 @@ append_glyph (struct it *it)
1463 struct glyph *glyph, *end; 1446 struct glyph *glyph, *end;
1464 int i; 1447 int i;
1465 1448
1466 xassert (it->glyph_row); 1449 eassert (it->glyph_row);
1467 glyph = (it->glyph_row->glyphs[it->area] 1450 glyph = (it->glyph_row->glyphs[it->area]
1468 + it->glyph_row->used[it->area]); 1451 + it->glyph_row->used[it->area]);
1469 end = it->glyph_row->glyphs[1 + it->area]; 1452 end = it->glyph_row->glyphs[1 + it->area];
@@ -1503,7 +1486,7 @@ append_glyph (struct it *it)
1503 { 1486 {
1504 glyph->resolved_level = it->bidi_it.resolved_level; 1487 glyph->resolved_level = it->bidi_it.resolved_level;
1505 if ((it->bidi_it.type & 7) != it->bidi_it.type) 1488 if ((it->bidi_it.type & 7) != it->bidi_it.type)
1506 abort (); 1489 emacs_abort ();
1507 glyph->bidi_type = it->bidi_it.type; 1490 glyph->bidi_type = it->bidi_it.type;
1508 } 1491 }
1509 else 1492 else
@@ -1550,7 +1533,7 @@ produce_glyphs (struct it *it)
1550 /* If a hook is installed, let it do the work. */ 1533 /* If a hook is installed, let it do the work. */
1551 1534
1552 /* Nothing but characters are supported on terminal frames. */ 1535 /* Nothing but characters are supported on terminal frames. */
1553 xassert (it->what == IT_CHARACTER 1536 eassert (it->what == IT_CHARACTER
1554 || it->what == IT_COMPOSITION 1537 || it->what == IT_COMPOSITION
1555 || it->what == IT_STRETCH 1538 || it->what == IT_STRETCH
1556 || it->what == IT_GLYPHLESS); 1539 || it->what == IT_GLYPHLESS);
@@ -1569,7 +1552,7 @@ produce_glyphs (struct it *it)
1569 1552
1570 if (it->what == IT_GLYPHLESS) 1553 if (it->what == IT_GLYPHLESS)
1571 { 1554 {
1572 produce_glyphless_glyph (it, 0, Qnil); 1555 produce_glyphless_glyph (it, Qnil);
1573 goto done; 1556 goto done;
1574 } 1557 }
1575 1558
@@ -1637,8 +1620,8 @@ produce_glyphs (struct it *it)
1637 { 1620 {
1638 Lisp_Object acronym = lookup_glyphless_char_display (-1, it); 1621 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
1639 1622
1640 xassert (it->what == IT_GLYPHLESS); 1623 eassert (it->what == IT_GLYPHLESS);
1641 produce_glyphless_glyph (it, 1, acronym); 1624 produce_glyphless_glyph (it, acronym);
1642 } 1625 }
1643 } 1626 }
1644 1627
@@ -1661,7 +1644,7 @@ append_composite_glyph (struct it *it)
1661{ 1644{
1662 struct glyph *glyph; 1645 struct glyph *glyph;
1663 1646
1664 xassert (it->glyph_row); 1647 eassert (it->glyph_row);
1665 glyph = it->glyph_row->glyphs[it->area] + it->glyph_row->used[it->area]; 1648 glyph = it->glyph_row->glyphs[it->area] + it->glyph_row->used[it->area];
1666 if (glyph < it->glyph_row->glyphs[1 + it->area]) 1649 if (glyph < it->glyph_row->glyphs[1 + it->area])
1667 { 1650 {
@@ -1700,7 +1683,7 @@ append_composite_glyph (struct it *it)
1700 { 1683 {
1701 glyph->resolved_level = it->bidi_it.resolved_level; 1684 glyph->resolved_level = it->bidi_it.resolved_level;
1702 if ((it->bidi_it.type & 7) != it->bidi_it.type) 1685 if ((it->bidi_it.type & 7) != it->bidi_it.type)
1703 abort (); 1686 emacs_abort ();
1704 glyph->bidi_type = it->bidi_it.type; 1687 glyph->bidi_type = it->bidi_it.type;
1705 } 1688 }
1706 else 1689 else
@@ -1753,7 +1736,7 @@ append_glyphless_glyph (struct it *it, int face_id, const char *str)
1753 struct glyph *glyph, *end; 1736 struct glyph *glyph, *end;
1754 int i; 1737 int i;
1755 1738
1756 xassert (it->glyph_row); 1739 eassert (it->glyph_row);
1757 glyph = it->glyph_row->glyphs[it->area] + it->glyph_row->used[it->area]; 1740 glyph = it->glyph_row->glyphs[it->area] + it->glyph_row->used[it->area];
1758 end = it->glyph_row->glyphs[1 + it->area]; 1741 end = it->glyph_row->glyphs[1 + it->area];
1759 1742
@@ -1785,7 +1768,7 @@ append_glyphless_glyph (struct it *it, int face_id, const char *str)
1785 { 1768 {
1786 glyph->resolved_level = it->bidi_it.resolved_level; 1769 glyph->resolved_level = it->bidi_it.resolved_level;
1787 if ((it->bidi_it.type & 7) != it->bidi_it.type) 1770 if ((it->bidi_it.type & 7) != it->bidi_it.type)
1788 abort (); 1771 emacs_abort ();
1789 glyph->bidi_type = it->bidi_it.type; 1772 glyph->bidi_type = it->bidi_it.type;
1790 } 1773 }
1791 else 1774 else
@@ -1812,14 +1795,12 @@ append_glyphless_glyph (struct it *it, int face_id, const char *str)
1812 the character. See the description of enum 1795 the character. See the description of enum
1813 glyphless_display_method in dispextern.h for the details. 1796 glyphless_display_method in dispextern.h for the details.
1814 1797
1815 FOR_NO_FONT is nonzero if and only if this is for a character that 1798 ACRONYM, if non-nil, is an acronym string for the character.
1816 is not supported by the coding system of the terminal. ACRONYM, if
1817 non-nil, is an acronym string for the character.
1818 1799
1819 The glyphs actually produced are of type CHAR_GLYPH. */ 1800 The glyphs actually produced are of type CHAR_GLYPH. */
1820 1801
1821static void 1802static void
1822produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym) 1803produce_glyphless_glyph (struct it *it, Lisp_Object acronym)
1823{ 1804{
1824 int face_id; 1805 int face_id;
1825 int len; 1806 int len;
@@ -1855,8 +1836,7 @@ produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
1855 len = 1; 1836 len = 1;
1856 else if (len > 4) 1837 else if (len > 4)
1857 len = 4; 1838 len = 4;
1858 sprintf (buf, "[%.*s]", len, str); 1839 len = sprintf (buf, "[%.*s]", len, str);
1859 len += 2;
1860 str = buf; 1840 str = buf;
1861 } 1841 }
1862 else 1842 else
@@ -1876,7 +1856,7 @@ produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
1876 } 1856 }
1877 else 1857 else
1878 { 1858 {
1879 xassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE); 1859 eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
1880 len = (it->c < 0x10000 ? sprintf (buf, "\\u%04X", it->c) 1860 len = (it->c < 0x10000 ? sprintf (buf, "\\u%04X", it->c)
1881 : it->c <= MAX_UNICODE_CHAR ? sprintf (buf, "\\U%06X", it->c) 1861 : it->c <= MAX_UNICODE_CHAR ? sprintf (buf, "\\U%06X", it->c)
1882 : sprintf (buf, "\\x%06X", it->c)); 1862 : sprintf (buf, "\\x%06X", it->c));
@@ -1890,67 +1870,6 @@ produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
1890 append_glyphless_glyph (it, face_id, str); 1870 append_glyphless_glyph (it, face_id, str);
1891} 1871}
1892 1872
1893
1894/* Get information about special display element WHAT in an
1895 environment described by IT. WHAT is one of IT_TRUNCATION or
1896 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1897 non-null glyph_row member. This function ensures that fields like
1898 face_id, c, len of IT are left untouched. */
1899
1900void
1901produce_special_glyphs (struct it *it, enum display_element_type what)
1902{
1903 struct it temp_it;
1904 Lisp_Object gc;
1905 GLYPH glyph;
1906
1907 temp_it = *it;
1908 temp_it.dp = NULL;
1909 temp_it.what = IT_CHARACTER;
1910 temp_it.len = 1;
1911 temp_it.object = make_number (0);
1912 memset (&temp_it.current, 0, sizeof temp_it.current);
1913
1914 if (what == IT_CONTINUATION)
1915 {
1916 /* Continuation glyph. For R2L lines, we mirror it by hand. */
1917 if (it->bidi_it.paragraph_dir == R2L)
1918 SET_GLYPH_FROM_CHAR (glyph, '/');
1919 else
1920 SET_GLYPH_FROM_CHAR (glyph, '\\');
1921 if (it->dp
1922 && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
1923 {
1924 /* FIXME: Should we mirror GC for R2L lines? */
1925 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
1926 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
1927 }
1928 }
1929 else if (what == IT_TRUNCATION)
1930 {
1931 /* Truncation glyph. */
1932 SET_GLYPH_FROM_CHAR (glyph, '$');
1933 if (it->dp
1934 && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
1935 {
1936 /* FIXME: Should we mirror GC for R2L lines? */
1937 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
1938 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
1939 }
1940 }
1941 else
1942 abort ();
1943
1944 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
1945 temp_it.face_id = GLYPH_FACE (glyph);
1946 temp_it.len = CHAR_BYTES (temp_it.c);
1947
1948 produce_glyphs (&temp_it);
1949 it->pixel_width = temp_it.pixel_width;
1950 it->nglyphs = temp_it.pixel_width;
1951}
1952
1953
1954 1873
1955/*********************************************************************** 1874/***********************************************************************
1956 Faces 1875 Faces
@@ -2026,17 +1945,16 @@ turn_on_face (struct frame *f, int face_id)
2026 if (face->tty_bold_p && MAY_USE_WITH_COLORS_P (tty, NC_BOLD)) 1945 if (face->tty_bold_p && MAY_USE_WITH_COLORS_P (tty, NC_BOLD))
2027 OUTPUT1_IF (tty, tty->TS_enter_bold_mode); 1946 OUTPUT1_IF (tty, tty->TS_enter_bold_mode);
2028 1947
2029 if (face->tty_dim_p && MAY_USE_WITH_COLORS_P (tty, NC_DIM)) 1948 if (face->tty_italic_p && MAY_USE_WITH_COLORS_P (tty, NC_ITALIC))
2030 OUTPUT1_IF (tty, tty->TS_enter_dim_mode); 1949 {
2031 1950 if (tty->TS_enter_italic_mode)
2032 /* Alternate charset and blinking not yet used. */ 1951 OUTPUT1 (tty, tty->TS_enter_italic_mode);
2033 if (face->tty_alt_charset_p 1952 else
2034 && MAY_USE_WITH_COLORS_P (tty, NC_ALT_CHARSET)) 1953 /* Italics mode is unavailable on many terminals. In that
2035 OUTPUT1_IF (tty, tty->TS_enter_alt_charset_mode); 1954 case, map slant to dimmed text; we want italic text to
2036 1955 appear different and dimming is not otherwise used. */
2037 if (face->tty_blinking_p 1956 OUTPUT1 (tty, tty->TS_enter_dim_mode);
2038 && MAY_USE_WITH_COLORS_P (tty, NC_BLINK)) 1957 }
2039 OUTPUT1_IF (tty, tty->TS_enter_blink_mode);
2040 1958
2041 if (face->tty_underline_p && MAY_USE_WITH_COLORS_P (tty, NC_UNDERLINE)) 1959 if (face->tty_underline_p && MAY_USE_WITH_COLORS_P (tty, NC_UNDERLINE))
2042 OUTPUT1_IF (tty, tty->TS_enter_underline_mode); 1960 OUTPUT1_IF (tty, tty->TS_enter_underline_mode);
@@ -2049,7 +1967,7 @@ turn_on_face (struct frame *f, int face_id)
2049 ts = tty->standout_mode ? tty->TS_set_background : tty->TS_set_foreground; 1967 ts = tty->standout_mode ? tty->TS_set_background : tty->TS_set_foreground;
2050 if (fg >= 0 && ts) 1968 if (fg >= 0 && ts)
2051 { 1969 {
2052 p = tparam (ts, NULL, 0, (int) fg, 0, 0, 0); 1970 p = tparam (ts, NULL, 0, fg, 0, 0, 0);
2053 OUTPUT (tty, p); 1971 OUTPUT (tty, p);
2054 xfree (p); 1972 xfree (p);
2055 } 1973 }
@@ -2057,7 +1975,7 @@ turn_on_face (struct frame *f, int face_id)
2057 ts = tty->standout_mode ? tty->TS_set_foreground : tty->TS_set_background; 1975 ts = tty->standout_mode ? tty->TS_set_foreground : tty->TS_set_background;
2058 if (bg >= 0 && ts) 1976 if (bg >= 0 && ts)
2059 { 1977 {
2060 p = tparam (ts, NULL, 0, (int) bg, 0, 0, 0); 1978 p = tparam (ts, NULL, 0, bg, 0, 0, 0);
2061 OUTPUT (tty, p); 1979 OUTPUT (tty, p);
2062 xfree (p); 1980 xfree (p);
2063 } 1981 }
@@ -2073,7 +1991,7 @@ turn_off_face (struct frame *f, int face_id)
2073 struct face *face = FACE_FROM_ID (f, face_id); 1991 struct face *face = FACE_FROM_ID (f, face_id);
2074 struct tty_display_info *tty = FRAME_TTY (f); 1992 struct tty_display_info *tty = FRAME_TTY (f);
2075 1993
2076 xassert (face != NULL); 1994 eassert (face != NULL);
2077 1995
2078 if (tty->TS_exit_attribute_mode) 1996 if (tty->TS_exit_attribute_mode)
2079 { 1997 {
@@ -2081,27 +1999,19 @@ turn_off_face (struct frame *f, int face_id)
2081 half-bright, reverse-video, standout, underline. It may or 1999 half-bright, reverse-video, standout, underline. It may or
2082 may not turn off alt-char-mode. */ 2000 may not turn off alt-char-mode. */
2083 if (face->tty_bold_p 2001 if (face->tty_bold_p
2084 || face->tty_dim_p 2002 || face->tty_italic_p
2085 || face->tty_reverse_p 2003 || face->tty_reverse_p
2086 || face->tty_alt_charset_p
2087 || face->tty_blinking_p
2088 || face->tty_underline_p) 2004 || face->tty_underline_p)
2089 { 2005 {
2090 OUTPUT1_IF (tty, tty->TS_exit_attribute_mode); 2006 OUTPUT1_IF (tty, tty->TS_exit_attribute_mode);
2091 if (strcmp (tty->TS_exit_attribute_mode, tty->TS_end_standout_mode) == 0) 2007 if (strcmp (tty->TS_exit_attribute_mode, tty->TS_end_standout_mode) == 0)
2092 tty->standout_mode = 0; 2008 tty->standout_mode = 0;
2093 } 2009 }
2094
2095 if (face->tty_alt_charset_p)
2096 OUTPUT_IF (tty, tty->TS_exit_alt_charset_mode);
2097 } 2010 }
2098 else 2011 else
2099 { 2012 {
2100 /* If we don't have "me" we can only have those appearances 2013 /* If we don't have "me" we can only have those appearances
2101 that have exit sequences defined. */ 2014 that have exit sequences defined. */
2102 if (face->tty_alt_charset_p)
2103 OUTPUT_IF (tty, tty->TS_exit_alt_charset_mode);
2104
2105 if (face->tty_underline_p) 2015 if (face->tty_underline_p)
2106 OUTPUT_IF (tty, tty->TS_exit_underline_mode); 2016 OUTPUT_IF (tty, tty->TS_exit_underline_mode);
2107 } 2017 }
@@ -2116,11 +2026,11 @@ turn_off_face (struct frame *f, int face_id)
2116} 2026}
2117 2027
2118 2028
2119/* Return non-zero if the terminal on frame F supports all of the 2029/* Return true if the terminal on frame F supports all of the
2120 capabilities in CAPS simultaneously, with foreground and background 2030 capabilities in CAPS simultaneously, with foreground and background
2121 colors FG and BG. */ 2031 colors FG and BG. */
2122 2032
2123int 2033bool
2124tty_capable_p (struct tty_display_info *tty, unsigned int caps, 2034tty_capable_p (struct tty_display_info *tty, unsigned int caps,
2125 unsigned long fg, unsigned long bg) 2035 unsigned long fg, unsigned long bg)
2126{ 2036{
@@ -2132,8 +2042,7 @@ tty_capable_p (struct tty_display_info *tty, unsigned int caps,
2132 TTY_CAPABLE_P_TRY (tty, TTY_CAP_UNDERLINE, tty->TS_enter_underline_mode, NC_UNDERLINE); 2042 TTY_CAPABLE_P_TRY (tty, TTY_CAP_UNDERLINE, tty->TS_enter_underline_mode, NC_UNDERLINE);
2133 TTY_CAPABLE_P_TRY (tty, TTY_CAP_BOLD, tty->TS_enter_bold_mode, NC_BOLD); 2043 TTY_CAPABLE_P_TRY (tty, TTY_CAP_BOLD, tty->TS_enter_bold_mode, NC_BOLD);
2134 TTY_CAPABLE_P_TRY (tty, TTY_CAP_DIM, tty->TS_enter_dim_mode, NC_DIM); 2044 TTY_CAPABLE_P_TRY (tty, TTY_CAP_DIM, tty->TS_enter_dim_mode, NC_DIM);
2135 TTY_CAPABLE_P_TRY (tty, TTY_CAP_BLINK, tty->TS_enter_blink_mode, NC_BLINK); 2045 TTY_CAPABLE_P_TRY (tty, TTY_CAP_ITALIC, tty->TS_enter_italic_mode, NC_ITALIC);
2136 TTY_CAPABLE_P_TRY (tty, TTY_CAP_ALT_CHARSET, tty->TS_enter_alt_charset_mode, NC_ALT_CHARSET);
2137 2046
2138 /* We can do it! */ 2047 /* We can do it! */
2139 return 1; 2048 return 1;
@@ -2147,7 +2056,7 @@ DEFUN ("tty-display-color-p", Ftty_display_color_p, Stty_display_color_p,
2147 2056
2148TERMINAL can be a terminal object, a frame, or nil (meaning the 2057TERMINAL can be a terminal object, a frame, or nil (meaning the
2149selected frame's terminal). This function always returns nil if 2058selected frame's terminal). This function always returns nil if
2150TERMINAL does not refer to a text-only terminal. */) 2059TERMINAL does not refer to a text terminal. */)
2151 (Lisp_Object terminal) 2060 (Lisp_Object terminal)
2152{ 2061{
2153 struct terminal *t = get_tty_terminal (terminal, 0); 2062 struct terminal *t = get_tty_terminal (terminal, 0);
@@ -2164,7 +2073,7 @@ DEFUN ("tty-display-color-cells", Ftty_display_color_cells,
2164 2073
2165TERMINAL can be a terminal object, a frame, or nil (meaning the 2074TERMINAL can be a terminal object, a frame, or nil (meaning the
2166selected frame's terminal). This function always returns 0 if 2075selected frame's terminal). This function always returns 0 if
2167TERMINAL does not refer to a text-only terminal. */) 2076TERMINAL does not refer to a text terminal. */)
2168 (Lisp_Object terminal) 2077 (Lisp_Object terminal)
2169{ 2078{
2170 struct terminal *t = get_tty_terminal (terminal, 0); 2079 struct terminal *t = get_tty_terminal (terminal, 0);
@@ -2189,7 +2098,7 @@ static char *default_set_background;
2189/* Save or restore the default color-related capabilities of this 2098/* Save or restore the default color-related capabilities of this
2190 terminal. */ 2099 terminal. */
2191static void 2100static void
2192tty_default_color_capabilities (struct tty_display_info *tty, int save) 2101tty_default_color_capabilities (struct tty_display_info *tty, bool save)
2193{ 2102{
2194 2103
2195 if (save) 2104 if (save)
@@ -2285,11 +2194,10 @@ set_tty_color_mode (struct tty_display_info *tty, struct frame *f)
2285 2194
2286 if (mode != tty->previous_color_mode) 2195 if (mode != tty->previous_color_mode)
2287 { 2196 {
2288 Lisp_Object funsym = intern ("tty-set-up-initial-frame-faces");
2289 tty->previous_color_mode = mode; 2197 tty->previous_color_mode = mode;
2290 tty_setup_colors (tty , mode); 2198 tty_setup_colors (tty , mode);
2291 /* This recomputes all the faces given the new color definitions. */ 2199 /* This recomputes all the faces given the new color definitions. */
2292 safe_call (1, &funsym); 2200 safe_call (1, intern ("tty-set-up-initial-frame-faces"));
2293 } 2201 }
2294} 2202}
2295 2203
@@ -2300,7 +2208,7 @@ set_tty_color_mode (struct tty_display_info *tty, struct frame *f)
2300/* Return the tty display object specified by TERMINAL. */ 2208/* Return the tty display object specified by TERMINAL. */
2301 2209
2302static struct terminal * 2210static struct terminal *
2303get_tty_terminal (Lisp_Object terminal, int throw) 2211get_tty_terminal (Lisp_Object terminal, bool throw)
2304{ 2212{
2305 struct terminal *t = get_terminal (terminal, throw); 2213 struct terminal *t = get_terminal (terminal, throw);
2306 2214
@@ -2327,8 +2235,7 @@ get_named_tty (const char *name)
2327{ 2235{
2328 struct terminal *t; 2236 struct terminal *t;
2329 2237
2330 if (!name) 2238 eassert (name);
2331 abort ();
2332 2239
2333 for (t = terminal_list; t; t = t->next_terminal) 2240 for (t = terminal_list; t; t = t->next_terminal)
2334 { 2241 {
@@ -2386,7 +2293,7 @@ no effect if used on a non-tty terminal.
2386 2293
2387TERMINAL can be a terminal object, a frame or nil (meaning the 2294TERMINAL can be a terminal object, a frame or nil (meaning the
2388selected frame's terminal). This function always returns nil if 2295selected frame's terminal). This function always returns nil if
2389TERMINAL does not refer to a text-only terminal. */) 2296TERMINAL does not refer to a text terminal. */)
2390 (Lisp_Object terminal) 2297 (Lisp_Object terminal)
2391{ 2298{
2392 struct terminal *t = get_terminal (terminal, 1); 2299 struct terminal *t = get_terminal (terminal, 1);
@@ -2396,6 +2303,21 @@ TERMINAL does not refer to a text-only terminal. */)
2396 return Qnil; 2303 return Qnil;
2397} 2304}
2398 2305
2306DEFUN ("tty-top-frame", Ftty_top_frame, Stty_top_frame, 0, 1, 0,
2307 doc: /* Return the topmost terminal frame on TERMINAL.
2308TERMINAL can be a terminal object, a frame or nil (meaning the
2309selected frame's terminal). This function returns nil if TERMINAL
2310does not refer to a text terminal. Otherwise, it returns the
2311top-most frame on the text terminal. */)
2312 (Lisp_Object terminal)
2313{
2314 struct terminal *t = get_terminal (terminal, 1);
2315
2316 if (t->type == output_termcap)
2317 return t->display_info.tty->top_frame;
2318 return Qnil;
2319}
2320
2399 2321
2400 2322
2401DEFUN ("suspend-tty", Fsuspend_tty, Ssuspend_tty, 0, 1, 0, 2323DEFUN ("suspend-tty", Fsuspend_tty, Ssuspend_tty, 0, 1, 0,
@@ -2450,7 +2372,7 @@ A suspended tty may be resumed by calling `resume-tty' on it. */)
2450 t->display_info.tty->output = 0; 2372 t->display_info.tty->output = 0;
2451 2373
2452 if (FRAMEP (t->display_info.tty->top_frame)) 2374 if (FRAMEP (t->display_info.tty->top_frame))
2453 FRAME_SET_VISIBLE (XFRAME (t->display_info.tty->top_frame), 0); 2375 SET_FRAME_VISIBLE (XFRAME (t->display_info.tty->top_frame), 0);
2454 2376
2455 } 2377 }
2456 2378
@@ -2495,15 +2417,20 @@ frame's terminal). */)
2495 t->display_info.tty->input = stdin; 2417 t->display_info.tty->input = stdin;
2496#else /* !MSDOS */ 2418#else /* !MSDOS */
2497 fd = emacs_open (t->display_info.tty->name, O_RDWR | O_NOCTTY, 0); 2419 fd = emacs_open (t->display_info.tty->name, O_RDWR | O_NOCTTY, 0);
2420 t->display_info.tty->input = t->display_info.tty->output
2421 = fd < 0 ? 0 : fdopen (fd, "w+");
2498 2422
2499 if (fd == -1) 2423 if (! t->display_info.tty->input)
2500 error ("Can not reopen tty device %s: %s", t->display_info.tty->name, strerror (errno)); 2424 {
2425 int open_errno = errno;
2426 emacs_close (fd);
2427 report_file_errno ("Cannot reopen tty device",
2428 build_string (t->display_info.tty->name),
2429 open_errno);
2430 }
2501 2431
2502 if (strcmp (t->display_info.tty->name, DEV_TTY)) 2432 if (!O_IGNORE_CTTY && strcmp (t->display_info.tty->name, DEV_TTY) != 0)
2503 dissociate_if_controlling_tty (fd); 2433 dissociate_if_controlling_tty (fd);
2504
2505 t->display_info.tty->output = fdopen (fd, "w+");
2506 t->display_info.tty->input = t->display_info.tty->output;
2507#endif 2434#endif
2508 2435
2509 add_keyboard_wait_descriptor (fd); 2436 add_keyboard_wait_descriptor (fd);
@@ -2520,7 +2447,7 @@ frame's terminal). */)
2520 get_tty_size (fileno (t->display_info.tty->input), &width, &height); 2447 get_tty_size (fileno (t->display_info.tty->input), &width, &height);
2521 if (width != old_width || height != old_height) 2448 if (width != old_width || height != old_height)
2522 change_frame_size (f, height, width, 0, 0, 0); 2449 change_frame_size (f, height, width, 0, 0, 0);
2523 FRAME_SET_VISIBLE (XFRAME (t->display_info.tty->top_frame), 1); 2450 SET_FRAME_VISIBLE (XFRAME (t->display_info.tty->top_frame), 1);
2524 } 2451 }
2525 2452
2526 set_tty_hooks (t); 2453 set_tty_hooks (t);
@@ -2555,9 +2482,9 @@ term_mouse_moveto (int x, int y)
2555 const char *name; 2482 const char *name;
2556 int fd; 2483 int fd;
2557 name = (const char *) ttyname (0); 2484 name = (const char *) ttyname (0);
2558 fd = open (name, O_WRONLY); 2485 fd = emacs_open (name, O_WRONLY, 0);
2559 SOME_FUNCTION (x, y, fd); 2486 SOME_FUNCTION (x, y, fd);
2560 close (fd); 2487 emacs_close (fd);
2561 last_mouse_x = x; 2488 last_mouse_x = x;
2562 last_mouse_y = y; */ 2489 last_mouse_y = y; */
2563} 2490}
@@ -2595,8 +2522,8 @@ tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row,
2595 cursor_to (f, save_y, save_x); 2522 cursor_to (f, save_y, save_x);
2596} 2523}
2597 2524
2598static int 2525static bool
2599term_mouse_movement (FRAME_PTR frame, Gpm_Event *event) 2526term_mouse_movement (struct frame *frame, Gpm_Event *event)
2600{ 2527{
2601 /* Has the mouse moved off the glyph it was on at the last sighting? */ 2528 /* Has the mouse moved off the glyph it was on at the last sighting? */
2602 if (event->x != last_mouse_x || event->y != last_mouse_y) 2529 if (event->x != last_mouse_x || event->y != last_mouse_y)
@@ -2611,6 +2538,18 @@ term_mouse_movement (FRAME_PTR frame, Gpm_Event *event)
2611 return 0; 2538 return 0;
2612} 2539}
2613 2540
2541/* Return the Time that corresponds to T. Wrap around on overflow. */
2542static Time
2543timeval_to_Time (struct timeval const *t)
2544{
2545 Time s_1000, ms;
2546
2547 s_1000 = t->tv_sec;
2548 s_1000 *= 1000;
2549 ms = t->tv_usec / 1000;
2550 return s_1000 + ms;
2551}
2552
2614/* Return the current position of the mouse. 2553/* Return the current position of the mouse.
2615 2554
2616 Set *f to the frame the mouse is in, or zero if the mouse is in no 2555 Set *f to the frame the mouse is in, or zero if the mouse is in no
@@ -2625,12 +2564,11 @@ term_mouse_movement (FRAME_PTR frame, Gpm_Event *event)
2625 This clears mouse_moved until the next motion 2564 This clears mouse_moved until the next motion
2626 event arrives. */ 2565 event arrives. */
2627static void 2566static void
2628term_mouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window, 2567term_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
2629 enum scroll_bar_part *part, Lisp_Object *x, 2568 enum scroll_bar_part *part, Lisp_Object *x,
2630 Lisp_Object *y, Time *timeptr) 2569 Lisp_Object *y, Time *timeptr)
2631{ 2570{
2632 struct timeval now; 2571 struct timeval now;
2633 Time sec, usec;
2634 2572
2635 *fp = SELECTED_FRAME (); 2573 *fp = SELECTED_FRAME ();
2636 (*fp)->mouse_moved = 0; 2574 (*fp)->mouse_moved = 0;
@@ -2641,9 +2579,7 @@ term_mouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window,
2641 XSETINT (*x, last_mouse_x); 2579 XSETINT (*x, last_mouse_x);
2642 XSETINT (*y, last_mouse_y); 2580 XSETINT (*y, last_mouse_y);
2643 gettimeofday(&now, 0); 2581 gettimeofday(&now, 0);
2644 sec = now.tv_sec; 2582 *timeptr = timeval_to_Time (&now);
2645 usec = now.tv_usec;
2646 *timeptr = (sec * 1000) + (usec / 1000);
2647} 2583}
2648 2584
2649/* Prepare a mouse-event in *RESULT for placement in the input queue. 2585/* Prepare a mouse-event in *RESULT for placement in the input queue.
@@ -2667,7 +2603,7 @@ term_mouse_click (struct input_event *result, Gpm_Event *event,
2667 } 2603 }
2668 } 2604 }
2669 gettimeofday(&now, 0); 2605 gettimeofday(&now, 0);
2670 result->timestamp = (now.tv_sec * 1000) + (now.tv_usec / 1000); 2606 result->timestamp = timeval_to_Time (&now);
2671 2607
2672 if (event->type & GPM_UP) 2608 if (event->type & GPM_UP)
2673 result->modifiers = up_modifier; 2609 result->modifiers = up_modifier;
@@ -2716,7 +2652,7 @@ handle_one_term_event (struct tty_display_info *tty, Gpm_Event *event, struct in
2716{ 2652{
2717 struct frame *f = XFRAME (tty->top_frame); 2653 struct frame *f = XFRAME (tty->top_frame);
2718 struct input_event ie; 2654 struct input_event ie;
2719 int do_help = 0; 2655 bool do_help = 0;
2720 int count = 0; 2656 int count = 0;
2721 2657
2722 EVENT_INIT (ie); 2658 EVENT_INIT (ie);
@@ -3775,13 +3711,9 @@ tty_menu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
3775void 3711void
3776create_tty_output (struct frame *f) 3712create_tty_output (struct frame *f)
3777{ 3713{
3778 struct tty_output *t; 3714 struct tty_output *t = xzalloc (sizeof *t);
3779 3715
3780 if (! FRAME_TERMCAP_P (f)) 3716 eassert (FRAME_TERMCAP_P (f));
3781 abort ();
3782
3783 t = xmalloc (sizeof (struct tty_output));
3784 memset (t, 0, sizeof (struct tty_output));
3785 3717
3786 t->display_info = FRAME_TERMINAL (f)->display_info.tty; 3718 t->display_info = FRAME_TERMINAL (f)->display_info.tty;
3787 3719
@@ -3793,8 +3725,7 @@ create_tty_output (struct frame *f)
3793static void 3725static void
3794tty_free_frame_resources (struct frame *f) 3726tty_free_frame_resources (struct frame *f)
3795{ 3727{
3796 if (! FRAME_TERMCAP_P (f)) 3728 eassert (FRAME_TERMCAP_P (f));
3797 abort ();
3798 3729
3799 if (FRAME_FACE_CACHE (f)) 3730 if (FRAME_FACE_CACHE (f))
3800 free_frame_faces (f); 3731 free_frame_faces (f);
@@ -3809,8 +3740,7 @@ tty_free_frame_resources (struct frame *f)
3809static void 3740static void
3810tty_free_frame_resources (struct frame *f) 3741tty_free_frame_resources (struct frame *f)
3811{ 3742{
3812 if (! FRAME_TERMCAP_P (f) && ! FRAME_MSDOS_P (f)) 3743 eassert (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f));
3813 abort ();
3814 3744
3815 if (FRAME_FACE_CACHE (f)) 3745 if (FRAME_FACE_CACHE (f))
3816 free_frame_faces (f); 3746 free_frame_faces (f);
@@ -3899,38 +3829,23 @@ set_tty_hooks (struct terminal *terminal)
3899 terminal->delete_terminal_hook = &delete_tty; 3829 terminal->delete_terminal_hook = &delete_tty;
3900} 3830}
3901 3831
3902/* Drop the controlling terminal if fd is the same device. */ 3832/* If FD is the controlling terminal, drop it. */
3903static void 3833static void
3904dissociate_if_controlling_tty (int fd) 3834dissociate_if_controlling_tty (int fd)
3905{ 3835{
3906#ifndef DOS_NT 3836 /* If tcgetpgrp succeeds, fd is the controlling terminal,
3907 int pgid = tcgetpgrp (fd); /* If tcgetpgrp succeeds, fd is the ctty. */ 3837 so dissociate it by invoking setsid. */
3908 if (pgid != -1) 3838 if (tcgetpgrp (fd) >= 0 && setsid () < 0)
3909 { 3839 {
3910#if defined (USG5) 3840#ifdef TIOCNOTTY
3911 setpgrp (); 3841 /* setsid failed, presumably because Emacs is already a process
3912 no_controlling_tty = 1; 3842 group leader. Fall back on the obsolescent way to dissociate
3913#elif defined (CYGWIN) 3843 a controlling tty. */
3914 setsid (); 3844 block_tty_out_signal ();
3915 no_controlling_tty = 1; 3845 ioctl (fd, TIOCNOTTY, 0);
3916#else 3846 unblock_tty_out_signal ();
3917#ifdef TIOCNOTTY /* Try BSD ioctls. */ 3847#endif
3918 sigblock (sigmask (SIGTTOU));
3919 fd = emacs_open (DEV_TTY, O_RDWR, 0);
3920 if (fd != -1 && ioctl (fd, TIOCNOTTY, 0) != -1)
3921 {
3922 no_controlling_tty = 1;
3923 }
3924 if (fd != -1)
3925 emacs_close (fd);
3926 sigunblock (sigmask (SIGTTOU));
3927#else
3928 /* Unknown system. */
3929 croak ();
3930#endif /* ! TIOCNOTTY */
3931#endif /* ! USG */
3932 } 3848 }
3933#endif /* !DOS_NT */
3934} 3849}
3935 3850
3936/* Create a termcap display on the tty device with the given name and 3851/* Create a termcap display on the tty device with the given name and
@@ -3942,18 +3857,21 @@ dissociate_if_controlling_tty (int fd)
3942 3857
3943 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100". 3858 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
3944 3859
3945 If MUST_SUCCEED is true, then all errors are fatal. */ 3860 If MUST_SUCCEED is true, then all errors are fatal. */
3946 3861
3947struct terminal * 3862struct terminal *
3948init_tty (const char *name, const char *terminal_type, int must_succeed) 3863init_tty (const char *name, const char *terminal_type, bool must_succeed)
3949{ 3864{
3950 char *area = NULL; 3865#ifdef TERMINFO
3866 char **address = 0;
3867#else
3868 char *area;
3951 char **address = &area; 3869 char **address = &area;
3952 int buffer_size = 4096; 3870#endif
3953 int status; 3871 int status;
3954 struct tty_display_info *tty = NULL; 3872 struct tty_display_info *tty = NULL;
3955 struct terminal *terminal = NULL; 3873 struct terminal *terminal = NULL;
3956 int ctty = 0; /* 1 if asked to open controlling tty. */ 3874 bool ctty = false; /* True if asked to open controlling tty. */
3957 3875
3958 if (!terminal_type) 3876 if (!terminal_type)
3959 maybe_fatal (must_succeed, 0, 3877 maybe_fatal (must_succeed, 0,
@@ -3982,9 +3900,9 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
3982 been_here = 1; 3900 been_here = 1;
3983 tty = &the_only_display_info; 3901 tty = &the_only_display_info;
3984#else 3902#else
3985 tty = (struct tty_display_info *) xmalloc (sizeof (struct tty_display_info)); 3903 tty = xzalloc (sizeof *tty);
3986#endif 3904#endif
3987 memset (tty, 0, sizeof (struct tty_display_info)); 3905 tty->top_frame = Qnil;
3988 tty->next = tty_list; 3906 tty->next = tty_list;
3989 tty_list = tty; 3907 tty_list = tty;
3990 3908
@@ -3992,7 +3910,7 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
3992 terminal->display_info.tty = tty; 3910 terminal->display_info.tty = tty;
3993 tty->terminal = terminal; 3911 tty->terminal = terminal;
3994 3912
3995 tty->Wcm = (struct cm *) xmalloc (sizeof (struct cm)); 3913 tty->Wcm = xmalloc (sizeof *tty->Wcm);
3996 Wcm_clear (tty); 3914 Wcm_clear (tty);
3997 3915
3998 encode_terminal_src_size = 0; 3916 encode_terminal_src_size = 0;
@@ -4003,48 +3921,32 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
4003 set_tty_hooks (terminal); 3921 set_tty_hooks (terminal);
4004 3922
4005 { 3923 {
4006 int fd; 3924 /* Open the terminal device. */
4007 FILE *file;
4008
4009#ifdef O_IGNORE_CTTY
4010 if (!ctty)
4011 /* Open the terminal device. Don't recognize it as our
4012 controlling terminal, and don't make it the controlling tty
4013 if we don't have one at the moment. */
4014 fd = emacs_open (name, O_RDWR | O_IGNORE_CTTY | O_NOCTTY, 0);
4015 else
4016#endif /* O_IGNORE_CTTY */
4017 /* Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
4018 defined on Hurd. On other systems, we need to explicitly
4019 dissociate ourselves from the controlling tty when we want to
4020 open a frame on the same terminal. */
4021 fd = emacs_open (name, O_RDWR | O_NOCTTY, 0);
4022 3925
4023 tty->name = xstrdup (name); 3926 /* If !ctty, don't recognize it as our controlling terminal, and
4024 terminal->name = xstrdup (name); 3927 don't make it the controlling tty if we don't have one now.
4025 3928
4026 if (fd < 0) 3929 Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
4027 maybe_fatal (must_succeed, terminal, 3930 defined on Hurd. On other systems, we need to explicitly
4028 "Could not open file: %s", 3931 dissociate ourselves from the controlling tty when we want to
4029 "Could not open file: %s", 3932 open a frame on the same terminal. */
4030 name); 3933 int flags = O_RDWR | O_NOCTTY | (ctty ? 0 : O_IGNORE_CTTY);
4031 if (!isatty (fd)) 3934 int fd = emacs_open (name, flags, 0);
3935 tty->input = tty->output = fd < 0 || ! isatty (fd) ? 0 : fdopen (fd, "w+");
3936
3937 if (! tty->input)
4032 { 3938 {
4033 close (fd); 3939 char const *diagnostic
4034 maybe_fatal (must_succeed, terminal, 3940 = tty->input ? "Not a tty device: %s" : "Could not open file: %s";
4035 "Not a tty device: %s", 3941 emacs_close (fd);
4036 "Not a tty device: %s", 3942 maybe_fatal (must_succeed, terminal, diagnostic, diagnostic, name);
4037 name);
4038 } 3943 }
4039 3944
4040#ifndef O_IGNORE_CTTY 3945 tty->name = xstrdup (name);
4041 if (!ctty) 3946 terminal->name = xstrdup (name);
4042 dissociate_if_controlling_tty (fd);
4043#endif
4044 3947
4045 file = fdopen (fd, "w+"); 3948 if (!O_IGNORE_CTTY && !ctty)
4046 tty->input = file; 3949 dissociate_if_controlling_tty (fd);
4047 tty->output = file;
4048 } 3950 }
4049 3951
4050 tty->type = xstrdup (terminal_type); 3952 tty->type = xstrdup (terminal_type);
@@ -4053,13 +3955,17 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
4053 3955
4054 Wcm_clear (tty); 3956 Wcm_clear (tty);
4055 3957
4056 tty->termcap_term_buffer = (char *) xmalloc (buffer_size);
4057
4058 /* On some systems, tgetent tries to access the controlling 3958 /* On some systems, tgetent tries to access the controlling
4059 terminal. */ 3959 terminal. */
4060 sigblock (sigmask (SIGTTOU)); 3960 block_tty_out_signal ();
3961#ifdef TERMINFO
3962 status = tgetent (0, terminal_type);
3963#else
4061 status = tgetent (tty->termcap_term_buffer, terminal_type); 3964 status = tgetent (tty->termcap_term_buffer, terminal_type);
4062 sigunblock (sigmask (SIGTTOU)); 3965 if (tty->termcap_term_buffer[TERMCAP_BUFFER_SIZE - 1])
3966 emacs_abort ();
3967#endif
3968 unblock_tty_out_signal ();
4063 3969
4064 if (status < 0) 3970 if (status < 0)
4065 { 3971 {
@@ -4090,11 +3996,8 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
4090 } 3996 }
4091 3997
4092#ifndef TERMINFO 3998#ifndef TERMINFO
4093 if (strlen (tty->termcap_term_buffer) >= buffer_size) 3999 area = tty->termcap_strings_buffer;
4094 abort ();
4095 buffer_size = strlen (tty->termcap_term_buffer);
4096#endif 4000#endif
4097 tty->termcap_strings_buffer = area = (char *) xmalloc (buffer_size);
4098 tty->TS_ins_line = tgetstr ("al", address); 4001 tty->TS_ins_line = tgetstr ("al", address);
4099 tty->TS_ins_multi_lines = tgetstr ("AL", address); 4002 tty->TS_ins_multi_lines = tgetstr ("AL", address);
4100 tty->TS_bell = tgetstr ("bl", address); 4003 tty->TS_bell = tgetstr ("bl", address);
@@ -4126,13 +4029,13 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
4126 Right (tty) = tgetstr ("nd", address); 4029 Right (tty) = tgetstr ("nd", address);
4127 Down (tty) = tgetstr ("do", address); 4030 Down (tty) = tgetstr ("do", address);
4128 if (!Down (tty)) 4031 if (!Down (tty))
4129 Down (tty) = tgetstr ("nl", address); /* Obsolete name for "do" */ 4032 Down (tty) = tgetstr ("nl", address); /* Obsolete name for "do". */
4130 if (tgetflag ("bs")) 4033 if (tgetflag ("bs"))
4131 Left (tty) = "\b"; /* can't possibly be longer! */ 4034 Left (tty) = "\b"; /* Can't possibly be longer! */
4132 else /* (Actually, "bs" is obsolete...) */ 4035 else /* (Actually, "bs" is obsolete...) */
4133 Left (tty) = tgetstr ("le", address); 4036 Left (tty) = tgetstr ("le", address);
4134 if (!Left (tty)) 4037 if (!Left (tty))
4135 Left (tty) = tgetstr ("bc", address); /* Obsolete name for "le" */ 4038 Left (tty) = tgetstr ("bc", address); /* Obsolete name for "le". */
4136 tty->TS_pad_char = tgetstr ("pc", address); 4039 tty->TS_pad_char = tgetstr ("pc", address);
4137 tty->TS_repeat = tgetstr ("rp", address); 4040 tty->TS_repeat = tgetstr ("rp", address);
4138 tty->TS_end_standout_mode = tgetstr ("se", address); 4041 tty->TS_end_standout_mode = tgetstr ("se", address);
@@ -4152,8 +4055,8 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
4152 tty->TS_enter_underline_mode = tgetstr ("us", address); 4055 tty->TS_enter_underline_mode = tgetstr ("us", address);
4153 tty->TS_exit_underline_mode = tgetstr ("ue", address); 4056 tty->TS_exit_underline_mode = tgetstr ("ue", address);
4154 tty->TS_enter_bold_mode = tgetstr ("md", address); 4057 tty->TS_enter_bold_mode = tgetstr ("md", address);
4058 tty->TS_enter_italic_mode = tgetstr ("ZH", address);
4155 tty->TS_enter_dim_mode = tgetstr ("mh", address); 4059 tty->TS_enter_dim_mode = tgetstr ("mh", address);
4156 tty->TS_enter_blink_mode = tgetstr ("mb", address);
4157 tty->TS_enter_reverse_mode = tgetstr ("mr", address); 4060 tty->TS_enter_reverse_mode = tgetstr ("mr", address);
4158 tty->TS_enter_alt_charset_mode = tgetstr ("as", address); 4061 tty->TS_enter_alt_charset_mode = tgetstr ("as", address);
4159 tty->TS_exit_alt_charset_mode = tgetstr ("ae", address); 4062 tty->TS_exit_alt_charset_mode = tgetstr ("ae", address);
@@ -4206,14 +4109,14 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
4206#ifdef WINDOWSNT 4109#ifdef WINDOWSNT
4207 { 4110 {
4208 struct frame *f = XFRAME (selected_frame); 4111 struct frame *f = XFRAME (selected_frame);
4112 int height, width;
4209 4113
4210 initialize_w32_display (terminal); 4114 initialize_w32_display (terminal, &width, &height);
4211 4115
4212 FrameRows (tty) = FRAME_LINES (f); 4116 FrameRows (tty) = height;
4213 FrameCols (tty) = FRAME_COLS (f); 4117 FrameCols (tty) = width;
4214 tty->specified_window = FRAME_LINES (f); 4118 tty->specified_window = height;
4215 4119
4216 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
4217 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none; 4120 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
4218 terminal->char_ins_del_ok = 1; 4121 terminal->char_ins_del_ok = 1;
4219 baud_rate = 19200; 4122 baud_rate = 19200;
@@ -4254,7 +4157,7 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
4254 don't think we're losing anything by turning it off. */ 4157 don't think we're losing anything by turning it off. */
4255 terminal->line_ins_del_ok = 0; 4158 terminal->line_ins_del_ok = 0;
4256 4159
4257 tty->TN_max_colors = 16; /* Required to be non-zero for tty-display-color-p */ 4160 tty->TN_max_colors = 16; /* Must be non-zero for tty-display-color-p. */
4258#endif /* DOS_NT */ 4161#endif /* DOS_NT */
4259 4162
4260#ifdef HAVE_GPM 4163#ifdef HAVE_GPM
@@ -4262,9 +4165,9 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
4262 tty->mouse_highlight.mouse_face_window = Qnil; 4165 tty->mouse_highlight.mouse_face_window = Qnil;
4263#endif 4166#endif
4264 4167
4265 terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD)); 4168 terminal->kboard = xmalloc (sizeof *terminal->kboard);
4266 init_kboard (terminal->kboard); 4169 init_kboard (terminal->kboard);
4267 KVAR (terminal->kboard, Vwindow_system) = Qnil; 4170 kset_window_system (terminal->kboard, Qnil);
4268 terminal->kboard->next_kboard = all_kboards; 4171 terminal->kboard->next_kboard = all_kboards;
4269 all_kboards = terminal->kboard; 4172 all_kboards = terminal->kboard;
4270 terminal->kboard->reference_count++; 4173 terminal->kboard->reference_count++;
@@ -4350,16 +4253,16 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
4350 tty->Wcm->cm_tab = 0; 4253 tty->Wcm->cm_tab = 0;
4351 /* We can't support standout mode, because it uses magic cookies. */ 4254 /* We can't support standout mode, because it uses magic cookies. */
4352 tty->TS_standout_mode = 0; 4255 tty->TS_standout_mode = 0;
4353 /* But that means we cannot rely on ^M to go to column zero! */ 4256 /* But that means we cannot rely on ^M to go to column zero! */
4354 CR (tty) = 0; 4257 CR (tty) = 0;
4355 /* LF can't be trusted either -- can alter hpos */ 4258 /* LF can't be trusted either -- can alter hpos. */
4356 /* if move at column 0 thru a line with TS_standout_mode */ 4259 /* If move at column 0 thru a line with TS_standout_mode. */
4357 Down (tty) = 0; 4260 Down (tty) = 0;
4358 } 4261 }
4359 4262
4360 tty->specified_window = FrameRows (tty); 4263 tty->specified_window = FrameRows (tty);
4361 4264
4362 if (Wcm_init (tty) == -1) /* can't do cursor motion */ 4265 if (Wcm_init (tty) == -1) /* Can't do cursor motion. */
4363 { 4266 {
4364 maybe_fatal (must_succeed, terminal, 4267 maybe_fatal (must_succeed, terminal,
4365 "Terminal type \"%s\" is not powerful enough to run Emacs", 4268 "Terminal type \"%s\" is not powerful enough to run Emacs",
@@ -4385,10 +4288,6 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
4385 = tty->TS_delete_mode && tty->TS_insert_mode 4288 = tty->TS_delete_mode && tty->TS_insert_mode
4386 && !strcmp (tty->TS_delete_mode, tty->TS_insert_mode); 4289 && !strcmp (tty->TS_delete_mode, tty->TS_insert_mode);
4387 4290
4388 tty->se_is_so = (tty->TS_standout_mode
4389 && tty->TS_end_standout_mode
4390 && !strcmp (tty->TS_standout_mode, tty->TS_end_standout_mode));
4391
4392 UseTabs (tty) = tabs_safe_p (fileno (tty->input)) && TabWidth (tty) == 8; 4291 UseTabs (tty) = tabs_safe_p (fileno (tty->input)) && TabWidth (tty) == 8;
4393 4292
4394 terminal->scroll_region_ok 4293 terminal->scroll_region_ok
@@ -4433,10 +4332,10 @@ vfatal (const char *str, va_list ap)
4433 4332
4434/* Auxiliary error-handling function for init_tty. 4333/* Auxiliary error-handling function for init_tty.
4435 Delete TERMINAL, then call error or fatal with str1 or str2, 4334 Delete TERMINAL, then call error or fatal with str1 or str2,
4436 respectively, according to whether MUST_SUCCEED is zero or not. */ 4335 respectively, according to whether MUST_SUCCEED is true. */
4437 4336
4438static void 4337static void
4439maybe_fatal (int must_succeed, struct terminal *terminal, 4338maybe_fatal (bool must_succeed, struct terminal *terminal,
4440 const char *str1, const char *str2, ...) 4339 const char *str1, const char *str2, ...)
4441{ 4340{
4442 va_list ap; 4341 va_list ap;
@@ -4448,9 +4347,6 @@ maybe_fatal (int must_succeed, struct terminal *terminal,
4448 vfatal (str2, ap); 4347 vfatal (str2, ap);
4449 else 4348 else
4450 verror (str1, ap); 4349 verror (str1, ap);
4451
4452 va_end (ap);
4453 abort ();
4454} 4350}
4455 4351
4456void 4352void
@@ -4459,7 +4355,6 @@ fatal (const char *str, ...)
4459 va_list ap; 4355 va_list ap;
4460 va_start (ap, str); 4356 va_start (ap, str);
4461 vfatal (str, ap); 4357 vfatal (str, ap);
4462 va_end (ap);
4463} 4358}
4464 4359
4465 4360
@@ -4476,8 +4371,7 @@ delete_tty (struct terminal *terminal)
4476 if (!terminal->name) 4371 if (!terminal->name)
4477 return; 4372 return;
4478 4373
4479 if (terminal->type != output_termcap) 4374 eassert (terminal->type == output_termcap);
4480 abort ();
4481 4375
4482 tty = terminal->display_info.tty; 4376 tty = terminal->display_info.tty;
4483 4377
@@ -4491,7 +4385,7 @@ delete_tty (struct terminal *terminal)
4491 4385
4492 if (! p) 4386 if (! p)
4493 /* This should not happen. */ 4387 /* This should not happen. */
4494 abort (); 4388 emacs_abort ();
4495 4389
4496 p->next = tty->next; 4390 p->next = tty->next;
4497 tty->next = 0; 4391 tty->next = 0;
@@ -4519,29 +4413,9 @@ delete_tty (struct terminal *terminal)
4519 4413
4520 xfree (tty->old_tty); 4414 xfree (tty->old_tty);
4521 xfree (tty->Wcm); 4415 xfree (tty->Wcm);
4522 xfree (tty->termcap_strings_buffer);
4523 xfree (tty->termcap_term_buffer);
4524
4525 memset (tty, 0, sizeof (struct tty_display_info));
4526 xfree (tty); 4416 xfree (tty);
4527} 4417}
4528 4418
4529
4530
4531/* Mark the pointers in the tty_display_info objects.
4532 Called by Fgarbage_collect. */
4533
4534void
4535mark_ttys (void)
4536{
4537 struct tty_display_info *tty;
4538
4539 for (tty = tty_list; tty; tty = tty->next)
4540 mark_object (tty->top_frame);
4541}
4542
4543
4544
4545void 4419void
4546syms_of_term (void) 4420syms_of_term (void)
4547{ 4421{
@@ -4555,14 +4429,14 @@ This variable can be used by terminal emulator packages. */);
4555#endif 4429#endif
4556 4430
4557 DEFVAR_LISP ("suspend-tty-functions", Vsuspend_tty_functions, 4431 DEFVAR_LISP ("suspend-tty-functions", Vsuspend_tty_functions,
4558 doc: /* Functions to be run after suspending a tty. 4432 doc: /* Functions run after suspending a tty.
4559The functions are run with one argument, the terminal object to be suspended. 4433The functions are run with one argument, the terminal object to be suspended.
4560See `suspend-tty'. */); 4434See `suspend-tty'. */);
4561 Vsuspend_tty_functions = Qnil; 4435 Vsuspend_tty_functions = Qnil;
4562 4436
4563 4437
4564 DEFVAR_LISP ("resume-tty-functions", Vresume_tty_functions, 4438 DEFVAR_LISP ("resume-tty-functions", Vresume_tty_functions,
4565 doc: /* Functions to be run after resuming a tty. 4439 doc: /* Functions run after resuming a tty.
4566The functions are run with one argument, the terminal object that was revived. 4440The functions are run with one argument, the terminal object that was revived.
4567See `resume-tty'. */); 4441See `resume-tty'. */);
4568 Vresume_tty_functions = Qnil; 4442 Vresume_tty_functions = Qnil;
@@ -4579,6 +4453,7 @@ bigger, or it may make it blink, or it may do nothing at all. */);
4579 defsubr (&Stty_no_underline); 4453 defsubr (&Stty_no_underline);
4580 defsubr (&Stty_type); 4454 defsubr (&Stty_type);
4581 defsubr (&Scontrolling_tty_p); 4455 defsubr (&Scontrolling_tty_p);
4456 defsubr (&Stty_top_frame);
4582 defsubr (&Ssuspend_tty); 4457 defsubr (&Ssuspend_tty);
4583 defsubr (&Sresume_tty); 4458 defsubr (&Sresume_tty);
4584#ifdef HAVE_GPM 4459#ifdef HAVE_GPM