From 7dbd9402c1f6c1d0a28c1e2f6af233ff3837ed31 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Tue, 31 Oct 2017 21:10:29 -0400 Subject: [PATCH] Add Jtk_SetWindowIcon() --- src/gui/Window.cc | 27 ++++++++++++++++++--------- src/gui/Window.h | 2 -- src/gui/jtk/Jtk_window.cc | 38 +++++++++++++++++++++++++++++++++++++- src/gui/jtk/Jtk_window.h | 2 ++ 4 files changed, 57 insertions(+), 12 deletions(-) diff --git a/src/gui/Window.cc b/src/gui/Window.cc index dba2fef..ced9dc1 100644 --- a/src/gui/Window.cc +++ b/src/gui/Window.cc @@ -52,16 +52,27 @@ static bool Initialize_OpenGL() return true; } -#if 0 void Window::set_window_icon() { - SDL_Surface * surface = SDL_CreateRGBSurfaceFrom((void *)jes_icon_32x32, 32, 32, 24, 32 * 3, 0xFF0000u, 0xFF00u, 0xFFu, 0u); - - SDL_SetWindowIcon(m_window, surface); - - SDL_FreeSurface(surface); + uint8_t * icon_bgra = (uint8_t *)malloc(32u * 32u * 4u); + uint8_t * out_icon = icon_bgra; + const uint8_t * in_icon = jes_icon_32x32; + for (int row = 0; row < 32; row++) + { + for (int col = 0; col < 32; col++) + { + uint8_t r = *in_icon++; + uint8_t g = *in_icon++; + uint8_t b = *in_icon++; + *out_icon++ = b; + *out_icon++ = g; + *out_icon++ = r; + *out_icon++ = 0xFFu; + } + } + Jtk_SetWindowIcon(m_window, icon_bgra, 32, 32); + free(icon_bgra); } -#endif /** * Create a Window. @@ -85,9 +96,7 @@ bool Window::create(std::shared_ptr buffer) } Jtk_SetWindowTitle(m_window, "jes"); -#if 0 set_window_icon(); -#endif if (!Initialize_OpenGL()) { diff --git a/src/gui/Window.h b/src/gui/Window.h index d470e42..cbfb660 100644 --- a/src/gui/Window.h +++ b/src/gui/Window.h @@ -46,9 +46,7 @@ protected: void handle_event(Jtk_Event & event); void handle_keypress(uint32_t keyval); void change_focus(std::shared_ptr buffer_pane); -#if 0 void set_window_icon(); -#endif void handle_command(const EncodedString & command); void command_write_file(const CommandParser & cp); diff --git a/src/gui/jtk/Jtk_window.cc b/src/gui/jtk/Jtk_window.cc index e538789..e7e43b3 100644 --- a/src/gui/jtk/Jtk_window.cc +++ b/src/gui/jtk/Jtk_window.cc @@ -1,4 +1,3 @@ - #include "Jtk.h" #ifdef JTK_X @@ -7,6 +6,7 @@ #include "Jtk_internal.h" #include #include +#include static Bool WaitForNotify(Display * display, XEvent * event, XPointer arg) { @@ -56,4 +56,40 @@ void Jtk_SetWindowTitle(void * window, const char * title) } } +/** + * Set the window icon. + * + * @param window + * The window to operate on. + * @param data + * The format of data must be 32 bits per pixel in BGRA format (e.g. data[0] + * is blue value, data[3] is alpha value of first pixel). + * @param width + * Icon width. + * @param height + * Icon height. + */ +void Jtk_SetWindowIcon(void * window, const uint8_t * data, + size_t width, size_t height) +{ + Atom net_wm_icon_atom = XInternAtom(g_display, "_NET_WM_ICON", False); + size_t property_size = (2u + width * height) * sizeof(long); + unsigned long * property_data = (unsigned long *)malloc(property_size); + property_data[0] = width; + property_data[1] = height; + unsigned long * dest = &property_data[2]; + const uint32_t * src = (const uint32_t *)data; + for (size_t row = 0u; row < height; row++) + { + for (size_t col = 0u; col < width; col++) + { + *dest++ = *src++; + } + } + XChangeProperty(g_display, (Window)window, net_wm_icon_atom, XA_CARDINAL, + 32, PropModeReplace, (uint8_t *)property_data, property_size); + XFlush(g_display); + free(property_data); +} + #endif diff --git a/src/gui/jtk/Jtk_window.h b/src/gui/jtk/Jtk_window.h index 720c036..a0dc373 100644 --- a/src/gui/jtk/Jtk_window.h +++ b/src/gui/jtk/Jtk_window.h @@ -5,5 +5,7 @@ void * Jtk_CreateWindow(); void Jtk_SwapBuffers(void * window); void Jtk_CloseWindow(void * window); void Jtk_SetWindowTitle(void * window, const char * title); +void Jtk_SetWindowIcon(void * window, const uint8_t * data, + size_t width, size_t height); #endif