src/video/SDL_video.c
author Sam Lantinga <slouken@libsdl.org>
Tue, 24 Mar 2009 10:43:53 +0000
changeset 3100 7dc982143c06
parent 3099 82e60908fab1
child 3130 fef1a835af43
child 3139 7f684f249ec9
permissions -rw-r--r--
Date: Sun, 22 Mar 2009 12:52:29 +0000
From: Luke Benstead
Subject: OpenGL 3.0 Context Creation

I've attached a patch which implements OpenGL 3.x context creation on
the latest SVN. I've added two options to SDL_GL_SetAttribute, these
are SDL_GL_CONTEXT_MAJOR_VERSION and SDL_GL_CONTEXT_MINOR_VERSION.
These default to 2 and 1 respectively. If the major version is less
than 3 then the current context creation method is used, otherwise the
appropriate new context creation function is called (depending on the
platform).

Sample code:

if (SDL_Init(SDL_INIT_VIDEO) != 0) {
printf("Unable to initialize SDL: %s\n", SDL_GetError());
return 1;
}

SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); //Without these 2 lines, SDL will create a GL 2.x context
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

SDL_Surface* screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL | SDL_FULLSCREEN );


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