src/test/SDL_test_common.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 04 Jun 2014 10:56:56 -0700
changeset 8820 0e935d5b193a
parent 8697 abf45e1abfe3
child 8927 be64f5daf64b
permissions -rw-r--r--
Added annotations to help code analysis tools

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