File indexing completed on 2024-05-19 05:28:22

0001 /*
0002     This file is part of Konsole, an X terminal.
0003 
0004     SPDX-FileCopyrightText: 2007-2008 Robert Knight <robertknight@gmail.com>
0005     SPDX-FileCopyrightText: 1997, 1998 Lars Doelle <lars.doelle@on-line.de>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 
0009     This program is distributed in the hope that it will be useful,
0010     but WITHOUT ANY WARRANTY; without even the implied warranty of
0011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012     GNU General Public License for more details.
0013 
0014     You should have received a copy of the GNU General Public License
0015     along with this program; if not, write to the Free Software
0016     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
0017     02110-1301  USA.
0018 */
0019 
0020 #ifndef VT102EMULATION_H
0021 #define VT102EMULATION_H
0022 
0023 // Standard Library
0024 #include <cstdio>
0025 
0026 // Qt
0027 #include <QHash>
0028 #include <QKeyEvent>
0029 #include <QTimer>
0030 
0031 // Konsole
0032 #include "Emulation.h"
0033 #include "Screen.h"
0034 
0035 constexpr auto MODE_AppScreen = (MODES_SCREEN + 0); // Mode #1
0036 constexpr auto MODE_AppCuKeys = (MODES_SCREEN + 1); // Application cursor keys (DECCKM)
0037 constexpr auto MODE_AppKeyPad = (MODES_SCREEN + 2); //
0038 constexpr auto MODE_Mouse1000 = (MODES_SCREEN + 3); // Send mouse X,Y position on press and release
0039 constexpr auto MODE_Mouse1001 = (MODES_SCREEN + 4); // Use Hilight mouse tracking
0040 constexpr auto MODE_Mouse1002 = (MODES_SCREEN + 5); // Use cell motion mouse tracking
0041 constexpr auto MODE_Mouse1003 = (MODES_SCREEN + 6); // Use all motion mouse tracking
0042 constexpr auto MODE_Mouse1005 = (MODES_SCREEN + 7); // Xterm-style extended coordinates
0043 constexpr auto MODE_Mouse1006 = (MODES_SCREEN + 8); // 2nd Xterm-style extended coordinates
0044 constexpr auto MODE_Mouse1015 = (MODES_SCREEN + 9); // Urxvt-style extended coordinates
0045 constexpr auto MODE_Ansi = (MODES_SCREEN + 10); // Use US Ascii for character sets G0-G3 (DECANM)
0046 constexpr auto MODE_132Columns = (MODES_SCREEN + 11); // 80 <-> 132 column mode switch (DECCOLM)
0047 constexpr auto MODE_Allow132Columns = (MODES_SCREEN + 12); // Allow DECCOLM mode
0048 constexpr auto MODE_BracketedPaste = (MODES_SCREEN + 13); // Xterm-style bracketed paste mode
0049 constexpr auto MODE_total = (MODES_SCREEN + 14);
0050 
0051 namespace Konsole
0052 {
0053 
0054 struct CharCodes {
0055     // coding info
0056     char charset[4]; //
0057     int cu_cs; // actual charset.
0058     bool graphic; // Some VT100 tricks
0059     bool pound; // Some VT100 tricks
0060     bool sa_graphic; // saved graphic
0061     bool sa_pound; // saved pound
0062 };
0063 
0064 /**
0065  * Provides an xterm compatible terminal emulation based on the DEC VT102 terminal.
0066  * A full description of this terminal can be found at http://vt100.net/docs/vt102-ug/
0067  *
0068  * In addition, various additional xterm escape sequences are supported to provide
0069  * features such as mouse input handling.
0070  * See http://rtfm.etla.org/xterm/ctlseq.html for a description of xterm's escape
0071  * sequences.
0072  *
0073  */
0074 class Vt102Emulation : public Emulation
0075 {
0076     Q_OBJECT
0077 
0078 public:
0079     /** Constructs a new emulation */
0080     Vt102Emulation();
0081     ~Vt102Emulation() override;
0082 
0083     // reimplemented from Emulation
0084     void clearEntireScreen() override;
0085     void reset() override;
0086     char eraseChar() const override;
0087 
0088 public Q_SLOTS:
0089     // reimplemented from Emulation
0090     void sendString(const char *, int length = -1) override;
0091     void sendText(const QString &text) override;
0092     void sendKeyEvent(QKeyEvent *, bool fromPaste) override;
0093     void sendMouseEvent(int buttons, int column, int line, int eventType) override;
0094     virtual void focusLost();
0095     virtual void focusGained();
0096 
0097 protected:
0098     // reimplemented from Emulation
0099     void setMode(int mode) override;
0100     void resetMode(int mode) override;
0101     void receiveChar(QChar cc) override;
0102 
0103 private Q_SLOTS:
0104     // causes changeTitle() to be emitted for each (int,QString) pair in pendingTitleUpdates
0105     // used to buffer multiple title updates
0106     void updateTitle();
0107 
0108 private:
0109     wchar_t applyCharset(char16_t c);
0110     void setCharset(int n, int cs);
0111     void useCharset(int n);
0112     void setAndUseCharset(int n, int cs);
0113     void saveCursor();
0114     void restoreCursor();
0115     void resetCharset(int scrno);
0116     QKeyEvent *remapKeyModifiersForMac(QKeyEvent *event);
0117 
0118     void setMargins(int top, int bottom);
0119     // set margins for all screens back to their defaults
0120     void setDefaultMargins();
0121 
0122     // returns true if 'mode' is set or false otherwise
0123     bool getMode(int mode);
0124     // saves the current boolean value of 'mode'
0125     void saveMode(int mode);
0126     // restores the boolean value of 'mode'
0127     void restoreMode(int mode);
0128     // resets all modes
0129     // (except MODE_Allow132Columns)
0130     void resetModes();
0131 
0132     void resetTokenizer();
0133 #define MAX_TOKEN_LENGTH 256 // Max length of tokens (e.g. window title)
0134     void addToCurrentToken(char16_t cc);
0135     char16_t tokenBuffer[MAX_TOKEN_LENGTH]; // FIXME: overflow?
0136     int tokenBufferPos;
0137 #define MAXARGS 15
0138     void addDigit(int dig);
0139     void addArgument();
0140     int argv[MAXARGS];
0141     int argc;
0142     void initTokenizer();
0143     int prevCC;
0144 
0145     // Set of flags for each of the ASCII characters which indicates
0146     // what category they fall into (printable character, control, digit etc.)
0147     // for the purposes of decoding terminal output
0148     int charClass[256];
0149 
0150     void reportDecodingError();
0151 
0152     void processToken(int code, char16_t p, int q);
0153     void processWindowAttributeChange();
0154     void requestWindowAttribute(int);
0155 
0156     void reportTerminalType();
0157     void reportSecondaryAttributes();
0158     void reportStatus();
0159     void reportAnswerBack();
0160     void reportCursorPosition();
0161     void reportTerminalParms(int p);
0162 
0163     void onScrollLock();
0164     void scrollLock(const bool lock);
0165 
0166     // clears the screen and resizes it to the specified
0167     // number of columns
0168     void clearScreenAndSetColumns(int columnCount);
0169 
0170     CharCodes _charset[2];
0171 
0172     class TerminalState
0173     {
0174     public:
0175         // Initializes all modes to false
0176         TerminalState()
0177         {
0178             memset(&mode, false, MODE_total * sizeof(bool));
0179         }
0180 
0181         bool mode[MODE_total];
0182     };
0183 
0184     TerminalState _currentModes;
0185     TerminalState _savedModes;
0186 
0187     // hash table and timer for buffering calls to the session instance
0188     // to update the name of the session
0189     // or window title.
0190     // these calls occur when certain escape sequences are seen in the
0191     // output from the terminal
0192     QHash<int, QString> _pendingTitleUpdates;
0193     QTimer *_titleUpdateTimer;
0194 
0195     bool _reportFocusEvents;
0196 };
0197 
0198 }
0199 
0200 #endif // VT102EMULATION_H