Compare commits
6 Commits
57cc217a11
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| b03a10d601 | |||
| a02355eb20 | |||
| 7d07c069b9 | |||
| b387457337 | |||
| 5474048db5 | |||
| 7370d562de |
@@ -1,20 +1,20 @@
|
||||
From c9dd87198ce5262e6ddf6bf3b0c18eb84784d35e Mon Sep 17 00:00:00 2001
|
||||
From e71364497354b511159bf3d883b0e6168f430187 Mon Sep 17 00:00:00 2001
|
||||
From: Oskari Alaranta <oskari.alaranta@bananymous.com>
|
||||
Date: Wed, 15 Apr 2026 17:52:54 +0300
|
||||
Date: Tue, 7 Jul 2026 05:04:45 +0300
|
||||
Subject: [PATCH] linux-window-server-sdl2
|
||||
|
||||
---
|
||||
userspace/libraries/LibGUI/Widget/Widget.cpp | 2 +-
|
||||
userspace/libraries/LibGUI/Window.cpp | 9 +-
|
||||
userspace/libraries/LibGUI/Window.cpp | 11 +-
|
||||
userspace/programs/ProgramLauncher/main.cpp | 2 +-
|
||||
userspace/programs/Terminal/Terminal.cpp | 4 +-
|
||||
userspace/programs/Terminal/Terminal.cpp | 10 +-
|
||||
.../programs/WindowServer/CMakeLists.txt | 3 +
|
||||
.../programs/WindowServer/Framebuffer.cpp | 52 +--
|
||||
userspace/programs/WindowServer/Window.cpp | 29 +-
|
||||
.../programs/WindowServer/WindowServer.cpp | 47 ++-
|
||||
.../programs/WindowServer/WindowServer.h | 1 +
|
||||
userspace/programs/WindowServer/main.cpp | 357 ++++++++++++------
|
||||
10 files changed, 340 insertions(+), 166 deletions(-)
|
||||
10 files changed, 345 insertions(+), 169 deletions(-)
|
||||
|
||||
diff --git a/userspace/libraries/LibGUI/Widget/Widget.cpp b/userspace/libraries/LibGUI/Widget/Widget.cpp
|
||||
index d6489d87..c532fb04 100644
|
||||
@@ -30,7 +30,7 @@ index d6489d87..c532fb04 100644
|
||||
}
|
||||
|
||||
diff --git a/userspace/libraries/LibGUI/Window.cpp b/userspace/libraries/LibGUI/Window.cpp
|
||||
index b4172f70..3a0e9cca 100644
|
||||
index 607421eb..d8aeee7e 100644
|
||||
--- a/userspace/libraries/LibGUI/Window.cpp
|
||||
+++ b/userspace/libraries/LibGUI/Window.cpp
|
||||
@@ -4,9 +4,8 @@
|
||||
@@ -44,7 +44,7 @@ index b4172f70..3a0e9cca 100644
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <time.h>
|
||||
@@ -271,7 +270,7 @@ namespace LibGUI
|
||||
@@ -311,23 +310,23 @@ namespace LibGUI
|
||||
|
||||
void Window::cleanup()
|
||||
{
|
||||
@@ -53,24 +53,25 @@ index b4172f70..3a0e9cca 100644
|
||||
close(m_server_fd);
|
||||
close(m_epoll_fd);
|
||||
}
|
||||
@@ -279,7 +278,7 @@ namespace LibGUI
|
||||
BAN::ErrorOr<void> Window::handle_resize_event(const EventPacket::ResizeWindowEvent& event)
|
||||
|
||||
BAN::ErrorOr<bool> Window::handle_resize_event(const EventPacket::ResizeWindowEvent& event)
|
||||
{
|
||||
- void* framebuffer_addr = smo_map(event.smo_key);
|
||||
+ void* framebuffer_addr = shmat(event.smo_key, nullptr, 0);
|
||||
if (framebuffer_addr == nullptr)
|
||||
{
|
||||
- if (errno == ENOENT)
|
||||
+ if (errno == EINVAL)
|
||||
return false;
|
||||
return BAN::Error::from_errno(errno);
|
||||
}
|
||||
|
||||
if (m_framebuffer_smo)
|
||||
- munmap(m_framebuffer_smo, m_width * m_height * 4);
|
||||
+ shmdt(m_framebuffer_smo);
|
||||
m_framebuffer_smo = nullptr;
|
||||
|
||||
TRY(m_texture.resize(event.width, event.height));
|
||||
@@ -287,7 +286,7 @@ namespace LibGUI
|
||||
if (m_root_widget)
|
||||
TRY(m_root_widget->set_fixed_geometry({ 0, 0, event.width, event.height }));
|
||||
|
||||
- void* framebuffer_addr = smo_map(event.smo_key);
|
||||
+ void* framebuffer_addr = shmat(event.smo_key, nullptr, 0);
|
||||
if (framebuffer_addr == nullptr)
|
||||
return BAN::Error::from_errno(errno);
|
||||
|
||||
diff --git a/userspace/programs/ProgramLauncher/main.cpp b/userspace/programs/ProgramLauncher/main.cpp
|
||||
index c833c582..0e1cc460 100644
|
||||
--- a/userspace/programs/ProgramLauncher/main.cpp
|
||||
@@ -85,10 +86,18 @@ index c833c582..0e1cc460 100644
|
||||
const auto full_program_list = get_program_list();
|
||||
|
||||
diff --git a/userspace/programs/Terminal/Terminal.cpp b/userspace/programs/Terminal/Terminal.cpp
|
||||
index e1bd317d..8a6b5bd0 100644
|
||||
index c470438d..709db432 100644
|
||||
--- a/userspace/programs/Terminal/Terminal.cpp
|
||||
+++ b/userspace/programs/Terminal/Terminal.cpp
|
||||
@@ -92,7 +92,7 @@ void Terminal::start_shell()
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
+#include <sys/ioctl.h>
|
||||
#include <sys/select.h>
|
||||
#include <termios.h>
|
||||
#include <time.h>
|
||||
@@ -92,7 +93,7 @@ void Terminal::start_shell()
|
||||
close(pts_slave);
|
||||
close(pts_master);
|
||||
|
||||
@@ -97,7 +106,7 @@ index e1bd317d..8a6b5bd0 100644
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ void Terminal::run()
|
||||
@@ -127,7 +128,7 @@ void Terminal::run()
|
||||
m_window->texture().set_bg_color(m_bg_color);
|
||||
m_window->invalidate();
|
||||
|
||||
@@ -106,6 +115,25 @@ index e1bd317d..8a6b5bd0 100644
|
||||
|
||||
m_window->set_min_size(m_font.width() * 8, m_font.height() * 2);
|
||||
|
||||
@@ -147,7 +148,8 @@ void Terminal::run()
|
||||
.ws_xpixel = static_cast<unsigned short>(m_window->width()),
|
||||
.ws_ypixel = static_cast<unsigned short>(m_window->height()),
|
||||
};
|
||||
- if (tcsetwinsize(m_shell_info.pts_master, &winsize) == -1)
|
||||
+
|
||||
+ if (ioctl(m_shell_info.pts_master, TIOCSWINSZ, &winsize) == -1)
|
||||
perror("tcsetwinsize");
|
||||
}
|
||||
|
||||
@@ -212,7 +214,7 @@ void Terminal::run()
|
||||
.ws_xpixel = static_cast<unsigned short>(m_window->width()),
|
||||
.ws_ypixel = static_cast<unsigned short>(m_window->height()),
|
||||
};
|
||||
- if (tcsetwinsize(m_shell_info.pts_master, &winsize) == -1)
|
||||
+ if (ioctl(m_shell_info.pts_master, TIOCSWINSZ, &winsize) == -1)
|
||||
perror("tcsetwinsize");
|
||||
});
|
||||
|
||||
diff --git a/userspace/programs/WindowServer/CMakeLists.txt b/userspace/programs/WindowServer/CMakeLists.txt
|
||||
index 8fdf79f9..fcaf441d 100644
|
||||
--- a/userspace/programs/WindowServer/CMakeLists.txt
|
||||
@@ -199,7 +227,7 @@ index 0e727e8f..119f1451 100644
|
||||
return framebuffer;
|
||||
}
|
||||
diff --git a/userspace/programs/WindowServer/Window.cpp b/userspace/programs/WindowServer/Window.cpp
|
||||
index 1e66f522..9759eec9 100644
|
||||
index 78de89c9..c5405695 100644
|
||||
--- a/userspace/programs/WindowServer/Window.cpp
|
||||
+++ b/userspace/programs/WindowServer/Window.cpp
|
||||
@@ -5,15 +5,14 @@
|
||||
@@ -221,7 +249,7 @@ index 1e66f522..9759eec9 100644
|
||||
|
||||
LibGUI::EventPacket::DestroyWindowEvent packet;
|
||||
|
||||
@@ -47,16 +46,16 @@ BAN::ErrorOr<void> Window::resize(uint32_t width, uint32_t height)
|
||||
@@ -45,16 +44,16 @@ BAN::ErrorOr<void> Window::resize(uint32_t width, uint32_t height)
|
||||
{
|
||||
const size_t fb_bytes = width * height * 4;
|
||||
|
||||
@@ -244,7 +272,7 @@ index 1e66f522..9759eec9 100644
|
||||
|
||||
{
|
||||
const auto old_area = m_client_area;
|
||||
@@ -70,16 +69,14 @@ BAN::ErrorOr<void> Window::resize(uint32_t width, uint32_t height)
|
||||
@@ -68,16 +67,14 @@ BAN::ErrorOr<void> Window::resize(uint32_t width, uint32_t height)
|
||||
return title_bar_ret.release_error();
|
||||
}
|
||||
|
||||
@@ -266,7 +294,7 @@ index 1e66f522..9759eec9 100644
|
||||
m_client_area.max_x = m_client_area.min_x + width;
|
||||
m_client_area.max_y = m_client_area.min_y + height;
|
||||
diff --git a/userspace/programs/WindowServer/WindowServer.cpp b/userspace/programs/WindowServer/WindowServer.cpp
|
||||
index 2c67d6c0..600704fd 100644
|
||||
index e6b01476..a14074c3 100644
|
||||
--- a/userspace/programs/WindowServer/WindowServer.cpp
|
||||
+++ b/userspace/programs/WindowServer/WindowServer.cpp
|
||||
@@ -8,19 +8,20 @@
|
||||
@@ -295,16 +323,16 @@ index 2c67d6c0..600704fd 100644
|
||||
{
|
||||
MUST(m_background_image.resize(m_framebuffer.width * m_framebuffer.height, 0xFF101010));
|
||||
|
||||
@@ -440,7 +441,7 @@ static void update_volume(const char* new_volume)
|
||||
@@ -512,7 +513,7 @@ static void update_volume(const char* new_volume)
|
||||
|
||||
void WindowServer::on_key_event(LibInput::KeyEvent event)
|
||||
{
|
||||
- if (event.key == LibInput::Key::Super)
|
||||
- if (event.key == LibInput::Key::LeftSuper)
|
||||
+ if (event.key == LibInput::Key::RightCtrl)
|
||||
m_is_mod_key_held = event.pressed();
|
||||
|
||||
if (event.pressed() && event.key == LibInput::Key::VolumeDown)
|
||||
@@ -461,7 +462,7 @@ void WindowServer::on_key_event(LibInput::KeyEvent event)
|
||||
@@ -533,7 +534,7 @@ void WindowServer::on_key_event(LibInput::KeyEvent event)
|
||||
pid_t pid = fork();
|
||||
if (pid == 0)
|
||||
{
|
||||
@@ -313,7 +341,7 @@ index 2c67d6c0..600704fd 100644
|
||||
exit(1);
|
||||
}
|
||||
if (pid == -1)
|
||||
@@ -475,7 +476,7 @@ void WindowServer::on_key_event(LibInput::KeyEvent event)
|
||||
@@ -547,7 +548,7 @@ void WindowServer::on_key_event(LibInput::KeyEvent event)
|
||||
pid_t pid = fork();
|
||||
if (pid == 0)
|
||||
{
|
||||
@@ -322,7 +350,7 @@ index 2c67d6c0..600704fd 100644
|
||||
exit(1);
|
||||
}
|
||||
if (pid == -1)
|
||||
@@ -1599,16 +1600,34 @@ void WindowServer::sync()
|
||||
@@ -1664,16 +1665,34 @@ void WindowServer::sync()
|
||||
|
||||
for (size_t i = 0; i < m_damaged_area_count; i++)
|
||||
{
|
||||
@@ -364,10 +392,10 @@ index 2c67d6c0..600704fd 100644
|
||||
|
||||
Rectangle WindowServer::cursor_area() const
|
||||
diff --git a/userspace/programs/WindowServer/WindowServer.h b/userspace/programs/WindowServer/WindowServer.h
|
||||
index 94fbc774..bcd7a6b9 100644
|
||||
index 9e2dc70e..40813f2e 100644
|
||||
--- a/userspace/programs/WindowServer/WindowServer.h
|
||||
+++ b/userspace/programs/WindowServer/WindowServer.h
|
||||
@@ -62,6 +62,7 @@ public:
|
||||
@@ -65,6 +65,7 @@ public:
|
||||
|
||||
bool is_damaged() const { return m_damaged_area_count > 0 || m_is_bouncing_window; }
|
||||
bool is_stopped() const { return m_is_stopped; }
|
||||
@@ -376,7 +404,7 @@ index 94fbc774..bcd7a6b9 100644
|
||||
private:
|
||||
void on_mouse_move_impl(int32_t new_x, int32_t new_y);
|
||||
diff --git a/userspace/programs/WindowServer/main.cpp b/userspace/programs/WindowServer/main.cpp
|
||||
index 46f2ba6d..520c8e7d 100644
|
||||
index 61d10e97..e77e5d97 100644
|
||||
--- a/userspace/programs/WindowServer/main.cpp
|
||||
+++ b/userspace/programs/WindowServer/main.cpp
|
||||
@@ -10,7 +10,6 @@
|
||||
@@ -518,7 +546,7 @@ index 46f2ba6d..520c8e7d 100644
|
||||
if (epoll_events == -1 && errno != EINTR)
|
||||
{
|
||||
dwarnln("epoll_pwait2: {}", strerror(errno));
|
||||
@@ -333,48 +288,6 @@ int main()
|
||||
@@ -334,48 +289,6 @@ int main()
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -567,7 +595,7 @@ index 46f2ba6d..520c8e7d 100644
|
||||
const int client_fd = events[i].data.fd;
|
||||
if (events[i].events & (EPOLLHUP | EPOLLERR))
|
||||
{
|
||||
@@ -500,3 +413,237 @@ int main()
|
||||
@@ -507,3 +420,237 @@ int main()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -806,5 +834,5 @@ index 46f2ba6d..520c8e7d 100644
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
2.53.0
|
||||
2.54.0
|
||||
|
||||
|
||||
2
banan-os
2
banan-os
Submodule banan-os updated: 1bf5e6a051...e713644973
484
xbanan/Base.cpp
484
xbanan/Base.cpp
@@ -296,85 +296,61 @@ static BAN::ErrorOr<void> send_visibility_events_recursively(Client& client_info
|
||||
return {};
|
||||
}
|
||||
|
||||
static void invalidate_window_recursive(WINDOW wid, int32_t x, int32_t y, int32_t w, int32_t h)
|
||||
static void invalidate_window_recursive(Object::Window& dst_window, int32_t dst_x, int32_t dst_y, const Object::Window& src_window, int32_t src_x, int32_t src_y, int32_t w, int32_t h)
|
||||
{
|
||||
ASSERT(wid != g_root.windowId);
|
||||
ASSERT(src_window.mapped);
|
||||
|
||||
if (x + w <= 0 || y + h <= 0)
|
||||
return;
|
||||
if (w <= 0 || h <= 0)
|
||||
return;
|
||||
|
||||
auto& object = *g_objects[wid];
|
||||
ASSERT(object.type == Object::Type::Window);
|
||||
|
||||
auto& window = object.object.get<Object::Window>();
|
||||
if (!window.mapped)
|
||||
return;
|
||||
|
||||
for (auto child_wid : window.children)
|
||||
if (src_window.c_class == InputOutput)
|
||||
{
|
||||
const auto& child_object = *g_objects[child_wid];
|
||||
ASSERT(child_object.type == Object::Type::Window);
|
||||
ASSERT(src_x >= 0);
|
||||
ASSERT(src_y >= 0);
|
||||
ASSERT(src_x + w <= src_window.width);
|
||||
ASSERT(src_y + h <= src_window.height);
|
||||
ASSERT(dst_x + w <= dst_window.width);
|
||||
ASSERT(dst_y + h <= dst_window.height);
|
||||
|
||||
const auto& child_window = child_object.object.get<Object::Window>();
|
||||
if (!child_window.mapped)
|
||||
continue;
|
||||
|
||||
const auto child_x = x - child_window.x;
|
||||
const auto child_y = y - child_window.y;
|
||||
|
||||
const auto child_w = BAN::Math::min<int32_t>(w - child_window.x, child_window.width - child_x);
|
||||
const auto child_h = BAN::Math::min<int32_t>(h - child_window.y, child_window.height - child_y);
|
||||
|
||||
invalidate_window_recursive(
|
||||
child_wid,
|
||||
child_x, child_y,
|
||||
child_w, child_h
|
||||
);
|
||||
for (int32_t y = 0; y < h; y++)
|
||||
{
|
||||
uint32_t* dst_u32 = &dst_window.double_buffer[(dst_y + y) * dst_window.width + dst_x];
|
||||
const uint32_t* src_u32 = &src_window. pixels[(src_y + y) * src_window.width + src_x];
|
||||
for (int32_t x = 0; x < w; x++)
|
||||
{
|
||||
if (src_u32[x] != COLOR_INVISIBLE)
|
||||
dst_u32[x] = 0xFF000000 | src_u32[x];
|
||||
else if (&dst_window == &src_window)
|
||||
dst_u32[x] = 0x00000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (window.platform_window || window.c_class == InputOnly)
|
||||
return;
|
||||
|
||||
auto& parent_object = *g_objects[window.parent];
|
||||
ASSERT(parent_object.type == Object::Type::Window);
|
||||
|
||||
auto& parent_window = parent_object.object.get<Object::Window>();
|
||||
|
||||
const uint32_t* child_pix = window.pixels.data();
|
||||
const int32_t child_w = window.width;
|
||||
const int32_t child_h = window.height;
|
||||
|
||||
uint32_t* parent_pix = parent_window.pixels.data();
|
||||
const int32_t parent_w = parent_window.width;
|
||||
const int32_t parent_h = parent_window.height;
|
||||
|
||||
// FIXME: optimize this
|
||||
for (int32_t y_off = 0; y_off < h; y_off++)
|
||||
for (auto child_wid : src_window.children)
|
||||
{
|
||||
const int32_t child_y = y + y_off;
|
||||
if (child_y < 0 || child_y >= child_h)
|
||||
const auto& child = g_objects[child_wid]->object.get<Object::Window>();
|
||||
if (!child.mapped)
|
||||
continue;
|
||||
|
||||
const int32_t parent_y = window.y + y + y_off;
|
||||
if (parent_y < 0 || parent_y >= parent_h)
|
||||
const auto diff_x = src_x - child.x;
|
||||
const auto diff_y = src_y - child.y;
|
||||
|
||||
const auto min_x = BAN::Math::max<int32_t>(diff_x, 0);
|
||||
const auto min_y = BAN::Math::max<int32_t>(diff_y, 0);
|
||||
|
||||
const auto max_x = BAN::Math::min<int32_t>(diff_x + w, child.width);
|
||||
const auto max_y = BAN::Math::min<int32_t>(diff_y + h, child.height);
|
||||
|
||||
if (max_x <= min_x || max_y <= min_y)
|
||||
continue;
|
||||
|
||||
for (int32_t x_off = 0; x_off < w; x_off++)
|
||||
{
|
||||
const int32_t child_x = x + x_off;
|
||||
if (child_x < 0 || child_x >= child_w)
|
||||
continue;
|
||||
|
||||
const int32_t parent_x = window.x + x + x_off;
|
||||
if (parent_x < 0 || parent_x >= parent_w)
|
||||
continue;
|
||||
|
||||
const uint32_t color = child_pix[child_y * child_w + child_x];
|
||||
if (color != COLOR_INVISIBLE)
|
||||
parent_pix[parent_y * parent_w + parent_x] = color;
|
||||
}
|
||||
invalidate_window_recursive(
|
||||
dst_window,
|
||||
dst_x - (diff_x - min_x),
|
||||
dst_y - (diff_y - min_y),
|
||||
child,
|
||||
min_x,
|
||||
min_y,
|
||||
max_x - min_x,
|
||||
max_y - min_y
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,68 +358,120 @@ void invalidate_window(WINDOW wid, int32_t x, int32_t y, int32_t w, int32_t h)
|
||||
{
|
||||
ASSERT(wid != g_root.windowId);
|
||||
|
||||
int32_t min_x { x }, max_x { x + w };
|
||||
int32_t min_y { y }, max_y { y + h };
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (wid == g_root.windowId)
|
||||
return;
|
||||
|
||||
auto& object = *g_objects[wid];
|
||||
ASSERT(object.type == Object::Type::Window);
|
||||
|
||||
auto& window = object.object.get<Object::Window>();
|
||||
const auto& window = g_objects[wid]->object.get<Object::Window>();
|
||||
if (!window.mapped)
|
||||
return;
|
||||
|
||||
if (min_x < 0)
|
||||
min_x = 0;
|
||||
if (min_y < 0)
|
||||
min_y = 0;
|
||||
|
||||
if (max_x > window.width)
|
||||
max_x = window.width;
|
||||
if (max_y > window.height)
|
||||
max_y = window.height;
|
||||
|
||||
if (max_x <= min_x || max_y <= min_y)
|
||||
return;
|
||||
|
||||
if (window.platform_window)
|
||||
break;
|
||||
|
||||
x += window.x;
|
||||
y += window.y;
|
||||
min_x += window.x;
|
||||
min_y += window.y;
|
||||
wid = window.parent;
|
||||
}
|
||||
|
||||
auto& object = *g_objects[wid];
|
||||
ASSERT(object.type == Object::Type::Window);
|
||||
auto& window = g_objects[wid]->object.get<Object::Window>();
|
||||
|
||||
auto& window = object.object.get<Object::Window>();
|
||||
ASSERT(window.platform_window);
|
||||
invalidate_window_recursive(
|
||||
window, min_x, min_y,
|
||||
window, min_x, min_y,
|
||||
max_x - min_x,
|
||||
max_y - min_y
|
||||
);
|
||||
|
||||
invalidate_window_recursive(wid, x, y, w, h);
|
||||
if (!window.platform_window_invalidated && g_platform_ops.begin_frame)
|
||||
g_platform_ops.begin_frame(window.platform_window.ptr());
|
||||
window.platform_window_invalidated = true;
|
||||
|
||||
const auto min_x = BAN::Math::max<int32_t>(x, 0);
|
||||
const auto min_y = BAN::Math::max<int32_t>(y, 0);
|
||||
const auto max_x = BAN::Math::min<int32_t>(x + w, window.width);
|
||||
const auto max_y = BAN::Math::min<int32_t>(y + h, window.height);
|
||||
|
||||
if (min_x >= max_x || min_y >= max_y)
|
||||
return;
|
||||
|
||||
uint32_t* pixels = window.pixels.data();
|
||||
for (auto y = min_y; y < max_y; y++)
|
||||
{
|
||||
for (auto x = min_x; x < max_x; x++)
|
||||
{
|
||||
auto& pixel = pixels[y * window.width + x];
|
||||
if (pixel == COLOR_INVISIBLE)
|
||||
pixel = 0x00000000;
|
||||
else
|
||||
pixel |= 0xFF000000;
|
||||
}
|
||||
}
|
||||
|
||||
g_platform_ops.invalidate(window.platform_window.ptr(), window.pixels.data(), min_x, min_y, max_x - min_x, max_y - min_y);
|
||||
g_platform_ops.invalidate(
|
||||
window.platform_window.ptr(),
|
||||
&window.double_buffer[min_y * window.width + min_x],
|
||||
window.width * sizeof(uint32_t),
|
||||
min_x, min_y,
|
||||
max_x - min_x,
|
||||
max_y - min_y
|
||||
);
|
||||
}
|
||||
|
||||
void send_exposure_recursive(WINDOW wid)
|
||||
BAN::ErrorOr<void> send_configure_notify(WINDOW wid)
|
||||
{
|
||||
auto& object = *g_objects[wid];
|
||||
ASSERT(object.type == Object::Type::Window);
|
||||
auto& window = g_objects[wid]->object.get<Object::Window>();
|
||||
|
||||
auto& window = object.object.get<Object::Window>();
|
||||
{
|
||||
xEvent event = { .u = {
|
||||
.configureNotify = {
|
||||
.event = wid,
|
||||
.window = wid,
|
||||
.aboveSibling = xFalse,
|
||||
.x = static_cast<INT16>(window.x),
|
||||
.y = static_cast<INT16>(window.y),
|
||||
.width = static_cast<CARD16>(window.width),
|
||||
.height = static_cast<CARD16>(window.height),
|
||||
.borderWidth = 0,
|
||||
.override = xFalse,
|
||||
}
|
||||
}};
|
||||
event.u.u.type = ConfigureNotify;
|
||||
TRY(window.send_event(event, StructureNotifyMask));
|
||||
}
|
||||
|
||||
auto& parent_object = *g_objects[window.parent];
|
||||
ASSERT(parent_object.type == Object::Type::Window);
|
||||
auto& parent_window = parent_object.object.get<Object::Window>();
|
||||
|
||||
{
|
||||
xEvent event = { .u = {
|
||||
.configureNotify = {
|
||||
.event = window.parent,
|
||||
.window = wid,
|
||||
.aboveSibling = xFalse,
|
||||
.x = static_cast<INT16>(window.x),
|
||||
.y = static_cast<INT16>(window.y),
|
||||
.width = static_cast<CARD16>(window.width),
|
||||
.height = static_cast<CARD16>(window.height),
|
||||
.borderWidth = 0,
|
||||
.override = xFalse,
|
||||
}
|
||||
}};
|
||||
event.u.u.type = ConfigureNotify;
|
||||
TRY(parent_window.send_event(event, SubstructureNotifyMask));
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> send_exposure_events_recursive(WINDOW wid)
|
||||
{
|
||||
auto& window = g_objects[wid]->object.get<Object::Window>();
|
||||
if (!window.mapped)
|
||||
return;
|
||||
return {};
|
||||
|
||||
for (auto child_wid : window.children)
|
||||
send_exposure_recursive(child_wid);
|
||||
TRY(send_exposure_events_recursive(child_wid));
|
||||
|
||||
if (window.c_class == InputOnly)
|
||||
return {};
|
||||
|
||||
xEvent event = { .u = {
|
||||
.expose = {
|
||||
@@ -455,66 +483,32 @@ void send_exposure_recursive(WINDOW wid)
|
||||
}
|
||||
}};
|
||||
event.u.u.type = Expose;
|
||||
MUST(window.send_event(event, ExposureMask));
|
||||
TRY(window.send_event(event, ExposureMask));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
struct PlatformWindowInfo
|
||||
{
|
||||
PlatformWindow* parent;
|
||||
WindowType type;
|
||||
};
|
||||
|
||||
static PlatformWindowInfo get_plaform_window_info(const Object::Window& window)
|
||||
static WindowType get_plaform_window_info(const Object::Window& window)
|
||||
{
|
||||
static const CARD32 ATOM = g_atoms_name_to_id["ATOM"_sv];
|
||||
static const CARD32 WINDOW = g_atoms_name_to_id["WINDOW"_sv];
|
||||
static const CARD32 WM_TRANSIENT_FOR = g_atoms_name_to_id["WM_TRANSIENT_FOR"_sv];
|
||||
static const CARD32 _NET_WM_WINDOW_TYPE = g_atoms_name_to_id["_NET_WM_WINDOW_TYPE"_sv];
|
||||
static const CARD32 _NET_WM_WINDOW_TYPE_DIALOG = g_atoms_name_to_id["_NET_WM_WINDOW_TYPE_DIALOG"_sv];
|
||||
static const CARD32 _NET_WM_WINDOW_TYPE_NORMAL = g_atoms_name_to_id["_NET_WM_WINDOW_TYPE_NORMAL"_sv];
|
||||
static const CARD32 _NET_WM_WINDOW_TYPE_SPLASH = g_atoms_name_to_id["_NET_WM_WINDOW_TYPE_SPLASH"_sv];
|
||||
static const CARD32 _NET_WM_WINDOW_TYPE_UTILITY = g_atoms_name_to_id["_NET_WM_WINDOW_TYPE_UTILITY"_sv];
|
||||
|
||||
PlatformWindowInfo info {
|
||||
.parent = nullptr,
|
||||
.type = WindowType::Normal,
|
||||
};
|
||||
auto it = window.properties.find(_NET_WM_WINDOW_TYPE);
|
||||
if (it == window.properties.end())
|
||||
return WindowType::Normal;
|
||||
|
||||
if (auto it = window.properties.find(_NET_WM_WINDOW_TYPE); it != window.properties.end())
|
||||
{
|
||||
if (it->value.type != ATOM || it->value.data.size() != sizeof(CARD32))
|
||||
goto wm_window_type_done;
|
||||
if (it->value.type != ATOM || it->value.data.size() != sizeof(CARD32))
|
||||
return WindowType::Normal;
|
||||
|
||||
const CARD32 type = *reinterpret_cast<const CARD32*>(it->value.data.data());
|
||||
if (type == _NET_WM_WINDOW_TYPE_NORMAL)
|
||||
info.type = WindowType::Normal;
|
||||
else if (type == _NET_WM_WINDOW_TYPE_SPLASH || type == _NET_WM_WINDOW_TYPE_DIALOG)
|
||||
info.type = WindowType::Utility;
|
||||
else
|
||||
info.type = WindowType::Popup;
|
||||
}
|
||||
wm_window_type_done:
|
||||
|
||||
if (auto it = window.properties.find(WM_TRANSIENT_FOR); it != window.properties.end())
|
||||
{
|
||||
if (it->value.type != WINDOW || it->value.data.size() != sizeof(CARD32))
|
||||
goto transitient_for_done;
|
||||
|
||||
const CARD32 wid = *reinterpret_cast<const CARD32*>(it->value.data.data());
|
||||
|
||||
auto it2 = g_objects.find(wid);
|
||||
if (it2 == g_objects.end())
|
||||
goto transitient_for_done;
|
||||
if (it2->value->type != Object::Type::Window)
|
||||
goto transitient_for_done;
|
||||
|
||||
// FIXME: support child windows
|
||||
auto& window = it2->value->object.get<Object::Window>();
|
||||
info.parent = window.platform_window.ptr();
|
||||
}
|
||||
transitient_for_done:
|
||||
|
||||
return info;
|
||||
const CARD32 type = *reinterpret_cast<const CARD32*>(it->value.data.data());
|
||||
if (type == _NET_WM_WINDOW_TYPE_NORMAL)
|
||||
return WindowType::Normal;
|
||||
if (type == _NET_WM_WINDOW_TYPE_SPLASH || type == _NET_WM_WINDOW_TYPE_DIALOG)
|
||||
return WindowType::Utility;
|
||||
return WindowType::Popup;
|
||||
}
|
||||
|
||||
static BAN::ErrorOr<void> map_window(Client& client_info, WINDOW wid)
|
||||
@@ -537,10 +531,13 @@ static BAN::ErrorOr<void> map_window(Client& client_info, WINDOW wid)
|
||||
if (window.width <= 10 || window.height <= 10)
|
||||
return {};
|
||||
|
||||
auto info = get_plaform_window_info(window);
|
||||
TRY(window.double_buffer.resize(window.width * window.height));
|
||||
for (auto& pixel : window.double_buffer)
|
||||
pixel = window.background;
|
||||
|
||||
const auto type = get_plaform_window_info(window);
|
||||
window.platform_window = TRY(g_platform_ops.create_window(
|
||||
info.parent,
|
||||
info.type,
|
||||
type,
|
||||
wid,
|
||||
window.x,
|
||||
window.y,
|
||||
@@ -584,19 +581,7 @@ static BAN::ErrorOr<void> map_window(Client& client_info, WINDOW wid)
|
||||
if (is_visible(window.parent))
|
||||
TRY(send_visibility_events_recursively(client_info, wid, true));
|
||||
|
||||
{
|
||||
xEvent event = { .u = {
|
||||
.expose = {
|
||||
.window = wid,
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = static_cast<CARD16>(window.width),
|
||||
.height = static_cast<CARD16>(window.height),
|
||||
}
|
||||
}};
|
||||
event.u.u.type = Expose;
|
||||
TRY(window.send_event(event, ExposureMask));
|
||||
}
|
||||
TRY(send_exposure_events_recursive(wid));
|
||||
|
||||
return {};
|
||||
}
|
||||
@@ -612,8 +597,8 @@ static BAN::ErrorOr<void> unmap_window(Client& client_info, WINDOW wid)
|
||||
|
||||
window.mapped = false;
|
||||
|
||||
if (window.platform_window)
|
||||
window.platform_window.clear();
|
||||
window.double_buffer.clear();
|
||||
window.platform_window.clear();
|
||||
|
||||
if (is_visible(window.parent))
|
||||
TRY(send_visibility_events_recursively(client_info, wid, false));
|
||||
@@ -765,7 +750,7 @@ void update_cursor(WINDOW wid, int32_t x, int32_t y)
|
||||
if (wid == None)
|
||||
return;
|
||||
|
||||
const CURSOR cid = [&wid]() -> CURSOR {
|
||||
const CURSOR cid = [](WINDOW wid) -> CURSOR {
|
||||
for (;;)
|
||||
{
|
||||
const auto& window = g_objects[wid]->object.get<Object::Window>();
|
||||
@@ -773,7 +758,7 @@ void update_cursor(WINDOW wid, int32_t x, int32_t y)
|
||||
return window.cursor;
|
||||
wid = window.parent;
|
||||
}
|
||||
}();
|
||||
}(wid);
|
||||
|
||||
static CURSOR active_cid = None;
|
||||
if (cid == active_cid)
|
||||
@@ -871,8 +856,8 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
|
||||
dprintln("CreateWindow");
|
||||
dprintln(" depth: {}", request.depth);
|
||||
dprintln(" wid: {}", request.wid);
|
||||
dprintln(" parent: {}", request.parent);
|
||||
dprintln(" wid: {h}", request.wid);
|
||||
dprintln(" parent: {h}", request.parent);
|
||||
dprintln(" x: {}", request.x);
|
||||
dprintln(" y: {}", request.y);
|
||||
dprintln(" width: {}", request.width);
|
||||
@@ -998,7 +983,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
auto request = decode<xChangeWindowAttributesReq>(packet).value();
|
||||
|
||||
dprintln("ChangeWindowAttributes");
|
||||
dprintln(" window: {}", request.window);
|
||||
dprintln(" window: {h}", request.window);
|
||||
dprintln(" valueMask: {8h}", request.valueMask);
|
||||
|
||||
auto& window = TRY_REF(get_window(client_info, request.window, opcode));
|
||||
@@ -1057,7 +1042,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
const CARD32 wid = packet.as_span<const uint32_t>()[1];
|
||||
|
||||
dprintln("GetWindowAttributes");
|
||||
dprintln(" window: {}", wid);
|
||||
dprintln(" window: {h}", wid);
|
||||
|
||||
const auto& window = TRY_REF(get_window(client_info, wid, opcode));
|
||||
|
||||
@@ -1094,7 +1079,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
const CARD32 wid = packet.as_span<const uint32_t>()[1];
|
||||
|
||||
dprintln("DestroyWinow");
|
||||
dprintln(" window: {}", wid);
|
||||
dprintln(" window: {h}", wid);
|
||||
|
||||
(void)TRY_REF(get_window(client_info, wid, opcode));
|
||||
TRY(destroy_window(client_info, wid));
|
||||
@@ -1106,8 +1091,8 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
auto request = decode<xReparentWindowReq>(packet).value();
|
||||
|
||||
dprintln("ReparentWinow");
|
||||
dprintln(" window: {}", request.window);
|
||||
dprintln(" parent: {}", request.parent);
|
||||
dprintln(" window: {h}", request.window);
|
||||
dprintln(" parent: {h}", request.parent);
|
||||
dprintln(" x: {}", request.x);
|
||||
dprintln(" y: {}", request.y);
|
||||
|
||||
@@ -1177,7 +1162,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
const CARD32 wid = packet.as_span<const uint32_t>()[1];
|
||||
|
||||
dprintln("MapWindow");
|
||||
dprintln(" window: {}", wid);
|
||||
dprintln(" window: {h}", wid);
|
||||
|
||||
(void)TRY_REF(get_window(client_info, wid, opcode));
|
||||
TRY(map_window(client_info, wid));
|
||||
@@ -1189,7 +1174,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
const CARD32 wid = packet.as_span<const uint32_t>()[1];
|
||||
|
||||
dprintln("MapSubwindows");
|
||||
dprintln(" window: {}", wid);
|
||||
dprintln(" window: {h}", wid);
|
||||
|
||||
const auto& window = TRY_REF(get_window(client_info, wid, opcode));
|
||||
for (auto child_wid : window.children)
|
||||
@@ -1202,7 +1187,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
const CARD32 wid = packet.as_span<const uint32_t>()[1];
|
||||
|
||||
dprintln("UnmapWindow");
|
||||
dprintln(" window: {}", wid);
|
||||
dprintln(" window: {h}", wid);
|
||||
|
||||
(void)TRY_REF(get_window(client_info, wid, opcode));
|
||||
TRY(unmap_window(client_info, wid));
|
||||
@@ -1214,7 +1199,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
const CARD32 wid = packet.as_span<const uint32_t>()[1];
|
||||
|
||||
dprintln("UnmapSubwindows");
|
||||
dprintln(" window: {}", wid);
|
||||
dprintln(" window: {h}", wid);
|
||||
|
||||
const auto& window = TRY_REF(get_window(client_info, wid, opcode));
|
||||
for (auto child_wid : window.children)
|
||||
@@ -1227,7 +1212,8 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
auto request = decode<xConfigureWindowReq>(packet).value();
|
||||
|
||||
dprintln("ConfigureWindow");
|
||||
dprintln(" window: {}", request.window);
|
||||
dprintln(" window: {h}", request.window);
|
||||
dprintln(" mask: {4h}", request.mask);
|
||||
|
||||
auto& window = TRY_REF(get_window(client_info, request.window, opcode));
|
||||
|
||||
@@ -1236,7 +1222,6 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
uint32_t new_width = window.width;
|
||||
uint32_t new_height = window.height;
|
||||
|
||||
dprintln(" mask:");
|
||||
for (size_t i = 0; i < 7; i++)
|
||||
{
|
||||
if (!(request.mask & (1 << i)))
|
||||
@@ -1248,15 +1233,19 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
{
|
||||
case 0:
|
||||
new_x = value;
|
||||
dprintln(" x: {}", value);
|
||||
break;
|
||||
case 1:
|
||||
new_y = value;
|
||||
dprintln(" y: {}", value);
|
||||
break;
|
||||
case 2:
|
||||
new_width = value;
|
||||
dprintln(" w: {}", value);
|
||||
break;
|
||||
case 3:
|
||||
new_height = value;
|
||||
dprintln(" h: {}", value);
|
||||
break;
|
||||
default:
|
||||
dprintln(" {4h}: {4h}", 1 << i, value);
|
||||
@@ -1264,7 +1253,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
}
|
||||
}
|
||||
|
||||
bool send_configure = false;
|
||||
bool should_send_configure_notify = false;
|
||||
|
||||
if (new_x != window.x || new_y != window.y)
|
||||
{
|
||||
@@ -1277,7 +1266,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
{
|
||||
window.x = new_x;
|
||||
window.y = new_y;
|
||||
send_configure = true;
|
||||
should_send_configure_notify = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1296,52 +1285,17 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
|
||||
window.width = new_width;
|
||||
window.height = new_height;
|
||||
send_configure = true;
|
||||
should_send_configure_notify = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!send_configure)
|
||||
if (!should_send_configure_notify)
|
||||
break;
|
||||
|
||||
{
|
||||
xEvent event = { .u = {
|
||||
.configureNotify = {
|
||||
.event = request.window,
|
||||
.window = request.window,
|
||||
.aboveSibling = xFalse,
|
||||
.x = static_cast<INT16>(window.x),
|
||||
.y = static_cast<INT16>(window.y),
|
||||
.width = static_cast<CARD16>(window.width),
|
||||
.height = static_cast<CARD16>(window.height),
|
||||
.borderWidth = 0,
|
||||
.override = xFalse,
|
||||
}
|
||||
}};
|
||||
event.u.u.type = ConfigureNotify;
|
||||
TRY(window.send_event(event, StructureNotifyMask));
|
||||
}
|
||||
TRY(send_configure_notify(request.window));
|
||||
|
||||
auto& parent_object = *g_objects[window.parent];
|
||||
ASSERT(parent_object.type == Object::Type::Window);
|
||||
auto& parent_window = parent_object.object.get<Object::Window>();
|
||||
|
||||
{
|
||||
xEvent event = { .u = {
|
||||
.configureNotify = {
|
||||
.event = window.parent,
|
||||
.window = request.window,
|
||||
.aboveSibling = xFalse,
|
||||
.x = static_cast<INT16>(window.x),
|
||||
.y = static_cast<INT16>(window.y),
|
||||
.width = static_cast<CARD16>(window.width),
|
||||
.height = static_cast<CARD16>(window.height),
|
||||
.borderWidth = 0,
|
||||
.override = xFalse,
|
||||
}
|
||||
}};
|
||||
event.u.u.type = ConfigureNotify;
|
||||
TRY(parent_window.send_event(event, SubstructureNotifyMask));
|
||||
}
|
||||
if (is_visible(request.window))
|
||||
TRY(send_exposure_events_recursive(request.window));
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -1350,7 +1304,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
const CARD32 drawable_id = packet.as_span<const uint32_t>()[1];
|
||||
|
||||
dprintln("GetGeometry");
|
||||
dprintln(" drawable: {}", drawable_id);
|
||||
dprintln(" drawable: {h}", drawable_id);
|
||||
|
||||
auto it = g_objects.find(drawable_id);
|
||||
if (it == g_objects.end() || (it->value->type != Object::Type::Window && it->value->type != Object::Type::Pixmap))
|
||||
@@ -1417,7 +1371,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
const auto wid = packet.as_span<const CARD32>()[1];
|
||||
|
||||
dprintln("QueryTree");
|
||||
dprintln(" window: {}", wid);
|
||||
dprintln(" window: {h}", wid);
|
||||
|
||||
const auto& window = TRY_REF(get_window(client_info, wid, opcode));
|
||||
|
||||
@@ -1501,7 +1455,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
|
||||
dprintln("ChangeProperty");
|
||||
dprintln(" mode: {}", request.mode);
|
||||
dprintln(" window: {}", request.window);
|
||||
dprintln(" window: {h}", request.window);
|
||||
dprintln(" property: {}", g_atoms_id_to_name[request.property]);
|
||||
dprintln(" type: {}", g_atoms_id_to_name[request.type]);
|
||||
dprintln(" format: {}", request.format);
|
||||
@@ -1566,7 +1520,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
auto request = decode<xDeletePropertyReq>(packet).value();
|
||||
|
||||
dprintln("DeleteProperty");
|
||||
dprintln(" window: {}", request.window);
|
||||
dprintln(" window: {h}", request.window);
|
||||
dprintln(" property: {}", g_atoms_id_to_name[request.property]);
|
||||
|
||||
auto& window = TRY_REF(get_window(client_info, request.window, opcode));
|
||||
@@ -1596,7 +1550,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
|
||||
dprintln("GetProperty");
|
||||
dprintln(" c_delete: {}", request.c_delete);
|
||||
dprintln(" window: {}", request.window);
|
||||
dprintln(" window: {h}", request.window);
|
||||
dprintln(" property: {}", g_atoms_id_to_name[request.property]);
|
||||
dprintln(" type: {}", request.type);
|
||||
dprintln(" longOffset: {}", request.longOffset);
|
||||
@@ -1679,7 +1633,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
const CARD32 wid = packet.as_span<const uint32_t>()[1];
|
||||
|
||||
dprintln("ListProperties");
|
||||
dprintln(" window: {}", wid);
|
||||
dprintln(" window: {h}", wid);
|
||||
|
||||
const auto& window = TRY_REF(get_window(client_info, wid, opcode));
|
||||
|
||||
@@ -1703,7 +1657,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
auto request = decode<xSetSelectionOwnerReq>(packet).value();
|
||||
|
||||
dprintln("SetSelectionOwner");
|
||||
dprintln(" window: {}", request.window);
|
||||
dprintln(" window: {h}", request.window);
|
||||
dprintln(" selection: {}", g_atoms_id_to_name[request.selection]);
|
||||
dprintln(" time: {}", request.time);
|
||||
|
||||
@@ -1759,7 +1713,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
auto request = decode<xConvertSelectionReq>(packet).value();
|
||||
|
||||
dprintln("ConvertSelection");
|
||||
dprintln(" requestor: {}", request.requestor);
|
||||
dprintln(" requestor: {h}", request.requestor);
|
||||
dprintln(" selection: {}", get_atom_name_safe(request.selection));
|
||||
dprintln(" target: {}", get_atom_name_safe(request.target));
|
||||
dprintln(" property: {}", get_atom_name_safe(request.property));
|
||||
@@ -1846,8 +1800,8 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
|
||||
dprintln("GrabPointer");
|
||||
dprintln(" ownerEvents: {}", request.ownerEvents);
|
||||
dprintln(" grabWindow: {}", request.grabWindow);
|
||||
dprintln(" eventMask: {}", request.eventMask);
|
||||
dprintln(" grabWindow: {h}", request.grabWindow);
|
||||
dprintln(" eventMask: {h}", request.eventMask);
|
||||
dprintln(" pointerMode: {}", request.pointerMode);
|
||||
dprintln(" keyboardMode: {}", request.keyboardMode);
|
||||
dprintln(" confineTo: {}", request.confineTo);
|
||||
@@ -1913,7 +1867,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
|
||||
dprintln("GrabKeyboard");
|
||||
dprintln(" ownerEvents: {}", request.ownerEvents);
|
||||
dprintln(" grabWindow: {}", request.grabWindow);
|
||||
dprintln(" grabWindow: {h}", request.grabWindow);
|
||||
dprintln(" pointerMode: {}", request.pointerMode);
|
||||
dprintln(" keyboardMode: {}", request.keyboardMode);
|
||||
dprintln(" time: {}", request.time);
|
||||
@@ -1988,7 +1942,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
const CARD32 wid = packet.as_span<const uint32_t>()[1];
|
||||
|
||||
dprintln("QueryPointer");
|
||||
dprintln(" window: {}", wid);
|
||||
dprintln(" window: {h}", wid);
|
||||
|
||||
const auto& window = TRY_REF(get_window(client_info, wid, opcode));
|
||||
|
||||
@@ -2035,8 +1989,8 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
auto request = decode<xTranslateCoordsReq>(packet).value();
|
||||
|
||||
dprintln("TranslateCoords");
|
||||
dprintln(" src_wid: {}", request.srcWid);
|
||||
dprintln(" dst_wid: {}", request.dstWid);
|
||||
dprintln(" src_wid: {h}", request.srcWid);
|
||||
dprintln(" dst_wid: {h}", request.dstWid);
|
||||
dprintln(" src_x: {}", request.srcX);
|
||||
dprintln(" src_y: {}", request.srcY);
|
||||
|
||||
@@ -2064,12 +2018,12 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
auto request = decode<xWarpPointerReq>(packet).value();
|
||||
|
||||
dprintln("WarpPointer");
|
||||
dprintln(" src_wid: {}", request.srcWid);
|
||||
dprintln(" src_wid: {h}", request.srcWid);
|
||||
dprintln(" src_x: {}", request.srcX);
|
||||
dprintln(" src_y: {}", request.srcY);
|
||||
dprintln(" src_w: {}", request.srcWidth);
|
||||
dprintln(" src_h: {}", request.srcHeight);
|
||||
dprintln(" dst_wid: {}", request.dstWid);
|
||||
dprintln(" dst_wid: {h}", request.dstWid);
|
||||
dprintln(" dst_x: {}", request.dstX);
|
||||
dprintln(" dst_y: {}", request.dstY);
|
||||
|
||||
@@ -2139,8 +2093,8 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
|
||||
dprintln("CreatePixmap");
|
||||
dprintln(" depth: {}", request.depth);
|
||||
dprintln(" pid: {}", request.pid);
|
||||
dprintln(" drawable: {}", request.drawable);
|
||||
dprintln(" pid: {h}", request.pid);
|
||||
dprintln(" drawable: {h}", request.drawable);
|
||||
dprintln(" width: {}", request.width);
|
||||
dprintln(" height: {}", request.height);
|
||||
|
||||
@@ -2174,7 +2128,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
const CARD32 pid = packet.as_span<const uint32_t>()[1];
|
||||
|
||||
dprintln("FreePixmap");
|
||||
dprintln(" pixmap: {}", pid);
|
||||
dprintln(" pixmap: {h}", pid);
|
||||
|
||||
(void)TRY_REF(get_pixmap(client_info, pid, opcode));
|
||||
client_info.objects.remove(pid);
|
||||
@@ -2187,14 +2141,14 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
auto request = decode<xCreateGCReq>(packet).value();
|
||||
|
||||
dprintln("CreateGC");
|
||||
dprintln(" drawable {}", request.drawable);
|
||||
dprintln(" drawable {h}", request.drawable);
|
||||
dprintln(" gc {}", request.gc);
|
||||
dprintln(" mask {8h}", request.mask);
|
||||
|
||||
// TODO: support invisible background
|
||||
|
||||
uint32_t foreground = 0x000000;
|
||||
uint32_t background = 0x000000;
|
||||
uint32_t background = 0xFFFFFF;
|
||||
uint16_t line_width = 0;
|
||||
uint32_t font = None;
|
||||
bool graphics_exposures = true;
|
||||
@@ -2269,7 +2223,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
auto request = decode<xChangeGCReq>(packet).value();
|
||||
|
||||
dprintln("ChangeGC");
|
||||
dprintln(" gc: {}", request.gc);
|
||||
dprintln(" gc: {h}", request.gc);
|
||||
dprintln(" mask: {8h}", request.mask);
|
||||
|
||||
auto& object = *g_objects[request.gc];
|
||||
@@ -2333,7 +2287,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
auto request = decode<xSetClipRectanglesReq>(packet).value();
|
||||
|
||||
dprintln("SetClipRectangles");
|
||||
dprintln(" gc: {}", request.gc);
|
||||
dprintln(" gc: {h}", request.gc);
|
||||
dprintln(" ordering: {}", request.ordering);
|
||||
dprintln(" xOrigin: {}", request.xOrigin);
|
||||
dprintln(" yOrigin: {}", request.yOrigin);
|
||||
@@ -2361,7 +2315,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
const CARD32 gc = packet.as_span<const uint32_t>()[1];
|
||||
|
||||
dprintln("FreeGC");
|
||||
dprintln(" gc: {}", gc);
|
||||
dprintln(" gc: {h}", gc);
|
||||
|
||||
(void)TRY_REF(get_gc(client_info, gc, opcode));
|
||||
client_info.objects.remove(gc);
|
||||
@@ -2375,7 +2329,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
|
||||
dprintln("ClearArea");
|
||||
dprintln(" exposures: {}", request.exposures);
|
||||
dprintln(" window: {}", request.window);
|
||||
dprintln(" window: {h}", request.window);
|
||||
dprintln(" x: {}", request.x);
|
||||
dprintln(" y: {}", request.y);
|
||||
dprintln(" width: {}", request.width);
|
||||
@@ -2409,9 +2363,9 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
auto request = decode<xCopyAreaReq>(packet).value();
|
||||
|
||||
dprintln("CopyArea");
|
||||
dprintln(" srcDrawable: {}", request.srcDrawable);
|
||||
dprintln(" dstDrawable: {}", request.dstDrawable);
|
||||
dprintln(" gc: {}", request.gc);
|
||||
dprintln(" srcDrawable: {h}", request.srcDrawable);
|
||||
dprintln(" dstDrawable: {h}", request.dstDrawable);
|
||||
dprintln(" gc: {h}", request.gc);
|
||||
dprintln(" srcX: {}", request.srcX);
|
||||
dprintln(" srcY: {}", request.srcY);
|
||||
dprintln(" dstX: {}", request.dstX);
|
||||
@@ -2504,8 +2458,8 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
auto request = decode<xPutImageReq>(packet).value();
|
||||
|
||||
dprintln("PutImage");
|
||||
dprintln(" drawable: {}", request.drawable);
|
||||
dprintln(" gc: {}", request.gc);
|
||||
dprintln(" drawable: {h}", request.drawable);
|
||||
dprintln(" gc: {h}", request.gc);
|
||||
dprintln(" format: {}", request.format);
|
||||
dprintln(" depth: {}", request.depth);
|
||||
dprintln(" dstX: {}", request.dstX);
|
||||
@@ -2553,7 +2507,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
auto request = decode<xGetImageReq>(packet).value();
|
||||
|
||||
dprintln("GetImage");
|
||||
dprintln(" drawable: {}", request.drawable);
|
||||
dprintln(" drawable: {h}", request.drawable);
|
||||
dprintln(" format: {}", request.format);
|
||||
dprintln(" x: {}", request.x);
|
||||
dprintln(" y: {}", request.y);
|
||||
@@ -2724,7 +2678,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
auto request = decode<xCreateCursorReq>(packet).value();
|
||||
|
||||
dprintln("CreateCursor");
|
||||
dprintln(" cid: {}", request.cid);
|
||||
dprintln(" cid: {h}", request.cid);
|
||||
dprintln(" source: {}", request.source);
|
||||
dprintln(" mask: {}", request.mask);
|
||||
dprintln(" foreRed: {}", request.foreRed);
|
||||
@@ -2795,7 +2749,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
const auto cid = packet.as_span<const uint32_t>()[1];
|
||||
|
||||
dprintln("FreeCursor");
|
||||
dprintln(" cid: {}", cid);
|
||||
dprintln(" cid: {h}", cid);
|
||||
|
||||
client_info.objects.remove(cid);
|
||||
g_objects.remove(cid);
|
||||
@@ -2808,7 +2762,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
|
||||
dprintln("QueryBestSize");
|
||||
dprintln(" class: {}", request.c_class);
|
||||
dprintln(" drawable: {}", request.drawable);
|
||||
dprintln(" drawable: {h}", request.drawable);
|
||||
dprintln(" width: {}", request.width);
|
||||
dprintln(" height: {}", request.height);
|
||||
|
||||
|
||||
@@ -6,7 +6,9 @@ BAN::ErrorOr<void> setup_client_conneciton(Client& client_info, const xConnClien
|
||||
BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet);
|
||||
|
||||
void invalidate_window(WINDOW wid, int32_t x, int32_t y, int32_t w, int32_t h);
|
||||
void send_exposure_recursive(WINDOW wid);
|
||||
|
||||
BAN::ErrorOr<void> send_configure_notify(WINDOW wid);
|
||||
BAN::ErrorOr<void> send_exposure_events_recursive(WINDOW wid);
|
||||
|
||||
void update_cursor(WINDOW wid, int32_t x, int32_t y);
|
||||
|
||||
@@ -16,7 +18,8 @@ WINDOW find_child_window(WINDOW wid, int32_t& x, int32_t& y);
|
||||
|
||||
xPoint get_window_position(WINDOW wid);
|
||||
|
||||
static constexpr uint32_t COLOR_INVISIBLE = 0x69000000;
|
||||
// random number with alpha 0 :D
|
||||
static constexpr uint32_t COLOR_INVISIBLE = 0x00b205AF;
|
||||
|
||||
extern CARD16 g_keymask;
|
||||
extern CARD16 g_butmask;
|
||||
|
||||
@@ -66,8 +66,11 @@ struct Object
|
||||
|
||||
uint32_t background { 0 };
|
||||
|
||||
bool platform_window_invalidated { false };
|
||||
BAN::UniqPtr<PlatformWindow> platform_window;
|
||||
|
||||
BAN::Vector<uint32_t> double_buffer;
|
||||
|
||||
BAN::HashMap<Client*, uint32_t> event_masks;
|
||||
|
||||
BAN::HashMap<ATOM, Property> properties;
|
||||
|
||||
@@ -107,7 +107,7 @@ BAN::ErrorOr<void> poly_line(Client& client_info, BAN::ConstByteSpan packet)
|
||||
auto request = decode<xPolyLineReq>(packet).value();
|
||||
|
||||
dprintln("PolyLine");
|
||||
dprintln(" drawable: {}", request.drawable);
|
||||
dprintln(" drawable: {h}", request.drawable);
|
||||
dprintln(" gc: {}", request.gc);
|
||||
dprintln(" coordMode: {}", request.coordMode);
|
||||
|
||||
@@ -161,7 +161,7 @@ BAN::ErrorOr<void> poly_segment(Client& client_info, BAN::ConstByteSpan packet)
|
||||
auto request = decode<xPolySegmentReq>(packet).value();
|
||||
|
||||
dprintln("PolySegment");
|
||||
dprintln(" drawable: {}", request.drawable);
|
||||
dprintln(" drawable: {h}", request.drawable);
|
||||
dprintln(" gc: {}", request.gc);
|
||||
|
||||
auto [out_data_u32, out_w, out_h, _] = TRY(get_drawable_info(client_info, request.drawable, X_PolySegment));
|
||||
@@ -203,7 +203,7 @@ BAN::ErrorOr<void> fill_poly(Client& client_info, BAN::ConstByteSpan packet)
|
||||
auto request = decode<xFillPolyReq>(packet).value();
|
||||
|
||||
dprintln("FillPoly");
|
||||
dprintln(" drawable: {}", request.drawable);
|
||||
dprintln(" drawable: {h}", request.drawable);
|
||||
dprintln(" gc: {}", request.gc);
|
||||
dprintln(" shape: {}", request.shape);
|
||||
dprintln(" coordMode: {}", request.coordMode);
|
||||
@@ -278,7 +278,7 @@ BAN::ErrorOr<void> poly_fill_rectangle(Client& client_info, BAN::ConstByteSpan p
|
||||
auto request = decode<xPolyFillRectangleReq>(packet).value();
|
||||
|
||||
dprintln("PolyFillRectangle");
|
||||
dprintln(" drawable: {}", request.drawable);
|
||||
dprintln(" drawable: {h}", request.drawable);
|
||||
dprintln(" gc: {}", request.gc);
|
||||
|
||||
auto [out_data_u32, out_w, out_h, _] = TRY(get_drawable_info(client_info, request.drawable, X_PolyFillRectangle));
|
||||
@@ -320,7 +320,7 @@ BAN::ErrorOr<void> poly_fill_arc(Client& client_info, BAN::ConstByteSpan packet)
|
||||
auto request = decode<xPolyFillArcReq>(packet).value();
|
||||
|
||||
dprintln("PolyFillArc");
|
||||
dprintln(" drawable: {}", request.drawable);
|
||||
dprintln(" drawable: {h}", request.drawable);
|
||||
dprintln(" gc: {}", request.gc);
|
||||
|
||||
auto [out_data_32, out_w, out_h, _] = TRY(get_drawable_info(client_info, request.drawable, X_PolyFillArc));
|
||||
|
||||
@@ -75,69 +75,26 @@ void on_window_close_event(WINDOW wid)
|
||||
}
|
||||
}
|
||||
|
||||
static void send_window_configure(WINDOW wid, Object::Window& window)
|
||||
{
|
||||
{
|
||||
xEvent event = { .u = {
|
||||
.configureNotify = {
|
||||
.event = wid,
|
||||
.window = wid,
|
||||
.aboveSibling = xFalse,
|
||||
.x = static_cast<INT16>(window.x),
|
||||
.y = static_cast<INT16>(window.y),
|
||||
.width = static_cast<CARD16>(window.width),
|
||||
.height = static_cast<CARD16>(window.height),
|
||||
.borderWidth = 0,
|
||||
.override = xFalse,
|
||||
}
|
||||
}};
|
||||
event.u.u.type = ConfigureNotify;
|
||||
MUST(window.send_event(event, StructureNotifyMask));
|
||||
}
|
||||
|
||||
auto& parent_object = *g_objects[window.parent];
|
||||
ASSERT(parent_object.type == Object::Type::Window);
|
||||
auto& parent_window = parent_object.object.get<Object::Window>();
|
||||
|
||||
{
|
||||
xEvent event = { .u = {
|
||||
.configureNotify = {
|
||||
.event = window.parent,
|
||||
.window = wid,
|
||||
.aboveSibling = xFalse,
|
||||
.x = static_cast<INT16>(window.x),
|
||||
.y = static_cast<INT16>(window.y),
|
||||
.width = static_cast<CARD16>(window.width),
|
||||
.height = static_cast<CARD16>(window.height),
|
||||
.borderWidth = 0,
|
||||
.override = xFalse,
|
||||
}
|
||||
}};
|
||||
event.u.u.type = ConfigureNotify;
|
||||
MUST(parent_window.send_event(event, SubstructureNotifyMask));
|
||||
}
|
||||
}
|
||||
|
||||
void on_window_resize_event(WINDOW wid, uint32_t new_width, uint32_t new_height)
|
||||
{
|
||||
auto& object = *g_objects[wid];
|
||||
ASSERT(object.type == Object::Type::Window);
|
||||
auto& window = object.object.get<Object::Window>();
|
||||
|
||||
{
|
||||
window.width = new_width;
|
||||
window.height = new_height;
|
||||
window.width = new_width;
|
||||
window.height = new_height;
|
||||
|
||||
MUST(window.pixels.resize(new_width * new_height));
|
||||
for (auto& pixel : window.pixels)
|
||||
pixel = window.background;
|
||||
}
|
||||
MUST(window.pixels.resize(new_width * new_height));
|
||||
for (auto& pixel : window.pixels)
|
||||
pixel = window.background;
|
||||
|
||||
send_window_configure(wid, window);
|
||||
MUST(window.double_buffer.resize(new_width * new_height));
|
||||
for (auto& pixel : window.double_buffer)
|
||||
pixel = window.background;
|
||||
|
||||
send_exposure_recursive(wid);
|
||||
MUST(send_configure_notify(wid));
|
||||
|
||||
invalidate_window(wid, 0, 0, window.width, window.height);
|
||||
MUST(send_exposure_events_recursive(wid));
|
||||
}
|
||||
|
||||
void on_window_move_event(WINDOW wid, int32_t x, int32_t y)
|
||||
@@ -149,7 +106,7 @@ void on_window_move_event(WINDOW wid, int32_t x, int32_t y)
|
||||
window.x = x;
|
||||
window.y = y;
|
||||
|
||||
send_window_configure(wid, window);
|
||||
MUST(send_configure_notify(wid));
|
||||
}
|
||||
|
||||
void on_window_focus_event(WINDOW wid, bool focused)
|
||||
|
||||
@@ -51,9 +51,14 @@ struct PlatformOps
|
||||
/* Handle pending events */
|
||||
void (*poll_events)(void*);
|
||||
/* Create a window with given size */
|
||||
BAN::ErrorOr<BAN::UniqPtr<PlatformWindow>> (*create_window)(PlatformWindow* parent, WindowType, WINDOW wid, int32_t x, int32_t y, uint32_t width, uint32_t height);
|
||||
/* Invaldate part of a window */
|
||||
void (*invalidate)(PlatformWindow*, const uint32_t* pixels, uint32_t x, uint32_t y, uint32_t width, uint32_t height);
|
||||
BAN::ErrorOr<BAN::UniqPtr<PlatformWindow>> (*create_window)(WindowType, WINDOW wid, int32_t x, int32_t y, uint32_t width, uint32_t height);
|
||||
/* All invalidate calls during one frame happen between calls to begin_frame and end_frame. pixels is in ARGB8888
|
||||
* invalidate should update the underlying textures
|
||||
* begin_frame should do any necessary preparations to update a frame
|
||||
* end_frame should flush the updated texturee to the window */
|
||||
void (*invalidate)(PlatformWindow*, const void* pixels, uint32_t pitch, uint32_t x, uint32_t y, uint32_t width, uint32_t height);
|
||||
void (*begin_frame)(PlatformWindow*);
|
||||
void (*end_frame)(PlatformWindow*);
|
||||
/* Request resize of a window, can be async */
|
||||
void (*request_resize)(PlatformWindow*, uint32_t width, uint32_t height);
|
||||
/* Request window repositioning */
|
||||
|
||||
@@ -108,7 +108,7 @@ static bool sdl3_initialize()
|
||||
return true;
|
||||
}
|
||||
|
||||
static BAN::ErrorOr<BAN::UniqPtr<PlatformWindow>> sdl3_create_window(PlatformWindow* parent, WindowType type, WINDOW wid, int32_t x, int32_t y, uint32_t width, uint32_t height)
|
||||
static BAN::ErrorOr<BAN::UniqPtr<PlatformWindow>> sdl3_create_window(WindowType type, WINDOW wid, int32_t x, int32_t y, uint32_t width, uint32_t height)
|
||||
{
|
||||
auto window = TRY(BAN::UniqPtr<SDLWindow>::create());
|
||||
|
||||
@@ -120,29 +120,19 @@ static BAN::ErrorOr<BAN::UniqPtr<PlatformWindow>> sdl3_create_window(PlatformWin
|
||||
switch (type)
|
||||
{
|
||||
case WindowType::Normal:
|
||||
case WindowType::Utility:
|
||||
flags = SDL_WINDOW_RESIZABLE;
|
||||
break;
|
||||
case WindowType::Utility:
|
||||
flags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_UTILITY;
|
||||
break;
|
||||
case WindowType::Popup:
|
||||
flags = SDL_WINDOW_BORDERLESS;
|
||||
flags = SDL_WINDOW_BORDERLESS | SDL_WINDOW_UTILITY;
|
||||
break;
|
||||
}
|
||||
|
||||
if (parent == nullptr || type != WindowType::Popup)
|
||||
{
|
||||
if (type != WindowType::Normal)
|
||||
flags |= SDL_WINDOW_UTILITY;
|
||||
window->window = SDL_CreateWindow("", width, height, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto& sdl_parent = *static_cast<SDLWindow*>(parent);
|
||||
flags |= SDL_WINDOW_TRANSPARENT;
|
||||
|
||||
int parent_x, parent_y;
|
||||
SDL_GetWindowPosition(sdl_parent.window, &parent_x, &parent_y);
|
||||
|
||||
window->window = SDL_CreatePopupWindow(sdl_parent.window, x - parent_x, y - parent_y, width, height, flags | SDL_WINDOW_POPUP_MENU);
|
||||
}
|
||||
window->window = SDL_CreateWindow("", width, height, flags);
|
||||
|
||||
if (window->window == nullptr)
|
||||
{
|
||||
@@ -150,6 +140,9 @@ static BAN::ErrorOr<BAN::UniqPtr<PlatformWindow>> sdl3_create_window(PlatformWin
|
||||
return BAN::Error::from_errno(EFAULT);
|
||||
}
|
||||
|
||||
if (x != 0 || y != 0)
|
||||
SDL_SetWindowPosition(window->window, x, y);
|
||||
|
||||
window->renderer = SDL_CreateRenderer(window->window, nullptr);
|
||||
if (window->renderer == nullptr)
|
||||
{
|
||||
@@ -157,6 +150,8 @@ static BAN::ErrorOr<BAN::UniqPtr<PlatformWindow>> sdl3_create_window(PlatformWin
|
||||
return BAN::Error::from_errno(EFAULT);
|
||||
}
|
||||
|
||||
SDL_SetRenderDrawColor(window->renderer, 0, 0, 0, 0);
|
||||
|
||||
window->texture = SDL_CreateTexture(window->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, width, height);
|
||||
if (window->texture == nullptr)
|
||||
{
|
||||
@@ -292,7 +287,7 @@ static void sdl3_poll_events(void*)
|
||||
}
|
||||
}
|
||||
|
||||
static void sdl3_invalidate(PlatformWindow* window, const uint32_t* src_pixels, uint32_t x, uint32_t y, uint32_t width, uint32_t height)
|
||||
static void sdl3_invalidate(PlatformWindow* window, const void* src_pixels, uint32_t src_pitch, uint32_t x, uint32_t y, uint32_t width, uint32_t height)
|
||||
{
|
||||
auto& sdl_window = *static_cast<SDLWindow*>(window);
|
||||
|
||||
@@ -317,16 +312,20 @@ static void sdl3_invalidate(PlatformWindow* window, const uint32_t* src_pixels,
|
||||
for (int32_t y_off = 0; y_off < rect.h; y_off++)
|
||||
{
|
||||
memcpy(
|
||||
static_cast<uint8_t*>(dst_pixels) + y_off * dst_pitch,
|
||||
&src_pixels[(rect.y + y_off) * sdl_window.width + rect.x],
|
||||
static_cast< uint8_t*>(dst_pixels) + y_off * dst_pitch,
|
||||
static_cast<const uint8_t*>(src_pixels) + y_off * src_pitch,
|
||||
rect.w * sizeof(uint32_t)
|
||||
);
|
||||
}
|
||||
|
||||
SDL_UnlockTexture(sdl_window.texture);
|
||||
}
|
||||
|
||||
static void sdl3_end_frame(PlatformWindow* window)
|
||||
{
|
||||
auto& sdl_window = *static_cast<SDLWindow*>(window);
|
||||
SDL_RenderClear(sdl_window.renderer);
|
||||
SDL_RenderTexture(sdl_window.renderer, sdl_window.texture, NULL, NULL);
|
||||
SDL_RenderTexture(sdl_window.renderer, sdl_window.texture, nullptr, nullptr);
|
||||
SDL_RenderPresent(sdl_window.renderer);
|
||||
}
|
||||
|
||||
@@ -439,6 +438,8 @@ PlatformOps g_platform_ops = {
|
||||
.poll_events = sdl3_poll_events,
|
||||
.create_window = sdl3_create_window,
|
||||
.invalidate = sdl3_invalidate,
|
||||
.begin_frame = nullptr,
|
||||
.end_frame = sdl3_end_frame,
|
||||
.request_resize = sdl3_request_resize,
|
||||
.request_reposition = sdl3_request_reposition,
|
||||
.request_fullscreen = sdl3_request_fullscreen,
|
||||
@@ -506,9 +507,9 @@ static uint32_t sdl3_keycode_to_x_keysym(SDL_Keycode keycode)
|
||||
{
|
||||
if (iswprint(keycode))
|
||||
{
|
||||
if ((keycode >= 0x20 && keycode <= 0x7E) || (keycode >= 0xA0 && keycode <= 0xFF))
|
||||
return keycode;
|
||||
return 0x01000000 | keycode;
|
||||
if (keycode >= 0x100)
|
||||
keycode |= 0x01000000;
|
||||
return keycode;
|
||||
}
|
||||
|
||||
switch (keycode)
|
||||
|
||||
@@ -26,6 +26,8 @@ struct BananCursor final : public PlatformCursor
|
||||
int32_t origin_y;
|
||||
};
|
||||
|
||||
static BAN::UniqPtr<LibGUI::Window> s_dummy_window;
|
||||
|
||||
static BAN::ErrorOr<void> bananos_initialize_keymap();
|
||||
|
||||
static bool bananos_initialize()
|
||||
@@ -40,7 +42,9 @@ static bool bananos_initialize()
|
||||
return false;
|
||||
}
|
||||
|
||||
register_display(0, 0, dummy_or_error.value()->width(), dummy_or_error.value()->height());
|
||||
s_dummy_window = dummy_or_error.release_value();
|
||||
|
||||
register_display(0, 0, s_dummy_window->width(), s_dummy_window->height());
|
||||
|
||||
if (auto ret = bananos_initialize_keymap(); ret.is_error())
|
||||
{
|
||||
@@ -57,12 +61,9 @@ static void bananos_poll_events(void* window)
|
||||
banan_window.window->poll_events();
|
||||
}
|
||||
|
||||
static BAN::ErrorOr<BAN::UniqPtr<PlatformWindow>> bananos_create_window(PlatformWindow* parent, WindowType type, WINDOW wid, int32_t x, int32_t y, uint32_t width, uint32_t height)
|
||||
static BAN::ErrorOr<BAN::UniqPtr<PlatformWindow>> bananos_create_window(WindowType type, WINDOW wid, int32_t x, int32_t y, uint32_t width, uint32_t height)
|
||||
{
|
||||
(void)parent;
|
||||
(void)type;
|
||||
(void)x;
|
||||
(void)y;
|
||||
|
||||
auto window = TRY(BAN::UniqPtr<BananWindow>::create());
|
||||
|
||||
@@ -70,10 +71,14 @@ static BAN::ErrorOr<BAN::UniqPtr<PlatformWindow>> bananos_create_window(Platform
|
||||
attributes.shown = true;
|
||||
attributes.title_bar = false;
|
||||
attributes.resizable = true;
|
||||
attributes.alpha_channel = true;
|
||||
|
||||
auto gui_window = TRY(LibGUI::Window::create(width, height, ""_sv, attributes));
|
||||
auto* winp = gui_window.ptr();
|
||||
|
||||
if (x != 0 || y != 0)
|
||||
gui_window->set_position(x, y);
|
||||
|
||||
gui_window->set_close_window_event_callback([wid] {
|
||||
on_window_close_event(wid);
|
||||
});
|
||||
@@ -86,6 +91,9 @@ static BAN::ErrorOr<BAN::UniqPtr<PlatformWindow>> bananos_create_window(Platform
|
||||
gui_window->set_window_fullscreen_event_callback([wid](auto event) {
|
||||
on_window_fullscreen_event(wid, event.fullscreen);
|
||||
});
|
||||
gui_window->set_window_move_event_callback([wid](auto event) {
|
||||
on_window_move_event(wid, event.x, event.y);
|
||||
});
|
||||
gui_window->set_mouse_move_event_callback([wid](auto event) {
|
||||
on_mouse_move_event(wid, event.x, event.y);
|
||||
});
|
||||
@@ -132,18 +140,34 @@ static void bananos_request_resize(PlatformWindow* window, uint32_t width, uint3
|
||||
banan_window.window->request_resize(width, height);
|
||||
}
|
||||
|
||||
static void bananos_invalidate(PlatformWindow* window, const uint32_t* pixels, uint32_t x, uint32_t y, uint32_t width, uint32_t height)
|
||||
static void bananos_request_reposition(PlatformWindow* window, int32_t x, int32_t y)
|
||||
{
|
||||
auto& banan_window = *static_cast<BananWindow*>(window);
|
||||
banan_window.window->set_position(x, y);
|
||||
}
|
||||
|
||||
static void bananos_invalidate(PlatformWindow* window, const void* src_pixels, uint32_t src_pitch, uint32_t x, uint32_t y, uint32_t width, uint32_t height)
|
||||
{
|
||||
auto& banan_window = *static_cast<BananWindow*>(window);
|
||||
|
||||
const uint32_t win_width = banan_window.window->width();
|
||||
auto& texture = banan_window.window->texture();
|
||||
void* dst_pixels = &texture.pixels()[y * texture.width() + x];
|
||||
const uint32_t dst_pitch = texture.width() * sizeof(uint32_t);
|
||||
|
||||
auto* out_pixels = banan_window.window->texture().pixels().data();
|
||||
for (uint32_t y_off = 0; y_off < height; y_off++)
|
||||
for (uint32_t x_off = 0; x_off < width; x_off++)
|
||||
out_pixels[(y + y_off) * win_width + (x + x_off)] = pixels[(y + y_off) * win_width + (x + x_off)];
|
||||
{
|
||||
memcpy(
|
||||
static_cast< uint8_t*>(dst_pixels) + y_off * dst_pitch,
|
||||
static_cast<const uint8_t*>(src_pixels) + y_off * src_pitch,
|
||||
width * sizeof(uint32_t)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
banan_window.window->invalidate(x, y, width, height);
|
||||
static void bananos_end_frame(PlatformWindow* window)
|
||||
{
|
||||
auto& banan_window = *static_cast<BananWindow*>(window);
|
||||
banan_window.window->invalidate();
|
||||
}
|
||||
|
||||
static void bananos_request_fullscreen(PlatformWindow* window, bool fullscreen)
|
||||
@@ -152,6 +176,26 @@ static void bananos_request_fullscreen(PlatformWindow* window, bool fullscreen)
|
||||
banan_window.window->set_fullscreen(fullscreen);
|
||||
}
|
||||
|
||||
static void bananos_query_ponter(int32_t* x, int32_t* y)
|
||||
{
|
||||
s_dummy_window->query_cursor_position();
|
||||
|
||||
bool queried { false };
|
||||
s_dummy_window->set_query_pointer_event_callback([&](auto event) {
|
||||
*x = event.x;
|
||||
*y = event.y;
|
||||
queried = true;
|
||||
});
|
||||
|
||||
while (!queried)
|
||||
{
|
||||
s_dummy_window->wait_events();
|
||||
s_dummy_window->poll_events();
|
||||
}
|
||||
|
||||
s_dummy_window->set_query_pointer_event_callback({});
|
||||
}
|
||||
|
||||
static BAN::ErrorOr<BAN::UniqPtr<PlatformCursor>> bananos_create_bitmap_cursor(const uint32_t* pixels, uint32_t width, uint32_t height, int32_t origin_x, int32_t origin_y)
|
||||
{
|
||||
auto cursor = TRY(BAN::UniqPtr<BananCursor>::create());
|
||||
@@ -186,11 +230,13 @@ PlatformOps g_platform_ops = {
|
||||
.poll_events = bananos_poll_events,
|
||||
.create_window = bananos_create_window,
|
||||
.invalidate = bananos_invalidate,
|
||||
.begin_frame = nullptr,
|
||||
.end_frame = bananos_end_frame,
|
||||
.request_resize = bananos_request_resize,
|
||||
.request_reposition = nullptr,
|
||||
.request_reposition = bananos_request_reposition,
|
||||
.request_fullscreen = bananos_request_fullscreen,
|
||||
.warp_pointer = nullptr,
|
||||
.query_pointer = nullptr,
|
||||
.query_pointer = bananos_query_ponter,
|
||||
.set_pointer_grab = nullptr,
|
||||
.create_system_cursor = nullptr,
|
||||
.create_bitmap_cursor = bananos_create_bitmap_cursor,
|
||||
@@ -298,9 +344,10 @@ static uint32_t bananos_keyevent_to_x_keysym(LibInput::KeyEvent event)
|
||||
case Key::CapsLock: return XK_Caps_Lock;
|
||||
case Key::LeftShift: return XK_Shift_L;
|
||||
case Key::LeftCtrl: return XK_Control_L;
|
||||
case Key::Super: return XK_Super_L;
|
||||
case Key::LeftSuper: return XK_Super_L;
|
||||
case Key::LeftAlt: return XK_Alt_L;
|
||||
case Key::RightAlt: return XK_Alt_R;
|
||||
case Key::RightSuper: return XK_Super_R;
|
||||
case Key::RightCtrl: return XK_Control_R;
|
||||
case Key::RightShift: return XK_Shift_R;
|
||||
case Key::ArrowUp: return XK_Up;
|
||||
@@ -333,10 +380,11 @@ static uint32_t bananos_keyevent_to_x_keysym(LibInput::KeyEvent event)
|
||||
case Key::MediaStop: return XF86XK_AudioStop;
|
||||
case Key::MediaPrevious: return XF86XK_AudioPrev;
|
||||
case Key::MediaNext: return XF86XK_AudioNext;
|
||||
case Key::Application: return XF86XK_ApplicationRight;
|
||||
default: break;
|
||||
}
|
||||
|
||||
static_assert(static_cast<size_t>(Key::Count) == 145, "update keymap");
|
||||
static_assert(static_cast<size_t>(Key::Count) == 147, "update keymap");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -629,6 +629,18 @@ int main()
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& [_, object] : g_objects)
|
||||
{
|
||||
if (object->type != Object::Type::Window)
|
||||
continue;
|
||||
auto& window = object->object.get<Object::Window>();
|
||||
if (!window.platform_window_invalidated)
|
||||
continue;
|
||||
if (g_platform_ops.end_frame)
|
||||
g_platform_ops.end_frame(window.platform_window.ptr());
|
||||
window.platform_window_invalidated = false;
|
||||
}
|
||||
|
||||
iterator_invalidated:
|
||||
for (auto& [_, thingy] : g_epoll_thingies)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user