diff --git a/Widgets/Event.h b/Widgets/Event.h index 917a6960bc..c1a1acaa4a 100644 --- a/Widgets/Event.h +++ b/Widgets/Event.h @@ -1,8 +1,9 @@ #pragma once -#include #include "Point.h" #include "Rect.h" +#include +#include static const char* eventNames[] = { "Invalid", @@ -106,9 +107,18 @@ public: } int key() const { return m_key; } + bool ctrl() const { return m_ctrl; } + bool alt() const { return m_alt; } + bool shift() const { return m_shift; } + String text() const { return m_text; } private: + friend class EventLoopSDL; int m_key { 0 }; + bool m_ctrl { false }; + bool m_alt { false }; + bool m_shift { false }; + String m_text; }; class MouseEvent final : public Event { diff --git a/Widgets/EventLoopSDL.cpp b/Widgets/EventLoopSDL.cpp index ad0d8a9060..dc26d87ed1 100644 --- a/Widgets/EventLoopSDL.cpp +++ b/Widgets/EventLoopSDL.cpp @@ -29,9 +29,46 @@ static inline MouseButton toMouseButton(byte sdlButton) return MouseButton::None; } -static inline int toKey(const SDL_Keysym& sym) +void EventLoopSDL::handleKeyEvent(Event::Type type, const SDL_KeyboardEvent& sdlKey) { - return sym.sym; + auto keyEvent = make(type, 0); + + if (sdlKey.keysym.sym > SDLK_UNKNOWN && sdlKey.keysym.sym <= 'z') { + char buf[] = { 0, 0 }; + char& ch = buf[0]; + ch = (char)sdlKey.keysym.sym; + if (sdlKey.keysym.mod & KMOD_SHIFT) { + if (ch >= 'a' && ch <= 'z') { + ch &= ~0x20; + } else { + switch (ch) { + case '1': ch = '!'; break; + case '2': ch = '@'; break; + case '3': ch = '#'; break; + case '4': ch = '$'; break; + case '5': ch = '%'; break; + case '6': ch = '^'; break; + case '7': ch = '&'; break; + case '8': ch = '*'; break; + case '9': ch = '('; break; + case '0': ch = ')'; break; + case '-': ch = '_'; break; + case '=': ch = '+'; break; + case '`': ch = '~'; break; + case ',': ch = '<'; break; + case '.': ch = '>'; break; + case '/': ch = '?'; break; + case '[': ch = '{'; break; + case ']': ch = '}'; break; + case '\\': ch = '|'; break; + case '\'': ch = '"'; break; + } + } + } + keyEvent->m_text = buf; + } + + postEvent(&WindowManager::the(), std::move(keyEvent)); } void EventLoopSDL::waitForEvent() @@ -59,10 +96,10 @@ void EventLoopSDL::waitForEvent() postEvent(&WindowManager::the(), make(Event::MouseUp, sdlEvent.button.x, sdlEvent.button.y, toMouseButton(sdlEvent.button.button))); return; case SDL_KEYDOWN: - postEvent(&WindowManager::the(), make(Event::KeyDown, toKey(sdlEvent.key.keysym))); + handleKeyEvent(Event::KeyDown, sdlEvent.key); return; case SDL_KEYUP: - postEvent(&WindowManager::the(), make(Event::KeyUp, toKey(sdlEvent.key.keysym))); + handleKeyEvent(Event::KeyUp, sdlEvent.key); return; } } diff --git a/Widgets/EventLoopSDL.h b/Widgets/EventLoopSDL.h index b5ac349060..733400689f 100644 --- a/Widgets/EventLoopSDL.h +++ b/Widgets/EventLoopSDL.h @@ -1,6 +1,8 @@ #pragma once +#include "Event.h" #include "EventLoop.h" +#include class EventLoopSDL final : public EventLoop { public: @@ -9,5 +11,7 @@ public: private: virtual void waitForEvent() override; + + void handleKeyEvent(Event::Type, const SDL_KeyboardEvent&); }; diff --git a/Widgets/Font.cpp b/Widgets/Font.cpp index 8d69a284be..61bb7aa1f0 100644 --- a/Widgets/Font.cpp +++ b/Widgets/Font.cpp @@ -30,5 +30,6 @@ const CBitmap* Font::glyphBitmap(byte ch) const const char* data = m_glyphs[(unsigned)ch - m_firstGlyph]; m_bitmaps[ch] = CBitmap::createFromASCII(data, m_glyphWidth, m_glyphHeight); } + ASSERT(ch >= m_firstGlyph && ch <= m_lastGlyph); return m_bitmaps[ch].ptr(); } diff --git a/Widgets/Makefile b/Widgets/Makefile index 2777bed7e1..33778a71e8 100644 --- a/Widgets/Makefile +++ b/Widgets/Makefile @@ -29,7 +29,7 @@ VFS_OBJS = \ OBJS = $(AK_OBJS) $(VFS_OBJS) -CXXFLAGS = -std=c++17 -O0 -W -Wall -Wextra -Wconversion -I. -I.. -g `sdl2-config --cflags` -DUSE_SDL +CXXFLAGS = -std=c++17 -O0 -W -Wall -Wextra -Wconversion -I. -I.. -ggdb3 `sdl2-config --cflags` -DUSE_SDL LDFLAGS = `sdl2-config --libs` diff --git a/Widgets/TerminalWidget.cpp b/Widgets/TerminalWidget.cpp index 94306ecce2..7eaff9420e 100644 --- a/Widgets/TerminalWidget.cpp +++ b/Widgets/TerminalWidget.cpp @@ -93,7 +93,7 @@ void TerminalWidget::onReceive(byte ch) //printf("receive %02x\n", ch); auto scrollScreen = [&] () { memmove(m_screen, m_screen + columns(), (m_rows - 1) * columns() * sizeof(CharacterWithAttributes)); - memset(m_screen + (m_rows - 1) * columns(), ' ', columns() * sizeof(CharacterWithAttributes) * 2); + memset(m_screen + (m_rows - 1) * columns(), ' ', columns() * sizeof(CharacterWithAttributes)); }; auto addChar = [&] (byte ch) { @@ -143,10 +143,9 @@ void TerminalWidget::onReceive(byte ch) void TerminalWidget::onKeyDown(KeyEvent& event) { - char buf[] = { 0, 0 }; - buf[0] = event.key(); - write(g_fd, buf, 2); - return Widget::onKeyDown(event); + if (event.text().isEmpty()) + return; + write(g_fd, event.text().characters(), event.text().length()); } void TerminalWidget::onKeyUp(KeyEvent& event)