src/video/SDL_video.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 11 Feb 2011 00:25:44 -0800
changeset 5249 7a963be087ef
parent 5246 58265e606e4e
child 5250 f908e06b3c96
permissions -rw-r--r--
Mostly fixed fullscreen mode on Mac OS X, and you can toggle it on and off.

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