summaryrefslogtreecommitdiff
path: root/contrib/SDL-3.2.8/src/test/SDL_test_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/SDL-3.2.8/src/test/SDL_test_common.c')
-rw-r--r--contrib/SDL-3.2.8/src/test/SDL_test_common.c2862
1 files changed, 2862 insertions, 0 deletions
diff --git a/contrib/SDL-3.2.8/src/test/SDL_test_common.c b/contrib/SDL-3.2.8/src/test/SDL_test_common.c
new file mode 100644
index 0000000..3203dde
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/test/SDL_test_common.c
@@ -0,0 +1,2862 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 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
22/* Ported from original test/common.c file. */
23#include <SDL3/SDL_test.h>
24
25#define SDL_MAIN_NOIMPL
26#define SDL_MAIN_USE_CALLBACKS
27#include <SDL3/SDL_main.h>
28
29static const char *common_usage[] = {
30 "[-h | --help]",
31 "[--trackmem]",
32 "[--randmem]",
33 "[--info all|video|modes|render|event|event_motion]",
34 "[--log all|error|system|audio|video|render|input]",
35 NULL
36};
37
38static const char *video_usage[] = {
39 "[--always-on-top]",
40 "[--aspect min-max]",
41 "[--auto-scale-content]",
42 "[--center | --position X,Y]",
43 "[--confine-cursor X,Y,W,H]",
44 "[--depth N]",
45 "[--display N]",
46 "[--flash-on-focus-loss]",
47 "[--fullscreen | --fullscreen-desktop | --windows N]",
48 "[--geometry WxH]",
49 "[--gldebug]",
50 "[--grab]",
51 "[--hidden]",
52 "[--hide-cursor]",
53 "[--high-pixel-density]",
54 "[--icon icon.bmp]",
55 "[--input-focus]",
56 "[--keyboard-grab]",
57 "[--logical-presentation disabled|match|stretch|letterbox|overscan|integer_scale]",
58 "[--logical-scale-quality nearest|linear|best]",
59 "[--logical WxH]",
60 "[--max-geometry WxH]",
61 "[--maximize]",
62 "[--metal-window | --opengl-window | --vulkan-window]",
63 "[--min-geometry WxH]",
64 "[--minimize]",
65 "[--mouse-focus]",
66 "[--noframe]",
67 "[--refresh R]",
68 "[--renderer driver]",
69 "[--resizable]",
70 "[--scale N]",
71 "[--title title]",
72 "[--transparent]",
73 "[--usable-bounds]",
74 "[--utility]",
75 "[--video driver]",
76 "[--gpu driver]",
77 "[--vsync]",
78 NULL
79};
80
81/* !!! FIXME: Float32? Sint32? */
82static const char *audio_usage[] = {
83 "[--audio driver]",
84 "[--rate N]",
85 "[--format U8|S8|S16|S16LE|S16BE|S32|S32LE|S32BE|F32|F32LE|F32BE]",
86 "[--channels N]",
87 NULL
88};
89
90static void SDL_snprintfcat(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
91{
92 size_t length = SDL_strlen(text);
93 va_list ap;
94
95 va_start(ap, fmt);
96 text += length;
97 maxlen -= length;
98 (void)SDL_vsnprintf(text, maxlen, fmt, ap);
99 va_end(ap);
100}
101
102static void SDLCALL SDLTest_CommonArgParserFinalize(void *data)
103{
104 SDLTest_CommonState *state = data;
105
106 if (!(state->flags & SDL_INIT_VIDEO)) {
107 state->video_argparser.usage = NULL;
108 }
109 if (!(state->flags & SDL_INIT_AUDIO)) {
110 state->audio_argparser.usage = NULL;
111 }
112}
113
114#define SEARCHARG(dim) \
115 while (*(dim) && *(dim) != ',') { \
116 ++(dim); \
117 } \
118 if (!*(dim)) { \
119 return -1; \
120 } \
121 *(dim)++ = '\0';
122
123static int SDLCALL SDLTest_CommonStateParseCommonArguments(void *data, char **argv, int index)
124{
125 SDLTest_CommonState *state = data;
126
127 if ((SDL_strcasecmp(argv[index], "-h") == 0) || (SDL_strcasecmp(argv[index], "--help") == 0)) {
128 /* Print the usage message */
129 return -1;
130 }
131 if (SDL_strcasecmp(argv[index], "--trackmem") == 0) {
132 /* Already handled in SDLTest_CommonCreateState() */
133 return 1;
134 }
135 if (SDL_strcasecmp(argv[index], "--randmem") == 0) {
136 /* Already handled in SDLTest_CommonCreateState() */
137 return 1;
138 }
139 if (SDL_strcasecmp(argv[index], "--log") == 0) {
140 ++index;
141 if (!argv[index]) {
142 return -1;
143 }
144 if (SDL_strcasecmp(argv[index], "all") == 0) {
145 SDL_SetLogPriorities(SDL_LOG_PRIORITY_VERBOSE);
146 return 2;
147 }
148 if (SDL_strcasecmp(argv[index], "system") == 0) {
149 SDL_SetLogPriority(SDL_LOG_CATEGORY_SYSTEM, SDL_LOG_PRIORITY_VERBOSE);
150 return 2;
151 }
152 if (SDL_strcasecmp(argv[index], "audio") == 0) {
153 SDL_SetLogPriority(SDL_LOG_CATEGORY_AUDIO, SDL_LOG_PRIORITY_VERBOSE);
154 return 2;
155 }
156 if (SDL_strcasecmp(argv[index], "video") == 0) {
157 SDL_SetLogPriority(SDL_LOG_CATEGORY_VIDEO, SDL_LOG_PRIORITY_VERBOSE);
158 return 2;
159 }
160 if (SDL_strcasecmp(argv[index], "render") == 0) {
161 SDL_SetLogPriority(SDL_LOG_CATEGORY_RENDER, SDL_LOG_PRIORITY_VERBOSE);
162 return 2;
163 }
164 if (SDL_strcasecmp(argv[index], "input") == 0) {
165 SDL_SetLogPriority(SDL_LOG_CATEGORY_INPUT, SDL_LOG_PRIORITY_VERBOSE);
166 return 2;
167 }
168 return -1;
169 }
170
171 if (SDL_strcasecmp(argv[index], "--info") == 0) {
172 ++index;
173 if (!argv[index]) {
174 return -1;
175 }
176 if (SDL_strcasecmp(argv[index], "all") == 0) {
177 state->verbose |=
178 (VERBOSE_VIDEO | VERBOSE_MODES | VERBOSE_RENDER |
179 VERBOSE_EVENT);
180 return 2;
181 }
182 if (SDL_strcasecmp(argv[index], "video") == 0) {
183 state->verbose |= VERBOSE_VIDEO;
184 return 2;
185 }
186 if (SDL_strcasecmp(argv[index], "modes") == 0) {
187 state->verbose |= VERBOSE_MODES;
188 return 2;
189 }
190 if (SDL_strcasecmp(argv[index], "render") == 0) {
191 state->verbose |= VERBOSE_RENDER;
192 return 2;
193 }
194 if (SDL_strcasecmp(argv[index], "event") == 0) {
195 state->verbose |= VERBOSE_EVENT;
196 return 2;
197 }
198 if (SDL_strcasecmp(argv[index], "event_motion") == 0) {
199 state->verbose |= (VERBOSE_EVENT | VERBOSE_MOTION);
200 return 2;
201 }
202 return -1;
203 }
204 if (SDL_strcmp(argv[index], "-NSDocumentRevisionsDebugMode") == 0) {
205 /* Debug flag sent by Xcode */
206 return 2;
207 }
208 return 0;
209}
210
211static int SDLCALL SDLTest_CommonStateParseVideoArguments(void *data, char **argv, int index)
212{
213 SDLTest_CommonState *state = data;
214
215 if (!(state->flags & SDL_INIT_VIDEO)) {
216 return 0;
217 }
218
219 if (SDL_strcasecmp(argv[index], "--video") == 0) {
220 ++index;
221 if (!argv[index]) {
222 return -1;
223 }
224 state->videodriver = argv[index];
225 SDL_SetHint(SDL_HINT_VIDEO_DRIVER, state->videodriver);
226 return 2;
227 }
228 if (SDL_strcasecmp(argv[index], "--renderer") == 0) {
229 ++index;
230 if (!argv[index]) {
231 return -1;
232 }
233 state->renderdriver = argv[index];
234 SDL_SetHint(SDL_HINT_RENDER_DRIVER, state->renderdriver);
235 return 2;
236 }
237 if (SDL_strcasecmp(argv[index], "--gldebug") == 0) {
238 state->gl_debug = 1;
239 return 1;
240 }
241 if (SDL_strcasecmp(argv[index], "--display") == 0) {
242 ++index;
243 if (!argv[index]) {
244 return -1;
245 }
246 state->display_index = SDL_atoi(argv[index]);
247 return 2;
248 }
249 if (SDL_strcasecmp(argv[index], "--metal-window") == 0) {
250 state->window_flags |= SDL_WINDOW_METAL;
251 return 1;
252 }
253 if (SDL_strcasecmp(argv[index], "--opengl-window") == 0) {
254 state->window_flags |= SDL_WINDOW_OPENGL;
255 return 1;
256 }
257 if (SDL_strcasecmp(argv[index], "--vulkan-window") == 0) {
258 state->window_flags |= SDL_WINDOW_VULKAN;
259 return 1;
260 }
261 if (SDL_strcasecmp(argv[index], "--fullscreen") == 0) {
262 state->window_flags |= SDL_WINDOW_FULLSCREEN;
263 state->fullscreen_exclusive = true;
264 state->num_windows = 1;
265 return 1;
266 }
267 if (SDL_strcasecmp(argv[index], "--fullscreen-desktop") == 0) {
268 state->window_flags |= SDL_WINDOW_FULLSCREEN;
269 state->fullscreen_exclusive = false;
270 state->num_windows = 1;
271 return 1;
272 }
273 if (SDL_strcasecmp(argv[index], "--windows") == 0) {
274 ++index;
275 if (!argv[index] || !SDL_isdigit((unsigned char) *argv[index])) {
276 return -1;
277 }
278 if (!(state->window_flags & SDL_WINDOW_FULLSCREEN)) {
279 state->num_windows = SDL_atoi(argv[index]);
280 }
281 return 2;
282 }
283 if (SDL_strcasecmp(argv[index], "--title") == 0) {
284 ++index;
285 if (!argv[index]) {
286 return -1;
287 }
288 state->window_title = argv[index];
289 return 2;
290 }
291 if (SDL_strcasecmp(argv[index], "--icon") == 0) {
292 ++index;
293 if (!argv[index]) {
294 return -1;
295 }
296 state->window_icon = argv[index];
297 return 2;
298 }
299 if (SDL_strcasecmp(argv[index], "--center") == 0) {
300 state->window_x = SDL_WINDOWPOS_CENTERED;
301 state->window_y = SDL_WINDOWPOS_CENTERED;
302 return 1;
303 }
304 if (SDL_strcasecmp(argv[index], "--position") == 0) {
305 char *x, *y;
306 ++index;
307 if (!argv[index]) {
308 return -1;
309 }
310 x = argv[index];
311 y = argv[index];
312 while (*y && *y != ',') {
313 ++y;
314 }
315 if (!*y) {
316 return -1;
317 }
318 *y++ = '\0';
319 state->window_x = SDL_atoi(x);
320 state->window_y = SDL_atoi(y);
321 return 2;
322 }
323 if (SDL_strcasecmp(argv[index], "--confine-cursor") == 0) {
324 char *x, *y, *w, *h;
325 ++index;
326 if (!argv[index]) {
327 return -1;
328 }
329 x = argv[index];
330 y = argv[index];
331 SEARCHARG(y)
332 w = y;
333 SEARCHARG(w)
334 h = w;
335 SEARCHARG(h)
336 state->confine.x = SDL_atoi(x);
337 state->confine.y = SDL_atoi(y);
338 state->confine.w = SDL_atoi(w);
339 state->confine.h = SDL_atoi(h);
340 return 2;
341 }
342 if (SDL_strcasecmp(argv[index], "--usable-bounds") == 0) {
343 state->fill_usable_bounds = true;
344 return 1;
345 }
346 if (SDL_strcasecmp(argv[index], "--geometry") == 0) {
347 char *w, *h;
348 ++index;
349 if (!argv[index]) {
350 return -1;
351 }
352 w = argv[index];
353 h = argv[index];
354 while (*h && *h != 'x') {
355 ++h;
356 }
357 if (!*h) {
358 return -1;
359 }
360 *h++ = '\0';
361 state->window_w = SDL_atoi(w);
362 state->window_h = SDL_atoi(h);
363 return 2;
364 }
365 if (SDL_strcasecmp(argv[index], "--min-geometry") == 0) {
366 char *w, *h;
367 ++index;
368 if (!argv[index]) {
369 return -1;
370 }
371 w = argv[index];
372 h = argv[index];
373 while (*h && *h != 'x') {
374 ++h;
375 }
376 if (!*h) {
377 return -1;
378 }
379 *h++ = '\0';
380 state->window_minW = SDL_atoi(w);
381 state->window_minH = SDL_atoi(h);
382 return 2;
383 }
384 if (SDL_strcasecmp(argv[index], "--max-geometry") == 0) {
385 char *w, *h;
386 ++index;
387 if (!argv[index]) {
388 return -1;
389 }
390 w = argv[index];
391 h = argv[index];
392 while (*h && *h != 'x') {
393 ++h;
394 }
395 if (!*h) {
396 return -1;
397 }
398 *h++ = '\0';
399 state->window_maxW = SDL_atoi(w);
400 state->window_maxH = SDL_atoi(h);
401 return 2;
402 }
403 if (SDL_strcasecmp(argv[index], "--aspect") == 0) {
404 char *min_aspect, *max_aspect;
405 ++index;
406 if (!argv[index]) {
407 return -1;
408 }
409 min_aspect = argv[index];
410 max_aspect = argv[index];
411 while (*max_aspect && *max_aspect != '-') {
412 ++max_aspect;
413 }
414 if (*max_aspect) {
415 *max_aspect++ = '\0';
416 } else {
417 max_aspect = min_aspect;
418 }
419 state->window_min_aspect = (float)SDL_atof(min_aspect);
420 state->window_max_aspect = (float)SDL_atof(max_aspect);
421 return 2;
422 }
423 if (SDL_strcasecmp(argv[index], "--logical") == 0) {
424 char *w, *h;
425 ++index;
426 if (!argv[index]) {
427 return -1;
428 }
429 w = argv[index];
430 h = argv[index];
431 while (*h && *h != 'x') {
432 ++h;
433 }
434 if (!*h) {
435 return -1;
436 }
437 *h++ = '\0';
438 state->logical_w = SDL_atoi(w);
439 state->logical_h = SDL_atoi(h);
440 return 2;
441 }
442 if (SDL_strcasecmp(argv[index], "--high-pixel-density") == 0) {
443 state->window_flags |= SDL_WINDOW_HIGH_PIXEL_DENSITY;
444 return 1;
445 }
446 if (SDL_strcasecmp(argv[index], "--auto-scale-content") == 0) {
447 state->auto_scale_content = true;
448
449 if (state->logical_presentation == SDL_LOGICAL_PRESENTATION_DISABLED) {
450 state->logical_presentation = SDL_LOGICAL_PRESENTATION_STRETCH;
451 }
452 return 1;
453 }
454 if (SDL_strcasecmp(argv[index], "--logical-presentation") == 0) {
455 ++index;
456 if (!argv[index]) {
457 return -1;
458 }
459 if (SDL_strcasecmp(argv[index], "disabled") == 0) {
460 state->logical_presentation = SDL_LOGICAL_PRESENTATION_DISABLED;
461 return 2;
462 }
463 if (SDL_strcasecmp(argv[index], "stretch") == 0) {
464 state->logical_presentation = SDL_LOGICAL_PRESENTATION_STRETCH;
465 return 2;
466 }
467 if (SDL_strcasecmp(argv[index], "letterbox") == 0) {
468 state->logical_presentation = SDL_LOGICAL_PRESENTATION_LETTERBOX;
469 return 2;
470 }
471 if (SDL_strcasecmp(argv[index], "overscan") == 0) {
472 state->logical_presentation = SDL_LOGICAL_PRESENTATION_OVERSCAN;
473 return 2;
474 }
475 if (SDL_strcasecmp(argv[index], "integer_scale") == 0) {
476 state->logical_presentation = SDL_LOGICAL_PRESENTATION_INTEGER_SCALE;
477 return 2;
478 }
479 return -1;
480 }
481 if (SDL_strcasecmp(argv[index], "--scale") == 0) {
482 ++index;
483 if (!argv[index]) {
484 return -1;
485 }
486 state->scale = (float) SDL_atof(argv[index]);
487 return 2;
488 }
489 if (SDL_strcasecmp(argv[index], "--depth") == 0) {
490 ++index;
491 if (!argv[index]) {
492 return -1;
493 }
494 state->depth = SDL_atoi(argv[index]);
495 return 2;
496 }
497 if (SDL_strcasecmp(argv[index], "--refresh") == 0) {
498 ++index;
499 if (!argv[index]) {
500 return -1;
501 }
502 state->refresh_rate = (float) SDL_atof(argv[index]);
503 return 2;
504 }
505 if (SDL_strcasecmp(argv[index], "--vsync") == 0) {
506 state->render_vsync = 1;
507 return 1;
508 }
509 if (SDL_strcasecmp(argv[index], "--noframe") == 0) {
510 state->window_flags |= SDL_WINDOW_BORDERLESS;
511 return 1;
512 }
513 if (SDL_strcasecmp(argv[index], "--resizable") == 0) {
514 state->window_flags |= SDL_WINDOW_RESIZABLE;
515 return 1;
516 }
517 if (SDL_strcasecmp(argv[index], "--transparent") == 0) {
518 state->window_flags |= SDL_WINDOW_TRANSPARENT;
519 return 1;
520 }
521 if (SDL_strcasecmp(argv[index], "--always-on-top") == 0) {
522 state->window_flags |= SDL_WINDOW_ALWAYS_ON_TOP;
523 return 1;
524 }
525 if (SDL_strcasecmp(argv[index], "--minimize") == 0) {
526 state->window_flags |= SDL_WINDOW_MINIMIZED;
527 return 1;
528 }
529 if (SDL_strcasecmp(argv[index], "--maximize") == 0) {
530 state->window_flags |= SDL_WINDOW_MAXIMIZED;
531 return 1;
532 }
533 if (SDL_strcasecmp(argv[index], "--hidden") == 0) {
534 state->window_flags |= SDL_WINDOW_HIDDEN;
535 return 1;
536 }
537 if (SDL_strcasecmp(argv[index], "--input-focus") == 0) {
538 state->window_flags |= SDL_WINDOW_INPUT_FOCUS;
539 return 1;
540 }
541 if (SDL_strcasecmp(argv[index], "--mouse-focus") == 0) {
542 state->window_flags |= SDL_WINDOW_MOUSE_FOCUS;
543 return 1;
544 }
545 if (SDL_strcasecmp(argv[index], "--flash-on-focus-loss") == 0) {
546 state->flash_on_focus_loss = true;
547 return 1;
548 }
549 if (SDL_strcasecmp(argv[index], "--grab") == 0) {
550 state->window_flags |= SDL_WINDOW_MOUSE_GRABBED;
551 return 1;
552 }
553 if (SDL_strcasecmp(argv[index], "--keyboard-grab") == 0) {
554 state->window_flags |= SDL_WINDOW_KEYBOARD_GRABBED;
555 return 1;
556 }
557 if (SDL_strcasecmp(argv[index], "--utility") == 0) {
558 state->window_flags |= SDL_WINDOW_UTILITY;
559 return 1;
560 }
561 if (SDL_strcasecmp(argv[index], "--hide-cursor") == 0) {
562 state->hide_cursor = true;
563 return 1;
564 }
565 if (SDL_strcasecmp(argv[index], "--gpu") == 0) {
566 ++index;
567 if (!argv[index]) {
568 return -1;
569 }
570 state->gpudriver = argv[index];
571 SDL_SetHint(SDL_HINT_GPU_DRIVER, state->gpudriver);
572 return 2;
573 }
574 return 0;
575}
576
577static int SDLCALL SDLTest_CommonStateParseAudioArguments(void *data, char **argv, int index)
578{
579 SDLTest_CommonState *state = data;
580
581 if (!(state->flags & SDL_INIT_AUDIO)) {
582 return 0;
583 }
584 if (SDL_strcasecmp(argv[index], "--audio") == 0) {
585 ++index;
586 if (!argv[index]) {
587 return -1;
588 }
589 state->audiodriver = argv[index];
590 SDL_SetHint(SDL_HINT_AUDIO_DRIVER, state->audiodriver);
591 return 2;
592 }
593 if (SDL_strcasecmp(argv[index], "--rate") == 0) {
594 ++index;
595 if (!argv[index]) {
596 return -1;
597 }
598 state->audio_freq = SDL_atoi(argv[index]);
599 return 2;
600 }
601 if (SDL_strcasecmp(argv[index], "--format") == 0) {
602 ++index;
603 if (!argv[index]) {
604 return -1;
605 }
606 if (SDL_strcasecmp(argv[index], "U8") == 0) {
607 state->audio_format = SDL_AUDIO_U8;
608 return 2;
609 }
610 if (SDL_strcasecmp(argv[index], "S8") == 0) {
611 state->audio_format = SDL_AUDIO_S8;
612 return 2;
613 }
614 if (SDL_strcasecmp(argv[index], "S16") == 0) {
615 state->audio_format = SDL_AUDIO_S16;
616 return 2;
617 }
618 if (SDL_strcasecmp(argv[index], "S16LE") == 0) {
619 state->audio_format = SDL_AUDIO_S16LE;
620 return 2;
621 }
622 if (SDL_strcasecmp(argv[index], "S16BE") == 0) {
623 state->audio_format = SDL_AUDIO_S16BE;
624 return 2;
625 }
626 if (SDL_strcasecmp(argv[index], "S32") == 0) {
627 state->audio_format = SDL_AUDIO_S32;
628 return 2;
629 }
630 if (SDL_strcasecmp(argv[index], "S32LE") == 0) {
631 state->audio_format = SDL_AUDIO_S32LE;
632 return 2;
633 }
634 if (SDL_strcasecmp(argv[index], "S32BE") == 0) {
635 state->audio_format = SDL_AUDIO_S32BE;
636 return 2;
637 }
638 if (SDL_strcasecmp(argv[index], "F32") == 0) {
639 state->audio_format = SDL_AUDIO_F32;
640 return 2;
641 }
642 if (SDL_strcasecmp(argv[index], "F32LE") == 0) {
643 state->audio_format = SDL_AUDIO_F32LE;
644 return 2;
645 }
646 if (SDL_strcasecmp(argv[index], "F32BE") == 0) {
647 state->audio_format = SDL_AUDIO_F32BE;
648 return 2;
649 }
650 return -1;
651 }
652 if (SDL_strcasecmp(argv[index], "--channels") == 0) {
653 ++index;
654 if (!argv[index]) {
655 return -1;
656 }
657 state->audio_channels = (Uint8) SDL_atoi(argv[index]);
658 return 2;
659 }
660 return 0;
661}
662
663SDLTest_CommonState *SDLTest_CommonCreateState(char **argv, SDL_InitFlags flags)
664{
665 int i;
666 SDLTest_CommonState *state;
667
668 /* Do this first so we catch all allocations */
669 for (i = 1; argv[i]; ++i) {
670 if (SDL_strcasecmp(argv[i], "--trackmem") == 0) {
671 SDLTest_TrackAllocations();
672 } else if (SDL_strcasecmp(argv[i], "--randmem") == 0) {
673 SDLTest_RandFillAllocations();
674 }
675 }
676
677 state = (SDLTest_CommonState *)SDL_calloc(1, sizeof(*state));
678 if (!state) {
679 return NULL;
680 }
681
682 /* Initialize some defaults */
683 state->argv = argv;
684 state->flags = flags;
685 state->window_title = argv[0];
686 state->window_flags = SDL_WINDOW_HIDDEN;
687 state->window_x = SDL_WINDOWPOS_UNDEFINED;
688 state->window_y = SDL_WINDOWPOS_UNDEFINED;
689 state->window_w = DEFAULT_WINDOW_WIDTH;
690 state->window_h = DEFAULT_WINDOW_HEIGHT;
691 state->logical_presentation = SDL_LOGICAL_PRESENTATION_DISABLED;
692 state->num_windows = 1;
693 state->audio_freq = 22050;
694 state->audio_format = SDL_AUDIO_S16;
695 state->audio_channels = 2;
696
697 /* Set some very sane GL defaults */
698 state->gl_red_size = 8;
699 state->gl_green_size = 8;
700 state->gl_blue_size = 8;
701 state->gl_alpha_size = 8;
702 state->gl_buffer_size = 0;
703 state->gl_depth_size = 16;
704 state->gl_stencil_size = 0;
705 state->gl_double_buffer = 1;
706 state->gl_accum_red_size = 0;
707 state->gl_accum_green_size = 0;
708 state->gl_accum_blue_size = 0;
709 state->gl_accum_alpha_size = 0;
710 state->gl_stereo = 0;
711 state->gl_multisamplebuffers = 0;
712 state->gl_multisamplesamples = 0;
713 state->gl_retained_backing = 1;
714 state->gl_accelerated = -1;
715 state->gl_debug = 0;
716
717 state->common_argparser.parse_arguments = SDLTest_CommonStateParseCommonArguments;
718 state->common_argparser.finalize = SDLTest_CommonArgParserFinalize;
719 state->common_argparser.usage = common_usage;
720 state->common_argparser.data = state;
721 state->common_argparser.next = &state->video_argparser;
722
723 state->video_argparser.parse_arguments = SDLTest_CommonStateParseVideoArguments;
724 state->video_argparser.finalize = NULL;
725 state->video_argparser.usage = video_usage;
726 state->video_argparser.data = state;
727 state->video_argparser.next = &state->audio_argparser;
728
729 state->audio_argparser.parse_arguments = SDLTest_CommonStateParseAudioArguments;
730 state->audio_argparser.finalize = NULL;
731 state->audio_argparser.usage = audio_usage;
732 state->audio_argparser.data = state;
733
734 state->argparser = &state->common_argparser;
735
736 return state;
737}
738
739void SDLTest_CommonDestroyState(SDLTest_CommonState *state) {
740 SDL_free(state);
741 SDLTest_LogAllocations();
742}
743
744int SDLTest_CommonArg(SDLTest_CommonState *state, int index)
745{
746 SDLTest_ArgumentParser *argparser = state->argparser;
747
748 /* Go back and parse arguments as we go */
749 while (argparser) {
750 if (argparser->parse_arguments) {
751 int consumed = argparser->parse_arguments(argparser->data, state->argv, index);
752 if (consumed != 0) {
753 return consumed;
754 }
755 }
756 argparser = argparser->next;
757 }
758 return 0;
759}
760
761void SDLTest_CommonLogUsage(SDLTest_CommonState *state, const char *argv0, const char **options)
762{
763 SDLTest_ArgumentParser *argparser;
764
765 SDL_Log("USAGE: %s", argv0);
766
767 for (argparser = state->argparser; argparser; argparser = argparser->next) {
768 if (argparser->finalize) {
769 argparser->finalize(argparser->data);
770 }
771 if (argparser->usage) {
772 int i;
773 for (i = 0; argparser->usage[i] != NULL; i++) {
774 SDL_Log(" %s", argparser->usage[i]);
775 }
776 }
777 }
778 if (options) {
779 int i;
780 for (i = 0; options[i] != NULL; i++) {
781 SDL_Log(" %s", options[i]);
782 }
783 }
784}
785
786bool SDLTest_CommonDefaultArgs(SDLTest_CommonState *state, int argc, char **argv)
787{
788 int i = 1;
789 while (i < argc) {
790 const int consumed = SDLTest_CommonArg(state, i);
791 if (consumed <= 0) {
792 SDLTest_CommonLogUsage(state, argv[0], NULL);
793 return false;
794 }
795 i += consumed;
796 }
797 return true;
798}
799
800static void SDLTest_PrintDisplayOrientation(char *text, size_t maxlen, SDL_DisplayOrientation orientation)
801{
802 switch (orientation) {
803 case SDL_ORIENTATION_UNKNOWN:
804 SDL_snprintfcat(text, maxlen, "UNKNOWN");
805 break;
806 case SDL_ORIENTATION_LANDSCAPE:
807 SDL_snprintfcat(text, maxlen, "LANDSCAPE");
808 break;
809 case SDL_ORIENTATION_LANDSCAPE_FLIPPED:
810 SDL_snprintfcat(text, maxlen, "LANDSCAPE_FLIPPED");
811 break;
812 case SDL_ORIENTATION_PORTRAIT:
813 SDL_snprintfcat(text, maxlen, "PORTRAIT");
814 break;
815 case SDL_ORIENTATION_PORTRAIT_FLIPPED:
816 SDL_snprintfcat(text, maxlen, "PORTRAIT_FLIPPED");
817 break;
818 default:
819 SDL_snprintfcat(text, maxlen, "0x%8.8x", orientation);
820 break;
821 }
822}
823
824static void SDLTest_PrintWindowFlag(char *text, size_t maxlen, SDL_WindowFlags flag)
825{
826 switch (flag) {
827 case SDL_WINDOW_FULLSCREEN:
828 SDL_snprintfcat(text, maxlen, "FULLSCREEN");
829 break;
830 case SDL_WINDOW_OPENGL:
831 SDL_snprintfcat(text, maxlen, "OPENGL");
832 break;
833 case SDL_WINDOW_OCCLUDED:
834 SDL_snprintfcat(text, maxlen, "OCCLUDED");
835 break;
836 case SDL_WINDOW_HIDDEN:
837 SDL_snprintfcat(text, maxlen, "HIDDEN");
838 break;
839 case SDL_WINDOW_BORDERLESS:
840 SDL_snprintfcat(text, maxlen, "BORDERLESS");
841 break;
842 case SDL_WINDOW_RESIZABLE:
843 SDL_snprintfcat(text, maxlen, "RESIZABLE");
844 break;
845 case SDL_WINDOW_MINIMIZED:
846 SDL_snprintfcat(text, maxlen, "MINIMIZED");
847 break;
848 case SDL_WINDOW_MAXIMIZED:
849 SDL_snprintfcat(text, maxlen, "MAXIMIZED");
850 break;
851 case SDL_WINDOW_MOUSE_GRABBED:
852 SDL_snprintfcat(text, maxlen, "MOUSE_GRABBED");
853 break;
854 case SDL_WINDOW_INPUT_FOCUS:
855 SDL_snprintfcat(text, maxlen, "INPUT_FOCUS");
856 break;
857 case SDL_WINDOW_MOUSE_FOCUS:
858 SDL_snprintfcat(text, maxlen, "MOUSE_FOCUS");
859 break;
860 case SDL_WINDOW_EXTERNAL:
861 SDL_snprintfcat(text, maxlen, "EXTERNAL");
862 break;
863 case SDL_WINDOW_MODAL:
864 SDL_snprintfcat(text, maxlen, "MODAL");
865 break;
866 case SDL_WINDOW_HIGH_PIXEL_DENSITY:
867 SDL_snprintfcat(text, maxlen, "HIGH_PIXEL_DENSITY");
868 break;
869 case SDL_WINDOW_MOUSE_CAPTURE:
870 SDL_snprintfcat(text, maxlen, "MOUSE_CAPTURE");
871 break;
872 case SDL_WINDOW_MOUSE_RELATIVE_MODE:
873 SDL_snprintfcat(text, maxlen, "MOUSE_RELATIVE_MODE");
874 break;
875 case SDL_WINDOW_ALWAYS_ON_TOP:
876 SDL_snprintfcat(text, maxlen, "ALWAYS_ON_TOP");
877 break;
878 case SDL_WINDOW_UTILITY:
879 SDL_snprintfcat(text, maxlen, "UTILITY");
880 break;
881 case SDL_WINDOW_TOOLTIP:
882 SDL_snprintfcat(text, maxlen, "TOOLTIP");
883 break;
884 case SDL_WINDOW_POPUP_MENU:
885 SDL_snprintfcat(text, maxlen, "POPUP_MENU");
886 break;
887 case SDL_WINDOW_KEYBOARD_GRABBED:
888 SDL_snprintfcat(text, maxlen, "KEYBOARD_GRABBED");
889 break;
890 case SDL_WINDOW_VULKAN:
891 SDL_snprintfcat(text, maxlen, "VULKAN");
892 break;
893 case SDL_WINDOW_METAL:
894 SDL_snprintfcat(text, maxlen, "METAL");
895 break;
896 case SDL_WINDOW_TRANSPARENT:
897 SDL_snprintfcat(text, maxlen, "TRANSPARENT");
898 break;
899 case SDL_WINDOW_NOT_FOCUSABLE:
900 SDL_snprintfcat(text, maxlen, "NOT_FOCUSABLE");
901 break;
902 default:
903 SDL_snprintfcat(text, maxlen, "0x%16.16" SDL_PRIx64, flag);
904 break;
905 }
906}
907
908static void SDLTest_PrintWindowFlags(char *text, size_t maxlen, SDL_WindowFlags flags)
909{
910 const SDL_WindowFlags window_flags[] = {
911 SDL_WINDOW_FULLSCREEN,
912 SDL_WINDOW_OPENGL,
913 SDL_WINDOW_OCCLUDED,
914 SDL_WINDOW_HIDDEN,
915 SDL_WINDOW_BORDERLESS,
916 SDL_WINDOW_RESIZABLE,
917 SDL_WINDOW_MINIMIZED,
918 SDL_WINDOW_MAXIMIZED,
919 SDL_WINDOW_MOUSE_GRABBED,
920 SDL_WINDOW_INPUT_FOCUS,
921 SDL_WINDOW_MOUSE_FOCUS,
922 SDL_WINDOW_EXTERNAL,
923 SDL_WINDOW_MODAL,
924 SDL_WINDOW_HIGH_PIXEL_DENSITY,
925 SDL_WINDOW_MOUSE_CAPTURE,
926 SDL_WINDOW_MOUSE_RELATIVE_MODE,
927 SDL_WINDOW_ALWAYS_ON_TOP,
928 SDL_WINDOW_UTILITY,
929 SDL_WINDOW_TOOLTIP,
930 SDL_WINDOW_POPUP_MENU,
931 SDL_WINDOW_KEYBOARD_GRABBED,
932 SDL_WINDOW_VULKAN,
933 SDL_WINDOW_METAL,
934 SDL_WINDOW_TRANSPARENT,
935 SDL_WINDOW_NOT_FOCUSABLE
936 };
937
938 int i;
939 int count = 0;
940 for (i = 0; i < (sizeof(window_flags) / sizeof(window_flags[0])); ++i) {
941 const SDL_WindowFlags flag = window_flags[i];
942 if ((flags & flag) == flag) {
943 if (count > 0) {
944 SDL_snprintfcat(text, maxlen, " | ");
945 }
946 SDLTest_PrintWindowFlag(text, maxlen, flag);
947 ++count;
948 }
949 }
950}
951
952static void SDLTest_PrintModStateFlag(char *text, size_t maxlen, SDL_Keymod flag)
953{
954 switch (flag) {
955 case SDL_KMOD_LSHIFT:
956 SDL_snprintfcat(text, maxlen, "LSHIFT");
957 break;
958 case SDL_KMOD_RSHIFT:
959 SDL_snprintfcat(text, maxlen, "RSHIFT");
960 break;
961 case SDL_KMOD_LEVEL5:
962 SDL_snprintfcat(text, maxlen, "LEVEL5");
963 break;
964 case SDL_KMOD_LCTRL:
965 SDL_snprintfcat(text, maxlen, "LCTRL");
966 break;
967 case SDL_KMOD_RCTRL:
968 SDL_snprintfcat(text, maxlen, "RCTRL");
969 break;
970 case SDL_KMOD_LALT:
971 SDL_snprintfcat(text, maxlen, "LALT");
972 break;
973 case SDL_KMOD_RALT:
974 SDL_snprintfcat(text, maxlen, "RALT");
975 break;
976 case SDL_KMOD_LGUI:
977 SDL_snprintfcat(text, maxlen, "LGUI");
978 break;
979 case SDL_KMOD_RGUI:
980 SDL_snprintfcat(text, maxlen, "RGUI");
981 break;
982 case SDL_KMOD_NUM:
983 SDL_snprintfcat(text, maxlen, "NUM");
984 break;
985 case SDL_KMOD_CAPS:
986 SDL_snprintfcat(text, maxlen, "CAPS");
987 break;
988 case SDL_KMOD_MODE:
989 SDL_snprintfcat(text, maxlen, "MODE");
990 break;
991 case SDL_KMOD_SCROLL:
992 SDL_snprintfcat(text, maxlen, "SCROLL");
993 break;
994 default:
995 SDL_snprintfcat(text, maxlen, "0x%8.8x", (unsigned int) flag);
996 break;
997 }
998}
999
1000static void SDLTest_PrintModState(char *text, size_t maxlen, SDL_Keymod keymod)
1001{
1002 const SDL_Keymod kmod_flags[] = {
1003 SDL_KMOD_LSHIFT,
1004 SDL_KMOD_RSHIFT,
1005 SDL_KMOD_LEVEL5,
1006 SDL_KMOD_LCTRL,
1007 SDL_KMOD_RCTRL,
1008 SDL_KMOD_LALT,
1009 SDL_KMOD_RALT,
1010 SDL_KMOD_LGUI,
1011 SDL_KMOD_RGUI,
1012 SDL_KMOD_NUM,
1013 SDL_KMOD_CAPS,
1014 SDL_KMOD_MODE,
1015 SDL_KMOD_SCROLL
1016 };
1017
1018 int i;
1019 int count = 0;
1020 for (i = 0; i < SDL_arraysize(kmod_flags); ++i) {
1021 const SDL_Keymod flag = kmod_flags[i];
1022 if ((keymod & flag) == flag) {
1023 if (count > 0) {
1024 SDL_snprintfcat(text, maxlen, " | ");
1025 }
1026 SDLTest_PrintModStateFlag(text, maxlen, flag);
1027 ++count;
1028 }
1029 }
1030}
1031
1032static void SDLTest_PrintButtonMask(char *text, size_t maxlen, SDL_MouseButtonFlags flags)
1033{
1034 int i;
1035 int count = 0;
1036 for (i = 1; i <= 32; ++i) {
1037 const Uint32 flag = SDL_BUTTON_MASK(i);
1038 if ((flags & flag) == flag) {
1039 if (count > 0) {
1040 SDL_snprintfcat(text, maxlen, " | ");
1041 }
1042 SDL_snprintfcat(text, maxlen, "SDL_BUTTON_MASK(%d)", i);
1043 ++count;
1044 }
1045 }
1046}
1047
1048static void SDLTest_PrintPixelFormat(char *text, size_t maxlen, Uint32 format)
1049{
1050 const char *name = SDL_GetPixelFormatName(format);
1051 if (name) {
1052 if (SDL_strncmp(name, "SDL_PIXELFORMAT_", 16) == 0) {
1053 name += 16;
1054 }
1055 SDL_snprintfcat(text, maxlen, name);
1056 } else {
1057 SDL_snprintfcat(text, maxlen, "0x%8.8x", format);
1058 }
1059}
1060
1061static void SDLTest_PrintLogicalPresentation(char *text, size_t maxlen, SDL_RendererLogicalPresentation logical_presentation)
1062{
1063 switch (logical_presentation) {
1064 case SDL_LOGICAL_PRESENTATION_DISABLED:
1065 SDL_snprintfcat(text, maxlen, "DISABLED");
1066 break;
1067 case SDL_LOGICAL_PRESENTATION_STRETCH:
1068 SDL_snprintfcat(text, maxlen, "STRETCH");
1069 break;
1070 case SDL_LOGICAL_PRESENTATION_LETTERBOX:
1071 SDL_snprintfcat(text, maxlen, "LETTERBOX");
1072 break;
1073 case SDL_LOGICAL_PRESENTATION_OVERSCAN:
1074 SDL_snprintfcat(text, maxlen, "OVERSCAN");
1075 break;
1076 case SDL_LOGICAL_PRESENTATION_INTEGER_SCALE:
1077 SDL_snprintfcat(text, maxlen, "INTEGER_SCALE");
1078 break;
1079 default:
1080 SDL_snprintfcat(text, maxlen, "0x%8.8x", logical_presentation);
1081 break;
1082 }
1083}
1084
1085static void SDLTest_PrintRenderer(SDL_Renderer *renderer)
1086{
1087 const char *name;
1088 int i;
1089 char text[1024];
1090 int max_texture_size;
1091 const SDL_PixelFormat *texture_formats;
1092
1093 name = SDL_GetRendererName(renderer);
1094
1095 SDL_Log(" Renderer %s:", name);
1096 if (SDL_strcmp(name, "gpu") == 0) {
1097 SDL_GPUDevice *device = SDL_GetPointerProperty(SDL_GetRendererProperties(renderer), SDL_PROP_RENDERER_GPU_DEVICE_POINTER, NULL);
1098 SDL_Log(" Driver: %s", SDL_GetGPUDeviceDriver(device));
1099 }
1100 SDL_Log(" VSync: %d", (int)SDL_GetNumberProperty(SDL_GetRendererProperties(renderer), SDL_PROP_RENDERER_VSYNC_NUMBER, 0));
1101
1102 texture_formats = (const SDL_PixelFormat *)SDL_GetPointerProperty(SDL_GetRendererProperties(renderer), SDL_PROP_RENDERER_TEXTURE_FORMATS_POINTER, NULL);
1103 if (texture_formats) {
1104 (void)SDL_snprintf(text, sizeof(text), " Texture formats: ");
1105 for (i = 0; texture_formats[i]; ++i) {
1106 if (i > 0) {
1107 SDL_snprintfcat(text, sizeof(text), ", ");
1108 }
1109 SDLTest_PrintPixelFormat(text, sizeof(text), texture_formats[i]);
1110 }
1111 SDL_Log("%s", text);
1112 }
1113
1114 max_texture_size = (int)SDL_GetNumberProperty(SDL_GetRendererProperties(renderer), SDL_PROP_RENDERER_MAX_TEXTURE_SIZE_NUMBER, 0);
1115 if (max_texture_size) {
1116 SDL_Log(" Max Texture Size: %dx%d", max_texture_size, max_texture_size);
1117 }
1118}
1119
1120static SDL_Surface *SDLTest_LoadIcon(const char *file)
1121{
1122 SDL_Surface *icon;
1123
1124 /* Load the icon surface */
1125 icon = SDL_LoadBMP(file);
1126 if (!icon) {
1127 SDL_Log("Couldn't load %s: %s", file, SDL_GetError());
1128 return NULL;
1129 }
1130
1131 if (icon->format == SDL_PIXELFORMAT_INDEX8) {
1132 /* Set the colorkey */
1133 SDL_SetSurfaceColorKey(icon, 1, *((Uint8 *)icon->pixels));
1134 }
1135
1136 return icon;
1137}
1138
1139static SDL_HitTestResult SDLCALL SDLTest_ExampleHitTestCallback(SDL_Window *win, const SDL_Point *area, void *data)
1140{
1141 int w, h;
1142 const int RESIZE_BORDER = 8;
1143 const int DRAGGABLE_TITLE = 32;
1144
1145 /*SDL_Log("Hit test point %d,%d", area->x, area->y);*/
1146
1147 SDL_GetWindowSize(win, &w, &h);
1148
1149 if (area->x < RESIZE_BORDER) {
1150 if (area->y < RESIZE_BORDER) {
1151 SDL_Log("SDL_HITTEST_RESIZE_TOPLEFT");
1152 return SDL_HITTEST_RESIZE_TOPLEFT;
1153 } else if (area->y >= (h - RESIZE_BORDER)) {
1154 SDL_Log("SDL_HITTEST_RESIZE_BOTTOMLEFT");
1155 return SDL_HITTEST_RESIZE_BOTTOMLEFT;
1156 } else {
1157 SDL_Log("SDL_HITTEST_RESIZE_LEFT");
1158 return SDL_HITTEST_RESIZE_LEFT;
1159 }
1160 } else if (area->x >= (w - RESIZE_BORDER)) {
1161 if (area->y < RESIZE_BORDER) {
1162 SDL_Log("SDL_HITTEST_RESIZE_TOPRIGHT");
1163 return SDL_HITTEST_RESIZE_TOPRIGHT;
1164 } else if (area->y >= (h - RESIZE_BORDER)) {
1165 SDL_Log("SDL_HITTEST_RESIZE_BOTTOMRIGHT");
1166 return SDL_HITTEST_RESIZE_BOTTOMRIGHT;
1167 } else {
1168 SDL_Log("SDL_HITTEST_RESIZE_RIGHT");
1169 return SDL_HITTEST_RESIZE_RIGHT;
1170 }
1171 } else if (area->y >= (h - RESIZE_BORDER)) {
1172 SDL_Log("SDL_HITTEST_RESIZE_BOTTOM");
1173 return SDL_HITTEST_RESIZE_BOTTOM;
1174 } else if (area->y < RESIZE_BORDER) {
1175 SDL_Log("SDL_HITTEST_RESIZE_TOP");
1176 return SDL_HITTEST_RESIZE_TOP;
1177 } else if (area->y < DRAGGABLE_TITLE) {
1178 SDL_Log("SDL_HITTEST_DRAGGABLE");
1179 return SDL_HITTEST_DRAGGABLE;
1180 }
1181 return SDL_HITTEST_NORMAL;
1182}
1183
1184bool SDLTest_CommonInit(SDLTest_CommonState *state)
1185{
1186 int i, j, m, n, w, h;
1187 char text[1024];
1188
1189 if (state->flags & SDL_INIT_VIDEO) {
1190 if (state->verbose & VERBOSE_VIDEO) {
1191 n = SDL_GetNumVideoDrivers();
1192 if (n == 0) {
1193 SDL_Log("No built-in video drivers");
1194 } else {
1195 (void)SDL_snprintf(text, sizeof(text), "Built-in video drivers:");
1196 for (i = 0; i < n; ++i) {
1197 if (i > 0) {
1198 SDL_snprintfcat(text, sizeof(text), ",");
1199 }
1200 SDL_snprintfcat(text, sizeof(text), " %s", SDL_GetVideoDriver(i));
1201 }
1202 SDL_Log("%s", text);
1203 }
1204 }
1205 if (!SDL_InitSubSystem(SDL_INIT_VIDEO)) {
1206 SDL_Log("Couldn't initialize video driver: %s",
1207 SDL_GetError());
1208 return false;
1209 }
1210 if (state->verbose & VERBOSE_VIDEO) {
1211 SDL_Log("Video driver: %s",
1212 SDL_GetCurrentVideoDriver());
1213 }
1214
1215 /* Upload GL settings */
1216 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, state->gl_red_size);
1217 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, state->gl_green_size);
1218 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, state->gl_blue_size);
1219 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, state->gl_alpha_size);
1220 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, state->gl_double_buffer);
1221 SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, state->gl_buffer_size);
1222 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, state->gl_depth_size);
1223 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, state->gl_stencil_size);
1224 SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, state->gl_accum_red_size);
1225 SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, state->gl_accum_green_size);
1226 SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, state->gl_accum_blue_size);
1227 SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, state->gl_accum_alpha_size);
1228 SDL_GL_SetAttribute(SDL_GL_STEREO, state->gl_stereo);
1229 SDL_GL_SetAttribute(SDL_GL_CONTEXT_RELEASE_BEHAVIOR, state->gl_release_behavior);
1230 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, state->gl_multisamplebuffers);
1231 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, state->gl_multisamplesamples);
1232 if (state->gl_accelerated >= 0) {
1233 SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL,
1234 state->gl_accelerated);
1235 }
1236 SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, state->gl_retained_backing);
1237 if (state->gl_major_version) {
1238 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, state->gl_major_version);
1239 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, state->gl_minor_version);
1240 }
1241 if (state->gl_debug) {
1242 SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
1243 }
1244 if (state->gl_profile_mask) {
1245 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, state->gl_profile_mask);
1246 }
1247
1248 if (state->verbose & VERBOSE_MODES) {
1249 SDL_DisplayID *displays;
1250 SDL_Rect bounds, usablebounds;
1251 SDL_DisplayMode **modes;
1252 const SDL_DisplayMode *mode;
1253 int bpp;
1254 Uint32 Rmask, Gmask, Bmask, Amask;
1255#ifdef SDL_VIDEO_DRIVER_WINDOWS
1256 int adapterIndex = 0;
1257 int outputIndex = 0;
1258#endif
1259 displays = SDL_GetDisplays(&n);
1260 SDL_Log("Number of displays: %d", n);
1261 for (i = 0; i < n; ++i) {
1262 SDL_DisplayID displayID = displays[i];
1263 SDL_Log("Display %" SDL_PRIu32 ": %s", displayID, SDL_GetDisplayName(displayID));
1264
1265 SDL_zero(bounds);
1266 SDL_GetDisplayBounds(displayID, &bounds);
1267
1268 SDL_zero(usablebounds);
1269 SDL_GetDisplayUsableBounds(displayID, &usablebounds);
1270
1271 SDL_Log("Bounds: %dx%d at %d,%d", bounds.w, bounds.h, bounds.x, bounds.y);
1272 SDL_Log("Usable bounds: %dx%d at %d,%d", usablebounds.w, usablebounds.h, usablebounds.x, usablebounds.y);
1273
1274 mode = SDL_GetDesktopDisplayMode(displayID);
1275 SDL_GetMasksForPixelFormat(mode->format, &bpp, &Rmask, &Gmask,
1276 &Bmask, &Amask);
1277 SDL_Log(" Desktop mode: %dx%d@%gx %gHz, %d bits-per-pixel (%s)",
1278 mode->w, mode->h, mode->pixel_density, mode->refresh_rate, bpp,
1279 SDL_GetPixelFormatName(mode->format));
1280 if (Rmask || Gmask || Bmask) {
1281 SDL_Log(" Red Mask = 0x%.8" SDL_PRIx32, Rmask);
1282 SDL_Log(" Green Mask = 0x%.8" SDL_PRIx32, Gmask);
1283 SDL_Log(" Blue Mask = 0x%.8" SDL_PRIx32, Bmask);
1284 if (Amask) {
1285 SDL_Log(" Alpha Mask = 0x%.8" SDL_PRIx32, Amask);
1286 }
1287 }
1288
1289 /* Print available fullscreen video modes */
1290 modes = SDL_GetFullscreenDisplayModes(displayID, &m);
1291 if (m == 0) {
1292 SDL_Log("No available fullscreen video modes");
1293 } else {
1294 SDL_Log(" Fullscreen video modes:");
1295 for (j = 0; j < m; ++j) {
1296 mode = modes[j];
1297 SDL_GetMasksForPixelFormat(mode->format, &bpp, &Rmask,
1298 &Gmask, &Bmask, &Amask);
1299 SDL_Log(" Mode %d: %dx%d@%gx %gHz, %d bits-per-pixel (%s)",
1300 j, mode->w, mode->h, mode->pixel_density, mode->refresh_rate, bpp,
1301 SDL_GetPixelFormatName(mode->format));
1302 if (Rmask || Gmask || Bmask) {
1303 SDL_Log(" Red Mask = 0x%.8" SDL_PRIx32,
1304 Rmask);
1305 SDL_Log(" Green Mask = 0x%.8" SDL_PRIx32,
1306 Gmask);
1307 SDL_Log(" Blue Mask = 0x%.8" SDL_PRIx32,
1308 Bmask);
1309 if (Amask) {
1310 SDL_Log(" Alpha Mask = 0x%.8" SDL_PRIx32, Amask);
1311 }
1312 }
1313 }
1314 }
1315 SDL_free(modes);
1316
1317#if defined(SDL_VIDEO_DRIVER_WINDOWS) && !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
1318 /* Print the D3D9 adapter index */
1319 adapterIndex = SDL_GetDirect3D9AdapterIndex(displayID);
1320 SDL_Log("D3D9 Adapter Index: %d", adapterIndex);
1321
1322 /* Print the DXGI adapter and output indices */
1323 SDL_GetDXGIOutputInfo(displayID, &adapterIndex, &outputIndex);
1324 SDL_Log("DXGI Adapter Index: %d Output Index: %d", adapterIndex, outputIndex);
1325#endif
1326 }
1327 SDL_free(displays);
1328 }
1329
1330 if (state->verbose & VERBOSE_RENDER) {
1331 n = SDL_GetNumRenderDrivers();
1332 if (n == 0) {
1333 SDL_Log("No built-in render drivers");
1334 } else {
1335 SDL_Log("Built-in render drivers:");
1336 for (i = 0; i < n; ++i) {
1337 SDL_Log(" %s", SDL_GetRenderDriver(i));
1338 }
1339 }
1340 }
1341
1342 state->displayID = SDL_GetPrimaryDisplay();
1343 if (state->display_index > 0) {
1344 SDL_DisplayID *displays = SDL_GetDisplays(&n);
1345 if (state->display_index < n) {
1346 state->displayID = displays[state->display_index];
1347 }
1348 SDL_free(displays);
1349
1350 if (SDL_WINDOWPOS_ISUNDEFINED(state->window_x)) {
1351 state->window_x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(state->displayID);
1352 state->window_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(state->displayID);
1353 } else if (SDL_WINDOWPOS_ISCENTERED(state->window_x)) {
1354 state->window_x = SDL_WINDOWPOS_CENTERED_DISPLAY(state->displayID);
1355 state->window_y = SDL_WINDOWPOS_CENTERED_DISPLAY(state->displayID);
1356 }
1357 }
1358
1359 {
1360 bool include_high_density_modes = false;
1361 if (state->window_flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) {
1362 include_high_density_modes = true;
1363 }
1364 SDL_GetClosestFullscreenDisplayMode(state->displayID, state->window_w, state->window_h, state->refresh_rate, include_high_density_modes, &state->fullscreen_mode);
1365 }
1366
1367 state->windows =
1368 (SDL_Window **)SDL_calloc(state->num_windows,
1369 sizeof(*state->windows));
1370 state->renderers =
1371 (SDL_Renderer **)SDL_calloc(state->num_windows,
1372 sizeof(*state->renderers));
1373 state->targets =
1374 (SDL_Texture **)SDL_calloc(state->num_windows,
1375 sizeof(*state->targets));
1376 if (!state->windows || !state->renderers) {
1377 SDL_Log("Out of memory!");
1378 return false;
1379 }
1380 for (i = 0; i < state->num_windows; ++i) {
1381 char title[1024];
1382 SDL_Rect r;
1383 SDL_PropertiesID props;
1384
1385 if (state->fill_usable_bounds) {
1386 SDL_GetDisplayUsableBounds(state->displayID, &r);
1387 } else {
1388 r.x = state->window_x;
1389 r.y = state->window_y;
1390 r.w = state->window_w;
1391 r.h = state->window_h;
1392 if (state->auto_scale_content) {
1393 float scale = SDL_GetDisplayContentScale(state->displayID);
1394 r.w = (int)SDL_ceilf(r.w * scale);
1395 r.h = (int)SDL_ceilf(r.h * scale);
1396 }
1397 }
1398
1399 if (state->num_windows > 1) {
1400 (void)SDL_snprintf(title, SDL_arraysize(title), "%s %d",
1401 state->window_title, i + 1);
1402 } else {
1403 SDL_strlcpy(title, state->window_title, SDL_arraysize(title));
1404 }
1405 props = SDL_CreateProperties();
1406 SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, title);
1407 SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, r.x);
1408 SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, r.y);
1409 SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, r.w);
1410 SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, r.h);
1411 SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_FLAGS_NUMBER, state->window_flags);
1412 state->windows[i] = SDL_CreateWindowWithProperties(props);
1413 SDL_DestroyProperties(props);
1414 if (!state->windows[i]) {
1415 SDL_Log("Couldn't create window: %s",
1416 SDL_GetError());
1417 return false;
1418 }
1419 if (state->window_minW || state->window_minH) {
1420 SDL_SetWindowMinimumSize(state->windows[i], state->window_minW, state->window_minH);
1421 }
1422 if (state->window_maxW || state->window_maxH) {
1423 SDL_SetWindowMaximumSize(state->windows[i], state->window_maxW, state->window_maxH);
1424 }
1425 if (state->window_min_aspect != 0.f || state->window_max_aspect != 0.f) {
1426 SDL_SetWindowAspectRatio(state->windows[i], state->window_min_aspect, state->window_max_aspect);
1427 }
1428 SDL_GetWindowSize(state->windows[i], &w, &h);
1429 if (!(state->window_flags & SDL_WINDOW_RESIZABLE) && (w != r.w || h != r.h)) {
1430 SDL_Log("Window requested size %dx%d, got %dx%d", r.w, r.h, w, h);
1431 state->window_w = w;
1432 state->window_h = h;
1433 }
1434 if (state->window_flags & SDL_WINDOW_FULLSCREEN) {
1435 if (state->fullscreen_exclusive) {
1436 SDL_SetWindowFullscreenMode(state->windows[i], &state->fullscreen_mode);
1437 }
1438 SDL_SetWindowFullscreen(state->windows[i], true);
1439 }
1440
1441 /* Add resize/drag areas for windows that are borderless and resizable */
1442 if ((state->window_flags & (SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS)) ==
1443 (SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS)) {
1444 SDL_SetWindowHitTest(state->windows[i], SDLTest_ExampleHitTestCallback, NULL);
1445 }
1446
1447 if (state->window_icon) {
1448 SDL_Surface *icon = SDLTest_LoadIcon(state->window_icon);
1449 if (icon) {
1450 SDL_SetWindowIcon(state->windows[i], icon);
1451 SDL_DestroySurface(icon);
1452 }
1453 }
1454
1455 if (!SDL_RectEmpty(&state->confine)) {
1456 SDL_SetWindowMouseRect(state->windows[i], &state->confine);
1457 }
1458
1459 if (!state->skip_renderer && (state->renderdriver || !(state->window_flags & (SDL_WINDOW_OPENGL | SDL_WINDOW_VULKAN | SDL_WINDOW_METAL)))) {
1460 state->renderers[i] = SDL_CreateRenderer(state->windows[i], state->renderdriver);
1461 if (!state->renderers[i]) {
1462 SDL_Log("Couldn't create renderer: %s",
1463 SDL_GetError());
1464 return false;
1465 }
1466 if (state->logical_w == 0 || state->logical_h == 0) {
1467 state->logical_w = state->window_w;
1468 state->logical_h = state->window_h;
1469 }
1470 if (state->render_vsync) {
1471 SDL_SetRenderVSync(state->renderers[i], state->render_vsync);
1472 }
1473 if (!SDL_SetRenderLogicalPresentation(state->renderers[i], state->logical_w, state->logical_h, state->logical_presentation)) {
1474 SDL_Log("Couldn't set logical presentation: %s", SDL_GetError());
1475 return false;
1476 }
1477 if (state->scale != 0.0f) {
1478 SDL_SetRenderScale(state->renderers[i], state->scale, state->scale);
1479 }
1480 if (state->verbose & VERBOSE_RENDER) {
1481 SDL_Log("Current renderer:");
1482 SDLTest_PrintRenderer(state->renderers[i]);
1483 }
1484 }
1485
1486 SDL_ShowWindow(state->windows[i]);
1487 }
1488 if (state->hide_cursor) {
1489 SDL_HideCursor();
1490 }
1491 }
1492
1493 if (state->flags & SDL_INIT_AUDIO) {
1494 if (state->verbose & VERBOSE_AUDIO) {
1495 n = SDL_GetNumAudioDrivers();
1496 if (n == 0) {
1497 SDL_Log("No built-in audio drivers");
1498 } else {
1499 (void)SDL_snprintf(text, sizeof(text), "Built-in audio drivers:");
1500 for (i = 0; i < n; ++i) {
1501 if (i > 0) {
1502 SDL_snprintfcat(text, sizeof(text), ",");
1503 }
1504 SDL_snprintfcat(text, sizeof(text), " %s", SDL_GetAudioDriver(i));
1505 }
1506 SDL_Log("%s", text);
1507 }
1508 }
1509 if (!SDL_InitSubSystem(SDL_INIT_AUDIO)) {
1510 SDL_Log("Couldn't initialize audio driver: %s",
1511 SDL_GetError());
1512 return false;
1513 }
1514 if (state->verbose & VERBOSE_AUDIO) {
1515 SDL_Log("Audio driver: %s",
1516 SDL_GetCurrentAudioDriver());
1517 }
1518
1519 const SDL_AudioSpec spec = { state->audio_format, state->audio_channels, state->audio_freq };
1520 state->audio_id = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec);
1521 if (!state->audio_id) {
1522 SDL_Log("Couldn't open audio: %s", SDL_GetError());
1523 return false;
1524 }
1525 }
1526
1527 if (state->flags & SDL_INIT_CAMERA) {
1528 SDL_InitSubSystem(SDL_INIT_CAMERA);
1529 }
1530
1531 return true;
1532}
1533
1534static const char *SystemThemeName(void)
1535{
1536 switch (SDL_GetSystemTheme()) {
1537#define CASE(X) \
1538 case SDL_SYSTEM_THEME_##X: \
1539 return #X
1540 CASE(UNKNOWN);
1541 CASE(LIGHT);
1542 CASE(DARK);
1543#undef CASE
1544 default:
1545 return "???";
1546 }
1547}
1548
1549static const char *DisplayOrientationName(int orientation)
1550{
1551 switch (orientation) {
1552#define CASE(X) \
1553 case SDL_ORIENTATION_##X: \
1554 return #X
1555 CASE(UNKNOWN);
1556 CASE(LANDSCAPE);
1557 CASE(LANDSCAPE_FLIPPED);
1558 CASE(PORTRAIT);
1559 CASE(PORTRAIT_FLIPPED);
1560#undef CASE
1561 default:
1562 return "???";
1563 }
1564}
1565
1566static const char *GamepadAxisName(const SDL_GamepadAxis axis)
1567{
1568 switch (axis) {
1569#define AXIS_CASE(ax) \
1570 case SDL_GAMEPAD_AXIS_##ax: \
1571 return #ax
1572 AXIS_CASE(INVALID);
1573 AXIS_CASE(LEFTX);
1574 AXIS_CASE(LEFTY);
1575 AXIS_CASE(RIGHTX);
1576 AXIS_CASE(RIGHTY);
1577 AXIS_CASE(LEFT_TRIGGER);
1578 AXIS_CASE(RIGHT_TRIGGER);
1579#undef AXIS_CASE
1580 default:
1581 return "???";
1582 }
1583}
1584
1585static const char *GamepadButtonName(const SDL_GamepadButton button)
1586{
1587 switch (button) {
1588#define BUTTON_CASE(btn) \
1589 case SDL_GAMEPAD_BUTTON_##btn: \
1590 return #btn
1591 BUTTON_CASE(INVALID);
1592 BUTTON_CASE(SOUTH);
1593 BUTTON_CASE(EAST);
1594 BUTTON_CASE(WEST);
1595 BUTTON_CASE(NORTH);
1596 BUTTON_CASE(BACK);
1597 BUTTON_CASE(GUIDE);
1598 BUTTON_CASE(START);
1599 BUTTON_CASE(LEFT_STICK);
1600 BUTTON_CASE(RIGHT_STICK);
1601 BUTTON_CASE(LEFT_SHOULDER);
1602 BUTTON_CASE(RIGHT_SHOULDER);
1603 BUTTON_CASE(DPAD_UP);
1604 BUTTON_CASE(DPAD_DOWN);
1605 BUTTON_CASE(DPAD_LEFT);
1606 BUTTON_CASE(DPAD_RIGHT);
1607#undef BUTTON_CASE
1608 default:
1609 return "???";
1610 }
1611}
1612
1613void SDLTest_PrintEvent(const SDL_Event *event)
1614{
1615 switch (event->type) {
1616 case SDL_EVENT_SYSTEM_THEME_CHANGED:
1617 SDL_Log("SDL EVENT: System theme changed to %s", SystemThemeName());
1618 break;
1619 case SDL_EVENT_DISPLAY_ADDED:
1620 SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " attached",
1621 event->display.displayID);
1622 break;
1623 case SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED:
1624 {
1625 float scale = SDL_GetDisplayContentScale(event->display.displayID);
1626 SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " changed content scale to %d%%",
1627 event->display.displayID, (int)(scale * 100.0f));
1628 }
1629 break;
1630 case SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED:
1631 SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " desktop mode changed to %" SDL_PRIs32 "x%" SDL_PRIs32,
1632 event->display.displayID, event->display.data1, event->display.data2);
1633 break;
1634 case SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED:
1635 SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " current mode changed to %" SDL_PRIs32 "x%" SDL_PRIs32,
1636 event->display.displayID, event->display.data1, event->display.data2);
1637 break;
1638 case SDL_EVENT_DISPLAY_MOVED:
1639 SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " changed position",
1640 event->display.displayID);
1641 break;
1642 case SDL_EVENT_DISPLAY_ORIENTATION:
1643 SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " changed orientation to %s",
1644 event->display.displayID, DisplayOrientationName(event->display.data1));
1645 break;
1646 case SDL_EVENT_DISPLAY_REMOVED:
1647 SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " removed",
1648 event->display.displayID);
1649 break;
1650 case SDL_EVENT_WINDOW_SHOWN:
1651 SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " shown", event->window.windowID);
1652 break;
1653 case SDL_EVENT_WINDOW_HIDDEN:
1654 SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " hidden", event->window.windowID);
1655 break;
1656 case SDL_EVENT_WINDOW_EXPOSED:
1657 SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " exposed", event->window.windowID);
1658 break;
1659 case SDL_EVENT_WINDOW_MOVED:
1660 SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " moved to %" SDL_PRIs32 ",%" SDL_PRIs32,
1661 event->window.windowID, event->window.data1, event->window.data2);
1662 break;
1663 case SDL_EVENT_WINDOW_RESIZED:
1664 SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " resized to %" SDL_PRIs32 "x%" SDL_PRIs32,
1665 event->window.windowID, event->window.data1, event->window.data2);
1666 break;
1667 case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
1668 SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " changed pixel size to %" SDL_PRIs32 "x%" SDL_PRIs32,
1669 event->window.windowID, event->window.data1, event->window.data2);
1670 break;
1671 case SDL_EVENT_WINDOW_METAL_VIEW_RESIZED:
1672 SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " changed metal view size",
1673 event->window.windowID);
1674 break;
1675 case SDL_EVENT_WINDOW_SAFE_AREA_CHANGED: {
1676 SDL_Rect rect;
1677
1678 SDL_GetWindowSafeArea(SDL_GetWindowFromEvent(event), &rect);
1679 SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " changed safe area to: %d,%d %dx%d",
1680 event->window.windowID, rect.x, rect.y, rect.w, rect.h);
1681 break;
1682 }
1683 case SDL_EVENT_WINDOW_MINIMIZED:
1684 SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " minimized", event->window.windowID);
1685 break;
1686 case SDL_EVENT_WINDOW_MAXIMIZED:
1687 SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " maximized", event->window.windowID);
1688 break;
1689 case SDL_EVENT_WINDOW_RESTORED:
1690 SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " restored", event->window.windowID);
1691 break;
1692 case SDL_EVENT_WINDOW_MOUSE_ENTER:
1693 SDL_Log("SDL EVENT: Mouse entered window %" SDL_PRIu32, event->window.windowID);
1694 break;
1695 case SDL_EVENT_WINDOW_MOUSE_LEAVE:
1696 SDL_Log("SDL EVENT: Mouse left window %" SDL_PRIu32, event->window.windowID);
1697 break;
1698 case SDL_EVENT_WINDOW_FOCUS_GAINED:
1699 SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " gained keyboard focus",
1700 event->window.windowID);
1701 break;
1702 case SDL_EVENT_WINDOW_FOCUS_LOST:
1703 SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " lost keyboard focus",
1704 event->window.windowID);
1705 break;
1706 case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
1707 SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " closed", event->window.windowID);
1708 break;
1709 case SDL_EVENT_WINDOW_HIT_TEST:
1710 SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " hit test", event->window.windowID);
1711 break;
1712 case SDL_EVENT_WINDOW_ICCPROF_CHANGED:
1713 SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " ICC profile changed", event->window.windowID);
1714 break;
1715 case SDL_EVENT_WINDOW_DISPLAY_CHANGED:
1716 SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " display changed to %" SDL_PRIs32, event->window.windowID, event->window.data1);
1717 break;
1718 case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED:
1719 SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " display scale changed to %d%%", event->window.windowID, (int)(SDL_GetWindowDisplayScale(SDL_GetWindowFromEvent(event)) * 100.0f));
1720 break;
1721 case SDL_EVENT_WINDOW_OCCLUDED:
1722 SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " occluded", event->window.windowID);
1723 break;
1724 case SDL_EVENT_WINDOW_ENTER_FULLSCREEN:
1725 SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " entered fullscreen", event->window.windowID);
1726 break;
1727 case SDL_EVENT_WINDOW_LEAVE_FULLSCREEN:
1728 SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " left fullscreen", event->window.windowID);
1729 break;
1730 case SDL_EVENT_WINDOW_DESTROYED:
1731 SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " destroyed", event->window.windowID);
1732 break;
1733 case SDL_EVENT_WINDOW_HDR_STATE_CHANGED:
1734 SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " HDR %s", event->window.windowID, event->window.data1 ? "enabled" : "disabled");
1735 break;
1736 case SDL_EVENT_KEYBOARD_ADDED:
1737 SDL_Log("SDL EVENT: Keyboard %" SDL_PRIu32 " attached",
1738 event->kdevice.which);
1739 break;
1740 case SDL_EVENT_KEYBOARD_REMOVED:
1741 SDL_Log("SDL EVENT: Keyboard %" SDL_PRIu32 " removed",
1742 event->kdevice.which);
1743 break;
1744 case SDL_EVENT_KEY_DOWN:
1745 case SDL_EVENT_KEY_UP: {
1746 char modstr[64];
1747 if (event->key.mod) {
1748 modstr[0] = '\0';
1749 SDLTest_PrintModState(modstr, sizeof (modstr), event->key.mod);
1750 } else {
1751 SDL_strlcpy(modstr, "NONE", sizeof (modstr));
1752 }
1753
1754 SDL_Log("SDL EVENT: Keyboard: key %s in window %" SDL_PRIu32 ": scancode 0x%08X = %s, keycode 0x%08" SDL_PRIX32 " = %s, mods = %s",
1755 (event->type == SDL_EVENT_KEY_DOWN) ? "pressed" : "released",
1756 event->key.windowID,
1757 event->key.scancode,
1758 SDL_GetScancodeName(event->key.scancode),
1759 event->key.key, SDL_GetKeyName(event->key.key),
1760 modstr);
1761 break;
1762 }
1763 case SDL_EVENT_TEXT_EDITING:
1764 SDL_Log("SDL EVENT: Keyboard: text editing \"%s\" in window %" SDL_PRIu32,
1765 event->edit.text, event->edit.windowID);
1766 break;
1767 case SDL_EVENT_TEXT_EDITING_CANDIDATES:
1768 SDL_Log("SDL EVENT: Keyboard: text editing candidates in window %" SDL_PRIu32,
1769 event->edit.windowID);
1770 break;
1771 case SDL_EVENT_TEXT_INPUT:
1772 SDL_Log("SDL EVENT: Keyboard: text input \"%s\" in window %" SDL_PRIu32,
1773 event->text.text, event->text.windowID);
1774 break;
1775 case SDL_EVENT_KEYMAP_CHANGED:
1776 SDL_Log("SDL EVENT: Keymap changed");
1777 break;
1778 case SDL_EVENT_MOUSE_ADDED:
1779 SDL_Log("SDL EVENT: Mouse %" SDL_PRIu32 " attached",
1780 event->mdevice.which);
1781 break;
1782 case SDL_EVENT_MOUSE_REMOVED:
1783 SDL_Log("SDL EVENT: Mouse %" SDL_PRIu32 " removed",
1784 event->mdevice.which);
1785 break;
1786 case SDL_EVENT_MOUSE_MOTION:
1787 SDL_Log("SDL EVENT: Mouse: moved to %g,%g (%g,%g) in window %" SDL_PRIu32,
1788 event->motion.x, event->motion.y,
1789 event->motion.xrel, event->motion.yrel,
1790 event->motion.windowID);
1791 break;
1792 case SDL_EVENT_MOUSE_BUTTON_DOWN:
1793 SDL_Log("SDL EVENT: Mouse: button %d pressed at %g,%g with click count %d in window %" SDL_PRIu32,
1794 event->button.button, event->button.x, event->button.y, event->button.clicks,
1795 event->button.windowID);
1796 break;
1797 case SDL_EVENT_MOUSE_BUTTON_UP:
1798 SDL_Log("SDL EVENT: Mouse: button %d released at %g,%g with click count %d in window %" SDL_PRIu32,
1799 event->button.button, event->button.x, event->button.y, event->button.clicks,
1800 event->button.windowID);
1801 break;
1802 case SDL_EVENT_MOUSE_WHEEL:
1803 SDL_Log("SDL EVENT: Mouse: wheel scrolled %g in x and %g in y (reversed: %d) in window %" SDL_PRIu32,
1804 event->wheel.x, event->wheel.y, event->wheel.direction, event->wheel.windowID);
1805 break;
1806 case SDL_EVENT_JOYSTICK_ADDED:
1807 SDL_Log("SDL EVENT: Joystick %" SDL_PRIu32 " attached",
1808 event->jdevice.which);
1809 break;
1810 case SDL_EVENT_JOYSTICK_REMOVED:
1811 SDL_Log("SDL EVENT: Joystick %" SDL_PRIu32 " removed",
1812 event->jdevice.which);
1813 break;
1814 case SDL_EVENT_JOYSTICK_AXIS_MOTION:
1815 SDL_Log("SDL EVENT: Joystick %" SDL_PRIu32 " axis %d value: %d",
1816 event->jaxis.which,
1817 event->jaxis.axis,
1818 event->jaxis.value);
1819 break;
1820 case SDL_EVENT_JOYSTICK_BALL_MOTION:
1821 SDL_Log("SDL EVENT: Joystick %" SDL_PRIs32 ": ball %d moved by %d,%d",
1822 event->jball.which, event->jball.ball, event->jball.xrel,
1823 event->jball.yrel);
1824 break;
1825 case SDL_EVENT_JOYSTICK_HAT_MOTION:
1826 {
1827 const char *position = "UNKNOWN";
1828 switch (event->jhat.value) {
1829 case SDL_HAT_CENTERED:
1830 position = "CENTER";
1831 break;
1832 case SDL_HAT_UP:
1833 position = "UP";
1834 break;
1835 case SDL_HAT_RIGHTUP:
1836 position = "RIGHTUP";
1837 break;
1838 case SDL_HAT_RIGHT:
1839 position = "RIGHT";
1840 break;
1841 case SDL_HAT_RIGHTDOWN:
1842 position = "RIGHTDOWN";
1843 break;
1844 case SDL_HAT_DOWN:
1845 position = "DOWN";
1846 break;
1847 case SDL_HAT_LEFTDOWN:
1848 position = "LEFTDOWN";
1849 break;
1850 case SDL_HAT_LEFT:
1851 position = "LEFT";
1852 break;
1853 case SDL_HAT_LEFTUP:
1854 position = "LEFTUP";
1855 break;
1856 }
1857 SDL_Log("SDL EVENT: Joystick %" SDL_PRIu32 ": hat %d moved to %s",
1858 event->jhat.which, event->jhat.hat, position);
1859 } break;
1860 case SDL_EVENT_JOYSTICK_BUTTON_DOWN:
1861 SDL_Log("SDL EVENT: Joystick %" SDL_PRIu32 ": button %d pressed",
1862 event->jbutton.which, event->jbutton.button);
1863 break;
1864 case SDL_EVENT_JOYSTICK_BUTTON_UP:
1865 SDL_Log("SDL EVENT: Joystick %" SDL_PRIu32 ": button %d released",
1866 event->jbutton.which, event->jbutton.button);
1867 break;
1868 case SDL_EVENT_JOYSTICK_BATTERY_UPDATED:
1869 SDL_Log("SDL EVENT: Joystick %" SDL_PRIu32 ": battery at %d percent",
1870 event->jbattery.which, event->jbattery.percent);
1871 break;
1872 case SDL_EVENT_GAMEPAD_ADDED:
1873 SDL_Log("SDL EVENT: Gamepad %" SDL_PRIu32 " attached",
1874 event->gdevice.which);
1875 break;
1876 case SDL_EVENT_GAMEPAD_REMOVED:
1877 SDL_Log("SDL EVENT: Gamepad %" SDL_PRIu32 " removed",
1878 event->gdevice.which);
1879 break;
1880 case SDL_EVENT_GAMEPAD_REMAPPED:
1881 SDL_Log("SDL EVENT: Gamepad %" SDL_PRIu32 " mapping changed",
1882 event->gdevice.which);
1883 break;
1884 case SDL_EVENT_GAMEPAD_AXIS_MOTION:
1885 SDL_Log("SDL EVENT: Gamepad %" SDL_PRIu32 " axis %d ('%s') value: %d",
1886 event->gaxis.which,
1887 event->gaxis.axis,
1888 GamepadAxisName((SDL_GamepadAxis)event->gaxis.axis),
1889 event->gaxis.value);
1890 break;
1891 case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
1892 SDL_Log("SDL EVENT: Gamepad %" SDL_PRIu32 "button %d ('%s') down",
1893 event->gbutton.which, event->gbutton.button,
1894 GamepadButtonName((SDL_GamepadButton)event->gbutton.button));
1895 break;
1896 case SDL_EVENT_GAMEPAD_BUTTON_UP:
1897 SDL_Log("SDL EVENT: Gamepad %" SDL_PRIu32 " button %d ('%s') up",
1898 event->gbutton.which, event->gbutton.button,
1899 GamepadButtonName((SDL_GamepadButton)event->gbutton.button));
1900 break;
1901 case SDL_EVENT_CLIPBOARD_UPDATE:
1902 SDL_Log("SDL EVENT: Clipboard updated");
1903 break;
1904
1905 case SDL_EVENT_FINGER_MOTION:
1906 SDL_Log("SDL EVENT: Finger: motion touch=%" SDL_PRIu64 ", finger=%" SDL_PRIu64 ", x=%f, y=%f, dx=%f, dy=%f, pressure=%f",
1907 event->tfinger.touchID,
1908 event->tfinger.fingerID,
1909 event->tfinger.x, event->tfinger.y,
1910 event->tfinger.dx, event->tfinger.dy, event->tfinger.pressure);
1911 break;
1912 case SDL_EVENT_FINGER_DOWN:
1913 case SDL_EVENT_FINGER_UP:
1914 case SDL_EVENT_FINGER_CANCELED:
1915 SDL_Log("SDL EVENT: Finger: %s touch=%" SDL_PRIu64 ", finger=%" SDL_PRIu64 ", x=%f, y=%f, dx=%f, dy=%f, pressure=%f",
1916 (event->type == SDL_EVENT_FINGER_DOWN) ? "down" :
1917 (event->type == SDL_EVENT_FINGER_UP) ? "up" : "cancel",
1918 event->tfinger.touchID,
1919 event->tfinger.fingerID,
1920 event->tfinger.x, event->tfinger.y,
1921 event->tfinger.dx, event->tfinger.dy, event->tfinger.pressure);
1922 break;
1923
1924 case SDL_EVENT_RENDER_TARGETS_RESET:
1925 SDL_Log("SDL EVENT: render targets reset in window %" SDL_PRIu32, event->render.windowID);
1926 break;
1927 case SDL_EVENT_RENDER_DEVICE_RESET:
1928 SDL_Log("SDL EVENT: render device reset in window %" SDL_PRIu32, event->render.windowID);
1929 break;
1930 case SDL_EVENT_RENDER_DEVICE_LOST:
1931 SDL_Log("SDL EVENT: render device lost in window %" SDL_PRIu32, event->render.windowID);
1932 break;
1933
1934 case SDL_EVENT_TERMINATING:
1935 SDL_Log("SDL EVENT: App terminating");
1936 break;
1937 case SDL_EVENT_LOW_MEMORY:
1938 SDL_Log("SDL EVENT: App running low on memory");
1939 break;
1940 case SDL_EVENT_WILL_ENTER_BACKGROUND:
1941 SDL_Log("SDL EVENT: App will enter the background");
1942 break;
1943 case SDL_EVENT_DID_ENTER_BACKGROUND:
1944 SDL_Log("SDL EVENT: App entered the background");
1945 break;
1946 case SDL_EVENT_WILL_ENTER_FOREGROUND:
1947 SDL_Log("SDL EVENT: App will enter the foreground");
1948 break;
1949 case SDL_EVENT_DID_ENTER_FOREGROUND:
1950 SDL_Log("SDL EVENT: App entered the foreground");
1951 break;
1952 case SDL_EVENT_DROP_BEGIN:
1953 SDL_Log("SDL EVENT: Drag and drop beginning in window %" SDL_PRIu32, event->drop.windowID);
1954 break;
1955 case SDL_EVENT_DROP_POSITION:
1956 SDL_Log("SDL EVENT: Drag and drop moving in window %" SDL_PRIu32 ": %g,%g", event->drop.windowID, event->drop.x, event->drop.y);
1957 break;
1958 case SDL_EVENT_DROP_FILE:
1959 SDL_Log("SDL EVENT: Drag and drop file in window %" SDL_PRIu32 ": '%s'", event->drop.windowID, event->drop.data);
1960 break;
1961 case SDL_EVENT_DROP_TEXT:
1962 SDL_Log("SDL EVENT: Drag and drop text in window %" SDL_PRIu32 ": '%s'", event->drop.windowID, event->drop.data);
1963 break;
1964 case SDL_EVENT_DROP_COMPLETE:
1965 SDL_Log("SDL EVENT: Drag and drop ending");
1966 break;
1967 case SDL_EVENT_AUDIO_DEVICE_ADDED:
1968 SDL_Log("SDL EVENT: Audio %s device %" SDL_PRIu32 " available",
1969 event->adevice.recording ? "recording" : "playback",
1970 event->adevice.which);
1971 break;
1972 case SDL_EVENT_AUDIO_DEVICE_REMOVED:
1973 SDL_Log("SDL EVENT: Audio %s device %" SDL_PRIu32 " removed",
1974 event->adevice.recording ? "recording" : "playback",
1975 event->adevice.which);
1976 break;
1977 case SDL_EVENT_AUDIO_DEVICE_FORMAT_CHANGED:
1978 SDL_Log("SDL EVENT: Audio %s device %" SDL_PRIu32 " format changed",
1979 event->adevice.recording ? "recording" : "playback",
1980 event->adevice.which);
1981 break;
1982 case SDL_EVENT_CAMERA_DEVICE_ADDED:
1983 SDL_Log("SDL EVENT: Camera device %" SDL_PRIu32 " available",
1984 event->cdevice.which);
1985 break;
1986 case SDL_EVENT_CAMERA_DEVICE_REMOVED:
1987 SDL_Log("SDL EVENT: Camera device %" SDL_PRIu32 " removed",
1988 event->cdevice.which);
1989 break;
1990 case SDL_EVENT_CAMERA_DEVICE_APPROVED:
1991 SDL_Log("SDL EVENT: Camera device %" SDL_PRIu32 " permission granted",
1992 event->cdevice.which);
1993 break;
1994 case SDL_EVENT_CAMERA_DEVICE_DENIED:
1995 SDL_Log("SDL EVENT: Camera device %" SDL_PRIu32 " permission denied",
1996 event->cdevice.which);
1997 break;
1998 case SDL_EVENT_SENSOR_UPDATE:
1999 SDL_Log("SDL EVENT: Sensor update for %" SDL_PRIu32,
2000 event->sensor.which);
2001 break;
2002 case SDL_EVENT_PEN_PROXIMITY_IN:
2003 SDL_Log("SDL EVENT: Pen %" SDL_PRIu32 " entered proximity",
2004 event->pproximity.which);
2005 break;
2006 case SDL_EVENT_PEN_PROXIMITY_OUT:
2007 SDL_Log("SDL EVENT: Pen %" SDL_PRIu32 " left proximity",
2008 event->ptouch.which);
2009 break;
2010 case SDL_EVENT_PEN_DOWN:
2011 SDL_Log("SDL EVENT: Pen %" SDL_PRIu32 " touched down at %g,%g",
2012 event->ptouch.which, event->ptouch.x, event->ptouch.y);
2013 break;
2014 case SDL_EVENT_PEN_UP:
2015 SDL_Log("SDL EVENT: Pen %" SDL_PRIu32 " lifted off at %g,%g",
2016 event->ptouch.which, event->ptouch.x, event->ptouch.y);
2017 break;
2018 case SDL_EVENT_PEN_BUTTON_DOWN:
2019 SDL_Log("SDL EVENT: Pen %" SDL_PRIu32 " button %d pressed at %g,%g",
2020 event->pbutton.which, event->pbutton.button, event->pbutton.x, event->pbutton.y);
2021 break;
2022 case SDL_EVENT_PEN_BUTTON_UP:
2023 SDL_Log("SDL EVENT: Pen %" SDL_PRIu32 " button %d released at %g,%g",
2024 event->pbutton.which, event->pbutton.button, event->pbutton.x, event->pbutton.y);
2025 break;
2026 case SDL_EVENT_PEN_MOTION:
2027 SDL_Log("SDL EVENT: Pen %" SDL_PRIu32 " moved to %g,%g",
2028 event->pmotion.which, event->pmotion.x, event->pmotion.y);
2029 break;
2030 case SDL_EVENT_PEN_AXIS:
2031 SDL_Log("SDL EVENT: Pen %" SDL_PRIu32 " axis %d changed to %.2f",
2032 event->paxis.which, event->paxis.axis, event->paxis.value);
2033 break;
2034 case SDL_EVENT_LOCALE_CHANGED:
2035 SDL_Log("SDL EVENT: Locale changed");
2036 break;
2037 case SDL_EVENT_QUIT:
2038 SDL_Log("SDL EVENT: Quit requested");
2039 break;
2040 case SDL_EVENT_USER:
2041 SDL_Log("SDL EVENT: User event %" SDL_PRIs32, event->user.code);
2042 break;
2043 default:
2044 SDL_Log("Unknown event 0x%4.4" SDL_PRIx32, event->type);
2045 break;
2046 }
2047}
2048
2049#define SCREENSHOT_FILE "screenshot.bmp"
2050
2051typedef struct
2052{
2053 void *image;
2054 size_t size;
2055} SDLTest_ClipboardData;
2056
2057static void SDLCALL SDLTest_ScreenShotClipboardCleanup(void *context)
2058{
2059 SDLTest_ClipboardData *data = (SDLTest_ClipboardData *)context;
2060
2061 SDL_Log("Cleaning up screenshot image data");
2062
2063 if (data->image) {
2064 SDL_free(data->image);
2065 }
2066 SDL_free(data);
2067}
2068
2069static const void * SDLCALL SDLTest_ScreenShotClipboardProvider(void *context, const char *mime_type, size_t *size)
2070{
2071 SDLTest_ClipboardData *data = (SDLTest_ClipboardData *)context;
2072
2073 if (SDL_strncmp(mime_type, "text", 4) == 0) {
2074 SDL_Log("Providing screenshot title to clipboard!");
2075
2076 /* Return "Test screenshot" */
2077 *size = 15;
2078 return "Test screenshot (but this isn't part of it)";
2079 }
2080
2081 SDL_Log("Providing screenshot image to clipboard!");
2082
2083 if (!data->image) {
2084 SDL_IOStream *file;
2085
2086 file = SDL_IOFromFile(SCREENSHOT_FILE, "r");
2087 if (file) {
2088 size_t length = (size_t)SDL_GetIOSize(file);
2089 void *image = SDL_malloc(length);
2090 if (image) {
2091 if (SDL_ReadIO(file, image, length) != length) {
2092 SDL_Log("Couldn't read %s: %s", SCREENSHOT_FILE, SDL_GetError());
2093 SDL_free(image);
2094 image = NULL;
2095 }
2096 }
2097 SDL_CloseIO(file);
2098
2099 if (image) {
2100 data->image = image;
2101 data->size = length;
2102 }
2103 } else {
2104 SDL_Log("Couldn't load %s: %s", SCREENSHOT_FILE, SDL_GetError());
2105 }
2106 }
2107
2108 *size = data->size;
2109 return data->image;
2110}
2111
2112static void SDLTest_CopyScreenShot(SDL_Renderer *renderer)
2113{
2114 SDL_Surface *surface;
2115 const char *image_formats[] = {
2116 "text/plain;charset=utf-8",
2117 "image/bmp"
2118 };
2119 SDLTest_ClipboardData *clipboard_data;
2120
2121 if (!renderer) {
2122 return;
2123 }
2124
2125 surface = SDL_RenderReadPixels(renderer, NULL);
2126 if (!surface) {
2127 SDL_Log("Couldn't read screen: %s", SDL_GetError());
2128 return;
2129 }
2130
2131 if (!SDL_SaveBMP(surface, SCREENSHOT_FILE)) {
2132 SDL_Log("Couldn't save %s: %s", SCREENSHOT_FILE, SDL_GetError());
2133 SDL_DestroySurface(surface);
2134 return;
2135 }
2136 SDL_DestroySurface(surface);
2137
2138 clipboard_data = (SDLTest_ClipboardData *)SDL_calloc(1, sizeof(*clipboard_data));
2139 if (!clipboard_data) {
2140 SDL_Log("Couldn't allocate clipboard data");
2141 return;
2142 }
2143 SDL_SetClipboardData(SDLTest_ScreenShotClipboardProvider, SDLTest_ScreenShotClipboardCleanup, clipboard_data, image_formats, SDL_arraysize(image_formats));
2144 SDL_Log("Saved screenshot to %s and clipboard", SCREENSHOT_FILE);
2145}
2146
2147static void SDLTest_PasteScreenShot(void)
2148{
2149 const char *image_formats[] = {
2150 "image/bmp",
2151 "image/png",
2152 "image/tiff",
2153 };
2154 size_t i;
2155
2156 for (i = 0; i < SDL_arraysize(image_formats); ++i) {
2157 size_t size;
2158 void *data = SDL_GetClipboardData(image_formats[i], &size);
2159 if (data) {
2160 char filename[16];
2161 SDL_IOStream *file;
2162
2163 SDL_snprintf(filename, sizeof(filename), "clipboard.%s", image_formats[i] + 6);
2164 file = SDL_IOFromFile(filename, "w");
2165 if (file) {
2166 SDL_Log("Writing clipboard image to %s", filename);
2167 SDL_WriteIO(file, data, size);
2168 SDL_CloseIO(file);
2169 }
2170 SDL_free(data);
2171 return;
2172 }
2173 }
2174 SDL_Log("No supported screenshot data in the clipboard");
2175}
2176
2177static void FullscreenTo(SDLTest_CommonState *state, int index, int windowId)
2178{
2179 int num_displays;
2180 SDL_DisplayID *displays;
2181 SDL_Window *window;
2182 SDL_WindowFlags flags;
2183 const SDL_DisplayMode *mode;
2184 struct SDL_Rect rect = { 0, 0, 0, 0 };
2185
2186 displays = SDL_GetDisplays(&num_displays);
2187 if (displays && index < num_displays) {
2188 window = SDL_GetWindowFromID(windowId);
2189 if (window) {
2190 SDL_GetDisplayBounds(displays[index], &rect);
2191
2192 flags = SDL_GetWindowFlags(window);
2193 if (flags & SDL_WINDOW_FULLSCREEN) {
2194 SDL_SetWindowFullscreen(window, false);
2195 SDL_Delay(15);
2196 }
2197
2198 mode = SDL_GetWindowFullscreenMode(window);
2199 if (mode) {
2200 /* Try to set the existing mode on the new display */
2201 SDL_DisplayMode new_mode;
2202
2203 SDL_memcpy(&new_mode, mode, sizeof(new_mode));
2204 new_mode.displayID = displays[index];
2205 if (!SDL_SetWindowFullscreenMode(window, &new_mode)) {
2206 /* Try again with a default mode */
2207 bool include_high_density_modes = false;
2208 if (state->window_flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) {
2209 include_high_density_modes = true;
2210 }
2211 if (SDL_GetClosestFullscreenDisplayMode(displays[index], state->window_w, state->window_h, state->refresh_rate, include_high_density_modes, &new_mode)) {
2212 SDL_SetWindowFullscreenMode(window, &new_mode);
2213 }
2214 }
2215 }
2216 if (!mode) {
2217 SDL_SetWindowPosition(window, rect.x, rect.y);
2218 }
2219 SDL_SetWindowFullscreen(window, true);
2220 }
2221 }
2222 SDL_free(displays);
2223}
2224
2225SDL_AppResult SDLTest_CommonEventMainCallbacks(SDLTest_CommonState *state, const SDL_Event *event)
2226{
2227 int i;
2228
2229 if (state->verbose & VERBOSE_EVENT) {
2230 if ((event->type != SDL_EVENT_MOUSE_MOTION &&
2231 event->type != SDL_EVENT_FINGER_MOTION &&
2232 event->type != SDL_EVENT_PEN_MOTION &&
2233 event->type != SDL_EVENT_PEN_AXIS &&
2234 event->type != SDL_EVENT_JOYSTICK_AXIS_MOTION) ||
2235 (state->verbose & VERBOSE_MOTION)) {
2236 SDLTest_PrintEvent(event);
2237 }
2238 }
2239
2240 switch (event->type) {
2241 case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED:
2242 if (state->auto_scale_content) {
2243 SDL_Window *window = SDL_GetWindowFromEvent(event);
2244 if (window) {
2245 float scale = SDL_GetDisplayContentScale(SDL_GetDisplayForWindow(window));
2246 int w = state->window_w;
2247 int h = state->window_h;
2248
2249 w = (int)SDL_ceilf(w * scale);
2250 h = (int)SDL_ceilf(h * scale);
2251 SDL_SetWindowSize(window, w, h);
2252 }
2253 }
2254 break;
2255 case SDL_EVENT_WINDOW_FOCUS_LOST:
2256 if (state->flash_on_focus_loss) {
2257 SDL_Window *window = SDL_GetWindowFromEvent(event);
2258 if (window) {
2259 SDL_FlashWindow(window, SDL_FLASH_UNTIL_FOCUSED);
2260 }
2261 }
2262 break;
2263 case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
2264 {
2265 SDL_Window *window = SDL_GetWindowFromEvent(event);
2266 if (window) {
2267 SDL_HideWindow(window);
2268 }
2269 break;
2270 }
2271 case SDL_EVENT_KEY_DOWN:
2272 {
2273 bool withControl = !!(event->key.mod & SDL_KMOD_CTRL);
2274 bool withShift = !!(event->key.mod & SDL_KMOD_SHIFT);
2275 bool withAlt = !!(event->key.mod & SDL_KMOD_ALT);
2276
2277 switch (event->key.key) {
2278 /* Add hotkeys here */
2279 case SDLK_PRINTSCREEN:
2280 {
2281 SDL_Window *window = SDL_GetWindowFromEvent(event);
2282 if (window) {
2283 for (i = 0; i < state->num_windows; ++i) {
2284 if (window == state->windows[i]) {
2285 SDLTest_CopyScreenShot(state->renderers[i]);
2286 }
2287 }
2288 }
2289 } break;
2290 case SDLK_EQUALS:
2291 if (withControl) {
2292 /* Ctrl-+ double the size of the window */
2293 SDL_Window *window = SDL_GetWindowFromEvent(event);
2294 if (window) {
2295 int w, h;
2296 SDL_GetWindowSize(window, &w, &h);
2297 SDL_SetWindowSize(window, w * 2, h * 2);
2298 }
2299 }
2300 break;
2301 case SDLK_MINUS:
2302 if (withControl) {
2303 /* Ctrl-- half the size of the window */
2304 SDL_Window *window = SDL_GetWindowFromEvent(event);
2305 if (window) {
2306 int w, h;
2307 SDL_GetWindowSize(window, &w, &h);
2308 SDL_SetWindowSize(window, w / 2, h / 2);
2309 }
2310 }
2311 break;
2312 case SDLK_UP:
2313 case SDLK_DOWN:
2314 case SDLK_LEFT:
2315 case SDLK_RIGHT:
2316 if (withAlt) {
2317 /* Alt-Up/Down/Left/Right switches between displays */
2318 SDL_Window *window = SDL_GetWindowFromEvent(event);
2319 if (window) {
2320 int num_displays;
2321 const SDL_DisplayID *displays = SDL_GetDisplays(&num_displays);
2322 if (displays) {
2323 SDL_DisplayID displayID = SDL_GetDisplayForWindow(window);
2324 int current_index = -1;
2325
2326 for (i = 0; i < num_displays; ++i) {
2327 if (displayID == displays[i]) {
2328 current_index = i;
2329 break;
2330 }
2331 }
2332 if (current_index >= 0) {
2333 SDL_DisplayID dest;
2334 if (event->key.key == SDLK_UP || event->key.key == SDLK_LEFT) {
2335 dest = displays[(current_index + num_displays - 1) % num_displays];
2336 } else {
2337 dest = displays[(current_index + num_displays + 1) % num_displays];
2338 }
2339 SDL_Log("Centering on display (%" SDL_PRIu32 ")", dest);
2340 SDL_SetWindowPosition(window,
2341 SDL_WINDOWPOS_CENTERED_DISPLAY(dest),
2342 SDL_WINDOWPOS_CENTERED_DISPLAY(dest));
2343 }
2344 }
2345 }
2346 }
2347 if (withShift) {
2348 /* Shift-Up/Down/Left/Right shift the window by 100px */
2349 SDL_Window *window = SDL_GetWindowFromEvent(event);
2350 if (window) {
2351 const int delta = 100;
2352 int x, y;
2353 SDL_GetWindowPosition(window, &x, &y);
2354
2355 if (event->key.key == SDLK_UP) {
2356 y -= delta;
2357 }
2358 if (event->key.key == SDLK_DOWN) {
2359 y += delta;
2360 }
2361 if (event->key.key == SDLK_LEFT) {
2362 x -= delta;
2363 }
2364 if (event->key.key == SDLK_RIGHT) {
2365 x += delta;
2366 }
2367
2368 SDL_Log("Setting position to (%d, %d)", x, y);
2369 SDL_SetWindowPosition(window, x, y);
2370 }
2371 }
2372 break;
2373 case SDLK_O:
2374 if (withControl) {
2375 /* Ctrl-O (or Ctrl-Shift-O) changes window opacity. */
2376 SDL_Window *window = SDL_GetWindowFromEvent(event);
2377 if (window) {
2378 float opacity = SDL_GetWindowOpacity(window);
2379 if (withShift) {
2380 opacity += 0.20f;
2381 } else {
2382 opacity -= 0.20f;
2383 }
2384 SDL_SetWindowOpacity(window, opacity);
2385 }
2386 }
2387 break;
2388 case SDLK_H:
2389 if (withControl) {
2390 /* Ctrl-H changes cursor visibility. */
2391 if (SDL_CursorVisible()) {
2392 SDL_HideCursor();
2393 } else {
2394 SDL_ShowCursor();
2395 }
2396 }
2397 break;
2398 case SDLK_C:
2399 if (withAlt) {
2400 /* Alt-C copy awesome text to the primary selection! */
2401 SDL_SetPrimarySelectionText("SDL rocks!\nYou know it!");
2402 SDL_Log("Copied text to primary selection");
2403
2404 } else if (withControl) {
2405 if (withShift) {
2406 /* Ctrl-Shift-C copy screenshot! */
2407 SDL_Window *window = SDL_GetWindowFromEvent(event);
2408 if (window) {
2409 for (i = 0; i < state->num_windows; ++i) {
2410 if (window == state->windows[i]) {
2411 SDLTest_CopyScreenShot(state->renderers[i]);
2412 }
2413 }
2414 }
2415 } else {
2416 /* Ctrl-C copy awesome text! */
2417 SDL_SetClipboardText("SDL rocks!\nYou know it!");
2418 SDL_Log("Copied text to clipboard");
2419 }
2420 break;
2421 }
2422 break;
2423 case SDLK_V:
2424 if (withAlt) {
2425 /* Alt-V paste awesome text from the primary selection! */
2426 char *text = SDL_GetPrimarySelectionText();
2427 if (*text) {
2428 SDL_Log("Primary selection: %s", text);
2429 } else {
2430 SDL_Log("Primary selection is empty");
2431 }
2432 SDL_free(text);
2433
2434 } else if (withControl) {
2435 if (withShift) {
2436 /* Ctrl-Shift-V paste screenshot! */
2437 SDLTest_PasteScreenShot();
2438 } else {
2439 /* Ctrl-V paste awesome text! */
2440 char *text = SDL_GetClipboardText();
2441 if (*text) {
2442 SDL_Log("Clipboard: %s", text);
2443 } else {
2444 SDL_Log("Clipboard is empty");
2445 }
2446 SDL_free(text);
2447 }
2448 }
2449 break;
2450 case SDLK_F:
2451 if (withControl) {
2452 /* Ctrl-F flash the window */
2453 SDL_Window *window = SDL_GetWindowFromEvent(event);
2454 if (window) {
2455 SDL_FlashWindow(window, SDL_FLASH_BRIEFLY);
2456 }
2457 }
2458 break;
2459 case SDLK_G:
2460 if (withControl) {
2461 /* Ctrl-G toggle mouse grab */
2462 SDL_Window *window = SDL_GetWindowFromEvent(event);
2463 if (window) {
2464 SDL_SetWindowMouseGrab(window, !SDL_GetWindowMouseGrab(window));
2465 }
2466 }
2467 break;
2468 case SDLK_K:
2469 if (withControl) {
2470 /* Ctrl-K toggle keyboard grab */
2471 SDL_Window *window = SDL_GetWindowFromEvent(event);
2472 if (window) {
2473 SDL_SetWindowKeyboardGrab(window, !SDL_GetWindowKeyboardGrab(window));
2474 }
2475 }
2476 break;
2477 case SDLK_M:
2478 if (withControl) {
2479 /* Ctrl-M maximize */
2480 SDL_Window *window = SDL_GetWindowFromEvent(event);
2481 if (window) {
2482 SDL_WindowFlags flags = SDL_GetWindowFlags(window);
2483 if (!(flags & SDL_WINDOW_RESIZABLE)) {
2484 SDL_SetWindowResizable(window, true);
2485 }
2486 if (flags & SDL_WINDOW_MAXIMIZED) {
2487 SDL_RestoreWindow(window);
2488 } else {
2489 SDL_MaximizeWindow(window);
2490 }
2491 if (!(flags & SDL_WINDOW_RESIZABLE)) {
2492 SDL_SetWindowResizable(window, false);
2493 }
2494 }
2495 }
2496 if (withShift) {
2497 SDL_Window *window = SDL_GetWindowFromEvent(event);
2498 if (window) {
2499 const bool shouldCapture = !(SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_CAPTURE);
2500 const bool rc = SDL_CaptureMouse(shouldCapture);
2501 SDL_Log("%sapturing mouse %s!", shouldCapture ? "C" : "Unc", rc ? "succeeded" : "failed");
2502 }
2503 }
2504 break;
2505 case SDLK_R:
2506 if (withControl) {
2507 /* Ctrl-R toggle mouse relative mode */
2508 SDL_Window *window = SDL_GetWindowFromEvent(event);
2509 if (window) {
2510 SDL_SetWindowRelativeMouseMode(window, !SDL_GetWindowRelativeMouseMode(window));
2511 }
2512 }
2513 break;
2514 case SDLK_T:
2515 if (withControl) {
2516 /* Ctrl-T toggle topmost mode */
2517 SDL_Window *window = SDL_GetWindowFromEvent(event);
2518 if (window) {
2519 SDL_WindowFlags flags = SDL_GetWindowFlags(window);
2520 if (flags & SDL_WINDOW_ALWAYS_ON_TOP) {
2521 SDL_SetWindowAlwaysOnTop(window, false);
2522 } else {
2523 SDL_SetWindowAlwaysOnTop(window, true);
2524 }
2525 }
2526 }
2527 break;
2528 case SDLK_Z:
2529 if (withControl) {
2530 /* Ctrl-Z minimize */
2531 SDL_Window *window = SDL_GetWindowFromEvent(event);
2532 if (window) {
2533 SDL_MinimizeWindow(window);
2534 }
2535 }
2536 break;
2537 case SDLK_RETURN:
2538 if (withControl) {
2539 /* Ctrl-Enter toggle fullscreen */
2540 SDL_Window *window = SDL_GetWindowFromEvent(event);
2541 if (window) {
2542 SDL_WindowFlags flags = SDL_GetWindowFlags(window);
2543 if (!(flags & SDL_WINDOW_FULLSCREEN) ||
2544 !SDL_GetWindowFullscreenMode(window)) {
2545 SDL_SetWindowFullscreenMode(window, &state->fullscreen_mode);
2546 SDL_SetWindowFullscreen(window, true);
2547 } else {
2548 SDL_SetWindowFullscreen(window, false);
2549 }
2550 }
2551 } else if (withAlt) {
2552 /* Alt-Enter toggle fullscreen desktop */
2553 SDL_Window *window = SDL_GetWindowFromEvent(event);
2554 if (window) {
2555 SDL_WindowFlags flags = SDL_GetWindowFlags(window);
2556 if (!(flags & SDL_WINDOW_FULLSCREEN) ||
2557 SDL_GetWindowFullscreenMode(window)) {
2558 SDL_SetWindowFullscreenMode(window, NULL);
2559 SDL_SetWindowFullscreen(window, true);
2560 } else {
2561 SDL_SetWindowFullscreen(window, false);
2562 }
2563 }
2564 }
2565
2566 break;
2567 case SDLK_B:
2568 if (withControl) {
2569 /* Ctrl-B toggle window border */
2570 SDL_Window *window = SDL_GetWindowFromEvent(event);
2571 if (window) {
2572 const SDL_WindowFlags flags = SDL_GetWindowFlags(window);
2573 const bool b = (flags & SDL_WINDOW_BORDERLESS) ? true : false;
2574 SDL_SetWindowBordered(window, b);
2575 }
2576 }
2577 break;
2578 case SDLK_A:
2579 if (withControl) {
2580 /* Ctrl-A toggle aspect ratio */
2581 SDL_Window *window = SDL_GetWindowFromEvent(event);
2582 if (window) {
2583 float min_aspect = 0.0f, max_aspect = 0.0f;
2584
2585 SDL_GetWindowAspectRatio(window, &min_aspect, &max_aspect);
2586 if (min_aspect > 0.0f || max_aspect > 0.0f) {
2587 min_aspect = 0.0f;
2588 max_aspect = 0.0f;
2589 } else {
2590 min_aspect = 1.0f;
2591 max_aspect = 1.0f;
2592 }
2593 SDL_SetWindowAspectRatio(window, min_aspect, max_aspect);
2594 }
2595 }
2596 break;
2597 case SDLK_0:
2598 if (withControl) {
2599 SDL_Window *window = SDL_GetWindowFromEvent(event);
2600 SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Test Message", "You're awesome!", window);
2601 }
2602 break;
2603 case SDLK_1:
2604 if (withControl) {
2605 FullscreenTo(state, 0, event->key.windowID);
2606 }
2607 break;
2608 case SDLK_2:
2609 if (withControl) {
2610 FullscreenTo(state, 1, event->key.windowID);
2611 }
2612 break;
2613 case SDLK_ESCAPE:
2614 return SDL_APP_SUCCESS;
2615 default:
2616 break;
2617 }
2618 break;
2619 }
2620 case SDL_EVENT_QUIT:
2621 return SDL_APP_SUCCESS;
2622 default:
2623 break;
2624 }
2625
2626 return SDL_APP_CONTINUE;
2627}
2628
2629void SDLTest_CommonEvent(SDLTest_CommonState *state, SDL_Event *event, int *done)
2630{
2631 if (SDLTest_CommonEventMainCallbacks(state, event) != SDL_APP_CONTINUE) {
2632 *done = 1;
2633 }
2634}
2635
2636void SDLTest_CommonQuit(SDLTest_CommonState *state)
2637{
2638 if (state) {
2639 int i;
2640
2641 if (state->targets) {
2642 for (i = 0; i < state->num_windows; ++i) {
2643 if (state->targets[i]) {
2644 SDL_DestroyTexture(state->targets[i]);
2645 }
2646 }
2647 SDL_free(state->targets);
2648 }
2649 if (state->renderers) {
2650 for (i = 0; i < state->num_windows; ++i) {
2651 if (state->renderers[i]) {
2652 SDL_DestroyRenderer(state->renderers[i]);
2653 }
2654 }
2655 SDL_free(state->renderers);
2656 }
2657 if (state->windows) {
2658 for (i = 0; i < state->num_windows; i++) {
2659 SDL_DestroyWindow(state->windows[i]);
2660 }
2661 SDL_free(state->windows);
2662 }
2663 }
2664 SDL_Quit();
2665 SDLTest_CommonDestroyState(state);
2666}
2667
2668void SDLTest_CommonDrawWindowInfo(SDL_Renderer *renderer, SDL_Window *window, float *usedHeight)
2669{
2670 char text[1024];
2671 float textY = 0.0f;
2672 const int lineHeight = 10;
2673 int x, y, w, h;
2674 float fx, fy;
2675 SDL_Rect rect;
2676 const SDL_DisplayMode *mode;
2677 float scaleX, scaleY;
2678 SDL_MouseButtonFlags flags;
2679 SDL_DisplayID windowDisplayID = SDL_GetDisplayForWindow(window);
2680 const char *name;
2681 SDL_RendererLogicalPresentation logical_presentation;
2682
2683 /* Video */
2684
2685 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
2686 SDLTest_DrawString(renderer, 0.0f, textY, "-- Video --");
2687 textY += lineHeight;
2688
2689 SDL_SetRenderDrawColor(renderer, 170, 170, 170, 255);
2690
2691 (void)SDL_snprintf(text, sizeof(text), "SDL_GetCurrentVideoDriver: %s", SDL_GetCurrentVideoDriver());
2692 SDLTest_DrawString(renderer, 0.0f, textY, text);
2693 textY += lineHeight;
2694
2695 /* Renderer */
2696
2697 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
2698 SDLTest_DrawString(renderer, 0.0f, textY, "-- Renderer --");
2699 textY += lineHeight;
2700
2701 SDL_SetRenderDrawColor(renderer, 170, 170, 170, 255);
2702
2703 name = SDL_GetRendererName(renderer);
2704 (void)SDL_snprintf(text, sizeof(text), "SDL_GetRendererName: %s", name);
2705 SDLTest_DrawString(renderer, 0.0f, textY, text);
2706 textY += lineHeight;
2707
2708 if (SDL_GetRenderOutputSize(renderer, &w, &h)) {
2709 (void)SDL_snprintf(text, sizeof(text), "SDL_GetRenderOutputSize: %dx%d", w, h);
2710 SDLTest_DrawString(renderer, 0.0f, textY, text);
2711 textY += lineHeight;
2712 }
2713
2714 if (SDL_GetCurrentRenderOutputSize(renderer, &w, &h)) {
2715 (void)SDL_snprintf(text, sizeof(text), "SDL_GetCurrentRenderOutputSize: %dx%d", w, h);
2716 SDLTest_DrawString(renderer, 0.0f, textY, text);
2717 textY += lineHeight;
2718 }
2719
2720 SDL_GetRenderViewport(renderer, &rect);
2721 (void)SDL_snprintf(text, sizeof(text), "SDL_GetRenderViewport: %d,%d, %dx%d",
2722 rect.x, rect.y, rect.w, rect.h);
2723 SDLTest_DrawString(renderer, 0.0f, textY, text);
2724 textY += lineHeight;
2725
2726 SDL_GetRenderScale(renderer, &scaleX, &scaleY);
2727 (void)SDL_snprintf(text, sizeof(text), "SDL_GetRenderScale: %g,%g",
2728 scaleX, scaleY);
2729 SDLTest_DrawString(renderer, 0.0f, textY, text);
2730 textY += lineHeight;
2731
2732 SDL_GetRenderLogicalPresentation(renderer, &w, &h, &logical_presentation);
2733 (void)SDL_snprintf(text, sizeof(text), "SDL_GetRenderLogicalPresentation: %dx%d ", w, h);
2734 SDLTest_PrintLogicalPresentation(text, sizeof(text), logical_presentation);
2735 textY += lineHeight;
2736
2737 /* Window */
2738
2739 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
2740 SDLTest_DrawString(renderer, 0.0f, textY, "-- Window --");
2741 textY += lineHeight;
2742
2743 SDL_SetRenderDrawColor(renderer, 170, 170, 170, 255);
2744
2745 SDL_GetWindowPosition(window, &x, &y);
2746 (void)SDL_snprintf(text, sizeof(text), "SDL_GetWindowPosition: %d,%d", x, y);
2747 SDLTest_DrawString(renderer, 0.0f, textY, text);
2748 textY += lineHeight;
2749
2750 SDL_GetWindowSize(window, &w, &h);
2751 (void)SDL_snprintf(text, sizeof(text), "SDL_GetWindowSize: %dx%d", w, h);
2752 SDLTest_DrawString(renderer, 0.0f, textY, text);
2753 textY += lineHeight;
2754
2755 SDL_GetWindowSafeArea(window, &rect);
2756 (void)SDL_snprintf(text, sizeof(text), "SDL_GetWindowSafeArea: %d,%d %dx%d", rect.x, rect.y, rect.w, rect.h);
2757 SDLTest_DrawString(renderer, 0.0f, textY, text);
2758 textY += lineHeight;
2759
2760 (void)SDL_snprintf(text, sizeof(text), "SDL_GetWindowFlags: ");
2761 SDLTest_PrintWindowFlags(text, sizeof(text), SDL_GetWindowFlags(window));
2762 SDLTest_DrawString(renderer, 0.0f, textY, text);
2763 textY += lineHeight;
2764
2765 mode = SDL_GetWindowFullscreenMode(window);
2766 if (mode) {
2767 (void)SDL_snprintf(text, sizeof(text), "SDL_GetWindowFullscreenMode: %dx%d@%gx %gHz, (%s)",
2768 mode->w, mode->h, mode->pixel_density, mode->refresh_rate, SDL_GetPixelFormatName(mode->format));
2769 SDLTest_DrawString(renderer, 0.0f, textY, text);
2770 textY += lineHeight;
2771 }
2772
2773 /* Display */
2774
2775 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
2776 SDLTest_DrawString(renderer, 0.0f, textY, "-- Display --");
2777 textY += lineHeight;
2778
2779 SDL_SetRenderDrawColor(renderer, 170, 170, 170, 255);
2780
2781 (void)SDL_snprintf(text, sizeof(text), "SDL_GetDisplayForWindow: %" SDL_PRIu32, windowDisplayID);
2782 SDLTest_DrawString(renderer, 0.0f, textY, text);
2783 textY += lineHeight;
2784
2785 (void)SDL_snprintf(text, sizeof(text), "SDL_GetDisplayName: %s", SDL_GetDisplayName(windowDisplayID));
2786 SDLTest_DrawString(renderer, 0.0f, textY, text);
2787 textY += lineHeight;
2788
2789 if (SDL_GetDisplayBounds(windowDisplayID, &rect)) {
2790 (void)SDL_snprintf(text, sizeof(text), "SDL_GetDisplayBounds: %d,%d, %dx%d",
2791 rect.x, rect.y, rect.w, rect.h);
2792 SDLTest_DrawString(renderer, 0.0f, textY, text);
2793 textY += lineHeight;
2794 }
2795
2796 mode = SDL_GetCurrentDisplayMode(windowDisplayID);
2797 if (mode) {
2798 (void)SDL_snprintf(text, sizeof(text), "SDL_GetCurrentDisplayMode: %dx%d@%gx %gHz, (%s)",
2799 mode->w, mode->h, mode->pixel_density, mode->refresh_rate, SDL_GetPixelFormatName(mode->format));
2800 SDLTest_DrawString(renderer, 0.0f, textY, text);
2801 textY += lineHeight;
2802 }
2803
2804 mode = SDL_GetDesktopDisplayMode(windowDisplayID);
2805 if (mode) {
2806 (void)SDL_snprintf(text, sizeof(text), "SDL_GetDesktopDisplayMode: %dx%d@%gx %gHz, (%s)",
2807 mode->w, mode->h, mode->pixel_density, mode->refresh_rate, SDL_GetPixelFormatName(mode->format));
2808 SDLTest_DrawString(renderer, 0.0f, textY, text);
2809 textY += lineHeight;
2810 }
2811
2812 (void)SDL_snprintf(text, sizeof(text), "SDL_GetNaturalDisplayOrientation: ");
2813 SDLTest_PrintDisplayOrientation(text, sizeof(text), SDL_GetNaturalDisplayOrientation(windowDisplayID));
2814 SDLTest_DrawString(renderer, 0.0f, textY, text);
2815 textY += lineHeight;
2816
2817 (void)SDL_snprintf(text, sizeof(text), "SDL_GetCurrentDisplayOrientation: ");
2818 SDLTest_PrintDisplayOrientation(text, sizeof(text), SDL_GetCurrentDisplayOrientation(windowDisplayID));
2819 SDLTest_DrawString(renderer, 0.0f, textY, text);
2820 textY += lineHeight;
2821
2822 (void)SDL_snprintf(text, sizeof(text), "SDL_GetDisplayContentScale: %g", SDL_GetDisplayContentScale(windowDisplayID));
2823 SDLTest_DrawString(renderer, 0.0f, textY, text);
2824 textY += lineHeight;
2825
2826 /* Mouse */
2827
2828 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
2829 SDLTest_DrawString(renderer, 0.0f, textY, "-- Mouse --");
2830 textY += lineHeight;
2831
2832 SDL_SetRenderDrawColor(renderer, 170, 170, 170, 255);
2833
2834 flags = SDL_GetMouseState(&fx, &fy);
2835 (void)SDL_snprintf(text, sizeof(text), "SDL_GetMouseState: %g,%g ", fx, fy);
2836 SDLTest_PrintButtonMask(text, sizeof(text), flags);
2837 SDLTest_DrawString(renderer, 0.0f, textY, text);
2838 textY += lineHeight;
2839
2840 flags = SDL_GetGlobalMouseState(&fx, &fy);
2841 (void)SDL_snprintf(text, sizeof(text), "SDL_GetGlobalMouseState: %g,%g ", fx, fy);
2842 SDLTest_PrintButtonMask(text, sizeof(text), flags);
2843 SDLTest_DrawString(renderer, 0.0f, textY, text);
2844 textY += lineHeight;
2845
2846 /* Keyboard */
2847
2848 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
2849 SDLTest_DrawString(renderer, 0, textY, "-- Keyboard --");
2850 textY += lineHeight;
2851
2852 SDL_SetRenderDrawColor(renderer, 170, 170, 170, 255);
2853
2854 (void)SDL_snprintf(text, sizeof(text), "SDL_GetModState: ");
2855 SDLTest_PrintModState(text, sizeof(text), SDL_GetModState());
2856 SDLTest_DrawString(renderer, 0, textY, text);
2857 textY += lineHeight;
2858
2859 if (usedHeight) {
2860 *usedHeight = textY;
2861 }
2862}