src/video/cocoa/SDL_cocoavideo.m
author Cameron Gutman <cameron.gutman@gmail.com>
Mon, 24 Jun 2019 21:08:26 -0700
changeset 12944 886b79177762
parent 12883 72ab279ffcaa
permissions -rw-r--r--
Allow hotplugging joysticks without udev
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2019 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_cocoavulkan.h"
    30 #include "SDL_assert.h"
    31 
    32 /* Initialization/Query functions */
    33 static int Cocoa_VideoInit(_THIS);
    34 static void Cocoa_VideoQuit(_THIS);
    35 
    36 /* Cocoa driver bootstrap functions */
    37 
    38 static int
    39 Cocoa_Available(void)
    40 {
    41     return (1);
    42 }
    43 
    44 static void
    45 Cocoa_DeleteDevice(SDL_VideoDevice * device)
    46 {
    47     SDL_free(device->driverdata);
    48     SDL_free(device);
    49 }
    50 
    51 static SDL_VideoDevice *
    52 Cocoa_CreateDevice(int devindex)
    53 {
    54     SDL_VideoDevice *device;
    55     SDL_VideoData *data;
    56 
    57     Cocoa_RegisterApp();
    58 
    59     /* Initialize all variables that we clean on shutdown */
    60     device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
    61     if (device) {
    62         data = (struct SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
    63     } else {
    64         data = NULL;
    65     }
    66     if (!data) {
    67         SDL_OutOfMemory();
    68         SDL_free(device);
    69         return NULL;
    70     }
    71     device->driverdata = data;
    72 
    73     /* Set the function pointers */
    74     device->VideoInit = Cocoa_VideoInit;
    75     device->VideoQuit = Cocoa_VideoQuit;
    76     device->GetDisplayBounds = Cocoa_GetDisplayBounds;
    77     device->GetDisplayUsableBounds = Cocoa_GetDisplayUsableBounds;
    78     device->GetDisplayDPI = Cocoa_GetDisplayDPI;
    79     device->GetDisplayModes = Cocoa_GetDisplayModes;
    80     device->SetDisplayMode = Cocoa_SetDisplayMode;
    81     device->PumpEvents = Cocoa_PumpEvents;
    82     device->SuspendScreenSaver = Cocoa_SuspendScreenSaver;
    83 
    84     device->CreateSDLWindow = Cocoa_CreateWindow;
    85     device->CreateSDLWindowFrom = Cocoa_CreateWindowFrom;
    86     device->SetWindowTitle = Cocoa_SetWindowTitle;
    87     device->SetWindowIcon = Cocoa_SetWindowIcon;
    88     device->SetWindowPosition = Cocoa_SetWindowPosition;
    89     device->SetWindowSize = Cocoa_SetWindowSize;
    90     device->SetWindowMinimumSize = Cocoa_SetWindowMinimumSize;
    91     device->SetWindowMaximumSize = Cocoa_SetWindowMaximumSize;
    92     device->SetWindowOpacity = Cocoa_SetWindowOpacity;
    93     device->ShowWindow = Cocoa_ShowWindow;
    94     device->HideWindow = Cocoa_HideWindow;
    95     device->RaiseWindow = Cocoa_RaiseWindow;
    96     device->MaximizeWindow = Cocoa_MaximizeWindow;
    97     device->MinimizeWindow = Cocoa_MinimizeWindow;
    98     device->RestoreWindow = Cocoa_RestoreWindow;
    99     device->SetWindowBordered = Cocoa_SetWindowBordered;
   100     device->SetWindowResizable = Cocoa_SetWindowResizable;
   101     device->SetWindowFullscreen = Cocoa_SetWindowFullscreen;
   102     device->SetWindowGammaRamp = Cocoa_SetWindowGammaRamp;
   103     device->GetWindowGammaRamp = Cocoa_GetWindowGammaRamp;
   104     device->SetWindowGrab = Cocoa_SetWindowGrab;
   105     device->DestroyWindow = Cocoa_DestroyWindow;
   106     device->GetWindowWMInfo = Cocoa_GetWindowWMInfo;
   107     device->SetWindowHitTest = Cocoa_SetWindowHitTest;
   108     device->AcceptDragAndDrop = Cocoa_AcceptDragAndDrop;
   109 
   110     device->shape_driver.CreateShaper = Cocoa_CreateShaper;
   111     device->shape_driver.SetWindowShape = Cocoa_SetWindowShape;
   112     device->shape_driver.ResizeWindowShape = Cocoa_ResizeWindowShape;
   113 
   114 #if SDL_VIDEO_OPENGL_CGL
   115     device->GL_LoadLibrary = Cocoa_GL_LoadLibrary;
   116     device->GL_GetProcAddress = Cocoa_GL_GetProcAddress;
   117     device->GL_UnloadLibrary = Cocoa_GL_UnloadLibrary;
   118     device->GL_CreateContext = Cocoa_GL_CreateContext;
   119     device->GL_MakeCurrent = Cocoa_GL_MakeCurrent;
   120     device->GL_GetDrawableSize = Cocoa_GL_GetDrawableSize;
   121     device->GL_SetSwapInterval = Cocoa_GL_SetSwapInterval;
   122     device->GL_GetSwapInterval = Cocoa_GL_GetSwapInterval;
   123     device->GL_SwapWindow = Cocoa_GL_SwapWindow;
   124     device->GL_DeleteContext = Cocoa_GL_DeleteContext;
   125 #elif SDL_VIDEO_OPENGL_EGL
   126     device->GL_LoadLibrary = Cocoa_GLES_LoadLibrary;
   127     device->GL_GetProcAddress = Cocoa_GLES_GetProcAddress;
   128     device->GL_UnloadLibrary = Cocoa_GLES_UnloadLibrary;
   129     device->GL_CreateContext = Cocoa_GLES_CreateContext;
   130     device->GL_MakeCurrent = Cocoa_GLES_MakeCurrent;
   131     device->GL_SetSwapInterval = Cocoa_GLES_SetSwapInterval;
   132     device->GL_GetSwapInterval = Cocoa_GLES_GetSwapInterval;
   133     device->GL_SwapWindow = Cocoa_GLES_SwapWindow;
   134     device->GL_DeleteContext = Cocoa_GLES_DeleteContext;
   135 #endif
   136 
   137 #if SDL_VIDEO_VULKAN
   138     device->Vulkan_LoadLibrary = Cocoa_Vulkan_LoadLibrary;
   139     device->Vulkan_UnloadLibrary = Cocoa_Vulkan_UnloadLibrary;
   140     device->Vulkan_GetInstanceExtensions = Cocoa_Vulkan_GetInstanceExtensions;
   141     device->Vulkan_CreateSurface = Cocoa_Vulkan_CreateSurface;
   142     device->Vulkan_GetDrawableSize = Cocoa_Vulkan_GetDrawableSize;
   143 #endif
   144 
   145     device->StartTextInput = Cocoa_StartTextInput;
   146     device->StopTextInput = Cocoa_StopTextInput;
   147     device->SetTextInputRect = Cocoa_SetTextInputRect;
   148 
   149     device->SetClipboardText = Cocoa_SetClipboardText;
   150     device->GetClipboardText = Cocoa_GetClipboardText;
   151     device->HasClipboardText = Cocoa_HasClipboardText;
   152 
   153     device->free = Cocoa_DeleteDevice;
   154 
   155     return device;
   156 }
   157 
   158 VideoBootStrap COCOA_bootstrap = {
   159     "cocoa", "SDL Cocoa video driver",
   160     Cocoa_Available, Cocoa_CreateDevice
   161 };
   162 
   163 
   164 int
   165 Cocoa_VideoInit(_THIS)
   166 {
   167     SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
   168 
   169     Cocoa_InitModes(_this);
   170     Cocoa_InitKeyboard(_this);
   171     if (Cocoa_InitMouse(_this) < 0) {
   172         return -1;
   173     }
   174 
   175     data->allow_spaces = ((floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) && SDL_GetHintBoolean(SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES, SDL_TRUE));
   176 
   177     /* The IOPM assertion API can disable the screensaver as of 10.7. */
   178     data->screensaver_use_iopm = floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6;
   179 
   180     data->swaplock = SDL_CreateMutex();
   181     if (!data->swaplock) {
   182         return -1;
   183     }
   184 
   185     return 0;
   186 }
   187 
   188 void
   189 Cocoa_VideoQuit(_THIS)
   190 {
   191     SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
   192     Cocoa_QuitModes(_this);
   193     Cocoa_QuitKeyboard(_this);
   194     Cocoa_QuitMouse(_this);
   195     SDL_DestroyMutex(data->swaplock);
   196     data->swaplock = NULL;
   197 }
   198 
   199 /* This function assumes that it's called from within an autorelease pool */
   200 NSImage *
   201 Cocoa_CreateImage(SDL_Surface * surface)
   202 {
   203     SDL_Surface *converted;
   204     NSBitmapImageRep *imgrep;
   205     Uint8 *pixels;
   206     int i;
   207     NSImage *img;
   208 
   209     converted = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_RGBA32, 0);
   210     if (!converted) {
   211         return nil;
   212     }
   213 
   214     imgrep = [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
   215                     pixelsWide: converted->w
   216                     pixelsHigh: converted->h
   217                     bitsPerSample: 8
   218                     samplesPerPixel: 4
   219                     hasAlpha: YES
   220                     isPlanar: NO
   221                     colorSpaceName: NSDeviceRGBColorSpace
   222                     bytesPerRow: converted->pitch
   223                     bitsPerPixel: converted->format->BitsPerPixel] autorelease];
   224     if (imgrep == nil) {
   225         SDL_FreeSurface(converted);
   226         return nil;
   227     }
   228 
   229     /* Copy the pixels */
   230     pixels = [imgrep bitmapData];
   231     SDL_memcpy(pixels, converted->pixels, converted->h * converted->pitch);
   232     SDL_FreeSurface(converted);
   233 
   234     /* Premultiply the alpha channel */
   235     for (i = (surface->h * surface->w); i--; ) {
   236         Uint8 alpha = pixels[3];
   237         pixels[0] = (Uint8)(((Uint16)pixels[0] * alpha) / 255);
   238         pixels[1] = (Uint8)(((Uint16)pixels[1] * alpha) / 255);
   239         pixels[2] = (Uint8)(((Uint16)pixels[2] * alpha) / 255);
   240         pixels += 4;
   241     }
   242 
   243     img = [[[NSImage alloc] initWithSize: NSMakeSize(surface->w, surface->h)] autorelease];
   244     if (img != nil) {
   245         [img addRepresentation: imgrep];
   246     }
   247     return img;
   248 }
   249 
   250 /*
   251  * Mac OS X log support.
   252  *
   253  * This doesn't really have aything to do with the interfaces of the SDL video
   254  *  subsystem, but we need to stuff this into an Objective-C source code file.
   255  */
   256 
   257 void SDL_NSLog(const char *text)
   258 {
   259     NSLog(@"%s", text);
   260 }
   261 
   262 #endif /* SDL_VIDEO_DRIVER_COCOA */
   263 
   264 /* vim: set ts=4 sw=4 expandtab: */