Implemented Cocoa_SetWindowIcon(), added SDL_ConvertSurfaceFormat()
authorSam Lantinga <slouken@libsdl.org>
Mon, 21 Feb 2011 16:45:23 -0800
changeset 5375 16877f74123c
parent 5374 dacb4f5e0dd3
child 5376 183ec2d4485c
Implemented Cocoa_SetWindowIcon(), added SDL_ConvertSurfaceFormat()
include/SDL_surface.h
src/video/SDL_surface.c
src/video/SDL_video.c
src/video/cocoa/SDL_cocoavideo.h
src/video/cocoa/SDL_cocoavideo.m
src/video/cocoa/SDL_cocoawindow.h
src/video/cocoa/SDL_cocoawindow.m
--- a/include/SDL_surface.h	Mon Feb 21 15:25:49 2011 -0800
+++ b/include/SDL_surface.h	Mon Feb 21 16:45:23 2011 -0800
@@ -351,6 +351,8 @@
  */
 extern DECLSPEC SDL_Surface *SDLCALL SDL_ConvertSurface
     (SDL_Surface * src, SDL_PixelFormat * fmt, Uint32 flags);
+extern DECLSPEC SDL_Surface *SDLCALL SDL_ConvertSurfaceFormat
+    (SDL_Surface * src, Uint32 pixel_format, Uint32 flags);
 
 /**
  * \brief Copy a block of pixels of one format to another format
--- a/src/video/SDL_surface.c	Mon Feb 21 15:25:49 2011 -0800
+++ b/src/video/SDL_surface.c	Mon Feb 21 16:45:23 2011 -0800
@@ -814,6 +814,21 @@
     return (convert);
 }
 
+SDL_Surface *
+SDL_ConvertSurfaceFormat(SDL_Surface * surface, Uint32 pixel_format,
+                         Uint32 flags)
+{
+    SDL_PixelFormat *fmt;
+    SDL_Surface *convert;
+
+    fmt = SDL_AllocFormat(pixel_format);
+    if (fmt) {
+        convert = SDL_ConvertSurface(surface, fmt, flags);
+        SDL_FreeFormat(fmt);
+    }
+    return convert;
+}
+
 /*
  * Create a surface on the stack for quick blit operations
  */
--- a/src/video/SDL_video.c	Mon Feb 21 15:25:49 2011 -0800
+++ b/src/video/SDL_video.c	Mon Feb 21 16:45:23 2011 -0800
@@ -1300,6 +1300,10 @@
 {
     CHECK_WINDOW_MAGIC(window, );
 
+    if (!icon) {
+        return;
+    }
+
     if (_this->SetWindowIcon) {
         _this->SetWindowIcon(_this, window, icon);
     }
--- a/src/video/cocoa/SDL_cocoavideo.h	Mon Feb 21 15:25:49 2011 -0800
+++ b/src/video/cocoa/SDL_cocoavideo.h	Mon Feb 21 16:45:23 2011 -0800
@@ -64,6 +64,9 @@
     Uint32 screensaver_activity;
 } SDL_VideoData;
 
+/* Utility functions */
+NSImage * Cocoa_CreateImage(SDL_Surface * surface);
+
 #endif /* _SDL_cocoavideo_h */
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/cocoa/SDL_cocoavideo.m	Mon Feb 21 15:25:49 2011 -0800
+++ b/src/video/cocoa/SDL_cocoavideo.m	Mon Feb 21 16:45:23 2011 -0800
@@ -21,6 +21,7 @@
 */
 #include "SDL_config.h"
 
+#include "SDL_endian.h"
 #include "SDL_cocoavideo.h"
 #include "SDL_cocoashape.h"
 #include "SDL_assert.h"
@@ -82,6 +83,7 @@
     device->CreateWindow = Cocoa_CreateWindow;
     device->CreateWindowFrom = Cocoa_CreateWindowFrom;
     device->SetWindowTitle = Cocoa_SetWindowTitle;
+    device->SetWindowIcon = Cocoa_SetWindowIcon;
     device->SetWindowPosition = Cocoa_SetWindowPosition;
     device->SetWindowSize = Cocoa_SetWindowSize;
     device->ShowWindow = Cocoa_ShowWindow;
@@ -147,6 +149,62 @@
     Cocoa_QuitMouse(_this);
 }
 
+/* This function assumes that it's called from within an autorelease pool */
+NSImage *
+Cocoa_CreateImage(SDL_Surface * surface)
+{
+    SDL_Surface *converted;
+    NSBitmapImageRep *imgrep;
+    Uint8 *pixels;
+    int i;
+    NSImage *img;
+
+    converted = SDL_ConvertSurfaceFormat(surface, 
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+                                         SDL_PIXELFORMAT_RGBA8888,
+#else
+                                         SDL_PIXELFORMAT_ABGR8888,
+#endif
+                                         0);
+    if (!converted) {
+        return nil;
+    }
+
+    imgrep = [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
+                    pixelsWide: converted->w
+                    pixelsHigh: converted->h
+                    bitsPerSample: 8
+                    samplesPerPixel: 4
+                    hasAlpha: YES
+                    isPlanar: NO
+                    colorSpaceName: NSDeviceRGBColorSpace
+                    bytesPerRow: converted->pitch
+                    bitsPerPixel: converted->format->BitsPerPixel] autorelease];
+    if (imgrep == nil) {
+        SDL_FreeSurface(converted);
+        return nil;
+    }
+
+    /* Copy the pixels */
+    pixels = [imgrep bitmapData];
+    SDL_memcpy(pixels, converted->pixels, converted->h * converted->pitch);
+    SDL_FreeSurface(converted);
+
+    /* Premultiply the alpha channel */
+    for (i = (converted->h * converted->w); i--; ) {
+        Uint8 alpha = pixels[3];
+        pixels[0] = (Uint8)(((Uint16)pixels[0] * alpha) / 255);
+        pixels[1] = (Uint8)(((Uint16)pixels[1] * alpha) / 255);
+        pixels[2] = (Uint8)(((Uint16)pixels[2] * alpha) / 255);
+        pixels += 4;
+    }
+
+    img = [[[NSImage alloc] initWithSize: NSMakeSize(surface->w, surface->h)] autorelease];
+    if (img != nil) {
+        [img addRepresentation: imgrep];
+    }
+    return img;
+}
 
 /*
  * Mac OS X assertion support.
--- a/src/video/cocoa/SDL_cocoawindow.h	Mon Feb 21 15:25:49 2011 -0800
+++ b/src/video/cocoa/SDL_cocoawindow.h	Mon Feb 21 16:45:23 2011 -0800
@@ -96,6 +96,7 @@
 extern int Cocoa_CreateWindowFrom(_THIS, SDL_Window * window,
                                   const void *data);
 extern void Cocoa_SetWindowTitle(_THIS, SDL_Window * window);
+extern void Cocoa_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon);
 extern void Cocoa_SetWindowPosition(_THIS, SDL_Window * window);
 extern void Cocoa_SetWindowSize(_THIS, SDL_Window * window);
 extern void Cocoa_ShowWindow(_THIS, SDL_Window * window);
--- a/src/video/cocoa/SDL_cocoawindow.m	Mon Feb 21 15:25:49 2011 -0800
+++ b/src/video/cocoa/SDL_cocoawindow.m	Mon Feb 21 16:45:23 2011 -0800
@@ -637,6 +637,19 @@
 }
 
 void
+Cocoa_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
+{
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    NSImage *nsimage = Cocoa_CreateImage(icon);
+
+    if (nsimage) {
+        [NSApp setApplicationIconImage:nsimage];
+    }
+
+    [pool release];
+}
+
+void
 Cocoa_SetWindowPosition(_THIS, SDL_Window * window)
 {
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];