Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Implemented SDL_SetWindowIcon(), with translucent icon support under …
Browse files Browse the repository at this point in the history
…X11.
  • Loading branch information
slouken committed Jan 2, 2009
1 parent ef658fe commit d76aa76
Show file tree
Hide file tree
Showing 11 changed files with 105 additions and 51 deletions.
4 changes: 2 additions & 2 deletions include/SDL_video.h
Expand Up @@ -591,13 +591,13 @@ extern DECLSPEC void SDLCALL SDL_SetWindowTitle(SDL_WindowID windowID,
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)
Expand Down
4 changes: 3 additions & 1 deletion src/SDL_compat.c
Expand Up @@ -39,6 +39,7 @@ static SDL_Surface *SDL_PublicSurface = NULL;
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)
Expand Down Expand Up @@ -522,6 +523,7 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
if (!SDL_VideoWindow) {
return NULL;
}
SDL_SetWindowIcon(SDL_VideoWindow, SDL_VideoIcon);

window_flags = SDL_GetWindowFlags(SDL_VideoWindow);
surface_flags = 0;
Expand Down Expand Up @@ -868,7 +870,7 @@ SDL_WM_GetCaption(const char **title, const char **icon)
void
SDL_WM_SetIcon(SDL_Surface * icon, Uint8 * mask)
{
/* FIXME */
SDL_VideoIcon = icon;
}

int
Expand Down
19 changes: 8 additions & 11 deletions src/video/SDL_bmp.c
Expand Up @@ -397,22 +397,19 @@ SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst)
) {
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");
}
}
}
Expand Down
15 changes: 12 additions & 3 deletions src/video/SDL_pixels.c
Expand Up @@ -347,16 +347,25 @@ SDL_AllocFormat(int bpp,
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 */
Expand Down Expand Up @@ -426,7 +435,7 @@ SDL_AllocFormat(int bpp,
}
format->palette = NULL;

return (format);
return format;
}

/*
Expand Down
3 changes: 3 additions & 0 deletions src/video/SDL_pixels_c.h
Expand Up @@ -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);

Expand Down
1 change: 1 addition & 0 deletions src/video/SDL_sysvideo.h
Expand Up @@ -238,6 +238,7 @@ struct SDL_VideoDevice
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);
Expand Down
56 changes: 33 additions & 23 deletions src/video/SDL_video.c
Expand Up @@ -965,6 +965,19 @@ SDL_GetWindowTitle(SDL_WindowID windowID)
return window->title;
}

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)
{
Expand Down Expand Up @@ -1590,33 +1603,30 @@ SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface)
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));
}
}
dst = SDL_ConvertSurface(surface, dst_fmt, 0);
if (dst) {
SDL_UpdateTexture(textureID, NULL, dst->pixels, dst->pitch);
SDL_FreeSurface(dst);
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));
}
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);
Expand Down
15 changes: 4 additions & 11 deletions src/video/x11/SDL_x11render.c
Expand Up @@ -87,7 +87,7 @@ typedef struct
Pixmap pixmaps[3];
int current_pixmap;
Drawable drawable;
SDL_PixelFormat *format;
SDL_PixelFormat format;
GC gc;
SDL_DirtyRectList dirty;
SDL_bool makedirty;
Expand Down Expand Up @@ -251,11 +251,7 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags)
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;
Expand Down Expand Up @@ -583,11 +579,11 @@ renderdrawcolor(SDL_Renderer * renderer, int premult)
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
Expand Down Expand Up @@ -852,9 +848,6 @@ X11_DestroyRenderer(SDL_Renderer * renderer)
XFreePixmap(data->display, data->pixmaps[i]);
}
}
if (data->format) {
SDL_FreeFormat(data->format);
}
if (data->gc) {
XFreeGC(data->display, data->gc);
}
Expand Down
1 change: 1 addition & 0 deletions src/video/x11/SDL_x11video.c
Expand Up @@ -174,6 +174,7 @@ X11_CreateDevice(int devindex)
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;
Expand Down
37 changes: 37 additions & 0 deletions src/video/x11/SDL_x11window.c
Expand Up @@ -645,6 +645,43 @@ X11_SetWindowTitle(_THIS, SDL_Window * window)
}
}

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)
{
Expand Down
1 change: 1 addition & 0 deletions src/video/x11/SDL_x11window.h
Expand Up @@ -36,6 +36,7 @@ typedef struct
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);
Expand Down

0 comments on commit d76aa76

Please sign in to comment.