Files
RedBear-OS/local/recipes/kde/konsole/source/src/Vt102Emulation.h
T

331 lines
9.9 KiB
C++

/*
SPDX-FileCopyrightText: 2007-2008 Robert Knight <robertknight@gmail.com>
SPDX-FileCopyrightText: 1997, 1998 Lars Doelle <lars.doelle@on-line.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef VT102EMULATION_H
#define VT102EMULATION_H
// Qt
#include "config-konsole.h"
#include <QHash>
#include <QMap>
#if HAVE_QTMULTIMEDIA
#include <QMediaPlayer>
#endif
#include <QPair>
#include <QVector>
#include <QList>
// Konsole
#include "Emulation.h"
#include "Screen.h"
#include "keyboardtranslator/KeyboardTranslator.h"
class QTimer;
class QKeyEvent;
#define MODE_AppCuKeys (MODES_SCREEN + 0) // Application cursor keys (DECCKM)
#define MODE_AppKeyPad (MODES_SCREEN + 1) //
#define MODE_Mouse1000 (MODES_SCREEN + 2) // Send mouse X,Y position on press and release
#define MODE_Mouse1001 (MODES_SCREEN + 3) // Use Highlight mouse tracking
#define MODE_Mouse1002 (MODES_SCREEN + 4) // Use cell motion mouse tracking
#define MODE_Mouse1003 (MODES_SCREEN + 5) // Use all motion mouse tracking
#define MODE_Mouse1005 (MODES_SCREEN + 6) // Xterm-style extended coordinates
#define MODE_Mouse1006 (MODES_SCREEN + 7) // 2nd Xterm-style extended coordinates
#define MODE_Mouse1007 (MODES_SCREEN + 8) // XTerm Alternate Scroll mode; also check AlternateScrolling profile property
#define MODE_Mouse1015 (MODES_SCREEN + 9) // Urxvt-style extended coordinates
#define MODE_Ansi (MODES_SCREEN + 10) // Use US Ascii for character sets G0-G3 (DECANM)
#define MODE_132Columns (MODES_SCREEN + 11) // 80 <-> 132 column mode switch (DECCOLM)
#define MODE_Allow132Columns (MODES_SCREEN + 12) // Allow DECCOLM mode
#define MODE_BracketedPaste (MODES_SCREEN + 13) // Xterm-style bracketed paste mode
#define MODE_Sixel (MODES_SCREEN + 14) // Xterm-style bracketed paste mode
#define MODE_total (MODES_SCREEN + 15)
namespace Konsole
{
extern unsigned short vt100_graphics[32];
struct CharCodes {
// coding info
char charset[4]; //
int cu_cs; // actual charset.
bool graphic; // Some VT100 tricks
bool pound; // Some VT100 tricks
bool sa_graphic; // saved graphic
bool sa_pound; // saved pound
};
/**
* Provides an xterm compatible terminal emulation based on the DEC VT102 terminal.
* A full description of this terminal can be found at https://vt100.net/docs/vt102-ug/
*
* In addition, various additional xterm escape sequences are supported to provide
* features such as mouse input handling.
* See https://invisible-island.net/xterm/ctlseqs/ctlseqs.html for a description of xterm's escape
* sequences.
*
*/
class KONSOLEPRIVATE_EXPORT Vt102Emulation : public Emulation
{
Q_OBJECT
public:
/** Constructs a new emulation */
Vt102Emulation();
~Vt102Emulation() override;
// reimplemented from Emulation
void clearEntireScreen() override;
void reset(bool softReset = false, bool preservePrompt = false) override;
char eraseChar() const override;
public Q_SLOTS:
// reimplemented from Emulation
void sendString(const QByteArray &string) override;
void sendText(const QString &text) override;
void sendKeyEvent(QKeyEvent *) override;
void sendMouseEvent(int buttons, int column, int line, int eventType) override;
void focusChanged(bool focused) override;
void clearHistory() override;
protected:
// reimplemented from Emulation
void setMode(int mode) override;
void resetMode(int mode) override;
void receiveChars(const QVector<uint> &chars) override;
private Q_SLOTS:
// Causes sessionAttributeChanged() to be emitted for each (int,QString)
// pair in _pendingSessionAttributesUpdates.
// Used to buffer multiple attribute updates in the current session
void updateSessionAttributes();
#if HAVE_QTMULTIMEDIA
void deletePlayer(QMediaPlayer::MediaStatus);
#endif
private:
unsigned int applyCharset(uint c);
void setCharset(int n, int cs);
void useCharset(int n);
void setAndUseCharset(int n, int cs);
void saveCursor();
void restoreCursor();
void resetCharset(int scrno);
void setMargins(int top, int bottom);
// set margins for all screens back to their defaults
void setDefaultMargins();
// returns true if 'mode' is set or false otherwise
bool getMode(int mode);
// saves the current boolean value of 'mode'
void saveMode(int mode);
// restores the boolean value of 'mode'
void restoreMode(int mode);
// resets all modes
// (except MODE_Allow132Columns)
void resetModes();
void resetTokenizer();
#define MAX_TOKEN_LENGTH 256 // Max length of tokens (e.g. window title)
void addToCurrentToken(uint cc);
int tokenBufferPos;
protected:
QList<char32_t> tokenBuffer;
private:
#define MAXARGS 16
void addDigit(int dig);
void addArgument();
void addSub();
struct subParam {
int value[MAXARGS]; // value[0] unused, it would correspond to the containing param value
int count;
};
struct {
int value[MAXARGS];
struct subParam sub[MAXARGS];
int count;
bool hasSubParams;
} params = {};
void initTokenizer();
enum ParserStates {
Ground,
Escape,
EscapeIntermediate,
CsiEntry,
CsiParam,
CsiIntermediate,
CsiIgnore,
DcsEntry,
DcsParam,
DcsIntermediate,
DcsPassthrough,
DcsIgnore,
OscString,
SosPmApcString,
Vt52Escape,
Vt52CupRow,
Vt52CupColumn,
};
enum {
Sos,
Pm,
Apc,
} _sosPmApc;
enum osc {
// https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Operating-System-Commands
ReportColors = 4,
ResetColors = 104,
// https://gitlab.freedesktop.org/Per_Bothner/specifications/blob/master/proposals/semantic-prompts.md
SemanticPrompts = 133,
// https://chromium.googlesource.com/apps/libapps/+/master/hterm/doc/ControlSequences.md#OSC
Notification = 777,
Image = 1337,
};
ParserStates _state = Ground;
bool _ignore = false;
int _nIntermediate = 0;
unsigned char _intermediate[1];
// Used to get expected behaviour in emulated up/down movement in REPL mode.
int _targetCol = -1;
void switchState(const ParserStates newState, const uint cc);
void esc_dispatch(const uint cc);
void clear();
void collect(const uint cc);
void param(const uint cc);
void csi_dispatch(const uint cc);
void osc_start();
void osc_put(const uint cc);
void osc_end(const uint cc);
void hook(const uint cc);
void unhook();
void put(const uint cc);
void apc_start(const uint cc);
void apc_put(const uint cc);
void apc_end();
// State machine for escape sequences containing large amount of data
int tokenState;
const char *tokenStateChange;
int tokenPos;
QByteArray tokenData;
// Set of flags for each of the ASCII characters which indicates
// what category they fall into (printable character, control, digit etc.)
// for the purposes of decoding terminal output
int charClass[256];
QByteArray imageData;
quint32 imageId;
QMap<char, qint64> savedKeys;
protected:
virtual void reportDecodingError(int token);
virtual void processToken(int code, int p, int q);
virtual void processSessionAttributeRequest(const int tokenSize, const uint terminator);
virtual void processChecksumRequest(int argc, int argv[]);
private:
void processGraphicsToken(int tokenSize);
void sendGraphicsReply(const QString &params, const QString &error);
void reportTerminalType();
void reportTertiaryAttributes();
void reportSecondaryAttributes();
void reportVersion();
void reportStatus();
void reportAnswerBack();
void reportCursorPosition();
void reportPixelSize();
void reportCellSize();
void iTermReportCellSize();
void reportSize();
void reportColor(int c, QColor color);
void reportTerminalParms(int p);
void emulateUpDown(int up, KeyboardTranslator::Entry entry, QByteArray &textToSend, int toCol = -1);
// clears the screen and resizes it to the specified
// number of columns
void clearScreenAndSetColumns(int columnCount);
CharCodes _charset[2];
class TerminalState
{
public:
// Initializes all modes to false
TerminalState()
{
memset(&mode, 0, MODE_total * sizeof(bool));
}
bool mode[MODE_total];
};
TerminalState _currentModes;
TerminalState _savedModes;
// Hash table and timer for buffering calls to update certain session
// attributes (e.g. the name of the session, window title).
// These calls occur when certain escape sequences are detected in the
// output from the terminal. See Emulation::sessionAttributeChanged()
QHash<int, QString> _pendingSessionAttributesUpdates;
QTimer *_sessionAttributesUpdateTimer;
bool _reportFocusEvents;
QColor colorTable[256];
// Sixel:
#define MAX_SIXEL_COLORS 256
#define MAX_IMAGE_DIM 16384
void sixelQuery(int query);
bool processSixel(uint cc);
void SixelModeEnable(int width, int height /*, bool preserveBackground*/);
void SixelModeAbort();
void SixelModeDisable();
void SixelColorChangeRGB(const int index, int red, int green, int blue);
void SixelColorChangeHSL(const int index, int hue, int saturation, int value);
void SixelCharacterAdd(uint8_t character, int repeat = 1);
bool m_SixelPictureDefinition = false;
bool m_SixelStarted = false;
QImage m_currentImage;
int m_currentX = 0;
int m_verticalPosition = 0;
uint8_t m_currentColor = 0;
bool m_preserveBackground = true;
QPair<int, int> m_aspect = qMakePair(1, 1);
bool m_SixelScrolling = true;
QSize m_actualSize; // For efficiency reasons, we keep the image in memory larger than what the end result is
// Kitty
QHash<int, QPixmap> _graphicsImages;
// For kitty graphics protocol - image cache
int getFreeGraphicsImageId();
#if HAVE_QTMULTIMEDIA
QMediaPlayer *player;
#endif
};
}
#endif // VT102EMULATION_H