summaryrefslogtreecommitdiff
path: root/Libraries
diff options
context:
space:
mode:
authorSergey Bugaev <bugaevc@serenityos.org>2020-05-27 00:31:30 +0300
committerAndreas Kling <kling@serenityos.org>2020-05-27 11:19:38 +0200
commit620697d924c15d62719ced9b4a2cab909bec74cb (patch)
tree2ff5fb4c1042726f7d674cb1605e3a7136f03cf8 /Libraries
parentfce49b3e32f1813670b413a517ea670ee0a0a912 (diff)
downloadserenity-620697d924c15d62719ced9b4a2cab909bec74cb.zip
LibVT: Move most of key press handling logic into VT::Terminal
This will let us share it between the userspace (TerminalWidget) and the Kernel.
Diffstat (limited to 'Libraries')
-rw-r--r--Libraries/LibVT/Terminal.cpp64
-rw-r--r--Libraries/LibVT/Terminal.h2
-rw-r--r--Libraries/LibVT/TerminalWidget.cpp96
3 files changed, 88 insertions, 74 deletions
diff --git a/Libraries/LibVT/Terminal.cpp b/Libraries/LibVT/Terminal.cpp
index 41567857fb..d35f64066e 100644
--- a/Libraries/LibVT/Terminal.cpp
+++ b/Libraries/LibVT/Terminal.cpp
@@ -25,6 +25,7 @@
*/
#include <AK/StringBuilder.h>
+#include <AK/StringView.h>
#include <LibVT/Terminal.h>
#include <string.h>
@@ -1004,6 +1005,69 @@ void Terminal::emit_string(const StringView& string)
m_client.emit((const u8*)string.characters_without_null_termination(), string.length());
}
+void Terminal::handle_key_press(KeyCode key, u8 character, u8 flags)
+{
+ bool ctrl = flags & Mod_Ctrl;
+ bool alt = flags & Mod_Alt;
+ bool shift = flags & Mod_Shift;
+
+ switch (key) {
+ case KeyCode::Key_Up:
+ emit_string(ctrl ? "\033[OA" : "\033[A");
+ return;
+ case KeyCode::Key_Down:
+ emit_string(ctrl ? "\033[OB" : "\033[B");
+ return;
+ case KeyCode::Key_Right:
+ emit_string(ctrl ? "\033[OC" : "\033[C");
+ return;
+ case KeyCode::Key_Left:
+ emit_string(ctrl ? "\033[OD" : "\033[D");
+ return;
+ case KeyCode::Key_Insert:
+ emit_string("\033[2~");
+ return;
+ case KeyCode::Key_Delete:
+ emit_string("\033[3~");
+ return;
+ case KeyCode::Key_Home:
+ emit_string("\033[H");
+ return;
+ case KeyCode::Key_End:
+ emit_string("\033[F");
+ return;
+ case KeyCode::Key_PageUp:
+ emit_string("\033[5~");
+ return;
+ case KeyCode::Key_PageDown:
+ emit_string("\033[6~");
+ return;
+ default:
+ break;
+ }
+
+ if (shift && key == KeyCode::Key_Tab) {
+ emit_string("\033[Z");
+ return;
+ }
+
+ // Key event was not one of the above special cases,
+ // attempt to treat it as a character...
+ if (ctrl) {
+ if (character >= 'a' && character <= 'z') {
+ character = character - 'a' + 1;
+ } else if (character == '\\') {
+ character = 0x1c;
+ }
+ }
+
+ // Alt modifier sends escape prefix.
+ if (alt)
+ emit_string("\033");
+
+ emit_string({ &character, 1 });
+}
+
void Terminal::unimplemented_escape()
{
StringBuilder builder;
diff --git a/Libraries/LibVT/Terminal.h b/Libraries/LibVT/Terminal.h
index d4061856df..4f8d10ad50 100644
--- a/Libraries/LibVT/Terminal.h
+++ b/Libraries/LibVT/Terminal.h
@@ -30,6 +30,7 @@
#include <AK/NonnullOwnPtrVector.h>
#include <AK/String.h>
#include <AK/Vector.h>
+#include <Kernel/KeyCode.h>
#include <LibVT/Line.h>
#include <LibVT/Position.h>
@@ -95,6 +96,7 @@ public:
const NonnullOwnPtrVector<Line>& history() const { return m_history; }
void inject_string(const StringView&);
+ void handle_key_press(KeyCode, u8 charatcter, u8 flags);
Attribute attribute_at(const Position&) const;
diff --git a/Libraries/LibVT/TerminalWidget.cpp b/Libraries/LibVT/TerminalWidget.cpp
index 75b5949f02..aa381566ee 100644
--- a/Libraries/LibVT/TerminalWidget.cpp
+++ b/Libraries/LibVT/TerminalWidget.cpp
@@ -206,90 +206,38 @@ void TerminalWidget::keydown_event(GUI::KeyEvent& event)
m_cursor_blink_timer->stop();
m_cursor_blink_state = true;
m_cursor_blink_timer->start();
- auto ctrl_held = !!(event.modifiers() & Mod_Ctrl);
- switch (event.key()) {
- case KeyCode::Key_Up:
- write(m_ptm_fd, ctrl_held ? "\033[OA" : "\033[A", 3 + ctrl_held);
- return;
- case KeyCode::Key_Down:
- write(m_ptm_fd, ctrl_held ? "\033[OB" : "\033[B", 3 + ctrl_held);
- return;
- case KeyCode::Key_Right:
- write(m_ptm_fd, ctrl_held ? "\033[OC" : "\033[C", 3 + ctrl_held);
- return;
- case KeyCode::Key_Left:
- write(m_ptm_fd, ctrl_held ? "\033[OD" : "\033[D", 3 + ctrl_held);
- return;
- case KeyCode::Key_Insert:
- write(m_ptm_fd, "\033[2~", 4);
+ if (event.key() == KeyCode::Key_PageUp && event.modifiers() == Mod_Shift) {
+ m_scrollbar->set_value(m_scrollbar->value() - m_terminal.rows());
return;
- case KeyCode::Key_Delete:
- write(m_ptm_fd, "\033[3~", 4);
- return;
- case KeyCode::Key_Home:
- write(m_ptm_fd, "\033[H", 3);
- return;
- case KeyCode::Key_End:
- write(m_ptm_fd, "\033[F", 3);
- return;
- case KeyCode::Key_PageUp:
- if (event.modifiers() == Mod_Shift) {
- m_scrollbar->set_value(m_scrollbar->value() - m_terminal.rows());
- return;
- }
- write(m_ptm_fd, "\033[5~", 4);
- return;
- case KeyCode::Key_PageDown:
- if (event.modifiers() == Mod_Shift) {
- m_scrollbar->set_value(m_scrollbar->value() + m_terminal.rows());
- return;
- }
- write(m_ptm_fd, "\033[6~", 4);
- return;
- case KeyCode::Key_Alt:
- m_alt_key_held = true;
+ }
+ if (event.key() == KeyCode::Key_PageDown && event.modifiers() == Mod_Shift) {
+ m_scrollbar->set_value(m_scrollbar->value() + m_terminal.rows());
return;
- default:
- break;
}
-
- if (event.shift() && event.key() == KeyCode::Key_Tab) {
- write(m_ptm_fd, "\033[Z", 3);
+ if (event.key() == KeyCode::Key_Alt) {
+ m_alt_key_held = true;
return;
}
- // Key event was not one of the above special cases,
- // attempt to treat it as a character...
- if (event.text().length() == 1) {
- // 1 byte input == ASCII
- char ch = !event.text().is_empty() ? event.text()[0] : 0;
- if (event.ctrl()) {
- if (ch >= 'a' && ch <= 'z') {
- ch = ch - 'a' + 1;
- } else if (ch == '\\') {
- ch = 0x1c;
- }
- }
-
- // ALT modifier sends escape prefix
- if (event.alt())
- write(m_ptm_fd, "\033", 1);
-
- //Clear the selection if we type in/behind it
- auto future_cursor_column = (event.key() == KeyCode::Key_Backspace) ? m_terminal.cursor_column() - 1 : m_terminal.cursor_column();
- auto min_selection_row = min(m_selection_start.row(), m_selection_end.row());
- auto max_selection_row = max(m_selection_start.row(), m_selection_end.row());
+ // Clear the selection if we type in/behind it.
+ auto future_cursor_column = (event.key() == KeyCode::Key_Backspace) ? m_terminal.cursor_column() - 1 : m_terminal.cursor_column();
+ auto min_selection_row = min(m_selection_start.row(), m_selection_end.row());
+ auto max_selection_row = max(m_selection_start.row(), m_selection_end.row());
- if (future_cursor_column <= last_selection_column_on_row(m_terminal.cursor_row()) && m_terminal.cursor_row() >= min_selection_row && m_terminal.cursor_row() <= max_selection_row) {
- m_selection_end = {};
- update();
- }
+ if (future_cursor_column <= last_selection_column_on_row(m_terminal.cursor_row()) && m_terminal.cursor_row() >= min_selection_row && m_terminal.cursor_row() <= max_selection_row) {
+ m_selection_end = {};
+ update();
+ }
- write(m_ptm_fd, &ch, 1);
- } else if (event.text().length() > 1) {
- // 2+ byte input == Unicode
+ if (event.text().length() > 2) {
+ // Unicode (likely emoji), just emit it.
write(m_ptm_fd, event.text().characters(), event.text().length());
+ } else {
+ // Ask the terminal to generate the correct character sequence and send
+ // it back to us via emit().
+ u8 character = event.text().length() == 1 ? event.text()[0] : 0;
+ m_terminal.handle_key_press(event.key(), character, event.modifiers());
}
if (event.key() != Key_Control && event.key() != Key_Alt && event.key() != Key_Shift && event.key() != Key_Logo)