src/video/cocoa/SDL_cocoavideo.m
author Ryan C. Gordon <icculus@icculus.org>
Mon, 03 Mar 2014 21:25:16 -0500
changeset 8295 56f7e38ff0bc
parent 8149 681eb46b8ac4
child 8931 44d8a2f4b431
permissions -rw-r--r--
Mac: Added a hint to opt-out of new Spaces code.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2014 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 #if defined(__APPLE__) && defined(__POWERPC__) && !defined(__APPLE_ALTIVEC__)
    26 #include <altivec.h>
    27 #undef bool
    28 #undef vector
    29 #undef pixel
    30 #endif
    31 
    32 #include "SDL.h"
    33 #include "SDL_endian.h"
    34 #include "SDL_cocoavideo.h"
    35 #include "SDL_cocoashape.h"
    36 #include "SDL_assert.h"
    37 
    38 /* Initialization/Query functions */
    39 static int Cocoa_VideoInit(_THIS);
    40 static void Cocoa_VideoQuit(_THIS);
    41 
    42 /* Cocoa driver bootstrap functions */
    43 
    44 static int
    45 Cocoa_Available(void)
    46 {
    47     return (1);
    48 }
    49 
    50 static void
    51 Cocoa_DeleteDevice(SDL_VideoDevice * device)
    52 {
    53     SDL_free(device->driverdata);
    54     SDL_free(device);
    55 }
    56 
    57 static SDL_VideoDevice *
    58 Cocoa_CreateDevice(int devindex)
    59 {
    60     SDL_VideoDevice *device;
    61     SDL_VideoData *data;
    62 
    63     Cocoa_RegisterApp();
    64 
    65     /* Initialize all variables that we clean on shutdown */
    66     device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
    67     if (device) {
    68         data = (struct SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
    69     } else {
    70         data = NULL;
    71     }
    72     if (!data) {
    73         SDL_OutOfMemory();
    74         SDL_free(device);
    75         return NULL;
    76     }
    77     device->driverdata = data;
    78 
    79     /* Find out what version of Mac OS X we're running */
    80     Gestalt(gestaltSystemVersion, &data->osversion);
    81 
    82     /* Set the function pointers */
    83     device->VideoInit = Cocoa_VideoInit;
    84     device->VideoQuit = Cocoa_VideoQuit;
    85     device->GetDisplayBounds = Cocoa_GetDisplayBounds;
    86     device->GetDisplayModes = Cocoa_GetDisplayModes;
    87     device->SetDisplayMode = Cocoa_SetDisplayMode;
    88     device->PumpEvents = Cocoa_PumpEvents;
    89 
    90     device->CreateWindow = Cocoa_CreateWindow;
    91     device->CreateWindowFrom = Cocoa_CreateWindowFrom;
    92     device->SetWindowTitle = Cocoa_SetWindowTitle;
    93     device->SetWindowIcon = Cocoa_SetWindowIcon;
    94     device->SetWindowPosition = Cocoa_SetWindowPosition;
    95     device->SetWindowSize = Cocoa_SetWindowSize;
    96     device->SetWindowMinimumSize = Cocoa_SetWindowMinimumSize;
    97     device->SetWindowMaximumSize = Cocoa_SetWindowMaximumSize;
    98     device->ShowWindow = Cocoa_ShowWindow;
    99     device->HideWindow = Cocoa_HideWindow;
   100     device->RaiseWindow = Cocoa_RaiseWindow;
   101     device->MaximizeWindow = Cocoa_MaximizeWindow;
   102     device->MinimizeWindow = Cocoa_MinimizeWindow;
   103     device->RestoreWindow = Cocoa_RestoreWindow;
   104     device->SetWindowBordered = Cocoa_SetWindowBordered;
   105     device->SetWindowFullscreen = Cocoa_SetWindowFullscreen;
   106     device->SetWindowGammaRamp = Cocoa_SetWindowGammaRamp;
   107     device->GetWindowGammaRamp = Cocoa_GetWindowGammaRamp;
   108     device->SetWindowGrab = Cocoa_SetWindowGrab;
   109     device->DestroyWindow = Cocoa_DestroyWindow;
   110     device->GetWindowWMInfo = Cocoa_GetWindowWMInfo;
   111 
   112     device->shape_driver.CreateShaper = Cocoa_CreateShaper;
   113     device->shape_driver.SetWindowShape = Cocoa_SetWindowShape;
   114     device->shape_driver.ResizeWindowShape = Cocoa_ResizeWindowShape;
   115 
   116 #if SDL_VIDEO_OPENGL_CGL
   117     device->GL_LoadLibrary = Cocoa_GL_LoadLibrary;
   118     device->GL_GetProcAddress = Cocoa_GL_GetProcAddress;
   119     device->GL_UnloadLibrary = Cocoa_GL_UnloadLibrary;
   120     device->GL_CreateContext = Cocoa_GL_CreateContext;
   121     device->GL_MakeCurrent = Cocoa_GL_MakeCurrent;
   122     device->GL_GetDrawableSize = Cocoa_GL_GetDrawableSize;
   123     device->GL_SetSwapInterval = Cocoa_GL_SetSwapInterval;
   124     device->GL_GetSwapInterval = Cocoa_GL_GetSwapInterval;
   125     device->GL_SwapWindow = Cocoa_GL_SwapWindow;
   126     device->GL_DeleteContext = Cocoa_GL_DeleteContext;
   127 #endif
   128 
   129     device->StartTextInput = Cocoa_StartTextInput;
   130     device->StopTextInput = Cocoa_StopTextInput;
   131     device->SetTextInputRect = Cocoa_SetTextInputRect;
   132 
   133     device->SetClipboardText = Cocoa_SetClipboardText;
   134     device->GetClipboardText = Cocoa_GetClipboardText;
   135     device->HasClipboardText = Cocoa_HasClipboardText;
   136 
   137     device->free = Cocoa_DeleteDevice;
   138 
   139     return device;
   140 }
   141 
   142 VideoBootStrap COCOA_bootstrap = {
   143     "cocoa", "SDL Cocoa video driver",
   144     Cocoa_Available, Cocoa_CreateDevice
   145 };
   146 
   147 
   148 int
   149 Cocoa_VideoInit(_THIS)
   150 {
   151     SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
   152 
   153     Cocoa_InitModes(_this);
   154     Cocoa_InitKeyboard(_this);
   155     Cocoa_InitMouse(_this);
   156 
   157     const char *hint = SDL_GetHint(SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES);
   158     data->allow_spaces = ( (data->osversion >= 0x1070) && (!hint || (*hint != '0')) );
   159 
   160     return 0;
   161 }
   162 
   163 void
   164 Cocoa_VideoQuit(_THIS)
   165 {
   166     Cocoa_QuitModes(_this);
   167     Cocoa_QuitKeyboard(_this);
   168     Cocoa_QuitMouse(_this);
   169 }
   170 
   171 /* This function assumes that it's called from within an autorelease pool */
   172 NSImage *
   173 Cocoa_CreateImage(SDL_Surface * surface)
   174 {
   175     SDL_Surface *converted;
   176     NSBitmapImageRep *imgrep;
   177     Uint8 *pixels;
   178     int i;
   179     NSImage *img;
   180 
   181     converted = SDL_ConvertSurfaceFormat(surface,
   182 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
   183                                          SDL_PIXELFORMAT_RGBA8888,
   184 #else
   185                                          SDL_PIXELFORMAT_ABGR8888,
   186 #endif
   187                                          0);
   188     if (!converted) {
   189         return nil;
   190     }
   191 
   192     imgrep = [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
   193                     pixelsWide: converted->w
   194                     pixelsHigh: converted->h
   195                     bitsPerSample: 8
   196                     samplesPerPixel: 4
   197                     hasAlpha: YES
   198                     isPlanar: NO
   199                     colorSpaceName: NSDeviceRGBColorSpace
   200                     bytesPerRow: converted->pitch
   201                     bitsPerPixel: converted->format->BitsPerPixel] autorelease];
   202     if (imgrep == nil) {
   203         SDL_FreeSurface(converted);
   204         return nil;
   205     }
   206 
   207     /* Copy the pixels */
   208     pixels = [imgrep bitmapData];
   209     SDL_memcpy(pixels, converted->pixels, converted->h * converted->pitch);
   210     SDL_FreeSurface(converted);
   211 
   212     /* Premultiply the alpha channel */
   213     for (i = (surface->h * surface->w); i--; ) {
   214         Uint8 alpha = pixels[3];
   215         pixels[0] = (Uint8)(((Uint16)pixels[0] * alpha) / 255);
   216         pixels[1] = (Uint8)(((Uint16)pixels[1] * alpha) / 255);
   217         pixels[2] = (Uint8)(((Uint16)pixels[2] * alpha) / 255);
   218         pixels += 4;
   219     }
   220 
   221     img = [[[NSImage alloc] initWithSize: NSMakeSize(surface->w, surface->h)] autorelease];
   222     if (img != nil) {
   223         [img addRepresentation: imgrep];
   224     }
   225     return img;
   226 }
   227 
   228 /*
   229  * Mac OS X log support.
   230  *
   231  * This doesn't really have aything to do with the interfaces of the SDL video
   232  *  subsystem, but we need to stuff this into an Objective-C source code file.
   233  */
   234 
   235 void SDL_NSLog(const char *text)
   236 {
   237     NSLog(@"%s", text);
   238 }
   239 
   240 #endif /* SDL_VIDEO_DRIVER_COCOA */
   241 
   242 /* vim: set ts=4 sw=4 expandtab: */