src/video/SDL_video.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 22 Jun 2015 23:36:06 -0700
changeset 9776 952ff8a5076f
parent 9745 885b6b5c8426
child 9813 0652406e46c6
permissions -rw-r--r--
Fixed bug 3030 - SDL_RecreateWindow fails to restore title, icon, etc.

Adam M.

It loses the title and icon when window recreation fails. For instance, this may happen when trying to create an OpenGL ES window on a system that doesn't support it. But at that point, the title and icon have already been lost.
slouken@8582
     1
/*
slouken@8582
     2
  Simple DirectMedia Layer
slouken@9619
     3
  Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
slouken@8582
     4
slouken@8582
     5
  This software is provided 'as-is', without any express or implied
slouken@8582
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@8582
     7
  arising from the use of this software.
slouken@8582
     8
slouken@8582
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@8582
    10
  including commercial applications, and to alter it and redistribute it
slouken@8582
    11
  freely, subject to the following restrictions:
slouken@8582
    12
slouken@8582
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@8582
    14
     claim that you wrote the original software. If you use this software
slouken@8582
    15
     in a product, an acknowledgment in the product documentation would be
slouken@8582
    16
     appreciated but is not required.
slouken@8582
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@8582
    18
     misrepresented as being the original software.
slouken@8582
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@8582
    20
*/
icculus@8093
    21
#include "../SDL_internal.h"
slouken@8582
    22
slouken@8582
    23
/* The high-level video driver subsystem */
slouken@8582
    24
slouken@8582
    25
#include "SDL.h"
slouken@8582
    26
#include "SDL_video.h"
slouken@8582
    27
#include "SDL_sysvideo.h"
slouken@8582
    28
#include "SDL_blit.h"
slouken@8582
    29
#include "SDL_pixels_c.h"
slouken@8582
    30
#include "SDL_rect_c.h"
slouken@8582
    31
#include "../events/SDL_events_c.h"
slouken@8582
    32
#include "../timer/SDL_timer_c.h"
slouken@8582
    33
slouken@8616
    34
#include "SDL_syswm.h"
slouken@8616
    35
slouken@8582
    36
#if SDL_VIDEO_OPENGL
slouken@8582
    37
#include "SDL_opengl.h"
slouken@8582
    38
#endif /* SDL_VIDEO_OPENGL */
slouken@8582
    39
slouken@8582
    40
#if SDL_VIDEO_OPENGL_ES
slouken@8582
    41
#include "SDL_opengles.h"
slouken@8582
    42
#endif /* SDL_VIDEO_OPENGL_ES */
slouken@8582
    43
slouken@8582
    44
/* GL and GLES2 headers conflict on Linux 32 bits */
slouken@8582
    45
#if SDL_VIDEO_OPENGL_ES2 && !SDL_VIDEO_OPENGL
slouken@8582
    46
#include "SDL_opengles2.h"
slouken@8582
    47
#endif /* SDL_VIDEO_OPENGL_ES2 && !SDL_VIDEO_OPENGL */
slouken@8582
    48
icculus@9416
    49
#ifndef GL_CONTEXT_RELEASE_BEHAVIOR_KHR
icculus@9416
    50
#define GL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x82FB
icculus@9416
    51
#endif
icculus@9416
    52
slouken@8582
    53
/* On Windows, windows.h defines CreateWindow */
slouken@8582
    54
#ifdef CreateWindow
slouken@8582
    55
#undef CreateWindow
slouken@8582
    56
#endif
slouken@8582
    57
slouken@8582
    58
/* Available video drivers */
slouken@8582
    59
static VideoBootStrap *bootstrap[] = {
slouken@8582
    60
#if SDL_VIDEO_DRIVER_COCOA
slouken@8582
    61
    &COCOA_bootstrap,
slouken@8582
    62
#endif
slouken@8582
    63
#if SDL_VIDEO_DRIVER_X11
slouken@8582
    64
    &X11_bootstrap,
slouken@8582
    65
#endif
icculus@8153
    66
#if SDL_VIDEO_DRIVER_MIR
icculus@8153
    67
    &MIR_bootstrap,
icculus@8153
    68
#endif
slouken@9164
    69
#if SDL_VIDEO_DRIVER_WAYLAND
slouken@9164
    70
    &Wayland_bootstrap,
slouken@9164
    71
#endif
slouken@9164
    72
#if SDL_VIDEO_DRIVER_VIVANTE
slouken@9164
    73
    &VIVANTE_bootstrap,
slouken@9164
    74
#endif
slouken@8582
    75
#if SDL_VIDEO_DRIVER_DIRECTFB
slouken@8582
    76
    &DirectFB_bootstrap,
slouken@8582
    77
#endif
slouken@8582
    78
#if SDL_VIDEO_DRIVER_WINDOWS
slouken@8582
    79
    &WINDOWS_bootstrap,
slouken@8582
    80
#endif
slouken@8582
    81
#if SDL_VIDEO_DRIVER_WINRT
slouken@8582
    82
    &WINRT_bootstrap,
slouken@8582
    83
#endif
slouken@8582
    84
#if SDL_VIDEO_DRIVER_HAIKU
slouken@8582
    85
    &HAIKU_bootstrap,
slouken@8582
    86
#endif
slouken@8582
    87
#if SDL_VIDEO_DRIVER_PANDORA
slouken@8582
    88
    &PND_bootstrap,
slouken@8582
    89
#endif
slouken@8582
    90
#if SDL_VIDEO_DRIVER_UIKIT
slouken@8582
    91
    &UIKIT_bootstrap,
slouken@8582
    92
#endif
slouken@8582
    93
#if SDL_VIDEO_DRIVER_ANDROID
slouken@8582
    94
    &Android_bootstrap,
slouken@8582
    95
#endif
slouken@8582
    96
#if SDL_VIDEO_DRIVER_PSP
slouken@8582
    97
    &PSP_bootstrap,
slouken@8582
    98
#endif
slouken@8582
    99
#if SDL_VIDEO_DRIVER_RPI
slouken@8582
   100
    &RPI_bootstrap,
slouken@8582
   101
#endif 
gabomdq@8833
   102
#if SDL_VIDEO_DRIVER_NACL
gabomdq@8833
   103
    &NACL_bootstrap,
gabomdq@8833
   104
#endif
icculus@9278
   105
#if SDL_VIDEO_DRIVER_EMSCRIPTEN
icculus@9278
   106
    &Emscripten_bootstrap,
icculus@9278
   107
#endif
slouken@8582
   108
#if SDL_VIDEO_DRIVER_DUMMY
slouken@8582
   109
    &DUMMY_bootstrap,
slouken@8582
   110
#endif
slouken@8582
   111
    NULL
slouken@8582
   112
};
slouken@8582
   113
slouken@8582
   114
static SDL_VideoDevice *_this = NULL;
slouken@8582
   115
slouken@8582
   116
#define CHECK_WINDOW_MAGIC(window, retval) \
slouken@8582
   117
    if (!_this) { \
slouken@8582
   118
        SDL_UninitializedVideo(); \
slouken@8582
   119
        return retval; \
slouken@8582
   120
    } \
slouken@8582
   121
    if (!window || window->magic != &_this->window_magic) { \
slouken@8582
   122
        SDL_SetError("Invalid window"); \
slouken@8582
   123
        return retval; \
slouken@8582
   124
    }
slouken@8582
   125
slouken@8582
   126
#define CHECK_DISPLAY_INDEX(displayIndex, retval) \
slouken@8582
   127
    if (!_this) { \
slouken@8582
   128
        SDL_UninitializedVideo(); \
slouken@8582
   129
        return retval; \
slouken@8582
   130
    } \
icculus@8651
   131
    SDL_assert(_this->displays != NULL); \
slouken@8582
   132
    if (displayIndex < 0 || displayIndex >= _this->num_displays) { \
slouken@8582
   133
        SDL_SetError("displayIndex must be in the range 0 - %d", \
slouken@8582
   134
                     _this->num_displays - 1); \
slouken@8582
   135
        return retval; \
slouken@8582
   136
    }
slouken@8582
   137
slouken@8818
   138
#define FULLSCREEN_MASK (SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN)
slouken@8582
   139
slouken@8582
   140
#ifdef __MACOSX__
slouken@8582
   141
/* Support for Mac OS X fullscreen spaces */
slouken@8582
   142
extern SDL_bool Cocoa_IsWindowInFullscreenSpace(SDL_Window * window);
slouken@8582
   143
extern SDL_bool Cocoa_SetWindowFullscreenSpace(SDL_Window * window, SDL_bool state);
slouken@8582
   144
#endif
slouken@8582
   145
slouken@8582
   146
slouken@8582
   147
/* Support for framebuffer emulation using an accelerated renderer */
slouken@8582
   148
slouken@8582
   149
#define SDL_WINDOWTEXTUREDATA   "_SDL_WindowTextureData"
slouken@8582
   150
slouken@8582
   151
typedef struct {
slouken@8582
   152
    SDL_Renderer *renderer;
slouken@8582
   153
    SDL_Texture *texture;
slouken@8582
   154
    void *pixels;
slouken@8582
   155
    int pitch;
slouken@8582
   156
    int bytes_per_pixel;
slouken@8582
   157
} SDL_WindowTextureData;
slouken@8582
   158
slouken@8582
   159
static SDL_bool
slouken@8582
   160
ShouldUseTextureFramebuffer()
slouken@8582
   161
{
slouken@8582
   162
    const char *hint;
slouken@8582
   163
slouken@8582
   164
    /* If there's no native framebuffer support then there's no option */
slouken@8582
   165
    if (!_this->CreateWindowFramebuffer) {
slouken@8582
   166
        return SDL_TRUE;
slouken@8582
   167
    }
slouken@8582
   168
slouken@8582
   169
    /* If the user has specified a software renderer we can't use a
slouken@8582
   170
       texture framebuffer, or renderer creation will go recursive.
slouken@8582
   171
     */
slouken@8582
   172
    hint = SDL_GetHint(SDL_HINT_RENDER_DRIVER);
slouken@8582
   173
    if (hint && SDL_strcasecmp(hint, "software") == 0) {
slouken@8582
   174
        return SDL_FALSE;
slouken@8582
   175
    }
slouken@8582
   176
slouken@8582
   177
    /* See if the user or application wants a specific behavior */
slouken@8582
   178
    hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION);
slouken@8582
   179
    if (hint) {
slouken@8582
   180
        if (*hint == '0') {
slouken@8582
   181
            return SDL_FALSE;
slouken@8582
   182
        } else {
slouken@8582
   183
            return SDL_TRUE;
slouken@8582
   184
        }
slouken@8582
   185
    }
slouken@8582
   186
slouken@8582
   187
    /* Each platform has different performance characteristics */
slouken@8582
   188
#if defined(__WIN32__)
slouken@8582
   189
    /* GDI BitBlt() is way faster than Direct3D dynamic textures right now.
slouken@8582
   190
     */
slouken@8582
   191
    return SDL_FALSE;
slouken@8582
   192
slouken@8582
   193
#elif defined(__MACOSX__)
slouken@8582
   194
    /* Mac OS X uses OpenGL as the native fast path */
slouken@8582
   195
    return SDL_TRUE;
slouken@8582
   196
slouken@8582
   197
#elif defined(__LINUX__)
slouken@8582
   198
    /* Properly configured OpenGL drivers are faster than MIT-SHM */
slouken@8582
   199
#if SDL_VIDEO_OPENGL
slouken@8582
   200
    /* Ugh, find a way to cache this value! */
slouken@8582
   201
    {
slouken@8582
   202
        SDL_Window *window;
slouken@8582
   203
        SDL_GLContext context;
slouken@8582
   204
        SDL_bool hasAcceleratedOpenGL = SDL_FALSE;
slouken@8582
   205
slouken@8582
   206
        window = SDL_CreateWindow("OpenGL test", -32, -32, 32, 32, SDL_WINDOW_OPENGL|SDL_WINDOW_HIDDEN);
slouken@8582
   207
        if (window) {
slouken@8582
   208
            context = SDL_GL_CreateContext(window);
slouken@8582
   209
            if (context) {
slouken@8582
   210
                const GLubyte *(APIENTRY * glGetStringFunc) (GLenum);
slouken@8582
   211
                const char *vendor = NULL;
slouken@8582
   212
slouken@8582
   213
                glGetStringFunc = SDL_GL_GetProcAddress("glGetString");
slouken@8582
   214
                if (glGetStringFunc) {
slouken@8582
   215
                    vendor = (const char *) glGetStringFunc(GL_VENDOR);
slouken@8582
   216
                }
slouken@8582
   217
                /* Add more vendors here at will... */
slouken@8582
   218
                if (vendor &&
slouken@8582
   219
                    (SDL_strstr(vendor, "ATI Technologies") ||
slouken@8582
   220
                     SDL_strstr(vendor, "NVIDIA"))) {
slouken@8582
   221
                    hasAcceleratedOpenGL = SDL_TRUE;
slouken@8582
   222
                }
slouken@8582
   223
                SDL_GL_DeleteContext(context);
slouken@8582
   224
            }
slouken@8582
   225
            SDL_DestroyWindow(window);
slouken@8582
   226
        }
slouken@8582
   227
        return hasAcceleratedOpenGL;
slouken@8582
   228
    }
slouken@8582
   229
#elif SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
slouken@8582
   230
    /* Let's be optimistic about this! */
slouken@8582
   231
    return SDL_TRUE;
slouken@8582
   232
#else
slouken@8582
   233
    return SDL_FALSE;
slouken@8582
   234
#endif
slouken@8582
   235
slouken@8582
   236
#else
slouken@8582
   237
    /* Play it safe, assume that if there is a framebuffer driver that it's
slouken@8582
   238
       optimized for the current platform.
slouken@8582
   239
    */
slouken@8582
   240
    return SDL_FALSE;
slouken@8582
   241
#endif
slouken@8582
   242
}
slouken@8582
   243
slouken@8582
   244
static int
slouken@8922
   245
SDL_CreateWindowTexture(SDL_VideoDevice *unused, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch)
slouken@8582
   246
{
slouken@8582
   247
    SDL_WindowTextureData *data;
slouken@8582
   248
slouken@8582
   249
    data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA);
slouken@8582
   250
    if (!data) {
slouken@8582
   251
        SDL_Renderer *renderer = NULL;
slouken@8582
   252
        int i;
slouken@8582
   253
        const char *hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION);
slouken@8582
   254
slouken@8582
   255
        /* Check to see if there's a specific driver requested */
slouken@8582
   256
        if (hint && *hint != '0' && *hint != '1' &&
slouken@8582
   257
            SDL_strcasecmp(hint, "software") != 0) {
slouken@8582
   258
            for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) {
slouken@8922
   259
                SDL_RendererInfo info;
slouken@8582
   260
                SDL_GetRenderDriverInfo(i, &info);
slouken@8582
   261
                if (SDL_strcasecmp(info.name, hint) == 0) {
slouken@8582
   262
                    renderer = SDL_CreateRenderer(window, i, 0);
slouken@8582
   263
                    break;
slouken@8582
   264
                }
slouken@8582
   265
            }
slouken@8582
   266
        }
gabomdq@8833
   267
        
slouken@8582
   268
        if (!renderer) {
slouken@8582
   269
            for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) {
slouken@8922
   270
                SDL_RendererInfo info;
slouken@8582
   271
                SDL_GetRenderDriverInfo(i, &info);
slouken@8582
   272
                if (SDL_strcmp(info.name, "software") != 0) {
slouken@8582
   273
                    renderer = SDL_CreateRenderer(window, i, 0);
slouken@8582
   274
                    if (renderer) {
slouken@8582
   275
                        break;
slouken@8582
   276
                    }
slouken@8582
   277
                }
slouken@8582
   278
            }
slouken@8582
   279
        }
slouken@8582
   280
        if (!renderer) {
slouken@8582
   281
            return SDL_SetError("No hardware accelerated renderers available");
slouken@8582
   282
        }
slouken@8582
   283
slouken@8582
   284
        /* Create the data after we successfully create the renderer (bug #1116) */
slouken@8582
   285
        data = (SDL_WindowTextureData *)SDL_calloc(1, sizeof(*data));
slouken@8582
   286
        if (!data) {
slouken@8582
   287
            SDL_DestroyRenderer(renderer);
slouken@8582
   288
            return SDL_OutOfMemory();
slouken@8582
   289
        }
slouken@8582
   290
        SDL_SetWindowData(window, SDL_WINDOWTEXTUREDATA, data);
slouken@8582
   291
slouken@8582
   292
        data->renderer = renderer;
slouken@8582
   293
    }
slouken@8582
   294
slouken@8582
   295
    /* Free any old texture and pixel data */
slouken@8582
   296
    if (data->texture) {
slouken@8582
   297
        SDL_DestroyTexture(data->texture);
slouken@8582
   298
        data->texture = NULL;
slouken@8582
   299
    }
slouken@8582
   300
    SDL_free(data->pixels);
slouken@8582
   301
    data->pixels = NULL;
slouken@8582
   302
slouken@8922
   303
    {
slouken@8922
   304
        SDL_RendererInfo info;
slouken@8922
   305
        Uint32 i;
slouken@8922
   306
slouken@8922
   307
        if (SDL_GetRendererInfo(data->renderer, &info) < 0) {
slouken@8922
   308
            return -1;
slouken@8922
   309
        }
slouken@8922
   310
slouken@8922
   311
        /* Find the first format without an alpha channel */
slouken@8922
   312
        *format = info.texture_formats[0];
slouken@8922
   313
slouken@8922
   314
        for (i = 0; i < info.num_texture_formats; ++i) {
slouken@8922
   315
            if (!SDL_ISPIXELFORMAT_FOURCC(info.texture_formats[i]) &&
slouken@8922
   316
                    !SDL_ISPIXELFORMAT_ALPHA(info.texture_formats[i])) {
slouken@8922
   317
                *format = info.texture_formats[i];
slouken@8922
   318
                break;
slouken@8922
   319
            }
slouken@8582
   320
        }
slouken@8582
   321
    }
slouken@8582
   322
slouken@8582
   323
    data->texture = SDL_CreateTexture(data->renderer, *format,
slouken@8582
   324
                                      SDL_TEXTUREACCESS_STREAMING,
slouken@8582
   325
                                      window->w, window->h);
slouken@8582
   326
    if (!data->texture) {
slouken@8582
   327
        return -1;
slouken@8582
   328
    }
slouken@8582
   329
slouken@8582
   330
    /* Create framebuffer data */
slouken@8582
   331
    data->bytes_per_pixel = SDL_BYTESPERPIXEL(*format);
slouken@8582
   332
    data->pitch = (((window->w * data->bytes_per_pixel) + 3) & ~3);
slouken@8582
   333
    data->pixels = SDL_malloc(window->h * data->pitch);
slouken@8582
   334
    if (!data->pixels) {
slouken@8582
   335
        return SDL_OutOfMemory();
slouken@8582
   336
    }
slouken@8582
   337
slouken@8582
   338
    *pixels = data->pixels;
slouken@8582
   339
    *pitch = data->pitch;
slouken@8582
   340
slouken@8582
   341
    /* Make sure we're not double-scaling the viewport */
slouken@8582
   342
    SDL_RenderSetViewport(data->renderer, NULL);
slouken@8582
   343
slouken@8582
   344
    return 0;
slouken@8582
   345
}
slouken@8582
   346
slouken@8582
   347
static int
slouken@8922
   348
SDL_UpdateWindowTexture(SDL_VideoDevice *unused, SDL_Window * window, const SDL_Rect * rects, int numrects)
slouken@8582
   349
{
slouken@8582
   350
    SDL_WindowTextureData *data;
slouken@8582
   351
    SDL_Rect rect;
slouken@8582
   352
    void *src;
slouken@8582
   353
slouken@8582
   354
    data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA);
slouken@8582
   355
    if (!data || !data->texture) {
slouken@8582
   356
        return SDL_SetError("No window texture data");
slouken@8582
   357
    }
slouken@8582
   358
slouken@8582
   359
    /* Update a single rect that contains subrects for best DMA performance */
slouken@8582
   360
    if (SDL_GetSpanEnclosingRect(window->w, window->h, numrects, rects, &rect)) {
slouken@8582
   361
        src = (void *)((Uint8 *)data->pixels +
slouken@8582
   362
                        rect.y * data->pitch +
slouken@8582
   363
                        rect.x * data->bytes_per_pixel);
slouken@8582
   364
        if (SDL_UpdateTexture(data->texture, &rect, src, data->pitch) < 0) {
slouken@8582
   365
            return -1;
slouken@8582
   366
        }
slouken@8582
   367
slouken@8582
   368
        if (SDL_RenderCopy(data->renderer, data->texture, NULL, NULL) < 0) {
slouken@8582
   369
            return -1;
slouken@8582
   370
        }
slouken@8582
   371
slouken@8582
   372
        SDL_RenderPresent(data->renderer);
slouken@8582
   373
    }
slouken@8582
   374
    return 0;
slouken@8582
   375
}
slouken@8582
   376
slouken@8582
   377
static void
slouken@8922
   378
SDL_DestroyWindowTexture(SDL_VideoDevice *unused, SDL_Window * window)
slouken@8582
   379
{
slouken@8582
   380
    SDL_WindowTextureData *data;
slouken@8582
   381
slouken@8582
   382
    data = SDL_SetWindowData(window, SDL_WINDOWTEXTUREDATA, NULL);
slouken@8582
   383
    if (!data) {
slouken@8582
   384
        return;
slouken@8582
   385
    }
slouken@8582
   386
    if (data->texture) {
slouken@8582
   387
        SDL_DestroyTexture(data->texture);
slouken@8582
   388
    }
slouken@8582
   389
    if (data->renderer) {
slouken@8582
   390
        SDL_DestroyRenderer(data->renderer);
slouken@8582
   391
    }
slouken@8582
   392
    SDL_free(data->pixels);
slouken@8582
   393
    SDL_free(data);
slouken@8582
   394
}
slouken@8582
   395
slouken@8582
   396
slouken@8582
   397
static int
slouken@8582
   398
cmpmodes(const void *A, const void *B)
slouken@8582
   399
{
slouken@8582
   400
    const SDL_DisplayMode *a = (const SDL_DisplayMode *) A;
slouken@8582
   401
    const SDL_DisplayMode *b = (const SDL_DisplayMode *) B;
slouken@8582
   402
    if (a == b) {
slouken@8582
   403
        return 0;
slouken@8582
   404
    } else if (a->w != b->w) {
slouken@8582
   405
        return b->w - a->w;
slouken@8582
   406
    } else if (a->h != b->h) {
slouken@8582
   407
        return b->h - a->h;
slouken@8582
   408
    } else if (SDL_BITSPERPIXEL(a->format) != SDL_BITSPERPIXEL(b->format)) {
slouken@8582
   409
        return SDL_BITSPERPIXEL(b->format) - SDL_BITSPERPIXEL(a->format);
slouken@8582
   410
    } else if (SDL_PIXELLAYOUT(a->format) != SDL_PIXELLAYOUT(b->format)) {
slouken@8582
   411
        return SDL_PIXELLAYOUT(b->format) - SDL_PIXELLAYOUT(a->format);
slouken@8582
   412
    } else if (a->refresh_rate != b->refresh_rate) {
slouken@8582
   413
        return b->refresh_rate - a->refresh_rate;
slouken@8582
   414
    }
slouken@8582
   415
    return 0;
slouken@8582
   416
}
slouken@8582
   417
slouken@8582
   418
static int
slouken@8582
   419
SDL_UninitializedVideo()
slouken@8582
   420
{
slouken@8582
   421
    return SDL_SetError("Video subsystem has not been initialized");
slouken@8582
   422
}
slouken@8582
   423
slouken@8582
   424
int
slouken@8582
   425
SDL_GetNumVideoDrivers(void)
slouken@8582
   426
{
slouken@8582
   427
    return SDL_arraysize(bootstrap) - 1;
slouken@8582
   428
}
slouken@8582
   429
slouken@8582
   430
const char *
slouken@8582
   431
SDL_GetVideoDriver(int index)
slouken@8582
   432
{
slouken@8582
   433
    if (index >= 0 && index < SDL_GetNumVideoDrivers()) {
slouken@8582
   434
        return bootstrap[index]->name;
slouken@8582
   435
    }
slouken@8582
   436
    return NULL;
slouken@8582
   437
}
slouken@8582
   438
slouken@8582
   439
/*
slouken@8582
   440
 * Initialize the video and event subsystems -- determine native pixel format
slouken@8582
   441
 */
slouken@8582
   442
int
slouken@8582
   443
SDL_VideoInit(const char *driver_name)
slouken@8582
   444
{
slouken@8582
   445
    SDL_VideoDevice *video;
slouken@8266
   446
    const char *hint;
slouken@8582
   447
    int index;
slouken@8582
   448
    int i;
slouken@8266
   449
    SDL_bool allow_screensaver;
slouken@8582
   450
slouken@8582
   451
    /* Check to make sure we don't overwrite '_this' */
slouken@8582
   452
    if (_this != NULL) {
slouken@8582
   453
        SDL_VideoQuit();
slouken@8582
   454
    }
slouken@8582
   455
slouken@8582
   456
#if !SDL_TIMERS_DISABLED
slouken@8268
   457
    SDL_TicksInit();
slouken@8582
   458
#endif
slouken@8582
   459
slouken@8582
   460
    /* Start the event loop */
slouken@8582
   461
    if (SDL_InitSubSystem(SDL_INIT_EVENTS) < 0 ||
slouken@8582
   462
        SDL_KeyboardInit() < 0 ||
slouken@8582
   463
        SDL_MouseInit() < 0 ||
slouken@8582
   464
        SDL_TouchInit() < 0) {
slouken@8582
   465
        return -1;
slouken@8582
   466
    }
slouken@8582
   467
slouken@8582
   468
    /* Select the proper video driver */
slouken@8582
   469
    index = 0;
slouken@8582
   470
    video = NULL;
slouken@8582
   471
    if (driver_name == NULL) {
slouken@8582
   472
        driver_name = SDL_getenv("SDL_VIDEODRIVER");
slouken@8582
   473
    }
slouken@8582
   474
    if (driver_name != NULL) {
slouken@8582
   475
        for (i = 0; bootstrap[i]; ++i) {
slouken@8582
   476
            if (SDL_strncasecmp(bootstrap[i]->name, driver_name, SDL_strlen(driver_name)) == 0) {
gabomdq@8117
   477
                if (bootstrap[i]->available()) {
gabomdq@8117
   478
                    video = bootstrap[i]->create(index);
gabomdq@8117
   479
                    break;
gabomdq@8117
   480
                }
slouken@8582
   481
            }
slouken@8582
   482
        }
slouken@8582
   483
    } else {
slouken@8582
   484
        for (i = 0; bootstrap[i]; ++i) {
slouken@8582
   485
            if (bootstrap[i]->available()) {
slouken@8582
   486
                video = bootstrap[i]->create(index);
slouken@8582
   487
                if (video != NULL) {
slouken@8582
   488
                    break;
slouken@8582
   489
                }
slouken@8582
   490
            }
slouken@8582
   491
        }
slouken@8582
   492
    }
slouken@8582
   493
    if (video == NULL) {
slouken@8582
   494
        if (driver_name) {
slouken@8582
   495
            return SDL_SetError("%s not available", driver_name);
slouken@8582
   496
        }
slouken@8582
   497
        return SDL_SetError("No available video device");
slouken@8582
   498
    }
slouken@8582
   499
    _this = video;
slouken@8582
   500
    _this->name = bootstrap[i]->name;
slouken@8582
   501
    _this->next_object_id = 1;
slouken@8582
   502
slouken@8582
   503
slouken@8582
   504
    /* Set some very sane GL defaults */
slouken@8582
   505
    _this->gl_config.driver_loaded = 0;
slouken@8582
   506
    _this->gl_config.dll_handle = NULL;
jorgen@8145
   507
    SDL_GL_ResetAttributes();
slouken@8582
   508
slouken@8582
   509
    _this->current_glwin_tls = SDL_TLSCreate();
slouken@8582
   510
    _this->current_glctx_tls = SDL_TLSCreate();
slouken@8582
   511
slouken@8582
   512
    /* Initialize the video subsystem */
slouken@8582
   513
    if (_this->VideoInit(_this) < 0) {
slouken@8582
   514
        SDL_VideoQuit();
slouken@8582
   515
        return -1;
slouken@8582
   516
    }
slouken@8582
   517
slouken@8582
   518
    /* Make sure some displays were added */
slouken@8582
   519
    if (_this->num_displays == 0) {
slouken@8582
   520
        SDL_VideoQuit();
slouken@8582
   521
        return SDL_SetError("The video driver did not add any displays");
slouken@8582
   522
    }
slouken@8582
   523
slouken@8582
   524
    /* Add the renderer framebuffer emulation if desired */
slouken@8582
   525
    if (ShouldUseTextureFramebuffer()) {
slouken@8582
   526
        _this->CreateWindowFramebuffer = SDL_CreateWindowTexture;
slouken@8582
   527
        _this->UpdateWindowFramebuffer = SDL_UpdateWindowTexture;
slouken@8582
   528
        _this->DestroyWindowFramebuffer = SDL_DestroyWindowTexture;
slouken@8582
   529
    }
slouken@8582
   530
icculus@8265
   531
    /* Disable the screen saver by default. This is a change from <= 2.0.1,
icculus@8265
   532
       but most things using SDL are games or media players; you wouldn't
icculus@8265
   533
       want a screensaver to trigger if you're playing exclusively with a
icculus@8265
   534
       joystick, or passively watching a movie. Things that use SDL but
icculus@8265
   535
       function more like a normal desktop app should explicitly reenable the
icculus@8265
   536
       screensaver. */
slouken@8266
   537
    hint = SDL_GetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER);
slouken@8266
   538
    if (hint) {
slouken@8266
   539
        allow_screensaver = SDL_atoi(hint) ? SDL_TRUE : SDL_FALSE;
slouken@8266
   540
    } else {
slouken@8266
   541
        allow_screensaver = SDL_FALSE;
slouken@8266
   542
    }
slouken@8266
   543
    if (!allow_screensaver) {
slouken@8266
   544
        SDL_DisableScreenSaver();
slouken@8266
   545
    }
icculus@8265
   546
slouken@8582
   547
    /* If we don't use a screen keyboard, turn on text input by default,
slouken@8582
   548
       otherwise programs that expect to get text events without enabling
slouken@8582
   549
       UNICODE input won't get any events.
slouken@8582
   550
slouken@8582
   551
       Actually, come to think of it, you needed to call SDL_EnableUNICODE(1)
slouken@8582
   552
       in SDL 1.2 before you got text input events.  Hmm...
slouken@8582
   553
     */
slouken@8582
   554
    if (!SDL_HasScreenKeyboardSupport()) {
slouken@8582
   555
        SDL_StartTextInput();
slouken@8582
   556
    }
slouken@8582
   557
slouken@8582
   558
    /* We're ready to go! */
slouken@8582
   559
    return 0;
slouken@8582
   560
}
slouken@8582
   561
slouken@8582
   562
const char *
slouken@8582
   563
SDL_GetCurrentVideoDriver()
slouken@8582
   564
{
slouken@8582
   565
    if (!_this) {
slouken@8582
   566
        SDL_UninitializedVideo();
slouken@8582
   567
        return NULL;
slouken@8582
   568
    }
slouken@8582
   569
    return _this->name;
slouken@8582
   570
}
slouken@8582
   571
slouken@8582
   572
SDL_VideoDevice *
slouken@8582
   573
SDL_GetVideoDevice(void)
slouken@8582
   574
{
slouken@8582
   575
    return _this;
slouken@8582
   576
}
slouken@8582
   577
slouken@8582
   578
int
slouken@8582
   579
SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode)
slouken@8582
   580
{
slouken@8582
   581
    SDL_VideoDisplay display;
slouken@8582
   582
slouken@8582
   583
    SDL_zero(display);
slouken@8582
   584
    if (desktop_mode) {
slouken@8582
   585
        display.desktop_mode = *desktop_mode;
slouken@8582
   586
    }
slouken@8582
   587
    display.current_mode = display.desktop_mode;
slouken@8582
   588
slouken@8582
   589
    return SDL_AddVideoDisplay(&display);
slouken@8582
   590
}
slouken@8582
   591
slouken@8582
   592
int
slouken@8582
   593
SDL_AddVideoDisplay(const SDL_VideoDisplay * display)
slouken@8582
   594
{
slouken@8582
   595
    SDL_VideoDisplay *displays;
slouken@8582
   596
    int index = -1;
slouken@8582
   597
slouken@8582
   598
    displays =
slouken@8582
   599
        SDL_realloc(_this->displays,
slouken@8582
   600
                    (_this->num_displays + 1) * sizeof(*displays));
slouken@8582
   601
    if (displays) {
slouken@8582
   602
        index = _this->num_displays++;
slouken@8582
   603
        displays[index] = *display;
slouken@8582
   604
        displays[index].device = _this;
slouken@8582
   605
        _this->displays = displays;
slouken@8582
   606
slouken@8582
   607
        if (display->name) {
slouken@8582
   608
            displays[index].name = SDL_strdup(display->name);
slouken@8582
   609
        } else {
slouken@8582
   610
            char name[32];
slouken@8582
   611
slouken@8582
   612
            SDL_itoa(index, name, 10);
slouken@8582
   613
            displays[index].name = SDL_strdup(name);
slouken@8582
   614
        }
slouken@8582
   615
    } else {
slouken@8582
   616
        SDL_OutOfMemory();
slouken@8582
   617
    }
slouken@8582
   618
    return index;
slouken@8582
   619
}
slouken@8582
   620
slouken@8582
   621
int
slouken@8582
   622
SDL_GetNumVideoDisplays(void)
slouken@8582
   623
{
slouken@8582
   624
    if (!_this) {
slouken@8582
   625
        SDL_UninitializedVideo();
slouken@8582
   626
        return 0;
slouken@8582
   627
    }
slouken@8582
   628
    return _this->num_displays;
slouken@8582
   629
}
slouken@8582
   630
slouken@8582
   631
static int
slouken@8582
   632
SDL_GetIndexOfDisplay(SDL_VideoDisplay *display)
slouken@8582
   633
{
slouken@8582
   634
    int displayIndex;
slouken@8582
   635
slouken@8582
   636
    for (displayIndex = 0; displayIndex < _this->num_displays; ++displayIndex) {
slouken@8582
   637
        if (display == &_this->displays[displayIndex]) {
slouken@8582
   638
            return displayIndex;
slouken@8582
   639
        }
slouken@8582
   640
    }
slouken@8582
   641
slouken@8582
   642
    /* Couldn't find the display, just use index 0 */
slouken@8582
   643
    return 0;
slouken@8582
   644
}
slouken@8582
   645
slouken@8582
   646
void *
slouken@8818
   647
SDL_GetDisplayDriverData(int displayIndex)
slouken@8582
   648
{
slouken@8818
   649
    CHECK_DISPLAY_INDEX(displayIndex, NULL);
slouken@8582
   650
slouken@8582
   651
    return _this->displays[displayIndex].driverdata;
slouken@8582
   652
}
slouken@8582
   653
slouken@8582
   654
const char *
slouken@8582
   655
SDL_GetDisplayName(int displayIndex)
slouken@8582
   656
{
slouken@8582
   657
    CHECK_DISPLAY_INDEX(displayIndex, NULL);
slouken@8582
   658
slouken@8582
   659
    return _this->displays[displayIndex].name;
slouken@8582
   660
}
slouken@8582
   661
slouken@8582
   662
int
slouken@8582
   663
SDL_GetDisplayBounds(int displayIndex, SDL_Rect * rect)
slouken@8582
   664
{
slouken@8582
   665
    CHECK_DISPLAY_INDEX(displayIndex, -1);
slouken@8582
   666
slouken@8582
   667
    if (rect) {
slouken@8582
   668
        SDL_VideoDisplay *display = &_this->displays[displayIndex];
slouken@8582
   669
slouken@8582
   670
        if (_this->GetDisplayBounds) {
slouken@8582
   671
            if (_this->GetDisplayBounds(_this, display, rect) == 0) {
slouken@8582
   672
                return 0;
slouken@8582
   673
            }
slouken@8582
   674
        }
slouken@8582
   675
slouken@8582
   676
        /* Assume that the displays are left to right */
slouken@8582
   677
        if (displayIndex == 0) {
slouken@8582
   678
            rect->x = 0;
slouken@8582
   679
            rect->y = 0;
slouken@8582
   680
        } else {
slouken@8582
   681
            SDL_GetDisplayBounds(displayIndex-1, rect);
slouken@8582
   682
            rect->x += rect->w;
slouken@8582
   683
        }
slouken@8582
   684
        rect->w = display->current_mode.w;
slouken@8582
   685
        rect->h = display->current_mode.h;
slouken@8582
   686
    }
slouken@8582
   687
    return 0;
slouken@8582
   688
}
slouken@8582
   689
slouken@8582
   690
SDL_bool
slouken@8582
   691
SDL_AddDisplayMode(SDL_VideoDisplay * display,  const SDL_DisplayMode * mode)
slouken@8582
   692
{
slouken@8582
   693
    SDL_DisplayMode *modes;
slouken@8582
   694
    int i, nmodes;
slouken@8582
   695
slouken@8582
   696
    /* Make sure we don't already have the mode in the list */
slouken@8582
   697
    modes = display->display_modes;
slouken@8582
   698
    nmodes = display->num_display_modes;
slouken@8582
   699
    for (i = 0; i < nmodes; ++i) {
slouken@8582
   700
        if (cmpmodes(mode, &modes[i]) == 0) {
slouken@8582
   701
            return SDL_FALSE;
slouken@8582
   702
        }
slouken@8582
   703
    }
slouken@8582
   704
slouken@8582
   705
    /* Go ahead and add the new mode */
slouken@8582
   706
    if (nmodes == display->max_display_modes) {
slouken@8582
   707
        modes =
slouken@8582
   708
            SDL_realloc(modes,
slouken@8582
   709
                        (display->max_display_modes + 32) * sizeof(*modes));
slouken@8582
   710
        if (!modes) {
slouken@8582
   711
            return SDL_FALSE;
slouken@8582
   712
        }
slouken@8582
   713
        display->display_modes = modes;
slouken@8582
   714
        display->max_display_modes += 32;
slouken@8582
   715
    }
slouken@8582
   716
    modes[nmodes] = *mode;
slouken@8582
   717
    display->num_display_modes++;
slouken@8582
   718
slouken@8582
   719
    /* Re-sort video modes */
slouken@8582
   720
    SDL_qsort(display->display_modes, display->num_display_modes,
slouken@8582
   721
              sizeof(SDL_DisplayMode), cmpmodes);
slouken@8582
   722
slouken@8582
   723
    return SDL_TRUE;
slouken@8582
   724
}
slouken@8582
   725
slouken@8582
   726
static int
slouken@8582
   727
SDL_GetNumDisplayModesForDisplay(SDL_VideoDisplay * display)
slouken@8582
   728
{
slouken@8582
   729
    if (!display->num_display_modes && _this->GetDisplayModes) {
slouken@8582
   730
        _this->GetDisplayModes(_this, display);
slouken@8582
   731
        SDL_qsort(display->display_modes, display->num_display_modes,
slouken@8582
   732
                  sizeof(SDL_DisplayMode), cmpmodes);
slouken@8582
   733
    }
slouken@8582
   734
    return display->num_display_modes;
slouken@8582
   735
}
slouken@8582
   736
slouken@8582
   737
int
slouken@8582
   738
SDL_GetNumDisplayModes(int displayIndex)
slouken@8582
   739
{
slouken@8582
   740
    CHECK_DISPLAY_INDEX(displayIndex, -1);
slouken@8582
   741
slouken@8582
   742
    return SDL_GetNumDisplayModesForDisplay(&_this->displays[displayIndex]);
slouken@8582
   743
}
slouken@8582
   744
slouken@8582
   745
int
slouken@8582
   746
SDL_GetDisplayMode(int displayIndex, int index, SDL_DisplayMode * mode)
slouken@8582
   747
{
slouken@8582
   748
    SDL_VideoDisplay *display;
slouken@8582
   749
slouken@8582
   750
    CHECK_DISPLAY_INDEX(displayIndex, -1);
slouken@8582
   751
slouken@8582
   752
    display = &_this->displays[displayIndex];
slouken@8582
   753
    if (index < 0 || index >= SDL_GetNumDisplayModesForDisplay(display)) {
slouken@8582
   754
        return SDL_SetError("index must be in the range of 0 - %d",
slouken@8582
   755
                            SDL_GetNumDisplayModesForDisplay(display) - 1);
slouken@8582
   756
    }
slouken@8582
   757
    if (mode) {
slouken@8582
   758
        *mode = display->display_modes[index];
slouken@8582
   759
    }
slouken@8582
   760
    return 0;
slouken@8582
   761
}
slouken@8582
   762
slouken@8582
   763
int
slouken@8582
   764
SDL_GetDesktopDisplayMode(int displayIndex, SDL_DisplayMode * mode)
slouken@8582
   765
{
slouken@8582
   766
    SDL_VideoDisplay *display;
slouken@8582
   767
slouken@8582
   768
    CHECK_DISPLAY_INDEX(displayIndex, -1);
slouken@8582
   769
slouken@8582
   770
    display = &_this->displays[displayIndex];
slouken@8582
   771
    if (mode) {
slouken@8582
   772
        *mode = display->desktop_mode;
slouken@8582
   773
    }
slouken@8582
   774
    return 0;
slouken@8582
   775
}
slouken@8582
   776
slouken@8582
   777
int
slouken@8582
   778
SDL_GetCurrentDisplayMode(int displayIndex, SDL_DisplayMode * mode)
slouken@8582
   779
{
slouken@8582
   780
    SDL_VideoDisplay *display;
slouken@8582
   781
slouken@8582
   782
    CHECK_DISPLAY_INDEX(displayIndex, -1);
slouken@8582
   783
slouken@8582
   784
    display = &_this->displays[displayIndex];
slouken@8582
   785
    if (mode) {
slouken@8582
   786
        *mode = display->current_mode;
slouken@8582
   787
    }
slouken@8582
   788
    return 0;
slouken@8582
   789
}
slouken@8582
   790
slouken@8582
   791
static SDL_DisplayMode *
slouken@8582
   792
SDL_GetClosestDisplayModeForDisplay(SDL_VideoDisplay * display,
slouken@8582
   793
                                    const SDL_DisplayMode * mode,
slouken@8582
   794
                                    SDL_DisplayMode * closest)
slouken@8582
   795
{
slouken@8582
   796
    Uint32 target_format;
slouken@8582
   797
    int target_refresh_rate;
slouken@8582
   798
    int i;
slouken@8582
   799
    SDL_DisplayMode *current, *match;
slouken@8582
   800
slouken@8582
   801
    if (!mode || !closest) {
slouken@8582
   802
        SDL_SetError("Missing desired mode or closest mode parameter");
slouken@8582
   803
        return NULL;
slouken@8582
   804
    }
slouken@8582
   805
slouken@8582
   806
    /* Default to the desktop format */
slouken@8582
   807
    if (mode->format) {
slouken@8582
   808
        target_format = mode->format;
slouken@8582
   809
    } else {
slouken@8582
   810
        target_format = display->desktop_mode.format;
slouken@8582
   811
    }
slouken@8582
   812
slouken@8582
   813
    /* Default to the desktop refresh rate */
slouken@8582
   814
    if (mode->refresh_rate) {
slouken@8582
   815
        target_refresh_rate = mode->refresh_rate;
slouken@8582
   816
    } else {
slouken@8582
   817
        target_refresh_rate = display->desktop_mode.refresh_rate;
slouken@8582
   818
    }
slouken@8582
   819
slouken@8582
   820
    match = NULL;
slouken@8582
   821
    for (i = 0; i < SDL_GetNumDisplayModesForDisplay(display); ++i) {
slouken@8582
   822
        current = &display->display_modes[i];
slouken@8582
   823
slouken@8582
   824
        if (current->w && (current->w < mode->w)) {
slouken@8582
   825
            /* Out of sorted modes large enough here */
slouken@8582
   826
            break;
slouken@8582
   827
        }
slouken@8582
   828
        if (current->h && (current->h < mode->h)) {
slouken@8582
   829
            if (current->w && (current->w == mode->w)) {
slouken@8582
   830
                /* Out of sorted modes large enough here */
slouken@8582
   831
                break;
slouken@8582
   832
            }
slouken@8582
   833
            /* Wider, but not tall enough, due to a different
slouken@8582
   834
               aspect ratio. This mode must be skipped, but closer
slouken@8582
   835
               modes may still follow. */
slouken@8582
   836
            continue;
slouken@8582
   837
        }
slouken@8582
   838
        if (!match || current->w < match->w || current->h < match->h) {
slouken@8582
   839
            match = current;
slouken@8582
   840
            continue;
slouken@8582
   841
        }
slouken@8582
   842
        if (current->format != match->format) {
slouken@8582
   843
            /* Sorted highest depth to lowest */
slouken@8582
   844
            if (current->format == target_format ||
slouken@8582
   845
                (SDL_BITSPERPIXEL(current->format) >=
slouken@8582
   846
                 SDL_BITSPERPIXEL(target_format)
slouken@8582
   847
                 && SDL_PIXELTYPE(current->format) ==
slouken@8582
   848
                 SDL_PIXELTYPE(target_format))) {
slouken@8582
   849
                match = current;
slouken@8582
   850
            }
slouken@8582
   851
            continue;
slouken@8582
   852
        }
slouken@8582
   853
        if (current->refresh_rate != match->refresh_rate) {
slouken@8582
   854
            /* Sorted highest refresh to lowest */
slouken@8582
   855
            if (current->refresh_rate >= target_refresh_rate) {
slouken@8582
   856
                match = current;
slouken@8582
   857
            }
slouken@8582
   858
        }
slouken@8582
   859
    }
slouken@8582
   860
    if (match) {
slouken@8582
   861
        if (match->format) {
slouken@8582
   862
            closest->format = match->format;
slouken@8582
   863
        } else {
slouken@8582
   864
            closest->format = mode->format;
slouken@8582
   865
        }
slouken@8582
   866
        if (match->w && match->h) {
slouken@8582
   867
            closest->w = match->w;
slouken@8582
   868
            closest->h = match->h;
slouken@8582
   869
        } else {
slouken@8582
   870
            closest->w = mode->w;
slouken@8582
   871
            closest->h = mode->h;
slouken@8582
   872
        }
slouken@8582
   873
        if (match->refresh_rate) {
slouken@8582
   874
            closest->refresh_rate = match->refresh_rate;
slouken@8582
   875
        } else {
slouken@8582
   876
            closest->refresh_rate = mode->refresh_rate;
slouken@8582
   877
        }
slouken@8582
   878
        closest->driverdata = match->driverdata;
slouken@8582
   879
slouken@8582
   880
        /*
slouken@8582
   881
         * Pick some reasonable defaults if the app and driver don't
slouken@8582
   882
         * care
slouken@8582
   883
         */
slouken@8582
   884
        if (!closest->format) {
slouken@8582
   885
            closest->format = SDL_PIXELFORMAT_RGB888;
slouken@8582
   886
        }
slouken@8582
   887
        if (!closest->w) {
slouken@8582
   888
            closest->w = 640;
slouken@8582
   889
        }
slouken@8582
   890
        if (!closest->h) {
slouken@8582
   891
            closest->h = 480;
slouken@8582
   892
        }
slouken@8582
   893
        return closest;
slouken@8582
   894
    }
slouken@8582
   895
    return NULL;
slouken@8582
   896
}
slouken@8582
   897
slouken@8582
   898
SDL_DisplayMode *
slouken@8582
   899
SDL_GetClosestDisplayMode(int displayIndex,
slouken@8582
   900
                          const SDL_DisplayMode * mode,
slouken@8582
   901
                          SDL_DisplayMode * closest)
slouken@8582
   902
{
slouken@8582
   903
    SDL_VideoDisplay *display;
slouken@8582
   904
slouken@8582
   905
    CHECK_DISPLAY_INDEX(displayIndex, NULL);
slouken@8582
   906
slouken@8582
   907
    display = &_this->displays[displayIndex];
slouken@8582
   908
    return SDL_GetClosestDisplayModeForDisplay(display, mode, closest);
slouken@8582
   909
}
slouken@8582
   910
slouken@8582
   911
static int
slouken@8582
   912
SDL_SetDisplayModeForDisplay(SDL_VideoDisplay * display, const SDL_DisplayMode * mode)
slouken@8582
   913
{
slouken@8582
   914
    SDL_DisplayMode display_mode;
slouken@8582
   915
    SDL_DisplayMode current_mode;
slouken@8582
   916
slouken@8582
   917
    if (mode) {
slouken@8582
   918
        display_mode = *mode;
slouken@8582
   919
slouken@8582
   920
        /* Default to the current mode */
slouken@8582
   921
        if (!display_mode.format) {
slouken@8582
   922
            display_mode.format = display->current_mode.format;
slouken@8582
   923
        }
slouken@8582
   924
        if (!display_mode.w) {
slouken@8582
   925
            display_mode.w = display->current_mode.w;
slouken@8582
   926
        }
slouken@8582
   927
        if (!display_mode.h) {
slouken@8582
   928
            display_mode.h = display->current_mode.h;
slouken@8582
   929
        }
slouken@8582
   930
        if (!display_mode.refresh_rate) {
slouken@8582
   931
            display_mode.refresh_rate = display->current_mode.refresh_rate;
slouken@8582
   932
        }
slouken@8582
   933
slouken@8582
   934
        /* Get a good video mode, the closest one possible */
slouken@8582
   935
        if (!SDL_GetClosestDisplayModeForDisplay(display, &display_mode, &display_mode)) {
slouken@8582
   936
            return SDL_SetError("No video mode large enough for %dx%d",
slouken@8582
   937
                                display_mode.w, display_mode.h);
slouken@8582
   938
        }
slouken@8582
   939
    } else {
slouken@8582
   940
        display_mode = display->desktop_mode;
slouken@8582
   941
    }
slouken@8582
   942
slouken@8582
   943
    /* See if there's anything left to do */
slouken@8582
   944
    current_mode = display->current_mode;
slouken@8582
   945
    if (SDL_memcmp(&display_mode, &current_mode, sizeof(display_mode)) == 0) {
slouken@8582
   946
        return 0;
slouken@8582
   947
    }
slouken@8582
   948
slouken@8582
   949
    /* Actually change the display mode */
slouken@8582
   950
    if (!_this->SetDisplayMode) {
slouken@8582
   951
        return SDL_SetError("Video driver doesn't support changing display mode");
slouken@8582
   952
    }
slouken@8582
   953
    if (_this->SetDisplayMode(_this, display, &display_mode) < 0) {
slouken@8582
   954
        return -1;
slouken@8582
   955
    }
slouken@8582
   956
    display->current_mode = display_mode;
slouken@8582
   957
    return 0;
slouken@8582
   958
}
slouken@8582
   959
slouken@8582
   960
int
slouken@8582
   961
SDL_GetWindowDisplayIndex(SDL_Window * window)
slouken@8582
   962
{
slouken@8582
   963
    int displayIndex;
slouken@8582
   964
    int i, dist;
slouken@8582
   965
    int closest = -1;
slouken@8582
   966
    int closest_dist = 0x7FFFFFFF;
slouken@8582
   967
    SDL_Point center;
slouken@8582
   968
    SDL_Point delta;
slouken@8582
   969
    SDL_Rect rect;
slouken@8582
   970
slouken@8582
   971
    CHECK_WINDOW_MAGIC(window, -1);
slouken@8582
   972
slouken@8582
   973
    if (SDL_WINDOWPOS_ISUNDEFINED(window->x) ||
slouken@8582
   974
        SDL_WINDOWPOS_ISCENTERED(window->x)) {
slouken@8582
   975
        displayIndex = (window->x & 0xFFFF);
slouken@8582
   976
        if (displayIndex >= _this->num_displays) {
slouken@8582
   977
            displayIndex = 0;
slouken@8582
   978
        }
slouken@8582
   979
        return displayIndex;
slouken@8582
   980
    }
slouken@8582
   981
    if (SDL_WINDOWPOS_ISUNDEFINED(window->y) ||
slouken@8582
   982
        SDL_WINDOWPOS_ISCENTERED(window->y)) {
slouken@8582
   983
        displayIndex = (window->y & 0xFFFF);
slouken@8582
   984
        if (displayIndex >= _this->num_displays) {
slouken@8582
   985
            displayIndex = 0;
slouken@8582
   986
        }
slouken@8582
   987
        return displayIndex;
slouken@8582
   988
    }
slouken@8582
   989
slouken@8582
   990
    /* Find the display containing the window */
slouken@8582
   991
    for (i = 0; i < _this->num_displays; ++i) {
slouken@8582
   992
        SDL_VideoDisplay *display = &_this->displays[i];
slouken@8582
   993
slouken@8582
   994
        if (display->fullscreen_window == window) {
slouken@8582
   995
            return i;
slouken@8582
   996
        }
slouken@8582
   997
    }
slouken@8582
   998
    center.x = window->x + window->w / 2;
slouken@8582
   999
    center.y = window->y + window->h / 2;
slouken@8582
  1000
    for (i = 0; i < _this->num_displays; ++i) {
slouken@8582
  1001
        SDL_GetDisplayBounds(i, &rect);
slouken@8582
  1002
        if (SDL_EnclosePoints(&center, 1, &rect, NULL)) {
slouken@8582
  1003
            return i;
slouken@8582
  1004
        }
slouken@8582
  1005
slouken@8582
  1006
        delta.x = center.x - (rect.x + rect.w / 2);
slouken@8582
  1007
        delta.y = center.y - (rect.y + rect.h / 2);
slouken@8582
  1008
        dist = (delta.x*delta.x + delta.y*delta.y);
slouken@8582
  1009
        if (dist < closest_dist) {
slouken@8582
  1010
            closest = i;
slouken@8582
  1011
            closest_dist = dist;
slouken@8582
  1012
        }
slouken@8582
  1013
    }
slouken@8582
  1014
    if (closest < 0) {
slouken@8582
  1015
        SDL_SetError("Couldn't find any displays");
slouken@8582
  1016
    }
slouken@8582
  1017
    return closest;
slouken@8582
  1018
}
slouken@8582
  1019
slouken@8582
  1020
SDL_VideoDisplay *
slouken@8582
  1021
SDL_GetDisplayForWindow(SDL_Window *window)
slouken@8582
  1022
{
slouken@8582
  1023
    int displayIndex = SDL_GetWindowDisplayIndex(window);
slouken@8582
  1024
    if (displayIndex >= 0) {
slouken@8582
  1025
        return &_this->displays[displayIndex];
slouken@8582
  1026
    } else {
slouken@8582
  1027
        return NULL;
slouken@8582
  1028
    }
slouken@8582
  1029
}
slouken@8582
  1030
slouken@8582
  1031
int
slouken@8582
  1032
SDL_SetWindowDisplayMode(SDL_Window * window, const SDL_DisplayMode * mode)
slouken@8582
  1033
{
slouken@8582
  1034
    CHECK_WINDOW_MAGIC(window, -1);
slouken@8582
  1035
slouken@8582
  1036
    if (mode) {
slouken@8582
  1037
        window->fullscreen_mode = *mode;
slouken@8582
  1038
    } else {
slouken@8582
  1039
        SDL_zero(window->fullscreen_mode);
slouken@8582
  1040
    }
slouken@8818
  1041
slouken@8818
  1042
    if (FULLSCREEN_VISIBLE(window) && (window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) {
slouken@8818
  1043
        SDL_DisplayMode fullscreen_mode;
slouken@8818
  1044
        if (SDL_GetWindowDisplayMode(window, &fullscreen_mode) == 0) {
slouken@8818
  1045
            SDL_SetDisplayModeForDisplay(SDL_GetDisplayForWindow(window), &fullscreen_mode);
slouken@8818
  1046
        }
slouken@8818
  1047
    }
slouken@8582
  1048
    return 0;
slouken@8582
  1049
}
slouken@8582
  1050
slouken@8582
  1051
int
slouken@8582
  1052
SDL_GetWindowDisplayMode(SDL_Window * window, SDL_DisplayMode * mode)
slouken@8582
  1053
{
slouken@8582
  1054
    SDL_DisplayMode fullscreen_mode;
slouken@8582
  1055
    SDL_VideoDisplay *display;
slouken@8582
  1056
slouken@8818
  1057
    CHECK_WINDOW_MAGIC(window, -1);
slouken@8818
  1058
slouken@8582
  1059
    if (!mode) {
slouken@8818
  1060
        return SDL_InvalidParamError("mode");
slouken@8582
  1061
    }
slouken@8582
  1062
slouken@8582
  1063
    fullscreen_mode = window->fullscreen_mode;
slouken@8582
  1064
    if (!fullscreen_mode.w) {
slouken@8823
  1065
        fullscreen_mode.w = window->windowed.w;
slouken@8582
  1066
    }
slouken@8582
  1067
    if (!fullscreen_mode.h) {
slouken@8823
  1068
        fullscreen_mode.h = window->windowed.h;
slouken@8582
  1069
    }
slouken@8582
  1070
slouken@8582
  1071
    display = SDL_GetDisplayForWindow(window);
slouken@8582
  1072
slouken@8582
  1073
    /* if in desktop size mode, just return the size of the desktop */
slouken@8818
  1074
    if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) {
slouken@8582
  1075
        fullscreen_mode = display->desktop_mode;
slouken@8818
  1076
    } else if (!SDL_GetClosestDisplayModeForDisplay(SDL_GetDisplayForWindow(window),
slouken@8582
  1077
                                             &fullscreen_mode,
slouken@8582
  1078
                                             &fullscreen_mode)) {
slouken@8582
  1079
        return SDL_SetError("Couldn't find display mode match");
slouken@8582
  1080
    }
slouken@8582
  1081
slouken@8582
  1082
    if (mode) {
slouken@8582
  1083
        *mode = fullscreen_mode;
slouken@8582
  1084
    }
slouken@8582
  1085
    return 0;
slouken@8582
  1086
}
slouken@8582
  1087
slouken@8582
  1088
Uint32
slouken@8582
  1089
SDL_GetWindowPixelFormat(SDL_Window * window)
slouken@8582
  1090
{
slouken@8582
  1091
    SDL_VideoDisplay *display;
slouken@8582
  1092
slouken@8582
  1093
    CHECK_WINDOW_MAGIC(window, SDL_PIXELFORMAT_UNKNOWN);
slouken@8582
  1094
slouken@8582
  1095
    display = SDL_GetDisplayForWindow(window);
slouken@8582
  1096
    return display->current_mode.format;
slouken@8582
  1097
}
slouken@8582
  1098
slouken@8582
  1099
static void
slouken@8582
  1100
SDL_RestoreMousePosition(SDL_Window *window)
slouken@8582
  1101
{
slouken@8582
  1102
    int x, y;
slouken@8582
  1103
slouken@8582
  1104
    if (window == SDL_GetMouseFocus()) {
slouken@8582
  1105
        SDL_GetMouseState(&x, &y);
slouken@8582
  1106
        SDL_WarpMouseInWindow(window, x, y);
slouken@8582
  1107
    }
slouken@8582
  1108
}
slouken@8582
  1109
slime73@9532
  1110
static int
slouken@8582
  1111
SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen)
slouken@8582
  1112
{
slouken@8582
  1113
    SDL_VideoDisplay *display;
slouken@8582
  1114
    SDL_Window *other;
slouken@8582
  1115
slime73@9532
  1116
    CHECK_WINDOW_MAGIC(window,-1);
icculus@8783
  1117
alfred@9037
  1118
    /* if we are in the process of hiding don't go back to fullscreen */
alfred@9037
  1119
    if ( window->is_hiding && fullscreen )
slime73@9532
  1120
        return 0;
alfred@9037
  1121
    
slouken@8582
  1122
#ifdef __MACOSX__
slouken@8582
  1123
    if (Cocoa_SetWindowFullscreenSpace(window, fullscreen)) {
jorgen@8110
  1124
        window->last_fullscreen_flags = window->flags;
slime73@9532
  1125
        return 0;
slouken@8582
  1126
    }
slouken@8582
  1127
#endif
slouken@8582
  1128
slouken@8582
  1129
    display = SDL_GetDisplayForWindow(window);
slouken@8582
  1130
slouken@8582
  1131
    if (fullscreen) {
slouken@8582
  1132
        /* Hide any other fullscreen windows */
slouken@8582
  1133
        if (display->fullscreen_window &&
slouken@8582
  1134
            display->fullscreen_window != window) {
slouken@8582
  1135
            SDL_MinimizeWindow(display->fullscreen_window);
slouken@8582
  1136
        }
slouken@8582
  1137
    }
slouken@8582
  1138
slouken@8582
  1139
    /* See if anything needs to be done now */
slouken@8582
  1140
    if ((display->fullscreen_window == window) == fullscreen) {
jorgen@8110
  1141
        if ((window->last_fullscreen_flags & FULLSCREEN_MASK) == (window->flags & FULLSCREEN_MASK)) {
slime73@9532
  1142
            return 0;
jorgen@8110
  1143
        }
slouken@8582
  1144
    }
slouken@8582
  1145
slouken@8582
  1146
    /* See if there are any fullscreen windows */
slouken@8582
  1147
    for (other = _this->windows; other; other = other->next) {
slouken@8582
  1148
        SDL_bool setDisplayMode = SDL_FALSE;
slouken@8582
  1149
slouken@8582
  1150
        if (other == window) {
slouken@8582
  1151
            setDisplayMode = fullscreen;
slouken@8582
  1152
        } else if (FULLSCREEN_VISIBLE(other) &&
slouken@8582
  1153
                   SDL_GetDisplayForWindow(other) == display) {
slouken@8582
  1154
            setDisplayMode = SDL_TRUE;
slouken@8582
  1155
        }
slouken@8582
  1156
slouken@8582
  1157
        if (setDisplayMode) {
slouken@8582
  1158
            SDL_DisplayMode fullscreen_mode;
slouken@8582
  1159
icculus@8656
  1160
            SDL_zero(fullscreen_mode);
icculus@8656
  1161
slouken@8582
  1162
            if (SDL_GetWindowDisplayMode(other, &fullscreen_mode) == 0) {
slouken@8582
  1163
                SDL_bool resized = SDL_TRUE;
slouken@8582
  1164
slouken@8582
  1165
                if (other->w == fullscreen_mode.w && other->h == fullscreen_mode.h) {
slouken@8582
  1166
                    resized = SDL_FALSE;
slouken@8582
  1167
                }
slouken@8582
  1168
slouken@8582
  1169
                /* only do the mode change if we want exclusive fullscreen */
slouken@8582
  1170
                if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) {
slime73@9532
  1171
                    if (SDL_SetDisplayModeForDisplay(display, &fullscreen_mode) < 0) {
slime73@9532
  1172
                        return -1;
slime73@9532
  1173
                    }
slouken@8582
  1174
                } else {
slime73@9532
  1175
                    if (SDL_SetDisplayModeForDisplay(display, NULL) < 0) {
slime73@9532
  1176
                        return -1;
slime73@9532
  1177
                    }
slouken@8582
  1178
                }
slouken@8582
  1179
slouken@8582
  1180
                if (_this->SetWindowFullscreen) {
slouken@8582
  1181
                    _this->SetWindowFullscreen(_this, other, display, SDL_TRUE);
slouken@8582
  1182
                }
slouken@8582
  1183
                display->fullscreen_window = other;
slouken@8582
  1184
slouken@8582
  1185
                /* Generate a mode change event here */
slouken@8582
  1186
                if (resized) {
slouken@8582
  1187
                    SDL_SendWindowEvent(other, SDL_WINDOWEVENT_RESIZED,
slouken@8582
  1188
                                        fullscreen_mode.w, fullscreen_mode.h);
slouken@8582
  1189
                } else {
slouken@8582
  1190
                    SDL_OnWindowResized(other);
slouken@8582
  1191
                }
slouken@8582
  1192
slouken@8582
  1193
                SDL_RestoreMousePosition(other);
jorgen@8110
  1194
jorgen@8110
  1195
                window->last_fullscreen_flags = window->flags;
slime73@9532
  1196
                return 0;
slouken@8582
  1197
            }
slouken@8582
  1198
        }
slouken@8582
  1199
    }
slouken@8582
  1200
slouken@8582
  1201
    /* Nope, restore the desktop mode */
slouken@8582
  1202
    SDL_SetDisplayModeForDisplay(display, NULL);
slouken@8582
  1203
slouken@8582
  1204
    if (_this->SetWindowFullscreen) {
slouken@8582
  1205
        _this->SetWindowFullscreen(_this, window, display, SDL_FALSE);
slouken@8582
  1206
    }
slouken@8582
  1207
    display->fullscreen_window = NULL;
slouken@8582
  1208
slouken@8582
  1209
    /* Generate a mode change event here */
slouken@8582
  1210
    SDL_OnWindowResized(window);
slouken@8582
  1211
slouken@8582
  1212
    /* Restore the cursor position */
slouken@8582
  1213
    SDL_RestoreMousePosition(window);
jorgen@8110
  1214
jorgen@8110
  1215
    window->last_fullscreen_flags = window->flags;
slime73@9532
  1216
    return 0;
slouken@8582
  1217
}
slouken@8582
  1218
slouken@8582
  1219
#define CREATE_FLAGS \
slouken@8582
  1220
    (SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI)
slouken@8582
  1221
slouken@8582
  1222
static void
slouken@8582
  1223
SDL_FinishWindowCreation(SDL_Window *window, Uint32 flags)
slouken@8582
  1224
{
slouken@8582
  1225
    window->windowed.x = window->x;
slouken@8582
  1226
    window->windowed.y = window->y;
slouken@8582
  1227
    window->windowed.w = window->w;
slouken@8582
  1228
    window->windowed.h = window->h;
slouken@8582
  1229
slouken@8582
  1230
    if (flags & SDL_WINDOW_MAXIMIZED) {
slouken@8582
  1231
        SDL_MaximizeWindow(window);
slouken@8582
  1232
    }
slouken@8582
  1233
    if (flags & SDL_WINDOW_MINIMIZED) {
slouken@8582
  1234
        SDL_MinimizeWindow(window);
slouken@8582
  1235
    }
slouken@8582
  1236
    if (flags & SDL_WINDOW_FULLSCREEN) {
slouken@8582
  1237
        SDL_SetWindowFullscreen(window, flags);
slouken@8582
  1238
    }
slouken@8582
  1239
    if (flags & SDL_WINDOW_INPUT_GRABBED) {
slouken@8582
  1240
        SDL_SetWindowGrab(window, SDL_TRUE);
slouken@8582
  1241
    }
slouken@8582
  1242
    if (!(flags & SDL_WINDOW_HIDDEN)) {
slouken@8582
  1243
        SDL_ShowWindow(window);
slouken@8582
  1244
    }
slouken@8582
  1245
}
slouken@8582
  1246
slouken@8582
  1247
SDL_Window *
slouken@8582
  1248
SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
slouken@8582
  1249
{
slouken@8582
  1250
    SDL_Window *window;
slouken@8582
  1251
    const char *hint;
slouken@8582
  1252
slouken@8582
  1253
    if (!_this) {
slouken@8582
  1254
        /* Initialize the video system if needed */
slouken@8582
  1255
        if (SDL_VideoInit(NULL) < 0) {
slouken@8582
  1256
            return NULL;
slouken@8582
  1257
        }
slouken@8582
  1258
    }
slouken@8582
  1259
slouken@8582
  1260
    /* Some platforms can't create zero-sized windows */
slouken@8582
  1261
    if (w < 1) {
slouken@8582
  1262
        w = 1;
slouken@8582
  1263
    }
slouken@8582
  1264
    if (h < 1) {
slouken@8582
  1265
        h = 1;
slouken@8582
  1266
    }
slouken@8582
  1267
icculus@9461
  1268
    /* Some platforms blow up if the windows are too large. Raise it later? */
icculus@9461
  1269
    if ((w > 16384) || (h > 16384)) {
icculus@9461
  1270
        SDL_SetError("Window is too large.");
icculus@9461
  1271
        return NULL;
icculus@9461
  1272
    }
icculus@9461
  1273
slouken@8582
  1274
    /* Some platforms have OpenGL enabled by default */
gabomdq@8833
  1275
#if (SDL_VIDEO_OPENGL && __MACOSX__) || __IPHONEOS__ || __ANDROID__ || __NACL__
slouken@8582
  1276
    flags |= SDL_WINDOW_OPENGL;
slouken@8582
  1277
#endif
slouken@8582
  1278
    if (flags & SDL_WINDOW_OPENGL) {
slouken@8582
  1279
        if (!_this->GL_CreateContext) {
slouken@8582
  1280
            SDL_SetError("No OpenGL support in video driver");
slouken@8582
  1281
            return NULL;
slouken@8582
  1282
        }
slouken@8582
  1283
        if (SDL_GL_LoadLibrary(NULL) < 0) {
slouken@8582
  1284
            return NULL;
slouken@8582
  1285
        }
slouken@8582
  1286
    }
slouken@8582
  1287
slouken@8582
  1288
    /* Unless the user has specified the high-DPI disabling hint, respect the
slouken@8582
  1289
     * SDL_WINDOW_ALLOW_HIGHDPI flag.
slouken@8582
  1290
     */
slouken@8582
  1291
    if (flags & SDL_WINDOW_ALLOW_HIGHDPI) {
slouken@8582
  1292
        hint = SDL_GetHint(SDL_HINT_VIDEO_HIGHDPI_DISABLED);
slouken@8582
  1293
        if (hint && SDL_atoi(hint) > 0) {
slouken@8582
  1294
            flags &= ~SDL_WINDOW_ALLOW_HIGHDPI;
slouken@8582
  1295
        }
slouken@8582
  1296
    }
slouken@8582
  1297
slouken@8582
  1298
    window = (SDL_Window *)SDL_calloc(1, sizeof(*window));
slouken@8582
  1299
    if (!window) {
slouken@8582
  1300
        SDL_OutOfMemory();
slouken@8582
  1301
        return NULL;
slouken@8582
  1302
    }
slouken@8582
  1303
    window->magic = &_this->window_magic;
slouken@8582
  1304
    window->id = _this->next_object_id++;
slouken@8582
  1305
    window->x = x;
slouken@8582
  1306
    window->y = y;
slouken@8582
  1307
    window->w = w;
slouken@8582
  1308
    window->h = h;
slouken@8582
  1309
    if (SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISUNDEFINED(y) ||
slouken@8582
  1310
        SDL_WINDOWPOS_ISCENTERED(x) || SDL_WINDOWPOS_ISCENTERED(y)) {
slouken@8582
  1311
        SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
slouken@8582
  1312
        int displayIndex;
slouken@8582
  1313
        SDL_Rect bounds;
slouken@8582
  1314
slouken@8582
  1315
        displayIndex = SDL_GetIndexOfDisplay(display);
slouken@8582
  1316
        SDL_GetDisplayBounds(displayIndex, &bounds);
slouken@8582
  1317
        if (SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISCENTERED(x)) {
slouken@8582
  1318
            window->x = bounds.x + (bounds.w - w) / 2;
slouken@8582
  1319
        }
slouken@8582
  1320
        if (SDL_WINDOWPOS_ISUNDEFINED(y) || SDL_WINDOWPOS_ISCENTERED(y)) {
slouken@8582
  1321
            window->y = bounds.y + (bounds.h - h) / 2;
slouken@8582
  1322
        }
slouken@8582
  1323
    }
slouken@8582
  1324
    window->flags = ((flags & CREATE_FLAGS) | SDL_WINDOW_HIDDEN);
jorgen@8110
  1325
    window->last_fullscreen_flags = window->flags;
slouken@8582
  1326
    window->brightness = 1.0f;
slouken@8582
  1327
    window->next = _this->windows;
jorgen@8112
  1328
    window->is_destroying = SDL_FALSE;
slouken@8582
  1329
slouken@8582
  1330
    if (_this->windows) {
slouken@8582
  1331
        _this->windows->prev = window;
slouken@8582
  1332
    }
slouken@8582
  1333
    _this->windows = window;
slouken@8582
  1334
slouken@8582
  1335
    if (_this->CreateWindow && _this->CreateWindow(_this, window) < 0) {
slouken@8582
  1336
        SDL_DestroyWindow(window);
slouken@8582
  1337
        return NULL;
slouken@8582
  1338
    }
slouken@8582
  1339
slouken@8582
  1340
    if (title) {
slouken@8582
  1341
        SDL_SetWindowTitle(window, title);
slouken@8582
  1342
    }
slouken@8582
  1343
    SDL_FinishWindowCreation(window, flags);
slouken@8582
  1344
slouken@8582
  1345
    /* If the window was created fullscreen, make sure the mode code matches */
slouken@8582
  1346
    SDL_UpdateFullscreenMode(window, FULLSCREEN_VISIBLE(window));
slouken@8582
  1347
slouken@8582
  1348
    return window;
slouken@8582
  1349
}
slouken@8582
  1350
slouken@8582
  1351
SDL_Window *
slouken@8582
  1352
SDL_CreateWindowFrom(const void *data)
slouken@8582
  1353
{
slouken@8582
  1354
    SDL_Window *window;
slouken@8582
  1355
slouken@8582
  1356
    if (!_this) {
slouken@8582
  1357
        SDL_UninitializedVideo();
slouken@8582
  1358
        return NULL;
slouken@8582
  1359
    }
slouken@9163
  1360
    if (!_this->CreateWindowFrom) {
slouken@9163
  1361
        SDL_Unsupported();
slouken@9163
  1362
        return NULL;
slouken@9163
  1363
    }
slouken@8582
  1364
    window = (SDL_Window *)SDL_calloc(1, sizeof(*window));
slouken@8582
  1365
    if (!window) {
slouken@8582
  1366
        SDL_OutOfMemory();
slouken@8582
  1367
        return NULL;
slouken@8582
  1368
    }
slouken@8582
  1369
    window->magic = &_this->window_magic;
slouken@8582
  1370
    window->id = _this->next_object_id++;
slouken@8582
  1371
    window->flags = SDL_WINDOW_FOREIGN;
jorgen@8110
  1372
    window->last_fullscreen_flags = window->flags;
jorgen@8112
  1373
    window->is_destroying = SDL_FALSE;
slouken@8582
  1374
    window->brightness = 1.0f;
slouken@8582
  1375
    window->next = _this->windows;
slouken@8582
  1376
    if (_this->windows) {
slouken@8582
  1377
        _this->windows->prev = window;
slouken@8582
  1378
    }
slouken@8582
  1379
    _this->windows = window;
slouken@8582
  1380
slouken@9163
  1381
    if (_this->CreateWindowFrom(_this, window, data) < 0) {
slouken@8582
  1382
        SDL_DestroyWindow(window);
slouken@8582
  1383
        return NULL;
slouken@8582
  1384
    }
slouken@8582
  1385
    return window;
slouken@8582
  1386
}
slouken@8582
  1387
slouken@8582
  1388
int
slouken@8582
  1389
SDL_RecreateWindow(SDL_Window * window, Uint32 flags)
slouken@8582
  1390
{
slouken@8906
  1391
    SDL_bool loaded_opengl = SDL_FALSE;
slouken@8582
  1392
slouken@8582
  1393
    if ((flags & SDL_WINDOW_OPENGL) && !_this->GL_CreateContext) {
slouken@8582
  1394
        return SDL_SetError("No OpenGL support in video driver");
slouken@8582
  1395
    }
slouken@8582
  1396
slouken@8582
  1397
    if (window->flags & SDL_WINDOW_FOREIGN) {
slouken@8582
  1398
        /* Can't destroy and re-create foreign windows, hrm */
slouken@8582
  1399
        flags |= SDL_WINDOW_FOREIGN;
slouken@8582
  1400
    } else {
slouken@8582
  1401
        flags &= ~SDL_WINDOW_FOREIGN;
slouken@8582
  1402
    }
slouken@8582
  1403
slouken@8582
  1404
    /* Restore video mode, etc. */
slouken@8582
  1405
    SDL_HideWindow(window);
slouken@8582
  1406
slouken@8582
  1407
    /* Tear down the old native window */
slouken@8582
  1408
    if (window->surface) {
slouken@8582
  1409
        window->surface->flags &= ~SDL_DONTFREE;
slouken@8582
  1410
        SDL_FreeSurface(window->surface);
slouken@8582
  1411
    }
slouken@8582
  1412
    if (_this->DestroyWindowFramebuffer) {
slouken@8582
  1413
        _this->DestroyWindowFramebuffer(_this, window);
slouken@8582
  1414
    }
slouken@8582
  1415
    if (_this->DestroyWindow && !(flags & SDL_WINDOW_FOREIGN)) {
slouken@8582
  1416
        _this->DestroyWindow(_this, window);
slouken@8582
  1417
    }
slouken@8582
  1418
slouken@8582
  1419
    if ((window->flags & SDL_WINDOW_OPENGL) != (flags & SDL_WINDOW_OPENGL)) {
slouken@8582
  1420
        if (flags & SDL_WINDOW_OPENGL) {
slouken@8582
  1421
            if (SDL_GL_LoadLibrary(NULL) < 0) {
slouken@8582
  1422
                return -1;
slouken@8582
  1423
            }
slouken@8906
  1424
            loaded_opengl = SDL_TRUE;
slouken@8582
  1425
        } else {
slouken@8582
  1426
            SDL_GL_UnloadLibrary();
slouken@8582
  1427
        }
slouken@8582
  1428
    }
slouken@8582
  1429
slouken@8582
  1430
    window->flags = ((flags & CREATE_FLAGS) | SDL_WINDOW_HIDDEN);
jorgen@8110
  1431
    window->last_fullscreen_flags = window->flags;
jorgen@8112
  1432
    window->is_destroying = SDL_FALSE;
slouken@8582
  1433
slouken@8582
  1434
    if (_this->CreateWindow && !(flags & SDL_WINDOW_FOREIGN)) {
slouken@8582
  1435
        if (_this->CreateWindow(_this, window) < 0) {
slouken@8906
  1436
            if (loaded_opengl) {
slouken@8582
  1437
                SDL_GL_UnloadLibrary();
slouken@8906
  1438
                window->flags &= ~SDL_WINDOW_OPENGL;
slouken@8582
  1439
            }
slouken@8582
  1440
            return -1;
slouken@8582
  1441
        }
slouken@8582
  1442
    }
slouken@9776
  1443
slouken@8708
  1444
    if (flags & SDL_WINDOW_FOREIGN) {
slouken@8708
  1445
        window->flags |= SDL_WINDOW_FOREIGN;
slouken@8708
  1446
    }
slouken@8582
  1447
slouken@9776
  1448
    if (_this->SetWindowTitle && window->title) {
slouken@9776
  1449
        _this->SetWindowTitle(_this, window);
slouken@8582
  1450
    }
slouken@9776
  1451
slouken@9776
  1452
    if (_this->SetWindowIcon && window->icon) {
slouken@9776
  1453
        _this->SetWindowIcon(_this, window, window->icon);
slouken@8582
  1454
    }
icculus@8931
  1455
icculus@8953
  1456
    if (window->hit_test) {
icculus@8935
  1457
        _this->SetWindowHitTest(window, SDL_TRUE);
icculus@8931
  1458
    }
icculus@8931
  1459
slouken@8582
  1460
    SDL_FinishWindowCreation(window, flags);
slouken@8582
  1461
slouken@8582
  1462
    return 0;
slouken@8582
  1463
}
slouken@8582
  1464
slouken@8582
  1465
Uint32
slouken@8582
  1466
SDL_GetWindowID(SDL_Window * window)
slouken@8582
  1467
{
slouken@8582
  1468
    CHECK_WINDOW_MAGIC(window, 0);
slouken@8582
  1469
slouken@8582
  1470
    return window->id;
slouken@8582
  1471
}
slouken@8582
  1472
slouken@8582
  1473
SDL_Window *
slouken@8582
  1474
SDL_GetWindowFromID(Uint32 id)
slouken@8582
  1475
{
slouken@8582
  1476
    SDL_Window *window;
slouken@8582
  1477
slouken@8582
  1478
    if (!_this) {
slouken@8582
  1479
        return NULL;
slouken@8582
  1480
    }
slouken@8582
  1481
    for (window = _this->windows; window; window = window->next) {
slouken@8582
  1482
        if (window->id == id) {
slouken@8582
  1483
            return window;
slouken@8582
  1484
        }
slouken@8582
  1485
    }
slouken@8582
  1486
    return NULL;
slouken@8582
  1487
}
slouken@8582
  1488
slouken@8582
  1489
Uint32
slouken@8582
  1490
SDL_GetWindowFlags(SDL_Window * window)
slouken@8582
  1491
{
slouken@8582
  1492
    CHECK_WINDOW_MAGIC(window, 0);
slouken@8582
  1493
slouken@8582
  1494
    return window->flags;
slouken@8582
  1495
}
slouken@8582
  1496
slouken@8582
  1497
void
slouken@8582
  1498
SDL_SetWindowTitle(SDL_Window * window, const char *title)
slouken@8582
  1499
{
slouken@8818
  1500
    CHECK_WINDOW_MAGIC(window,);
slouken@8582
  1501
slouken@8582
  1502
    if (title == window->title) {
slouken@8582
  1503
        return;
slouken@8582
  1504
    }
slouken@8582
  1505
    SDL_free(window->title);
icculus@9474
  1506
icculus@9474
  1507
    window->title = SDL_strdup(title ? title : "");
slouken@8582
  1508
slouken@8582
  1509
    if (_this->SetWindowTitle) {
slouken@8582
  1510
        _this->SetWindowTitle(_this, window);
slouken@8582
  1511
    }
slouken@8582
  1512
}
slouken@8582
  1513
slouken@8582
  1514
const char *
slouken@8582
  1515
SDL_GetWindowTitle(SDL_Window * window)
slouken@8582
  1516
{
slouken@8582
  1517
    CHECK_WINDOW_MAGIC(window, "");
slouken@8582
  1518
slouken@8582
  1519
    return window->title ? window->title : "";
slouken@8582
  1520
}
slouken@8582
  1521
slouken@8582
  1522
void
slouken@8582
  1523
SDL_SetWindowIcon(SDL_Window * window, SDL_Surface * icon)
slouken@8582
  1524
{
slouken@8818
  1525
    CHECK_WINDOW_MAGIC(window,);
slouken@8582
  1526
slouken@8582
  1527
    if (!icon) {
slouken@8582
  1528
        return;
slouken@8582
  1529
    }
slouken@8582
  1530
slouken@8582
  1531
    SDL_FreeSurface(window->icon);
slouken@8582
  1532
slouken@8582
  1533
    /* Convert the icon into ARGB8888 */
slouken@8582
  1534
    window->icon = SDL_ConvertSurfaceFormat(icon, SDL_PIXELFORMAT_ARGB8888, 0);
slouken@8582
  1535
    if (!window->icon) {
slouken@8582
  1536
        return;
slouken@8582
  1537
    }
slouken@8582
  1538
slouken@8582
  1539
    if (_this->SetWindowIcon) {
slouken@8582
  1540
        _this->SetWindowIcon(_this, window, window->icon);
slouken@8582
  1541
    }
slouken@8582
  1542
}
slouken@8582
  1543
slouken@8582
  1544
void*
slouken@8582
  1545
SDL_SetWindowData(SDL_Window * window, const char *name, void *userdata)
slouken@8582
  1546
{
slouken@8582
  1547
    SDL_WindowUserData *prev, *data;
slouken@8582
  1548
slouken@8582
  1549
    CHECK_WINDOW_MAGIC(window, NULL);
slouken@8582
  1550
slouken@8582
  1551
    /* Input validation */
slouken@8582
  1552
    if (name == NULL || name[0] == '\0') {
slouken@8582
  1553
      SDL_InvalidParamError("name");
slouken@8582
  1554
      return NULL;
slouken@8582
  1555
    }
slouken@8582
  1556
slouken@8582
  1557
    /* See if the named data already exists */
slouken@8582
  1558
    prev = NULL;
slouken@8582
  1559
    for (data = window->data; data; prev = data, data = data->next) {
slouken@8582
  1560
        if (data->name && SDL_strcmp(data->name, name) == 0) {
slouken@8582
  1561
            void *last_value = data->data;
slouken@8582
  1562
slouken@8582
  1563
            if (userdata) {
slouken@8582
  1564
                /* Set the new value */
slouken@8582
  1565
                data->data = userdata;
slouken@8582
  1566
            } else {
slouken@8582
  1567
                /* Delete this value */
slouken@8582
  1568
                if (prev) {
slouken@8582
  1569
                    prev->next = data->next;
slouken@8582
  1570
                } else {
slouken@8582
  1571
                    window->data = data->next;
slouken@8582
  1572
                }
slouken@8582
  1573
                SDL_free(data->name);
slouken@8582
  1574
                SDL_free(data);
slouken@8582
  1575
            }
slouken@8582
  1576
            return last_value;
slouken@8582
  1577
        }
slouken@8582
  1578
    }
slouken@8582
  1579
slouken@8582
  1580
    /* Add new data to the window */
slouken@8582
  1581
    if (userdata) {
slouken@8582
  1582
        data = (SDL_WindowUserData *)SDL_malloc(sizeof(*data));
slouken@8582
  1583
        data->name = SDL_strdup(name);
slouken@8582
  1584
        data->data = userdata;
slouken@8582
  1585
        data->next = window->data;
slouken@8582
  1586
        window->data = data;
slouken@8582
  1587
    }
slouken@8582
  1588
    return NULL;
slouken@8582
  1589
}
slouken@8582
  1590
slouken@8582
  1591
void *
slouken@8582
  1592
SDL_GetWindowData(SDL_Window * window, const char *name)
slouken@8582
  1593
{
slouken@8582
  1594
    SDL_WindowUserData *data;
slouken@8582
  1595
slouken@8582
  1596
    CHECK_WINDOW_MAGIC(window, NULL);
slouken@8582
  1597
slouken@8582
  1598
    /* Input validation */
slouken@8582
  1599
    if (name == NULL || name[0] == '\0') {
slouken@8582
  1600
      SDL_InvalidParamError("name");
slouken@8582
  1601
      return NULL;
slouken@8582
  1602
    }
slouken@8582
  1603
slouken@8582
  1604
    for (data = window->data; data; data = data->next) {
slouken@8582
  1605
        if (data->name && SDL_strcmp(data->name, name) == 0) {
slouken@8582
  1606
            return data->data;
slouken@8582
  1607
        }
slouken@8582
  1608
    }
slouken@8582
  1609
    return NULL;
slouken@8582
  1610
}
slouken@8582
  1611
slouken@8582
  1612
void
slouken@8582
  1613
SDL_SetWindowPosition(SDL_Window * window, int x, int y)
slouken@8582
  1614
{
slouken@8818
  1615
    CHECK_WINDOW_MAGIC(window,);
slouken@8582
  1616
slouken@8582
  1617
    if (SDL_WINDOWPOS_ISCENTERED(x) || SDL_WINDOWPOS_ISCENTERED(y)) {
urkle@9363
  1618
        int displayIndex = (x & 0xFFFF);
slouken@8582
  1619
        SDL_Rect bounds;
urkle@9363
  1620
        if (displayIndex > _this->num_displays) {
urkle@9363
  1621
            displayIndex = 0;
urkle@9363
  1622
        }
slouken@8582
  1623
icculus@8655
  1624
        SDL_zero(bounds);
icculus@8655
  1625
slouken@8582
  1626
        SDL_GetDisplayBounds(displayIndex, &bounds);
slouken@8582
  1627
        if (SDL_WINDOWPOS_ISCENTERED(x)) {
slouken@8582
  1628
            x = bounds.x + (bounds.w - window->w) / 2;
slouken@8582
  1629
        }
slouken@8582
  1630
        if (SDL_WINDOWPOS_ISCENTERED(y)) {
slouken@8582
  1631
            y = bounds.y + (bounds.h - window->h) / 2;
slouken@8582
  1632
        }
slouken@8582
  1633
    }
slouken@8582
  1634
slouken@8582
  1635
    if ((window->flags & SDL_WINDOW_FULLSCREEN)) {
slouken@8582
  1636
        if (!SDL_WINDOWPOS_ISUNDEFINED(x)) {
slouken@8582
  1637
            window->windowed.x = x;
slouken@8582
  1638
        }
slouken@8582
  1639
        if (!SDL_WINDOWPOS_ISUNDEFINED(y)) {
slouken@8582
  1640
            window->windowed.y = y;
slouken@8582
  1641
        }
slouken@8582
  1642
    } else {
slouken@8582
  1643
        if (!SDL_WINDOWPOS_ISUNDEFINED(x)) {
slouken@8582
  1644
            window->x = x;
slouken@8582
  1645
        }
slouken@8582
  1646
        if (!SDL_WINDOWPOS_ISUNDEFINED(y)) {
slouken@8582
  1647
            window->y = y;
slouken@8582
  1648
        }
slouken@8582
  1649
slouken@8582
  1650
        if (_this->SetWindowPosition) {
slouken@8582
  1651
            _this->SetWindowPosition(_this, window);
slouken@8582
  1652
        }
slouken@8582
  1653
        SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, x, y);
slouken@8582
  1654
    }
slouken@8582
  1655
}
slouken@8582
  1656
slouken@8582
  1657
void
slouken@8582
  1658
SDL_GetWindowPosition(SDL_Window * window, int *x, int *y)
slouken@8582
  1659
{
slouken@8818
  1660
    CHECK_WINDOW_MAGIC(window,);
slouken@8582
  1661
slouken@8582
  1662
    /* Fullscreen windows are always at their display's origin */
slouken@8582
  1663
    if (window->flags & SDL_WINDOW_FULLSCREEN) {
slouken@8582
  1664
        if (x) {
slouken@8582
  1665
            *x = 0;
slouken@8582
  1666
        }
slouken@8582
  1667
        if (y) {
slouken@8582
  1668
            *y = 0;
slouken@8582
  1669
        }
slouken@8582
  1670
    } else {
slouken@8582
  1671
        if (x) {
slouken@8582
  1672
            *x = window->x;
slouken@8582
  1673
        }
slouken@8582
  1674
        if (y) {
slouken@8582
  1675
            *y = window->y;
slouken@8582
  1676
        }
slouken@8582
  1677
    }
slouken@8582
  1678
}
slouken@8582
  1679
slouken@8582
  1680
void
slouken@8582
  1681
SDL_SetWindowBordered(SDL_Window * window, SDL_bool bordered)
slouken@8582
  1682
{
slouken@8818
  1683
    CHECK_WINDOW_MAGIC(window,);
slouken@8582
  1684
    if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
slouken@8582
  1685
        const int want = (bordered != SDL_FALSE);  /* normalize the flag. */
slouken@8582
  1686
        const int have = ((window->flags & SDL_WINDOW_BORDERLESS) == 0);
slouken@8582
  1687
        if ((want != have) && (_this->SetWindowBordered)) {
slouken@8582
  1688
            if (want) {
slouken@8582
  1689
                window->flags &= ~SDL_WINDOW_BORDERLESS;
slouken@8582
  1690
            } else {
slouken@8582
  1691
                window->flags |= SDL_WINDOW_BORDERLESS;
slouken@8582
  1692
            }
slouken@8582
  1693
            _this->SetWindowBordered(_this, window, (SDL_bool) want);
slouken@8582
  1694
        }
slouken@8582
  1695
    }
slouken@8582
  1696
}
slouken@8582
  1697
slouken@8582
  1698
void
slouken@8582
  1699
SDL_SetWindowSize(SDL_Window * window, int w, int h)
slouken@8582
  1700
{
slouken@8818
  1701
    CHECK_WINDOW_MAGIC(window,);
slouken@8582
  1702
    if (w <= 0) {
slouken@8582
  1703
        SDL_InvalidParamError("w");
slouken@8582
  1704
        return;
slouken@8582
  1705
    }
slouken@8582
  1706
    if (h <= 0) {
slouken@8582
  1707
        SDL_InvalidParamError("h");
slouken@8582
  1708
        return;
slouken@8582
  1709
    }
slouken@8582
  1710
slouken@8582
  1711
    /* Make sure we don't exceed any window size limits */
slouken@8582
  1712
    if (window->min_w && w < window->min_w)
slouken@8582
  1713
    {
slouken@8582
  1714
        w = window->min_w;
slouken@8582
  1715
    }
slouken@8582
  1716
    if (window->max_w && w > window->max_w)
slouken@8582
  1717
    {
slouken@8582
  1718
        w = window->max_w;
slouken@8582
  1719
    }
slouken@8582
  1720
    if (window->min_h && h < window->min_h)
slouken@8582
  1721
    {
slouken@8582
  1722
        h = window->min_h;
slouken@8582
  1723
    }
slouken@8582
  1724
    if (window->max_h && h > window->max_h)
slouken@8582
  1725
    {
slouken@8582
  1726
        h = window->max_h;
slouken@8582
  1727
    }
slouken@8582
  1728
slouken@8823
  1729
    window->windowed.w = w;
slouken@8823
  1730
    window->windowed.h = h;
slouken@8823
  1731
slouken@8582
  1732
    if (window->flags & SDL_WINDOW_FULLSCREEN) {
slouken@8818
  1733
        if (FULLSCREEN_VISIBLE(window) && (window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) {
slouken@8823
  1734
            window->last_fullscreen_flags = 0;
slouken@8823
  1735
            SDL_UpdateFullscreenMode(window, SDL_TRUE);
slouken@8818
  1736
        }
slouken@8582
  1737
    } else {
slouken@8582
  1738
        window->w = w;
slouken@8582
  1739
        window->h = h;
slouken@8582
  1740
        if (_this->SetWindowSize) {
slouken@8582
  1741
            _this->SetWindowSize(_this, window);
slouken@8582
  1742
        }
slouken@8582
  1743
        if (window->w == w && window->h == h) {
slouken@8582
  1744
            /* We didn't get a SDL_WINDOWEVENT_RESIZED event (by design) */
slouken@8582
  1745
            SDL_OnWindowResized(window);
slouken@8582
  1746
        }
slouken@8582
  1747
    }
slouken@8582
  1748
}
slouken@8582
  1749
slouken@8582
  1750
void
slouken@8582
  1751
SDL_GetWindowSize(SDL_Window * window, int *w, int *h)
slouken@8582
  1752
{
slouken@8818
  1753
    CHECK_WINDOW_MAGIC(window,);
slouken@8582
  1754
    if (w) {
slouken@8582
  1755
        *w = window->w;
slouken@8582
  1756
    }
slouken@8582
  1757
    if (h) {
slouken@8582
  1758
        *h = window->h;
slouken@8582
  1759
    }
slouken@8582
  1760
}
slouken@8582
  1761
slouken@8582
  1762
void
slouken@8582
  1763
SDL_SetWindowMinimumSize(SDL_Window * window, int min_w, int min_h)
slouken@8582
  1764
{
slouken@8818
  1765
    CHECK_WINDOW_MAGIC(window,);
slouken@8582
  1766
    if (min_w <= 0) {
slouken@8582
  1767
        SDL_InvalidParamError("min_w");
slouken@8582
  1768
        return;
slouken@8582
  1769
    }
slouken@8582
  1770
    if (min_h <= 0) {
slouken@8582
  1771
        SDL_InvalidParamError("min_h");
slouken@8582
  1772
        return;
slouken@8582
  1773
    }
slouken@8582
  1774
slouken@8582
  1775
    if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
slouken@8582
  1776
        window->min_w = min_w;
slouken@8582
  1777
        window->min_h = min_h;
slouken@8582
  1778
        if (_this->SetWindowMinimumSize) {
slouken@8582
  1779
            _this->SetWindowMinimumSize(_this, window);
slouken@8582
  1780
        }
slouken@8582
  1781
        /* Ensure that window is not smaller than minimal size */
slouken@8582
  1782
        SDL_SetWindowSize(window, SDL_max(window->w, window->min_w), SDL_max(window->h, window->min_h));
slouken@8582
  1783
    }
slouken@8582
  1784
}
slouken@8582
  1785
slouken@8582
  1786
void
slouken@8582
  1787
SDL_GetWindowMinimumSize(SDL_Window * window, int *min_w, int *min_h)
slouken@8582
  1788
{
slouken@8818
  1789
    CHECK_WINDOW_MAGIC(window,);
slouken@8582
  1790
    if (min_w) {
slouken@8582
  1791
        *min_w = window->min_w;
slouken@8582
  1792
    }
slouken@8582
  1793
    if (min_h) {
slouken@8582
  1794
        *min_h = window->min_h;
slouken@8582
  1795
    }
slouken@8582
  1796
}
slouken@8582
  1797
slouken@8582
  1798
void
slouken@8582
  1799
SDL_SetWindowMaximumSize(SDL_Window * window, int max_w, int max_h)
slouken@8582
  1800
{
slouken@8818
  1801
    CHECK_WINDOW_MAGIC(window,);
slouken@8582
  1802
    if (max_w <= 0) {
slouken@8582
  1803
        SDL_InvalidParamError("max_w");
slouken@8582
  1804
        return;
slouken@8582
  1805
    }
slouken@8582
  1806
    if (max_h <= 0) {
slouken@8582
  1807
        SDL_InvalidParamError("max_h");
slouken@8582
  1808
        return;
slouken@8582
  1809
    }
slouken@8582
  1810
slouken@8582
  1811
    if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
slouken@8582
  1812
        window->max_w = max_w;
slouken@8582
  1813
        window->max_h = max_h;
slouken@8582
  1814
        if (_this->SetWindowMaximumSize) {
slouken@8582
  1815
            _this->SetWindowMaximumSize(_this, window);
slouken@8582
  1816
        }
slouken@8582
  1817
        /* Ensure that window is not larger than maximal size */
slouken@8582
  1818
        SDL_SetWindowSize(window, SDL_min(window->w, window->max_w), SDL_min(window->h, window->max_h));
slouken@8582
  1819
    }
slouken@8582
  1820
}
slouken@8582
  1821
slouken@8582
  1822
void
slouken@8582
  1823
SDL_GetWindowMaximumSize(SDL_Window * window, int *max_w, int *max_h)
slouken@8582
  1824
{
slouken@8818
  1825
    CHECK_WINDOW_MAGIC(window,);
slouken@8582
  1826
    if (max_w) {
slouken@8582
  1827
        *max_w = window->max_w;
slouken@8582
  1828
    }
slouken@8582
  1829
    if (max_h) {
slouken@8582
  1830
        *max_h = window->max_h;
slouken@8582
  1831
    }
slouken@8582
  1832
}
slouken@8582
  1833
slouken@8582
  1834
void
slouken@8582
  1835
SDL_ShowWindow(SDL_Window * window)
slouken@8582
  1836
{
slouken@8818
  1837
    CHECK_WINDOW_MAGIC(window,);
slouken@8582
  1838
slouken@8582
  1839
    if (window->flags & SDL_WINDOW_SHOWN) {
slouken@8582
  1840
        return;
slouken@8582
  1841
    }
slouken@8582
  1842
slouken@8582
  1843
    if (_this->ShowWindow) {
slouken@8582
  1844
        _this->ShowWindow(_this, window);
slouken@8582
  1845
    }
slouken@8582
  1846
    SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0);
slouken@8582
  1847
}
slouken@8582
  1848
slouken@8582
  1849
void
slouken@8582
  1850
SDL_HideWindow(SDL_Window * window)
slouken@8582
  1851
{
slouken@8818
  1852
    CHECK_WINDOW_MAGIC(window,);
slouken@8582
  1853
slouken@8582
  1854
    if (!(window->flags & SDL_WINDOW_SHOWN)) {
slouken@8582
  1855
        return;
slouken@8582
  1856
    }
slouken@8582
  1857
alfred@9037
  1858
	window->is_hiding = SDL_TRUE;
slouken@8582
  1859
    SDL_UpdateFullscreenMode(window, SDL_FALSE);
slouken@8582
  1860
slouken@8582
  1861
    if (_this->HideWindow) {
slouken@8582
  1862
        _this->HideWindow(_this, window);
slouken@8582
  1863
    }
alfred@9037
  1864
	window->is_hiding = SDL_FALSE;
slouken@8582
  1865
    SDL_SendWindowEvent(window, SDL_WINDOWEVENT_HIDDEN, 0, 0);
slouken@8582
  1866
}
slouken@8582
  1867
slouken@8582
  1868
void
slouken@8582
  1869
SDL_RaiseWindow(SDL_Window * window)
slouken@8582
  1870
{
slouken@8818
  1871
    CHECK_WINDOW_MAGIC(window,);
slouken@8582
  1872
slouken@8582
  1873
    if (!(window->flags & SDL_WINDOW_SHOWN)) {
slouken@8582
  1874
        return;
slouken@8582
  1875
    }
slouken@8582
  1876
    if (_this->RaiseWindow) {
slouken@8582
  1877
        _this->RaiseWindow(_this, window);
slouken@8582
  1878
    }
slouken@8582
  1879
}
slouken@8582
  1880
slouken@8582
  1881
void
slouken@8582
  1882
SDL_MaximizeWindow(SDL_Window * window)
slouken@8582
  1883
{
slouken@8818
  1884
    CHECK_WINDOW_MAGIC(window,);
slouken@8582
  1885
slouken@8582
  1886
    if (window->flags & SDL_WINDOW_MAXIMIZED) {
slouken@8582
  1887
        return;
slouken@8582
  1888
    }
slouken@8582
  1889
slouken@8582
  1890
    /* !!! FIXME: should this check if the window is resizable? */
slouken@8582
  1891
slouken@8582
  1892
    if (_this->MaximizeWindow) {
slouken@8582
  1893
        _this->MaximizeWindow(_this, window);
slouken@8582
  1894
    }
slouken@8582
  1895
}
slouken@8582
  1896
slouken@8582
  1897
void
slouken@8582
  1898
SDL_MinimizeWindow(SDL_Window * window)
slouken@8582
  1899
{
slouken@8818
  1900
    CHECK_WINDOW_MAGIC(window,);
slouken@8582
  1901
slouken@8582
  1902
    if (window->flags & SDL_WINDOW_MINIMIZED) {
slouken@8582
  1903
        return;
slouken@8582
  1904
    }
slouken@8582
  1905
slouken@8582
  1906
    SDL_UpdateFullscreenMode(window, SDL_FALSE);
slouken@8582
  1907
slouken@8582
  1908
    if (_this->MinimizeWindow) {
slouken@8582
  1909
        _this->MinimizeWindow(_this, window);
slouken@8582
  1910
    }
slouken@8582
  1911
}
slouken@8582
  1912
slouken@8582
  1913
void
slouken@8582
  1914
SDL_RestoreWindow(SDL_Window * window)
slouken@8582
  1915
{
slouken@8818
  1916
    CHECK_WINDOW_MAGIC(window,);
slouken@8582
  1917
slouken@8582
  1918
    if (!(window->flags & (SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED))) {
slouken@8582
  1919
        return;
slouken@8582
  1920
    }
slouken@8582
  1921
slouken@8582
  1922
    if (_this->RestoreWindow) {
slouken@8582
  1923
        _this->RestoreWindow(_this, window);
slouken@8582
  1924
    }
slouken@8582
  1925
}
slouken@8582
  1926
slouken@8582
  1927
int
slouken@8582
  1928
SDL_SetWindowFullscreen(SDL_Window * window, Uint32 flags)
slouken@8582
  1929
{
slouken@8582
  1930
    CHECK_WINDOW_MAGIC(window, -1);
slouken@8582
  1931
slouken@8582
  1932
    flags &= FULLSCREEN_MASK;
slouken@8582
  1933
slouken@8818
  1934
    if (flags == (window->flags & FULLSCREEN_MASK)) {
slouken@8582
  1935
        return 0;
slouken@8582
  1936
    }
slouken@8582
  1937
slouken@8582
  1938
    /* clear the previous flags and OR in the new ones */
slouken@8582
  1939
    window->flags &= ~FULLSCREEN_MASK;
slouken@8582
  1940
    window->flags |= flags;
slouken@8582
  1941
slime73@9532
  1942
    return SDL_UpdateFullscreenMode(window, FULLSCREEN_VISIBLE(window));
slouken@8582
  1943
}
slouken@8582
  1944
slouken@8582
  1945
static SDL_Surface *
slouken@8582
  1946
SDL_CreateWindowFramebuffer(SDL_Window * window)
slouken@8582
  1947
{
slouken@8582
  1948
    Uint32 format;
slouken@8582
  1949
    void *pixels;
slouken@8582
  1950
    int pitch;
slouken@8582
  1951
    int bpp;
slouken@8582
  1952
    Uint32 Rmask, Gmask, Bmask, Amask;
slouken@8582
  1953
slouken@8582
  1954
    if (!_this->CreateWindowFramebuffer || !_this->UpdateWindowFramebuffer) {
slouken@8582
  1955
        return NULL;
slouken@8582
  1956
    }
slouken@8582
  1957
slouken@8582
  1958
    if (_this->CreateWindowFramebuffer(_this, window, &format, &pixels, &pitch) < 0) {
slouken@8582
  1959
        return NULL;
slouken@8582
  1960
    }
slouken@8582
  1961
slouken@8582
  1962
    if (!SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
slouken@8582
  1963
        return NULL;
slouken@8582
  1964
    }
slouken@8582
  1965
slouken@8582
  1966
    return SDL_CreateRGBSurfaceFrom(pixels, window->w, window->h, bpp, pitch, Rmask, Gmask, Bmask, Amask);
slouken@8582
  1967
}
slouken@8582
  1968
slouken@8582
  1969
SDL_Surface *
slouken@8582
  1970
SDL_GetWindowSurface(SDL_Window * window)
slouken@8582
  1971
{
slouken@8582
  1972
    CHECK_WINDOW_MAGIC(window, NULL);
slouken@8582
  1973
slouken@8582
  1974
    if (!window->surface_valid) {
slouken@8582
  1975
        if (window->surface) {
slouken@8582
  1976
            window->surface->flags &= ~SDL_DONTFREE;
slouken@8582
  1977
            SDL_FreeSurface(window->surface);
slouken@8582
  1978
        }
slouken@8582
  1979
        window->surface = SDL_CreateWindowFramebuffer(window);
slouken@8582
  1980
        if (window->surface) {
slouken@8582
  1981
            window->surface_valid = SDL_TRUE;
slouken@8582
  1982
            window->surface->flags |= SDL_DONTFREE;
slouken@8582
  1983
        }
slouken@8582
  1984
    }
slouken@8582
  1985
    return window->surface;
slouken@8582
  1986
}
slouken@8582
  1987
slouken@8582
  1988
int
slouken@8582
  1989
SDL_UpdateWindowSurface(SDL_Window * window)
slouken@8582
  1990
{
slouken@8582
  1991
    SDL_Rect full_rect;
slouken@8582
  1992
slouken@8582
  1993
    CHECK_WINDOW_MAGIC(window, -1);
slouken@8582
  1994
slouken@8582
  1995
    full_rect.x = 0;
slouken@8582
  1996
    full_rect.y = 0;
slouken@8582
  1997
    full_rect.w = window->w;
slouken@8582
  1998
    full_rect.h = window->h;
slouken@8582
  1999
    return SDL_UpdateWindowSurfaceRects(window, &full_rect, 1);
slouken@8582
  2000
}
slouken@8582
  2001
slouken@8582
  2002
int
slouken@8582
  2003
SDL_UpdateWindowSurfaceRects(SDL_Window * window, const SDL_Rect * rects,
slouken@8582
  2004
                             int numrects)
slouken@8582
  2005
{
slouken@8582
  2006
    CHECK_WINDOW_MAGIC(window, -1);
slouken@8582
  2007
slouken@8582
  2008
    if (!window->surface_valid) {
slouken@8582
  2009
        return SDL_SetError("Window surface is invalid, please call SDL_GetWindowSurface() to get a new surface");
slouken@8582
  2010
    }
slouken@8582
  2011
slouken@8582
  2012
    return _this->UpdateWindowFramebuffer(_this, window, rects, numrects);
slouken@8582
  2013
}
slouken@8582
  2014
slouken@8582
  2015
int
slouken@8582
  2016
SDL_SetWindowBrightness(SDL_Window * window, float brightness)
slouken@8582
  2017
{
slouken@8582
  2018
    Uint16 ramp[256];
slouken@8582
  2019
    int status;
slouken@8582
  2020
slouken@8582
  2021
    CHECK_WINDOW_MAGIC(window, -1);
slouken@8582
  2022
slouken@8582
  2023
    SDL_CalculateGammaRamp(brightness, ramp);
slouken@8582
  2024
    status = SDL_SetWindowGammaRamp(window, ramp, ramp, ramp);
slouken@8582
  2025
    if (status == 0) {
slouken@8582
  2026
        window->brightness = brightness;
slouken@8582
  2027
    }
slouken@8582
  2028
    return status;
slouken@8582
  2029
}
slouken@8582
  2030
slouken@8582
  2031
float
slouken@8582
  2032
SDL_GetWindowBrightness(SDL_Window * window)
slouken@8582
  2033
{
slouken@8582
  2034
    CHECK_WINDOW_MAGIC(window, 1.0f);
slouken@8582
  2035
slouken@8582
  2036
    return window->brightness;
slouken@8582
  2037
}
slouken@8582
  2038
slouken@8582
  2039
int
slouken@8582
  2040
SDL_SetWindowGammaRamp(SDL_Window * window, const Uint16 * red,
slouken@8582
  2041
                                            const Uint16 * green,
slouken@8582
  2042
                                            const Uint16 * blue)
slouken@8582
  2043
{
slouken@8582
  2044
    CHECK_WINDOW_MAGIC(window, -1);
slouken@8582
  2045
slouken@8582
  2046
    if (!_this->SetWindowGammaRamp) {
slouken@8582
  2047
        return SDL_Unsupported();
slouken@8582
  2048
    }
slouken@8582
  2049
slouken@8582
  2050
    if (!window->gamma) {
slouken@8582
  2051
        if (SDL_GetWindowGammaRamp(window, NULL, NULL, NULL) < 0) {
slouken@8582
  2052
            return -1;
slouken@8582
  2053
        }
icculus@9546
  2054
        SDL_assert(window->gamma != NULL);
slouken@8582
  2055
    }
slouken@8582
  2056
slouken@8582
  2057
    if (red) {
slouken@8582
  2058
        SDL_memcpy(&window->gamma[0*256], red, 256*sizeof(Uint16));
slouken@8582
  2059
    }
slouken@8582
  2060
    if (green) {
slouken@8582
  2061
        SDL_memcpy(&window->gamma[1*256], green, 256*sizeof(Uint16));
slouken@8582
  2062
    }
slouken@8582
  2063
    if (blue) {
slouken@8582
  2064
        SDL_memcpy(&window->gamma[2*256], blue, 256*sizeof(Uint16));
slouken@8582
  2065
    }
slouken@8582
  2066
    if (window->flags & SDL_WINDOW_INPUT_FOCUS) {
slouken@8582
  2067
        return _this->SetWindowGammaRamp(_this, window, window->gamma);
slouken@8582
  2068
    } else {
slouken@8582
  2069
        return 0;
slouken@8582
  2070
    }
slouken@8582
  2071
}
slouken@8582
  2072
slouken@8582
  2073
int
slouken@8582
  2074
SDL_GetWindowGammaRamp(SDL_Window * window, Uint16 * red,
slouken@8582
  2075
                                            Uint16 * green,
slouken@8582
  2076
                                            Uint16 * blue)
slouken@8582
  2077
{
slouken@8582
  2078
    CHECK_WINDOW_MAGIC(window, -1);
slouken@8582
  2079
slouken@8582
  2080
    if (!window->gamma) {
slouken@8582
  2081
        int i;
slouken@8582
  2082
slouken@8582
  2083
        window->gamma = (Uint16 *)SDL_malloc(256*6*sizeof(Uint16));
slouken@8582
  2084
        if (!window->gamma) {
slouken@8582
  2085
            return SDL_OutOfMemory();
slouken@8582
  2086
        }
slouken@8582
  2087
        window->saved_gamma = window->gamma + 3*256;
slouken@8582
  2088
slouken@8582
  2089
        if (_this->GetWindowGammaRamp) {
slouken@8582
  2090
            if (_this->GetWindowGammaRamp(_this, window, window->gamma) < 0) {
slouken@8582
  2091
                return -1;
slouken@8582
  2092
            }
slouken@8582
  2093
        } else {
slouken@8582
  2094
            /* Create an identity gamma ramp */
slouken@8582
  2095
            for (i = 0; i < 256; ++i) {
slouken@8582
  2096
                Uint16 value = (Uint16)((i << 8) | i);
slouken@8582
  2097
slouken@8582
  2098
                window->gamma[0*256+i] = value;
slouken@8582
  2099
                window->gamma[1*256+i] = value;
slouken@8582
  2100
                window->gamma[2*256+i] = value;
slouken@8582
  2101
            }
slouken@8582
  2102
        }
slouken@8582
  2103
        SDL_memcpy(window->saved_gamma, window->gamma, 3*256*sizeof(Uint16));
slouken@8582
  2104
    }
slouken@8582
  2105
slouken@8582
  2106
    if (red) {
slouken@8582
  2107
        SDL_memcpy(red, &window->gamma[0*256], 256*sizeof(Uint16));
slouken@8582
  2108
    }
slouken@8582
  2109
    if (green) {
slouken@8582
  2110
        SDL_memcpy(green, &window->gamma[1*256], 256*sizeof(Uint16));
slouken@8582
  2111
    }
slouken@8582
  2112
    if (blue) {
slouken@8582
  2113
        SDL_memcpy(blue, &window->gamma[2*256], 256*sizeof(Uint16));
slouken@8582
  2114
    }
slouken@8582
  2115
    return 0;
slouken@8582
  2116
}
slouken@8582
  2117
slouken@8582
  2118
void
slouken@8582
  2119
SDL_UpdateWindowGrab(SDL_Window * window)
slouken@8582
  2120
{
slouken@9745
  2121
    SDL_Window *grabbed_window;
slouken@9745
  2122
    SDL_bool grabbed;
slouken@9745
  2123
    if ((SDL_GetMouse()->relative_mode || (window->flags & SDL_WINDOW_INPUT_GRABBED)) &&
slouken@9745
  2124
         (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
slouken@9745
  2125
        grabbed = SDL_TRUE;
slouken@9745
  2126
    } else {
slouken@9745
  2127
        grabbed = SDL_FALSE;
slouken@9745
  2128
    }
slouken@9745
  2129
slouken@9745
  2130
    grabbed_window = _this->grabbed_window;
slouken@9745
  2131
    if (grabbed) {
slouken@9745
  2132
        if (grabbed_window && (grabbed_window != window)) {
slouken@9745
  2133
            /* stealing a grab from another window! */
slouken@9745
  2134
            grabbed_window->flags &= ~SDL_WINDOW_INPUT_GRABBED;
slouken@9745
  2135
            if (_this->SetWindowGrab) {
icculus@9447
  2136
                _this->SetWindowGrab(_this, grabbed_window, SDL_FALSE);
icculus@9447
  2137
            }
icculus@9447
  2138
        }
slouken@9745
  2139
        _this->grabbed_window = window;
slouken@9745
  2140
    } else if (grabbed_window == window) {
slouken@9745
  2141
        _this->grabbed_window = NULL;  /* ungrabbing. */
slouken@9745
  2142
    }
slouken@9745
  2143
slouken@9745
  2144
    if (_this->SetWindowGrab) {
slouken@8582
  2145
        _this->SetWindowGrab(_this, window, grabbed);
slouken@8582
  2146
    }
slouken@8582
  2147
}
slouken@8582
  2148
slouken@8582
  2149
void
slouken@8582
  2150
SDL_SetWindowGrab(SDL_Window * window, SDL_bool grabbed)
slouken@8582
  2151
{
slouken@8818
  2152
    CHECK_WINDOW_MAGIC(window,);
slouken@8582
  2153
slouken@8582
  2154
    if (!!grabbed == !!(window->flags & SDL_WINDOW_INPUT_GRABBED)) {
slouken@8582
  2155
        return;
slouken@8582
  2156
    }
slouken@8582
  2157
    if (grabbed) {
slouken@8582
  2158
        window->flags |= SDL_WINDOW_INPUT_GRABBED;
slouken@8582
  2159
    } else {
slouken@8582
  2160
        window->flags &= ~SDL_WINDOW_INPUT_GRABBED;
slouken@8582
  2161
    }
slouken@8582
  2162
    SDL_UpdateWindowGrab(window);
slouken@8582
  2163
}
slouken@8582
  2164
slouken@8582
  2165
SDL_bool
slouken@8582
  2166
SDL_GetWindowGrab(SDL_Window * window)
slouken@8582
  2167
{
slouken@8582
  2168
    CHECK_WINDOW_MAGIC(window, SDL_FALSE);
icculus@9447
  2169
    SDL_assert(!_this->grabbed_window || ((_this->grabbed_window->flags & SDL_WINDOW_INPUT_GRABBED) != 0));
icculus@9447
  2170
    return window == _this->grabbed_window;
icculus@9447
  2171
}
icculus@9447
  2172
icculus@9447
  2173
SDL_Window *
icculus@9447
  2174
SDL_GetGrabbedWindow(void)
icculus@9447
  2175
{
icculus@9447
  2176
    SDL_assert(!_this->grabbed_window || ((_this->grabbed_window->flags & SDL_WINDOW_INPUT_GRABBED) != 0));
icculus@9447
  2177
    return _this->grabbed_window;
slouken@8582
  2178
}
slouken@8582
  2179
slouken@8582
  2180
void
slouken@8582
  2181
SDL_OnWindowShown(SDL_Window * window)
slouken@8582
  2182
{
slouken@8582
  2183
    SDL_OnWindowRestored(window);
slouken@8582
  2184
}
slouken@8582
  2185
slouken@8582
  2186
void
slouken@8582
  2187
SDL_OnWindowHidden(SDL_Window * window)
slouken@8582
  2188
{
slouken@8582
  2189
    SDL_UpdateFullscreenMode(window, SDL_FALSE);
slouken@8582
  2190
}
slouken@8582
  2191
slouken@8582
  2192
void
slouken@8582
  2193
SDL_OnWindowResized(SDL_Window * window)
slouken@8582
  2194
{
slouken@8582
  2195
    window->surface_valid = SDL_FALSE;
slouken@8582
  2196
    SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h);
slouken@8582
  2197
}
slouken@8582
  2198
slouken@8582
  2199
void
slouken@8582
  2200
SDL_OnWindowMinimized(SDL_Window * window)
slouken@8582
  2201
{
slouken@8582
  2202
    SDL_UpdateFullscreenMode(window, SDL_FALSE);
slouken@8582
  2203
}
slouken@8582
  2204
slouken@8582
  2205
void
slouken@8582
  2206
SDL_OnWindowRestored(SDL_Window * window)
slouken@8582
  2207
{
pgriffais@8683
  2208
    /*
pgriffais@8683
  2209
     * FIXME: Is this fine to just remove this, or should it be preserved just
pgriffais@8683
  2210
     * for the fullscreen case? In principle it seems like just hiding/showing
pgriffais@8683
  2211
     * windows shouldn't affect the stacking order; maybe the right fix is to
pgriffais@8683
  2212
     * re-decouple OnWindowShown and OnWindowRestored.
pgriffais@8683
  2213
     */
icculus@8684
  2214
    /*SDL_RaiseWindow(window);*/
slouken@8582
  2215
slouken@8582
  2216
    if (FULLSCREEN_VISIBLE(window)) {
slouken@8582
  2217
        SDL_UpdateFullscreenMode(window, SDL_TRUE);
slouken@8582
  2218
    }
slouken@8582
  2219
}
slouken@8582
  2220
slouken@8582
  2221
void
slouken@8582
  2222
SDL_OnWindowEnter(SDL_Window * window)
slouken@8582
  2223
{
slouken@8582
  2224
    if (_this->OnWindowEnter) {
slouken@8582
  2225
        _this->OnWindowEnter(_this, window);
slouken@8582
  2226
    }
slouken@8582
  2227
}
slouken@8582
  2228
slouken@8582
  2229
void
slouken@8582
  2230
SDL_OnWindowLeave(SDL_Window * window)
slouken@8582
  2231
{
slouken@8582
  2232
}
slouken@8582
  2233
slouken@8582
  2234
void
slouken@8582
  2235
SDL_OnWindowFocusGained(SDL_Window * window)
slouken@8582
  2236
{
slouken@8582
  2237
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@8582
  2238
slouken@8582
  2239
    if (window->gamma && _this->SetWindowGammaRamp) {
slouken@8582
  2240
        _this->SetWindowGammaRamp(_this, window, window->gamma);
slouken@8582
  2241
    }
slouken@8582
  2242
slouken@8582
  2243
    if (mouse && mouse->relative_mode) {
slouken@8582
  2244
        SDL_SetMouseFocus(window);
slouken@8582
  2245
        SDL_WarpMouseInWindow(window, window->w/2, window->h/2);
slouken@8582
  2246
    }
slouken@8582
  2247
slouken@8582
  2248
    SDL_UpdateWindowGrab(window);
slouken@8582
  2249
}
slouken@8582
  2250
slouken@8582
  2251
static SDL_bool
slouken@8582
  2252
ShouldMinimizeOnFocusLoss(SDL_Window * window)
slouken@8582
  2253
{
slouken@8582
  2254
    const char *hint;
slouken@8582
  2255
jorgen@8112
  2256
    if (!(window->flags & SDL_WINDOW_FULLSCREEN) || window->is_destroying) {
slouken@8582
  2257
        return SDL_FALSE;
slouken@8582
  2258
    }
slouken@8582
  2259
slouken@8582
  2260
#ifdef __MACOSX__
slouken@8582
  2261
    if (Cocoa_IsWindowInFullscreenSpace(window)) {
slouken@8582
  2262
        return SDL_FALSE;
slouken@8582
  2263
    }
slouken@8582
  2264
#endif
slouken@8582
  2265
slouken@8582
  2266
    hint = SDL_GetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS);
slouken@8582
  2267
    if (hint) {
slouken@8582
  2268
        if (*hint == '0') {
slouken@8582
  2269
            return SDL_FALSE;
slouken@8582
  2270
        } else {
slouken@8582
  2271
            return SDL_TRUE;
slouken@8582
  2272
        }
slouken@8582
  2273
    }
slouken@8582
  2274
slouken@8582
  2275
    return SDL_TRUE;
slouken@8582
  2276
}
slouken@8582
  2277
slouken@8582
  2278
void
slouken@8582
  2279
SDL_OnWindowFocusLost(SDL_Window * window)
slouken@8582
  2280
{
slouken@8582
  2281
    if (window->gamma && _this->SetWindowGammaRamp) {
slouken@8582
  2282
        _this->SetWindowGammaRamp(_this, window, window->saved_gamma);
slouken@8582
  2283
    }
slouken@8582
  2284
slouken@8582
  2285
    SDL_UpdateWindowGrab(window);
slouken@8582
  2286
slouken@8582
  2287
    if (ShouldMinimizeOnFocusLoss(window)) {
slouken@8582
  2288
        SDL_MinimizeWindow(window);
slouken@8582
  2289
    }
slouken@8582
  2290
}
slouken@8582
  2291
icculus@8783
  2292
/* !!! FIXME: is this different than SDL_GetKeyboardFocus()?
icculus@8783
  2293
   !!! FIXME:  Also, SDL_GetKeyboardFocus() is O(1), this isn't. */
slouken@8582
  2294
SDL_Window *
slouken@8582
  2295
SDL_GetFocusWindow(void)
slouken@8582
  2296
{
slouken@8582
  2297
    SDL_Window *window;
slouken@8582
  2298
slouken@8582
  2299
    if (!_this) {
slouken@8582
  2300
        return NULL;
slouken@8582
  2301
    }
slouken@8582
  2302
    for (window = _this->windows; window; window = window->next) {
slouken@8582
  2303
        if (window->flags & SDL_WINDOW_INPUT_FOCUS) {
slouken@8582
  2304
            return window;
slouken@8582
  2305
        }
slouken@8582
  2306
    }
slouken@8582
  2307
    return NULL;
slouken@8582
  2308
}
slouken@8582
  2309
slouken@8582
  2310
void
slouken@8582
  2311
SDL_DestroyWindow(SDL_Window * window)
slouken@8582
  2312
{
slouken@8582
  2313
    SDL_VideoDisplay *display;
slouken@8582
  2314
slouken@8818
  2315
    CHECK_WINDOW_MAGIC(window,);
slouken@8582
  2316
jorgen@8112
  2317
    window->is_destroying = SDL_TRUE;
jorgen@8112
  2318
slouken@8582
  2319
    /* Restore video mode, etc. */
slouken@8582
  2320
    SDL_HideWindow(window);
slouken@8582
  2321
slouken@8582
  2322
    /* Make sure this window no longer has focus */
slouken@8582
  2323
    if (SDL_GetKeyboardFocus() == window) {
slouken@8582
  2324
        SDL_SetKeyboardFocus(NULL);
slouken@8582
  2325
    }
slouken@8582
  2326
    if (SDL_GetMouseFocus() == window) {
slouken@8582
  2327
        SDL_SetMouseFocus(NULL);
slouken@8582
  2328
    }
slouken@8582
  2329
slouken@8582
  2330
    /* make no context current if this is the current context window. */
slouken@8582
  2331
    if (window->flags & SDL_WINDOW_OPENGL) {
slouken@8582
  2332
        if (_this->current_glwin == window) {
slouken@8582
  2333
            SDL_GL_MakeCurrent(window, NULL);
slouken@8582
  2334
        }
slouken@8582
  2335
    }
slouken@8582
  2336
slouken@8582
  2337
    if (window->surface) {
slouken@8582
  2338
        window->surface->flags &= ~SDL_DONTFREE;
slouken@8582
  2339
        SDL_FreeSurface(window->surface);
slouken@8582
  2340
    }
slouken@8582
  2341
    if (_this->DestroyWindowFramebuffer) {
slouken@8582
  2342
        _this->DestroyWindowFramebuffer(_this, window);
slouken@8582
  2343
    }
slouken@8582
  2344
    if (_this->DestroyWindow) {
slouken@8582
  2345
        _this->DestroyWindow(_this, window);
slouken@8582
  2346
    }
slouken@8582
  2347
    if (window->flags & SDL_WINDOW_OPENGL) {
slouken@8582
  2348
        SDL_GL_UnloadLibrary();
slouken@8582
  2349
    }
slouken@8582
  2350
slouken@8582
  2351
    display = SDL_GetDisplayForWindow(window);
slouken@8582
  2352
    if (display->fullscreen_window == window) {
slouken@8582
  2353
        display->fullscreen_window = NULL;
slouken@8582
  2354
    }
slouken@8582
  2355
slouken@8582
  2356
    /* Now invalidate magic */
slouken@8582
  2357
    window->magic = NULL;
slouken@8582
  2358
slouken@8582
  2359
    /* Free memory associated with the window */
slouken@8582
  2360
    SDL_free(window->title);
slouken@8582
  2361
    SDL_FreeSurface(window->icon);
slouken@8582
  2362
    SDL_free(window->gamma);
slouken@8582
  2363
    while (window->data) {
slouken@8582
  2364
        SDL_WindowUserData *data = window->data;
slouken@8582
  2365
slouken@8582
  2366
        window->data = data->next;
slouken@8582
  2367
        SDL_free(data->name);
slouken@8582
  2368
        SDL_free(data);
slouken@8582
  2369
    }
slouken@8582
  2370
slouken@8582
  2371
    /* Unlink the window from the list */
slouken@8582
  2372
    if (window->next) {
slouken@8582
  2373
        window->next->prev = window->prev;
slouken@8582
  2374
    }
slouken@8582
  2375
    if (window->prev) {
slouken@8582
  2376
        window->prev->next = window->next;
slouken@8582
  2377
    } else {
slouken@8582
  2378
        _this->windows = window->next;
slouken@8582
  2379
    }
slouken@8582
  2380
slouken@8582
  2381
    SDL_free(window);
slouken@8582
  2382
}
slouken@8582
  2383
slouken@8582
  2384
SDL_bool
slouken@8582
  2385
SDL_IsScreenSaverEnabled()
slouken@8582
  2386
{
slouken@8582
  2387
    if (!_this) {
slouken@8582
  2388
        return SDL_TRUE;
slouken@8582
  2389
    }
slouken@8582
  2390
    return _this->suspend_screensaver ? SDL_FALSE : SDL_TRUE;
slouken@8582
  2391
}
slouken@8582
  2392
slouken@8582
  2393
void
slouken@8582
  2394
SDL_EnableScreenSaver()
slouken@8582
  2395
{
slouken@8582
  2396
    if (!_this) {
slouken@8582
  2397
        return;
slouken@8582
  2398
    }
slouken@8582
  2399
    if (!_this->suspend_screensaver) {
slouken@8582
  2400
        return;
slouken@8582
  2401
    }
slouken@8582
  2402
    _this->suspend_screensaver = SDL_FALSE;
slouken@8582
  2403
    if (_this->SuspendScreenSaver) {
slouken@8582
  2404
        _this->SuspendScreenSaver(_this);
slouken@8582
  2405
    }
slouken@8582
  2406
}
slouken@8582
  2407
slouken@8582
  2408
void
slouken@8582
  2409
SDL_DisableScreenSaver()
slouken@8582
  2410
{
slouken@8582
  2411
    if (!_this) {
slouken@8582
  2412
        return;
slouken@8582
  2413
    }
slouken@8582
  2414
    if (_this->suspend_screensaver) {
slouken@8582
  2415
        return;
slouken@8582
  2416
    }
slouken@8582
  2417
    _this->suspend_screensaver = SDL_TRUE;
slouken@8582
  2418
    if (_this->SuspendScreenSaver) {
slouken@8582
  2419
        _this->SuspendScreenSaver(_this);
slouken@8582
  2420
    }
slouken@8582
  2421
}
slouken@8582
  2422
slouken@8582
  2423
void
slouken@8582
  2424
SDL_VideoQuit(void)
slouken@8582
  2425
{
slouken@8582
  2426
    int i, j;
slouken@8582
  2427
slouken@8582
  2428
    if (!_this) {
slouken@8582
  2429
        return;
slouken@8582
  2430
    }
slouken@8582
  2431
slouken@8582
  2432
    /* Halt event processing before doing anything else */
slouken@8582
  2433
    SDL_TouchQuit();
slouken@8582
  2434
    SDL_MouseQuit();
slouken@8582
  2435
    SDL_KeyboardQuit();
slouken@8582
  2436
    SDL_QuitSubSystem(SDL_INIT_EVENTS);
slouken@8582
  2437
slouken@8582
  2438
    SDL_EnableScreenSaver();
slouken@8582
  2439
slouken@8582
  2440
    /* Clean up the system video */
slouken@8582
  2441
    while (_this->windows) {
slouken@8582
  2442
        SDL_DestroyWindow(_this->windows);
slouken@8582
  2443
    }
slouken@8582
  2444
    _this->VideoQuit(_this);
slouken@8582
  2445
slouken@8582
  2446
    for (i = 0; i < _this->num_displays; ++i) {
slouken@8582
  2447
        SDL_VideoDisplay *display = &_this->displays[i];
slouken@8582
  2448
        for (j = display->num_display_modes; j--;) {
slouken@8582
  2449
            SDL_free(display->display_modes[j].driverdata);
slouken@8582
  2450
            display->display_modes[j].driverdata = NULL;
slouken@8582
  2451
        }
slouken@8582
  2452
        SDL_free(display->display_modes);
slouken@8582
  2453
        display->display_modes = NULL;
slouken@8582
  2454
        SDL_free(display->desktop_mode.driverdata);
slouken@8582
  2455
        display->desktop_mode.driverdata = NULL;
slouken@8582
  2456
        SDL_free(display->driverdata);
slouken@8582
  2457
        display->driverdata = NULL;
slouken@8582
  2458
    }
slouken@8582
  2459
    if (_this->displays) {
slouken@8582
  2460
        for (i = 0; i < _this->num_displays; ++i) {
slouken@8582
  2461
            SDL_free(_this->displays[i].name);
slouken@8582
  2462
        }
slouken@8582
  2463
        SDL_free(_this->displays);
slouken@8582
  2464
        _this->displays = NULL;
slouken@8582
  2465
        _this->num_displays = 0;
slouken@8582
  2466
    }
slouken@8582
  2467
    SDL_free(_this->clipboard_text);
slouken@8582
  2468
    _this->clipboard_text = NULL;
slouken@8582
  2469
    _this->free(_this);
slouken@8582
  2470
    _this = NULL;
slouken@8582
  2471
}
slouken@8582
  2472
slouken@8582
  2473
int
slouken@8582
  2474
SDL_GL_LoadLibrary(const char *path)
slouken@8582
  2475
{
slouken@8582
  2476
    int retval;
slouken@8582
  2477
slouken@8582
  2478
    if (!_this) {
slouken@8582
  2479
        return SDL_UninitializedVideo();
slouken@8582
  2480
    }
slouken@8582
  2481
    if (_this->gl_config.driver_loaded) {
slouken@8582
  2482
        if (path && SDL_strcmp(path, _this->gl_config.driver_path) != 0) {
slouken@8582
  2483
            return SDL_SetError("OpenGL library already loaded");
slouken@8582
  2484
        }
slouken@8582
  2485
        retval = 0;
slouken@8582
  2486
    } else {
slouken@8582
  2487
        if (!_this->GL_LoadLibrary) {
slouken@8582
  2488
            return SDL_SetError("No dynamic GL support in video driver");
slouken@8582
  2489
        }
slouken@8582
  2490
        retval = _this->GL_LoadLibrary(_this, path);
slouken@8582
  2491
    }
slouken@8582
  2492
    if (retval == 0) {
slouken@8582
  2493
        ++_this->gl_config.driver_loaded;
slouken@8582
  2494
    } else {
slouken@8582
  2495
        if (_this->GL_UnloadLibrary) {
slouken@8582
  2496
            _this->GL_UnloadLibrary(_this);
slouken@8582
  2497
        }
slouken@8582
  2498
    }
slouken@8582
  2499
    return (retval);
slouken@8582
  2500
}
slouken@8582
  2501
slouken@8582
  2502
void *
slouken@8582
  2503
SDL_GL_GetProcAddress(const char *proc)
slouken@8582
  2504
{
slouken@8582
  2505
    void *func;
slouken@8582
  2506
slouken@8582
  2507
    if (!_this) {
slouken@8582
  2508
        SDL_UninitializedVideo();
slouken@8582
  2509
        return NULL;
slouken@8582
  2510
    }
slouken@8582
  2511
    func = NULL;
slouken@8582
  2512
    if (_this->GL_GetProcAddress) {
slouken@8582
  2513
        if (_this->gl_config.driver_loaded) {
slouken@8582
  2514
            func = _this->GL_GetProcAddress(_this, proc);
slouken@8582
  2515
        } else {
slouken@8582
  2516
            SDL_SetError("No GL driver has been loaded");
slouken@8582
  2517
        }
slouken@8582
  2518
    } else {
slouken@8582
  2519
        SDL_SetError("No dynamic GL support in video driver");
slouken@8582
  2520
    }
slouken@8582
  2521
    return func;
slouken@8582
  2522
}
slouken@8582
  2523
slouken@8582
  2524
void
slouken@8582
  2525
SDL_GL_UnloadLibrary(void)
slouken@8582
  2526
{
slouken@8582
  2527
    if (!_this) {
slouken@8582
  2528
        SDL_UninitializedVideo();
slouken@8582
  2529
        return;
slouken@8582
  2530
    }
slouken@8582
  2531
    if (_this->gl_config.driver_loaded > 0) {
slouken@8582
  2532
        if (--_this->gl_config.driver_loaded > 0) {
slouken@8582
  2533
            return;
slouken@8582
  2534
        }
slouken@8582
  2535
        if (_this->GL_UnloadLibrary) {
slouken@8582
  2536
            _this->GL_UnloadLibrary(_this);
slouken@8582
  2537
        }
slouken@8582
  2538
    }
slouken@8582
  2539
}
slouken@8582
  2540
slouken@8582
  2541
static SDL_INLINE SDL_bool
slouken@8582
  2542
isAtLeastGL3(const char *verstr)
slouken@8582
  2543
{
slouken@8818
  2544
    return (verstr && (SDL_atoi(verstr) >= 3));
slouken@8582
  2545
}
slouken@8582
  2546
slouken@8582
  2547
SDL_bool
slouken@8582
  2548
SDL_GL_ExtensionSupported(const char *extension)
slouken@8582
  2549
{
slouken@8582
  2550
#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
slouken@8582
  2551
    const GLubyte *(APIENTRY * glGetStringFunc) (GLenum);
slouken@8582
  2552
    const char *extensions;
slouken@8582
  2553
    const char *start;
slouken@8582
  2554
    const char *where, *terminator;
slouken@8582
  2555
slouken@8582
  2556
    /* Extension names should not have spaces. */
slouken@8582
  2557
    where = SDL_strchr(extension, ' ');
slouken@8582
  2558
    if (where || *extension == '\0') {
slouken@8582
  2559
        return SDL_FALSE;
slouken@8582
  2560
    }
slouken@8582
  2561
    /* See if there's an environment variable override */
slouken@8582
  2562
    start = SDL_getenv(extension);
slouken@8582
  2563
    if (start && *start == '0') {
slouken@8582
  2564
        return SDL_FALSE;
slouken@8582
  2565
    }
slouken@8582
  2566
slouken@8582
  2567
    /* Lookup the available extensions */
slouken@8582
  2568
slouken@8582
  2569
    glGetStringFunc = SDL_GL_GetProcAddress("glGetString");
slouken@8582
  2570
    if (!glGetStringFunc) {
slouken@8582
  2571
        return SDL_FALSE;
slouken@8582
  2572
    }
slouken@8582
  2573
slouken@8582
  2574
    if (isAtLeastGL3((const char *) glGetStringFunc(GL_VERSION))) {
slouken@8582
  2575
        const GLubyte *(APIENTRY * glGetStringiFunc) (GLenum, GLuint);
slouken@8582
  2576
        void (APIENTRY * glGetIntegervFunc) (GLenum pname, GLint * params);
slouken@8582
  2577
        GLint num_exts = 0;
slouken@8582
  2578
        GLint i;
slouken@8582
  2579
slouken@8582
  2580
        glGetStringiFunc = SDL_GL_GetProcAddress("glGetStringi");
slouken@8582
  2581
        glGetIntegervFunc = SDL_GL_GetProcAddress("glGetIntegerv");
slouken@8582
  2582
        if ((!glGetStringiFunc) || (!glGetIntegervFunc)) {
slouken@8582
  2583
            return SDL_FALSE;
slouken@8582
  2584
        }
slouken@8582
  2585
slouken@8582
  2586
        #ifndef GL_NUM_EXTENSIONS
slouken@8582
  2587
        #define GL_NUM_EXTENSIONS 0x821D
slouken@8582
  2588
        #endif
slouken@8582
  2589
        glGetIntegervFunc(GL_NUM_EXTENSIONS, &num_exts);
slouken@8582
  2590
        for (i = 0; i < num_exts; i++) {
slouken@8582
  2591
            const char *thisext = (const char *) glGetStringiFunc(GL_EXTENSIONS, i);
slouken@8582
  2592
            if (SDL_strcmp(thisext, extension) == 0) {
slouken@8582
  2593
                return SDL_TRUE;
slouken@8582
  2594
            }
slouken@8582
  2595
        }
slouken@8582
  2596
slouken@8582
  2597
        return SDL_FALSE;
slouken@8582
  2598
    }
slouken@8582
  2599
slouken@8582
  2600
    /* Try the old way with glGetString(GL_EXTENSIONS) ... */
slouken@8582
  2601
slouken@8582
  2602
    extensions = (const char *) glGetStringFunc(GL_EXTENSIONS);
slouken@8582
  2603
    if (!extensions) {
slouken@8582
  2604
        return SDL_FALSE;
slouken@8582
  2605
    }
slouken@8582
  2606
    /*
slouken@8582
  2607
     * It takes a bit of care to be fool-proof about parsing the OpenGL
slouken@8582
  2608
     * extensions string. Don't be fooled by sub-strings, etc.
slouken@8582
  2609
     */
slouken@8582
  2610
slouken@8582
  2611
    start = extensions;
slouken@8582
  2612
slouken@8582
  2613
    for (;;) {
slouken@8582
  2614
        where = SDL_strstr(start, extension);
slouken@8582
  2615
        if (!where)
slouken@8582
  2616
            break;
slouken@8582
  2617
slouken@8582
  2618
        terminator = where + SDL_strlen(extension);
slouken@8582
  2619
        if (where == start || *(where - 1) == ' ')
slouken@8582
  2620
            if (*terminator == ' ' || *terminator == '\0')
slouken@8582
  2621
                return SDL_TRUE;
slouken@8582
  2622
slouken@8582
  2623
        start = terminator;
slouken@8582
  2624
    }
slouken@8582
  2625
    return SDL_FALSE;
slouken@8582
  2626
#else
slouken@8582
  2627
    return SDL_FALSE;
slouken@8582
  2628
#endif
slouken@8582
  2629
}
slouken@8582
  2630
jorgen@8145
  2631
void
jorgen@8145
  2632
SDL_GL_ResetAttributes()
jorgen@8145
  2633
{
jorgen@8145
  2634
    if (!_this) {
jorgen@8145
  2635
        return;
jorgen@8145
  2636
    }
jorgen@8145
  2637
jorgen@8145
  2638
    _this->gl_config.red_size = 3;
jorgen@8145
  2639
    _this->gl_config.green_size = 3;
jorgen@8145
  2640
    _this->gl_config.blue_size = 2;
jorgen@8145
  2641
    _this->gl_config.alpha_size = 0;
jorgen@8145
  2642
    _this->gl_config.buffer_size = 0;
jorgen@8145
  2643
    _this->gl_config.depth_size = 16;
jorgen@8145
  2644
    _this->gl_config.stencil_size = 0;
jorgen@8145
  2645
    _this->gl_config.double_buffer = 1;
jorgen@8145
  2646
    _this->gl_config.accum_red_size = 0;
jorgen@8145
  2647
    _this->gl_config.accum_green_size = 0;
jorgen@8145
  2648
    _this->gl_config.accum_blue_size = 0;
jorgen@8145
  2649
    _this->gl_config.accum_alpha_size = 0;
jorgen@8145
  2650
    _this->gl_config.stereo = 0;
jorgen@8145
  2651
    _this->gl_config.multisamplebuffers = 0;
jorgen@8145
  2652
    _this->gl_config.multisamplesamples = 0;
jorgen@8145
  2653
    _this->gl_config.retained_backing = 1;
jorgen@8145
  2654
    _this->gl_config.accelerated = -1;  /* accelerated or not, both are fine */
slouken@8601
  2655
    _this->gl_config.profile_mask = 0;
icculus@8586
  2656
#if SDL_VIDEO_OPENGL
slouken@8601
  2657
    _this->gl_config.major_version = 2;
slouken@8601
  2658
    _this->gl_config.minor_version = 1;
jorgen@8145
  2659
#elif SDL_VIDEO_OPENGL_ES2
jorgen@8145
  2660
    _this->gl_config.major_version = 2;
jorgen@8145
  2661
    _this->gl_config.minor_version = 0;
jorgen@8145
  2662
    _this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES;
jorgen@8145
  2663
#elif SDL_VIDEO_OPENGL_ES
jorgen@8145
  2664
    _this->gl_config.major_version = 1;
jorgen@8145
  2665
    _this->gl_config.minor_version = 1;
jorgen@8145
  2666
    _this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES;
jorgen@8145
  2667
#endif
jorgen@8145
  2668
    _this->gl_config.flags = 0;
jorgen@8145
  2669
    _this->gl_config.framebuffer_srgb_capable = 0;
mdiluzio@9412
  2670
    _this->gl_config.release_behavior = SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH;
jorgen@8145
  2671
jorgen@8145
  2672
    _this->gl_config.share_with_current_context = 0;
jorgen@8145
  2673
}
jorgen@8145
  2674
slouken@8582
  2675
int
slouken@8582
  2676
SDL_GL_SetAttribute(SDL_GLattr attr, int value)
slouken@8582
  2677
{
slouken@8582
  2678
#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
slouken@8582
  2679
    int retval;
slouken@8582
  2680
slouken@8582
  2681
    if (!_this) {
slouken@8582
  2682
        return SDL_UninitializedVideo();
slouken@8582
  2683
    }
slouken@8582
  2684
    retval = 0;
slouken@8582
  2685
    switch (attr) {
slouken@8582
  2686
    case SDL_GL_RED_SIZE:
slouken@8582
  2687
        _this->gl_config.red_size = value;
slouken@8582
  2688
        break;
slouken@8582
  2689
    case SDL_GL_GREEN_SIZE:
slouken@8582
  2690
        _this->gl_config.green_size = value;
slouken@8582
  2691
        break;
slouken@8582
  2692
    case SDL_GL_BLUE_SIZE:
slouken@8582
  2693
        _this->gl_config.blue_size = value;
slouken@8582
  2694
        break;
slouken@8582
  2695
    case SDL_GL_ALPHA_SIZE:
slouken@8582
  2696
        _this->gl_config.alpha_size = value;
slouken@8582
  2697
        break;
slouken@8582
  2698
    case SDL_GL_DOUBLEBUFFER:
slouken@8582
  2699
        _this->gl_config.double_buffer = value;
slouken@8582
  2700
        break;
slouken@8582
  2701
    case SDL_GL_BUFFER_SIZE:
slouken@8582
  2702
        _this->gl_config.buffer_size = value;
slouken@8582
  2703
        break;
slouken@8582
  2704
    case SDL_GL_DEPTH_SIZE:
slouken@8582
  2705
        _this->gl_config.depth_size = value;
slouken@8582
  2706
        break;
slouken@8582
  2707
    case SDL_GL_STENCIL_SIZE:
slouken@8582
  2708
        _this->gl_config.stencil_size = value;
slouken@8582
  2709
        break;
slouken@8582
  2710
    case SDL_GL_ACCUM_RED_SIZE:
slouken@8582
  2711
        _this->gl_config.accum_red_size = value;
slouken@8582
  2712
        break;
slouken@8582
  2713
    case SDL_GL_ACCUM_GREEN_SIZE:
slouken@8582
  2714
        _this->gl_config.accum_green_size = value;
slouken@8582
  2715
        break;
slouken@8582
  2716
    case SDL_GL_ACCUM_BLUE_SIZE:
slouken@8582
  2717
        _this->gl_config.accum_blue_size = value;
slouken@8582
  2718
        break;
slouken@8582
  2719
    case SDL_GL_ACCUM_ALPHA_SIZE:
slouken@8582
  2720
        _this->gl_config.accum_alpha_size = value;
slouken@8582
  2721
        break;
slouken@8582
  2722
    case SDL_GL_STEREO:
slouken@8582
  2723
        _this->gl_config.stereo = value;
slouken@8582
  2724
        break;
slouken@8582
  2725
    case SDL_GL_MULTISAMPLEBUFFERS:
slouken@8582
  2726
        _this->gl_config.multisamplebuffers = value;
slouken@8582
  2727
        break;
slouken@8582
  2728
    case SDL_GL_MULTISAMPLESAMPLES:
slouken@8582
  2729
        _this->gl_config.multisamplesamples = value;
slouken@8582
  2730
        break;
slouken@8582
  2731
    case SDL_GL_ACCELERATED_VISUAL:
slouken@8582
  2732
        _this->gl_config.accelerated = value;
slouken@8582
  2733
        break;
slouken@8582
  2734
    case SDL_GL_RETAINED_BACKING:
slouken@8582
  2735
        _this->gl_config.retained_backing = value;
slouken@8582
  2736
        break;
slouken@8582
  2737
    case SDL_GL_CONTEXT_MAJOR_VERSION:
slouken@8582
  2738
        _this->gl_config.major_version = value;
slouken@8582
  2739
        break;
slouken@8582
  2740
    case SDL_GL_CONTEXT_MINOR_VERSION:
slouken@8582
  2741
        _this->gl_config.minor_version = value;
slouken@8582
  2742
        break;
slouken@8582
  2743
    case SDL_GL_CONTEXT_EGL:
slouken@8582
  2744
        /* FIXME: SDL_GL_CONTEXT_EGL to be deprecated in SDL 2.1 */
slouken@8582
  2745
        if (value != 0) {
slouken@8582
  2746
            SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
slouken@8582
  2747
        } else {
slouken@8582
  2748
            SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, 0);
slouken@8582
  2749
        };
slouken@8582
  2750
        break;
slouken@8582
  2751
    case SDL_GL_CONTEXT_FLAGS:
slouken@8818
  2752
        if (value & ~(SDL_GL_CONTEXT_DEBUG_FLAG |
slouken@8818
  2753
                      SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG |
slouken@8818
  2754
                      SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG |
slouken@8818
  2755
                      SDL_GL_CONTEXT_RESET_ISOLATION_FLAG)) {
slouken@8818
  2756
            retval = SDL_SetError("Unknown OpenGL context flag %d", value);
slouken@8818
  2757
            break;
slouken@8818
  2758
        }
slouken@8582
  2759
        _this->gl_config.flags = value;
slouken@8582
  2760
        break;
slouken@8582
  2761
    case SDL_GL_CONTEXT_PROFILE_MASK:
slouken@8818
  2762
        if (value != 0 &&
slouken@8818
  2763
            value != SDL_GL_CONTEXT_PROFILE_CORE &&
slouken@8818
  2764
            value != SDL_GL_CONTEXT_PROFILE_COMPATIBILITY &&
slouken@8818
  2765
            value != SDL_GL_CONTEXT_PROFILE_ES) {
slouken@8818
  2766
            retval = SDL_SetError("Unknown OpenGL context profile %d", value);
slouken@8818
  2767
            break;
slouken@8818
  2768
        }
slouken@8582