src/video/SDL_video.c
author Sam Lantinga <slouken@libsdl.org>
Sat, 20 Dec 2008 12:00:00 +0000
changeset 2884 9dde605c7540
parent 2876 3fcb0d447bcd
child 2885 ca6499468250
permissions -rw-r--r--
Date: Fri, 19 Dec 2008 20:17:35 +0100
From: Couriersud
Subject: Re: Aw: Experience using SDL1.3 in sdlmame/Proposal for api additions

> For consistency you'd probably want:
> SDL_SetRenderDrawColor(Uint8 r, Uint8 g, Uint8 b, Uint8 a);
> SDL_SetRenderDrawBlendMode(SDL_BlendMode blendMode);
> SDL_RenderLine(int x1, int y1, int x2, int y2);
> SDL_RenderFill(SDL_Rect *rect);
>
> You probably also want to add API functions query the current state.
>

I have implemented the above api for the opengl, x11, directfb and
software renderers. I have also renamed *TEXTUREBLENDMODE* constants to
BLENDMODE*. The unix build compiles. The windows renderer still needs to
be updated, but I have no windows development machine at hand. Have a
look at the x11 renderer for a sample.

Vector games now run at 90% both on opengl and directfb in comparison to
sdlmame's own opengl renderer. The same applies to raster games.

The diff also includes

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