diff options
Diffstat (limited to 'src/terminal.c')
-rw-r--r-- | src/terminal.c | 66 |
1 files changed, 65 insertions, 1 deletions
diff --git a/src/terminal.c b/src/terminal.c index b48d0623e12..15d74f4e812 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -28,6 +28,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #include "coding.h" #include "keyboard.h" +#ifdef HAVE_LINUX_KD_H +# include <errno.h> +# include <linux/kd.h> +#endif + /* Chain of all terminals currently in use. */ struct terminal *terminal_list; @@ -193,7 +198,7 @@ ins_del_lines (struct frame *f, int vpos, int n) } /* Return the terminal object specified by TERMINAL. TERMINAL may - be a terminal object, a frame, or nil for the terminal device of +” be a terminal object, a frame, or nil for the terminal device of the current frame. If TERMINAL is neither from the above or the resulting terminal object is deleted, return NULL. */ @@ -526,6 +531,65 @@ selected frame's terminal). */) return store_terminal_param (decode_live_terminal (terminal), parameter, value); } +#if HAVE_LINUX_KD_H + +/* Compute the glyph code table for T. */ + +static void +calculate_glyph_code_table (struct terminal *t) +{ + Lisp_Object glyphtab = Qt; + enum { initial_unipairs = 1000 }; + int entry_ct = initial_unipairs; + struct unipair unipair_buffer[initial_unipairs]; + struct unipair *entries = unipair_buffer; + struct unipair *alloced = 0; + + while (true) + { + int fd = fileno (t->display_info.tty->output); + struct unimapdesc unimapdesc = { entry_ct, entries }; + if (ioctl (fd, GIO_UNIMAP, &unimapdesc) == 0) + { + glyphtab = Fmake_char_table (Qnil, make_number (-1)); + for (int i = 0; i < unimapdesc.entry_ct; i++) + char_table_set (glyphtab, entries[i].unicode, + make_number (entries[i].fontpos)); + break; + } + if (errno != ENOMEM) + break; + entry_ct = unimapdesc.entry_ct; + entries = alloced = xrealloc (alloced, entry_ct * sizeof *alloced); + } + + xfree (alloced); + t->glyph_code_table = glyphtab; +} +#endif + +/* Return the glyph code in T of character CH, or -1 if CH does not + have a font position in T, or nil if T does not report glyph codes. */ + +Lisp_Object +terminal_glyph_code (struct terminal *t, int ch) +{ +#if HAVE_LINUX_KD_H + if (t->type == output_termcap) + { + /* As a hack, recompute the table when CH is the maximum + character. */ + if (NILP (t->glyph_code_table) || ch == MAX_CHAR) + calculate_glyph_code_table (t); + + if (! EQ (t->glyph_code_table, Qt)) + return char_table_ref (t->glyph_code_table, ch); + } +#endif + + return Qnil; +} + /* Initial frame has no device-dependent output data, but has face cache which should be freed when the frame is deleted. */ |