Implemented SDL_SetWindowIcon(), with translucent icon support under X11.
--- a/include/SDL_video.h Fri Jan 02 16:38:31 2009 +0000
+++ b/include/SDL_video.h Fri Jan 02 17:39:48 2009 +0000
@@ -591,13 +591,13 @@
extern DECLSPEC const char *SDLCALL SDL_GetWindowTitle(SDL_WindowID windowID);
/**
- * \fn void SDL_SetWindowIcon(SDL_Surface *icon)
+ * \fn void SDL_SetWindowIcon(SDL_WindowID windowID, SDL_Surface *icon)
*
* \brief Set the icon of the window.
*
* \param icon The icon for the window
*/
-extern DECLSPEC void SDLCALL SDL_SetWindowIcon(SDL_Surface * icon);
+extern DECLSPEC void SDLCALL SDL_SetWindowIcon(SDL_WindowID windowID, SDL_Surface * icon);
/**
* \fn void SDL_SetWindowData(SDL_WindowID windowID, void *userdata)
--- a/src/SDL_compat.c Fri Jan 02 16:38:31 2009 +0000
+++ b/src/SDL_compat.c Fri Jan 02 17:39:48 2009 +0000
@@ -39,6 +39,7 @@
static SDL_GLContext *SDL_VideoContext = NULL;
static Uint32 SDL_VideoFlags = 0;
static char *wm_title = NULL;
+static SDL_Surface *SDL_VideoIcon;
char *
SDL_AudioDriverName(char *namebuf, int maxlen)
@@ -522,6 +523,7 @@
if (!SDL_VideoWindow) {
return NULL;
}
+ SDL_SetWindowIcon(SDL_VideoWindow, SDL_VideoIcon);
window_flags = SDL_GetWindowFlags(SDL_VideoWindow);
surface_flags = 0;
@@ -868,7 +870,7 @@
void
SDL_WM_SetIcon(SDL_Surface * icon, Uint8 * mask)
{
- /* FIXME */
+ SDL_VideoIcon = icon;
}
int
--- a/src/video/SDL_bmp.c Fri Jan 02 16:38:31 2009 +0000
+++ b/src/video/SDL_bmp.c Fri Jan 02 17:39:48 2009 +0000
@@ -397,22 +397,19 @@
) {
surface = saveme;
} else {
- SDL_PixelFormat *format;
+ SDL_PixelFormat format;
/* Convert to 24 bits per pixel */
- format = SDL_AllocFormat(24,
+ SDL_InitFormat(&format, 24,
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
- 0x00FF0000, 0x0000FF00, 0x000000FF,
+ 0x00FF0000, 0x0000FF00, 0x000000FF,
#else
- 0x000000FF, 0x0000FF00, 0x00FF0000,
+ 0x000000FF, 0x0000FF00, 0x00FF0000,
#endif
- 0);
- if (format != NULL) {
- surface = SDL_ConvertSurface(saveme, format, 0);
- if (!surface) {
- SDL_SetError("Couldn't convert image to 24 bpp");
- }
- SDL_FreeFormat(format);
+ 0);
+ surface = SDL_ConvertSurface(saveme, &format, 0);
+ if (!surface) {
+ SDL_SetError("Couldn't convert image to 24 bpp");
}
}
}
--- a/src/video/SDL_pixels.c Fri Jan 02 16:38:31 2009 +0000
+++ b/src/video/SDL_pixels.c Fri Jan 02 17:39:48 2009 +0000
@@ -347,16 +347,25 @@
Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
{
SDL_PixelFormat *format;
- Uint32 mask;
/* Allocate an empty pixel format structure */
- format = SDL_calloc(1, sizeof(*format));
+ format = SDL_malloc(sizeof(*format));
if (format == NULL) {
SDL_OutOfMemory();
return (NULL);
}
/* Set up the format */
+ return SDL_InitFormat(format, bpp, Rmask, Gmask, Bmask, Amask);
+}
+
+SDL_PixelFormat *
+SDL_InitFormat(SDL_PixelFormat *format, int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
+{
+ Uint32 mask;
+
+ /* Set up the format */
+ SDL_zerop(format);
format->BitsPerPixel = bpp;
format->BytesPerPixel = (bpp + 7) / 8;
if (Rmask || Bmask || Gmask) { /* Packed pixels with custom mask */
@@ -426,7 +435,7 @@
}
format->palette = NULL;
- return (format);
+ return format;
}
/*
--- a/src/video/SDL_pixels_c.h Fri Jan 02 16:38:31 2009 +0000
+++ b/src/video/SDL_pixels_c.h Fri Jan 02 17:39:48 2009 +0000
@@ -29,6 +29,9 @@
extern SDL_PixelFormat *SDL_AllocFormat(int bpp,
Uint32 Rmask, Uint32 Gmask,
Uint32 Bmask, Uint32 Amask);
+extern SDL_PixelFormat *SDL_InitFormat(SDL_PixelFormat *format, int bpp,
+ Uint32 Rmask, Uint32 Gmask,
+ Uint32 Bmask, Uint32 Amask);
extern void SDL_FormatChanged(SDL_Surface * surface);
extern void SDL_FreeFormat(SDL_PixelFormat * format);
--- a/src/video/SDL_sysvideo.h Fri Jan 02 16:38:31 2009 +0000
+++ b/src/video/SDL_sysvideo.h Fri Jan 02 17:39:48 2009 +0000
@@ -238,6 +238,7 @@
int (*CreateWindow) (_THIS, SDL_Window * window);
int (*CreateWindowFrom) (_THIS, SDL_Window * window, const void *data);
void (*SetWindowTitle) (_THIS, SDL_Window * window);
+ void (*SetWindowIcon) (_THIS, SDL_Window * window, SDL_Surface * icon);
void (*SetWindowPosition) (_THIS, SDL_Window * window);
void (*SetWindowSize) (_THIS, SDL_Window * window);
void (*ShowWindow) (_THIS, SDL_Window * window);
--- a/src/video/SDL_video.c Fri Jan 02 16:38:31 2009 +0000
+++ b/src/video/SDL_video.c Fri Jan 02 17:39:48 2009 +0000
@@ -966,6 +966,19 @@
}
void
+SDL_SetWindowIcon(SDL_WindowID windowID, SDL_Surface * icon)
+{
+ SDL_Window *window = SDL_GetWindowFromID(windowID);
+
+ if (!window) {
+ return;
+ }
+ if (_this->SetWindowIcon) {
+ _this->SetWindowIcon(_this, window, icon);
+ }
+}
+
+void
SDL_SetWindowData(SDL_WindowID windowID, void *userdata)
{
SDL_Window *window = SDL_GetWindowFromID(windowID);
@@ -1590,33 +1603,30 @@
surface->pitch);
}
} else {
- SDL_PixelFormat *dst_fmt;
+ SDL_PixelFormat dst_fmt;
SDL_Surface *dst = NULL;
/* Set up a destination surface for the texture update */
- dst_fmt = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask);
- if (dst_fmt) {
- if (SDL_ISPIXELFORMAT_INDEXED(format)) {
- dst_fmt->palette =
- SDL_AllocPalette((1 << SDL_BITSPERPIXEL(format)));
- if (dst_fmt->palette) {
- /*
- * FIXME: Should we try to copy
- * fmt->palette?
- */
- SDL_DitherColors(dst_fmt->palette->colors,
- SDL_BITSPERPIXEL(format));
- }
+ SDL_InitFormat(&dst_fmt, bpp, Rmask, Gmask, Bmask, Amask);
+ if (SDL_ISPIXELFORMAT_INDEXED(format)) {
+ dst_fmt.palette =
+ SDL_AllocPalette((1 << SDL_BITSPERPIXEL(format)));
+ if (dst_fmt.palette) {
+ /*
+ * FIXME: Should we try to copy
+ * fmt->palette?
+ */
+ SDL_DitherColors(dst_fmt.palette->colors,
+ SDL_BITSPERPIXEL(format));
}
- dst = SDL_ConvertSurface(surface, dst_fmt, 0);
- if (dst) {
- SDL_UpdateTexture(textureID, NULL, dst->pixels, dst->pitch);
- SDL_FreeSurface(dst);
- }
- if (dst_fmt->palette) {
- SDL_FreePalette(dst_fmt->palette);
- }
- SDL_FreeFormat(dst_fmt);
+ }
+ dst = SDL_ConvertSurface(surface, &dst_fmt, 0);
+ if (dst) {
+ SDL_UpdateTexture(textureID, NULL, dst->pixels, dst->pitch);
+ SDL_FreeSurface(dst);
+ }
+ if (dst_fmt.palette) {
+ SDL_FreePalette(dst_fmt.palette);
}
if (!dst) {
SDL_DestroyTexture(textureID);
--- a/src/video/x11/SDL_x11render.c Fri Jan 02 16:38:31 2009 +0000
+++ b/src/video/x11/SDL_x11render.c Fri Jan 02 17:39:48 2009 +0000
@@ -87,7 +87,7 @@
Pixmap pixmaps[3];
int current_pixmap;
Drawable drawable;
- SDL_PixelFormat *format;
+ SDL_PixelFormat format;
GC gc;
SDL_DirtyRectList dirty;
SDL_bool makedirty;
@@ -251,11 +251,7 @@
X11_DestroyRenderer(renderer);
return NULL;
}
- data->format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask);
- if (!data->format) {
- X11_DestroyRenderer(renderer);
- return NULL;
- }
+ SDL_InitFormat(&data->format, bpp, Rmask, Gmask, Bmask, Amask);
/* Create the drawing context */
gcv.graphics_exposures = False;
@@ -583,11 +579,11 @@
Uint8 b = renderer->b;
Uint8 a = renderer->a;
if (premult)
- return SDL_MapRGBA(data->format, ((int) r * (int) a) / 255,
+ return SDL_MapRGBA(&data->format, ((int) r * (int) a) / 255,
((int) g * (int) a) / 255,
((int) b * (int) a) / 255, 255);
else
- return SDL_MapRGBA(data->format, r, g, b, a);
+ return SDL_MapRGBA(&data->format, r, g, b, a);
}
static int
@@ -852,9 +848,6 @@
XFreePixmap(data->display, data->pixmaps[i]);
}
}
- if (data->format) {
- SDL_FreeFormat(data->format);
- }
if (data->gc) {
XFreeGC(data->display, data->gc);
}
--- a/src/video/x11/SDL_x11video.c Fri Jan 02 16:38:31 2009 +0000
+++ b/src/video/x11/SDL_x11video.c Fri Jan 02 17:39:48 2009 +0000
@@ -174,6 +174,7 @@
device->CreateWindow = X11_CreateWindow;
device->CreateWindowFrom = X11_CreateWindowFrom;
device->SetWindowTitle = X11_SetWindowTitle;
+ device->SetWindowIcon = X11_SetWindowIcon;
device->SetWindowPosition = X11_SetWindowPosition;
device->SetWindowSize = X11_SetWindowSize;
device->ShowWindow = X11_ShowWindow;
--- a/src/video/x11/SDL_x11window.c Fri Jan 02 16:38:31 2009 +0000
+++ b/src/video/x11/SDL_x11window.c Fri Jan 02 17:39:48 2009 +0000
@@ -646,6 +646,43 @@
}
void
+X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ Display *display = data->videodata->display;
+ Atom _NET_WM_ICON = XInternAtom(display, "_NET_WM_ICON", False);
+
+ if (icon) {
+ SDL_PixelFormat format;
+ SDL_Surface *surface;
+ int propsize;
+ Uint32 *propdata;
+
+ /* Convert the icon to ARGB for modern window managers */
+ SDL_InitFormat(&format, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
+ surface = SDL_ConvertSurface(icon, &format, 0);
+ if (!surface) {
+ return;
+ }
+
+ /* Set the _NET_WM_ICON property */
+ propsize = 2+(icon->w*icon->h);
+ propdata = SDL_malloc(propsize * sizeof(Uint32));
+ if (propdata) {
+ propdata[0] = icon->w;
+ propdata[1] = icon->h;
+ SDL_memcpy(&propdata[2], surface->pixels, surface->h*surface->pitch);
+ XChangeProperty(display, data->window, _NET_WM_ICON,
+ XA_CARDINAL, 32, PropModeReplace,
+ (unsigned char *) propdata, propsize);
+ }
+ SDL_FreeSurface(surface);
+ } else {
+ XDeleteProperty(display, data->window, _NET_WM_ICON);
+ }
+}
+
+void
X11_SetWindowPosition(_THIS, SDL_Window * window)
{
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
--- a/src/video/x11/SDL_x11window.h Fri Jan 02 16:38:31 2009 +0000
+++ b/src/video/x11/SDL_x11window.h Fri Jan 02 17:39:48 2009 +0000
@@ -36,6 +36,7 @@
extern int X11_CreateWindow(_THIS, SDL_Window * window);
extern int X11_CreateWindowFrom(_THIS, SDL_Window * window, const void *data);
extern void X11_SetWindowTitle(_THIS, SDL_Window * window);
+extern void X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon);
extern void X11_SetWindowPosition(_THIS, SDL_Window * window);
extern void X11_SetWindowSize(_THIS, SDL_Window * window);
extern void X11_ShowWindow(_THIS, SDL_Window * window);