1/*
2 This file is part of Konsole, KDE's terminal.
3
4 Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
5 Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301 USA.
21*/
22
23#ifndef SCREEN_H
24#define SCREEN_H
25
26// Qt
27#include <QRect>
28#include <QTextStream>
29#include <QVarLengthArray>
30
31// Konsole
32#include "Character.h"
33#include "History.h"
34
35#define MODE_Origin 0
36#define MODE_Wrap 1
37#define MODE_Insert 2
38#define MODE_Screen 3
39#define MODE_Cursor 4
40#define MODE_NewLine 5
41#define MODES_SCREEN 6
42
43namespace Konsole
44{
45
46class TerminalCharacterDecoder;
47
48/**
49 \brief An image of characters with associated attributes.
50
51 The terminal emulation ( Emulation ) receives a serial stream of
52 characters from the program currently running in the terminal.
53 From this stream it creates an image of characters which is ultimately
54 rendered by the display widget ( TerminalDisplay ). Some types of emulation
55 may have more than one screen image.
56
57 getImage() is used to retrieve the currently visible image
58 which is then used by the display widget to draw the output from the
59 terminal.
60
61 The number of lines of output history which are kept in addition to the current
62 screen image depends on the history scroll being used to store the output.
63 The scroll is specified using setScroll()
64 The output history can be retrieved using writeToStream()
65
66 The screen image has a selection associated with it, specified using
67 setSelectionStart() and setSelectionEnd(). The selected text can be retrieved
68 using selectedText(). When getImage() is used to retrieve the visible image,
69 characters which are part of the selection have their colours inverted.
70*/
71class Screen
72{
73public:
74 /** Construct a new screen image of size @p lines by @p columns. */
75 Screen(int lines, int columns);
76 ~Screen();
77
78 // VT100/2 Operations
79 // Cursor Movement
80
81 /**
82 * Move the cursor up by @p n lines. The cursor will stop at the
83 * top margin.
84 */
85 void cursorUp(int n);
86 /**
87 * Move the cursor down by @p n lines. The cursor will stop at the
88 * bottom margin.
89 */
90 void cursorDown(int n);
91 /**
92 * Move the cursor to the left by @p n columns.
93 * The cursor will stop at the first column.
94 */
95 void cursorLeft(int n);
96 /**
97 * Move the cursor to the right by @p n columns.
98 * The cursor will stop at the right-most column.
99 */
100 void cursorRight(int n);
101 /** Position the cursor on line @p y. */
102 void setCursorY(int y);
103 /** Position the cursor at column @p x. */
104 void setCursorX(int x);
105 /** Position the cursor at line @p y, column @p x. */
106 void setCursorYX(int y, int x);
107 /**
108 * Sets the margins for scrolling the screen.
109 *
110 * @param topLine The top line of the new scrolling margin.
111 * @param bottomLine The bottom line of the new scrolling margin.
112 */
113 void setMargins(int topLine , int bottomLine);
114 /** Returns the top line of the scrolling region. */
115 int topMargin() const;
116 /** Returns the bottom line of the scrolling region. */
117 int bottomMargin() const;
118
119 /**
120 * Resets the scrolling margins back to the top and bottom lines
121 * of the screen.
122 */
123 void setDefaultMargins();
124
125 /**
126 * Moves the cursor down one line, if the MODE_NewLine mode
127 * flag is enabled then the cursor is returned to the leftmost
128 * column first.
129 *
130 * Equivalent to NextLine() if the MODE_NewLine flag is set
131 * or index() otherwise.
132 */
133 void newLine();
134 /**
135 * Moves the cursor down one line and positions it at the beginning
136 * of the line. Equivalent to calling Return() followed by index()
137 */
138 void nextLine();
139
140 /**
141 * Move the cursor down one line. If the cursor is on the bottom
142 * line of the scrolling region (as returned by bottomMargin()) the
143 * scrolling region is scrolled up by one line instead.
144 */
145 void index();
146 /**
147 * Move the cursor up one line. If the cursor is on the top line
148 * of the scrolling region (as returned by topMargin()) the scrolling
149 * region is scrolled down by one line instead.
150 */
151 void reverseIndex();
152
153 /**
154 * Scroll the scrolling region of the screen up by @p n lines.
155 * The scrolling region is initially the whole screen, but can be changed
156 * using setMargins()
157 */
158 void scrollUp(int n);
159 /**
160 * Scroll the scrolling region of the screen down by @p n lines.
161 * The scrolling region is initially the whole screen, but can be changed
162 * using setMargins()
163 */
164 void scrollDown(int n);
165 /**
166 * Moves the cursor to the beginning of the current line.
167 * Equivalent to setCursorX(0)
168 */
169 void toStartOfLine();
170 /**
171 * Moves the cursor one column to the left and erases the character
172 * at the new cursor position.
173 */
174 void backspace();
175 /** Moves the cursor @p n tab-stops to the right. */
176 void tab(int n = 1);
177 /** Moves the cursor @p n tab-stops to the left. */
178 void backtab(int n);
179
180 // Editing
181
182 /**
183 * Erase @p n characters beginning from the current cursor position.
184 * This is equivalent to over-writing @p n characters starting with the current
185 * cursor position with spaces.
186 * If @p n is 0 then one character is erased.
187 */
188 void eraseChars(int n);
189 /**
190 * Delete @p n characters beginning from the current cursor position.
191 * If @p n is 0 then one character is deleted.
192 */
193 void deleteChars(int n);
194 /**
195 * Insert @p n blank characters beginning from the current cursor position.
196 * The position of the cursor is not altered.
197 * If @p n is 0 then one character is inserted.
198 */
199 void insertChars(int n);
200 /**
201 * Repeat the preceeding graphic character @count times, including SPACE.
202 * If @count is 0 then the character is repeated once.
203 */
204 void repeatChars(int count);
205 /**
206 * Removes @p n lines beginning from the current cursor position.
207 * The position of the cursor is not altered.
208 * If @p n is 0 then one line is removed.
209 */
210 void deleteLines(int n);
211 /**
212 * Inserts @p lines beginning from the current cursor position.
213 * The position of the cursor is not altered.
214 * If @p n is 0 then one line is inserted.
215 */
216 void insertLines(int n);
217 /** Clears all the tab stops. */
218 void clearTabStops();
219 /** Sets or removes a tab stop at the cursor's current column. */
220 void changeTabStop(bool set);
221
222 /** Resets (clears) the specified screen @p mode. */
223 void resetMode(int mode);
224 /** Sets (enables) the specified screen @p mode. */
225 void setMode(int mode);
226 /**
227 * Saves the state of the specified screen @p mode. It can be restored
228 * using restoreMode()
229 */
230 void saveMode(int mode);
231 /** Restores the state of a screen @p mode saved by calling saveMode() */
232 void restoreMode(int mode);
233 /** Returns whether the specified screen @p mode is enabled or not .*/
234 bool getMode(int mode) const;
235
236 /**
237 * Saves the current position and appearance (text color and style) of the cursor.
238 * It can be restored by calling restoreCursor()
239 */
240 void saveCursor();
241 /** Restores the position and appearance of the cursor. See saveCursor() */
242 void restoreCursor();
243
244 /** Clear the whole screen, moving the current screen contents into the history first. */
245 void clearEntireScreen();
246 /**
247 * Clear the area of the screen from the current cursor position to the end of
248 * the screen.
249 */
250 void clearToEndOfScreen();
251 /**
252 * Clear the area of the screen from the current cursor position to the start
253 * of the screen.
254 */
255 void clearToBeginOfScreen();
256 /** Clears the whole of the line on which the cursor is currently positioned. */
257 void clearEntireLine();
258 /** Clears from the current cursor position to the end of the line. */
259 void clearToEndOfLine();
260 /** Clears from the current cursor position to the beginning of the line. */
261 void clearToBeginOfLine();
262
263 /** Fills the entire screen with the letter 'E' */
264 void helpAlign();
265
266 /**
267 * Enables the given @p rendition flag. Rendition flags control the appearance
268 * of characters on the screen.
269 *
270 * @see Character::rendition
271 */
272 void setRendition(int rendition);
273 /**
274 * Disables the given @p rendition flag. Rendition flags control the appearance
275 * of characters on the screen.
276 *
277 * @see Character::rendition
278 */
279 void resetRendition(int rendition);
280
281 /**
282 * Sets the cursor's foreground color.
283 * @param space The color space used by the @p color argument
284 * @param color The new foreground color. The meaning of this depends on
285 * the color @p space used.
286 *
287 * @see CharacterColor
288 */
289 void setForeColor(int space, int color);
290 /**
291 * Sets the cursor's background color.
292 * @param space The color space used by the @p color argumnet.
293 * @param color The new background color. The meaning of this depends on
294 * the color @p space used.
295 *
296 * @see CharacterColor
297 */
298 void setBackColor(int space, int color);
299 /**
300 * Resets the cursor's color back to the default and sets the
301 * character's rendition flags back to the default settings.
302 */
303 void setDefaultRendition();
304
305 /** Returns the column which the cursor is positioned at. */
306 int getCursorX() const;
307 /** Returns the line which the cursor is positioned on. */
308 int getCursorY() const;
309
310 /** Clear the entire screen and move the cursor to the home position.
311 * Equivalent to calling clearEntireScreen() followed by home().
312 */
313 void clear();
314 /**
315 * Sets the position of the cursor to the 'home' position at the top-left
316 * corner of the screen (0,0)
317 */
318 void home();
319 /**
320 * Resets the state of the screen. This resets the various screen modes
321 * back to their default states. The cursor style and colors are reset
322 * (as if setDefaultRendition() had been called)
323 *
324 * <ul>
325 * <li>Line wrapping is enabled.</li>
326 * <li>Origin mode is disabled.</li>
327 * <li>Insert mode is disabled.</li>
328 * <li>Cursor mode is enabled. TODO Document me</li>
329 * <li>Screen mode is disabled. TODO Document me</li>
330 * <li>New line mode is disabled. TODO Document me</li>
331 * </ul>
332 *
333 * If @p clearScreen is true then the screen contents are erased entirely,
334 * otherwise they are unaltered.
335 */
336 void reset(bool clearScreen = true);
337
338 /**
339 * Displays a new character at the current cursor position.
340 *
341 * If the cursor is currently positioned at the right-edge of the screen and
342 * line wrapping is enabled then the character is added at the start of a new
343 * line below the current one.
344 *
345 * If the MODE_Insert screen mode is currently enabled then the character
346 * is inserted at the current cursor position, otherwise it will replace the
347 * character already at the current cursor position.
348 */
349 void displayCharacter(wchar_t c);
350
351 // Do composition with last shown character FIXME: Not implemented yet for KDE 4
352 void compose(const QString& compose);
353
354 /**
355 * Resizes the image to a new fixed size of @p new_lines by @p new_columns.
356 * In the case that @p new_columns is smaller than the current number of columns,
357 * existing lines are not truncated. This prevents characters from being lost
358 * if the terminal display is resized smaller and then larger again.
359 *
360 * The top and bottom margins are reset to the top and bottom of the new
361 * screen size. Tab stops are also reset and the current selection is
362 * cleared.
363 */
364 void resizeImage(int new_lines, int new_columns);
365
366 /**
367 * Returns the current screen image.
368 * The result is an array of Characters of size [getLines()][getColumns()] which
369 * must be freed by the caller after use.
370 *
371 * @param dest Buffer to copy the characters into
372 * @param size Size of @p dest in Characters
373 * @param startLine Index of first line to copy
374 * @param endLine Index of last line to copy
375 */
376 void getImage( Character* dest , int size , int startLine , int endLine ) const;
377
378 /**
379 * Returns the additional attributes associated with lines in the image.
380 * The most important attribute is LINE_WRAPPED which specifies that the
381 * line is wrapped,
382 * other attributes control the size of characters in the line.
383 */
384 QVector<LineProperty> getLineProperties( int startLine , int endLine ) const;
385
386
387 /** Return the number of lines. */
388 int getLines() const
389 { return lines; }
390 /** Return the number of columns. */
391 int getColumns() const
392 { return columns; }
393 /** Return the number of lines in the history buffer. */
394 int getHistLines() const;
395 /**
396 * Sets the type of storage used to keep lines in the history.
397 * If @p copyPreviousScroll is true then the contents of the previous
398 * history buffer are copied into the new scroll.
399 */
400 void setScroll(const HistoryType& , bool copyPreviousScroll = true);
401 /** Returns the type of storage used to keep lines in the history. */
402 const HistoryType& getScroll() const;
403 /**
404 * Returns true if this screen keeps lines that are scrolled off the screen
405 * in a history buffer.
406 */
407 bool hasScroll() const;
408
409 /**
410 * Sets the start of the selection.
411 *
412 * @param column The column index of the first character in the selection.
413 * @param line The line index of the first character in the selection.
414 * @param blockSelectionMode True if the selection is in column mode.
415 */
416 void setSelectionStart(const int column, const int line, const bool blockSelectionMode);
417
418 /**
419 * Sets the end of the current selection.
420 *
421 * @param column The column index of the last character in the selection.
422 * @param line The line index of the last character in the selection.
423 */
424 void setSelectionEnd(const int column, const int line);
425
426 /**
427 * Retrieves the start of the selection or the cursor position if there
428 * is no selection.
429 */
430 void getSelectionStart(int& column , int& line) const;
431
432 /**
433 * Retrieves the end of the selection or the cursor position if there
434 * is no selection.
435 */
436 void getSelectionEnd(int& column , int& line) const;
437
438 /** Clears the current selection */
439 void clearSelection();
440
441 /**
442 * Returns true if the character at (@p column, @p line) is part of the
443 * current selection.
444 */
445 bool isSelected(const int column,const int line) const;
446
447 /**
448 * Convenience method. Returns the currently selected text.
449 * @param preserveLineBreaks Specifies whether new line characters should
450 * be inserted into the returned text at the end of each terminal line.
451 */
452 QString selectedText(bool preserveLineBreaks) const;
453
454 /**
455 * Copies part of the output to a stream.
456 *
457 * @param decoder A decoder which converts terminal characters into text
458 * @param fromLine The first line in the history to retrieve
459 * @param toLine The last line in the history to retrieve
460 */
461 void writeLinesToStream(TerminalCharacterDecoder* decoder, int fromLine, int toLine) const;
462
463 /**
464 * Copies the selected characters, set using @see setSelBeginXY and @see setSelExtentXY
465 * into a stream.
466 *
467 * @param decoder A decoder which converts terminal characters into text.
468 * PlainTextDecoder is the most commonly used decoder which converts characters
469 * into plain text with no formatting.
470 * @param preserveLineBreaks Specifies whether new line characters should
471 * be inserted into the returned text at the end of each terminal line.
472 */
473 void writeSelectionToStream(TerminalCharacterDecoder* decoder , bool
474 preserveLineBreaks = true) const;
475
476 /**
477 * Checks if the text between from and to is inside the current
478 * selection. If this is the case, the selection is cleared. The
479 * from and to are coordinates in the current viewable window.
480 * The loc(x,y) macro can be used to generate these values from a
481 * column,line pair.
482 *
483 * @param from The start of the area to check.
484 * @param to The end of the area to check
485 */
486 void checkSelection(int from, int to);
487
488 /**
489 * Sets or clears an attribute of the current line.
490 *
491 * @param property The attribute to set or clear
492 * Possible properties are:
493 * LINE_WRAPPED: Specifies that the line is wrapped.
494 * LINE_DOUBLEWIDTH: Specifies that the characters in the current line
495 * should be double the normal width.
496 * LINE_DOUBLEHEIGHT:Specifies that the characters in the current line
497 * should be double the normal height.
498 * Double-height lines are formed of two lines containing the same characters,
499 * with both having the LINE_DOUBLEHEIGHT attribute.
500 * This allows other parts of the code to work on the
501 * assumption that all lines are the same height.
502 *
503 * @param enable true to apply the attribute to the current line or false to remove it
504 */
505 void setLineProperty(LineProperty property , bool enable);
506
507 /**
508 * Returns the number of lines that the image has been scrolled up or down by,
509 * since the last call to resetScrolledLines().
510 *
511 * a positive return value indicates that the image has been scrolled up,
512 * a negative return value indicates that the image has been scrolled down.
513 */
514 int scrolledLines() const;
515
516 /**
517 * Returns the region of the image which was last scrolled.
518 *
519 * This is the area of the image from the top margin to the
520 * bottom margin when the last scroll occurred.
521 */
522 QRect lastScrolledRegion() const;
523
524 /**
525 * Resets the count of the number of lines that the image has been scrolled up or down by,
526 * see scrolledLines()
527 */
528 void resetScrolledLines();
529
530 /**
531 * Returns the number of lines of output which have been
532 * dropped from the history since the last call
533 * to resetDroppedLines()
534 *
535 * If the history is not unlimited then it will drop
536 * the oldest lines of output if new lines are added when
537 * it is full.
538 */
539 int droppedLines() const;
540
541 /**
542 * Resets the count of the number of lines dropped from
543 * the history.
544 */
545 void resetDroppedLines();
546
547 /**
548 * Fills the buffer @p dest with @p count instances of the default (ie. blank)
549 * Character style.
550 */
551 static void fillWithDefaultChar(Character* dest, int count);
552
553private:
554
555 //copies a line of text from the screen or history into a stream using a
556 //specified character decoder. Returns the number of lines actually copied,
557 //which may be less than 'count' if (start+count) is more than the number of characters on
558 //the line
559 //
560 //line - the line number to copy, from 0 (the earliest line in the history) up to
561 // history->getLines() + lines - 1
562 //start - the first column on the line to copy
563 //count - the number of characters on the line to copy
564 //decoder - a decoder which converts terminal characters (an Character array) into text
565 //appendNewLine - if true a new line character (\n) is appended to the end of the line
566 int copyLineToStream(int line,
567 int start,
568 int count,
569 TerminalCharacterDecoder* decoder,
570 bool appendNewLine,
571 bool preserveLineBreaks) const;
572
573 //fills a section of the screen image with the character 'c'
574 //the parameters are specified as offsets from the start of the screen image.
575 //the loc(x,y) macro can be used to generate these values from a column,line pair.
576 void clearImage(int loca, int loce, char c);
577
578 //move screen image between 'sourceBegin' and 'sourceEnd' to 'dest'.
579 //the parameters are specified as offsets from the start of the screen image.
580 //the loc(x,y) macro can be used to generate these values from a column,line pair.
581 //
582 //NOTE: moveImage() can only move whole lines
583 void moveImage(int dest, int sourceBegin, int sourceEnd);
584 // scroll up 'i' lines in current region, clearing the bottom 'i' lines
585 void scrollUp(int from, int i);
586 // scroll down 'i' lines in current region, clearing the top 'i' lines
587 void scrollDown(int from, int i);
588
589 void addHistLine();
590
591 void initTabStops();
592
593 void updateEffectiveRendition();
594 void reverseRendition(Character& p) const;
595
596 bool isSelectionValid() const;
597 // copies text from 'startIndex' to 'endIndex' to a stream
598 // startIndex and endIndex are positions generated using the loc(x,y) macro
599 void writeToStream(TerminalCharacterDecoder* decoder, int startIndex,
600 int endIndex, bool preserveLineBreaks = true) const;
601 // copies 'count' lines from the screen buffer into 'dest',
602 // starting from 'startLine', where 0 is the first line in the screen buffer
603 void copyFromScreen(Character* dest, int startLine, int count) const;
604 // copies 'count' lines from the history buffer into 'dest',
605 // starting from 'startLine', where 0 is the first line in the history
606 void copyFromHistory(Character* dest, int startLine, int count) const;
607
608
609 // screen image ----------------
610 int lines;
611 int columns;
612
613 typedef QVector<Character> ImageLine; // [0..columns]
614 ImageLine* screenLines; // [lines]
615
616 int _scrolledLines;
617 QRect _lastScrolledRegion;
618
619 int _droppedLines;
620
621 QVarLengthArray<LineProperty,64> lineProperties;
622
623 // history buffer ---------------
624 HistoryScroll* history;
625
626 // cursor location
627 int cuX;
628 int cuY;
629
630 // cursor color and rendition info
631 CharacterColor currentForeground;
632 CharacterColor currentBackground;
633 quint8 currentRendition;
634
635 // margins ----------------
636 int _topMargin;
637 int _bottomMargin;
638
639 // states ----------------
640 int currentModes[MODES_SCREEN];
641 int savedModes[MODES_SCREEN];
642
643 // ----------------------------
644
645 QBitArray tabStops;
646
647 // selection -------------------
648 int selBegin; // The first location selected.
649 int selTopLeft; // TopLeft Location.
650 int selBottomRight; // Bottom Right Location.
651 bool blockSelectionMode; // Column selection mode
652
653 // effective colors and rendition ------------
654 CharacterColor effectiveForeground; // These are derived from
655 CharacterColor effectiveBackground; // the cu_* variables above
656 quint8 effectiveRendition; // to speed up operation
657
658 class SavedState
659 {
660 public:
661 SavedState()
662 : cursorColumn(0),cursorLine(0),rendition(0) {}
663
664 int cursorColumn;
665 int cursorLine;
666 quint8 rendition;
667 CharacterColor foreground;
668 CharacterColor background;
669 };
670 SavedState savedState;
671
672 // last position where we added a character
673 int lastPos;
674
675 // used in REP (repeating char)
676 unsigned short lastDrawnChar;
677
678 static Character defaultChar;
679};
680
681}
682
683#endif // SCREEN_H
684