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