src/video/SDL_video.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 07 Jul 2010 23:54:03 -0700
changeset 4495 dbbfdb9ea716
parent 4472 791b3256fb22
child 4526 c04dd942610d
permissions -rw-r--r--
Simplified clipboard API for sanity's sake.

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