src/video/SDL_video.c
author Sam Lantinga <slouken@libsdl.org>
Tue, 01 Dec 2009 08:56:12 +0000
changeset 3502 98a819296cdc
parent 3501 467e67d301f3
child 3503 7931094e4c48
permissions -rw-r--r--
Whenever a window becomes fullscreen, shown, unminimized, and has input focus it will change the display to the corresponding fullscreen video mode.
If it loses any of those properties the desktop mode will be restored.
slouken@0
     1
/*
slouken@0
     2
    SDL - Simple DirectMedia Layer
slouken@2859
     3
    Copyright (C) 1997-2009 Sam Lantinga
slouken@0
     4
slouken@0
     5
    This library is free software; you can redistribute it and/or
slouken@1312
     6
    modify it under the terms of the GNU Lesser General Public
slouken@0
     7
    License as published by the Free Software Foundation; either
slouken@1312
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@0
     9
slouken@0
    10
    This library is distributed in the hope that it will be useful,
slouken@0
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@0
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1312
    13
    Lesser General Public License for more details.
slouken@0
    14
slouken@1312
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1312
    16
    License along with this library; if not, write to the Free Software
slouken@1312
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@0
    18
slouken@0
    19
    Sam Lantinga
slouken@252
    20
    slouken@libsdl.org
slouken@0
    21
*/
slouken@1402
    22
#include "SDL_config.h"
slouken@0
    23
slouken@0
    24
/* The high-level video driver subsystem */
slouken@0
    25
slouken@2999
    26
#include "SDL.h"
slouken@2984
    27
#include "SDL_video.h"
slouken@0
    28
#include "SDL_sysvideo.h"
slouken@0
    29
#include "SDL_blit.h"
slouken@0
    30
#include "SDL_pixels_c.h"
slouken@1918
    31
#include "SDL_renderer_gl.h"
hfutrell@2745
    32
#include "SDL_renderer_gles.h"
slouken@1895
    33
#include "SDL_renderer_sw.h"
slouken@1361
    34
#include "../events/SDL_sysevents.h"
slouken@1361
    35
#include "../events/SDL_events_c.h"
slouken@0
    36
hfutrell@2745
    37
#if SDL_VIDEO_OPENGL_ES
hfutrell@2745
    38
#include "SDL_opengles.h"
slouken@2753
    39
#endif /* SDL_VIDEO_OPENGL_ES */
hfutrell@2745
    40
slouken@1926
    41
#if SDL_VIDEO_OPENGL
slouken@1926
    42
#include "SDL_opengl.h"
slouken@1926
    43
slouken@1926
    44
/* On Windows, windows.h defines CreateWindow */
slouken@1926
    45
#ifdef CreateWindow
slouken@1926
    46
#undef CreateWindow
slouken@1926
    47
#endif
slouken@2753
    48
#endif /* SDL_VIDEO_OPENGL */
slouken@1926
    49
slouken@0
    50
/* Available video drivers */
lestat@3166
    51
static VideoBootStrap *bootstrap[] = {
slouken@1931
    52
#if SDL_VIDEO_DRIVER_COCOA
slouken@2753
    53
    &COCOA_bootstrap,
icculus@1133
    54
#endif
slouken@1361
    55
#if SDL_VIDEO_DRIVER_X11
slouken@2753
    56
    &X11_bootstrap,
slouken@0
    57
#endif
slouken@1361
    58
#if SDL_VIDEO_DRIVER_FBCON
slouken@2753
    59
    &FBCON_bootstrap,
slouken@0
    60
#endif
slouken@1361
    61
#if SDL_VIDEO_DRIVER_DIRECTFB
slouken@2753
    62
    &DirectFB_bootstrap,
slouken@167
    63
#endif
slouken@1361
    64
#if SDL_VIDEO_DRIVER_PS2GS
slouken@2753
    65
    &PS2GS_bootstrap,
slouken@0
    66
#endif
slouken@3257
    67
#if SDL_VIDEO_DRIVER_PS3
slouken@3257
    68
    &PS3_bootstrap,
slouken@3257
    69
#endif
slouken@1361
    70
#if SDL_VIDEO_DRIVER_SVGALIB
slouken@2753
    71
    &SVGALIB_bootstrap,
slouken@0
    72
#endif
slouken@1361
    73
#if SDL_VIDEO_DRIVER_GAPI
slouken@2753
    74
    &GAPI_bootstrap,
slouken@1361
    75
#endif
slouken@1895
    76
#if SDL_VIDEO_DRIVER_WIN32
slouken@2753
    77
    &WIN32_bootstrap,
slouken@1361
    78
#endif
slouken@1361
    79
#if SDL_VIDEO_DRIVER_BWINDOW
slouken@2753
    80
    &BWINDOW_bootstrap,
slouken@1361
    81
#endif
slouken@1361
    82
#if SDL_VIDEO_DRIVER_PHOTON
slouken@3083
    83
    &photon_bootstrap,
slouken@3083
    84
#endif
slouken@3083
    85
#if SDL_VIDEO_DRIVER_QNXGF
slouken@3083
    86
    &qnxgf_bootstrap,
slouken@1361
    87
#endif
slouken@1361
    88
#if SDL_VIDEO_DRIVER_EPOC
slouken@2753
    89
    &EPOC_bootstrap,
slouken@1361
    90
#endif
slouken@1361
    91
#if SDL_VIDEO_DRIVER_RISCOS
slouken@2753
    92
    &RISCOS_bootstrap,
slouken@1361
    93
#endif
hfutrell@2743
    94
#if SDL_VIDEO_DRIVER_NDS
slouken@2753
    95
    &NDS_bootstrap,
slouken@2735
    96
#endif
hfutrell@2745
    97
#if SDL_VIDEO_DRIVER_UIKIT
slouken@2753
    98
    &UIKIT_bootstrap,
hfutrell@2745
    99
#endif
slouken@1361
   100
#if SDL_VIDEO_DRIVER_DUMMY
slouken@2753
   101
    &DUMMY_bootstrap,
slouken@610
   102
#endif
slouken@3161
   103
#if SDL_VIDEO_DRIVER_PANDORA
slouken@3161
   104
    &PND_bootstrap,
slouken@3161
   105
#endif
slouken@2753
   106
    NULL
slouken@0
   107
};
slouken@173
   108
slouken@1895
   109
static SDL_VideoDevice *_this = NULL;
slouken@0
   110
slouken@0
   111
/* Various local functions */
slouken@2876
   112
static void SDL_UpdateWindowGrab(SDL_Window * window);
slouken@0
   113
slouken@1895
   114
static int
slouken@1895
   115
cmpmodes(const void *A, const void *B)
slouken@1895
   116
{
slouken@2753
   117
    SDL_DisplayMode a = *(const SDL_DisplayMode *) A;
slouken@2753
   118
    SDL_DisplayMode b = *(const SDL_DisplayMode *) B;
slouken@0
   119
slouken@2753
   120
    if (a.w != b.w) {
slouken@2753
   121
        return b.w - a.w;
slouken@2753
   122
    }
slouken@2753
   123
    if (a.h != b.h) {
slouken@2753
   124
        return b.h - a.h;
slouken@2753
   125
    }
slouken@2753
   126
    if (SDL_BITSPERPIXEL(a.format) != SDL_BITSPERPIXEL(b.format)) {
slouken@2753
   127
        return SDL_BITSPERPIXEL(b.format) - SDL_BITSPERPIXEL(a.format);
slouken@2753
   128
    }
lestat@3178
   129
    if (SDL_PIXELLAYOUT(a.format) != SDL_PIXELLAYOUT(b.format)) {
lestat@3178
   130
        return SDL_PIXELLAYOUT(b.format) - SDL_PIXELLAYOUT(a.format);
lestat@3178
   131
    }
slouken@2753
   132
    if (a.refresh_rate != b.refresh_rate) {
slouken@2753
   133
        return b.refresh_rate - a.refresh_rate;
slouken@2753
   134
    }
slouken@2753
   135
    return 0;
slouken@1895
   136
}
slouken@1895
   137
slouken@1912
   138
static void
slouken@1912
   139
SDL_UninitializedVideo()
slouken@1912
   140
{
slouken@2753
   141
    SDL_SetError("Video subsystem has not been initialized");
slouken@1912
   142
}
slouken@1912
   143
slouken@1895
   144
int
slouken@1895
   145
SDL_GetNumVideoDrivers(void)
slouken@1895
   146
{
slouken@2753
   147
    return SDL_arraysize(bootstrap) - 1;
slouken@1895
   148
}
slouken@1895
   149
slouken@2753
   150
const char *
slouken@1895
   151
SDL_GetVideoDriver(int index)
slouken@1895
   152
{
slouken@2753
   153
    if (index >= 0 && index < SDL_GetNumVideoDrivers()) {
slouken@2753
   154
        return bootstrap[index]->name;
slouken@2753
   155
    }
slouken@2753
   156
    return NULL;
slouken@1895
   157
}
slouken@0
   158
slouken@0
   159
/*
slouken@0
   160
 * Initialize the video and event subsystems -- determine native pixel format
slouken@0
   161
 */
slouken@1895
   162
int
slouken@1895
   163
SDL_VideoInit(const char *driver_name, Uint32 flags)
slouken@0
   164
{
slouken@2753
   165
    SDL_VideoDevice *video;
slouken@2753
   166
    int index;
slouken@2753
   167
    int i;
slouken@0
   168
slouken@2753
   169
    /* Toggle the event thread flags, based on OS requirements */
slouken@0
   170
#if defined(MUST_THREAD_EVENTS)
slouken@2753
   171
    flags |= SDL_INIT_EVENTTHREAD;
slouken@0
   172
#elif defined(CANT_THREAD_EVENTS)
slouken@2753
   173
    if ((flags & SDL_INIT_EVENTTHREAD) == SDL_INIT_EVENTTHREAD) {
slouken@2753
   174
        SDL_SetError("OS doesn't support threaded events");
slouken@2753
   175
        return -1;
slouken@2753
   176
    }
slouken@0
   177
#endif
slouken@0
   178
slouken@2753
   179
    /* Start the event loop */
slouken@2753
   180
    if (SDL_StartEventLoop(flags) < 0) {
slouken@2753
   181
        return -1;
slouken@2753
   182
    }
slouken@2753
   183
    /* Check to make sure we don't overwrite '_this' */
slouken@2753
   184
    if (_this != NULL) {
slouken@2753
   185
        SDL_VideoQuit();
slouken@2753
   186
    }
slouken@2753
   187
    /* Select the proper video driver */
slouken@2753
   188
    index = 0;
slouken@2753
   189
    video = NULL;
slouken@2753
   190
    if (driver_name == NULL) {
slouken@2753
   191
        driver_name = SDL_getenv("SDL_VIDEODRIVER");
slouken@2753
   192
    }
slouken@2753
   193
    if (driver_name != NULL) {
slouken@2753
   194
        for (i = 0; bootstrap[i]; ++i) {
slouken@2753
   195
            if (SDL_strcasecmp(bootstrap[i]->name, driver_name) == 0) {
slouken@3448
   196
                video = bootstrap[i]->create(index);
slouken@2753
   197
                break;
slouken@2753
   198
            }
slouken@2753
   199
        }
slouken@2753
   200
    } else {
slouken@2753
   201
        for (i = 0; bootstrap[i]; ++i) {
slouken@2753
   202
            if (bootstrap[i]->available()) {
slouken@2753
   203
                video = bootstrap[i]->create(index);
slouken@2753
   204
                if (video != NULL) {
slouken@2753
   205
                    break;
slouken@2753
   206
                }
slouken@2753
   207
            }
slouken@2753
   208
        }
slouken@2753
   209
    }
slouken@2753
   210
    if (video == NULL) {
slouken@2753
   211
        if (driver_name) {
slouken@2753
   212
            SDL_SetError("%s not available", driver_name);
slouken@2753
   213
        } else {
slouken@2753
   214
            SDL_SetError("No available video device");
slouken@2753
   215
        }
slouken@2753
   216
        return -1;
slouken@2753
   217
    }
slouken@2753
   218
    _this = video;
slouken@2753
   219
    _this->name = bootstrap[i]->name;
slouken@2753
   220
    _this->next_object_id = 1;
slouken@0
   221
slouken@0
   222
slouken@2753
   223
    /* Set some very sane GL defaults */
slouken@2753
   224
    _this->gl_config.driver_loaded = 0;
slouken@2753
   225
    _this->gl_config.dll_handle = NULL;
slouken@2753
   226
    _this->gl_config.red_size = 3;
slouken@2753
   227
    _this->gl_config.green_size = 3;
slouken@2753
   228
    _this->gl_config.blue_size = 2;
slouken@2753
   229
    _this->gl_config.alpha_size = 0;
slouken@2753
   230
    _this->gl_config.buffer_size = 0;
slouken@2753
   231
    _this->gl_config.depth_size = 16;
slouken@2753
   232
    _this->gl_config.stencil_size = 0;
slouken@2753
   233
    _this->gl_config.double_buffer = 1;
slouken@2753
   234
    _this->gl_config.accum_red_size = 0;
slouken@2753
   235
    _this->gl_config.accum_green_size = 0;
slouken@2753
   236
    _this->gl_config.accum_blue_size = 0;
slouken@2753
   237
    _this->gl_config.accum_alpha_size = 0;
slouken@2753
   238
    _this->gl_config.stereo = 0;
slouken@2753
   239
    _this->gl_config.multisamplebuffers = 0;
slouken@2753
   240
    _this->gl_config.multisamplesamples = 0;
slouken@2753
   241
    _this->gl_config.retained_backing = 1;
slouken@2753
   242
    _this->gl_config.accelerated = -1;  /* not known, don't set */
slouken@3100
   243
    _this->gl_config.major_version = 2;
slouken@3100
   244
    _this->gl_config.minor_version = 1;
slouken@0
   245
slouken@2753
   246
    /* Initialize the video subsystem */
slouken@2753
   247
    if (_this->VideoInit(_this) < 0) {
slouken@2753
   248
        SDL_VideoQuit();
slouken@2753
   249
        return -1;
slouken@2753
   250
    }
slouken@2753
   251
    /* Make sure some displays were added */
slouken@2753
   252
    if (_this->num_displays == 0) {
slouken@2753
   253
        SDL_SetError("The video driver did not add any displays");
slouken@2753
   254
        SDL_VideoQuit();
slouken@2753
   255
        return (-1);
slouken@2753
   256
    }
slouken@2753
   257
    /* The software renderer is always available */
slouken@2753
   258
    for (i = 0; i < _this->num_displays; ++i) {
slouken@3500
   259
        SDL_VideoDisplay *display = &_this->displays[i];
slouken@3450
   260
        if (_this->GL_CreateContext) {
hfutrell@2744
   261
#if SDL_VIDEO_RENDER_OGL
slouken@3500
   262
            SDL_AddRenderDriver(display, &GL_RenderDriver);
hfutrell@2744
   263
#endif
hfutrell@2745
   264
#if SDL_VIDEO_RENDER_OGL_ES
slouken@3500
   265
            SDL_AddRenderDriver(display, &GL_ES_RenderDriver);
hfutrell@2745
   266
#endif
slouken@3450
   267
        }
slouken@3500
   268
        if (display->num_render_drivers > 0) {
slouken@3500
   269
            SDL_AddRenderDriver(display, &SW_RenderDriver);
slouken@2753
   270
        }
slouken@2753
   271
    }
slouken@0
   272
slouken@2753
   273
    /* We're ready to go! */
slouken@2753
   274
    return 0;
slouken@0
   275
}
slouken@0
   276
slouken@2753
   277
const char *
slouken@1895
   278
SDL_GetCurrentVideoDriver()
slouken@0
   279
{
slouken@2753
   280
    if (!_this) {
slouken@2753
   281
        SDL_UninitializedVideo();
slouken@2753
   282
        return NULL;
slouken@2753
   283
    }
slouken@2753
   284
    return _this->name;
slouken@0
   285
}
slouken@0
   286
slouken@1895
   287
SDL_VideoDevice *
slouken@1895
   288
SDL_GetVideoDevice()
slouken@0
   289
{
slouken@2753
   290
    return _this;
slouken@0
   291
}
slouken@0
   292
slouken@1895
   293
int
slouken@1895
   294
SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode)
slouken@0
   295
{
slouken@2753
   296
    SDL_VideoDisplay display;
slouken@0
   297
slouken@2753
   298
    SDL_zero(display);
slouken@2753
   299
    if (desktop_mode) {
slouken@2753
   300
        display.desktop_mode = *desktop_mode;
slouken@2753
   301
    }
slouken@2753
   302
    display.current_mode = display.desktop_mode;
slouken@1895
   303
slouken@2753
   304
    return SDL_AddVideoDisplay(&display);
slouken@0
   305
}
slouken@0
   306
slouken@1895
   307
int
slouken@1895
   308
SDL_AddVideoDisplay(const SDL_VideoDisplay * display)
slouken@0
   309
{
slouken@2753
   310
    SDL_VideoDisplay *displays;
slouken@2753
   311
    int index = -1;
slouken@0
   312
slouken@2753
   313
    displays =
slouken@2753
   314
        SDL_realloc(_this->displays,
slouken@2753
   315
                    (_this->num_displays + 1) * sizeof(*displays));
slouken@2753
   316
    if (displays) {
slouken@2753
   317
        index = _this->num_displays++;
slouken@2753
   318
        displays[index] = *display;
slouken@2753
   319
        displays[index].device = _this;
slouken@2753
   320
        _this->displays = displays;
slouken@2753
   321
    } else {
slouken@2753
   322
        SDL_OutOfMemory();
slouken@2753
   323
    }
slouken@2753
   324
    return index;
slouken@0
   325
}
slouken@0
   326
slouken@1895
   327
int
slouken@1895
   328
SDL_GetNumVideoDisplays(void)
slouken@0
   329
{
slouken@2753
   330
    if (!_this) {
slouken@2753
   331
        SDL_UninitializedVideo();
slouken@2753
   332
        return 0;
slouken@2753
   333
    }
slouken@2753
   334
    return _this->num_displays;
slouken@0
   335
}
slouken@0
   336
slouken@1895
   337
int
slouken@1895
   338
SDL_SelectVideoDisplay(int index)
slouken@0
   339
{
slouken@2753
   340
    if (!_this) {
slouken@2753
   341
        SDL_UninitializedVideo();
slouken@2753
   342
        return (-1);
slouken@2753
   343
    }
slouken@2753
   344
    if (index < 0 || index >= _this->num_displays) {
slouken@2753
   345
        SDL_SetError("index must be in the range 0 - %d",
slouken@2753
   346
                     _this->num_displays - 1);
slouken@2753
   347
        return -1;
slouken@2753
   348
    }
slouken@2753
   349
    _this->current_display = index;
slouken@2753
   350
    return 0;
slouken@1963
   351
}
slouken@1963
   352
slouken@1963
   353
int
slouken@1963
   354
SDL_GetCurrentVideoDisplay(void)
slouken@1963
   355
{
slouken@2753
   356
    if (!_this) {
slouken@2753
   357
        SDL_UninitializedVideo();
slouken@2753
   358
        return (-1);
slouken@2753
   359
    }
slouken@2753
   360
    return _this->current_display;
slouken@0
   361
}
slouken@0
   362
slouken@1895
   363
SDL_bool
slouken@3500
   364
SDL_AddDisplayMode(SDL_VideoDisplay * display,  const SDL_DisplayMode * mode)
slouken@0
   365
{
slouken@2753
   366
    SDL_DisplayMode *modes;
slouken@2753
   367
    int i, nmodes;
slouken@0
   368
slouken@2753
   369
    /* Make sure we don't already have the mode in the list */
slouken@2753
   370
    modes = display->display_modes;
slouken@2753
   371
    nmodes = display->num_display_modes;
slouken@2753
   372
    for (i = nmodes; i--;) {
slouken@2753
   373
        if (SDL_memcmp(mode, &modes[i], sizeof(*mode)) == 0) {
slouken@2753
   374
            return SDL_FALSE;
slouken@2753
   375
        }
slouken@2753
   376
    }
slouken@1895
   377
slouken@2753
   378
    /* Go ahead and add the new mode */
slouken@2753
   379
    if (nmodes == display->max_display_modes) {
slouken@2753
   380
        modes =
slouken@2753
   381
            SDL_realloc(modes,
slouken@2753
   382
                        (display->max_display_modes + 32) * sizeof(*modes));
slouken@2753
   383
        if (!modes) {
slouken@2753
   384
            return SDL_FALSE;
slouken@2753
   385
        }
slouken@2753
   386
        display->display_modes = modes;
slouken@2753
   387
        display->max_display_modes += 32;
slouken@2753
   388
    }
slouken@2753
   389
    modes[nmodes] = *mode;
slouken@2753
   390
    display->num_display_modes++;
slouken@1895
   391
lestat@3178
   392
    /* Re-sort video modes */
lestat@3178
   393
    SDL_qsort(display->display_modes, display->num_display_modes,
slouken@3186
   394
              sizeof(SDL_DisplayMode), cmpmodes);
lestat@3178
   395
slouken@2753
   396
    return SDL_TRUE;
slouken@0
   397
}
slouken@0
   398
slouken@1895
   399
int
slouken@3500
   400
SDL_GetNumDisplayModesForDisplay(SDL_VideoDisplay * display)
slouken@3500
   401
{
slouken@3500
   402
    if (!display->num_display_modes && _this->GetDisplayModes) {
slouken@3500
   403
        _this->GetDisplayModes(_this, display);
slouken@3500
   404
        SDL_qsort(display->display_modes, display->num_display_modes,
slouken@3500
   405
                  sizeof(SDL_DisplayMode), cmpmodes);
slouken@3500
   406
    }
slouken@3500
   407
    return display->num_display_modes;
slouken@3500
   408
}
slouken@3500
   409
slouken@3500
   410
int
slouken@1895
   411
SDL_GetNumDisplayModes()
slouken@0
   412
{
slouken@2753
   413
    if (_this) {
slouken@3500
   414
        return SDL_GetNumDisplayModesForDisplay(&SDL_CurrentDisplay);
slouken@3500
   415
    }
slouken@3500
   416
    return 0;
slouken@3500
   417
}
slouken@3500
   418
slouken@3500
   419
int
slouken@3500
   420
SDL_GetDisplayModeForDisplay(SDL_VideoDisplay * display, int index, SDL_DisplayMode * mode)
slouken@3500
   421
{
slouken@3500
   422
    if (index < 0 || index >= SDL_GetNumDisplayModesForDisplay(display)) {
slouken@3500
   423
        SDL_SetError("index must be in the range of 0 - %d",
slouken@3500
   424
                     SDL_GetNumDisplayModesForDisplay(display) - 1);
slouken@3500
   425
        return -1;
slouken@3500
   426
    }
slouken@3500
   427
    if (mode) {
slouken@3500
   428
        *mode = display->display_modes[index];
slouken@2753
   429
    }
slouken@2753
   430
    return 0;
slouken@0
   431
}
slouken@0
   432
slouken@1967
   433
int
slouken@1967
   434
SDL_GetDisplayMode(int index, SDL_DisplayMode * mode)
slouken@0
   435
{
slouken@3500
   436
    return SDL_GetDisplayModeForDisplay(&SDL_CurrentDisplay, index, mode);
slouken@3500
   437
}
slouken@3500
   438
slouken@3500
   439
int
slouken@3500
   440
SDL_GetDesktopDisplayModeForDisplay(SDL_VideoDisplay * display, SDL_DisplayMode * mode)
slouken@3500
   441
{
slouken@2753
   442
    if (mode) {
slouken@3500
   443
        *mode = display->desktop_mode;
slouken@2753
   444
    }
slouken@2753
   445
    return 0;
slouken@0
   446
}
slouken@0
   447
slouken@1967
   448
int
slouken@1967
   449
SDL_GetDesktopDisplayMode(SDL_DisplayMode * mode)
slouken@0
   450
{
slouken@2753
   451
    if (!_this) {
slouken@2753
   452
        SDL_UninitializedVideo();
slouken@2753
   453
        return -1;
slouken@2753
   454
    }
slouken@3500
   455
    return SDL_GetDesktopDisplayModeForDisplay(&SDL_CurrentDisplay, mode);
slouken@3500
   456
}
slouken@3500
   457
slouken@3500
   458
int
slouken@3500
   459
SDL_GetCurrentDisplayModeForDisplay(SDL_VideoDisplay * display, SDL_DisplayMode * mode)
slouken@3500
   460
{
slouken@2753
   461
    if (mode) {
slouken@3500
   462
        *mode = display->current_mode;
slouken@2753
   463
    }
slouken@2753
   464
    return 0;
slouken@0
   465
}
slouken@0
   466
slouken@1967
   467
int
slouken@1967
   468
SDL_GetCurrentDisplayMode(SDL_DisplayMode * mode)
slouken@0
   469
{
slouken@2753
   470
    if (!_this) {
slouken@2753
   471
        SDL_UninitializedVideo();
slouken@2753
   472
        return -1;
slouken@2753
   473
    }
slouken@3500
   474
    return SDL_GetCurrentDisplayModeForDisplay(&SDL_CurrentDisplay, mode);
slouken@0
   475
}
slouken@0
   476
slouken@1895
   477
SDL_DisplayMode *
slouken@3500
   478
SDL_GetClosestDisplayModeForDisplay(SDL_VideoDisplay * display,
slouken@3500
   479
                                    const SDL_DisplayMode * mode,
slouken@3500
   480
                                    SDL_DisplayMode * closest)
slouken@0
   481
{
slouken@2753
   482
    Uint32 target_format;
slouken@2753
   483
    int target_refresh_rate;
slouken@2753
   484
    int i;
slouken@2753
   485
    SDL_DisplayMode *current, *match;
slouken@0
   486
slouken@3500
   487
    if (!mode || !closest) {
slouken@3500
   488
        SDL_SetError("Missing desired mode or closest mode parameter");
slouken@2753
   489
        return NULL;
slouken@2753
   490
    }
slouken@3500
   491
slouken@2753
   492
    /* Default to the desktop format */
slouken@2753
   493
    if (mode->format) {
slouken@2753
   494
        target_format = mode->format;
slouken@2753
   495
    } else {
slouken@3500
   496
        target_format = display->desktop_mode.format;
slouken@2753
   497
    }
slouken@0
   498
slouken@2753
   499
    /* Default to the desktop refresh rate */
slouken@2753
   500
    if (mode->refresh_rate) {
slouken@2753
   501
        target_refresh_rate = mode->refresh_rate;
slouken@2753
   502
    } else {
slouken@3500
   503
        target_refresh_rate = display->desktop_mode.refresh_rate;
slouken@2753
   504
    }
slouken@0
   505
slouken@2753
   506
    match = NULL;
slouken@3500
   507
    for (i = 0; i < SDL_GetNumDisplayModesForDisplay(display); ++i) {
slouken@3500
   508
        current = &display->display_modes[i];
slouken@0
   509
slouken@2789
   510
        if (current->w && (current->w < mode->w)) {
slouken@2753
   511
            /* Out of sorted modes large enough here */
slouken@2753
   512
            break;
slouken@2753
   513
        }
slouken@2789
   514
        if (current->h && (current->h < mode->h)) {
slouken@2789
   515
            if (current->w && (current->w == mode->w)) {
slouken@2789
   516
                /* Out of sorted modes large enough here */
slouken@2789
   517
                break;
slouken@2789
   518
            }
slouken@2789
   519
            /* Wider, but not tall enough, due to a different
slouken@2789
   520
               aspect ratio. This mode must be skipped, but closer
slouken@2789
   521
               modes may still follow. */
slouken@2789
   522
            continue;
slouken@2789
   523
        }
slouken@2753
   524
        if (!match || current->w < match->w || current->h < match->h) {
slouken@2753
   525
            match = current;
slouken@2753
   526
            continue;
slouken@2753
   527
        }
slouken@2753
   528
        if (current->format != match->format) {
slouken@2753
   529
            /* Sorted highest depth to lowest */
slouken@2753
   530
            if (current->format == target_format ||
slouken@2753
   531
                (SDL_BITSPERPIXEL(current->format) >=
slouken@2753
   532
                 SDL_BITSPERPIXEL(target_format)
slouken@2753
   533
                 && SDL_PIXELTYPE(current->format) ==
slouken@2753
   534
                 SDL_PIXELTYPE(target_format))) {
slouken@2753
   535
                match = current;
slouken@2753
   536
            }
slouken@2753
   537
            continue;
slouken@2753
   538
        }
slouken@2753
   539
        if (current->refresh_rate != match->refresh_rate) {
slouken@2753
   540
            /* Sorted highest refresh to lowest */
slouken@2753
   541
            if (current->refresh_rate >= target_refresh_rate) {
slouken@2753
   542
                match = current;
slouken@2753
   543
            }
slouken@2753
   544
        }
slouken@2753
   545
    }
slouken@2753
   546
    if (match) {
slouken@2753
   547
        if (match->format) {
slouken@2753
   548
            closest->format = match->format;
slouken@2753
   549
        } else {
slouken@2753
   550
            closest->format = mode->format;
slouken@2753
   551
        }
slouken@2753
   552
        if (match->w && match->h) {
slouken@2753
   553
            closest->w = match->w;
slouken@2753
   554
            closest->h = match->h;
slouken@2753
   555
        } else {
slouken@2753
   556
            closest->w = mode->w;
slouken@2753
   557
            closest->h = mode->h;
slouken@2753
   558
        }
slouken@2753
   559
        if (match->refresh_rate) {
slouken@2753
   560
            closest->refresh_rate = match->refresh_rate;
slouken@2753
   561
        } else {
slouken@2753
   562
            closest->refresh_rate = mode->refresh_rate;
slouken@2753
   563
        }
slouken@2753
   564
        closest->driverdata = match->driverdata;
slouken@1895
   565
slouken@2753
   566
        /*
slouken@2753
   567
         * Pick some reasonable defaults if the app and driver don't
slouken@2753
   568
         * care
slouken@2753
   569
         */
slouken@2753
   570
        if (!closest->format) {
slouken@2753
   571
            closest->format = SDL_PIXELFORMAT_RGB888;
slouken@2753
   572
        }
slouken@2753
   573
        if (!closest->w) {
slouken@2753
   574
            closest->w = 640;
slouken@2753
   575
        }
slouken@2753
   576
        if (!closest->h) {
slouken@2753
   577
            closest->h = 480;
slouken@2753
   578
        }
slouken@2753
   579
        return closest;
slouken@2753
   580
    }
slouken@2753
   581
    return NULL;
slouken@0
   582
}
slouken@0
   583
slouken@3500
   584
SDL_DisplayMode *
slouken@3500
   585
SDL_GetClosestDisplayMode(const SDL_DisplayMode * mode,
slouken@3500
   586
                          SDL_DisplayMode * closest)
slouken@3500
   587
{
slouken@3500
   588
    if (!_this) {
slouken@3500
   589
        SDL_UninitializedVideo();
slouken@3500
   590
        return NULL;
slouken@3500
   591
    }
slouken@3500
   592
    return SDL_GetClosestDisplayModeForDisplay(&SDL_CurrentDisplay, mode, closest);
slouken@3500
   593
}
slouken@3500
   594
slouken@1895
   595
int
slouken@3500
   596
SDL_SetDisplayModeForDisplay(SDL_VideoDisplay * display, const SDL_DisplayMode * mode)
slouken@0
   597
{
slouken@2753
   598
    SDL_DisplayMode display_mode;
slouken@2753
   599
    SDL_DisplayMode current_mode;
slouken@2753
   600
    int i, ncolors;
slouken@0
   601
slouken@3502
   602
    if (mode) {
slouken@3502
   603
        display_mode = *mode;
slouken@3502
   604
slouken@3502
   605
        /* Default to the current mode */
slouken@3502
   606
        if (!display_mode.format) {
slouken@3502
   607
            display_mode.format = display->current_mode.format;
slouken@3502
   608
        }
slouken@3502
   609
        if (!display_mode.w) {
slouken@3502
   610
            display_mode.w = display->current_mode.w;
slouken@3502
   611
        }
slouken@3502
   612
        if (!display_mode.h) {
slouken@3502
   613
            display_mode.h = display->current_mode.h;
slouken@3502
   614
        }
slouken@3502
   615
        if (!display_mode.refresh_rate) {
slouken@3502
   616
            display_mode.refresh_rate = display->current_mode.refresh_rate;
slouken@3502
   617
        }
slouken@3502
   618
slouken@3502
   619
        /* Get a good video mode, the closest one possible */
slouken@3502
   620
        if (!SDL_GetClosestDisplayModeForDisplay(display, &display_mode, &display_mode)) {
slouken@3502
   621
            SDL_SetError("No video mode large enough for %dx%d",
slouken@3502
   622
                         display_mode.w, display_mode.h);
slouken@3502
   623
            return -1;
slouken@3502
   624
        }
slouken@3502
   625
    } else {
slouken@3502
   626
        display_mode = display->desktop_mode;
slouken@2753
   627
    }
slouken@3500
   628
slouken@2753
   629
    /* See if there's anything left to do */
slouken@3500
   630
    SDL_GetCurrentDisplayModeForDisplay(display, &current_mode);
slouken@2753
   631
    if (SDL_memcmp(&display_mode, &current_mode, sizeof(display_mode)) == 0) {
slouken@2753
   632
        return 0;
slouken@2753
   633
    }
slouken@3500
   634
slouken@2753
   635
    /* Actually change the display mode */
slouken@3500
   636
    if (_this->SetDisplayMode(_this, display, &display_mode) < 0) {
slouken@2753
   637
        return -1;
slouken@2753
   638
    }
slouken@2753
   639
    display->current_mode = display_mode;
slouken@1895
   640
slouken@2753
   641
    /* Set up a palette, if necessary */
slouken@2753
   642
    if (SDL_ISPIXELFORMAT_INDEXED(display_mode.format)) {
slouken@2753
   643
        ncolors = (1 << SDL_BITSPERPIXEL(display_mode.format));
slouken@2753
   644
    } else {
slouken@2753
   645
        ncolors = 0;
slouken@2753
   646
    }
slouken@2753
   647
    if ((!ncolors && display->palette) || (ncolors && !display->palette)
slouken@2753
   648
        || (ncolors && ncolors != display->palette->ncolors)) {
slouken@2753
   649
        if (display->palette) {
slouken@2753
   650
            SDL_FreePalette(display->palette);
slouken@2753
   651
            display->palette = NULL;
slouken@2753
   652
        }
slouken@2753
   653
        if (ncolors) {
slouken@2753
   654
            display->palette = SDL_AllocPalette(ncolors);
slouken@2753
   655
            if (!display->palette) {
slouken@2753
   656
                return -1;
slouken@2753
   657
            }
slouken@2753
   658
            SDL_DitherColors(display->palette->colors,
slouken@2753
   659
                             SDL_BITSPERPIXEL(display_mode.format));
slouken@2753
   660
        }
slouken@2753
   661
    }
slouken@1895
   662
slouken@2753
   663
    return 0;
slouken@0
   664
}
slouken@0
   665
slouken@1895
   666
int
slouken@3500
   667
SDL_SetDisplayMode(const SDL_DisplayMode * mode)
slouken@0
   668
{
slouken@2753
   669
    if (!_this) {
slouken@2753
   670
        SDL_UninitializedVideo();
slouken@2753
   671
        return -1;
slouken@2753
   672
    }
slouken@3500
   673
    return SDL_SetDisplayModeForDisplay(&SDL_CurrentDisplay, mode);
slouken@3500
   674
}
slouken@3500
   675
slouken@3500
   676
int
slouken@3500
   677
SDL_SetWindowDisplayMode(SDL_WindowID windowID, const SDL_DisplayMode * mode)
slouken@3500
   678
{
slouken@3500
   679
    SDL_Window *window = SDL_GetWindowFromID(windowID);
slouken@3500
   680
slouken@3500
   681
    if (!window) {
slouken@3500
   682
        return -1;
slouken@3500
   683
    }
slouken@3500
   684
slouken@2753
   685
    if (mode) {
slouken@3500
   686
        window->fullscreen_mode = *mode;
slouken@3500
   687
    } else {
slouken@3500
   688
        SDL_zero(window->fullscreen_mode);
slouken@3500
   689
    }
slouken@3500
   690
}
slouken@3500
   691
slouken@3500
   692
int
slouken@3500
   693
SDL_GetWindowDisplayMode(SDL_WindowID windowID, SDL_DisplayMode * mode)
slouken@3500
   694
{
slouken@3500
   695
    SDL_Window *window = SDL_GetWindowFromID(windowID);
slouken@3500
   696
    SDL_DisplayMode fullscreen_mode;
slouken@3500
   697
slouken@3500
   698
    if (!window) {
slouken@3500
   699
        return -1;
slouken@3500
   700
    }
slouken@3500
   701
slouken@3500
   702
    fullscreen_mode = window->fullscreen_mode;
slouken@3500
   703
    if (!fullscreen_mode.w) {
slouken@3500
   704
        fullscreen_mode.w = window->w;
slouken@3500
   705
    }
slouken@3500
   706
    if (!fullscreen_mode.h) {
slouken@3500
   707
        fullscreen_mode.h = window->h;
slouken@3500
   708
    }
slouken@3500
   709
slouken@3500
   710
    if (!SDL_GetClosestDisplayModeForDisplay(SDL_GetDisplayFromWindow(window),
slouken@3500
   711
                                             &fullscreen_mode,
slouken@3500
   712
                                             &fullscreen_mode)) {
slouken@3500
   713
        SDL_SetError("Couldn't find display mode match");
slouken@3500
   714
        return -1;
slouken@3500
   715
    }
slouken@3500
   716
slouken@3500
   717
    if (mode) {
slouken@3500
   718
        *mode = fullscreen_mode;
slouken@2753
   719
    }
slouken@2753
   720
    return 0;
slouken@0
   721
}
slouken@0
   722
slouken@3502
   723
static void
slouken@3502
   724
SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool attempt)
slouken@3502
   725
{
slouken@3502
   726
    SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
slouken@3502
   727
    int i;
slouken@3502
   728
slouken@3502
   729
    /* See if we're already processing a window */
slouken@3502
   730
    if (display->updating_fullscreen) {
slouken@3502
   731
        return;
slouken@3502
   732
    }
slouken@3502
   733
slouken@3502
   734
    display->updating_fullscreen = SDL_TRUE;
slouken@3502
   735
slouken@3502
   736
    /* See if we even want to do anything here */
slouken@3502
   737
    if ((window->flags & SDL_WINDOW_FULLSCREEN) &&
slouken@3502
   738
        (window->flags & SDL_WINDOW_SHOWN)) {
slouken@3502
   739
        if (attempt) {
slouken@3502
   740
            /* We just gained some state, try to gain all states */
slouken@3502
   741
            if (window->flags & SDL_WINDOW_MINIMIZED) {
slouken@3502
   742
                SDL_RestoreWindow(window->id);
slouken@3502
   743
            } else {
slouken@3502
   744
                SDL_RaiseWindow(window->id);
slouken@3502
   745
            }
slouken@3502
   746
        } else {
slouken@3502
   747
            /* We just lost some state, try to release all states */
slouken@3502
   748
            SDL_MinimizeWindow(window->id);
slouken@3502
   749
        }
slouken@3502
   750
    }
slouken@3502
   751
slouken@3502
   752
    if (FULLSCREEN_VISIBLE(window)) {
slouken@3502
   753
        /* Hide any other fullscreen windows */
slouken@3502
   754
        for (i = 0; i < display->num_windows; ++i) {
slouken@3502
   755
            SDL_Window *other = &display->windows[i];
slouken@3502
   756
            if (other != window && FULLSCREEN_VISIBLE(other)) {
slouken@3502
   757
                SDL_MinimizeWindow(other->id);
slouken@3502
   758
            }
slouken@3502
   759
        }
slouken@3502
   760
    }
slouken@3502
   761
slouken@3502
   762
    display->updating_fullscreen = SDL_FALSE;
slouken@3502
   763
slouken@3502
   764
    /* See if there are any fullscreen windows */
slouken@3502
   765
    for (i = 0; i < display->num_windows; ++i) {
slouken@3502
   766
        window = &display->windows[i];
slouken@3502
   767
        if (FULLSCREEN_VISIBLE(window)) {
slouken@3502
   768
            SDL_DisplayMode fullscreen_mode;
slouken@3502
   769
            if (SDL_GetWindowDisplayMode(window->id, &fullscreen_mode) == 0) {
slouken@3502
   770
                SDL_SetDisplayModeForDisplay(display, &fullscreen_mode);
slouken@3502
   771
                return;
slouken@3502
   772
            }
slouken@3502
   773
        }
slouken@3502
   774
    }
slouken@3502
   775
slouken@3502
   776
    /* Nope, restore the desktop mode */
slouken@3502
   777
    SDL_SetDisplayModeForDisplay(display, NULL);
slouken@3502
   778
}
slouken@3502
   779
slouken@1895
   780
int
slouken@3501
   781
SDL_SetPaletteForDisplay(SDL_VideoDisplay * display, const SDL_Color * colors, int firstcolor, int ncolors)
slouken@3500
   782
{
slouken@3500
   783
    SDL_Palette *palette;
slouken@3500
   784
    int status = 0;
slouken@3500
   785
slouken@3500
   786
    palette = display->palette;
slouken@3500
   787
    if (!palette) {
slouken@3500
   788
        SDL_SetError("Display mode does not have a palette");
slouken@3500
   789
        return -1;
slouken@3500
   790
    }
slouken@3500
   791
    status = SDL_SetPaletteColors(palette, colors, firstcolor, ncolors);
slouken@3500
   792
slouken@3500
   793
    if (_this->SetDisplayPalette) {
slouken@3500
   794
        if (_this->SetDisplayPalette(_this, display, palette) < 0) {
slouken@3500
   795
            status = -1;
slouken@3500
   796
        }
slouken@3500
   797
    }
slouken@3500
   798
    return status;
slouken@3500
   799
}
slouken@3500
   800
slouken@3500
   801
int
slouken@1895
   802
SDL_SetDisplayPalette(const SDL_Color * colors, int firstcolor, int ncolors)
slouken@0
   803
{
slouken@2753
   804
    if (!_this) {
slouken@2753
   805
        SDL_UninitializedVideo();
slouken@2753
   806
        return -1;
slouken@2753
   807
    }
slouken@3501
   808
    return SDL_SetPaletteForDisplay(&SDL_CurrentDisplay, colors, firstcolor, ncolors);
slouken@3500
   809
}
slouken@3500
   810
slouken@3500
   811
int
slouken@3501
   812
SDL_GetPaletteForDisplay(SDL_VideoDisplay * display, SDL_Color * colors, int firstcolor, int ncolors)
slouken@3500
   813
{
slouken@3500
   814
    SDL_Palette *palette;
slouken@3500
   815
slouken@3500
   816
    palette = display->palette;
slouken@3500
   817
    if (!palette || !palette->ncolors) {
slouken@2753
   818
        SDL_SetError("Display mode does not have a palette");
slouken@2753
   819
        return -1;
slouken@2753
   820
    }
slouken@3500
   821
    if (firstcolor < 0 || (firstcolor + ncolors) > palette->ncolors) {
slouken@3500
   822
        SDL_SetError("Palette indices are out of range");
slouken@3500
   823
        return -1;
slouken@3500
   824
    }
slouken@3500
   825
    SDL_memcpy(colors, &palette->colors[firstcolor],
slouken@3500
   826
               ncolors * sizeof(*colors));
slouken@3500
   827
    return 0;
slouken@0
   828
}
slouken@0
   829
slouken@1895
   830
int
slouken@1895
   831
SDL_GetDisplayPalette(SDL_Color * colors, int firstcolor, int ncolors)
slouken@0
   832
{
slouken@2753
   833
    SDL_Palette *palette;
slouken@1895
   834
slouken@2753
   835
    if (!_this) {
slouken@2753
   836
        SDL_UninitializedVideo();
slouken@2753
   837
        return -1;
slouken@2753
   838
    }
slouken@3501
   839
    return SDL_GetPaletteForDisplay(&SDL_CurrentDisplay, colors, firstcolor, ncolors);
slouken@0
   840
}
slouken@0
   841
slouken@1895
   842
SDL_WindowID
slouken@1895
   843
SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
slouken@0
   844
{
slouken@2753
   845
    const Uint32 allowed_flags = (SDL_WINDOW_FULLSCREEN |
slouken@2753
   846
                                  SDL_WINDOW_OPENGL |
slouken@2753
   847
                                  SDL_WINDOW_BORDERLESS |
slouken@2875
   848
                                  SDL_WINDOW_RESIZABLE |
slouken@2875
   849
                                  SDL_WINDOW_INPUT_GRABBED);
slouken@2753
   850
    SDL_VideoDisplay *display;
slouken@2753
   851
    SDL_Window window;
slouken@2753
   852
    int num_windows;
slouken@2753
   853
    SDL_Window *windows;
slouken@0
   854
slouken@2753
   855
    if (!_this) {
slouken@3417
   856
        /* Initialize the video system if needed */
slouken@3417
   857
        if (SDL_VideoInit(NULL, 0) < 0) {
slouken@3417
   858
            return 0;
slouken@3417
   859
        }
slouken@2753
   860
    }
slouken@3057
   861
    if (flags & SDL_WINDOW_OPENGL) {
slouken@3057
   862
        if (!_this->GL_CreateContext) {
slouken@3057
   863
            SDL_SetError("No OpenGL support in video driver");
slouken@3057
   864
            return 0;
slouken@3057
   865
        }
slouken@3057
   866
        SDL_GL_LoadLibrary(NULL);
slouken@2753
   867
    }
slouken@2753
   868
    SDL_zero(window);
slouken@2753
   869
    window.id = _this->next_object_id++;
slouken@2753
   870
    window.x = x;
slouken@2753
   871
    window.y = y;
slouken@2753
   872
    window.w = w;
slouken@2753
   873
    window.h = h;
slouken@2753
   874
    window.flags = (flags & allowed_flags);
slouken@2753
   875
    window.display = _this->current_display;
slouken@1912
   876
slouken@2753
   877
    if (_this->CreateWindow && _this->CreateWindow(_this, &window) < 0) {
slouken@3057
   878
        if (flags & SDL_WINDOW_OPENGL) {
slouken@3057
   879
            SDL_GL_UnloadLibrary();
slouken@3057
   880
        }
slouken@2753
   881
        return 0;
slouken@2753
   882
    }
slouken@2753
   883
    display = &SDL_CurrentDisplay;
slouken@2753
   884
    num_windows = display->num_windows;
slouken@2753
   885
    windows =
slouken@2753
   886
        SDL_realloc(display->windows, (num_windows + 1) * sizeof(*windows));
slouken@2753
   887
    if (!windows) {
slouken@2753
   888
        if (_this->DestroyWindow) {
slouken@2753
   889
            _this->DestroyWindow(_this, &window);
slouken@2753
   890
        }
slouken@3057
   891
        if (flags & SDL_WINDOW_OPENGL) {
slouken@3057
   892
            SDL_GL_UnloadLibrary();
slouken@3057
   893
        }
slouken@2753
   894
        return 0;
slouken@2753
   895
    }
slouken@2753
   896
    windows[num_windows] = window;
slouken@2753
   897
    display->windows = windows;
slouken@2753
   898
    display->num_windows++;
slouken@0
   899
slouken@2753
   900
    if (title) {
slouken@2753
   901
        SDL_SetWindowTitle(window.id, title);
slouken@2753
   902
    }
slouken@2753
   903
    if (flags & SDL_WINDOW_MAXIMIZED) {
slouken@2753
   904
        SDL_MaximizeWindow(window.id);
slouken@2753
   905
    }
slouken@2753
   906
    if (flags & SDL_WINDOW_MINIMIZED) {
slouken@2753
   907
        SDL_MinimizeWindow(window.id);
slouken@2753
   908
    }
slouken@2753
   909
    if (flags & SDL_WINDOW_SHOWN) {
slouken@2753
   910
        SDL_ShowWindow(window.id);
slouken@2753
   911
    }
slouken@2875
   912
    SDL_UpdateWindowGrab(&window);
slouken@2875
   913
slouken@2753
   914
    return window.id;
slouken@1895
   915
}
slouken@0
   916
slouken@1895
   917
SDL_WindowID
slouken@1895
   918
SDL_CreateWindowFrom(const void *data)
slouken@1895
   919
{
slouken@2753
   920
    SDL_VideoDisplay *display;
slouken@2753
   921
    SDL_Window window;
slouken@2753
   922
    int num_windows;
slouken@2753
   923
    SDL_Window *windows;
slouken@0
   924
slouken@2753
   925
    if (!_this) {
slouken@2753
   926
        SDL_UninitializedVideo();
slouken@2753
   927
        return (0);
slouken@2753
   928
    }
slouken@2753
   929
    SDL_zero(window);
slouken@2753
   930
    window.id = _this->next_object_id++;
slouken@2753
   931
    window.display = _this->current_display;
slouken@3057
   932
    window.flags = SDL_WINDOW_FOREIGN;
slouken@1895
   933
slouken@2753
   934
    if (!_this->CreateWindowFrom ||
slouken@2753
   935
        _this->CreateWindowFrom(_this, &window, data) < 0) {
slouken@2753
   936
        return 0;
slouken@2753
   937
    }
slouken@3500
   938
    /* FIXME: Find out what display this window is actually on... */
slouken@2753
   939
    display = &SDL_CurrentDisplay;
slouken@2753
   940
    num_windows = display->num_windows;
slouken@2753
   941
    windows =
slouken@2753
   942
        SDL_realloc(display->windows, (num_windows + 1) * sizeof(*windows));
slouken@2753
   943
    if (!windows) {
slouken@2753
   944
        if (_this->DestroyWindow) {
slouken@2753
   945
            _this->DestroyWindow(_this, &window);
slouken@2753
   946
        }
slouken@2753
   947
        if (window.title) {
slouken@2753
   948
            SDL_free(window.title);
slouken@2753
   949
        }
slouken@2753
   950
        return 0;
slouken@2753
   951
    }
slouken@2753
   952
    windows[num_windows] = window;
slouken@2753
   953
    display->windows = windows;
slouken@2753
   954
    display->num_windows++;
slouken@1895
   955
slouken@2753
   956
    return window.id;
slouken@1895
   957
}
slouken@1895
   958
slouken@1924
   959
int
slouken@1928
   960
SDL_RecreateWindow(SDL_Window * window, Uint32 flags)
slouken@1924
   961
{
slouken@3057
   962
    const Uint32 allowed_flags = (SDL_WINDOW_FULLSCREEN |
slouken@3057
   963
                                  SDL_WINDOW_OPENGL |
slouken@3057
   964
                                  SDL_WINDOW_BORDERLESS |
slouken@3057
   965
                                  SDL_WINDOW_RESIZABLE |
slouken@3486
   966
                                  SDL_WINDOW_INPUT_GRABBED |
slouken@3486
   967
                                  SDL_WINDOW_FOREIGN);
slouken@2753
   968
    char *title = window->title;
slouken@1956
   969
slouken@2753
   970
    if ((flags & SDL_WINDOW_OPENGL) && !_this->GL_CreateContext) {
slouken@2753
   971
        SDL_SetError("No OpenGL support in video driver");
slouken@2753
   972
        return -1;
slouken@2753
   973
    }
slouken@3057
   974
    if ((window->flags & SDL_WINDOW_OPENGL) != (flags & SDL_WINDOW_OPENGL)) {
slouken@3057
   975
        if (flags & SDL_WINDOW_OPENGL) {
slouken@3057
   976
            SDL_GL_LoadLibrary(NULL);
slouken@3057
   977
        } else {
slouken@3057
   978
            SDL_GL_UnloadLibrary();
slouken@3057
   979
        }
slouken@3057
   980
    }
slouken@3057
   981
slouken@3057
   982
    if (window->flags & SDL_WINDOW_FOREIGN) {
slouken@3057
   983
        /* Can't destroy and re-create foreign windows, hrm */
slouken@3057
   984
        flags |= SDL_WINDOW_FOREIGN;
slouken@3057
   985
    } else {
slouken@3057
   986
        flags &= ~SDL_WINDOW_FOREIGN;
slouken@3057
   987
    }
slouken@3057
   988
slouken@3057
   989
    if (_this->DestroyWindow && !(flags & SDL_WINDOW_FOREIGN)) {
slouken@2753
   990
        _this->DestroyWindow(_this, window);
slouken@2753
   991
    }
slouken@3057
   992
slouken@2753
   993
    window->title = NULL;
slouken@3057
   994
    window->flags = (flags & allowed_flags);
slouken@1956
   995
slouken@3057
   996
    if (_this->CreateWindow && !(flags & SDL_WINDOW_FOREIGN)) {
slouken@3057
   997
        if (_this->CreateWindow(_this, window) < 0) {
slouken@3057
   998
            if (flags & SDL_WINDOW_OPENGL) {
slouken@3057
   999
                SDL_GL_UnloadLibrary();
slouken@3057
  1000
            }
slouken@3057
  1001
            return -1;
slouken@3057
  1002
        }
slouken@2753
  1003
    }
slouken@3057
  1004
slouken@2753
  1005
    if (title) {
slouken@2753
  1006
        SDL_SetWindowTitle(window->id, title);
slouken@2753
  1007
        SDL_free(title);
slouken@2753
  1008
    }
slouken@2753
  1009
    if (flags & SDL_WINDOW_MAXIMIZED) {
slouken@2753
  1010
        SDL_MaximizeWindow(window->id);
slouken@2753
  1011
    }
slouken@2753
  1012
    if (flags & SDL_WINDOW_MINIMIZED) {
slouken@2753
  1013
        SDL_MinimizeWindow(window->id);
slouken@2753
  1014
    }
slouken@2753
  1015
    if (flags & SDL_WINDOW_SHOWN) {
slouken@2753
  1016
        SDL_ShowWindow(window->id);
slouken@2753
  1017
    }
slouken@2875
  1018
    SDL_UpdateWindowGrab(window);
slouken@2875
  1019
slouken@2753
  1020
    return 0;
slouken@1924
  1021
}
slouken@1924
  1022
slouken@2753
  1023
SDL_Window *
slouken@1895
  1024
SDL_GetWindowFromID(SDL_WindowID windowID)
slouken@1895
  1025
{
slouken@2753
  1026
    int i, j;
slouken@1895
  1027
slouken@2753
  1028
    if (!_this) {
slouken@2753
  1029
        SDL_UninitializedVideo();
slouken@2753
  1030
        return NULL;
slouken@2753
  1031
    }
slouken@3417
  1032
    if (windowID) {
slouken@3417
  1033
        for (i = 0; i < _this->num_displays; ++i) {
slouken@3417
  1034
            SDL_VideoDisplay *display = &_this->displays[i];
slouken@3417
  1035
            for (j = 0; j < display->num_windows; ++j) {
slouken@3417
  1036
                SDL_Window *window = &display->windows[j];
slouken@3417
  1037
                if (window->id == windowID) {
slouken@3417
  1038
                    return window;
slouken@3417
  1039
                }
slouken@3417
  1040
            }
slouken@3417
  1041
        }
slouken@3417
  1042
    } else {
slouken@3417
  1043
        /* Just return the first active window */
slouken@3417
  1044
        for (i = 0; i < _this->num_displays; ++i) {
slouken@3417
  1045
            SDL_VideoDisplay *display = &_this->displays[i];
slouken@3417
  1046
            for (j = 0; j < display->num_windows; ++j) {
slouken@3417
  1047
                SDL_Window *window = &display->windows[j];
slouken@2753
  1048
                return window;
slouken@2753
  1049
            }
slouken@2753
  1050
        }
slouken@2753
  1051
    }
slouken@3417
  1052
    /* Couldn't find the window with the requested ID */
slouken@3417
  1053
    SDL_SetError("Invalid window ID");
slouken@2753
  1054
    return NULL;
slouken@1895
  1055
}
slouken@1895
  1056
slouken@1895
  1057
SDL_VideoDisplay *
slouken@1895
  1058
SDL_GetDisplayFromWindow(SDL_Window * window)
slouken@1895
  1059
{
slouken@2753
  1060
    if (!_this) {
slouken@2753
  1061
        SDL_UninitializedVideo();
slouken@2753
  1062
        return NULL;
slouken@2753
  1063
    }
slouken@2753
  1064
    if (!window) {
slouken@2753
  1065
        return NULL;
slouken@2753
  1066
    }
slouken@2753
  1067
    return &_this->displays[window->display];
slouken@1895
  1068
}
slouken@1895
  1069
slouken@3417
  1070
static __inline__ SDL_Renderer *
slouken@3485
  1071
SDL_GetCurrentRenderer(SDL_bool create)
slouken@3417
  1072
{
slouken@3417
  1073
    if (!_this) {
slouken@3417
  1074
        SDL_UninitializedVideo();
slouken@3417
  1075
        return NULL;
slouken@3417
  1076
    }
slouken@3417
  1077
    if (!SDL_CurrentRenderer) {
slouken@3485
  1078
        if (!create) {
slouken@3485
  1079
            SDL_SetError("Use SDL_CreateRenderer() to create a renderer");
slouken@3485
  1080
            return NULL;
slouken@3485
  1081
        }
slouken@3417
  1082
        if (SDL_CreateRenderer(0, -1, 0) < 0) {
slouken@3417
  1083
            return NULL;
slouken@3417
  1084
        }
slouken@3417
  1085
    }
slouken@3417
  1086
    return SDL_CurrentRenderer;
slouken@3417
  1087
}
slouken@3417
  1088
slouken@1895
  1089
Uint32
slouken@1895
  1090
SDL_GetWindowFlags(SDL_WindowID windowID)
slouken@1895
  1091
{
slouken@2753
  1092
    SDL_Window *window = SDL_GetWindowFromID(windowID);
slouken@1895
  1093
slouken@2753
  1094
    if (!window) {
slouken@2753
  1095
        return 0;
slouken@2753
  1096
    }
slouken@2753
  1097
    return window->flags;
slouken@1895
  1098
}
slouken@1895
  1099
slouken@1895
  1100
void
slouken@1895
  1101
SDL_SetWindowTitle(SDL_WindowID windowID, const char *title)
slouken@1895
  1102
{
slouken@2753
  1103
    SDL_Window *window = SDL_GetWindowFromID(windowID);
slouken@1895
  1104
slouken@2753
  1105
    if (!window || title == window->title) {
slouken@2753
  1106
        return;
slouken@2753
  1107
    }
slouken@2753
  1108
    if (window->title) {
slouken@2753
  1109
        SDL_free(window->title);
slouken@2753
  1110
    }
slouken@2753
  1111
    if (title) {
slouken@2753
  1112
        window->title = SDL_strdup(title);
slouken@2753
  1113
    } else {
slouken@2753
  1114
        window->title = NULL;
slouken@2753
  1115
    }
slouken@1956
  1116
slouken@2753
  1117
    if (_this->SetWindowTitle) {
slouken@2753
  1118
        _this->SetWindowTitle(_this, window);
slouken@2753
  1119
    }
slouken@1895
  1120
}
slouken@1895
  1121
slouken@2753
  1122
const char *
slouken@1895
  1123
SDL_GetWindowTitle(SDL_WindowID windowID)
slouken@1895
  1124
{
slouken@2753
  1125
    SDL_Window *window = SDL_GetWindowFromID(windowID);
slouken@1895
  1126
slouken@2753
  1127
    if (!window) {
slouken@2753
  1128
        return NULL;
slouken@2753
  1129
    }
slouken@2753
  1130
    return window->title;
slouken@1895
  1131
}
slouken@1895
  1132
slouken@1895
  1133
void
slouken@2967
  1134
SDL_SetWindowIcon(SDL_WindowID windowID, SDL_Surface * icon)
slouken@2967
  1135
{
slouken@2967
  1136
    SDL_Window *window = SDL_GetWindowFromID(windowID);
slouken@2967
  1137
slouken@2967
  1138
    if (!window) {
slouken@2967
  1139
        return;
slouken@2967
  1140
    }
slouken@2967
  1141
    if (_this->SetWindowIcon) {
slouken@2967
  1142
        _this->SetWindowIcon(_this, window, icon);
slouken@2967
  1143
    }
slouken@2967
  1144
}
slouken@2967
  1145
slouken@2967
  1146
void
slouken@1895
  1147
SDL_SetWindowData(SDL_WindowID windowID, void *userdata)
slouken@1895
  1148
{
slouken@2753
  1149
    SDL_Window *window = SDL_GetWindowFromID(windowID);
slouken@1895
  1150
slouken@2753
  1151
    if (!window) {
slouken@2753
  1152
        return;
slouken@2753
  1153
    }
slouken@2753
  1154
    window->userdata = userdata;
slouken@1895
  1155
}
slouken@1895
  1156
slouken@2753
  1157
void *
slouken@1895
  1158
SDL_GetWindowData(SDL_WindowID windowID)
slouken@1895
  1159
{
slouken@2753
  1160
    SDL_Window *window = SDL_GetWindowFromID(windowID);
slouken@1895
  1161
slouken@2753
  1162
    if (!window) {
slouken@2753
  1163
        return NULL;
slouken@2753
  1164
    }
slouken@2753
  1165
    return window->userdata;
slouken@1895
  1166
}
slouken@1895
  1167
slouken@1895
  1168
void
slouken@1895
  1169
SDL_SetWindowPosition(SDL_WindowID windowID, int x, int y)
slouken@1895
  1170
{
slouken@2753
  1171
    SDL_Window *window = SDL_GetWindowFromID(windowID);
slouken@2753
  1172
    SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
slouken@1895
  1173
slouken@2753
  1174
    if (!window) {
slouken@2753
  1175
        return;
slouken@2753
  1176
    }
slouken@2875
  1177
    if (x != SDL_WINDOWPOS_UNDEFINED) {
slouken@2753
  1178
        window->x = x;
slouken@2753
  1179
    }
slouken@2875
  1180
    if (y != SDL_WINDOWPOS_UNDEFINED) {
slouken@2753
  1181
        window->y = y;
slouken@2753
  1182
    }
slouken@2753
  1183
    if (_this->SetWindowPosition) {
slouken@2753
  1184
        _this->SetWindowPosition(_this, window);
slouken@2753
  1185
    }
slouken@2875
  1186
    SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_MOVED, x, y);
slouken@1895
  1187
}
slouken@1895
  1188
slouken@1895
  1189
void
slouken@1895
  1190
SDL_GetWindowPosition(SDL_WindowID windowID, int *x, int *y)
slouken@1895
  1191
{
slouken@2753
  1192
    SDL_Window *window = SDL_GetWindowFromID(windowID);
slouken@1895
  1193
slouken@2753
  1194
    if (!window) {
slouken@2753
  1195
        return;
slouken@2753
  1196
    }
slouken@2753
  1197
    if (x) {
slouken@2753
  1198
        *x = window->x;
slouken@2753
  1199
    }
slouken@2753
  1200
    if (y) {
slouken@2753
  1201
        *y = window->y;
slouken@2753
  1202
    }
slouken@1895
  1203
}
slouken@1895
  1204
slouken@1895
  1205
void
slouken@1895
  1206
SDL_SetWindowSize(SDL_WindowID windowID, int w, int h)
slouken@1895
  1207
{
slouken@2753
  1208
    SDL_Window *window = SDL_GetWindowFromID(windowID);
slouken@1895
  1209
slouken@2753
  1210
    if (!window) {
slouken@2753
  1211
        return;
slouken@2753
  1212
    }
slouken@2753
  1213
    window->w = w;
slouken@2753
  1214
    window->h = h;
slouken@1895
  1215
slouken@2753
  1216
    if (_this->SetWindowSize) {
slouken@2753
  1217
        _this->SetWindowSize(_this, window);
slouken@2753
  1218
    }
slouken@2849
  1219
    SDL_OnWindowResized(window);
slouken@1895
  1220
}
slouken@1895
  1221
slouken@1895
  1222
void
slouken@1895
  1223
SDL_GetWindowSize(SDL_WindowID windowID, int *w, int *h)
slouken@1895
  1224
{
slouken@2753
  1225
    SDL_Window *window = SDL_GetWindowFromID(windowID);
slouken@1895
  1226
slouken@2860
  1227
    if (window) {
slouken@2849
  1228
        if (w) {
slouken@2849
  1229
            *w = window->w;
slouken@2849
  1230
        }
slouken@2849
  1231
        if (h) {
slouken@2849
  1232
            *h = window->h;
slouken@2849
  1233
        }
slouken@2849
  1234
    } else {
slouken@2849
  1235
        if (w) {
slouken@2849
  1236
            *w = 0;
slouken@2849
  1237
        }
slouken@2849
  1238
        if (h) {
slouken@2849
  1239
            *h = 0;
slouken@2849
  1240
        }
slouken@2753
  1241
    }
slouken@1895
  1242
}
slouken@1895
  1243
slouken@1895
  1244
void
slouken@1895
  1245
SDL_ShowWindow(SDL_WindowID windowID)
slouken@1895
  1246
{
slouken@2753
  1247
    SDL_Window *window = SDL_GetWindowFromID(windowID);
slouken@1895
  1248
slouken@2753
  1249
    if (!window || (window->flags & SDL_WINDOW_SHOWN)) {
slouken@2753
  1250
        return;
slouken@2753
  1251
    }
slouken@1895
  1252
slouken@2753
  1253
    if (_this->ShowWindow) {
slouken@2753
  1254
        _this->ShowWindow(_this, window);
slouken@2753
  1255
    }
slouken@2875
  1256
    SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_SHOWN, 0, 0);
slouken@1895
  1257
}
slouken@1895
  1258
slouken@1895
  1259
void
slouken@1895
  1260
SDL_HideWindow(SDL_WindowID windowID)
slouken@1895
  1261
{
slouken@2753
  1262
    SDL_Window *window = SDL_GetWindowFromID(windowID);
slouken@1895
  1263
slouken@2753
  1264
    if (!window || !(window->flags & SDL_WINDOW_SHOWN)) {
slouken@2753
  1265
        return;
slouken@2753
  1266
    }
slouken@1895
  1267
slouken@2753
  1268
    if (_this->HideWindow) {
slouken@2753
  1269
        _this->HideWindow(_this, window);
slouken@2753
  1270
    }
slouken@2875
  1271
    SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_HIDDEN, 0, 0);
slouken@1895
  1272
}
slouken@1895
  1273
slouken@1895
  1274
void
slouken@1895
  1275
SDL_RaiseWindow(SDL_WindowID windowID)
slouken@1895
  1276
{
slouken@2753
  1277
    SDL_Window *window = SDL_GetWindowFromID(windowID);
slouken@1895
  1278
slouken@2753
  1279
    if (!window || !(window->flags & SDL_WINDOW_SHOWN)) {
slouken@2753
  1280
        return;
slouken@2753
  1281
    }
slouken@2753
  1282
    if (_this->RaiseWindow) {
slouken@2753
  1283
        _this->RaiseWindow(_this, window);
slouken@3502
  1284
    } else {
slouken@3502
  1285
        /* FIXME: What we really want is a way to request focus */
slouken@3502
  1286
        SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0);
slouken@2753
  1287
    }
slouken@1895
  1288
}
slouken@1895
  1289
slouken@1895
  1290
void
slouken@1895
  1291
SDL_MaximizeWindow(SDL_WindowID windowID)
slouken@1895
  1292
{
slouken@2753
  1293
    SDL_Window *window = SDL_GetWindowFromID(windowID);
slouken@1895
  1294
slouken@2753
  1295
    if (!window || (window->flags & SDL_WINDOW_MAXIMIZED)) {
slouken@2753
  1296
        return;
slouken@2753
  1297
    }
slouken@1895
  1298
slouken@2753
  1299
    if (_this->MaximizeWindow) {
slouken@2753
  1300
        _this->MaximizeWindow(_this, window);
slouken@2753
  1301
    }
slouken@2875
  1302
    SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_MAXIMIZED, 0, 0);
slouken@1895
  1303
}
slouken@1895
  1304
slouken@1895
  1305
void
slouken@1895
  1306
SDL_MinimizeWindow(SDL_WindowID windowID)
slouken@1895
  1307
{
slouken@2753
  1308
    SDL_Window *window = SDL_GetWindowFromID(windowID);
slouken@1895
  1309
slouken@2753
  1310
    if (!window || (window->flags & SDL_WINDOW_MINIMIZED)) {
slouken@2753
  1311
        return;
slouken@2753
  1312
    }
slouken@1895
  1313
slouken@2753
  1314
    if (_this->MinimizeWindow) {
slouken@2753
  1315
        _this->MinimizeWindow(_this, window);
slouken@2753
  1316
    }
slouken@2875
  1317
    SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
slouken@1895
  1318
}
slouken@1895
  1319
slouken@1895
  1320
void
slouken@1895
  1321
SDL_RestoreWindow(SDL_WindowID windowID)
slouken@1895
  1322
{
slouken@2753
  1323
    SDL_Window *window = SDL_GetWindowFromID(windowID);
slouken@1895
  1324
slouken@2753
  1325
    if (!window
slouken@2934
  1326
        || !(window->flags & (SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED))) {
slouken@2753
  1327
        return;
slouken@2753
  1328
    }
slouken@1895
  1329
slouken@2753
  1330
    if (_this->RestoreWindow) {
slouken@2753
  1331
        _this->RestoreWindow(_this, window);
slouken@2753
  1332
    }
slouken@2875
  1333
    SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_RESTORED, 0, 0);
slouken@1895
  1334
}
slouken@1895
  1335
slouken@1895
  1336
int
slouken@1895
  1337
SDL_SetWindowFullscreen(SDL_WindowID windowID, int fullscreen)
slouken@1895
  1338
{
slouken@2753
  1339
    SDL_Window *window = SDL_GetWindowFromID(windowID);
slouken@1895
  1340
slouken@2753
  1341
    if (!window) {
slouken@2753
  1342
        return -1;
slouken@2753
  1343
    }
slouken@2753
  1344
    if (fullscreen) {
slouken@2753
  1345
        fullscreen = SDL_WINDOW_FULLSCREEN;
slouken@2753
  1346
    }
slouken@2753
  1347
    if ((window->flags & SDL_WINDOW_FULLSCREEN) == fullscreen) {
slouken@2753
  1348
        return 0;
slouken@2753
  1349
    }
slouken@2753
  1350
    if (fullscreen) {
slouken@2753
  1351
        window->flags |= SDL_WINDOW_FULLSCREEN;
slouken@1895
  1352
slouken@3502
  1353
        SDL_UpdateFullscreenMode(window, SDL_TRUE);
slouken@2753
  1354
    } else {
slouken@2753
  1355
        window->flags &= ~SDL_WINDOW_FULLSCREEN;
slouken@1895
  1356
slouken@3502
  1357
        SDL_UpdateFullscreenMode(window, SDL_FALSE);
slouken@2753
  1358
    }
slouken@2753
  1359
    return 0;
slouken@1895
  1360
}
slouken@1895
  1361
slouken@1895
  1362
void
slouken@1895
  1363
SDL_SetWindowGrab(SDL_WindowID windowID, int mode)
slouken@1895
  1364
{
slouken@2753
  1365
    SDL_Window *window = SDL_GetWindowFromID(windowID);
slouken@1895
  1366
slouken@2753
  1367
    if (!window || (!!mode == !!(window->flags & SDL_WINDOW_INPUT_GRABBED))) {
slouken@2753
  1368
        return;
slouken@2753
  1369
    }
slouken@2753
  1370
    if (mode) {
slouken@2753
  1371
        window->flags |= SDL_WINDOW_INPUT_GRABBED;
slouken@2753
  1372
    } else {
slouken@2753
  1373
        window->flags &= ~SDL_WINDOW_INPUT_GRABBED;
slouken@2753
  1374
    }
slouken@2875
  1375
    SDL_UpdateWindowGrab(window);
slouken@2875
  1376
}
slouken@1895
  1377
slouken@2875
  1378
static void
slouken@2876
  1379
SDL_UpdateWindowGrab(SDL_Window * window)
slouken@2875
  1380
{
slouken@2753
  1381
    if ((window->flags & SDL_WINDOW_INPUT_FOCUS) && _this->SetWindowGrab) {
slouken@2753
  1382
        _this->SetWindowGrab(_this, window);
slouken@2753
  1383
    }
slouken@1895
  1384
}
slouken@1895
  1385
slouken@1895
  1386
int
slouken@1895
  1387
SDL_GetWindowGrab(SDL_WindowID windowID)
slouken@1895
  1388
{
slouken@2753
  1389
    SDL_Window *window = SDL_GetWindowFromID(windowID);
slouken@1895
  1390
slouken@2753
  1391
    if (!window) {
slouken@2753
  1392
        return 0;
slouken@2753
  1393
    }
slouken@2753
  1394
    return ((window->flags & SDL_WINDOW_INPUT_GRABBED) != 0);
slouken@1895
  1395
}
slouken@1895
  1396
slouken@1895
  1397
void
slouken@1895
  1398
SDL_OnWindowShown(SDL_Window * window)
slouken@1895
  1399
{
slouken@3502
  1400
    SDL_RaiseWindow(window->id);
slouken@3502
  1401
    SDL_UpdateFullscreenMode(window, SDL_TRUE);
slouken@1895
  1402
}
slouken@1895
  1403
slouken@1895
  1404
void
slouken@1895
  1405
SDL_OnWindowHidden(SDL_Window * window)
slouken@1895
  1406
{
slouken@3502
  1407
    SDL_UpdateFullscreenMode(window, SDL_FALSE);
slouken@1895
  1408
}
slouken@1895
  1409
slouken@1895
  1410
void
slouken@1970
  1411
SDL_OnWindowResized(SDL_Window * window)
slouken@1970
  1412
{
slouken@2753
  1413
    SDL_Renderer *renderer = window->renderer;
slouken@1970
  1414
slouken@2753
  1415
    if (renderer && renderer->DisplayModeChanged) {
slouken@2753
  1416
        renderer->DisplayModeChanged(renderer);
slouken@2753
  1417
    }
slouken@1970
  1418
}
slouken@1970
  1419
slouken@1970
  1420
void
slouken@3502
  1421
SDL_OnWindowMinimized(SDL_Window * window)
slouken@3502
  1422
{
slouken@3502
  1423
    SDL_UpdateFullscreenMode(window, SDL_FALSE);
slouken@3502
  1424
}
slouken@3502
  1425
slouken@3502
  1426
void
slouken@3502
  1427
SDL_OnWindowRestored(SDL_Window * window)
slouken@3502
  1428
{
slouken@3502
  1429
    SDL_RaiseWindow(window->id);
slouken@3502
  1430
    SDL_UpdateFullscreenMode(window, SDL_TRUE);
slouken@3502
  1431
}
slouken@3502
  1432
slouken@3502
  1433
void
slouken@1895
  1434
SDL_OnWindowFocusGained(SDL_Window * window)
slouken@1895
  1435
{
slouken@2753
  1436
    SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
slouken@1895
  1437
slouken@3502
  1438
    SDL_UpdateFullscreenMode(window, SDL_TRUE);
slouken@2753
  1439
    if (display->gamma && _this->SetDisplayGammaRamp) {
slouken@3500
  1440
        _this->SetDisplayGammaRamp(_this, display, display->gamma);
slouken@2753
  1441
    }
slouken@2876
  1442
    if ((window->flags & (SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_FULLSCREEN))
slouken@2876
  1443
        && _this->SetWindowGrab) {
slouken@2753
  1444
        _this->SetWindowGrab(_this, window);
slouken@2753
  1445
    }
slouken@1895
  1446
}
slouken@1895
  1447
slouken@1895
  1448
void
slouken@1895
  1449
SDL_OnWindowFocusLost(SDL_Window * window)
slouken@1895
  1450
{
slouken@2753
  1451
    SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
slouken@1895
  1452
slouken@3502
  1453
    SDL_UpdateFullscreenMode(window, SDL_FALSE);
slouken@2753
  1454
    if (display->gamma && _this->SetDisplayGammaRamp) {
slouken@3500
  1455
        _this->SetDisplayGammaRamp(_this, display, display->saved_gamma);
slouken@2753
  1456
    }
slouken@2876
  1457
    if ((window->flags & (SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_FULLSCREEN))
slouken@2876
  1458
        && _this->SetWindowGrab) {
slouken@2753
  1459
        _this->SetWindowGrab(_this, window);
slouken@2753
  1460
    }
slouken@1895
  1461
}
slouken@1895
  1462
slouken@1895
  1463
SDL_WindowID
slouken@1895
  1464
SDL_GetFocusWindow(void)
slouken@1895
  1465
{
slouken@2753
  1466
    SDL_VideoDisplay *display;
slouken@2753
  1467
    int i;
slouken@1895
  1468
slouken@2753
  1469
    if (!_this) {
slouken@2753
  1470
        return 0;
slouken@2753
  1471
    }
slouken@2753
  1472
    display = &SDL_CurrentDisplay;
slouken@2753
  1473
    for (i = 0; i < display->num_windows; ++i) {
slouken@2753
  1474
        SDL_Window *window = &display->windows[i];
slouken@1895
  1475
slouken@2753
  1476
        if (window->flags & SDL_WINDOW_INPUT_FOCUS) {
slouken@2753
  1477
            return window->id;
slouken@2753
  1478
        }
slouken@2753
  1479
    }
slouken@2753
  1480
    return 0;
slouken@1895
  1481
}
slouken@1895
  1482
slouken@1895
  1483
void
slouken@1895
  1484
SDL_DestroyWindow(SDL_WindowID windowID)
slouken@1895
  1485
{
slouken@2753
  1486
    int i, j;
slouken@1895
  1487
slouken@2753
  1488
    if (!_this) {
slouken@2753
  1489
        return;
slouken@2753
  1490
    }
slouken@2753
  1491
    /* Restore video mode, etc. */
slouken@2753
  1492
    SDL_SendWindowEvent(windowID, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
slouken@1895
  1493
slouken@2753
  1494
    for (i = 0; i < _this->num_displays; ++i) {
slouken@2753
  1495
        SDL_VideoDisplay *display = &_this->displays[i];
slouken@2753
  1496
        for (j = 0; j < display->num_windows; ++j) {
slouken@2753
  1497
            SDL_Window *window = &display->windows[j];
slouken@2753
  1498
            if (window->id != windowID) {
slouken@2753
  1499
                continue;
slouken@2753
  1500
            }
slouken@2753
  1501
            if (window->title) {
slouken@2753
  1502
                SDL_free(window->title);
slouken@2753
  1503
                window->title = NULL;
slouken@2753
  1504
            }
slouken@2753
  1505
            if (window->renderer) {
slouken@2753
  1506
                SDL_DestroyRenderer(window->id);
slouken@2753
  1507
                window->renderer = NULL;
slouken@2753
  1508
            }
slouken@2753
  1509
            if (_this->DestroyWindow) {
slouken@2753
  1510
                _this->DestroyWindow(_this, window);
slouken@2753
  1511
            }
slouken@3057
  1512
            if (window->flags & SDL_WINDOW_OPENGL) {
slouken@3057
  1513
                SDL_GL_UnloadLibrary();
slouken@3057
  1514
            }
slouken@2753
  1515
            if (j != display->num_windows - 1) {
slouken@2753
  1516
                SDL_memcpy(&display->windows[i],
slouken@2753
  1517
                           &display->windows[i + 1],
slouken@2753
  1518
                           (display->num_windows - i - 1) * sizeof(*window));
slouken@2753
  1519
            }
slouken@2753
  1520
            --display->num_windows;
slouken@2753
  1521
            return;
slouken@2753
  1522
        }
slouken@2753
  1523
    }
slouken@1895
  1524
}
slouken@1895
  1525
slouken@1895
  1526
void
slouken@3500
  1527
SDL_AddRenderDriver(SDL_VideoDisplay * display, const SDL_RenderDriver * driver)
slouken@1895
  1528
{
slouken@2753
  1529
    SDL_RenderDriver *render_drivers;
slouken@1895
  1530
slouken@2753
  1531
    render_drivers =
slouken@2753
  1532
        SDL_realloc(display->render_drivers,
slouken@2753
  1533
                    (display->num_render_drivers +
slouken@2753
  1534
                     1) * sizeof(*render_drivers));
slouken@2753
  1535
    if (render_drivers) {
slouken@2753
  1536
        render_drivers[display->num_render_drivers] = *driver;
slouken@2753
  1537
        display->render_drivers = render_drivers;
slouken@2753
  1538
        display->num_render_drivers++;
slouken@2753
  1539
    }
slouken@1895
  1540
}
slouken@1895
  1541
slouken@1895
  1542
int
slouken@1969
  1543
SDL_GetNumRenderDrivers(void)
slouken@1895
  1544
{
slouken@2753
  1545
    if (_this) {
slouken@2753
  1546
        return SDL_CurrentDisplay.num_render_drivers;
slouken@2753
  1547
    }
slouken@2753
  1548
    return 0;
slouken@1895
  1549
}
slouken@1895
  1550
slouken@1895
  1551
int
slouken@1969
  1552
SDL_GetRenderDriverInfo(int index, SDL_RendererInfo * info)
slouken@1895
  1553
{
slouken@2753
  1554
    if (!_this) {
slouken@2753
  1555
        SDL_UninitializedVideo();
slouken@2753
  1556
        return -1;
slouken@2753
  1557
    }
slouken@2753
  1558
    if (index < 0 || index >= SDL_GetNumRenderDrivers()) {
slouken@2753
  1559
        SDL_SetError("index must be in the range of 0 - %d",
slouken@2753
  1560
                     SDL_GetNumRenderDrivers() - 1);
slouken@2753
  1561
        return -1;
slouken@2753
  1562
    }
slouken@2753
  1563
    *info = SDL_CurrentDisplay.render_drivers[index].info;
slouken@2753
  1564
    return 0;
slouken@1895
  1565
}
slouken@1895
  1566
slouken@1895
  1567
int
slouken@1895
  1568
SDL_CreateRenderer(SDL_WindowID windowID, int index, Uint32 flags)
slouken@1895
  1569
{
slouken@2753
  1570
    SDL_Window *window = SDL_GetWindowFromID(windowID);
slouken@1895
  1571
slouken@2753
  1572
    if (!window) {
slouken@3091
  1573
        SDL_SetError("Invalid window ID");
slouken@3091
  1574
        return -1;
slouken@2753
  1575
    }
slouken@3424
  1576
slouken@3424
  1577
    /* Free any existing renderer */
slouken@3424
  1578
    SDL_DestroyRenderer(windowID);
slouken@3424
  1579
slouken@2753
  1580
    if (index < 0) {
slouken@3488
  1581
        char *override = SDL_getenv("SDL_VIDEO_RENDERER");
slouken@3488
  1582
        int n = SDL_GetNumRenderDrivers();
slouken@3488
  1583
lestat@3489
  1584
#if SDL_VIDEO_RENDER_OGL
slouken@3488
  1585
        if (!override && (window->flags & SDL_WINDOW_OPENGL)) {
slouken@3488
  1586
            override = "opengl";
slouken@3488
  1587
        }
lestat@3489
  1588
#endif /* SDL_VIDEO_RENDER_OGL */
lestat@3489
  1589
#if SDL_VIDEO_RENDER_OGL_ES
lestat@3489
  1590
        if (!override && (window->flags & SDL_WINDOW_OPENGL)) {
lestat@3489
  1591
            override = "opengl_es";
lestat@3489
  1592
        }
lestat@3489
  1593
#endif /* SDL_VIDEO_RENDER_OGL_ES */
slouken@3424
  1594
        if (override) {
slouken@3488
  1595
            for (index = 0; index < n; ++index) {
slouken@3424
  1596
                SDL_RenderDriver *driver =
slouken@3488
  1597
                    &SDL_CurrentDisplay.render_drivers[index];
slouken@3488
  1598
slouken@3424
  1599
                if (SDL_strcasecmp(override, driver->info.name) == 0) {
slouken@3488
  1600
                    /* Create a new renderer instance */
slouken@3488
  1601
                    window->renderer = driver->CreateRenderer(window, flags);
slouken@3424
  1602
                    break;
slouken@3424
  1603
                }
slouken@3424
  1604
            }
slouken@3488
  1605
        } else {
slouken@3488
  1606
            for (index = 0; index < n; ++index) {
slouken@3488
  1607
                SDL_RenderDriver *driver =
slouken@3488
  1608
                    &SDL_CurrentDisplay.render_drivers[index];
slouken@3488
  1609
slouken@3488
  1610
                if ((driver->info.flags & flags) == flags) {
slouken@3488
  1611
                    /* Create a new renderer instance */
slouken@3488
  1612
                    window->renderer = driver->CreateRenderer(window, flags);
slouken@3488
  1613
                    if (window->renderer) {
slouken@3488
  1614
                        /* Yay, we got one! */
slouken@3488
  1615
                        break;
slouken@3488
  1616
                    }
slouken@2753
  1617
                }
slouken@2753
  1618
            }
slouken@2753
  1619
        }
slouken@2753
  1620
        if (index == n) {
slouken@2753
  1621
            SDL_SetError("Couldn't find matching render driver");
slouken@2753
  1622
            return -1;
slouken@2753
  1623
        }
slouken@3424
  1624
    } else {
slouken@3424
  1625
        if (index >= SDL_GetNumRenderDrivers()) {
slouken@3424
  1626
            SDL_SetError("index must be -1 or in the range of 0 - %d",
slouken@3424
  1627
                         SDL_GetNumRenderDrivers() - 1);
slouken@3424
  1628
            return -1;
slouken@3424
  1629
        }
slouken@3424
  1630
        /* Create a new renderer instance */
slouken@3424
  1631
        window->renderer = SDL_CurrentDisplay.render_drivers[index].CreateRenderer(window, flags);
slouken@2753
  1632
    }
slouken@3092
  1633
slouken@3139
  1634
    if (window->renderer == NULL) {
slouken@3139
  1635
        /* Assuming renderer set its error */
slouken@3139
  1636
        return -1;
slouken@3092
  1637
    }
slouken@3092
  1638
slouken@2753
  1639
    SDL_SelectRenderer(window->id);
slouken@1895
  1640
slouken@2753
  1641
    return 0;
slouken@1895
  1642
}
slouken@1895
  1643
slouken@1895
  1644
int
slouken@1895
  1645
SDL_SelectRenderer(SDL_WindowID windowID)
slouken@1895
  1646
{
slouken@2753
  1647
    SDL_Window *window = SDL_GetWindowFromID(windowID);
slouken@2753
  1648
    SDL_Renderer *renderer;
slouken@1895
  1649
slouken@3318
  1650
    if (!window) {
slouken@3318
  1651
        SDL_SetError("Invalid window ID");
slouken@2753
  1652
        return -1;
slouken@2753
  1653
    }
slouken@2753
  1654
    renderer = window->renderer;
slouken@3485
  1655
    if (!renderer) {
slouken@3485
  1656
        SDL_SetError("Use SDL_CreateRenderer() to create a renderer");
slouken@3485
  1657
        return -1;
slouken@3485
  1658
    }
slouken@3485
  1659
    if (renderer->ActivateRenderer) {
slouken@3485
  1660
        if (renderer->ActivateRenderer(renderer) < 0) {
slouken@2753
  1661
            return -1;
slouken@2753
  1662
        }
slouken@2753
  1663
    }
slouken@3485
  1664
    SDL_CurrentDisplay.current_renderer = renderer;
slouken@2753
  1665
    return 0;
slouken@1895
  1666
}
slouken@1895
  1667
slouken@1969
  1668
int
slouken@1969
  1669
SDL_GetRendererInfo(SDL_RendererInfo * info)
slouken@1969
  1670
{
slouken@3485
  1671
    SDL_Renderer *renderer = SDL_GetCurrentRenderer(SDL_FALSE);
slouken@3417
  1672
    if (!renderer) {
slouken@2753
  1673
        return -1;
slouken@2753
  1674
    }
slouken@3417
  1675
    *info = renderer->info;
slouken@2753
  1676
    return 0;
slouken@1969
  1677
}
slouken@1969
  1678
slouken@1895
  1679
SDL_TextureID
slouken@1895
  1680
SDL_CreateTexture(Uint32 format, int access, int w, int h)
slouken@1895
  1681
{
slouken@2753
  1682
    int hash;
slouken@2753
  1683
    SDL_Renderer *renderer;
slouken@2753
  1684
    SDL_Texture *texture;
slouken@1895
  1685
slouken@3485
  1686
    renderer = SDL_GetCurrentRenderer(SDL_TRUE);
slouken@2810
  1687
    if (!renderer) {
slouken@2810
  1688
        return 0;
slouken@2810
  1689
    }
slouken@2810
  1690
    if (!renderer->CreateTexture) {
slouken@2810
  1691
        SDL_Unsupported();
slouken@2753
  1692
        return 0;
slouken@2753
  1693
    }
slouken@2753
  1694
    texture = (SDL_Texture *) SDL_calloc(1, sizeof(*texture));
slouken@2753
  1695
    if (!texture) {
slouken@2753
  1696
        SDL_OutOfMemory();
slouken@2753
  1697
        return 0;
slouken@2753
  1698
    }
slouken@2753
  1699
    texture->id = _this->next_object_id++;
slouken@2753
  1700
    texture->format = format;
slouken@2753
  1701
    texture->access = access;
slouken@2753
  1702
    texture->w = w;
slouken@2753
  1703
    texture->h = h;
slouken@2753
  1704
    texture->r = 255;
slouken@2753
  1705
    texture->g = 255;
slouken@2753
  1706
    texture->b = 255;
slouken@2753
  1707
    texture->a = 255;
slouken@2753
  1708
    texture->renderer = renderer;
slouken@1895
  1709
slouken@2753
  1710
    if (renderer->CreateTexture(renderer, texture) < 0) {
slouken@2753
  1711
        if (renderer->DestroyTexture) {
slouken@2753
  1712
            renderer->DestroyTexture(renderer, texture);
slouken@2753
  1713
        }
slouken@2753
  1714
        SDL_free(texture);
slouken@2753
  1715
        return 0;
slouken@2753
  1716
    }
slouken@2753
  1717
    hash = (texture->id % SDL_arraysize(SDL_CurrentDisplay.textures));
slouken@2753
  1718
    texture->next = SDL_CurrentDisplay.textures[hash];
slouken@2753
  1719
    SDL_CurrentDisplay.textures[hash] = texture;
slouken@1895
  1720
slouken@2753
  1721
    return texture->id;
slouken@1895
  1722
}
slouken@1895
  1723
slouken@1895
  1724
SDL_TextureID
slouken@2222
  1725
SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface)
slouken@1895
  1726
{
slouken@2753
  1727
    SDL_TextureID textureID;
slouken@3057
  1728
    Uint32 requested_format = format;
slouken@2753
  1729
    SDL_PixelFormat *fmt;
lestat@3166
  1730
    SDL_Renderer *renderer;
slouken@2753
  1731
    int bpp;
slouken@2753
  1732
    Uint32 Rmask, Gmask, Bmask, Amask;
slouken@1895
  1733
slouken@2753
  1734
    if (!surface) {
slouken@2753
  1735
        SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface");
slouken@2753
  1736
        return 0;
slouken@2753
  1737
    }
slouken@2753
  1738
    fmt = surface->format;
slouken@1895
  1739
slouken@3485
  1740
    renderer = SDL_GetCurrentRenderer(SDL_TRUE);
lestat@3166
  1741
    if (!renderer) {
lestat@3166
  1742
        return 0;
lestat@3166
  1743
    }
lestat@3166
  1744
slouken@2753
  1745
    if (format) {
slouken@2753
  1746
        if (!SDL_PixelFormatEnumToMasks
slouken@2753
  1747
            (format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
slouken@2753
  1748
            SDL_SetError("Unknown pixel format");
slouken@2753
  1749
            return 0;
slouken@2753
  1750
        }
slouken@2753
  1751
    } else {
slouken@2753
  1752
        if (surface->format->Amask
slouken@2753
  1753
            || !(surface->map->info.flags &
slouken@2753
  1754
                 (SDL_COPY_COLORKEY | SDL_COPY_MASK | SDL_COPY_BLEND))) {
slouken@3196
  1755
            Uint32 it;
lestat@3178
  1756
            int pfmt;
lestat@3178
  1757
lestat@3178
  1758
            /* Pixel formats, sorted by best first */
slouken@3186
  1759
            static const Uint32 sdl_pformats[] = {
slouken@3186
  1760
                SDL_PIXELFORMAT_ARGB8888,
slouken@3186
  1761
                SDL_PIXELFORMAT_RGBA8888,
slouken@3186
  1762
                SDL_PIXELFORMAT_ABGR8888,
slouken@3186
  1763
                SDL_PIXELFORMAT_BGRA8888,
slouken@3186
  1764
                SDL_PIXELFORMAT_RGB888,
slouken@3186
  1765
                SDL_PIXELFORMAT_BGR888,
slouken@3186
  1766
                SDL_PIXELFORMAT_RGB24,
slouken@3186
  1767
                SDL_PIXELFORMAT_BGR24,
slouken@3186
  1768
                SDL_PIXELFORMAT_RGB565,
slouken@3186
  1769
                SDL_PIXELFORMAT_BGR565,
slouken@3186
  1770
                SDL_PIXELFORMAT_ARGB1555,
slouken@3186
  1771
                SDL_PIXELFORMAT_ABGR1555,
slouken@3186
  1772
                SDL_PIXELFORMAT_RGB555,
slouken@3186
  1773
                SDL_PIXELFORMAT_BGR555,
slouken@3186
  1774
                SDL_PIXELFORMAT_ARGB4444,
slouken@3186
  1775
                SDL_PIXELFORMAT_ABGR4444,
slouken@3186
  1776
                SDL_PIXELFORMAT_RGB444,
slouken@3186
  1777
                SDL_PIXELFORMAT_ARGB2101010,
slouken@3186
  1778
                SDL_PIXELFORMAT_INDEX8,
slouken@3186
  1779
                SDL_PIXELFORMAT_INDEX4LSB,
slouken@3186
  1780
                SDL_PIXELFORMAT_INDEX4MSB,
slouken@3186
  1781
                SDL_PIXELFORMAT_RGB332,
slouken@3186
  1782
                SDL_PIXELFORMAT_INDEX1LSB,
slouken@3186
  1783
                SDL_PIXELFORMAT_INDEX1MSB,
slouken@3186
  1784
                SDL_PIXELFORMAT_UNKNOWN
slouken@3186
  1785
            };
lestat@3178
  1786
slouken@2753
  1787
            bpp = fmt->BitsPerPixel;
slouken@2753
  1788
            Rmask = fmt->Rmask;
slouken@2753
  1789
            Gmask = fmt->Gmask;
slouken@2753
  1790
            Bmask = fmt->Bmask;
slouken@2753
  1791
            Amask = fmt->Amask;
lestat@3178
  1792
slouken@3186
  1793
            format =
slouken@3186
  1794
                SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask);
lestat@3178
  1795
            if (!format) {
lestat@3178
  1796
                SDL_SetError("Unknown pixel format");
lestat@3178
  1797
                return 0;
lestat@3178
  1798
            }
lestat@3178
  1799
lestat@3178
  1800
            /* Search requested format in the supported texture */
lestat@3178
  1801
            /* formats by current renderer                      */
slouken@3186
  1802
            for (it = 0; it < renderer->info.num_texture_formats; it++) {
slouken@3186
  1803
                if (renderer->info.texture_formats[it] == format) {
slouken@3186
  1804
                    break;
lestat@3178
  1805
                }
lestat@3178
  1806
            }
lestat@3178
  1807
lestat@3178
  1808
            /* If requested format can't be found, search any best */
lestat@3178
  1809
            /* format which renderer provides                      */
slouken@3186
  1810
            if (it == renderer->info.num_texture_formats) {
slouken@3186
  1811
                pfmt = 0;
slouken@3186
  1812
                for (;;) {
slouken@3186
  1813
                    if (sdl_pformats[pfmt] == SDL_PIXELFORMAT_UNKNOWN) {
lestat@3178
  1814
                        break;
lestat@3178
  1815
                    }
lestat@3178
  1816
slouken@3186
  1817
                    for (it = 0; it < renderer->info.num_texture_formats;
slouken@3186
  1818
                         it++) {
slouken@3186
  1819
                        if (renderer->info.texture_formats[it] ==
slouken@3186
  1820
                            sdl_pformats[pfmt]) {
slouken@3186
  1821
                            break;
slouken@3186
  1822
                        }
lestat@3178
  1823
                    }
lestat@3178
  1824
slouken@3186
  1825
                    if (it != renderer->info.num_texture_formats) {
slouken@3186
  1826
                        /* The best format has been found */
slouken@3186
  1827
                        break;
lestat@3178
  1828
                    }
lestat@3178
  1829
                    pfmt++;
lestat@3178
  1830
                }
lestat@3178
  1831
lestat@3178
  1832
                /* If any format can't be found, then return an error */
slouken@3186
  1833
                if (it == renderer->info.num_texture_formats) {
slouken@3186
  1834
                    SDL_SetError
slouken@3186
  1835
                        ("Any of the supported pixel formats can't be found");
lestat@3178
  1836
                    return 0;
lestat@3178
  1837
                }
lestat@3178
  1838
lestat@3178
  1839
                /* Convert found pixel format back to color masks */
slouken@3186
  1840
                if (SDL_PixelFormatEnumToMasks
slouken@3186
  1841
                    (renderer->info.texture_formats[it], &bpp, &Rmask, &Gmask,
slouken@3186
  1842
                     &Bmask, &Amask) != SDL_TRUE) {
lestat@3178
  1843
                    SDL_SetError("Unknown pixel format");
lestat@3178
  1844
                    return 0;
lestat@3178
  1845
                }
lestat@3178
  1846
            }
slouken@2753
  1847
        } else {
slouken@2753
  1848
            /* Need a format with alpha */
slouken@3196
  1849
            Uint32 it;
lestat@3166
  1850
            int apfmt;
lestat@3166
  1851
lestat@3166
  1852
            /* Pixel formats with alpha, sorted by best first */
slouken@3169
  1853
            static const Uint32 sdl_alpha_pformats[] = {
slouken@3169
  1854
                SDL_PIXELFORMAT_ARGB8888,
slouken@3169
  1855
                SDL_PIXELFORMAT_RGBA8888,
slouken@3169
  1856
                SDL_PIXELFORMAT_ABGR8888,
slouken@3169
  1857
                SDL_PIXELFORMAT_BGRA8888,
slouken@3169
  1858
                SDL_PIXELFORMAT_ARGB1555,
slouken@3169
  1859
                SDL_PIXELFORMAT_ABGR1555,
slouken@3169
  1860
                SDL_PIXELFORMAT_ARGB4444,
slouken@3169
  1861
                SDL_PIXELFORMAT_ABGR4444,
slouken@3169
  1862
                SDL_PIXELFORMAT_ARGB2101010,
slouken@3169
  1863
                SDL_PIXELFORMAT_UNKNOWN
slouken@3169
  1864
            };
lestat@3166
  1865
lestat@3178
  1866
            if (surface->format->Amask) {
lestat@3178
  1867
                /* If surface already has alpha, then try an original */
lestat@3178
  1868
                /* surface format first                               */
lestat@3178
  1869
                bpp = fmt->BitsPerPixel;
lestat@3178
  1870
                Rmask = fmt->Rmask;
lestat@3178
  1871
                Gmask = fmt->Gmask;
lestat@3178
  1872
                Bmask = fmt->Bmask;
lestat@3178
  1873
                Amask = fmt->Amask;
lestat@3178
  1874
            } else {
lestat@3178
  1875
                bpp = 32;
lestat@3178
  1876
                Rmask = 0x00FF0000;
lestat@3178
  1877
                Gmask = 0x0000FF00;
lestat@3178
  1878
                Bmask = 0x000000FF;
lestat@3178
  1879
                Amask = 0xFF000000;
lestat@3178
  1880
            }
lestat@3166
  1881
slouken@3169
  1882
            format =
slouken@3169
  1883
                SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask);
lestat@3166
  1884
            if (!format) {
lestat@3166
  1885
                SDL_SetError("Unknown pixel format");
lestat@3166
  1886
                return 0;
lestat@3166
  1887
            }
lestat@3166
  1888
lestat@3166
  1889
            /* Search this format in the supported texture formats */
lestat@3166
  1890
            /* by current renderer                                 */
slouken@3169
  1891
            for (it = 0; it < renderer->info.num_texture_formats; it++) {
slouken@3169
  1892
                if (renderer->info.texture_formats[it] == format) {
slouken@3169
  1893
                    break;
lestat@3166
  1894
                }
lestat@3166
  1895
            }
lestat@3166
  1896
lestat@3166
  1897
            /* If this format can't be found, search any best       */
lestat@3166
  1898
            /* compatible format with alpha which renderer provides */
slouken@3169
  1899
            if (it == renderer->info.num_texture_formats) {
slouken@3169
  1900
                apfmt = 0;
slouken@3169
  1901
                for (;;) {
slouken@3169
  1902
                    if (sdl_alpha_pformats[apfmt] == SDL_PIXELFORMAT_UNKNOWN) {
lestat@3166
  1903
                        break;
lestat@3166
  1904
                    }
lestat@3166
  1905
slouken@3169
  1906
                    for (it = 0; it < renderer->info.num_texture_formats;
slouken@3169
  1907
                         it++) {
slouken@3169
  1908
                        if (renderer->info.texture_formats[it] ==
slouken@3169
  1909
                            sdl_alpha_pformats[apfmt]) {
slouken@3169
  1910
                            break;
slouken@3169
  1911
                        }
lestat@3166
  1912
                    }
lestat@3166
  1913
slouken@3169
  1914
                    if (it != renderer->info.num_texture_formats) {
slouken@3169
  1915
                        /* Compatible format has been found */
slouken@3169
  1916
                        break;
lestat@3166
  1917
                    }
lestat@3166
  1918
                    apfmt++;
lestat@3166
  1919
                }
lestat@3166
  1920
lestat@3166
  1921
                /* If compatible format can't be found, then return an error */
slouken@3169
  1922
                if (it == renderer->info.num_texture_formats) {
lestat@3166
  1923
                    SDL_SetError("Compatible pixel format can't be found");
lestat@3166
  1924
                    return 0;
lestat@3166
  1925
                }
lestat@3166
  1926
lestat@3166
  1927
                /* Convert found pixel format back to color masks */
slouken@3169
  1928
                if (SDL_PixelFormatEnumToMasks
slouken@3169
  1929
                    (renderer->info.texture_formats[it], &bpp, &Rmask, &Gmask,
slouken@3169
  1930
                     &Bmask, &Amask) != SDL_TRUE) {
lestat@3166
  1931
                    SDL_SetError("Unknown pixel format");
lestat@3166
  1932
                    return 0;
lestat@3166
  1933
                }
lestat@3166
  1934
            }
slouken@2753
  1935
        }
lestat@3166
  1936
slouken@2753
  1937
        format = SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask);
slouken@2753
  1938
        if (!format) {
slouken@2753
  1939
            SDL_SetError("Unknown pixel format");
slouken@2753
  1940
            return 0;
slouken@2753
  1941
        }
slouken@2753
  1942
    }
slouken@1895
  1943
slouken@2753
  1944
    textureID =
slouken@2753
  1945
        SDL_CreateTexture(format, SDL_TEXTUREACCESS_STATIC, surface->w,
slouken@2753
  1946
                          surface->h);
slouken@3057
  1947
    if (!textureID && !requested_format) {
slouken@3057
  1948
        SDL_DisplayMode desktop_mode;
slouken@3057
  1949
        SDL_GetDesktopDisplayMode(&desktop_mode);
slouken@3057
  1950
        format = desktop_mode.format;
slouken@3057
  1951
        textureID =
slouken@3057
  1952
            SDL_CreateTexture(format, SDL_TEXTUREACCESS_STATIC, surface->w,
slouken@3057
  1953
                              surface->h);
slouken@3057
  1954
    }
slouken@2753
  1955
    if (!textureID) {
slouken@2753
  1956
        return 0;
slouken@2753
  1957
    }
slouken@2753
  1958
    if (bpp == fmt->BitsPerPixel && Rmask == fmt->Rmask && Gmask == fmt->Gmask
slouken@2753
  1959
        && Bmask == fmt->Bmask && Amask == fmt->Amask) {
slouken@2753
  1960
        if (SDL_MUSTLOCK(surface)) {
slouken@3315
  1961
            SDL_LockSurface(surface);
slouken@2753
  1962
            SDL_UpdateTexture(textureID, NULL, surface->pixels,
slouken@2753
  1963
                              surface->pitch);
slouken@2753
  1964
            SDL_UnlockSurface(surface);
slouken@2753
  1965
        } else {
slouken@2753
  1966
            SDL_UpdateTexture(textureID, NULL, surface->pixels,
slouken@2753
  1967
                              surface->pitch);
slouken@2753
  1968
        }
slouken@2753
  1969
    } else {
slouken@2967
  1970
        SDL_PixelFormat dst_fmt;
slouken@2753
  1971
        SDL_Surface *dst = NULL;
slouken@1895
  1972
slouken@2753
  1973
        /* Set up a destination surface for the texture update */
slouken@2967
  1974
        SDL_InitFormat(&dst_fmt, bpp, Rmask, Gmask, Bmask, Amask);
slouken@2967
  1975
        if (SDL_ISPIXELFORMAT_INDEXED(format)) {
slouken@2967
  1976
            dst_fmt.palette =
slouken@2967
  1977
                SDL_AllocPalette((1 << SDL_BITSPERPIXEL(format)));
slouken@2967
  1978
            if (dst_fmt.palette) {
slouken@2967
  1979
                /*
slouken@2967
  1980
                 * FIXME: Should we try to copy
slouken@2967
  1981
                 * fmt->palette?
slouken@2967
  1982
                 */
slouken@2967
  1983
                SDL_DitherColors(dst_fmt.palette->colors,
slouken@2967
  1984
                                 SDL_BITSPERPIXEL(format));
slouken@2753
  1985
            }
slouken@2967
  1986
        }
slouken@2967
  1987
        dst = SDL_ConvertSurface(surface, &dst_fmt, 0);
slouken@2967
  1988
        if (dst) {
slouken@2967
  1989
            SDL_UpdateTexture(textureID, NULL, dst->pixels, dst->pitch);
slouken@2967
  1990
            SDL_FreeSurface(dst);
slouken@2967
  1991
        }
slouken@2967
  1992
        if (dst_fmt.palette) {
slouken@2967
  1993
            SDL_FreePalette(dst_fmt.palette);
slouken@2753
  1994
        }
slouken@2753
  1995
        if (!dst) {
slouken@2753
  1996
            SDL_DestroyTexture(textureID);
slouken@2753
  1997
            return 0;
slouken@2753
  1998
        }
slouken@2753
  1999
    }
slouken@2222
  2000
slouken@3053
  2001
    {
slouken@3053
  2002
        Uint8 r, g, b, a;
slouken@3053
  2003
        int blendMode;
slouken@3053
  2004
        int scaleMode;
slouken@3053
  2005
slouken@3053
  2006
        SDL_GetSurfaceColorMod(surface, &r, &g, &b);
slouken@3053
  2007
        SDL_SetTextureColorMod(textureID, r, g, b);
slouken@3053
  2008
slouken@3053
  2009
        SDL_GetSurfaceAlphaMod(surface, &a);
slouken@3053
  2010
        SDL_SetTextureAlphaMod(textureID, a);
slouken@3053
  2011
slouken@3053
  2012
        SDL_GetSurfaceBlendMode(surface, &blendMode);
slouken@3053
  2013
        SDL_SetTextureBlendMode(textureID, blendMode);
slouken@3053
  2014
slouken@3053
  2015
        SDL_GetSurfaceScaleMode(surface, &scaleMode);
slouken@3053
  2016
        SDL_SetTextureScaleMode(textureID, scaleMode);
slouken@3053
  2017
    }
slouken@3053
  2018
slouken@2753
  2019
    if (SDL_ISPIXELFORMAT_INDEXED(format) && fmt->palette) {
slouken@2753
  2020
        SDL_SetTexturePalette(textureID, fmt->palette->colors, 0,
slouken@2753
  2021
                              fmt->palette->ncolors);
slouken@2753
  2022
    }
slouken@2753
  2023
    return textureID;
slouken@1895
  2024
}
slouken@1895
  2025
slouken@1895
  2026
static __inline__ SDL_Texture *
slouken@1895
  2027
SDL_GetTextureFromID(SDL_TextureID textureID)
slouken@1895
  2028
{
slouken@2753
  2029
    int hash;
slouken@2753
  2030
    SDL_Texture *texture;
slouken@1895
  2031
slouken@2753
  2032
    if (!_this) {
slouken@2753
  2033
        return NULL;
slouken@2753
  2034
    }
slouken@2753
  2035
    hash = (textureID % SDL_arraysize(SDL_CurrentDisplay.textures));
slouken@2753
  2036
    for (texture = SDL_CurrentDisplay.textures[hash]; texture;
slouken@2753
  2037
         texture = texture->next) {
slouken@2753
  2038
        if (texture->id == textureID) {
slouken@2753
  2039
            return texture;
slouken@2753
  2040
        }
slouken@2753
  2041
    }
slouken@2753
  2042
    return NULL;
slouken@1895
  2043
}
slouken@1895
  2044
slouken@1895
  2045
int
slouken@1895
  2046
SDL_QueryTexture(SDL_TextureID textureID, Uint32 * format, int *access,
slouken@2753
  2047
                 int *w, int *h)
slouken@1895
  2048
{
slouken@2753
  2049
    SDL_Texture *texture = SDL_GetTextureFromID(textureID);
slouken@1895
  2050
slouken@2753
  2051
    if (!texture) {
slouken@2753
  2052
        return -1;
slouken@2753
  2053
    }
slouken@2753
  2054
    if (format) {
slouken@2753
  2055
        *format = texture->format;
slouken@2753
  2056
    }
slouken@2753
  2057
    if (access) {
slouken@2753
  2058
        *access = texture->access;
slouken@2753
  2059
    }
slouken@2753
  2060
    if (w) {
slouken@2753
  2061
        *w = texture->w;
slouken@2753
  2062
    }
slouken@2753
  2063
    if (h) {
slouken@2753
  2064
        *h = texture->h;
slouken@2753
  2065
    }
slouken@2753
  2066
    return 0;
slouken@1895
  2067
}
slouken@1895
  2068
slouken@1895
  2069
int
slouken@1895
  2070
SDL_QueryTexturePixels(SDL_TextureID textureID, void **pixels, int *pitch)
slouken@1895
  2071
{
slouken@2753
  2072
    SDL_Texture *texture = SDL_GetTextureFromID(textureID);
slouken@2753
  2073
    SDL_Renderer *renderer;
slouken@1895
  2074
slouken@2753
  2075
    if (!texture) {
slouken@2753
  2076
        return -1;
slouken@2753
  2077
    }
slouken@2753
  2078
    renderer = texture->renderer;
slouken@2753
  2079
    if (!renderer->QueryTexturePixels) {
slouken@2810
  2080
        SDL_Unsupported();
slouken@2753
  2081
        return -1;
slouken@2753
  2082
    }
slouken@2753
  2083
    return renderer->QueryTexturePixels(renderer, texture, pixels, pitch);
slouken@1895
  2084
}
slouken@1895
  2085
slouken@1895
  2086
int
slouken@1895
  2087
SDL_SetTexturePalette(SDL_TextureID textureID, const SDL_Color * colors,
slouken@2753
  2088
                      int firstcolor, int ncolors)
slouken@1895
  2089
{
slouken@2753
  2090
    SDL_Texture *texture = SDL_GetTextureFromID(textureID);
slouken@2753
  2091
    SDL_Renderer *renderer;
slouken@1895
  2092
slouken@2753
  2093
    if (!texture) {
slouken@2753
  2094
        return -1;
slouken@2753
  2095
    }
slouken@2753
  2096
    renderer = texture->renderer;
slouken@2753
  2097
    if (!renderer->SetTexturePalette) {
slouken@2810
  2098
        SDL_Unsupported();
slouken@2753
  2099
        return -1;
slouken@2753
  2100
    }
slouken@2753
  2101
    return renderer->SetTexturePalette(renderer, texture, colors, firstcolor,
slouken@2753
  2102
                                       ncolors);
slouken@1895
  2103
}
slouken@1895
  2104
slouken@1895
  2105
int
slouken@1895
  2106
SDL_GetTexturePalette(SDL_TextureID textureID, SDL_Color * colors,
slouken@2753
  2107
                      int firstcolor, int ncolors)
slouken@1895
  2108
{
slouken@2753
  2109
    SDL_Texture *texture = SDL_GetTextureFromID(textureID);
slouken@2753
  2110
    SDL_Renderer *renderer;
slouken@1895
  2111
slouken@2753
  2112
    if (!texture) {
slouken@2753
  2113
        return -1;
slouken@2753
  2114
    }
slouken@2753
  2115
    renderer = texture->renderer;
slouken@2753
  2116
    if (!renderer->GetTexturePalette) {
slouken@2810
  2117
        SDL_Unsupported();
slouken@2753
  2118
        return -1;
slouken@2753
  2119
    }
slouken@2753
  2120
    return renderer->GetTexturePalette(renderer, texture, colors, firstcolor,
slouken@2753
  2121
                                       ncolors);
slouken@1895
  2122
}
slouken@1895
  2123
slouken@1895
  2124
int
slouken@1985
  2125
SDL_SetTextureColorMod(SDL_TextureID textureID, Uint8 r, Uint8 g, Uint8 b)
slouken@1985
  2126
{
slouken@2753
  2127
    SDL_Texture *texture = SDL_GetTextureFromID(textureID);
slouken@2753
  2128
    SDL_Renderer *renderer;
slouken@1985
  2129
slouken@2753
  2130
    if (!texture) {
slouken@2753
  2131
        return -1;
slouken@2753
  2132
    }
slouken@2753
  2133
    renderer = texture->renderer;
slouken@2753
  2134
    if (!renderer->SetTextureColorMod) {
slouken@2810
  2135
        SDL_Unsupported();
slouken@2753
  2136
        return -1;
slouken@2753
  2137
    }
slouken@2753
  2138
    if (r < 255 || g < 255 || b < 255) {
slouken@2753
  2139
        texture->modMode |= SDL_TEXTUREMODULATE_COLOR;
slouken@2753
  2140
    } else {
slouken@2753
  2141
        texture->modMode &= ~SDL_TEXTUREMODULATE_COLOR;
slouken@2753
  2142
    }
slouken@2753
  2143
    texture->r = r;
slouken@2753
  2144
    texture->g = g;
slouken@2753
  2145
    texture->b = b;
slouken@2753
  2146
    return renderer->SetTextureColorMod(renderer, texture);
slouken@1985
  2147
}
slouken@1985
  2148
slouken@1985
  2149
int
slouken@1985
  2150
SDL_GetTextureColorMod(SDL_TextureID textureID, Uint8 * r, Uint8 * g,
slouken@2753
  2151
                       Uint8 * b)
slouken@1985
  2152
{
slouken@2753
  2153
    SDL_Texture *texture = SDL_GetTextureFromID(textureID);
slouken@2753
  2154
    SDL_Renderer *renderer;
slouken@1985
  2155
slouken@2753
  2156
    if (!texture) {
slouken@2753
  2157
        return -1;
slouken@2753
  2158
    }
slouken@2753
  2159
    renderer = texture->renderer;
slouken@2753
  2160
    if (r) {
slouken@2753
  2161
        *r = texture->r;
slouken@2753
  2162
    }
slouken@2753
  2163
    if (g) {
slouken@2753
  2164
        *g = texture->g;
slouken@2753
  2165
    }
slouken@2753
  2166
    if (b) {
slouken@2753
  2167
        *b = texture->b;
slouken@2753
  2168
    }
slouken@2753
  2169
    return 0;
slouken@1985
  2170
}
slouken@1985
  2171
slouken@1985
  2172
int
slouken@1985
  2173
SDL_SetTextureAlphaMod(SDL_TextureID textureID, Uint8 alpha)
slouken@1985
  2174
{
slouken@2753
  2175
    SDL_Texture *texture = SDL_GetTextureFromID(textureID);
slouken@2753
  2176
    SDL_Renderer *renderer;
slouken@1985
  2177
slouken@2753
  2178
    if (!texture) {
slouken@2753
  2179
        return -1;
slouken@2753
  2180
    }
slouken@2753
  2181
    renderer = texture->renderer;
slouken@2753
  2182
    if (!renderer->SetTextureAlphaMod) {
slouken@2810
  2183
        SDL_Unsupported();
slouken@2753
  2184
        return -1;
slouken@2753
  2185
    }
slouken@2753
  2186
    if (alpha < 255) {
slouken@2753
  2187
        texture->modMode |= SDL_TEXTUREMODULATE_ALPHA;
slouken@2753
  2188
    } else {
slouken@2753
  2189
        texture->modMode &= ~SDL_TEXTUREMODULATE_ALPHA;
slouken@2753
  2190
    }
slouken@2753
  2191
    texture->a = alpha;
slouken@2753
  2192
    return renderer->SetTextureAlphaMod(renderer, texture);
slouken@1985
  2193
}
slouken@1985
  2194
slouken@1985
  2195
int
slouken@1985
  2196
SDL_GetTextureAlphaMod(SDL_TextureID textureID, Uint8 * alpha)
slouken@1985
  2197
{
slouken@2753
  2198
    SDL_Texture *texture = SDL_GetTextureFromID(textureID);
slouken@1985
  2199
slouken@2753
  2200
    if (!texture) {
slouken@2753
  2201
        return -1;
slouken@2753
  2202
    }
slouken@2753
  2203
    if (alpha) {
slouken@2753
  2204
        *alpha = texture->a;
slouken@2753
  2205
    }
slouken@2753
  2206
    return 0;
slouken@1985
  2207
}
slouken@1985
  2208
slouken@1985
  2209
int
slouken@1985
  2210
SDL_SetTextureBlendMode(SDL_TextureID textureID, int blendMode)
slouken@1985
  2211
{
slouken@2753
  2212
    SDL_Texture *texture = SDL_GetTextureFromID(textureID);
slouken@2753
  2213
    SDL_Renderer *renderer;
slouken@1985
  2214
slouken@2753
  2215
    if (!texture) {
slouken@2753
  2216
        return -1;
slouken@2753
  2217
    }
slouken@2753
  2218
    renderer = texture->renderer;
slouken@2753
  2219
    if (!renderer->SetTextureBlendMode) {
slouken@2810
  2220
        SDL_Unsupported();
slouken@2753
  2221
        return -1;
slouken@2753
  2222
    }
slouken@2753
  2223
    texture->blendMode = blendMode;
slouken@2753
  2224
    return renderer->SetTextureBlendMode(renderer, texture);
slouken@1985
  2225
}
slouken@1985
  2226
slouken@1985
  2227
int
slouken@1985
  2228
SDL_GetTextureBlendMode(SDL_TextureID textureID, int *blendMode)
slouken@1985
  2229
{
slouken@2753
  2230
    SDL_Texture *texture = SDL_GetTextureFromID(textureID);
slouken@1985
  2231
slouken@2753
  2232
    if (!texture) {
slouken@2753
  2233
        return -1;
slouken@2753
  2234
    }
slouken@2753
  2235
    if (blendMode) {
slouken@2753
  2236
        *blendMode = texture->blendMode;
slouken@2753
  2237
    }
slouken@2753
  2238
    return 0;
slouken@1985
  2239
}
slouken@1985
  2240
slouken@1985
  2241
int
slouken@1985
  2242
SDL_SetTextureScaleMode(SDL_TextureID textureID, int scaleMode)
slouken@1985
  2243
{
slouken@2753
  2244
    SDL_Texture *texture = SDL_GetTextureFromID(textureID);
slouken@2753
  2245
    SDL_Renderer *renderer;
slouken@1985
  2246
slouken@2753
  2247
    if (!texture) {
slouken@2753
  2248
        return -1;
slouken@2753
  2249
    }
slouken@2753
  2250
    renderer = texture->renderer;
slouken@2753
  2251
    if (!renderer->SetTextureScaleMode) {
slouken@2810
  2252
        SDL_Unsupported();
slouken@2753
  2253
        return -1;
slouken@2753
  2254
    }
slouken@2753
  2255
    texture->scaleMode = scaleMode;
slouken@2753
  2256
    return renderer->SetTextureScaleMode(renderer, texture);
slouken@1985
  2257
}
slouken@1985
  2258
slouken@1985
  2259
int
slouken@1985
  2260
SDL_GetTextureScaleMode(SDL_TextureID textureID, int *scaleMode)
slouken@1985
  2261
{
slouken@2753
  2262
    SDL_Texture *texture = SDL_GetTextureFromID(textureID);
slouken@1985
  2263
slouken@2753
  2264
    if (!texture) {
slouken@2753
  2265
        return -1;
slouken@2753
  2266
    }
slouken@2753
  2267
    if (scaleMode) {
slouken@2753
  2268
        *scaleMode = texture->scaleMode;
slouken@2753
  2269
    }
slouken@2753
  2270
    return 0;
slouken@1985
  2271
}
slouken@1985
  2272
slouken@1985
  2273
int
slouken@1895
  2274
SDL_UpdateTexture(SDL_TextureID textureID, const SDL_Rect * rect,
slouken@2753
  2275
                  const void *pixels, int pitch)
slouken@1895
  2276
{
slouken@2753
  2277
    SDL_Texture *texture = SDL_GetTextureFromID(textureID);
slouken@2753
  2278
    SDL_Renderer *renderer;
slouken@2753
  2279
    SDL_Rect full_rect;
slouken@1895
  2280
slouken@2753
  2281
    if (!texture) {
slouken@2753
  2282
        return -1;
slouken@2753
  2283
    }
slouken@2753
  2284
    renderer = texture->renderer;
slouken@2753
  2285
    if (!renderer->UpdateTexture) {
slouken@2810
  2286
        SDL_Unsupported();
slouken@2753
  2287
        return -1;
slouken@2753
  2288
    }
slouken@2753
  2289
    if (!rect) {
slouken@2753
  2290
        full_rect.x = 0;
slouken@2753
  2291
        full_rect.y = 0;
slouken@2753
  2292
        full_rect.w = texture->w;
slouken@2753
  2293
        full_rect.h = texture->h;
slouken@2753
  2294
        rect = &full_rect;
slouken@2753
  2295
    }
slouken@2753
  2296
    return renderer->UpdateTexture(renderer, texture, rect, pixels, pitch);
slouken@1895
  2297
}
slouken@1895
  2298
slouken@1895
  2299
int
slouken@1895
  2300
SDL_LockTexture(SDL_TextureID textureID, const SDL_Rect * rect, int markDirty,
slouken@2753
  2301
                void **pixels, int *pitch)
slouken@1895
  2302
{
slouken@2753
  2303
    SDL_Texture *texture = SDL_GetTextureFromID(textureID);
slouken@2753
  2304
    SDL_Renderer *renderer;
slouken@2753
  2305
    SDL_Rect full_rect;
slouken@1895
  2306
slouken@2753
  2307
    if (!texture) {
slouken@2753
  2308
        return -1;
slouken@2753
  2309
    }
slouken@2753
  2310
    if (texture->access != SDL_TEXTUREACCESS_STREAMING) {
slouken@2753
  2311
        SDL_SetError("SDL_LockTexture(): texture must be streaming");
slouken@2753
  2312
        return -1;
slouken@2753
  2313
    }
slouken@2753
  2314
    renderer = texture->renderer;
slouken@2753
  2315
    if (!renderer->LockTexture) {
slouken@2810
  2316
        SDL_Unsupported();
slouken@2753
  2317
        return -1;
slouken@2753
  2318
    }
slouken@2753
  2319
    if (!rect) {
slouken@2753
  2320
        full_rect.x = 0;
slouken@2753
  2321
        full_rect.y = 0;
slouken@2753
  2322
        full_rect.w = texture->w;
slouken@2753
  2323
        full_rect.h = texture->h;
slouken@2753
  2324
        rect = &full_rect;
slouken@2753
  2325
    }
slouken@2753
  2326
    return renderer->LockTexture(renderer, texture, rect, markDirty, pixels,
slouken@2753
  2327
                                 pitch);
slouken@1895
  2328
}
slouken@1895
  2329
slouken@1895
  2330
void
slouken@1895
  2331
SDL_UnlockTexture(SDL_TextureID textureID)
slouken@1895
  2332
{
slouken@2753
  2333
    SDL_Texture *texture = SDL_GetTextureFromID(textureID);
slouken@2753
  2334
    SDL_Renderer *renderer;
slouken@1895
  2335
slouken@2753
  2336
    if (!texture) {
slouken@2753
  2337
        return;
slouken@2753
  2338
    }
slouken@2753
  2339
    if (texture->access != SDL_TEXTUREACCESS_STREAMING) {
slouken@2753
  2340
        return;
slouken@2753
  2341
    }
slouken@2753
  2342
    renderer = texture->renderer;
slouken@2753
  2343
    if (!renderer->UnlockTexture) {
slouken@2753
  2344
        return;
slouken@2753
  2345
    }
slouken@2753
  2346
    renderer->UnlockTexture(renderer, texture);
slouken@1895
  2347
}
slouken@1895
  2348
slouken@1895
  2349
void
slouken@1895
  2350
SDL_DirtyTexture(SDL_TextureID textureID, int numrects,
slouken@2753
  2351
                 const SDL_Rect * rects)
slouken@1895
  2352
{
slouken@2753
  2353
    SDL_Texture *texture = SDL_GetTextureFromID(textureID);
slouken@2753
  2354
    SDL_Renderer *renderer;
slouken@1895
  2355
slouken@2753
  2356
    if (!texture) {
slouken@2753
  2357
        return;
slouken@2753
  2358
    }
slouken@2753
  2359
    if (texture->access != SDL_TEXTUREACCESS_STREAMING) {
slouken@2753
  2360
        return;
slouken@2753
  2361
    }
slouken@2753
  2362
    renderer = texture->renderer;
slouken@2753
  2363
    if (!renderer->DirtyTexture) {
slouken@2753
  2364
        return;
slouken@2753
  2365
    }
slouken@2753
  2366
    renderer->DirtyTexture(renderer, texture, numrects, rects);
slouken@1895
  2367
}
slouken@1895
  2368
slouken@1895
  2369
int
slouken@2884
  2370
SDL_SetRenderDrawColor(Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@2884
  2371
{
slouken@2884
  2372
    SDL_Renderer *renderer;
slouken@2884
  2373
slouken@3485
  2374
    renderer = SDL_GetCurrentRenderer(SDL_TRUE);
slouken@2884
  2375
    if (!renderer) {
slouken@2884
  2376
        return -1;
slouken@2884
  2377
    }
slouken@2884
  2378
    renderer->r = r;
slouken@2884
  2379
    renderer->g = g;
slouken@2884
  2380
    renderer->b = b;
slouken@2884
  2381
    renderer->a = a;
slouken@2927
  2382
    if (renderer->SetDrawColor) {
slouken@2927
  2383
        return renderer->SetDrawColor(renderer);
slouken@2927
  2384
    } else {
slouken@2927
  2385
        return 0;
slouken@2927
  2386
    }
slouken@2884
  2387
}
slouken@2884
  2388
slouken@2884
  2389
int
slouken@2885
  2390
SDL_GetRenderDrawColor(Uint8 * r, Uint8 * g, Uint8 * b, Uint8 * a)
slouken@2884
  2391
{
slouken@2884
  2392
    SDL_Renderer *renderer;
slouken@2884
  2393
slouken@3485
  2394
    renderer = SDL_GetCurrentRenderer(SDL_TRUE);
slouken@2884
  2395
    if (!renderer) {
slouken@2884
  2396
        return -1;
slouken@2884
  2397
    }
slouken@2884
  2398
    if (r) {
slouken@2884
  2399
        *r = renderer->r;
slouken@2884
  2400
    }
slouken@2884
  2401
    if (g) {
slouken@2884
  2402
        *g = renderer->g;
slouken@2884
  2403
    }
slouken@2884
  2404
    if (b) {
slouken@2884
  2405
        *b = renderer->b;
slouken@2884
  2406
    }
slouken@2884
  2407
    if (a) {
slouken@2884
  2408
        *a = renderer->a;
slouken@2884
  2409
    }
slouken@2928
  2410
    return 0;
slouken@2884
  2411
}
slouken@2884
  2412
slouken@2884
  2413
int
slouken@2884
  2414
SDL_SetRenderDrawBlendMode(int blendMode)
slouken@2884
  2415
{
slouken@2884
  2416
    SDL_Renderer *renderer;
slouken@2884
  2417
slouken@3485
  2418
    renderer = SDL_GetCurrentRenderer(SDL_TRUE);
slouken@2884
  2419
    if (!renderer) {
slouken@2884
  2420
        return -1;
slouken@2884
  2421
    }
slouken@2927
  2422
    renderer->blendMode = blendMode;
slouken@2927
  2423
    if (renderer->SetDrawBlendMode) {
slouken@2927
  2424
        return renderer->SetDrawBlendMode(renderer);
slouken@2927
  2425
    } else {
slouken@2927
  2426
        return 0;
slouken@2884
  2427
    }
slouken@2884
  2428
}
slouken@2884
  2429
slouken@2884
  2430
int
slouken@2884
  2431
SDL_GetRenderDrawBlendMode(int *blendMode)
slouken@2884
  2432
{
slouken@2884
  2433
    SDL_Renderer *renderer;
slouken@2884
  2434
slouken@3485
  2435
    renderer = SDL_GetCurrentRenderer(SDL_TRUE);
slouken@2884
  2436
    if (!renderer) {
slouken@2884
  2437
        return -1;
slouken@2884
  2438
    }
slouken@2884
  2439
    *blendMode = renderer->blendMode;
slouken@2884
  2440
    return 0;
slouken@2884
  2441
}
slouken@2884
  2442
slouken@2901
  2443
int
slouken@2901
  2444
SDL_RenderPoint(int x, int y)
slouken@2901
  2445
{
slouken@2901
  2446
    SDL_Renderer *renderer;
slouken@2901
  2447
    SDL_Window *window;
slouken@2901
  2448
slouken@3485
  2449
    renderer = SDL_GetCurrentRenderer(SDL_TRUE);
slouken@2901
  2450
    if (!renderer) {
slouken@2901
  2451
        return -1;
slouken@2901
  2452
    }
slouken@2901
  2453
    if (!renderer->RenderPoint) {
slouken@2901
  2454
        SDL_Unsupported();
slouken@2901
  2455
        return -1;
slouken@2901
  2456
    }
slouken@2901
  2457
    window = SDL_GetWindowFromID(renderer->window);
slouken@2901
  2458
    if (x < 0 || y < 0 || x >= window->w || y >= window->h) {
slouken@2901
  2459
        return 0;
slouken@2901
  2460
    }
slouken@2901
  2461
    return renderer->RenderPoint(renderer, x, y);
slouken@2901
  2462
}
slouken@2901
  2463
slouken@2901
  2464
int
slouken@2901
  2465
SDL_RenderLine(int x1, int y1, int x2, int y2)
slouken@2901
  2466
{
slouken@2901
  2467
    SDL_Renderer *renderer;
slouken@2901
  2468
    SDL_Window *window;
slouken@2901
  2469
    SDL_Rect real_rect;
slouken@2901
  2470
slouken@2901
  2471
    if (x1 == x2 && y1 == y2) {
slouken@2901
  2472
        return SDL_RenderPoint(x1, y1);
slouken@2901
  2473
    }
slouken@2901
  2474
slouken@3485
  2475
    renderer = SDL_GetCurrentRenderer(SDL_TRUE);
slouken@2901
  2476
    if (!renderer) {
slouken@2901
  2477
        return -1;
slouken@2901
  2478
    }
slouken@2901
  2479
    if (!renderer->RenderLine) {
slouken@2901
  2480
        SDL_Unsupported();
slouken@2901
  2481
        return -1;
slouken@2901
  2482
    }
slouken@2901
  2483
    window = SDL_GetWindowFromID(renderer->window);
slouken@2909
  2484
slouken@2901
  2485
    real_rect.x = 0;
slouken@2901
  2486
    real_rect.y = 0;
slouken@2901
  2487
    real_rect.w = window->w;
slouken@2901
  2488
    real_rect.h = window->h;
slouken@2910
  2489
    if (!SDL_IntersectRectAndLine(&real_rect, &x1, &y1, &x2, &y2)) {
slouken@2909
  2490
        return (0);
slouken@2901
  2491
    }
slouken@2901
  2492
    return renderer->RenderLine(renderer, x1, y1, x2, y2);
slouken@2901
  2493
}
slouken@2884
  2494
slouken@2884
  2495
int
slouken@2884
  2496
SDL_RenderFill(const SDL_Rect * rect)
slouken@1895
  2497
{
slouken@2753
  2498
    SDL_Renderer *renderer;
slouken@2753
  2499
    SDL_Window *window;
slouken@2753
  2500
    SDL_Rect real_rect;
slouken@1895
  2501
slouken@3485
  2502
    renderer = SDL_GetCurrentRenderer(SDL_TRUE);
slouken@2810
  2503
    if (!renderer) {
slouken@2810
  2504
        return -1;
slouken@2810
  2505
    }
slouken@2814
  2506
    if (!renderer->RenderFill) {
slouken@2810
  2507
        SDL_Unsupported();
slouken@2753
  2508
        return -1;
slouken@2753
  2509
    }
slouken@2753
  2510
    window = SDL_GetWindowFromID(renderer->window);
slouken@2908
  2511
slouken@2753
  2512
    real_rect.x = 0;
slouken@2753
  2513
    real_rect.y = 0;
slouken@2753
  2514
    real_rect.w = window->w;
slouken@2753
  2515
    real_rect.h = window->h;
slouken@2753
  2516
    if (rect) {
slouken@2753
  2517
        if (!SDL_IntersectRect(rect, &real_rect, &real_rect)) {
slouken@2753
  2518
            return 0;
slouken@2753
  2519
        }
slouken@2753
  2520
    }
slouken@2884
  2521
    return renderer->RenderFill(renderer, &real_rect);
slouken@2884
  2522
}
slouken@2884
  2523
slouken@2884
  2524
int
slouken@1895
  2525
SDL_RenderCopy(SDL_TextureID textureID, const SDL_Rect * srcrect,
slouken@2753
  2526
               const SDL_Rect * dstrect)
slouken@1895
  2527
{
slouken@2753
  2528
    SDL_Texture *texture = SDL_GetTextureFromID(textureID);
slouken@2753
  2529
    SDL_Renderer *renderer;
slouken@2753
  2530
    SDL_Window *window;
slouken@2753
  2531
    SDL_Rect real_srcrect;
slouken@2753
  2532
    SDL_Rect real_dstrect;
slouken@1895
  2533
slouken@3485
  2534
    renderer = SDL_GetCurrentRenderer(SDL_TRUE);
slouken@3316
  2535
    if (!renderer) {
slouken@2753
  2536
        return -1;
slouken@2753
  2537
    }
slouken@3316
  2538
    if (!texture) {
slouken@3316
  2539
        SDL_SetError("Texture not found");
slouken@3316
  2540
        return -1;
slouken@3316
  2541
    }
slouken@3316
  2542
    if (texture->renderer != renderer) {
slouken@3316
  2543
        SDL_SetError("Texture was not created with this renderer");
slouken@2810
  2544
        return -1;
slouken@2810
  2545
    }
slouken@2810
  2546
    if (!renderer->RenderCopy) {
slouken@2810
  2547
        SDL_Unsupported();
slouken@2753
  2548
        return -1;
slouken@2753
  2549
    }
slouken@2753
  2550
    window = SDL_GetWindowFromID(renderer->window);
slouken@2908
  2551
slouken@2908
  2552
    real_srcrect.x = 0;
slouken@2908
  2553
    real_srcrect.y = 0;
slouken@2908
  2554
    real_srcrect.w = texture->w;
slouken@2908
  2555
    real_srcrect.h = texture->h;
slouken@2753
  2556
    if (srcrect) {
slouken@2908
  2557
        if (!SDL_IntersectRect(srcrect, &real_srcrect, &real_srcrect)) {
slouken@2908
  2558
            return 0;
slouken@2908
  2559
        }
slouken@2753
  2560
    }
slouken@2908
  2561
slouken@2908
  2562
    real_dstrect.x = 0;
slouken@2908
  2563
    real_dstrect.y = 0;
slouken@2908
  2564
    real_dstrect.w = window->w;
slouken@2908
  2565
    real_dstrect.h = window->h;
slouken@2753
  2566
    if (dstrect) {
slouken@2908
  2567
        if (!SDL_IntersectRect(dstrect, &real_dstrect, &real_dstrect)) {
slouken@2908
  2568
            return 0;
slouken@2908
  2569
        }
slouken@2912
  2570
        /* Clip srcrect by the same amount as dstrect was clipped */
slouken@2912
  2571
        if (dstrect->w != real_dstrect.w) {
slouken@2912
  2572
            int deltax = (real_dstrect.x - dstrect->x);
slouken@2912
  2573
            int deltaw = (real_dstrect.w - dstrect->w);
slouken@3333
  2574
            real_srcrect.x += (deltax * real_srcrect.w) / dstrect->w;
slouken@3333
  2575
            real_srcrect.w += (deltaw * real_srcrect.w) / dstrect->w;
slouken@2912
  2576
        }
slouken@2912
  2577
        if (dstrect->h != real_dstrect.h) {
slouken@2912
  2578
            int deltay = (real_dstrect.y - dstrect->y);
slouken@2912
  2579
            int deltah = (real_dstrect.h - dstrect->h);
slouken@3333
  2580
            real_srcrect.y += (deltay * real_srcrect.h) / dstrect->h;
slouken@3333
  2581
            real_srcrect.h += (deltah * real_srcrect.h) / dstrect->h;
slouken@2912
  2582
        }
slouken@2753
  2583
    }
slouken@1895
  2584
slouken@2753
  2585
    return renderer->RenderCopy(renderer, texture, &real_srcrect,
slouken@2753
  2586
                                &real_dstrect);
slouken@1895
  2587
}
slouken@1895
  2588
slouken@3427
  2589
int
slouken@3435
  2590
SDL_RenderReadPixels(const SDL_Rect * rect, Uint32 format,
slouken@3435
  2591
                     void * pixels, int pitch)
slouken@3427
  2592
{
slouken@3427
  2593
    SDL_Renderer *renderer;
slouken@3427
  2594
    SDL_Window *window;
slouken@3427
  2595
    SDL_Rect real_rect;
slouken@3427
  2596
slouken@3485
  2597
    renderer = SDL_GetCurrentRenderer(SDL_TRUE);
slouken@3427
  2598
    if (!renderer) {
slouken@3427
  2599
        return -1;
slouken@3427
  2600
    }
slouken@3427
  2601
    if (!renderer->RenderReadPixels) {
slouken@3427
  2602
        SDL_Unsupported();
slouken@3427
  2603
        return -1;
slouken@3427
  2604
    }
slouken@3427
  2605
    window = SDL_GetWindowFromID(renderer->window);
slouken@3427
  2606
slouken@3435
  2607
    if (!format) {
slouken@3435
  2608
        format = SDL_GetDisplayFromWindow(window)->current_mode.format;
slouken@3435
  2609
    }
slouken@3435
  2610
slouken@3427
  2611
    real_rect.x = 0;
slouken@3427
  2612
    real_rect.y = 0;
slouken@3427
  2613
    real_rect.w = window->w;
slouken@3427
  2614
    real_rect.h = window->h;
slouken@3427
  2615
    if (rect) {
slouken@3427
  2616
        if (!SDL_IntersectRect(rect, &real_rect, &real_rect)) {
slouken@3427
  2617
            return 0;
slouken@3427
  2618
        }
slouken@3427
  2619
        if (real_rect.y > rect->y) {
slouken@3427
  2620
            pixels = (Uint8 *)pixels + pitch * (real_rect.y - rect->y);
slouken@3427
  2621
        }
slouken@3427
  2622
        if (real_rect.x > rect->x) {
slouken@3427
  2623
            Uint32 format = SDL_CurrentDisplay.current_mode.format;
slouken@3427
  2624
            int bpp = SDL_BYTESPERPIXEL(format);
slouken@3427
  2625
            pixels = (Uint8 *)pixels + bpp * (real_rect.x - rect->x);
slouken@3427
  2626
        }
slouken@3427
  2627
    }
slouken@3427
  2628
slouken@3435
  2629
    return renderer->RenderReadPixels(renderer, &real_rect,
slouken@3435
  2630
                                      format, pixels, pitch);
slouken@3427
  2631
}
slouken@3427
  2632
slouken@3427
  2633
int
slouken@3435
  2634
SDL_RenderWritePixels(const SDL_Rect * rect, Uint32 format,
slouken@3435
  2635
                      const void * pixels, int pitch)
slouken@3427
  2636
{
slouken@3427
  2637
    SDL_Renderer *renderer;
slouken@3427
  2638
    SDL_Window *window;
slouken@3427
  2639
    SDL_Rect real_rect;
slouken@3427
  2640
slouken@3485
  2641
    renderer = SDL_GetCurrentRenderer(SDL_TRUE);
slouken@3427
  2642
    if (!renderer) {
slouken@3427
  2643
        return -1;
slouken@3427
  2644
    }
slouken@3427
  2645
    if (!renderer->RenderWritePixels) {
slouken@3427
  2646
        SDL_Unsupported();
slouken@3427
  2647
        return -1;
slouken@3427
  2648
    }
slouken@3427
  2649
    window = SDL_GetWindowFromID(renderer->window);
slouken@3427
  2650
slouken@3435
  2651
    if (!format) {
slouken@3435
  2652
        format = SDL_GetDisplayFromWindow(window)->current_mode.format;
slouken@3435
  2653
    }
slouken@3435
  2654
slouken@3427
  2655
    real_rect.x = 0;
slouken@3427
  2656
    real_rect.y = 0;
slouken@3427
  2657
    real_rect.w = window->w;
slouken@3427
  2658
    real_rect.h = window->h;
slouken@3427
  2659
    if (rect) {
slouken@3427
  2660
        if (!SDL_IntersectRect(rect, &real_rect, &real_rect)) {
slouken@3427
  2661
            return 0;
slouken@3427
  2662
        }
slouken@3427
  2663
        if (real_rect.y > rect->y) {
slouken@3427
  2664
            pixels = (const Uint8 *)pixels + pitch * (real_rect.y - rect->y);
slouken@3427
  2665
        }
slouken@3427
  2666
        if (real_rect.x > rect->x) {
slouken@3427
  2667
            Uint32 format = SDL_CurrentDisplay.current_mode.format;
slouken@3427
  2668
            int bpp = SDL_BYTESPERPIXEL(format);
slouken@3427
  2669
            pixels = (const Uint8 *)pixels + bpp * (real_rect.x - rect->x);
slouken@3427
  2670
        }
slouken@3427
  2671
    }
slouken@3427
  2672
slouken@3435
  2673
    return renderer->RenderWritePixels(renderer, &real_rect,
slouken@3435
  2674
                                       format, pixels, pitch);
slouken@3427
  2675
}
slouken@3427
  2676
slouken@1895
  2677
void
slouken@1895
  2678
SDL_RenderPresent(void)
slouken@1895
  2679
{
slouken@2753
  2680
    SDL_Renderer *renderer;
slouken@1895
  2681
slouken@3485
  2682
    renderer = SDL_GetCurrentRenderer(SDL_TRUE);
slouken@2753
  2683
    if (!renderer || !renderer->RenderPresent) {
slouken@2753
  2684
        return;
slouken@2753
  2685
    }
slouken@2753
  2686
    renderer->RenderPresent(renderer);
slouken@1895
  2687
}
slouken@1895
  2688
slouken@1895
  2689
void
slouken@1895
  2690
SDL_DestroyTexture(SDL_TextureID textureID)
slouken@1895
  2691
{
slouken@2753
  2692
    int hash;
slouken@2753
  2693
    SDL_Texture *prev, *texture;
slouken@2753
  2694
    SDL_Renderer *renderer;
slouken@1895
  2695
slouken@2753
  2696
    if (!_this) {
slouken@2753
  2697
        SDL_UninitializedVideo();
slouken@2753
  2698
        return;
slouken@2753
  2699
    }
slouken@2753
  2700
    /* Look up the texture in the hash table */
slouken@2753
  2701
    hash = (textureID % SDL_arraysize(SDL_CurrentDisplay.textures));
slouken@2753
  2702
    prev = NULL;
slouken@2753
  2703
    for (texture = SDL_CurrentDisplay.textures[hash]; texture;
slouken@2753
  2704
         prev = texture, texture = texture->next) {
slouken@2753
  2705
        if (texture->id == textureID) {
slouken@2753
  2706
            break;
slouken@2753
  2707
        }
slouken@2753
  2708
    }
slouken@2753
  2709
    if (!texture) {
slouken@2753
  2710
        return;
slouken@2753
  2711
    }
slouken@2753
  2712
    /* Unlink the texture from the list */
slouken@2753
  2713
    if (prev) {
slouken@2753
  2714
        prev->next = texture->next;
slouken@2753
  2715
    } else {
slouken@2753
  2716
        SDL_CurrentDisplay.textures[hash] = texture->next;
slouken@2753
  2717
    }
slouken@1895
  2718
slouken@2753
  2719
    /* Free the texture */
slouken@2753
  2720
    renderer = texture->renderer;
slouken@2753
  2721
    renderer->DestroyTexture(renderer, texture);
slouken@2753
  2722
    SDL_free(texture);
slouken@1895
  2723
}
slouken@1895
  2724
slouken@1895
  2725
void
slouken@1895
  2726
SDL_DestroyRenderer(SDL_WindowID windowID)
slouken@1895
  2727
{
slouken@2753
  2728
    SDL_Window *window = SDL_GetWindowFromID(windowID);
slouken@2753
  2729
    SDL_Renderer *renderer;
slouken@2753
  2730
    int i;
slouken@1895
  2731
slouken@2753
  2732
    if (!window) {
slouken@2753
  2733
        return;
slouken@2753
  2734
    }
slouken@2753
  2735
    renderer = window->renderer;
slouken@2753
  2736
    if (!renderer) {
slouken@2753
  2737
        return;
slouken@2753
  2738
    }
slouken@2753
  2739
    /* Free existing textures for this renderer */
slouken@2753
  2740
    for (i = 0; i < SDL_arraysize(SDL_CurrentDisplay.textures); ++i) {
slouken@2753
  2741
        SDL_Texture *texture;
slouken@2753
  2742
        SDL_Texture *prev = NULL;
slouken@2753
  2743
        SDL_Texture *next;
slouken@2753
  2744
        for (texture = SDL_CurrentDisplay.textures[i]; texture;
slouken@2753
  2745
             texture = next) {
slouken@2753
  2746
            next = texture->next;
slouken@2753
  2747
            if (texture->renderer == renderer) {
slouken@2753
  2748
                if (prev) {
slouken@2753
  2749
                    prev->next = next;
slouken@2753
  2750
                } else {
slouken@2753
  2751
                    SDL_CurrentDisplay.textures[i] = next;
slouken@2753
  2752
                }
slouken@2753
  2753
                renderer->DestroyTexture(renderer, texture);
slouken@2753
  2754
                SDL_free(texture);
slouken@2753
  2755
            } else {
slouken@2753
  2756
                prev = texture;
slouken@2753
  2757
            }
slouken@2753
  2758
        }
slouken@2753
  2759
    }
slouken@1895
  2760
slouken@2753
  2761
    /* Free the renderer instance */
slouken@2753
  2762
    renderer->DestroyRenderer(renderer);
slouken@1895
  2763
slouken@2753
  2764
    /* Clear references */
slouken@2753
  2765
    window->renderer = NULL;
slouken@2753
  2766
    if (SDL_CurrentDisplay.current_renderer == renderer) {
slouken@2753
  2767
        SDL_CurrentDisplay.current_renderer = NULL;
slouken@2753
  2768
    }
slouken@1895
  2769
}
slouken@1895
  2770
slouken@3025
  2771
SDL_bool
slouken@3025
  2772
SDL_IsScreenSaverEnabled()
slouken@3025
  2773
{
slouken@3025
  2774
    if (!_this) {
slouken@3025
  2775
        return SDL_TRUE;
slouken@3025
  2776
    }
slouken@3025
  2777
    return _this->suspend_screensaver ? SDL_FALSE : SDL_TRUE;
slouken@3025
  2778
}
slouken@3025
  2779
slouken@3025
  2780
void
slouken@3025
  2781
SDL_EnableScreenSaver()
slouken@3025
  2782
{
slouken@3025
  2783
    if (!_this) {
slouken@3025
  2784
        return;
slouken@3025
  2785
    }
slouken@3025
  2786
    if (!_this->suspend_screensaver) {
slouken@3025
  2787
        return;
slouken@3025
  2788
    }
slouken@3025
  2789
    _this->suspend_screensaver = SDL_FALSE;
slouken@3025
  2790
    if (_this->SuspendScreenSaver) {