From f5c24e8c9e789cc3bc4ec074f97cb776ca30abb5 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 21 Feb 2011 16:45:23 -0800 Subject: [PATCH] Implemented Cocoa_SetWindowIcon(), added SDL_ConvertSurfaceFormat() --- include/SDL_surface.h | 2 ++ src/video/SDL_surface.c | 15 ++++++++ src/video/SDL_video.c | 4 +++ src/video/cocoa/SDL_cocoavideo.h | 3 ++ src/video/cocoa/SDL_cocoavideo.m | 58 +++++++++++++++++++++++++++++++ src/video/cocoa/SDL_cocoawindow.h | 1 + src/video/cocoa/SDL_cocoawindow.m | 13 +++++++ 7 files changed, 96 insertions(+) diff --git a/include/SDL_surface.h b/include/SDL_surface.h index 08e68fd48..25f64d270 100644 --- a/include/SDL_surface.h +++ b/include/SDL_surface.h @@ -351,6 +351,8 @@ extern DECLSPEC void SDLCALL SDL_GetClipRect(SDL_Surface * surface, */ 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 diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c index 48d2ee7b7..b9c07b06a 100644 --- a/src/video/SDL_surface.c +++ b/src/video/SDL_surface.c @@ -814,6 +814,21 @@ SDL_ConvertSurface(SDL_Surface * surface, SDL_PixelFormat * format, 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 */ diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 3548f9bde..d7778eda8 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -1300,6 +1300,10 @@ SDL_SetWindowIcon(SDL_Window * window, SDL_Surface * icon) { CHECK_WINDOW_MAGIC(window, ); + if (!icon) { + return; + } + if (_this->SetWindowIcon) { _this->SetWindowIcon(_this, window, icon); } diff --git a/src/video/cocoa/SDL_cocoavideo.h b/src/video/cocoa/SDL_cocoavideo.h index 2d301c071..9c9d7c0ff 100644 --- a/src/video/cocoa/SDL_cocoavideo.h +++ b/src/video/cocoa/SDL_cocoavideo.h @@ -64,6 +64,9 @@ typedef struct SDL_VideoData Uint32 screensaver_activity; } SDL_VideoData; +/* Utility functions */ +NSImage * Cocoa_CreateImage(SDL_Surface * surface); + #endif /* _SDL_cocoavideo_h */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/cocoa/SDL_cocoavideo.m b/src/video/cocoa/SDL_cocoavideo.m index a4bcab190..52d19c5c3 100644 --- a/src/video/cocoa/SDL_cocoavideo.m +++ b/src/video/cocoa/SDL_cocoavideo.m @@ -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. diff --git a/src/video/cocoa/SDL_cocoawindow.h b/src/video/cocoa/SDL_cocoawindow.h index 5e0ebaded..10465037e 100644 --- a/src/video/cocoa/SDL_cocoawindow.h +++ b/src/video/cocoa/SDL_cocoawindow.h @@ -96,6 +96,7 @@ extern int Cocoa_CreateWindow(_THIS, SDL_Window * window); 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); diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m index 1db11457a..e660a0cce 100644 --- a/src/video/cocoa/SDL_cocoawindow.m +++ b/src/video/cocoa/SDL_cocoawindow.m @@ -636,6 +636,19 @@ - (void)rightMouseDown:(NSEvent *)theEvent [pool release]; } +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) {