Much improved mouse emulation.

This commit is contained in:
Filippo Scognamiglio 2014-08-27 21:53:15 +02:00
parent 765c41307f
commit a0bfe0f77f
5 changed files with 599 additions and 462 deletions

View File

@ -1,6 +1,6 @@
/* /*
This file is part of Konsole, KDE's terminal. This file is part of Konsole, KDE's terminal.
Copyright 2007-2008 by Robert Knight <robertknight@gmail.com> Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de> Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
@ -53,7 +53,7 @@ static const int LINE_DOUBLEHEIGHT = (1 << 2);
class Character class Character
{ {
public: public:
/** /**
* Constructs a new character. * Constructs a new character.
* *
* @param _c The unicode character value of this character. * @param _c The unicode character value of this character.
@ -71,25 +71,25 @@ public:
{ {
/** The unicode character value for this character. */ /** The unicode character value for this character. */
quint16 character; quint16 character;
/** /**
* Experimental addition which allows a single Character instance to contain more than * Experimental addition which allows a single Character instance to contain more than
* one unicode character. * one unicode character.
* *
* charSequence is a hash code which can be used to look up the unicode * charSequence is a hash code which can be used to look up the unicode
* character sequence in the ExtendedCharTable used to create the sequence. * character sequence in the ExtendedCharTable used to create the sequence.
*/ */
quint16 charSequence; quint16 charSequence;
}; };
/** A combination of RENDITION flags which specify options for drawing the character. */ /** A combination of RENDITION flags which specify options for drawing the character. */
quint8 rendition; quint8 rendition;
/** The foreground color used to draw this character. */ /** The foreground color used to draw this character. */
CharacterColor foregroundColor; CharacterColor foregroundColor;
/** The color used to draw this character's background. */ /** The color used to draw this character's background. */
CharacterColor backgroundColor; CharacterColor backgroundColor;
/** /**
* Returns true if this character has a transparent background when * Returns true if this character has a transparent background when
* it is drawn with the specified @p palette. * it is drawn with the specified @p palette.
*/ */
@ -97,16 +97,16 @@ public:
/** /**
* Returns true if this character should always be drawn in bold when * Returns true if this character should always be drawn in bold when
* it is drawn with the specified @p palette, independent of whether * it is drawn with the specified @p palette, independent of whether
* or not the character has the RE_BOLD rendition flag. * or not the character has the RE_BOLD rendition flag.
*/ */
ColorEntry::FontWeight fontWeight(const ColorEntry* base) const; ColorEntry::FontWeight fontWeight(const ColorEntry* base) const;
/** /**
* returns true if the format (color, rendition flag) of the compared characters is equal * returns true if the format (color, rendition flag) of the compared characters is equal
*/ */
bool equalsFormat(const Character &other) const; bool equalsFormat(const Character &other) const;
/** /**
* Compares two characters and returns true if they have the same unicode character value, * Compares two characters and returns true if they have the same unicode character value,
* rendition and colors. * rendition and colors.
*/ */
@ -119,36 +119,36 @@ public:
}; };
inline bool operator == (const Character& a, const Character& b) inline bool operator == (const Character& a, const Character& b)
{ {
return a.character == b.character && return a.character == b.character &&
a.rendition == b.rendition && a.rendition == b.rendition &&
a.foregroundColor == b.foregroundColor && a.foregroundColor == b.foregroundColor &&
a.backgroundColor == b.backgroundColor; a.backgroundColor == b.backgroundColor;
} }
inline bool operator != (const Character& a, const Character& b) inline bool operator != (const Character& a, const Character& b)
{ {
return a.character != b.character || return a.character != b.character ||
a.rendition != b.rendition || a.rendition != b.rendition ||
a.foregroundColor != b.foregroundColor || a.foregroundColor != b.foregroundColor ||
a.backgroundColor != b.backgroundColor; a.backgroundColor != b.backgroundColor;
} }
inline bool Character::isTransparent(const ColorEntry* base) const inline bool Character::isTransparent(const ColorEntry* base) const
{ {
return ((backgroundColor._colorSpace == COLOR_SPACE_DEFAULT) && return ((backgroundColor._colorSpace == COLOR_SPACE_DEFAULT) &&
base[backgroundColor._u+0+(backgroundColor._v?BASE_COLORS:0)].transparent) base[backgroundColor._u+0+(backgroundColor._v?BASE_COLORS:0)].transparent)
|| ((backgroundColor._colorSpace == COLOR_SPACE_SYSTEM) && || ((backgroundColor._colorSpace == COLOR_SPACE_SYSTEM) &&
base[backgroundColor._u+2+(backgroundColor._v?BASE_COLORS:0)].transparent); base[backgroundColor._u+2+(backgroundColor._v?BASE_COLORS:0)].transparent);
} }
inline bool Character::equalsFormat(const Character& other) const inline bool Character::equalsFormat(const Character& other) const
{ {
return return
backgroundColor==other.backgroundColor && backgroundColor==other.backgroundColor &&
foregroundColor==other.foregroundColor && foregroundColor==other.foregroundColor &&
rendition==other.rendition; rendition==other.rendition;
} }
inline ColorEntry::FontWeight Character::fontWeight(const ColorEntry* base) const inline ColorEntry::FontWeight Character::fontWeight(const ColorEntry* base) const
{ {
@ -193,7 +193,7 @@ public:
* which was added to the table using createExtendedChar(). * which was added to the table using createExtendedChar().
* *
* @param hash The hash key returned by createExtendedChar() * @param hash The hash key returned by createExtendedChar()
* @param length This variable is set to the length of the * @param length This variable is set to the length of the
* character sequence. * character sequence.
* *
* @return A unicode character sequence of size @p length. * @return A unicode character sequence of size @p length.
@ -205,7 +205,7 @@ public:
private: private:
// calculates the hash key of a sequence of unicode points of size 'length' // calculates the hash key of a sequence of unicode points of size 'length'
ushort extendedCharHash(ushort* unicodePoints , ushort length) const; ushort extendedCharHash(ushort* unicodePoints , ushort length) const;
// tests whether the entry in the table specified by 'hash' matches the // tests whether the entry in the table specified by 'hash' matches the
// character sequence 'unicodePoints' of size 'length' // character sequence 'unicodePoints' of size 'length'
bool extendedCharMatch(ushort hash , ushort* unicodePoints , ushort length) const; bool extendedCharMatch(ushort hash , ushort* unicodePoints , ushort length) const;
// internal, maps hash keys to character sequence buffers. The first ushort // internal, maps hash keys to character sequence buffers. The first ushort

View File

@ -376,6 +376,12 @@ signals:
*/ */
void imageSizeChanged(int lineCount , int columnCount); void imageSizeChanged(int lineCount , int columnCount);
/**
* Emitted after receiving the escape sequence which asks to change
* the terminal emulator's size
*/
void imageResizeRequest(const QSize& sizz);
/** /**
* Emitted when the terminal program requests to change various properties * Emitted when the terminal program requests to change various properties
* of the terminal display. * of the terminal display.

View File

@ -48,9 +48,10 @@
#include "ShellCommand.h" // REUSE THIS #include "ShellCommand.h" // REUSE THIS
#include "Vt102Emulation.h" // REUSE THIS #include "Vt102Emulation.h" // REUSE THIS
int Session::lastSessionId = 0; int Session::lastSessionId = 0;
using namespace Konsole;
Session::Session() : Session::Session() :
_shellProcess(0) _shellProcess(0)
, _emulation(0) , _emulation(0)

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/* /*
This file is part of Konsole, an X terminal. This file is part of Konsole, an X terminal.
Copyright 2007-2008 by Robert Knight <robertknight@gmail.com> Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de> Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
@ -23,168 +23,169 @@
#ifndef VT102EMULATION_H #ifndef VT102EMULATION_H
#define VT102EMULATION_H #define VT102EMULATION_H
// Standard Library
#include <stdio.h>
// Qt // Qt
#include <QtGui/QKeyEvent>
#include <QtCore/QHash> #include <QtCore/QHash>
#include <QtCore/QTimer>
// Konsole // Konsole
#include "Emulation.h" #include "Emulation.h"
#include "Screen.h" #include "Screen.h"
#include "ScreenWindow.h"
#include "TerminalDisplay.h" class QTimer;
class QKeyEvent;
#define MODE_AppScreen (MODES_SCREEN+0) // Mode #1 #define MODE_AppScreen (MODES_SCREEN+0) // Mode #1
#define MODE_AppCuKeys (MODES_SCREEN+1) // Application cursor keys (DECCKM) #define MODE_AppCuKeys (MODES_SCREEN+1) // Application cursor keys (DECCKM)
#define MODE_AppKeyPad (MODES_SCREEN+2) // #define MODE_AppKeyPad (MODES_SCREEN+2) //
#define MODE_Mouse1000 (MODES_SCREEN+3) // Send mouse X,Y position on press and release #define MODE_Mouse1000 (MODES_SCREEN+3) // Send mouse X,Y position on press and release
#define MODE_Mouse1001 (MODES_SCREEN+4) // Use Hilight mouse tracking #define MODE_Mouse1001 (MODES_SCREEN+4) // Use Hilight mouse tracking
#define MODE_Mouse1002 (MODES_SCREEN+5) // Use cell motion mouse tracking #define MODE_Mouse1002 (MODES_SCREEN+5) // Use cell motion mouse tracking
#define MODE_Mouse1003 (MODES_SCREEN+6) // Use all motion mouse tracking #define MODE_Mouse1003 (MODES_SCREEN+6) // Use all motion mouse tracking
#define MODE_Ansi (MODES_SCREEN+7) // Use US Ascii for character sets G0-G3 (DECANM) #define MODE_Mouse1005 (MODES_SCREEN+7) // Xterm-style extended coordinates
#define MODE_132Columns (MODES_SCREEN+8) // 80 <-> 132 column mode switch (DECCOLM) #define MODE_Mouse1006 (MODES_SCREEN+8) // 2nd Xterm-style extended coordinates
#define MODE_Allow132Columns (MODES_SCREEN+9) // Allow DECCOLM mode #define MODE_Mouse1015 (MODES_SCREEN+9) // Urxvt-style extended coordinates
#define MODE_total (MODES_SCREEN+10) #define MODE_Ansi (MODES_SCREEN+10) // Use US Ascii for character sets G0-G3 (DECANM)
#define MODE_132Columns (MODES_SCREEN+11) // 80 <-> 132 column mode switch (DECCOLM)
#define MODE_Allow132Columns (MODES_SCREEN+12) // Allow DECCOLM mode
#define MODE_BracketedPaste (MODES_SCREEN+13) // Xterm-style bracketed paste mode
#define MODE_total (MODES_SCREEN+14)
namespace Konsole
struct CharCodes
{ {
// coding info extern unsigned short vt100_graphics[32];
char charset[4]; //
int cu_cs; // actual charset. struct CharCodes {
bool graphic; // Some VT100 tricks // coding info
bool pound ; // Some VT100 tricks char charset[4]; //
bool sa_graphic; // saved graphic int cu_cs; // actual charset.
bool sa_pound; // saved pound bool graphic; // Some VT100 tricks
bool pound; // Some VT100 tricks
bool sa_graphic; // saved graphic
bool sa_pound; // saved pound
}; };
/** /**
* Provides an xterm compatible terminal emulation based on the DEC VT102 terminal. * Provides an xterm compatible terminal emulation based on the DEC VT102 terminal.
* A full description of this terminal can be found at http://vt100.net/docs/vt102-ug/ * A full description of this terminal can be found at http://vt100.net/docs/vt102-ug/
* *
* In addition, various additional xterm escape sequences are supported to provide * In addition, various additional xterm escape sequences are supported to provide
* features such as mouse input handling. * features such as mouse input handling.
* See http://rtfm.etla.org/xterm/ctlseq.html for a description of xterm's escape * See http://rtfm.etla.org/xterm/ctlseq.html for a description of xterm's escape
* sequences. * sequences.
* *
*/ */
class Vt102Emulation : public Emulation class Vt102Emulation : public Emulation
{ {
Q_OBJECT Q_OBJECT
public: public:
/** Constructs a new emulation */ /** Constructs a new emulation */
Vt102Emulation(); Vt102Emulation();
~Vt102Emulation(); ~Vt102Emulation();
// reimplemented from Emulation // reimplemented from Emulation
virtual void clearEntireScreen(); virtual void clearEntireScreen();
virtual void reset(); virtual void reset();
virtual char eraseChar() const; virtual char eraseChar() const;
public slots: public slots:
// reimplemented from Emulation // reimplemented from Emulation
virtual void sendString(const char*,int length = -1); virtual void sendString(const char*, int length = -1);
virtual void sendText(const QString& text); virtual void sendText(const QString& text);
virtual void sendKeyEvent(QKeyEvent*); virtual void sendKeyEvent(QKeyEvent*);
virtual void sendMouseEvent(int buttons, int column, int line, int eventType); virtual void sendMouseEvent(int buttons, int column, int line, int eventType);
protected: protected:
// reimplemented from Emulation // reimplemented from Emulation
virtual void setMode(int mode); virtual void setMode(int mode);
virtual void resetMode(int mode); virtual void resetMode(int mode);
virtual void receiveChar(int cc); virtual void receiveChar(int cc);
private slots: private slots:
//causes changeTitle() to be emitted for each (int,QString) pair in pendingTitleUpdates //causes changeTitle() to be emitted for each (int,QString) pair in pendingTitleUpdates
//used to buffer multiple title updates //used to buffer multiple title updates
void updateTitle(); void updateTitle();
private: private:
unsigned short applyCharset(unsigned short c); unsigned short applyCharset(unsigned short c);
void setCharset(int n, int cs); void setCharset(int n, int cs);
void useCharset(int n); void useCharset(int n);
void setAndUseCharset(int n, int cs); void setAndUseCharset(int n, int cs);
void saveCursor(); void saveCursor();
void restoreCursor(); void restoreCursor();
void resetCharset(int scrno); void resetCharset(int scrno);
void setMargins(int top, int bottom); void setMargins(int top, int bottom);
//set margins for all screens back to their defaults //set margins for all screens back to their defaults
void setDefaultMargins(); void setDefaultMargins();
// returns true if 'mode' is set or false otherwise // returns true if 'mode' is set or false otherwise
bool getMode (int mode); bool getMode(int mode);
// saves the current boolean value of 'mode' // saves the current boolean value of 'mode'
void saveMode (int mode); void saveMode(int mode);
// restores the boolean value of 'mode' // restores the boolean value of 'mode'
void restoreMode(int mode); void restoreMode(int mode);
// resets all modes // resets all modes
// (except MODE_Allow132Columns) // (except MODE_Allow132Columns)
void resetModes(); void resetModes();
void resetTokenizer(); void resetTokenizer();
#define MAX_TOKEN_LENGTH 80 #define MAX_TOKEN_LENGTH 256 // Max length of tokens (e.g. window title)
void addToCurrentToken(int cc); void addToCurrentToken(int cc);
int tokenBuffer[MAX_TOKEN_LENGTH]; //FIXME: overflow? int tokenBuffer[MAX_TOKEN_LENGTH]; //FIXME: overflow?
int tokenBufferPos; int tokenBufferPos;
#define MAXARGS 15 #define MAXARGS 15
void addDigit(int dig); void addDigit(int dig);
void addArgument(); void addArgument();
int argv[MAXARGS]; int argv[MAXARGS];
int argc; int argc;
void initTokenizer(); void initTokenizer();
// Set of flags for each of the ASCII characters which indicates // Set of flags for each of the ASCII characters which indicates
// what category they fall into (printable character, control, digit etc.) // what category they fall into (printable character, control, digit etc.)
// for the purposes of decoding terminal output // for the purposes of decoding terminal output
int charClass[256]; int charClass[256];
void reportDecodingError(); void reportDecodingError();
void processToken(int code, int p, int q); void processToken(int code, int p, int q);
void processWindowAttributeChange(); void processWindowAttributeChange();
void reportTerminalType(); void reportTerminalType();
void reportSecondaryAttributes(); void reportSecondaryAttributes();
void reportStatus(); void reportStatus();
void reportAnswerBack(); void reportAnswerBack();
void reportCursorPosition(); void reportCursorPosition();
void reportTerminalParms(int p); void reportTerminalParms(int p);
void onScrollLock(); // clears the screen and resizes it to the specified
void scrollLock(const bool lock); // number of columns
void clearScreenAndSetColumns(int columnCount);
// clears the screen and resizes it to the specified CharCodes _charset[2];
// number of columns
void clearScreenAndSetColumns(int columnCount);
CharCodes _charset[2]; class TerminalState
{
public:
// Initializes all modes to false
TerminalState() {
memset(&mode, false, MODE_total * sizeof(bool));
}
class TerminalState bool mode[MODE_total];
{ };
public:
// Initializes all modes to false
TerminalState()
{ memset(&mode,false,MODE_total * sizeof(bool)); }
bool mode[MODE_total]; TerminalState _currentModes;
}; TerminalState _savedModes;
TerminalState _currentModes; //hash table and timer for buffering calls to the session instance
TerminalState _savedModes; //to update the name of the session
//or window title.
//hash table and timer for buffering calls to the session instance //these calls occur when certain escape sequences are seen in the
//to update the name of the session //output from the terminal
//or window title. QHash<int, QString> _pendingTitleUpdates;
//these calls occur when certain escape sequences are seen in the QTimer* _titleUpdateTimer;
//output from the terminal
QHash<int,QString> _pendingTitleUpdates;
QTimer* _titleUpdateTimer;
}; };
}
#endif // VT102EMULATION_H #endif // VT102EMULATION_H