GNU Octave  3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Emulation.h
Go to the documentation of this file.
1 /*
2  This file is part of Konsole, an X terminal.
3 
4  Copyright (C) 2007, 2013 by Robert Knight <robertknight@gmail.com>
5  Copyright (C) 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
6 
7  Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
8 
9  This program is free software; you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation; either version 2 of the License, or
12  (at your option) any later version.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  02110-1301 USA.
23 */
24 
25 #ifndef EMULATION_H
26 #define EMULATION_H
27 
28 // System
29 #include <stdio.h>
30 
31 // Qt
32 #include <QKeyEvent>
33 
34 #include <QtCore/QTextCodec>
35 #include <QtCore/QTextStream>
36 #include <QtCore/QTimer>
37 
38 class KeyboardTranslator;
39 class HistoryType;
40 class Screen;
41 class ScreenWindow;
43 
44 /**
45  * This enum describes the available states which
46  * the terminal emulation may be set to.
47  *
48  * These are the values used by Emulation::stateChanged()
49  */
50 enum
51 {
52  /** The emulation is currently receiving user input. */
54  /**
55  * The terminal program has triggered a bell event
56  * to get the user's attention.
57  */
59  /**
60  * The emulation is currently receiving data from its
61  * terminal input.
62  */
64 
65  // unused here?
67 };
68 
69 /**
70  * Base class for terminal emulation back-ends.
71  *
72  * The back-end is responsible for decoding an incoming character stream and
73  * producing an output image of characters.
74  *
75  * When input from the terminal is received, the receiveData() slot should be called with
76  * the data which has arrived. The emulation will process the data and update the
77  * screen image accordingly. The codec used to decode the incoming character stream
78  * into the unicode characters used internally can be specified using setCodec()
79  *
80  * The size of the screen image can be specified by calling setImageSize() with the
81  * desired number of lines and columns. When new lines are added, old content
82  * is moved into a history store, which can be set by calling setHistory().
83  *
84  * The screen image can be accessed by creating a ScreenWindow onto this emulation
85  * by calling createWindow(). Screen windows provide access to a section of the
86  * output. Each screen window covers the same number of lines and columns as the
87  * image size returned by imageSize(). The screen window can be moved up and down
88  * and provides transparent access to both the current on-screen image and the
89  * previous output. The screen windows emit an outputChanged signal
90  * when the section of the image they are looking at changes.
91  * Graphical views can then render the contents of a screen window, listening for notifications
92  * of output changes from the screen window which they are associated with and updating
93  * accordingly.
94  *
95  * The emulation also is also responsible for converting input from the connected views such
96  * as keypresses and mouse activity into a character string which can be sent
97  * to the terminal program. Key presses can be processed by calling the sendKeyEvent() slot,
98  * while mouse events can be processed using the sendMouseEvent() slot. When the character
99  * stream has been produced, the emulation will emit a sendData() signal with a pointer
100  * to the character buffer. This data should be fed to the standard input of the terminal
101  * process. The translation of key presses into an output character stream is performed
102  * using a lookup in a set of key bindings which map key sequences to output
103  * character sequences. The name of the key bindings set used can be specified using
104  * setKeyBindings()
105  *
106  * The emulation maintains certain state information which changes depending on the
107  * input received. The emulation can be reset back to its starting state by calling
108  * reset().
109  *
110  * The emulation also maintains an activity state, which specifies whether
111  * terminal is currently active ( when data is received ), normal
112  * ( when the terminal is idle or receiving user input ) or trying
113  * to alert the user ( also known as a "Bell" event ). The stateSet() signal
114  * is emitted whenever the activity state is set. This can be used to determine
115  * how long the emulation has been active/idle for and also respond to
116  * a 'bell' event in different ways.
117  */
118 class Emulation : public QObject
119 {
120 Q_OBJECT
121 
122 public:
123 
124  /** Constructs a new terminal emulation */
125  Emulation();
126  ~Emulation();
127 
128  /**
129  * Creates a new window onto the output from this emulation. The contents
130  * of the window are then rendered by views which are set to use this window using the
131  * TerminalDisplay::setScreenWindow() method.
132  */
134 
135  /** Returns the size of the screen image which the emulation produces */
136  QSize imageSize();
137 
138  /**
139  * Returns the total number of lines, including those stored in the history.
140  */
141  int lineCount();
142 
143 
144  /**
145  * Sets the history store used by this emulation. When new lines
146  * are added to the output, older lines at the top of the screen are transferred to a history
147  * store.
148  *
149  * The number of lines which are kept and the storage location depend on the
150  * type of store.
151  */
152  void setHistory(const HistoryType&);
153  /** Returns the history store used by this emulation. See setHistory() */
154  const HistoryType& history();
155  /** Clears the history scroll. */
156  void clearHistory();
157 
158  /**
159  * Copies the output history from @p startLine to @p endLine
160  * into @p stream, using @p decoder to convert the terminal
161  * characters into text.
162  *
163  * @param decoder A decoder which converts lines of terminal characters with
164  * appearance attributes into output text. PlainTextDecoder is the most commonly
165  * used decoder.
166  * @param startLine The first
167  */
168  virtual void writeToStream(TerminalCharacterDecoder* decoder,int startLine,int endLine);
169 
170 
171  /** Returns the codec used to decode incoming characters. See setCodec() */
172  const QTextCodec* codec() { return _codec; }
173  /** Sets the codec used to decode incoming characters. */
174  void setCodec(const QTextCodec*);
175 
176  /**
177  * Convenience method.
178  * Returns true if the current codec used to decode incoming
179  * characters is UTF-8
180  */
181  bool utf8() { Q_ASSERT(_codec); return _codec->mibEnum() == 106; }
182 
183 
184  /** TODO Document me */
185  virtual char getErase() const;
186 
187  /**
188  * Sets the key bindings used to key events
189  * ( received through sendKeyEvent() ) into character
190  * streams to send to the terminal.
191  */
192  void setKeyBindings(const QString& name);
193  /**
194  * Returns the name of the emulation's current key bindings.
195  * See setKeyBindings()
196  */
197  QString keyBindings();
198 
199  /**
200  * Copies the current image into the history and clears the screen.
201  */
202  virtual void clearEntireScreen() =0;
203 
204  /** Resets the state of the terminal. */
205  virtual void reset() =0;
206 
207  /**
208  * Returns true if the active terminal program wants
209  * mouse input events.
210  *
211  * The programUsesMouseChanged() signal is emitted when this
212  * changes.
213  */
214  bool programUsesMouse() const;
215 
216 public slots:
217 
218  /** Change the size of the emulation's image */
219  virtual void setImageSize(int lines, int columns);
220 
221  /**
222  * Interprets a sequence of characters and sends the result to the terminal.
223  * This is equivalent to calling sendKeyEvent() for each character in @p text in succession.
224  */
225  virtual void sendText(const QString& text) = 0;
226 
227  /**
228  * Interprets a key press event and emits the sendData() signal with
229  * the resulting character stream.
230  */
231  virtual void sendKeyEvent(QKeyEvent*);
232 
233  /**
234  * Converts information about a mouse event into an xterm-compatible escape
235  * sequence and emits the character sequence via sendData()
236  */
237  virtual void sendMouseEvent(int buttons, int column, int line, int eventType);
238 
239  /**
240  * Sends a string of characters to the foreground terminal process.
241  *
242  * @param string The characters to send.
243  * @param length Length of @p string or if set to a negative value, @p string will
244  * be treated as a null-terminated string and its length will be determined automatically.
245  */
246  virtual void sendString(const char* string, int length = -1) = 0;
247 
248  /**
249  * Processes an incoming stream of characters. receiveData() decodes the incoming
250  * character buffer using the current codec(), and then calls receiveChar() for
251  * each unicode character in the resulting buffer.
252  *
253  * receiveData() also starts a timer which causes the outputChanged() signal
254  * to be emitted when it expires. The timer allows multiple updates in quick
255  * succession to be buffered into a single outputChanged() signal emission.
256  *
257  * @param buffer A string of characters received from the terminal program.
258  * @param len The length of @p buffer
259  */
260  void receiveData(const char* buffer,int len);
261 
262 signals:
263 
264  /**
265  * Emitted when a buffer of data is ready to send to the
266  * standard input of the terminal.
267  *
268  * @param data The buffer of data ready to be sent
269  * @paran len The length of @p data in bytes
270  */
271  void sendData(const char* data,int len);
272 
273  /**
274  * Requests that sending of input to the emulation
275  * from the terminal process be suspended or resumed.
276  *
277  * @param suspend If true, requests that sending of
278  * input from the terminal process' stdout be
279  * suspended. Otherwise requests that sending of
280  * input be resumed.
281  */
282  void lockPtyRequest(bool suspend);
283 
284  /**
285  * Requests that the pty used by the terminal process
286  * be set to UTF 8 mode.
287  *
288  * TODO: More documentation
289  */
290  void useUtf8Request(bool);
291 
292  /**
293  * Emitted when the activity state of the emulation is set.
294  *
295  * @param state The new activity state, one of NOTIFYNORMAL, NOTIFYACTIVITY
296  * or NOTIFYBELL
297  */
298  void stateSet(int state);
299 
300 
301  /**
302  * Requests that the color of the text used
303  * to represent the tabs associated with this
304  * emulation be changed. This is a Konsole-specific
305  * extension from pre-KDE 4 times.
306  *
307  * TODO: Document how the parameter works.
308  */
309  void changeTabTextColorRequest(int color);
310 
311  /**
312  * This is emitted when the program running in the shell indicates whether or
313  * not it is interested in mouse events.
314  *
315  * @param usesMouse This will be true if the program wants to be informed about
316  * mouse events or false otherwise.
317  */
318  void programUsesMouseChanged(bool usesMouse);
319 
320  /**
321  * Emitted when the contents of the screen image change.
322  * The emulation buffers the updates from successive image changes,
323  * and only emits outputChanged() at sensible intervals when
324  * there is a lot of terminal activity.
325  *
326  * Normally there is no need for objects other than the screen windows
327  * created with createWindow() to listen for this signal.
328  *
329  * ScreenWindow objects created using createWindow() will emit their
330  * own outputChanged() signal in response to this signal.
331  */
332  void outputChanged();
333 
334  /**
335  * Emitted when the program running in the terminal wishes to update the
336  * session's title. This also allows terminal programs to customize other
337  * aspects of the terminal emulation display.
338  *
339  * This signal is emitted when the escape sequence "\033]ARG;VALUE\007"
340  * is received in the input string, where ARG is a number specifying what
341  * should change and VALUE is a string specifying the new value.
342  *
343  * TODO: The name of this method is not very accurate since this method
344  * is used to perform a whole range of tasks besides just setting
345  * the user-title of the session.
346  *
347  * @param title Specifies what to change.
348  * <ul>
349  * <li>0 - Set window icon text and session title to @p newTitle</li>
350  * <li>1 - Set window icon text to @p newTitle</li>
351  * <li>2 - Set session title to @p newTitle</li>
352  * <li>11 - Set the session's default background color to @p newTitle,
353  * where @p newTitle can be an HTML-style string (#RRGGBB) or a named
354  * color (eg 'red', 'blue').
355  * See http://doc.trolltech.com/4.2/qcolor.html#setNamedColor for more
356  * details.
357  * </li>
358  * <li>31 - Supposedly treats @p newTitle as a URL and opens it (NOT IMPLEMENTED)</li>
359  * <li>32 - Sets the icon associated with the session. @p newTitle is the name
360  * of the icon to use, which can be the name of any icon in the current KDE icon
361  * theme (eg: 'konsole', 'kate', 'folder_home')</li>
362  * </ul>
363  * @param newTitle Specifies the new title
364  */
365 
366  void titleChanged(int title,const QString& newTitle);
367 
368  /**
369  * Emitted when the program running in the terminal changes the
370  * screen size.
371  */
372  void imageSizeChanged(int lineCount , int columnCount);
373 
374  /**
375  * Emitted when the terminal program requests to change various properties
376  * of the terminal display.
377  *
378  * A profile change command occurs when a special escape sequence, followed
379  * by a string containing a series of name and value pairs is received.
380  * This string can be parsed using a ProfileCommandParser instance.
381  *
382  * @param text A string expected to contain a series of key and value pairs in
383  * the form: name=value;name2=value2 ...
384  */
385  void profileChangeCommandReceived(const QString& text);
386 
387 protected:
388  virtual void setMode (int mode) = 0;
389  virtual void resetMode(int mode) = 0;
390 
391  /**
392  * Processes an incoming character. See receiveData()
393  * @p ch A unicode character code.
394  */
395  virtual void receiveChar(int ch);
396 
397  /**
398  * Sets the active screen. The terminal has two screens, primary and alternate.
399  * The primary screen is used by default. When certain interactive programs such
400  * as Vim are run, they trigger a switch to the alternate screen.
401  *
402  * @param index 0 to switch to the primary screen, or 1 to switch to the alternate screen
403  */
404  void setScreen(int index);
405 
407  {
410  };
411  void setCodec(EmulationCodec codec); // codec number, 0 = locale, 1=utf8
412 
413 
415 
416  Screen* _currentScreen; // pointer to the screen which is currently active,
417  // this is one of the elements in the screen[] array
418 
419  Screen* _screen[2]; // 0 = primary screen ( used by most programs, including the shell
420  // scrollbars are enabled in this mode )
421  // 1 = alternate ( used by vi , emacs etc.
422  // scrollbars are not enabled in this mode )
423 
424 
425  //decodes an incoming C-style character stream into a unicode QString using
426  //the current text codec. (this allows for rendering of non-ASCII characters in text files etc.)
427  const QTextCodec* _codec;
428  QTextDecoder* _decoder;
429 
430  const KeyboardTranslator* _keyTranslator; // the keyboard layout
431 
432 protected slots:
433  /**
434  * Schedules an update of attached views.
435  * Repeated calls to bufferedUpdate() in close succession will result in only a single update,
436  * much like the Qt buffered update of widgets.
437  */
438  void bufferedUpdate();
439 
440 private slots:
441 
442  // triggered by timer, causes the emulation to send an updated screen image to each
443  // view
444  void showBulk();
445 
446  void usesMouseChanged(bool usesMouse);
447 
448 private:
449 
451  QTimer _bulkTimer1;
452  QTimer _bulkTimer2;
453 
454 };
455 
456 #endif // ifndef EMULATION_H