# HG changeset patch # User John W. Eaton # Date 1557847616 0 # Node ID 55301e06b238094998a090f7015245969f31c50b # Parent 4092ffc1e43c50ed937484bc43337db2672ca83b experimental qterminal diff -r 4092ffc1e43c -r 55301e06b238 libgui/qterminal/libqterminal/QGenericTerminalColors.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libgui/qterminal/libqterminal/QGenericTerminalColors.cpp Tue May 14 15:26:56 2019 +0000 @@ -0,0 +1,46 @@ +/* + +Copyright (C) 2011-2019 Michael Goffioul + +This file is part of QConsole. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, +see . + +*/ + +#include "QGenericTerminalColors.h" + +////////////////////////////////////////////////////////////////////////////// + +QConsoleColors::QConsoleColors (void) + : QMap () +{ + (*this)[0] = Qt::black; + (*this)[1] = Qt::darkBlue; + (*this)[2] = Qt::darkGreen; + (*this)[3] = Qt::darkCyan; + (*this)[4] = Qt::darkRed; + (*this)[5] = Qt::darkMagenta; + (*this)[6] = Qt::darkYellow; + (*this)[7] = Qt::lightGray; + (*this)[8] = Qt::darkGray; + (*this)[9] = Qt::blue; + (*this)[10] = Qt::green; + (*this)[11] = Qt::cyan; + (*this)[12] = Qt::red; + (*this)[13] = Qt::magenta; + (*this)[14] = Qt::yellow; + (*this)[15] = Qt::white; +} diff -r 4092ffc1e43c -r 55301e06b238 libgui/qterminal/libqterminal/QGenericTerminalColors.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libgui/qterminal/libqterminal/QGenericTerminalColors.h Tue May 14 15:26:56 2019 +0000 @@ -0,0 +1,39 @@ +/* + +Copyright (C) 2011-2019 Michael Goffioul + +This file is part of QConsole. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, +see . + +*/ + +#ifndef __QConsoleColors_h__ +#define __QConsoleColors_h__ 1 + +#include +#include + +////////////////////////////////////////////////////////////////////////////// + +class QConsoleColors : public QMap +{ +public: + QConsoleColors (void); +}; + +////////////////////////////////////////////////////////////////////////////// + +#endif // __QConsoleColors_h__ diff -r 4092ffc1e43c -r 55301e06b238 libgui/qterminal/libqterminal/QGenericTerminalImpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libgui/qterminal/libqterminal/QGenericTerminalImpl.cpp Tue May 14 15:26:56 2019 +0000 @@ -0,0 +1,1549 @@ +/* + +Copyright (C) 2011-2019 Michael Goffioul + +This file is part of QConsole. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, +see . + +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "QGenericTerminalImpl.h" +#include "QGenericTerminalColors.h" + +// Uncomment to log activity to LOGFILENAME +// #define DEBUG_QCONSOLE +#define LOGFILENAME "QConsole.log" + +typedef void CHAR_INFO; + +////////////////////////////////////////////////////////////////////////////// + +class QConsoleView : public QWidget +{ +public: + QConsoleView (QGenericTerminalImpl* parent = 0) : QWidget (parent), q (parent) { } + ~QConsoleView (void) { } + +protected: + void paintEvent (QPaintEvent* event) { q->viewPaintEvent (this, event); } + void resizeEvent (QResizeEvent* event) { q->viewResizeEvent (this, event); } + +private: + QGenericTerminalImpl* q; +}; + +////////////////////////////////////////////////////////////////////////////// + +class QConsoleThread : public QThread +{ +public: + QConsoleThread (QGenericTerminalImpl* console) : QThread (console), q (console) { } + +protected: + void run (void) + { q->start (); } + +private: + QGenericTerminalImpl* q; +}; + +////////////////////////////////////////////////////////////////////////////// + +static QString translateKey (QKeyEvent *ev) +{ + QString esc = "\x1b"; + QString s; + + if (ev->key () == Qt::Key_Delete) + s = esc + "[C\b"; + else if (!ev->text ().isEmpty ()) + s = ev->text (); + else + { + + switch (ev->key ()) + { + case Qt::Key_Up: + s = esc + "[A"; + break; + + case Qt::Key_Down: + s = esc + "[B"; + break; + + case Qt::Key_Right: + s = esc + "[C"; + break; + + case Qt::Key_Left: + s = esc + "[D"; + break; + + case Qt::Key_Home: + s = esc + "[H"; + break; + + case Qt::Key_End: + s = esc + "[F"; + break; + + case Qt::Key_Insert: + s = esc + "[2~"; + break; + + case Qt::Key_PageUp: + s = esc + "[5~"; + break; + + case Qt::Key_PageDown: + s = esc + "[6~"; + break; + + case Qt::Key_Escape: + s = esc; + break; + + default: + break; + } + } + + return s; +} + +class QConsolePrivate +{ + friend class QGenericTerminalImpl; + +public: + + enum KeyboardCursorType + { + BlockCursor, + UnderlineCursor, + IBeamCursor + }; + + QConsolePrivate (QGenericTerminalImpl* parent, const QString& cmd = QString ()); + ~QConsolePrivate (void); + + void updateConsoleSize (bool sync = false, bool allow_smaller_width = false); + void updateHorizontalScrollBar (void); + void updateVerticalScrollBar (void); + void setHorizontalScrollValue (int value); + void setVerticalScrollValue (int value); + void updateConsoleView (bool grab = true); + void sendConsoleText (const QString& s); + QRect cursorRect (void); + void selectAll(); + void selectWord(const QPoint& cellPos); + void selectLine(const QPoint& cellPos); + + void log (const char* fmt, ...); + + QPoint posToCell (const QPoint& pt); + QString getSelection (void); + void updateSelection (void); + void clearSelection (void); + + QColor backgroundColor (void) const; + QColor foregroundColor (void) const; + QColor selectionColor (void) const; + QColor cursorColor (void) const; + + void setBackgroundColor (const QColor& color); + void setForegroundColor (const QColor& color); + void setSelectionColor (const QColor& color); + void setCursorColor (bool useForegroundColor, const QColor& color); + void setScrollBufferSize (int value); + + void drawTextBackground (QPainter& p, int cx1, int cy1, int cx2, int cy2, + int cw, int ch); + + void drawSelection (QPainter& p, int cx1, int cy1, int cx2, int cy2, + int cw, int ch); + + void drawCursor (QPainter& p); + + void drawText (QPainter& p, int cx1, int cy1, int cx2, int cy2, + int cw, int ch); + +private: + QGenericTerminalImpl* q; + +private: + QFont m_font; + QString m_command; + QConsoleColors m_colors; + bool m_inWheelEvent; + QString m_title; + + QSize m_charSize; + QSize m_bufferSize; + QRect m_consoleRect; + bool m_auto_scroll; + QPoint m_cursorPos; + bool m_cursorBlinking; + bool m_hasBlinkingCursor; + QTimer *m_blinkCursorTimer; + KeyboardCursorType m_cursorType; + + QPoint m_beginSelection; + QPoint m_endSelection; + bool m_settingSelection; + + QColor m_selectionColor; + QColor m_cursorColor; + + //XX CHAR_INFO* m_buffer; + //XX CHAR_INFO* m_tmpBuffer; + + QConsoleView* m_consoleView; + QScrollBar* m_horizontalScrollBar; + QScrollBar* m_verticalScrollBar; + + // The delay in milliseconds between redrawing blinking text. + static const int BLINK_DELAY = 500; +}; + +static void maybeSwapPoints (QPoint& begin, QPoint& end) +{ + if (end.y () < begin.y () + || (end.y () == begin.y () && end.x () < begin.x ())) + qSwap (begin, end); +} + +////////////////////////////////////////////////////////////////////////////// + +QConsolePrivate::QConsolePrivate (QGenericTerminalImpl* parent, const QString& cmd) + : q (parent), m_command (cmd), m_auto_scroll (true), m_cursorBlinking (false), + m_hasBlinkingCursor (true), m_cursorType (BlockCursor), + m_beginSelection (0, 0), m_endSelection (0, 0), m_settingSelection (false), + m_inWheelEvent (false) +{ + log (NULL); + + // XXX FIXME XXX + m_bufferSize = QSize (100, 500); + m_consoleRect = QRect (0, 0, 100, 500); + m_cursorPos = QPoint (0, 0); + + log ("Initial console parameters:\n"); + log (" buffer size: %d x %d\n", m_bufferSize.width (), + m_bufferSize.height ()); + log (" window: (%d, %d) -> (%d, %d) [%d x %d]\n", + m_consoleRect.left (), m_consoleRect.top (), + m_consoleRect.right (), m_consoleRect.bottom (), + m_consoleRect.width (), m_consoleRect.height ()); + +#if 0 + + wchar_t titleBuf[260]; + GetConsoleTitleW (titleBuf, sizeof (titleBuf)); + q->setWindowTitle (QString::fromWCharArray (titleBuf)); + +#endif + + m_font.setFamily ("Lucida Console"); + m_font.setPointSize (9); + m_font.setStyleHint (QFont::TypeWriter); + +#if 0 + + m_buffer = m_tmpBuffer = 0; + +#endif + + m_consoleView = new QConsoleView (parent); + m_horizontalScrollBar = new QScrollBar (Qt::Horizontal, parent); + m_verticalScrollBar = new QScrollBar (Qt::Vertical, parent); + + QGridLayout* l = new QGridLayout (parent); + l->setContentsMargins (0, 0, 0, 0); + l->setSpacing (0); + l->addWidget (m_consoleView, 0, 0); + l->addWidget (m_horizontalScrollBar, 1, 0); + l->addWidget (m_verticalScrollBar, 0, 1); + + // Defaults. + setBackgroundColor (Qt::white); + setForegroundColor (Qt::black); + setSelectionColor (Qt::lightGray); + setCursorColor (false, Qt::darkGray); + + // FIXME -- should we set the palette? + QPalette palette (backgroundColor ()); + m_consoleView->setPalette (palette); + + m_consoleView->setAutoFillBackground (true); + + m_consoleView->setFont (m_font); + parent->setFocusPolicy (Qt::StrongFocus); + parent->winId (); + + updateHorizontalScrollBar (); + updateVerticalScrollBar (); + + m_blinkCursorTimer = new QTimer (parent); + QObject::connect (m_blinkCursorTimer, SIGNAL (timeout()), + q, SLOT (blinkCursorEvent ())); + + QObject::connect (m_horizontalScrollBar, SIGNAL (valueChanged (int)), + q, SLOT (horizontalScrollValueChanged (int))); + + QObject::connect (m_verticalScrollBar, SIGNAL (valueChanged (int)), + q, SLOT (verticalScrollValueChanged (int))); +} + +////////////////////////////////////////////////////////////////////////////// + +QConsolePrivate::~QConsolePrivate (void) +{ +#if 0 + + delete [] m_buffer; + delete [] m_tmpBuffer; + +#endif +} + +////////////////////////////////////////////////////////////////////////////// + +QPoint QConsolePrivate::posToCell (const QPoint& p) +{ + return QPoint (m_consoleRect.left () + p.x () / m_charSize.width (), + m_consoleRect.top () + p.y () / m_charSize.height ()); +} + +QString QConsolePrivate::getSelection (void) +{ + QString selection; + + QPoint begin = m_beginSelection; + QPoint end = m_endSelection; + + maybeSwapPoints (begin, end); + + if (begin != end) + { +#if 0 + CHAR_INFO* buf; + COORD bufSize, bufCoord; + SMALL_RECT bufRect; + int nr; + + nr = end.y () - begin.y () + 1; + buf = new CHAR_INFO[m_bufferSize.width () * nr]; + bufSize.X = m_bufferSize.width (); + bufSize.Y = nr; + bufCoord.X = 0; + bufCoord.Y = 0; + + bufRect.Left = 0; + bufRect.Right = m_bufferSize.width (); + bufRect.Top = begin.y (); + bufRect.Bottom = end.y (); + + if (ReadConsoleOutput (m_stdOut, buf, bufSize, bufCoord, &bufRect)) + { + int start_pos = begin.x (); + int end_pos = (nr - 1) * m_bufferSize.width () + end.x (); + int lastNonSpace = -1; + + for (int i = start_pos; i <= end_pos; i++) + { + if (i && (i % m_bufferSize.width ()) == 0) + { + if (lastNonSpace >= 0) + selection.truncate (lastNonSpace); + selection.append ('\n'); + lastNonSpace = selection.length (); + } + + QChar c (buf[i].Char.UnicodeChar); + if (c.isNull ()) + c = QChar (' '); + + selection.append (c); + if (! c.isSpace ()) + lastNonSpace = selection.length (); + } + + if (lastNonSpace >= 0) + selection.truncate (lastNonSpace); + } +#endif + } + + return selection; +} + +void QConsolePrivate::updateSelection (void) +{ + QPoint begin = m_beginSelection; + QPoint end = m_endSelection; + + maybeSwapPoints (begin, end); + + begin.rx () = 0; + end.rx () = m_consoleRect.width (); + + m_consoleView->update (); +} + +void QConsolePrivate::clearSelection (void) +{ + m_beginSelection = m_endSelection = QPoint (); + + m_consoleView->update (); +} + +QColor QConsolePrivate::backgroundColor (void) const +{ + return m_colors[15]; +} + +QColor QConsolePrivate::foregroundColor (void) const +{ + return m_colors[0]; +} + +QColor QConsolePrivate::selectionColor (void) const +{ + return m_selectionColor; +} + +QColor QConsolePrivate::cursorColor (void) const +{ + return m_cursorColor.isValid () ? m_cursorColor : foregroundColor (); +} + +void QConsolePrivate::setBackgroundColor (const QColor& color) +{ + m_colors[15] = color; + + QPalette palette (color); + m_consoleView->setPalette (palette); +} + +void QConsolePrivate::setForegroundColor (const QColor& color) +{ + m_colors[0] = color; +} + +void QConsolePrivate::setSelectionColor (const QColor& color) +{ + m_selectionColor = color; +} + +void QConsolePrivate::setCursorColor (bool useForegroundColor, + const QColor& color) +{ + m_cursorColor = useForegroundColor ? QColor () : color; +} + +void QConsolePrivate::setScrollBufferSize (int value) +{ +#if 0 + + CONSOLE_SCREEN_BUFFER_INFO sbi; + GetConsoleScreenBufferInfo (m_stdOut, &sbi); + + m_bufferSize = QSize (sbi.dwSize.X, (SHORT)value); + + updateConsoleSize (true); + +#endif +} + +void QConsolePrivate::drawTextBackground (QPainter& p, int cx1, int cy1, + int cx2, int cy2, int cw, int ch) +{ + p.save (); + +#if 0 + + int ascent = p.fontMetrics ().ascent (); + int stride = m_consoleRect.width (); + int y = ascent + cy1 * ch;; + + for (int j = cy1; j <= cy2; j++, y += ch) + { + int len = 0; + bool hasChar = false; + int x = cx1 * cw; + WORD attr = 0; + + for (int i = cx1; i <= cx2; i++) + { + CHAR_INFO* ci = &(m_buffer[stride*j+i]); + + if ((ci->Attributes & 0x00ff) != attr) + { + // Character attributes changed + if (len != 0) + { + // String buffer not empty -> draw it + if (hasChar || (attr & 0x00f0)) + { + if (attr & 0x00f0) + p.fillRect (x, y-ascent, len * cw, ch, p.brush ()); + } + + x += (len * cw); + len = 0; + hasChar = false; + } + // Update current brush and store current attributes + attr = (ci->Attributes & 0x00ff); + p.setBrush (m_colors[(attr >> 4) & 0x000f]); + } + + // Append current character to the string buffer + len++; + if (ci->Char.UnicodeChar != L' ') + hasChar = true; + } + + if (len != 0 && (hasChar || (attr & 0x00f0))) + { + // Line end reached, but string buffer not empty -> draw it + // No need to update s or x, they will be reset on the next + // for-loop iteration + + if (attr & 0x00f0) + p.fillRect (x, y-ascent, len * cw, ch, p.brush ()); + } + } +#endif + + p.restore (); +} + +void QConsolePrivate::selectAll() +{ + m_beginSelection = QPoint (0,0); + m_endSelection = QPoint(m_bufferSize.width (), + m_cursorPos.y()); + updateSelection(); +} + +void QConsolePrivate::selectWord (const QPoint & cellpos) +{ + QPoint begin = cellpos; + QPoint end = cellpos; + + int stride = m_consoleRect.width (); + + int verticalScrollOffset = m_consoleRect.top (); + int horizontalScrollOffset = m_consoleRect.left (); + + // get begin, end in buffer offsets + begin.ry () -= verticalScrollOffset; + end.ry () -= verticalScrollOffset; + + begin.rx () -= horizontalScrollOffset; + end.rx () -= horizontalScrollOffset; + +#if 0 + + // loog at current clicked on char to determinate ig getting space chunk or nonspace chunk + if (QChar(m_buffer[begin.y ()*stride + begin.x ()].Char.UnicodeChar).isSpace () == false) + { + // from current char, go back and fwd to find start and end of block + while(begin.x () > 0 && + QChar(m_buffer[begin.y ()*stride + begin.x () -1].Char.UnicodeChar).isSpace() == false) + { + begin.rx () --; + } + + while(end.x () < m_consoleRect.width () && + QChar(m_buffer[end.y ()*stride + end.x () +1].Char.UnicodeChar).isSpace() == false) + { + end.rx () ++; + } + } + else + { + while(begin.x () > 0 && + QChar(m_buffer[begin.y ()*stride + begin.x () -1].Char.UnicodeChar).isSpace()) + { + begin.rx () --; + } + + while(end.x () < m_consoleRect.width () && + QChar(m_buffer[end.y ()*stride + end.x () +1].Char.UnicodeChar).isSpace ()) + { + end.rx () ++; + } + } + + // convert console offsets to absolute cell positions + begin.ry () += verticalScrollOffset; + end.ry () += verticalScrollOffset; + + begin.rx () += horizontalScrollOffset; + end.rx () += horizontalScrollOffset; + + m_beginSelection = begin; + m_endSelection = end; + + updateSelection (); + +#endif +} + +void QConsolePrivate::selectLine (const QPoint & cellpos) +{ +#if 0 + + m_beginSelection = QPoint (0, cellpos.y ()); + m_endSelection = QPoint (m_bufferSize.width ()-1, cellpos.y ()); + updateSelection (); + +#endif +} + + +void QConsolePrivate::drawSelection (QPainter& p, int cx1, int cy1, + int cx2, int cy2, int cw, int ch) +{ + p.save (); + +#if 0 + + QPoint begin = m_beginSelection; + QPoint end = m_endSelection; + + bool haveSelection = (begin != end); + + if (haveSelection) + maybeSwapPoints (begin, end); + + int verticalScrollOffset = m_consoleRect.top (); + int horizontalScrollOffset = m_consoleRect.left (); + + begin.ry () -= verticalScrollOffset; + end.ry () -= verticalScrollOffset; + + begin.rx () -= horizontalScrollOffset; + end.rx () -= horizontalScrollOffset; + + int ascent = p.fontMetrics ().ascent (); + int stride = m_consoleRect.width (); + + int y = ascent + cy1 * ch;; + for (int j = cy1; j <= cy2; j++, y += ch) + { + int charsThisLine = 0; + int len = 0; + bool hasChar = false; + WORD attr = 0; + + for (int i = cx1; i <= cx2; i++) + { + CHAR_INFO* ci = &(m_buffer[stride*j+i]); + + if ((ci->Attributes & 0x00ff) != attr) + { + // Character attributes changed + if (len != 0) + { + charsThisLine += len; + len = 0; + hasChar = false; + } + + // Store current attributes + attr = (ci->Attributes & 0x00ff); + } + + // Append current character to the string buffer + len++; + if (ci->Char.UnicodeChar != L' ') + hasChar = true; + } + + if (len != 0 && (hasChar || (attr & 0x00f0))) + charsThisLine += len; + + if (haveSelection && j >= begin.y () && j <= end.y ()) + { + int selectionBegin = j == begin.y () ? begin.x (): 0; + + int len = ((j == end.y () && end.x () < charsThisLine) + ? end.x () - selectionBegin + 1 + : stride - selectionBegin); + + p.fillRect (selectionBegin * cw, y-ascent, len * cw, ch, + selectionColor ()); + } + } +#endif + + p.restore (); +} + +void QConsolePrivate::drawCursor (QPainter& p) +{ + if (! m_cursorBlinking) + { + p.save (); + + QRect rect = cursorRect (); + QColor color = cursorColor (); + + p.setPen (color); + + if (m_cursorType == QConsolePrivate::BlockCursor) + { + if (q->hasFocus ()) + p.fillRect (rect, color); + else + { + // draw the cursor outline, adjusting the area so that + // it is draw entirely inside 'rect' + + int penWidth = qMax (1, p.pen().width()); + + p.drawRect (rect.adjusted (penWidth/2, penWidth/2, + - penWidth/2 - penWidth%2, + - penWidth/2 - penWidth%2)); + } + } + else if (m_cursorType == QConsolePrivate::UnderlineCursor) + { + p.drawLine (rect.left (), rect.bottom (), + rect.right (), rect.bottom ()); + } + else if (m_cursorType == QConsolePrivate::IBeamCursor) + { + p.drawLine (rect.left (), rect.top (), + rect.left (), rect.bottom ()); + } + + p.restore (); + } +} + +void QConsolePrivate::drawText (QPainter& p, int cx1, int cy1, + int cx2, int cy2, int cw, int ch) +{ + p.save (); + + p.setFont (m_font); + p.setPen (foregroundColor ()); + + QString s; + s.reserve (cx2 - cx1 + 1); + + int ascent = p.fontMetrics ().ascent (); + int stride = m_consoleRect.width (); + +#if 0 + + int y = ascent + cy1 * ch;; + for (int j = cy1; j <= cy2; j++, y += ch) + { + // Reset string buffer and starting X coordinate + s.clear (); + bool hasChar = false; + int x = cx1 * cw; + WORD attr = 0; + + for (int i = cx1; i <= cx2; i++) + { + CHAR_INFO* ci = &(m_buffer[stride*j+i]); + + if ((ci->Attributes & 0x00ff) != attr) + { + // Character attributes changed + if (! s.isEmpty ()) + { + // String buffer not empty -> draw it + if (hasChar || (attr & 0x00f0)) + p.drawText (x, y, s); + + x += (s.length () * cw); + s.clear (); + hasChar = false; + } + // Update current pen and store current attributes + attr = (ci->Attributes & 0x00ff); + p.setPen (m_colors[attr & 0x000f]); + } + + // Append current character to the string buffer + s.append (ci->Char.UnicodeChar); + if (ci->Char.UnicodeChar != L' ') + hasChar = true; + } + + if (! s.isEmpty () && (hasChar || (attr & 0x00f0))) + { + // Line end reached, but string buffer not empty -> draw it + // No need to update s or x, they will be reset on the next + // for-loop iteration + + p.drawText (x, y, s); + } + } + +#endif + + p.restore (); +} + +///////////////////////////////////////////////////////////////////////////// + +void QConsolePrivate::log (const char* fmt, ...) +{ +#ifdef DEBUG_QCONSOLE + if (fmt) + { + va_list l; + FILE* flog = fopen (LOGFILENAME, "ab"); + + va_start (l, fmt); + vfprintf (flog, fmt, l); + va_end (l); + fclose (flog); + } + else + { + // Special case to re-initialize the log file + FILE* flog = fopen (LOGFILENAME, "w"); + fclose (flog); + } +#else + Q_UNUSED (fmt); +#endif +} + +////////////////////////////////////////////////////////////////////////////// + +void QConsolePrivate::updateConsoleSize (bool sync, bool allow_smaller_width) +{ +#if 0 + + QFontMetrics fm = m_consoleView->fontMetrics (); + QSize winSize = m_consoleView->size (); + + m_charSize.rwidth () = fm.averageCharWidth (); + m_charSize.rheight () = fm.lineSpacing (); + + m_consoleRect.setWidth (winSize.width () / fm.averageCharWidth ()); + m_consoleRect.setHeight (winSize.height () / fm.lineSpacing ()); + + // Don't shrink the size of the buffer. That way wide lines won't be + // truncated and will reappear if the window is enlarged again later. + + if (allow_smaller_width || m_consoleRect.width () > m_bufferSize.width ()) + m_bufferSize.rwidth () = m_consoleRect.width (); + + if (qMax (m_bufferSize.height (), m_consoleRect.height ()) + > m_bufferSize.height ()) + m_bufferSize.rheight () = qMax (m_bufferSize.height (), + m_consoleRect.height ()); + + // Store the terminal size in the environment. When Octave is + // initialized, we ask the command editor (usually readline) to prefer + // using these values rather than querying the terminal so that the + // buffer size can be larger than the size of the window that the + // command editor will actually use. + + qputenv ("LINES", QByteArray::number (m_consoleRect.height ())); + qputenv ("COLUMNS", QByteArray::number (m_consoleRect.width ())); + + // Force the command line editor (usually readline) to notice the + // change in screen size as soon as possible. + + q->setSize (m_consoleRect.height (), m_consoleRect.width ()); + + m_consoleRect.moveLeft (0); + if (m_consoleRect.bottom () >= m_bufferSize.height ()) + m_consoleRect.moveTop (m_bufferSize.height () - m_consoleRect.height ()); + + log ("Console resized:\n"); + log (" widget size: %d x %d\n", winSize.width (), winSize.height ()); + log (" buffer size: %d x %d\n", m_bufferSize.width (), + m_bufferSize.height ()); + log (" window: (%d, %d) -> (%d, %d) [%d x %d]\n", + m_consoleRect.left (), m_consoleRect.top (), + m_consoleRect.right (), m_consoleRect.bottom (), + m_consoleRect.width (), m_consoleRect.height ()); + + if (sync) + syncConsoleParameters (); + + updateHorizontalScrollBar (); + updateVerticalScrollBar (); + +#endif +} + +////////////////////////////////////////////////////////////////////////////// + +void QConsolePrivate::updateHorizontalScrollBar (void) +{ + m_horizontalScrollBar->setMinimum (0); + if (m_bufferSize.width () > m_consoleRect.width ()) + m_horizontalScrollBar->setMaximum (m_bufferSize.width () - m_consoleRect.width ()); + else + m_horizontalScrollBar->setMaximum (0); + m_horizontalScrollBar->setSingleStep (1); + m_horizontalScrollBar->setPageStep (m_consoleRect.width ()); + m_horizontalScrollBar->setValue (m_consoleRect.left ()); + + log ("Horizontal scrollbar parameters updated: %d/%d/%d/%d\n", + m_horizontalScrollBar->minimum (), + m_horizontalScrollBar->maximum (), + m_horizontalScrollBar->singleStep (), + m_horizontalScrollBar->pageStep ()); +} + +void QConsolePrivate::updateVerticalScrollBar (void) +{ + m_verticalScrollBar->setMinimum (0); + if (m_bufferSize.height () > m_consoleRect.height ()) + m_verticalScrollBar->setMaximum (m_bufferSize.height () - m_consoleRect.height ()); + else + m_verticalScrollBar->setMaximum (0); + m_verticalScrollBar->setSingleStep (1); + m_verticalScrollBar->setPageStep (m_consoleRect.height ()); + m_verticalScrollBar->setValue (m_consoleRect.top ()); + + log ("Vertical scrollbar parameters updated: %d/%d/%d/%d\n", + m_verticalScrollBar->minimum (), m_verticalScrollBar->maximum (), + m_verticalScrollBar->singleStep (), m_verticalScrollBar->pageStep ()); +} + +////////////////////////////////////////////////////////////////////////////// + +void QConsolePrivate::setHorizontalScrollValue (int value) +{ + if (value == m_consoleRect.left ()) + return; + +#if 0 + + SMALL_RECT r; + HANDLE hStdOut = m_stdOut; + + if (value + m_consoleRect.width () > m_bufferSize.width ()) + value = m_bufferSize.width () - m_consoleRect.width (); + + r.Left = value; + r.Top = m_consoleRect.top (); + r.Right = value + m_consoleRect.width () - 1; + r.Bottom = m_consoleRect.bottom (); + + log ("Scrolling window horizontally: (%d, %d) -> (%d, %d) [%d x %d]\n", + r.Left, r.Top, r.Right, r.Bottom, + r.Right - r.Left + 1, r.Bottom - r.Top + 1); + + if (SetConsoleWindowInfo (hStdOut, TRUE, &r)) + { + m_consoleRect.moveLeft (value); + updateConsoleView (); + } + +#endif +} + +void QConsolePrivate::setVerticalScrollValue (int value) +{ + if (value == m_consoleRect.top ()) + return; + +#if 0 + + SMALL_RECT r; + HANDLE hStdOut = m_stdOut; + + if (value + m_consoleRect.height () > m_bufferSize.height ()) + value = m_bufferSize.height () - m_consoleRect.height (); + + r.Left = m_consoleRect.left (); + r.Top = value; + r.Right = m_consoleRect.right (); + r.Bottom = value + m_consoleRect.height () - 1; + + log ("Scrolling window vertically: (%d, %d) -> (%d, %d) [%d x %d]\n", + r.Left, r.Top, r.Right, r.Bottom, + r.Right - r.Left + 1, r.Bottom - r.Top + 1); + + if (SetConsoleWindowInfo (hStdOut, TRUE, &r)) + { + m_consoleRect.moveTop (value); + + CONSOLE_SCREEN_BUFFER_INFO sbi; + if (GetConsoleScreenBufferInfo (hStdOut, &sbi)) + { + if (sbi.dwCursorPosition.Y > m_consoleRect.bottom ()) + m_auto_scroll = false; + else + m_auto_scroll = true; + } + + updateConsoleView (); + } + +#endif +} + +////////////////////////////////////////////////////////////////////////////// + +void QConsolePrivate::updateConsoleView (bool grab) +{ + m_consoleView->update (); +} + +////////////////////////////////////////////////////////////////////////////// + +void QConsolePrivate::sendConsoleText (const QString& s) +{ + // Send the string in chunks of 512 characters. Each character is + // translated into an equivalent keypress event. + +#define TEXT_CHUNK_SIZE 512 + + // clear any selection on inserting text + clearSelection(); + // enable auto-scrolling + m_auto_scroll = true; + + int len = s.length (); + +#if 0 + + INPUT_RECORD events[TEXT_CHUNK_SIZE]; + DWORD nEvents = 0, written; + HANDLE hStdIn = GetStdHandle (STD_INPUT_HANDLE); + + ZeroMemory (events, sizeof (events)); + + for (int i = 0; i < len; i++) + { + QChar c = s.at (i); + + if (c == L'\r' || c == L'\n') + { + if (c == L'\r' && i < (len - 1) && s.at (i+1) == L'\n') + i++; + + // add new line + events[nEvents].EventType = KEY_EVENT; + events[nEvents].Event.KeyEvent.bKeyDown = TRUE; + events[nEvents].Event.KeyEvent.wRepeatCount = 1; + events[nEvents].Event.KeyEvent.wVirtualKeyCode = + VK_RETURN; + events[nEvents].Event.KeyEvent.wVirtualScanCode = 0; + events[nEvents].Event.KeyEvent.uChar.UnicodeChar = c.unicode (); + events[nEvents].Event.KeyEvent.dwControlKeyState = 0; + nEvents++; + + WriteConsoleInput (hStdIn, events, nEvents, &written); + nEvents = 0; + ZeroMemory (events, sizeof (events)); + + } + else + { + events[nEvents].EventType = KEY_EVENT; + events[nEvents].Event.KeyEvent.bKeyDown = TRUE; + events[nEvents].Event.KeyEvent.wRepeatCount = 1; + events[nEvents].Event.KeyEvent.wVirtualKeyCode = + LOBYTE (VkKeyScan (c.unicode ())); + events[nEvents].Event.KeyEvent.wVirtualScanCode = 0; + events[nEvents].Event.KeyEvent.uChar.UnicodeChar = c.unicode (); + events[nEvents].Event.KeyEvent.dwControlKeyState = 0; + nEvents++; + } + + if (nEvents == TEXT_CHUNK_SIZE + || (nEvents > 0 && i == (len - 1))) + { + WriteConsoleInput (hStdIn, events, nEvents, &written); + nEvents = 0; + ZeroMemory (events, sizeof (events)); + } + } + +#endif +} + +QRect +QConsolePrivate::cursorRect (void) +{ + int cw = m_charSize.width (); + int ch = m_charSize.height (); + + return QRect ((m_cursorPos.x () - m_consoleRect.x ()) * cw, + (m_cursorPos.y () - m_consoleRect.y ()) * ch, + cw, ch); +} + +////////////////////////////////////////////////////////////////////////////// + +QGenericTerminalImpl::QGenericTerminalImpl (QWidget* parent) + : QTerminal (parent), d (new QConsolePrivate (this)), + allowTripleClick (false) +{ + installEventFilter (this); + + connect (this, SIGNAL (set_global_shortcuts_signal (bool)), + parent, SLOT (set_global_shortcuts (bool))); + connect (this, SIGNAL (set_global_shortcuts_signal (bool)), + this, SLOT (set_global_shortcuts (bool))); + + connect (this, SIGNAL (set_screen_size_signal (int, int)), + parent, SLOT (set_screen_size (int, int))); + + setAcceptDrops (true); +} + +////////////////////////////////////////////////////////////////////////////// + +QGenericTerminalImpl::QGenericTerminalImpl (const QString& cmd, QWidget* parent) + : QTerminal (parent), d (new QConsolePrivate (this, cmd)) +{ +} + +////////////////////////////////////////////////////////////////////////////// + +QGenericTerminalImpl::~QGenericTerminalImpl (void) +{ + delete d; +} + +void QGenericTerminalImpl::mouseMoveEvent (QMouseEvent *event) +{ + if (d->m_settingSelection) + { + d->m_endSelection = d->posToCell (event->pos ()); + + updateSelection (); + } +} + +void QGenericTerminalImpl::mousePressEvent (QMouseEvent *event) +{ + if (allowTripleClick) + { + mouseTripleClickEvent (event); + } + else if (event->button () == Qt::LeftButton) + { + d->m_settingSelection = true; + + d->m_beginSelection = d->posToCell (event->pos ()); + } +} + +void QGenericTerminalImpl::mouseReleaseEvent (QMouseEvent *event) +{ + if (event->button () == Qt::LeftButton && d->m_settingSelection) + { + d->m_endSelection = d->posToCell (event->pos ()); + + updateSelection (); + + d->m_settingSelection = false; + } +} + +void QGenericTerminalImpl::mouseDoubleClickEvent (QMouseEvent *event) +{ + if (event->button () == Qt::LeftButton) + { + // doubleclick - select word + d->m_settingSelection = false; + + d->selectWord (d->posToCell (event->pos ())); + + allowTripleClick = true; + + QTimer::singleShot (QApplication::doubleClickInterval (),this, + SLOT (tripleClickTimeout ())); + + } +} + +void QGenericTerminalImpl::mouseTripleClickEvent (QMouseEvent *event) +{ + if (event->button () == Qt::LeftButton) + { + d->selectLine (d->posToCell (event->pos ())); + } +} + +void QGenericTerminalImpl::tripleClickTimeout () +{ + allowTripleClick = false; +} + +////////////////////////////////////////////////////////////////////////////// + +void QGenericTerminalImpl::viewResizeEvent (QConsoleView*, QResizeEvent*) +{ + d->updateConsoleSize (true); +} + +////////////////////////////////////////////////////////////////////////////// + +void QGenericTerminalImpl::viewPaintEvent (QConsoleView* w, QPaintEvent* event) +{ + QPainter p (w); + + int cw = d->m_charSize.width (); + int ch = d->m_charSize.height (); + + QRect updateRect = event->rect (); + + int cx1 = updateRect.left () / cw; + int cy1 = updateRect.top () / ch; + int cx2 = qMin (d->m_consoleRect.width () - 1, updateRect.right () / cw); + int cy2 = qMin (d->m_consoleRect.height () - 1, updateRect.bottom () / ch); + + if (cx1 > d->m_consoleRect.width () - 1 + || cy1 > d->m_consoleRect.height () - 1) + return; + + d->drawTextBackground (p, cx1, cy1, cx2, cy2, cw, ch); + d->drawSelection (p, cx1, cy1, cx2, cy2, cw, ch); + d->drawCursor (p); + d->drawText (p, cx1, cy1, cx2, cy2, cw, ch); +} + +void QGenericTerminalImpl::blinkCursorEvent (void) +{ + if (d->m_hasBlinkingCursor) + d->m_cursorBlinking = ! d->m_cursorBlinking; + else + d->m_cursorBlinking = false; + + d->m_consoleView->update (d->cursorRect ()); +} + +void QGenericTerminalImpl::setBlinkingCursor (bool blink) +{ + d->m_hasBlinkingCursor = blink; + + setBlinkingCursorState (blink); +} + +void QGenericTerminalImpl::setBlinkingCursorState (bool blink) +{ + if (blink && ! d->m_blinkCursorTimer->isActive ()) + d->m_blinkCursorTimer->start (d->BLINK_DELAY); + + if (! blink && d->m_blinkCursorTimer->isActive ()) + { + d->m_blinkCursorTimer->stop (); + + if (d->m_cursorBlinking) + blinkCursorEvent (); + } +} + +// Reset width of console buffer and terminal window to be the same. + +void QGenericTerminalImpl::init_terminal_size (void) +{ + d->updateConsoleSize (true, true); +} + +////////////////////////////////////////////////////////////////////////////// + +void QGenericTerminalImpl::wheelEvent (QWheelEvent* event) +{ + if (! d->m_inWheelEvent) + { + // Forward to the scrollbar (avoid recursion) + d->m_inWheelEvent = true; + QApplication::sendEvent (d->m_verticalScrollBar, event); + d->m_inWheelEvent = false; + } +} + +////////////////////////////////////////////////////////////////////////////// + +void QGenericTerminalImpl::horizontalScrollValueChanged (int value) +{ + d->setHorizontalScrollValue (value); +} + +void QGenericTerminalImpl::verticalScrollValueChanged (int value) +{ + d->setVerticalScrollValue (value); +} + +////////////////////////////////////////////////////////////////////////////// + +void QGenericTerminalImpl::updateSelection (void) +{ + d->updateSelection (); +} + +////////////////////////////////////////////////////////////////////////////// + +void QGenericTerminalImpl::focusInEvent (QFocusEvent* event) +{ + emit set_global_shortcuts_signal (false); // disable some shortcuts + + setBlinkingCursorState (true); + + QWidget::focusInEvent (event); +} + +void QGenericTerminalImpl::focusOutEvent (QFocusEvent* event) +{ + emit set_global_shortcuts_signal (true); // re-enable shortcuts + + // Force the cursor to be redrawn. + d->m_cursorBlinking = true; + + setBlinkingCursorState (false); + + QWidget::focusOutEvent (event); +} + +bool QGenericTerminalImpl::eventFilter (QObject *obj, QEvent * event) +{ + // if a keypress, filter out tab keys so that the next/prev tabbing is + // disabled - but we still need to pass along to the console . + if (event->type () == QEvent::KeyPress) + { + QKeyEvent* k = static_cast(event); + if (k->key () == Qt::Key_Tab) + { + sendText ("\t"); + return true; + } + } + return false; +} + +void QGenericTerminalImpl::keyPressEvent (QKeyEvent* event) +{ + QString s = translateKey (event); + if (!s.isEmpty ()) + sendText (s); + + if (d->m_hasBlinkingCursor) + { + d->m_blinkCursorTimer->start (d->BLINK_DELAY); + + if (d->m_cursorBlinking) + blinkCursorEvent (); + } + + QWidget::keyPressEvent (event); +} + +////////////////////////////////////////////////////////////////////////////// + +void QGenericTerminalImpl::start (void) +{ +} + +////////////////////////////////////////////////////////////////////////////// + +void QGenericTerminalImpl::sendText (const QString& s) +{ + d->sendConsoleText (s); +} + +void QGenericTerminalImpl::setCursorType (CursorType type, bool blinking) +{ + switch (type) + { + case UnderlineCursor: + d->m_cursorType = QConsolePrivate::UnderlineCursor; + break; + + case BlockCursor: + d->m_cursorType = QConsolePrivate::BlockCursor; + break; + + case IBeamCursor: + d->m_cursorType = QConsolePrivate::IBeamCursor; + break; + } + + setBlinkingCursor (blinking); +} + +void QGenericTerminalImpl::setBackgroundColor (const QColor& color) +{ + d->setBackgroundColor (color); +} + +void QGenericTerminalImpl::setForegroundColor (const QColor& color) +{ + d->setForegroundColor (color); +} + +void QGenericTerminalImpl::setSelectionColor (const QColor& color) +{ + d->setSelectionColor (color); +} + +void QGenericTerminalImpl::setCursorColor (bool useForegroundColor, + const QColor& color) +{ + d->setCursorColor (useForegroundColor, color); +} + +void QGenericTerminalImpl::setScrollBufferSize(int value) +{ + d->setScrollBufferSize (value); +} + + +////////////////////////////////////////////////////////////////////////////// + +void QGenericTerminalImpl::setTerminalFont (const QFont& f) +{ + d->m_font = f; + d->m_consoleView->setFont (f); + d->updateConsoleSize (true); +} + +////////////////////////////////////////////////////////////////////////////// + +void QGenericTerminalImpl::setSize (int columns, int lines) +{ + d->log ("emit set_screen_size_signal (%d, %d)\n", columns, lines); + + emit set_screen_size_signal (columns, lines); +} + +////////////////////////////////////////////////////////////////////////////// + +void QGenericTerminalImpl::copyClipboard () +{ + if(!hasFocus()) return; + + QClipboard *clipboard = QApplication::clipboard (); + + QString selection = d->getSelection (); + + if (selection.isEmpty ()) + { + if (! _extra_interrupt) + terminal_interrupt (); + } + else + { + clipboard->setText (selection); + emit report_status_message (tr ("copied selection to clipboard")); + } +} + +////////////////////////////////////////////////////////////////////////////// + +void QGenericTerminalImpl::pasteClipboard (void) +{ + if(!hasFocus()) return; + + QString text = QApplication::clipboard()->text (QClipboard::Clipboard); + + if (! text.isEmpty ()) + sendText (text); +} + +////////////////////////////////////////////////////////////////////////////// + +void QGenericTerminalImpl::selectAll (void) +{ + if(!hasFocus()) return; + + d->selectAll(); +} + + + +////////////////////////////////////////////////////////////////////////////// + +QString QGenericTerminalImpl::selectedText () +{ + QString selection = d->getSelection (); + return selection; +} + +////////////////////////////////////////////////////////////////////////////// + +void QGenericTerminalImpl::dragEnterEvent (QDragEnterEvent *event) +{ + if (event->mimeData ()->hasUrls ()) + { + event->acceptProposedAction(); + } +} + +////////////////////////////////////////////////////////////////////////////// + +void QGenericTerminalImpl::dropEvent (QDropEvent *event) +{ + QString dropText; + + if (event->mimeData ()->hasUrls ()) + { + foreach (QUrl url, event->mimeData ()->urls ()) + { + if(dropText.length () > 0) + dropText += '\n'; + dropText += url.toLocalFile (); + } + sendText (dropText); + } +} + +////////////////////////////////////////////////////////////////////////////// + +void QGenericTerminalImpl::has_extra_interrupt (bool extra) +{ + _extra_interrupt = extra; +} diff -r 4092ffc1e43c -r 55301e06b238 libgui/qterminal/libqterminal/QGenericTerminalImpl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libgui/qterminal/libqterminal/QGenericTerminalImpl.h Tue May 14 15:26:56 2019 +0000 @@ -0,0 +1,119 @@ +/* + +Copyright (C) 2011-2019 Michael Goffioul + +This file is part of QConsole. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, +see . + +*/ + +#ifndef __QConsole_h__ +#define __QConsole_h__ 1 + +#include +#include "QTerminal.h" +class QFocusEvent; +class QKeyEvent; +class QPainter; +class QPaintEvent; +class QResizeEvent; +class QWheelEvent; +class QPoint; +class QDragEnterEvent; +class QDropEvent; + +class QConsolePrivate; +class QConsoleThread; +class QConsoleView; + +////////////////////////////////////////////////////////////////////////////// + +class QGenericTerminalImpl : public QTerminal +{ + Q_OBJECT + friend class QConsolePrivate; + friend class QConsoleThread; + friend class QConsoleView; + +public: + QGenericTerminalImpl (QWidget* parent = 0); + QGenericTerminalImpl (const QString& cmd, QWidget* parent = 0); + ~QGenericTerminalImpl (void); + + void setTerminalFont (const QFont& font); + void setSize (int columns, int lines); + void sendText (const QString& s); + void setCursorType (CursorType type, bool blinking); + + void setBackgroundColor (const QColor& color); + void setForegroundColor (const QColor& color); + void setSelectionColor (const QColor& color); + void setCursorColor (bool useForegoundColor, const QColor& color); + void setScrollBufferSize(int value); + + QString selectedText (); + + void has_extra_interrupt (bool); + +public slots: + void copyClipboard (void); + void pasteClipboard (void); + void selectAll (void); + void blinkCursorEvent (void); + void init_terminal_size (void); + +signals: + void terminated (void); + void titleChanged (const QString&); + void set_global_shortcuts_signal (bool); + void set_screen_size_signal (int, int); + +protected: + void viewPaintEvent (QConsoleView*, QPaintEvent*); + void setBlinkingCursor (bool blink); + void setBlinkingCursorState (bool blink); + void viewResizeEvent (QConsoleView*, QResizeEvent*); + void wheelEvent (QWheelEvent*); + void focusInEvent (QFocusEvent*); + void focusOutEvent (QFocusEvent*); + void keyPressEvent (QKeyEvent*); + virtual void start (void); + void mouseMoveEvent (QMouseEvent *event); + void mousePressEvent (QMouseEvent *event); + void mouseReleaseEvent (QMouseEvent *event); + void mouseDoubleClickEvent (QMouseEvent* event); + void mouseTripleClickEvent (QMouseEvent* event); + + bool eventFilter(QObject *obj, QEvent *ev); + + void dragEnterEvent(QDragEnterEvent *event); + void dropEvent(QDropEvent *event); + +private slots: + void horizontalScrollValueChanged (int value); + void verticalScrollValueChanged (int value); + void updateSelection (void); + void tripleClickTimeout (void); + +private: + QConsolePrivate* d; + bool allowTripleClick; + bool _extra_interrupt; +}; + +////////////////////////////////////////////////////////////////////////////// + +#endif // __QConsole_h__ diff -r 4092ffc1e43c -r 55301e06b238 libgui/qterminal/libqterminal/QTerminal.cc --- a/libgui/qterminal/libqterminal/QTerminal.cc Fri May 10 22:15:37 2019 +0200 +++ b/libgui/qterminal/libqterminal/QTerminal.cc Tue May 14 15:26:56 2019 +0000 @@ -24,7 +24,11 @@ #include "QTerminal.h" #include "gui-preferences.h" -#if defined (Q_OS_WIN32) +#define OCTAVE_USE_EXPERIMENTAL_GENERIC_TERMINAL 1 + +#if defined (OCTAVE_USE_EXPERIMENTAL_GENERIC_TERMINAL) +# include "QGenericTerminalImpl.h" +#elif defined (Q_OS_WIN32) # include "win32/QWinTerminalImpl.h" #else # include "unix/QUnixTerminalImpl.h" @@ -33,7 +37,9 @@ QTerminal * QTerminal::create (QWidget *xparent) { -#if defined (Q_OS_WIN32) +#if defined (OCTAVE_USE_EXPERIMENTAL_GENERIC_TERMINAL) + return new QGenericTerminalImpl (xparent); +#elif defined (Q_OS_WIN32) return new QWinTerminalImpl (xparent); #else return new QUnixTerminalImpl (xparent); diff -r 4092ffc1e43c -r 55301e06b238 libgui/qterminal/module.mk --- a/libgui/qterminal/module.mk Fri May 10 22:15:37 2019 +0200 +++ b/libgui/qterminal/module.mk Tue May 14 15:26:56 2019 +0000 @@ -1,5 +1,7 @@ noinst_HEADERS += \ %reldir%/libqterminal/QTerminal.h \ + %reldir%/libqterminal/QGenericTerminalImpl.h \ + %reldir%/libqterminal/QGenericTerminalColors.h \ %reldir%/libqterminal/win32/QTerminalColors.h \ %reldir%/libqterminal/win32/QWinTerminalImpl.h \ %reldir%/libqterminal/unix/BlockArray.h \ @@ -112,6 +114,13 @@ endif +%canon_reldir%_libqterminal_la_SOURCES += \ + %reldir%/libqterminal/QGenericTerminalColors.cpp \ + %reldir%/libqterminal/QGenericTerminalImpl.cpp + +%canon_reldir%_libqterminal_la_MOC += \ + %reldir%/libqterminal/moc-QGenericTerminalImpl.cc + noinst_LTLIBRARIES += %reldir%/libqterminal.la libgui_CLEANFILES += $(%canon_reldir%_libqterminal_la_MOC)