src/test/SDL_test_common.c
author Ozkan Sezer <sezeroz@gmail.com>
Mon, 21 Oct 2019 10:20:25 +0300
changeset 13153 74ac66d0e8ca
parent 13125 ddf39a1fc78d
permissions -rw-r--r--
Fix typo with __MIPSEB__ preprocessor check (bug #4836.)

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