src/video/cocoa/SDL_cocoavideo.m
author Sam Lantinga <slouken@libsdl.org>
Sat, 02 Jan 2016 10:10:34 -0800
changeset 9998 f67cf37e9cd4
parent 9619 b94b6d0bff0f
child 10019 36f7e8084508
permissions -rw-r--r--
Updated copyright to 2016
     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->GetDisplayModes = Cocoa_GetDisplayModes;
    77     device->SetDisplayMode = Cocoa_SetDisplayMode;
    78     device->PumpEvents = Cocoa_PumpEvents;
    79     device->SuspendScreenSaver = Cocoa_SuspendScreenSaver;
    80 
    81     device->CreateWindow = Cocoa_CreateWindow;
    82     device->CreateWindowFrom = Cocoa_CreateWindowFrom;
    83     device->SetWindowTitle = Cocoa_SetWindowTitle;
    84     device->SetWindowIcon = Cocoa_SetWindowIcon;
    85     device->SetWindowPosition = Cocoa_SetWindowPosition;
    86     device->SetWindowSize = Cocoa_SetWindowSize;
    87     device->SetWindowMinimumSize = Cocoa_SetWindowMinimumSize;
    88     device->SetWindowMaximumSize = Cocoa_SetWindowMaximumSize;
    89     device->ShowWindow = Cocoa_ShowWindow;
    90     device->HideWindow = Cocoa_HideWindow;
    91     device->RaiseWindow = Cocoa_RaiseWindow;
    92     device->MaximizeWindow = Cocoa_MaximizeWindow;
    93     device->MinimizeWindow = Cocoa_MinimizeWindow;
    94     device->RestoreWindow = Cocoa_RestoreWindow;
    95     device->SetWindowBordered = Cocoa_SetWindowBordered;
    96     device->SetWindowFullscreen = Cocoa_SetWindowFullscreen;
    97     device->SetWindowGammaRamp = Cocoa_SetWindowGammaRamp;
    98     device->GetWindowGammaRamp = Cocoa_GetWindowGammaRamp;
    99     device->SetWindowGrab = Cocoa_SetWindowGrab;
   100     device->DestroyWindow = Cocoa_DestroyWindow;
   101     device->GetWindowWMInfo = Cocoa_GetWindowWMInfo;
   102     device->SetWindowHitTest = Cocoa_SetWindowHitTest;
   103 
   104     device->shape_driver.CreateShaper = Cocoa_CreateShaper;
   105     device->shape_driver.SetWindowShape = Cocoa_SetWindowShape;
   106     device->shape_driver.ResizeWindowShape = Cocoa_ResizeWindowShape;
   107 
   108 #if SDL_VIDEO_OPENGL_CGL
   109     device->GL_LoadLibrary = Cocoa_GL_LoadLibrary;
   110     device->GL_GetProcAddress = Cocoa_GL_GetProcAddress;
   111     device->GL_UnloadLibrary = Cocoa_GL_UnloadLibrary;
   112     device->GL_CreateContext = Cocoa_GL_CreateContext;
   113     device->GL_MakeCurrent = Cocoa_GL_MakeCurrent;
   114     device->GL_GetDrawableSize = Cocoa_GL_GetDrawableSize;
   115     device->GL_SetSwapInterval = Cocoa_GL_SetSwapInterval;
   116     device->GL_GetSwapInterval = Cocoa_GL_GetSwapInterval;
   117     device->GL_SwapWindow = Cocoa_GL_SwapWindow;
   118     device->GL_DeleteContext = Cocoa_GL_DeleteContext;
   119 #endif
   120 
   121     device->StartTextInput = Cocoa_StartTextInput;
   122     device->StopTextInput = Cocoa_StopTextInput;
   123     device->SetTextInputRect = Cocoa_SetTextInputRect;
   124 
   125     device->SetClipboardText = Cocoa_SetClipboardText;
   126     device->GetClipboardText = Cocoa_GetClipboardText;
   127     device->HasClipboardText = Cocoa_HasClipboardText;
   128 
   129     device->free = Cocoa_DeleteDevice;
   130 
   131     return device;
   132 }
   133 
   134 VideoBootStrap COCOA_bootstrap = {
   135     "cocoa", "SDL Cocoa video driver",
   136     Cocoa_Available, Cocoa_CreateDevice
   137 };
   138 
   139 
   140 int
   141 Cocoa_VideoInit(_THIS)
   142 {
   143     SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
   144 
   145     Cocoa_InitModes(_this);
   146     Cocoa_InitKeyboard(_this);
   147     Cocoa_InitMouse(_this);
   148 
   149     const char *hint = SDL_GetHint(SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES);
   150     data->allow_spaces = ( (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) && (!hint || (*hint != '0')) );
   151 
   152     /* The IOPM assertion API can disable the screensaver as of 10.7. */
   153     data->screensaver_use_iopm = floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6;
   154 
   155     return 0;
   156 }
   157 
   158 void
   159 Cocoa_VideoQuit(_THIS)
   160 {
   161     Cocoa_QuitModes(_this);
   162     Cocoa_QuitKeyboard(_this);
   163     Cocoa_QuitMouse(_this);
   164 }
   165 
   166 /* This function assumes that it's called from within an autorelease pool */
   167 NSImage *
   168 Cocoa_CreateImage(SDL_Surface * surface)
   169 {
   170     SDL_Surface *converted;
   171     NSBitmapImageRep *imgrep;
   172     Uint8 *pixels;
   173     int i;
   174     NSImage *img;
   175 
   176     converted = SDL_ConvertSurfaceFormat(surface,
   177 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
   178                                          SDL_PIXELFORMAT_RGBA8888,
   179 #else
   180                                          SDL_PIXELFORMAT_ABGR8888,
   181 #endif
   182                                          0);
   183     if (!converted) {
   184         return nil;
   185     }
   186 
   187     imgrep = [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
   188                     pixelsWide: converted->w
   189                     pixelsHigh: converted->h
   190                     bitsPerSample: 8
   191                     samplesPerPixel: 4
   192                     hasAlpha: YES
   193                     isPlanar: NO
   194                     colorSpaceName: NSDeviceRGBColorSpace
   195                     bytesPerRow: converted->pitch
   196                     bitsPerPixel: converted->format->BitsPerPixel] autorelease];
   197     if (imgrep == nil) {
   198         SDL_FreeSurface(converted);
   199         return nil;
   200     }
   201 
   202     /* Copy the pixels */
   203     pixels = [imgrep bitmapData];
   204     SDL_memcpy(pixels, converted->pixels, converted->h * converted->pitch);
   205     SDL_FreeSurface(converted);
   206 
   207     /* Premultiply the alpha channel */
   208     for (i = (surface->h * surface->w); i--; ) {
   209         Uint8 alpha = pixels[3];
   210         pixels[0] = (Uint8)(((Uint16)pixels[0] * alpha) / 255);
   211         pixels[1] = (Uint8)(((Uint16)pixels[1] * alpha) / 255);
   212         pixels[2] = (Uint8)(((Uint16)pixels[2] * alpha) / 255);
   213         pixels += 4;
   214     }
   215 
   216     img = [[[NSImage alloc] initWithSize: NSMakeSize(surface->w, surface->h)] autorelease];
   217     if (img != nil) {
   218         [img addRepresentation: imgrep];
   219     }
   220     return img;
   221 }
   222 
   223 /*
   224  * Mac OS X log support.
   225  *
   226  * This doesn't really have aything to do with the interfaces of the SDL video
   227  *  subsystem, but we need to stuff this into an Objective-C source code file.
   228  */
   229 
   230 void SDL_NSLog(const char *text)
   231 {
   232     NSLog(@"%s", text);
   233 }
   234 
   235 #endif /* SDL_VIDEO_DRIVER_COCOA */
   236 
   237 /* vim: set ts=4 sw=4 expandtab: */