mirror of
				https://github.com/Swordfish90/cool-retro-term.git
				synced 2025-10-30 22:54:21 +00:00 
			
		
		
		
	Merge pull request #103 from Swordfish90/improvemouse
Improved mouse behavior. Enabled mouse support for applications.
This commit is contained in:
		| @@ -133,41 +133,34 @@ Item{ | ||||
|         acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton | ||||
|         anchors.fill: parent | ||||
|         onWheel:{ | ||||
|             var coord = correctDistortion(wheel.x, wheel.y); | ||||
|             var lines = wheel.angleDelta.y > 0 ? -2 : 2; | ||||
|             kterminal.scrollWheel(coord.width, coord.height, lines); | ||||
|         } | ||||
|         onClicked: { | ||||
|             if (mouse.button == Qt.RightButton){ | ||||
|                 contextmenu.popup(); | ||||
|             } else if (mouse.button == Qt.MiddleButton){ | ||||
|                 kterminal.pasteSelection(); | ||||
|             if(wheel.modifiers & Qt.ControlModifier){ | ||||
|                wheel.angleDelta.y > 0 ? zoomIn.trigger() : zoomOut.trigger();  | ||||
|             } else { | ||||
|                 var coord = correctDistortion(wheel.x, wheel.y); | ||||
|                 var lines = wheel.angleDelta.y > 0 ? -1 : 1; | ||||
|                 kterminal.scrollWheelEvent(coord, lines); | ||||
|             } | ||||
|         } | ||||
|         onDoubleClicked: { | ||||
|             if (mouse.button == Qt.LeftButton){ | ||||
|                 var coord = correctDistortion(mouse.x, mouse.y); | ||||
|                 kterminal.mouseDoubleClick(coord.width, coord.height); | ||||
|             } | ||||
|         } | ||||
|         onPositionChanged: { | ||||
|             if (pressedButtons & Qt.LeftButton){ | ||||
|                 var coord = correctDistortion(mouse.x, mouse.y); | ||||
|                 kterminal.mouseMove(coord.width, coord.height); | ||||
|             } | ||||
|             var coord = correctDistortion(mouse.x, mouse.y); | ||||
|             kterminal.mouseDoubleClickEvent(coord, mouse.button, mouse.modifiers); | ||||
|         } | ||||
|         onPressed: { | ||||
|             if (mouse.button == Qt.LeftButton){ | ||||
| 	    if((!kterminal.usesMouse || mouse.modifiers & Qt.ShiftModifier) && mouse.button == Qt.RightButton) { | ||||
|                 contextmenu.popup(); | ||||
|             } else { | ||||
|                 var coord = correctDistortion(mouse.x, mouse.y); | ||||
|                 kterminal.mousePress(coord.width, coord.height); | ||||
|                 kterminal.mousePressEvent(coord, mouse.button, mouse.modifiers) | ||||
|             } | ||||
|         } | ||||
|         onReleased: { | ||||
|             if (mouse.button == Qt.LeftButton){ | ||||
|                 var coord = correctDistortion(mouse.x, mouse.y); | ||||
|                 kterminal.mouseRelease(coord.width, coord.height); | ||||
|             } | ||||
|             var coord = correctDistortion(mouse.x, mouse.y); | ||||
|             kterminal.mouseReleaseEvent(coord, mouse.button, mouse.modifiers); | ||||
|         } | ||||
| 	onPositionChanged: { | ||||
| 	    var coord = correctDistortion(mouse.x, mouse.y); | ||||
| 	    kterminal.mouseMoveEvent(coord, mouse.button, mouse.buttons, mouse.modifiers); | ||||
| 	} | ||||
|  | ||||
|         //Frame displacement properties | ||||
|         property real dtop: frame.item.displacementTop | ||||
| @@ -185,7 +178,7 @@ Item{ | ||||
|             var cc = Qt.size(0.5 - x, 0.5 - y); | ||||
|             var distortion = (cc.height * cc.height + cc.width * cc.width) * shadersettings.screen_distortion; | ||||
|  | ||||
|             return Qt.size((x - cc.width  * (1+distortion) * distortion) * width, | ||||
|             return Qt.point((x - cc.width  * (1+distortion) * distortion) * width, | ||||
|                            (y - cc.height * (1+distortion) * distortion) * height) | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -376,6 +376,12 @@ signals: | ||||
|    */ | ||||
|   void imageSizeChanged(int lineCount , int columnCount); | ||||
|  | ||||
|   /** | ||||
|    * Emitted after receiving the escape sequence which asks to change | ||||
|    * the terminal emulator's size | ||||
|    */ | ||||
|   void imageResizeRequest(const QSize& sizz); | ||||
|  | ||||
|   /**  | ||||
|    * Emitted when the terminal program requests to change various properties | ||||
|    * of the terminal display.   | ||||
|   | ||||
| @@ -48,9 +48,10 @@ | ||||
| #include "ShellCommand.h" // REUSE THIS | ||||
| #include "Vt102Emulation.h" // REUSE THIS | ||||
|  | ||||
|  | ||||
| int Session::lastSessionId = 0; | ||||
|  | ||||
| using namespace Konsole; | ||||
|  | ||||
| Session::Session() : | ||||
|         _shellProcess(0) | ||||
|         , _emulation(0) | ||||
| @@ -199,14 +200,9 @@ void Session::addView(KTerminalDisplay * widget) | ||||
|  | ||||
|         // allow emulation to notify view when the foreground process | ||||
|         // indicates whether or not it is interested in mouse signals | ||||
|  | ||||
|         // TODO Disabled since at the moment it is not working properly. | ||||
|         // Remember to reenable that once it' is's working. | ||||
|  | ||||
|         //connect( _emulation , SIGNAL(programUsesMouseChanged(bool)) , widget , | ||||
|         //         SLOT(setUsesMouse(bool)) ); | ||||
|  | ||||
|         //widget->setUsesMouse( _emulation->programUsesMouse() ); | ||||
|         connect( _emulation , SIGNAL(programUsesMouseChanged(bool)) , widget , | ||||
|                  SLOT(setUsesMouse(bool)) ); | ||||
|         widget->setUsesMouse( _emulation->programUsesMouse() ); | ||||
|  | ||||
|         widget->setScreenWindow(_emulation->createWindow()); | ||||
|     } | ||||
|   | ||||
| @@ -447,92 +447,377 @@ QStringList KTerminalDisplay::availableColorSchemes() | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| void KTerminalDisplay::scrollWheel(qreal x, qreal y, int lines){ | ||||
| void KTerminalDisplay::scrollWheelEvent(QPoint position, int lines){ | ||||
|     if(_mouseMarks){ | ||||
|         int charLine; | ||||
|         int charColumn; | ||||
|         getCharacterPosition(QPoint(x,y) , charLine , charColumn); | ||||
|  | ||||
|         emit mouseSignal(lines > 0 ? 5 : 4, | ||||
|                          charColumn + 1, | ||||
|                          charLine + 1, | ||||
|                          0); | ||||
|     } else { | ||||
|         if(_screenWindow->lineCount() == _screenWindow->windowLines()){ | ||||
|             const int keyCode = lines > 0 ? Qt::Key_Down : Qt::Key_Up; | ||||
|             QKeyEvent keyEvent(QEvent::KeyPress, keyCode, Qt::NoModifier); | ||||
|  | ||||
|             emit keyPressedSignal(&keyEvent); | ||||
|             emit keyPressedSignal(&keyEvent); | ||||
|         } else { | ||||
|             _screenWindow->scrollBy( ScreenWindow::ScrollLines, lines ); | ||||
|             _screenWindow->scrollCount(); | ||||
|             updateImage(); | ||||
|         } | ||||
|     } else { | ||||
|         int charLine; | ||||
|         int charColumn; | ||||
|         getCharacterPosition(position, charLine, charColumn); | ||||
|  | ||||
|         emit mouseSignal(lines > 0 ? 5 : 4, | ||||
|                          charColumn + 1, | ||||
|                          charLine + 1, | ||||
|                          0); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void KTerminalDisplay::mousePress(qreal x, qreal y){ | ||||
|     if (m_focusOnClick) forcedFocus(); | ||||
|     if (m_showVKBonClick) ShowVKB(true); | ||||
| void KTerminalDisplay::doPaste(QString text, bool appendReturn) | ||||
| { | ||||
|     if (!_screenWindow) | ||||
|         return; | ||||
|  | ||||
|     if (appendReturn) | ||||
|         text.append("\r"); | ||||
|  | ||||
|     if (!text.isEmpty()) { | ||||
|         text.replace('\n', '\r'); | ||||
| //        if (bracketedPasteMode()) { | ||||
| //            text.prepend("\e[200~"); | ||||
| //            text.append("\e[201~"); | ||||
| //        } | ||||
|         // perform paste by simulating keypress events | ||||
|         QKeyEvent e(QEvent::KeyPress, 0, Qt::NoModifier, text); | ||||
|         emit keyPressedSignal(&e); | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| void KTerminalDisplay::pasteFromClipboard(bool appendEnter) | ||||
| { | ||||
|     QString text = QGuiApplication::clipboard()->text(QClipboard::Clipboard); | ||||
|     doPaste(text, appendEnter); | ||||
| } | ||||
|  | ||||
| void KTerminalDisplay::pasteFromX11Selection(bool appendEnter) | ||||
| { | ||||
|     QString text = QGuiApplication::clipboard()->text(QClipboard::Selection); | ||||
|     doPaste(text, appendEnter); | ||||
| } | ||||
|  | ||||
|  | ||||
| void KTerminalDisplay::processMidButtonClick(QPoint &position, Qt::KeyboardModifier modifiers) | ||||
| { | ||||
|     if (_mouseMarks || (modifiers & Qt::ShiftModifier)) { | ||||
|         const bool appendEnter = modifiers & Qt::ControlModifier; | ||||
|  | ||||
|         if (true /*_middleClickPasteMode == Enum::PasteFromX11Selection*/) { | ||||
|             pasteFromX11Selection(appendEnter); | ||||
|         } else if (false /*_middleClickPasteMode == Enum::PasteFromClipboard*/) { | ||||
|             pasteFromClipboard(appendEnter); | ||||
|         } else { | ||||
|             Q_ASSERT(false); | ||||
|         } | ||||
|     } else { | ||||
|         int charLine = 0; | ||||
|         int charColumn = 0; | ||||
|         getCharacterPosition(position, charLine, charColumn); | ||||
|  | ||||
|         emit mouseSignal(1, charColumn + 1, charLine + 1, 0); | ||||
|         //emit mouseSignal(1, charColumn + 1, charLine + 1 + _scrollBar->value() - _scrollBar->maximum() , 0); | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| void KTerminalDisplay::mousePressEvent(QPoint position, int but, int mod) | ||||
| { | ||||
|     Qt::MouseButton button = (Qt::MouseButton) but; | ||||
|     Qt::KeyboardModifier modifiers = (Qt::KeyboardModifier) mod; | ||||
| //    if (_possibleTripleClick && (ev->button() == Qt::LeftButton)) { | ||||
| //        mouseTripleClickEvent(ev); | ||||
| //        return; | ||||
| //    } | ||||
|  | ||||
|     if (!_screenWindow) return; | ||||
|  | ||||
|     int charLine; | ||||
|     int charColumn; | ||||
|     getCharacterPosition(QPoint(x,y), charLine, charColumn); | ||||
|     getCharacterPosition(position, charLine, charColumn); | ||||
|     QPoint pos = QPoint(charColumn, charLine); | ||||
|  | ||||
|     _wordSelectionMode = false; | ||||
|     _lineSelectionMode = false; | ||||
|     if (button == Qt::LeftButton) { | ||||
|         _lineSelectionMode = false; | ||||
|         _wordSelectionMode = false; | ||||
|  | ||||
|     if(_mouseMarks){ | ||||
|         emit mouseSignal(0, charColumn + 1, charLine + 1, 0); | ||||
|     } else { | ||||
|         QPoint pos = QPoint(charColumn, charLine); | ||||
|         _preserveLineBreaks = !((modifiers & Qt::ControlModifier) && !(modifiers & Qt::AltModifier)); | ||||
|         _columnSelectionMode = (modifiers & Qt::AltModifier) && (modifiers & Qt::ControlModifier); | ||||
|  | ||||
|         _screenWindow->clearSelection(); | ||||
|         _iPntSel = _pntSel = pos; | ||||
|         _actSel = 1; // left mouse button pressed but nothing selected yet. | ||||
|         if (_mouseMarks || (modifiers == Qt::ShiftModifier)) { | ||||
|             // Only extend selection for programs not interested in mouse | ||||
|             if (_mouseMarks && (modifiers == Qt::ShiftModifier)) { | ||||
|                 extendSelection(position); | ||||
|             } else { | ||||
|                 _screenWindow->clearSelection(); | ||||
|  | ||||
|                 //pos.ry() += _scrollBar->value(); | ||||
|                 _iPntSel = _pntSel = pos; | ||||
|                 _actSel = 1; // left mouse button pressed but nothing selected yet. | ||||
|             } | ||||
|         } else { | ||||
|             emit mouseSignal(0, charColumn + 1, charLine + 1, 0); | ||||
|         } | ||||
|     } else if (button == Qt::MidButton) { | ||||
|         processMidButtonClick(position, modifiers); | ||||
|     } else if (button == Qt::RightButton) { | ||||
|         if (!_mouseMarks) | ||||
|             emit mouseSignal(2, charColumn + 1, charLine + 1, 0); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void KTerminalDisplay::mouseMove(qreal x, qreal y){ | ||||
|     QPoint pos(x, y); | ||||
| void KTerminalDisplay::mouseMoveEvent(QPoint position, int but, int buts, int mod) | ||||
| { | ||||
|     Qt::MouseButton button = (Qt::MouseButton) but; | ||||
|     Qt::KeyboardModifier modifiers = (Qt::KeyboardModifier) mod; | ||||
|     Qt::MouseButtons buttons = (Qt::MouseButtons) buts; | ||||
|  | ||||
|     if(_mouseMarks){ | ||||
|         int charLine; | ||||
|         int charColumn; | ||||
|         getCharacterPosition(pos, charLine, charColumn); | ||||
|     int charLine = 0; | ||||
|     int charColumn = 0; | ||||
|     getCharacterPosition(position, charLine, charColumn); | ||||
|  | ||||
|         emit mouseSignal(0, charColumn + 1, charLine + 1, 1); | ||||
|     } else { | ||||
|         extendSelection(pos); | ||||
|     // for auto-hiding the cursor, we need mouseTracking | ||||
|     if (buttons == Qt::NoButton) return; | ||||
|  | ||||
|     // if the terminal is interested in mouse movements | ||||
|     // then emit a mouse movement signal, unless the shift | ||||
|     // key is being held down, which overrides this. | ||||
|     if (!_mouseMarks && !(modifiers & Qt::ShiftModifier)) { | ||||
|         int button = 3; | ||||
|         if (buttons & Qt::LeftButton) | ||||
|             button = 0; | ||||
|         if (buttons & Qt::MidButton) | ||||
|             button = 1; | ||||
|         if (buttons & Qt::RightButton) | ||||
|             button = 2; | ||||
|  | ||||
|         emit mouseSignal(button, charColumn + 1, charLine + 1, 1); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     if (_actSel == 0) return; | ||||
|  | ||||
|     // don't extend selection while pasting | ||||
|     if (buttons & Qt::MidButton) return; | ||||
|  | ||||
|     extendSelection(position); | ||||
| } | ||||
|  | ||||
| void KTerminalDisplay::mouseDoubleClick(qreal x, qreal y){ | ||||
|     QPoint pos(x, y); | ||||
|  | ||||
|     if(_mouseMarks){ | ||||
|         int charLine; | ||||
|         int charColumn; | ||||
|         getCharacterPosition(pos, charLine, charColumn); | ||||
| QPoint KTerminalDisplay::findWordEnd(const QPoint &pnt) | ||||
| { | ||||
|     const int regSize = qMax(_screenWindow->windowLines(), 10); | ||||
|     const int curLine = _screenWindow->currentLine(); | ||||
|     int i = pnt.y(); | ||||
|     int x = pnt.x(); | ||||
|     int y = i + curLine; | ||||
|     int j = loc(x, i); | ||||
|     QVector<LineProperty> lineProperties = _lineProperties; | ||||
|     Screen *screen = _screenWindow->screen(); | ||||
|     Character *image = _image; | ||||
|     Character *tmp_image = NULL; | ||||
|     const QChar selClass = charClass(image[j]); | ||||
|     const int imageSize = regSize * _columns; | ||||
|     const int maxY = _screenWindow->lineCount() - 1; | ||||
|     const int maxX = _columns - 1; | ||||
|  | ||||
|         emit mouseSignal(0, charColumn + 1, charLine + 1, 0); | ||||
|         //emit mouseSignal(0, charColumn + 1, charLine + 1, 0); | ||||
|     } else { | ||||
|         _wordSelectionMode = true; | ||||
|         extendSelection(pos); | ||||
|     while (true) { | ||||
|         const int lineCount = lineProperties.count(); | ||||
|         for (;;j++, x++) { | ||||
|             if (x < maxX) { | ||||
|                 if (charClass(image[j + 1]) == selClass) | ||||
|                     continue; | ||||
|                 goto out; | ||||
|             } else if (i < lineCount - 1) { | ||||
|                 if (lineProperties[i] & LINE_WRAPPED && | ||||
|                     charClass(image[j + 1]) == selClass) { | ||||
|                     x = -1; | ||||
|                     i++; | ||||
|                     y++; | ||||
|                     continue; | ||||
|                 } | ||||
|                 goto out; | ||||
|             } else if (y < maxY) { | ||||
|                 if (i < lineCount && !(lineProperties[i] & LINE_WRAPPED)) | ||||
|                     goto out; | ||||
|                 break; | ||||
|             } else { | ||||
|                 goto out; | ||||
|             } | ||||
|         } | ||||
|         int newRegEnd = qMin(y + regSize - 1, maxY); | ||||
|         lineProperties = screen->getLineProperties(y, newRegEnd); | ||||
|         i = 0; | ||||
|         if (!tmp_image) { | ||||
|             tmp_image = new Character[imageSize]; | ||||
|             image = tmp_image; | ||||
|         } | ||||
|         screen->getImage(tmp_image, imageSize, y, newRegEnd); | ||||
|         x--; | ||||
|         j = loc(x, i); | ||||
|     } | ||||
| out: | ||||
|     y -= curLine; | ||||
|     // In word selection mode don't select @ (64) if at end of word. | ||||
|     if (((image[j].rendition & RE_EXTENDED_CHAR) == 0) && | ||||
|         (QChar(image[j].character) == '@') && | ||||
|         (y > pnt.y() || x > pnt.x())) { | ||||
|         if (x > 0) { | ||||
|             x--; | ||||
|         } else { | ||||
|             y--; | ||||
|         } | ||||
|     } | ||||
|     if (tmp_image) { | ||||
|         delete[] tmp_image; | ||||
|     } | ||||
|     return QPoint(x, y); | ||||
| } | ||||
|  | ||||
| void KTerminalDisplay::mouseRelease(qreal x, qreal y){ | ||||
|     _actSel = 0; | ||||
| QPoint KTerminalDisplay::findWordStart(const QPoint &pnt) | ||||
| { | ||||
|     const int regSize = qMax(_screenWindow->windowLines(), 10); | ||||
|     const int curLine = _screenWindow->currentLine(); | ||||
|     int i = pnt.y(); | ||||
|     int x = pnt.x(); | ||||
|     int y = i + curLine; | ||||
|     int j = loc(x, i); | ||||
|     QVector<LineProperty> lineProperties = _lineProperties; | ||||
|     Screen *screen = _screenWindow->screen(); | ||||
|     Character *image = _image; | ||||
|     Character *tmp_image = NULL; | ||||
|     const QChar selClass = charClass(image[j]); | ||||
|     const int imageSize = regSize * _columns; | ||||
|  | ||||
|     if(_mouseMarks){ | ||||
|         int charLine; | ||||
|         int charColumn; | ||||
|         getCharacterPosition(QPoint(x,y), charLine, charColumn); | ||||
|     while (true) { | ||||
|         for (;;j--, x--) { | ||||
|             if (x > 0) { | ||||
|                 if (charClass(image[j - 1]) == selClass) | ||||
|                     continue; | ||||
|                 goto out; | ||||
|             } else if (i > 0) { | ||||
|                 if (lineProperties[i - 1] & LINE_WRAPPED && | ||||
|                     charClass(image[j - 1]) == selClass) { | ||||
|                     x = _columns; | ||||
|                     i--; | ||||
|                     y--; | ||||
|                     continue; | ||||
|                 } | ||||
|                 goto out; | ||||
|             } else if (y > 0) { | ||||
|                 break; | ||||
|             } else { | ||||
|                 goto out; | ||||
|             } | ||||
|         } | ||||
|         int newRegStart = qMax(0, y - regSize); | ||||
|         lineProperties = screen->getLineProperties(newRegStart, y - 1); | ||||
|         i = y - newRegStart; | ||||
|         if (!tmp_image) { | ||||
|             tmp_image = new Character[imageSize]; | ||||
|             image = tmp_image; | ||||
|         } | ||||
|         screen->getImage(tmp_image, imageSize, newRegStart, y - 1); | ||||
|         j = loc(x, i); | ||||
|     } | ||||
| out: | ||||
|     if (tmp_image) { | ||||
|         delete[] tmp_image; | ||||
|     } | ||||
|     return QPoint(x, y - curLine); | ||||
| } | ||||
|  | ||||
|         emit mouseSignal(0, charColumn + 1, charLine + 1, 2); | ||||
|  | ||||
|  | ||||
| void KTerminalDisplay::mouseDoubleClickEvent(QPoint position, int but, int mod) | ||||
| { | ||||
|     Qt::MouseButton button = (Qt::MouseButton) but; | ||||
|     Qt::KeyboardModifier modifiers = (Qt::KeyboardModifier) mod; | ||||
|  | ||||
|     if (button != Qt::LeftButton) return; | ||||
|     if (!_screenWindow) return; | ||||
|  | ||||
|     int charLine = 0; | ||||
|     int charColumn = 0; | ||||
|  | ||||
|     getCharacterPosition(position, charLine, charColumn); | ||||
|  | ||||
|     // If the application is interested in mouse events. They have already been forwarded. | ||||
|     if (!_mouseMarks && !(modifiers & Qt::ShiftModifier)) | ||||
|         return; | ||||
|  | ||||
|     _screenWindow->clearSelection(); | ||||
|  | ||||
|     _wordSelectionMode = true; | ||||
|     _actSel = 2; // within selection | ||||
|  | ||||
|     _iPntSel = QPoint(charColumn, charLine); | ||||
|     const QPoint bgnSel = findWordStart(_iPntSel); | ||||
|     const QPoint endSel = findWordEnd(_iPntSel); | ||||
|  | ||||
|     _screenWindow->setSelectionStart(bgnSel.x() , bgnSel.y() , false); | ||||
|     _screenWindow->setSelectionEnd(endSel.x() , endSel.y()); | ||||
|     copyToX11Selection(); | ||||
|  | ||||
|     //TODO implement triple click. | ||||
| //    _possibleTripleClick = true; | ||||
|  | ||||
| //    QTimer::singleShot(QApplication::doubleClickInterval(), this, | ||||
| //                       SLOT(tripleClickTimeout())); | ||||
| } | ||||
|  | ||||
|  | ||||
| void KTerminalDisplay::copyToX11Selection() | ||||
| { | ||||
|     if (!_screenWindow) | ||||
|         return; | ||||
|  | ||||
|     QString text = _screenWindow->selectedText(_preserveLineBreaks); | ||||
|     if (text.isEmpty()) | ||||
|         return; | ||||
|  | ||||
|     QGuiApplication::clipboard()->setText(text, QClipboard::Selection); | ||||
| } | ||||
|  | ||||
|  | ||||
| void KTerminalDisplay::mouseReleaseEvent(QPoint position, int but, int mod) | ||||
| { | ||||
|     Qt::MouseButton button = (Qt::MouseButton) but; | ||||
|     Qt::KeyboardModifier modifiers = (Qt::KeyboardModifier) mod; | ||||
|  | ||||
|     if (!_screenWindow) | ||||
|         return; | ||||
|  | ||||
|     int charLine; | ||||
|     int charColumn; | ||||
|     getCharacterPosition(position, charLine, charColumn); | ||||
|  | ||||
|     if (button == Qt::LeftButton) { | ||||
|         if (_actSel > 1) { | ||||
|             copyToX11Selection(); | ||||
|         } | ||||
|  | ||||
|         _actSel = 0; | ||||
|  | ||||
|         //FIXME: emits a release event even if the mouse is | ||||
|         //       outside the range. The procedure used in `mouseMoveEvent' | ||||
|         //       applies here, too. | ||||
|  | ||||
|         if (!_mouseMarks && !(modifiers & Qt::ShiftModifier)) | ||||
|             emit mouseSignal(0, charColumn + 1, charLine + 1 , 2); | ||||
|     } | ||||
|  | ||||
|     if (!_mouseMarks && | ||||
|             (button == Qt::RightButton || button == Qt::MidButton) && | ||||
|             !(modifiers & Qt::ShiftModifier)) { | ||||
|         emit mouseSignal(button == Qt::MidButton ? 1 : 2, charColumn + 1, charLine + 1, 2); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -546,7 +831,12 @@ void KTerminalDisplay::scrollScreenWindow(enum ScreenWindow::RelativeScrollMode | ||||
|  | ||||
|  | ||||
| void KTerminalDisplay::setUsesMouse(bool usesMouse){ | ||||
|     _mouseMarks = !usesMouse; | ||||
|     _mouseMarks = usesMouse; | ||||
|     emit usesMouseChanged(); | ||||
| } | ||||
|  | ||||
| bool KTerminalDisplay::getUsesMouse(){ | ||||
|     return !_mouseMarks; | ||||
| } | ||||
|  | ||||
| void KTerminalDisplay::setAutoFocus(bool au) | ||||
| @@ -1361,16 +1651,33 @@ void KTerminalDisplay::updateLineProperties() | ||||
|     _lineProperties = _screenWindow->getLineProperties(); | ||||
| } | ||||
|  | ||||
| QChar KTerminalDisplay::charClass(QChar qch) const | ||||
| QChar KTerminalDisplay::charClass(const Character& ch) const | ||||
| { | ||||
|     if ( qch.isSpace() ) return ' '; | ||||
|     if (ch.rendition & RE_EXTENDED_CHAR) { | ||||
|         ushort extendedCharLength = 0; | ||||
|         const ushort* chars = ExtendedCharTable::instance.lookupExtendedChar(ch.character, extendedCharLength); | ||||
|         if (chars && extendedCharLength > 0) { | ||||
|             const QString s = QString::fromUtf16(chars, extendedCharLength); | ||||
|             if (_wordCharacters.contains(s, Qt::CaseInsensitive)) | ||||
|                 return 'a'; | ||||
|             bool allLetterOrNumber = true; | ||||
|             for (int i = 0; allLetterOrNumber && i < s.size(); ++i) | ||||
|                 allLetterOrNumber = s.at(i).isLetterOrNumber(); | ||||
|             return allLetterOrNumber ? 'a' : s.at(0); | ||||
|         } | ||||
|         return 0; | ||||
|     } else { | ||||
|         const QChar qch(ch.character); | ||||
|         if (qch.isSpace()) return ' '; | ||||
|  | ||||
|     if ( qch.isLetterOrNumber() || _wordCharacters.contains(qch, Qt::CaseInsensitive ) ) | ||||
|         return 'a'; | ||||
|         if (qch.isLetterOrNumber() || _wordCharacters.contains(qch, Qt::CaseInsensitive)) | ||||
|             return 'a'; | ||||
|  | ||||
|     return qch; | ||||
|         return qch; | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| void KTerminalDisplay::setWordCharacters(const QString& wc) | ||||
| { | ||||
|     _wordCharacters = wc; | ||||
|   | ||||
| @@ -70,6 +70,7 @@ class KONSOLEPRIVATE_EXPORT KTerminalDisplay : public QQuickPaintedItem | ||||
|     Q_PROPERTY(bool ShowIMEOnClick     READ autoVKB         WRITE setAutoVKB     NOTIFY changedAutoVKB) | ||||
|     Q_PROPERTY(QSize terminalSize      READ getTerminalSize                      NOTIFY terminalSizeChanged) | ||||
|     Q_PROPERTY(QSize paintedFontSize   READ getFontSize                          NOTIFY paintedFontSizeChanged) | ||||
|     Q_PROPERTY(bool usesMouse          READ getUsesMouse                         NOTIFY usesMouseChanged) | ||||
|  | ||||
|  | ||||
| public: | ||||
| @@ -311,15 +312,10 @@ public slots: | ||||
|     void setColorScheme(const QString &name); | ||||
|     QStringList availableColorSchemes(); | ||||
|  | ||||
|     void scrollWheel(qreal x, qreal y, int lines); | ||||
|     void mousePress(qreal x, qreal y); | ||||
|     void mouseMove(qreal x, qreal y); | ||||
|     void mouseDoubleClick(qreal x, qreal y); | ||||
|     void mouseRelease(qreal x, qreal y); | ||||
|  | ||||
|     void scrollScreenWindow(enum ScreenWindow::RelativeScrollMode mode, int amount); | ||||
|  | ||||
|     void setUsesMouse(bool usesMouse); | ||||
|     bool getUsesMouse(void); | ||||
|  | ||||
|     bool autoFocus() { return m_focusOnClick; } | ||||
|     void setAutoFocus(bool au); | ||||
| @@ -425,6 +421,8 @@ signals: | ||||
|  | ||||
|     void mouseSignal(int,int,int,int); | ||||
|  | ||||
|     void usesMouseChanged(); | ||||
|  | ||||
|     void terminalSizeChanged(); | ||||
|     void paintedFontSizeChanged(); | ||||
|  | ||||
| @@ -477,7 +475,11 @@ protected: | ||||
|     void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); | ||||
|     QRect geometryRound(const QRectF &r) const; | ||||
|  | ||||
|     //void mousePressEvent(QMouseEvent*ev); | ||||
|     Q_INVOKABLE void mousePressEvent(QPoint position, int but, int mod); | ||||
|     Q_INVOKABLE void mouseReleaseEvent(QPoint position, int but, int mod); | ||||
|     Q_INVOKABLE void mouseDoubleClickEvent(QPoint position, int but, int mod); | ||||
|     Q_INVOKABLE void mouseMoveEvent(QPoint position, int but, int buts, int mod); | ||||
|     Q_INVOKABLE void scrollWheelEvent(QPoint position, int lines); | ||||
|     //void mouseReleaseEvent( QMouseEvent* ); | ||||
|     //void mouseMoveEvent( QMouseEvent* ); | ||||
|  | ||||
| @@ -497,7 +499,7 @@ protected: | ||||
|     //     - A space (returns ' ') | ||||
|     //     - Part of a word (returns 'a') | ||||
|     //     - Other characters (returns the input character) | ||||
|     QChar charClass(QChar ch) const; | ||||
|     QChar charClass(const Character& ch) const; | ||||
|  | ||||
|     void clearImage(); | ||||
|  | ||||
| @@ -594,6 +596,14 @@ private: | ||||
|     // redraws the cursor | ||||
|     void updateCursor(); | ||||
|  | ||||
|     QPoint findWordStart(const QPoint &pnt); | ||||
|     QPoint findWordEnd(const QPoint &pnt); | ||||
|     void processMidButtonClick(QPoint &position, Qt::KeyboardModifier modifiers); | ||||
|     void copyToX11Selection(); | ||||
|     void pasteFromClipboard(bool appendEnter); | ||||
|     void pasteFromX11Selection(bool appendEnter); | ||||
|     void doPaste(QString text, bool appendReturn); | ||||
|  | ||||
|     bool handleShortcutOverrideEvent(QKeyEvent* event); | ||||
|     ///////////////////////////////////////////////////////////////////////////////////// | ||||
|     ///////////////////////////////////////////////////////////////////////////////////// | ||||
|   | ||||
| @@ -23,47 +23,57 @@ | ||||
| // Own | ||||
| #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 | ||||
| #include <stdio.h> | ||||
| #include <unistd.h> | ||||
| #include <assert.h> | ||||
|  | ||||
| // Qt | ||||
| #include <QtCore/QEvent> | ||||
| #include <QtCore/QTimer> | ||||
| #include <QtGui/QKeyEvent> | ||||
| #include <QtCore/QByteRef> | ||||
|  | ||||
| // KDE | ||||
| //#include <kdebug.h> | ||||
| //#include <klocale.h> | ||||
| //#include <KLocalizedString> | ||||
| //#include <KDebug> | ||||
|  | ||||
| // Konsole | ||||
| #include "KeyboardTranslator.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() | ||||
|     : Emulation(), | ||||
|      _titleUpdateTimer(new QTimer(this)) | ||||
|       _titleUpdateTimer(new QTimer(this)) | ||||
| { | ||||
|   _titleUpdateTimer->setSingleShot(true); | ||||
|   QObject::connect(_titleUpdateTimer , SIGNAL(timeout()) , this , SLOT(updateTitle())); | ||||
|     _titleUpdateTimer->setSingleShot(true); | ||||
|     QObject::connect(_titleUpdateTimer , SIGNAL(timeout()) , this , SLOT(updateTitle())); | ||||
|  | ||||
|   initTokenizer(); | ||||
|   reset(); | ||||
|     initTokenizer(); | ||||
|     reset(); | ||||
| } | ||||
|  | ||||
| Vt102Emulation::~Vt102Emulation() | ||||
| @@ -71,21 +81,29 @@ Vt102Emulation::~Vt102Emulation() | ||||
|  | ||||
| void Vt102Emulation::clearEntireScreen() | ||||
| { | ||||
|   _currentScreen->clearEntireScreen(); | ||||
|   bufferedUpdate();  | ||||
|     _currentScreen->clearEntireScreen(); | ||||
|     bufferedUpdate(); | ||||
| } | ||||
|  | ||||
| void Vt102Emulation::reset() | ||||
| { | ||||
|   resetTokenizer(); | ||||
|   resetModes(); | ||||
|   resetCharset(0); | ||||
|   _screen[0]->reset(); | ||||
|   resetCharset(1); | ||||
|   _screen[1]->reset(); | ||||
|   setCodec(LocaleCodec); | ||||
|     // Save the current codec so we can set it later. | ||||
|     // Ideally we would want to use the profile setting | ||||
|     const QTextCodec* currentCodec = codec(); | ||||
|  | ||||
|   bufferedUpdate(); | ||||
|     resetTokenizer(); | ||||
|     resetModes(); | ||||
|     resetCharset(0); | ||||
|     _screen[0]->reset(); | ||||
|     resetCharset(1); | ||||
|     _screen[1]->reset(); | ||||
|  | ||||
|     if (currentCodec) | ||||
|         setCodec(currentCodec); | ||||
|     else | ||||
|         setCodec(LocaleCodec); | ||||
|  | ||||
|     bufferedUpdate(); | ||||
| } | ||||
|  | ||||
| /* ------------------------------------------------------------------------- */ | ||||
| @@ -142,7 +160,7 @@ void Vt102Emulation::reset() | ||||
|    The last two forms allow list of arguments. Since the elements of | ||||
|    the lists are treated individually the same way, they are passed | ||||
|    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'). | ||||
|  | ||||
| */ | ||||
| @@ -162,7 +180,7 @@ void Vt102Emulation::reset() | ||||
| #define TY_CSI_PG(A)  TY_CONSTRUCT(9,A,0) | ||||
| #define TY_CSI_PE(A)  TY_CONSTRUCT(10,A,0) | ||||
|  | ||||
| #define MAX_ARGUMENT 4096 | ||||
| const int MAX_ARGUMENT = 4096; | ||||
|  | ||||
| // Tokenizer --------------------------------------------------------------- -- | ||||
|  | ||||
| @@ -175,64 +193,62 @@ void Vt102Emulation::reset() | ||||
|  | ||||
| void Vt102Emulation::resetTokenizer() | ||||
| { | ||||
|   tokenBufferPos = 0;  | ||||
|   argc = 0;  | ||||
|   argv[0] = 0;  | ||||
|   argv[1] = 0; | ||||
|     tokenBufferPos = 0; | ||||
|     argc = 0; | ||||
|     argv[0] = 0; | ||||
|     argv[1] = 0; | ||||
| } | ||||
|  | ||||
| void Vt102Emulation::addDigit(int digit) | ||||
| { | ||||
|   if (argv[argc] < MAX_ARGUMENT) | ||||
|       argv[argc] = 10*argv[argc] + digit; | ||||
|     if (argv[argc] < MAX_ARGUMENT) | ||||
|         argv[argc] = 10 * argv[argc] + digit; | ||||
| } | ||||
|  | ||||
| void Vt102Emulation::addArgument() | ||||
| { | ||||
|   argc = qMin(argc+1,MAXARGS-1); | ||||
|   argv[argc] = 0; | ||||
|     argc = qMin(argc + 1, MAXARGS - 1); | ||||
|     argv[argc] = 0; | ||||
| } | ||||
|  | ||||
| void Vt102Emulation::addToCurrentToken(int cc) | ||||
| { | ||||
|   tokenBuffer[tokenBufferPos] = cc; | ||||
|   tokenBufferPos = qMin(tokenBufferPos+1,MAX_TOKEN_LENGTH-1); | ||||
|     tokenBuffer[tokenBufferPos] = cc; | ||||
|     tokenBufferPos = qMin(tokenBufferPos + 1, MAX_TOKEN_LENGTH - 1); | ||||
| } | ||||
|  | ||||
| // Character Class flags used while decoding | ||||
|  | ||||
| #define CTL  1  // Control character | ||||
| #define CHR  2  // Printable character | ||||
| #define CPN  4  // TODO: Document me  | ||||
| #define DIG  8  // Digit | ||||
| #define SCS 16  // TODO: Document me   | ||||
| #define GRP 32  // TODO: Document me | ||||
| #define CPS 64  // Character which indicates end of window resize | ||||
|                 // escape sequence '\e[8;<row>;<col>t' | ||||
| const int CTL =  1;  // Control character | ||||
| const int CHR =  2;  // Printable character | ||||
| const int CPN =  4;  // TODO: Document me | ||||
| const int DIG =  8;  // Digit | ||||
| const int SCS = 16;  // Select Character Set | ||||
| const int GRP = 32;  // TODO: Document me | ||||
| const int CPS = 64;  // Character which indicates end of window resize | ||||
|  | ||||
| void Vt102Emulation::initTokenizer() | ||||
| { | ||||
|   int i;  | ||||
|   quint8* s; | ||||
|   for(i = 0;i < 256; ++i)  | ||||
|     charClass[i] = 0; | ||||
|   for(i = 0;i < 32; ++i)  | ||||
|     charClass[i] |= CTL; | ||||
|   for(i = 32;i < 256; ++i)  | ||||
|     charClass[i] |= CHR; | ||||
|   for(s = (quint8*)"@ABCDGHILMPSTXZcdfry"; *s; ++s)  | ||||
|     charClass[*s] |= CPN; | ||||
|   // resize = \e[8;<row>;<col>t | ||||
|   for(s = (quint8*)"t"; *s; ++s)  | ||||
|     charClass[*s] |= CPS; | ||||
|   for(s = (quint8*)"0123456789"; *s; ++s)  | ||||
|     charClass[*s] |= DIG; | ||||
|   for(s = (quint8*)"()+*%"; *s; ++s)  | ||||
|     charClass[*s] |= SCS; | ||||
|   for(s = (quint8*)"()+*#[]%"; *s; ++s)  | ||||
|     charClass[*s] |= GRP; | ||||
|     int i; | ||||
|     quint8* s; | ||||
|     for (i = 0; i < 256; ++i) | ||||
|         charClass[i] = 0; | ||||
|     for (i = 0; i < 32; ++i) | ||||
|         charClass[i] |= CTL; | ||||
|     for (i = 32; i < 256; ++i) | ||||
|         charClass[i] |= CHR; | ||||
|     for (s = (quint8*)"@ABCDGHILMPSTXZcdfry"; *s; ++s) | ||||
|         charClass[*s] |= CPN; | ||||
|     // resize = \e[8;<row>;<col>t | ||||
|     for (s = (quint8*)"t"; *s; ++s) | ||||
|         charClass[*s] |= CPS; | ||||
|     for (s = (quint8*)"0123456789"; *s; ++s) | ||||
|         charClass[*s] |= DIG; | ||||
|     for (s = (quint8*)"()+*%"; *s; ++s) | ||||
|         charClass[*s] |= SCS; | ||||
|     for (s = (quint8*)"()+*#[]%"; *s; ++s) | ||||
|         charClass[*s] |= GRP; | ||||
|  | ||||
|   resetTokenizer(); | ||||
|     resetTokenizer(); | ||||
| } | ||||
|  | ||||
| /* Ok, here comes the nasty part of the decoder. | ||||
| @@ -267,13 +283,14 @@ void Vt102Emulation::initTokenizer() | ||||
| #define Xte        (Xpe      && cc ==  7 ) | ||||
| #define ces(C)     (cc < 256 && (charClass[cc] & (C)) == (C) && !Xte) | ||||
|  | ||||
| #define ESC 27 | ||||
| #define CNTL(c) ((c)-'@') | ||||
| const int ESC = 27; | ||||
| const int DEL = 127; | ||||
|  | ||||
| // process an incoming unicode character | ||||
| void Vt102Emulation::receiveChar(int cc) | ||||
| { | ||||
|   if (cc == 127)  | ||||
|   if (cc == DEL) | ||||
|     return; //VT100: ignore. | ||||
|  | ||||
|   if (ces(CTL)) | ||||
| @@ -294,7 +311,7 @@ void Vt102Emulation::receiveChar(int cc) | ||||
|   addToCurrentToken(cc); | ||||
|  | ||||
|   int* s = tokenBuffer; | ||||
|   int  p = tokenBufferPos; | ||||
|   const int  p = tokenBufferPos; | ||||
|  | ||||
|   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 (ees(DIG)) { addDigit(cc-'0'); return; } | ||||
|     if (eec(';')) { addArgument();    return; } | ||||
|     for (int i=0;i<=argc;i++) | ||||
|     for (int i = 0; i <= argc; i++) | ||||
|     { | ||||
|         if (epp()) | ||||
|             processToken( TY_CSI_PR(cc,argv[i]), 0, 0); | ||||
|             processToken(TY_CSI_PR(cc,argv[i]), 0, 0); | ||||
|         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) | ||||
|         { | ||||
|             // ESC[ ... 48;2;<red>;<green>;<blue> ... m -or- ESC[ ... 38;2;<red>;<green>;<blue> ... m | ||||
|             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; | ||||
|         } | ||||
|         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 | ||||
|             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 | ||||
|             processToken( TY_CSI_PS(cc,argv[i]), 0, 0); | ||||
|             processToken(TY_CSI_PS(cc,argv[i]), 0, 0); | ||||
|     } | ||||
|     resetTokenizer(); | ||||
|   } | ||||
| @@ -364,11 +381,11 @@ void Vt102Emulation::receiveChar(int cc) | ||||
|         return; | ||||
|     if (p < 4) | ||||
|     { | ||||
|         processToken( TY_VT52(s[1] ), 0, 0);  | ||||
|         processToken(TY_VT52(s[1] ), 0, 0); | ||||
|         resetTokenizer(); | ||||
|         return; | ||||
|     } | ||||
|     processToken( TY_VT52(s[1]), s[2], s[3]);  | ||||
|     processToken(TY_VT52(s[1]), s[2], s[3]); | ||||
|     resetTokenizer(); | ||||
|     return; | ||||
|   } | ||||
| @@ -418,7 +435,7 @@ void Vt102Emulation::updateTitle() | ||||
|    meaning is assigned to them. These are either operations of | ||||
|    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. | ||||
|  | ||||
|    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) | ||||
|   { | ||||
|  | ||||
|     case TY_CHR(         ) : _currentScreen->displayCharacter     (p         ); break; //UTF16 | ||||
|  | ||||
|     //             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; | ||||
|  | ||||
| // 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 | ||||
|     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',   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',   5) : _currentScreen->  setRendition     (RE_BLINK    ); break; //VT100 | ||||
|     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',  12) : /* IGNORED: mapping related          */ break; //LINUX | ||||
|     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',  25) : _currentScreen->resetRendition     (RE_BLINK    ); 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('C'      ) : _currentScreen->cursorRight          (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('H'      ) : _currentScreen->setCursorYX          (p,      q); break; //VT100 | ||||
|     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('h',   3) :          setMode      (MODE_132Columns);break; //VT100 | ||||
|     case TY_CSI_PR('l',   3) :        resetMode      (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('h',   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('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', 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('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 | ||||
|     case TY_CSI_PE('p'      ) : /* IGNORED: reset         (        ) */ break; | ||||
|  | ||||
| @@ -797,13 +839,13 @@ void Vt102Emulation::sendString(const char* s , int length) | ||||
|   if ( length >= 0 ) | ||||
|     emit sendData(s,length); | ||||
|   else | ||||
|     emit sendData(s,strlen(s)); | ||||
|     emit sendData(s,qstrlen(s)); | ||||
| } | ||||
|  | ||||
| void Vt102Emulation::reportCursorPosition() | ||||
| { | ||||
|   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); | ||||
| } | ||||
|  | ||||
| @@ -822,7 +864,7 @@ void Vt102Emulation::reportTerminalType() | ||||
|  | ||||
| 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)) | ||||
|     sendString("\033[>0;115;0c"); // Why 115?  ;) | ||||
|   else | ||||
| @@ -830,96 +872,137 @@ void Vt102Emulation::reportSecondaryAttributes() | ||||
|                                   // 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) | ||||
| // DECREPTPARM | ||||
| { | ||||
|   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); | ||||
| } | ||||
|  | ||||
| void Vt102Emulation::reportStatus() | ||||
| { | ||||
|   sendString("\033[0n"); //VT100. Device status report. 0 = Ready. | ||||
|     sendString("\033[0n"); //VT100. Device status report. 0 = Ready. | ||||
| } | ||||
|  | ||||
| void Vt102Emulation::reportAnswerBack() | ||||
| { | ||||
|   // FIXME - Test this with VTTEST | ||||
|   // This is really obsolete VT100 stuff. | ||||
|   const char* ANSWER_BACK = ""; | ||||
|   sendString(ANSWER_BACK); | ||||
|     // FIXME - Test this with VTTEST | ||||
|     // This is really obsolete VT100 stuff. | ||||
|     const char* ANSWER_BACK = ""; | ||||
|     sendString(ANSWER_BACK); | ||||
| } | ||||
|  | ||||
| /*! | ||||
|     `cx',`cy' are 1-based. | ||||
|     `eventType' indicates the button pressed (0-2) | ||||
|                 or a general mouse release (3). | ||||
|     `cb' indicates the button pressed or released (0-2) or scroll event (4-5). | ||||
|  | ||||
|     eventType represents the kind of mouse action that occurred: | ||||
|         0 = Mouse button press or release | ||||
|         0 = Mouse button press | ||||
|         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) | ||||
|     return; | ||||
|     if (cx < 1 || cy < 1) | ||||
|         return; | ||||
|  | ||||
|   // normal buttons are passed as 0x20 + button, | ||||
|   // mouse wheel (buttons 4,5) as 0x5c + button | ||||
|   if (cb >= 4) | ||||
|     cb += 0x3c; | ||||
|     // 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; | ||||
|  | ||||
|   //Mouse motion handling | ||||
|   if ((getMode(MODE_Mouse1002) || getMode(MODE_Mouse1003)) && eventType == 1) | ||||
|       cb += 0x20; //add 32 to signify motion event | ||||
|     // normal buttons are passed as 0x20 + button, | ||||
|     // mouse wheel (buttons 4,5) as 0x5c + button | ||||
|     if (cb >= 4) | ||||
|         cb += 0x3c; | ||||
|  | ||||
|   char command[20]; | ||||
|   sprintf(command,"\033[M%c%c%c",cb+0x20,cx+0x20,cy+0x20); | ||||
|   sendString(command); | ||||
|     //Mouse motion handling | ||||
|     if ((getMode(MODE_Mouse1002) || getMode(MODE_Mouse1003)) && eventType == 1) | ||||
|         cb += 0x20; //add 32 to signify motion event | ||||
|  | ||||
|     char command[32]; | ||||
|     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); | ||||
| } | ||||
|  | ||||
| void Vt102Emulation::sendText( const QString& text ) | ||||
| void Vt102Emulation::sendText(const QString& text) | ||||
| { | ||||
|   if (!text.isEmpty())  | ||||
|   { | ||||
|     QKeyEvent event(QEvent::KeyPress,  | ||||
|                     0,  | ||||
|                     Qt::NoModifier,  | ||||
|                     text); | ||||
|     sendKeyEvent(&event); // expose as a big fat keypress event | ||||
|   } | ||||
|     if (!text.isEmpty()) { | ||||
|         QKeyEvent event(QEvent::KeyPress, | ||||
|                         0, | ||||
|                         Qt::NoModifier, | ||||
|                         text); | ||||
|         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; | ||||
|  | ||||
|     // get current states | ||||
|     if (getMode(MODE_NewLine)  ) states |= KeyboardTranslator::NewLineState; | ||||
|     if (getMode(MODE_Ansi)     ) states |= KeyboardTranslator::AnsiState; | ||||
|     if (getMode(MODE_NewLine)) states |= KeyboardTranslator::NewLineState; | ||||
|     if (getMode(MODE_Ansi)) states |= KeyboardTranslator::AnsiState; | ||||
|     if (getMode(MODE_AppCuKeys)) states |= KeyboardTranslator::CursorKeysState; | ||||
|     if (getMode(MODE_AppScreen)) states |= KeyboardTranslator::AlternateScreenState; | ||||
|     if (getMode(MODE_AppKeyPad) && (modifiers & Qt::KeypadModifier)) | ||||
|         states |= KeyboardTranslator::ApplicationKeypadState; | ||||
|  | ||||
|     // check flow control state | ||||
|     if (modifiers & Qt::ControlModifier) | ||||
|     { | ||||
|         if (event->key() == Qt::Key_S) | ||||
|     if (modifiers & Qt::ControlModifier) { | ||||
|         switch (event->key()) { | ||||
|         case Qt::Key_S: | ||||
|             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); | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // lookup key binding | ||||
|     if ( _keyTranslator ) | ||||
|     { | ||||
|     KeyboardTranslator::Entry entry = _keyTranslator->findEntry(  | ||||
|                                                 event->key() ,  | ||||
|                                                 modifiers, | ||||
|                                                 states ); | ||||
|     // look up key binding | ||||
|     if (_keyTranslator) { | ||||
|         KeyboardTranslator::Entry entry = _keyTranslator->findEntry( | ||||
|                                               event->key() , | ||||
|                                               modifiers, | ||||
|                                               states); | ||||
|  | ||||
|         // send result to terminal | ||||
|         QByteArray textToSend; | ||||
| @@ -928,8 +1011,9 @@ void Vt102Emulation::sendKeyEvent( QKeyEvent* event ) | ||||
|         // Alt+[Character] results in Esc+[Character] being sent | ||||
|         // (unless there is an entry defined for this particular combination | ||||
|         //  in the keyboard modifier) | ||||
|         bool wantsAltModifier = entry.modifiers() & entry.modifierMask() & Qt::AltModifier; | ||||
|         bool wantsAnyModifier = entry.state() &  | ||||
|         const bool wantsAltModifier = entry.modifiers() & entry.modifierMask() & Qt::AltModifier; | ||||
|         const bool wantsMetaModifier = entry.modifiers() & entry.modifierMask() & Qt::MetaModifier; | ||||
|         const bool wantsAnyModifier = entry.state() & | ||||
|                                 entry.stateMask() & KeyboardTranslator::AnyModifierState; | ||||
|  | ||||
|         if ( modifiers & Qt::AltModifier && !(wantsAltModifier || wantsAnyModifier) | ||||
| @@ -937,13 +1021,18 @@ void Vt102Emulation::sendKeyEvent( QKeyEvent* event ) | ||||
|         { | ||||
|             textToSend.prepend("\033"); | ||||
|         } | ||||
|         if ( modifiers & Qt::MetaModifier && !(wantsMetaModifier || wantsAnyModifier) | ||||
|              && !event->text().isEmpty() ) | ||||
|         { | ||||
|             textToSend.prepend("\030@s"); | ||||
|         } | ||||
|  | ||||
|         if ( entry.command() != KeyboardTranslator::NoCommand ) | ||||
|         { | ||||
|             KTerminalDisplay* currentView = _currentScreen->currentTerminalDisplay(); | ||||
|             if (entry.command() & KeyboardTranslator::EraseCommand) | ||||
|             KTerminalDisplay * currentView = _currentScreen->currentTerminalDisplay(); | ||||
|             if (entry.command() & KeyboardTranslator::EraseCommand) { | ||||
|                 textToSend += eraseChar(); | ||||
|             else if (entry.command() & KeyboardTranslator::ScrollPageUpCommand) | ||||
|             } else if (entry.command() & KeyboardTranslator::ScrollPageUpCommand) | ||||
|                 currentView->scrollScreenWindow(ScreenWindow::ScrollPages, -1); | ||||
|             else if (entry.command() & KeyboardTranslator::ScrollPageDownCommand) | ||||
|                 currentView->scrollScreenWindow(ScreenWindow::ScrollPages, 1); | ||||
| @@ -951,28 +1040,31 @@ void Vt102Emulation::sendKeyEvent( QKeyEvent* event ) | ||||
|                 currentView->scrollScreenWindow(ScreenWindow::ScrollLines, -1); | ||||
|             else if (entry.command() & KeyboardTranslator::ScrollLineDownCommand) | ||||
|                 currentView->scrollScreenWindow(ScreenWindow::ScrollLines, 1); | ||||
|  | ||||
|             // TODO command handling | ||||
| //            else if (entry.command() & KeyboardTranslator::ScrollUpToTopCommand) | ||||
| //                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)); | ||||
|         } | ||||
|         else | ||||
|             textToSend += _codec->fromUnicode(event->text()); | ||||
|  | ||||
|         sendData( textToSend.constData() , textToSend.length() ); | ||||
|         sendData(textToSend.constData(), textToSend.length()); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         // print an error message to the terminal if no key translator has been | ||||
|         // set | ||||
|         QString translatorError =  tr("No keyboard translator available.  " | ||||
|                                          "The information needed to convert key presses " | ||||
|                                          "into characters to send to the terminal "  | ||||
|                                          "is missing."); | ||||
| //        QString translatorError =  i18n("No keyboard translator available.  " | ||||
| //                                         "The information needed to convert key presses " | ||||
| //                                         "into characters to send to the terminal " | ||||
| //                                         "is missing."); | ||||
|         reset(); | ||||
|         receiveData( translatorError.toLatin1().constData() , translatorError.count() ); | ||||
| //        receiveData(translatorError.toAscii().constData(), translatorError.count()); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -1006,9 +1098,9 @@ void Vt102Emulation::sendKeyEvent( QKeyEvent* event ) | ||||
|  | ||||
| unsigned short Vt102Emulation::applyCharset(unsigned short c) | ||||
| { | ||||
|   if (CHARSET.graphic && 0x5f <= c && c <= 0x7e) return vt100_graphics[c-0x5f]; | ||||
|   if (CHARSET.pound && c == '#' ) return 0xa3; //This mode is obsolete | ||||
|   return c; | ||||
|     if (CHARSET.graphic && 0x5f <= c && c <= 0x7e) return vt100_graphics[c - 0x5f]; | ||||
|     if (CHARSET.pound && c == '#') return 0xa3;  //This mode is obsolete | ||||
|     return c; | ||||
| } | ||||
|  | ||||
| /* | ||||
| @@ -1021,31 +1113,31 @@ unsigned short Vt102Emulation::applyCharset(unsigned short c) | ||||
|  | ||||
| void Vt102Emulation::resetCharset(int scrno) | ||||
| { | ||||
|   _charset[scrno].cu_cs = 0; | ||||
|   strncpy(_charset[scrno].charset,"BBBB",4); | ||||
|   _charset[scrno].sa_graphic = false; | ||||
|   _charset[scrno].sa_pound = false; | ||||
|   _charset[scrno].graphic = false; | ||||
|   _charset[scrno].pound = false; | ||||
|     _charset[scrno].cu_cs = 0; | ||||
|     qstrncpy(_charset[scrno].charset, "BBBB", 4); | ||||
|     _charset[scrno].sa_graphic = false; | ||||
|     _charset[scrno].sa_pound = false; | ||||
|     _charset[scrno].graphic = false; | ||||
|     _charset[scrno].pound = false; | ||||
| } | ||||
|  | ||||
| void Vt102Emulation::setCharset(int n, int cs) // on both screens. | ||||
| { | ||||
|   _charset[0].charset[n&3] = cs; useCharset(_charset[0].cu_cs); | ||||
|   _charset[1].charset[n&3] = cs; useCharset(_charset[1].cu_cs); | ||||
|     _charset[0].charset[n & 3] = cs; useCharset(_charset[0].cu_cs); | ||||
|     _charset[1].charset[n & 3] = cs; useCharset(_charset[1].cu_cs); | ||||
| } | ||||
|  | ||||
| void Vt102Emulation::setAndUseCharset(int n, int cs) | ||||
| { | ||||
|   CHARSET.charset[n&3] = cs; | ||||
|   useCharset(n&3); | ||||
|     CHARSET.charset[n & 3] = cs; | ||||
|     useCharset(n & 3); | ||||
| } | ||||
|  | ||||
| void Vt102Emulation::useCharset(int n) | ||||
| { | ||||
|   CHARSET.cu_cs   = n&3; | ||||
|   CHARSET.graphic = (CHARSET.charset[n&3] == '0'); | ||||
|   CHARSET.pound   = (CHARSET.charset[n&3] == 'A'); //This mode is obsolete | ||||
|     CHARSET.cu_cs   = n & 3; | ||||
|     CHARSET.graphic = (CHARSET.charset[n & 3] == '0'); | ||||
|     CHARSET.pound   = (CHARSET.charset[n & 3] == 'A'); //This mode is obsolete | ||||
| } | ||||
|  | ||||
| void Vt102Emulation::setDefaultMargins() | ||||
| @@ -1056,25 +1148,25 @@ void Vt102Emulation::setDefaultMargins() | ||||
|  | ||||
| void Vt102Emulation::setMargins(int t, int b) | ||||
| { | ||||
|   _screen[0]->setMargins(t, b); | ||||
|   _screen[1]->setMargins(t, b); | ||||
|     _screen[0]->setMargins(t, b); | ||||
|     _screen[1]->setMargins(t, b); | ||||
| } | ||||
|  | ||||
| void Vt102Emulation::saveCursor() | ||||
| { | ||||
|   CHARSET.sa_graphic = CHARSET.graphic; | ||||
|   CHARSET.sa_pound   = CHARSET.pound; //This mode is obsolete | ||||
|   // we are not clear about these | ||||
|   //sa_charset = charsets[cScreen->_charset]; | ||||
|   //sa_charset_num = cScreen->_charset; | ||||
|   _currentScreen->saveCursor(); | ||||
|     CHARSET.sa_graphic = CHARSET.graphic; | ||||
|     CHARSET.sa_pound   = CHARSET.pound; //This mode is obsolete | ||||
|     // we are not clear about these | ||||
|     //sa_charset = charsets[cScreen->_charset]; | ||||
|     //sa_charset_num = cScreen->_charset; | ||||
|     _currentScreen->saveCursor(); | ||||
| } | ||||
|  | ||||
| void Vt102Emulation::restoreCursor() | ||||
| { | ||||
|   CHARSET.graphic = CHARSET.sa_graphic; | ||||
|   CHARSET.pound   = CHARSET.sa_pound; //This mode is obsolete | ||||
|   _currentScreen->restoreCursor(); | ||||
|     CHARSET.graphic = CHARSET.sa_graphic; | ||||
|     CHARSET.pound   = CHARSET.sa_pound; //This mode is obsolete | ||||
|     _currentScreen->restoreCursor(); | ||||
| } | ||||
|  | ||||
| /* ------------------------------------------------------------------------- */ | ||||
| @@ -1099,27 +1191,30 @@ void Vt102Emulation::restoreCursor() | ||||
|  | ||||
| void Vt102Emulation::resetModes() | ||||
| { | ||||
|   // MODE_Allow132Columns is not reset here | ||||
|   // to match Xterm's behaviour (see Xterm's VTReset() function) | ||||
|     // MODE_Allow132Columns is not reset here | ||||
|     // to match Xterm's behavior (see Xterm's VTReset() function) | ||||
|  | ||||
|   resetMode(MODE_132Columns); saveMode(MODE_132Columns); | ||||
|   resetMode(MODE_Mouse1000);  saveMode(MODE_Mouse1000); | ||||
|   resetMode(MODE_Mouse1001);  saveMode(MODE_Mouse1001); | ||||
|   resetMode(MODE_Mouse1002);  saveMode(MODE_Mouse1002); | ||||
|   resetMode(MODE_Mouse1003);  saveMode(MODE_Mouse1003); | ||||
|     resetMode(MODE_132Columns); saveMode(MODE_132Columns); | ||||
|     resetMode(MODE_Mouse1000);  saveMode(MODE_Mouse1000); | ||||
|     resetMode(MODE_Mouse1001);  saveMode(MODE_Mouse1001); | ||||
|     resetMode(MODE_Mouse1002);  saveMode(MODE_Mouse1002); | ||||
|     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_AppCuKeys);  saveMode(MODE_AppCuKeys); | ||||
|   resetMode(MODE_AppKeyPad);  saveMode(MODE_AppKeyPad); | ||||
|   resetMode(MODE_NewLine); | ||||
|   setMode(MODE_Ansi); | ||||
|     resetMode(MODE_AppScreen);  saveMode(MODE_AppScreen); | ||||
|     resetMode(MODE_AppCuKeys);  saveMode(MODE_AppCuKeys); | ||||
|     resetMode(MODE_AppKeyPad);  saveMode(MODE_AppKeyPad); | ||||
|     resetMode(MODE_NewLine); | ||||
|     setMode(MODE_Ansi); | ||||
| } | ||||
|  | ||||
| void Vt102Emulation::setMode(int m) | ||||
| { | ||||
|   _currentModes.mode[m] = true; | ||||
|   switch (m) | ||||
|   { | ||||
|     _currentModes.mode[m] = true; | ||||
|     switch (m) { | ||||
|     case MODE_132Columns: | ||||
|         if (getMode(MODE_Allow132Columns)) | ||||
|             clearScreenAndSetColumns(132); | ||||
| @@ -1130,25 +1225,30 @@ void Vt102Emulation::setMode(int m) | ||||
|     case MODE_Mouse1001: | ||||
|     case MODE_Mouse1002: | ||||
|     case MODE_Mouse1003: | ||||
|          emit programUsesMouseChanged(false);  | ||||
|     break; | ||||
|         emit programUsesMouseChanged(false); | ||||
|         break; | ||||
|  | ||||
|     case MODE_AppScreen : _screen[1]->clearSelection(); | ||||
|                           setScreen(1); | ||||
|     break; | ||||
|   } | ||||
|   if (m < MODES_SCREEN || m == MODE_NewLine) | ||||
|   { | ||||
|     _screen[0]->setMode(m); | ||||
|     _screen[1]->setMode(m); | ||||
|   } | ||||
|     case MODE_BracketedPaste: | ||||
|         //emit programBracketedPasteModeChanged(true); | ||||
|         break; | ||||
|  | ||||
|     case MODE_AppScreen : | ||||
|         _screen[1]->clearSelection(); | ||||
|         setScreen(1); | ||||
|         break; | ||||
|     } | ||||
|     // 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[1]->setMode(m); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void Vt102Emulation::resetMode(int m) | ||||
| { | ||||
|   _currentModes.mode[m] = false; | ||||
|   switch (m) | ||||
|   { | ||||
|     _currentModes.mode[m] = false; | ||||
|     switch (m) { | ||||
|     case MODE_132Columns: | ||||
|         if (getMode(MODE_Allow132Columns)) | ||||
|             clearScreenAndSetColumns(80); | ||||
| @@ -1158,73 +1258,102 @@ void Vt102Emulation::resetMode(int m) | ||||
|     case MODE_Mouse1002 : | ||||
|     case MODE_Mouse1003 : | ||||
|         emit programUsesMouseChanged(true); | ||||
|     break; | ||||
|         break; | ||||
|  | ||||
|     case MODE_BracketedPaste: | ||||
|         //emit programBracketedPasteModeChanged(false); | ||||
|         break; | ||||
|  | ||||
|     case MODE_AppScreen : | ||||
|         _screen[0]->clearSelection(); | ||||
|         setScreen(0); | ||||
|     break; | ||||
|   } | ||||
|   if (m < MODES_SCREEN || m == MODE_NewLine) | ||||
|   { | ||||
|     _screen[0]->resetMode(m); | ||||
|     _screen[1]->resetMode(m); | ||||
|   } | ||||
|         break; | ||||
|     } | ||||
|     // 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[1]->resetMode(m); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void Vt102Emulation::saveMode(int m) | ||||
| { | ||||
|   _savedModes.mode[m] = _currentModes.mode[m]; | ||||
|     _savedModes.mode[m] = _currentModes.mode[m]; | ||||
| } | ||||
|  | ||||
| void Vt102Emulation::restoreMode(int m) | ||||
| { | ||||
|   if (_savedModes.mode[m])  | ||||
|       setMode(m);  | ||||
|   else  | ||||
|       resetMode(m); | ||||
|     if (_savedModes.mode[m]) | ||||
|         setMode(m); | ||||
|     else | ||||
|         resetMode(m); | ||||
| } | ||||
|  | ||||
| bool Vt102Emulation::getMode(int m) | ||||
| { | ||||
|   return _currentModes.mode[m]; | ||||
|     return _currentModes.mode[m]; | ||||
| } | ||||
|  | ||||
| char Vt102Emulation::eraseChar() const | ||||
| { | ||||
|   KeyboardTranslator::Entry entry = _keyTranslator->findEntry( | ||||
|                                             Qt::Key_Backspace, | ||||
|                                             0, | ||||
|                                             0); | ||||
|   if ( entry.text().count() > 0 ) | ||||
|       return entry.text()[0]; | ||||
|   else | ||||
|       return '\b'; | ||||
|     KeyboardTranslator::Entry entry = _keyTranslator->findEntry( | ||||
|                                           Qt::Key_Backspace, | ||||
|                                           0, | ||||
|                                           0); | ||||
|     if (entry.text().count() > 0) | ||||
|         return entry.text()[0]; | ||||
|     else | ||||
|         return '\b'; | ||||
| } | ||||
|  | ||||
| #if 0 | ||||
| // print contents of the scan buffer | ||||
| static void hexdump(int* s, int len) | ||||
| { int i; | ||||
|   for (i = 0; i < len; i++) | ||||
|   { | ||||
|     if (s[i] == '\\') | ||||
|       printf("\\\\"); | ||||
|     else | ||||
|     if ((s[i]) > 32 && s[i] < 127) | ||||
|       printf("%c",s[i]); | ||||
|     else | ||||
|       printf("\\%04x(hex)",s[i]); | ||||
|   } | ||||
| { | ||||
|     int i; | ||||
|     for (i = 0; i < len; i++) { | ||||
|         if (s[i] == '\\') | ||||
|             printf("\\\\"); | ||||
|         else if ((s[i]) > 32 && s[i] < 127) | ||||
|             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() | ||||
| { | ||||
|   if (tokenBufferPos == 0 || ( tokenBufferPos == 1 && (tokenBuffer[0] & 0xff) >= 32) )  | ||||
|     return; | ||||
|   printf("Undecodable sequence: ");  | ||||
|   hexdump(tokenBuffer,tokenBufferPos);  | ||||
|   printf("\n"); | ||||
|     if (tokenBufferPos == 0 || (tokenBufferPos == 1 && (tokenBuffer[0] & 0xff) >= 32)) | ||||
|         return; | ||||
|  | ||||
| //    printf("Undecodable sequence: "); | ||||
| //    hexdump(tokenBuffer, tokenBufferPos); | ||||
| //    printf("\n"); | ||||
|  | ||||
|     QString outputError = QString("Undecodable sequence: "); | ||||
|     outputError.append(hexdump2(tokenBuffer, tokenBufferPos)); | ||||
|     //kDebug() << outputError; | ||||
| } | ||||
|  | ||||
| //#include "Vt102Emulation.moc" | ||||
|  | ||||
|   | ||||
| @@ -23,19 +23,16 @@ | ||||
| #ifndef VT102EMULATION_H | ||||
| #define VT102EMULATION_H | ||||
|  | ||||
| // Standard Library | ||||
| #include <stdio.h> | ||||
|  | ||||
| // Qt | ||||
| #include <QtGui/QKeyEvent> | ||||
| #include <QtCore/QHash> | ||||
| #include <QtCore/QTimer> | ||||
|  | ||||
| // Konsole | ||||
| #include "Emulation.h" | ||||
| #include "Screen.h" | ||||
| #include "ScreenWindow.h" | ||||
| #include "TerminalDisplay.h" | ||||
|  | ||||
| class QTimer; | ||||
| class QKeyEvent; | ||||
|  | ||||
| #define MODE_AppScreen       (MODES_SCREEN+0)   // Mode #1 | ||||
| #define MODE_AppCuKeys       (MODES_SCREEN+1)   // Application cursor keys (DECCKM) | ||||
| @@ -44,21 +41,27 @@ | ||||
| #define MODE_Mouse1001       (MODES_SCREEN+4)   // Use Hilight mouse tracking | ||||
| #define MODE_Mouse1002       (MODES_SCREEN+5)   // Use cell motion mouse tracking | ||||
| #define MODE_Mouse1003       (MODES_SCREEN+6)   // Use all motion mouse tracking | ||||
| #define MODE_Ansi            (MODES_SCREEN+7)   // Use US Ascii for character sets G0-G3 (DECANM)  | ||||
| #define MODE_132Columns      (MODES_SCREEN+8)   // 80 <-> 132 column mode switch (DECCOLM) | ||||
| #define MODE_Allow132Columns (MODES_SCREEN+9)   // Allow DECCOLM mode | ||||
| #define MODE_total           (MODES_SCREEN+10) | ||||
| #define MODE_Mouse1005       (MODES_SCREEN+7)   // Xterm-style extended coordinates | ||||
| #define MODE_Mouse1006       (MODES_SCREEN+8)   // 2nd Xterm-style extended coordinates | ||||
| #define MODE_Mouse1015       (MODES_SCREEN+9)   // Urxvt-style extended coordinates | ||||
| #define MODE_Ansi            (MODES_SCREEN+10)   // Use US Ascii for character sets G0-G3 (DECANM) | ||||
| #define MODE_132Columns      (MODES_SCREEN+11)  // 80 <-> 132 column mode switch (DECCOLM) | ||||
| #define MODE_Allow132Columns (MODES_SCREEN+12)  // Allow DECCOLM mode | ||||
| #define MODE_BracketedPaste  (MODES_SCREEN+13)  // Xterm-style bracketed paste mode | ||||
| #define MODE_total           (MODES_SCREEN+14) | ||||
|  | ||||
|  | ||||
| struct CharCodes | ||||
| namespace Konsole | ||||
| { | ||||
|   // coding info | ||||
|   char charset[4]; // | ||||
|   int  cu_cs;      // actual charset. | ||||
|   bool graphic;    // Some VT100 tricks | ||||
|   bool pound  ;    // Some VT100 tricks | ||||
|   bool sa_graphic; // saved graphic | ||||
|   bool sa_pound;   // saved pound | ||||
| extern unsigned short vt100_graphics[32]; | ||||
|  | ||||
| struct CharCodes { | ||||
|     // coding info | ||||
|     char charset[4]; // | ||||
|     int  cu_cs;      // actual charset. | ||||
|     bool graphic;    // Some VT100 tricks | ||||
|     bool pound;      // Some VT100 tricks | ||||
|     bool sa_graphic; // saved graphic | ||||
|     bool sa_pound;   // saved pound | ||||
| }; | ||||
|  | ||||
| /** | ||||
| @@ -73,118 +76,116 @@ struct CharCodes | ||||
|  */ | ||||
| class Vt102Emulation : public Emulation | ||||
| { | ||||
| Q_OBJECT | ||||
|     Q_OBJECT | ||||
|  | ||||
| public: | ||||
|   /** Constructs a new emulation */ | ||||
|   Vt102Emulation(); | ||||
|   ~Vt102Emulation(); | ||||
|     /** Constructs a new emulation */ | ||||
|     Vt102Emulation(); | ||||
|     ~Vt102Emulation(); | ||||
|  | ||||
|   // reimplemented from Emulation | ||||
|   virtual void clearEntireScreen(); | ||||
|   virtual void reset(); | ||||
|   virtual char eraseChar() const; | ||||
|     // reimplemented from Emulation | ||||
|     virtual void clearEntireScreen(); | ||||
|     virtual void reset(); | ||||
|     virtual char eraseChar() const; | ||||
|  | ||||
| public slots: | ||||
|   // reimplemented from Emulation  | ||||
|   virtual void sendString(const char*,int length = -1); | ||||
|   virtual void sendText(const QString& text); | ||||
|   virtual void sendKeyEvent(QKeyEvent*); | ||||
|   virtual void sendMouseEvent(int buttons, int column, int line, int eventType); | ||||
|     // reimplemented from Emulation | ||||
|     virtual void sendString(const char*, int length = -1); | ||||
|     virtual void sendText(const QString& text); | ||||
|     virtual void sendKeyEvent(QKeyEvent*); | ||||
|     virtual void sendMouseEvent(int buttons, int column, int line, int eventType); | ||||
|  | ||||
| protected: | ||||
|   // reimplemented from Emulation | ||||
|   virtual void setMode(int mode); | ||||
|   virtual void resetMode(int mode); | ||||
|   virtual void receiveChar(int cc); | ||||
|     // reimplemented from Emulation | ||||
|     virtual void setMode(int mode); | ||||
|     virtual void resetMode(int mode); | ||||
|     virtual void receiveChar(int cc); | ||||
|  | ||||
| private slots: | ||||
|   //causes changeTitle() to be emitted for each (int,QString) pair in pendingTitleUpdates | ||||
|   //used to buffer multiple title updates | ||||
|   void updateTitle(); | ||||
|     //causes changeTitle() to be emitted for each (int,QString) pair in pendingTitleUpdates | ||||
|     //used to buffer multiple title updates | ||||
|     void updateTitle(); | ||||
|  | ||||
| private: | ||||
|   unsigned short applyCharset(unsigned short c); | ||||
|   void setCharset(int n, int cs); | ||||
|   void useCharset(int n); | ||||
|   void setAndUseCharset(int n, int cs); | ||||
|   void saveCursor(); | ||||
|   void restoreCursor(); | ||||
|   void resetCharset(int scrno); | ||||
|     unsigned short applyCharset(unsigned short c); | ||||
|     void setCharset(int n, int cs); | ||||
|     void useCharset(int n); | ||||
|     void setAndUseCharset(int n, int cs); | ||||
|     void saveCursor(); | ||||
|     void restoreCursor(); | ||||
|     void resetCharset(int scrno); | ||||
|  | ||||
|   void setMargins(int top, int bottom); | ||||
|   //set margins for all screens back to their defaults | ||||
|   void setDefaultMargins(); | ||||
|     void setMargins(int top, int bottom); | ||||
|     //set margins for all screens back to their defaults | ||||
|     void setDefaultMargins(); | ||||
|  | ||||
|   // returns true if 'mode' is set or false otherwise | ||||
|   bool getMode    (int mode); | ||||
|   // saves the current boolean value of 'mode' | ||||
|   void saveMode   (int mode); | ||||
|   // restores the boolean value of 'mode'  | ||||
|   void restoreMode(int mode); | ||||
|   // resets all modes | ||||
|   // (except MODE_Allow132Columns) | ||||
|   void resetModes(); | ||||
|     // returns true if 'mode' is set or false otherwise | ||||
|     bool getMode(int mode); | ||||
|     // saves the current boolean value of 'mode' | ||||
|     void saveMode(int mode); | ||||
|     // restores the boolean value of 'mode' | ||||
|     void restoreMode(int mode); | ||||
|     // resets all modes | ||||
|     // (except MODE_Allow132Columns) | ||||
|     void resetModes(); | ||||
|  | ||||
|   void resetTokenizer(); | ||||
|   #define MAX_TOKEN_LENGTH 80 | ||||
|   void addToCurrentToken(int cc); | ||||
|   int tokenBuffer[MAX_TOKEN_LENGTH]; //FIXME: overflow? | ||||
|   int tokenBufferPos; | ||||
|     void resetTokenizer(); | ||||
| #define MAX_TOKEN_LENGTH 256 // Max length of tokens (e.g. window title) | ||||
|     void addToCurrentToken(int cc); | ||||
|     int tokenBuffer[MAX_TOKEN_LENGTH]; //FIXME: overflow? | ||||
|     int tokenBufferPos; | ||||
| #define MAXARGS 15 | ||||
|   void addDigit(int dig); | ||||
|   void addArgument(); | ||||
|   int argv[MAXARGS]; | ||||
|   int argc; | ||||
|   void initTokenizer(); | ||||
|     void addDigit(int dig); | ||||
|     void addArgument(); | ||||
|     int argv[MAXARGS]; | ||||
|     int argc; | ||||
|     void initTokenizer(); | ||||
|  | ||||
|   // Set of flags for each of the ASCII characters which indicates | ||||
|   // what category they fall into (printable character, control, digit etc.) | ||||
|   // for the purposes of decoding terminal output | ||||
|   int charClass[256]; | ||||
|     // Set of flags for each of the ASCII characters which indicates | ||||
|     // what category they fall into (printable character, control, digit etc.) | ||||
|     // for the purposes of decoding terminal output | ||||
|     int charClass[256]; | ||||
|  | ||||
|   void reportDecodingError();  | ||||
|     void reportDecodingError(); | ||||
|  | ||||
|   void processToken(int code, int p, int q); | ||||
|   void processWindowAttributeChange(); | ||||
|     void processToken(int code, int p, int q); | ||||
|     void processWindowAttributeChange(); | ||||
|  | ||||
|   void reportTerminalType(); | ||||
|   void reportSecondaryAttributes(); | ||||
|   void reportStatus(); | ||||
|   void reportAnswerBack(); | ||||
|   void reportCursorPosition(); | ||||
|   void reportTerminalParms(int p); | ||||
|     void reportTerminalType(); | ||||
|     void reportSecondaryAttributes(); | ||||
|     void reportStatus(); | ||||
|     void reportAnswerBack(); | ||||
|     void reportCursorPosition(); | ||||
|     void reportTerminalParms(int p); | ||||
|  | ||||
|   void onScrollLock(); | ||||
|   void scrollLock(const bool lock); | ||||
|     // clears the screen and resizes it to the specified | ||||
|     // number of columns | ||||
|     void clearScreenAndSetColumns(int columnCount); | ||||
|  | ||||
|   // clears the screen and resizes it to the specified | ||||
|   // number of columns | ||||
|   void clearScreenAndSetColumns(int columnCount); | ||||
|     CharCodes _charset[2]; | ||||
|  | ||||
|   CharCodes _charset[2]; | ||||
|     class TerminalState | ||||
|     { | ||||
|     public: | ||||
|         // Initializes all modes to false | ||||
|         TerminalState() { | ||||
|             memset(&mode, false, MODE_total * sizeof(bool)); | ||||
|         } | ||||
|  | ||||
|   class TerminalState | ||||
|   { | ||||
|   public: | ||||
|     // Initializes all modes to false | ||||
|     TerminalState() | ||||
|     { memset(&mode,false,MODE_total * sizeof(bool)); } | ||||
|         bool mode[MODE_total]; | ||||
|     }; | ||||
|  | ||||
|     bool mode[MODE_total]; | ||||
|   }; | ||||
|     TerminalState _currentModes; | ||||
|     TerminalState _savedModes; | ||||
|  | ||||
|   TerminalState _currentModes; | ||||
|   TerminalState _savedModes; | ||||
|  | ||||
|   //hash table and timer for buffering calls to the session instance  | ||||
|   //to update the name of the session | ||||
|   //or window title. | ||||
|   //these calls occur when certain escape sequences are seen in the  | ||||
|   //output from the terminal | ||||
|   QHash<int,QString> _pendingTitleUpdates; | ||||
|   QTimer* _titleUpdateTimer; | ||||
|     //hash table and timer for buffering calls to the session instance | ||||
|     //to update the name of the session | ||||
|     //or window title. | ||||
|     //these calls occur when certain escape sequences are seen in the | ||||
|     //output from the terminal | ||||
|     QHash<int, QString> _pendingTitleUpdates; | ||||
|     QTimer* _titleUpdateTimer; | ||||
| }; | ||||
|  | ||||
| } | ||||
|  | ||||
| #endif // VT102EMULATION_H | ||||
|   | ||||
		Reference in New Issue
	
	Block a user