2005-09-15 09:58:31 -04:00
|
|
|
#ifndef EL__TERMINAL_TERMINAL_H
|
|
|
|
#define EL__TERMINAL_TERMINAL_H
|
|
|
|
|
|
|
|
#include "config/options.h"
|
|
|
|
#include "terminal/event.h"
|
|
|
|
#include "util/lists.h"
|
|
|
|
|
2020-10-05 14:14:55 -04:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2006-05-20 08:59:40 -04:00
|
|
|
struct module;
|
2005-09-15 09:58:31 -04:00
|
|
|
struct option;
|
|
|
|
struct terminal_screen;
|
|
|
|
struct terminal_interlink;
|
|
|
|
|
|
|
|
|
2007-07-27 09:50:37 -04:00
|
|
|
/** The terminal type, meaningful for frames (lines) drawing. */
|
2005-09-15 09:58:31 -04:00
|
|
|
enum term_mode_type {
|
|
|
|
TERM_DUMB = 0,
|
|
|
|
TERM_VT100,
|
|
|
|
TERM_LINUX,
|
|
|
|
TERM_KOI8,
|
|
|
|
TERM_FREEBSD,
|
2009-03-27 14:44:46 -04:00
|
|
|
TERM_FBTERM,
|
2005-09-15 09:58:31 -04:00
|
|
|
};
|
|
|
|
|
2022-01-28 11:54:58 -05:00
|
|
|
typedef int term_mode_type_T;
|
2007-07-27 09:50:37 -04:00
|
|
|
/** This is a bitmask describing the environment we are living in,
|
2005-09-15 09:58:31 -04:00
|
|
|
* terminal-wise. We can then conditionally use various features available
|
|
|
|
* in such an environment. */
|
|
|
|
enum term_env_type {
|
2007-07-27 09:50:37 -04:00
|
|
|
/** This basically means that we can use the text i/o :). Always set. */
|
2005-09-15 09:58:31 -04:00
|
|
|
ENV_CONSOLE = 1,
|
2007-07-27 09:50:37 -04:00
|
|
|
/** We are running in a xterm-compatible box in some windowing
|
2005-09-15 09:58:31 -04:00
|
|
|
* environment. */
|
|
|
|
ENV_XWIN = 2,
|
2007-07-27 09:50:37 -04:00
|
|
|
/** We are running under a screen. */
|
2005-09-15 09:58:31 -04:00
|
|
|
ENV_SCREEN = 4,
|
2007-07-27 09:50:37 -04:00
|
|
|
/** We are running in a OS/2 VIO terminal. */
|
2005-09-15 09:58:31 -04:00
|
|
|
ENV_OS2VIO = 8,
|
2007-07-27 09:50:37 -04:00
|
|
|
/** BeOS text terminal. */
|
2005-09-15 09:58:31 -04:00
|
|
|
ENV_BE = 16,
|
2007-07-27 09:50:37 -04:00
|
|
|
/** We live in a TWIN text-mode windowing environment. */
|
2005-09-15 09:58:31 -04:00
|
|
|
ENV_TWIN = 32,
|
2007-07-27 09:50:37 -04:00
|
|
|
/** Microsoft Windows cmdline thing. */
|
2005-09-15 09:58:31 -04:00
|
|
|
ENV_WIN32 = 64,
|
2007-07-27 09:50:37 -04:00
|
|
|
/** Match all terminal environments */
|
2005-09-15 09:58:31 -04:00
|
|
|
ENV_ANY = ~0,
|
|
|
|
};
|
|
|
|
|
2022-01-28 11:37:43 -05:00
|
|
|
typedef int term_env_type_T;
|
|
|
|
|
2005-09-15 09:58:31 -04:00
|
|
|
enum term_redrawing_state {
|
2007-07-27 09:50:37 -04:00
|
|
|
TREDRAW_READY = 0, /**< Can redraw */
|
|
|
|
TREDRAW_BUSY = 1, /**< Redrawing already in progress */
|
|
|
|
TREDRAW_DELAYED = 2, /**< Do not redraw for now */
|
2005-09-15 09:58:31 -04:00
|
|
|
};
|
|
|
|
|
2007-07-27 09:50:37 -04:00
|
|
|
/** This is one of the axis of ELinks' user interaction. struct terminal
|
2005-09-15 09:58:31 -04:00
|
|
|
* defines the terminal ELinks is running on --- each ELinks instance has
|
|
|
|
* one. It contains the basic terminal attributes, the settings associated
|
|
|
|
* with this terminal, screen content (and more abstract description of what
|
|
|
|
* is currently displayed on it) etc. It also maintains some runtime
|
2007-07-27 09:50:37 -04:00
|
|
|
* information about the actual ELinks instance owning this terminal.
|
|
|
|
*
|
2007-07-31 06:38:00 -04:00
|
|
|
* @todo TODO: Regroup the following into logical chunks. --pasky */
|
2005-09-15 09:58:31 -04:00
|
|
|
struct terminal {
|
2007-07-27 09:50:37 -04:00
|
|
|
LIST_HEAD(struct terminal); /*!< ::terminals is the sentinel. */
|
2005-09-15 09:58:31 -04:00
|
|
|
|
2011-11-13 03:01:27 -05:00
|
|
|
#ifdef CONFIG_SCRIPTING_SPIDERMONKEY
|
|
|
|
struct JSObject *jsobject; /* Instance of terminal_class */
|
|
|
|
struct JSObject *session_array_jsobject; /* Instance of session_array_class */
|
|
|
|
#endif
|
|
|
|
|
2007-07-27 09:50:37 -04:00
|
|
|
/** This is (at least partially) a stack of all the windows living in
|
2005-09-15 09:58:31 -04:00
|
|
|
* this terminal. A window can be wide range of stuff, from a menu box
|
|
|
|
* through classical dialog window to a tab. See terminal/window.h for
|
|
|
|
* more on windows.
|
|
|
|
*
|
|
|
|
* Tabs are special windows, though, and you never want to display them
|
2007-07-27 09:50:37 -04:00
|
|
|
* all, but only one of them. ALWAYS check inactive_tab() during
|
2005-09-15 09:58:31 -04:00
|
|
|
* iterations through this list (unless it is really useless or you
|
|
|
|
* are sure what are you doing) to make sure that you don't distribute
|
|
|
|
* events etc to inactive tabs.
|
|
|
|
*
|
2007-07-27 09:50:37 -04:00
|
|
|
* The stack is top-down, thus @c .next is the stack's top, the
|
|
|
|
* current window; and @c .prev is the bottom, covered by others.
|
2006-05-14 07:03:17 -04:00
|
|
|
* - Dialogs or active menus are at the top.
|
2007-07-27 09:50:37 -04:00
|
|
|
* - Next come all tabs (window.type == ::WINDOW_TAB). The tab
|
2006-05-14 15:17:26 -04:00
|
|
|
* listed leftmost in the tab bar is at the top, and the tab
|
2007-07-27 09:50:37 -04:00
|
|
|
* listed rightmost is at the bottom; but #current_tab controls
|
2006-05-14 15:17:26 -04:00
|
|
|
* which tab is actually displayed.
|
2006-05-14 07:03:17 -04:00
|
|
|
* - If the main menu is inactive, then it is at the very bottom,
|
|
|
|
* hidden under the tabs.
|
2007-07-27 09:50:37 -04:00
|
|
|
* Call assert_window_stacking() to verify this.
|
2005-09-15 09:58:31 -04:00
|
|
|
*
|
2007-07-27 09:50:37 -04:00
|
|
|
* @todo FIXME: Tabs violate the stack nature of this list, they
|
|
|
|
* appear there randomly but always in the order in which they were
|
|
|
|
* inserted there. Eventually, they should all live at the stack
|
|
|
|
* bottom, with the actual tab living on the VERY bottom. --pasky
|
2006-05-14 07:03:17 -04:00
|
|
|
*
|
|
|
|
* Keeping the current tab at the very bottom would require storing
|
|
|
|
* tab numbers explicitly, rather than computing them from the
|
|
|
|
* stack order as is done now. Also, what should be done with the
|
|
|
|
* inactive main menu? --KON */
|
2007-07-26 12:04:35 -04:00
|
|
|
LIST_OF(struct window) windows;
|
2005-09-15 09:58:31 -04:00
|
|
|
|
2007-07-27 09:50:37 -04:00
|
|
|
/** The specification of terminal in terms of terminal options. */
|
2005-09-15 09:58:31 -04:00
|
|
|
struct option *spec;
|
|
|
|
|
2007-07-27 09:50:37 -04:00
|
|
|
/** This is the terminal's current title, as perhaps displayed
|
|
|
|
* somewhere in the X window frame or so. */
|
2021-01-02 10:20:27 -05:00
|
|
|
char *title;
|
2005-09-15 09:58:31 -04:00
|
|
|
|
2007-07-27 09:50:37 -04:00
|
|
|
/** This is the screen. See terminal/screen.h */
|
2005-09-15 09:58:31 -04:00
|
|
|
struct terminal_screen *screen;
|
|
|
|
|
2007-07-27 09:50:37 -04:00
|
|
|
/** This is for displaying main menu */
|
2006-03-03 13:01:15 -05:00
|
|
|
struct menu *main_menu;
|
2007-07-27 09:50:37 -04:00
|
|
|
|
|
|
|
/** These are pipes for communication with the ELinks instance owning
|
|
|
|
* this terminal.
|
|
|
|
* @see struct itrm */
|
2005-09-15 09:58:31 -04:00
|
|
|
int fdin, fdout;
|
|
|
|
|
2007-07-27 09:50:37 -04:00
|
|
|
/** This indicates that the terminal is blocked, that is nothing should
|
2005-09-15 09:58:31 -04:00
|
|
|
* be drawn on it etc. Typically an external program is running on it
|
|
|
|
* right now. This is a file descriptor. */
|
|
|
|
int blocked;
|
|
|
|
|
2007-07-27 09:50:37 -04:00
|
|
|
/** Terminal dimensions. */
|
2005-09-15 09:58:31 -04:00
|
|
|
int width, height;
|
|
|
|
|
2007-07-27 09:50:37 -04:00
|
|
|
/** Indicates whether we are currently in the process of redrawing the
|
2005-09-15 09:58:31 -04:00
|
|
|
* stuff being displayed on the terminal. It is typically used to
|
|
|
|
* prevent redrawing inside of redrawing. */
|
|
|
|
enum term_redrawing_state redrawing;
|
|
|
|
|
2007-07-27 09:50:37 -04:00
|
|
|
/** Indicates the master terminal, that is the terminal under
|
2005-09-15 09:58:31 -04:00
|
|
|
* supervision of the master ELinks instance (the one doing all the
|
|
|
|
* work and even maintaining these structures ;-). */
|
|
|
|
unsigned int master:1;
|
|
|
|
|
2006-09-17 09:12:47 -04:00
|
|
|
#ifdef CONFIG_UTF8
|
2007-07-27 09:50:37 -04:00
|
|
|
/** Indicates whether the charset of the terminal is UTF-8. */
|
2007-05-20 06:50:47 -04:00
|
|
|
unsigned int utf8_cp:1;
|
|
|
|
|
2007-07-27 09:50:37 -04:00
|
|
|
/** Indicates whether UTF-8 I/O is used. Forced on if the
|
2006-12-09 14:13:13 -05:00
|
|
|
* UTF-8 charset is selected. (bug 827) */
|
2007-05-20 08:31:02 -04:00
|
|
|
unsigned int utf8_io:1;
|
2006-09-17 09:12:47 -04:00
|
|
|
#endif /* CONFIG_UTF8 */
|
2006-01-14 16:44:00 -05:00
|
|
|
|
2007-07-27 09:50:37 -04:00
|
|
|
/** The current tab number. */
|
2005-09-15 09:58:31 -04:00
|
|
|
int current_tab;
|
|
|
|
|
|
|
|
#ifdef CONFIG_LEDS
|
2007-07-27 09:50:37 -04:00
|
|
|
/** Current length of leds part of status bar. */
|
2005-09-15 09:58:31 -04:00
|
|
|
int leds_length;
|
|
|
|
#endif
|
|
|
|
|
2007-07-27 09:50:37 -04:00
|
|
|
/** The type of environment this terminal lives in. */
|
2022-01-28 11:37:43 -05:00
|
|
|
term_env_type_T environment;
|
2005-09-15 09:58:31 -04:00
|
|
|
|
2007-07-27 09:50:37 -04:00
|
|
|
/** The current working directory for this terminal / ELinks instance. */
|
2021-01-02 10:20:27 -05:00
|
|
|
char cwd[MAX_CWD_LEN];
|
2005-09-15 09:58:31 -04:00
|
|
|
|
2007-07-27 09:50:37 -04:00
|
|
|
/** For communication between instances */
|
2005-09-15 09:58:31 -04:00
|
|
|
struct terminal_interlink *interlink;
|
|
|
|
|
2007-09-01 08:02:21 -04:00
|
|
|
/* Data for textarea_edit(). */
|
|
|
|
void *textarea_data;
|
2007-09-01 05:02:01 -04:00
|
|
|
|
2005-09-15 09:58:31 -04:00
|
|
|
struct term_event_mouse prev_mouse_event;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define do_not_ignore_next_mouse_event(term) \
|
|
|
|
memset(&(term)->prev_mouse_event, 0, sizeof((term)->prev_mouse_event))
|
|
|
|
|
bug 1054: Don't abort downloads when closing a terminal.
Except if they have external handlers.
When ELinks receives an event from a terminal, move that terminal to
the beginning of the global "terminals" list, so that the terminals
are always sorted according to the time of the most recent use. Note,
this affects the numbering of bookmark folders in session snapshots.
Add get_default_terminal(), which returns the most recently used
terminal that is still open. Use that in various places that
previously used terminals.prev or terminals.next. Four functions
fetch the size of the terminal for User-Agent headers, and
get_default_terminal() is not really right, but neither was the
original code; add TODO comments in those functions.
When the user chooses "Background and Notify", associate the download
with the terminal where the dialog box is. So any later messages will
then appear in that terminal, if it is still open. However, don't
change the terminal if the download has an external handler.
When a download gets some data, don't immediately check the associated
terminal. Instead, wait for the download to end. Then, if the
terminal of the download has been closed, use get_default_terminal()
instead. If there is no default terminal either, just skip any
message boxes.
2008-10-15 04:05:43 -04:00
|
|
|
/** We keep track about all the terminals in this list.
|
|
|
|
* The list is sorted so that terminals.next is the terminal
|
|
|
|
* from which ELinks most recently got an event. But please
|
|
|
|
* call get_default_terminal() for that. */
|
2007-07-26 12:04:35 -04:00
|
|
|
extern LIST_OF(struct terminal) terminals;
|
2005-09-15 09:58:31 -04:00
|
|
|
|
|
|
|
|
2007-01-24 17:05:36 -05:00
|
|
|
extern const unsigned char frame_dumb[];
|
2005-09-15 09:58:31 -04:00
|
|
|
|
|
|
|
struct terminal *init_term(int, int);
|
|
|
|
void destroy_terminal(struct terminal *);
|
|
|
|
void redraw_terminal(struct terminal *term);
|
|
|
|
void redraw_terminal_cls(struct terminal *term);
|
|
|
|
void cls_redraw_all_terminals(void);
|
bug 1054: Don't abort downloads when closing a terminal.
Except if they have external handlers.
When ELinks receives an event from a terminal, move that terminal to
the beginning of the global "terminals" list, so that the terminals
are always sorted according to the time of the most recent use. Note,
this affects the numbering of bookmark folders in session snapshots.
Add get_default_terminal(), which returns the most recently used
terminal that is still open. Use that in various places that
previously used terminals.prev or terminals.next. Four functions
fetch the size of the terminal for User-Agent headers, and
get_default_terminal() is not really right, but neither was the
original code; add TODO comments in those functions.
When the user chooses "Background and Notify", associate the download
with the terminal where the dialog box is. So any later messages will
then appear in that terminal, if it is still open. However, don't
change the terminal if the download has an external handler.
When a download gets some data, don't immediately check the associated
terminal. Instead, wait for the download to end. Then, if the
terminal of the download has been closed, use get_default_terminal()
instead. If there is no default terminal either, just skip any
message boxes.
2008-10-15 04:05:43 -04:00
|
|
|
struct terminal *get_default_terminal(void);
|
2008-12-28 10:42:29 -05:00
|
|
|
int get_terminal_codepage(const struct terminal *);
|
2005-09-15 09:58:31 -04:00
|
|
|
|
|
|
|
void redraw_all_terminals(void);
|
|
|
|
void destroy_all_terminals(void);
|
2021-01-02 10:20:27 -05:00
|
|
|
void exec_thread(char *, int);
|
2005-09-15 09:58:31 -04:00
|
|
|
void close_handle(void *);
|
|
|
|
|
2008-09-30 03:06:20 -04:00
|
|
|
#ifdef CONFIG_FASTMEM
|
|
|
|
#define assert_terminal_ptr_not_dangling(suspect) ((void) 0)
|
|
|
|
#else /* assert() does something */
|
|
|
|
void assert_terminal_ptr_not_dangling(const struct terminal *);
|
|
|
|
#endif
|
|
|
|
|
Bug 885: Proper charset support in xterm window title
When ELinks runs in an X11 terminal emulator (e.g. xterm), or in GNU
Screen, it tries to update the title of the window to match the title
of the current document. To do this, ELinks sends an "OSC 1 ; Pt BEL"
sequence to the terminal. Unfortunately, xterm expects the Pt string
to be in the ISO-8859-1 charset, making it impossible to display e.g.
Cyrillic characters. In xterm patch #210 (2006-03-12) however, there
is a menu item and a resource that can make xterm take the Pt string
in UTF-8 instead, allowing characters from all around the world.
The downside is that ELinks apparently cannot ask xterm whether the
setting is on or off; so add a terminal._template_.latin1_title option
to ELinks and let the user edit that instead.
Complete list of changes:
- Add the terminal._template_.latin1_title option. But do not add
that to the terminal options window because it's already rather
crowded there.
- In set_window_title(), take a new codepage argument. Use it to
decode the title into Unicode characters, and remove only actual
control characters. For example, CP437 has graphical characters in
the 0x80...0x9F range, so don't remove those, even though ISO-8859-1
has control characters in the same range. Likewise, don't
misinterpret single bytes of UTF-8 characters as control characters.
- In set_window_title(), do not truncate the title to the width of the
window. The font is likely to be different and proportional anyway.
But do truncate before 1024 bytes, an xterm limit.
- In struct itrm, add a title_codepage member to remember which
charset the master said it was going to use in the terminal window
title. Initialize title_codepage in handle_trm(), update it in
dispatch_special() if the master sends the new request
TERM_FN_TITLE_CODEPAGE, and use it in most set_window_title() calls;
but not in the one that sets $TERM as the title, because that string
was not received from the master and should consist of ASCII
characters only.
- In set_terminal_title(), convert the caller-provided title to
ISO-8859-1 or UTF-8 if appropriate, and report the codepage to the
slave with the new TERM_FN_TITLE_CODEPAGE request. The conversion
can run out of memory, so return a success/error flag, rather than
void. In display_window_title(), check this result and don't update
caches on error.
- Add a NEWS entry for all of this.
2008-12-28 20:09:53 -05:00
|
|
|
/** Operations that can be requested with do_terminal_function() in
|
|
|
|
* the master and then executed with dispatch_special() in a slave.
|
2007-07-14 05:26:45 -04:00
|
|
|
* The interlink protocol passes these values as one byte in a
|
|
|
|
* null-terminated string, so zero cannot be used. */
|
2007-07-27 09:50:37 -04:00
|
|
|
enum {
|
Bug 885: Proper charset support in xterm window title
When ELinks runs in an X11 terminal emulator (e.g. xterm), or in GNU
Screen, it tries to update the title of the window to match the title
of the current document. To do this, ELinks sends an "OSC 1 ; Pt BEL"
sequence to the terminal. Unfortunately, xterm expects the Pt string
to be in the ISO-8859-1 charset, making it impossible to display e.g.
Cyrillic characters. In xterm patch #210 (2006-03-12) however, there
is a menu item and a resource that can make xterm take the Pt string
in UTF-8 instead, allowing characters from all around the world.
The downside is that ELinks apparently cannot ask xterm whether the
setting is on or off; so add a terminal._template_.latin1_title option
to ELinks and let the user edit that instead.
Complete list of changes:
- Add the terminal._template_.latin1_title option. But do not add
that to the terminal options window because it's already rather
crowded there.
- In set_window_title(), take a new codepage argument. Use it to
decode the title into Unicode characters, and remove only actual
control characters. For example, CP437 has graphical characters in
the 0x80...0x9F range, so don't remove those, even though ISO-8859-1
has control characters in the same range. Likewise, don't
misinterpret single bytes of UTF-8 characters as control characters.
- In set_window_title(), do not truncate the title to the width of the
window. The font is likely to be different and proportional anyway.
But do truncate before 1024 bytes, an xterm limit.
- In struct itrm, add a title_codepage member to remember which
charset the master said it was going to use in the terminal window
title. Initialize title_codepage in handle_trm(), update it in
dispatch_special() if the master sends the new request
TERM_FN_TITLE_CODEPAGE, and use it in most set_window_title() calls;
but not in the one that sets $TERM as the title, because that string
was not received from the master and should consist of ASCII
characters only.
- In set_terminal_title(), convert the caller-provided title to
ISO-8859-1 or UTF-8 if appropriate, and report the codepage to the
slave with the new TERM_FN_TITLE_CODEPAGE request. The conversion
can run out of memory, so return a success/error flag, rather than
void. In display_window_title(), check this result and don't update
caches on error.
- Add a NEWS entry for all of this.
2008-12-28 20:09:53 -05:00
|
|
|
TERM_FN_TITLE = 1,
|
|
|
|
TERM_FN_RESIZE = 2,
|
|
|
|
TERM_FN_TITLE_CODEPAGE = 3
|
2007-07-27 09:50:37 -04:00
|
|
|
};
|
2005-09-15 09:58:31 -04:00
|
|
|
|
2007-07-27 09:50:37 -04:00
|
|
|
/** How to execute a program in a terminal. These values are used in
|
2007-07-14 05:26:45 -04:00
|
|
|
* the interlink protocol and must fit in one byte. */
|
|
|
|
enum term_exec {
|
2007-07-27 09:50:37 -04:00
|
|
|
/** Execute in the background. ELinks keeps using the terminal
|
2007-07-14 05:26:45 -04:00
|
|
|
* and the program should not use it. */
|
|
|
|
TERM_EXEC_BG = 0,
|
|
|
|
|
2007-07-27 09:50:37 -04:00
|
|
|
/** Execute in the foreground. The program may use the terminal.
|
2007-07-14 05:26:45 -04:00
|
|
|
* ELinks will redraw when the program exits. */
|
|
|
|
TERM_EXEC_FG = 1,
|
|
|
|
|
2007-07-27 09:50:37 -04:00
|
|
|
/** Execute in the background and in a new process group. */
|
2007-07-14 05:26:45 -04:00
|
|
|
TERM_EXEC_NEWWIN = 2
|
|
|
|
};
|
|
|
|
|
2022-01-28 09:11:23 -05:00
|
|
|
typedef int term_exec_T;
|
|
|
|
|
2022-02-20 07:52:47 -05:00
|
|
|
void exec_on_terminal(struct terminal *, const char *, const char *, term_exec_T);
|
2005-09-15 09:58:31 -04:00
|
|
|
void exec_shell(struct terminal *term);
|
|
|
|
|
2021-01-02 10:20:27 -05:00
|
|
|
int set_terminal_title(struct terminal *, char *);
|
2022-02-18 09:45:47 -05:00
|
|
|
void do_terminal_function(struct terminal *, unsigned char, const char *);
|
2005-09-15 09:58:31 -04:00
|
|
|
|
|
|
|
int check_terminal_pipes(void);
|
|
|
|
void close_terminal_pipes(void);
|
|
|
|
struct terminal *attach_terminal(int in, int out, int ctl, void *info, int len);
|
|
|
|
|
2006-05-20 08:59:40 -04:00
|
|
|
extern struct module terminal_module;
|
|
|
|
|
2020-10-05 14:14:55 -04:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2005-09-15 09:58:31 -04:00
|
|
|
#endif /* EL__TERMINAL_TERMINAL_H */
|