src/video/SDL_video.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 03 Feb 2011 21:13:55 -0800
changeset 5169 ededa1ccf91c
parent 5168 db487f28419e
child 5172 51b4cfdf7ebb
permissions -rw-r--r--
Switched the SDL 1.2 compatibility to use the window surface, so it's fast even when there's no hardware acceleration available.
This means that the YUV overlay now uses software, but that's okay since fast YUV code should be using the textures now anyway.
slouken@0
     1
/*
slouken@0
     2
    SDL - Simple DirectMedia Layer
slouken@3697
     3
    Copyright (C) 1997-2010 Sam Lantinga
slouken@0
     4
slouken@0
     5
    This library is free software; you can redistribute it and/or
slouken@1312
     6
    modify it under the terms of the GNU Lesser General Public
slouken@0
     7
    License as published by the Free Software Foundation; either
slouken@1312
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@0
     9
slouken@0
    10
    This library is distributed in the hope that it will be useful,
slouken@0
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@0
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1312
    13
    Lesser General Public License for more details.
slouken@0
    14
slouken@1312
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1312
    16
    License along with this library; if not, write to the Free Software
slouken@1312
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@0
    18
slouken@0
    19
    Sam Lantinga
slouken@252
    20
    slouken@libsdl.org
slouken@0
    21
*/
slouken@1402
    22
#include "SDL_config.h"
slouken@0
    23
slouken@0
    24
/* The high-level video driver subsystem */
slouken@0
    25
slouken@2999
    26
#include "SDL.h"
slouken@2984
    27
#include "SDL_video.h"
slouken@0
    28
#include "SDL_sysvideo.h"
slouken@0
    29
#include "SDL_blit.h"
slouken@0
    30
#include "SDL_pixels_c.h"
slouken@1361
    31
#include "../events/SDL_events_c.h"
slouken@0
    32
hfutrell@2745
    33
#if SDL_VIDEO_OPENGL_ES
hfutrell@2745
    34
#include "SDL_opengles.h"
slouken@2753
    35
#endif /* SDL_VIDEO_OPENGL_ES */
hfutrell@2745
    36
slouken@1926
    37
#if SDL_VIDEO_OPENGL
slouken@1926
    38
#include "SDL_opengl.h"
slouken@4900
    39
#endif /* SDL_VIDEO_OPENGL */
slouken@4900
    40
slouken@4900
    41
#include "SDL_syswm.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@1926
    47
slouken@0
    48
/* Available video drivers */
lestat@3166
    49
static VideoBootStrap *bootstrap[] = {
slouken@1931
    50
#if SDL_VIDEO_DRIVER_COCOA
slouken@2753
    51
    &COCOA_bootstrap,
icculus@1133
    52
#endif
slouken@1361
    53
#if SDL_VIDEO_DRIVER_X11
slouken@2753
    54
    &X11_bootstrap,
slouken@0
    55
#endif
slouken@1361
    56
#if SDL_VIDEO_DRIVER_DIRECTFB
slouken@2753
    57
    &DirectFB_bootstrap,
slouken@167
    58
#endif
slouken@5062
    59
#if SDL_VIDEO_DRIVER_WINDOWS
slouken@5062
    60
    &WINDOWS_bootstrap,
slouken@1361
    61
#endif
slouken@1361
    62
#if SDL_VIDEO_DRIVER_BWINDOW
slouken@2753
    63
    &BWINDOW_bootstrap,
slouken@1361
    64
#endif
slouken@5150
    65
#if SDL_VIDEO_DRIVER_PANDORA
slouken@5150
    66
    &PND_bootstrap,
slouken@1361
    67
#endif
hfutrell@2743
    68
#if SDL_VIDEO_DRIVER_NDS
slouken@2753
    69
    &NDS_bootstrap,
slouken@2735
    70
#endif
hfutrell@2745
    71
#if SDL_VIDEO_DRIVER_UIKIT
slouken@2753
    72
    &UIKIT_bootstrap,
hfutrell@2745
    73
#endif
slouken@5150
    74
#if SDL_VIDEO_DRIVER_ANDROID
slouken@5150
    75
    &Android_bootstrap,
slouken@5150
    76
#endif
slouken@1361
    77
#if SDL_VIDEO_DRIVER_DUMMY
slouken@2753
    78
    &DUMMY_bootstrap,
slouken@610
    79
#endif
slouken@2753
    80
    NULL
slouken@0
    81
};
slouken@173
    82
slouken@1895
    83
static SDL_VideoDevice *_this = NULL;
slouken@0
    84
slouken@3695
    85
#define CHECK_WINDOW_MAGIC(window, retval) \
slouken@3695
    86
    if (!_this) { \
slouken@3695
    87
        SDL_UninitializedVideo(); \
slouken@3695
    88
        return retval; \
slouken@3695
    89
    } \
slouken@3701
    90
    if (!window || window->magic != &_this->window_magic) { \
slouken@3695
    91
        SDL_SetError("Invalid window"); \
slouken@3695
    92
        return retval; \
slouken@3695
    93
    }
slouken@3695
    94
slouken@0
    95
/* Various local functions */
slouken@2876
    96
static void SDL_UpdateWindowGrab(SDL_Window * window);
slouken@0
    97
slouken@5166
    98
/* Support for framebuffer emulation using an accelerated renderer */
slouken@5166
    99
slouken@5166
   100
#define SDL_WINDOWTEXTUREDATA   "_SDL_WindowTextureData"
slouken@5166
   101
slouken@5166
   102
typedef struct {
slouken@5166
   103
    SDL_Renderer *renderer;
slouken@5166
   104
    SDL_Texture *texture;
slouken@5166
   105
    void *pixels;
slouken@5166
   106
    int pitch;
slouken@5166
   107
} SDL_WindowTextureData;
slouken@5166
   108
slouken@5166
   109
static int
slouken@5166
   110
SDL_CreateWindowTexture(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch)
slouken@5166
   111
{
slouken@5166
   112
    SDL_WindowTextureData *data;
slouken@5166
   113
    SDL_Renderer *renderer;
slouken@5166
   114
    SDL_RendererInfo info;
slouken@5166
   115
    Uint32 i;
slouken@5166
   116
slouken@5166
   117
    data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA);
slouken@5166
   118
    if (!data) {
slouken@5166
   119
        data = (SDL_WindowTextureData *)SDL_calloc(1, sizeof(*data));
slouken@5166
   120
        if (!data) {
slouken@5166
   121
            SDL_OutOfMemory();
slouken@5166
   122
            return -1;
slouken@5166
   123
        }
slouken@5166
   124
        SDL_SetWindowData(window, SDL_WINDOWTEXTUREDATA, data);
slouken@5166
   125
    }
slouken@5166
   126
slouken@5166
   127
    renderer = data->renderer;
slouken@5166
   128
    if (!renderer) {
slouken@5168
   129
        SDL_RendererInfo info;
slouken@5168
   130
        int i;
slouken@5168
   131
slouken@5168
   132
        /* We need to make sure we don't get a software renderer */
slouken@5168
   133
        for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) {
slouken@5168
   134
            SDL_GetRenderDriverInfo(i, &info);
slouken@5168
   135
            if (SDL_strcmp(info.name, "software") != 0) {
slouken@5168
   136
                renderer = SDL_CreateRenderer(window, i, 0);
slouken@5168
   137
                if (renderer) {
slouken@5168
   138
                    break;
slouken@5168
   139
                }
slouken@5168
   140
            }
slouken@5168
   141
        }
slouken@5166
   142
        if (!renderer) {
slouken@5166
   143
            return -1;
slouken@5166
   144
        }
slouken@5166
   145
        data->renderer = renderer;
slouken@5166
   146
    }
slouken@5166
   147
slouken@5166
   148
    /* Free any old texture and pixel data */
slouken@5166
   149
    if (data->texture) {
slouken@5166
   150
        SDL_DestroyTexture(data->texture);
slouken@5166
   151
        data->texture = NULL;
slouken@5166
   152
    }
slouken@5166
   153
    if (data->pixels) {
slouken@5166
   154
        SDL_free(data->pixels);
slouken@5166
   155
        data->pixels = NULL;
slouken@5166
   156
    }
slouken@5166
   157
slouken@5166
   158
    if (SDL_GetRendererInfo(renderer, &info) < 0) {
slouken@5166
   159
        return -1;
slouken@5166
   160
    }
slouken@5166
   161
slouken@5166
   162
    /* Find the first format without an alpha channel */
slouken@5166
   163
    *format = info.texture_formats[0];
slouken@5166
   164
    for (i = 0; i < info.num_texture_formats; ++i) {
slouken@5166
   165
        if (!SDL_ISPIXELFORMAT_ALPHA(info.texture_formats[i])) {
slouken@5166
   166
            *format = info.texture_formats[i];
slouken@5166
   167
            break;
slouken@5166
   168
        }
slouken@5166
   169
    }
slouken@5166
   170
slouken@5166
   171
    data->texture = SDL_CreateTexture(renderer, *format,
slouken@5166
   172
                                      SDL_TEXTUREACCESS_STREAMING,
slouken@5166
   173
                                      window->w, window->h);
slouken@5166
   174
    if (!data->texture) {
slouken@5166
   175
        return -1;
slouken@5166
   176
    }
slouken@5166
   177
slouken@5166
   178
    /* Create framebuffer data */
slouken@5166
   179
    data->pitch = (((window->w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3);
slouken@5166
   180
    data->pixels = SDL_malloc(window->h * data->pitch);
slouken@5166
   181
    if (!data->pixels) {
slouken@5166
   182
        SDL_OutOfMemory();
slouken@5166
   183
        return -1;
slouken@5166
   184
    }
slouken@5166
   185
slouken@5166
   186
    *pixels = data->pixels;
slouken@5166
   187
    *pitch = data->pitch;
slouken@5166
   188
    return 0;
slouken@5166
   189
}
slouken@5166
   190
slouken@5166
   191
static int
slouken@5166
   192
SDL_UpdateWindowTexture(_THIS, SDL_Window * window, int numrects, SDL_Rect * rects)
slouken@5166
   193
{
slouken@5166
   194
    SDL_WindowTextureData *data;
slouken@5166
   195
slouken@5166
   196
    data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA);
slouken@5166
   197
    if (!data || !data->texture) {
slouken@5166
   198
        SDL_SetError("No window texture data");
slouken@5166
   199
        return -1;
slouken@5166
   200
    }
slouken@5166
   201
slouken@5166
   202
    if (SDL_UpdateTexture(data->texture, NULL, data->pixels, data->pitch) < 0) {
slouken@5166
   203
        return -1;
slouken@5166
   204
    }
slouken@5166
   205
    if (SDL_RenderCopy(data->renderer, data->texture, NULL, NULL) < 0) {
slouken@5166
   206
        return -1;
slouken@5166
   207
    }
slouken@5166
   208
    SDL_RenderPresent(data->renderer);
slouken@5166
   209
    return 0;
slouken@5166
   210
}
slouken@5166
   211
slouken@5166
   212
static void
slouken@5166
   213
SDL_DestroyWindowTexture(_THIS, SDL_Window * window)
slouken@5166
   214
{
slouken@5166
   215
    SDL_WindowTextureData *data;
slouken@5166
   216
slouken@5166
   217
    data = SDL_SetWindowData(window, SDL_WINDOWTEXTUREDATA, NULL);
slouken@5166
   218
    if (!data) {
slouken@5166
   219
        return;
slouken@5166
   220
    }
slouken@5166
   221
    if (data->texture) {
slouken@5166
   222
        SDL_DestroyTexture(data->texture);
slouken@5166
   223
    }
slouken@5166
   224
    if (data->renderer) {
slouken@5166
   225
        SDL_DestroyRenderer(data->renderer);
slouken@5166
   226
    }
slouken@5166
   227
    if (data->pixels) {
slouken@5166
   228
        SDL_free(data->pixels);
slouken@5166
   229
    }
slouken@5166
   230
    SDL_free(data);
slouken@5166
   231
}
slouken@5166
   232
slouken@5166
   233
slouken@1895
   234
static int
slouken@1895
   235
cmpmodes(const void *A, const void *B)
slouken@1895
   236
{
slouken@2753
   237
    SDL_DisplayMode a = *(const SDL_DisplayMode *) A;
slouken@2753
   238
    SDL_DisplayMode b = *(const SDL_DisplayMode *) B;
slouken@0
   239
slouken@2753
   240
    if (a.w != b.w) {
slouken@2753
   241
        return b.w - a.w;
slouken@2753
   242
    }
slouken@2753
   243
    if (a.h != b.h) {
slouken@2753
   244
        return b.h - a.h;
slouken@2753
   245
    }
slouken@2753
   246
    if (SDL_BITSPERPIXEL(a.format) != SDL_BITSPERPIXEL(b.format)) {
slouken@2753
   247
        return SDL_BITSPERPIXEL(b.format) - SDL_BITSPERPIXEL(a.format);
slouken@2753
   248
    }
lestat@3178
   249
    if (SDL_PIXELLAYOUT(a.format) != SDL_PIXELLAYOUT(b.format)) {
lestat@3178
   250
        return SDL_PIXELLAYOUT(b.format) - SDL_PIXELLAYOUT(a.format);
lestat@3178
   251
    }
slouken@2753
   252
    if (a.refresh_rate != b.refresh_rate) {
slouken@2753
   253
        return b.refresh_rate - a.refresh_rate;
slouken@2753
   254
    }
slouken@2753
   255
    return 0;
slouken@1895
   256
}
slouken@1895
   257
slouken@1912
   258
static void
slouken@1912
   259
SDL_UninitializedVideo()
slouken@1912
   260
{
slouken@2753
   261
    SDL_SetError("Video subsystem has not been initialized");
slouken@1912
   262
}
slouken@1912
   263
slouken@1895
   264
int
slouken@1895
   265
SDL_GetNumVideoDrivers(void)
slouken@1895
   266
{
slouken@2753
   267
    return SDL_arraysize(bootstrap) - 1;
slouken@1895
   268
}
slouken@1895
   269
slouken@2753
   270
const char *
slouken@1895
   271
SDL_GetVideoDriver(int index)
slouken@1895
   272
{
slouken@2753
   273
    if (index >= 0 && index < SDL_GetNumVideoDrivers()) {
slouken@2753
   274
        return bootstrap[index]->name;
slouken@2753
   275
    }
slouken@2753
   276
    return NULL;
slouken@1895
   277
}
slouken@0
   278
slouken@0
   279
/*
slouken@0
   280
 * Initialize the video and event subsystems -- determine native pixel format
slouken@0
   281
 */
slouken@1895
   282
int
slouken@5123
   283
SDL_VideoInit(const char *driver_name)
slouken@0
   284
{
slouken@2753
   285
    SDL_VideoDevice *video;
slouken@2753
   286
    int index;
slouken@2753
   287
    int i;
slouken@0
   288
slouken@3694
   289
    /* Check to make sure we don't overwrite '_this' */
slouken@3694
   290
    if (_this != NULL) {
slouken@3694
   291
        SDL_VideoQuit();
slouken@3694
   292
    }
slouken@3694
   293
slouken@2753
   294
    /* Start the event loop */
slouken@5123
   295
    if (SDL_StartEventLoop() < 0 ||
slouken@5123
   296
        SDL_KeyboardInit() < 0 ||
slouken@5123
   297
        SDL_MouseInit() < 0 ||
slouken@5123
   298
        SDL_TouchInit() < 0 ||
slouken@5123
   299
        SDL_QuitInit() < 0) {
slouken@2753
   300
        return -1;
slouken@2753
   301
    }
slouken@3694
   302
slouken@2753
   303
    /* Select the proper video driver */
slouken@2753
   304
    index = 0;
slouken@2753
   305
    video = NULL;
slouken@2753
   306
    if (driver_name == NULL) {
slouken@2753
   307
        driver_name = SDL_getenv("SDL_VIDEODRIVER");
slouken@2753
   308
    }
slouken@2753
   309
    if (driver_name != NULL) {
slouken@2753
   310
        for (i = 0; bootstrap[i]; ++i) {
slouken@2753
   311
            if (SDL_strcasecmp(bootstrap[i]->name, driver_name) == 0) {
slouken@3448
   312
                video = bootstrap[i]->create(index);
slouken@2753
   313
                break;
slouken@2753
   314
            }
slouken@2753
   315
        }
slouken@2753
   316
    } else {
slouken@2753
   317
        for (i = 0; bootstrap[i]; ++i) {
slouken@2753
   318
            if (bootstrap[i]->available()) {
slouken@2753
   319
                video = bootstrap[i]->create(index);
slouken@2753
   320
                if (video != NULL) {
slouken@2753
   321
                    break;
slouken@2753
   322
                }
slouken@2753
   323
            }
slouken@2753
   324
        }
slouken@2753
   325
    }
slouken@2753
   326
    if (video == NULL) {
slouken@2753
   327
        if (driver_name) {
slouken@2753
   328
            SDL_SetError("%s not available", driver_name);
slouken@2753
   329
        } else {
slouken@2753
   330
            SDL_SetError("No available video device");
slouken@2753
   331
        }
slouken@2753
   332
        return -1;
slouken@2753
   333
    }
slouken@2753
   334
    _this = video;
slouken@2753
   335
    _this->name = bootstrap[i]->name;
slouken@2753
   336
    _this->next_object_id = 1;
slouken@0
   337
slouken@0
   338
slouken@2753
   339
    /* Set some very sane GL defaults */
slouken@2753
   340
    _this->gl_config.driver_loaded = 0;
slouken@2753
   341
    _this->gl_config.dll_handle = NULL;
slouken@2753
   342
    _this->gl_config.red_size = 3;
slouken@2753
   343
    _this->gl_config.green_size = 3;
slouken@2753
   344
    _this->gl_config.blue_size = 2;
slouken@2753
   345
    _this->gl_config.alpha_size = 0;
slouken@2753
   346
    _this->gl_config.buffer_size = 0;
slouken@2753
   347
    _this->gl_config.depth_size = 16;
slouken@2753
   348
    _this->gl_config.stencil_size = 0;
slouken@2753
   349
    _this->gl_config.double_buffer = 1;
slouken@2753
   350
    _this->gl_config.accum_red_size = 0;
slouken@2753
   351
    _this->gl_config.accum_green_size = 0;
slouken@2753
   352
    _this->gl_config.accum_blue_size = 0;
slouken@2753
   353
    _this->gl_config.accum_alpha_size = 0;
slouken@2753
   354
    _this->gl_config.stereo = 0;
slouken@2753
   355
    _this->gl_config.multisamplebuffers = 0;
slouken@2753
   356
    _this->gl_config.multisamplesamples = 0;
slouken@2753
   357
    _this->gl_config.retained_backing = 1;
slouken@3571
   358
    _this->gl_config.accelerated = -1;  /* accelerated or not, both are fine */
slouken@3100
   359
    _this->gl_config.major_version = 2;
slouken@3100
   360
    _this->gl_config.minor_version = 1;
slouken@0
   361
slouken@2753
   362
    /* Initialize the video subsystem */
slouken@2753
   363
    if (_this->VideoInit(_this) < 0) {
slouken@2753
   364
        SDL_VideoQuit();
slouken@2753
   365
        return -1;
slouken@2753
   366
    }
slouken@5166
   367
slouken@2753
   368
    /* Make sure some displays were added */
slouken@2753
   369
    if (_this->num_displays == 0) {
slouken@2753
   370
        SDL_SetError("The video driver did not add any displays");
slouken@2753
   371
        SDL_VideoQuit();
slouken@2753
   372
        return (-1);
slouken@2753
   373
    }
slouken@0
   374
slouken@5166
   375
    /* Add the renderer framebuffer emulation if needed */
slouken@5166
   376
    if (!_this->CreateWindowFramebuffer) {
slouken@5166
   377
        _this->CreateWindowFramebuffer = SDL_CreateWindowTexture;
slouken@5166
   378
        _this->UpdateWindowFramebuffer = SDL_UpdateWindowTexture;
slouken@5166
   379
        _this->DestroyWindowFramebuffer = SDL_DestroyWindowTexture;
slouken@5166
   380
    }
slouken@5166
   381
slouken@2753
   382
    /* We're ready to go! */
slouken@2753
   383
    return 0;
slouken@0
   384
}
slouken@0
   385
slouken@2753
   386
const char *
slouken@1895
   387
SDL_GetCurrentVideoDriver()
slouken@0
   388
{
slouken@2753
   389
    if (!_this) {
slouken@2753
   390
        SDL_UninitializedVideo();
slouken@2753
   391
        return NULL;
slouken@2753
   392
    }
slouken@2753
   393
    return _this->name;
slouken@0
   394
}
slouken@0
   395
slouken@1895
   396
SDL_VideoDevice *
slouken@4472
   397
SDL_GetVideoDevice(void)
slouken@0
   398
{
slouken@2753
   399
    return _this;
slouken@0
   400
}
slouken@0
   401
slouken@1895
   402
int
slouken@1895
   403
SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode)
slouken@0
   404
{
slouken@2753
   405
    SDL_VideoDisplay display;
slouken@0
   406
slouken@2753
   407
    SDL_zero(display);
slouken@2753
   408
    if (desktop_mode) {
slouken@2753
   409
        display.desktop_mode = *desktop_mode;
slouken@2753
   410
    }
slouken@2753
   411
    display.current_mode = display.desktop_mode;
slouken@1895
   412
slouken@2753
   413
    return SDL_AddVideoDisplay(&display);
slouken@0
   414
}
slouken@0
   415
slouken@1895
   416
int
slouken@1895
   417
SDL_AddVideoDisplay(const SDL_VideoDisplay * display)
slouken@0
   418
{
slouken@2753
   419
    SDL_VideoDisplay *displays;
slouken@2753
   420
    int index = -1;
slouken@0
   421
slouken@2753
   422
    displays =
slouken@2753
   423
        SDL_realloc(_this->displays,
slouken@2753
   424
                    (_this->num_displays + 1) * sizeof(*displays));
slouken@2753
   425
    if (displays) {
slouken@2753
   426
        index = _this->num_displays++;
slouken@2753
   427
        displays[index] = *display;
slouken@2753
   428
        displays[index].device = _this;
slouken@2753
   429
        _this->displays = displays;
slouken@2753
   430
    } else {
slouken@2753
   431
        SDL_OutOfMemory();
slouken@2753
   432
    }
slouken@2753
   433
    return index;
slouken@0
   434
}
slouken@0
   435
slouken@1895
   436
int
slouken@1895
   437
SDL_GetNumVideoDisplays(void)
slouken@0
   438
{
slouken@2753
   439
    if (!_this) {
slouken@2753
   440
        SDL_UninitializedVideo();
slouken@2753
   441
        return 0;
slouken@2753
   442
    }
slouken@2753
   443
    return _this->num_displays;
slouken@0
   444
}
slouken@0
   445
slouken@1895
   446
int
slouken@3528
   447
SDL_GetDisplayBounds(int index, SDL_Rect * rect)
slouken@3528
   448
{
slouken@3528
   449
    if (!_this) {
slouken@3528
   450
        SDL_UninitializedVideo();
slouken@3528
   451
        return -1;
slouken@3528
   452
    }
slouken@3528
   453
    if (index < 0 || index >= _this->num_displays) {
slouken@3528
   454
        SDL_SetError("index must be in the range 0 - %d",
slouken@3528
   455
                     _this->num_displays - 1);
slouken@3528
   456
        return -1;
slouken@3528
   457
    }
slouken@3528
   458
    if (rect) {
slouken@3528
   459
        SDL_VideoDisplay *display = &_this->displays[index];
slouken@3528
   460
slouken@3528
   461
        if (_this->GetDisplayBounds) {
slouken@3528
   462
            if (_this->GetDisplayBounds(_this, display, rect) < 0) {
slouken@3528
   463
                return -1;
slouken@3528
   464
            }
slouken@3528
   465
        } else {
slouken@3528
   466
            /* Assume that the displays are left to right */
slouken@3528
   467
            if (index == 0) {
slouken@3528
   468
                rect->x = 0;
slouken@3528
   469
                rect->y = 0;
slouken@3528
   470
            } else {
slouken@3528
   471
                SDL_GetDisplayBounds(index-1, rect);
slouken@3528
   472
                rect->x += rect->w;
slouken@3528
   473
            }
slouken@3528
   474
            rect->w = display->desktop_mode.w;
slouken@3528
   475
            rect->h = display->desktop_mode.h;
slouken@3528
   476
        }
slouken@3528
   477
    }
slouken@3528
   478
    return 0;
slouken@3528
   479
}
slouken@3528
   480
slouken@3528
   481
int
slouken@1895
   482
SDL_SelectVideoDisplay(int index)
slouken@0
   483
{
slouken@2753
   484
    if (!_this) {
slouken@2753
   485
        SDL_UninitializedVideo();
slouken@2753
   486
        return (-1);
slouken@2753
   487
    }
slouken@2753
   488
    if (index < 0 || index >= _this->num_displays) {
slouken@2753
   489
        SDL_SetError("index must be in the range 0 - %d",
slouken@2753
   490
                     _this->num_displays - 1);
slouken@2753
   491
        return -1;
slouken@2753
   492
    }
slouken@2753
   493
    _this->current_display = index;
slouken@2753
   494
    return 0;
slouken@1963
   495
}
slouken@1963
   496
slouken@1963
   497
int
slouken@1963
   498
SDL_GetCurrentVideoDisplay(void)
slouken@1963
   499
{
slouken@2753
   500
    if (!_this) {
slouken@2753
   501
        SDL_UninitializedVideo();
slouken@2753
   502
        return (-1);
slouken@2753
   503
    }
slouken@2753
   504
    return _this->current_display;
slouken@0
   505
}
slouken@0
   506
slouken@1895
   507
SDL_bool
slouken@3500
   508
SDL_AddDisplayMode(SDL_VideoDisplay * display,  const SDL_DisplayMode * mode)
slouken@0
   509
{
slouken@2753
   510
    SDL_DisplayMode *modes;
slouken@2753
   511
    int i, nmodes;
slouken@0
   512
slouken@2753
   513
    /* Make sure we don't already have the mode in the list */
slouken@2753
   514
    modes = display->display_modes;
slouken@2753
   515
    nmodes = display->num_display_modes;
slouken@2753
   516
    for (i = nmodes; i--;) {
slouken@2753
   517
        if (SDL_memcmp(mode, &modes[i], sizeof(*mode)) == 0) {
slouken@2753
   518
            return SDL_FALSE;
slouken@2753
   519
        }
slouken@2753
   520
    }
slouken@1895
   521
slouken@2753
   522
    /* Go ahead and add the new mode */
slouken@2753
   523
    if (nmodes == display->max_display_modes) {
slouken@2753
   524
        modes =
slouken@2753
   525
            SDL_realloc(modes,
slouken@2753
   526
                        (display->max_display_modes + 32) * sizeof(*modes));
slouken@2753
   527
        if (!modes) {
slouken@2753
   528
            return SDL_FALSE;
slouken@2753
   529
        }
slouken@2753
   530
        display->display_modes = modes;
slouken@2753
   531
        display->max_display_modes += 32;
slouken@2753
   532
    }
slouken@2753
   533
    modes[nmodes] = *mode;
slouken@2753
   534
    display->num_display_modes++;
slouken@1895
   535
lestat@3178
   536
    /* Re-sort video modes */
lestat@3178
   537
    SDL_qsort(display->display_modes, display->num_display_modes,
slouken@3186
   538
              sizeof(SDL_DisplayMode), cmpmodes);
lestat@3178
   539
slouken@2753
   540
    return SDL_TRUE;
slouken@0
   541
}
slouken@0
   542
slouken@1895
   543
int
slouken@3500
   544
SDL_GetNumDisplayModesForDisplay(SDL_VideoDisplay * display)
slouken@3500
   545
{
slouken@3500
   546
    if (!display->num_display_modes && _this->GetDisplayModes) {
slouken@3500
   547
        _this->GetDisplayModes(_this, display);
slouken@3500
   548
        SDL_qsort(display->display_modes, display->num_display_modes,
slouken@3500
   549
                  sizeof(SDL_DisplayMode), cmpmodes);
slouken@3500
   550
    }
slouken@3500
   551
    return display->num_display_modes;
slouken@3500
   552
}
slouken@3500
   553
slouken@3500
   554
int
slouken@1895
   555
SDL_GetNumDisplayModes()
slouken@0
   556
{
slouken@2753
   557
    if (_this) {
slouken@3685
   558
        return SDL_GetNumDisplayModesForDisplay(SDL_CurrentDisplay);
slouken@3500
   559
    }
slouken@3500
   560
    return 0;
slouken@3500
   561
}
slouken@3500
   562
slouken@3500
   563
int
slouken@3500
   564
SDL_GetDisplayModeForDisplay(SDL_VideoDisplay * display, int index, SDL_DisplayMode * mode)
slouken@3500
   565
{
slouken@3500
   566
    if (index < 0 || index >= SDL_GetNumDisplayModesForDisplay(display)) {
slouken@3500
   567
        SDL_SetError("index must be in the range of 0 - %d",
slouken@3500
   568
                     SDL_GetNumDisplayModesForDisplay(display) - 1);
slouken@3500
   569
        return -1;
slouken@3500
   570
    }
slouken@3500
   571
    if (mode) {
slouken@3500
   572
        *mode = display->display_modes[index];
slouken@2753
   573
    }
slouken@2753
   574
    return 0;
slouken@0
   575
}
slouken@0
   576
slouken@1967
   577
int
slouken@1967
   578
SDL_GetDisplayMode(int index, SDL_DisplayMode * mode)
slouken@0
   579
{
slouken@3685
   580
    return SDL_GetDisplayModeForDisplay(SDL_CurrentDisplay, index, mode);
slouken@3500
   581
}
slouken@3500
   582
slouken@3500
   583
int
slouken@3500
   584
SDL_GetDesktopDisplayModeForDisplay(SDL_VideoDisplay * display, SDL_DisplayMode * mode)
slouken@3500
   585
{
slouken@2753
   586
    if (mode) {
slouken@3500
   587
        *mode = display->desktop_mode;
slouken@2753
   588
    }
slouken@2753
   589
    return 0;
slouken@0
   590
}
slouken@0
   591
slouken@1967
   592
int
slouken@1967
   593
SDL_GetDesktopDisplayMode(SDL_DisplayMode * mode)
slouken@0
   594
{
slouken@2753
   595
    if (!_this) {
slouken@2753
   596
        SDL_UninitializedVideo();
slouken@2753
   597
        return -1;
slouken@2753
   598
    }
slouken@3685
   599
    return SDL_GetDesktopDisplayModeForDisplay(SDL_CurrentDisplay, mode);
slouken@3500
   600
}
slouken@3500
   601
slouken@3500
   602
int
slouken@3500
   603
SDL_GetCurrentDisplayModeForDisplay(SDL_VideoDisplay * display, SDL_DisplayMode * mode)
slouken@3500
   604
{
slouken@2753
   605
    if (mode) {
slouken@3500
   606
        *mode = display->current_mode;
slouken@2753
   607
    }
slouken@2753
   608
    return 0;
slouken@0
   609
}
slouken@0
   610
slouken@1967
   611
int
slouken@1967
   612
SDL_GetCurrentDisplayMode(SDL_DisplayMode * mode)
slouken@0
   613
{
slouken@2753
   614
    if (!_this) {
slouken@2753
   615
        SDL_UninitializedVideo();
slouken@2753
   616
        return -1;
slouken@2753
   617
    }
slouken@3685
   618
    return SDL_GetCurrentDisplayModeForDisplay(SDL_CurrentDisplay, mode);
slouken@0
   619
}
slouken@0
   620
slouken@1895
   621
SDL_DisplayMode *
slouken@3500
   622
SDL_GetClosestDisplayModeForDisplay(SDL_VideoDisplay * display,
slouken@3500
   623
                                    const SDL_DisplayMode * mode,
slouken@3500
   624
                                    SDL_DisplayMode * closest)
slouken@0
   625
{
slouken@2753
   626
    Uint32 target_format;
slouken@2753
   627
    int target_refresh_rate;
slouken@2753
   628
    int i;
slouken@2753
   629
    SDL_DisplayMode *current, *match;
slouken@0
   630
slouken@3500
   631
    if (!mode || !closest) {
slouken@3500
   632
        SDL_SetError("Missing desired mode or closest mode parameter");
slouken@2753
   633
        return NULL;
slouken@2753
   634
    }
slouken@3500
   635
slouken@2753
   636
    /* Default to the desktop format */
slouken@2753
   637
    if (mode->format) {
slouken@2753
   638
        target_format = mode->format;
slouken@2753
   639
    } else {
slouken@3500
   640
        target_format = display->desktop_mode.format;
slouken@2753
   641
    }
slouken@0
   642
slouken@2753
   643
    /* Default to the desktop refresh rate */
slouken@2753
   644
    if (mode->refresh_rate) {
slouken@2753
   645
        target_refresh_rate = mode->refresh_rate;
slouken@2753
   646
    } else {
slouken@3500
   647
        target_refresh_rate = display->desktop_mode.refresh_rate;
slouken@2753
   648
    }
slouken@0
   649
slouken@2753
   650
    match = NULL;
slouken@3500
   651
    for (i = 0; i < SDL_GetNumDisplayModesForDisplay(display); ++i) {
slouken@3500
   652
        current = &display->display_modes[i];
slouken@0
   653
slouken@2789
   654
        if (current->w && (current->w < mode->w)) {
slouken@2753
   655
            /* Out of sorted modes large enough here */
slouken@2753
   656
            break;
slouken@2753
   657
        }
slouken@2789
   658
        if (current->h && (current->h < mode->h)) {
slouken@2789
   659
            if (current->w && (current->w == mode->w)) {
slouken@2789
   660
                /* Out of sorted modes large enough here */
slouken@2789
   661
                break;
slouken@2789
   662
            }
slouken@2789
   663
            /* Wider, but not tall enough, due to a different
slouken@2789
   664
               aspect ratio. This mode must be skipped, but closer
slouken@2789
   665
               modes may still follow. */
slouken@2789
   666
            continue;
slouken@2789
   667
        }
slouken@2753
   668
        if (!match || current->w < match->w || current->h < match->h) {
slouken@2753
   669
            match = current;
slouken@2753
   670
            continue;
slouken@2753
   671
        }
slouken@2753
   672
        if (current->format != match->format) {
slouken@2753
   673
            /* Sorted highest depth to lowest */
slouken@2753
   674
            if (current->format == target_format ||
slouken@2753
   675
                (SDL_BITSPERPIXEL(current->format) >=
slouken@2753
   676
                 SDL_BITSPERPIXEL(target_format)
slouken@2753
   677
                 && SDL_PIXELTYPE(current->format) ==
slouken@2753
   678
                 SDL_PIXELTYPE(target_format))) {
slouken@2753
   679
                match = current;
slouken@2753
   680
            }
slouken@2753
   681
            continue;
slouken@2753
   682
        }
slouken@2753
   683
        if (current->refresh_rate != match->refresh_rate) {
slouken@2753
   684
            /* Sorted highest refresh to lowest */
slouken@2753
   685
            if (current->refresh_rate >= target_refresh_rate) {
slouken@2753
   686
                match = current;
slouken@2753
   687
            }
slouken@2753
   688
        }
slouken@2753
   689
    }
slouken@2753
   690
    if (match) {
slouken@2753
   691
        if (match->format) {
slouken@2753
   692
            closest->format = match->format;
slouken@2753
   693
        } else {
slouken@2753
   694
            closest->format = mode->format;
slouken@2753
   695
        }
slouken@2753
   696
        if (match->w && match->h) {
slouken@2753
   697
            closest->w = match->w;
slouken@2753
   698
            closest->h = match->h;
slouken@2753
   699
        } else {
slouken@2753
   700
            closest->w = mode->w;
slouken@2753
   701
            closest->h = mode->h;
slouken@2753
   702
        }
slouken@2753
   703
        if (match->refresh_rate) {
slouken@2753
   704
            closest->refresh_rate = match->refresh_rate;
slouken@2753
   705
        } else {
slouken@2753
   706
            closest->refresh_rate = mode->refresh_rate;
slouken@2753
   707
        }
slouken@2753
   708
        closest->driverdata = match->driverdata;
slouken@1895
   709
slouken@2753
   710
        /*
slouken@2753
   711
         * Pick some reasonable defaults if the app and driver don't
slouken@2753
   712
         * care
slouken@2753
   713
         */
slouken@2753
   714
        if (!closest->format) {
slouken@2753
   715
            closest->format = SDL_PIXELFORMAT_RGB888;
slouken@2753
   716
        }
slouken@2753
   717
        if (!closest->w) {
slouken@2753
   718
            closest->w = 640;
slouken@2753
   719
        }
slouken@2753
   720
        if (!closest->h) {
slouken@2753
   721
            closest->h = 480;
slouken@2753
   722
        }
slouken@2753
   723
        return closest;
slouken@2753
   724
    }
slouken@2753
   725
    return NULL;
slouken@0
   726
}
slouken@0
   727
slouken@3500
   728
SDL_DisplayMode *
slouken@3500
   729
SDL_GetClosestDisplayMode(const SDL_DisplayMode * mode,
slouken@3500
   730
                          SDL_DisplayMode * closest)
slouken@3500
   731
{
slouken@3500
   732
    if (!_this) {
slouken@3500
   733
        SDL_UninitializedVideo();
slouken@3500
   734
        return NULL;
slouken@3500
   735
    }
slouken@3685
   736
    return SDL_GetClosestDisplayModeForDisplay(SDL_CurrentDisplay, mode, closest);
slouken@3500
   737
}
slouken@3500
   738
slouken@1895
   739
int
slouken@3500
   740
SDL_SetDisplayModeForDisplay(SDL_VideoDisplay * display, const SDL_DisplayMode * mode)
slouken@0
   741
{
slouken@2753
   742
    SDL_DisplayMode display_mode;
slouken@2753
   743
    SDL_DisplayMode current_mode;
slouken@0
   744
slouken@3502
   745
    if (mode) {
slouken@3502
   746
        display_mode = *mode;
slouken@3502
   747
slouken@3502
   748
        /* Default to the current mode */
slouken@3502
   749
        if (!display_mode.format) {
slouken@3502
   750
            display_mode.format = display->current_mode.format;
slouken@3502
   751
        }
slouken@3502
   752
        if (!display_mode.w) {
slouken@3502
   753
            display_mode.w = display->current_mode.w;
slouken@3502
   754
        }
slouken@3502
   755
        if (!display_mode.h) {
slouken@3502
   756
            display_mode.h = display->current_mode.h;
slouken@3502
   757
        }
slouken@3502
   758
        if (!display_mode.refresh_rate) {
slouken@3502
   759
            display_mode.refresh_rate = display->current_mode.refresh_rate;
slouken@3502
   760
        }
slouken@3502
   761
slouken@3502
   762
        /* Get a good video mode, the closest one possible */
slouken@3502
   763
        if (!SDL_GetClosestDisplayModeForDisplay(display, &display_mode, &display_mode)) {
slouken@3502
   764
            SDL_SetError("No video mode large enough for %dx%d",
slouken@3502
   765
                         display_mode.w, display_mode.h);
slouken@3502
   766
            return -1;
slouken@3502
   767
        }
slouken@3502
   768
    } else {
slouken@3502
   769
        display_mode = display->desktop_mode;
slouken@2753
   770
    }
slouken@3500
   771
slouken@2753
   772
    /* See if there's anything left to do */
slouken@3500
   773
    SDL_GetCurrentDisplayModeForDisplay(display, &current_mode);
slouken@2753
   774
    if (SDL_memcmp(&display_mode, &current_mode, sizeof(display_mode)) == 0) {
slouken@2753
   775
        return 0;
slouken@2753
   776
    }
slouken@3500
   777
slouken@2753
   778
    /* Actually change the display mode */
slouken@4978
   779
    if (!_this->SetDisplayMode) {
slouken@4978
   780
        SDL_SetError("Video driver doesn't support changing display mode");
slouken@4978
   781
        return -1;
slouken@4978
   782
    }
slouken@3500
   783
    if (_this->SetDisplayMode(_this, display, &display_mode) < 0) {
slouken@2753
   784
        return -1;
slouken@2753
   785
    }
slouken@2753
   786
    display->current_mode = display_mode;
slouken@2753
   787
    return 0;
slouken@0
   788
}
slouken@0
   789
slouken@1895
   790
int
slouken@3685
   791
SDL_SetWindowDisplayMode(SDL_Window * window, const SDL_DisplayMode * mode)
slouken@3500
   792
{
slouken@3695
   793
    CHECK_WINDOW_MAGIC(window, -1);
slouken@3500
   794
slouken@2753
   795
    if (mode) {
slouken@3500
   796
        window->fullscreen_mode = *mode;
slouken@3500
   797
    } else {
slouken@3500
   798
        SDL_zero(window->fullscreen_mode);
slouken@3500
   799
    }
slouken@3526
   800
    return 0;
slouken@3500
   801
}
slouken@3500
   802
slouken@3500
   803
int
slouken@3685
   804
SDL_GetWindowDisplayMode(SDL_Window * window, SDL_DisplayMode * mode)
slouken@3500
   805
{
slouken@3500
   806
    SDL_DisplayMode fullscreen_mode;
slouken@3500
   807
slouken@3695
   808
    CHECK_WINDOW_MAGIC(window, -1);
slouken@3500
   809
slouken@3500
   810
    fullscreen_mode = window->fullscreen_mode;
slouken@3500
   811
    if (!fullscreen_mode.w) {
slouken@3500
   812
        fullscreen_mode.w = window->w;
slouken@3500
   813
    }
slouken@3500
   814
    if (!fullscreen_mode.h) {
slouken@3500
   815
        fullscreen_mode.h = window->h;
slouken@3500
   816
    }
slouken@3500
   817
slouken@3685
   818
    if (!SDL_GetClosestDisplayModeForDisplay(window->display,
slouken@3500
   819
                                             &fullscreen_mode,
slouken@3500
   820
                                             &fullscreen_mode)) {
slouken@3500
   821
        SDL_SetError("Couldn't find display mode match");
slouken@3500
   822
        return -1;
slouken@3500
   823
    }
slouken@3500
   824
slouken@3500
   825
    if (mode) {
slouken@3500
   826
        *mode = fullscreen_mode;
slouken@2753
   827
    }
slouken@2753
   828
    return 0;
slouken@0
   829
}
slouken@0
   830
slouken@5154
   831
Uint32
slouken@5154
   832
SDL_GetWindowPixelFormat(SDL_Window * window)
slouken@5154
   833
{
slouken@5154
   834
    SDL_VideoDisplay *display = window->display;
slouken@5154
   835
    SDL_DisplayMode *displayMode = &display->current_mode;
slouken@5154
   836
    return displayMode->format;
slouken@5154
   837
}
slouken@5154
   838
slouken@3502
   839
static void
slouken@3502
   840
SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool attempt)
slouken@3502
   841
{
slouken@3685
   842
    SDL_VideoDisplay *display = window->display;
slouken@3502
   843
slouken@3502
   844
    /* See if we're already processing a window */
slouken@3502
   845
    if (display->updating_fullscreen) {
slouken@3502
   846
        return;
slouken@3502
   847
    }
slouken@3502
   848
slouken@3502
   849
    display->updating_fullscreen = SDL_TRUE;
slouken@3502
   850
slouken@3502
   851
    /* See if we even want to do anything here */
slouken@3502
   852
    if ((window->flags & SDL_WINDOW_FULLSCREEN) &&
slouken@3502
   853
        (window->flags & SDL_WINDOW_SHOWN)) {
slouken@3502
   854
        if (attempt) {
slouken@3502
   855
            /* We just gained some state, try to gain all states */
slouken@3502
   856
            if (window->flags & SDL_WINDOW_MINIMIZED) {
slouken@3685
   857
                SDL_RestoreWindow(window);
slouken@3502
   858
            } else {
slouken@3685
   859
                SDL_RaiseWindow(window);
slouken@3502
   860
            }
slouken@3502
   861
        } else {
slouken@3502
   862
            /* We just lost some state, try to release all states */
slouken@3685
   863
            SDL_MinimizeWindow(window);
slouken@3502
   864
        }
slouken@3502
   865
    }
slouken@3502
   866
slouken@3502
   867
    if (FULLSCREEN_VISIBLE(window)) {
slouken@3502
   868
        /* Hide any other fullscreen windows */
slouken@3701
   869
        SDL_Window *other;
slouken@3701
   870
        for (other = display->windows; other; other = other->next) {
slouken@3502
   871
            if (other != window && FULLSCREEN_VISIBLE(other)) {
slouken@3685
   872
                SDL_MinimizeWindow(other);
slouken@3502
   873
            }
slouken@3502
   874
        }
slouken@3502
   875
    }
slouken@3502
   876
slouken@3502
   877
    display->updating_fullscreen = SDL_FALSE;
slouken@3502
   878
slouken@3502
   879
    /* See if there are any fullscreen windows */
slouken@3701
   880
    for (window = display->windows; window; window = window->next) {
slouken@3502
   881
        if (FULLSCREEN_VISIBLE(window)) {
slouken@3502
   882
            SDL_DisplayMode fullscreen_mode;
slouken@3685
   883
            if (SDL_GetWindowDisplayMode(window, &fullscreen_mode) == 0) {
slouken@3502
   884
                SDL_SetDisplayModeForDisplay(display, &fullscreen_mode);
slouken@3517
   885
                display->fullscreen_window = window;
slouken@3502
   886
                return;
slouken@3502
   887
            }
slouken@3502
   888
        }
slouken@3502
   889
    }
slouken@3502
   890
slouken@3502
   891
    /* Nope, restore the desktop mode */
slouken@3502
   892
    SDL_SetDisplayModeForDisplay(display, NULL);
slouken@3517
   893
    display->fullscreen_window = NULL;
slouken@3502
   894
}
slouken@3502
   895
slouken@3685
   896
SDL_Window *
slouken@1895
   897
SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
slouken@0
   898
{
slouken@2753
   899
    const Uint32 allowed_flags = (SDL_WINDOW_FULLSCREEN |
slouken@2753
   900
                                  SDL_WINDOW_OPENGL |
slouken@2753
   901
                                  SDL_WINDOW_BORDERLESS |
slouken@2875
   902
                                  SDL_WINDOW_RESIZABLE |
slouken@2875
   903
                                  SDL_WINDOW_INPUT_GRABBED);
slouken@2753
   904
    SDL_VideoDisplay *display;
slouken@3685
   905
    SDL_Window *window;
slouken@0
   906
slouken@2753
   907
    if (!_this) {
slouken@3417
   908
        /* Initialize the video system if needed */
slouken@5123
   909
        if (SDL_VideoInit(NULL) < 0) {
slouken@3685
   910
            return NULL;
slouken@3417
   911
        }
slouken@2753
   912
    }
slouken@3057
   913
    if (flags & SDL_WINDOW_OPENGL) {
slouken@3057
   914
        if (!_this->GL_CreateContext) {
slouken@3057
   915
            SDL_SetError("No OpenGL support in video driver");
slouken@3685
   916
            return NULL;
slouken@3057
   917
        }
slouken@3057
   918
        SDL_GL_LoadLibrary(NULL);
slouken@2753
   919
    }
slouken@3685
   920
    display = SDL_CurrentDisplay;
slouken@3685
   921
    window = (SDL_Window *)SDL_calloc(1, sizeof(*window));
slouken@3695
   922
    window->magic = &_this->window_magic;
slouken@3685
   923
    window->id = _this->next_object_id++;
slouken@3685
   924
    window->x = x;
slouken@3685
   925
    window->y = y;
slouken@3685
   926
    window->w = w;
slouken@3685
   927
    window->h = h;
slouken@3685
   928
    window->flags = (flags & allowed_flags);
slouken@3685
   929
    window->display = display;
slouken@3685
   930
    window->next = display->windows;
slouken@3693
   931
    if (display->windows) {
slouken@3693
   932
        display->windows->prev = window;
slouken@3693
   933
    }
slouken@3685
   934
    display->windows = window;
slouken@3685
   935
slouken@3685
   936
    if (_this->CreateWindow && _this->CreateWindow(_this, window) < 0) {
slouken@3685
   937
        SDL_DestroyWindow(window);
slouken@3685
   938
        return NULL;
slouken@3685
   939
    }
slouken@0
   940
slouken@2753
   941
    if (title) {
slouken@3685
   942
        SDL_SetWindowTitle(window, title);
slouken@2753
   943
    }
slouken@2753
   944
    if (flags & SDL_WINDOW_MAXIMIZED) {
slouken@3685
   945
        SDL_MaximizeWindow(window);
slouken@2753
   946
    }
slouken@2753
   947
    if (flags & SDL_WINDOW_MINIMIZED) {
slouken@3685
   948
        SDL_MinimizeWindow(window);
slouken@2753
   949
    }
slouken@2753
   950
    if (flags & SDL_WINDOW_SHOWN) {
slouken@3685
   951
        SDL_ShowWindow(window);
slouken@3685
   952
    }
slouken@3685
   953
    SDL_UpdateWindowGrab(window);
slouken@3685
   954
slouken@3685
   955
    return window;
slouken@1895
   956
}
slouken@0
   957
slouken@3685
   958
SDL_Window *
slouken@1895
   959
SDL_CreateWindowFrom(const void *data)
slouken@1895
   960
{
slouken@2753
   961
    SDL_VideoDisplay *display;
slouken@3685
   962
    SDL_Window *window;
slouken@0
   963
slouken@2753
   964
    if (!_this) {
slouken@2753
   965
        SDL_UninitializedVideo();
slouken@3685
   966
        return NULL;
slouken@3685
   967
    }
slouken@3685
   968
    display = SDL_CurrentDisplay;
slouken@3685
   969
    window = (SDL_Window *)SDL_calloc(1, sizeof(*window));
slouken@3695
   970
    window->magic = &_this->window_magic;
slouken@3685
   971
    window->id = _this->next_object_id++;
slouken@3685
   972
    window->flags = SDL_WINDOW_FOREIGN;
slouken@3685
   973
    window->display = display;
slouken@3685
   974
    window->next = display->windows;
slouken@3693
   975
    if (display->windows) {
slouken@3693
   976
        display->windows->prev = window;
slouken@3693
   977
    }
slouken@3685
   978
    display->windows = window;
slouken@1895
   979
slouken@2753
   980
    if (!_this->CreateWindowFrom ||
slouken@3685
   981
        _this->CreateWindowFrom(_this, window, data) < 0) {
slouken@3685
   982
        SDL_DestroyWindow(window);
slouken@3685
   983
        return NULL;
slouken@3685
   984
    }
slouken@3685
   985
    return window;
slouken@1895
   986
}
slouken@1895
   987
slouken@1924
   988
int
slouken@1928
   989
SDL_RecreateWindow(SDL_Window * window, Uint32 flags)
slouken@1924
   990
{
slouken@3057
   991
    const Uint32 allowed_flags = (SDL_WINDOW_FULLSCREEN |
slouken@3057
   992
                                  SDL_WINDOW_OPENGL |
slouken@3057
   993
                                  SDL_WINDOW_BORDERLESS |
slouken@3057
   994
                                  SDL_WINDOW_RESIZABLE |
slouken@3486
   995
                                  SDL_WINDOW_INPUT_GRABBED |
slouken@3486
   996
                                  SDL_WINDOW_FOREIGN);
slouken@2753
   997
    char *title = window->title;
slouken@1956
   998
slouken@2753
   999
    if ((flags & SDL_WINDOW_OPENGL) && !_this->GL_CreateContext) {
slouken@2753
  1000
        SDL_SetError("No OpenGL support in video driver");
slouken@2753
  1001
        return -1;
slouken@2753
  1002
    }
slouken@3057
  1003
    if ((window->flags & SDL_WINDOW_OPENGL) != (flags & SDL_WINDOW_OPENGL)) {
slouken@3057
  1004
        if (flags & SDL_WINDOW_OPENGL) {
slouken@3057
  1005
            SDL_GL_LoadLibrary(NULL);
slouken@3057
  1006
        } else {
slouken@3057
  1007
            SDL_GL_UnloadLibrary();
slouken@3057
  1008
        }
slouken@3057
  1009
    }
slouken@3057
  1010
slouken@3057
  1011
    if (window->flags & SDL_WINDOW_FOREIGN) {
slouken@3057
  1012
        /* Can't destroy and re-create foreign windows, hrm */
slouken@3057
  1013
        flags |= SDL_WINDOW_FOREIGN;
slouken@3057
  1014
    } else {
slouken@3057
  1015
        flags &= ~SDL_WINDOW_FOREIGN;
slouken@3057
  1016
    }
slouken@3057
  1017
slouken@3057
  1018
    if (_this->DestroyWindow && !(flags & SDL_WINDOW_FOREIGN)) {
slouken@2753
  1019
        _this->DestroyWindow(_this, window);
slouken@2753
  1020
    }
slouken@3057
  1021
slouken@2753
  1022
    window->title = NULL;
slouken@3057
  1023
    window->flags = (flags & allowed_flags);
slouken@1956
  1024
slouken@3057
  1025
    if (_this->CreateWindow && !(flags & SDL_WINDOW_FOREIGN)) {
slouken@3057
  1026
        if (_this->CreateWindow(_this, window) < 0) {
slouken@3057
  1027
            if (flags & SDL_WINDOW_OPENGL) {
slouken@3057
  1028
                SDL_GL_UnloadLibrary();
slouken@3057
  1029
            }
slouken@3057
  1030
            return -1;
slouken@3057
  1031
        }
slouken@2753
  1032
    }
slouken@3057
  1033
slouken@2753
  1034
    if (title) {
slouken@3685
  1035
        SDL_SetWindowTitle(window, title);
slouken@2753
  1036
        SDL_free(title);
slouken@2753
  1037
    }
slouken@2753
  1038
    if (flags & SDL_WINDOW_MAXIMIZED) {
slouken@3685
  1039
        SDL_MaximizeWindow(window);
slouken@2753
  1040
    }
slouken@2753
  1041
    if (flags & SDL_WINDOW_MINIMIZED) {
slouken@3685
  1042
        SDL_MinimizeWindow(window);
slouken@2753
  1043
    }
slouken@2753
  1044
    if (flags & SDL_WINDOW_SHOWN) {
slouken@3685
  1045
        SDL_ShowWindow(window);
slouken@2753
  1046
    }
slouken@2875
  1047
    SDL_UpdateWindowGrab(window);
slouken@2875
  1048
slouken@2753
  1049
    return 0;
slouken@1924
  1050
}
slouken@1924
  1051
slouken@1895
  1052
Uint32
slouken@3685
  1053
SDL_GetWindowID(SDL_Window * window)
slouken@1895
  1054
{
slouken@3695
  1055
    CHECK_WINDOW_MAGIC(window, 0);
slouken@3695
  1056
slouken@3685
  1057
    return window->id;
slouken@3685
  1058
}
slouken@3685
  1059
slouken@3685
  1060
SDL_Window *
slouken@3685
  1061
SDL_GetWindowFromID(Uint32 id)
slouken@3685
  1062
{
slouken@3685
  1063
    SDL_Window *window;
slouken@3685
  1064
    int i;
slouken@3685
  1065
slouken@3685
  1066
    if (!_this) {
slouken@3685
  1067
        return NULL;
slouken@3685
  1068
    }
slouken@3685
  1069
    /* FIXME: Should we keep a separate hash table for these? */
slouken@3685
  1070
    for (i = _this->num_displays; i--;) {
slouken@3685
  1071
        SDL_VideoDisplay *display = &_this->displays[i];
slouken@3685
  1072
        for (window = display->windows; window; window = window->next) {
slouken@3685
  1073
            if (window->id == id) {
slouken@3685
  1074
                return window;
slouken@3685
  1075
            }
slouken@3685
  1076
        }
slouken@3685
  1077
    }
slouken@3685
  1078
    return NULL;
slouken@3685
  1079
}
slouken@3685
  1080
slouken@3685
  1081
Uint32
slouken@3685
  1082
SDL_GetWindowFlags(SDL_Window * window)
slouken@3685
  1083
{
slouken@3695
  1084
    CHECK_WINDOW_MAGIC(window, 0);
slouken@3695
  1085
slouken@2753
  1086
    return window->flags;
slouken@1895
  1087
}
slouken@1895
  1088
slouken@1895
  1089
void
slouken@3685
  1090
SDL_SetWindowTitle(SDL_Window * window, const char *title)
slouken@1895
  1091
{
slouken@3695
  1092
    CHECK_WINDOW_MAGIC(window, );
slouken@3695
  1093
slouken@3695
  1094
    if (title == window->title) {
slouken@2753
  1095
        return;
slouken@2753
  1096
    }
slouken@2753
  1097
    if (window->title) {
slouken@2753
  1098
        SDL_free(window->title);
slouken@2753
  1099
    }
slouken@4871
  1100
    if (title && *title) {
slouken@2753
  1101
        window->title = SDL_strdup(title);
slouken@2753
  1102
    } else {
slouken@2753
  1103
        window->title = NULL;
slouken@2753
  1104
    }
slouken@1956
  1105
slouken@2753
  1106
    if (_this->SetWindowTitle) {
slouken@2753
  1107
        _this->SetWindowTitle(_this, window);
slouken@2753
  1108
    }
slouken@1895
  1109
}
slouken@1895
  1110
slouken@2753
  1111
const char *
slouken@3685
  1112
SDL_GetWindowTitle(SDL_Window * window)
slouken@1895
  1113
{
slouken@4872
  1114
    CHECK_WINDOW_MAGIC(window, "");
slouken@3695
  1115
slouken@4871
  1116
    return window->title ? window->title : "";
slouken@1895
  1117
}
slouken@1895
  1118
slouken@1895
  1119
void
slouken@3685
  1120
SDL_SetWindowIcon(SDL_Window * window, SDL_Surface * icon)
slouken@2967
  1121
{
slouken@3695
  1122
    CHECK_WINDOW_MAGIC(window, );
slouken@3695
  1123
slouken@2967
  1124
    if (_this->SetWindowIcon) {
slouken@2967
  1125
        _this->SetWindowIcon(_this, window, icon);
slouken@2967
  1126
    }
slouken@2967
  1127
}
slouken@2967
  1128
slouken@5165
  1129
void*
slouken@5165
  1130
SDL_SetWindowData(SDL_Window * window, const char *name, void *userdata)
slouken@1895
  1131
{
slouken@5165
  1132
    SDL_WindowUserData *prev, *data;
slouken@3695
  1133
slouken@5165
  1134
    CHECK_WINDOW_MAGIC(window, NULL);
slouken@5165
  1135
slouken@5165
  1136
    /* See if the named data already exists */
slouken@5165
  1137
    prev = NULL;
slouken@5165
  1138
    for (data = window->data; data; prev = data, data = data->next) {
slouken@5165
  1139
        if (SDL_strcmp(data->name, name) == 0) {
slouken@5165
  1140
            void *last_value = data->data;
slouken@5165
  1141
slouken@5165
  1142
            if (userdata) {
slouken@5165
  1143
                /* Set the new value */
slouken@5165
  1144
                data->data = userdata;
slouken@5165
  1145
            } else {
slouken@5165
  1146
                /* Delete this value */
slouken@5165
  1147
                if (prev) {
slouken@5165
  1148
                    prev->next = data->next;
slouken@5165
  1149
                } else {
slouken@5165
  1150
                    window->data = data->next;
slouken@5165
  1151
                }
slouken@5165
  1152
                SDL_free(data->name);
slouken@5165
  1153
                SDL_free(data);
slouken@5165
  1154
            }
slouken@5165
  1155
            return last_value;
slouken@5165
  1156
        }
slouken@5165
  1157
    }
slouken@5165
  1158
slouken@5165
  1159
    /* Add new data to the window */
slouken@5165
  1160
    if (userdata) {
slouken@5165
  1161
        data = (SDL_WindowUserData *)SDL_malloc(sizeof(*data));
slouken@5165
  1162
        data->name = SDL_strdup(name);
slouken@5165
  1163
        data->data = userdata;
slouken@5165
  1164
        data->next = window->data;
slouken@5165
  1165
        window->data = data;
slouken@5165
  1166
    }
slouken@5165
  1167
    return NULL;
slouken@1895
  1168
}
slouken@1895
  1169
slouken@2753
  1170
void *
slouken@5165
  1171
SDL_GetWindowData(SDL_Window * window, const char *name)
slouken@1895
  1172
{
slouken@5165
  1173
    SDL_WindowUserData *data;
slouken@5165
  1174
slouken@3695
  1175
    CHECK_WINDOW_MAGIC(window, NULL);
slouken@3695
  1176
slouken@5165
  1177
    for (data = window->data; data; data = data->next) {
slouken@5165
  1178
        if (SDL_strcmp(data->name, name) == 0) {
slouken@5165
  1179
            return data->data;
slouken@5165
  1180
        }
slouken@5165
  1181
    }
slouken@5165
  1182
    return NULL;
slouken@1895
  1183
}
slouken@1895
  1184
slouken@1895
  1185
void
slouken@3685
  1186
SDL_SetWindowPosition(SDL_Window * window, int x, int y)
slouken@1895
  1187
{
slouken@3695
  1188
    CHECK_WINDOW_MAGIC(window, );
slouken@3695
  1189
slouken@2875
  1190
    if (x != SDL_WINDOWPOS_UNDEFINED) {
slouken@2753
  1191
        window->x = x;
slouken@2753
  1192
    }
slouken@2875
  1193
    if (y != SDL_WINDOWPOS_UNDEFINED) {
slouken@2753
  1194
        window->y = y;
slouken@2753
  1195
    }
slouken@2753
  1196
    if (_this->SetWindowPosition) {
slouken@2753
  1197
        _this->SetWindowPosition(_this, window);
slouken@2753
  1198
    }
slouken@3685
  1199
    SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, x, y);
slouken@1895
  1200
}
slouken@1895
  1201
slouken@1895
  1202
void
slouken@3685
  1203
SDL_GetWindowPosition(SDL_Window * window, int *x, int *y)
slouken@1895
  1204
{
slouken@3695
  1205
    CHECK_WINDOW_MAGIC(window, );
slouken@3695
  1206
slouken@2753
  1207
    if (x) {
slouken@2753
  1208
        *x = window->x;
slouken@2753
  1209
    }
slouken@2753
  1210
    if (y) {
slouken@2753
  1211
        *y = window->y;
slouken@2753
  1212
    }
slouken@1895
  1213
}
slouken@1895
  1214
slouken@1895
  1215
void
slouken@3685
  1216
SDL_SetWindowSize(SDL_Window * window, int w, int h)
slouken@1895
  1217
{
slouken@3695
  1218
    CHECK_WINDOW_MAGIC(window, );
slouken@3695
  1219
slouken@2753
  1220
    window->w = w;
slouken@2753
  1221
    window->h = h;
slouken@1895
  1222
slouken@2753
  1223
    if (_this->SetWindowSize) {
slouken@2753
  1224
        _this->SetWindowSize(_this, window);
slouken@2753
  1225
    }
slouken@5147
  1226
    SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, w, h);
slouken@1895
  1227
}
slouken@1895
  1228
slouken@1895
  1229
void
slouken@3685
  1230
SDL_GetWindowSize(SDL_Window * window, int *w, int *h)
slouken@1895
  1231
{
slouken@2860
  1232
    if (window) {
slouken@2849
  1233
        if (w) {
slouken@2849
  1234
            *w = window->w;
slouken@2849
  1235
        }
slouken@2849
  1236
        if (h) {
slouken@2849
  1237
            *h = window->h;
slouken@2849
  1238
        }
slouken@2849
  1239
    } else {
slouken@2849
  1240
        if (w) {
slouken@2849
  1241
            *w = 0;
slouken@2849
  1242
        }
slouken@2849
  1243
        if (h) {
slouken@2849
  1244
            *h = 0;
slouken@2849
  1245
        }
slouken@2753
  1246
    }
slouken@1895
  1247
}
slouken@1895
  1248
slouken@1895
  1249
void
slouken@3685
  1250
SDL_ShowWindow(SDL_Window * window)
slouken@1895
  1251
{
slouken@3695
  1252
    CHECK_WINDOW_MAGIC(window, );
slouken@3695
  1253
slouken@3695
  1254
    if (window->flags & SDL_WINDOW_SHOWN) {
slouken@2753
  1255
        return;
slouken@2753
  1256
    }
slouken@1895
  1257
slouken@2753
  1258
    if (_this->ShowWindow) {
slouken@2753
  1259
        _this->ShowWindow(_this, window);
slouken@2753
  1260
    }
slouken@3685
  1261
    SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0);
slouken@1895
  1262
}
slouken@1895
  1263
slouken@1895
  1264
void
slouken@3685
  1265
SDL_HideWindow(SDL_Window * window)
slouken@1895
  1266
{
slouken@3695
  1267
    CHECK_WINDOW_MAGIC(window, );
slouken@3695
  1268
slouken@3695
  1269
    if (!(window->flags & SDL_WINDOW_SHOWN)) {
slouken@2753
  1270
        return;
slouken@2753
  1271
    }
slouken@1895
  1272
slouken@2753
  1273
    if (_this->HideWindow) {
slouken@2753
  1274
        _this->HideWindow(_this, window);
slouken@2753
  1275
    }
slouken@3685
  1276
    SDL_SendWindowEvent(window, SDL_WINDOWEVENT_HIDDEN, 0, 0);
slouken@1895
  1277
}
slouken@1895
  1278
slouken@1895
  1279
void
slouken@3685
  1280
SDL_RaiseWindow(SDL_Window * window)
slouken@1895
  1281
{
slouken@3695
  1282
    CHECK_WINDOW_MAGIC(window, );
slouken@3695
  1283
slouken@3695
  1284
    if (!(window->flags & SDL_WINDOW_SHOWN)) {
slouken@2753
  1285
        return;
slouken@2753
  1286
    }
slouken@2753
  1287
    if (_this->RaiseWindow) {
slouken@2753
  1288
        _this->RaiseWindow(_this, window);
slouken@3502
  1289
    } else {
slouken@3502
  1290
        /* FIXME: What we really want is a way to request focus */
slouken@3685
  1291
        SDL_SendWindowEvent(window, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0);
slouken@2753
  1292
    }
slouken@1895
  1293
}
slouken@1895
  1294
slouken@1895
  1295
void
slouken@3685
  1296
SDL_MaximizeWindow(SDL_Window * window)
slouken@1895
  1297
{
slouken@3695
  1298
    CHECK_WINDOW_MAGIC(window, );
slouken@3695
  1299
slouken@3695
  1300
    if (window->flags & SDL_WINDOW_MAXIMIZED) {
slouken@2753
  1301
        return;
slouken@2753
  1302
    }
slouken@1895
  1303
slouken@2753
  1304
    if (_this->MaximizeWindow) {
slouken@2753
  1305
        _this->MaximizeWindow(_this, window);
slouken@2753
  1306
    }
slouken@3685
  1307
    SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MAXIMIZED, 0, 0);
slouken@1895
  1308
}
slouken@1895
  1309
slouken@1895
  1310
void
slouken@3685
  1311
SDL_MinimizeWindow(SDL_Window * window)
slouken@1895
  1312
{
slouken@3695
  1313
    CHECK_WINDOW_MAGIC(window, );
slouken@3695
  1314
slouken@3695
  1315
    if (window->flags & SDL_WINDOW_MINIMIZED) {
slouken@2753
  1316
        return;
slouken@2753
  1317
    }
slouken@1895
  1318
slouken@2753
  1319
    if (_this->MinimizeWindow) {
slouken@2753
  1320
        _this->MinimizeWindow(_this, window);
slouken@2753
  1321
    }
slouken@3685
  1322
    SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
slouken@1895
  1323
}
slouken@1895
  1324
slouken@1895
  1325
void
slouken@3685
  1326
SDL_RestoreWindow(SDL_Window * window)
slouken@1895
  1327
{
slouken@3695
  1328
    CHECK_WINDOW_MAGIC(window, );
slouken@3695
  1329
slouken@3695
  1330
    if (!(window->flags & (SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED))) {
slouken@2753
  1331
        return;
slouken@2753
  1332
    }
slouken@1895
  1333
slouken@2753
  1334
    if (_this->RestoreWindow) {
slouken@2753
  1335
        _this->RestoreWindow(_this, window);
slouken@2753
  1336
    }
slouken@3685
  1337
    SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0);
slouken@1895
  1338
}
slouken@1895
  1339
slouken@1895
  1340
int
slouken@3685
  1341
SDL_SetWindowFullscreen(SDL_Window * window, int fullscreen)
slouken@1895
  1342
{
slouken@3695
  1343
    CHECK_WINDOW_MAGIC(window, -1);
slouken@3695
  1344
slouken@2753
  1345
    if (fullscreen) {
slouken@2753
  1346
        fullscreen = SDL_WINDOW_FULLSCREEN;
slouken@2753
  1347
    }
slouken@2753
  1348
    if ((window->flags & SDL_WINDOW_FULLSCREEN) == fullscreen) {
slouken@2753
  1349
        return 0;
slouken@2753
  1350
    }
slouken@2753
  1351
    if (fullscreen) {
slouken@2753
  1352
        window->flags |= SDL_WINDOW_FULLSCREEN;
slouken@1895
  1353
slouken@3502
  1354
        SDL_UpdateFullscreenMode(window, SDL_TRUE);
slouken@2753
  1355
    } else {
slouken@2753
  1356
        window->flags &= ~SDL_WINDOW_FULLSCREEN;
slouken@1895
  1357
slouken@3502
  1358
        SDL_UpdateFullscreenMode(window, SDL_FALSE);
slouken@2753
  1359
    }
slouken@2753
  1360
    return 0;
slouken@1895
  1361
}
slouken@1895
  1362
slouken@5166
  1363
static SDL_Surface *
slouken@5166
  1364
SDL_CreateWindowFramebuffer(SDL_Window * window)
slouken@5166
  1365
{
slouken@5166
  1366
    Uint32 format;
slouken@5166
  1367
    void *pixels;
slouken@5166
  1368
    int pitch;
slouken@5166
  1369
    int bpp;
slouken@5166
  1370
    Uint32 Rmask, Gmask, Bmask, Amask;
slouken@5166
  1371
slouken@5166
  1372
    if (!_this->CreateWindowFramebuffer || !_this->UpdateWindowFramebuffer) {
slouken@5166
  1373
        return NULL;
slouken@5166
  1374
    }
slouken@5166
  1375
slouken@5166
  1376
    if (_this->CreateWindowFramebuffer(_this, window, &format, &pixels, &pitch) < 0) {
slouken@5166
  1377
        return NULL;
slouken@5166
  1378
    }
slouken@5166
  1379
slouken@5166
  1380
    if (!SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
slouken@5166
  1381
        return NULL;
slouken@5166
  1382
    }
slouken@5166
  1383
slouken@5166
  1384
    return SDL_CreateRGBSurfaceFrom(pixels, window->w, window->h, bpp, pitch, Rmask, Gmask, Bmask, Amask);
slouken@5166
  1385
}
slouken@5166
  1386
slouken@5166
  1387
SDL_Surface *
slouken@5166
  1388
SDL_GetWindowSurface(SDL_Window * window)
slouken@5166
  1389
{
slouken@5166
  1390
    CHECK_WINDOW_MAGIC(window, NULL);
slouken@5166
  1391
slouken@5166
  1392
    if (!window->surface) {
slouken@5166
  1393
        window->surface = SDL_CreateWindowFramebuffer(window);
slouken@5169
  1394
        if (window->surface) {
slouken@5169
  1395
            window->surface->refcount = 0x7FFFFFF;
slouken@5169
  1396
        }
slouken@5166
  1397
    }
slouken@5166
  1398
    return window->surface;
slouken@5166
  1399
}
slouken@5166
  1400
slouken@5166
  1401
int
slouken@5166
  1402
SDL_UpdateWindowSurface(SDL_Window * window)
slouken@5166
  1403
{
slouken@5166
  1404
    SDL_Rect full_rect;
slouken@5166
  1405
slouken@5166
  1406
    CHECK_WINDOW_MAGIC(window, -1);
slouken@5166
  1407
slouken@5166
  1408
    full_rect.x = 0;
slouken@5166
  1409
    full_rect.y = 0;
slouken@5166
  1410
    full_rect.w = window->w;
slouken@5166
  1411
    full_rect.h = window->h;
slouken@5166
  1412
    return SDL_UpdateWindowSurfaceRects(window, 1, &full_rect);
slouken@5166
  1413
}
slouken@5166
  1414
slouken@5166
  1415
int
slouken@5166
  1416
SDL_UpdateWindowSurfaceRects(SDL_Window * window,
slouken@5166
  1417
                             int numrects, SDL_Rect * rects)
slouken@5166
  1418
{
slouken@5166
  1419
    CHECK_WINDOW_MAGIC(window, -1);
slouken@5166
  1420
slouken@5166
  1421
    if (!window->surface) {
slouken@5166
  1422
        SDL_SetError("Window surface is invalid, please call SDL_GetWindowSurface() to get a new surface");
slouken@5166
  1423
        return -1;
slouken@5166
  1424
    }
slouken@5166
  1425
slouken@5166
  1426
    return _this->UpdateWindowFramebuffer(_this, window, numrects, rects);
slouken@5166
  1427
}
slouken@5166
  1428
slouken@1895
  1429
void
slouken@3685
  1430
SDL_SetWindowGrab(SDL_Window * window, int mode)
slouken@1895
  1431
{
slouken@3695
  1432
    CHECK_WINDOW_MAGIC(window, );
slouken@3695
  1433
slouken@3695
  1434
    if ((!!mode == !!(window->flags & SDL_WINDOW_INPUT_GRABBED))) {
slouken@2753
  1435
        return;
slouken@2753
  1436
    }
slouken@2753
  1437
    if (mode) {
slouken@2753
  1438
        window->flags |= SDL_WINDOW_INPUT_GRABBED;
slouken@2753
  1439
    } else {
slouken@2753
  1440
        window->flags &= ~SDL_WINDOW_INPUT_GRABBED;
slouken@2753
  1441
    }
slouken@2875
  1442
    SDL_UpdateWindowGrab(window);
slouken@2875
  1443
}
slouken@1895
  1444
slouken@2875
  1445
static void
slouken@2876
  1446
SDL_UpdateWindowGrab(SDL_Window * window)
slouken@2875
  1447
{
slouken@2753
  1448
    if ((window->flags & SDL_WINDOW_INPUT_FOCUS) && _this->SetWindowGrab) {
slouken@2753
  1449
        _this->SetWindowGrab(_this, window);
slouken@2753
  1450
    }
slouken@1895
  1451
}
slouken@1895
  1452
slouken@1895
  1453
int
slouken@3685
  1454
SDL_GetWindowGrab(SDL_Window * window)
slouken@1895
  1455
{
slouken@3695
  1456
    CHECK_WINDOW_MAGIC(window, 0);
slouken@3695
  1457
slouken@2753
  1458
    return ((window->flags & SDL_WINDOW_INPUT_GRABBED) != 0);
slouken@1895
  1459
}
slouken@1895
  1460
slouken@1895
  1461
void
slouken@1895
  1462
SDL_OnWindowShown(SDL_Window * window)
slouken@1895
  1463
{
slouken@3685
  1464
    SDL_RaiseWindow(window);
slouken@3502
  1465
    SDL_UpdateFullscreenMode(window, SDL_TRUE);
slouken@1895
  1466
}
slouken@1895
  1467
slouken@1895
  1468
void
slouken@1895
  1469
SDL_OnWindowHidden(SDL_Window * window)
slouken@1895
  1470
{
slouken@3502
  1471
    SDL_UpdateFullscreenMode(window, SDL_FALSE);
slouken@1895
  1472
}
slouken@1895
  1473
slouken@1895
  1474
void
slouken@5166
  1475
SDL_OnWindowResized(SDL_Window * window)
slouken@5166
  1476
{
slouken@5166
  1477
    if (window->surface) {
slouken@5169
  1478
        window->surface->refcount = 0;
slouken@5166
  1479
        SDL_FreeSurface(window->surface);
slouken@5166
  1480
        window->surface = NULL;
slouken@5166
  1481
    }
slouken@5166
  1482
}
slouken@5166
  1483
slouken@5166
  1484
void
slouken@3502
  1485
SDL_OnWindowMinimized(SDL_Window * window)
slouken@3502
  1486
{
slouken@3502
  1487
    SDL_UpdateFullscreenMode(window, SDL_FALSE);
slouken@3502
  1488
}
slouken@3502
  1489
slouken@3502
  1490
void
slouken@3502
  1491
SDL_OnWindowRestored(SDL_Window * window)
slouken@3502
  1492
{
slouken@3685
  1493
    SDL_RaiseWindow(window);
slouken@3502
  1494
    SDL_UpdateFullscreenMode(window, SDL_TRUE);
slouken@3502
  1495
}
slouken@3502
  1496
slouken@3502
  1497
void
slouken@1895
  1498
SDL_OnWindowFocusGained(SDL_Window * window)
slouken@1895
  1499
{
slouken@3685
  1500
    SDL_VideoDisplay *display = window->display;
slouken@1895
  1501
slouken@2753
  1502
    if (display->gamma && _this->SetDisplayGammaRamp) {
slouken@3500
  1503
        _this->SetDisplayGammaRamp(_this, display, display->gamma);
slouken@2753
  1504
    }
slouken@2876
  1505
    if ((window->flags & (SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_FULLSCREEN))
slouken@2876
  1506
        && _this->SetWindowGrab) {
slouken@2753
  1507
        _this->SetWindowGrab(_this, window);
slouken@2753
  1508
    }
slouken@1895
  1509
}
slouken@1895
  1510
slouken@1895
  1511
void
slouken@1895
  1512
SDL_OnWindowFocusLost(SDL_Window * window)
slouken@1895
  1513
{
slouken@3685
  1514
    SDL_VideoDisplay *display = window->display;
slouken@1895
  1515
slouken@3512
  1516
    /* If we're fullscreen on a single-head system and lose focus, minimize */
slouken@3512
  1517
    if ((window->flags & SDL_WINDOW_FULLSCREEN) &&
slouken@3512
  1518
        _this->num_displays == 1) {
slouken@3685
  1519
        SDL_MinimizeWindow(window);
slouken@3512
  1520
    }
slouken@3512
  1521
slouken@2753
  1522
    if (display->gamma && _this->SetDisplayGammaRamp) {
slouken@3500
  1523
        _this->SetDisplayGammaRamp(_this, display, display->saved_gamma);
slouken@2753
  1524
    }
slouken@2876
  1525
    if ((window->flags & (SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_FULLSCREEN))
slouken@2876
  1526
        && _this->SetWindowGrab) {
slouken@2753
  1527
        _this->SetWindowGrab(_this, window);
slouken@2753
  1528
    }
slouken@1895
  1529
}
slouken@1895
  1530
slouken@3685
  1531
SDL_Window *
slouken@1895
  1532
SDL_GetFocusWindow(void)
slouken@1895
  1533
{
slouken@2753
  1534
    SDL_VideoDisplay *display;
slouken@3685
  1535
    SDL_Window *window;
slouken@1895
  1536
slouken@2753
  1537
    if (!_this) {
slouken@3685
  1538
        return NULL;
slouken@3685
  1539
    }
slouken@3685
  1540
    display = SDL_CurrentDisplay;
slouken@3685
  1541
    for (window = display->windows; window; window = window->next) {
slouken@2753
  1542
        if (window->flags & SDL_WINDOW_INPUT_FOCUS) {
slouken@3685
  1543
            return window;
slouken@2753
  1544
        }
slouken@2753
  1545
    }
slouken@3685
  1546
    return NULL;
slouken@1895
  1547
}
slouken@1895
  1548
slouken@1895
  1549
void
slouken@3685
  1550
SDL_DestroyWindow(SDL_Window * window)
slouken@1895
  1551
{
slouken@3685
  1552
    SDL_VideoDisplay *display;
slouken@3685
  1553
slouken@3695
  1554
    CHECK_WINDOW_MAGIC(window, );
slouken@3503
  1555
slouken@3685
  1556
    /* Restore video mode, etc. */
slouken@3685
  1557
    SDL_UpdateFullscreenMode(window, SDL_FALSE);
slouken@3685
  1558
slouken@5169
  1559
    if (window->surface) {
slouken@5169
  1560
        window->surface->refcount = 0;
slouken@5169
  1561
        SDL_FreeSurface(window->surface);
slouken@5169
  1562
    }
slouken@5166
  1563
    if (_this->DestroyWindowFramebuffer) {
slouken@5166
  1564
        _this->DestroyWindowFramebuffer(_this, window);
slouken@5166
  1565
    }
slouken@3685
  1566
    if (_this->DestroyWindow) {
slouken@3685
  1567
        _this->DestroyWindow(_this, window);
slouken@3685
  1568
    }
slouken@3685
  1569
    if (window->flags & SDL_WINDOW_OPENGL) {
slouken@3685
  1570
        SDL_GL_UnloadLibrary();
slouken@3685
  1571
    }
slouken@3685
  1572
slouken@4901
  1573
    /* Now invalidate magic */
slouken@4897
  1574
    window->magic = NULL;
slouken@4897
  1575
slouken@5165
  1576
    /* Free memory associated with the window */
slouken@5165
  1577
    if (window->title) {
slouken@5165
  1578
        SDL_free(window->title);
slouken@5165
  1579
    }
slouken@5165
  1580
    while (window->data) {
slouken@5165
  1581
        SDL_WindowUserData *data = window->data;
slouken@5165
  1582
slouken@5165
  1583
        window->data = data->next;
slouken@5165
  1584
        SDL_free(data->name);
slouken@5165
  1585
        SDL_free(data);
slouken@5165
  1586
    }
slouken@5165
  1587
slouken@3685
  1588
    /* Unlink the window from the list */
slouken@3685
  1589
    display = window->display;
slouken@3693
  1590
    if (window->next) {
slouken@3693
  1591
        window->next->prev = window->prev;
slouken@3693
  1592
    }
slouken@3685
  1593
    if (window->prev) {
slouken@3685
  1594
        window->prev->next = window->next;
slouken@3685
  1595
    } else {
slouken@3685
  1596
        display->windows = window->next;
slouken@3685
  1597
    }
slouken@3685
  1598
slouken@3685
  1599
    SDL_free(window);
slouken@1895
  1600
}
slouken@1895
  1601
slouken@3025
  1602
SDL_bool
slouken@3025
  1603
SDL_IsScreenSaverEnabled()
slouken@3025
  1604
{
slouken@3025
  1605
    if (!_this) {
slouken@3025
  1606
        return SDL_TRUE;
slouken@3025
  1607
    }
slouken@3025
  1608
    return _this->suspend_screensaver ? SDL_FALSE : SDL_TRUE;
slouken@3025
  1609
}
slouken@3025
  1610
slouken@3025
  1611
void
slouken@3025
  1612
SDL_EnableScreenSaver()
slouken@3025
  1613
{
slouken@3025
  1614
    if (!_this) {
slouken@3025
  1615
        return;
slouken@3025
  1616
    }
slouken@3025
  1617
    if (!_this->suspend_screensaver) {
slouken@3025
  1618
        return;
slouken@3025
  1619
    }
slouken@3025
  1620
    _this->suspend_screensaver = SDL_FALSE;
slouken@3025
  1621
    if (_this->SuspendScreenSaver) {
slouken@3025
  1622
        _this->SuspendScreenSaver(_this);
slouken@3025
  1623
    }
slouken@3025
  1624
}
slouken@3025
  1625
slouken@3025
  1626
void
slouken@3025
  1627
SDL_DisableScreenSaver()
slouken@3025
  1628
{
slouken@3025
  1629
    if (!_this) {
slouken@3025
  1630
        return;
slouken@3025
  1631
    }
slouken@3025
  1632
    if (_this->suspend_screensaver) {
slouken@3025
  1633
        return;
slouken@3025
  1634
    }
slouken@3025
  1635
    _this->suspend_screensaver = SDL_TRUE;
slouken@3025
  1636
    if (_this->SuspendScreenSaver) {
slouken@3025
  1637
        _this->SuspendScreenSaver(_this);
slouken@3025
  1638
    }
slouken@3025
  1639
}
slouken@3025
  1640
slouken@1895
  1641
void
slouken@1895
  1642
SDL_VideoQuit(void)
slouken@1895
  1643
{
slouken@2753
  1644
    int i, j;
slouken@1895
  1645
slouken@2753
  1646
    if (!_this) {
slouken@2753
  1647
        return;
slouken@2753
  1648
    }
slouken@5123
  1649
slouken@2753
  1650
    /* Halt event processing before doing anything else */
slouken@5123
  1651
    SDL_QuitQuit();
slouken@5123
  1652
    SDL_MouseQuit();
slouken@5123
  1653
    SDL_KeyboardQuit();
slouken@2753
  1654
    SDL_StopEventLoop();
slouken@5123
  1655
slouken@3029
  1656
    SDL_EnableScreenSaver();
slouken@1895
  1657
slouken@2753
  1658
    /* Clean up the system video */
slouken@2753
  1659
    for (i = _this->num_displays; i--;) {
slouken@2753
  1660
        SDL_VideoDisplay *display = &_this->displays[i];
slouken@3685
  1661
        while (display->windows) {
slouken@3685
  1662
            SDL_DestroyWindow(display->windows);
slouken@2753
  1663
        }
slouken@2753
  1664
    }
slouken@2753
  1665
    _this->VideoQuit(_this);
slouken@1895
  1666
slouken@2753
  1667
    for (i = _this->num_displays; i--;) {
slouken@2753
  1668
        SDL_VideoDisplay *display = &_this->displays[i];
slouken@2753
  1669
        for (j = display->num_display_modes; j--;) {
slouken@2753
  1670
            if (display->display_modes[j].driverdata) {
slouken@2753
  1671
                SDL_free(display->display_modes[j].driverdata);
slouken@2753
  1672
                display->display_modes[j].driverdata = NULL;
slouken@2753
  1673
            }
slouken@2753
  1674
        }
slouken@2753
  1675
        if (display->display_modes) {
slouken@2753
  1676
            SDL_free(display->display_modes);
slouken@2753
  1677
            display->display_modes = NULL;
slouken@2753
  1678
        }
slouken@2753
  1679
        if (display->desktop_mode.driverdata) {
slouken@2753
  1680
            SDL_free(display->desktop_mode.driverdata);
slouken@2753
  1681
            display->desktop_mode.driverdata = NULL;
slouken@2753
  1682
        }
slouken@2753
  1683
        if (display->gamma) {
slouken@2753
  1684
            SDL_free(display->gamma);
slouken@2753
  1685
            display->gamma = NULL;
slouken@2753
  1686
        }
slouken@2753
  1687
        if (display->driverdata) {
slouken@2753
  1688
            SDL_free(display->driverdata);
slouken@2753
  1689
            display->driverdata = NULL;
slouken@2753
  1690
        }
slouken@2753
  1691
    }
slouken@2753
  1692
    if (_this->displays) {
slouken@2753
  1693
        SDL_free(_this->displays);
slouken@2753
  1694
        _this->displays = NULL;
slouken@2753
  1695
    }
slouken@4495
  1696
    if (_this->clipboard_text) {
slouken@4495
  1697
        SDL_free(_this->clipboard_text);
slouken@4495
  1698
        _this->clipboard_text = NULL;
slouken@4495
  1699
    }
slouken@2753
  1700
    _this->free(_this);
slouken@2753
  1701
    _this = NULL;
slouken@0
  1702
}
slouken@0
  1703
slouken@1895
  1704
int
slouken@1895
  1705
SDL_GL_LoadLibrary(const char *path)
slouken@0
  1706
{
slouken@2753
  1707
    int retval;
slouken@0
  1708
slouken@2753
  1709
    if (!_this) {
slouken@2753
  1710
        SDL_UninitializedVideo();
slouken@2753
  1711
        return -1;
slouken@2753
  1712
    }
slouken@3057
  1713
    if (_this->gl_config.driver_loaded) {
slouken@3057
  1714
        if (path && SDL_strcmp(path, _this->gl_config.driver_path) != 0) {
slouken@3057
  1715
            SDL_SetError("OpenGL library already loaded");
slouken@3057
  1716
            return -1;
slouken@3057
  1717
        }
slouken@3057
  1718
        retval = 0;
slouken@3057
  1719
    } else {
slouken@3057
  1720
        if (!_this->GL_LoadLibrary) {
slouken@3057
  1721
            SDL_SetError("No dynamic GL support in video driver");
slouken@3057
  1722
            return -1;
slouken@3057
  1723
        }
slouken@2753
  1724
        retval = _this->GL_LoadLibrary(_this, path);
slouken@3057
  1725
    }
slouken@3057
  1726
    if (retval == 0) {
slouken@3057
  1727
        ++_this->gl_config.driver_loaded;
slouken@2753
  1728
    }
slouken@2753
  1729
    return (retval);
slouken@0
  1730
}
slouken@0
  1731
slouken@2753
  1732
void *
slouken@1895
  1733
SDL_GL_GetProcAddress(const char *proc)
slouken@0
  1734
{
slouken@2753
  1735
    void *func;
slouken@0
  1736
slouken@2753
  1737
    if (!_this) {
slouken@2753
  1738
        SDL_UninitializedVideo();
slouken@2753
  1739
        return NULL;
slouken@2753
  1740
    }
slouken@2753
  1741
    func = NULL;
slouken@2753
  1742
    if (_this->GL_GetProcAddress) {
slouken@2753
  1743
        if (_this->gl_config.driver_loaded) {
slouken@2753
  1744
            func = _this->GL_GetProcAddress(_this, proc);
slouken@2753
  1745
        } else {
slouken@2753
  1746
            SDL_SetError("No GL driver has been loaded");
slouken@2753
  1747
        }
slouken@2753
  1748
    } else {
slouken@2753
  1749
        SDL_SetError("No dynamic GL support in video driver");
slouken@2753
  1750
    }
slouken@2753
  1751
    return func;
slouken@0
  1752
}
slouken@0
  1753
slouken@3057
  1754
void
slouken@3057
  1755
SDL_GL_UnloadLibrary(void)
slouken@3057
  1756
{
slouken@3057
  1757
    if (!_this) {
slouken@3057
  1758
        SDL_UninitializedVideo();
slouken@3057
  1759
        return;
slouken@3057
  1760
    }
slouken@3057
  1761
    if (_this->gl_config.driver_loaded > 0) {
slouken@3057
  1762
        if (--_this->gl_config.driver_loaded > 0) {
slouken@3057
  1763
            return;
slouken@3057
  1764
        }
slouken@3057
  1765
        if (_this->GL_UnloadLibrary) {
slouken@3057
  1766
            _this->GL_UnloadLibrary(_this);
slouken@3057
  1767
        }
slouken@3057
  1768
    }
slouken@3057
  1769
}
slouken@3057
  1770
slouken@1926
  1771
SDL_bool
slouken@1926
  1772
SDL_GL_ExtensionSupported(const char *extension)
slouken@1926
  1773
{
hfutrell@2745
  1774
#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES
slouken@2753
  1775
    const GLubyte *(APIENTRY * glGetStringFunc) (GLenum);
slouken@2753
  1776
    const char *extensions;
slouken@2753
  1777
    const char *start;
slouken@2753
  1778
    const char *where, *terminator;
slouken@1926
  1779
slouken@2753
  1780
    /* Extension names should not have spaces. */
slouken@2753
  1781
    where = SDL_strchr(extension, ' ');
slouken@2753
  1782
    if (where || *extension == '\0') {
slouken@2753
  1783
        return SDL_FALSE;
slouken@2753
  1784
    }
slouken@2753
  1785
    /* See if there's an environment variable override */
slouken@2753
  1786
    start = SDL_getenv(extension);
slouken@2753
  1787
    if (start && *start == '0') {
slouken@2753
  1788
        return SDL_FALSE;
slouken@2753
  1789
    }
slouken@2753
  1790
    /* Lookup the available extensions */
slouken@2753
  1791
    glGetStringFunc = SDL_GL_GetProcAddress("glGetString");
slouken@2753
  1792
    if (glGetStringFunc) {
slouken@2753
  1793
        extensions = (const char *) glGetStringFunc(GL_EXTENSIONS);
slouken@2753
  1794
    } else {
slouken@2753
  1795
        extensions = NULL;
slouken@2753
  1796
    }
slouken@2753
  1797
    if (!extensions) {
slouken@2753
  1798
        return SDL_FALSE;
slouken@2753
  1799
    }
slouken@2753
  1800
    /*
slouken@2753
  1801
     * It takes a bit of care to be fool-proof about parsing the OpenGL
slouken@2753
  1802
     * extensions string. Don't be fooled by sub-strings, etc.
slouken@2753
  1803
     */
slouken@1926
  1804
slouken@2753
  1805
    start = extensions;
slouken@1926
  1806
slouken@2753
  1807
    for (;;) {
slouken@2753
  1808
        where = SDL_strstr(start, extension);
slouken@2753
  1809
        if (!where)
slouken@2753
  1810
            break;
slouken@1926
  1811
slouken@2753
  1812
        terminator = where + SDL_strlen(extension);
slouken@2753
  1813
        if (where == start || *(where - 1) == ' ')
slouken@2753
  1814
            if (*terminator == ' ' || *terminator == '\0')
slouken@2753
  1815
                return SDL_TRUE;
slouken@1926
  1816
slouken@2753
  1817
        start = terminator;
slouken@2753
  1818
    }
slouken@2753
  1819
    return SDL_FALSE;
slouken@1926
  1820
#else
slouken@2753
  1821
    return SDL_FALSE;
slouken@1926
  1822
#endif
slouken@1926
  1823
}
slouken@1926
  1824
slouken@1895
  1825
int
slouken@1895
  1826
SDL_GL_SetAttribute(SDL_GLattr attr, int value)
slouken@0
  1827
{
hfutrell@2745
  1828
#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES
slouken@2753
  1829
    int retval;
slouken@0
  1830
slouken@2753
  1831
    if (!_this) {
slouken@2753
  1832
        SDL_UninitializedVideo();
slouken@2753
  1833
        return -1;
slouken@2753
  1834
    }
slouken@2753
  1835
    retval = 0;
slouken@2753
  1836
    switch (attr) {
slouken@2753
  1837
    case SDL_GL_RED_SIZE:
slouken@2753
  1838
        _this->gl_config.red_size = value;
slouken@2753
  1839
        break;
slouken@2753
  1840
    case SDL_GL_GREEN_SIZE:
slouken@2753
  1841
        _this->gl_config.green_size = value;
slouken@2753
  1842
        break;
slouken@2753
  1843
    case SDL_GL_BLUE_SIZE:
slouken@2753
  1844
        _this->gl_config.blue_size = value;
slouken@2753
  1845
        break;
slouken@2753
  1846
    case SDL_GL_ALPHA_SIZE:
slouken@2753
  1847
        _this->gl_config.alpha_size = value;
slouken@2753
  1848
        break;
slouken@2753
  1849
    case SDL_GL_DOUBLEBUFFER:
slouken@2753
  1850
        _this->gl_config.double_buffer = value;
slouken@2753
  1851
        break;
slouken@2753
  1852
    case SDL_GL_BUFFER_SIZE:
slouken@2753
  1853
        _this->gl_config.buffer_size = value;
slouken@2753
  1854
        break;
slouken@2753
  1855
    case SDL_GL_DEPTH_SIZE:
slouken@2753
  1856
        _this->gl_config.depth_size = value;
slouken@2753
  1857
        break;
slouken@2753
  1858
    case SDL_GL_STENCIL_SIZE:
slouken@2753
  1859
        _this->gl_config.stencil_size = value;
slouken@2753
  1860
        break;
slouken@2753
  1861
    case SDL_GL_ACCUM_RED_SIZE:
slouken@2753
  1862
        _this->gl_config.accum_red_size = value;
slouken@2753
  1863
        break;
slouken@2753
  1864
    case SDL_GL_ACCUM_GREEN_SIZE:
slouken@2753
  1865
        _this->gl_config.accum_green_size = value;
slouken@2753
  1866
        break;
slouken@2753
  1867
    case SDL_GL_ACCUM_BLUE_SIZE:
slouken@2753
  1868
        _this->gl_config.accum_blue_size = value;
slouken@2753
  1869
        break;
slouken@2753
  1870
    case SDL_GL_ACCUM_ALPHA_SIZE:
slouken@2753
  1871
        _this->gl_config.accum_alpha_size = value;
slouken@2753
  1872
        break;
slouken@2753
  1873
    case SDL_GL_STEREO:
slouken@2753
  1874
        _this->gl_config.stereo = value;
slouken@2753
  1875
        break;
slouken@2753
  1876
    case SDL_GL_MULTISAMPLEBUFFERS:
slouken@2753
  1877
        _this->gl_config.multisamplebuffers = value;
slouken@2753
  1878
        break;
slouken@2753
  1879
    case SDL_GL_MULTISAMPLESAMPLES:
slouken@2753
  1880
        _this->gl_config.multisamplesamples = value;
slouken@2753
  1881
        break;
slouken@2753
  1882
    case SDL_GL_ACCELERATED_VISUAL:
slouken@2753
  1883
        _this->gl_config.accelerated = value;
slouken@2753
  1884
        break;
slouken@2753
  1885
    case SDL_GL_RETAINED_BACKING:
slouken@2753
  1886
        _this->gl_config.retained_backing = value;
slouken@2753
  1887
        break;
slouken@3100
  1888
    case SDL_GL_CONTEXT_MAJOR_VERSION:
slouken@3100
  1889
        _this->gl_config.major_version = value;
slouken@3100
  1890
        break;
slouken@3100
  1891
    case SDL_GL_CONTEXT_MINOR_VERSION:
slouken@3100
  1892
        _this->gl_config.minor_version = value;
slouken@3100
  1893
        break;
slouken@2753
  1894
    default:
slouken@2753
  1895
        SDL_SetError("Unknown OpenGL attribute");
slouken@2753
  1896
        retval = -1;
slouken@2753
  1897
        break;
slouken@2753
  1898
    }
slouken@2753
  1899
    return retval;
slouken@1936
  1900
#else
slouken@2753
  1901
    SDL_Unsupported();
slouken@2753
  1902
    return -1;
slouken@2753
  1903
#endif /* SDL_VIDEO_OPENGL */
slouken@0
  1904
}
slouken@0
  1905
slouken@1895
  1906
int
slouken@1936
  1907
SDL_GL_GetAttribute(SDL_GLattr attr, int *value)
slouken@0
  1908
{
hfutrell@2745
  1909
#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES
slouken@2753
  1910
    void (APIENTRY * glGetIntegervFunc) (GLenum pname, GLint * params);
slouken@3139
  1911
    GLenum(APIENTRY * glGetErrorFunc) (void);
slouken@2753
  1912
    GLenum attrib = 0;
slouken@3099
  1913
    GLenum error = 0;
slouken@1912
  1914
slouken@2753
  1915
    glGetIntegervFunc = SDL_GL_GetProcAddress("glGetIntegerv");
slouken@2753
  1916
    if (!glGetIntegervFunc) {
slouken@2753
  1917
        return -1;
slouken@2753
  1918
    }
slouken@3099
  1919
slouken@3099
  1920
    glGetErrorFunc = SDL_GL_GetProcAddress("glGetError");
slouken@3099
  1921
    if (!glGetErrorFunc) {
slouken@3099
  1922
        return -1;
slouken@3099
  1923
    }
slouken@3099
  1924
slouken@3099
  1925
    /* Clear value in any case */
slouken@3139
  1926
    *value = 0;
slouken@3099
  1927
slouken@2753
  1928
    switch (attr) {
slouken@2753
  1929
    case SDL_GL_RETAINED_BACKING:
slouken@2753
  1930
        *value = _this->gl_config.retained_backing;
slouken@2753
  1931
        return 0;
slouken@2753
  1932
    case SDL_GL_RED_SIZE:
slouken@2753
  1933
        attrib = GL_RED_BITS;
slouken@2753
  1934
        break;
slouken@2753
  1935
    case SDL_GL_BLUE_SIZE:
slouken@2753
  1936
        attrib = GL_BLUE_BITS;
slouken@2753
  1937
        break;
slouken@2753
  1938
    case SDL_GL_GREEN_SIZE:
slouken@2753
  1939
        attrib = GL_GREEN_BITS;
slouken@2753
  1940
        break;
slouken@2753
  1941
    case SDL_GL_ALPHA_SIZE:
slouken@2753
  1942
        attrib = GL_ALPHA_BITS;
slouken@2753
  1943
        break;
slouken@2753
  1944
    case SDL_GL_DOUBLEBUFFER:
hfutrell@2745
  1945
#ifndef SDL_VIDEO_OPENGL_ES
slouken@2753
  1946
        attrib = GL_DOUBLEBUFFER;
slouken@2753
  1947
        break;
hfutrell@2745
  1948
#else
slouken@3099
  1949
        /* OpenGL ES 1.0 and above specifications have EGL_SINGLE_BUFFER      */
slouken@3099
  1950
        /* parameter which switches double buffer to single buffer. OpenGL ES */
slouken@3099
  1951
        /* SDL driver must set proper value after initialization              */
slouken@3099
  1952
        *value = _this->gl_config.double_buffer;
slouken@2753
  1953
        return 0;
hfutrell@2745
  1954
#endif
slouken@2753
  1955
    case SDL_GL_DEPTH_SIZE:
slouken@2753
  1956
        attrib = GL_DEPTH_BITS;
slouken@2753
  1957
        break;
slouken@2753
  1958
    case SDL_GL_STENCIL_SIZE:
slouken@2753
  1959
        attrib = GL_STENCIL_BITS;
slouken@2753
  1960
        break;
hfutrell@2745
  1961
#ifndef SDL_VIDEO_OPENGL_ES
slouken@2753
  1962
    case SDL_GL_ACCUM_RED_SIZE:
slouken@2753
  1963
        attrib = GL_ACCUM_RED_BITS;
slouken@2753
  1964
        break;
slouken@2753
  1965
    case SDL_GL_ACCUM_GREEN_SIZE:
slouken@2753
  1966
        attrib = GL_ACCUM_GREEN_BITS;
slouken@2753
  1967
        break;
slouken@2753
  1968
    case SDL_GL_ACCUM_BLUE_SIZE:
slouken@2753
  1969
        attrib = GL_ACCUM_BLUE_BITS;
slouken@2753
  1970
        break;
slouken@2753
  1971
    case SDL_GL_ACCUM_ALPHA_SIZE:
slouken@2753
  1972
        attrib = GL_ACCUM_ALPHA_BITS;
slouken@2753
  1973
        break;
slouken@2753
  1974
    case SDL_GL_STEREO:
slouken@2753
  1975
        attrib = GL_STEREO;
slouken@2753
  1976
        break;
hfutrell@2745
  1977
#else
slouken@2753
  1978
    case SDL_GL_ACCUM_RED_SIZE:
slouken@2753
  1979
    case SDL_GL_ACCUM_GREEN_SIZE:
slouken@2753
  1980
    case SDL_GL_ACCUM_BLUE_SIZE:
slouken@2753
  1981
    case SDL_GL_ACCUM_ALPHA_SIZE:
slouken@2753
  1982
    case SDL_GL_STEREO:
slouken@2753
  1983
        /* none of these are supported in OpenGL ES */
slouken@2753
  1984
        *value = 0;
slouken@2753
  1985
        return 0;
hfutrell@2745
  1986
#endif
slouken@2753
  1987
    case SDL_GL_MULTISAMPLEBUFFERS:
hfutrell@2745
  1988
#ifndef SDL_VIDEO_OPENGL_ES
slouken@2753
  1989
        attrib = GL_SAMPLE_BUFFERS_ARB;
hfutrell@2745
  1990
#else
slouken@2753
  1991
        attrib = GL_SAMPLE_BUFFERS;
hfutrell@2745
  1992
#endif
slouken@2753
  1993
        break;
slouken@2753
  1994
    case SDL_GL_MULTISAMPLESAMPLES:
hfutrell@2745
  1995
#ifndef SDL_VIDEO_OPENGL_ES
slouken@2753
  1996
        attrib = GL_SAMPLES_ARB;
hfutrell@2745
  1997
#else
slouken@2753
  1998
        attrib = GL_SAMPLES;
hfutrell@2745
  1999
#endif
slouken@2753
  2000
        break;
slouken@2753
  2001
    case SDL_GL_BUFFER_SIZE:
slouken@2753
  2002
        {
slouken@2753
  2003
            GLint bits = 0;
slouken@2753
  2004
            GLint component;
slouken@1936
  2005
slouken@2753
  2006
            /*
slouken@2753
  2007
             * there doesn't seem to be a single flag in OpenGL
slouken@2753
  2008
             * for this!
slouken@2753
  2009
             */
slouken@2753
  2010
            glGetIntegervFunc(GL_RED_BITS, &component);
slouken@2753
  2011
            bits += component;
slouken@2753
  2012
            glGetIntegervFunc(GL_GREEN_BITS, &component);
slouken@2753
  2013
            bits += component;
slouken@2753
  2014
            glGetIntegervFunc(GL_BLUE_BITS, &component);
slouken@2753
  2015
            bits += component;
slouken@2753
  2016
            glGetIntegervFunc(GL_ALPHA_BITS, &component);
slouken@2753
  2017
            bits += component;
slouken@1936
  2018
slouken@2753
  2019
            *value = bits;
slouken@2753
  2020
            return 0;
slouken@2753
  2021
        }
slouken@2753
  2022
    case SDL_GL_ACCELERATED_VISUAL:
slouken@2753
  2023
        {
slouken@2753
  2024
            /* FIXME: How do we get this information? */
slouken@3571
  2025
            *value = (_this->gl_config.accelerated != 0);
slouken@2753
  2026
            return 0;
slouken@2753
  2027
        }
slouken@2753
  2028
    default:
slouken@2753
  2029
        SDL_SetError("Unknown OpenGL attribute");
slouken@2753
  2030
        return -1;
slouken@2753
  2031
    }
slouken@0
  2032
slouken@2753
  2033
    glGetIntegervFunc(attrib, (GLint *) value);
slouken@3139
  2034
    error = glGetErrorFunc();
slouken@3139
  2035
    if (error != GL_NO_ERROR) {
slouken@3139
  2036
        switch (error) {
slouken@3139
  2037
        case GL_INVALID_ENUM:
slouken@3139
  2038
            {
slouken@3139
  2039
                SDL_SetError("OpenGL error: GL_INVALID_ENUM");
slouken@3139
  2040
            }
slouken@3139
  2041
            break;
slouken@3139
  2042
        case GL_INVALID_VALUE:
slouken@3139
  2043
            {
slouken@3139
  2044
                SDL_SetError("OpenGL error: GL_INVALID_VALUE");
slouken@3139
  2045
            }
slouken@3139
  2046
            break;
slouken@3139
  2047
        default:
slouken@3139
  2048
            {
slouken@3139
  2049
                SDL_SetError("OpenGL error: %08X", error);
slouken@3139
  2050
            }
slouken@3139
  2051
            break;
slouken@3139
  2052
        }
slouken@3139
  2053
        return -1;
slouken@3099
  2054
    }
slouken@2753
  2055
    return 0;
slouken@1936
  2056
#else
slouken@2753
  2057
    SDL_Unsupported();
slouken@2753
  2058
    return -1;
slouken@2753
  2059
#endif /* SDL_VIDEO_OPENGL */
slouken@0
  2060
}
slouken@0
  2061
slouken@1912
  2062
SDL_GLContext
slouken@3685
  2063
SDL_GL_CreateContext(SDL_Window * window)
slouken@1912
  2064
{
slouken@3695
  2065
    CHECK_WINDOW_MAGIC(window, NULL);
slouken@3695
  2066
slouken@2753
  2067
    if (!(window->flags & SDL_WINDOW_OPENGL)) {
slouken@2753
  2068
        SDL_SetError("The specified window isn't an OpenGL window");
slouken@2753
  2069
        return NULL;
slouken@2753
  2070
    }
slouken@2753
  2071
    return _this->GL_CreateContext(_this, window);
slouken@1912
  2072
}
slouken@1912
  2073
slouken@1912
  2074
int
slouken@3685
  2075
SDL_GL_MakeCurrent(SDL_Window * window, SDL_GLContext context)
slouken@1912
  2076
{
slouken@3695
  2077
    CHECK_WINDOW_MAGIC(window, -1);
slouken@3695
  2078
slouken@3695
  2079
    if (!(window->flags & SDL_WINDOW_OPENGL)) {
slouken@2753
  2080
        SDL_SetError("The specified window isn't an OpenGL window");
slouken@2753
  2081
        return -1;
slouken@2753
  2082
    }
slouken@2753
  2083
    if (!context) {
slouken@2753
  2084
        window = NULL;
slouken@2753
  2085
    }
slouken@2753
  2086
    return _this->GL_MakeCurrent(_this, window, context);
slouken@1912
  2087
}
slouken@1912
  2088
slouken@1912
  2089
int
slouken@1912
  2090
SDL_GL_SetSwapInterval(int interval)
slouken@1912
  2091
{
slouken@2753
  2092
    if (!_this) {
slouken@2753
  2093
        SDL_UninitializedVideo();
slouken@2753
  2094
        return -1;
slouken@2753
  2095
    }
slouken@2753
  2096
    if (_this->GL_SetSwapInterval) {
slouken@2753
  2097
        return _this->GL_SetSwapInterval(_this, interval);
slouken@2753
  2098
    } else {
slouken@2753
  2099
        SDL_SetError("Setting the swap interval is not supported");
slouken@2753
  2100
        return -1;
slouken@2753
  2101
    }
slouken@1912
  2102
}
slouken@1912
  2103
slouken@1912
  2104
int
slouken@1912
  2105
SDL_GL_GetSwapInterval(void)
slouken@1912
  2106
{
slouken@2753
  2107
    if (!_this) {
slouken@2753
  2108
        SDL_UninitializedVideo();
slouken@2753
  2109
        return -1;
slouken@2753
  2110
    }
slouken@2753
  2111
    if (_this->GL_GetSwapInterval) {
slouken@2753
  2112
        return _this->GL_GetSwapInterval(_this);
slouken@2753
  2113
    } else {
slouken@2753
  2114
        SDL_SetError("Getting the swap interval is not supported");
slouken@2753
  2115
        return -1;
slouken@2753
  2116
    }
slouken@1912
  2117
}
slouken@1912
  2118
slouken@1895
  2119
void
slouken@3685
  2120
SDL_GL_SwapWindow(SDL_Window * window)
slouken@0
  2121
{
slouken@3695
  2122
    CHECK_WINDOW_MAGIC(window, );
slouken@3695
  2123
slouken@2753
  2124
    if (!(window->flags & SDL_WINDOW_OPENGL)) {
slouken@2753
  2125
        SDL_SetError("The specified window isn't an OpenGL window");
slouken@2753
  2126
        return;
slouken@2753
  2127
    }
slouken@2753
  2128
    _this->GL_SwapWindow(_this, window);
slouken@1912
  2129
}
slouken@1912
  2130
slouken@1912
  2131
void
slouken@1912
  2132
SDL_GL_DeleteContext(SDL_GLContext context)
slouken@1912
  2133
{
slouken@4526
  2134
    if (!_this || !_this->gl_data || !context) {
slouken@2753
  2135
        return;
slouken@2753
  2136
    }
slouken@2753
  2137
    _this->GL_MakeCurrent(_this, NULL, NULL);
slouken@2753
  2138
    _this->GL_DeleteContext(_this, context);
slouken@0
  2139
}
slouken@0
  2140
slouken@1895
  2141
#if 0                           // FIXME
hfutrell@2744
  2142
/*
hfutrell@2744
  2143
 * Utility function used by SDL_WM_SetIcon(); flags & 1 for color key, flags
hfutrell@2744
  2144
 * & 2 for alpha channel.
hfutrell@2744
  2145
 */
slouken@1895
  2146
static void
slouken@1895
  2147
CreateMaskFromColorKeyOrAlpha(SDL_Surface * icon, Uint8 * mask, int flags)
slouken@0
  2148
{
slouken@2753
  2149
    int x, y;
slouken@2753
  2150
    Uint32 colorkey;
slouken@0
  2151
#define SET_MASKBIT(icon, x, y, mask) \
slouken@0
  2152
	mask[(y*((icon->w+7)/8))+(x/8)] &= ~(0x01<<(7-(x%8)))
slouken@0
  2153
slouken@2753
  2154
    colorkey = icon->format->colorkey;
slouken@2753
  2155
    switch (icon->format->BytesPerPixel) {
slouken@2753
  2156
    case 1:
slouken@2753
  2157
        {
slouken@2753
  2158
            Uint8 *pixels;
slouken@2753
  2159
            for (y = 0; y < icon->h; ++y) {
slouken@2753
  2160
                pixels = (Uint8 *) icon->pixels + y * icon->pitch;
slouken@2753
  2161
                for (x = 0; x < icon->w; ++x) {
slouken@2753
  2162
                    if (*pixels++ == colorkey) {
slouken@2753
  2163
                        SET_MASKBIT(icon, x, y, mask);
slouken@2753
  2164
                    }
slouken@2753
  2165
                }
slouken@2753
  2166
            }
slouken@2753
  2167
        }
slouken@2753
  2168
        break;
slouken@0
  2169
slouken@2753
  2170
    case 2:
slouken@2753
  2171
        {
slouken@2753
  2172
            Uint16 *pixels;
slouken@2753
  2173
            for (y = 0; y < icon->h; ++y) {
slouken@2753
  2174
                pixels = (Uint16 *) icon->pixels + y * icon->pitch / 2;
slouken@2753
  2175
                for (x = 0; x < icon->w; ++x) {
slouken@2753
  2176
                    if ((flags & 1) && *pixels == colorkey) {
slouken@2753
  2177
                        SET_MASKBIT(icon, x, y, mask);
slouken@2753
  2178
                    } else if ((flags & 2)
slouken@2753
  2179
                               && (*pixels & icon->format->Amask) == 0) {
slouken@2753
  2180
                        SET_MASKBIT(icon, x, y, mask);
slouken@2753
  2181
                    }
slouken@2753
  2182
                    pixels++;
slouken@2753
  2183
                }
slouken@2753
  2184
            }
slouken@2753
  2185
        }
slouken@2753
  2186
        break;
slouken@0
  2187
slouken@2753
  2188
    case 4:
slouken@2753
  2189
        {
slouken@2753
  2190
            Uint32 *pixels;
slouken@2753
  2191
            for (y = 0; y < icon->h; ++y) {
slouken@2753
  2192
                pixels = (Uint32 *) icon->pixels + y * icon->pitch / 4;
slouken@2753
  2193
                for (x = 0; x < icon->w; ++x) {
slouken@2753
  2194
                    if ((flags & 1) && *pixels == colorkey) {
slouken@2753
  2195
                        SET_MASKBIT(icon, x, y, mask);
slouken@2753
  2196
                    } else if ((flags & 2)
slouken@2753
  2197
                               && (*pixels & icon->format->Amask) == 0) {
slouken@2753
  2198
                        SET_MASKBIT(icon, x, y, mask);
slouken@2753
  2199
                    }
slouken@2753
  2200
                    pixels++;
slouken@2753
  2201
                }
slouken@2753
  2202
            }
slouken@2753
  2203
        }
slouken@2753
  2204
        break;
slouken@2753
  2205
    }
slouken@0
  2206
}
slouken@0
  2207
slouken@0
  2208
/*
slouken@0
  2209
 * Sets the window manager icon for the display window.
slouken@0
  2210
 */
slouken@1895
  2211
void
slouken@1895
  2212
SDL_WM_SetIcon(SDL_Surface * icon, Uint8 * mask)
slouken@0
  2213
{
slouken@2753
  2214
    if (icon && _this->SetIcon) {
slouken@2753
  2215
        /* Generate a mask if necessary, and create the icon! */
slouken@2753
  2216
        if (mask == NULL) {
slouken@2753
  2217
            int mask_len = icon->h * (icon->w + 7) / 8;
slouken@2753
  2218
            int flags = 0;
slouken@2753
  2219
            mask = (Uint8 *) SDL_malloc(mask_len);
slouken@2753
  2220
            if (mask == NULL) {
slouken@2753
  2221
                return;
slouken@2753
  2222
            }
slouken@2753
  2223
            SDL_memset(mask, ~0, mask_len);
slouken@2753
  2224
            if (icon->flags & SDL_SRCCOLORKEY)
slouken@2753
  2225
                flags |= 1;
slouken@2753
  2226
            if (icon->flags & SDL_SRCALPHA)
slouken@2753
  2227
                flags |= 2;
slouken@2753
  2228
            if (flags) {
slouken@2753
  2229
                CreateMaskFromColorKeyOrAlpha(icon, mask, flags);
slouken@2753
  2230
            }
slouken@2753
  2231
            _this->SetIcon(_this, icon, mask);
slouken@2753
  2232
            SDL_free(mask);
slouken@2753
  2233
        } else {
slouken@2753
  2234
            _this->SetIcon(_this, icon, mask);
slouken@2753
  2235
        }
slouken@2753
  2236
    }
slouken@1895
  2237
}
slouken@1895
  2238
#endif
slouken@0
  2239
slouken@1895
  2240
SDL_bool
slouken@3685
  2241
SDL_GetWindowWMInfo(SDL_Window * window, struct SDL_SysWMinfo *info)
slouken@1895
  2242
{
slouken@3695
  2243
    CHECK_WINDOW_MAGIC(window, SDL_FALSE);
slouken@3695
  2244
slouken@4900
  2245
    if (!info) {
slouken@4900
  2246
        return SDL_FALSE;
slouken@4900
  2247
    }
slouken@4900
  2248
    info->subsystem = SDL_SYSWM_UNKNOWN;
slouken@4900
  2249
slouken@3695
  2250
    if (!_this->GetWindowWMInfo) {
slouken@2753
  2251
        return SDL_FALSE;
slouken@2753
  2252
    }
slouken@2753
  2253
    return (_this->GetWindowWMInfo(_this, window, info));
slouken@0
  2254
}
slouken@0
  2255
slouken@3280
  2256
void
slouken@3280
  2257
SDL_StartTextInput(void)
slouken@3280
  2258
{
slouken@3683
  2259
    if (_this && _this->StartTextInput) {
slouken@3280
  2260
        _this->StartTextInput(_this);
slouken@3280
  2261
    }
slouken@3280
  2262
    SDL_EventState(SDL_TEXTINPUT, SDL_ENABLE);
slouken@3280
  2263
    SDL_EventState(SDL_TEXTEDITING, SDL_ENABLE);
slouken@3280
  2264
}
slouken@3280
  2265
slouken@3280
  2266
void
slouken@3280
  2267
SDL_StopTextInput(void)
slouken@3280
  2268
{
slouken@3683
  2269
    if (_this && _this->StopTextInput) {
slouken@3280
  2270
        _this->StopTextInput(_this);
slouken@3280
  2271
    }
slouken@3280
  2272
    SDL_EventState(SDL_TEXTINPUT, SDL_DISABLE);
slouken@3280
  2273
    SDL_EventState(SDL_TEXTEDITING, SDL_DISABLE);
slouken@3280
  2274
}
slouken@3280
  2275
slouken@3280
  2276
void
slouken@3280
  2277
SDL_SetTextInputRect(SDL_Rect *rect)
slouken@3280
  2278
{
slouken@3683
  2279
    if (_this && _this->SetTextInputRect) {
slouken@3280
  2280
        _this->SetTextInputRect(_this, rect);
slouken@3280
  2281
    }
slouken@3280
  2282
}
slouken@3280
  2283
slouken@1895
  2284
/* vi: set ts=4 sw=4 expandtab: */