diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 554e6e575..99bfa6ad9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -161,14 +161,9 @@ if(WIN32) main/settings.manifest) endif() -if(UNIX AND NOT APPLE AND USE_ALLEG4_BACKEND) - set(x11_resources main/xpm_icon.c) -endif() - add_executable(aseprite WIN32 main/main.cpp - ${win32_resources} - ${x11_resources}) + ${win32_resources}) target_link_libraries(aseprite app-lib ${PLATFORM_LIBS}) add_dependencies(aseprite copy_data) diff --git a/src/app/app.cpp b/src/app/app.cpp index 8cf7877a2..ef76dfcd3 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -57,9 +57,11 @@ #include "base/unique_ptr.h" #include "doc/site.h" #include "doc/sprite.h" +#include "fmt/format.h" #include "render/render.h" #include "she/display.h" #include "she/error.h" +#include "she/surface.h" #include "she/system.h" #include "ui/intern.h" #include "ui/ui.h" @@ -229,6 +231,32 @@ void App::initialize(const AppOptions& options) } she::instance()->finishLaunching(); + +#if !defined(_WIN32) && !defined(__APPLE__) + try { + she::Display* display = she::instance()->defaultDisplay(); + she::SurfaceList icons; + + for (const int size : { 32, 64, 128 }) { + ResourceFinder rf; + rf.includeDataDir(fmt::format("icons/ase{0}.png", size).c_str()); + if (rf.findFirst()) { + she::Surface* surf = she::instance()->loadRgbaSurface(rf.filename().c_str()); + if (surf) + icons.push_back(surf); + } + } + + display->setIcons(icons); + + for (auto surf : icons) + surf->dispose(); + } + catch (const std::exception&) { + // Just ignore the exception, we couldn't change the app icon, no + // big deal. + } +#endif } void App::run() diff --git a/src/main/xpm_icon.c b/src/main/xpm_icon.c deleted file mode 100644 index 87920a122..000000000 --- a/src/main/xpm_icon.c +++ /dev/null @@ -1,39 +0,0 @@ -#include -/* XPM */ -static const char *ase16png_xpm[] = { -/* columns rows colors chars-per-pixel */ -"16 16 8 1", -" c #010000", -". c #325C70", -"X c #AD947D", -"o c #529BC1", -"O c #65D7DE", -"+ c #EDD6C0", -"@ c #FFFFFF", -"# c None", -/* pixels */ -"################", -"################", -"########XXXX@ ##", -"#######oX+@@ ##", -"######oOX@++Xo##", -"#####oOoo+++Xo##", -"####oOo@Oo+XXo##", -"###oOo@OO@oXX.##", -"##.Oo@OOOOoo.###", -"##.o@OOOOoo.####", -"##.OOOOOoo.#####", -"##.oOOOoo.######", -"###.oOoo.#######", -"####....########", -"################", -"################" -}; -#if defined ALLEGRO_WITH_XWINDOWS && defined ALLEGRO_USE_CONSTRUCTOR -extern void *allegro_icon; -CONSTRUCTOR_FUNCTION(static void _set_allegro_icon(void)); -static void _set_allegro_icon(void) -{ - allegro_icon = ase16png_xpm; -} -#endif diff --git a/src/she/alleg4/alleg_display.cpp b/src/she/alleg4/alleg_display.cpp index 751f45a72..ba800d4a8 100644 --- a/src/she/alleg4/alleg_display.cpp +++ b/src/she/alleg4/alleg_display.cpp @@ -1,5 +1,5 @@ // SHE library -// Copyright (C) 2012-2016 David Capello +// Copyright (C) 2012-2017 David Capello // // This file is released under the terms of the MIT license. // Read LICENSE.txt for more information. @@ -40,6 +40,7 @@ #elif defined ALLEGRO_UNIX #include + #include #ifdef None #undef None #define X11_None 0L @@ -532,6 +533,49 @@ void Alleg4Display::setTitleBar(const std::string& title) set_window_title(title.c_str()); } +void Alleg4Display::setIcons(const SurfaceList& icons) +{ +#ifdef ALLEGRO_UNIX + + bool first = true; + for (Surface* icon : icons) { + auto display = _xwin.display; + auto window = _xwin.wm_window; + const int w = icon->width(); + const int h = icon->height(); + + SurfaceFormatData format; + icon->getFormat(&format); + + std::vector data(w*h+2); + int i = 0; + data[i++] = w; + data[i++] = h; + for (int y=0; ygetData(0, y); + for (int x=0; x> format.blueShift ) ) | + (((c & format.greenMask) >> format.greenShift) << 8) | + (((c & format.redMask ) >> format.redShift ) << 16) | + (((c & format.alphaMask) >> format.alphaShift) << 24); + } + } + + Atom _NET_WM_ICON = XInternAtom(display, "_NET_WM_ICON", False); + XChangeProperty( + display, window, _NET_WM_ICON, XA_CARDINAL, 32, + first ? PropModeReplace: + PropModeAppend, + (const unsigned char*)&data[0], data.size()); + + first = false; + } + +#endif +} + NativeCursor Alleg4Display::nativeMouseCursor() { return m_nativeCursor; diff --git a/src/she/alleg4/alleg_display.h b/src/she/alleg4/alleg_display.h index 5c50f9d77..e063441f6 100644 --- a/src/she/alleg4/alleg_display.h +++ b/src/she/alleg4/alleg_display.h @@ -1,5 +1,5 @@ // SHE library -// Copyright (C) 2012-2016 David Capello +// Copyright (C) 2012-2017 David Capello // // This file is released under the terms of the MIT license. // Read LICENSE.txt for more information. @@ -33,6 +33,7 @@ namespace she { bool isMaximized() const override; bool isMinimized() const override; void setTitleBar(const std::string& title) override; + void setIcons(const SurfaceList& icons) override; NativeCursor nativeMouseCursor() override; bool setNativeMouseCursor(NativeCursor cursor) override; bool setNativeMouseCursor(const she::Surface* surface, diff --git a/src/she/display.h b/src/she/display.h index 21db42036..fc9a60228 100644 --- a/src/she/display.h +++ b/src/she/display.h @@ -1,5 +1,5 @@ // SHE library -// Copyright (C) 2012-2016 David Capello +// Copyright (C) 2012-2017 David Capello // // This file is released under the terms of the MIT license. // Read LICENSE.txt for more information. @@ -11,6 +11,7 @@ #include "gfx/point.h" #include "she/display_handle.h" #include "she/native_cursor.h" +#include "she/surface_list.h" #include @@ -55,6 +56,7 @@ namespace she { virtual bool isMinimized() const = 0; virtual void setTitleBar(const std::string& title) = 0; + virtual void setIcons(const SurfaceList& icons) = 0; virtual NativeCursor nativeMouseCursor() = 0; virtual bool setNativeMouseCursor(NativeCursor cursor) = 0; diff --git a/src/she/skia/skia_display.cpp b/src/she/skia/skia_display.cpp index 8114317c6..bd82cb916 100644 --- a/src/she/skia/skia_display.cpp +++ b/src/she/skia/skia_display.cpp @@ -137,6 +137,11 @@ void SkiaDisplay::setTitleBar(const std::string& title) m_window.setTitle(title); } +void SkiaDisplay::setIcons(const SurfaceList& icons) +{ + // TODO copy the Allegro impl +} + NativeCursor SkiaDisplay::nativeMouseCursor() { return m_nativeCursor; diff --git a/src/she/skia/skia_display.h b/src/she/skia/skia_display.h index b9ba96127..be9ca2337 100644 --- a/src/she/skia/skia_display.h +++ b/src/she/skia/skia_display.h @@ -1,5 +1,5 @@ // SHE library -// Copyright (C) 2012-2016 David Capello +// Copyright (C) 2012-2017 David Capello // // This file is released under the terms of the MIT license. // Read LICENSE.txt for more information. @@ -48,6 +48,7 @@ public: bool isMaximized() const override; bool isMinimized() const override; void setTitleBar(const std::string& title) override; + void setIcons(const SurfaceList& icons) override; NativeCursor nativeMouseCursor() override; bool setNativeMouseCursor(NativeCursor cursor) override; bool setNativeMouseCursor(const she::Surface* surface, diff --git a/src/she/surface_list.h b/src/she/surface_list.h new file mode 100644 index 000000000..789cb40d6 --- /dev/null +++ b/src/she/surface_list.h @@ -0,0 +1,21 @@ +// SHE library +// Copyright (C) 2017 David Capello +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#ifndef SHE_SURFACE_LIST_H_INCLUDED +#define SHE_SURFACE_LIST_H_INCLUDED +#pragma once + +#include + +namespace she { + + class Surface; + + typedef std::vector SurfaceList; + +} // namespace she + +#endif