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