WindowServer: Add support for background images
WindowServer now looks in _$HOME/.config/WindowServer.conf_ for a configuration file that can specify a background image. Also add default background image /usr/share/images/sample.ppm to the base sysroot provided in the git repo.
This commit is contained in:
parent
14d4551476
commit
dd64e2060e
Binary file not shown.
|
@ -11,7 +11,7 @@ set(SOURCES
|
||||||
|
|
||||||
add_executable(WindowServer ${SOURCES})
|
add_executable(WindowServer ${SOURCES})
|
||||||
target_compile_options(WindowServer PUBLIC -O2 -g)
|
target_compile_options(WindowServer PUBLIC -O2 -g)
|
||||||
target_link_libraries(WindowServer PUBLIC libc ban libfont libgui libinput)
|
target_link_libraries(WindowServer PUBLIC libc ban libfont libgui libimage libinput)
|
||||||
|
|
||||||
add_custom_target(WindowServer-install
|
add_custom_target(WindowServer-install
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/WindowServer ${BANAN_BIN}/
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/WindowServer ${BANAN_BIN}/
|
||||||
|
|
|
@ -11,6 +11,15 @@
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
BAN::ErrorOr<void> WindowServer::set_background_image(BAN::UniqPtr<LibImage::Image> image)
|
||||||
|
{
|
||||||
|
if (image->width() != (uint64_t)m_framebuffer.width || image->height() != (uint64_t)m_framebuffer.height)
|
||||||
|
image = TRY(image->resize(m_framebuffer.width, m_framebuffer.height));
|
||||||
|
m_background_image = BAN::move(image);
|
||||||
|
invalidate(m_framebuffer.area());
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
void WindowServer::on_window_packet(int fd, LibGUI::WindowPacket packet)
|
void WindowServer::on_window_packet(int fd, LibGUI::WindowPacket packet)
|
||||||
{
|
{
|
||||||
switch (packet.type)
|
switch (packet.type)
|
||||||
|
@ -270,8 +279,19 @@ void WindowServer::invalidate(Rectangle area)
|
||||||
return;
|
return;
|
||||||
area = fb_overlap.release_value();
|
area = fb_overlap.release_value();
|
||||||
|
|
||||||
|
if (m_background_image)
|
||||||
|
{
|
||||||
|
ASSERT(m_background_image->width() == (uint64_t)m_framebuffer.width);
|
||||||
|
ASSERT(m_background_image->height() == (uint64_t)m_framebuffer.height);
|
||||||
|
for (int32_t y = area.y; y < area.y + area.height; y++)
|
||||||
|
for (int32_t x = area.x; x < area.x + area.width; x++)
|
||||||
|
m_framebuffer.mmap[y * m_framebuffer.width + x] = m_background_image->get_color(x, y).as_rgba();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
for (int32_t y = area.y; y < area.y + area.height; y++)
|
for (int32_t y = area.y; y < area.y + area.height; y++)
|
||||||
memset(&m_framebuffer.mmap[y * m_framebuffer.width + area.x], 0x10, area.width * 4);
|
memset(&m_framebuffer.mmap[y * m_framebuffer.width + area.x], 0x10, area.width * 4);
|
||||||
|
}
|
||||||
|
|
||||||
for (auto& pwindow : m_client_windows)
|
for (auto& pwindow : m_client_windows)
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include <LibFont/Font.h>
|
#include <LibFont/Font.h>
|
||||||
#include <LibGUI/Window.h>
|
#include <LibGUI/Window.h>
|
||||||
|
#include <LibImage/Image.h>
|
||||||
#include <LibInput/KeyEvent.h>
|
#include <LibInput/KeyEvent.h>
|
||||||
#include <LibInput/MouseEvent.h>
|
#include <LibInput/MouseEvent.h>
|
||||||
|
|
||||||
|
@ -26,6 +27,8 @@ public:
|
||||||
invalidate(m_framebuffer.area());
|
invalidate(m_framebuffer.area());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<void> set_background_image(BAN::UniqPtr<LibImage::Image>);
|
||||||
|
|
||||||
void on_window_packet(int fd, LibGUI::WindowPacket);
|
void on_window_packet(int fd, LibGUI::WindowPacket);
|
||||||
|
|
||||||
void on_key_event(LibInput::KeyEvent event);
|
void on_key_event(LibInput::KeyEvent event);
|
||||||
|
@ -50,6 +53,8 @@ private:
|
||||||
BAN::Vector<BAN::RefPtr<Window>> m_client_windows;
|
BAN::Vector<BAN::RefPtr<Window>> m_client_windows;
|
||||||
BAN::Vector<int> m_client_fds;
|
BAN::Vector<int> m_client_fds;
|
||||||
|
|
||||||
|
BAN::UniqPtr<LibImage::Image> m_background_image;
|
||||||
|
|
||||||
bool m_is_mod_key_held { false };
|
bool m_is_mod_key_held { false };
|
||||||
bool m_is_moving_window { false };
|
bool m_is_moving_window { false };
|
||||||
BAN::RefPtr<Window> m_focused_window;
|
BAN::RefPtr<Window> m_focused_window;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "WindowServer.h"
|
#include "WindowServer.h"
|
||||||
|
|
||||||
#include <BAN/Debug.h>
|
#include <BAN/Debug.h>
|
||||||
|
#include <BAN/ScopeGuard.h>
|
||||||
|
|
||||||
#include <LibGUI/Window.h>
|
#include <LibGUI/Window.h>
|
||||||
#include <LibInput/KeyboardLayout.h>
|
#include <LibInput/KeyboardLayout.h>
|
||||||
|
@ -15,6 +16,88 @@
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
struct Config
|
||||||
|
{
|
||||||
|
BAN::UniqPtr<LibImage::Image> background_image;
|
||||||
|
};
|
||||||
|
|
||||||
|
BAN::Optional<BAN::String> file_read_line(FILE* file)
|
||||||
|
{
|
||||||
|
BAN::String line;
|
||||||
|
|
||||||
|
char buffer[128];
|
||||||
|
while (fgets(buffer, sizeof(buffer), file))
|
||||||
|
{
|
||||||
|
MUST(line.append(buffer));
|
||||||
|
if (line.back() == '\n')
|
||||||
|
{
|
||||||
|
line.pop_back();
|
||||||
|
return BAN::move(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.empty())
|
||||||
|
return {};
|
||||||
|
return BAN::move(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
Config parse_config()
|
||||||
|
{
|
||||||
|
Config config;
|
||||||
|
|
||||||
|
auto home_env = getenv("HOME");
|
||||||
|
if (!home_env)
|
||||||
|
{
|
||||||
|
dprintln("HOME environment variable not set");
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto config_path = BAN::String::formatted("{}/.config/WindowServer.conf", home_env);
|
||||||
|
FILE* fconfig = fopen(config_path.data(), "r");
|
||||||
|
if (!fconfig)
|
||||||
|
{
|
||||||
|
dprintln("Could not open '{}'", config_path);
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::ScopeGuard _([fconfig] { fclose(fconfig); });
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
auto line = file_read_line(fconfig);
|
||||||
|
if (!line.has_value())
|
||||||
|
break;
|
||||||
|
if (line->empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto parts = MUST(line->sv().split('='));
|
||||||
|
if (parts.size() != 2)
|
||||||
|
{
|
||||||
|
dwarnln("Invalid config line: {}", line.value());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto variable = parts[0];
|
||||||
|
auto value = parts[1];
|
||||||
|
|
||||||
|
if (variable == "bg"sv)
|
||||||
|
{
|
||||||
|
auto image = LibImage::Image::load_from_file(value);
|
||||||
|
if (image.is_error())
|
||||||
|
dwarnln("Could not load image: {}", image.error());
|
||||||
|
else
|
||||||
|
config.background_image = image.release_value();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dwarnln("Unknown config variable: {}", variable);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
int open_server_fd()
|
int open_server_fd()
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
@ -91,7 +174,13 @@ int main()
|
||||||
window_packet_sizes[LibGUI::WindowPacketType::Invalidate] = sizeof(LibGUI::WindowInvalidatePacket);
|
window_packet_sizes[LibGUI::WindowPacketType::Invalidate] = sizeof(LibGUI::WindowInvalidatePacket);
|
||||||
static_assert(LibGUI::WindowPacketType::COUNT == 3);
|
static_assert(LibGUI::WindowPacketType::COUNT == 3);
|
||||||
|
|
||||||
|
auto config = parse_config();
|
||||||
|
|
||||||
WindowServer window_server(framebuffer);
|
WindowServer window_server(framebuffer);
|
||||||
|
if (config.background_image)
|
||||||
|
if (auto ret = window_server.set_background_image(BAN::move(config.background_image)); ret.is_error())
|
||||||
|
dwarnln("Could not set background image: {}", ret.error());
|
||||||
|
|
||||||
while (!window_server.is_stopped())
|
while (!window_server.is_stopped())
|
||||||
{
|
{
|
||||||
int max_fd = server_fd;
|
int max_fd = server_fd;
|
||||||
|
|
Loading…
Reference in New Issue