1 /*
2     DSDL
3     Copyright (C) 2025 Inochi2D Project <luna@foxgirls.gay>
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     ==========================================================================
22 
23     Simple DirectMedia Layer
24     Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
25 
26     This software is provided 'as-is', without any express or implied
27     warranty.  In no event will the authors be held liable for any damages
28     arising from the use of this software.
29 
30     Permission is granted to anyone to use this software for any purpose,
31     including commercial applications, and to alter it and redistribute it
32     freely, subject to the following restrictions:
33 
34     1. The origin of this software must not be misrepresented; you must not
35         claim that you wrote the original software. If you use this software
36         in a product, an acknowledgment in the product documentation would be
37         appreciated but is not required.
38     2. Altered source versions must be plainly marked as such, and must not be
39         misrepresented as being the original software.
40     3. This notice may not be removed or altered from any source distribution.
41 */
42 
43 /**
44     SDL Initialization
45 
46     See_Also:
47         $(LINK2 https://wiki.libsdl.org/SDL3/CategoryInit, SDL3 Documentation)
48     
49     Copyright: © 2025 Inochi2D Project, © 1997-2025 Sam Lantinga
50     License: Subject to the terms of the Zlib License, as written in the LICENSE file.
51     Authors: 
52         Luna Nielsen
53 */
54 module sdl.init;
55 import sdl.stdc;
56 import sdl.events;
57 
58 extern (C) nothrow @nogc:
59 
60 /**
61     Initialization flags for $(D SDL_Init) and/or $(D SDL_InitSubSystem)
62 
63     These are the flags which may be passed to $(D SDL_Init). You should specify
64     the subsystems which you will be using in your application.
65 
66     See_Also:
67         $(D SDL_Init)
68         $(D SDL_Quit)
69         $(D SDL_InitSubSystem)
70         $(D SDL_QuitSubSystem)
71         $(D SDL_WasInit)
72 */
73 alias SDL_InitFlags = Uint32;
74 
75 /**
76     $(D SDL_INIT_AUDIO) implies $(D SDL_INIT_EVENTS)
77 */
78 enum SDL_InitFlags SDL_INIT_AUDIO = 0x00000010u;
79 
80 /**
81     $(D SDL_INIT_VIDEO) implies $(D SDL_INIT_EVENTS), should be initialized on the main thread
82 */
83 enum SDL_InitFlags SDL_INIT_VIDEO = 0x00000020u;
84 
85 /**
86     $(D SDL_INIT_JOYSTICK) implies $(D SDL_INIT_EVENTS), should be initialized on the same thread as $(D SDL_INIT_VIDEO) on Windows if you don't set $(D SDL_HINT_JOYSTICK_THREAD)
87 */
88 enum SDL_InitFlags SDL_INIT_JOYSTICK = 0x00000200u;
89 
90 /**
91     $(D SDL_INIT_GAMEPAD) implies $(D SDL_INIT_JOYSTICK)
92 */
93 enum SDL_InitFlags SDL_INIT_GAMEPAD = 0x00002000u;
94 
95 /**
96     $(D SDL_INIT_SENSOR) implies $(D SDL_INIT_EVENTS)
97 */
98 enum SDL_InitFlags SDL_INIT_SENSOR = 0x00008000u;
99 
100 /**
101     $(D SDL_INIT_CAMERA) implies $(D SDL_INIT_EVENTS)
102 */
103 enum SDL_InitFlags SDL_INIT_CAMERA = 0x00010000u;
104 
105 enum SDL_InitFlags SDL_INIT_EVENTS = 0x00004000u;
106 enum SDL_InitFlags SDL_INIT_HAPTIC = 0x00001000u;
107 enum SDL_InitFlags SDL_INIT_EVERYTHING = 
108     SDL_INIT_AUDIO | SDL_INIT_VIDEO | 
109     SDL_INIT_GAMEPAD | SDL_INIT_CAMERA | 
110     SDL_INIT_SENSOR;
111 
112 /**
113     Return values for optional main callbacks.
114 
115     Returning SDL_APP_SUCCESS or SDL_APP_FAILURE from SDL_AppInit,
116     SDL_AppEvent, or SDL_AppIterate will terminate the program and report
117     success/failure to the operating system. What that means is
118     platform-dependent. On Unix, for example, on success, the process error
119     code will be zero, and on failure it will be 1. This interface doesn't
120     allow you to return specific exit codes, just whether there was an error
121     generally or not.
122 
123     Returning SDL_APP_CONTINUE from these functions will let the app continue
124     to run.
125 
126     See $(LINK2 https://wiki.libsdl.org/SDL3/README/main-functions#main-callbacks-in-sdl3, Main callbacks in SDL3)
127     for complete details.
128 */
129 enum SDL_AppResult {
130 
131     /**
132         Value that requests that the app continue from the main callbacks.
133     */
134     SDL_APP_CONTINUE,
135 
136     /**
137         Value that requests termination with success from the main callbacks.
138     */
139     SDL_APP_SUCCESS,
140 
141     /**
142         Value that requests termination with error from the main callbacks.
143     */
144     SDL_APP_FAILURE
145 }
146 
147 /**
148     Function pointer typedef for SDL_AppInit.
149 
150     These are used by SDL_EnterAppMainCallbacks. This mechanism operates behind
151     the scenes for apps using the optional main callbacks. Apps that want to
152     use this should just implement SDL_AppInit directly.
153 
154     Params:
155         appstate =  a place where the app can optionally store a pointer for
156                     future use.
157         argc =      the standard ANSI C main's argc; number of elements in `argv`.
158         argv =      the standard ANSI C main's argv; array of command line
159                     arguments.
160     
161     Returns:
162         SDL_APP_FAILURE to terminate with an error, SDL_APP_SUCCESS to
163         terminate with success, SDL_APP_CONTINUE to continue.
164 */
165 alias SDL_AppInit_func = SDL_AppResult function(void** appstate, int argc, char** argv);
166 
167 /**
168     Function pointer typedef for SDL_AppIterate.
169 
170     These are used by SDL_EnterAppMainCallbacks. This mechanism operates behind
171     the scenes for apps using the optional main callbacks. Apps that want to
172     use this should just implement SDL_AppIterate directly.
173 
174     Params:
175         appstate = an optional pointer, provided by the app in SDL_AppInit.
176     
177     Returns:
178         SDL_APP_FAILURE to terminate with an error, SDL_APP_SUCCESS to
179         terminate with success, SDL_APP_CONTINUE to continue.
180 
181 */
182 alias SDL_AppIterate_func = SDL_AppResult function(void* appstate);
183 
184 /**
185     Function pointer typedef for SDL_AppEvent.
186 
187     These are used by SDL_EnterAppMainCallbacks. This mechanism operates behind
188     the scenes for apps using the optional main callbacks. Apps that want to
189     use this should just implement SDL_AppEvent directly.
190 
191     Params:
192         appstate =  an optional pointer, provided by the app in SDL_AppInit.
193         event =     the new event for the app to examine.
194     
195     Returns:
196         SDL_APP_FAILURE to terminate with an error, SDL_APP_SUCCESS to
197         terminate with success, SDL_APP_CONTINUE to continue.
198 
199 */
200 alias SDL_AppEvent_func = SDL_AppResult function(void* appstate, SDL_Event* event);
201 
202 /**
203     Function pointer typedef for SDL_AppQuit.
204 
205     These are used by SDL_EnterAppMainCallbacks. This mechanism operates behind
206     the scenes for apps using the optional main callbacks. Apps that want to
207     use this should just implement SDL_AppEvent directly.
208 
209     \param appstate an optional pointer, provided by the app in SDL_AppInit.
210     \param result the result code that terminated the app (success or failure).
211 
212 */
213 alias SDL_AppQuit_func = void function(void* appstate, SDL_AppResult result);
214 
215 /**
216     Initialize the SDL library.
217 
218     SDL_Init() simply forwards to calling SDL_InitSubSystem(). Therefore, the
219     two may be used interchangeably. Though for readability of your code
220     SDL_InitSubSystem() might be preferred.
221 
222     The file I/O (for example: SDL_IOFromFile) and threading (SDL_CreateThread)
223     subsystems are initialized by default. Message boxes
224     (SDL_ShowSimpleMessageBox) also attempt to work without initializing the
225     video subsystem, in hopes of being useful in showing an error dialog when
226     SDL_Init fails. You must specifically initialize other subsystems if you
227     use them in your application.
228 
229     Logging (such as SDL_Log) works without initialization, too.
230 
231     `flags` may be any of the following OR'd together:
232 
233     -   `SDL_INIT_AUDIO`: audio subsystem; automatically initializes the events
234         subsystem
235     -   `SDL_INIT_VIDEO`: video subsystem; automatically initializes the events
236         subsystem, should be initialized on the main thread.
237     -   `SDL_INIT_JOYSTICK`: joystick subsystem; automatically initializes the
238         events subsystem
239     -   `SDL_INIT_HAPTIC`: haptic (force feedback) subsystem
240     -   `SDL_INIT_GAMEPAD`: gamepad subsystem; automatically initializes the
241         joystick subsystem
242     -   `SDL_INIT_EVENTS`: events subsystem
243     -   `SDL_INIT_SENSOR`: sensor subsystem; automatically initializes the events
244         subsystem
245     -   `SDL_INIT_CAMERA`: camera subsystem; automatically initializes the events
246         subsystem
247 
248     Subsystem initialization is ref-counted, you must call SDL_QuitSubSystem()
249     for each SDL_InitSubSystem() to correctly shutdown a subsystem manually (or
250     call SDL_Quit() to force shutdown). If a subsystem is already loaded then
251     this call will increase the ref-count and return.
252 
253     Consider reporting some basic metadata about your application before
254     calling SDL_Init, using either SDL_SetAppMetadata() or
255     SDL_SetAppMetadataProperty().
256 
257     Params:
258         flags = subsystem initialization flags.
259     
260     Returns:
261         true on success or false on failure; call SDL_GetError() for more
262         information.
263 
264     See_Also:
265         $(D SDL_SetAppMetadata)
266         $(D SDL_SetAppMetadataProperty)
267         $(D SDL_InitSubSystem)
268         $(D SDL_Quit)
269         $(D SDL_SetMainReady)
270         $(D SDL_WasInit)
271 */
272 extern bool SDL_Init(SDL_InitFlags flags);
273 
274 /**
275     Compatibility function to initialize the SDL library.
276 
277     This function and SDL_Init() are interchangeable.
278 
279     Params:
280         flags = any of the flags used by SDL_Init(); see SDL_Init for details.
281     
282     Returns:
283         true on success or false on failure; call SDL_GetError() for more
284         information.
285 
286     See_Also:
287         $(D SDL_Init)
288         $(D SDL_Quit)
289         $(D SDL_QuitSubSystem)
290 */
291 extern bool SDL_InitSubSystem(SDL_InitFlags flags);
292 
293 /**
294     Shut down specific SDL subsystems.
295 
296     You still need to call SDL_Quit() even if you close all open subsystems
297     with SDL_QuitSubSystem().
298 
299     Params:
300         flags = any of the flags used by SDL_Init(); see SDL_Init for details.
301 
302     See_Also:
303         $(D SDL_InitSubSystem)
304         $(D SDL_Quit)
305 */
306 extern void SDL_QuitSubSystem(SDL_InitFlags flags);
307 
308 /**
309     Get a mask of the specified subsystems which are currently initialized.
310 
311     Params:
312         flags = any of the flags used by SDL_Init(); see SDL_Init for details.
313     
314     Returns:
315         A mask of all initialized subsystems if `flags` is 0, otherwise it
316         returns the initialization status of the specified subsystems.
317 
318     See_Also:
319         $(D SDL_Init)
320         $(D SDL_InitSubSystem)
321 */
322 extern SDL_InitFlags SDL_WasInit(SDL_InitFlags flags);
323 
324 /**
325     Clean up all initialized subsystems.
326 
327     You should call this function even if you have already shutdown each
328     initialized subsystem with SDL_QuitSubSystem(). It is safe to call this
329     function even in the case of errors in initialization.
330 
331     You can use this function with atexit() to ensure that it is run when your
332     application is shutdown, but it is not wise to do this from a library or
333     other dynamically loaded code.
334 
335     See_Also:
336         $(D SDL_Init)
337         $(D SDL_QuitSubSystem)
338 */
339 extern void SDL_Quit();
340 
341 /**
342     Return whether this is the main thread.
343 
344     On Apple platforms, the main thread is the thread that runs your program's
345     main() entry point. On other platforms, the main thread is the one that
346     calls SDL_Init(SDL_INIT_VIDEO), which should usually be the one that runs
347     your program's main() entry point. If you are using the main callbacks,
348     SDL_AppInit(), SDL_AppIterate(), and SDL_AppQuit() are all called on the
349     main thread.
350 
351     Returns:
352         true if this thread is the main thread, or false otherwise.
353 
354     Threadsafety:
355         It is safe to call this function from any thread.
356 
357     See_Also:
358         $(D SDL_RunOnMainThread)
359 */
360 extern bool SDL_IsMainThread();
361 
362 /**
363     Callback run on the main thread.
364 
365     \param userdata an app-controlled pointer that is passed to the callback.
366 
367 
368     \sa SDL_RunOnMainThread
369 */
370 alias SDL_MainThreadCallback = void function(void* userdata);
371 
372 /**
373     Call a function on the main thread during event processing.
374 
375     If this is called on the main thread, the callback is executed immediately.
376     If this is called on another thread, this callback is queued for execution
377     on the main thread during event processing.
378 
379     Be careful of deadlocks when using this functionality. You should not have
380     the main thread wait for the current thread while this function is being
381     called with `wait_complete` true.
382 
383     Params:
384         callback =      the callback to call on the main thread.
385         userdata =      a pointer that is passed to `callback`.
386         wait_complete = true to wait for the callback to complete, false to
387                         return immediately.
388     
389     Returns:
390         true on success or false on failure; call SDL_GetError() for more
391         information.
392 
393     Threadsafety:
394         It is safe to call this function from any thread.
395 
396     See_Also:
397         $(D SDL_IsMainThread)
398 */
399 extern bool SDL_RunOnMainThread(SDL_MainThreadCallback callback, void* userdata, bool wait_complete);
400 
401 /**
402     Specify basic metadata about your app.
403 
404     You can optionally provide metadata about your app to SDL. This is not
405     required, but strongly encouraged.
406 
407     There are several locations where SDL can make use of metadata (an "About"
408     box in the macOS menu bar, the name of the app can be shown on some audio
409     mixers, etc). Any piece of metadata can be left as NULL, if a specific
410     detail doesn't make sense for the app.
411 
412     This function should be called as early as possible, before SDL_Init.
413     Multiple calls to this function are allowed, but various state might not
414     change once it has been set up with a previous call to this function.
415 
416     Passing a NULL removes any previous metadata.
417 
418     This is a simplified interface for the most important information. You can
419     supply significantly more detailed metadata with
420     SDL_SetAppMetadataProperty().
421 
422     Params:
423         appname =       The name of the application ("My Game 2: Bad Guy's
424                         Revenge!").
425         appversion =    The version of the application ("1.0.0beta5" or a git
426                         hash, or whatever makes sense).
427         appidentifier = A unique string in reverse-domain format that
428                         identifies this app ("com.example.mygame2").
429     
430     Returns:
431         true on success or false on failure; call SDL_GetError() for more
432         information.
433 
434     Threadsafety:
435         It is safe to call this function from any thread.
436 
437     See_Also:
438         $(D SDL_SetAppMetadataProperty)
439 */
440 extern bool SDL_SetAppMetadata(const(char)* appname, const(char)* appversion, const(char)* appidentifier);
441 
442 /**
443     Specify metadata about your app through a set of properties.
444 
445     You can optionally provide metadata about your app to SDL. This is not
446     required, but strongly encouraged.
447 
448     There are several locations where SDL can make use of metadata (an "About"
449     box in the macOS menu bar, the name of the app can be shown on some audio
450     mixers, etc). Any piece of metadata can be left out, if a specific detail
451     doesn't make sense for the app.
452 
453     This function should be called as early as possible, before SDL_Init.
454     Multiple calls to this function are allowed, but various state might not
455     change once it has been set up with a previous call to this function.
456 
457     Once set, this metadata can be read using SDL_GetAppMetadataProperty().
458 
459     These are the supported properties:
460 
461     -   `SDL_PROP_APP_METADATA_NAME_STRING`: The human-readable name of the
462         application, like "My Game 2: Bad Guy's Revenge!". This will show up
463         anywhere the OS shows the name of the application separately from window
464         titles, such as volume control applets, etc. This defaults to "SDL
465         Application".
466     -   `SDL_PROP_APP_METADATA_VERSION_STRING`: The version of the app that is
467         running; there are no rules on format, so "1.0.3beta2" and "April 22nd,
468         2024" and a git hash are all valid options. This has no default.
469     -   `SDL_PROP_APP_METADATA_IDENTIFIER_STRING`: A unique string that
470         identifies this app. This must be in reverse-domain format, like
471         "com.example.mygame2". This string is used by desktop compositors to
472         identify and group windows together, as well as match applications with
473         associated desktop settings and icons. If you plan to package your
474         application in a container such as Flatpak, the app ID should match the
475         name of your Flatpak container as well. This has no default.
476     -   `SDL_PROP_APP_METADATA_CREATOR_STRING`: The human-readable name of the
477         creator/developer/maker of this app, like "MojoWorkshop, LLC"
478     -   `SDL_PROP_APP_METADATA_COPYRIGHT_STRING`: The human-readable copyright
479         notice, like "Copyright (c) 2024 MojoWorkshop, LLC" or whatnot. Keep this
480         to one line, don't paste a copy of a whole software license in here. This
481         has no default.
482     -   `SDL_PROP_APP_METADATA_URL_STRING`: A URL to the app on the web. Maybe a
483         product page, or a storefront, or even a GitHub repository, for user's
484         further information This has no default.
485     -   `SDL_PROP_APP_METADATA_TYPE_STRING`: The type of application this is.
486         Currently this string can be "game" for a video game, "mediaplayer" for a
487         media player, or generically "application" if nothing else applies.
488         Future versions of SDL might add new types. This defaults to
489         "application".
490 
491     Params:
492         name =  the name of the metadata property to set.
493         value = the value of the property, or NULL to remove that property.
494     
495     Returns:
496         true on success or false on failure; call SDL_GetError() for more
497         information.
498 
499     Threadsafety:
500         It is safe to call this function from any thread.
501 
502     See_Also:
503         $(D SDL_GetAppMetadataProperty)
504         $(D SDL_SetAppMetadata)
505 */
506 extern bool SDL_SetAppMetadataProperty(const(char)* name, const(char)* value);
507 
508 enum SDL_PROP_APP_METADATA_NAME_STRING = "SDL.app.metadata.name";
509 enum SDL_PROP_APP_METADATA_VERSION_STRING = "SDL.app.metadata.version";
510 enum SDL_PROP_APP_METADATA_IDENTIFIER_STRING = "SDL.app.metadata.identifier";
511 enum SDL_PROP_APP_METADATA_CREATOR_STRING = "SDL.app.metadata.creator";
512 enum SDL_PROP_APP_METADATA_COPYRIGHT_STRING = "SDL.app.metadata.copyright";
513 enum SDL_PROP_APP_METADATA_URL_STRING = "SDL.app.metadata.url";
514 enum SDL_PROP_APP_METADATA_TYPE_STRING = "SDL.app.metadata.type";
515 
516 /**
517     Get metadata about your app.
518 
519     This returns metadata previously set using SDL_SetAppMetadata() or
520     SDL_SetAppMetadataProperty(). See SDL_SetAppMetadataProperty() for the list
521     of available properties and their meanings.
522 
523     Params:
524         name =  the name of the metadata property to get.
525     
526     Returns:
527         The current value of the metadata property, or the default if it
528         is not set, NULL for properties with no default.
529 
530     Threadsafety:
531         It is safe to call this function from any thread, although
532         the string returned is not protected and could potentially be
533         freed if you call SDL_SetAppMetadataProperty() to set that
534         property from another thread.
535 
536     See_Also:
537         $(D SDL_SetAppMetadata)
538         $(D SDL_SetAppMetadataProperty)
539 */
540 extern const(char)* SDL_GetAppMetadataProperty(const(char)* name);