From c6d685400abe6a0c249c38c01836b7f920f63667 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 14 Jul 2013 18:17:28 -0700 Subject: [PATCH] Fixed bug 1919 - Window icon disappears as soon as a renderer is created Sebastian Setting a window icon works just fine until a renderer is added to the window. After adding the renderer the icon disappears. Reproduce by: - Take the example code from the wiki: http://wiki.libsdl.org/moin.fcg/SDL_SetWindowIcon - Add the following two lines after SDL_FreeSurface(surface); SDL_Delay(1000); SDL_Renderer* ren = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); -compile and run You will see the window icon correctly at first. After the Delay the Icon will disappear. --- src/video/SDL_sysvideo.h | 1 + src/video/SDL_video.c | 21 ++++++++++++++++++++- src/video/windows/SDL_windowswindow.c | 23 ++++++++++------------- src/video/x11/SDL_x11window.c | 14 +++----------- 4 files changed, 34 insertions(+), 25 deletions(-) diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 3020bc773..598782833 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -73,6 +73,7 @@ struct SDL_Window const void *magic; Uint32 id; char *title; + SDL_Surface *icon; int x, y; int w, h; int min_w, min_h; diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 21b46523b..f96539dfa 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -1297,6 +1297,7 @@ int SDL_RecreateWindow(SDL_Window * window, Uint32 flags) { char *title = window->title; + SDL_Surface *icon = window->icon; if ((flags & SDL_WINDOW_OPENGL) && !_this->GL_CreateContext) { return SDL_SetError("No OpenGL support in video driver"); @@ -1335,6 +1336,7 @@ SDL_RecreateWindow(SDL_Window * window, Uint32 flags) } window->title = NULL; + window->icon = NULL; window->flags = ((flags & CREATE_FLAGS) | SDL_WINDOW_HIDDEN); if (_this->CreateWindow && !(flags & SDL_WINDOW_FOREIGN)) { @@ -1350,6 +1352,10 @@ SDL_RecreateWindow(SDL_Window * window, Uint32 flags) SDL_SetWindowTitle(window, title); SDL_free(title); } + if (icon) { + SDL_SetWindowIcon(window, icon); + SDL_FreeSurface(icon); + } SDL_FinishWindowCreation(window, flags); return 0; @@ -1426,8 +1432,18 @@ SDL_SetWindowIcon(SDL_Window * window, SDL_Surface * icon) return; } + if (window->icon) { + SDL_FreeSurface(window->icon); + } + + /* Convert the icon into ARGB8888 */ + window->icon = SDL_ConvertSurfaceFormat(icon, SDL_PIXELFORMAT_ARGB8888, 0); + if (!window->icon) { + return; + } + if (_this->SetWindowIcon) { - _this->SetWindowIcon(_this, window, icon); + _this->SetWindowIcon(_this, window, window->icon); } } @@ -2167,6 +2183,9 @@ SDL_DestroyWindow(SDL_Window * window) if (window->title) { SDL_free(window->title); } + if (window->icon) { + SDL_FreeSurface(window->icon); + } if (window->gamma) { SDL_free(window->gamma); } diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c index 1e41182e4..e89f3f60d 100644 --- a/src/video/windows/SDL_windowswindow.c +++ b/src/video/windows/SDL_windowswindow.c @@ -22,6 +22,7 @@ #if SDL_VIDEO_DRIVER_WINDOWS +#include "SDL_assert.h" #include "../SDL_sysvideo.h" #include "../SDL_pixels_c.h" #include "../../events/SDL_keyboard_c.h" @@ -292,7 +293,6 @@ WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) BYTE *icon_bmp; int icon_len; SDL_RWops *dst; - SDL_Surface *surface; /* Create temporary bitmap buffer */ icon_len = 40 + icon->h * icon->w * 4; @@ -316,19 +316,16 @@ WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) SDL_WriteLE32(dst, 0); SDL_WriteLE32(dst, 0); - /* Convert the icon to a 32-bit surface with alpha channel */ - surface = SDL_ConvertSurfaceFormat(icon, SDL_PIXELFORMAT_ARGB8888, 0); - if (surface) { - /* Write the pixels upside down into the bitmap buffer */ - int y = surface->h; - while (y--) { - Uint8 *src = (Uint8 *) surface->pixels + y * surface->pitch; - SDL_RWwrite(dst, src, surface->pitch, 1); - } - SDL_FreeSurface(surface); - - hicon = CreateIconFromResource(icon_bmp, icon_len, TRUE, 0x00030000); + /* Write the pixels upside down into the bitmap buffer */ + SDL_assert(icon->format->format == SDL_PIXELFORMAT_ARGB8888); + int y = icon->h; + while (y--) { + Uint8 *src = (Uint8 *) icon->pixels + y * icon->pitch; + SDL_RWwrite(dst, src, icon->pitch, 1); } + + hicon = CreateIconFromResource(icon_bmp, icon_len, TRUE, 0x00030000); + SDL_RWclose(dst); SDL_stack_free(icon_bmp); diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c index f48496f1a..07a836dcf 100644 --- a/src/video/x11/SDL_x11window.c +++ b/src/video/x11/SDL_x11window.c @@ -22,6 +22,7 @@ #if SDL_VIDEO_DRIVER_X11 +#include "SDL_assert.h" #include "SDL_hints.h" #include "../SDL_sysvideo.h" #include "../SDL_pixels_c.h" @@ -698,19 +699,11 @@ X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) Atom _NET_WM_ICON = data->videodata->_NET_WM_ICON; if (icon) { - SDL_PixelFormat format; - SDL_Surface *surface; int propsize; long *propdata; - /* Convert the icon to ARGB for modern window managers */ - SDL_InitFormat(&format, SDL_PIXELFORMAT_ARGB8888); - surface = SDL_ConvertSurface(icon, &format, 0); - if (!surface) { - return; - } - /* Set the _NET_WM_ICON property */ + SDL_assert(icon->format->format == SDL_PIXELFORMAT_ARGB8888); propsize = 2 + (icon->w * icon->h); propdata = SDL_malloc(propsize * sizeof(long)); if (propdata) { @@ -722,7 +715,7 @@ X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) propdata[1] = icon->h; dst = &propdata[2]; for (y = 0; y < icon->h; ++y) { - src = (Uint32*)((Uint8*)surface->pixels + y * surface->pitch); + src = (Uint32*)((Uint8*)icon->pixels + y * icon->pitch); for (x = 0; x < icon->w; ++x) { *dst++ = *src++; } @@ -732,7 +725,6 @@ X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) propsize); } SDL_free(propdata); - SDL_FreeSurface(surface); } else { XDeleteProperty(display, data->xwindow, _NET_WM_ICON); }