From 78696236d3426a2b33bb35ea346cd66b4356021b Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Tue, 15 Jan 2019 06:49:52 +0100 Subject: [PATCH] Add very basic KeyDown events to the GUI event stream. The Terminal program now hosts an interactive shell. :^) --- Kernel/GUITypes.h | 19 ++++++++++++++++--- Kernel/Process.cpp | 3 +++ Terminal/main.cpp | 15 ++++++++++----- Widgets/Window.cpp | 4 ++++ 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/Kernel/GUITypes.h b/Kernel/GUITypes.h index 490f2499f8..088b94b734 100644 --- a/Kernel/GUITypes.h +++ b/Kernel/GUITypes.h @@ -42,11 +42,18 @@ struct GUI_WindowBackingStoreInfo { enum class GUI_MouseButton : unsigned char { NoButton = 0, - Left = 1, - Right = 2, - Middle = 4, + Left = 1, + Right = 2, + Middle = 4, }; +struct GUI_KeyModifiers { enum { + Shift = 1 << 0, + Alt = 1 << 1, + Ctrl = 1 << 2, +}; }; + + struct GUI_Event { enum Type : unsigned { Invalid, @@ -54,6 +61,8 @@ struct GUI_Event { MouseMove, MouseDown, MouseUp, + KeyDown, + KeyUp, }; Type type { Invalid }; int window_id { -1 }; @@ -66,6 +75,10 @@ struct GUI_Event { GUI_Point position; GUI_MouseButton button; } mouse; + struct { + char character; + unsigned modifiers; + } key; }; }; diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 9869f1421d..e6accc4761 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -1173,6 +1173,7 @@ int Process::sys$fcntl(int fd, int cmd, dword arg) case F_GETFL: return descriptor->file_flags(); case F_SETFL: + // FIXME: Support changing O_NONBLOCK descriptor->set_file_flags(arg); break; default: @@ -1294,6 +1295,8 @@ int Process::sys$open(const char* path, int options) return error; if (options & O_DIRECTORY && !descriptor->is_directory()) return -ENOTDIR; // FIXME: This should be handled by VFS::open. + if (options & O_NONBLOCK) + descriptor->set_blocking(false); int fd = 0; for (; fd < (int)m_max_open_file_descriptors; ++fd) { diff --git a/Terminal/main.cpp b/Terminal/main.cpp index c325a7734b..96bf34a443 100644 --- a/Terminal/main.cpp +++ b/Terminal/main.cpp @@ -43,7 +43,7 @@ static void make_shell(int ptm_fd) int main(int, char**) { - int ptm_fd = open("/dev/ptm0", O_RDWR); + int ptm_fd = open("/dev/ptm0", O_RDWR | O_NONBLOCK); if (ptm_fd < 0) { perror("open"); return 1; @@ -53,7 +53,7 @@ int main(int, char**) make_shell(ptm_fd); - int event_fd = open("/dev/gui_events", O_RDONLY); + int event_fd = open("/dev/gui_events", O_RDONLY | O_NONBLOCK); if (event_fd < 0) { perror("open"); return 1; @@ -72,13 +72,15 @@ int main(int, char**) } terminal.paint(); } -#if 0 + GUI_Event event; ssize_t nread = read(event_fd, &event, sizeof(event)); if (nread < 0) { perror("read"); return 1; } + if (nread == 0) + continue; assert(nread == sizeof(event)); dbgprintf("(Terminal:%d) ", getpid()); switch (event.type) { @@ -86,13 +88,16 @@ int main(int, char**) case GUI_Event::Type::MouseDown: dbgprintf("WID=%x MouseDown %d,%d\n", event.window_id, event.mouse.position.x, event.mouse.position.y); break; case GUI_Event::Type::MouseUp: dbgprintf("WID=%x MouseUp %d,%d\n", event.window_id, event.mouse.position.x, event.mouse.position.y); break; case GUI_Event::Type::MouseMove: dbgprintf("WID=%x MouseMove %d,%d\n", event.window_id, event.mouse.position.x, event.mouse.position.y); break; + case GUI_Event::Type::KeyDown: dbgprintf("WID=%x KeyDown 0x%b (%c)\n", event.window_id, event.key.character, event.key.character); break; default: ASSERT_NOT_REACHED(); } - if (event.type == GUI_Event::Type::MouseDown) + if (event.type == GUI_Event::Type::Paint) { terminal.paint(); -#endif + } else if (event.type == GUI_Event::Type::KeyDown) { + write(ptm_fd, &event.key.character, 1); + } } return 0; } diff --git a/Widgets/Window.cpp b/Widgets/Window.cpp index 4f4f7f2da5..f70dcee59e 100644 --- a/Widgets/Window.cpp +++ b/Widgets/Window.cpp @@ -72,6 +72,10 @@ void Window::event(Event& event) gui_event.mouse.position = static_cast(event).position(); gui_event.mouse.button = to_api(static_cast(event).button()); break; + case Event::KeyDown: + gui_event.type = GUI_Event::Type::KeyDown; + gui_event.key.character = static_cast(event).text()[0]; + break; } if (gui_event.type == GUI_Event::Type::Invalid)