1 /+ 2 + Copyright 2022 – 2023 Aya Partridge 3 + Copyright 2018 - 2022 Michael D. Parker 4 + Distributed under the Boost Software License, Version 1.0. 5 + (See accompanying file LICENSE_1_0.txt or copy at 6 + http://www.boost.org/LICENSE_1_0.txt) 7 +/ 8 module sdl.video; 9 10 import bindbc.sdl.config; 11 import bindbc.sdl.codegen; 12 13 import sdl.rect: SDL_Rect; 14 import sdl.stdinc: SDL_bool; 15 import sdl.surface: SDL_Surface; 16 17 struct SDL_DisplayMode{ 18 uint format; 19 int w; 20 int h; 21 int refresh_rate; 22 void* driverdata; 23 } 24 25 struct SDL_Window; 26 27 alias SDL_WindowFlags = uint; 28 enum: SDL_WindowFlags{ 29 SDL_WINDOW_FULLSCREEN = 0x0000_0001, 30 SDL_WINDOW_OPENGL = 0x0000_0002, 31 SDL_WINDOW_SHOWN = 0x0000_0004, 32 SDL_WINDOW_HIDDEN = 0x0000_0008, 33 SDL_WINDOW_BORDERLESS = 0x0000_0010, 34 SDL_WINDOW_RESIZABLE = 0x0000_0020, 35 SDL_WINDOW_MINIMIZED = 0x0000_0040, 36 SDL_WINDOW_MAXIMIZED = 0x0000_0080, 37 SDL_WINDOW_INPUT_GRABBED = 0x0000_0100, 38 SDL_WINDOW_INPUT_FOCUS = 0x0000_0200, 39 SDL_WINDOW_MOUSE_FOCUS = 0x0000_0400, 40 SDL_WINDOW_FULLSCREEN_DESKTOP = 0x0000_1000 | SDL_WINDOW_FULLSCREEN, 41 SDL_WINDOW_FOREIGN = 0x0000_0800, 42 } 43 static if(sdlSupport >= SDLSupport.v2_0_1) 44 enum: SDL_WindowFlags{ 45 SDL_WINDOW_ALLOW_HIGHDPI = 0x0000_2000, 46 } 47 static if(sdlSupport >= SDLSupport.v2_0_4) 48 enum: SDL_WindowFlags{ 49 SDL_WINDOW_MOUSE_CAPTURE = 0x0000_4000, 50 } 51 static if(sdlSupport >= SDLSupport.v2_0_5) 52 enum: SDL_WindowFlags{ 53 SDL_WINDOW_ALWAYS_ON_TOP = 0x0000_8000, 54 SDL_WINDOW_SKIP_TASKBAR = 0x0001_0000, 55 SDL_WINDOW_UTILITY = 0x0002_0000, 56 SDL_WINDOW_TOOLTIP = 0x0004_0000, 57 SDL_WINDOW_POPUP_MENU = 0x0008_0000, 58 } 59 static if(sdlSupport >= SDLSupport.v2_0_6) 60 enum: SDL_WindowFlags{ 61 SDL_WINDOW_VULKAN = 0x1000_0000, 62 } 63 static if(sdlSupport >= SDLSupport.v2_0_6) 64 enum: SDL_WindowFlags{ 65 SDL_WINDOW_METAL = 0x2000_0000, 66 } 67 static if(sdlSupport >= SDLSupport.v2_0_16) 68 enum: SDL_WindowFlags{ 69 SDL_WINDOW_MOUSE_GRABBED = SDL_WINDOW_INPUT_GRABBED, 70 SDL_WINDOW_KEYBOARD_GRABBED = 0x0010_0000, 71 } 72 73 enum: uint{ 74 SDL_WINDOWPOS_UNDEFINED_MASK = 0x1FFF0000, 75 SDL_WINDOWPOS_UNDEFINED = SDL_WINDOWPOS_UNDEFINED_DISPLAY(0), 76 SDL_WINDOWPOS_CENTERED_MASK = 0x2FFF0000, 77 SDL_WINDOWPOS_CENTERED = SDL_WINDOWPOS_CENTERED_DISPLAY(0), 78 } 79 80 pragma(inline, true) @nogc nothrow pure @safe{ 81 uint SDL_WINDOWPOS_UNDEFINED_DISPLAY(uint x){ return SDL_WINDOWPOS_UNDEFINED_MASK | x; } 82 uint SDL_WINDOWPOS_ISUNDEFINED(uint x){ return (x & 0xFFFF0000) == SDL_WINDOWPOS_UNDEFINED_MASK; } 83 uint SDL_WINDOWPOS_CENTERED_DISPLAY(uint x){ return SDL_WINDOWPOS_CENTERED_MASK | x; } 84 uint SDL_WINDOWPOS_ISCENTERED(uint x){ return (x & 0xFFFF0000) == SDL_WINDOWPOS_CENTERED_MASK; } 85 } 86 87 alias SDL_WindowEventID = ubyte; 88 enum: SDL_WindowEventID{ 89 SDL_WINDOWEVENT_NONE = 0, 90 SDL_WINDOWEVENT_SHOWN = 1, 91 SDL_WINDOWEVENT_HIDDEN = 2, 92 SDL_WINDOWEVENT_EXPOSED = 3, 93 SDL_WINDOWEVENT_MOVED = 4, 94 SDL_WINDOWEVENT_RESIZED = 5, 95 SDL_WINDOWEVENT_SIZE_CHANGED = 6, 96 SDL_WINDOWEVENT_MINIMIZED = 7, 97 SDL_WINDOWEVENT_MAXIMIZED = 8, 98 SDL_WINDOWEVENT_RESTORED = 9, 99 SDL_WINDOWEVENT_ENTER = 10, 100 SDL_WINDOWEVENT_LEAVE = 11, 101 SDL_WINDOWEVENT_FOCUS_GAINED = 12, 102 SDL_WINDOWEVENT_FOCUS_LOST = 13, 103 SDL_WINDOWEVENT_CLOSE = 14, 104 } 105 static if(sdlSupport >= SDLSupport.v2_0_5) 106 enum: SDL_WindowEventID{ 107 SDL_WINDOWEVENT_TAKE_FOCUS = 15, 108 SDL_WINDOWEVENT_HIT_TEST = 16, 109 } 110 static if(sdlSupport >= SDLSupport.v2_0_18) 111 enum: SDL_WindowEventID{ 112 SDL_WINDOWEVENT_ICCPROF_CHANGED = 17, 113 SDL_WINDOWEVENT_DISPLAY_CHANGED = 18, 114 } 115 116 static if(sdlSupport >= SDLSupport.v2_0_9){ 117 alias SDL_DisplayEventID = int; 118 enum: SDL_DisplayEventID{ 119 SDL_DISPLAYEVENT_NONE = 0, 120 SDL_DISPLAYEVENT_ORIENTATION = 1, 121 } 122 static if(sdlSupport >= SDLSupport.v2_0_14) 123 enum: SDL_DisplayEventID{ 124 SDL_DISPLAYEVENT_CONNECTED = 2, 125 SDL_DISPLAYEVENT_DISCONNECTED = 3, 126 } 127 } 128 129 static if(sdlSupport >= SDLSupport.v2_0_9){ 130 alias SDL_DisplayOrientation = int; 131 enum: SDL_DisplayOrientation{ 132 SDL_ORIENTATION_UNKNOWN = 0, 133 SDL_ORIENTATION_LANDSCAPE = 1, 134 SDL_ORIENTATION_LANDSCAPE_FLIPPED = 2, 135 SDL_ORIENTATION_PORTRAIT = 3, 136 SDL_ORIENTATION_PORTRAIT_FLIPPED = 4, 137 } 138 } 139 140 static if(sdlSupport >= SDLSupport.v2_0_16){ 141 alias SDL_FlashOperation = int; 142 enum: SDL_FlashOperation{ 143 SDL_FLASH_CANCEL = 0, 144 SDL_FLASH_BRIEFLY = 1, 145 SDL_FLASH_UNTIL_FOCUSED = 2, 146 } 147 } 148 149 alias SDL_GLContext = void*; 150 151 alias SDL_GLattr = int; 152 enum: SDL_GLattr{ 153 SDL_GL_RED_SIZE = 0, 154 SDL_GL_GREEN_SIZE = 1, 155 SDL_GL_BLUE_SIZE = 2, 156 SDL_GL_ALPHA_SIZE = 3, 157 SDL_GL_BUFFER_SIZE = 4, 158 SDL_GL_DOUBLEBUFFER = 5, 159 SDL_GL_DEPTH_SIZE = 6, 160 SDL_GL_STENCIL_SIZE = 7, 161 SDL_GL_ACCUM_RED_SIZE = 8, 162 SDL_GL_ACCUM_GREEN_SIZE = 9, 163 SDL_GL_ACCUM_BLUE_SIZE = 10, 164 SDL_GL_ACCUM_ALPHA_SIZE = 11, 165 SDL_GL_STEREO = 12, 166 SDL_GL_MULTISAMPLEBUFFERS = 13, 167 SDL_GL_MULTISAMPLESAMPLES = 14, 168 SDL_GL_ACCELERATED_VISUAL = 15, 169 SDL_GL_RETAINED_BACKING = 16, 170 SDL_GL_CONTEXT_MAJOR_VERSION = 17, 171 SDL_GL_CONTEXT_MINOR_VERSION = 18, 172 SDL_GL_CONTEXT_EGL = 19, 173 SDL_GL_CONTEXT_FLAGS = 20, 174 SDL_GL_CONTEXT_PROFILE_MASK = 21, 175 SDL_GL_SHARE_WITH_CURRENT_CONTEXT = 22, 176 } 177 static if(sdlSupport >= SDLSupport.v2_0_1) 178 enum: SDL_GLattr{ 179 SDL_GL_FRAMEBUFFER_SRGB_CAPABLE = 23, 180 } 181 static if(sdlSupport >= SDLSupport.v2_0_4) 182 enum: SDL_GLattr{ 183 deprecated("Please use `SDL_GL_CONTEXT_RELEASE_BEHAVIOR` instead") SDL_GL_RELEASE_BEHAVIOR = 24, //NOTE: this name was a typo to begin with 184 SDL_GL_CONTEXT_RELEASE_BEHAVIOR = 24, 185 } 186 static if(sdlSupport >= SDLSupport.v2_0_6) 187 enum: SDL_GLattr{ 188 SDL_GL_CONTEXT_RESET_NOTIFICATION = 25, 189 SDL_GL_CONTEXT_NO_ERROR = 26, 190 } 191 static if(sdlSupport >= SDLSupport.v2_0_6) 192 enum: SDL_GLattr{ 193 SDL_GL_FLOATBUFFERS = 27, 194 } 195 196 alias SDL_GLprofile = int; 197 enum: SDL_GLprofile{ 198 SDL_GL_CONTEXT_PROFILE_CORE = 0x0001, 199 SDL_GL_CONTEXT_PROFILE_COMPATIBILITY = 0x0002, 200 SDL_GL_CONTEXT_PROFILE_ES = 0x0004, 201 } 202 203 alias SDL_GLcontextFlag = int; 204 enum: SDL_GLcontextFlag{ 205 SDL_GL_CONTEXT_DEBUG_FLAG = 0x0001, 206 SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG = 0x0002, 207 SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG = 0x0004, 208 SDL_GL_CONTEXT_RESET_ISOLATION_FLAG = 0x0008, 209 } 210 211 static if(sdlSupport >= SDLSupport.v2_0_4){ 212 alias SDL_GLcontextReleaseFlag = int; 213 enum: SDL_GLcontextReleaseFlag{ 214 SDL_GL_CONTEXT_RELEASE_BEHAVIOR_NONE = 0x0000, 215 SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH = 0x0001, 216 } 217 218 alias SDL_HitTestResult = int; 219 enum: SDL_HitTestResult{ 220 SDL_HITTEST_NORMAL = 0, 221 SDL_HITTEST_DRAGGABLE = 1, 222 SDL_HITTEST_RESIZE_TOPLEFT = 2, 223 SDL_HITTEST_RESIZE_TOP = 3, 224 SDL_HITTEST_RESIZE_TOPRIGHT = 4, 225 SDL_HITTEST_RESIZE_RIGHT = 5, 226 SDL_HITTEST_RESIZE_BOTTOMRIGHT = 6, 227 SDL_HITTEST_RESIZE_BOTTOM = 7, 228 SDL_HITTEST_RESIZE_BOTTOMLEFT = 8, 229 SDL_HITTEST_RESIZE_LEFT = 9, 230 } 231 232 import sdl.rect: SDL_Point; 233 alias SDL_HitTest = extern(C) SDL_HitTestResult function(SDL_Window* win, const(SDL_Point)* area, void* data) nothrow; 234 } 235 236 static if(sdlSupport >= SDLSupport.v2_0_6){ 237 alias SDL_GLContextResetNotification = int; 238 enum: SDL_GLContextResetNotification{ 239 SDL_GL_CONTEXT_RESET_NO_NOTIFICATION = 0x0000, 240 SDL_GL_CONTEXT_RESET_LOSE_CONTEXT = 0x0001, 241 } 242 } 243 244 mixin(joinFnBinds((){ 245 string[][] ret; 246 ret ~= makeFnBinds([ 247 [q{int}, q{SDL_GetNumVideoDrivers}, q{}], 248 [q{const(char)*}, q{SDL_GetVideoDriver}, q{int index}], 249 [q{int}, q{SDL_VideoInit}, q{const(char)* driver_name}], 250 [q{void}, q{SDL_VideoQuit}, q{}], 251 [q{const(char)*}, q{SDL_GetCurrentVideoDriver}, q{}], 252 [q{int}, q{SDL_GetNumVideoDisplays}, q{}], 253 [q{const(char)*}, q{SDL_GetDisplayName}, q{int displayIndex}], 254 [q{int}, q{SDL_GetDisplayBounds}, q{int displayIndex, SDL_Rect* rect}], 255 [q{int}, q{SDL_GetNumDisplayModes}, q{int displayIndex}], 256 [q{int}, q{SDL_GetDisplayMode}, q{int displayIndex, int modeIndex, SDL_DisplayMode* mode}], 257 [q{int}, q{SDL_GetDesktopDisplayMode}, q{int displayIndex, SDL_DisplayMode* mode}], 258 [q{int}, q{SDL_GetCurrentDisplayMode}, q{int displayIndex, SDL_DisplayMode* mode}], 259 [q{SDL_DisplayMode*}, q{SDL_GetClosestDisplayMode}, q{int displayIndex, const(SDL_DisplayMode)* mode, SDL_DisplayMode* closest}], 260 [q{int}, q{SDL_GetWindowDisplayIndex}, q{SDL_Window* window}], 261 [q{int}, q{SDL_SetWindowDisplayMode}, q{SDL_Window* window, const(SDL_DisplayMode)* mode}], 262 [q{int}, q{SDL_GetWindowDisplayMode}, q{SDL_Window* window, SDL_DisplayMode* mode}], 263 [q{uint}, q{SDL_GetWindowPixelFormat}, q{SDL_Window* window}], 264 [q{SDL_Window*}, q{SDL_CreateWindow}, q{const(char)* title, int x, int y, int w, int h, SDL_WindowFlags flags}], 265 [q{SDL_Window*}, q{SDL_CreateWindowFrom}, q{const(void)* data}], 266 [q{uint}, q{SDL_GetWindowID}, q{SDL_Window* window}], 267 [q{SDL_Window*}, q{SDL_GetWindowFromID}, q{uint id}], 268 [q{SDL_WindowFlags}, q{SDL_GetWindowFlags}, q{SDL_Window* window}], 269 [q{void}, q{SDL_SetWindowTitle}, q{SDL_Window* window, const(char)* title}], 270 [q{const(char)*}, q{SDL_GetWindowTitle}, q{SDL_Window* window}], 271 [q{void}, q{SDL_SetWindowIcon}, q{SDL_Window* window, SDL_Surface* icon}], 272 [q{void*}, q{SDL_SetWindowData}, q{SDL_Window* window, const(char)* name, void* userdata}], 273 [q{void*}, q{SDL_GetWindowData}, q{SDL_Window* window, const(char)* name}], 274 [q{void}, q{SDL_SetWindowPosition}, q{SDL_Window* window, int x, int y}], 275 [q{void}, q{SDL_GetWindowPosition}, q{SDL_Window* window, int* x, int* y}], 276 [q{void}, q{SDL_SetWindowSize}, q{SDL_Window* window, int w, int h}], 277 [q{void}, q{SDL_GetWindowSize}, q{SDL_Window* window, int* w, int* h}], 278 [q{void}, q{SDL_SetWindowMinimumSize}, q{SDL_Window* window, int min_w, int min_h}], 279 [q{void}, q{SDL_GetWindowMinimumSize}, q{SDL_Window* window, int* w, int* h}], 280 [q{void}, q{SDL_SetWindowMaximumSize}, q{SDL_Window* window, int max_w, int max_h}], 281 [q{void}, q{SDL_GetWindowMaximumSize}, q{SDL_Window* window, int* w, int* h}], 282 [q{void}, q{SDL_SetWindowBordered}, q{SDL_Window* window, SDL_bool bordered}], 283 [q{void}, q{SDL_ShowWindow}, q{SDL_Window* window}], 284 [q{void}, q{SDL_HideWindow}, q{SDL_Window* window}], 285 [q{void}, q{SDL_RaiseWindow}, q{SDL_Window* window}], 286 [q{void}, q{SDL_MaximizeWindow}, q{SDL_Window* window}], 287 [q{void}, q{SDL_MinimizeWindow}, q{SDL_Window* window}], 288 [q{void}, q{SDL_RestoreWindow}, q{SDL_Window* window}], 289 [q{int}, q{SDL_SetWindowFullscreen}, q{SDL_Window* window, SDL_WindowFlags flags}], 290 [q{SDL_Surface*}, q{SDL_GetWindowSurface}, q{SDL_Window* window}], 291 [q{int}, q{SDL_UpdateWindowSurface}, q{SDL_Window* window}], 292 [q{int}, q{SDL_UpdateWindowSurfaceRects}, q{SDL_Window* window, SDL_Rect* rects, int numrects}], 293 [q{void}, q{SDL_SetWindowGrab}, q{SDL_Window* window, SDL_bool grabbed}], 294 [q{SDL_bool}, q{SDL_GetWindowGrab}, q{SDL_Window* window}], 295 [q{int}, q{SDL_SetWindowBrightness}, q{SDL_Window* window, float brightness}], 296 [q{float}, q{SDL_GetWindowBrightness}, q{SDL_Window* window}], 297 [q{int}, q{SDL_SetWindowGammaRamp}, q{SDL_Window* window, const(ushort)* red, const(ushort)* green, const(ushort)* blue}], 298 [q{int}, q{SDL_GetWindowGammaRamp}, q{SDL_Window* window, ushort* red, ushort* green, ushort* blue}], 299 [q{void}, q{SDL_DestroyWindow}, q{SDL_Window* window}], 300 [q{SDL_bool}, q{SDL_IsScreenSaverEnabled}, q{}], 301 [q{void}, q{SDL_EnableScreenSaver}, q{}], 302 [q{void}, q{SDL_DisableScreenSaver}, q{}], 303 [q{int}, q{SDL_GL_LoadLibrary}, q{const(char)* path}], 304 [q{void*}, q{SDL_GL_GetProcAddress}, q{const(char)* proc}], 305 [q{void}, q{SDL_GL_UnloadLibrary}, q{}], 306 [q{SDL_bool}, q{SDL_GL_ExtensionSupported}, q{const(char)* extension}], 307 [q{int}, q{SDL_GL_SetAttribute}, q{SDL_GLattr attr, int value}], 308 [q{int}, q{SDL_GL_GetAttribute}, q{SDL_GLattr attr, int* value}], 309 [q{SDL_GLContext}, q{SDL_GL_CreateContext}, q{SDL_Window* window}], 310 [q{int}, q{SDL_GL_MakeCurrent}, q{SDL_Window* window, SDL_GLContext context}], 311 [q{SDL_Window*}, q{SDL_GL_GetCurrentWindow}, q{}], 312 [q{SDL_GLContext}, q{SDL_GL_GetCurrentContext}, q{}], 313 [q{int}, q{SDL_GL_SetSwapInterval}, q{int interval}], 314 [q{int}, q{SDL_GL_GetSwapInterval}, q{}], 315 [q{void}, q{SDL_GL_SwapWindow}, q{SDL_Window* window}], 316 [q{void}, q{SDL_GL_DeleteContext}, q{SDL_GLContext context}], 317 ]); 318 static if(sdlSupport >= SDLSupport.v2_0_1){ 319 ret ~= makeFnBinds([ 320 [q{void}, q{SDL_GL_GetDrawableSize}, q{SDL_Window* window, int* w, int* h}], 321 ]); 322 } 323 static if(sdlSupport >= SDLSupport.v2_0_2){ 324 ret ~= makeFnBinds([ 325 [q{void}, q{SDL_GL_ResetAttributes}, q{}], 326 ]); 327 } 328 static if(sdlSupport >= SDLSupport.v2_0_4){ 329 ret ~= makeFnBinds([ 330 [q{int}, q{SDL_GetDisplayDPI}, q{int displayIndex, float* ddpi, float* hdpi, float* vdpi}], 331 [q{SDL_Window*}, q{SDL_GetGrabbedWindow}, q{}], 332 [q{int}, q{SDL_SetWindowHitTest}, q{SDL_Window* window, SDL_HitTest callback, void* callback_data}], 333 ]); 334 } 335 static if(sdlSupport >= SDLSupport.v2_0_5){ 336 ret ~= makeFnBinds([ 337 [q{int}, q{SDL_GetDisplayUsableBounds}, q{int displayIndex, SDL_Rect* rect}], 338 [q{int}, q{SDL_GetWindowBordersSize}, q{SDL_Window* window, int* top, int* left, int* bottom, int* right}], 339 [q{int}, q{SDL_GetWindowOpacity}, q{SDL_Window* window, float* opacity}], 340 [q{int}, q{SDL_SetWindowInputFocus}, q{SDL_Window* window}], 341 [q{int}, q{SDL_SetWindowModalFor}, q{SDL_Window* modal_window, SDL_Window* parent_window}], 342 [q{int}, q{SDL_SetWindowOpacity}, q{SDL_Window* window, float opacity}], 343 [q{void}, q{SDL_SetWindowResizable}, q{SDL_Window* window, SDL_bool resizable}], 344 ]); 345 } 346 static if(sdlSupport >= SDLSupport.v2_0_9){ 347 ret ~= makeFnBinds([ 348 [q{SDL_DisplayOrientation}, q{SDL_GetDisplayOrientation}, q{int displayIndex}], 349 ]); 350 } 351 static if(sdlSupport >= SDLSupport.v2_0_16){ 352 ret ~= makeFnBinds([ 353 [q{int}, q{SDL_FlashWindow}, q{SDL_Window* window, SDL_FlashOperation operation}], 354 [q{void}, q{SDL_SetWindowAlwaysOnTop}, q{SDL_Window* window, SDL_bool on_top}], 355 [q{void}, q{SDL_SetWindowKeyboardGrab}, q{SDL_Window* window, SDL_bool grabbed}], 356 [q{SDL_bool}, q{SDL_GetWindowKeyboardGrab}, q{SDL_Window * window}], 357 [q{void}, q{SDL_SetWindowMouseGrab}, q{SDL_Window* window, SDL_bool grabbed}], 358 [q{SDL_bool}, q{SDL_GetWindowMouseGrab}, q{SDL_Window* window}], 359 ]); 360 } 361 static if(sdlSupport >= SDLSupport.v2_0_18){ 362 ret ~= makeFnBinds([ 363 [q{void*}, q{SDL_GetWindowICCProfile}, q{SDL_Window* window, size_t* size}], 364 [q{int}, q{SDL_SetWindowMouseRect}, q{SDL_Window* window, const(SDL_Rect)* rect}], 365 [q{const(SDL_Rect)*}, q{SDL_GetWindowMouseRect}, q{SDL_Window* window}], 366 ]); 367 } 368 static if(sdlSupport >= SDLSupport.v2_24){ 369 ret ~= makeFnBinds([ 370 [q{int}, q{SDL_GetPointDisplayIndex}, q{const(SDL_Point)* point}], 371 [q{int}, q{SDL_GetRectDisplayIndex}, q{const(SDL_Rect)* rect}], 372 ]); 373 } 374 static if(sdlSupport >= SDLSupport.v2_26){ 375 ret ~= makeFnBinds([ 376 [q{void}, q{SDL_GetWindowSizeInPixels}, q{SDL_Window* window, int* w, int* h}], 377 ]); 378 } 379 return ret; 380 }()));