2 Simple DirectMedia Layer
3 Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
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.
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:
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.
21 #include "../../SDL_internal.h"
23 #if SDL_VIDEO_DRIVER_COCOA
26 #include "SDL_endian.h"
27 #include "SDL_cocoavideo.h"
28 #include "SDL_cocoashape.h"
29 #include "SDL_cocoavulkan.h"
30 #include "SDL_cocoametalview.h"
32 /* Initialization/Query functions */
33 static int Cocoa_VideoInit(_THIS);
34 static void Cocoa_VideoQuit(_THIS);
36 /* Cocoa driver bootstrap functions */
39 Cocoa_DeleteDevice(SDL_VideoDevice * device)
41 SDL_free(device->driverdata);
45 static SDL_VideoDevice *
46 Cocoa_CreateDevice(int devindex)
48 SDL_VideoDevice *device;
53 /* Initialize all variables that we clean on shutdown */
54 device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
56 data = (struct SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
65 device->driverdata = data;
67 /* Set the function pointers */
68 device->VideoInit = Cocoa_VideoInit;
69 device->VideoQuit = Cocoa_VideoQuit;
70 device->GetDisplayBounds = Cocoa_GetDisplayBounds;
71 device->GetDisplayUsableBounds = Cocoa_GetDisplayUsableBounds;
72 device->GetDisplayDPI = Cocoa_GetDisplayDPI;
73 device->GetDisplayModes = Cocoa_GetDisplayModes;
74 device->SetDisplayMode = Cocoa_SetDisplayMode;
75 device->PumpEvents = Cocoa_PumpEvents;
76 device->SuspendScreenSaver = Cocoa_SuspendScreenSaver;
78 device->CreateSDLWindow = Cocoa_CreateWindow;
79 device->CreateSDLWindowFrom = Cocoa_CreateWindowFrom;
80 device->SetWindowTitle = Cocoa_SetWindowTitle;
81 device->SetWindowIcon = Cocoa_SetWindowIcon;
82 device->SetWindowPosition = Cocoa_SetWindowPosition;
83 device->SetWindowSize = Cocoa_SetWindowSize;
84 device->SetWindowMinimumSize = Cocoa_SetWindowMinimumSize;
85 device->SetWindowMaximumSize = Cocoa_SetWindowMaximumSize;
86 device->SetWindowOpacity = Cocoa_SetWindowOpacity;
87 device->ShowWindow = Cocoa_ShowWindow;
88 device->HideWindow = Cocoa_HideWindow;
89 device->RaiseWindow = Cocoa_RaiseWindow;
90 device->MaximizeWindow = Cocoa_MaximizeWindow;
91 device->MinimizeWindow = Cocoa_MinimizeWindow;
92 device->RestoreWindow = Cocoa_RestoreWindow;
93 device->SetWindowBordered = Cocoa_SetWindowBordered;
94 device->SetWindowResizable = Cocoa_SetWindowResizable;
95 device->SetWindowFullscreen = Cocoa_SetWindowFullscreen;
96 device->SetWindowGammaRamp = Cocoa_SetWindowGammaRamp;
97 device->GetWindowGammaRamp = Cocoa_GetWindowGammaRamp;
98 device->SetWindowGrab = Cocoa_SetWindowGrab;
99 device->DestroyWindow = Cocoa_DestroyWindow;
100 device->GetWindowWMInfo = Cocoa_GetWindowWMInfo;
101 device->SetWindowHitTest = Cocoa_SetWindowHitTest;
102 device->AcceptDragAndDrop = Cocoa_AcceptDragAndDrop;
104 device->shape_driver.CreateShaper = Cocoa_CreateShaper;
105 device->shape_driver.SetWindowShape = Cocoa_SetWindowShape;
106 device->shape_driver.ResizeWindowShape = Cocoa_ResizeWindowShape;
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 #elif SDL_VIDEO_OPENGL_EGL
120 device->GL_LoadLibrary = Cocoa_GLES_LoadLibrary;
121 device->GL_GetProcAddress = Cocoa_GLES_GetProcAddress;
122 device->GL_UnloadLibrary = Cocoa_GLES_UnloadLibrary;
123 device->GL_CreateContext = Cocoa_GLES_CreateContext;
124 device->GL_MakeCurrent = Cocoa_GLES_MakeCurrent;
125 device->GL_SetSwapInterval = Cocoa_GLES_SetSwapInterval;
126 device->GL_GetSwapInterval = Cocoa_GLES_GetSwapInterval;
127 device->GL_SwapWindow = Cocoa_GLES_SwapWindow;
128 device->GL_DeleteContext = Cocoa_GLES_DeleteContext;
132 device->Vulkan_LoadLibrary = Cocoa_Vulkan_LoadLibrary;
133 device->Vulkan_UnloadLibrary = Cocoa_Vulkan_UnloadLibrary;
134 device->Vulkan_GetInstanceExtensions = Cocoa_Vulkan_GetInstanceExtensions;
135 device->Vulkan_CreateSurface = Cocoa_Vulkan_CreateSurface;
136 device->Vulkan_GetDrawableSize = Cocoa_Vulkan_GetDrawableSize;
140 device->Metal_CreateView = Cocoa_Metal_CreateView;
141 device->Metal_DestroyView = Cocoa_Metal_DestroyView;
142 device->Metal_GetLayer = Cocoa_Metal_GetLayer;
143 device->Metal_GetDrawableSize = Cocoa_Metal_GetDrawableSize;
146 device->StartTextInput = Cocoa_StartTextInput;
147 device->StopTextInput = Cocoa_StopTextInput;
148 device->SetTextInputRect = Cocoa_SetTextInputRect;
150 device->SetClipboardText = Cocoa_SetClipboardText;
151 device->GetClipboardText = Cocoa_GetClipboardText;
152 device->HasClipboardText = Cocoa_HasClipboardText;
154 device->free = Cocoa_DeleteDevice;
159 VideoBootStrap COCOA_bootstrap = {
160 "cocoa", "SDL Cocoa video driver",
166 Cocoa_VideoInit(_THIS)
168 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
170 Cocoa_InitModes(_this);
171 Cocoa_InitKeyboard(_this);
172 if (Cocoa_InitMouse(_this) < 0) {
176 data->allow_spaces = ((floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) && SDL_GetHintBoolean(SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES, SDL_TRUE));
178 /* The IOPM assertion API can disable the screensaver as of 10.7. */
179 data->screensaver_use_iopm = floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6;
181 data->swaplock = SDL_CreateMutex();
182 if (!data->swaplock) {
190 Cocoa_VideoQuit(_THIS)
192 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
193 Cocoa_QuitModes(_this);
194 Cocoa_QuitKeyboard(_this);
195 Cocoa_QuitMouse(_this);
196 SDL_DestroyMutex(data->swaplock);
197 data->swaplock = NULL;
200 /* This function assumes that it's called from within an autorelease pool */
202 Cocoa_CreateImage(SDL_Surface * surface)
204 SDL_Surface *converted;
205 NSBitmapImageRep *imgrep;
210 converted = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_RGBA32, 0);
215 imgrep = [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
216 pixelsWide: converted->w
217 pixelsHigh: converted->h
222 colorSpaceName: NSDeviceRGBColorSpace
223 bytesPerRow: converted->pitch
224 bitsPerPixel: converted->format->BitsPerPixel] autorelease];
226 SDL_FreeSurface(converted);
230 /* Copy the pixels */
231 pixels = [imgrep bitmapData];
232 SDL_memcpy(pixels, converted->pixels, converted->h * converted->pitch);
233 SDL_FreeSurface(converted);
235 /* Premultiply the alpha channel */
236 for (i = (surface->h * surface->w); i--; ) {
237 Uint8 alpha = pixels[3];
238 pixels[0] = (Uint8)(((Uint16)pixels[0] * alpha) / 255);
239 pixels[1] = (Uint8)(((Uint16)pixels[1] * alpha) / 255);
240 pixels[2] = (Uint8)(((Uint16)pixels[2] * alpha) / 255);
244 img = [[[NSImage alloc] initWithSize: NSMakeSize(surface->w, surface->h)] autorelease];
246 [img addRepresentation: imgrep];
252 * Mac OS X log support.
254 * This doesn't really have aything to do with the interfaces of the SDL video
255 * subsystem, but we need to stuff this into an Objective-C source code file.
257 * NOTE: This is copypasted in src/video/uikit/SDL_uikitvideo.m! Be sure both
258 * versions remain identical!
261 void SDL_NSLog(const char *text)
266 #endif /* SDL_VIDEO_DRIVER_COCOA */
268 /* vim: set ts=4 sw=4 expandtab: */