ELinks 0.16.1.1
screen.c File Reference

Terminal screen drawing routines. More...

#include <stdlib.h>
#include <string.h>
#include "elinks.h"
#include "config/options.h"
#include "intl/charsets.h"
#include "main/module.h"
#include "osdep/ascii.h"
#include "osdep/osdep.h"
#include "terminal/color.h"
#include "terminal/draw.h"
#include "terminal/hardio.h"
#include "terminal/kbd.h"
#include "terminal/screen.h"
#include "terminal/terminal.h"
#include "util/conv.h"
#include "util/error.h"
#include "util/memory.h"
#include "util/string.h"
Include dependency graph for screen.c:

Data Structures

struct  screen_driver_opt
struct  screen_driver
 Used in add_char*() and redraw_screen() to reduce the logic. More...
struct  screen_state

Macros

#define TERM_STRING(str)
#define add_term_string(str, tstr)
 Like add_string_to_string() but has fewer checks to slow it down.
#define use_utf8_io(driver)
#define CURSOR_NUM_LEN   10 /* 10 chars for @y and @x numbers should be more than enough. */
#define INIT_SCREEN_STATE   { 0xFF, 0xFF, 0xFF, 0xFF, 0, { 0xFF } }
#define add_chars(image_, term_, driver_, state_, ADD_CHAR, compare_bg_color, compare_fg_color)

Functions

static void set_screen_driver_opt (struct screen_driver *driver, struct option *term_spec)
 Set screen_driver.opt according to screen_driver.type and term_spec.
static int screen_driver_change_hook (struct session *ses, struct option *term_spec, struct option *changed)
static struct screen_driveradd_screen_driver (term_mode_type_T type, struct terminal *term, int env_len)
static struct screen_driverget_screen_driver (struct terminal *term)
void done_screen_drivers (struct module *xxx)
 Release private screen drawing utilities.
static struct stringadd_cursor_move_to_string (struct string *screen, int y, int x)
 Adds the term code for positioning the cursor at x and y to string.
static int compare_color_16 (unsigned char *a, unsigned char *b)
static int compare_bg_color_16 (unsigned char *a, unsigned char *b)
static int compare_fg_color_16 (unsigned char *a, unsigned char *b)
static void copy_color_16 (unsigned char *a, unsigned char *b)
static void add_char_data (struct string *screen, struct screen_driver *driver, unicode_val_T data, unsigned char border)
static void add_char16 (struct string *screen, struct screen_driver *driver, struct screen_char *ch, struct screen_state *state)
 Time critical section.
void redraw_screen (struct terminal *term)
 Updates the terminal screen.
void erase_screen (struct terminal *term)
 Erases the entire screen and moves the cursor to the upper left corner.
void beep_terminal (struct terminal *term)
 Meeep!
struct terminal_screeninit_screen (void)
 Initializes a screen.
void resize_screen (struct terminal *term, int width, int height)
 Update the size of the previous and the current screen image to hold x time y chars.
void done_screen (struct terminal_screen *screen)
 Cleans up after the screen.

Variables

const unsigned char frame_dumb [48]
 Mapping from (enum border_char - 0xB0) to ASCII characters.
static const unsigned char frame_vt100 [48]
 Mapping from (enum border_char - 0xB0) to VT100 line-drawing characters.
static const unsigned char frame_vt100_u [48]
 Mapping from (enum border_char - 0xB0) to VT100 line-drawing characters encoded in CP437.
static const unsigned char frame_freebsd [48]
 Mapping from (enum border_char - 0xB0) to obsolete FreeBSD ACS graphics.
static const unsigned char frame_freebsd_u [48]
 Mapping from (enum border_char - 0xB0) to obsolete FreeBSD ACS graphics encoded in CP437.
static const unsigned char frame_koi [48]
 Mapping from (enum border_char - 0xB0) to KOI8-R.
static const unsigned char frame_restrict [48]
 Mapping from (enum border_char - 0xB0) to CP850 or CP852.
static const struct string m11_hack_frame_seqs []
 Frame begin/end sequences that switch fonts with ECMA-48 SGR.
static const struct string vt100_frame_seqs []
 Frame begin/end sequences for VT100.
static const struct string italic_seqs []
 Italic begin/end sequences using ECMA-48 SGR.
static const struct string underline_seqs []
 Underline begin/end sequences using ECMA-48 SGR.
static const struct screen_driver_opt dumb_screen_driver_opt
 Default options for TERM_DUMB.
static const struct screen_driver_opt vt100_screen_driver_opt
 Default options for TERM_VT100.
static const struct screen_driver_opt linux_screen_driver_opt
 Default options for TERM_LINUX.
static const struct screen_driver_opt koi8_screen_driver_opt
 Default options for TERM_KOI8.
static const struct screen_driver_opt freebsd_screen_driver_opt
 Default options for TERM_FREEBSD.
static const struct screen_driver_opt fbterm_screen_driver_opt
 Default options for TERM_FBTERM.
static const struct screen_driver_opt *const screen_driver_opts []
 Default options for all the different types of terminals.
static struct screen_driver list active_screen_drivers = { D_LIST_HEAD(active_screen_drivers) }
struct module terminal_screen_module

Detailed Description

Terminal screen drawing routines.

Macro Definition Documentation

◆ add_chars

#define add_chars ( image_,
term_,
driver_,
state_,
ADD_CHAR,
compare_bg_color,
compare_fg_color )

◆ add_term_string

#define add_term_string ( str,
tstr )
Value:
add_bytes_to_string(str, (tstr).source, (tstr).length)
#define add_bytes_to_string(string, bytes, length)
Definition string.h:260

Like add_string_to_string() but has fewer checks to slow it down.

◆ CURSOR_NUM_LEN

#define CURSOR_NUM_LEN   10 /* 10 chars for @y and @x numbers should be more than enough. */

◆ INIT_SCREEN_STATE

#define INIT_SCREEN_STATE   { 0xFF, 0xFF, 0xFF, 0xFF, 0, { 0xFF } }

◆ TERM_STRING

#define TERM_STRING ( str)
Value:
INIT_STRING(str, sizeof(str) - 1)
#define INIT_STRING(s, l)
Definition string.h:175

◆ use_utf8_io

#define use_utf8_io ( driver)
Value:
((driver)->opt.charsets[0] != -1)

Function Documentation

◆ add_char16()

void add_char16 ( struct string * screen,
struct screen_driver * driver,
struct screen_char * ch,
struct screen_state * state )
inlinestatic

Time critical section.

◆ add_char_data()

void add_char_data ( struct string * screen,
struct screen_driver * driver,
unicode_val_T data,
unsigned char border )
inlinestatic

◆ add_cursor_move_to_string()

struct string * add_cursor_move_to_string ( struct string * screen,
int y,
int x )
inlinestatic

Adds the term code for positioning the cursor at x and y to string.

The template term code is: "\033[<y>;<x>H"

◆ add_screen_driver()

struct screen_driver * add_screen_driver ( term_mode_type_T type,
struct terminal * term,
int env_len )
inlinestatic

◆ beep_terminal()

void beep_terminal ( struct terminal * term)

Meeep!

◆ compare_bg_color_16()

int compare_bg_color_16 ( unsigned char * a,
unsigned char * b )
inlinestatic

◆ compare_color_16()

int compare_color_16 ( unsigned char * a,
unsigned char * b )
inlinestatic

◆ compare_fg_color_16()

int compare_fg_color_16 ( unsigned char * a,
unsigned char * b )
inlinestatic

◆ copy_color_16()

void copy_color_16 ( unsigned char * a,
unsigned char * b )
inlinestatic

◆ done_screen()

void done_screen ( struct terminal_screen * screen)

Cleans up after the screen.

◆ done_screen_drivers()

void done_screen_drivers ( struct module * xxx)

Release private screen drawing utilities.

◆ erase_screen()

void erase_screen ( struct terminal * term)

Erases the entire screen and moves the cursor to the upper left corner.

◆ get_screen_driver()

struct screen_driver * get_screen_driver ( struct terminal * term)
inlinestatic

◆ init_screen()

struct terminal_screen * init_screen ( void )

Initializes a screen.

Returns NULL upon allocation failure.

◆ redraw_screen()

void redraw_screen ( struct terminal * term)

Updates the terminal screen.

Updating of the terminal screen is done by checking what needs to be updated using the last screen.

◆ resize_screen()

void resize_screen ( struct terminal * term,
int width,
int height )

Update the size of the previous and the current screen image to hold x time y chars.

The two images are allocated in one chunk.

Todo
TODO: It seems allocation failure here is fatal. We should do something!

◆ screen_driver_change_hook()

int screen_driver_change_hook ( struct session * ses,
struct option * term_spec,
struct option * changed )
static

◆ set_screen_driver_opt()

void set_screen_driver_opt ( struct screen_driver * driver,
struct option * term_spec )
static

Set screen_driver.opt according to screen_driver.type and term_spec.

Other members of *driver need not have been initialized.

If you modify anything here, check whether option descriptions should be updated.

Variable Documentation

◆ active_screen_drivers

struct screen_driver list active_screen_drivers = { D_LIST_HEAD(active_screen_drivers) }
static

◆ dumb_screen_driver_opt

const struct screen_driver_opt dumb_screen_driver_opt
static
Initial value:
= {
{ -1, -1 },
1,
0,
}
#define NULL
Definition explodename.c:35
static const struct string italic_seqs[]
Italic begin/end sequences using ECMA-48 SGR.
Definition screen.c:199
static const struct string underline_seqs[]
Underline begin/end sequences using ECMA-48 SGR.
Definition screen.c:209
const unsigned char frame_dumb[48]
Mapping from (enum border_char - 0xB0) to ASCII characters.
Definition screen.c:37
@ COLOR_MODE_16
Definition color.h:60

Default options for TERM_DUMB.

◆ fbterm_screen_driver_opt

const struct screen_driver_opt fbterm_screen_driver_opt
static
Initial value:
= {
{ -1, -1 },
NULL,
1,
0,
}

Default options for TERM_FBTERM.

◆ frame_dumb

const unsigned char frame_dumb[48]
Initial value:
= {
' ',' ',' ','|','|','|','|','+',
'+','|','|','+','+','+','+','+',
'+','-','-','|','-','+','|','|',
'+','+','-','-','|','-','+','-',
'-','-','-','+','+','+','+','+',
'+','+','+',' ',' ',' ',' ',' '
}

Mapping from (enum border_char - 0xB0) to ASCII characters.

◆ frame_freebsd

const unsigned char frame_freebsd[48]
static
Initial value:
= {
130, 138, 128, 153, 150, 150, 150, 140,
140, 150, 153, 140, 139, 139, 139, 140,
142, 151, 152, 149, 146, 143, 149, 149,
142, 141, 151, 152, 149, 146, 143, 151,
151, 152, 152, 142, 142, 141, 141, 143,
143, 139, 141, 128, 128, 128, 128, 128,
}

Mapping from (enum border_char - 0xB0) to obsolete FreeBSD ACS graphics.

This is for FreeBSD fonts that place graphics characters in the 0x80...0x9F range, which ISO 8859 does not use. The characters are supposed to be sorted according to the codes used in VT100 or in the terminfo "acsc" capability:

*  0x80  U+2588   '0'   ACS_BLOCK
*  0x81  U+25C6   '`'   ACS_DIAMOND
*  0x82  U+2592   'a'   ACS_CKBOARD
*  0x83  U+2409   'b'   -
*  0x84  U+240C   'c'   -
*  0x85  U+240D   'd'   -
*  0x86  U+240A   'e'   -
*  0x87  U+00B0   'f'   ACS_DEGREE
*  0x88  U+00B1   'g'   ACS_PLMINUS
*  0x89  U+2424   'h'   -
*  0x8A  U+240B   'i'   -
*  0x8B  U+2518   'j'   ACS_LRCORNER
*  0x8C  U+2510   'k'   ACS_URCORNER
*  0x8D  U+250C   'l'   ACS_ULCORNER
*  0x8E  U+2514   'm'   ACS_LLCORNER
*  0x8F  U+253C   'n'   ACS_PLUS
*  0x90  U+23BA   'o'   ACS_S1
*  0x91  U+23BB   'p'   ACS_S3
*  0x92  U+2500   'q'   ACS_HLINE
*  0x93  U+23BC   'r'   ACS_S7
*  0x94  U+23BD   's'   ACS_S9
*  0x95  U+251C   't'   ACS_LTEE
*  0x96  U+2524   'u'   ACS_RTEE
*  0x97  U+2534   'v'   ACS_BTEE
*  0x98  U+252C   'w'   ACS_TTEE
*  0x99  U+2502   'x'   ACS_VLINE
*  0x9A  U+2264   'y'   ACS_LEQUAL
*  0x9B  U+2265   'z'   ACS_GEQUAL
*  0x9C  U+03C0   '{'   ACS_PI
*  0x9D  U+2260   '|'   ACS_NEQUAL
*  0x9E  U+00A3   '}'   ACS_STERLING
*  0x9F  U+00B7   '~'   ACS_BULLET
* 

(Ncurses 5.5 defines ACS_BOARD using 'h' and ACS_LANTERN using 'i', but those are not the characters meant above.)

In FreeBSD CVS, src/share/syscons/fonts/iso-8x16.fnt revision 1.1 includes these characters, except it has a space at 0x80. In revision 1.2 however, all the characters not defined by ISO 8859-1 have been blanked out. This change was made on 2001-11-22 and included in FreeBSD 4.6.0, which was then released in June 2002. Yet, support for these characters was added to Links on 2003-11-18 and to ELinks on 2003-12-07, so perhaps we should keep it for now.

◆ frame_freebsd_u

const unsigned char frame_freebsd_u[48]
static
Initial value:
= {
177, 177, 219, 179, 180, 180, 180, 191,
191, 180, 179, 191, 217, 217, 217, 191,
192, 193, 194, 195, 196, 197, 195, 195,
192, 218, 193, 194, 195, 196, 197, 193,
193, 194, 194, 192, 192, 218, 218, 197,
197, 217, 218, 219, 219, 219, 219, 219,
}

Mapping from (enum border_char - 0xB0) to obsolete FreeBSD ACS graphics encoded in CP437.

When UTF-8 I/O is enabled, ELinks uses this array instead of frame_freebsd[], and converts the characters from CP437 to UTF-8.

Derived from frame_freebsd[] by converting the characters to Unicode and back to CP437. frame_freebsd[1] = 138 = 0x8a = U+240B SYMBOL FOR VERTICAL TABULATION does not exist in CP437, so we substitute U+2592 MEDIUM SHADE.

◆ frame_koi

const unsigned char frame_koi[48]
static
Initial value:
= {
144, 145, 146, 129, 135, 178, 180, 167,
166, 181, 161, 168, 174, 173, 172, 131,
132, 137, 136, 134, 128, 138, 175, 176,
171, 165, 187, 184, 177, 160, 190, 185,
186, 182, 183, 170, 169, 162, 164, 189,
188, 133, 130, 141, 140, 142, 143, 139,
}

Mapping from (enum border_char - 0xB0) to KOI8-R.

◆ frame_restrict

const unsigned char frame_restrict[48]
static
Initial value:
= {
176, 177, 178, 179, 180, 179, 186, 186,
205, 185, 186, 187, 188, 186, 205, 191,
192, 193, 194, 195, 196, 197, 179, 186,
200, 201, 202, 203, 204, 205, 206, 205,
196, 205, 196, 186, 205, 205, 186, 186,
179, 217, 218, 219, 220, 221, 222, 223,
}

Mapping from (enum border_char - 0xB0) to CP850 or CP852.

Most of this table is just 0xB0 + <index in table>, because these codepages are quite similar to CP437. However, they lack some line-drawing characters, so we must use others instead.

◆ frame_vt100

const unsigned char frame_vt100[48]
static
Initial value:
= {
'a','a','a','x','u','u','u','k',
'k','u','x','k','j','j','j','k',
'm','v','w','t','q','n','t','t',
'm','l','v','w','t','q','n','v',
'v','w','w','m','m','l','l','n',
'n','j','l','a',' ',' ',' ',' '
}

Mapping from (enum border_char - 0xB0) to VT100 line-drawing characters.

◆ frame_vt100_u

const unsigned char frame_vt100_u[48]
static
Initial value:
= {
177, 177, 177, 179, 180, 180, 180, 191,
191, 180, 179, 191, 217, 217, 217, 191,
192, 193, 194, 195, 196, 197, 195, 195,
192, 218, 193, 194, 195, 196, 197, 193,
193, 194, 194, 192, 192, 218, 218, 197,
197, 217, 218, 177, 32, 32, 32, 32
}

Mapping from (enum border_char - 0xB0) to VT100 line-drawing characters encoded in CP437.

When UTF-8 I/O is enabled, ELinks uses this array instead of frame_vt100[], and converts the characters from CP437 to UTF-8.

◆ freebsd_screen_driver_opt

const struct screen_driver_opt freebsd_screen_driver_opt
static
Initial value:
= {
{ -1, -1 },
NULL,
1,
0,
}
static const unsigned char frame_freebsd[48]
Mapping from (enum border_char - 0xB0) to obsolete FreeBSD ACS graphics.
Definition screen.c:123

Default options for TERM_FREEBSD.

◆ italic_seqs

const struct string italic_seqs[]
static
Initial value:
= {
TERM_STRING("\033[23m"),
TERM_STRING("\033[3m"),
}
#define TERM_STRING(str)
Definition screen.c:173

Italic begin/end sequences using ECMA-48 SGR.

ECMA-48: CSI Ps... 06/13 = SGR - SELECT GRAPHIC RENDITION

  • Ps = 3 = italicized
  • Ps = 20 = Fraktur (Gothic)
  • Ps = 23 = not italicized, not fraktur

◆ koi8_screen_driver_opt

const struct screen_driver_opt koi8_screen_driver_opt
static
Initial value:
= {
{ -1, -1 },
1,
0,
}
static const unsigned char frame_koi[48]
Mapping from (enum border_char - 0xB0) to KOI8-R.
Definition screen.c:151

Default options for TERM_KOI8.

◆ linux_screen_driver_opt

const struct screen_driver_opt linux_screen_driver_opt
static
Initial value:
= {
{ -1, -1 },
NULL,
NULL,
1,
0,
}

Default options for TERM_LINUX.

◆ m11_hack_frame_seqs

const struct string m11_hack_frame_seqs[]
static
Initial value:
= {
TERM_STRING("\033[10m"),
TERM_STRING("\033[11m"),
}

Frame begin/end sequences that switch fonts with ECMA-48 SGR.

ECMA-48: CSI Ps... 06/13 = SGR - SELECT GRAPHIC RENDITION

  • Ps = 10 = primary (default) font
  • Ps = 11 = first alternative font

◆ screen_driver_opts

const struct screen_driver_opt* const screen_driver_opts[]
static
Initial value:
= {
}
static const struct screen_driver_opt dumb_screen_driver_opt
Default options for TERM_DUMB.
Definition screen.c:293
static const struct screen_driver_opt fbterm_screen_driver_opt
Default options for TERM_FBTERM.
Definition screen.c:408
static const struct screen_driver_opt vt100_screen_driver_opt
Default options for TERM_VT100.
Definition screen.c:316
static const struct screen_driver_opt freebsd_screen_driver_opt
Default options for TERM_FREEBSD.
Definition screen.c:385
static const struct screen_driver_opt koi8_screen_driver_opt
Default options for TERM_KOI8.
Definition screen.c:362
static const struct screen_driver_opt linux_screen_driver_opt
Default options for TERM_LINUX.
Definition screen.c:339

Default options for all the different types of terminals.

XXX: Keep in sync with term_mode_type_T.

◆ terminal_screen_module

struct module terminal_screen_module
Initial value:
"Terminal Screen",
)
#define struct_module(name, options, hooks, submods, data, init, done)
Definition module.h:44
void done_screen_drivers(struct module *xxx)
Release private screen drawing utilities.
Definition screen.c:658

◆ underline_seqs

const struct string underline_seqs[]
static
Initial value:
= {
TERM_STRING("\033[24m"),
TERM_STRING("\033[4m"),
}

Underline begin/end sequences using ECMA-48 SGR.

ECMA-48: CSI Ps... 06/13 = SGR - SELECT GRAPHIC RENDITION

  • Ps = 4 = singly underlined
  • Ps = 21 = doubly underlined
  • Ps = 24 = not underlined (neither singly nor doubly)

◆ vt100_frame_seqs

const struct string vt100_frame_seqs[]
static
Initial value:
= {
TERM_STRING("\x0f"),
TERM_STRING("\x0e"),
}

Frame begin/end sequences for VT100.

◆ vt100_screen_driver_opt

const struct screen_driver_opt vt100_screen_driver_opt
static
Initial value:
= {
{ -1, -1 },
1,
0,
}
static const struct string vt100_frame_seqs[]
Frame begin/end sequences for VT100.
Definition screen.c:189
static const unsigned char frame_vt100[48]
Mapping from (enum border_char - 0xB0) to VT100 line-drawing characters.
Definition screen.c:48

Default options for TERM_VT100.