From cbb6964393161c0b7b1df75a6fd87a9541f3258b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marti=CC=81n=20Lucas=20Golini?= Date: Mon, 20 Jun 2022 02:03:30 -0300 Subject: [PATCH] Added display invalidation. --- src/tools/eterm/eterm.cpp | 22 +++--- src/tools/eterm/eterminaldisplay.cpp | 72 +++++++------------ src/tools/eterm/eterminaldisplay.hpp | 12 ++-- src/tools/eterm/terminal/terminalemulator.cpp | 3 +- src/tools/eterm/terminal/types.hpp | 12 +++- 5 files changed, 60 insertions(+), 61 deletions(-) diff --git a/src/tools/eterm/eterm.cpp b/src/tools/eterm/eterm.cpp index e5de31834..157e15408 100644 --- a/src/tools/eterm/eterm.cpp +++ b/src/tools/eterm/eterm.cpp @@ -48,35 +48,41 @@ void inputCallback( InputEvent* event ) { } void mainLoop() { - win->clear(); - win->getInput()->update(); + terminal->Update(); - if ( terminal ) { - terminal->Update(); - + if ( terminal->isDirty() ) { + win->clear(); terminal->Draw( win->hasFocus() ); + win->display(); + } else { + win->getInput()->waitEvent( Milliseconds( win->hasFocus() ? 16 : 100 ) ); } - - win->display(); } EE_MAIN_FUNC int main( int, char*[] ) { + DisplayManager* displayManager = Engine::instance()->getDisplayManager(); + Display* currentDisplay = displayManager->getDisplayIndex( 0 ); FileSystem::changeWorkingDirectory( Sys::getProcessPath() ); + displayManager->enableScreenSaver(); + displayManager->enableMouseFocusClickThrough(); + displayManager->disableBypassCompositor(); + win = Engine::instance()->createWindow( WindowSettings( 1280, 720, "eterm", WindowStyle::Default, WindowBackend::Default, 32, "assets/icon/ee.png" ), ContextSettings( true ) ); if ( win->isOpen() ) { + PixelDensity::setPixelDensity( currentDisplay->getPixelDensity() ); win->setClearColor( RGB( 0, 0, 0 ) ); FontTrueType* fontMono = FontTrueType::New( "monospace" ); fontMono->loadFromFile( "assets/fonts/DejaVuSansMono.ttf" ); if ( !terminal || terminal->HasTerminated() ) { - auto fontSize = 15; + auto fontSize = PixelDensity::dpToPx( 12 ); auto charWidth = fontMono->getGlyph( 'A', fontSize, false ).advance; auto charHeight = terminal ? terminal->getFontSize() : fontSize; Sizef contentRegion = win->getSize().asFloat(); diff --git a/src/tools/eterm/eterminaldisplay.cpp b/src/tools/eterm/eterminaldisplay.cpp index 4685b7e6e..a2b16ffa8 100644 --- a/src/tools/eterm/eterminaldisplay.cpp +++ b/src/tools/eterm/eterminaldisplay.cpp @@ -457,31 +457,32 @@ bool ETerminalDisplay::DrawBegin( int columns, int rows ) { m_buffer.resize( columns * rows, defaultGlyph ); m_columns = columns; m_rows = rows; + invalidate(); } - m_checkDirty = false; return ( ( mMode & MODE_VISIBLE ) != 0 ); } void ETerminalDisplay::DrawLine( Line line, int x1, int y, int x2 ) { - m_checkDirty = true; memcpy( &m_buffer[y * m_columns + x1], line, ( x2 - x1 ) * sizeof( TerminalGlyph ) ); for ( int i = x1; i < x2; i++ ) { if ( m_terminal->selected( i, y ) ) { m_buffer[y * m_columns + i].mode |= ATTR_REVERSE; } } + invalidate(); } void ETerminalDisplay::DrawCursor( int cx, int cy, TerminalGlyph g, int, int, TerminalGlyph ) { - m_cursorx = cx; - m_cursory = cy; - m_cursorg = g; + if ( m_cursor != Vector2i(cx, cy) || m_cursorg != g ) { + m_cursor.x = cx; + m_cursor.y = cy; + m_cursorg = g; + invalidate(); + } } void ETerminalDisplay::DrawEnd() { - if ( m_checkDirty ) - m_dirty = true; } void ETerminalDisplay::Draw( bool hasFocus ) { @@ -507,6 +508,7 @@ void ETerminalDisplay::onMouseMotion( const Vector2i& pos, const Uint32& flags ) m_terminal->selextend( gridPos.x, gridPos.y, mWindow->getInput()->getModState() == KEYMOD_SHIFT ? SEL_RECTANGULAR : SEL_REGULAR, 0 ); + invalidate(); } } @@ -515,6 +517,7 @@ void ETerminalDisplay::onMouseDown( const Vector2i& pos, const Uint32& flags ) { ( m_terminal->getSelectionMode() == selection_mode::SEL_IDLE ) ) { auto gridPos{ positionToGrid( pos ) }; m_terminal->selstart( gridPos.x, gridPos.y, 0 ); + invalidate(); } } @@ -524,6 +527,7 @@ void ETerminalDisplay::onMouseUp( const Vector2i&, const Uint32& flags ) { if ( selection ) SetClipboard( selection ); m_terminal->selclear(); + invalidate(); } } @@ -544,6 +548,8 @@ static inline Color GetCol( unsigned int terminalColor, #define COL32_A_SHIFT 0 void ETerminalDisplay::Draw( Vector2f pos ) { + m_drawing = true; + if ( mClock.getElapsedTime().asSeconds() > 0.7 ) { mMode ^= MODE_BLINK; mClock.restart(); @@ -751,28 +757,16 @@ void ETerminalDisplay::Draw( Vector2f pos ) { if ( !IS_SET( MODE_HIDE ) ) { Color drawcol; - - m_cursorg.mode &= - ATTR_BOLD | ATTR_ITALIC | ATTR_UNDERLINE | ATTR_STRUCK | ATTR_WIDE | ATTR_BOXDRAW; if ( IS_SET( MODE_REVERSE ) ) { - m_cursorg.mode |= ATTR_REVERSE; - m_cursorg.bg = mEmulator->GetDefaultForeground(); - if ( mEmulator->IsSelected( m_cursorx, m_cursory ) ) { + if ( mEmulator->IsSelected( m_cursor.x, m_cursor.y ) ) { drawcol = GetCol( mEmulator->GetDefaultCursorColor(), m_colors ); - m_cursorg.fg = mEmulator->GetDefaultReverseCursorColor(); } else { drawcol = GetCol( mEmulator->GetDefaultReverseCursorColor(), m_colors ); - m_cursorg.fg = mEmulator->GetDefaultCursorColor(); } } else { - if ( mEmulator->IsSelected( m_cursorx, m_cursory ) ) { - m_cursorg.fg = mEmulator->GetDefaultForeground(); - m_cursorg.bg = mEmulator->GetDefaultReverseCursorColor(); - } else { - m_cursorg.fg = mEmulator->GetDefaultBackground(); - m_cursorg.bg = mEmulator->GetDefaultCursorColor(); - } - drawcol = GetCol( m_cursorg.bg, m_colors ); + drawcol = GetCol( mEmulator->IsSelected( m_cursor.x, m_cursor.y ) ? + mEmulator->GetDefaultReverseCursorColor() : + mEmulator->GetDefaultCursorColor(), m_colors ); } Vector2f a{}, b{}, c{}, d{}; @@ -797,41 +791,27 @@ void ETerminalDisplay::Draw( Vector2f pos ) { case cursor_mode::MAX_CURSOR: case 4: /* Steady Underline */ p.drawRectangle( Rectf( - { pos.x + borderpx + m_cursorx * spaceCharAdvanceX, - pos.y + borderpx + ( m_cursory + 1 ) * line_height - cursorthickness }, + { pos.x + borderpx + m_cursor.x * spaceCharAdvanceX, + pos.y + borderpx + ( m_cursor.y + 1 ) * line_height - cursorthickness }, { spaceCharAdvanceX, cursorthickness } ) ); break; case 5: /* Blinking bar */ case 6: /* Steady bar */ - p.drawRectangle( Rectf( { pos.x + borderpx + m_cursorx * spaceCharAdvanceX, - pos.y + m_cursory * line_height }, + p.drawRectangle( Rectf( { pos.x + borderpx + m_cursor.x * spaceCharAdvanceX, + pos.y + m_cursor.y * line_height }, { spaceCharAdvanceX, line_height } ) ); break; } } else { p.setFillMode( PrimitiveFillMode::DRAW_LINE ); - p.drawRectangle( Rectf( { pos.x + borderpx + m_cursorx * spaceCharAdvanceX, - pos.y + borderpx + m_cursory * line_height }, + p.drawRectangle( Rectf( { pos.x + borderpx + m_cursor.x * spaceCharAdvanceX, + pos.y + borderpx + m_cursor.y * line_height }, { spaceCharAdvanceX, line_height } ) ); } } - /*if ( hasFocus ) { - auto mousePos = mWindow->getInput()->getMousePos(); - auto relPos = Vector2i{ mousePos.x - pos.x, mousePos.y - pos.y }; - int mouseX = 0; - int mouseY = 0; - - if ( mousePos.x <= 0.0f || mousePos.y <= 0.0f ) { - mouseX = 0; - mouseY = 0; - } else if ( relPos.x >= 0.0f && relPos.y >= 0.0f ) { - mouseX = eeclamp( (int)std::floor( relPos.x / spaceCharAdvanceX ), 0, clipColumns ); - mouseY = eeclamp( (int)std::floor( relPos.y / fontSize ), 0, clipRows ); - } - - ProcessInput( mouseX, mouseY ); - }*/ + m_drawing = false; + m_dirty = false; } Vector2i ETerminalDisplay::positionToGrid( const Vector2i& pos ) { @@ -972,3 +952,5 @@ void ETerminalDisplay::setSize( const Sizef& size ) { onSizeChange(); } } + +void ETerminalDisplay::invalidate() { m_dirty = true; } diff --git a/src/tools/eterm/eterminaldisplay.hpp b/src/tools/eterm/eterminaldisplay.hpp index 5f3c62eeb..cb01f72a9 100644 --- a/src/tools/eterm/eterminaldisplay.hpp +++ b/src/tools/eterm/eterminaldisplay.hpp @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -165,6 +166,10 @@ class ETerminalDisplay : public TerminalDisplay { void setSize( const Sizef& size ); + bool isDirty() const { return m_dirty; } + + void invalidate(); + protected: EE::Window::Window* mWindow; std::vector m_buffer; @@ -178,10 +183,9 @@ class ETerminalDisplay : public TerminalDisplay { Sizef mSize; int m_columns{ 0 }; int m_rows{ 0 }; - bool m_dirty; - bool m_checkDirty; - int m_cursorx; - int m_cursory; + std::atomic m_dirty{ true }; + std::atomic m_drawing{ false }; + Vector2i m_cursor; TerminalGlyph m_cursorg; bool m_useBoxDrawing; bool m_useColorEmoji; diff --git a/src/tools/eterm/terminal/terminalemulator.cpp b/src/tools/eterm/terminal/terminalemulator.cpp index 220787bed..8038089cf 100644 --- a/src/tools/eterm/terminal/terminalemulator.cpp +++ b/src/tools/eterm/terminal/terminalemulator.cpp @@ -2153,7 +2153,7 @@ void TerminalEmulator::drawregion( TerminalDisplay& dpy, int x1, int y1, int x2, } } -void TerminalEmulator::draw( void ) { +void TerminalEmulator::draw() { int cx = term.c.x /*, ocx = term.ocx, ocy = term.ocy*/; { @@ -2323,7 +2323,6 @@ void TerminalEmulator::Update() { // TODO: Handle blink - // TODO: Do not draw every update draw(); m_process->CheckExitStatus(); diff --git a/src/tools/eterm/terminal/types.hpp b/src/tools/eterm/terminal/types.hpp index 3234e4b74..4d319876c 100644 --- a/src/tools/eterm/terminal/types.hpp +++ b/src/tools/eterm/terminal/types.hpp @@ -91,12 +91,20 @@ typedef unsigned short ushort; typedef uint_least32_t Rune; -typedef struct { +struct TerminalGlyph { Rune u; /* character code */ ushort mode; /* attribute flags */ uint32_t fg; /* foreground */ uint32_t bg; /* background */ -} TerminalGlyph; + + bool operator==( const TerminalGlyph& r ) { + return u == r.u && mode == r.mode && fg == r.fg && bg == r.bg; + } + + bool operator!=( const TerminalGlyph& r ) { + return !(*this == r); + } +}; typedef TerminalGlyph* Line;