Merge pull request #103 from Swordfish90/improvemouse

Improved mouse behavior. Enabled mouse support for applications.
This commit is contained in:
Filippo Scognamiglio 2014-08-30 01:38:58 +02:00
commit 98b2511660
8 changed files with 1003 additions and 561 deletions

View File

@ -133,41 +133,34 @@ Item{
acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton
anchors.fill: parent
onWheel:{
var coord = correctDistortion(wheel.x, wheel.y);
var lines = wheel.angleDelta.y > 0 ? -2 : 2;
kterminal.scrollWheel(coord.width, coord.height, lines);
}
onClicked: {
if (mouse.button == Qt.RightButton){
contextmenu.popup();
} else if (mouse.button == Qt.MiddleButton){
kterminal.pasteSelection();
if(wheel.modifiers & Qt.ControlModifier){
wheel.angleDelta.y > 0 ? zoomIn.trigger() : zoomOut.trigger();
} else {
var coord = correctDistortion(wheel.x, wheel.y);
var lines = wheel.angleDelta.y > 0 ? -1 : 1;
kterminal.scrollWheelEvent(coord, lines);
}
}
onDoubleClicked: {
if (mouse.button == Qt.LeftButton){
var coord = correctDistortion(mouse.x, mouse.y);
kterminal.mouseDoubleClick(coord.width, coord.height);
}
}
onPositionChanged: {
if (pressedButtons & Qt.LeftButton){
var coord = correctDistortion(mouse.x, mouse.y);
kterminal.mouseMove(coord.width, coord.height);
}
var coord = correctDistortion(mouse.x, mouse.y);
kterminal.mouseDoubleClickEvent(coord, mouse.button, mouse.modifiers);
}
onPressed: {
if (mouse.button == Qt.LeftButton){
if((!kterminal.usesMouse || mouse.modifiers & Qt.ShiftModifier) && mouse.button == Qt.RightButton) {
contextmenu.popup();
} else {
var coord = correctDistortion(mouse.x, mouse.y);
kterminal.mousePress(coord.width, coord.height);
kterminal.mousePressEvent(coord, mouse.button, mouse.modifiers)
}
}
onReleased: {
if (mouse.button == Qt.LeftButton){
var coord = correctDistortion(mouse.x, mouse.y);
kterminal.mouseRelease(coord.width, coord.height);
}
var coord = correctDistortion(mouse.x, mouse.y);
kterminal.mouseReleaseEvent(coord, mouse.button, mouse.modifiers);
}
onPositionChanged: {
var coord = correctDistortion(mouse.x, mouse.y);
kterminal.mouseMoveEvent(coord, mouse.button, mouse.buttons, mouse.modifiers);
}
//Frame displacement properties
property real dtop: frame.item.displacementTop
@ -185,7 +178,7 @@ Item{
var cc = Qt.size(0.5 - x, 0.5 - y);
var distortion = (cc.height * cc.height + cc.width * cc.width) * shadersettings.screen_distortion;
return Qt.size((x - cc.width * (1+distortion) * distortion) * width,
return Qt.point((x - cc.width * (1+distortion) * distortion) * width,
(y - cc.height * (1+distortion) * distortion) * height)
}
}

View File

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

View File

@ -376,6 +376,12 @@ signals:
*/
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
* of the terminal display.

View File

@ -48,9 +48,10 @@
#include "ShellCommand.h" // REUSE THIS
#include "Vt102Emulation.h" // REUSE THIS
int Session::lastSessionId = 0;
using namespace Konsole;
Session::Session() :
_shellProcess(0)
, _emulation(0)
@ -199,14 +200,9 @@ void Session::addView(KTerminalDisplay * widget)
// allow emulation to notify view when the foreground process
// indicates whether or not it is interested in mouse signals
// TODO Disabled since at the moment it is not working properly.
// Remember to reenable that once it' is's working.
//connect( _emulation , SIGNAL(programUsesMouseChanged(bool)) , widget ,
// SLOT(setUsesMouse(bool)) );
//widget->setUsesMouse( _emulation->programUsesMouse() );
connect( _emulation , SIGNAL(programUsesMouseChanged(bool)) , widget ,
SLOT(setUsesMouse(bool)) );
widget->setUsesMouse( _emulation->programUsesMouse() );
widget->setScreenWindow(_emulation->createWindow());
}

View File

@ -447,92 +447,377 @@ QStringList KTerminalDisplay::availableColorSchemes()
return ret;
}
void KTerminalDisplay::scrollWheel(qreal x, qreal y, int lines){
void KTerminalDisplay::scrollWheelEvent(QPoint position, int lines){
if(_mouseMarks){
int charLine;
int charColumn;
getCharacterPosition(QPoint(x,y) , charLine , charColumn);
emit mouseSignal(lines > 0 ? 5 : 4,
charColumn + 1,
charLine + 1,
0);
} else {
if(_screenWindow->lineCount() == _screenWindow->windowLines()){
const int keyCode = lines > 0 ? Qt::Key_Down : Qt::Key_Up;
QKeyEvent keyEvent(QEvent::KeyPress, keyCode, Qt::NoModifier);
emit keyPressedSignal(&keyEvent);
emit keyPressedSignal(&keyEvent);
} else {
_screenWindow->scrollBy( ScreenWindow::ScrollLines, lines );
_screenWindow->scrollCount();
updateImage();
}
} else {
int charLine;
int charColumn;
getCharacterPosition(position, charLine, charColumn);
emit mouseSignal(lines > 0 ? 5 : 4,
charColumn + 1,
charLine + 1,
0);
}
}
void KTerminalDisplay::mousePress(qreal x, qreal y){
if (m_focusOnClick) forcedFocus();
if (m_showVKBonClick) ShowVKB(true);
void KTerminalDisplay::doPaste(QString text, bool appendReturn)
{
if (!_screenWindow)
return;
if (appendReturn)
text.append("\r");
if (!text.isEmpty()) {
text.replace('\n', '\r');
// if (bracketedPasteMode()) {
// text.prepend("\e[200~");
// text.append("\e[201~");
// }
// perform paste by simulating keypress events
QKeyEvent e(QEvent::KeyPress, 0, Qt::NoModifier, text);
emit keyPressedSignal(&e);
}
}
void KTerminalDisplay::pasteFromClipboard(bool appendEnter)
{
QString text = QGuiApplication::clipboard()->text(QClipboard::Clipboard);
doPaste(text, appendEnter);
}
void KTerminalDisplay::pasteFromX11Selection(bool appendEnter)
{
QString text = QGuiApplication::clipboard()->text(QClipboard::Selection);
doPaste(text, appendEnter);
}
void KTerminalDisplay::processMidButtonClick(QPoint &position, Qt::KeyboardModifier modifiers)
{
if (_mouseMarks || (modifiers & Qt::ShiftModifier)) {
const bool appendEnter = modifiers & Qt::ControlModifier;
if (true /*_middleClickPasteMode == Enum::PasteFromX11Selection*/) {
pasteFromX11Selection(appendEnter);
} else if (false /*_middleClickPasteMode == Enum::PasteFromClipboard*/) {
pasteFromClipboard(appendEnter);
} else {
Q_ASSERT(false);
}
} else {
int charLine = 0;
int charColumn = 0;
getCharacterPosition(position, charLine, charColumn);
emit mouseSignal(1, charColumn + 1, charLine + 1, 0);
//emit mouseSignal(1, charColumn + 1, charLine + 1 + _scrollBar->value() - _scrollBar->maximum() , 0);
}
}
void KTerminalDisplay::mousePressEvent(QPoint position, int but, int mod)
{
Qt::MouseButton button = (Qt::MouseButton) but;
Qt::KeyboardModifier modifiers = (Qt::KeyboardModifier) mod;
// if (_possibleTripleClick && (ev->button() == Qt::LeftButton)) {
// mouseTripleClickEvent(ev);
// return;
// }
if (!_screenWindow) return;
int charLine;
int charColumn;
getCharacterPosition(QPoint(x,y), charLine, charColumn);
getCharacterPosition(position, charLine, charColumn);
QPoint pos = QPoint(charColumn, charLine);
_wordSelectionMode = false;
_lineSelectionMode = false;
if (button == Qt::LeftButton) {
_lineSelectionMode = false;
_wordSelectionMode = false;
if(_mouseMarks){
emit mouseSignal(0, charColumn + 1, charLine + 1, 0);
} else {
QPoint pos = QPoint(charColumn, charLine);
_preserveLineBreaks = !((modifiers & Qt::ControlModifier) && !(modifiers & Qt::AltModifier));
_columnSelectionMode = (modifiers & Qt::AltModifier) && (modifiers & Qt::ControlModifier);
_screenWindow->clearSelection();
_iPntSel = _pntSel = pos;
_actSel = 1; // left mouse button pressed but nothing selected yet.
if (_mouseMarks || (modifiers == Qt::ShiftModifier)) {
// Only extend selection for programs not interested in mouse
if (_mouseMarks && (modifiers == Qt::ShiftModifier)) {
extendSelection(position);
} else {
_screenWindow->clearSelection();
//pos.ry() += _scrollBar->value();
_iPntSel = _pntSel = pos;
_actSel = 1; // left mouse button pressed but nothing selected yet.
}
} else {
emit mouseSignal(0, charColumn + 1, charLine + 1, 0);
}
} else if (button == Qt::MidButton) {
processMidButtonClick(position, modifiers);
} else if (button == Qt::RightButton) {
if (!_mouseMarks)
emit mouseSignal(2, charColumn + 1, charLine + 1, 0);
}
}
void KTerminalDisplay::mouseMove(qreal x, qreal y){
QPoint pos(x, y);
void KTerminalDisplay::mouseMoveEvent(QPoint position, int but, int buts, int mod)
{
Qt::MouseButton button = (Qt::MouseButton) but;
Qt::KeyboardModifier modifiers = (Qt::KeyboardModifier) mod;
Qt::MouseButtons buttons = (Qt::MouseButtons) buts;
if(_mouseMarks){
int charLine;
int charColumn;
getCharacterPosition(pos, charLine, charColumn);
int charLine = 0;
int charColumn = 0;
getCharacterPosition(position, charLine, charColumn);
emit mouseSignal(0, charColumn + 1, charLine + 1, 1);
} else {
extendSelection(pos);
// for auto-hiding the cursor, we need mouseTracking
if (buttons == Qt::NoButton) return;
// if the terminal is interested in mouse movements
// then emit a mouse movement signal, unless the shift
// key is being held down, which overrides this.
if (!_mouseMarks && !(modifiers & Qt::ShiftModifier)) {
int button = 3;
if (buttons & Qt::LeftButton)
button = 0;
if (buttons & Qt::MidButton)
button = 1;
if (buttons & Qt::RightButton)
button = 2;
emit mouseSignal(button, charColumn + 1, charLine + 1, 1);
return;
}
if (_actSel == 0) return;
// don't extend selection while pasting
if (buttons & Qt::MidButton) return;
extendSelection(position);
}
void KTerminalDisplay::mouseDoubleClick(qreal x, qreal y){
QPoint pos(x, y);
if(_mouseMarks){
int charLine;
int charColumn;
getCharacterPosition(pos, charLine, charColumn);
QPoint KTerminalDisplay::findWordEnd(const QPoint &pnt)
{
const int regSize = qMax(_screenWindow->windowLines(), 10);
const int curLine = _screenWindow->currentLine();
int i = pnt.y();
int x = pnt.x();
int y = i + curLine;
int j = loc(x, i);
QVector<LineProperty> lineProperties = _lineProperties;
Screen *screen = _screenWindow->screen();
Character *image = _image;
Character *tmp_image = NULL;
const QChar selClass = charClass(image[j]);
const int imageSize = regSize * _columns;
const int maxY = _screenWindow->lineCount() - 1;
const int maxX = _columns - 1;
emit mouseSignal(0, charColumn + 1, charLine + 1, 0);
//emit mouseSignal(0, charColumn + 1, charLine + 1, 0);
} else {
_wordSelectionMode = true;
extendSelection(pos);
while (true) {
const int lineCount = lineProperties.count();
for (;;j++, x++) {
if (x < maxX) {
if (charClass(image[j + 1]) == selClass)
continue;
goto out;
} else if (i < lineCount - 1) {
if (lineProperties[i] & LINE_WRAPPED &&
charClass(image[j + 1]) == selClass) {
x = -1;
i++;
y++;
continue;
}
goto out;
} else if (y < maxY) {
if (i < lineCount && !(lineProperties[i] & LINE_WRAPPED))
goto out;
break;
} else {
goto out;
}
}
int newRegEnd = qMin(y + regSize - 1, maxY);
lineProperties = screen->getLineProperties(y, newRegEnd);
i = 0;
if (!tmp_image) {
tmp_image = new Character[imageSize];
image = tmp_image;
}
screen->getImage(tmp_image, imageSize, y, newRegEnd);
x--;
j = loc(x, i);
}
out:
y -= curLine;
// In word selection mode don't select @ (64) if at end of word.
if (((image[j].rendition & RE_EXTENDED_CHAR) == 0) &&
(QChar(image[j].character) == '@') &&
(y > pnt.y() || x > pnt.x())) {
if (x > 0) {
x--;
} else {
y--;
}
}
if (tmp_image) {
delete[] tmp_image;
}
return QPoint(x, y);
}
void KTerminalDisplay::mouseRelease(qreal x, qreal y){
_actSel = 0;
QPoint KTerminalDisplay::findWordStart(const QPoint &pnt)
{
const int regSize = qMax(_screenWindow->windowLines(), 10);
const int curLine = _screenWindow->currentLine();
int i = pnt.y();
int x = pnt.x();
int y = i + curLine;
int j = loc(x, i);
QVector<LineProperty> lineProperties = _lineProperties;
Screen *screen = _screenWindow->screen();
Character *image = _image;
Character *tmp_image = NULL;
const QChar selClass = charClass(image[j]);
const int imageSize = regSize * _columns;
if(_mouseMarks){
int charLine;
int charColumn;
getCharacterPosition(QPoint(x,y), charLine, charColumn);
while (true) {
for (;;j--, x--) {
if (x > 0) {
if (charClass(image[j - 1]) == selClass)
continue;
goto out;
} else if (i > 0) {
if (lineProperties[i - 1] & LINE_WRAPPED &&
charClass(image[j - 1]) == selClass) {
x = _columns;
i--;
y--;
continue;
}
goto out;
} else if (y > 0) {
break;
} else {
goto out;
}
}
int newRegStart = qMax(0, y - regSize);
lineProperties = screen->getLineProperties(newRegStart, y - 1);
i = y - newRegStart;
if (!tmp_image) {
tmp_image = new Character[imageSize];
image = tmp_image;
}
screen->getImage(tmp_image, imageSize, newRegStart, y - 1);
j = loc(x, i);
}
out:
if (tmp_image) {
delete[] tmp_image;
}
return QPoint(x, y - curLine);
}
emit mouseSignal(0, charColumn + 1, charLine + 1, 2);
void KTerminalDisplay::mouseDoubleClickEvent(QPoint position, int but, int mod)
{
Qt::MouseButton button = (Qt::MouseButton) but;
Qt::KeyboardModifier modifiers = (Qt::KeyboardModifier) mod;
if (button != Qt::LeftButton) return;
if (!_screenWindow) return;
int charLine = 0;
int charColumn = 0;
getCharacterPosition(position, charLine, charColumn);
// If the application is interested in mouse events. They have already been forwarded.
if (!_mouseMarks && !(modifiers & Qt::ShiftModifier))
return;
_screenWindow->clearSelection();
_wordSelectionMode = true;
_actSel = 2; // within selection
_iPntSel = QPoint(charColumn, charLine);
const QPoint bgnSel = findWordStart(_iPntSel);
const QPoint endSel = findWordEnd(_iPntSel);
_screenWindow->setSelectionStart(bgnSel.x() , bgnSel.y() , false);
_screenWindow->setSelectionEnd(endSel.x() , endSel.y());
copyToX11Selection();
//TODO implement triple click.
// _possibleTripleClick = true;
// QTimer::singleShot(QApplication::doubleClickInterval(), this,
// SLOT(tripleClickTimeout()));
}
void KTerminalDisplay::copyToX11Selection()
{
if (!_screenWindow)
return;
QString text = _screenWindow->selectedText(_preserveLineBreaks);
if (text.isEmpty())
return;
QGuiApplication::clipboard()->setText(text, QClipboard::Selection);
}
void KTerminalDisplay::mouseReleaseEvent(QPoint position, int but, int mod)
{
Qt::MouseButton button = (Qt::MouseButton) but;
Qt::KeyboardModifier modifiers = (Qt::KeyboardModifier) mod;
if (!_screenWindow)
return;
int charLine;
int charColumn;
getCharacterPosition(position, charLine, charColumn);
if (button == Qt::LeftButton) {
if (_actSel > 1) {
copyToX11Selection();
}
_actSel = 0;
//FIXME: emits a release event even if the mouse is
// outside the range. The procedure used in `mouseMoveEvent'
// applies here, too.
if (!_mouseMarks && !(modifiers & Qt::ShiftModifier))
emit mouseSignal(0, charColumn + 1, charLine + 1 , 2);
}
if (!_mouseMarks &&
(button == Qt::RightButton || button == Qt::MidButton) &&
!(modifiers & Qt::ShiftModifier)) {
emit mouseSignal(button == Qt::MidButton ? 1 : 2, charColumn + 1, charLine + 1, 2);
}
}
@ -546,7 +831,12 @@ void KTerminalDisplay::scrollScreenWindow(enum ScreenWindow::RelativeScrollMode
void KTerminalDisplay::setUsesMouse(bool usesMouse){
_mouseMarks = !usesMouse;
_mouseMarks = usesMouse;
emit usesMouseChanged();
}
bool KTerminalDisplay::getUsesMouse(){
return !_mouseMarks;
}
void KTerminalDisplay::setAutoFocus(bool au)
@ -1361,16 +1651,33 @@ void KTerminalDisplay::updateLineProperties()
_lineProperties = _screenWindow->getLineProperties();
}
QChar KTerminalDisplay::charClass(QChar qch) const
QChar KTerminalDisplay::charClass(const Character& ch) const
{
if ( qch.isSpace() ) return ' ';
if (ch.rendition & RE_EXTENDED_CHAR) {
ushort extendedCharLength = 0;
const ushort* chars = ExtendedCharTable::instance.lookupExtendedChar(ch.character, extendedCharLength);
if (chars && extendedCharLength > 0) {
const QString s = QString::fromUtf16(chars, extendedCharLength);
if (_wordCharacters.contains(s, Qt::CaseInsensitive))
return 'a';
bool allLetterOrNumber = true;
for (int i = 0; allLetterOrNumber && i < s.size(); ++i)
allLetterOrNumber = s.at(i).isLetterOrNumber();
return allLetterOrNumber ? 'a' : s.at(0);
}
return 0;
} else {
const QChar qch(ch.character);
if (qch.isSpace()) return ' ';
if ( qch.isLetterOrNumber() || _wordCharacters.contains(qch, Qt::CaseInsensitive ) )
return 'a';
if (qch.isLetterOrNumber() || _wordCharacters.contains(qch, Qt::CaseInsensitive))
return 'a';
return qch;
return qch;
}
}
void KTerminalDisplay::setWordCharacters(const QString& wc)
{
_wordCharacters = wc;

View File

@ -70,6 +70,7 @@ class KONSOLEPRIVATE_EXPORT KTerminalDisplay : public QQuickPaintedItem
Q_PROPERTY(bool ShowIMEOnClick READ autoVKB WRITE setAutoVKB NOTIFY changedAutoVKB)
Q_PROPERTY(QSize terminalSize READ getTerminalSize NOTIFY terminalSizeChanged)
Q_PROPERTY(QSize paintedFontSize READ getFontSize NOTIFY paintedFontSizeChanged)
Q_PROPERTY(bool usesMouse READ getUsesMouse NOTIFY usesMouseChanged)
public:
@ -311,15 +312,10 @@ public slots:
void setColorScheme(const QString &name);
QStringList availableColorSchemes();
void scrollWheel(qreal x, qreal y, int lines);
void mousePress(qreal x, qreal y);
void mouseMove(qreal x, qreal y);
void mouseDoubleClick(qreal x, qreal y);
void mouseRelease(qreal x, qreal y);
void scrollScreenWindow(enum ScreenWindow::RelativeScrollMode mode, int amount);
void setUsesMouse(bool usesMouse);
bool getUsesMouse(void);
bool autoFocus() { return m_focusOnClick; }
void setAutoFocus(bool au);
@ -425,6 +421,8 @@ signals:
void mouseSignal(int,int,int,int);
void usesMouseChanged();
void terminalSizeChanged();
void paintedFontSizeChanged();
@ -477,7 +475,11 @@ protected:
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
QRect geometryRound(const QRectF &r) const;
//void mousePressEvent(QMouseEvent*ev);
Q_INVOKABLE void mousePressEvent(QPoint position, int but, int mod);
Q_INVOKABLE void mouseReleaseEvent(QPoint position, int but, int mod);
Q_INVOKABLE void mouseDoubleClickEvent(QPoint position, int but, int mod);
Q_INVOKABLE void mouseMoveEvent(QPoint position, int but, int buts, int mod);
Q_INVOKABLE void scrollWheelEvent(QPoint position, int lines);
//void mouseReleaseEvent( QMouseEvent* );
//void mouseMoveEvent( QMouseEvent* );
@ -497,7 +499,7 @@ protected:
// - A space (returns ' ')
// - Part of a word (returns 'a')
// - Other characters (returns the input character)
QChar charClass(QChar ch) const;
QChar charClass(const Character& ch) const;
void clearImage();
@ -594,6 +596,14 @@ private:
// redraws the cursor
void updateCursor();
QPoint findWordStart(const QPoint &pnt);
QPoint findWordEnd(const QPoint &pnt);
void processMidButtonClick(QPoint &position, Qt::KeyboardModifier modifiers);
void copyToX11Selection();
void pasteFromClipboard(bool appendEnter);
void pasteFromX11Selection(bool appendEnter);
void doPaste(QString text, bool appendReturn);
bool handleShortcutOverrideEvent(QKeyEvent* event);
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////

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