src/video/cocoa/SDL_cocoavideo.m
author Ryan C. Gordon <icculus@icculus.org>
Tue, 05 Jan 2016 02:46:10 -0500
changeset 10025 bf4f8cde1c54
parent 10019 36f7e8084508
child 10038 2bab6f8d403e
permissions -rw-r--r--
Added SDL_SetWindowOpacity() and SDL_GetWindowOpacity().

This is currently implemented for X11, Cocoa, Windows, and DirectFB.

This patch is based on work in Unreal Engine 4's fork of SDL,
compliments of Epic Games.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 #include "../../SDL_internal.h"
    22 
    23 #if SDL_VIDEO_DRIVER_COCOA
    24 
    25 #include "SDL.h"
    26 #include "SDL_endian.h"
    27 #include "SDL_cocoavideo.h"
    28 #include "SDL_cocoashape.h"
    29 #include "SDL_assert.h"
    30 
    31 /* Initialization/Query functions */
    32 static int Cocoa_VideoInit(_THIS);
    33 static void Cocoa_VideoQuit(_THIS);
    34 
    35 /* Cocoa driver bootstrap functions */
    36 
    37 static int
    38 Cocoa_Available(void)
    39 {
    40     return (1);
    41 }
    42 
    43 static void
    44 Cocoa_DeleteDevice(SDL_VideoDevice * device)
    45 {
    46     SDL_free(device->driverdata);
    47     SDL_free(device);
    48 }
    49 
    50 static SDL_VideoDevice *
    51 Cocoa_CreateDevice(int devindex)
    52 {
    53     SDL_VideoDevice *device;
    54     SDL_VideoData *data;
    55 
    56     Cocoa_RegisterApp();
    57 
    58     /* Initialize all variables that we clean on shutdown */
    59     device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
    60     if (device) {
    61         data = (struct SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
    62     } else {
    63         data = NULL;
    64     }
    65     if (!data) {
    66         SDL_OutOfMemory();
    67         SDL_free(device);
    68         return NULL;
    69     }
    70     device->driverdata = data;
    71 
    72     /* Set the function pointers */
    73     device->VideoInit = Cocoa_VideoInit;
    74     device->VideoQuit = Cocoa_VideoQuit;
    75     device->GetDisplayBounds = Cocoa_GetDisplayBounds;
    76     device->GetDisplayUsableBounds = Cocoa_GetDisplayUsableBounds;
    77     device->GetDisplayModes = Cocoa_GetDisplayModes;
    78     device->SetDisplayMode = Cocoa_SetDisplayMode;
    79     device->PumpEvents = Cocoa_PumpEvents;
    80     device->SuspendScreenSaver = Cocoa_SuspendScreenSaver;
    81 
    82     device->CreateWindow = Cocoa_CreateWindow;
    83     device->CreateWindowFrom = Cocoa_CreateWindowFrom;
    84     device->SetWindowTitle = Cocoa_SetWindowTitle;
    85     device->SetWindowIcon = Cocoa_SetWindowIcon;
    86     device->SetWindowPosition = Cocoa_SetWindowPosition;
    87     device->SetWindowSize = Cocoa_SetWindowSize;
    88     device->SetWindowMinimumSize = Cocoa_SetWindowMinimumSize;
    89     device->SetWindowMaximumSize = Cocoa_SetWindowMaximumSize;
    90     device->SetWindowOpacity = Cocoa_SetWindowOpacity;
    91     device->ShowWindow = Cocoa_ShowWindow;
    92     device->HideWindow = Cocoa_HideWindow;
    93     device->RaiseWindow = Cocoa_RaiseWindow;
    94     device->MaximizeWindow = Cocoa_MaximizeWindow;
    95     device->MinimizeWindow = Cocoa_MinimizeWindow;
    96     device->RestoreWindow = Cocoa_RestoreWindow;
    97     device->SetWindowBordered = Cocoa_SetWindowBordered;
    98     device->SetWindowFullscreen = Cocoa_SetWindowFullscreen;
    99     device->SetWindowGammaRamp = Cocoa_SetWindowGammaRamp;
   100     device->GetWindowGammaRamp = Cocoa_GetWindowGammaRamp;
   101     device->SetWindowGrab = Cocoa_SetWindowGrab;
   102     device->DestroyWindow = Cocoa_DestroyWindow;
   103     device->GetWindowWMInfo = Cocoa_GetWindowWMInfo;
   104     device->SetWindowHitTest = Cocoa_SetWindowHitTest;
   105 
   106     device->shape_driver.CreateShaper = Cocoa_CreateShaper;
   107     device->shape_driver.SetWindowShape = Cocoa_SetWindowShape;
   108     device->shape_driver.ResizeWindowShape = Cocoa_ResizeWindowShape;
   109 
   110 #if SDL_VIDEO_OPENGL_CGL
   111     device->GL_LoadLibrary = Cocoa_GL_LoadLibrary;
   112     device->GL_GetProcAddress = Cocoa_GL_GetProcAddress;
   113     device->GL_UnloadLibrary = Cocoa_GL_UnloadLibrary;
   114     device->GL_CreateContext = Cocoa_GL_CreateContext;
   115     device->GL_MakeCurrent = Cocoa_GL_MakeCurrent;
   116     device->GL_GetDrawableSize = Cocoa_GL_GetDrawableSize;
   117     device->GL_SetSwapInterval = Cocoa_GL_SetSwapInterval;
   118     device->GL_GetSwapInterval = Cocoa_GL_GetSwapInterval;
   119     device->GL_SwapWindow = Cocoa_GL_SwapWindow;
   120     device->GL_DeleteContext = Cocoa_GL_DeleteContext;
   121 #endif
   122 
   123     device->StartTextInput = Cocoa_StartTextInput;
   124     device->StopTextInput = Cocoa_StopTextInput;
   125     device->SetTextInputRect = Cocoa_SetTextInputRect;
   126 
   127     device->SetClipboardText = Cocoa_SetClipboardText;
   128     device->GetClipboardText = Cocoa_GetClipboardText;
   129     device->HasClipboardText = Cocoa_HasClipboardText;
   130 
   131     device->free = Cocoa_DeleteDevice;
   132 
   133     return device;
   134 }
   135 
   136 VideoBootStrap COCOA_bootstrap = {
   137     "cocoa", "SDL Cocoa video driver",
   138     Cocoa_Available, Cocoa_CreateDevice
   139 };
   140 
   141 
   142 int
   143 Cocoa_VideoInit(_THIS)
   144 {
   145     SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
   146 
   147     Cocoa_InitModes(_this);
   148     Cocoa_InitKeyboard(_this);
   149     Cocoa_InitMouse(_this);
   150 
   151     const char *hint = SDL_GetHint(SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES);
   152     data->allow_spaces = ( (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) && (!hint || (*hint != '0')) );
   153 
   154     /* The IOPM assertion API can disable the screensaver as of 10.7. */
   155     data->screensaver_use_iopm = floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6;
   156 
   157     return 0;
   158 }
   159 
   160 void
   161 Cocoa_VideoQuit(_THIS)
   162 {
   163     Cocoa_QuitModes(_this);
   164     Cocoa_QuitKeyboard(_this);
   165     Cocoa_QuitMouse(_this);
   166 }
   167 
   168 /* This function assumes that it's called from within an autorelease pool */
   169 NSImage *
   170 Cocoa_CreateImage(SDL_Surface * surface)
   171 {
   172     SDL_Surface *converted;
   173     NSBitmapImageRep *imgrep;
   174     Uint8 *pixels;
   175     int i;
   176     NSImage *img;
   177 
   178     converted = SDL_ConvertSurfaceFormat(surface,
   179 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
   180                                          SDL_PIXELFORMAT_RGBA8888,
   181 #else
   182                                          SDL_PIXELFORMAT_ABGR8888,
   183 #endif
   184                                          0);
   185     if (!converted) {
   186         return nil;
   187     }
   188 
   189     imgrep = [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
   190                     pixelsWide: converted->w
   191                     pixelsHigh: converted->h
   192                     bitsPerSample: 8
   193                     samplesPerPixel: 4
   194                     hasAlpha: YES
   195                     isPlanar: NO
   196                     colorSpaceName: NSDeviceRGBColorSpace
   197                     bytesPerRow: converted->pitch
   198                     bitsPerPixel: converted->format->BitsPerPixel] autorelease];
   199     if (imgrep == nil) {
   200         SDL_FreeSurface(converted);
   201         return nil;
   202     }
   203 
   204     /* Copy the pixels */
   205     pixels = [imgrep bitmapData];
   206     SDL_memcpy(pixels, converted->pixels, converted->h * converted->pitch);
   207     SDL_FreeSurface(converted);
   208 
   209     /* Premultiply the alpha channel */
   210     for (i = (surface->h * surface->w); i--; ) {
   211         Uint8 alpha = pixels[3];
   212         pixels[0] = (Uint8)(((Uint16)pixels[0] * alpha) / 255);
   213         pixels[1] = (Uint8)(((Uint16)pixels[1] * alpha) / 255);
   214         pixels[2] = (Uint8)(((Uint16)pixels[2] * alpha) / 255);
   215         pixels += 4;
   216     }
   217 
   218     img = [[[NSImage alloc] initWithSize: NSMakeSize(surface->w, surface->h)] autorelease];
   219     if (img != nil) {
   220         [img addRepresentation: imgrep];
   221     }
   222     return img;
   223 }
   224 
   225 /*
   226  * Mac OS X log support.
   227  *
   228  * This doesn't really have aything to do with the interfaces of the SDL video
   229  *  subsystem, but we need to stuff this into an Objective-C source code file.
   230  */
   231 
   232 void SDL_NSLog(const char *text)
   233 {
   234     NSLog(@"%s", text);
   235 }
   236 
   237 #endif /* SDL_VIDEO_DRIVER_COCOA */
   238 
   239 /* vim: set ts=4 sw=4 expandtab: */