File indexing completed on 2025-03-16 08:11:27
0001 /* 0002 This file is part of Konsole, KDE's 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 SCREEN_H 0021 #define SCREEN_H 0022 0023 // Qt 0024 #include <QRect> 0025 #include <QTextStream> 0026 #include <QVarLengthArray> 0027 #include <memory> 0028 0029 // Konsole 0030 #include "Character.h" 0031 #include "History.h" 0032 0033 #define MODE_Origin 0 0034 #define MODE_Wrap 1 0035 #define MODE_Insert 2 0036 #define MODE_Screen 3 0037 #define MODE_Cursor 4 0038 #define MODE_NewLine 5 0039 #define MODES_SCREEN 6 0040 0041 namespace Konsole 0042 { 0043 0044 class TerminalCharacterDecoder; 0045 0046 /** 0047 \brief An image of characters with associated attributes. 0048 0049 The terminal emulation ( Emulation ) receives a serial stream of 0050 characters from the program currently running in the terminal. 0051 From this stream it creates an image of characters which is ultimately 0052 rendered by the display widget ( TerminalDisplay ). Some types of emulation 0053 may have more than one screen image. 0054 0055 getImage() is used to retrieve the currently visible image 0056 which is then used by the display widget to draw the output from the 0057 terminal. 0058 0059 The number of lines of output history which are kept in addition to the current 0060 screen image depends on the history scroll being used to store the output. 0061 The scroll is specified using setScroll() 0062 The output history can be retrieved using writeToStream() 0063 0064 The screen image has a selection associated with it, specified using 0065 setSelectionStart() and setSelectionEnd(). The selected text can be retrieved 0066 using selectedText(). When getImage() is used to retrieve the visible image, 0067 characters which are part of the selection have their colours inverted. 0068 */ 0069 class Screen 0070 { 0071 public: 0072 /** Construct a new screen image of size @p lines by @p columns. */ 0073 Screen(int lines, int columns); 0074 ~Screen(); 0075 0076 // VT100/2 Operations 0077 // Cursor Movement 0078 0079 /** 0080 * Move the cursor up by @p n lines. The cursor will stop at the 0081 * top margin. 0082 */ 0083 void cursorUp(int n); 0084 /** 0085 * Move the cursor down by @p n lines. The cursor will stop at the 0086 * bottom margin. 0087 */ 0088 void cursorDown(int n); 0089 /** 0090 * Move the cursor to the left by @p n columns. 0091 * The cursor will stop at the first column. 0092 */ 0093 void cursorLeft(int n); 0094 /** 0095 * Move the cursor to the right by @p n columns. 0096 * The cursor will stop at the right-most column. 0097 */ 0098 void cursorRight(int n); 0099 /** Position the cursor on line @p y. */ 0100 void setCursorY(int y); 0101 /** Position the cursor at column @p x. */ 0102 void setCursorX(int x); 0103 /** Position the cursor at line @p y, column @p x. */ 0104 void setCursorYX(int y, int x); 0105 /** 0106 * Sets the margins for scrolling the screen. 0107 * 0108 * @param topLine The top line of the new scrolling margin. 0109 * @param bottomLine The bottom line of the new scrolling margin. 0110 */ 0111 void setMargins(int topLine, int bottomLine); 0112 /** Returns the top line of the scrolling region. */ 0113 int topMargin() const; 0114 /** Returns the bottom line of the scrolling region. */ 0115 int bottomMargin() const; 0116 0117 /** 0118 * Resets the scrolling margins back to the top and bottom lines 0119 * of the screen. 0120 */ 0121 void setDefaultMargins(); 0122 0123 /** 0124 * Moves the cursor down one line, if the MODE_NewLine mode 0125 * flag is enabled then the cursor is returned to the leftmost 0126 * column first. 0127 * 0128 * Equivalent to NextLine() if the MODE_NewLine flag is set 0129 * or index() otherwise. 0130 */ 0131 void newLine(); 0132 /** 0133 * Moves the cursor down one line and positions it at the beginning 0134 * of the line. Equivalent to calling Return() followed by index() 0135 */ 0136 void nextLine(); 0137 0138 /** 0139 * Move the cursor down one line. If the cursor is on the bottom 0140 * line of the scrolling region (as returned by bottomMargin()) the 0141 * scrolling region is scrolled up by one line instead. 0142 */ 0143 void index(); 0144 /** 0145 * Move the cursor up one line. If the cursor is on the top line 0146 * of the scrolling region (as returned by topMargin()) the scrolling 0147 * region is scrolled down by one line instead. 0148 */ 0149 void reverseIndex(); 0150 0151 /** 0152 * Scroll the scrolling region of the screen up by @p n lines. 0153 * The scrolling region is initially the whole screen, but can be changed 0154 * using setMargins() 0155 */ 0156 void scrollUp(int n); 0157 /** 0158 * Scroll the scrolling region of the screen down by @p n lines. 0159 * The scrolling region is initially the whole screen, but can be changed 0160 * using setMargins() 0161 */ 0162 void scrollDown(int n); 0163 /** 0164 * Moves the cursor to the beginning of the current line. 0165 * Equivalent to setCursorX(0) 0166 */ 0167 void toStartOfLine(); 0168 /** 0169 * Moves the cursor one column to the left and erases the character 0170 * at the new cursor position. 0171 */ 0172 void backspace(); 0173 /** Moves the cursor @p n tab-stops to the right. */ 0174 void tab(int n = 1); 0175 /** Moves the cursor @p n tab-stops to the left. */ 0176 void backtab(int n); 0177 0178 // Editing 0179 0180 /** 0181 * Erase @p n characters beginning from the current cursor position. 0182 * This is equivalent to over-writing @p n characters starting with the current 0183 * cursor position with spaces. 0184 * If @p n is 0 then one character is erased. 0185 */ 0186 void eraseChars(int n); 0187 /** 0188 * Delete @p n characters beginning from the current cursor position. 0189 * If @p n is 0 then one character is deleted. 0190 */ 0191 void deleteChars(int n); 0192 /** 0193 * Insert @p n blank characters beginning from the current cursor position. 0194 * The position of the cursor is not altered. 0195 * If @p n is 0 then one character is inserted. 0196 */ 0197 void insertChars(int n); 0198 /** 0199 * Repeat the preceeding graphic character @count times, including SPACE. 0200 * If @count is 0 then the character is repeated once. 0201 */ 0202 void repeatChars(int count); 0203 /** 0204 * Removes @p n lines beginning from the current cursor position. 0205 * The position of the cursor is not altered. 0206 * If @p n is 0 then one line is removed. 0207 */ 0208 void deleteLines(int n); 0209 /** 0210 * Inserts @p lines beginning from the current cursor position. 0211 * The position of the cursor is not altered. 0212 * If @p n is 0 then one line is inserted. 0213 */ 0214 void insertLines(int n); 0215 /** Clears all the tab stops. */ 0216 void clearTabStops(); 0217 /** Sets or removes a tab stop at the cursor's current column. */ 0218 void changeTabStop(bool set); 0219 0220 /** Resets (clears) the specified screen @p mode. */ 0221 void resetMode(int mode); 0222 /** Sets (enables) the specified screen @p mode. */ 0223 void setMode(int mode); 0224 /** 0225 * Saves the state of the specified screen @p mode. It can be restored 0226 * using restoreMode() 0227 */ 0228 void saveMode(int mode); 0229 /** Restores the state of a screen @p mode saved by calling saveMode() */ 0230 void restoreMode(int mode); 0231 /** Returns whether the specified screen @p mode is enabled or not .*/ 0232 bool getMode(int mode) const; 0233 0234 /** 0235 * Saves the current position and appearance (text color and style) of the cursor. 0236 * It can be restored by calling restoreCursor() 0237 */ 0238 void saveCursor(); 0239 /** Restores the position and appearance of the cursor. See saveCursor() */ 0240 void restoreCursor(); 0241 0242 /** Clear the whole screen, moving the current screen contents into the history first. */ 0243 void clearEntireScreen(); 0244 /** 0245 * Clear the area of the screen from the current cursor position to the end of 0246 * the screen. 0247 */ 0248 void clearToEndOfScreen(); 0249 /** 0250 * Clear the area of the screen from the current cursor position to the start 0251 * of the screen. 0252 */ 0253 void clearToBeginOfScreen(); 0254 /** Clears the whole of the line on which the cursor is currently positioned. */ 0255 void clearEntireLine(); 0256 /** Clears from the current cursor position to the end of the line. */ 0257 void clearToEndOfLine(); 0258 /** Clears from the current cursor position to the beginning of the line. */ 0259 void clearToBeginOfLine(); 0260 0261 /** Fills the entire screen with the letter 'E' */ 0262 void helpAlign(); 0263 0264 /** 0265 * Enables the given @p rendition flag. Rendition flags control the appearance 0266 * of characters on the screen. 0267 * 0268 * @see Character::rendition 0269 */ 0270 void setRendition(int rendition); 0271 /** 0272 * Disables the given @p rendition flag. Rendition flags control the appearance 0273 * of characters on the screen. 0274 * 0275 * @see Character::rendition 0276 */ 0277 void resetRendition(int rendition); 0278 0279 /** 0280 * Sets the cursor's foreground color. 0281 * @param space The color space used by the @p color argument 0282 * @param color The new foreground color. The meaning of this depends on 0283 * the color @p space used. 0284 * 0285 * @see CharacterColor 0286 */ 0287 void setForeColor(int space, int color); 0288 /** 0289 * Sets the cursor's background color. 0290 * @param space The color space used by the @p color argumnet. 0291 * @param color The new background color. The meaning of this depends on 0292 * the color @p space used. 0293 * 0294 * @see CharacterColor 0295 */ 0296 void setBackColor(int space, int color); 0297 /** 0298 * Resets the cursor's color back to the default and sets the 0299 * character's rendition flags back to the default settings. 0300 */ 0301 void setDefaultRendition(); 0302 0303 /** Returns the column which the cursor is positioned at. */ 0304 int getCursorX() const; 0305 /** Returns the line which the cursor is positioned on. */ 0306 int getCursorY() const; 0307 0308 /** Clear the entire screen and move the cursor to the home position. 0309 * Equivalent to calling clearEntireScreen() followed by home(). 0310 */ 0311 void clear(); 0312 /** 0313 * Sets the position of the cursor to the 'home' position at the top-left 0314 * corner of the screen (0,0) 0315 */ 0316 void home(); 0317 /** 0318 * Resets the state of the screen. This resets the various screen modes 0319 * back to their default states. The cursor style and colors are reset 0320 * (as if setDefaultRendition() had been called) 0321 * 0322 * <ul> 0323 * <li>Line wrapping is enabled.</li> 0324 * <li>Origin mode is disabled.</li> 0325 * <li>Insert mode is disabled.</li> 0326 * <li>Cursor mode is enabled. TODO Document me</li> 0327 * <li>Screen mode is disabled. TODO Document me</li> 0328 * <li>New line mode is disabled. TODO Document me</li> 0329 * </ul> 0330 * 0331 * If @p clearScreen is true then the screen contents are erased entirely, 0332 * otherwise they are unaltered. 0333 */ 0334 void reset(bool clearScreen = true); 0335 0336 /** 0337 * Displays a new character at the current cursor position. 0338 * 0339 * If the cursor is currently positioned at the right-edge of the screen and 0340 * line wrapping is enabled then the character is added at the start of a new 0341 * line below the current one. 0342 * 0343 * If the MODE_Insert screen mode is currently enabled then the character 0344 * is inserted at the current cursor position, otherwise it will replace the 0345 * character already at the current cursor position. 0346 */ 0347 void displayCharacter(QChar c); 0348 0349 // Do composition with last shown character FIXME: Not implemented yet for KDE 4 0350 void compose(const QString &compose); 0351 0352 /** 0353 * Resizes the image to a new fixed size of @p new_lines by @p new_columns. 0354 * In the case that @p new_columns is smaller than the current number of columns, 0355 * existing lines are not truncated. This prevents characters from being lost 0356 * if the terminal display is resized smaller and then larger again. 0357 * 0358 * The top and bottom margins are reset to the top and bottom of the new 0359 * screen size. Tab stops are also reset and the current selection is 0360 * cleared. 0361 */ 0362 void resizeImage(int new_lines, int new_columns); 0363 0364 /** 0365 * Returns the current screen image. 0366 * The result is an array of Characters of size [getLines()][getColumns()] which 0367 * must be freed by the caller after use. 0368 * 0369 * @param dest Buffer to copy the characters into 0370 * @param size Size of @p dest in Characters 0371 * @param startLine Index of first line to copy 0372 * @param endLine Index of last line to copy 0373 */ 0374 void getImage(std::span<Character> dest, int size, int startLine, int endLine) const; 0375 0376 /** 0377 * Returns the additional attributes associated with lines in the image. 0378 * The most important attribute is LINE_WRAPPED which specifies that the 0379 * line is wrapped, 0380 * other attributes control the size of characters in the line. 0381 */ 0382 QVector<LineProperty> getLineProperties(int startLine, int endLine) const; 0383 0384 /** Return the number of lines. */ 0385 int getLines() const 0386 { 0387 return lines; 0388 } 0389 /** Return the number of columns. */ 0390 int getColumns() const 0391 { 0392 return columns; 0393 } 0394 /** Return the number of lines in the history buffer. */ 0395 int getHistLines() const; 0396 /** 0397 * Sets the type of storage used to keep lines in the history. 0398 * If @p copyPreviousScroll is true then the contents of the previous 0399 * history buffer are copied into the new scroll. 0400 */ 0401 void setScroll(const HistoryType &, bool copyPreviousScroll = true); 0402 /** Returns the type of storage used to keep lines in the history. */ 0403 const HistoryType &getScroll() const; 0404 /** 0405 * Returns true if this screen keeps lines that are scrolled off the screen 0406 * in a history buffer. 0407 */ 0408 bool hasScroll() const; 0409 0410 /** 0411 * Sets the start of the selection. 0412 * 0413 * @param column The column index of the first character in the selection. 0414 * @param line The line index of the first character in the selection. 0415 * @param blockSelectionMode True if the selection is in column mode. 0416 */ 0417 void setSelectionStart(const int column, const int line, const bool blockSelectionMode); 0418 0419 /** 0420 * Sets the end of the current selection. 0421 * 0422 * @param column The column index of the last character in the selection. 0423 * @param line The line index of the last character in the selection. 0424 */ 0425 void setSelectionEnd(const int column, const int line); 0426 0427 /** 0428 * Retrieves the start of the selection or the cursor position if there 0429 * is no selection. 0430 */ 0431 void getSelectionStart(int &column, int &line) const; 0432 0433 /** 0434 * Retrieves the end of the selection or the cursor position if there 0435 * is no selection. 0436 */ 0437 void getSelectionEnd(int &column, int &line) const; 0438 0439 /** Clears the current selection */ 0440 void clearSelection(); 0441 0442 /** 0443 * Returns true if the character at (@p column, @p line) is part of the 0444 * current selection. 0445 */ 0446 bool isSelected(const int column, const int line) const; 0447 0448 /** 0449 * Convenience method. Returns the currently selected text. 0450 * @param preserveLineBreaks Specifies whether new line characters should 0451 * be inserted into the returned text at the end of each terminal line. 0452 */ 0453 QString selectedText(bool preserveLineBreaks) const; 0454 0455 /** 0456 * Copies part of the output to a stream. 0457 * 0458 * @param decoder A decoder which converts terminal characters into text 0459 * @param fromLine The first line in the history to retrieve 0460 * @param toLine The last line in the history to retrieve 0461 */ 0462 void writeLinesToStream(TerminalCharacterDecoder *decoder, int fromLine, int toLine) const; 0463 0464 /** 0465 * Copies the selected characters, set using @see setSelBeginXY and @see setSelExtentXY 0466 * into a stream. 0467 * 0468 * @param decoder A decoder which converts terminal characters into text. 0469 * PlainTextDecoder is the most commonly used decoder which converts characters 0470 * into plain text with no formatting. 0471 * @param preserveLineBreaks Specifies whether new line characters should 0472 * be inserted into the returned text at the end of each terminal line. 0473 */ 0474 void writeSelectionToStream(TerminalCharacterDecoder *decoder, bool preserveLineBreaks = true) const; 0475 0476 /** 0477 * Checks if the text between from and to is inside the current 0478 * selection. If this is the case, the selection is cleared. The 0479 * from and to are coordinates in the current viewable window. 0480 * The loc(x,y) macro can be used to generate these values from a 0481 * column,line pair. 0482 * 0483 * @param from The start of the area to check. 0484 * @param to The end of the area to check 0485 */ 0486 void checkSelection(int from, int to); 0487 0488 /** 0489 * Sets or clears an attribute of the current line. 0490 * 0491 * @param property The attribute to set or clear 0492 * Possible properties are: 0493 * LINE_WRAPPED: Specifies that the line is wrapped. 0494 * LINE_DOUBLEWIDTH: Specifies that the characters in the current line 0495 * should be double the normal width. 0496 * LINE_DOUBLEHEIGHT:Specifies that the characters in the current line 0497 * should be double the normal height. 0498 * Double-height lines are formed of two lines containing the same characters, 0499 * with both having the LINE_DOUBLEHEIGHT attribute. 0500 * This allows other parts of the code to work on the 0501 * assumption that all lines are the same height. 0502 * 0503 * @param enable true to apply the attribute to the current line or false to remove it 0504 */ 0505 void setLineProperty(LineProperty property, bool enable); 0506 0507 /** 0508 * Returns the number of lines that the image has been scrolled up or down by, 0509 * since the last call to resetScrolledLines(). 0510 * 0511 * a positive return value indicates that the image has been scrolled up, 0512 * a negative return value indicates that the image has been scrolled down. 0513 */ 0514 int scrolledLines() const; 0515 0516 /** 0517 * Returns the region of the image which was last scrolled. 0518 * 0519 * This is the area of the image from the top margin to the 0520 * bottom margin when the last scroll occurred. 0521 */ 0522 QRect lastScrolledRegion() const; 0523 0524 /** 0525 * Resets the count of the number of lines that the image has been scrolled up or down by, 0526 * see scrolledLines() 0527 */ 0528 void resetScrolledLines(); 0529 0530 /** 0531 * Returns the number of lines of output which have been 0532 * dropped from the history since the last call 0533 * to resetDroppedLines() 0534 * 0535 * If the history is not unlimited then it will drop 0536 * the oldest lines of output if new lines are added when 0537 * it is full. 0538 */ 0539 int droppedLines() const; 0540 0541 /** 0542 * Resets the count of the number of lines dropped from 0543 * the history. 0544 */ 0545 void resetDroppedLines(); 0546 0547 /** 0548 * Fills the buffer @p dest with @p count instances of the default (ie. blank) 0549 * Character style. 0550 */ 0551 static void fillWithDefaultChar(std::span<Character> dest, int count); 0552 0553 private: 0554 Screen(const Screen &) = delete; 0555 Screen &operator=(const Screen &) = delete; 0556 0557 // copies a line of text from the screen or history into a stream using a 0558 // specified character decoder. Returns the number of lines actually copied, 0559 // which may be less than 'count' if (start+count) is more than the number of characters on 0560 // the line 0561 // 0562 // line - the line number to copy, from 0 (the earliest line in the history) up to 0563 // history->getLines() + lines - 1 0564 // start - the first column on the line to copy 0565 // count - the number of characters on the line to copy 0566 // decoder - a decoder which converts terminal characters (an Character array) into text 0567 // appendNewLine - if true a new line character (\n) is appended to the end of the line 0568 int copyLineToStream(int line, int start, int count, TerminalCharacterDecoder *decoder, bool appendNewLine, bool preserveLineBreaks) const; 0569 0570 // fills a section of the screen image with the character 'c' 0571 // the parameters are specified as offsets from the start of the screen image. 0572 // the loc(x,y) macro can be used to generate these values from a column,line pair. 0573 void clearImage(int loca, int loce, char c); 0574 0575 // move screen image between 'sourceBegin' and 'sourceEnd' to 'dest'. 0576 // the parameters are specified as offsets from the start of the screen image. 0577 // the loc(x,y) macro can be used to generate these values from a column,line pair. 0578 // 0579 // NOTE: moveImage() can only move whole lines 0580 void moveImage(int dest, int sourceBegin, int sourceEnd); 0581 // scroll up 'i' lines in current region, clearing the bottom 'i' lines 0582 void scrollUp(int from, int i); 0583 // scroll down 'i' lines in current region, clearing the top 'i' lines 0584 void scrollDown(int from, int i); 0585 0586 void addHistLine(); 0587 0588 void initTabStops(); 0589 0590 void updateEffectiveRendition(); 0591 void reverseRendition(Character &p) const; 0592 0593 bool isSelectionValid() const; 0594 // copies text from 'startIndex' to 'endIndex' to a stream 0595 // startIndex and endIndex are positions generated using the loc(x,y) macro 0596 void writeToStream(TerminalCharacterDecoder *decoder, int startIndex, int endIndex, bool preserveLineBreaks = true) const; 0597 // copies 'count' lines from the screen buffer into 'dest', 0598 // starting from 'startLine', where 0 is the first line in the screen buffer 0599 void copyFromScreen(std::span<Character> dest, int startLine, int count) const; 0600 // copies 'count' lines from the history buffer into 'dest', 0601 // starting from 'startLine', where 0 is the first line in the history 0602 void copyFromHistory(std::span<Character> dest, int startLine, int count) const; 0603 0604 // screen image ---------------- 0605 int lines; 0606 int columns; 0607 0608 typedef QVector<Character> ImageLine; // [0..columns] 0609 QVector<ImageLine> screenLines; // [lines] 0610 0611 int _scrolledLines; 0612 QRect _lastScrolledRegion; 0613 0614 int _droppedLines; 0615 0616 QVarLengthArray<LineProperty, 64> lineProperties; 0617 0618 // history buffer --------------- 0619 std::unique_ptr<HistoryScroll> history; 0620 0621 // cursor location 0622 int cuX; 0623 int cuY; 0624 0625 // cursor color and rendition info 0626 CharacterColor currentForeground; 0627 CharacterColor currentBackground; 0628 quint8 currentRendition; 0629 0630 // margins ---------------- 0631 int _topMargin; 0632 int _bottomMargin; 0633 0634 // states ---------------- 0635 bool currentModes[MODES_SCREEN]; 0636 bool savedModes[MODES_SCREEN]; 0637 0638 // ---------------------------- 0639 0640 QBitArray tabStops; 0641 0642 // selection ------------------- 0643 int selBegin; // The first location selected. 0644 int selTopLeft; // TopLeft Location. 0645 int selBottomRight; // Bottom Right Location. 0646 bool blockSelectionMode; // Column selection mode 0647 0648 // effective colors and rendition ------------ 0649 CharacterColor effectiveForeground; // These are derived from 0650 CharacterColor effectiveBackground; // the cu_* variables above 0651 quint8 effectiveRendition; // to speed up operation 0652 0653 class SavedState 0654 { 0655 public: 0656 constexpr SavedState() 0657 : cursorColumn(0) 0658 , cursorLine(0) 0659 , rendition(0) 0660 { 0661 } 0662 0663 int cursorColumn; 0664 int cursorLine; 0665 quint8 rendition; 0666 CharacterColor foreground; 0667 CharacterColor background; 0668 }; 0669 SavedState savedState; 0670 0671 // last position where we added a character 0672 int lastPos; 0673 0674 // used in REP (repeating char) 0675 QChar lastDrawnChar; 0676 0677 static Character defaultChar; 0678 }; 0679 0680 } 0681 0682 #endif // SCREEN_H