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})
|
||||
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
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/WindowServer ${BANAN_BIN}/
|
||||
|
|
|
@ -11,6 +11,15 @@
|
|||
#include <sys/mman.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)
|
||||
{
|
||||
switch (packet.type)
|
||||
|
@ -270,8 +279,19 @@ void WindowServer::invalidate(Rectangle area)
|
|||
return;
|
||||
area = fb_overlap.release_value();
|
||||
|
||||
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);
|
||||
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++)
|
||||
memset(&m_framebuffer.mmap[y * m_framebuffer.width + area.x], 0x10, area.width * 4);
|
||||
}
|
||||
|
||||
for (auto& pwindow : m_client_windows)
|
||||
{
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <LibFont/Font.h>
|
||||
#include <LibGUI/Window.h>
|
||||
#include <LibImage/Image.h>
|
||||
#include <LibInput/KeyEvent.h>
|
||||
#include <LibInput/MouseEvent.h>
|
||||
|
||||
|
@ -26,6 +27,8 @@ public:
|
|||
invalidate(m_framebuffer.area());
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> set_background_image(BAN::UniqPtr<LibImage::Image>);
|
||||
|
||||
void on_window_packet(int fd, LibGUI::WindowPacket);
|
||||
|
||||
void on_key_event(LibInput::KeyEvent event);
|
||||
|
@ -50,6 +53,8 @@ private:
|
|||
BAN::Vector<BAN::RefPtr<Window>> m_client_windows;
|
||||
BAN::Vector<int> m_client_fds;
|
||||
|
||||
BAN::UniqPtr<LibImage::Image> m_background_image;
|
||||
|
||||
bool m_is_mod_key_held { false };
|
||||
bool m_is_moving_window { false };
|
||||
BAN::RefPtr<Window> m_focused_window;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "WindowServer.h"
|
||||
|
||||
#include <BAN/Debug.h>
|
||||
#include <BAN/ScopeGuard.h>
|
||||
|
||||
#include <LibGUI/Window.h>
|
||||
#include <LibInput/KeyboardLayout.h>
|
||||
|
@ -15,6 +16,88 @@
|
|||
#include <sys/un.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()
|
||||
{
|
||||
struct stat st;
|
||||
|
@ -91,7 +174,13 @@ int main()
|
|||
window_packet_sizes[LibGUI::WindowPacketType::Invalidate] = sizeof(LibGUI::WindowInvalidatePacket);
|
||||
static_assert(LibGUI::WindowPacketType::COUNT == 3);
|
||||
|
||||
auto config = parse_config();
|
||||
|
||||
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())
|
||||
{
|
||||
int max_fd = server_fd;
|
||||
|
|
Loading…
Reference in New Issue