1 /*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2020 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
24 #include "SDL_config.h"
25 #include "SDL_test.h"
26
27 #include <stdio.h>
28
29 static const char *video_usage[] = {
30 "[--video driver]", "[--renderer driver]", "[--gldebug]",
31 "[--info all|video|modes|render|event]",
32 "[--log all|error|system|audio|video|render|input]", "[--display N]",
33 "[--fullscreen | --fullscreen-desktop | --windows N]", "[--title title]",
34 "[--icon icon.bmp]", "[--center | --position X,Y]", "[--geometry WxH]",
35 "[--min-geometry WxH]", "[--max-geometry WxH]", "[--logical WxH]",
36 "[--scale N]", "[--depth N]", "[--refresh R]", "[--vsync]", "[--noframe]",
37 "[--resize]", "[--minimize]", "[--maximize]", "[--grab]",
38 "[--allow-highdpi]", "[--usable-bounds]"
39 };
40
41 static const char *audio_usage[] = {
42 "[--rate N]", "[--format U8|S8|U16|U16LE|U16BE|S16|S16LE|S16BE]",
43 "[--channels N]", "[--samples N]"
44 };
45
SDL_snprintfcat(SDL_OUT_Z_CAP (maxlen)char * text,size_t maxlen,SDL_PRINTF_FORMAT_STRING const char * fmt,...)46 static void SDL_snprintfcat(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, SDL_PRINTF_FORMAT_STRING const char *fmt, ... )
47 {
48 size_t length = SDL_strlen(text);
49 va_list ap;
50
51 va_start(ap, fmt);
52 text += length;
53 maxlen -= length;
54 SDL_vsnprintf(text, maxlen, fmt, ap);
55 va_end(ap);
56 }
57
58 SDLTest_CommonState *
SDLTest_CommonCreateState(char ** argv,Uint32 flags)59 SDLTest_CommonCreateState(char **argv, Uint32 flags)
60 {
61 int i;
62 SDLTest_CommonState *state;
63
64 /* Do this first so we catch all allocations */
65 for (i = 1; argv[i]; ++i) {
66 if (SDL_strcasecmp(argv[i], "--trackmem") == 0) {
67 SDLTest_TrackAllocations();
68 break;
69 }
70 }
71
72 state = (SDLTest_CommonState *)SDL_calloc(1, sizeof(*state));
73 if (!state) {
74 SDL_OutOfMemory();
75 return NULL;
76 }
77
78 /* Initialize some defaults */
79 state->argv = argv;
80 state->flags = flags;
81 state->window_title = argv[0];
82 state->window_flags = 0;
83 state->window_x = SDL_WINDOWPOS_UNDEFINED;
84 state->window_y = SDL_WINDOWPOS_UNDEFINED;
85 state->window_w = DEFAULT_WINDOW_WIDTH;
86 state->window_h = DEFAULT_WINDOW_HEIGHT;
87 state->num_windows = 1;
88 state->audiospec.freq = 22050;
89 state->audiospec.format = AUDIO_S16;
90 state->audiospec.channels = 2;
91 state->audiospec.samples = 2048;
92
93 /* Set some very sane GL defaults */
94 state->gl_red_size = 3;
95 state->gl_green_size = 3;
96 state->gl_blue_size = 2;
97 state->gl_alpha_size = 0;
98 state->gl_buffer_size = 0;
99 state->gl_depth_size = 16;
100 state->gl_stencil_size = 0;
101 state->gl_double_buffer = 1;
102 state->gl_accum_red_size = 0;
103 state->gl_accum_green_size = 0;
104 state->gl_accum_blue_size = 0;
105 state->gl_accum_alpha_size = 0;
106 state->gl_stereo = 0;
107 state->gl_multisamplebuffers = 0;
108 state->gl_multisamplesamples = 0;
109 state->gl_retained_backing = 1;
110 state->gl_accelerated = -1;
111 state->gl_debug = 0;
112
113 return state;
114 }
115
116 int
SDLTest_CommonArg(SDLTest_CommonState * state,int index)117 SDLTest_CommonArg(SDLTest_CommonState * state, int index)
118 {
119 char **argv = state->argv;
120
121 if (SDL_strcasecmp(argv[index], "--video") == 0) {
122 ++index;
123 if (!argv[index]) {
124 return -1;
125 }
126 state->videodriver = argv[index];
127 return 2;
128 }
129 if (SDL_strcasecmp(argv[index], "--renderer") == 0) {
130 ++index;
131 if (!argv[index]) {
132 return -1;
133 }
134 state->renderdriver = argv[index];
135 return 2;
136 }
137 if (SDL_strcasecmp(argv[index], "--gldebug") == 0) {
138 state->gl_debug = 1;
139 return 1;
140 }
141 if (SDL_strcasecmp(argv[index], "--info") == 0) {
142 ++index;
143 if (!argv[index]) {
144 return -1;
145 }
146 if (SDL_strcasecmp(argv[index], "all") == 0) {
147 state->verbose |=
148 (VERBOSE_VIDEO | VERBOSE_MODES | VERBOSE_RENDER |
149 VERBOSE_EVENT);
150 return 2;
151 }
152 if (SDL_strcasecmp(argv[index], "video") == 0) {
153 state->verbose |= VERBOSE_VIDEO;
154 return 2;
155 }
156 if (SDL_strcasecmp(argv[index], "modes") == 0) {
157 state->verbose |= VERBOSE_MODES;
158 return 2;
159 }
160 if (SDL_strcasecmp(argv[index], "render") == 0) {
161 state->verbose |= VERBOSE_RENDER;
162 return 2;
163 }
164 if (SDL_strcasecmp(argv[index], "event") == 0) {
165 state->verbose |= VERBOSE_EVENT;
166 return 2;
167 }
168 return -1;
169 }
170 if (SDL_strcasecmp(argv[index], "--log") == 0) {
171 ++index;
172 if (!argv[index]) {
173 return -1;
174 }
175 if (SDL_strcasecmp(argv[index], "all") == 0) {
176 SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE);
177 return 2;
178 }
179 if (SDL_strcasecmp(argv[index], "error") == 0) {
180 SDL_LogSetPriority(SDL_LOG_CATEGORY_ERROR, SDL_LOG_PRIORITY_VERBOSE);
181 return 2;
182 }
183 if (SDL_strcasecmp(argv[index], "system") == 0) {
184 SDL_LogSetPriority(SDL_LOG_CATEGORY_SYSTEM, SDL_LOG_PRIORITY_VERBOSE);
185 return 2;
186 }
187 if (SDL_strcasecmp(argv[index], "audio") == 0) {
188 SDL_LogSetPriority(SDL_LOG_CATEGORY_AUDIO, SDL_LOG_PRIORITY_VERBOSE);
189 return 2;
190 }
191 if (SDL_strcasecmp(argv[index], "video") == 0) {
192 SDL_LogSetPriority(SDL_LOG_CATEGORY_VIDEO, SDL_LOG_PRIORITY_VERBOSE);
193 return 2;
194 }
195 if (SDL_strcasecmp(argv[index], "render") == 0) {
196 SDL_LogSetPriority(SDL_LOG_CATEGORY_RENDER, SDL_LOG_PRIORITY_VERBOSE);
197 return 2;
198 }
199 if (SDL_strcasecmp(argv[index], "input") == 0) {
200 SDL_LogSetPriority(SDL_LOG_CATEGORY_INPUT, SDL_LOG_PRIORITY_VERBOSE);
201 return 2;
202 }
203 return -1;
204 }
205 if (SDL_strcasecmp(argv[index], "--display") == 0) {
206 ++index;
207 if (!argv[index]) {
208 return -1;
209 }
210 state->display = SDL_atoi(argv[index]);
211 if (SDL_WINDOWPOS_ISUNDEFINED(state->window_x)) {
212 state->window_x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(state->display);
213 state->window_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(state->display);
214 }
215 if (SDL_WINDOWPOS_ISCENTERED(state->window_x)) {
216 state->window_x = SDL_WINDOWPOS_CENTERED_DISPLAY(state->display);
217 state->window_y = SDL_WINDOWPOS_CENTERED_DISPLAY(state->display);
218 }
219 return 2;
220 }
221 if (SDL_strcasecmp(argv[index], "--fullscreen") == 0) {
222 state->window_flags |= SDL_WINDOW_FULLSCREEN;
223 state->num_windows = 1;
224 return 1;
225 }
226 if (SDL_strcasecmp(argv[index], "--fullscreen-desktop") == 0) {
227 state->window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
228 state->num_windows = 1;
229 return 1;
230 }
231 if (SDL_strcasecmp(argv[index], "--allow-highdpi") == 0) {
232 state->window_flags |= SDL_WINDOW_ALLOW_HIGHDPI;
233 return 1;
234 }
235 if (SDL_strcasecmp(argv[index], "--windows") == 0) {
236 ++index;
237 if (!argv[index] || !SDL_isdigit(*argv[index])) {
238 return -1;
239 }
240 if (!(state->window_flags & SDL_WINDOW_FULLSCREEN)) {
241 state->num_windows = SDL_atoi(argv[index]);
242 }
243 return 2;
244 }
245 if (SDL_strcasecmp(argv[index], "--title") == 0) {
246 ++index;
247 if (!argv[index]) {
248 return -1;
249 }
250 state->window_title = argv[index];
251 return 2;
252 }
253 if (SDL_strcasecmp(argv[index], "--icon") == 0) {
254 ++index;
255 if (!argv[index]) {
256 return -1;
257 }
258 state->window_icon = argv[index];
259 return 2;
260 }
261 if (SDL_strcasecmp(argv[index], "--center") == 0) {
262 state->window_x = SDL_WINDOWPOS_CENTERED;
263 state->window_y = SDL_WINDOWPOS_CENTERED;
264 return 1;
265 }
266 if (SDL_strcasecmp(argv[index], "--position") == 0) {
267 char *x, *y;
268 ++index;
269 if (!argv[index]) {
270 return -1;
271 }
272 x = argv[index];
273 y = argv[index];
274 while (*y && *y != ',') {
275 ++y;
276 }
277 if (!*y) {
278 return -1;
279 }
280 *y++ = '\0';
281 state->window_x = SDL_atoi(x);
282 state->window_y = SDL_atoi(y);
283 return 2;
284 }
285 if (SDL_strcasecmp(argv[index], "--usable-bounds") == 0) {
286 /* !!! FIXME: this is a bit of a hack, but I don't want to add a
287 !!! FIXME: flag to the public structure in 2.0.x */
288 state->window_x = -1;
289 state->window_y = -1;
290 state->window_w = -1;
291 state->window_h = -1;
292 return 1;
293 }
294 if (SDL_strcasecmp(argv[index], "--geometry") == 0) {
295 char *w, *h;
296 ++index;
297 if (!argv[index]) {
298 return -1;
299 }
300 w = argv[index];
301 h = argv[index];
302 while (*h && *h != 'x') {
303 ++h;
304 }
305 if (!*h) {
306 return -1;
307 }
308 *h++ = '\0';
309 state->window_w = SDL_atoi(w);
310 state->window_h = SDL_atoi(h);
311 return 2;
312 }
313 if (SDL_strcasecmp(argv[index], "--min-geometry") == 0) {
314 char *w, *h;
315 ++index;
316 if (!argv[index]) {
317 return -1;
318 }
319 w = argv[index];
320 h = argv[index];
321 while (*h && *h != 'x') {
322 ++h;
323 }
324 if (!*h) {
325 return -1;
326 }
327 *h++ = '\0';
328 state->window_minW = SDL_atoi(w);
329 state->window_minH = SDL_atoi(h);
330 return 2;
331 }
332 if (SDL_strcasecmp(argv[index], "--max-geometry") == 0) {
333 char *w, *h;
334 ++index;
335 if (!argv[index]) {
336 return -1;
337 }
338 w = argv[index];
339 h = argv[index];
340 while (*h && *h != 'x') {
341 ++h;
342 }
343 if (!*h) {
344 return -1;
345 }
346 *h++ = '\0';
347 state->window_maxW = SDL_atoi(w);
348 state->window_maxH = SDL_atoi(h);
349 return 2;
350 }
351 if (SDL_strcasecmp(argv[index], "--logical") == 0) {
352 char *w, *h;
353 ++index;
354 if (!argv[index]) {
355 return -1;
356 }
357 w = argv[index];
358 h = argv[index];
359 while (*h && *h != 'x') {
360 ++h;
361 }
362 if (!*h) {
363 return -1;
364 }
365 *h++ = '\0';
366 state->logical_w = SDL_atoi(w);
367 state->logical_h = SDL_atoi(h);
368 return 2;
369 }
370 if (SDL_strcasecmp(argv[index], "--scale") == 0) {
371 ++index;
372 if (!argv[index]) {
373 return -1;
374 }
375 state->scale = (float)SDL_atof(argv[index]);
376 return 2;
377 }
378 if (SDL_strcasecmp(argv[index], "--depth") == 0) {
379 ++index;
380 if (!argv[index]) {
381 return -1;
382 }
383 state->depth = SDL_atoi(argv[index]);
384 return 2;
385 }
386 if (SDL_strcasecmp(argv[index], "--refresh") == 0) {
387 ++index;
388 if (!argv[index]) {
389 return -1;
390 }
391 state->refresh_rate = SDL_atoi(argv[index]);
392 return 2;
393 }
394 if (SDL_strcasecmp(argv[index], "--vsync") == 0) {
395 state->render_flags |= SDL_RENDERER_PRESENTVSYNC;
396 return 1;
397 }
398 if (SDL_strcasecmp(argv[index], "--noframe") == 0) {
399 state->window_flags |= SDL_WINDOW_BORDERLESS;
400 return 1;
401 }
402 if (SDL_strcasecmp(argv[index], "--resize") == 0) {
403 state->window_flags |= SDL_WINDOW_RESIZABLE;
404 return 1;
405 }
406 if (SDL_strcasecmp(argv[index], "--minimize") == 0) {
407 state->window_flags |= SDL_WINDOW_MINIMIZED;
408 return 1;
409 }
410 if (SDL_strcasecmp(argv[index], "--maximize") == 0) {
411 state->window_flags |= SDL_WINDOW_MAXIMIZED;
412 return 1;
413 }
414 if (SDL_strcasecmp(argv[index], "--grab") == 0) {
415 state->window_flags |= SDL_WINDOW_INPUT_GRABBED;
416 return 1;
417 }
418 if (SDL_strcasecmp(argv[index], "--rate") == 0) {
419 ++index;
420 if (!argv[index]) {
421 return -1;
422 }
423 state->audiospec.freq = SDL_atoi(argv[index]);
424 return 2;
425 }
426 if (SDL_strcasecmp(argv[index], "--format") == 0) {
427 ++index;
428 if (!argv[index]) {
429 return -1;
430 }
431 if (SDL_strcasecmp(argv[index], "U8") == 0) {
432 state->audiospec.format = AUDIO_U8;
433 return 2;
434 }
435 if (SDL_strcasecmp(argv[index], "S8") == 0) {
436 state->audiospec.format = AUDIO_S8;
437 return 2;
438 }
439 if (SDL_strcasecmp(argv[index], "U16") == 0) {
440 state->audiospec.format = AUDIO_U16;
441 return 2;
442 }
443 if (SDL_strcasecmp(argv[index], "U16LE") == 0) {
444 state->audiospec.format = AUDIO_U16LSB;
445 return 2;
446 }
447 if (SDL_strcasecmp(argv[index], "U16BE") == 0) {
448 state->audiospec.format = AUDIO_U16MSB;
449 return 2;
450 }
451 if (SDL_strcasecmp(argv[index], "S16") == 0) {
452 state->audiospec.format = AUDIO_S16;
453 return 2;
454 }
455 if (SDL_strcasecmp(argv[index], "S16LE") == 0) {
456 state->audiospec.format = AUDIO_S16LSB;
457 return 2;
458 }
459 if (SDL_strcasecmp(argv[index], "S16BE") == 0) {
460 state->audiospec.format = AUDIO_S16MSB;
461 return 2;
462 }
463 return -1;
464 }
465 if (SDL_strcasecmp(argv[index], "--channels") == 0) {
466 ++index;
467 if (!argv[index]) {
468 return -1;
469 }
470 state->audiospec.channels = (Uint8) SDL_atoi(argv[index]);
471 return 2;
472 }
473 if (SDL_strcasecmp(argv[index], "--samples") == 0) {
474 ++index;
475 if (!argv[index]) {
476 return -1;
477 }
478 state->audiospec.samples = (Uint16) SDL_atoi(argv[index]);
479 return 2;
480 }
481 if (SDL_strcasecmp(argv[index], "--trackmem") == 0) {
482 /* Already handled in SDLTest_CommonCreateState() */
483 return 1;
484 }
485 if ((SDL_strcasecmp(argv[index], "-h") == 0)
486 || (SDL_strcasecmp(argv[index], "--help") == 0)) {
487 /* Print the usage message */
488 return -1;
489 }
490 if (SDL_strcmp(argv[index], "-NSDocumentRevisionsDebugMode") == 0) {
491 /* Debug flag sent by Xcode */
492 return 2;
493 }
494 return 0;
495 }
496
497 void
SDLTest_CommonLogUsage(SDLTest_CommonState * state,const char * argv0,const char ** options)498 SDLTest_CommonLogUsage(SDLTest_CommonState * state, const char *argv0, const char **options)
499 {
500 int i;
501
502 SDL_Log("USAGE: %s", argv0);
503 SDL_Log(" %s", "[--trackmem]");
504
505 if (state->flags & SDL_INIT_VIDEO) {
506 for (i = 0; i < SDL_arraysize(video_usage); i++) {
507 SDL_Log(" %s", video_usage[i]);
508 }
509 }
510
511 if (state->flags & SDL_INIT_AUDIO) {
512 for (i = 0; i < SDL_arraysize(audio_usage); i++) {
513 SDL_Log(" %s", audio_usage[i]);
514 }
515 }
516
517 if (options) {
518 for (i = 0; options[i] != NULL; i++) {
519 SDL_Log(" %s", options[i]);
520 }
521 }
522 }
523
524 static const char *
BuildCommonUsageString(char ** pstr,const char ** strlist,const int numitems,const char ** strlist2,const int numitems2)525 BuildCommonUsageString(char **pstr, const char **strlist, const int numitems, const char **strlist2, const int numitems2)
526 {
527 char *str = *pstr;
528 if (!str) {
529 size_t len = SDL_strlen("[--trackmem]") + 2;
530 int i;
531 for (i = 0; i < numitems; i++) {
532 len += SDL_strlen(strlist[i]) + 1;
533 }
534 if (strlist2) {
535 for (i = 0; i < numitems2; i++) {
536 len += SDL_strlen(strlist2[i]) + 1;
537 }
538 }
539 str = (char *) SDL_calloc(1, len);
540 if (!str) {
541 return ""; /* oh well. */
542 }
543 SDL_strlcat(str, "[--trackmem] ", len);
544 for (i = 0; i < numitems-1; i++) {
545 SDL_strlcat(str, strlist[i], len);
546 SDL_strlcat(str, " ", len);
547 }
548 SDL_strlcat(str, strlist[i], len);
549 if (strlist2) {
550 SDL_strlcat(str, " ", len);
551 for (i = 0; i < numitems2-1; i++) {
552 SDL_strlcat(str, strlist2[i], len);
553 SDL_strlcat(str, " ", len);
554 }
555 SDL_strlcat(str, strlist2[i], len);
556 }
557 *pstr = str;
558 }
559 return str;
560 }
561
562 static char *common_usage_video = NULL;
563 static char *common_usage_audio = NULL;
564 static char *common_usage_videoaudio = NULL;
565
566 const char *
SDLTest_CommonUsage(SDLTest_CommonState * state)567 SDLTest_CommonUsage(SDLTest_CommonState * state)
568 {
569
570 switch (state->flags & (SDL_INIT_VIDEO | SDL_INIT_AUDIO)) {
571 case SDL_INIT_VIDEO:
572 return BuildCommonUsageString(&common_usage_video, video_usage, SDL_arraysize(video_usage), NULL, 0);
573 case SDL_INIT_AUDIO:
574 return BuildCommonUsageString(&common_usage_audio, audio_usage, SDL_arraysize(audio_usage), NULL, 0);
575 case (SDL_INIT_VIDEO | SDL_INIT_AUDIO):
576 return BuildCommonUsageString(&common_usage_videoaudio, video_usage, SDL_arraysize(video_usage), audio_usage, SDL_arraysize(audio_usage));
577 default:
578 return "[--trackmem]";
579 }
580 }
581
582
583 SDL_bool
SDLTest_CommonDefaultArgs(SDLTest_CommonState * state,const int argc,char ** argv)584 SDLTest_CommonDefaultArgs(SDLTest_CommonState *state, const int argc, char **argv)
585 {
586 int i = 1;
587 while (i < argc) {
588 const int consumed = SDLTest_CommonArg(state, i);
589 if (consumed == 0) {
590 SDLTest_CommonLogUsage(state, argv[0], NULL);
591 return SDL_FALSE;
592 }
593 i += consumed;
594 }
595 return SDL_TRUE;
596 }
597
598 static void
SDLTest_PrintRendererFlag(char * text,size_t maxlen,Uint32 flag)599 SDLTest_PrintRendererFlag(char *text, size_t maxlen, Uint32 flag)
600 {
601 switch (flag) {
602 case SDL_RENDERER_SOFTWARE:
603 SDL_snprintfcat(text, maxlen, "Software");
604 break;
605 case SDL_RENDERER_ACCELERATED:
606 SDL_snprintfcat(text, maxlen, "Accelerated");
607 break;
608 case SDL_RENDERER_PRESENTVSYNC:
609 SDL_snprintfcat(text, maxlen, "PresentVSync");
610 break;
611 case SDL_RENDERER_TARGETTEXTURE:
612 SDL_snprintfcat(text, maxlen, "TargetTexturesSupported");
613 break;
614 default:
615 SDL_snprintfcat(text, maxlen, "0x%8.8x", flag);
616 break;
617 }
618 }
619
620 static void
SDLTest_PrintPixelFormat(char * text,size_t maxlen,Uint32 format)621 SDLTest_PrintPixelFormat(char *text, size_t maxlen, Uint32 format)
622 {
623 switch (format) {
624 case SDL_PIXELFORMAT_UNKNOWN:
625 SDL_snprintfcat(text, maxlen, "Unknown");
626 break;
627 case SDL_PIXELFORMAT_INDEX1LSB:
628 SDL_snprintfcat(text, maxlen, "Index1LSB");
629 break;
630 case SDL_PIXELFORMAT_INDEX1MSB:
631 SDL_snprintfcat(text, maxlen, "Index1MSB");
632 break;
633 case SDL_PIXELFORMAT_INDEX4LSB:
634 SDL_snprintfcat(text, maxlen, "Index4LSB");
635 break;
636 case SDL_PIXELFORMAT_INDEX4MSB:
637 SDL_snprintfcat(text, maxlen, "Index4MSB");
638 break;
639 case SDL_PIXELFORMAT_INDEX8:
640 SDL_snprintfcat(text, maxlen, "Index8");
641 break;
642 case SDL_PIXELFORMAT_RGB332:
643 SDL_snprintfcat(text, maxlen, "RGB332");
644 break;
645 case SDL_PIXELFORMAT_RGB444:
646 SDL_snprintfcat(text, maxlen, "RGB444");
647 break;
648 case SDL_PIXELFORMAT_BGR444:
649 SDL_snprintfcat(text, maxlen, "BGR444");
650 break;
651 case SDL_PIXELFORMAT_RGB555:
652 SDL_snprintfcat(text, maxlen, "RGB555");
653 break;
654 case SDL_PIXELFORMAT_BGR555:
655 SDL_snprintfcat(text, maxlen, "BGR555");
656 break;
657 case SDL_PIXELFORMAT_ARGB4444:
658 SDL_snprintfcat(text, maxlen, "ARGB4444");
659 break;
660 case SDL_PIXELFORMAT_ABGR4444:
661 SDL_snprintfcat(text, maxlen, "ABGR4444");
662 break;
663 case SDL_PIXELFORMAT_ARGB1555:
664 SDL_snprintfcat(text, maxlen, "ARGB1555");
665 break;
666 case SDL_PIXELFORMAT_ABGR1555:
667 SDL_snprintfcat(text, maxlen, "ABGR1555");
668 break;
669 case SDL_PIXELFORMAT_RGB565:
670 SDL_snprintfcat(text, maxlen, "RGB565");
671 break;
672 case SDL_PIXELFORMAT_BGR565:
673 SDL_snprintfcat(text, maxlen, "BGR565");
674 break;
675 case SDL_PIXELFORMAT_RGB24:
676 SDL_snprintfcat(text, maxlen, "RGB24");
677 break;
678 case SDL_PIXELFORMAT_BGR24:
679 SDL_snprintfcat(text, maxlen, "BGR24");
680 break;
681 case SDL_PIXELFORMAT_RGB888:
682 SDL_snprintfcat(text, maxlen, "RGB888");
683 break;
684 case SDL_PIXELFORMAT_BGR888:
685 SDL_snprintfcat(text, maxlen, "BGR888");
686 break;
687 case SDL_PIXELFORMAT_ARGB8888:
688 SDL_snprintfcat(text, maxlen, "ARGB8888");
689 break;
690 case SDL_PIXELFORMAT_RGBA8888:
691 SDL_snprintfcat(text, maxlen, "RGBA8888");
692 break;
693 case SDL_PIXELFORMAT_ABGR8888:
694 SDL_snprintfcat(text, maxlen, "ABGR8888");
695 break;
696 case SDL_PIXELFORMAT_BGRA8888:
697 SDL_snprintfcat(text, maxlen, "BGRA8888");
698 break;
699 case SDL_PIXELFORMAT_ARGB2101010:
700 SDL_snprintfcat(text, maxlen, "ARGB2101010");
701 break;
702 case SDL_PIXELFORMAT_YV12:
703 SDL_snprintfcat(text, maxlen, "YV12");
704 break;
705 case SDL_PIXELFORMAT_IYUV:
706 SDL_snprintfcat(text, maxlen, "IYUV");
707 break;
708 case SDL_PIXELFORMAT_YUY2:
709 SDL_snprintfcat(text, maxlen, "YUY2");
710 break;
711 case SDL_PIXELFORMAT_UYVY:
712 SDL_snprintfcat(text, maxlen, "UYVY");
713 break;
714 case SDL_PIXELFORMAT_YVYU:
715 SDL_snprintfcat(text, maxlen, "YVYU");
716 break;
717 case SDL_PIXELFORMAT_NV12:
718 SDL_snprintfcat(text, maxlen, "NV12");
719 break;
720 case SDL_PIXELFORMAT_NV21:
721 SDL_snprintfcat(text, maxlen, "NV21");
722 break;
723 default:
724 SDL_snprintfcat(text, maxlen, "0x%8.8x", format);
725 break;
726 }
727 }
728
729 static void
SDLTest_PrintRenderer(SDL_RendererInfo * info)730 SDLTest_PrintRenderer(SDL_RendererInfo * info)
731 {
732 int i, count;
733 char text[1024];
734
735 SDL_Log(" Renderer %s:\n", info->name);
736
737 SDL_snprintf(text, sizeof(text), " Flags: 0x%8.8X", info->flags);
738 SDL_snprintfcat(text, sizeof(text), " (");
739 count = 0;
740 for (i = 0; i < sizeof(info->flags) * 8; ++i) {
741 Uint32 flag = (1 << i);
742 if (info->flags & flag) {
743 if (count > 0) {
744 SDL_snprintfcat(text, sizeof(text), " | ");
745 }
746 SDLTest_PrintRendererFlag(text, sizeof(text), flag);
747 ++count;
748 }
749 }
750 SDL_snprintfcat(text, sizeof(text), ")");
751 SDL_Log("%s\n", text);
752
753 SDL_snprintf(text, sizeof(text), " Texture formats (%d): ", info->num_texture_formats);
754 for (i = 0; i < (int) info->num_texture_formats; ++i) {
755 if (i > 0) {
756 SDL_snprintfcat(text, sizeof(text), ", ");
757 }
758 SDLTest_PrintPixelFormat(text, sizeof(text), info->texture_formats[i]);
759 }
760 SDL_Log("%s\n", text);
761
762 if (info->max_texture_width || info->max_texture_height) {
763 SDL_Log(" Max Texture Size: %dx%d\n",
764 info->max_texture_width, info->max_texture_height);
765 }
766 }
767
768 static SDL_Surface *
SDLTest_LoadIcon(const char * file)769 SDLTest_LoadIcon(const char *file)
770 {
771 SDL_Surface *icon;
772
773 /* Load the icon surface */
774 icon = SDL_LoadBMP(file);
775 if (icon == NULL) {
776 SDL_Log("Couldn't load %s: %s\n", file, SDL_GetError());
777 return (NULL);
778 }
779
780 if (icon->format->palette) {
781 /* Set the colorkey */
782 SDL_SetColorKey(icon, 1, *((Uint8 *) icon->pixels));
783 }
784
785 return (icon);
786 }
787
788 static SDL_HitTestResult SDLCALL
SDLTest_ExampleHitTestCallback(SDL_Window * win,const SDL_Point * area,void * data)789 SDLTest_ExampleHitTestCallback(SDL_Window *win, const SDL_Point *area, void *data)
790 {
791 int w, h;
792 const int RESIZE_BORDER = 8;
793 const int DRAGGABLE_TITLE = 32;
794
795 /*SDL_Log("Hit test point %d,%d\n", area->x, area->y);*/
796
797 SDL_GetWindowSize(win, &w, &h);
798
799 if (area->x < RESIZE_BORDER) {
800 if (area->y < RESIZE_BORDER) {
801 SDL_Log("SDL_HITTEST_RESIZE_TOPLEFT\n");
802 return SDL_HITTEST_RESIZE_TOPLEFT;
803 } else if (area->y >= (h-RESIZE_BORDER)) {
804 SDL_Log("SDL_HITTEST_RESIZE_BOTTOMLEFT\n");
805 return SDL_HITTEST_RESIZE_BOTTOMLEFT;
806 } else {
807 SDL_Log("SDL_HITTEST_RESIZE_LEFT\n");
808 return SDL_HITTEST_RESIZE_LEFT;
809 }
810 } else if (area->x >= (w-RESIZE_BORDER)) {
811 if (area->y < RESIZE_BORDER) {
812 SDL_Log("SDL_HITTEST_RESIZE_TOPRIGHT\n");
813 return SDL_HITTEST_RESIZE_TOPRIGHT;
814 } else if (area->y >= (h-RESIZE_BORDER)) {
815 SDL_Log("SDL_HITTEST_RESIZE_BOTTOMRIGHT\n");
816 return SDL_HITTEST_RESIZE_BOTTOMRIGHT;
817 } else {
818 SDL_Log("SDL_HITTEST_RESIZE_RIGHT\n");
819 return SDL_HITTEST_RESIZE_RIGHT;
820 }
821 } else if (area->y >= (h-RESIZE_BORDER)) {
822 SDL_Log("SDL_HITTEST_RESIZE_BOTTOM\n");
823 return SDL_HITTEST_RESIZE_BOTTOM;
824 } else if (area->y < RESIZE_BORDER) {
825 SDL_Log("SDL_HITTEST_RESIZE_TOP\n");
826 return SDL_HITTEST_RESIZE_TOP;
827 } else if (area->y < DRAGGABLE_TITLE) {
828 SDL_Log("SDL_HITTEST_DRAGGABLE\n");
829 return SDL_HITTEST_DRAGGABLE;
830 }
831 return SDL_HITTEST_NORMAL;
832 }
833
834 SDL_bool
SDLTest_CommonInit(SDLTest_CommonState * state)835 SDLTest_CommonInit(SDLTest_CommonState * state)
836 {
837 int i, j, m, n, w, h;
838 SDL_DisplayMode fullscreen_mode;
839 char text[1024];
840
841 if (state->flags & SDL_INIT_VIDEO) {
842 if (state->verbose & VERBOSE_VIDEO) {
843 n = SDL_GetNumVideoDrivers();
844 if (n == 0) {
845 SDL_Log("No built-in video drivers\n");
846 } else {
847 SDL_snprintf(text, sizeof(text), "Built-in video drivers:");
848 for (i = 0; i < n; ++i) {
849 if (i > 0) {
850 SDL_snprintfcat(text, sizeof(text), ",");
851 }
852 SDL_snprintfcat(text, sizeof(text), " %s", SDL_GetVideoDriver(i));
853 }
854 SDL_Log("%s\n", text);
855 }
856 }
857 if (SDL_VideoInit(state->videodriver) < 0) {
858 SDL_Log("Couldn't initialize video driver: %s\n",
859 SDL_GetError());
860 return SDL_FALSE;
861 }
862 if (state->verbose & VERBOSE_VIDEO) {
863 SDL_Log("Video driver: %s\n",
864 SDL_GetCurrentVideoDriver());
865 }
866
867 /* Upload GL settings */
868 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, state->gl_red_size);
869 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, state->gl_green_size);
870 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, state->gl_blue_size);
871 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, state->gl_alpha_size);
872 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, state->gl_double_buffer);
873 SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, state->gl_buffer_size);
874 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, state->gl_depth_size);
875 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, state->gl_stencil_size);
876 SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, state->gl_accum_red_size);
877 SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, state->gl_accum_green_size);
878 SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, state->gl_accum_blue_size);
879 SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, state->gl_accum_alpha_size);
880 SDL_GL_SetAttribute(SDL_GL_STEREO, state->gl_stereo);
881 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, state->gl_multisamplebuffers);
882 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, state->gl_multisamplesamples);
883 if (state->gl_accelerated >= 0) {
884 SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL,
885 state->gl_accelerated);
886 }
887 SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, state->gl_retained_backing);
888 if (state->gl_major_version) {
889 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, state->gl_major_version);
890 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, state->gl_minor_version);
891 }
892 if (state->gl_debug) {
893 SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
894 }
895 if (state->gl_profile_mask) {
896 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, state->gl_profile_mask);
897 }
898
899 if (state->verbose & VERBOSE_MODES) {
900 SDL_Rect bounds, usablebounds;
901 float hdpi = 0;
902 float vdpi = 0;
903 SDL_DisplayMode mode;
904 int bpp;
905 Uint32 Rmask, Gmask, Bmask, Amask;
906 #if SDL_VIDEO_DRIVER_WINDOWS
907 int adapterIndex = 0;
908 int outputIndex = 0;
909 #endif
910 n = SDL_GetNumVideoDisplays();
911 SDL_Log("Number of displays: %d\n", n);
912 for (i = 0; i < n; ++i) {
913 SDL_Log("Display %d: %s\n", i, SDL_GetDisplayName(i));
914
915 SDL_zero(bounds);
916 SDL_GetDisplayBounds(i, &bounds);
917
918 SDL_zero(usablebounds);
919 SDL_GetDisplayUsableBounds(i, &usablebounds);
920
921 SDL_GetDisplayDPI(i, NULL, &hdpi, &vdpi);
922
923 SDL_Log("Bounds: %dx%d at %d,%d\n", bounds.w, bounds.h, bounds.x, bounds.y);
924 SDL_Log("Usable bounds: %dx%d at %d,%d\n", usablebounds.w, usablebounds.h, usablebounds.x, usablebounds.y);
925 SDL_Log("DPI: %fx%f\n", hdpi, vdpi);
926
927 SDL_GetDesktopDisplayMode(i, &mode);
928 SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask, &Gmask,
929 &Bmask, &Amask);
930 SDL_Log(" Current mode: %dx%d@%dHz, %d bits-per-pixel (%s)\n",
931 mode.w, mode.h, mode.refresh_rate, bpp,
932 SDL_GetPixelFormatName(mode.format));
933 if (Rmask || Gmask || Bmask) {
934 SDL_Log(" Red Mask = 0x%.8x\n", Rmask);
935 SDL_Log(" Green Mask = 0x%.8x\n", Gmask);
936 SDL_Log(" Blue Mask = 0x%.8x\n", Bmask);
937 if (Amask)
938 SDL_Log(" Alpha Mask = 0x%.8x\n", Amask);
939 }
940
941 /* Print available fullscreen video modes */
942 m = SDL_GetNumDisplayModes(i);
943 if (m == 0) {
944 SDL_Log("No available fullscreen video modes\n");
945 } else {
946 SDL_Log(" Fullscreen video modes:\n");
947 for (j = 0; j < m; ++j) {
948 SDL_GetDisplayMode(i, j, &mode);
949 SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask,
950 &Gmask, &Bmask, &Amask);
951 SDL_Log(" Mode %d: %dx%d@%dHz, %d bits-per-pixel (%s)\n",
952 j, mode.w, mode.h, mode.refresh_rate, bpp,
953 SDL_GetPixelFormatName(mode.format));
954 if (Rmask || Gmask || Bmask) {
955 SDL_Log(" Red Mask = 0x%.8x\n",
956 Rmask);
957 SDL_Log(" Green Mask = 0x%.8x\n",
958 Gmask);
959 SDL_Log(" Blue Mask = 0x%.8x\n",
960 Bmask);
961 if (Amask)
962 SDL_Log(" Alpha Mask = 0x%.8x\n",
963 Amask);
964 }
965 }
966 }
967
968 #if SDL_VIDEO_DRIVER_WINDOWS
969 /* Print the D3D9 adapter index */
970 adapterIndex = SDL_Direct3D9GetAdapterIndex( i );
971 SDL_Log("D3D9 Adapter Index: %d", adapterIndex);
972
973 /* Print the DXGI adapter and output indices */
974 SDL_DXGIGetOutputInfo(i, &adapterIndex, &outputIndex);
975 SDL_Log("DXGI Adapter Index: %d Output Index: %d", adapterIndex, outputIndex);
976 #endif
977 }
978 }
979
980 if (state->verbose & VERBOSE_RENDER) {
981 SDL_RendererInfo info;
982
983 n = SDL_GetNumRenderDrivers();
984 if (n == 0) {
985 SDL_Log("No built-in render drivers\n");
986 } else {
987 SDL_Log("Built-in render drivers:\n");
988 for (i = 0; i < n; ++i) {
989 SDL_GetRenderDriverInfo(i, &info);
990 SDLTest_PrintRenderer(&info);
991 }
992 }
993 }
994
995 SDL_zero(fullscreen_mode);
996 switch (state->depth) {
997 case 8:
998 fullscreen_mode.format = SDL_PIXELFORMAT_INDEX8;
999 break;
1000 case 15:
1001 fullscreen_mode.format = SDL_PIXELFORMAT_RGB555;
1002 break;
1003 case 16:
1004 fullscreen_mode.format = SDL_PIXELFORMAT_RGB565;
1005 break;
1006 case 24:
1007 fullscreen_mode.format = SDL_PIXELFORMAT_RGB24;
1008 break;
1009 default:
1010 fullscreen_mode.format = SDL_PIXELFORMAT_RGB888;
1011 break;
1012 }
1013 fullscreen_mode.refresh_rate = state->refresh_rate;
1014
1015 state->windows =
1016 (SDL_Window **) SDL_calloc(state->num_windows,
1017 sizeof(*state->windows));
1018 state->renderers =
1019 (SDL_Renderer **) SDL_calloc(state->num_windows,
1020 sizeof(*state->renderers));
1021 state->targets =
1022 (SDL_Texture **) SDL_calloc(state->num_windows,
1023 sizeof(*state->targets));
1024 if (!state->windows || !state->renderers) {
1025 SDL_Log("Out of memory!\n");
1026 return SDL_FALSE;
1027 }
1028 for (i = 0; i < state->num_windows; ++i) {
1029 char title[1024];
1030 SDL_Rect r;
1031
1032 r.x = state->window_x;
1033 r.y = state->window_y;
1034 r.w = state->window_w;
1035 r.h = state->window_h;
1036
1037 /* !!! FIXME: hack to make --usable-bounds work for now. */
1038 if ((r.x == -1) && (r.y == -1) && (r.w == -1) && (r.h == -1)) {
1039 SDL_GetDisplayUsableBounds(state->display, &r);
1040 }
1041
1042 if (state->num_windows > 1) {
1043 SDL_snprintf(title, SDL_arraysize(title), "%s %d",
1044 state->window_title, i + 1);
1045 } else {
1046 SDL_strlcpy(title, state->window_title, SDL_arraysize(title));
1047 }
1048 state->windows[i] =
1049 SDL_CreateWindow(title, r.x, r.y, r.w, r.h, state->window_flags);
1050 if (!state->windows[i]) {
1051 SDL_Log("Couldn't create window: %s\n",
1052 SDL_GetError());
1053 return SDL_FALSE;
1054 }
1055 if (state->window_minW || state->window_minH) {
1056 SDL_SetWindowMinimumSize(state->windows[i], state->window_minW, state->window_minH);
1057 }
1058 if (state->window_maxW || state->window_maxH) {
1059 SDL_SetWindowMaximumSize(state->windows[i], state->window_maxW, state->window_maxH);
1060 }
1061 SDL_GetWindowSize(state->windows[i], &w, &h);
1062 if (!(state->window_flags & SDL_WINDOW_RESIZABLE) &&
1063 (w != state->window_w || h != state->window_h)) {
1064 printf("Window requested size %dx%d, got %dx%d\n", state->window_w, state->window_h, w, h);
1065 state->window_w = w;
1066 state->window_h = h;
1067 }
1068 if (SDL_SetWindowDisplayMode(state->windows[i], &fullscreen_mode) < 0) {
1069 SDL_Log("Can't set up fullscreen display mode: %s\n",
1070 SDL_GetError());
1071 return SDL_FALSE;
1072 }
1073
1074 /* Add resize/drag areas for windows that are borderless and resizable */
1075 if ((state->window_flags & (SDL_WINDOW_RESIZABLE|SDL_WINDOW_BORDERLESS)) ==
1076 (SDL_WINDOW_RESIZABLE|SDL_WINDOW_BORDERLESS)) {
1077 SDL_SetWindowHitTest(state->windows[i], SDLTest_ExampleHitTestCallback, NULL);
1078 }
1079
1080 if (state->window_icon) {
1081 SDL_Surface *icon = SDLTest_LoadIcon(state->window_icon);
1082 if (icon) {
1083 SDL_SetWindowIcon(state->windows[i], icon);
1084 SDL_FreeSurface(icon);
1085 }
1086 }
1087
1088 SDL_ShowWindow(state->windows[i]);
1089
1090 if (!state->skip_renderer
1091 && (state->renderdriver
1092 || !(state->window_flags & (SDL_WINDOW_OPENGL | SDL_WINDOW_VULKAN)))) {
1093 m = -1;
1094 if (state->renderdriver) {
1095 SDL_RendererInfo info;
1096 n = SDL_GetNumRenderDrivers();
1097 for (j = 0; j < n; ++j) {
1098 SDL_GetRenderDriverInfo(j, &info);
1099 if (SDL_strcasecmp(info.name, state->renderdriver) ==
1100 0) {
1101 m = j;
1102 break;
1103 }
1104 }
1105 if (m == -1) {
1106 SDL_Log("Couldn't find render driver named %s",
1107 state->renderdriver);
1108 return SDL_FALSE;
1109 }
1110 }
1111 state->renderers[i] = SDL_CreateRenderer(state->windows[i],
1112 m, state->render_flags);
1113 if (!state->renderers[i]) {
1114 SDL_Log("Couldn't create renderer: %s\n",
1115 SDL_GetError());
1116 return SDL_FALSE;
1117 }
1118 if (state->logical_w && state->logical_h) {
1119 SDL_RenderSetLogicalSize(state->renderers[i], state->logical_w, state->logical_h);
1120 } else if (state->scale != 0.) {
1121 SDL_RenderSetScale(state->renderers[i], state->scale, state->scale);
1122 }
1123 if (state->verbose & VERBOSE_RENDER) {
1124 SDL_RendererInfo info;
1125
1126 SDL_Log("Current renderer:\n");
1127 SDL_GetRendererInfo(state->renderers[i], &info);
1128 SDLTest_PrintRenderer(&info);
1129 }
1130 }
1131 }
1132 }
1133
1134 if (state->flags & SDL_INIT_AUDIO) {
1135 if (state->verbose & VERBOSE_AUDIO) {
1136 n = SDL_GetNumAudioDrivers();
1137 if (n == 0) {
1138 SDL_Log("No built-in audio drivers\n");
1139 } else {
1140 SDL_snprintf(text, sizeof(text), "Built-in audio drivers:");
1141 for (i = 0; i < n; ++i) {
1142 if (i > 0) {
1143 SDL_snprintfcat(text, sizeof(text), ",");
1144 }
1145 SDL_snprintfcat(text, sizeof(text), " %s", SDL_GetAudioDriver(i));
1146 }
1147 SDL_Log("%s\n", text);
1148 }
1149 }
1150 if (SDL_AudioInit(state->audiodriver) < 0) {
1151 SDL_Log("Couldn't initialize audio driver: %s\n",
1152 SDL_GetError());
1153 return SDL_FALSE;
1154 }
1155 if (state->verbose & VERBOSE_AUDIO) {
1156 SDL_Log("Audio driver: %s\n",
1157 SDL_GetCurrentAudioDriver());
1158 }
1159
1160 if (SDL_OpenAudio(&state->audiospec, NULL) < 0) {
1161 SDL_Log("Couldn't open audio: %s\n", SDL_GetError());
1162 return SDL_FALSE;
1163 }
1164 }
1165
1166 return SDL_TRUE;
1167 }
1168
1169 static const char *
DisplayOrientationName(int orientation)1170 DisplayOrientationName(int orientation)
1171 {
1172 switch (orientation)
1173 {
1174 #define CASE(X) case SDL_ORIENTATION_##X: return #X
1175 CASE(UNKNOWN);
1176 CASE(LANDSCAPE);
1177 CASE(LANDSCAPE_FLIPPED);
1178 CASE(PORTRAIT);
1179 CASE(PORTRAIT_FLIPPED);
1180 #undef CASE
1181 default: return "???";
1182 }
1183 }
1184
1185 static const char *
ControllerAxisName(const SDL_GameControllerAxis axis)1186 ControllerAxisName(const SDL_GameControllerAxis axis)
1187 {
1188 switch (axis)
1189 {
1190 #define AXIS_CASE(ax) case SDL_CONTROLLER_AXIS_##ax: return #ax
1191 AXIS_CASE(INVALID);
1192 AXIS_CASE(LEFTX);
1193 AXIS_CASE(LEFTY);
1194 AXIS_CASE(RIGHTX);
1195 AXIS_CASE(RIGHTY);
1196 AXIS_CASE(TRIGGERLEFT);
1197 AXIS_CASE(TRIGGERRIGHT);
1198 #undef AXIS_CASE
1199 default: return "???";
1200 }
1201 }
1202
1203 static const char *
ControllerButtonName(const SDL_GameControllerButton button)1204 ControllerButtonName(const SDL_GameControllerButton button)
1205 {
1206 switch (button)
1207 {
1208 #define BUTTON_CASE(btn) case SDL_CONTROLLER_BUTTON_##btn: return #btn
1209 BUTTON_CASE(INVALID);
1210 BUTTON_CASE(A);
1211 BUTTON_CASE(B);
1212 BUTTON_CASE(X);
1213 BUTTON_CASE(Y);
1214 BUTTON_CASE(BACK);
1215 BUTTON_CASE(GUIDE);
1216 BUTTON_CASE(START);
1217 BUTTON_CASE(LEFTSTICK);
1218 BUTTON_CASE(RIGHTSTICK);
1219 BUTTON_CASE(LEFTSHOULDER);
1220 BUTTON_CASE(RIGHTSHOULDER);
1221 BUTTON_CASE(DPAD_UP);
1222 BUTTON_CASE(DPAD_DOWN);
1223 BUTTON_CASE(DPAD_LEFT);
1224 BUTTON_CASE(DPAD_RIGHT);
1225 #undef BUTTON_CASE
1226 default: return "???";
1227 }
1228 }
1229
1230 static void
SDLTest_PrintEvent(SDL_Event * event)1231 SDLTest_PrintEvent(SDL_Event * event)
1232 {
1233 if ((event->type == SDL_MOUSEMOTION) || (event->type == SDL_FINGERMOTION)) {
1234 /* Mouse and finger motion are really spammy */
1235 return;
1236 }
1237
1238 switch (event->type) {
1239 case SDL_DISPLAYEVENT:
1240 switch (event->display.event) {
1241 case SDL_DISPLAYEVENT_ORIENTATION:
1242 SDL_Log("SDL EVENT: Display %d changed orientation to %s", event->display.display, DisplayOrientationName(event->display.data1));
1243 break;
1244 default:
1245 SDL_Log("SDL EVENT: Display %d got unknown event 0x%4.4x",
1246 event->display.display, event->display.event);
1247 break;
1248 }
1249 break;
1250 case SDL_WINDOWEVENT:
1251 switch (event->window.event) {
1252 case SDL_WINDOWEVENT_SHOWN:
1253 SDL_Log("SDL EVENT: Window %d shown", event->window.windowID);
1254 break;
1255 case SDL_WINDOWEVENT_HIDDEN:
1256 SDL_Log("SDL EVENT: Window %d hidden", event->window.windowID);
1257 break;
1258 case SDL_WINDOWEVENT_EXPOSED:
1259 SDL_Log("SDL EVENT: Window %d exposed", event->window.windowID);
1260 break;
1261 case SDL_WINDOWEVENT_MOVED:
1262 SDL_Log("SDL EVENT: Window %d moved to %d,%d",
1263 event->window.windowID, event->window.data1,
1264 event->window.data2);
1265 break;
1266 case SDL_WINDOWEVENT_RESIZED:
1267 SDL_Log("SDL EVENT: Window %d resized to %dx%d",
1268 event->window.windowID, event->window.data1,
1269 event->window.data2);
1270 break;
1271 case SDL_WINDOWEVENT_SIZE_CHANGED:
1272 SDL_Log("SDL EVENT: Window %d changed size to %dx%d",
1273 event->window.windowID, event->window.data1,
1274 event->window.data2);
1275 break;
1276 case SDL_WINDOWEVENT_MINIMIZED:
1277 SDL_Log("SDL EVENT: Window %d minimized", event->window.windowID);
1278 break;
1279 case SDL_WINDOWEVENT_MAXIMIZED:
1280 SDL_Log("SDL EVENT: Window %d maximized", event->window.windowID);
1281 break;
1282 case SDL_WINDOWEVENT_RESTORED:
1283 SDL_Log("SDL EVENT: Window %d restored", event->window.windowID);
1284 break;
1285 case SDL_WINDOWEVENT_ENTER:
1286 SDL_Log("SDL EVENT: Mouse entered window %d",
1287 event->window.windowID);
1288 break;
1289 case SDL_WINDOWEVENT_LEAVE:
1290 SDL_Log("SDL EVENT: Mouse left window %d", event->window.windowID);
1291 break;
1292 case SDL_WINDOWEVENT_FOCUS_GAINED:
1293 SDL_Log("SDL EVENT: Window %d gained keyboard focus",
1294 event->window.windowID);
1295 break;
1296 case SDL_WINDOWEVENT_FOCUS_LOST:
1297 SDL_Log("SDL EVENT: Window %d lost keyboard focus",
1298 event->window.windowID);
1299 break;
1300 case SDL_WINDOWEVENT_CLOSE:
1301 SDL_Log("SDL EVENT: Window %d closed", event->window.windowID);
1302 break;
1303 case SDL_WINDOWEVENT_TAKE_FOCUS:
1304 SDL_Log("SDL EVENT: Window %d take focus", event->window.windowID);
1305 break;
1306 case SDL_WINDOWEVENT_HIT_TEST:
1307 SDL_Log("SDL EVENT: Window %d hit test", event->window.windowID);
1308 break;
1309 default:
1310 SDL_Log("SDL EVENT: Window %d got unknown event 0x%4.4x",
1311 event->window.windowID, event->window.event);
1312 break;
1313 }
1314 break;
1315 case SDL_KEYDOWN:
1316 SDL_Log("SDL EVENT: Keyboard: key pressed in window %d: scancode 0x%08X = %s, keycode 0x%08X = %s",
1317 event->key.windowID,
1318 event->key.keysym.scancode,
1319 SDL_GetScancodeName(event->key.keysym.scancode),
1320 event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym));
1321 break;
1322 case SDL_KEYUP:
1323 SDL_Log("SDL EVENT: Keyboard: key released in window %d: scancode 0x%08X = %s, keycode 0x%08X = %s",
1324 event->key.windowID,
1325 event->key.keysym.scancode,
1326 SDL_GetScancodeName(event->key.keysym.scancode),
1327 event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym));
1328 break;
1329 case SDL_TEXTEDITING:
1330 SDL_Log("SDL EVENT: Keyboard: text editing \"%s\" in window %d",
1331 event->edit.text, event->edit.windowID);
1332 break;
1333 case SDL_TEXTINPUT:
1334 SDL_Log("SDL EVENT: Keyboard: text input \"%s\" in window %d",
1335 event->text.text, event->text.windowID);
1336 break;
1337 case SDL_KEYMAPCHANGED:
1338 SDL_Log("SDL EVENT: Keymap changed");
1339 break;
1340 case SDL_MOUSEMOTION:
1341 SDL_Log("SDL EVENT: Mouse: moved to %d,%d (%d,%d) in window %d",
1342 event->motion.x, event->motion.y,
1343 event->motion.xrel, event->motion.yrel,
1344 event->motion.windowID);
1345 break;
1346 case SDL_MOUSEBUTTONDOWN:
1347 SDL_Log("SDL EVENT: Mouse: button %d pressed at %d,%d with click count %d in window %d",
1348 event->button.button, event->button.x, event->button.y, event->button.clicks,
1349 event->button.windowID);
1350 break;
1351 case SDL_MOUSEBUTTONUP:
1352 SDL_Log("SDL EVENT: Mouse: button %d released at %d,%d with click count %d in window %d",
1353 event->button.button, event->button.x, event->button.y, event->button.clicks,
1354 event->button.windowID);
1355 break;
1356 case SDL_MOUSEWHEEL:
1357 SDL_Log("SDL EVENT: Mouse: wheel scrolled %d in x and %d in y (reversed: %d) in window %d",
1358 event->wheel.x, event->wheel.y, event->wheel.direction, event->wheel.windowID);
1359 break;
1360 case SDL_JOYDEVICEADDED:
1361 SDL_Log("SDL EVENT: Joystick index %d attached",
1362 event->jdevice.which);
1363 break;
1364 case SDL_JOYDEVICEREMOVED:
1365 SDL_Log("SDL EVENT: Joystick %d removed",
1366 event->jdevice.which);
1367 break;
1368 case SDL_JOYBALLMOTION:
1369 SDL_Log("SDL EVENT: Joystick %d: ball %d moved by %d,%d",
1370 event->jball.which, event->jball.ball, event->jball.xrel,
1371 event->jball.yrel);
1372 break;
1373 case SDL_JOYHATMOTION:
1374 {
1375 const char *position = "UNKNOWN";
1376 switch (event->jhat.value) {
1377 case SDL_HAT_CENTERED:
1378 position = "CENTER";
1379 break;
1380 case SDL_HAT_UP:
1381 position = "UP";
1382 break;
1383 case SDL_HAT_RIGHTUP:
1384 position = "RIGHTUP";
1385 break;
1386 case SDL_HAT_RIGHT:
1387 position = "RIGHT";
1388 break;
1389 case SDL_HAT_RIGHTDOWN:
1390 position = "RIGHTDOWN";
1391 break;
1392 case SDL_HAT_DOWN:
1393 position = "DOWN";
1394 break;
1395 case SDL_HAT_LEFTDOWN:
1396 position = "LEFTDOWN";
1397 break;
1398 case SDL_HAT_LEFT:
1399 position = "LEFT";
1400 break;
1401 case SDL_HAT_LEFTUP:
1402 position = "LEFTUP";
1403 break;
1404 }
1405 SDL_Log("SDL EVENT: Joystick %d: hat %d moved to %s", event->jhat.which,
1406 event->jhat.hat, position);
1407 }
1408 break;
1409 case SDL_JOYBUTTONDOWN:
1410 SDL_Log("SDL EVENT: Joystick %d: button %d pressed",
1411 event->jbutton.which, event->jbutton.button);
1412 break;
1413 case SDL_JOYBUTTONUP:
1414 SDL_Log("SDL EVENT: Joystick %d: button %d released",
1415 event->jbutton.which, event->jbutton.button);
1416 break;
1417 case SDL_CONTROLLERDEVICEADDED:
1418 SDL_Log("SDL EVENT: Controller index %d attached",
1419 event->cdevice.which);
1420 break;
1421 case SDL_CONTROLLERDEVICEREMOVED:
1422 SDL_Log("SDL EVENT: Controller %d removed",
1423 event->cdevice.which);
1424 break;
1425 case SDL_CONTROLLERAXISMOTION:
1426 SDL_Log("SDL EVENT: Controller %d axis %d ('%s') value: %d",
1427 event->caxis.which,
1428 event->caxis.axis,
1429 ControllerAxisName((SDL_GameControllerAxis)event->caxis.axis),
1430 event->caxis.value);
1431 break;
1432 case SDL_CONTROLLERBUTTONDOWN:
1433 SDL_Log("SDL EVENT: Controller %d button %d ('%s') down",
1434 event->cbutton.which, event->cbutton.button,
1435 ControllerButtonName((SDL_GameControllerButton)event->cbutton.button));
1436 break;
1437 case SDL_CONTROLLERBUTTONUP:
1438 SDL_Log("SDL EVENT: Controller %d button %d ('%s') up",
1439 event->cbutton.which, event->cbutton.button,
1440 ControllerButtonName((SDL_GameControllerButton)event->cbutton.button));
1441 break;
1442 case SDL_CLIPBOARDUPDATE:
1443 SDL_Log("SDL EVENT: Clipboard updated");
1444 break;
1445
1446 case SDL_FINGERMOTION:
1447 SDL_Log("SDL EVENT: Finger: motion touch=%ld, finger=%ld, x=%f, y=%f, dx=%f, dy=%f, pressure=%f",
1448 (long) event->tfinger.touchId,
1449 (long) event->tfinger.fingerId,
1450 event->tfinger.x, event->tfinger.y,
1451 event->tfinger.dx, event->tfinger.dy, event->tfinger.pressure);
1452 break;
1453 case SDL_FINGERDOWN:
1454 case SDL_FINGERUP:
1455 SDL_Log("SDL EVENT: Finger: %s touch=%ld, finger=%ld, x=%f, y=%f, dx=%f, dy=%f, pressure=%f",
1456 (event->type == SDL_FINGERDOWN) ? "down" : "up",
1457 (long) event->tfinger.touchId,
1458 (long) event->tfinger.fingerId,
1459 event->tfinger.x, event->tfinger.y,
1460 event->tfinger.dx, event->tfinger.dy, event->tfinger.pressure);
1461 break;
1462 case SDL_DOLLARGESTURE:
1463 SDL_Log("SDL_EVENT: Dollar gesture detect: %ld", (long) event->dgesture.gestureId);
1464 break;
1465 case SDL_DOLLARRECORD:
1466 SDL_Log("SDL_EVENT: Dollar gesture record: %ld", (long) event->dgesture.gestureId);
1467 break;
1468 case SDL_MULTIGESTURE:
1469 SDL_Log("SDL_EVENT: Multi gesture fingers: %d", event->mgesture.numFingers);
1470 break;
1471
1472 case SDL_RENDER_DEVICE_RESET:
1473 SDL_Log("SDL EVENT: render device reset");
1474 break;
1475 case SDL_RENDER_TARGETS_RESET:
1476 SDL_Log("SDL EVENT: render targets reset");
1477 break;
1478
1479 case SDL_APP_TERMINATING:
1480 SDL_Log("SDL EVENT: App terminating");
1481 break;
1482 case SDL_APP_LOWMEMORY:
1483 SDL_Log("SDL EVENT: App running low on memory");
1484 break;
1485 case SDL_APP_WILLENTERBACKGROUND:
1486 SDL_Log("SDL EVENT: App will enter the background");
1487 break;
1488 case SDL_APP_DIDENTERBACKGROUND:
1489 SDL_Log("SDL EVENT: App entered the background");
1490 break;
1491 case SDL_APP_WILLENTERFOREGROUND:
1492 SDL_Log("SDL EVENT: App will enter the foreground");
1493 break;
1494 case SDL_APP_DIDENTERFOREGROUND:
1495 SDL_Log("SDL EVENT: App entered the foreground");
1496 break;
1497 case SDL_DROPBEGIN:
1498 SDL_Log("SDL EVENT: Drag and drop beginning");
1499 break;
1500 case SDL_DROPFILE:
1501 SDL_Log("SDL EVENT: Drag and drop file: '%s'", event->drop.file);
1502 break;
1503 case SDL_DROPTEXT:
1504 SDL_Log("SDL EVENT: Drag and drop text: '%s'", event->drop.file);
1505 break;
1506 case SDL_DROPCOMPLETE:
1507 SDL_Log("SDL EVENT: Drag and drop ending");
1508 break;
1509 case SDL_QUIT:
1510 SDL_Log("SDL EVENT: Quit requested");
1511 break;
1512 case SDL_USEREVENT:
1513 SDL_Log("SDL EVENT: User event %d", event->user.code);
1514 break;
1515 default:
1516 SDL_Log("Unknown event 0x%4.4x", event->type);
1517 break;
1518 }
1519 }
1520
1521 static void
SDLTest_ScreenShot(SDL_Renderer * renderer)1522 SDLTest_ScreenShot(SDL_Renderer *renderer)
1523 {
1524 SDL_Rect viewport;
1525 SDL_Surface *surface;
1526
1527 if (!renderer) {
1528 return;
1529 }
1530
1531 SDL_RenderGetViewport(renderer, &viewport);
1532 surface = SDL_CreateRGBSurface(0, viewport.w, viewport.h, 24,
1533 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
1534 0x00FF0000, 0x0000FF00, 0x000000FF,
1535 #else
1536 0x000000FF, 0x0000FF00, 0x00FF0000,
1537 #endif
1538 0x00000000);
1539 if (!surface) {
1540 SDL_Log("Couldn't create surface: %s\n", SDL_GetError());
1541 return;
1542 }
1543
1544 if (SDL_RenderReadPixels(renderer, NULL, surface->format->format,
1545 surface->pixels, surface->pitch) < 0) {
1546 SDL_Log("Couldn't read screen: %s\n", SDL_GetError());
1547 SDL_free(surface);
1548 return;
1549 }
1550
1551 if (SDL_SaveBMP(surface, "screenshot.bmp") < 0) {
1552 SDL_Log("Couldn't save screenshot.bmp: %s\n", SDL_GetError());
1553 SDL_free(surface);
1554 return;
1555 }
1556 }
1557
1558 static void
FullscreenTo(int index,int windowId)1559 FullscreenTo(int index, int windowId)
1560 {
1561 Uint32 flags;
1562 struct SDL_Rect rect = { 0, 0, 0, 0 };
1563 SDL_Window *window = SDL_GetWindowFromID(windowId);
1564 if (!window) {
1565 return;
1566 }
1567
1568 SDL_GetDisplayBounds( index, &rect );
1569
1570 flags = SDL_GetWindowFlags(window);
1571 if (flags & SDL_WINDOW_FULLSCREEN) {
1572 SDL_SetWindowFullscreen( window, SDL_FALSE );
1573 SDL_Delay( 15 );
1574 }
1575
1576 SDL_SetWindowPosition( window, rect.x, rect.y );
1577 SDL_SetWindowFullscreen( window, SDL_TRUE );
1578 }
1579
1580 void
SDLTest_CommonEvent(SDLTest_CommonState * state,SDL_Event * event,int * done)1581 SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done)
1582 {
1583 int i;
1584 static SDL_MouseMotionEvent lastEvent;
1585
1586 if (state->verbose & VERBOSE_EVENT) {
1587 SDLTest_PrintEvent(event);
1588 }
1589
1590 switch (event->type) {
1591 case SDL_WINDOWEVENT:
1592 switch (event->window.event) {
1593 case SDL_WINDOWEVENT_CLOSE:
1594 {
1595 SDL_Window *window = SDL_GetWindowFromID(event->window.windowID);
1596 if (window) {
1597 for (i = 0; i < state->num_windows; ++i) {
1598 if (window == state->windows[i]) {
1599 if (state->targets[i]) {
1600 SDL_DestroyTexture(state->targets[i]);
1601 state->targets[i] = NULL;
1602 }
1603 if (state->renderers[i]) {
1604 SDL_DestroyRenderer(state->renderers[i]);
1605 state->renderers[i] = NULL;
1606 }
1607 SDL_DestroyWindow(state->windows[i]);
1608 state->windows[i] = NULL;
1609 break;
1610 }
1611 }
1612 }
1613 }
1614 break;
1615 }
1616 break;
1617 case SDL_KEYDOWN: {
1618 SDL_bool withControl = !!(event->key.keysym.mod & KMOD_CTRL);
1619 SDL_bool withShift = !!(event->key.keysym.mod & KMOD_SHIFT);
1620 SDL_bool withAlt = !!(event->key.keysym.mod & KMOD_ALT);
1621
1622 switch (event->key.keysym.sym) {
1623 /* Add hotkeys here */
1624 case SDLK_PRINTSCREEN: {
1625 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
1626 if (window) {
1627 for (i = 0; i < state->num_windows; ++i) {
1628 if (window == state->windows[i]) {
1629 SDLTest_ScreenShot(state->renderers[i]);
1630 }
1631 }
1632 }
1633 }
1634 break;
1635 case SDLK_EQUALS:
1636 if (withControl) {
1637 /* Ctrl-+ double the size of the window */
1638 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
1639 if (window) {
1640 int w, h;
1641 SDL_GetWindowSize(window, &w, &h);
1642 SDL_SetWindowSize(window, w*2, h*2);
1643 }
1644 }
1645 break;
1646 case SDLK_MINUS:
1647 if (withControl) {
1648 /* Ctrl-- half the size of the window */
1649 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
1650 if (window) {
1651 int w, h;
1652 SDL_GetWindowSize(window, &w, &h);
1653 SDL_SetWindowSize(window, w/2, h/2);
1654 }
1655 }
1656 break;
1657 case SDLK_UP:
1658 case SDLK_DOWN:
1659 case SDLK_LEFT:
1660 case SDLK_RIGHT:
1661 if (withAlt) {
1662 /* Alt-Up/Down/Left/Right switches between displays */
1663 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
1664 if (window) {
1665 int currentIndex = SDL_GetWindowDisplayIndex(window);
1666 int numDisplays = SDL_GetNumVideoDisplays();
1667
1668 if (currentIndex >= 0 && numDisplays >= 1) {
1669 int dest;
1670 if (event->key.keysym.sym == SDLK_UP || event->key.keysym.sym == SDLK_LEFT) {
1671 dest = (currentIndex + numDisplays - 1) % numDisplays;
1672 } else {
1673 dest = (currentIndex + numDisplays + 1) % numDisplays;
1674 }
1675 SDL_Log("Centering on display %d\n", dest);
1676 SDL_SetWindowPosition(window,
1677 SDL_WINDOWPOS_CENTERED_DISPLAY(dest),
1678 SDL_WINDOWPOS_CENTERED_DISPLAY(dest));
1679 }
1680 }
1681 }
1682 if (withShift) {
1683 /* Shift-Up/Down/Left/Right shift the window by 100px */
1684 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
1685 if (window) {
1686 const int delta = 100;
1687 int x, y;
1688 SDL_GetWindowPosition(window, &x, &y);
1689
1690 if (event->key.keysym.sym == SDLK_UP) y -= delta;
1691 if (event->key.keysym.sym == SDLK_DOWN) y += delta;
1692 if (event->key.keysym.sym == SDLK_LEFT) x -= delta;
1693 if (event->key.keysym.sym == SDLK_RIGHT) x += delta;
1694
1695 SDL_Log("Setting position to (%d, %d)\n", x, y);
1696 SDL_SetWindowPosition(window, x, y);
1697 }
1698 }
1699 break;
1700 case SDLK_o:
1701 if (withControl) {
1702 /* Ctrl-O (or Ctrl-Shift-O) changes window opacity. */
1703 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
1704 if (window) {
1705 float opacity;
1706 if (SDL_GetWindowOpacity(window, &opacity) == 0) {
1707 if (withShift) {
1708 opacity += 0.20f;
1709 } else {
1710 opacity -= 0.20f;
1711 }
1712 SDL_SetWindowOpacity(window, opacity);
1713 }
1714 }
1715 }
1716 break;
1717
1718 case SDLK_c:
1719 if (withControl) {
1720 /* Ctrl-C copy awesome text! */
1721 SDL_SetClipboardText("SDL rocks!\nYou know it!");
1722 printf("Copied text to clipboard\n");
1723 }
1724 if (withAlt) {
1725 /* Alt-C toggle a render clip rectangle */
1726 for (i = 0; i < state->num_windows; ++i) {
1727 int w, h;
1728 if (state->renderers[i]) {
1729 SDL_Rect clip;
1730 SDL_GetWindowSize(state->windows[i], &w, &h);
1731 SDL_RenderGetClipRect(state->renderers[i], &clip);
1732 if (SDL_RectEmpty(&clip)) {
1733 clip.x = w/4;
1734 clip.y = h/4;
1735 clip.w = w/2;
1736 clip.h = h/2;
1737 SDL_RenderSetClipRect(state->renderers[i], &clip);
1738 } else {
1739 SDL_RenderSetClipRect(state->renderers[i], NULL);
1740 }
1741 }
1742 }
1743 }
1744 if (withShift) {
1745 SDL_Window *current_win = SDL_GetKeyboardFocus();
1746 if (current_win) {
1747 const SDL_bool shouldCapture = (SDL_GetWindowFlags(current_win) & SDL_WINDOW_MOUSE_CAPTURE) == 0;
1748 const int rc = SDL_CaptureMouse(shouldCapture);
1749 SDL_Log("%sapturing mouse %s!\n", shouldCapture ? "C" : "Unc", (rc == 0) ? "succeeded" : "failed");
1750 }
1751 }
1752 break;
1753 case SDLK_v:
1754 if (withControl) {
1755 /* Ctrl-V paste awesome text! */
1756 char *text = SDL_GetClipboardText();
1757 if (*text) {
1758 printf("Clipboard: %s\n", text);
1759 } else {
1760 printf("Clipboard is empty\n");
1761 }
1762 SDL_free(text);
1763 }
1764 break;
1765 case SDLK_g:
1766 if (withControl) {
1767 /* Ctrl-G toggle grab */
1768 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
1769 if (window) {
1770 SDL_SetWindowGrab(window, !SDL_GetWindowGrab(window) ? SDL_TRUE : SDL_FALSE);
1771 }
1772 }
1773 break;
1774 case SDLK_m:
1775 if (withControl) {
1776 /* Ctrl-M maximize */
1777 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
1778 if (window) {
1779 Uint32 flags = SDL_GetWindowFlags(window);
1780 if (flags & SDL_WINDOW_MAXIMIZED) {
1781 SDL_RestoreWindow(window);
1782 } else {
1783 SDL_MaximizeWindow(window);
1784 }
1785 }
1786 }
1787 break;
1788 case SDLK_r:
1789 if (withControl) {
1790 /* Ctrl-R toggle mouse relative mode */
1791 SDL_SetRelativeMouseMode(!SDL_GetRelativeMouseMode() ? SDL_TRUE : SDL_FALSE);
1792 }
1793 break;
1794 case SDLK_z:
1795 if (withControl) {
1796 /* Ctrl-Z minimize */
1797 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
1798 if (window) {
1799 SDL_MinimizeWindow(window);
1800 }
1801 }
1802 break;
1803 case SDLK_RETURN:
1804 if (withControl) {
1805 /* Ctrl-Enter toggle fullscreen */
1806 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
1807 if (window) {
1808 Uint32 flags = SDL_GetWindowFlags(window);
1809 if (flags & SDL_WINDOW_FULLSCREEN) {
1810 SDL_SetWindowFullscreen(window, SDL_FALSE);
1811 } else {
1812 SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
1813 }
1814 }
1815 } else if (withAlt) {
1816 /* Alt-Enter toggle fullscreen desktop */
1817 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
1818 if (window) {
1819 Uint32 flags = SDL_GetWindowFlags(window);
1820 if (flags & SDL_WINDOW_FULLSCREEN) {
1821 SDL_SetWindowFullscreen(window, SDL_FALSE);
1822 } else {
1823 SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
1824 }
1825 }
1826 } else if (withShift) {
1827 /* Shift-Enter toggle fullscreen desktop / fullscreen */
1828 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
1829 if (window) {
1830 Uint32 flags = SDL_GetWindowFlags(window);
1831 if ((flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) {
1832 SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
1833 } else {
1834 SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
1835 }
1836 }
1837 }
1838
1839 break;
1840 case SDLK_b:
1841 if (withControl) {
1842 /* Ctrl-B toggle window border */
1843 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
1844 if (window) {
1845 const Uint32 flags = SDL_GetWindowFlags(window);
1846 const SDL_bool b = ((flags & SDL_WINDOW_BORDERLESS) != 0) ? SDL_TRUE : SDL_FALSE;
1847 SDL_SetWindowBordered(window, b);
1848 }
1849 }
1850 break;
1851 case SDLK_a:
1852 if (withControl) {
1853 /* Ctrl-A reports absolute mouse position. */
1854 int x, y;
1855 const Uint32 mask = SDL_GetGlobalMouseState(&x, &y);
1856 SDL_Log("ABSOLUTE MOUSE: (%d, %d)%s%s%s%s%s\n", x, y,
1857 (mask & SDL_BUTTON_LMASK) ? " [LBUTTON]" : "",
1858 (mask & SDL_BUTTON_MMASK) ? " [MBUTTON]" : "",
1859 (mask & SDL_BUTTON_RMASK) ? " [RBUTTON]" : "",
1860 (mask & SDL_BUTTON_X1MASK) ? " [X2BUTTON]" : "",
1861 (mask & SDL_BUTTON_X2MASK) ? " [X2BUTTON]" : "");
1862 }
1863 break;
1864 case SDLK_0:
1865 if (withControl) {
1866 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
1867 SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Test Message", "You're awesome!", window);
1868 }
1869 break;
1870 case SDLK_1:
1871 if (withControl) {
1872 FullscreenTo(0, event->key.windowID);
1873 }
1874 break;
1875 case SDLK_2:
1876 if (withControl) {
1877 FullscreenTo(1, event->key.windowID);
1878 }
1879 break;
1880 case SDLK_ESCAPE:
1881 *done = 1;
1882 break;
1883 case SDLK_SPACE:
1884 {
1885 char message[256];
1886 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
1887
1888 SDL_snprintf(message, sizeof(message), "(%i, %i), rel (%i, %i)\n", lastEvent.x, lastEvent.y, lastEvent.xrel, lastEvent.yrel);
1889 SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Last mouse position", message, window);
1890 break;
1891 }
1892 default:
1893 break;
1894 }
1895 break;
1896 }
1897 case SDL_QUIT:
1898 *done = 1;
1899 break;
1900 case SDL_MOUSEMOTION:
1901 lastEvent = event->motion;
1902 break;
1903
1904 case SDL_DROPFILE:
1905 case SDL_DROPTEXT:
1906 SDL_free(event->drop.file);
1907 break;
1908 }
1909 }
1910
1911 void
SDLTest_CommonQuit(SDLTest_CommonState * state)1912 SDLTest_CommonQuit(SDLTest_CommonState * state)
1913 {
1914 int i;
1915
1916 SDL_free(common_usage_video);
1917 SDL_free(common_usage_audio);
1918 SDL_free(common_usage_videoaudio);
1919 common_usage_video = NULL;
1920 common_usage_audio = NULL;
1921 common_usage_videoaudio = NULL;
1922
1923 SDL_free(state->windows);
1924 if (state->targets) {
1925 for (i = 0; i < state->num_windows; ++i) {
1926 if (state->targets[i]) {
1927 SDL_DestroyTexture(state->targets[i]);
1928 }
1929 }
1930 SDL_free(state->targets);
1931 }
1932 if (state->renderers) {
1933 for (i = 0; i < state->num_windows; ++i) {
1934 if (state->renderers[i]) {
1935 SDL_DestroyRenderer(state->renderers[i]);
1936 }
1937 }
1938 SDL_free(state->renderers);
1939 }
1940 if (state->flags & SDL_INIT_VIDEO) {
1941 SDL_VideoQuit();
1942 }
1943 if (state->flags & SDL_INIT_AUDIO) {
1944 SDL_AudioQuit();
1945 }
1946 SDL_free(state);
1947 SDL_Quit();
1948 SDLTest_LogAllocations();
1949 }
1950
1951 /* vi: set ts=4 sw=4 expandtab: */
1952