src/video/SDL_video.c
author Sam Lantinga <slouken@libsdl.org>
Tue, 03 Mar 2009 04:21:51 +0000
changeset 3083 0bc41e0361d3
parent 3058 17c5930f498e
child 3091 32efcc94b3da
permissions -rw-r--r--
Date: Mon, 2 Mar 2009 16:27:42 +0200
From: "Mike Gorchak"
Subject: About QNX support in SDL 1.3

Right now I'm working on QNX SDL 1.3 drivers implementation and looks like a
lot of code must be completely reworked. But I'm ready for it :) Also I want
to add QNX Graphics Framework SDL driver, which is fullscreen graphics
framework, with support of hardware accelerated OpenGL ES implementations.
This Graphics Framework (called GF in QNX) could also use QNX Photon (window
manager GUI) as window manager.

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