GNU Octave 7.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
Emulation.cpp
Go to the documentation of this file.
1/*
2 This file is part of Konsole, an X terminal.
3
4 Copyright (C) 2007, 2013 Robert Knight <robertknight@gmail.com>
5 Copyright (C) 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
6 Copyright (C) 1996, 2013 by Matthias Ettrich <ettrich@kde.org>
7
8 Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
9
10 This program is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 02110-1301 USA.
24*/
25
26// Own
27#include "unix/Emulation.h"
28
29// System
30#include <assert.h>
31#include <stdio.h>
32#include <stdlib.h>
33#include <unistd.h>
34
35// Qt
36#include <QApplication>
37#include <QClipboard>
38#include <QtCore/QHash>
39#include <QKeyEvent>
40#include <QtCore/QRegExp>
41#include <QtCore/QTextStream>
42#include <QtCore/QThread>
43
44#include <QtCore/QTime>
45
46// Konsole
48#include "unix/Screen.h"
50#include "unix/ScreenWindow.h"
51
53 _currentScreen(nullptr),
54 _codec(nullptr),
55 _decoder(nullptr),
56 _keyTranslator(nullptr),
57 _usesMouse(false),
58 _bracketedPasteMode(false)
59{
60
61 // create screens with a default size
62 _screen[0] = new Screen(40,80);
63 _screen[1] = new Screen(40,80);
65
66 QObject::connect(&_bulkTimer1, SIGNAL(timeout()), this, SLOT(showBulk()) );
67 QObject::connect(&_bulkTimer2, SIGNAL(timeout()), this, SLOT(showBulk()) );
68
69 // listen for mouse status changes
70 connect( this , SIGNAL(programUsesMouseChanged(bool)) ,
71 SLOT(usesMouseChanged(bool)) );
72 connect(this , SIGNAL(programBracketedPasteModeChanged(bool)) ,
73 SLOT(bracketedPasteModeChanged(bool)));
74}
75
77{
78 return _usesMouse;
79}
80
81void Emulation::usesMouseChanged(bool usesMouse)
82{
83 _usesMouse = usesMouse;
84}
85
87{
89}
90
91void Emulation::bracketedPasteModeChanged(bool bracketedPasteMode)
92{
93 _bracketedPasteMode = bracketedPasteMode;
94}
95
97{
98 ScreenWindow* window = new ScreenWindow();
100 _windows << window;
101
102 connect(window , SIGNAL(selectionChanged()),
103 this , SLOT(bufferedUpdate()));
104
105 connect(this , SIGNAL(outputChanged()),
106 window , SLOT(notifyOutputChanged()) );
107 return window;
108}
109
110/*!
111*/
112
114{
115 QListIterator<ScreenWindow*> windowIter(_windows);
116
117 while (windowIter.hasNext())
118 {
119 delete windowIter.next();
120 }
121
122 delete _screen[0];
123 delete _screen[1];
124 delete _decoder;
125}
126
127/*! change between primary and alternate _screen
128*/
129
131{
132 Screen *old = _currentScreen;
133 _currentScreen = _screen[n&1];
134 if (_currentScreen != old)
135 {
136 old->setBusySelecting(false);
137
138 // tell all windows onto this emulation to switch to the newly active _screen
139 QListIterator<ScreenWindow*> windowIter(_windows);
140 while ( windowIter.hasNext() )
141 {
142 windowIter.next()->setScreen(_currentScreen);
143 }
144 }
145}
146
148{
149 _screen[0]->setScroll( _screen[0]->getScroll() , false );
150}
152{
153 _screen[0]->setScroll(t);
154
155 showBulk();
156}
157
159{
160 return _screen[0]->getScroll();
161}
162
163void Emulation::setCodec(const QTextCodec * qtc)
164{
165 Q_ASSERT( qtc );
166
167 _codec = qtc;
168 delete _decoder;
169 _decoder = _codec->makeDecoder();
170
171 emit useUtf8Request(utf8());
172}
173
175{
176 if ( codec == Utf8Codec )
177 setCodec( QTextCodec::codecForName("utf8") );
178 else if ( codec == LocaleCodec )
179 setCodec( QTextCodec::codecForLocale() );
180}
181
182void Emulation::setKeyBindings(const QString& name)
183{
185}
186
188{
189 return _keyTranslator->name();
190}
191
192
193// Interpreting Codes ---------------------------------------------------------
194
195/*
196 This section deals with decoding the incoming character stream.
197 Decoding means here, that the stream is first separated into `tokens'
198 which are then mapped to a `meaning' provided as operations by the
199 `Screen' class.
200*/
201
202/*!
203*/
204
206// process application unicode input to terminal
207// this is a trivial scanner
208{
209 c &= 0xff;
210 switch (c)
211 {
212 case '\b' : _currentScreen->BackSpace(); break;
213 case '\t' : _currentScreen->Tabulate(); break;
214 case '\n' : _currentScreen->NewLine(); break;
215 case '\r' : _currentScreen->Return(); break;
216 case 0x07 : emit stateSet(NOTIFYBELL);
217 break;
218 default : _currentScreen->ShowCharacter(c); break;
219 };
220}
221
222/* ------------------------------------------------------------------------- */
223/* */
224/* Keyboard Handling */
225/* */
226/* ------------------------------------------------------------------------- */
227
228/*!
229*/
230
231void Emulation::sendKeyEvent( QKeyEvent* ev )
232{
234
235 if (!ev->text().isEmpty())
236 { // A block of text
237 // Note that the text is proper unicode.
238 // We should do a conversion here, but since this
239 // routine will never be used, we simply emit plain ascii.
240 //emit sendBlock(ev->text().toAscii(),ev->text().length());
241 emit sendData(ev->text().toUtf8(),ev->text().length());
242 }
243}
244
245void Emulation::sendString(const char*,int)
246{
247 // default implementation does nothing
248}
249
250void Emulation::sendMouseEvent(int /*buttons*/, int /*column*/, int /*row*/, int /*eventType*/)
251{
252 // default implementation does nothing
253}
254
255// Unblocking, Byte to Unicode translation --------------------------------- --
256
257/*
258 We are doing code conversion from locale to unicode first.
259TODO: Character composition from the old code. See #96536
260*/
261
262void Emulation::receiveData(const char* text, int length)
263{
265
267
268 QString unicodeText = _decoder->toUnicode(text,length);
269
270 //send characters to terminal emulator
271 for (int i=0;i<unicodeText.length();i++)
272 {
273 receiveChar(unicodeText[i].unicode());
274 }
275}
276
277// Selection --------------------------------------------------------------- --
278
280 int startLine ,
281 int endLine)
282{
283 _currentScreen->writeToStream(_decoder,startLine,endLine);
284}
285
287{
288 // sum number of lines currently on _screen plus number of lines in history
290}
291
292// Refreshing -------------------------------------------------------------- --
293
294#define BULK_TIMEOUT1 10
295#define BULK_TIMEOUT2 40
296
297/*!
298*/
300{
301 _bulkTimer1.stop();
302 _bulkTimer2.stop();
303
304 emit outputChanged();
305
308}
309
311{
312 _bulkTimer1.setSingleShot(true);
314 if (!_bulkTimer2.isActive())
315 {
316 _bulkTimer2.setSingleShot(true);
318 }
319}
320
322{
323 return '\b';
324}
325
326void Emulation::setImageSize(int lines, int columns)
327{
328 //kDebug() << "Resizing image to: " << lines << "by" << columns << QTime::currentTime().msec();
329 Q_ASSERT( lines > 0 );
330 Q_ASSERT( columns > 0 );
331
332 _screen[0]->resizeImage(lines,columns);
333 _screen[1]->resizeImage(lines,columns);
334
335 emit imageSizeChanged(lines,columns);
336
338}
339
341{
343}
344
345ushort ExtendedCharTable::extendedCharHash(ushort* unicodePoints , ushort length) const
346{
347 ushort hash = 0;
348 for ( ushort i = 0 ; i < length ; i++ )
349 {
350 hash = 31*hash + unicodePoints[i];
351 }
352 return hash;
353}
354bool ExtendedCharTable::extendedCharMatch(ushort hash , ushort* unicodePoints , ushort length) const
355{
356 ushort* entry = extendedCharTable[hash];
357
358 // compare given length with stored sequence length ( given as the first ushort in the
359 // stored buffer )
360 if ( entry == nullptr || entry[0] != length )
361 return false;
362 // if the lengths match, each character must be checked. the stored buffer starts at
363 // entry[1]
364 for ( int i = 0 ; i < length ; i++ )
365 {
366 if ( entry[i+1] != unicodePoints[i] )
367 return false;
368 }
369 return true;
370}
371ushort ExtendedCharTable::createExtendedChar(ushort* unicodePoints , ushort length)
372{
373 // look for this sequence of points in the table
374 ushort hash = extendedCharHash(unicodePoints,length);
375
376 // check existing entry for match
377 while ( extendedCharTable.contains(hash) )
378 {
379 if ( extendedCharMatch(hash,unicodePoints,length) )
380 {
381 // this sequence already has an entry in the table,
382 // return its hash
383 return hash;
384 }
385 else
386 {
387 // if hash is already used by another, different sequence of unicode character
388 // points then try next hash
389 hash++;
390 }
391 }
392
393
394 // add the new sequence to the table and
395 // return that index
396 ushort* buffer = new ushort[length+1];
397 buffer[0] = length;
398 for ( int i = 0 ; i < length ; i++ )
399 buffer[i+1] = unicodePoints[i];
400
401 extendedCharTable.insert(hash,buffer);
402
403 return hash;
404}
405
406ushort* ExtendedCharTable::lookupExtendedChar(ushort hash , ushort& length) const
407{
408 // lookup index in table and if found, set the length
409 // argument and return a pointer to the character sequence
410
411 ushort* buffer = extendedCharTable[hash];
412 if ( buffer )
413 {
414 length = buffer[0];
415 return buffer+1;
416 }
417 else
418 {
419 length = 0;
420 return nullptr;
421 }
422}
423
425{
426}
428{
429 // free all allocated character buffers
430 QHashIterator<ushort,ushort*> iter(extendedCharTable);
431 while ( iter.hasNext() )
432 {
433 iter.next();
434 delete[] iter.value();
435 }
436}
437
438// global instance
#define BULK_TIMEOUT1
Definition: Emulation.cpp:294
#define BULK_TIMEOUT2
Definition: Emulation.cpp:295
@ NOTIFYBELL
The terminal program has triggered a bell event to get the user's attention.
Definition: Emulation.h:58
@ NOTIFYACTIVITY
The emulation is currently receiving data from its terminal input.
Definition: Emulation.h:63
@ NOTIFYNORMAL
The emulation is currently receiving user input.
Definition: Emulation.h:53
virtual void receiveChar(int ch)
Processes an incoming character.
Definition: Emulation.cpp:205
void usesMouseChanged(bool usesMouse)
Definition: Emulation.cpp:81
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...
Definition: Emulation.cpp:250
const QTextCodec * _codec
Definition: Emulation.h:431
Screen * _currentScreen
Definition: Emulation.h:420
bool programUsesMouse() const
Returns true if the active terminal program wants mouse input events.
Definition: Emulation.cpp:76
void bracketedPasteModeChanged(bool bracketedPasteMode)
Definition: Emulation.cpp:91
void showBulk()
Definition: Emulation.cpp:299
virtual void sendKeyEvent(QKeyEvent *)
Interprets a key press event and emits the sendData() signal with the resulting character stream.
Definition: Emulation.cpp:231
const QTextCodec * codec()
Returns the codec used to decode incoming characters.
Definition: Emulation.h:172
void receiveData(const char *buffer, int len)
Processes an incoming stream of characters.
Definition: Emulation.cpp:262
void programUsesMouseChanged(bool usesMouse)
This is emitted when the program running in the shell indicates whether or not it is interested in mo...
Emulation()
Constructs a new terminal emulation.
Definition: Emulation.cpp:52
void bufferedUpdate()
Schedules an update of attached views.
Definition: Emulation.cpp:310
int lineCount()
Returns the total number of lines, including those stored in the history.
Definition: Emulation.cpp:286
const KeyboardTranslator * _keyTranslator
Definition: Emulation.h:434
void programBracketedPasteModeChanged(bool bracketedPasteMode)
QString keyBindings()
Returns the name of the emulation's current key bindings.
Definition: Emulation.cpp:187
const HistoryType & history()
Returns the history store used by this emulation.
Definition: Emulation.cpp:158
void useUtf8Request(bool)
Requests that the pty used by the terminal process be set to UTF 8 mode.
ScreenWindow * createWindow()
Creates a new window onto the output from this emulation.
Definition: Emulation.cpp:96
QTimer _bulkTimer2
Definition: Emulation.h:459
QTextDecoder * _decoder
Definition: Emulation.h:432
bool _usesMouse
Definition: Emulation.h:456
QTimer _bulkTimer1
Definition: Emulation.h:458
@ LocaleCodec
Definition: Emulation.h:412
void imageSizeChanged(int lineCount, int columnCount)
Emitted when the program running in the terminal changes the screen size.
void sendData(const char *data, int len)
Emitted when a buffer of data is ready to send to the standard input of the terminal.
QSize imageSize()
Returns the size of the screen image which the emulation produces.
Definition: Emulation.cpp:340
virtual void setImageSize(int lines, int columns)
Change the size of the emulation's image.
Definition: Emulation.cpp:326
QList< ScreenWindow * > _windows
Definition: Emulation.h:418
bool programBracketedPasteMode() const
Definition: Emulation.cpp:86
bool _bracketedPasteMode
Definition: Emulation.h:457
void setScreen(int index)
Sets the active screen.
Definition: Emulation.cpp:130
Screen * _screen[2]
Definition: Emulation.h:423
void clearHistory()
Clears the history scroll.
Definition: Emulation.cpp:147
void setKeyBindings(const QString &name)
Sets the key bindings used to key events ( received through sendKeyEvent() ) into character streams t...
Definition: Emulation.cpp:182
void setHistory(const HistoryType &)
Sets the history store used by this emulation.
Definition: Emulation.cpp:151
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...
Definition: Emulation.cpp:279
void outputChanged()
Emitted when the contents of the screen image change.
void stateSet(int state)
Emitted when the activity state of the emulation is set.
virtual char getErase() const
TODO Document me.
Definition: Emulation.cpp:321
void setCodec(const QTextCodec *)
Sets the codec used to decode incoming characters.
Definition: Emulation.cpp:163
virtual void sendString(const char *string, int length=-1)=0
Sends a string of characters to the foreground terminal process.
Definition: Emulation.cpp:245
bool utf8()
Convenience method.
Definition: Emulation.h:181
A table which stores sequences of unicode characters, referenced by hash keys.
Definition: Character.h:160
ushort * lookupExtendedChar(ushort hash, ushort &length) const
Looks up and returns a pointer to a sequence of unicode characters which was added to the table using...
Definition: Emulation.cpp:406
static ExtendedCharTable instance
The global ExtendedCharTable instance.
Definition: Character.h:191
ushort extendedCharHash(ushort *unicodePoints, ushort length) const
Definition: Emulation.cpp:345
ushort createExtendedChar(ushort *unicodePoints, ushort length)
Adds a sequences of unicode characters to the table and returns a hash code which can be used later t...
Definition: Emulation.cpp:371
QHash< ushort, ushort * > extendedCharTable
Definition: Character.h:201
ExtendedCharTable()
Constructs a new character table.
Definition: Emulation.cpp:424
bool extendedCharMatch(ushort hash, ushort *unicodePoints, ushort length) const
Definition: Emulation.cpp:354
const KeyboardTranslator * findTranslator(const QString &name)
Returns the keyboard translator with the given name or 0 if no translator with that name exists.
static KeyboardTranslatorManager * instance()
Returns the global KeyboardTranslatorManager instance.
QString name() const
Returns the name of this keyboard translator.
Provides a window onto a section of a terminal screen.
Definition: ScreenWindow.h:52
void setScreen(Screen *screen)
Sets the screen which this window looks onto.
An image of characters with associated attributes.
Definition: Screen.h:76
void resizeImage(int new_lines, int new_columns)
Resizes the image to a new fixed size of new_lines by new_columns.
Definition: Screen.cpp:380
int getColumns()
Return the number of columns.
Definition: Screen.h:379
void setScroll(const HistoryType &, bool copyPreviousScroll=true)
Sets the type of storage used to keep lines in the history.
Definition: Screen.cpp:1527
void setBusySelecting(bool busy)
Definition: Screen.h:428
void writeToStream(TerminalCharacterDecoder *decoder, int from, int to)
Copies part of the output to a stream.
Definition: Screen.cpp:1444
void BackSpace()
Moves the cursor one column to the left and erases the character at the new cursor position.
Definition: Screen.cpp:667
void Return()
Moves the cursor to the beginning of the current line.
Definition: Screen.cpp:935
int getHistLines()
Return the number of lines in the history buffer.
Definition: Screen.cpp:1522
void NewLine()
Moves the cursor down one line, if the MODE_NewLine mode flag is enabled then the cursor is returned ...
Definition: Screen.cpp:729
void Tabulate(int n=1)
Moves the cursor n tab-stops to the right.
Definition: Screen.cpp:679
void resetScrolledLines()
Resets the count of the number of lines that the image has been scrolled up or down by,...
Definition: Screen.cpp:846
void resetDroppedLines()
Resets the count of the number of lines dropped from the history.
Definition: Screen.cpp:842
const HistoryType & getScroll()
Returns the type of storage used to keep lines in the history.
Definition: Screen.cpp:1546
void ShowCharacter(unsigned short c)
Displays a new character at the current cursor position.
Definition: Screen.cpp:752
int getLines()
Return the number of lines.
Definition: Screen.h:377
Base class for terminal character decoders.
QString name
std::string hash(hash_fptr hash_fcn, const std::string &str, int result_buf_len)
Definition: lo-hash.cc:45