MauiKit Terminal

Emulation.h
1/*
2 This file is part of Konsole, an X terminal.
3
4 SPDX-FileCopyrightText: 2007-2008 Robert Knight <robertknight@gmail.com>
5 SPDX-FileCopyrightText: 1997, 1998 Lars Doelle <lars.doelle@on-line.de>
6
7 SPDX-License-Identifier: GPL-2.0-or-later
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301 USA.
18*/
19
20#ifndef EMULATION_H
21#define EMULATION_H
22
23// System
24#include <cstdio>
25
26// Qt
27#include <QKeyEvent>
28// #include <QPointer>
29#include <QTextCodec>
30#include <QTextStream>
31#include <QTimer>
32
33// std
34#include <memory>
35
36#include "KeyboardTranslator.h"
37
38namespace Konsole
39{
40
41class HistoryType;
42class Screen;
43class ScreenWindow;
44class TerminalCharacterDecoder;
45
46/**
47 * This enum describes the available states which
48 * the terminal emulation may be set to.
49 *
50 * These are the values used by Emulation::stateChanged()
51 */
52enum {
53 /** The emulation is currently receiving user input. */
54 NOTIFYNORMAL = 0,
55 /**
56 * The terminal program has triggered a bell event
57 * to get the user's attention.
58 */
59 NOTIFYBELL = 1,
60 /**
61 * The emulation is currently receiving data from its
62 * terminal input.
63 */
64 NOTIFYACTIVITY = 2,
65
66 // unused here?
67 NOTIFYSILENCE = 3
68};
69
70/**
71 * Base class for terminal emulation back-ends.
72 *
73 * The back-end is responsible for decoding an incoming character stream and
74 * producing an output image of characters.
75 *
76 * When input from the terminal is received, the receiveData() slot should be called with
77 * the data which has arrived. The emulation will process the data and update the
78 * screen image accordingly. The codec used to decode the incoming character stream
79 * into the unicode characters used internally can be specified using setCodec()
80 *
81 * The size of the screen image can be specified by calling setImageSize() with the
82 * desired number of lines and columns. When new lines are added, old content
83 * is moved into a history store, which can be set by calling setHistory().
84 *
85 * The screen image can be accessed by creating a ScreenWindow onto this emulation
86 * by calling createWindow(). Screen windows provide access to a section of the
87 * output. Each screen window covers the same number of lines and columns as the
88 * image size returned by imageSize(). The screen window can be moved up and down
89 * and provides transparent access to both the current on-screen image and the
90 * previous output. The screen windows Q_EMIT an outputChanged signal
91 * when the section of the image they are looking at changes.
92 * Graphical views can then render the contents of a screen window, listening for notifications
93 * of output changes from the screen window which they are associated with and updating
94 * accordingly.
95 *
96 * The emulation also is also responsible for converting input from the connected views such
97 * as keypresses and mouse activity into a character string which can be sent
98 * to the terminal program. Key presses can be processed by calling the sendKeyEvent() slot,
99 * while mouse events can be processed using the sendMouseEvent() slot. When the character
100 * stream has been produced, the emulation will Q_EMIT a sendData() signal with a pointer
101 * to the character buffer. This data should be fed to the standard input of the terminal
102 * process. The translation of key presses into an output character stream is performed
103 * using a lookup in a set of key bindings which map key sequences to output
104 * character sequences. The name of the key bindings set used can be specified using
105 * setKeyBindings()
106 *
107 * The emulation maintains certain state information which changes depending on the
108 * input received. The emulation can be reset back to its starting state by calling
109 * reset().
110 *
111 * The emulation also maintains an activity state, which specifies whether
112 * terminal is currently active ( when data is received ), normal
113 * ( when the terminal is idle or receiving user input ) or trying
114 * to alert the user ( also known as a "Bell" event ). The stateSet() signal
115 * is emitted whenever the activity state is set. This can be used to determine
116 * how long the emulation has been active/idle for and also respond to
117 * a 'bell' event in different ways.
118 */
119class Emulation : public QObject
120{
122
123public:
124 /**
125 * This enum describes the available shapes for the keyboard cursor.
126 * See setKeyboardCursorShape()
127 */
129 /** A rectangular block which covers the entire area of the cursor character. */
130 BlockCursor = 0,
131 /**
132 * A single flat line which occupies the space at the bottom of the cursor
133 * character's area.
134 */
135 UnderlineCursor = 1,
136 /**
137 * An cursor shaped like the capital letter 'I', similar to the IBeam
138 * cursor used in Qt/KDE text editors.
139 */
140 IBeamCursor = 2
141 };
142
143 /** Constructs a new terminal emulation */
144 Emulation();
145 ~Emulation() override;
146
147 /**
148 * Creates a new window onto the output from this emulation. The contents
149 * of the window are then rendered by views which are set to use this window using the
150 * TerminalDisplay::setScreenWindow() method.
151 */
153
154 /** Returns the size of the screen image which the emulation produces */
155 QSize imageSize() const;
156
157 /**
158 * Returns the total number of lines, including those stored in the history.
159 */
160 int lineCount() const;
161
162 /**
163 * Sets the history store used by this emulation. When new lines
164 * are added to the output, older lines at the top of the screen are transferred to a history
165 * store.
166 *
167 * The number of lines which are kept and the storage location depend on the
168 * type of store.
169 */
170 void setHistory(const HistoryType &);
171 /** Returns the history store used by this emulation. See setHistory() */
172 const HistoryType &history() const;
173 /** Clears the history scroll. */
174 void clearHistory();
175
176 /**
177 * Copies the output history from @p startLine to @p endLine
178 * into @p stream, using @p decoder to convert the terminal
179 * characters into text.
180 *
181 * @param decoder A decoder which converts lines of terminal characters with
182 * appearance attributes into output text. PlainTextDecoder is the most commonly
183 * used decoder.
184 * @param startLine Index of first line to copy
185 * @param endLine Index of last line to copy
186 */
187 virtual void writeToStream(TerminalCharacterDecoder *decoder, int startLine, int endLine);
188
189 /**
190 * Copies the complete output history into @p stream, using @p decoder to convert
191 * the terminal characters into text.
192 *
193 * @param decoder A decoder which converts lines of terminal characters with
194 * appearance attributes into output text. PlainTextDecoder is the most commonly
195 * used decoder.
196 */
197 virtual void writeToStream(TerminalCharacterDecoder *decoder);
198
199 /** Returns the codec used to decode incoming characters. See setCodec() */
200 const QTextCodec *codec() const
201 {
202 return _codec;
203 }
204 /** Sets the codec used to decode incoming characters. */
205 void setCodec(const QTextCodec *);
206
207 /**
208 * Convenience method.
209 * Returns true if the current codec used to decode incoming
210 * characters is UTF-8
211 */
212 bool utf8() const
213 {
214 Q_ASSERT(_codec);
215 return _codec->mibEnum() == 106;
216 }
217
218 /** TODO Document me */
219 virtual char eraseChar() const;
220
221 /**
222 * Sets the key bindings used to key events
223 * ( received through sendKeyEvent() ) into character
224 * streams to send to the terminal.
225 */
226 void setKeyBindings(const QString &name);
227 /**
228 * Returns the name of the emulation's current key bindings.
229 * See setKeyBindings()
230 */
231 QString keyBindings() const;
232
233 /**
234 * Copies the current image into the history and clears the screen.
235 */
236 virtual void clearEntireScreen() = 0;
237
238 /** Resets the state of the terminal. */
239 virtual void reset() = 0;
240
241 /**
242 * Returns true if the active terminal program wants
243 * mouse input events.
244 *
245 * The programUsesMouseChanged() signal is emitted when this
246 * changes.
247 */
248 bool programUsesMouse() const;
249
250 bool programBracketedPasteMode() const;
251
252public Q_SLOTS:
253
254 /** Change the size of the emulation's image */
255 virtual void setImageSize(int lines, int columns);
256
257 /**
258 * Interprets a sequence of characters and sends the result to the terminal.
259 * This is equivalent to calling sendKeyEvent() for each character in @p text in succession.
260 */
261 virtual void sendText(const QString &text) = 0;
262
263 /**
264 * Interprets a key press event and emits the sendData() signal with
265 * the resulting character stream.
266 */
267 virtual void sendKeyEvent(QKeyEvent *, bool fromPaste);
268
269 /**
270 * Converts information about a mouse event into an xterm-compatible escape
271 * sequence and emits the character sequence via sendData()
272 */
273 virtual void sendMouseEvent(int buttons, int column, int line, int eventType);
274
275 /**
276 * Sends a string of characters to the foreground terminal process.
277 *
278 * @param string The characters to send.
279 * @param length Length of @p string or if set to a negative value, @p string will
280 * be treated as a null-terminated string and its length will be determined automatically.
281 */
282 virtual void sendString(const char *string, int length = -1) = 0;
283
284 /**
285 * Processes an incoming stream of characters. receiveData() decodes the incoming
286 * character buffer using the current codec(), and then calls receiveChar() for
287 * each unicode character in the resulting buffer.
288 *
289 * receiveData() also starts a timer which causes the outputChanged() signal
290 * to be emitted when it expires. The timer allows multiple updates in quick
291 * succession to be buffered into a single outputChanged() signal emission.
292 *
293 * @param buffer A string of characters received from the terminal program.
294 * @param len The length of @p buffer
295 */
296 void receiveData(const char *buffer, int len);
297
299
300 /**
301 * Emitted when a buffer of data is ready to send to the
302 * standard input of the terminal.
303 *
304 * @param data The buffer of data ready to be sent
305 * @param len The length of @p data in bytes
306 */
307 void sendData(const char *data, int len);
308
309 /**
310 * Requests that the pty used by the terminal process
311 * be set to UTF 8 mode.
312 *
313 * TODO: More documentation
314 */
315 void useUtf8Request(bool);
316
317 /**
318 * Emitted when the activity state of the emulation is set.
319 *
320 * @param state The new activity state, one of NOTIFYNORMAL, NOTIFYACTIVITY
321 * or NOTIFYBELL
322 */
323 void stateSet(int state);
324
325 /** TODO Document me */
327
328 /**
329 * Requests that the color of the text used
330 * to represent the tabs associated with this
331 * emulation be changed. This is a Konsole-specific
332 * extension from pre-KDE 4 times.
333 *
334 * TODO: Document how the parameter works.
335 */
337
338 /**
339 * This is emitted when the program running in the shell indicates whether or
340 * not it is interested in mouse events.
341 *
342 * @param usesMouse This will be true if the program wants to be informed about
343 * mouse events or false otherwise.
344 */
345 void programUsesMouseChanged(bool usesMouse);
346
347 void programBracketedPasteModeChanged(bool bracketedPasteMode);
348
349 /**
350 * Emitted when the contents of the screen image change.
351 * The emulation buffers the updates from successive image changes,
352 * and only emits outputChanged() at sensible intervals when
353 * there is a lot of terminal activity.
354 *
355 * Normally there is no need for objects other than the screen windows
356 * created with createWindow() to listen for this signal.
357 *
358 * ScreenWindow objects created using createWindow() will Q_EMIT their
359 * own outputChanged() signal in response to this signal.
360 */
362
363 /**
364 * Emitted when the program running in the terminal wishes to update the
365 * session's title. This also allows terminal programs to customize other
366 * aspects of the terminal emulation display.
367 *
368 * This signal is emitted when the escape sequence "\033]ARG;VALUE\007"
369 * is received in the input string, where ARG is a number specifying what
370 * should change and VALUE is a string specifying the new value.
371 *
372 * TODO: The name of this method is not very accurate since this method
373 * is used to perform a whole range of tasks besides just setting
374 * the user-title of the session.
375 *
376 * @param title Specifies what to change.
377 * <ul>
378 * <li>0 - Set window icon text and session title to @p newTitle</li>
379 * <li>1 - Set window icon text to @p newTitle</li>
380 * <li>2 - Set session title to @p newTitle</li>
381 * <li>11 - Set the session's default background color to @p newTitle,
382 * where @p newTitle can be an HTML-style string ("#RRGGBB") or a named
383 * color (eg 'red', 'blue').
384 * See http://doc.trolltech.com/4.2/qcolor.html#setNamedColor for more
385 * details.
386 * </li>
387 * <li>31 - Supposedly treats @p newTitle as a URL and opens it (NOT IMPLEMENTED)</li>
388 * <li>32 - Sets the icon associated with the session. @p newTitle is the name
389 * of the icon to use, which can be the name of any icon in the current KDE icon
390 * theme (eg: 'konsole', 'kate', 'folder_home')</li>
391 * </ul>
392 * @param newTitle Specifies the new title
393 */
394
395 void titleChanged(int title, const QString &newTitle);
396
397 /**
398 * Emitted when the program running in the terminal changes the
399 * screen size.
400 */
401 void imageSizeChanged(int lineCount, int columnCount);
402
403 /**
404 * Emitted when the setImageSize() is called on this emulation for
405 * the first time.
406 */
408
409 /**
410 * Emitted after receiving the escape sequence which asks to change
411 * the terminal emulator's size
412 */
413 void imageResizeRequest(const QSize &sizz);
414
415 /**
416 * Emitted when the terminal program requests to change various properties
417 * of the terminal display.
418 *
419 * A profile change command occurs when a special escape sequence, followed
420 * by a string containing a series of name and value pairs is received.
421 * This string can be parsed using a ProfileCommandParser instance.
422 *
423 * @param text A string expected to contain a series of key and value pairs in
424 * the form: name=value;name2=value2 ...
425 */
427
428 /**
429 * Emitted when a flow control key combination ( Ctrl+S or Ctrl+Q ) is pressed.
430 * @param suspendKeyPressed True if Ctrl+S was pressed to suspend output or Ctrl+Q to
431 * resume output.
432 */
433 void flowControlKeyPressed(bool suspendKeyPressed);
434
435 /**
436 * Emitted when the cursor shape or its blinking state is changed via
437 * DECSCUSR sequences.
438 *
439 * @param cursorShape One of 3 possible values in KeyboardCursorShape enum
440 * @param blinkingCursorEnabled Whether to enable blinking or not
441 */
442 void cursorChanged(KeyboardCursorShape cursorShape, bool blinkingCursorEnabled);
443
444 void handleCommandFromKeyboard(KeyboardTranslator::Command command);
445 void outputFromKeypressEvent(void);
446
447protected:
448 virtual void setMode(int mode) = 0;
449 virtual void resetMode(int mode) = 0;
450
451 /**
452 * Processes an incoming character. See receiveData()
453 * @p ch A unicode character code.
454 */
455 virtual void receiveChar(QChar ch);
456
457 /**
458 * Sets the active screen. The terminal has two screens, primary and alternate.
459 * The primary screen is used by default. When certain interactive programs such
460 * as Vim are run, they trigger a switch to the alternate screen.
461 *
462 * @param index 0 to switch to the primary screen, or 1 to switch to the alternate screen
463 */
464 void setScreen(int index);
465
466 enum EmulationCodec { LocaleCodec = 0, Utf8Codec = 1 };
467 void setCodec(EmulationCodec codec); // codec number, 0 = locale, 1=utf8
468
469 std::vector<std::unique_ptr<ScreenWindow>> _windows;
470
471 Screen *_currentScreen; // pointer to the screen which is currently active,
472 // this is one of the elements in the screen[] array
473
474 std::unique_ptr<Screen> _primaryScreen; // 0 = primary screen ( used by most programs, including the shell
475 // scrollbars are enabled in this mode )
476 std::unique_ptr<Screen> _alternateScreen; // 1 = alternate ( used by vi , emacs etc.
477 // scrollbars are not enabled in this mode )
478
479 // decodes an incoming C-style character stream into a unicode QString using
480 // the current text codec. (this allows for rendering of non-ASCII characters in text files etc.)
481 const QTextCodec *_codec;
482 std::unique_ptr<QTextDecoder> _decoder;
483 const KeyboardTranslator *_keyTranslator; // the keyboard layout
484
485protected Q_SLOTS:
486 /**
487 * Schedules an update of attached views.
488 * Repeated calls to bufferedUpdate() in close succession will result in only a single update,
489 * much like the Qt buffered update of widgets.
490 */
491 void bufferedUpdate();
492
493private Q_SLOTS:
494
495 // triggered by timer, causes the emulation to send an updated screen image to each
496 // view
497 void showBulk();
498
499 void usesMouseChanged(bool usesMouse);
500
501 void bracketedPasteModeChanged(bool bracketedPasteMode);
502
503private:
504 bool _usesMouse;
505 bool _bracketedPasteMode;
506 QTimer _bulkTimer1;
507 QTimer _bulkTimer2;
508};
509
510}
511
512#endif // ifndef EMULATION_H
Base class for terminal emulation back-ends.
Definition Emulation.h:120
virtual void sendMouseEvent(int buttons, int column, int line, int eventType)
Converts information about a mouse event into an xterm-compatible escape sequence and emits the chara...
void imageSizeChanged(int lineCount, int columnCount)
Emitted when the program running in the terminal changes the screen size.
bool programUsesMouse() const
Returns true if the active terminal program wants mouse input events.
Definition Emulation.cpp:78
void programUsesMouseChanged(bool usesMouse)
This is emitted when the program running in the shell indicates whether or not it is interested in mo...
void zmodemDetected()
TODO Document me.
virtual void sendText(const QString &text)=0
Interprets a sequence of characters and sends the result to the terminal.
void imageResizeRequest(const QSize &sizz)
Emitted after receiving the escape sequence which asks to change the terminal emulator's size.
void receiveData(const char *buffer, int len)
Processes an incoming stream of characters.
Emulation()
Constructs a new terminal emulation.
Definition Emulation.cpp:50
KeyboardCursorShape
This enum describes the available shapes for the keyboard cursor.
Definition Emulation.h:128
@ UnderlineCursor
A single flat line which occupies the space at the bottom of the cursor character's area.
@ BlockCursor
A rectangular block which covers the entire area of the cursor character.
@ IBeamCursor
An cursor shaped like the capital letter 'I', similar to the IBeam cursor used in Qt/KDE text editors...
void bufferedUpdate()
Schedules an update of attached views.
void profileChangeCommandReceived(const QString &text)
Emitted when the terminal program requests to change various properties of the terminal display.
void changeTabTextColorRequest(int color)
Requests that the color of the text used to represent the tabs associated with this emulation be chan...
void stateSet(int state)
Emitted when the activity state of the emulation is set.
virtual void clearEntireScreen()=0
Copies the current image into the history and clears the screen.
ScreenWindow * createWindow()
Creates a new window onto the output from this emulation.
Definition Emulation.cpp:98
int lineCount() const
Returns the total number of lines, including those stored in the history.
const HistoryType & history() const
Returns the history store used by this emulation.
virtual char eraseChar() const
TODO Document me.
void outputChanged()
Emitted when the contents of the screen image change.
void flowControlKeyPressed(bool suspendKeyPressed)
Emitted when a flow control key combination ( Ctrl+S or Ctrl+Q ) is pressed.
const QTextCodec * codec() const
Returns the codec used to decode incoming characters.
Definition Emulation.h:200
QSize imageSize() const
Returns the size of the screen image which the emulation produces.
virtual void setImageSize(int lines, int columns)
Change the size of the emulation's image.
virtual void reset()=0
Resets the state of the terminal.
void setScreen(int index)
Sets the active screen.
void titleChanged(int title, const QString &newTitle)
Emitted when the program running in the terminal wishes to update the session's title.
virtual void sendKeyEvent(QKeyEvent *, bool fromPaste)
Interprets a key press event and emits the sendData() signal with the resulting character stream.
void clearHistory()
Clears the history scroll.
bool utf8() const
Convenience method.
Definition Emulation.h:212
void setKeyBindings(const QString &name)
Sets the key bindings used to key events ( received through sendKeyEvent() ) into character streams t...
void setHistory(const HistoryType &)
Sets the history store used by this emulation.
QString keyBindings() const
Returns the name of the emulation's current key bindings.
void cursorChanged(KeyboardCursorShape cursorShape, bool blinkingCursorEnabled)
Emitted when the cursor shape or its blinking state is changed via DECSCUSR sequences.
virtual void writeToStream(TerminalCharacterDecoder *decoder, int startLine, int endLine)
Copies the output history from startLine to endLine into stream, using decoder to convert the termina...
void imageSizeInitialized()
Emitted when the setImageSize() is called on this emulation for the first time.
void sendData(const char *data, int len)
Emitted when a buffer of data is ready to send to the standard input of the terminal.
void useUtf8Request(bool)
Requests that the pty used by the terminal process be set to UTF 8 mode.
void setCodec(const QTextCodec *)
Sets the codec used to decode incoming characters.
virtual void sendString(const char *string, int length=-1)=0
Sends a string of characters to the foreground terminal process.
virtual void receiveChar(QChar ch)
Processes an incoming character.
A convertor which maps between key sequences pressed by the user and the character strings which shou...
Command
This enum describes commands which are associated with particular key sequences.
Provides a window onto a section of a terminal screen.
An image of characters with associated attributes.
Definition Screen.h:70
Base class for terminal character decoders.
Q_OBJECTQ_OBJECT
Q_SIGNALSQ_SIGNALS
Q_SLOTSQ_SLOTS
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Nov 29 2024 11:55:13 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.