term-screen.c revision 2bb4c7e384c31de4727f1330da3f4de2f0bb7784
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
/*
* Terminal Screens
* The term_screen layer implements the terminal-side. It handles all commands
* returned by the seq-parser and applies them to its own pages.
*
* While there are a lot of legacy control-sequences, we only support a small
* subset. There is no reason to implement unused codes like horizontal
* scrolling.
* If you implement new commands, make sure to document them properly.
*
* Standards:
* ECMA-48
* ANSI X3.64
* References:
* ASCII
*/
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <xkbcommon/xkbcommon-keysyms.h>
#include "macro.h"
#include "term-internal.h"
#include "util.h"
#include "utf8.h"
int term_screen_new(term_screen **out, term_screen_write_fn write_fn, void *write_fn_data, term_screen_cmd_fn cmd_fn, void *cmd_fn_data) {
int r;
if (!screen)
return -ENOMEM;
if (r < 0)
return r;
if (r < 0)
return r;
if (r < 0)
return r;
if (r < 0)
return r;
return 0;
}
if (!screen)
return NULL;
return screen;
}
if (!screen)
return NULL;
return NULL;
return NULL;
}
/*
* Write-Helpers
* Unfortunately, 7bit/8bit compat mode requires us to send C1 controls encoded
* as 7bit if asked by the application. This is really used in the wild, so we
* cannot fall back to "always 7bit".
* screen_write() is the underlying backend which forwards any writes to the
* users's callback. It's the users responsibility to buffer these and write
* them out once their call to term_screen_feed_*() returns.
* directly in the code-base without requiring any intermediate buffer during
* runtime.
*/
#define C0_CSI "\e["
#define C1_CSI "\x9b"
screen_write((_screen), \
return 0;
}
/*
* Command Forwarding
* Some commands cannot be handled by the screen-layer directly. Those are
* forwarded to the command-handler of the caller. This is rarely used and can
* safely be set to NULL.
*/
return 0;
}
/*
* Screen Helpers
* These helpers implement common-operations like cursor-handler and more, which
* are used by several command dispatchers.
*/
return x;
}
return y;
}
return false;
}
if (cell)
}
}
x = screen_clamp_x(screen, x);
y = screen_clamp_y(screen, y);
return;
}
x = screen_clamp_x(screen, x);
y -= 1;
}
}
screen_cursor_set(screen, x, y);
}
}
unsigned int i;
while (i > 0 && num > 0) {
if (screen_tab_is_set(screen, --i))
--num;
}
}
}
unsigned int i;
if (screen_tab_is_set(screen, ++i))
--num;
}
}
unsigned int max;
} else {
if (num < 1)
return;
if (scroll)
} else {
}
}
}
unsigned int max;
} else {
if (num < 1)
return;
if (scroll)
} else {
}
}
}
}
}
}
if (set) {
} else {
}
}
if (set)
else
}
switch (mode) {
case 20:
/*
* TODO
*/
break;
default:
}
}
switch (mode) {
case 1:
/*
* DECCKM: cursor-keys
* TODO
*/
break;
case 6:
/*
* DECOM: origin-mode
* TODO
*/
break;
case 7:
/*
* DECAWN: auto-wrap mode
* TODO
*/
break;
case 25:
/*
* DECTCEM: text-cursor-enable
* TODO
*/
break;
case 47:
/*
* XTERM-ASB: alternate-screen-buffer
* It effectively saves the current page content and
* allows you to restore it when changing to the
* original screen-buffer again.
*/
break;
case 1047:
/*
* XTERM-ASBPE: alternate-screen-buffer-post-erase
* This is the same as XTERM-ASB but erases the
* alternate screen-buffer before switching back to the
* original buffer. Use it to discard any data on the
* alternate screen buffer when done.
*/
if (!set)
break;
case 1048:
/*
* XTERM-ASBCS: alternate-screen-buffer-cursor-state
* separate state buffer. It is usually used in
* combination with alternate screen buffers to provide
* stacked state storage.
*/
if (set)
else
break;
case 1049:
/*
* XTERM-ASBX: alternate-screen-buffer-extended
* This combines XTERM-ASBPE and XTERM-ASBCS somewhat.
* When enabling, state is saved, alternate screen
* buffer is activated and cleared.
* When disabled, alternate screen buffer is cleared,
* then normal screen buffer is enabled and state is
* restored.
*/
if (set)
if (!set)
break;
default:
}
}
/* map a character according to current GL and GR maps */
/* 32 and 127 always map to identity. 160 and 255 map to identity iff a
* 96 character set is loaded into GR. Values above 255 always map to
* identity. */
switch (val) {
case 33 ... 126:
} else {
}
break;
case 160 ... 255:
} else {
}
break;
}
}
/*
* Command Handlers
* This is the unofficial documentation of all the TERM_CMD_* definitions. Each
* handled command has a separate function with an extensive comment on the
* semantics of the command.
* Note that many semantics are unknown and need to be verified. This is mostly
* about error-handling, though. Applications rarely rely on those features.
*/
}
term_page_write(screen->page, screen->state.cursor_x, screen->state.cursor_y, ch, 1, &screen->state.attr, screen->age, false);
else
return 0;
}
/*
* BEL - sound bell tone
* This command should trigger an acoustic bell. Usually, this is
* forwarded directly to the pcspkr. However, bells have become quite
* uncommon and annoying, so we're not implementing them here. Instead,
* it's one of the commands we forward to the caller.
*/
}
/*
* BS - backspace
* Move cursor one cell to the left. If already at the left margin,
* nothing happens.
*/
return 0;
}
/*
* CBT - cursor-backward-tabulation
* Move the cursor @args[0] tabs backwards (to the left). The
* current cursor cell, in case it's a tab, is not counted.
* Furthermore, the cursor cannot be moved beyond position 0 and
* it will stop there.
*
* Defaults:
* args[0]: 1
*/
unsigned int num = 1;
return 0;
}
/*
* CHA - cursor-horizontal-absolute
* Move the cursor to position @args[0] in the current line. The
* cursor cannot be moved beyond the rightmost cell and will stop
* there.
*
* Defaults:
* args[0]: 1
*/
unsigned int pos = 1;
return 0;
}
/*
* CHT - cursor-horizontal-forward-tabulation
* Move the cursor @args[0] tabs forward (to the right). The
* current cursor cell, in case it's a tab, is not counted.
* Furthermore, the cursor cannot be moved beyond the rightmost cell
* and will stop there.
*
* Defaults:
* args[0]: 1
*/
unsigned int num = 1;
return 0;
}
/*
* CNL - cursor-next-line
* Move the cursor @args[0] lines down.
*
* TODO: Does this stop at the bottom or cause a scroll-up?
*
* Defaults:
* args[0]: 1
*/
unsigned int num = 1;
return 0;
}
/*
* CPL - cursor-preceding-line
* Move the cursor @args[0] lines up.
*
* TODO: Does this stop at the top or cause a scroll-up?
*
* Defaults:
* args[0]: 1
*/
unsigned int num = 1;
return 0;
}
/*
* CR - carriage-return
* Move the cursor to the left margin on the current line.
*/
return 0;
}
/*
* CUB - cursor-backward
* Move the cursor @args[0] positions to the left. The cursor stops
* at the left-most position.
*
* Defaults:
* args[0]: 1
*/
unsigned int num = 1;
return 0;
}
/*
* CUD - cursor-down
* Move the cursor @args[0] positions down. The cursor stops at the
* bottom margin. If it was already moved further, it stops at the
* bottom line.
*
* Defaults:
* args[0]: 1
*/
unsigned int num = 1;
return 0;
}
/*
* CUF -cursor-forward
* Move the cursor @args[0] positions to the right. The cursor stops
* at the right-most position.
*
* Defaults:
* args[0]: 1
*/
unsigned int num = 1;
return 0;
}
/*
* CUP - cursor-position
* Moves the cursor to position @args[1] x @args[0]. If either is 0, it
* is treated as 1. The positions are subject to the origin-mode and
*
* Defaults:
* args[0]: 1
* args[1]: 1
*/
unsigned int x = 1, y = 1;
return 0;
}
/*
* CUU - cursor-up
* Move the cursor @args[0] positions up. The cursor stops at the
* top margin. If it was already moved further, it stops at the
* top line.
*
* Defaults:
* args[0]: 1
*
*/
unsigned int num = 1;
return 0;
}
/*
* DA1 - primary-device-attributes
* The primary DA asks for basic terminal features. We simply return
* a hard-coded list of features we implement.
* Note that the primary DA asks for supported features, not currently
* enabled features.
*
* The terminal's answer is:
* ^[ ? 64 ; ARGS c
* The first argument, 64, is fixed and denotes a VT420, the last
* DEC-term that extended this number.
* All following arguments denote supported features. Note
* that at most 15 features can be sent (max CSI args). It is safe to
* send more, but clients might not be able to parse them. This is a
* client's problem and we shouldn't care. There is no other way to
* send those feature lists, so we have to extend them beyond 15 in
* those cases.
*
* Known modes:
* 1: 132 column mode
* The 132 column mode is supported by the terminal.
* 2: printer port
* A priner-port is supported and can be addressed via
* control-codes.
* 3: ReGIS graphics
* Support for ReGIS graphics is available. The ReGIS routines
* provide the "remote graphics instruction set" and allow basic
* vector-rendering.
* 4: sixel
* Support of Sixel graphics is available. This provides access
* to the sixel bitmap routines.
* 6: selective erase
* The terminal supports DECSCA and related selective-erase
* functions. This allows to protect specific cells from being
* erased, if specified.
* 7: soft character set (DRCS)
* TODO: ?
* 8: user-defined keys (UDKs)
* TODO: ?
* 9: national-replacement character sets (NRCS)
* National-replacement character-sets are available.
* 12: Yugoslavian (SCS)
* TODO: ?
* 15: technical character set
* The DEC technical-character-set is available.
* 18: windowing capability
* TODO: ?
* 21: horizontal scrolling
* TODO: ?
* 22: ANSII color
* TODO: ?
* 23: Greek
* TODO: ?
* 24: Turkish
* TODO: ?
* 29: ANSI text locator
* TODO: ?
* 42: ISO Latin-2 character set
* TODO: ?
* 44: PCTerm
* TODO: ?
* 45: soft keymap
* TODO: ?
* 46: ASCII emulation
* TODO: ?
*/
}
/*
* DA2 - secondary-device-attributes
* The secondary DA asks for the terminal-ID, firmware versions and
* other non-primary attributes. All these values are
* informational-only and should not be used by the host to detect
* terminal features.
*
* The terminal's response is:
* ^[ > 61 ; FIRMWARE ; KEYBOARD c
* whereas 65 is fixed for VT525 terminals, the last terminal-line that
* increased this number. FIRMWARE is the firmware
* keyboard and 1 for PC keyboards.
*
* We replace the firmware-version with the systemd-version so clients
* can decode it again.
*/
}
/*
* DA3 - tertiary-device-attributes
* The tertiary DA is used to query the terminal-ID.
*
* The terminal's response is:
* ^P ! | XX AA BB CC ^\
* whereas all four parameters are hexadecimal-encoded pairs. XX
* denotes the manufacturing site, AA BB CC is the terminal's ID.
*/
/* we do not support tertiary DAs */
return 0;
}
/*
* DC1 - device-control-1 or XON
* This clears any previous XOFF and resumes terminal-transmission.
*/
/* we do not support XON */
return 0;
}
/*
* DC3 - device-control-3 or XOFF
* Stops terminal transmission. No further characters are sent until
* an XON is received.
*/
/* we do not support XOFF */
return 0;
}
/*
* DCH - delete-character
* This deletes @argv[0] characters at the current cursor position. As
* characters are deleted, the remaining characters between the cursor
* and right margin move to the left. Character attributes move with the
* characters. The terminal adds blank spaces with no visual character
* attributes at the right margin. DCH has no effect outside the
* scrolling margins.
*
* Defaults:
* args[0]: 1
*/
unsigned int num = 1;
term_page_delete_cells(screen->page, screen->state.cursor_x, screen->state.cursor_y, num, &screen->state.attr, screen->age);
return 0;
}
/*
* DECALN - screen-alignment-pattern
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECANM - ansi-mode
* Set the terminal into VT52 compatibility mode. Control sequences
* overlap with regular sequences so we have to detect them early before
* dispatching them.
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECBI - back-index
* This control function moves the cursor backward one column. If the
* cursor is at the left margin, then all screen data within the margin
* moves one column to the right. The column that shifted past the right
* margin is lost.
* DECBI adds a new column at the left margin with no visual attributes.
* DECBI does not affect the margins. If the cursor is beyond the
* left-margin at the left border, then the terminal ignores DECBI.
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECCARA - change-attributes-in-rectangular-area
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECCRA - copy-rectangular-area
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECDC - delete-column
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECDHL_BH - double-width-double-height-line: bottom half
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECDHL_TH - double-width-double-height-line: top half
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECDWL - double-width-single-height-line
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECEFR - enable-filter-rectangle
* Defines the coordinates of a filter rectangle (top, left, bottom,
* right as @args[0] to @args[3]) and activates it.
* Anytime the locator is detected outside of the filter rectangle, an
* outside rectangle event is generated and the rectangle is disabled.
* Filter rectangles are always treated as "one-shot" events. Any
* parameters that are omitted default to the current locator position.
* If all parameters are omitted, any locator motion will be reported.
* DECELR always cancels any prevous rectangle definition.
*
* The locator is usually associated with the mouse-cursor, but based
* on cells instead of pixels. See DECELR how to initialize and enable
* it. DECELR can also enable pixel-mode instead of cell-mode.
*
* TODO: implement
*/
return 0;
}
/*
* DECELF - enable-local-functions
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECELR - enable-locator-reporting
* This changes the locator-reporting mode. @args[0] specifies the mode
* to set, 0 disables locator-reporting, 1 enables it continuously, 2
* enables it for a single report. @args[1] specifies the
* precision-mode. 0 and 2 set the reporting to cell-precision, 1 sets
* pixel-precision.
*
* Defaults:
* args[0]: 0
* args[1]: 0
*
* TODO: implement
*/
return 0;
}
/*
* DECERA - erase-rectangular-area
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECFI - forward-index
* This control function moves the cursor forward one column. If the
* cursor is at the right margin, then all screen data within the
* margins moves one column to the left. The column shifted past the
* left margin is lost.
* DECFI adds a new column at the right margin, with no visual
* attributes. DECFI does not affect margins. If the cursor is beyond
* the right margin at the border of the page when the terminal
* receives DECFI, then the terminal ignores DECFI.
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECFRA - fill-rectangular-area
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECIC - insert-column
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECID - return-terminal-id
* This is an obsolete form of TERM_CMD_DA1.
*/
}
/*
* DECINVM - invoke-macro
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECKBD - keyboard-language-selection
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECKPAM - keypad-application-mode
* Enables the keypad-application mode. If enabled, the keypad sends
* special characters instead of the printed characters. This way,
* applications can detect whether a numeric key was pressed on the
* top-row or on the keypad.
* Default is keypad-numeric-mode.
*/
return 0;
}
/*
* DECKPNM - keypad-numeric-mode
* This disables the keypad-application-mode (DECKPAM) and returns to
* the keypad-numeric-mode. Keypresses on the keypad generate the same
* sequences as corresponding keypresses on the main keyboard.
* Default is keypad-numeric-mode.
*/
return 0;
}
/*
* DECLFKC - local-function-key-control
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECLL - load-leds
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECLTOD - load-time-of-day
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECPCTERM - pcterm-mode
*
*/
return 0;
}
/*
* DECPKA - program-key-action
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECPKFMR - program-key-free-memory-report
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECRARA - reverse-attributes-in-rectangular-area
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECRC - restore-cursor
* Restores the terminal to the state saved by the save cursor (DECSC)
* function. This includes more than just the cursor-position.
*
* If nothing was saved by DECSC, then DECRC performs the following
* actions:
* * Moves the cursor to the home position (upper left of screen).
* * Resets origin mode (DECOM).
* * Turns all character attributes off (normal setting).
* * Maps the ASCII character set into GL, and the DEC Supplemental
* Graphic set into GR.
*
* The terminal maintains a separate DECSC buffer for the main display
* and the status line. This feature lets you save a separate operating
* state for the main display and the status line.
*/
return 0;
}
/*
* DECREQTPARM - request-terminal-parameters
* The sequence DECREPTPARM is sent by the terminal controller to notify
* the host of the status of selected terminal parameters. The status
* sequence may be sent when requested by the host or at the terminal's
* discretion. DECREPTPARM is sent upon receipt of a DECREQTPARM.
*
* If @args[0] is 0, this marks a request and the terminal is allowed
* to send DECREPTPARM messages without request. If it is 1, the same
* applies but the terminal should no longer send DECREPTPARM
* unrequested.
* 2 and 3 mark a report, but 3 is only used if the terminal answers as
* an explicit request with @args[0] == 1.
*
* The other arguments are ignored in requests, but have the following
* meaning in responses:
* args[1]: 1=no-parity-set 4=parity-set-and-odd 5=parity-set-and-even
* args[2]: 1=8bits-per-char 2=7bits-per-char
* args[3]: transmission-speed
* args[4]: receive-speed
* args[5]: 1=bit-rate-multiplier-is-16
* args[6]: This value communicates the four switch values in block 5
* of SETUP B, which are only visible to the user when an STP
* option is installed. These bits may be assigned for an STP
* device. The four bits are a decimal-encoded binary number.
* Value between 0-15.
*
* The transmission/receive speeds have mappings for number => bits/s
* which are quite weird. Examples are: 96->3600, 112->9600, 120->19200
*
* Defaults:
* args[0]: 0
*/
} else {
return 0;
}
}
/*
* DECRPKT - report-key-type
* Response to DECRQKT, we can safely ignore it as we're the one sending
* it to the host.
*/
return 0;
}
/*
* DECRQCRA - request-checksum-of-rectangular-area
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECRQDE - request-display-extent
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECRQKT - request-key-type
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECRQLP - request-locator-position
* See DECELR for locator-information.
*
* TODO: document and implement
*/
return 0;
}
/*
* DECRQM_ANSI - request-mode-ansi
* The host sends this control function to find out if a particular mode
* is set or reset. The terminal responds with a report mode function.
* @args[0] contains the mode to query.
*
* Response is DECRPM with the first argument set to the mode that was
* queried, second argument is 0 if mode is invalid, 1 if mode is set,
* 2 if mode is not set (reset), 3 if mode is permanently set and 4 if
* mode is permanently not set (reset):
* ANSI: ^[ MODE ; VALUE $ y
* DEC: ^[ ? MODE ; VALUE $ y
*
* TODO: implement
*/
return 0;
}
/*
* DECRQM_DEC - request-mode-dec
* Same as DECRQM_ANSI but for DEC modes.
*
* TODO: implement
*/
return 0;
}
/*
* DECRQPKFM - request-program-key-free-memory
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECRQPSR - request-presentation-state-report
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECRQTSR - request-terminal-state-report
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECRQUPSS - request-user-preferred-supplemental-set
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECSACE - select-attribute-change-extent
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECSASD - select-active-status-display
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECSC - save-cursor
* Save cursor and terminal state so it can be restored later on.
* Saves the following items in the terminal's memory:
* * Cursor position
* * Character attributes set by the SGR command
* * Character sets (G0, G1, G2, or G3) currently in GL and GR
* * Wrap flag (autowrap or no autowrap)
* * State of origin mode (DECOM)
* * Selective erase attribute
* * Any single shift 2 (SS2) or single shift 3 (SS3) functions sent
*/
return 0;
}
/*
* DECSCA - select-character-protection-attribute
* Defines the characters that come after it as erasable or not erasable
* from the screen. The selective erase control functions (DECSED and
* DECSEL) can only erase characters defined as erasable.
*
* @args[0] specifies the new mode. 0 and 2 mark any following character
* as erasable, 1 marks it as not erasable.
*
* Defaults:
* args[0]: 0
*/
unsigned int mode = 0;
switch (mode) {
case 0:
case 2:
break;
case 1:
break;
}
return 0;
}
/*
* DECSCL - select-conformance-level
* Select the terminal's operating level. The factory default is
* level 4 (VT Level 4 mode, 7-bit controls).
* When you change the conformance level, the terminal performs a hard
* reset (RIS).
*
* @args[0] defines the conformance-level, valid values are:
* 61: Level 1 (VT100)
* 62: Level 2 (VT200)
* 63: Level 3 (VT300)
* 64: Level 4 (VT400)
* @args[1] defines the 8bit-mode, valid values are:
* 0: 8-bit controls
* 1: 7-bit controls
* 2: 8-bit controls (same as 0)
*
* If @args[0] is 61, then @args[1] is ignored and 7bit controls are
* enforced.
*
* Defaults:
* args[0]: 64
* args[1]: 0
*/
}
switch (level) {
case 61:
break;
case 62 ... 69:
if (bit == 1)
else
break;
}
return 0;
}
/*
* DECSCP - select-communication-port
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECSCPP - select-columns-per-page
* Select columns per page. The number of rows is unaffected by this.
* @args[0] selectes the number of columns (width), DEC only defines 80
* and 132, but we allow any integer here. 0 is equivalent to 80.
* Page content is *not* cleared and the cursor is left untouched.
* However, if the page is reduced in width and the cursor would be
* outside the visible region, it's set to the right border. Newly added
* cells are cleared. No data is retained outside the visible region.
*
* Defaults:
* args[0]: 0
*
* TODO: implement
*/
return 0;
}
/*
* DECSCS - select-communication-speed
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECSCUSR - set-cursor-style
* This changes the style of the cursor. @args[0] can be one of:
* 0, 1: blinking block
* 2: steady block
* 3: blinking underline
* 4: steady underline
* Changing this setting does _not_ affect the cursor visibility itself.
* Use DECTCEM for that.
*
* Defaults:
* args[0]: 0
*
* TODO: implement
*/
return 0;
}
/*
* DECSDDT - select-disconnect-delay-time
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECSDPT - select-digital-printed-data-type
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECSED - selective-erase-in-display
* This control function erases some or all of the erasable characters
* in the display. DECSED can only erase characters defined as erasable
* by the DECSCA control function. DECSED works inside or outside the
* scrolling margins.
*
* @args[0] defines which regions are erased. If it is 0, all cells from
* the cursor (inclusive) till the end of the display are erase. If it
* is 1, all cells from the start of the display till the cursor
* (inclusive) are erased. If it is 2, all cells are erased.
*
* Defaults:
* args[0]: 0
*/
unsigned int mode = 0;
switch (mode) {
case 0:
break;
case 1:
0, 0,
break;
case 2:
0, 0,
break;
}
return 0;
}
/*
* DECSEL - selective-erase-in-line
* This control function erases some or all of the erasable characters
* in a single line of text. DECSEL erases only those characters defined
* as erasable by the DECSCA control function. DECSEL works inside or
* outside the scrolling margins.
*
* @args[0] defines the region to be erased. If it is 0, all cells from
* the cursor (inclusive) till the end of the line are erase. If it is
* 1, all cells from the start of the line till the cursor (inclusive)
* are erased. If it is 2, the whole line of the cursor is erased.
*
* Defaults:
* args[0]: 0
*/
unsigned int mode = 0;
switch (mode) {
case 0:
break;
case 1:
break;
case 2:
break;
}
return 0;
}
/*
* DECSERA - selective-erase-rectangular-area
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECSFC - select-flow-control
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECSKCV - set-key-click-volume
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECSLCK - set-lock-key-style
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECSLE - select-locator-events
*
* TODO: implement
*/
return 0;
}
/*
* DECSLPP - set-lines-per-page
* Set the number of lines used for the page. @args[0] specifies the
* number of lines to be used. DEC only allows a limited number of
* choices, however, we allow all integers. 0 is equivalent to 24.
*
* Defaults:
* args[0]: 0
*
* TODO: implement
*/
return 0;
}
/*
* DECSLRM_OR_SC - set-left-and-right-margins or save-cursor
*
* TODO: Detect save-cursor and run it. DECSLRM is not worth
* implementing.
*/
return 0;
}
/*
* DECSMBV - set-margin-bell-volume
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECSMKR - select-modifier-key-reporting
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECSNLS - set-lines-per-screen
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECSPP - set-port-parameter
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECSPPCS - select-pro-printer-character-set
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECSPRTT - select-printer-type
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECSR - secure-reset
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECSRFR - select-refresh-rate
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECSSCLS - set-scroll-speed
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECSSDT - select-status-display-line-type
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECSSL - select-setup-language
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECST8C - set-tab-at-every-8-columns
* Clear the tab-ruler and reset it to a tab at every 8th column,
* starting at 9 (though, setting a tab at 1 is fine as it has no
* effect).
*/
unsigned int i;
return 0;
}
/*
* DECSTBM - set-top-and-bottom-margins
* This control function sets the top and bottom margins for the current
* page. You cannot perform scrolling outside the margins.
*
* @args[0] defines the top margin, @args[1] defines the bottom margin.
* The bottom margin must be lower than the top-margin.
*
* This call resets the cursor position to 0/0 of the page.
*
* Defaults:
* args[0]: 1
* args[1]: last page-line
*/
top = 1;
top = 1;
}
screen_cursor_set(screen, 0, 0);
return 0;
}
/*
* DECSTR - soft-terminal-reset
* Perform a soft reset to the default values.
*/
return 0;
}
/*
* DECSTRL - set-transmit-rate-limit
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECSWBV - set-warning-bell-volume
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECSWL - single-width-single-height-line
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECTID - select-terminal-id
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECTME - terminal-mode-emulation
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DECTST - invoke-confidence-test
*
* Probably not worth implementing.
*/
return 0;
}
/*
* DL - delete-line
* This control function deletes one or more lines in the scrolling
* region, starting with the line that has the cursor. @args[0] defines
* the number of lines to delete. 0 is treated the same as 1.
* As lines are deleted, lines below the cursor and in the scrolling
* region move up. The terminal adds blank lines with no visual
* character attributes at the bottom of the scrolling region. If it is
* greater than the number of lines remaining on the page, DL deletes
* only the remaining lines. DL has no effect outside the scrolling
* margins.
*
* Defaults:
* args[0]: 1
*/
unsigned int num = 1;
term_page_delete_lines(screen->page, screen->state.cursor_y, num, &screen->state.attr, screen->age);
return 0;
}
/*
* DSR_ANSI - device-status-report-ansi
*
* TODO: implement
*/
return 0;
}
/*
* DSR_DEC - device-status-report-dec
*
* TODO: implement
*/
return 0;
}
/*
* ECH - erase-character
* This control function erases one or more characters, from the cursor
* position to the right. ECH clears character attributes from erased
* character positions. ECH works inside or outside the scrolling
* margins.
* @args[0] defines the number of characters to erase. 0 is treated the
* same as 1.
*
* Defaults:
* args[0]: 1
*/
unsigned int num = 1;
return 0;
}
/*
* ED - erase-in-display
* This control function erases characters from part or all of the
* display. When you erase complete lines, they become single-height,
* single-width lines, with all visual character attributes cleared. ED
* works inside or outside the scrolling margins.
*
* @args[0] defines the region to erase. 0 means from cursor (inclusive)
* till the end of the screen. 1 means from the start of the screen till
* the cursor (inclusive) and 2 means the whole screen.
*
* Defaults:
* args[0]: 0
*/
unsigned int mode = 0;
switch (mode) {
case 0:
break;
case 1:
0, 0,
break;
case 2:
0, 0,
break;
}
return 0;
}
/*
* EL - erase-in-line
* This control function erases characters on the line that has the
* cursor. EL clears all character attributes from erased character
* positions. EL works inside or outside the scrolling margins.
*
* @args[0] defines the region to erase. 0 means from cursor (inclusive)
* till the end of the line. 1 means from the start of the line till the
* cursor (inclusive) and 2 means the whole line.
*
* Defaults:
* args[0]: 0
*/
unsigned int mode = 0;
switch (mode) {
case 0:
break;
case 1:
break;
case 2:
break;
}
return 0;
}
/*
* ENQ - enquiry
* Transmit the answerback-string. If none is set, do nothing.
*/
if (screen->answerback)
return 0;
}
/*
* EPA - end-of-guarded-area
*
* TODO: What is this?
*/
return 0;
}
/*
* FF - form-feed
* This causes the cursor to jump to the next line. It is treated the
* same as LF.
*/
}
/*
* HPA - horizontal-position-absolute
* HPA causes the active position to be moved to the n-th horizontal
* position of the active line. If an attempt is made to move the active
* position past the last position on the line, then the active position
* stops at the last position on the line.
*
* @args[0] defines the horizontal position. 0 is treated as 1.
*
* Defaults:
* args[0]: 1
*/
unsigned int num = 1;
return 0;
}
/*
* HPR - horizontal-position-relative
* HPR causes the active position to be moved to the n-th following
* horizontal position of the active line. If an attempt is made to move
* the active position past the last position on the line, then the
* active position stops at the last position on the line.
*
* @args[0] defines the horizontal position. 0 is treated as 1.
*
* Defaults:
* args[0]: 1
*/
unsigned int num = 1;
return 0;
}
/*
* HT - horizontal-tab
* Moves the cursor to the next tab stop. If there are no more tab
* stops, the cursor moves to the right margin. HT does not cause text
* to auto wrap.
*/
return 0;
}
/*
* HTS - horizontal-tab-set
* HTS sets a horizontal tab stop at the column position indicated by
* the value of the active column when the terminal receives an HTS.
*
* Executing an HTS does not effect the other horizontal tab stop
* settings.
*/
unsigned int pos;
return 0;
}
/*
* HVP - horizontal-and-vertical-position
* This control function works the same as the cursor position (CUP)
* function. Origin mode (DECOM) selects line numbering and the ability
* to move the cursor into margins.
*
* Defaults:
* args[0]: 1
* args[1]: 1
*/
}
/*
* ICH - insert-character
* This control function inserts one or more space (SP) characters
* starting at the cursor position. @args[0] is the number of characters
* to insert. 0 is treated as 1.
*
* The ICH sequence inserts blank characters with the normal
* character attribute. The cursor remains at the beginning of the blank
* characters. Text between the cursor and right margin moves to the
* right. Characters scrolled past the right margin are lost. ICH has no
* effect outside the scrolling margins.
*
* Defaults:
* args[0]: 1
*/
unsigned int num = 1;
term_page_insert_cells(screen->page, screen->state.cursor_x, screen->state.cursor_y, num, &screen->state.attr, screen->age);
return 0;
}
/*
* IL - insert-line
* This control function inserts one or more blank lines, starting at
* the cursor. @args[0] is the number of lines to insert. 0 is treated
* as 1.
*
* As lines are inserted, lines below the cursor and in the scrolling
* region move down. Lines scrolled off the page are lost. IL has no
* effect outside the page margins.
*
* Defaults:
* args[0]: 1
*/
unsigned int num = 1;
term_page_insert_lines(screen->page, screen->state.cursor_y, num, &screen->state.attr, screen->age);
return 0;
}
/*
* IND - index
* IND moves the cursor down one line in the same column. If the cursor
* is at the bottom margin, then the screen performs a scroll-up.
*/
return 0;
}
/*
* LF - line-feed
* Causes a line feed or a new line operation, depending on the setting
*/
return 0;
}
/*
* LS1R - locking-shift-1-right
* Map G1 into GR.
*/
return 0;
}
/*
* LS2 - locking-shift-2
* Map G2 into GL.
*/
return 0;
}
/*
* LS2R - locking-shift-2-right
* Map G2 into GR.
*/
return 0;
}
/*
* LS3 - locking-shift-3
* Map G3 into GL.
*/
return 0;
}
/*
* LS3R - locking-shift-3-right
* Map G3 into GR.
*/
return 0;
}
/*
* MC_ANSI - media-copy-ansi
*
* Probably not worth implementing.
*/
return 0;
}
/*
* MC_DEC - media-copy-dec
*
* Probably not worth implementing.
*/
return 0;
}
/*
* NEL - next-line
* Moves cursor to first position on next line. If cursor is at bottom
* margin, then screen performs a scroll-up.
*/
return 0;
}
/*
* NP - next-page
* This control function moves the cursor forward to the home position
* on one of the following pages in page memory. If there is only one
* page, then the terminal ignores NP.
* If NP tries to move the cursor past the last page in memory, then the
* cursor stops at the last page.
*
* @args[0] defines the number of pages to forward. 0 is treated as 1.
*
* Defaults:
* args[0]: 1
*
* Probably not worth implementing. We only support a single page.
*/
return 0;
}
/*
* NULL - null
* The NULL operation does nothing. ASCII NULL is always ignored.
*/
return 0;
}
/*
* PP - preceding-page
* This control function moves the cursor backward to the home position
* on one of the preceding pages in page memory. If there is only one
* page, then the terminal ignores PP.
* If PP tries to move the cursor back farther than the first page in
* memory, then the cursor stops at the first page.
*
* @args[0] defines the number of pages to go backwards. 0 is treated
* as 1.
*
* Defaults:
* args[0]: 1
*
* Probably not worth implementing. We only support a single page.
*/
return 0;
}
/*
* PPA - page-position-absolute
* This control function can move the cursor to the corresponding row
* and column on any page in page memory. You select the page by its
* number. If there is only one page, then the terminal ignores PPA.
*
* @args[0] is the number of the page to move the cursor to. If it is
* greater than the number of the last page in memory, then the cursor
* stops at the last page. If it is less than the number of the first
* page, then the cursor stops at the first page.
*
* Defaults:
* args[0]: 1
*
* Probably not worth implementing. We only support a single page.
*/
return 0;
}
/*
* PPB - page-position-backward
* This control function moves the cursor backward to the corresponding
* row and column on one of the preceding pages in page memory. If there
* is only one page, then the terminal ignores PPB.
*
* @args[0] indicates the number of pages to move the cursor backward.
* If it tries to move the cursor back farther than the first page in
* memory, then the cursor stops at the first page. 0 is treated as 1.
*
* Defaults:
* args[0]: 1
*
* Probably not worth implementing. We only support a single page.
*/
return 0;
}
/*
* PPR - page-position-relative
* This control function moves the cursor forward to the corresponding
* row and column on one of the following pages in page memory. If there
* is only one page, then the terminal ignores PPR.
*
* @args[0] indicates how many pages to move the cursor forward. If it
* tries to move the cursor beyond the last page in memory, then the
* cursor stops at the last page. 0 is treated as 1.
*
* Defaults:
* args[0]: 1
*
* Probably not worth implementing. We only support a single page.
*/
return 0;
}
/*
* RC - restore-cursor
*/
}
/*
* REP - repeat
* Repeat the preceding graphics-character the given number of times.
* @args[0] specifies how often it shall be repeated. 0 is treated as 1.
*
* Defaults:
* args[0]: 1
*
* Probably not worth implementing.
*/
return 0;
}
/*
* RI - reverse-index
* Moves the cursor up one line in the same column. If the cursor is at
* the top margin, the page scrolls down.
*/
return 0;
}
/*
* RIS - reset-to-initial-state
* This control function causes a nonvolatile memory (NVR) recall to
* occur. RIS replaces all set-up features with their saved settings.
*
* The terminal stores these saved settings in NVR memory. The saved
* setting for a feature is the same as the factory-default setting,
* unless you saved a new setting.
*/
return 0;
}
/*
* RM_ANSI - reset-mode-ansi
*
* TODO: implement (see VT510rm manual)
*/
unsigned int i;
return 0;
}
/*
* RM_DEC - reset-mode-dec
* This is the same as RM_ANSI but for DEC modes.
*/
unsigned int i;
return 0;
}
/*
* S7C1T - set-7bit-c1-terminal
* This causes the terminal to start sending C1 controls as 7bit
* sequences instead of 8bit C1 controls.
* This is ignored if the terminal is below level-2 emulation mode
* (VT100 and below), the terminal already sends 7bit controls then.
*/
return 0;
}
/*
* S8C1T - set-8bit-c1-terminal
* This causes the terminal to start sending C1 controls as 8bit C1
* control instead of 7bit sequences.
* This is ignored if the terminal is below level-2 emulation mode
* (VT100 and below). The terminal always sends 7bit controls in those
* modes.
*/
return 0;
}
/*
* SCS - select-character-set
* Designate character sets to G-sets. The mapping from intermediates
* and terminal characters in the escape sequence to G-sets and
* character-sets is non-trivial and implemented separately. See there
* for more information.
* This call simply sets the selected G-set to the desired
* character-set.
*/
/* TODO: support more of them? */
break;
break;
break;
case TERM_CHARSET_DUTCH_NRCS:
case TERM_CHARSET_FRENCH_NRCS:
case TERM_CHARSET_GERMAN_NRCS:
case TERM_CHARSET_GREEK_DEC:
case TERM_CHARSET_GREEK_NRCS:
case TERM_CHARSET_HEBREW_DEC:
case TERM_CHARSET_HEBREW_NRCS:
case TERM_CHARSET_SCS_NRCS:
case TERM_CHARSET_SWISS_NRCS:
case TERM_CHARSET_TURKISH_DEC:
break;
break;
}
return 0;
}
/*
* SD - scroll-down
* This control function moves the user window down a specified number
* of lines in page memory.
* @args[0] is the number of lines to move the
* user window up in page memory. New lines appear at the top of the
* display. Old lines disappear at the bottom of the display. You
* cannot pan past the top margin of the current page. 0 is treated
* as 1.
*
* Defaults:
* args[0]: 1
*/
unsigned int num = 1;
return 0;
}
/*
* SGR - select-graphics-rendition
*/
unsigned int i, code;
int v;
return 0;
}
switch (v) {
case 1:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 7:
break;
case 8:
break;
case 22:
break;
case 23:
break;
case 24:
break;
case 25:
break;
case 27:
break;
case 28:
break;
case 30 ... 37:
break;
case 39:
break;
case 40 ... 47:
break;
case 49:
break;
case 90 ... 97:
break;
case 100 ... 107:
break;
case 38:
/* fallthrough */
case 48:
if (v == 38)
else
++i;
break;
case 2:
/* 24bit-color support */
i += 3;
break;
break;
case 5:
/* 256-color support */
++i;
break;
break;
}
break;
case -1:
/* fallthrough */
case 0:
break;
}
}
return 0;
}
/*
* SI - shift-in
* Map G0 into GL.
*/
return 0;
}
/*
* SM_ANSI - set-mode-ansi
*
* TODO: implement
*/
unsigned int i;
return 0;
}
/*
* SM_DEC - set-mode-dec
* This is the same as SM_ANSI but for DEC modes.
*/
unsigned int i;
return 0;
}
/*
* SO - shift-out
* Map G1 into GL.
*/
return 0;
}
/*
* SPA - start-of-protected-area
*
* TODO: What is this?
*/
return 0;
}
/*
* SS2 - single-shift-2
* Temporarily map G2 into GL for the next graphics character.
*/
return 0;
}
/*
* SS3 - single-shift-3
* Temporarily map G3 into GL for the next graphics character
*/
return 0;
}
/*
* ST - string-terminator
* The string-terminator is usually part of control-sequences and
* handled by the parser. In all other situations it is silently
* ignored.
*/
return 0;
}
/*
* SU - scroll-up
* This control function moves the user window up a specified number of
* lines in page memory.
* @args[0] is the number of lines to move the
* user window down in page memory. New lines appear at the bottom of
* the display. Old lines disappear at the top of the display. You
* cannot pan past the bottom margin of the current page. 0 is treated
* as 1.
*
* Defaults:
* args[0]: 1
*/
unsigned int num = 1;
return 0;
}
/*
* SUB - substitute
* Cancel the current control-sequence and print a replacement
* character. Our parser already handles this so all we have to do is
* print the replacement character.
*/
.type = TERM_SEQ_GRAPHIC,
.terminator = 0xfffd,
};
}
/*
* TBC - tab-clear
* This clears tab-stops. If @args[0] is 0, the tab-stop at the current
* cursor position is cleared. If it is 3, all tab stops are cleared.
*
* Defaults:
* args[0]: 0
*/
switch (mode) {
case 0:
break;
case 3:
break;
}
return 0;
}
/*
* VPA - vertical-line-position-absolute
* VPA causes the active position to be moved to the corresponding
* horizontal position. @args[0] specifies the line to jump to. If an
* attempt is made to move the active position below the last line, then
* the active position stops on the last line. 0 is treated as 1.
*
* Defaults:
* args[0]: 1
*/
unsigned int pos = 1;
return 0;
}
/*
* VPR - vertical-line-position-relative
* VPR causes the active position to be moved to the corresponding
* horizontal position. @args[0] specifies the number of lines to jump
* down relative to the current cursor position. If an attempt is made
* to move the active position below the last line, the active position
* stops at the last line. 0 is treated as 1.
*
* Defaults:
* args[0]: 1
*/
unsigned int num = 1;
return 0;
}
/*
* VT - vertical-tab
* This causes a vertical jump by one line. Terminals treat it exactly
* the same as LF.
*/
}
/*
* XTERM_CLLHP - xterm-cursor-lower-left-hp-bugfix
* Move the cursor to the lower-left corner of the page. This is an HP
* bugfix by xterm.
*
* Probably not worth implementing.
*/
return 0;
}
/*
* XTERM_IHMT - xterm-initiate-highlight-mouse-tracking
*
* Probably not worth implementing.
*/
return 0;
}
/*
* XTERM_MLHP - xterm-memory-lock-hp-bugfix
*
* Probably not worth implementing.
*/
return 0;
}
/*
* XTERM_MUHP - xterm-memory-unlock-hp-bugfix
*
* Probably not worth implementing.
*/
return 0;
}
/*
* XTERM_RPM - xterm-restore-private-mode
*
* Probably not worth implementing.
*/
return 0;
}
/*
* XTERM_RRV - xterm-reset-resource-value
*
* Probably not worth implementing.
*/
return 0;
}
/*
* XTERM_RTM - xterm-reset-title-mode
*
* Probably not worth implementing.
*/
return 0;
}
/*
* XTERM_SACL1 - xterm-set-ansi-conformance-level-1
*
* Probably not worth implementing.
*/
return 0;
}
/*
* XTERM_SACL2 - xterm-set-ansi-conformance-level-2
*
* Probably not worth implementing.
*/
return 0;
}
/*
* XTERM_SACL3 - xterm-set-ansi-conformance-level-3
*
* Probably not worth implementing.
*/
return 0;
}
/*
* XTERM_SDCS - xterm-set-default-character-set
* Select the default character set. We treat this the same as UTF-8 as
* this is our default character set. As we always use UTF-8, this
* becomes as no-op.
*/
return 0;
}
/*
* XTERM_SGFX - xterm-sixel-graphics
*
* Probably not worth implementing.
*/
return 0;
}
/*
* XTERM_SPM - xterm-set-private-mode
*
* Probably not worth implementing.
*/
return 0;
}
/*
* XTERM_SRV - xterm-set-resource-value
*
* Probably not worth implementing.
*/
return 0;
}
/*
* XTERM_STM - xterm-set-title-mode
*
* Probably not worth implementing.
*/
return 0;
}
/*
* XTERM_SUCS - xterm-select-utf8-character-set
* Select UTF-8 as character set. This is our default on only character
* set. Hence, this is a no-op.
*/
return 0;
}
/*
* XTERM_WM - xterm-window-management
*
* Probably not worth implementing.
*/
return 0;
}
/*
* Feeding data
* The screen_feed_*() handlers take data from the user and feed it into the
* screen. Once the parser has detected a sequence, we parse the command-type
* and forward it to the command-dispatchers.
*/
case TERM_CMD_GRAPHIC:
case TERM_CMD_BEL:
case TERM_CMD_BS:
case TERM_CMD_CBT:
case TERM_CMD_CHA:
case TERM_CMD_CHT:
case TERM_CMD_CNL:
case TERM_CMD_CPL:
case TERM_CMD_CR:
case TERM_CMD_CUB:
case TERM_CMD_CUD:
case TERM_CMD_CUF:
case TERM_CMD_CUP:
case TERM_CMD_CUU:
case TERM_CMD_DA1:
case TERM_CMD_DA2:
case TERM_CMD_DA3:
case TERM_CMD_DC1:
case TERM_CMD_DC3:
case TERM_CMD_DCH:
case TERM_CMD_DECALN:
case TERM_CMD_DECANM:
case TERM_CMD_DECBI:
case TERM_CMD_DECCARA:
case TERM_CMD_DECCRA:
case TERM_CMD_DECDC:
case TERM_CMD_DECDHL_BH:
case TERM_CMD_DECDHL_TH:
case TERM_CMD_DECDWL:
case TERM_CMD_DECEFR:
case TERM_CMD_DECELF:
case TERM_CMD_DECELR:
case TERM_CMD_DECERA:
case TERM_CMD_DECFI:
case TERM_CMD_DECFRA:
case TERM_CMD_DECIC:
case TERM_CMD_DECID:
case TERM_CMD_DECINVM:
case TERM_CMD_DECKBD:
case TERM_CMD_DECKPAM:
case TERM_CMD_DECKPNM:
case TERM_CMD_DECLFKC:
case TERM_CMD_DECLL:
case TERM_CMD_DECLTOD:
case TERM_CMD_DECPCTERM:
case TERM_CMD_DECPKA:
case TERM_CMD_DECPKFMR:
case TERM_CMD_DECRARA:
case TERM_CMD_DECRC:
case TERM_CMD_DECREQTPARM:
case TERM_CMD_DECRPKT:
case TERM_CMD_DECRQCRA:
case TERM_CMD_DECRQDE:
case TERM_CMD_DECRQKT:
case TERM_CMD_DECRQLP:
case TERM_CMD_DECRQM_ANSI:
case TERM_CMD_DECRQM_DEC:
case TERM_CMD_DECRQPKFM:
case TERM_CMD_DECRQPSR:
case TERM_CMD_DECRQTSR:
case TERM_CMD_DECRQUPSS:
case TERM_CMD_DECSACE:
case TERM_CMD_DECSASD:
case TERM_CMD_DECSC:
case TERM_CMD_DECSCA:
case TERM_CMD_DECSCL:
case TERM_CMD_DECSCP:
case TERM_CMD_DECSCPP:
case TERM_CMD_DECSCS:
case TERM_CMD_DECSCUSR:
case TERM_CMD_DECSDDT:
case TERM_CMD_DECSDPT:
case TERM_CMD_DECSED:
case TERM_CMD_DECSEL:
case TERM_CMD_DECSERA:
case TERM_CMD_DECSFC:
case TERM_CMD_DECSKCV:
case TERM_CMD_DECSLCK:
case TERM_CMD_DECSLE:
case TERM_CMD_DECSLPP:
case TERM_CMD_DECSLRM_OR_SC:
case TERM_CMD_DECSMBV:
case TERM_CMD_DECSMKR:
case TERM_CMD_DECSNLS:
case TERM_CMD_DECSPP:
case TERM_CMD_DECSPPCS:
case TERM_CMD_DECSPRTT:
case TERM_CMD_DECSR:
case TERM_CMD_DECSRFR:
case TERM_CMD_DECSSCLS:
case TERM_CMD_DECSSDT:
case TERM_CMD_DECSSL:
case TERM_CMD_DECST8C:
case TERM_CMD_DECSTBM:
case TERM_CMD_DECSTR:
case TERM_CMD_DECSTRL:
case TERM_CMD_DECSWBV:
case TERM_CMD_DECSWL:
case TERM_CMD_DECTID:
case TERM_CMD_DECTME:
case TERM_CMD_DECTST:
case TERM_CMD_DL:
case TERM_CMD_DSR_ANSI:
case TERM_CMD_DSR_DEC:
case TERM_CMD_ECH:
case TERM_CMD_ED:
case TERM_CMD_EL:
case TERM_CMD_ENQ:
case TERM_CMD_EPA:
case TERM_CMD_FF:
case TERM_CMD_HPA:
case TERM_CMD_HPR:
case TERM_CMD_HT:
case TERM_CMD_HTS:
case TERM_CMD_HVP:
case TERM_CMD_ICH:
case TERM_CMD_IL:
case TERM_CMD_IND:
case TERM_CMD_LF:
case TERM_CMD_LS1R:
case TERM_CMD_LS2:
case TERM_CMD_LS2R:
case TERM_CMD_LS3:
case TERM_CMD_LS3R:
case TERM_CMD_MC_ANSI:
case TERM_CMD_MC_DEC:
case TERM_CMD_NEL:
case TERM_CMD_NP:
case TERM_CMD_NULL:
case TERM_CMD_PP:
case TERM_CMD_PPA:
case TERM_CMD_PPB:
case TERM_CMD_PPR:
case TERM_CMD_RC:
case TERM_CMD_REP:
case TERM_CMD_RI:
case TERM_CMD_RIS:
case TERM_CMD_RM_ANSI:
case TERM_CMD_RM_DEC:
case TERM_CMD_S7C1T:
case TERM_CMD_S8C1T:
case TERM_CMD_SCS:
case TERM_CMD_SD:
case TERM_CMD_SGR:
case TERM_CMD_SI:
case TERM_CMD_SM_ANSI:
case TERM_CMD_SM_DEC:
case TERM_CMD_SO:
case TERM_CMD_SPA:
case TERM_CMD_SS2:
case TERM_CMD_SS3:
case TERM_CMD_ST:
case TERM_CMD_SU:
case TERM_CMD_SUB:
case TERM_CMD_TBC:
case TERM_CMD_VPA:
case TERM_CMD_VPR:
case TERM_CMD_VT:
case TERM_CMD_XTERM_CLLHP:
case TERM_CMD_XTERM_IHMT:
case TERM_CMD_XTERM_MLHP:
case TERM_CMD_XTERM_MUHP:
case TERM_CMD_XTERM_RPM:
case TERM_CMD_XTERM_RRV:
case TERM_CMD_XTERM_RTM:
case TERM_CMD_XTERM_SACL1:
case TERM_CMD_XTERM_SACL2:
case TERM_CMD_XTERM_SACL3:
case TERM_CMD_XTERM_SDCS:
case TERM_CMD_XTERM_SGFX:
case TERM_CMD_XTERM_SPM:
case TERM_CMD_XTERM_SRV:
case TERM_CMD_XTERM_STM:
case TERM_CMD_XTERM_SUCS:
case TERM_CMD_XTERM_WM:
}
return 0;
}
}
}
assert_return(screen, 0);
}
int r;
/* Feed bytes into utf8 decoder and handle parsed ucs4 chars. We always
* treat data as UTF-8, but the parser makes sure to fall back to raw
* 8bit mode if the stream is not valid UTF-8. This should be more than
* enough to support old 7bit/8bit modes. */
for (i = 0; i < size; ++i) {
for (j = 0; j < ucs4_len; ++j) {
if (r < 0) {
return r;
} else if (r != TERM_SEQ_NONE) {
if (r < 0)
return r;
}
}
}
return 0;
}
char *p,
unsigned int mods) {
uint32_t v;
size_t i;
/* TODO: All these key-mappings need to be verified. Public information
* on those mappings is pretty scarce and every emulator seems to do it
* slightly differently.
* A lot of mappings are also missing. */
if (n_syms < 1)
return p;
if (n_syms == 1)
v = keysyms[0];
else
v = XKB_KEY_NoSymbol;
/* In some mappings, the modifiers are encoded as CSI parameters. The
* encoding is rather arbitrary, but seems to work. */
ch_mods = 0;
case TERM_KBDMOD_SHIFT:
ch_mods = '2';
break;
case TERM_KBDMOD_ALT:
ch_mods = '3';
break;
case TERM_KBDMOD_SHIFT | TERM_KBDMOD_ALT:
ch_mods = '4';
break;
case TERM_KBDMOD_CTRL:
ch_mods = '5';
break;
case TERM_KBDMOD_CTRL | TERM_KBDMOD_SHIFT:
ch_mods = '6';
break;
case TERM_KBDMOD_CTRL | TERM_KBDMOD_ALT:
ch_mods = '7';
break;
ch_mods = '8';
break;
}
/* A user might actually use multiple layouts for keyboard
* input. @keysyms[0] contains the actual keysym that the user
* used. But if this keysym is not in the ascii range, the
* input handler does check all other layouts that the user
* specified whether one of them maps the key to some ASCII
* keysym and provides this via @ascii. We always use the real
* keysym except when handling CTRL+<XY> shortcuts we use the
* ascii keysym. This is for compatibility to xterm et. al. so
* ctrl+c always works regardless of the currently active
* keyboard layout. But if no ascii-sym is found, we still use
* the real keysym. */
if (ascii == XKB_KEY_NoSymbol)
ascii = v;
/* map CTRL+<ascii> */
if (mods & TERM_KBDMOD_CTRL) {
switch (ascii) {
case 0x60 ... 0x7e:
/* Right hand side is mapped to the left and then
* treated equally. Fall through to left-hand side.. */
ascii -= 0x20;
case 0x20 ... 0x5f:
/* Printable ASCII is mapped 1-1 in XKB and in
* combination with CTRL bit 7 is flipped. This
* is equivalent to the caret-notation. */
*p++ = ascii ^ 0x40;
return p;
}
}
/* map cursor keys */
ch = 0;
switch (v) {
case XKB_KEY_Up:
ch = 'A';
break;
case XKB_KEY_Down:
ch = 'B';
break;
case XKB_KEY_Right:
ch = 'C';
break;
case XKB_KEY_Left:
ch = 'D';
break;
case XKB_KEY_Home:
ch = 'H';
break;
case XKB_KEY_End:
ch = 'F';
break;
}
if (ch) {
*p++ = 0x1b;
*p++ = 'O';
else
*p++ = '[';
if (ch_mods) {
*p++ = '1';
*p++ = ';';
*p++ = ch_mods;
}
*p++ = ch;
return p;
}
/* map action keys */
ch = 0;
switch (v) {
case XKB_KEY_Find:
ch = '1';
break;
case XKB_KEY_Insert:
ch = '2';
break;
case XKB_KEY_Delete:
ch = '3';
break;
case XKB_KEY_Select:
ch = '4';
break;
case XKB_KEY_Page_Up:
ch = '5';
break;
case XKB_KEY_Page_Down:
ch = '6';
break;
}
if (ch) {
*p++ = 0x1b;
*p++ = '[';
*p++ = ch;
if (ch_mods) {
*p++ = ';';
*p++ = ch_mods;
}
*p++ = '~';
return p;
}
/* map lower function keys */
ch = 0;
switch (v) {
case XKB_KEY_F1:
ch = 'P';
break;
case XKB_KEY_F2:
ch = 'Q';
break;
case XKB_KEY_F3:
ch = 'R';
break;
case XKB_KEY_F4:
ch = 'S';
break;
}
if (ch) {
if (ch_mods) {
*p++ = 0x1b;
*p++ = '[';
*p++ = '1';
*p++ = ';';
*p++ = ch_mods;
*p++ = ch;
} else {
*p++ = 0x1b;
*p++ = 'O';
*p++ = ch;
}
return p;
}
/* map upper function keys */
ch = 0;
ch2 = 0;
switch (v) {
case XKB_KEY_F5:
ch = '1';
ch2 = '5';
break;
case XKB_KEY_F6:
ch = '1';
ch2 = '7';
break;
case XKB_KEY_F7:
ch = '1';
ch2 = '8';
break;
case XKB_KEY_F8:
ch = '1';
ch2 = '9';
break;
case XKB_KEY_F9:
ch = '2';
ch2 = '0';
break;
case XKB_KEY_F10:
ch = '2';
ch2 = '1';
break;
case XKB_KEY_F11:
ch = '2';
ch2 = '2';
break;
case XKB_KEY_F12:
ch = '2';
ch2 = '3';
break;
}
if (ch) {
*p++ = 0x1b;
*p++ = '[';
*p++ = ch;
if (ch2)
*p++ = ch2;
if (ch_mods) {
*p++ = ';';
*p++ = ch_mods;
}
*p++ = '~';
return p;
}
/* map special keys */
switch (v) {
case 0xff08: /* XKB_KEY_BackSpace */
case 0xff09: /* XKB_KEY_Tab */
case 0xff0a: /* XKB_KEY_Linefeed */
case 0xff0b: /* XKB_KEY_Clear */
case 0xff15: /* XKB_KEY_Sys_Req */
case 0xff1b: /* XKB_KEY_Escape */
case 0xffff: /* XKB_KEY_Delete */
*p++ = v - 0xff00;
return p;
case 0xff13: /* XKB_KEY_Pause */
/* TODO: What should we do with this key?
* Sending XOFF is awful as there is no simple
* way on modern keyboards to send XON again.
* If someone wants this, we can re-eanble
* optionally. */
return p;
case 0xff14: /* XKB_KEY_Scroll_Lock */
/* TODO: What should we do on scroll-lock?
* Sending 0x14 is what the specs say but it is
* not used today the way most users would
* expect so we disable it. If someone wants
* this, we can re-enable it (optionally). */
return p;
case XKB_KEY_Return:
*p++ = 0x0d;
*p++ = 0x0a;
return p;
case XKB_KEY_ISO_Left_Tab:
*p++ = 0x09;
return p;
}
/* map unicode keys */
for (i = 0; i < n_syms; ++i)
p += utf8_encode_unichar(p, ucs4[i]);
return p;
}
unsigned int mods) {
/* allocate buffer if too small */
if (!dyn)
return -ENOMEM;
}
/* reserve prefix space */
p = start;
if (!p || p - start < 1)
return 0;
/* The ALT modifier causes ESC to be prepended to any key-stroke. We
* already accounted for that buffer space above, so simply prepend it
* here.
* TODO: is altSendsEscape a suitable default? What are the semantics
* already is an escape character? */
*--start = 0x1b;
/* turn C0 into C1 */
*++start ^= 0x40;
}
unsigned int i;
uint8_t *t;
int r;
if (r < 0)
return r;
if (r < 0)
return r;
if (!t)
return -ENOMEM;
}
return 0;
}
unsigned int i;
}
term_page_erase(screen->page_main, 0, 0, screen->page->width, screen->page->height, &screen->state.attr, screen->age, false);
term_page_erase(screen->page_alt, 0, 0, screen->page->width, screen->page->height, &screen->state.attr, screen->age, false);
}
char *t = NULL;
if (answerback) {
t = strdup(answerback);
if (!t)
return -ENOMEM;
}
screen->answerback = t;
return 0;
}
void *userdata,
unsigned int x,
unsigned int y,
unsigned int ch_width),
void *userdata,
unsigned int i, j, cw;
int r;
if (fb_age)
continue;
/* Character-width of 0 is used for cleared cells.
* Always treat this as single-cell character, so
* renderers can assume ch_width is set properpy. */
i,
j,
&attr,
ch_n,
cw);
if (r != 0)
return r;
}
}
if (fb_age)
return 0;
}