mirror of
				https://github.com/Swordfish90/cool-retro-term.git
				synced 2025-10-31 07:04:20 +00:00 
			
		
		
		
	Merge pull request #103 from Swordfish90/improvemouse
Improved mouse behavior. Enabled mouse support for applications.
This commit is contained in:
		| @@ -133,40 +133,33 @@ Item{ | |||||||
|         acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton |         acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton | ||||||
|         anchors.fill: parent |         anchors.fill: parent | ||||||
|         onWheel:{ |         onWheel:{ | ||||||
|  |             if(wheel.modifiers & Qt.ControlModifier){ | ||||||
|  |                wheel.angleDelta.y > 0 ? zoomIn.trigger() : zoomOut.trigger();  | ||||||
|  |             } else { | ||||||
|                 var coord = correctDistortion(wheel.x, wheel.y); |                 var coord = correctDistortion(wheel.x, wheel.y); | ||||||
|             var lines = wheel.angleDelta.y > 0 ? -2 : 2; |                 var lines = wheel.angleDelta.y > 0 ? -1 : 1; | ||||||
|             kterminal.scrollWheel(coord.width, coord.height, lines); |                 kterminal.scrollWheelEvent(coord, lines); | ||||||
|         } |  | ||||||
|         onClicked: { |  | ||||||
|             if (mouse.button == Qt.RightButton){ |  | ||||||
|                 contextmenu.popup(); |  | ||||||
|             } else if (mouse.button == Qt.MiddleButton){ |  | ||||||
|                 kterminal.pasteSelection(); |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         onDoubleClicked: { |         onDoubleClicked: { | ||||||
|             if (mouse.button == Qt.LeftButton){ |  | ||||||
|             var coord = correctDistortion(mouse.x, mouse.y); |             var coord = correctDistortion(mouse.x, mouse.y); | ||||||
|                 kterminal.mouseDoubleClick(coord.width, coord.height); |             kterminal.mouseDoubleClickEvent(coord, mouse.button, mouse.modifiers); | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         onPositionChanged: { |  | ||||||
|             if (pressedButtons & Qt.LeftButton){ |  | ||||||
|                 var coord = correctDistortion(mouse.x, mouse.y); |  | ||||||
|                 kterminal.mouseMove(coord.width, coord.height); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|         onPressed: { |         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); |                 var coord = correctDistortion(mouse.x, mouse.y); | ||||||
|                 kterminal.mousePress(coord.width, coord.height); |                 kterminal.mousePressEvent(coord, mouse.button, mouse.modifiers) | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         onReleased: { |         onReleased: { | ||||||
|             if (mouse.button == Qt.LeftButton){ |  | ||||||
|             var coord = correctDistortion(mouse.x, mouse.y); |             var coord = correctDistortion(mouse.x, mouse.y); | ||||||
|                 kterminal.mouseRelease(coord.width, coord.height); |             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 |         //Frame displacement properties | ||||||
| @@ -185,7 +178,7 @@ Item{ | |||||||
|             var cc = Qt.size(0.5 - x, 0.5 - y); |             var cc = Qt.size(0.5 - x, 0.5 - y); | ||||||
|             var distortion = (cc.height * cc.height + cc.width * cc.width) * shadersettings.screen_distortion; |             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) |                            (y - cc.height * (1+distortion) * distortion) * height) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -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.   | ||||||
|   | |||||||
| @@ -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) | ||||||
| @@ -199,14 +200,9 @@ void Session::addView(KTerminalDisplay * widget) | |||||||
|  |  | ||||||
|         // allow emulation to notify view when the foreground process |         // allow emulation to notify view when the foreground process | ||||||
|         // indicates whether or not it is interested in mouse signals |         // indicates whether or not it is interested in mouse signals | ||||||
|  |         connect( _emulation , SIGNAL(programUsesMouseChanged(bool)) , widget , | ||||||
|         // TODO Disabled since at the moment it is not working properly. |                  SLOT(setUsesMouse(bool)) ); | ||||||
|         // Remember to reenable that once it' is's working. |         widget->setUsesMouse( _emulation->programUsesMouse() ); | ||||||
|  |  | ||||||
|         //connect( _emulation , SIGNAL(programUsesMouseChanged(bool)) , widget , |  | ||||||
|         //         SLOT(setUsesMouse(bool)) ); |  | ||||||
|  |  | ||||||
|         //widget->setUsesMouse( _emulation->programUsesMouse() ); |  | ||||||
|  |  | ||||||
|         widget->setScreenWindow(_emulation->createWindow()); |         widget->setScreenWindow(_emulation->createWindow()); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -447,92 +447,377 @@ QStringList KTerminalDisplay::availableColorSchemes() | |||||||
|     return ret; |     return ret; | ||||||
| } | } | ||||||
|  |  | ||||||
| void KTerminalDisplay::scrollWheel(qreal x, qreal y, int lines){ | void KTerminalDisplay::scrollWheelEvent(QPoint position, int lines){ | ||||||
|     if(_mouseMarks){ |     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()){ |         if(_screenWindow->lineCount() == _screenWindow->windowLines()){ | ||||||
|             const int keyCode = lines > 0 ? Qt::Key_Down : Qt::Key_Up; |             const int keyCode = lines > 0 ? Qt::Key_Down : Qt::Key_Up; | ||||||
|             QKeyEvent keyEvent(QEvent::KeyPress, keyCode, Qt::NoModifier); |             QKeyEvent keyEvent(QEvent::KeyPress, keyCode, Qt::NoModifier); | ||||||
|  |  | ||||||
|             emit keyPressedSignal(&keyEvent); |             emit keyPressedSignal(&keyEvent); | ||||||
|             emit keyPressedSignal(&keyEvent); |  | ||||||
|         } else { |         } else { | ||||||
|             _screenWindow->scrollBy( ScreenWindow::ScrollLines, lines ); |             _screenWindow->scrollBy( ScreenWindow::ScrollLines, lines ); | ||||||
|             _screenWindow->scrollCount(); |             _screenWindow->scrollCount(); | ||||||
|             updateImage(); |             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){ | void KTerminalDisplay::doPaste(QString text, bool appendReturn) | ||||||
|     if (m_focusOnClick) forcedFocus(); | { | ||||||
|     if (m_showVKBonClick) ShowVKB(true); |     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 charLine; | ||||||
|     int charColumn; |     int charColumn; | ||||||
|     getCharacterPosition(QPoint(x,y), charLine, charColumn); |     getCharacterPosition(position, charLine, charColumn); | ||||||
|  |  | ||||||
|     _wordSelectionMode = false; |  | ||||||
|     _lineSelectionMode = false; |  | ||||||
|  |  | ||||||
|     if(_mouseMarks){ |  | ||||||
|         emit mouseSignal(0, charColumn + 1, charLine + 1, 0); |  | ||||||
|     } else { |  | ||||||
|     QPoint pos = QPoint(charColumn, charLine); |     QPoint pos = QPoint(charColumn, charLine); | ||||||
|  |  | ||||||
|  |     if (button == Qt::LeftButton) { | ||||||
|  |         _lineSelectionMode = false; | ||||||
|  |         _wordSelectionMode = false; | ||||||
|  |  | ||||||
|  |         _preserveLineBreaks = !((modifiers & Qt::ControlModifier) && !(modifiers & Qt::AltModifier)); | ||||||
|  |         _columnSelectionMode = (modifiers & Qt::AltModifier) && (modifiers & Qt::ControlModifier); | ||||||
|  |  | ||||||
|  |         if (_mouseMarks || (modifiers == Qt::ShiftModifier)) { | ||||||
|  |             // Only extend selection for programs not interested in mouse | ||||||
|  |             if (_mouseMarks && (modifiers == Qt::ShiftModifier)) { | ||||||
|  |                 extendSelection(position); | ||||||
|  |             } else { | ||||||
|                 _screenWindow->clearSelection(); |                 _screenWindow->clearSelection(); | ||||||
|  |  | ||||||
|  |                 //pos.ry() += _scrollBar->value(); | ||||||
|                 _iPntSel = _pntSel = pos; |                 _iPntSel = _pntSel = pos; | ||||||
|                 _actSel = 1; // left mouse button pressed but nothing selected yet. |                 _actSel = 1; // left mouse button pressed but nothing selected yet. | ||||||
|             } |             } | ||||||
| } |  | ||||||
|  |  | ||||||
| void KTerminalDisplay::mouseMove(qreal x, qreal y){ |  | ||||||
|     QPoint pos(x, y); |  | ||||||
|  |  | ||||||
|     if(_mouseMarks){ |  | ||||||
|         int charLine; |  | ||||||
|         int charColumn; |  | ||||||
|         getCharacterPosition(pos, charLine, charColumn); |  | ||||||
|  |  | ||||||
|         emit mouseSignal(0, charColumn + 1, charLine + 1, 1); |  | ||||||
|         } else { |         } else { | ||||||
|         extendSelection(pos); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void KTerminalDisplay::mouseDoubleClick(qreal x, qreal y){ |  | ||||||
|     QPoint pos(x, y); |  | ||||||
|  |  | ||||||
|     if(_mouseMarks){ |  | ||||||
|         int charLine; |  | ||||||
|         int charColumn; |  | ||||||
|         getCharacterPosition(pos, charLine, charColumn); |  | ||||||
|  |  | ||||||
|             emit mouseSignal(0, charColumn + 1, charLine + 1, 0); |             emit mouseSignal(0, charColumn + 1, charLine + 1, 0); | ||||||
|         //emit mouseSignal(0, charColumn + 1, charLine + 1, 0); |         } | ||||||
|     } else { |     } else if (button == Qt::MidButton) { | ||||||
|         _wordSelectionMode = true; |         processMidButtonClick(position, modifiers); | ||||||
|         extendSelection(pos); |     } else if (button == Qt::RightButton) { | ||||||
|  |         if (!_mouseMarks) | ||||||
|  |             emit mouseSignal(2, charColumn + 1, charLine + 1, 0); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| void KTerminalDisplay::mouseRelease(qreal x, qreal 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; | ||||||
|  |  | ||||||
|  |     int charLine = 0; | ||||||
|  |     int charColumn = 0; | ||||||
|  |     getCharacterPosition(position, charLine, charColumn); | ||||||
|  |  | ||||||
|  |     // 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); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 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; | ||||||
|  |  | ||||||
|  |     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); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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; | ||||||
|  |  | ||||||
|  |     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); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 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; |         _actSel = 0; | ||||||
|  |  | ||||||
|     if(_mouseMarks){ |         //FIXME: emits a release event even if the mouse is | ||||||
|         int charLine; |         //       outside the range. The procedure used in `mouseMoveEvent' | ||||||
|         int charColumn; |         //       applies here, too. | ||||||
|         getCharacterPosition(QPoint(x,y), charLine, charColumn); |  | ||||||
|  |  | ||||||
|         emit mouseSignal(0, charColumn + 1, charLine + 1, 2); |         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){ | void KTerminalDisplay::setUsesMouse(bool usesMouse){ | ||||||
|     _mouseMarks = !usesMouse; |     _mouseMarks = usesMouse; | ||||||
|  |     emit usesMouseChanged(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool KTerminalDisplay::getUsesMouse(){ | ||||||
|  |     return !_mouseMarks; | ||||||
| } | } | ||||||
|  |  | ||||||
| void KTerminalDisplay::setAutoFocus(bool au) | void KTerminalDisplay::setAutoFocus(bool au) | ||||||
| @@ -1361,16 +1651,33 @@ void KTerminalDisplay::updateLineProperties() | |||||||
|     _lineProperties = _screenWindow->getLineProperties(); |     _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 ) ) |         if (qch.isLetterOrNumber() || _wordCharacters.contains(qch, Qt::CaseInsensitive)) | ||||||
|             return 'a'; |             return 'a'; | ||||||
|  |  | ||||||
|         return qch; |         return qch; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| void KTerminalDisplay::setWordCharacters(const QString& wc) | void KTerminalDisplay::setWordCharacters(const QString& wc) | ||||||
| { | { | ||||||
|     _wordCharacters = wc; |     _wordCharacters = wc; | ||||||
|   | |||||||
| @@ -70,6 +70,7 @@ class KONSOLEPRIVATE_EXPORT KTerminalDisplay : public QQuickPaintedItem | |||||||
|     Q_PROPERTY(bool ShowIMEOnClick     READ autoVKB         WRITE setAutoVKB     NOTIFY changedAutoVKB) |     Q_PROPERTY(bool ShowIMEOnClick     READ autoVKB         WRITE setAutoVKB     NOTIFY changedAutoVKB) | ||||||
|     Q_PROPERTY(QSize terminalSize      READ getTerminalSize                      NOTIFY terminalSizeChanged) |     Q_PROPERTY(QSize terminalSize      READ getTerminalSize                      NOTIFY terminalSizeChanged) | ||||||
|     Q_PROPERTY(QSize paintedFontSize   READ getFontSize                          NOTIFY paintedFontSizeChanged) |     Q_PROPERTY(QSize paintedFontSize   READ getFontSize                          NOTIFY paintedFontSizeChanged) | ||||||
|  |     Q_PROPERTY(bool usesMouse          READ getUsesMouse                         NOTIFY usesMouseChanged) | ||||||
|  |  | ||||||
|  |  | ||||||
| public: | public: | ||||||
| @@ -311,15 +312,10 @@ public slots: | |||||||
|     void setColorScheme(const QString &name); |     void setColorScheme(const QString &name); | ||||||
|     QStringList availableColorSchemes(); |     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 scrollScreenWindow(enum ScreenWindow::RelativeScrollMode mode, int amount); | ||||||
|  |  | ||||||
|     void setUsesMouse(bool usesMouse); |     void setUsesMouse(bool usesMouse); | ||||||
|  |     bool getUsesMouse(void); | ||||||
|  |  | ||||||
|     bool autoFocus() { return m_focusOnClick; } |     bool autoFocus() { return m_focusOnClick; } | ||||||
|     void setAutoFocus(bool au); |     void setAutoFocus(bool au); | ||||||
| @@ -425,6 +421,8 @@ signals: | |||||||
|  |  | ||||||
|     void mouseSignal(int,int,int,int); |     void mouseSignal(int,int,int,int); | ||||||
|  |  | ||||||
|  |     void usesMouseChanged(); | ||||||
|  |  | ||||||
|     void terminalSizeChanged(); |     void terminalSizeChanged(); | ||||||
|     void paintedFontSizeChanged(); |     void paintedFontSizeChanged(); | ||||||
|  |  | ||||||
| @@ -477,7 +475,11 @@ protected: | |||||||
|     void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); |     void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); | ||||||
|     QRect geometryRound(const QRectF &r) const; |     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 mouseReleaseEvent( QMouseEvent* ); | ||||||
|     //void mouseMoveEvent( QMouseEvent* ); |     //void mouseMoveEvent( QMouseEvent* ); | ||||||
|  |  | ||||||
| @@ -497,7 +499,7 @@ protected: | |||||||
|     //     - A space (returns ' ') |     //     - A space (returns ' ') | ||||||
|     //     - Part of a word (returns 'a') |     //     - Part of a word (returns 'a') | ||||||
|     //     - Other characters (returns the input character) |     //     - Other characters (returns the input character) | ||||||
|     QChar charClass(QChar ch) const; |     QChar charClass(const Character& ch) const; | ||||||
|  |  | ||||||
|     void clearImage(); |     void clearImage(); | ||||||
|  |  | ||||||
| @@ -594,6 +596,14 @@ private: | |||||||
|     // redraws the cursor |     // redraws the cursor | ||||||
|     void updateCursor(); |     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); |     bool handleShortcutOverrideEvent(QKeyEvent* event); | ||||||
|     ///////////////////////////////////////////////////////////////////////////////////// |     ///////////////////////////////////////////////////////////////////////////////////// | ||||||
|     ///////////////////////////////////////////////////////////////////////////////////// |     ///////////////////////////////////////////////////////////////////////////////////// | ||||||
|   | |||||||
| @@ -23,37 +23,47 @@ | |||||||
| // Own | // Own | ||||||
| #include "Vt102Emulation.h" | #include "Vt102Emulation.h" | ||||||
|  |  | ||||||
| // XKB |  | ||||||
| //#include <config-konsole.h> |  | ||||||
|  |  | ||||||
| // this allows konsole to be compiled without XKB and XTEST extensions |  | ||||||
| // even though it might be available on a particular system. |  | ||||||
| #if defined(AVOID_XKB) |  | ||||||
|     #undef HAVE_XKB |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #if defined(HAVE_XKB) |  | ||||||
|     void scrolllock_set_off(); |  | ||||||
|     void scrolllock_set_on(); |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| // Standard | // Standard | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| #include <assert.h> |  | ||||||
|  |  | ||||||
| // Qt | // Qt | ||||||
| #include <QtCore/QEvent> | #include <QtCore/QEvent> | ||||||
|  | #include <QtCore/QTimer> | ||||||
| #include <QtGui/QKeyEvent> | #include <QtGui/QKeyEvent> | ||||||
| #include <QtCore/QByteRef> |  | ||||||
|  |  | ||||||
| // KDE | // KDE | ||||||
| //#include <kdebug.h> | //#include <KLocalizedString> | ||||||
| //#include <klocale.h> | //#include <KDebug> | ||||||
|  |  | ||||||
| // Konsole | // Konsole | ||||||
| #include "KeyboardTranslator.h" | #include "KeyboardTranslator.h" | ||||||
| #include "Screen.h" | #include "Screen.h" | ||||||
|  | #include "TerminalDisplay.h" | ||||||
|  |  | ||||||
|  | using Konsole::Vt102Emulation; | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |    The VT100 has 32 special graphical characters. The usual vt100 extended | ||||||
|  |    xterm fonts have these at 0x00..0x1f. | ||||||
|  |  | ||||||
|  |    QT's iso mapping leaves 0x00..0x7f without any changes. But the graphicals | ||||||
|  |    come in here as proper unicode characters. | ||||||
|  |  | ||||||
|  |    We treat non-iso10646 fonts as VT100 extended and do the required mapping | ||||||
|  |    from unicode to 0x00..0x1f. The remaining translation is then left to the | ||||||
|  |    QCodec. | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | // assert for i in [0..31] : vt100extended(vt100_graphics[i]) == i. | ||||||
|  |  | ||||||
|  | unsigned short Konsole::vt100_graphics[32] = { | ||||||
|  |     // 0/8     1/9    2/10    3/11    4/12    5/13    6/14    7/15 | ||||||
|  |     0x0020, 0x25C6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, | ||||||
|  |     0x00b1, 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, | ||||||
|  |     0xF800, 0xF801, 0x2500, 0xF803, 0xF804, 0x251c, 0x2524, 0x2534, | ||||||
|  |     0x252c, 0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00b7 | ||||||
|  | }; | ||||||
|  |  | ||||||
| Vt102Emulation::Vt102Emulation() | Vt102Emulation::Vt102Emulation() | ||||||
|     : Emulation(), |     : Emulation(), | ||||||
| @@ -77,12 +87,20 @@ void Vt102Emulation::clearEntireScreen() | |||||||
|  |  | ||||||
| void Vt102Emulation::reset() | void Vt102Emulation::reset() | ||||||
| { | { | ||||||
|  |     // Save the current codec so we can set it later. | ||||||
|  |     // Ideally we would want to use the profile setting | ||||||
|  |     const QTextCodec* currentCodec = codec(); | ||||||
|  |  | ||||||
|     resetTokenizer(); |     resetTokenizer(); | ||||||
|     resetModes(); |     resetModes(); | ||||||
|     resetCharset(0); |     resetCharset(0); | ||||||
|     _screen[0]->reset(); |     _screen[0]->reset(); | ||||||
|     resetCharset(1); |     resetCharset(1); | ||||||
|     _screen[1]->reset(); |     _screen[1]->reset(); | ||||||
|  |  | ||||||
|  |     if (currentCodec) | ||||||
|  |         setCodec(currentCodec); | ||||||
|  |     else | ||||||
|         setCodec(LocaleCodec); |         setCodec(LocaleCodec); | ||||||
|  |  | ||||||
|     bufferedUpdate(); |     bufferedUpdate(); | ||||||
| @@ -142,7 +160,7 @@ void Vt102Emulation::reset() | |||||||
|    The last two forms allow list of arguments. Since the elements of |    The last two forms allow list of arguments. Since the elements of | ||||||
|    the lists are treated individually the same way, they are passed |    the lists are treated individually the same way, they are passed | ||||||
|    as individual tokens to the interpretation. Further, because the |    as individual tokens to the interpretation. Further, because the | ||||||
|    meaning of the parameters are names (althought represented as numbers), |    meaning of the parameters are names (although represented as numbers), | ||||||
|    they are includes within the token ('N'). |    they are includes within the token ('N'). | ||||||
|  |  | ||||||
| */ | */ | ||||||
| @@ -162,7 +180,7 @@ void Vt102Emulation::reset() | |||||||
| #define TY_CSI_PG(A)  TY_CONSTRUCT(9,A,0) | #define TY_CSI_PG(A)  TY_CONSTRUCT(9,A,0) | ||||||
| #define TY_CSI_PE(A)  TY_CONSTRUCT(10,A,0) | #define TY_CSI_PE(A)  TY_CONSTRUCT(10,A,0) | ||||||
|  |  | ||||||
| #define MAX_ARGUMENT 4096 | const int MAX_ARGUMENT = 4096; | ||||||
|  |  | ||||||
| // Tokenizer --------------------------------------------------------------- -- | // Tokenizer --------------------------------------------------------------- -- | ||||||
|  |  | ||||||
| @@ -184,52 +202,50 @@ void Vt102Emulation::resetTokenizer() | |||||||
| void Vt102Emulation::addDigit(int digit) | void Vt102Emulation::addDigit(int digit) | ||||||
| { | { | ||||||
|     if (argv[argc] < MAX_ARGUMENT) |     if (argv[argc] < MAX_ARGUMENT) | ||||||
|       argv[argc] = 10*argv[argc] + digit; |         argv[argc] = 10 * argv[argc] + digit; | ||||||
| } | } | ||||||
|  |  | ||||||
| void Vt102Emulation::addArgument() | void Vt102Emulation::addArgument() | ||||||
| { | { | ||||||
|   argc = qMin(argc+1,MAXARGS-1); |     argc = qMin(argc + 1, MAXARGS - 1); | ||||||
|     argv[argc] = 0; |     argv[argc] = 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| void Vt102Emulation::addToCurrentToken(int cc) | void Vt102Emulation::addToCurrentToken(int cc) | ||||||
| { | { | ||||||
|     tokenBuffer[tokenBufferPos] = cc; |     tokenBuffer[tokenBufferPos] = cc; | ||||||
|   tokenBufferPos = qMin(tokenBufferPos+1,MAX_TOKEN_LENGTH-1); |     tokenBufferPos = qMin(tokenBufferPos + 1, MAX_TOKEN_LENGTH - 1); | ||||||
| } | } | ||||||
|  |  | ||||||
| // Character Class flags used while decoding | // Character Class flags used while decoding | ||||||
|  | const int CTL =  1;  // Control character | ||||||
| #define CTL  1  // Control character | const int CHR =  2;  // Printable character | ||||||
| #define CHR  2  // Printable character | const int CPN =  4;  // TODO: Document me | ||||||
| #define CPN  4  // TODO: Document me  | const int DIG =  8;  // Digit | ||||||
| #define DIG  8  // Digit | const int SCS = 16;  // Select Character Set | ||||||
| #define SCS 16  // TODO: Document me   | const int GRP = 32;  // TODO: Document me | ||||||
| #define GRP 32  // TODO: Document me | const int CPS = 64;  // Character which indicates end of window resize | ||||||
| #define CPS 64  // Character which indicates end of window resize |  | ||||||
|                 // escape sequence '\e[8;<row>;<col>t' |  | ||||||
|  |  | ||||||
| void Vt102Emulation::initTokenizer() | void Vt102Emulation::initTokenizer() | ||||||
| { | { | ||||||
|     int i; |     int i; | ||||||
|     quint8* s; |     quint8* s; | ||||||
|   for(i = 0;i < 256; ++i)  |     for (i = 0; i < 256; ++i) | ||||||
|         charClass[i] = 0; |         charClass[i] = 0; | ||||||
|   for(i = 0;i < 32; ++i)  |     for (i = 0; i < 32; ++i) | ||||||
|         charClass[i] |= CTL; |         charClass[i] |= CTL; | ||||||
|   for(i = 32;i < 256; ++i)  |     for (i = 32; i < 256; ++i) | ||||||
|         charClass[i] |= CHR; |         charClass[i] |= CHR; | ||||||
|   for(s = (quint8*)"@ABCDGHILMPSTXZcdfry"; *s; ++s)  |     for (s = (quint8*)"@ABCDGHILMPSTXZcdfry"; *s; ++s) | ||||||
|         charClass[*s] |= CPN; |         charClass[*s] |= CPN; | ||||||
|     // resize = \e[8;<row>;<col>t |     // resize = \e[8;<row>;<col>t | ||||||
|   for(s = (quint8*)"t"; *s; ++s)  |     for (s = (quint8*)"t"; *s; ++s) | ||||||
|         charClass[*s] |= CPS; |         charClass[*s] |= CPS; | ||||||
|   for(s = (quint8*)"0123456789"; *s; ++s)  |     for (s = (quint8*)"0123456789"; *s; ++s) | ||||||
|         charClass[*s] |= DIG; |         charClass[*s] |= DIG; | ||||||
|   for(s = (quint8*)"()+*%"; *s; ++s)  |     for (s = (quint8*)"()+*%"; *s; ++s) | ||||||
|         charClass[*s] |= SCS; |         charClass[*s] |= SCS; | ||||||
|   for(s = (quint8*)"()+*#[]%"; *s; ++s)  |     for (s = (quint8*)"()+*#[]%"; *s; ++s) | ||||||
|         charClass[*s] |= GRP; |         charClass[*s] |= GRP; | ||||||
|  |  | ||||||
|     resetTokenizer(); |     resetTokenizer(); | ||||||
| @@ -267,13 +283,14 @@ void Vt102Emulation::initTokenizer() | |||||||
| #define Xte        (Xpe      && cc ==  7 ) | #define Xte        (Xpe      && cc ==  7 ) | ||||||
| #define ces(C)     (cc < 256 && (charClass[cc] & (C)) == (C) && !Xte) | #define ces(C)     (cc < 256 && (charClass[cc] & (C)) == (C) && !Xte) | ||||||
|  |  | ||||||
| #define ESC 27 |  | ||||||
| #define CNTL(c) ((c)-'@') | #define CNTL(c) ((c)-'@') | ||||||
|  | const int ESC = 27; | ||||||
|  | const int DEL = 127; | ||||||
|  |  | ||||||
| // process an incoming unicode character | // process an incoming unicode character | ||||||
| void Vt102Emulation::receiveChar(int cc) | void Vt102Emulation::receiveChar(int cc) | ||||||
| { | { | ||||||
|   if (cc == 127)  |   if (cc == DEL) | ||||||
|     return; //VT100: ignore. |     return; //VT100: ignore. | ||||||
|  |  | ||||||
|   if (ces(CTL)) |   if (ces(CTL)) | ||||||
| @@ -294,7 +311,7 @@ void Vt102Emulation::receiveChar(int cc) | |||||||
|   addToCurrentToken(cc); |   addToCurrentToken(cc); | ||||||
|  |  | ||||||
|   int* s = tokenBuffer; |   int* s = tokenBuffer; | ||||||
|   int  p = tokenBufferPos; |   const int  p = tokenBufferPos; | ||||||
|  |  | ||||||
|   if (getMode(MODE_Ansi)) |   if (getMode(MODE_Ansi)) | ||||||
|   { |   { | ||||||
| @@ -323,27 +340,27 @@ void Vt102Emulation::receiveChar(int cc) | |||||||
|     if (epe(   )) { processToken( TY_CSI_PE(cc), 0, 0); resetTokenizer(); return; } |     if (epe(   )) { processToken( TY_CSI_PE(cc), 0, 0); resetTokenizer(); return; } | ||||||
|     if (ees(DIG)) { addDigit(cc-'0'); return; } |     if (ees(DIG)) { addDigit(cc-'0'); return; } | ||||||
|     if (eec(';')) { addArgument();    return; } |     if (eec(';')) { addArgument();    return; } | ||||||
|     for (int i=0;i<=argc;i++) |     for (int i = 0; i <= argc; i++) | ||||||
|     { |     { | ||||||
|         if (epp()) |         if (epp()) | ||||||
|             processToken( TY_CSI_PR(cc,argv[i]), 0, 0); |             processToken(TY_CSI_PR(cc,argv[i]), 0, 0); | ||||||
|         else if (egt()) |         else if (egt()) | ||||||
|             processToken( TY_CSI_PG(cc), 0, 0); // spec. case for ESC]>0c or ESC]>c |             processToken(TY_CSI_PG(cc), 0, 0); // spec. case for ESC]>0c or ESC]>c | ||||||
|         else if (cc == 'm' && argc - i >= 4 && (argv[i] == 38 || argv[i] == 48) && argv[i+1] == 2) |         else if (cc == 'm' && argc - i >= 4 && (argv[i] == 38 || argv[i] == 48) && argv[i+1] == 2) | ||||||
|         { |         { | ||||||
|             // ESC[ ... 48;2;<red>;<green>;<blue> ... m -or- ESC[ ... 38;2;<red>;<green>;<blue> ... m |             // ESC[ ... 48;2;<red>;<green>;<blue> ... m -or- ESC[ ... 38;2;<red>;<green>;<blue> ... m | ||||||
|             i += 2; |             i += 2; | ||||||
|             processToken( TY_CSI_PS(cc, argv[i-2]), COLOR_SPACE_RGB, (argv[i] << 16) | (argv[i+1] << 8) | argv[i+2]); |             processToken(TY_CSI_PS(cc, argv[i-2]), COLOR_SPACE_RGB, (argv[i] << 16) | (argv[i+1] << 8) | argv[i+2]); | ||||||
|             i += 2; |             i += 2; | ||||||
|         } |         } | ||||||
|         else if (cc == 'm' && argc - i >= 2 && (argv[i] == 38 || argv[i] == 48) && argv[i+1] == 5) |         else if (cc == 'm' && argc - i >= 2 && (argv[i] == 38 || argv[i] == 48) && argv[i+1] == 5) | ||||||
|         { |         { | ||||||
|             // ESC[ ... 48;5;<index> ... m -or- ESC[ ... 38;5;<index> ... m |             // ESC[ ... 48;5;<index> ... m -or- ESC[ ... 38;5;<index> ... m | ||||||
|             i += 2; |             i += 2; | ||||||
|             processToken( TY_CSI_PS(cc, argv[i-2]), COLOR_SPACE_256, argv[i]); |             processToken(TY_CSI_PS(cc, argv[i-2]), COLOR_SPACE_256, argv[i]); | ||||||
|         } |         } | ||||||
|         else |         else | ||||||
|             processToken( TY_CSI_PS(cc,argv[i]), 0, 0); |             processToken(TY_CSI_PS(cc,argv[i]), 0, 0); | ||||||
|     } |     } | ||||||
|     resetTokenizer(); |     resetTokenizer(); | ||||||
|   } |   } | ||||||
| @@ -364,11 +381,11 @@ void Vt102Emulation::receiveChar(int cc) | |||||||
|         return; |         return; | ||||||
|     if (p < 4) |     if (p < 4) | ||||||
|     { |     { | ||||||
|         processToken( TY_VT52(s[1] ), 0, 0);  |         processToken(TY_VT52(s[1] ), 0, 0); | ||||||
|         resetTokenizer(); |         resetTokenizer(); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     processToken( TY_VT52(s[1]), s[2], s[3]);  |     processToken(TY_VT52(s[1]), s[2], s[3]); | ||||||
|     resetTokenizer(); |     resetTokenizer(); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
| @@ -418,7 +435,7 @@ void Vt102Emulation::updateTitle() | |||||||
|    meaning is assigned to them. These are either operations of |    meaning is assigned to them. These are either operations of | ||||||
|    the current _screen, or of the emulation class itself. |    the current _screen, or of the emulation class itself. | ||||||
|  |  | ||||||
|    The token to be interpreteted comes in as a machine word |    The token to be interpreted comes in as a machine word | ||||||
|    possibly accompanied by two parameters. |    possibly accompanied by two parameters. | ||||||
|  |  | ||||||
|    Likewise, the operations assigned to, come with up to two |    Likewise, the operations assigned to, come with up to two | ||||||
| @@ -433,7 +450,6 @@ void Vt102Emulation::processToken(int token, int p, int q) | |||||||
| { | { | ||||||
|   switch (token) |   switch (token) | ||||||
|   { |   { | ||||||
|  |  | ||||||
|     case TY_CHR(         ) : _currentScreen->displayCharacter     (p         ); break; //UTF16 |     case TY_CHR(         ) : _currentScreen->displayCharacter     (p         ); break; //UTF16 | ||||||
|  |  | ||||||
|     //             127 DEL    : ignored on input |     //             127 DEL    : ignored on input | ||||||
| @@ -528,7 +544,9 @@ void Vt102Emulation::processToken(int token, int p, int q) | |||||||
|     case TY_ESC_DE('8'      ) : _currentScreen->helpAlign            (          ); break; |     case TY_ESC_DE('8'      ) : _currentScreen->helpAlign            (          ); break; | ||||||
|  |  | ||||||
| // resize = \e[8;<row>;<col>t | // resize = \e[8;<row>;<col>t | ||||||
|     case TY_CSI_PS('t',   8) : setImageSize( q /* columns */, p /* lines */ );    break; |     case TY_CSI_PS('t',   8) : setImageSize( p /*lines */, q /* columns */ ); | ||||||
|  |                                emit imageResizeRequest(QSize(q, p)); | ||||||
|  |                                break; | ||||||
|  |  | ||||||
| // change tab text color : \e[28;<color>t  color: 0-16,777,215 | // change tab text color : \e[28;<color>t  color: 0-16,777,215 | ||||||
|     case TY_CSI_PS('t',   28) : emit changeTabTextColorRequest      ( p        );          break; |     case TY_CSI_PS('t',   28) : emit changeTabTextColorRequest      ( p        );          break; | ||||||
| @@ -552,6 +570,7 @@ void Vt102Emulation::processToken(int token, int p, int q) | |||||||
|  |  | ||||||
|     case TY_CSI_PS('m',   0) : _currentScreen->setDefaultRendition  (          ); break; |     case TY_CSI_PS('m',   0) : _currentScreen->setDefaultRendition  (          ); break; | ||||||
|     case TY_CSI_PS('m',   1) : _currentScreen->  setRendition     (RE_BOLD     ); break; //VT100 |     case TY_CSI_PS('m',   1) : _currentScreen->  setRendition     (RE_BOLD     ); break; //VT100 | ||||||
|  |     //case TY_CSI_PS('m',   3) : _currentScreen->  setRendition     (RE_ITALIC   ); break; //VT100 | ||||||
|     case TY_CSI_PS('m',   4) : _currentScreen->  setRendition     (RE_UNDERLINE); break; //VT100 |     case TY_CSI_PS('m',   4) : _currentScreen->  setRendition     (RE_UNDERLINE); break; //VT100 | ||||||
|     case TY_CSI_PS('m',   5) : _currentScreen->  setRendition     (RE_BLINK    ); break; //VT100 |     case TY_CSI_PS('m',   5) : _currentScreen->  setRendition     (RE_BLINK    ); break; //VT100 | ||||||
|     case TY_CSI_PS('m',   7) : _currentScreen->  setRendition     (RE_REVERSE  ); break; |     case TY_CSI_PS('m',   7) : _currentScreen->  setRendition     (RE_REVERSE  ); break; | ||||||
| @@ -559,6 +578,7 @@ void Vt102Emulation::processToken(int token, int p, int q) | |||||||
|     case TY_CSI_PS('m',  11) : /* IGNORED: mapping related          */ break; //LINUX |     case TY_CSI_PS('m',  11) : /* IGNORED: mapping related          */ break; //LINUX | ||||||
|     case TY_CSI_PS('m',  12) : /* IGNORED: mapping related          */ break; //LINUX |     case TY_CSI_PS('m',  12) : /* IGNORED: mapping related          */ break; //LINUX | ||||||
|     case TY_CSI_PS('m',  22) : _currentScreen->resetRendition     (RE_BOLD     ); break; |     case TY_CSI_PS('m',  22) : _currentScreen->resetRendition     (RE_BOLD     ); break; | ||||||
|  |     //case TY_CSI_PS('m',  23) : _currentScreen->resetRendition     (RE_ITALIC   ); break; //VT100 | ||||||
|     case TY_CSI_PS('m',  24) : _currentScreen->resetRendition     (RE_UNDERLINE); break; |     case TY_CSI_PS('m',  24) : _currentScreen->resetRendition     (RE_UNDERLINE); break; | ||||||
|     case TY_CSI_PS('m',  25) : _currentScreen->resetRendition     (RE_BLINK    ); break; |     case TY_CSI_PS('m',  25) : _currentScreen->resetRendition     (RE_BLINK    ); break; | ||||||
|     case TY_CSI_PS('m',  27) : _currentScreen->resetRendition     (RE_REVERSE  ); break; |     case TY_CSI_PS('m',  27) : _currentScreen->resetRendition     (RE_REVERSE  ); break; | ||||||
| @@ -622,6 +642,8 @@ void Vt102Emulation::processToken(int token, int p, int q) | |||||||
|     case TY_CSI_PN('B'      ) : _currentScreen->cursorDown           (p         ); break; //VT100 |     case TY_CSI_PN('B'      ) : _currentScreen->cursorDown           (p         ); break; //VT100 | ||||||
|     case TY_CSI_PN('C'      ) : _currentScreen->cursorRight          (p         ); break; //VT100 |     case TY_CSI_PN('C'      ) : _currentScreen->cursorRight          (p         ); break; //VT100 | ||||||
|     case TY_CSI_PN('D'      ) : _currentScreen->cursorLeft           (p         ); break; //VT100 |     case TY_CSI_PN('D'      ) : _currentScreen->cursorLeft           (p         ); break; //VT100 | ||||||
|  |     case TY_CSI_PN('E'      ) : /* Not implemented: cursor next p lines */         break; //VT100 | ||||||
|  |     case TY_CSI_PN('F'      ) : /* Not implemented: cursor preceding p lines */    break; //VT100 | ||||||
|     case TY_CSI_PN('G'      ) : _currentScreen->setCursorX           (p         ); break; //LINUX |     case TY_CSI_PN('G'      ) : _currentScreen->setCursorX           (p         ); break; //LINUX | ||||||
|     case TY_CSI_PN('H'      ) : _currentScreen->setCursorYX          (p,      q); break; //VT100 |     case TY_CSI_PN('H'      ) : _currentScreen->setCursorYX          (p,      q); break; //VT100 | ||||||
|     case TY_CSI_PN('I'      ) : _currentScreen->tab                  (p         ); break; |     case TY_CSI_PN('I'      ) : _currentScreen->tab                  (p         ); break; | ||||||
| @@ -645,8 +667,8 @@ void Vt102Emulation::processToken(int token, int p, int q) | |||||||
|  |  | ||||||
|     case TY_CSI_PR('l',   2) :        resetMode      (MODE_Ansi     ); break; //VT100 |     case TY_CSI_PR('l',   2) :        resetMode      (MODE_Ansi     ); break; //VT100 | ||||||
|  |  | ||||||
|     case TY_CSI_PR('h',   3) :          setMode      (MODE_132Columns);break; //VT100 |     case TY_CSI_PR('h',   3) :          setMode      (MODE_132Columns); break; //VT100 | ||||||
|     case TY_CSI_PR('l',   3) :        resetMode      (MODE_132Columns);break; //VT100 |     case TY_CSI_PR('l',   3) :        resetMode      (MODE_132Columns); break; //VT100 | ||||||
|  |  | ||||||
|     case TY_CSI_PR('h',   4) : /* IGNORED: soft scrolling           */ break; //VT100 |     case TY_CSI_PR('h',   4) : /* IGNORED: soft scrolling           */ break; //VT100 | ||||||
|     case TY_CSI_PR('l',   4) : /* IGNORED: soft scrolling           */ break; //VT100 |     case TY_CSI_PR('l',   4) : /* IGNORED: soft scrolling           */ break; //VT100 | ||||||
| @@ -736,6 +758,21 @@ void Vt102Emulation::processToken(int token, int p, int q) | |||||||
|     case TY_CSI_PR('s', 1003) :         saveMode      (MODE_Mouse1003); break; //XTERM |     case TY_CSI_PR('s', 1003) :         saveMode      (MODE_Mouse1003); break; //XTERM | ||||||
|     case TY_CSI_PR('r', 1003) :      restoreMode      (MODE_Mouse1003); break; //XTERM |     case TY_CSI_PR('r', 1003) :      restoreMode      (MODE_Mouse1003); break; //XTERM | ||||||
|  |  | ||||||
|  |     case TY_CSI_PR('h', 1005) :          setMode      (MODE_Mouse1005); break; //XTERM | ||||||
|  |     case TY_CSI_PR('l', 1005) :        resetMode      (MODE_Mouse1005); break; //XTERM | ||||||
|  |     case TY_CSI_PR('s', 1005) :         saveMode      (MODE_Mouse1005); break; //XTERM | ||||||
|  |     case TY_CSI_PR('r', 1005) :      restoreMode      (MODE_Mouse1005); break; //XTERM | ||||||
|  |  | ||||||
|  |     case TY_CSI_PR('h', 1006) :          setMode      (MODE_Mouse1006); break; //XTERM | ||||||
|  |     case TY_CSI_PR('l', 1006) :        resetMode      (MODE_Mouse1006); break; //XTERM | ||||||
|  |     case TY_CSI_PR('s', 1006) :         saveMode      (MODE_Mouse1006); break; //XTERM | ||||||
|  |     case TY_CSI_PR('r', 1006) :      restoreMode      (MODE_Mouse1006); break; //XTERM | ||||||
|  |  | ||||||
|  |     case TY_CSI_PR('h', 1015) :          setMode      (MODE_Mouse1015); break; //URXVT | ||||||
|  |     case TY_CSI_PR('l', 1015) :        resetMode      (MODE_Mouse1015); break; //URXVT | ||||||
|  |     case TY_CSI_PR('s', 1015) :         saveMode      (MODE_Mouse1015); break; //URXVT | ||||||
|  |     case TY_CSI_PR('r', 1015) :      restoreMode      (MODE_Mouse1015); break; //URXVT | ||||||
|  |  | ||||||
|     case TY_CSI_PR('h', 1034) : /* IGNORED: 8bitinput activation     */ break; //XTERM |     case TY_CSI_PR('h', 1034) : /* IGNORED: 8bitinput activation     */ break; //XTERM | ||||||
|  |  | ||||||
|     case TY_CSI_PR('h', 1047) :          setMode      (MODE_AppScreen); break; //XTERM |     case TY_CSI_PR('h', 1047) :          setMode      (MODE_AppScreen); break; //XTERM | ||||||
| @@ -754,6 +791,11 @@ void Vt102Emulation::processToken(int token, int p, int q) | |||||||
|     case TY_CSI_PR('h', 1049) : saveCursor(); _screen[1]->clearEntireScreen(); setMode(MODE_AppScreen); break; //XTERM |     case TY_CSI_PR('h', 1049) : saveCursor(); _screen[1]->clearEntireScreen(); setMode(MODE_AppScreen); break; //XTERM | ||||||
|     case TY_CSI_PR('l', 1049) : resetMode(MODE_AppScreen); restoreCursor(); break; //XTERM |     case TY_CSI_PR('l', 1049) : resetMode(MODE_AppScreen); restoreCursor(); break; //XTERM | ||||||
|  |  | ||||||
|  |     case TY_CSI_PR('h', 2004) :          setMode      (MODE_BracketedPaste); break; //XTERM | ||||||
|  |     case TY_CSI_PR('l', 2004) :        resetMode      (MODE_BracketedPaste); break; //XTERM | ||||||
|  |     case TY_CSI_PR('s', 2004) :         saveMode      (MODE_BracketedPaste); break; //XTERM | ||||||
|  |     case TY_CSI_PR('r', 2004) :      restoreMode      (MODE_BracketedPaste); break; //XTERM | ||||||
|  |  | ||||||
|     //FIXME: weird DEC reset sequence |     //FIXME: weird DEC reset sequence | ||||||
|     case TY_CSI_PE('p'      ) : /* IGNORED: reset         (        ) */ break; |     case TY_CSI_PE('p'      ) : /* IGNORED: reset         (        ) */ break; | ||||||
|  |  | ||||||
| @@ -797,13 +839,13 @@ void Vt102Emulation::sendString(const char* s , int length) | |||||||
|   if ( length >= 0 ) |   if ( length >= 0 ) | ||||||
|     emit sendData(s,length); |     emit sendData(s,length); | ||||||
|   else |   else | ||||||
|     emit sendData(s,strlen(s)); |     emit sendData(s,qstrlen(s)); | ||||||
| } | } | ||||||
|  |  | ||||||
| void Vt102Emulation::reportCursorPosition() | void Vt102Emulation::reportCursorPosition() | ||||||
| { | { | ||||||
|   char tmp[20]; |   char tmp[20]; | ||||||
|   sprintf(tmp,"\033[%d;%dR",_currentScreen->getCursorY()+1,_currentScreen->getCursorX()+1); |   snprintf(tmp, sizeof(tmp), "\033[%d;%dR", _currentScreen->getCursorY()+1, _currentScreen->getCursorX()+1); | ||||||
|   sendString(tmp); |   sendString(tmp); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -822,7 +864,7 @@ void Vt102Emulation::reportTerminalType() | |||||||
|  |  | ||||||
| void Vt102Emulation::reportSecondaryAttributes() | void Vt102Emulation::reportSecondaryAttributes() | ||||||
| { | { | ||||||
|   // Seconday device attribute response (Request was: ^[[>0c or ^[[>c) |   // Secondary device attribute response (Request was: ^[[>0c or ^[[>c) | ||||||
|   if (getMode(MODE_Ansi)) |   if (getMode(MODE_Ansi)) | ||||||
|     sendString("\033[>0;115;0c"); // Why 115?  ;) |     sendString("\033[>0;115;0c"); // Why 115?  ;) | ||||||
|   else |   else | ||||||
| @@ -830,11 +872,24 @@ void Vt102Emulation::reportSecondaryAttributes() | |||||||
|                                   // konsoles backward compatibility. |                                   // konsoles backward compatibility. | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* DECREPTPARM – Report Terminal Parameters | ||||||
|  |     ESC [ <sol>; <par>; <nbits>; <xspeed>; <rspeed>; <clkmul>; <flags> x | ||||||
|  |  | ||||||
|  |     http://vt100.net/docs/vt100-ug/chapter3.html | ||||||
|  | */ | ||||||
| void Vt102Emulation::reportTerminalParms(int p) | void Vt102Emulation::reportTerminalParms(int p) | ||||||
| // DECREPTPARM |  | ||||||
| { | { | ||||||
|   char tmp[100]; |   char tmp[100]; | ||||||
|   sprintf(tmp,"\033[%d;1;1;112;112;1;0x",p); // not really true. | /* | ||||||
|  |    sol=1: This message is a request; report in response to a request. | ||||||
|  |    par=1: No parity set | ||||||
|  |    nbits=1: 8 bits per character | ||||||
|  |    xspeed=112: 9600 | ||||||
|  |    rspeed=112: 9600 | ||||||
|  |    clkmul=1: The bit rate multiplier is 16. | ||||||
|  |    flags=0: None | ||||||
|  | */ | ||||||
|  |   snprintf(tmp, sizeof(tmp), "\033[%d;1;1;112;112;1;0x", p); // not really true. | ||||||
|   sendString(tmp); |   sendString(tmp); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -853,19 +908,24 @@ void Vt102Emulation::reportAnswerBack() | |||||||
|  |  | ||||||
| /*! | /*! | ||||||
|     `cx',`cy' are 1-based. |     `cx',`cy' are 1-based. | ||||||
|     `eventType' indicates the button pressed (0-2) |     `cb' indicates the button pressed or released (0-2) or scroll event (4-5). | ||||||
|                 or a general mouse release (3). |  | ||||||
|  |  | ||||||
|     eventType represents the kind of mouse action that occurred: |     eventType represents the kind of mouse action that occurred: | ||||||
|         0 = Mouse button press or release |         0 = Mouse button press | ||||||
|         1 = Mouse drag |         1 = Mouse drag | ||||||
|  |         2 = Mouse button release | ||||||
| */ | */ | ||||||
|  |  | ||||||
| void Vt102Emulation::sendMouseEvent( int cb, int cx, int cy , int eventType ) | void Vt102Emulation::sendMouseEvent(int cb, int cx, int cy , int eventType) | ||||||
| { | { | ||||||
|     if (cx < 1 || cy < 1) |     if (cx < 1 || cy < 1) | ||||||
|         return; |         return; | ||||||
|  |  | ||||||
|  |     // With the exception of the 1006 mode, button release is encoded in cb. | ||||||
|  |     // Note that if multiple extensions are enabled, the 1006 is used, so it's okay to check for only that. | ||||||
|  |     if (eventType == 2 && !getMode(MODE_Mouse1006)) | ||||||
|  |         cb = 3; | ||||||
|  |  | ||||||
|     // normal buttons are passed as 0x20 + button, |     // normal buttons are passed as 0x20 + button, | ||||||
|     // mouse wheel (buttons 4,5) as 0x5c + button |     // mouse wheel (buttons 4,5) as 0x5c + button | ||||||
|     if (cb >= 4) |     if (cb >= 4) | ||||||
| @@ -875,15 +935,35 @@ void Vt102Emulation::sendMouseEvent( int cb, int cx, int cy , int eventType ) | |||||||
|     if ((getMode(MODE_Mouse1002) || getMode(MODE_Mouse1003)) && eventType == 1) |     if ((getMode(MODE_Mouse1002) || getMode(MODE_Mouse1003)) && eventType == 1) | ||||||
|         cb += 0x20; //add 32 to signify motion event |         cb += 0x20; //add 32 to signify motion event | ||||||
|  |  | ||||||
|   char command[20]; |     char command[32]; | ||||||
|   sprintf(command,"\033[M%c%c%c",cb+0x20,cx+0x20,cy+0x20); |     command[0] = '\0'; | ||||||
|  |     // Check the extensions in decreasing order of preference. Encoding the release event above assumes that 1006 comes first. | ||||||
|  |     if (getMode(MODE_Mouse1006)) { | ||||||
|  |         snprintf(command, sizeof(command), "\033[<%d;%d;%d%c", cb, cx, cy, eventType == 2 ? 'm' : 'M'); | ||||||
|  |     } else if (getMode(MODE_Mouse1015)) { | ||||||
|  |         snprintf(command, sizeof(command), "\033[%d;%d;%dM", cb + 0x20, cx, cy); | ||||||
|  |     } else if (getMode(MODE_Mouse1005)) { | ||||||
|  |         if (cx <= 2015 && cy <= 2015) { | ||||||
|  |             // The xterm extension uses UTF-8 (up to 2 bytes) to encode | ||||||
|  |             // coordinate+32, no matter what the locale is. We could easily | ||||||
|  |             // convert manually, but QString can also do it for us. | ||||||
|  |             QChar coords[2]; | ||||||
|  |             coords[0] = cx + 0x20; | ||||||
|  |             coords[1] = cy + 0x20; | ||||||
|  |             QString coordsStr = QString(coords, 2); | ||||||
|  |             QByteArray utf8 = coordsStr.toUtf8(); | ||||||
|  |             snprintf(command, sizeof(command), "\033[M%c%s", cb + 0x20, (const char *)utf8); | ||||||
|  |         } | ||||||
|  |     } else if (cx <= 223 && cy <= 223) { | ||||||
|  |         snprintf(command, sizeof(command), "\033[M%c%c%c", cb + 0x20, cx + 0x20, cy + 0x20); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     sendString(command); |     sendString(command); | ||||||
| } | } | ||||||
|  |  | ||||||
| void Vt102Emulation::sendText( const QString& text ) | void Vt102Emulation::sendText(const QString& text) | ||||||
| { | { | ||||||
|   if (!text.isEmpty())  |     if (!text.isEmpty()) { | ||||||
|   { |  | ||||||
|         QKeyEvent event(QEvent::KeyPress, |         QKeyEvent event(QEvent::KeyPress, | ||||||
|                         0, |                         0, | ||||||
|                         Qt::NoModifier, |                         Qt::NoModifier, | ||||||
| @@ -891,35 +971,38 @@ void Vt102Emulation::sendText( const QString& text ) | |||||||
|         sendKeyEvent(&event); // expose as a big fat keypress event |         sendKeyEvent(&event); // expose as a big fat keypress event | ||||||
|     } |     } | ||||||
| } | } | ||||||
| void Vt102Emulation::sendKeyEvent( QKeyEvent* event ) | void Vt102Emulation::sendKeyEvent(QKeyEvent* event) | ||||||
| { | { | ||||||
|     Qt::KeyboardModifiers modifiers = event->modifiers(); |     const Qt::KeyboardModifiers modifiers = event->modifiers(); | ||||||
|     KeyboardTranslator::States states = KeyboardTranslator::NoState; |     KeyboardTranslator::States states = KeyboardTranslator::NoState; | ||||||
|  |  | ||||||
|     // get current states |     // get current states | ||||||
|     if (getMode(MODE_NewLine)  ) states |= KeyboardTranslator::NewLineState; |     if (getMode(MODE_NewLine)) states |= KeyboardTranslator::NewLineState; | ||||||
|     if (getMode(MODE_Ansi)     ) states |= KeyboardTranslator::AnsiState; |     if (getMode(MODE_Ansi)) states |= KeyboardTranslator::AnsiState; | ||||||
|     if (getMode(MODE_AppCuKeys)) states |= KeyboardTranslator::CursorKeysState; |     if (getMode(MODE_AppCuKeys)) states |= KeyboardTranslator::CursorKeysState; | ||||||
|     if (getMode(MODE_AppScreen)) states |= KeyboardTranslator::AlternateScreenState; |     if (getMode(MODE_AppScreen)) states |= KeyboardTranslator::AlternateScreenState; | ||||||
|     if (getMode(MODE_AppKeyPad) && (modifiers & Qt::KeypadModifier)) |     if (getMode(MODE_AppKeyPad) && (modifiers & Qt::KeypadModifier)) | ||||||
|         states |= KeyboardTranslator::ApplicationKeypadState; |         states |= KeyboardTranslator::ApplicationKeypadState; | ||||||
|  |  | ||||||
|     // check flow control state |     // check flow control state | ||||||
|     if (modifiers & Qt::ControlModifier) |     if (modifiers & Qt::ControlModifier) { | ||||||
|     { |         switch (event->key()) { | ||||||
|         if (event->key() == Qt::Key_S) |         case Qt::Key_S: | ||||||
|             emit flowControlKeyPressed(true); |             emit flowControlKeyPressed(true); | ||||||
|         else if (event->key() == Qt::Key_Q) |             break; | ||||||
|  |         case Qt::Key_Q: | ||||||
|  |         case Qt::Key_C: // cancel flow control | ||||||
|             emit flowControlKeyPressed(false); |             emit flowControlKeyPressed(false); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // lookup key binding |     // look up key binding | ||||||
|     if ( _keyTranslator ) |     if (_keyTranslator) { | ||||||
|     { |  | ||||||
|         KeyboardTranslator::Entry entry = _keyTranslator->findEntry( |         KeyboardTranslator::Entry entry = _keyTranslator->findEntry( | ||||||
|                                               event->key() , |                                               event->key() , | ||||||
|                                               modifiers, |                                               modifiers, | ||||||
|                                                 states ); |                                               states); | ||||||
|  |  | ||||||
|         // send result to terminal |         // send result to terminal | ||||||
|         QByteArray textToSend; |         QByteArray textToSend; | ||||||
| @@ -928,8 +1011,9 @@ void Vt102Emulation::sendKeyEvent( QKeyEvent* event ) | |||||||
|         // Alt+[Character] results in Esc+[Character] being sent |         // Alt+[Character] results in Esc+[Character] being sent | ||||||
|         // (unless there is an entry defined for this particular combination |         // (unless there is an entry defined for this particular combination | ||||||
|         //  in the keyboard modifier) |         //  in the keyboard modifier) | ||||||
|         bool wantsAltModifier = entry.modifiers() & entry.modifierMask() & Qt::AltModifier; |         const bool wantsAltModifier = entry.modifiers() & entry.modifierMask() & Qt::AltModifier; | ||||||
|         bool wantsAnyModifier = entry.state() &  |         const bool wantsMetaModifier = entry.modifiers() & entry.modifierMask() & Qt::MetaModifier; | ||||||
|  |         const bool wantsAnyModifier = entry.state() & | ||||||
|                                 entry.stateMask() & KeyboardTranslator::AnyModifierState; |                                 entry.stateMask() & KeyboardTranslator::AnyModifierState; | ||||||
|  |  | ||||||
|         if ( modifiers & Qt::AltModifier && !(wantsAltModifier || wantsAnyModifier) |         if ( modifiers & Qt::AltModifier && !(wantsAltModifier || wantsAnyModifier) | ||||||
| @@ -937,13 +1021,18 @@ void Vt102Emulation::sendKeyEvent( QKeyEvent* event ) | |||||||
|         { |         { | ||||||
|             textToSend.prepend("\033"); |             textToSend.prepend("\033"); | ||||||
|         } |         } | ||||||
|  |         if ( modifiers & Qt::MetaModifier && !(wantsMetaModifier || wantsAnyModifier) | ||||||
|  |              && !event->text().isEmpty() ) | ||||||
|  |         { | ||||||
|  |             textToSend.prepend("\030@s"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         if ( entry.command() != KeyboardTranslator::NoCommand ) |         if ( entry.command() != KeyboardTranslator::NoCommand ) | ||||||
|         { |         { | ||||||
|             KTerminalDisplay* currentView = _currentScreen->currentTerminalDisplay(); |             KTerminalDisplay * currentView = _currentScreen->currentTerminalDisplay(); | ||||||
|             if (entry.command() & KeyboardTranslator::EraseCommand) |             if (entry.command() & KeyboardTranslator::EraseCommand) { | ||||||
|                 textToSend += eraseChar(); |                 textToSend += eraseChar(); | ||||||
|             else if (entry.command() & KeyboardTranslator::ScrollPageUpCommand) |             } else if (entry.command() & KeyboardTranslator::ScrollPageUpCommand) | ||||||
|                 currentView->scrollScreenWindow(ScreenWindow::ScrollPages, -1); |                 currentView->scrollScreenWindow(ScreenWindow::ScrollPages, -1); | ||||||
|             else if (entry.command() & KeyboardTranslator::ScrollPageDownCommand) |             else if (entry.command() & KeyboardTranslator::ScrollPageDownCommand) | ||||||
|                 currentView->scrollScreenWindow(ScreenWindow::ScrollPages, 1); |                 currentView->scrollScreenWindow(ScreenWindow::ScrollPages, 1); | ||||||
| @@ -951,28 +1040,31 @@ void Vt102Emulation::sendKeyEvent( QKeyEvent* event ) | |||||||
|                 currentView->scrollScreenWindow(ScreenWindow::ScrollLines, -1); |                 currentView->scrollScreenWindow(ScreenWindow::ScrollLines, -1); | ||||||
|             else if (entry.command() & KeyboardTranslator::ScrollLineDownCommand) |             else if (entry.command() & KeyboardTranslator::ScrollLineDownCommand) | ||||||
|                 currentView->scrollScreenWindow(ScreenWindow::ScrollLines, 1); |                 currentView->scrollScreenWindow(ScreenWindow::ScrollLines, 1); | ||||||
|  | //            else if (entry.command() & KeyboardTranslator::ScrollUpToTopCommand) | ||||||
|             // TODO command handling | //                currentView->scrollScreenWindow(ScreenWindow::ScrollLines, | ||||||
|  | //                                                - currentView->screenWindow()->currentLine()); | ||||||
|  | //            else if (entry.command() & KeyboardTranslator::ScrollDownToBottomCommand) | ||||||
|  | //                currentView->scrollScreenWindow(ScreenWindow::ScrollLines, lineCount()); | ||||||
|         } |         } | ||||||
|         else if ( !entry.text().isEmpty() )  |         else if (!entry.text().isEmpty()) | ||||||
|         { |         { | ||||||
|             textToSend += _codec->fromUnicode(entry.text(true,modifiers)); |             textToSend += _codec->fromUnicode(entry.text(true,modifiers)); | ||||||
|         } |         } | ||||||
|         else |         else | ||||||
|             textToSend += _codec->fromUnicode(event->text()); |             textToSend += _codec->fromUnicode(event->text()); | ||||||
|  |  | ||||||
|         sendData( textToSend.constData() , textToSend.length() ); |         sendData(textToSend.constData(), textToSend.length()); | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|         // print an error message to the terminal if no key translator has been |         // print an error message to the terminal if no key translator has been | ||||||
|         // set |         // set | ||||||
|         QString translatorError =  tr("No keyboard translator available.  " | //        QString translatorError =  i18n("No keyboard translator available.  " | ||||||
|                                          "The information needed to convert key presses " | //                                         "The information needed to convert key presses " | ||||||
|                                          "into characters to send to the terminal "  | //                                         "into characters to send to the terminal " | ||||||
|                                          "is missing."); | //                                         "is missing."); | ||||||
|         reset(); |         reset(); | ||||||
|         receiveData( translatorError.toLatin1().constData() , translatorError.count() ); | //        receiveData(translatorError.toAscii().constData(), translatorError.count()); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1006,8 +1098,8 @@ void Vt102Emulation::sendKeyEvent( QKeyEvent* event ) | |||||||
|  |  | ||||||
| unsigned short Vt102Emulation::applyCharset(unsigned short c) | unsigned short Vt102Emulation::applyCharset(unsigned short c) | ||||||
| { | { | ||||||
|   if (CHARSET.graphic && 0x5f <= c && c <= 0x7e) return vt100_graphics[c-0x5f]; |     if (CHARSET.graphic && 0x5f <= c && c <= 0x7e) return vt100_graphics[c - 0x5f]; | ||||||
|   if (CHARSET.pound && c == '#' ) return 0xa3; //This mode is obsolete |     if (CHARSET.pound && c == '#') return 0xa3;  //This mode is obsolete | ||||||
|     return c; |     return c; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1022,7 +1114,7 @@ unsigned short Vt102Emulation::applyCharset(unsigned short c) | |||||||
| void Vt102Emulation::resetCharset(int scrno) | void Vt102Emulation::resetCharset(int scrno) | ||||||
| { | { | ||||||
|     _charset[scrno].cu_cs = 0; |     _charset[scrno].cu_cs = 0; | ||||||
|   strncpy(_charset[scrno].charset,"BBBB",4); |     qstrncpy(_charset[scrno].charset, "BBBB", 4); | ||||||
|     _charset[scrno].sa_graphic = false; |     _charset[scrno].sa_graphic = false; | ||||||
|     _charset[scrno].sa_pound = false; |     _charset[scrno].sa_pound = false; | ||||||
|     _charset[scrno].graphic = false; |     _charset[scrno].graphic = false; | ||||||
| @@ -1031,21 +1123,21 @@ void Vt102Emulation::resetCharset(int scrno) | |||||||
|  |  | ||||||
| void Vt102Emulation::setCharset(int n, int cs) // on both screens. | void Vt102Emulation::setCharset(int n, int cs) // on both screens. | ||||||
| { | { | ||||||
|   _charset[0].charset[n&3] = cs; useCharset(_charset[0].cu_cs); |     _charset[0].charset[n & 3] = cs; useCharset(_charset[0].cu_cs); | ||||||
|   _charset[1].charset[n&3] = cs; useCharset(_charset[1].cu_cs); |     _charset[1].charset[n & 3] = cs; useCharset(_charset[1].cu_cs); | ||||||
| } | } | ||||||
|  |  | ||||||
| void Vt102Emulation::setAndUseCharset(int n, int cs) | void Vt102Emulation::setAndUseCharset(int n, int cs) | ||||||
| { | { | ||||||
|   CHARSET.charset[n&3] = cs; |     CHARSET.charset[n & 3] = cs; | ||||||
|   useCharset(n&3); |     useCharset(n & 3); | ||||||
| } | } | ||||||
|  |  | ||||||
| void Vt102Emulation::useCharset(int n) | void Vt102Emulation::useCharset(int n) | ||||||
| { | { | ||||||
|   CHARSET.cu_cs   = n&3; |     CHARSET.cu_cs   = n & 3; | ||||||
|   CHARSET.graphic = (CHARSET.charset[n&3] == '0'); |     CHARSET.graphic = (CHARSET.charset[n & 3] == '0'); | ||||||
|   CHARSET.pound   = (CHARSET.charset[n&3] == 'A'); //This mode is obsolete |     CHARSET.pound   = (CHARSET.charset[n & 3] == 'A'); //This mode is obsolete | ||||||
| } | } | ||||||
|  |  | ||||||
| void Vt102Emulation::setDefaultMargins() | void Vt102Emulation::setDefaultMargins() | ||||||
| @@ -1100,13 +1192,17 @@ void Vt102Emulation::restoreCursor() | |||||||
| void Vt102Emulation::resetModes() | void Vt102Emulation::resetModes() | ||||||
| { | { | ||||||
|     // MODE_Allow132Columns is not reset here |     // MODE_Allow132Columns is not reset here | ||||||
|   // to match Xterm's behaviour (see Xterm's VTReset() function) |     // to match Xterm's behavior (see Xterm's VTReset() function) | ||||||
|  |  | ||||||
|     resetMode(MODE_132Columns); saveMode(MODE_132Columns); |     resetMode(MODE_132Columns); saveMode(MODE_132Columns); | ||||||
|     resetMode(MODE_Mouse1000);  saveMode(MODE_Mouse1000); |     resetMode(MODE_Mouse1000);  saveMode(MODE_Mouse1000); | ||||||
|     resetMode(MODE_Mouse1001);  saveMode(MODE_Mouse1001); |     resetMode(MODE_Mouse1001);  saveMode(MODE_Mouse1001); | ||||||
|     resetMode(MODE_Mouse1002);  saveMode(MODE_Mouse1002); |     resetMode(MODE_Mouse1002);  saveMode(MODE_Mouse1002); | ||||||
|     resetMode(MODE_Mouse1003);  saveMode(MODE_Mouse1003); |     resetMode(MODE_Mouse1003);  saveMode(MODE_Mouse1003); | ||||||
|  |     resetMode(MODE_Mouse1005);  saveMode(MODE_Mouse1005); | ||||||
|  |     resetMode(MODE_Mouse1006);  saveMode(MODE_Mouse1006); | ||||||
|  |     resetMode(MODE_Mouse1015);  saveMode(MODE_Mouse1015); | ||||||
|  |     resetMode(MODE_BracketedPaste);  saveMode(MODE_BracketedPaste); | ||||||
|  |  | ||||||
|     resetMode(MODE_AppScreen);  saveMode(MODE_AppScreen); |     resetMode(MODE_AppScreen);  saveMode(MODE_AppScreen); | ||||||
|     resetMode(MODE_AppCuKeys);  saveMode(MODE_AppCuKeys); |     resetMode(MODE_AppCuKeys);  saveMode(MODE_AppCuKeys); | ||||||
| @@ -1118,8 +1214,7 @@ void Vt102Emulation::resetModes() | |||||||
| void Vt102Emulation::setMode(int m) | void Vt102Emulation::setMode(int m) | ||||||
| { | { | ||||||
|     _currentModes.mode[m] = true; |     _currentModes.mode[m] = true; | ||||||
|   switch (m) |     switch (m) { | ||||||
|   { |  | ||||||
|     case MODE_132Columns: |     case MODE_132Columns: | ||||||
|         if (getMode(MODE_Allow132Columns)) |         if (getMode(MODE_Allow132Columns)) | ||||||
|             clearScreenAndSetColumns(132); |             clearScreenAndSetColumns(132); | ||||||
| @@ -1133,12 +1228,18 @@ void Vt102Emulation::setMode(int m) | |||||||
|         emit programUsesMouseChanged(false); |         emit programUsesMouseChanged(false); | ||||||
|         break; |         break; | ||||||
|  |  | ||||||
|     case MODE_AppScreen : _screen[1]->clearSelection(); |     case MODE_BracketedPaste: | ||||||
|  |         //emit programBracketedPasteModeChanged(true); | ||||||
|  |         break; | ||||||
|  |  | ||||||
|  |     case MODE_AppScreen : | ||||||
|  |         _screen[1]->clearSelection(); | ||||||
|         setScreen(1); |         setScreen(1); | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|   if (m < MODES_SCREEN || m == MODE_NewLine) |     // FIXME: Currently this has a redundant condition as MODES_SCREEN is 6 | ||||||
|   { |     // and MODE_NewLine is 5 | ||||||
|  |     if (m < MODES_SCREEN || m == MODE_NewLine) { | ||||||
|         _screen[0]->setMode(m); |         _screen[0]->setMode(m); | ||||||
|         _screen[1]->setMode(m); |         _screen[1]->setMode(m); | ||||||
|     } |     } | ||||||
| @@ -1147,8 +1248,7 @@ void Vt102Emulation::setMode(int m) | |||||||
| void Vt102Emulation::resetMode(int m) | void Vt102Emulation::resetMode(int m) | ||||||
| { | { | ||||||
|     _currentModes.mode[m] = false; |     _currentModes.mode[m] = false; | ||||||
|   switch (m) |     switch (m) { | ||||||
|   { |  | ||||||
|     case MODE_132Columns: |     case MODE_132Columns: | ||||||
|         if (getMode(MODE_Allow132Columns)) |         if (getMode(MODE_Allow132Columns)) | ||||||
|             clearScreenAndSetColumns(80); |             clearScreenAndSetColumns(80); | ||||||
| @@ -1160,13 +1260,18 @@ void Vt102Emulation::resetMode(int m) | |||||||
|         emit programUsesMouseChanged(true); |         emit programUsesMouseChanged(true); | ||||||
|         break; |         break; | ||||||
|  |  | ||||||
|  |     case MODE_BracketedPaste: | ||||||
|  |         //emit programBracketedPasteModeChanged(false); | ||||||
|  |         break; | ||||||
|  |  | ||||||
|     case MODE_AppScreen : |     case MODE_AppScreen : | ||||||
|         _screen[0]->clearSelection(); |         _screen[0]->clearSelection(); | ||||||
|         setScreen(0); |         setScreen(0); | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|   if (m < MODES_SCREEN || m == MODE_NewLine) |     // FIXME: Currently this has a redundant condition as MODES_SCREEN is 6 | ||||||
|   { |     // and MODE_NewLine is 5 | ||||||
|  |     if (m < MODES_SCREEN || m == MODE_NewLine) { | ||||||
|         _screen[0]->resetMode(m); |         _screen[0]->resetMode(m); | ||||||
|         _screen[1]->resetMode(m); |         _screen[1]->resetMode(m); | ||||||
|     } |     } | ||||||
| @@ -1196,35 +1301,59 @@ char Vt102Emulation::eraseChar() const | |||||||
|                                           Qt::Key_Backspace, |                                           Qt::Key_Backspace, | ||||||
|                                           0, |                                           0, | ||||||
|                                           0); |                                           0); | ||||||
|   if ( entry.text().count() > 0 ) |     if (entry.text().count() > 0) | ||||||
|         return entry.text()[0]; |         return entry.text()[0]; | ||||||
|     else |     else | ||||||
|         return '\b'; |         return '\b'; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #if 0 | ||||||
| // print contents of the scan buffer | // print contents of the scan buffer | ||||||
| static void hexdump(int* s, int len) | static void hexdump(int* s, int len) | ||||||
| { int i; | { | ||||||
|   for (i = 0; i < len; i++) |     int i; | ||||||
|   { |     for (i = 0; i < len; i++) { | ||||||
|         if (s[i] == '\\') |         if (s[i] == '\\') | ||||||
|             printf("\\\\"); |             printf("\\\\"); | ||||||
|  |         else if ((s[i]) > 32 && s[i] < 127) | ||||||
|  |             printf("%c", s[i]); | ||||||
|         else |         else | ||||||
|     if ((s[i]) > 32 && s[i] < 127) |             printf("\\%04x(hex)", s[i]); | ||||||
|       printf("%c",s[i]); |  | ||||||
|     else |  | ||||||
|       printf("\\%04x(hex)",s[i]); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | // return contents of the scan buffer | ||||||
|  | static QString hexdump2(int* s, int len) | ||||||
|  | { | ||||||
|  |     int i; | ||||||
|  |     char dump[128]; | ||||||
|  |     QString returnDump; | ||||||
|  |  | ||||||
|  |     for (i = 0; i < len; i++) { | ||||||
|  |         if (s[i] == '\\') | ||||||
|  |             snprintf(dump, sizeof(dump), "%s", "\\\\"); | ||||||
|  |         else if ((s[i]) > 32 && s[i] < 127) | ||||||
|  |             snprintf(dump, sizeof(dump), "%c", s[i]); | ||||||
|  |         else | ||||||
|  |             snprintf(dump, sizeof(dump), "\\%04x(hex)", s[i]); | ||||||
|  |         returnDump.append(QString(dump)); | ||||||
|  |     } | ||||||
|  |     return returnDump; | ||||||
|  | } | ||||||
|  |  | ||||||
| void Vt102Emulation::reportDecodingError() | void Vt102Emulation::reportDecodingError() | ||||||
| { | { | ||||||
|   if (tokenBufferPos == 0 || ( tokenBufferPos == 1 && (tokenBuffer[0] & 0xff) >= 32) )  |     if (tokenBufferPos == 0 || (tokenBufferPos == 1 && (tokenBuffer[0] & 0xff) >= 32)) | ||||||
|         return; |         return; | ||||||
|   printf("Undecodable sequence: ");  |  | ||||||
|   hexdump(tokenBuffer,tokenBufferPos);  | //    printf("Undecodable sequence: "); | ||||||
|   printf("\n"); | //    hexdump(tokenBuffer, tokenBufferPos); | ||||||
|  | //    printf("\n"); | ||||||
|  |  | ||||||
|  |     QString outputError = QString("Undecodable sequence: "); | ||||||
|  |     outputError.append(hexdump2(tokenBuffer, tokenBufferPos)); | ||||||
|  |     //kDebug() << outputError; | ||||||
| } | } | ||||||
|  |  | ||||||
| //#include "Vt102Emulation.moc" | //#include "Vt102Emulation.moc" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -23,19 +23,16 @@ | |||||||
| #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) | ||||||
| @@ -44,19 +41,25 @@ | |||||||
| #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 |  | ||||||
| { | { | ||||||
|  | extern unsigned short vt100_graphics[32]; | ||||||
|  |  | ||||||
|  | struct CharCodes { | ||||||
|     // coding info |     // coding info | ||||||
|     char charset[4]; // |     char charset[4]; // | ||||||
|     int  cu_cs;      // actual charset. |     int  cu_cs;      // actual charset. | ||||||
|     bool graphic;    // Some VT100 tricks |     bool graphic;    // Some VT100 tricks | ||||||
|   bool pound  ;    // Some VT100 tricks |     bool pound;      // Some VT100 tricks | ||||||
|     bool sa_graphic; // saved graphic |     bool sa_graphic; // saved graphic | ||||||
|     bool sa_pound;   // saved pound |     bool sa_pound;   // saved pound | ||||||
| }; | }; | ||||||
| @@ -73,7 +76,7 @@ struct CharCodes | |||||||
|  */ |  */ | ||||||
| class Vt102Emulation : public Emulation | class Vt102Emulation : public Emulation | ||||||
| { | { | ||||||
| Q_OBJECT |     Q_OBJECT | ||||||
|  |  | ||||||
| public: | public: | ||||||
|     /** Constructs a new emulation */ |     /** Constructs a new emulation */ | ||||||
| @@ -87,7 +90,7 @@ public: | |||||||
|  |  | ||||||
| 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); | ||||||
| @@ -117,9 +120,9 @@ private: | |||||||
|     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 | ||||||
| @@ -127,7 +130,7 @@ private: | |||||||
|     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; | ||||||
| @@ -155,9 +158,6 @@ private: | |||||||
|     void reportCursorPosition(); |     void reportCursorPosition(); | ||||||
|     void reportTerminalParms(int p); |     void reportTerminalParms(int p); | ||||||
|  |  | ||||||
|   void onScrollLock(); |  | ||||||
|   void scrollLock(const bool lock); |  | ||||||
|  |  | ||||||
|     // clears the screen and resizes it to the specified |     // clears the screen and resizes it to the specified | ||||||
|     // number of columns |     // number of columns | ||||||
|     void clearScreenAndSetColumns(int columnCount); |     void clearScreenAndSetColumns(int columnCount); | ||||||
| @@ -168,8 +168,9 @@ private: | |||||||
|     { |     { | ||||||
|     public: |     public: | ||||||
|         // Initializes all modes to false |         // Initializes all modes to false | ||||||
|     TerminalState() |         TerminalState() { | ||||||
|     { memset(&mode,false,MODE_total * sizeof(bool)); } |             memset(&mode, false, MODE_total * sizeof(bool)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         bool mode[MODE_total]; |         bool mode[MODE_total]; | ||||||
|     }; |     }; | ||||||
| @@ -182,9 +183,9 @@ private: | |||||||
|     //or window title. |     //or window title. | ||||||
|     //these calls occur when certain escape sequences are seen in the |     //these calls occur when certain escape sequences are seen in the | ||||||
|     //output from the terminal |     //output from the terminal | ||||||
|   QHash<int,QString> _pendingTitleUpdates; |     QHash<int, QString> _pendingTitleUpdates; | ||||||
|     QTimer* _titleUpdateTimer; |     QTimer* _titleUpdateTimer; | ||||||
| }; | }; | ||||||
|  | } | ||||||
|  |  | ||||||
| #endif // VT102EMULATION_H | #endif // VT102EMULATION_H | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user