Skip to content

Commit a904af1

Browse files
Kontrabantslouken
authored andcommitted
tray: Save icons on *nix platforms to PNG instead of BMP
PNG has better compatibility with certain desktops. This requires the stb_image_write header for PNG writing functionality.
1 parent 285df94 commit a904af1

File tree

4 files changed

+1814
-4
lines changed

4 files changed

+1814
-4
lines changed

src/tray/unix/SDL_tray.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "SDL_internal.h"
2323

2424
#include "../SDL_tray_utils.h"
25+
#include "../../video/SDL_stb_c.h"
2526

2627
#include <dlfcn.h>
2728
#include <errno.h>
@@ -184,7 +185,7 @@ static bool new_tmp_filename(SDL_Tray *tray)
184185
{
185186
static int count = 0;
186187

187-
int would_have_written = SDL_asprintf(&tray->icon_path, "%s/%d.bmp", tray->icon_dir, count++);
188+
int would_have_written = SDL_asprintf(&tray->icon_path, "%s/%d.png", tray->icon_dir, count++);
188189

189190
if (would_have_written >= 0) {
190191
return true;
@@ -289,7 +290,7 @@ SDL_Tray *SDL_CreateTray(SDL_Surface *icon, const char *tooltip)
289290
goto icon_dir_error;
290291
}
291292

292-
SDL_SaveBMP(icon, tray->icon_path);
293+
SDL_SavePNG(icon, tray->icon_path);
293294
} else {
294295
// allocate a dummy icon path
295296
SDL_asprintf(&tray->icon_path, " ");
@@ -342,7 +343,7 @@ void SDL_SetTrayIcon(SDL_Tray *tray, SDL_Surface *icon)
342343
/* AppIndicator caches the icon files; always change filename to avoid caching */
343344

344345
if (icon && new_tmp_filename(tray)) {
345-
SDL_SaveBMP(icon, tray->icon_path);
346+
SDL_SavePNG(icon, tray->icon_path);
346347
app_indicator_set_icon(tray->indicator, tray->icon_path);
347348
} else {
348349
SDL_free(tray->icon_path);

src/video/SDL_stb.c

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#include "SDL_internal.h"
2222

2323
#include "SDL_stb_c.h"
24-
24+
#include "SDL_surface_c.h"
2525

2626
// We currently only support JPEG, but we could add other image formats if we wanted
2727
#ifdef SDL_HAVE_STB
@@ -59,6 +59,13 @@
5959
#define STB_IMAGE_IMPLEMENTATION
6060
#include "stb_image.h"
6161

62+
#undef memcpy
63+
#define STB_IMAGE_WRITE_IMPLEMENTATION
64+
#define STB_IMAGE_WRITE_STATIC
65+
#define STBI_WRITE_NO_STDIO
66+
#define STBIW_ASSERT SDL_assert
67+
#include "stb_image_write.h"
68+
6269
#undef memset
6370
#endif
6471

@@ -119,3 +126,68 @@ bool SDL_ConvertPixels_STB(int width, int height,
119126
return SDL_SetError("SDL not built with STB image support");
120127
#endif
121128
}
129+
130+
#ifdef SDL_HAVE_STB
131+
static void SDL_STBWriteFunc(void *context, void *data, int size)
132+
{
133+
SDL_WriteIO(context, data, size);
134+
}
135+
#endif
136+
137+
bool SDL_SavePNG_IO(SDL_Surface *surface, SDL_IOStream *dst, bool closeio)
138+
{
139+
#ifdef SDL_HAVE_STB
140+
bool retval = true;
141+
142+
// Make sure we have somewhere to save
143+
if (!SDL_SurfaceValid(surface)) {
144+
retval = SDL_InvalidParamError("surface");
145+
goto done;
146+
}
147+
if (!dst) {
148+
retval = SDL_InvalidParamError("dst");
149+
goto done;
150+
}
151+
152+
bool free_surface = false;
153+
if (surface->format != SDL_PIXELFORMAT_ABGR8888) {
154+
surface = SDL_ConvertSurface(surface, SDL_PIXELFORMAT_ABGR8888);
155+
if (!surface) {
156+
retval = false;
157+
goto done;
158+
}
159+
free_surface = true;
160+
}
161+
162+
if (!stbi_write_png_to_func(SDL_STBWriteFunc, dst, surface->w, surface->h, 4, surface->pixels, surface->pitch)) {
163+
retval = SDL_SetError("Failed to write PNG");
164+
}
165+
166+
if (free_surface) {
167+
SDL_DestroySurface(surface);
168+
}
169+
170+
done:
171+
if (dst && closeio) {
172+
retval = SDL_CloseIO(dst);
173+
}
174+
175+
return retval;
176+
#else
177+
return SDL_SetError("SDL not built with STB image write support");
178+
#endif
179+
}
180+
181+
bool SDL_SavePNG(SDL_Surface *surface, const char *file)
182+
{
183+
#ifdef SDL_HAVE_STB
184+
SDL_IOStream *stream = SDL_IOFromFile(file, "wb");
185+
if (!stream) {
186+
return false;
187+
}
188+
189+
return SDL_SavePNG_IO(surface, stream, true);
190+
#else
191+
return SDL_SetError("SDL not built with STB image write support");
192+
#endif
193+
}

src/video/SDL_stb_c.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,7 @@
2727
// Image conversion functions
2828

2929
extern bool SDL_ConvertPixels_STB(int width, int height, SDL_PixelFormat src_format, SDL_Colorspace src_colorspace, SDL_PropertiesID src_properties, const void *src, int src_pitch, SDL_PixelFormat dst_format, SDL_Colorspace dst_colorspace, SDL_PropertiesID dst_properties, void *dst, int dst_pitch);
30+
extern bool SDL_SavePNG_IO(SDL_Surface *surface, SDL_IOStream *dst, bool closeio);
31+
extern bool SDL_SavePNG(SDL_Surface *surface, const char *file);
3032

3133
#endif // SDL_stb_c_h_

0 commit comments

Comments
 (0)