ELinks 0.18.0
kbd.c File Reference

Support for keyboard interface. More...

#include <stdlib.h>
#include <string.h>
#include "elinks.h"
#include "config/options.h"
#include "intl/libintl.h"
#include "main/main.h"
#include "main/select.h"
#include "main/timer.h"
#include "osdep/ascii.h"
#include "osdep/osdep.h"
#include "terminal/hardio.h"
#include "terminal/itrm.h"
#include "terminal/kbd.h"
#include "terminal/mouse.h"
#include "terminal/terminal.h"
#include "util/error.h"
#include "util/memory.h"
#include "util/string.h"
#include "util/time.h"
#include "terminal/key.inc"
Include dependency graph for kbd.c:

Macros

#define HPUX_PIPE   1
 
#define write_sequence(fd, seq)    hard_write(fd, seq, sizeof(seq) - 1)
 
#define INIT_TERMINAL_SEQ   "\033)0\0337"
 Special Character and Line Drawing Set, Save Cursor.
 
#define INIT_ALT_SCREEN_SEQ   "\033[?47h"
 Use Alternate Screen Buffer.
 
#define INIT_BRACKETED_PASTE_SEQ   "\033[?2004h"
 Enable XTerm bracketed paste mode.
 
#define DONE_CLS_SEQ   "\033[2J"
 Erase in Display, Clear All.
 
#define DONE_TERMINAL_SEQ   "\0338\r \b"
 Restore Cursor (DECRC) + ???
 
#define DONE_ALT_SCREEN_SEQ   "\033[?47l"
 Use Normal Screen Buffer.
 
#define DONE_BRACKETED_PASTE_SEQ   "\033[?2004l"
 Disable XTerm bracketed paste mode.
 
#define RD(xx)
 

Functions

static void free_itrm (struct itrm *)
 
static void in_kbd (struct itrm *itrm)
 A select_handler_T read_func for itrm_in.std.
 
static void in_sock (struct itrm *itrm)
 A select_handler_T read_func for itrm_in.sock.
 
static int process_queue (struct itrm *itrm)
 Parse one event from itrm_in.queue and append to itrm_out.queue.
 
static void handle_itrm_stdin (struct itrm *itrm)
 Enable reading from itrm_in.std.
 
static void unhandle_itrm_stdin (struct itrm *itrm)
 Disable reading from itrm_in.std.
 
int is_blocked (void)
 
void free_all_itrms (void)
 
static void itrm_queue_write (struct itrm *itrm)
 A select_handler_T write_func for itrm_out.sock.
 
void itrm_queue_event (struct itrm *itrm, char *data, int len)
 
void kbd_ctrl_c (void)
 
static void send_init_sequence (int h, int altscreen)
 
static void send_done_sequence (int h, int altscreen)
 
void resize_terminal (void)
 
void get_terminal_name (char name[MAX_TERM_LEN])
 
static int setraw (struct itrm *itrm, int save_orig)
 
void handle_trm (int std_in, int std_out, int sock_in, int sock_out, int ctl_in, void *init_string, int init_len, int remote)
 Construct the struct itrm of this process, make ditrm point to it, set up select() handlers, and send the initial interlink packet.
 
static void unblock_itrm_x (void *h)
 A select_handler_T read_func and error_func for the pipe (intptr_t) h.
 
int unblock_itrm (void)
 
void block_itrm (void)
 
static void resize_terminal_from_str (const char *text_)
 Resize terminal to dimensions specified by text string.
 
void dispatch_special (const char *text)
 
static void safe_hard_write (int fd, const char *buf, int len)
 
static int get_esc_code (unsigned char *str, int len, unsigned char *code, int *num, int *el)
 
static int get_ui_double_esc (void)
 
static int decode_terminal_escape_sequence (struct itrm *itrm, struct interlink_event *ev)
 Decode a control sequence that begins with CSI (CONTROL SEQUENCE INTRODUCER) encoded as ESC [, and set *ev accordingly.
 
static int decode_terminal_application_key (struct itrm *itrm, struct interlink_event *ev)
 Decode an escape sequence that begins with SS3 (SINGLE SHIFT 3).
 
static void set_kbd_event (const struct itrm *itrm, struct interlink_event *ev, int key, term_event_modifier_T modifier)
 Initialize *ev to match the byte key received from the terminal.
 
static void kbd_timeout (struct itrm *itrm)
 Timer callback for itrm.timer.
 

Variables

struct itrmditrm = NULL
 
static enum term_event_special_key dummy_term_event_special_key
 This hack makes GCC put enum term_event_special_key in the debug information even though it is not otherwise used.
 
int ui_double_esc
 

Detailed Description

Support for keyboard interface.

Todo
TODO: move stuff from here to itrm.{c,h} and mouse.{c,h}

Macro Definition Documentation

◆ DONE_ALT_SCREEN_SEQ

#define DONE_ALT_SCREEN_SEQ   "\033[?47l"

Use Normal Screen Buffer.

◆ DONE_BRACKETED_PASTE_SEQ

#define DONE_BRACKETED_PASTE_SEQ   "\033[?2004l"

Disable XTerm bracketed paste mode.

◆ DONE_CLS_SEQ

#define DONE_CLS_SEQ   "\033[2J"

Erase in Display, Clear All.

◆ DONE_TERMINAL_SEQ

#define DONE_TERMINAL_SEQ   "\0338\r \b"

Restore Cursor (DECRC) + ???

◆ HPUX_PIPE

#define HPUX_PIPE   1

◆ INIT_ALT_SCREEN_SEQ

#define INIT_ALT_SCREEN_SEQ   "\033[?47h"

Use Alternate Screen Buffer.

◆ INIT_BRACKETED_PASTE_SEQ

#define INIT_BRACKETED_PASTE_SEQ   "\033[?2004h"

Enable XTerm bracketed paste mode.

◆ INIT_TERMINAL_SEQ

#define INIT_TERMINAL_SEQ   "\033)0\0337"

Special Character and Line Drawing Set, Save Cursor.

◆ RD

#define RD ( xx)
Value:
{ \
char cc; \
\
if (p < bytes_read) \
cc = buf[p++]; \
else if ((hard_read(itrm->in.sock, &cc, 1)) <= 0) \
goto free_and_return; \
xx = cc; \
}
ssize_t hard_read(int fd, char *data, size_t datalen)
Definition hardio.c:129
int sock
In a slave process, a file descriptor for a socket from which it reads data sent by the master proces...
Definition itrm.h:46
A connection between a terminal and a master ELinks process.
Definition itrm.h:97
struct itrm_in in
Input.
Definition itrm.h:98

◆ write_sequence

#define write_sequence ( fd,
seq )    hard_write(fd, seq, sizeof(seq) - 1)

Function Documentation

◆ block_itrm()

void block_itrm ( void )

◆ decode_terminal_application_key()

static int decode_terminal_application_key ( struct itrm * itrm,
struct interlink_event * ev )
static

Decode an escape sequence that begins with SS3 (SINGLE SHIFT 3).

These are used for application cursor keys and the application keypad.

Returns
one of:
  • -1 if the escape sequence is not yet complete; the caller sets a timer.
  • 0 if the escape sequence should be parsed by some other function.
  • The length of the escape sequence otherwise. Returning >0 does not imply this function has altered *ev.

◆ decode_terminal_escape_sequence()

static int decode_terminal_escape_sequence ( struct itrm * itrm,
struct interlink_event * ev )
static

Decode a control sequence that begins with CSI (CONTROL SEQUENCE INTRODUCER) encoded as ESC [, and set *ev accordingly.

(ECMA-48 also allows 0x9B as a single-byte CSI, but we don't support that here.)

Returns
one of:
  • -1 if the control sequence is not yet complete; the caller sets a timer.
  • 0 if the control sequence should be parsed by some other function.
  • The length of the control sequence otherwise. Returning >0 does not imply this function has altered *ev.

◆ dispatch_special()

void dispatch_special ( const char * text)

◆ free_all_itrms()

void free_all_itrms ( void )

◆ free_itrm()

static void free_itrm ( struct itrm * itrm)
static

◆ get_esc_code()

static int get_esc_code ( unsigned char * str,
int len,
unsigned char * code,
int * num,
int * el )
static

◆ get_terminal_name()

void get_terminal_name ( char name[MAX_TERM_LEN])

◆ get_ui_double_esc()

static int get_ui_double_esc ( void )
inlinestatic

◆ handle_itrm_stdin()

static void handle_itrm_stdin ( struct itrm * itrm)
static

Enable reading from itrm_in.std.

ELinks will read any available bytes from the tty into itrm->in.queue and then parse them. Reading should be enabled whenever itrm->in.queue is not full and itrm->blocked is 0.

◆ handle_trm()

void handle_trm ( int std_in,
int std_out,
int sock_in,
int sock_out,
int ctl_in,
void * init_string,
int init_len,
int remote )

Construct the struct itrm of this process, make ditrm point to it, set up select() handlers, and send the initial interlink packet.

The first five parameters are file descriptors that this function saves in submembers of struct itrm, and for which this function may set select() handlers. Please see the definitions of struct itrm_in and struct itrm_out for further explanations.

Parameters
std_initrm_in.std: read tty device (or pipe)
std_outitrm_out.std: write tty device (or pipe)
sock_initrm_in.sock
  • If master: == std_out (masterhood flag)
  • If slave: read socket from master
sock_outitrm_out.sock
  • If master: write pipe to same process
  • If slave: write socket to master
ctl_initrm_in.ctl: control tty device

The remaining three parameters control the initial interlink packet.

Parameters
init_stringA string to be passed to the master process. Need not be null-terminated. If remote == 0, this is a URI. Otherwise, this is a remote command.
init_lenThe length of init_string, in bytes.
remote= 0 if asking the master to start a new session and display it via this process. Otherwise, enum remote_session_flags.

◆ in_kbd()

static void in_kbd ( struct itrm * itrm)
static

A select_handler_T read_func for itrm_in.std.

This is called when characters typed by the user arrive from the terminal.

◆ in_sock()

static void in_sock ( struct itrm * itrm)
static

A select_handler_T read_func for itrm_in.sock.

A slave process calls this when the master sends it data to be displayed. The master process never calls this.

◆ is_blocked()

int is_blocked ( void )

◆ itrm_queue_event()

void itrm_queue_event ( struct itrm * itrm,
char * data,
int len )

◆ itrm_queue_write()

static void itrm_queue_write ( struct itrm * itrm)
static

A select_handler_T write_func for itrm_out.sock.

This is called when there is data in itrm->out.queue and it is possible to write it to itrm->out.sock. When itrm->out.queue becomes empty, this handler is temporarily removed.

◆ kbd_ctrl_c()

void kbd_ctrl_c ( void )

◆ kbd_timeout()

static void kbd_timeout ( struct itrm * itrm)
static

Timer callback for itrm.timer.

As explained in install_timer(), this function must erase the expired timer ID from all variables.

◆ process_queue()

static int process_queue ( struct itrm * itrm)
static

Parse one event from itrm_in.queue and append to itrm_out.queue.

Precondition
On entry, *itrm must not be blocked.
Returns
the number of bytes removed from itrm->in.queue; at least 0.
Postcondition
If this function leaves the queue not full, it also reenables reading from itrm->in.std. (Because it does not add to the queue, it never need disable reading.)

◆ resize_terminal()

void resize_terminal ( void )

◆ resize_terminal_from_str()

static void resize_terminal_from_str ( const char * text_)
inlinestatic

Resize terminal to dimensions specified by text string.

text should look like "width,height,old-width,old-height" where width and height are integers.

◆ safe_hard_write()

static void safe_hard_write ( int fd,
const char * buf,
int len )
inlinestatic

◆ send_done_sequence()

static void send_done_sequence ( int h,
int altscreen )
static

◆ send_init_sequence()

static void send_init_sequence ( int h,
int altscreen )
static

◆ set_kbd_event()

static void set_kbd_event ( const struct itrm * itrm,
struct interlink_event * ev,
int key,
term_event_modifier_T modifier )
static

Initialize *ev to match the byte key received from the terminal.

key must not be a value from enum term_event_special_key.

◆ setraw()

static int setraw ( struct itrm * itrm,
int save_orig )
static

◆ unblock_itrm()

int unblock_itrm ( void )

◆ unblock_itrm_x()

static void unblock_itrm_x ( void * h)
static

A select_handler_T read_func and error_func for the pipe (intptr_t) h.

This is called when the subprocess started on the terminal of this ELinks process exits. ELinks then resumes using the terminal.

◆ unhandle_itrm_stdin()

static void unhandle_itrm_stdin ( struct itrm * itrm)
static

Disable reading from itrm_in.std.

Reading should be disabled whenever itrm->in.queue is full (there is no room for the data) or itrm->blocked is 1 (other processes may read the data).

Variable Documentation

◆ ditrm

struct itrm* ditrm = NULL

◆ dummy_term_event_special_key

enum term_event_special_key dummy_term_event_special_key
static

This hack makes GCC put enum term_event_special_key in the debug information even though it is not otherwise used.

The const prevents an unused-variable warning.

◆ ui_double_esc

int ui_double_esc