summaryrefslogtreecommitdiff
path: root/Servers/WindowServer/WSScreen.cpp
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-03-20 04:34:14 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-03-20 04:34:14 +0100
commitd17a91f1851e8f0b3a3353d677ad8d1f51e921b7 (patch)
tree30316253f23ab99c106832deeb6c7d36adab27fc /Servers/WindowServer/WSScreen.cpp
parent9120b05a4044b346be397b0ae5b9b7e9a8cbd0b1 (diff)
downloadserenity-d17a91f1851e8f0b3a3353d677ad8d1f51e921b7.zip
Move WindowServer into Servers.
Diffstat (limited to 'Servers/WindowServer/WSScreen.cpp')
-rw-r--r--Servers/WindowServer/WSScreen.cpp98
1 files changed, 98 insertions, 0 deletions
diff --git a/Servers/WindowServer/WSScreen.cpp b/Servers/WindowServer/WSScreen.cpp
new file mode 100644
index 0000000000..f491b014c6
--- /dev/null
+++ b/Servers/WindowServer/WSScreen.cpp
@@ -0,0 +1,98 @@
+#include "WSScreen.h"
+#include "WSMessageLoop.h"
+#include "WSMessage.h"
+#include "WSWindowManager.h"
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+
+static WSScreen* s_the;
+
+WSScreen& WSScreen::the()
+{
+ ASSERT(s_the);
+ return *s_the;
+}
+
+WSScreen::WSScreen(unsigned width, unsigned height)
+ : m_width(width)
+ , m_height(height)
+{
+ ASSERT(!s_the);
+ s_the = this;
+ m_cursor_location = rect().center();
+ m_framebuffer_fd = open("/dev/bxvga", O_RDWR);
+ ASSERT(m_framebuffer_fd >= 0);
+
+ set_resolution(width, height);
+}
+
+WSScreen::~WSScreen()
+{
+}
+
+void WSScreen::set_resolution(int width, int height)
+{
+ struct BXVGAResolution {
+ int width;
+ int height;
+ };
+ BXVGAResolution resolution { (int)width, (int)height};
+ int rc = ioctl(m_framebuffer_fd, 1985, (int)&resolution);
+ ASSERT(rc == 0);
+
+ if (m_framebuffer) {
+ size_t previous_size_in_bytes = m_width * m_height * sizeof(RGBA32) * 2;
+ int rc = munmap(m_framebuffer, previous_size_in_bytes);
+ ASSERT(rc == 0);
+ }
+
+ size_t framebuffer_size_in_bytes = width * height * sizeof(RGBA32) * 2;
+ m_framebuffer = (RGBA32*)mmap(nullptr, framebuffer_size_in_bytes, PROT_READ | PROT_WRITE, MAP_SHARED, m_framebuffer_fd, 0);
+ ASSERT(m_framebuffer && m_framebuffer != (void*)-1);
+
+ m_width = width;
+ m_height = height;
+
+ m_cursor_location.constrain(rect());
+}
+
+void WSScreen::on_receive_mouse_data(int dx, int dy, unsigned buttons)
+{
+ auto prev_location = m_cursor_location;
+ m_cursor_location.move_by(dx, dy);
+ m_cursor_location.constrain(rect());
+ unsigned prev_buttons = m_mouse_button_state;
+ m_mouse_button_state = buttons;
+ unsigned changed_buttons = prev_buttons ^ buttons;
+ auto post_mousedown_or_mouseup_if_needed = [&] (MouseButton button) {
+ if (!(changed_buttons & (unsigned)button))
+ return;
+ auto message = make<WSMouseEvent>(buttons & (unsigned)button ? WSMessage::MouseDown : WSMessage::MouseUp, m_cursor_location, buttons, button, m_modifiers);
+ WSMessageLoop::the().post_message(WSWindowManager::the(), move(message));
+ };
+ post_mousedown_or_mouseup_if_needed(MouseButton::Left);
+ post_mousedown_or_mouseup_if_needed(MouseButton::Right);
+ post_mousedown_or_mouseup_if_needed(MouseButton::Middle);
+ if (m_cursor_location != prev_location) {
+ auto message = make<WSMouseEvent>(WSMessage::MouseMove, m_cursor_location, buttons, MouseButton::None, m_modifiers);
+ WSMessageLoop::the().post_message(WSWindowManager::the(), move(message));
+ }
+ // NOTE: Invalidate the cursor if it moved, or if the left button changed state (for the cursor color inversion.)
+ if (m_cursor_location != prev_location || changed_buttons & (unsigned)MouseButton::Left)
+ WSWindowManager::the().invalidate_cursor();
+}
+
+void WSScreen::on_receive_keyboard_data(KeyEvent kernel_event)
+{
+ m_modifiers = kernel_event.modifiers();
+ auto message = make<WSKeyEvent>(kernel_event.is_press() ? WSMessage::KeyDown : WSMessage::KeyUp, kernel_event.key, kernel_event.character, kernel_event.modifiers());
+ WSMessageLoop::the().post_message(WSWindowManager::the(), move(message));
+}
+
+void WSScreen::set_y_offset(int offset)
+{
+ int rc = ioctl(m_framebuffer_fd, 1982, offset);
+ ASSERT(rc == 0);
+}