From f5d80aa46f100a5fd76955998341fad7c3f42a47 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Tue, 27 Oct 2020 17:04:10 +0100 Subject: [PATCH] Platform/Unix/X11Display: Implement setIcon() --- source/Platform/Unix/X11Display.cpp | 35 ++++++++++++++++++++++++++++- source/Platform/Unix/X11Display.h | 3 +++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/source/Platform/Unix/X11Display.cpp b/source/Platform/Unix/X11Display.cpp index 968a9c3..94cea38 100644 --- a/source/Platform/Unix/X11Display.cpp +++ b/source/Platform/Unix/X11Display.cpp @@ -1,6 +1,7 @@ #include // Prevents conflict with X.h defining "None" #include +#include #include "X11WindowEventHandler.h" #include "X11SharedDisplay.h" #include "GLXContext.h" @@ -116,9 +117,41 @@ void X11Display::setCaption(const std::string& caption) ::XStoreName(m_disp, m_win, caption.c_str()); } +// TODO: Move this up to the non-platform layer. void X11Display::setIcon(const std::string& icon) { - // TODO: Implement + Image img; + + if (img.loadFromFile(icon)) { + setIcon(img.getWidth(), img.getHeight(), img.getPixels()); + } +} + +void X11Display::setIcon(unsigned int width, unsigned int height, const uint8_t *pixels) +{ + ::Atom net_wm_icon = getAtom("_NET_WM_ICON", False); + ::Atom cardinal = getAtom("CARDINAL", False); + std::vector buffer(2 + width * height); + uint64_t *ptr = &buffer[0]; + + *ptr++ = width; + *ptr++ = height; + + // TODO: Conversion between differnet formats should be defined as functions in Graphics/PixelFormat.h + for (std::size_t i = 0; i < width * height; i++) { + *ptr++ = (pixels[i * 4 + 2] << 0) + | (pixels[i * 4 + 1] << 8) + | (pixels[i * 4 + 0] << 16) + | (pixels[i * 4 + 3] << 24); + } + + ::XChangeProperty(m_disp, m_win, + net_wm_icon, cardinal, 32, + PropModeReplace, + reinterpret_cast(&buffer[0]), + 2 + width * height); + + XFlush(m_disp); } void X11Display::createHiddenCursor() diff --git a/source/Platform/Unix/X11Display.h b/source/Platform/Unix/X11Display.h index ec4c094..538e5c0 100644 --- a/source/Platform/Unix/X11Display.h +++ b/source/Platform/Unix/X11Display.h @@ -6,6 +6,7 @@ #include #include #include +#include #include namespace sp { @@ -35,6 +36,8 @@ public : virtual void setIcon(const std::string& icon); + virtual void setIcon(unsigned int width, unsigned int height, const uint8_t *pixels); + virtual void showCursor(bool value); void processEvent(const ::XEvent& event);