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