1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-06-30 01:55:30 +00:00
elinks/src/terminal/terminal.h

261 lines
8.2 KiB
C
Raw Normal View History

#ifndef EL__TERMINAL_TERMINAL_H
#define EL__TERMINAL_TERMINAL_H
#include "config/options.h"
#include "terminal/event.h"
#include "util/lists.h"
#ifdef __cplusplus
extern "C" {
#endif
2006-05-20 12:59:40 +00:00
struct module;
struct option;
struct terminal_screen;
struct terminal_interlink;
2007-07-27 13:50:37 +00:00
/** The terminal type, meaningful for frames (lines) drawing. */
enum term_mode_type {
TERM_DUMB = 0,
TERM_VT100,
TERM_LINUX,
TERM_KOI8,
TERM_FREEBSD,
TERM_FBTERM,
};
typedef int term_mode_type_T;
2007-07-27 13:50:37 +00:00
/** This is a bitmask describing the environment we are living in,
* terminal-wise. We can then conditionally use various features available
* in such an environment. */
enum term_env_type {
2007-07-27 13:50:37 +00:00
/** This basically means that we can use the text i/o :). Always set. */
ENV_CONSOLE = 1,
2007-07-27 13:50:37 +00:00
/** We are running in a xterm-compatible box in some windowing
* environment. */
ENV_XWIN = 2,
2007-07-27 13:50:37 +00:00
/** We are running under a screen. */
ENV_SCREEN = 4,
2007-07-27 13:50:37 +00:00
/** We are running in a OS/2 VIO terminal. */
ENV_OS2VIO = 8,
2007-07-27 13:50:37 +00:00
/** BeOS text terminal. */
ENV_BE = 16,
2007-07-27 13:50:37 +00:00
/** We live in a TWIN text-mode windowing environment. */
ENV_TWIN = 32,
2007-07-27 13:50:37 +00:00
/** Microsoft Windows cmdline thing. */
ENV_WIN32 = 64,
2007-07-27 13:50:37 +00:00
/** Match all terminal environments */
ENV_ANY = ~0,
};
typedef int term_env_type_T;
enum term_redrawing_state {
2007-07-27 13:50:37 +00:00
TREDRAW_READY = 0, /**< Can redraw */
TREDRAW_BUSY = 1, /**< Redrawing already in progress */
TREDRAW_DELAYED = 2, /**< Do not redraw for now */
};
2007-07-27 13:50:37 +00:00
/** This is one of the axis of ELinks' user interaction. struct terminal
* 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 13:50:37 +00:00
* information about the actual ELinks instance owning this terminal.
*
2007-07-31 10:38:00 +00:00
* @todo TODO: Regroup the following into logical chunks. --pasky */
struct terminal {
LIST_HEAD_EL(struct terminal); /*!< ::terminals is the sentinel. */
#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 13:50:37 +00:00
/** This is (at least partially) a stack of all the windows living in
* 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 13:50:37 +00:00
* all, but only one of them. ALWAYS check inactive_tab() during
* 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 13:50:37 +00: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.
* - Dialogs or active menus are at the top.
2007-07-27 13:50:37 +00:00
* - Next come all tabs (window.type == ::WINDOW_TAB). The tab
* listed leftmost in the tab bar is at the top, and the tab
2007-07-27 13:50:37 +00:00
* listed rightmost is at the bottom; but #current_tab controls
* which tab is actually displayed.
* - If the main menu is inactive, then it is at the very bottom,
* hidden under the tabs.
2007-07-27 13:50:37 +00:00
* Call assert_window_stacking() to verify this.
*
2007-07-27 13:50:37 +00: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
*
* 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 */
LIST_OF(struct window) windows;
2007-07-27 13:50:37 +00:00
/** The specification of terminal in terms of terminal options. */
struct option *spec;
2007-07-27 13:50:37 +00:00
/** This is the terminal's current title, as perhaps displayed
* somewhere in the X window frame or so. */
char *title;
2007-07-27 13:50:37 +00:00
/** This is the screen. See terminal/screen.h */
struct terminal_screen *screen;
2007-07-27 13:50:37 +00:00
/** This is for displaying main menu */
struct menu *main_menu;
2007-07-27 13:50:37 +00:00
/** These are pipes for communication with the ELinks instance owning
* this terminal.
* @see struct itrm */
int fdin, fdout;
2007-07-27 13:50:37 +00:00
/** This indicates that the terminal is blocked, that is nothing should
* 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 13:50:37 +00:00
/** Terminal dimensions. */
int width, height;
2007-07-27 13:50:37 +00:00
/** Indicates whether we are currently in the process of redrawing the
* stuff being displayed on the terminal. It is typically used to
* prevent redrawing inside of redrawing. */
enum term_redrawing_state redrawing;
2007-07-27 13:50:37 +00:00
/** Indicates the master terminal, that is the terminal under
* supervision of the master ELinks instance (the one doing all the
* work and even maintaining these structures ;-). */
unsigned int master:1;
#ifdef CONFIG_UTF8
2007-07-27 13:50:37 +00:00
/** Indicates whether the charset of the terminal is UTF-8. */
unsigned int utf8_cp:1;
2007-07-27 13:50:37 +00:00
/** Indicates whether UTF-8 I/O is used. Forced on if the
* UTF-8 charset is selected. (bug 827) */
unsigned int utf8_io:1;
#endif /* CONFIG_UTF8 */
2006-01-14 21:44:00 +00:00
#ifdef CONFIG_LIBSIXEL
unsigned int sixel:1;
#endif
2007-07-27 13:50:37 +00:00
/** The current tab number. */
int current_tab;
#ifdef CONFIG_LEDS
2007-07-27 13:50:37 +00:00
/** Current length of leds part of status bar. */
int leds_length;
#endif
2007-07-27 13:50:37 +00:00
/** The type of environment this terminal lives in. */
term_env_type_T environment;
2007-07-27 13:50:37 +00:00
/** The current working directory for this terminal / ELinks instance. */
char cwd[MAX_CWD_LEN];
2007-07-27 13:50:37 +00:00
/** For communication between instances */
struct terminal_interlink *interlink;
/* Data for textarea_edit(). */
void *textarea_data;
struct term_event_mouse prev_mouse_event;
#ifdef CONFIG_LIBSIXEL
LIST_OF(struct image) images;
int cell_width;
int cell_height;
#endif
};
#define do_not_ignore_next_mouse_event(term) \
memset(&(term)->prev_mouse_event, 0, sizeof((term)->prev_mouse_event))
/** 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. */
extern LIST_OF(struct terminal) terminals;
2007-01-24 22:05:36 +00:00
extern const unsigned char frame_dumb[];
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);
struct terminal *get_default_terminal(void);
int get_terminal_codepage(const struct terminal *);
void redraw_all_terminals(void);
void destroy_all_terminals(void);
void exec_thread(char *, int);
void close_handle(void *);
#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-29 01:09:53 +00: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 09:26:45 +00:00
* The interlink protocol passes these values as one byte in a
* null-terminated string, so zero cannot be used. */
2007-07-27 13:50:37 +00: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-29 01:09:53 +00:00
TERM_FN_TITLE = 1,
TERM_FN_RESIZE = 2,
TERM_FN_TITLE_CODEPAGE = 3
2007-07-27 13:50:37 +00:00
};
2007-07-27 13:50:37 +00:00
/** How to execute a program in a terminal. These values are used in
2007-07-14 09:26:45 +00:00
* the interlink protocol and must fit in one byte. */
enum term_exec {
2007-07-27 13:50:37 +00:00
/** Execute in the background. ELinks keeps using the terminal
2007-07-14 09:26:45 +00:00
* and the program should not use it. */
TERM_EXEC_BG = 0,
2007-07-27 13:50:37 +00:00
/** Execute in the foreground. The program may use the terminal.
2007-07-14 09:26:45 +00:00
* ELinks will redraw when the program exits. */
TERM_EXEC_FG = 1,
2007-07-27 13:50:37 +00:00
/** Execute in the background and in a new process group. */
2007-07-14 09:26:45 +00:00
TERM_EXEC_NEWWIN = 2
};
2022-01-28 14:11:23 +00:00
typedef int term_exec_T;
2022-02-20 12:52:47 +00:00
void exec_on_terminal(struct terminal *, const char *, const char *, term_exec_T);
void exec_shell(struct terminal *term);
int set_terminal_title(struct terminal *, char *);
void do_terminal_function(struct terminal *, unsigned char, const char *);
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 12:59:40 +00:00
extern struct module terminal_module;
#ifdef __cplusplus
}
#endif
#endif /* EL__TERMINAL_TERMINAL_H */