Implemented SDL_SetWindowIcon(), with translucent icon support under X11.
authorSam Lantinga <slouken@libsdl.org>
Fri, 02 Jan 2009 17:39:48 +0000
changeset 2967e4a469d6ddab
parent 2966 c1e3621ba959
child 2968 efe4d0ce2e97
Implemented SDL_SetWindowIcon(), with translucent icon support under X11.
include/SDL_video.h
src/SDL_compat.c
src/video/SDL_bmp.c
src/video/SDL_pixels.c
src/video/SDL_pixels_c.h
src/video/SDL_sysvideo.h
src/video/SDL_video.c
src/video/x11/SDL_x11render.c
src/video/x11/SDL_x11video.c
src/video/x11/SDL_x11window.c
src/video/x11/SDL_x11window.h
     1.1 --- a/include/SDL_video.h	Fri Jan 02 16:38:31 2009 +0000
     1.2 +++ b/include/SDL_video.h	Fri Jan 02 17:39:48 2009 +0000
     1.3 @@ -591,13 +591,13 @@
     1.4  extern DECLSPEC const char *SDLCALL SDL_GetWindowTitle(SDL_WindowID windowID);
     1.5  
     1.6  /**
     1.7 - * \fn void SDL_SetWindowIcon(SDL_Surface *icon)
     1.8 + * \fn void SDL_SetWindowIcon(SDL_WindowID windowID, SDL_Surface *icon)
     1.9   *
    1.10   * \brief Set the icon of the window.
    1.11   *
    1.12   * \param icon The icon for the window
    1.13   */
    1.14 -extern DECLSPEC void SDLCALL SDL_SetWindowIcon(SDL_Surface * icon);
    1.15 +extern DECLSPEC void SDLCALL SDL_SetWindowIcon(SDL_WindowID windowID, SDL_Surface * icon);
    1.16  
    1.17  /**
    1.18   * \fn void SDL_SetWindowData(SDL_WindowID windowID, void *userdata)
     2.1 --- a/src/SDL_compat.c	Fri Jan 02 16:38:31 2009 +0000
     2.2 +++ b/src/SDL_compat.c	Fri Jan 02 17:39:48 2009 +0000
     2.3 @@ -39,6 +39,7 @@
     2.4  static SDL_GLContext *SDL_VideoContext = NULL;
     2.5  static Uint32 SDL_VideoFlags = 0;
     2.6  static char *wm_title = NULL;
     2.7 +static SDL_Surface *SDL_VideoIcon;
     2.8  
     2.9  char *
    2.10  SDL_AudioDriverName(char *namebuf, int maxlen)
    2.11 @@ -522,6 +523,7 @@
    2.12      if (!SDL_VideoWindow) {
    2.13          return NULL;
    2.14      }
    2.15 +    SDL_SetWindowIcon(SDL_VideoWindow, SDL_VideoIcon);
    2.16  
    2.17      window_flags = SDL_GetWindowFlags(SDL_VideoWindow);
    2.18      surface_flags = 0;
    2.19 @@ -868,7 +870,7 @@
    2.20  void
    2.21  SDL_WM_SetIcon(SDL_Surface * icon, Uint8 * mask)
    2.22  {
    2.23 -    /* FIXME */
    2.24 +    SDL_VideoIcon = icon;
    2.25  }
    2.26  
    2.27  int
     3.1 --- a/src/video/SDL_bmp.c	Fri Jan 02 16:38:31 2009 +0000
     3.2 +++ b/src/video/SDL_bmp.c	Fri Jan 02 17:39:48 2009 +0000
     3.3 @@ -397,22 +397,19 @@
     3.4              ) {
     3.5              surface = saveme;
     3.6          } else {
     3.7 -            SDL_PixelFormat *format;
     3.8 +            SDL_PixelFormat format;
     3.9  
    3.10              /* Convert to 24 bits per pixel */
    3.11 -            format = SDL_AllocFormat(24,
    3.12 +            SDL_InitFormat(&format, 24,
    3.13  #if SDL_BYTEORDER == SDL_LIL_ENDIAN
    3.14 -                                     0x00FF0000, 0x0000FF00, 0x000000FF,
    3.15 +                           0x00FF0000, 0x0000FF00, 0x000000FF,
    3.16  #else
    3.17 -                                     0x000000FF, 0x0000FF00, 0x00FF0000,
    3.18 +                           0x000000FF, 0x0000FF00, 0x00FF0000,
    3.19  #endif
    3.20 -                                     0);
    3.21 -            if (format != NULL) {
    3.22 -                surface = SDL_ConvertSurface(saveme, format, 0);
    3.23 -                if (!surface) {
    3.24 -                    SDL_SetError("Couldn't convert image to 24 bpp");
    3.25 -                }
    3.26 -                SDL_FreeFormat(format);
    3.27 +                           0);
    3.28 +            surface = SDL_ConvertSurface(saveme, &format, 0);
    3.29 +            if (!surface) {
    3.30 +                SDL_SetError("Couldn't convert image to 24 bpp");
    3.31              }
    3.32          }
    3.33      }
     4.1 --- a/src/video/SDL_pixels.c	Fri Jan 02 16:38:31 2009 +0000
     4.2 +++ b/src/video/SDL_pixels.c	Fri Jan 02 17:39:48 2009 +0000
     4.3 @@ -347,16 +347,25 @@
     4.4                  Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
     4.5  {
     4.6      SDL_PixelFormat *format;
     4.7 -    Uint32 mask;
     4.8  
     4.9      /* Allocate an empty pixel format structure */
    4.10 -    format = SDL_calloc(1, sizeof(*format));
    4.11 +    format = SDL_malloc(sizeof(*format));
    4.12      if (format == NULL) {
    4.13          SDL_OutOfMemory();
    4.14          return (NULL);
    4.15      }
    4.16  
    4.17      /* Set up the format */
    4.18 +    return SDL_InitFormat(format, bpp, Rmask, Gmask, Bmask, Amask);
    4.19 +}
    4.20 +
    4.21 +SDL_PixelFormat *
    4.22 +SDL_InitFormat(SDL_PixelFormat *format, int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
    4.23 +{
    4.24 +    Uint32 mask;
    4.25 +
    4.26 +    /* Set up the format */
    4.27 +    SDL_zerop(format);
    4.28      format->BitsPerPixel = bpp;
    4.29      format->BytesPerPixel = (bpp + 7) / 8;
    4.30      if (Rmask || Bmask || Gmask) {      /* Packed pixels with custom mask */
    4.31 @@ -426,7 +435,7 @@
    4.32      }
    4.33      format->palette = NULL;
    4.34  
    4.35 -    return (format);
    4.36 +    return format;
    4.37  }
    4.38  
    4.39  /*
     5.1 --- a/src/video/SDL_pixels_c.h	Fri Jan 02 16:38:31 2009 +0000
     5.2 +++ b/src/video/SDL_pixels_c.h	Fri Jan 02 17:39:48 2009 +0000
     5.3 @@ -29,6 +29,9 @@
     5.4  extern SDL_PixelFormat *SDL_AllocFormat(int bpp,
     5.5                                          Uint32 Rmask, Uint32 Gmask,
     5.6                                          Uint32 Bmask, Uint32 Amask);
     5.7 +extern SDL_PixelFormat *SDL_InitFormat(SDL_PixelFormat *format, int bpp,
     5.8 +                                        Uint32 Rmask, Uint32 Gmask,
     5.9 +                                        Uint32 Bmask, Uint32 Amask);
    5.10  extern void SDL_FormatChanged(SDL_Surface * surface);
    5.11  extern void SDL_FreeFormat(SDL_PixelFormat * format);
    5.12  
     6.1 --- a/src/video/SDL_sysvideo.h	Fri Jan 02 16:38:31 2009 +0000
     6.2 +++ b/src/video/SDL_sysvideo.h	Fri Jan 02 17:39:48 2009 +0000
     6.3 @@ -238,6 +238,7 @@
     6.4      int (*CreateWindow) (_THIS, SDL_Window * window);
     6.5      int (*CreateWindowFrom) (_THIS, SDL_Window * window, const void *data);
     6.6      void (*SetWindowTitle) (_THIS, SDL_Window * window);
     6.7 +    void (*SetWindowIcon) (_THIS, SDL_Window * window, SDL_Surface * icon);
     6.8      void (*SetWindowPosition) (_THIS, SDL_Window * window);
     6.9      void (*SetWindowSize) (_THIS, SDL_Window * window);
    6.10      void (*ShowWindow) (_THIS, SDL_Window * window);
     7.1 --- a/src/video/SDL_video.c	Fri Jan 02 16:38:31 2009 +0000
     7.2 +++ b/src/video/SDL_video.c	Fri Jan 02 17:39:48 2009 +0000
     7.3 @@ -966,6 +966,19 @@
     7.4  }
     7.5  
     7.6  void
     7.7 +SDL_SetWindowIcon(SDL_WindowID windowID, SDL_Surface * icon)
     7.8 +{
     7.9 +    SDL_Window *window = SDL_GetWindowFromID(windowID);
    7.10 +
    7.11 +    if (!window) {
    7.12 +        return;
    7.13 +    }
    7.14 +    if (_this->SetWindowIcon) {
    7.15 +        _this->SetWindowIcon(_this, window, icon);
    7.16 +    }
    7.17 +}
    7.18 +
    7.19 +void
    7.20  SDL_SetWindowData(SDL_WindowID windowID, void *userdata)
    7.21  {
    7.22      SDL_Window *window = SDL_GetWindowFromID(windowID);
    7.23 @@ -1590,33 +1603,30 @@
    7.24                                surface->pitch);
    7.25          }
    7.26      } else {
    7.27 -        SDL_PixelFormat *dst_fmt;
    7.28 +        SDL_PixelFormat dst_fmt;
    7.29          SDL_Surface *dst = NULL;
    7.30  
    7.31          /* Set up a destination surface for the texture update */
    7.32 -        dst_fmt = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask);
    7.33 -        if (dst_fmt) {
    7.34 -            if (SDL_ISPIXELFORMAT_INDEXED(format)) {
    7.35 -                dst_fmt->palette =
    7.36 -                    SDL_AllocPalette((1 << SDL_BITSPERPIXEL(format)));
    7.37 -                if (dst_fmt->palette) {
    7.38 -                    /*
    7.39 -                     * FIXME: Should we try to copy
    7.40 -                     * fmt->palette?
    7.41 -                     */
    7.42 -                    SDL_DitherColors(dst_fmt->palette->colors,
    7.43 -                                     SDL_BITSPERPIXEL(format));
    7.44 -                }
    7.45 +        SDL_InitFormat(&dst_fmt, bpp, Rmask, Gmask, Bmask, Amask);
    7.46 +        if (SDL_ISPIXELFORMAT_INDEXED(format)) {
    7.47 +            dst_fmt.palette =
    7.48 +                SDL_AllocPalette((1 << SDL_BITSPERPIXEL(format)));
    7.49 +            if (dst_fmt.palette) {
    7.50 +                /*
    7.51 +                 * FIXME: Should we try to copy
    7.52 +                 * fmt->palette?
    7.53 +                 */
    7.54 +                SDL_DitherColors(dst_fmt.palette->colors,
    7.55 +                                 SDL_BITSPERPIXEL(format));
    7.56              }
    7.57 -            dst = SDL_ConvertSurface(surface, dst_fmt, 0);
    7.58 -            if (dst) {
    7.59 -                SDL_UpdateTexture(textureID, NULL, dst->pixels, dst->pitch);
    7.60 -                SDL_FreeSurface(dst);
    7.61 -            }
    7.62 -            if (dst_fmt->palette) {
    7.63 -                SDL_FreePalette(dst_fmt->palette);
    7.64 -            }
    7.65 -            SDL_FreeFormat(dst_fmt);
    7.66 +        }
    7.67 +        dst = SDL_ConvertSurface(surface, &dst_fmt, 0);
    7.68 +        if (dst) {
    7.69 +            SDL_UpdateTexture(textureID, NULL, dst->pixels, dst->pitch);
    7.70 +            SDL_FreeSurface(dst);
    7.71 +        }
    7.72 +        if (dst_fmt.palette) {
    7.73 +            SDL_FreePalette(dst_fmt.palette);
    7.74          }
    7.75          if (!dst) {
    7.76              SDL_DestroyTexture(textureID);
     8.1 --- a/src/video/x11/SDL_x11render.c	Fri Jan 02 16:38:31 2009 +0000
     8.2 +++ b/src/video/x11/SDL_x11render.c	Fri Jan 02 17:39:48 2009 +0000
     8.3 @@ -87,7 +87,7 @@
     8.4      Pixmap pixmaps[3];
     8.5      int current_pixmap;
     8.6      Drawable drawable;
     8.7 -    SDL_PixelFormat *format;
     8.8 +    SDL_PixelFormat format;
     8.9      GC gc;
    8.10      SDL_DirtyRectList dirty;
    8.11      SDL_bool makedirty;
    8.12 @@ -251,11 +251,7 @@
    8.13          X11_DestroyRenderer(renderer);
    8.14          return NULL;
    8.15      }
    8.16 -    data->format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask);
    8.17 -    if (!data->format) {
    8.18 -        X11_DestroyRenderer(renderer);
    8.19 -        return NULL;
    8.20 -    }
    8.21 +    SDL_InitFormat(&data->format, bpp, Rmask, Gmask, Bmask, Amask);
    8.22  
    8.23      /* Create the drawing context */
    8.24      gcv.graphics_exposures = False;
    8.25 @@ -583,11 +579,11 @@
    8.26      Uint8 b = renderer->b;
    8.27      Uint8 a = renderer->a;
    8.28      if (premult)
    8.29 -        return SDL_MapRGBA(data->format, ((int) r * (int) a) / 255,
    8.30 +        return SDL_MapRGBA(&data->format, ((int) r * (int) a) / 255,
    8.31                             ((int) g * (int) a) / 255,
    8.32                             ((int) b * (int) a) / 255, 255);
    8.33      else
    8.34 -        return SDL_MapRGBA(data->format, r, g, b, a);
    8.35 +        return SDL_MapRGBA(&data->format, r, g, b, a);
    8.36  }
    8.37  
    8.38  static int
    8.39 @@ -852,9 +848,6 @@
    8.40                  XFreePixmap(data->display, data->pixmaps[i]);
    8.41              }
    8.42          }
    8.43 -        if (data->format) {
    8.44 -            SDL_FreeFormat(data->format);
    8.45 -        }
    8.46          if (data->gc) {
    8.47              XFreeGC(data->display, data->gc);
    8.48          }
     9.1 --- a/src/video/x11/SDL_x11video.c	Fri Jan 02 16:38:31 2009 +0000
     9.2 +++ b/src/video/x11/SDL_x11video.c	Fri Jan 02 17:39:48 2009 +0000
     9.3 @@ -174,6 +174,7 @@
     9.4      device->CreateWindow = X11_CreateWindow;
     9.5      device->CreateWindowFrom = X11_CreateWindowFrom;
     9.6      device->SetWindowTitle = X11_SetWindowTitle;
     9.7 +    device->SetWindowIcon = X11_SetWindowIcon;
     9.8      device->SetWindowPosition = X11_SetWindowPosition;
     9.9      device->SetWindowSize = X11_SetWindowSize;
    9.10      device->ShowWindow = X11_ShowWindow;
    10.1 --- a/src/video/x11/SDL_x11window.c	Fri Jan 02 16:38:31 2009 +0000
    10.2 +++ b/src/video/x11/SDL_x11window.c	Fri Jan 02 17:39:48 2009 +0000
    10.3 @@ -646,6 +646,43 @@
    10.4  }
    10.5  
    10.6  void
    10.7 +X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
    10.8 +{
    10.9 +    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
   10.10 +    Display *display = data->videodata->display;
   10.11 +    Atom _NET_WM_ICON = XInternAtom(display, "_NET_WM_ICON", False);
   10.12 +
   10.13 +    if (icon) {
   10.14 +        SDL_PixelFormat format;
   10.15 +        SDL_Surface *surface;
   10.16 +        int propsize;
   10.17 +        Uint32 *propdata;
   10.18 +
   10.19 +        /* Convert the icon to ARGB for modern window managers */
   10.20 +        SDL_InitFormat(&format, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
   10.21 +        surface = SDL_ConvertSurface(icon, &format, 0);
   10.22 +        if (!surface) {
   10.23 +            return;
   10.24 +        }
   10.25 +
   10.26 +        /* Set the _NET_WM_ICON property */
   10.27 +        propsize = 2+(icon->w*icon->h);
   10.28 +        propdata = SDL_malloc(propsize * sizeof(Uint32));
   10.29 +        if (propdata) {
   10.30 +            propdata[0] = icon->w;
   10.31 +            propdata[1] = icon->h;
   10.32 +            SDL_memcpy(&propdata[2], surface->pixels, surface->h*surface->pitch);
   10.33 +            XChangeProperty(display, data->window, _NET_WM_ICON, 
   10.34 +                            XA_CARDINAL, 32, PropModeReplace,
   10.35 +                            (unsigned char *) propdata, propsize);
   10.36 +        }
   10.37 +        SDL_FreeSurface(surface);
   10.38 +    } else {
   10.39 +        XDeleteProperty(display, data->window, _NET_WM_ICON);
   10.40 +    }
   10.41 +}
   10.42 +
   10.43 +void
   10.44  X11_SetWindowPosition(_THIS, SDL_Window * window)
   10.45  {
   10.46      SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
    11.1 --- a/src/video/x11/SDL_x11window.h	Fri Jan 02 16:38:31 2009 +0000
    11.2 +++ b/src/video/x11/SDL_x11window.h	Fri Jan 02 17:39:48 2009 +0000
    11.3 @@ -36,6 +36,7 @@
    11.4  extern int X11_CreateWindow(_THIS, SDL_Window * window);
    11.5  extern int X11_CreateWindowFrom(_THIS, SDL_Window * window, const void *data);
    11.6  extern void X11_SetWindowTitle(_THIS, SDL_Window * window);
    11.7 +extern void X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon);
    11.8  extern void X11_SetWindowPosition(_THIS, SDL_Window * window);
    11.9  extern void X11_SetWindowSize(_THIS, SDL_Window * window);
   11.10  extern void X11_ShowWindow(_THIS, SDL_Window * window);