Atlas - SDL_test_common.c

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