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