src/video/x11/SDL_x11modes.c
author Gabriel Jacobo <gabomdq@gmail.com>
Wed, 21 Aug 2013 09:47:10 -0300
changeset 7678 286c42d7c5ed
parent 7677 871d43c6968a
child 7827 a03ec8de0426
permissions -rw-r--r--
OCD fixes: Adds a space after /* (glory to regular expressions!)
slouken@1950
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@6885
     3
  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
slouken@1950
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@1950
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@1950
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@1950
    20
*/
slouken@1950
    21
#include "SDL_config.h"
slouken@1950
    22
slouken@5481
    23
#if SDL_VIDEO_DRIVER_X11
slouken@5481
    24
slouken@6472
    25
#include "SDL_hints.h"
slouken@1950
    26
#include "SDL_x11video.h"
slouken@6796
    27
#include "edid.h"
slouken@1950
    28
gabomdq@7678
    29
/* #define X11MODES_DEBUG */
slouken@6558
    30
slouken@6559
    31
/* I'm becoming more and more convinced that the application should never
slouken@6559
    32
 * use XRandR, and it's the window manager's responsibility to track and
slouken@6559
    33
 * manage display modes for fullscreen windows.  Right now XRandR is completely
slouken@6559
    34
 * broken with respect to window manager behavior on every window manager that
slouken@6559
    35
 * I can find.  For example, on Unity 3D if you show a fullscreen window while
slouken@6559
    36
 * the resolution is changing (within ~250 ms) your window will retain the
slouken@6559
    37
 * fullscreen state hint but be decorated and windowed.
slouken@6796
    38
 *
slouken@6796
    39
 * However, many people swear by it, so let them swear at it. :)
slouken@6558
    40
*/
gabomdq@7678
    41
/* #define XRANDR_DISABLED_BY_DEFAULT */
slouken@6558
    42
slouken@1950
    43
slouken@1950
    44
static int
slouken@1950
    45
get_visualinfo(Display * display, int screen, XVisualInfo * vinfo)
slouken@1950
    46
{
slouken@1950
    47
    const char *visual_id = SDL_getenv("SDL_VIDEO_X11_VISUALID");
slouken@1950
    48
    int depth;
slouken@1950
    49
slouken@1950
    50
    /* Look for an exact visual, if requested */
slouken@1950
    51
    if (visual_id) {
slouken@3697
    52
        XVisualInfo *vi, template;
slouken@3697
    53
        int nvis;
slouken@1950
    54
slouken@1950
    55
        SDL_zero(template);
slouken@1950
    56
        template.visualid = SDL_strtol(visual_id, NULL, 0);
slouken@1950
    57
        vi = XGetVisualInfo(display, VisualIDMask, &template, &nvis);
slouken@1950
    58
        if (vi) {
slouken@1950
    59
            *vinfo = *vi;
slouken@1950
    60
            XFree(vi);
slouken@1950
    61
            return 0;
slouken@1950
    62
        }
slouken@1950
    63
    }
slouken@3697
    64
slouken@1950
    65
    depth = DefaultDepth(display, screen);
slouken@5466
    66
    if ((X11_UseDirectColorVisuals() &&
slouken@5466
    67
         XMatchVisualInfo(display, screen, depth, DirectColor, vinfo)) ||
slouken@5466
    68
        XMatchVisualInfo(display, screen, depth, TrueColor, vinfo) ||
slouken@1950
    69
        XMatchVisualInfo(display, screen, depth, PseudoColor, vinfo) ||
slouken@1950
    70
        XMatchVisualInfo(display, screen, depth, StaticColor, vinfo)) {
slouken@1950
    71
        return 0;
slouken@1950
    72
    }
slouken@1950
    73
    return -1;
slouken@1950
    74
}
slouken@1950
    75
slouken@5182
    76
int
slouken@5182
    77
X11_GetVisualInfoFromVisual(Display * display, Visual * visual, XVisualInfo * vinfo)
slouken@5182
    78
{
slouken@5182
    79
    XVisualInfo *vi;
slouken@5182
    80
    int nvis;
slouken@5182
    81
slouken@5182
    82
    vinfo->visualid = XVisualIDFromVisual(visual);
slouken@5182
    83
    vi = XGetVisualInfo(display, VisualIDMask, vinfo, &nvis);
slouken@5182
    84
    if (vi) {
slouken@5182
    85
        *vinfo = *vi;
slouken@5182
    86
        XFree(vi);
slouken@5182
    87
        return 0;
slouken@5182
    88
    }
slouken@5182
    89
    return -1;
slouken@5182
    90
}
slouken@5182
    91
slouken@5182
    92
Uint32
slouken@2874
    93
X11_GetPixelFormatFromVisualInfo(Display * display, XVisualInfo * vinfo)
slouken@2870
    94
{
slouken@2870
    95
    if (vinfo->class == DirectColor || vinfo->class == TrueColor) {
slouken@2870
    96
        int bpp;
slouken@2870
    97
        Uint32 Rmask, Gmask, Bmask, Amask;
slouken@2870
    98
slouken@2870
    99
        Rmask = vinfo->visual->red_mask;
slouken@2870
   100
        Gmask = vinfo->visual->green_mask;
slouken@2870
   101
        Bmask = vinfo->visual->blue_mask;
slouken@2870
   102
        if (vinfo->depth == 32) {
slouken@2870
   103
            Amask = (0xFFFFFFFF & ~(Rmask | Gmask | Bmask));
slouken@2870
   104
        } else {
slouken@2870
   105
            Amask = 0;
slouken@2870
   106
        }
slouken@2870
   107
slouken@2870
   108
        bpp = vinfo->depth;
slouken@2870
   109
        if (bpp == 24) {
slouken@2870
   110
            int i, n;
slouken@2870
   111
            XPixmapFormatValues *p = XListPixmapFormats(display, &n);
slouken@2870
   112
            if (p) {
slouken@2870
   113
                for (i = 0; i < n; ++i) {
slouken@2870
   114
                    if (p[i].depth == 24) {
slouken@2870
   115
                        bpp = p[i].bits_per_pixel;
slouken@2870
   116
                        break;
slouken@2870
   117
                    }
slouken@2870
   118
                }
slouken@2870
   119
                XFree(p);
slouken@2870
   120
            }
slouken@2870
   121
        }
slouken@2870
   122
slouken@2870
   123
        return SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask);
slouken@2870
   124
    }
slouken@2870
   125
slouken@2870
   126
    if (vinfo->class == PseudoColor || vinfo->class == StaticColor) {
slouken@2870
   127
        switch (vinfo->depth) {
slouken@2870
   128
        case 8:
slouken@2870
   129
            return SDL_PIXELTYPE_INDEX8;
slouken@2870
   130
        case 4:
slouken@2870
   131
            if (BitmapBitOrder(display) == LSBFirst) {
slouken@2870
   132
                return SDL_PIXELFORMAT_INDEX4LSB;
slouken@2870
   133
            } else {
slouken@2870
   134
                return SDL_PIXELFORMAT_INDEX4MSB;
slouken@2870
   135
            }
slouken@2870
   136
            break;
slouken@2870
   137
        case 1:
slouken@2870
   138
            if (BitmapBitOrder(display) == LSBFirst) {
slouken@2870
   139
                return SDL_PIXELFORMAT_INDEX1LSB;
slouken@2870
   140
            } else {
slouken@2870
   141
                return SDL_PIXELFORMAT_INDEX1MSB;
slouken@2870
   142
            }
slouken@2870
   143
            break;
slouken@2870
   144
        }
slouken@2870
   145
    }
slouken@2870
   146
slouken@2870
   147
    return SDL_PIXELFORMAT_UNKNOWN;
slouken@2870
   148
}
slouken@1950
   149
slouken@2873
   150
/* Global for the error handler */
slouken@2873
   151
int vm_event, vm_error = -1;
slouken@2873
   152
slouken@2873
   153
#if SDL_VIDEO_DRIVER_X11_XINERAMA
slouken@2873
   154
static SDL_bool
slouken@2874
   155
CheckXinerama(Display * display, int *major, int *minor)
slouken@2873
   156
{
icculus@6027
   157
    int event_base = 0;
icculus@6027
   158
    int error_base = 0;
slouken@2873
   159
    const char *env;
slouken@2873
   160
slouken@2873
   161
    /* Default the extension not available */
slouken@2873
   162
    *major = *minor = 0;
slouken@2873
   163
slouken@2873
   164
    /* Allow environment override */
slouken@6472
   165
    env = SDL_GetHint(SDL_HINT_VIDEO_X11_XINERAMA);
slouken@2873
   166
    if (env && !SDL_atoi(env)) {
slouken@6468
   167
#ifdef X11MODES_DEBUG
slouken@6472
   168
        printf("Xinerama disabled due to hint\n");
slouken@6468
   169
#endif
slouken@2873
   170
        return SDL_FALSE;
slouken@2873
   171
    }
slouken@2873
   172
slouken@5408
   173
    if (!SDL_X11_HAVE_XINERAMA) {
slouken@6468
   174
#ifdef X11MODES_DEBUG
slouken@6468
   175
        printf("Xinerama support not available\n");
slouken@6468
   176
#endif
slouken@5408
   177
        return SDL_FALSE;
slouken@5408
   178
    }
slouken@5408
   179
slouken@2873
   180
    /* Query the extension version */
icculus@6027
   181
    if (!XineramaQueryExtension(display, &event_base, &error_base) ||
icculus@6027
   182
        !XineramaQueryVersion(display, major, minor) ||
slouken@5408
   183
        !XineramaIsActive(display)) {
slouken@6468
   184
#ifdef X11MODES_DEBUG
slouken@6468
   185
        printf("Xinerama not active on the display\n");
slouken@6468
   186
#endif
slouken@2873
   187
        return SDL_FALSE;
slouken@2873
   188
    }
slouken@6468
   189
#ifdef X11MODES_DEBUG
slouken@6548
   190
    printf("Xinerama available at version %d.%d!\n", *major, *minor);
slouken@6468
   191
#endif
slouken@2873
   192
    return SDL_TRUE;
slouken@2873
   193
}
slouken@2873
   194
#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
slouken@2873
   195
slouken@2873
   196
#if SDL_VIDEO_DRIVER_X11_XRANDR
slouken@2873
   197
static SDL_bool
slouken@2874
   198
CheckXRandR(Display * display, int *major, int *minor)
slouken@2873
   199
{
slouken@2873
   200
    const char *env;
slouken@2873
   201
slouken@2873
   202
    /* Default the extension not available */
slouken@2873
   203
    *major = *minor = 0;
slouken@2873
   204
slouken@2873
   205
    /* Allow environment override */
slouken@6472
   206
    env = SDL_GetHint(SDL_HINT_VIDEO_X11_XRANDR);
slouken@6558
   207
#ifdef XRANDR_DISABLED_BY_DEFAULT
slouken@6558
   208
    if (!env || !SDL_atoi(env)) {
slouken@6558
   209
#ifdef X11MODES_DEBUG
slouken@6558
   210
        printf("XRandR disabled by default due to window manager issues\n");
slouken@6558
   211
#endif
slouken@6558
   212
        return SDL_FALSE;
slouken@6558
   213
    }
slouken@6558
   214
#else
slouken@2873
   215
    if (env && !SDL_atoi(env)) {
slouken@6468
   216
#ifdef X11MODES_DEBUG
slouken@6472
   217
        printf("XRandR disabled due to hint\n");
slouken@6468
   218
#endif
slouken@2873
   219
        return SDL_FALSE;
slouken@2873
   220
    }
slouken@6558
   221
#endif /* XRANDR_ENABLED_BY_DEFAULT */
slouken@2873
   222
slouken@2873
   223
    if (!SDL_X11_HAVE_XRANDR) {
slouken@6468
   224
#ifdef X11MODES_DEBUG
slouken@6468
   225
        printf("XRandR support not available\n");
slouken@6468
   226
#endif
slouken@2873
   227
        return SDL_FALSE;
slouken@2873
   228
    }
slouken@2873
   229
slouken@2873
   230
    /* Query the extension version */
slouken@2873
   231
    if (!XRRQueryVersion(display, major, minor)) {
slouken@6468
   232
#ifdef X11MODES_DEBUG
slouken@6468
   233
        printf("XRandR not active on the display\n");
slouken@6468
   234
#endif
slouken@2873
   235
        return SDL_FALSE;
slouken@2873
   236
    }
slouken@6468
   237
#ifdef X11MODES_DEBUG
slouken@6548
   238
    printf("XRandR available at version %d.%d!\n", *major, *minor);
slouken@6468
   239
#endif
slouken@2873
   240
    return SDL_TRUE;
slouken@2873
   241
}
slouken@6537
   242
slouken@6537
   243
#define XRANDR_ROTATION_LEFT    (1 << 1)
slouken@6537
   244
#define XRANDR_ROTATION_RIGHT   (1 << 3)
slouken@6537
   245
slouken@6548
   246
static int
slouken@6548
   247
CalculateXRandRRefreshRate(const XRRModeInfo *info)
slouken@6537
   248
{
slouken@6548
   249
    return (info->hTotal
slouken@6551
   250
            && info->vTotal) ? (info->dotClock / (info->hTotal * info->vTotal)) : 0;
slouken@6548
   251
}
slouken@6548
   252
slouken@6548
   253
static SDL_bool
slouken@6548
   254
SetXRandRModeInfo(Display *display, XRRScreenResources *res, XRROutputInfo *output_info,
slouken@6548
   255
                  RRMode modeID, SDL_DisplayMode *mode)
slouken@6548
   256
{
slouken@6548
   257
    int i;
slouken@6548
   258
    for (i = 0; i < res->nmode; ++i) {
slouken@6548
   259
        if (res->modes[i].id == modeID) {
slouken@6548
   260
            XRRCrtcInfo *crtc;
slouken@6548
   261
            Rotation rotation = 0;
slouken@6548
   262
            const XRRModeInfo *info = &res->modes[i];
slouken@6548
   263
slouken@6548
   264
            crtc = XRRGetCrtcInfo(display, res, output_info->crtc);
slouken@6548
   265
            if (crtc) {
slouken@6548
   266
                rotation = crtc->rotation;
slouken@6548
   267
                XRRFreeCrtcInfo(crtc);
slouken@6548
   268
            }
slouken@6548
   269
slouken@6548
   270
            if (rotation & (XRANDR_ROTATION_LEFT|XRANDR_ROTATION_RIGHT)) {
slouken@6548
   271
                mode->w = info->height;
slouken@6548
   272
                mode->h = info->width;
slouken@6548
   273
            } else {
slouken@6548
   274
                mode->w = info->width;
slouken@6548
   275
                mode->h = info->height;
slouken@6548
   276
            }
slouken@6548
   277
            mode->refresh_rate = CalculateXRandRRefreshRate(info);
slouken@6548
   278
            ((SDL_DisplayModeData*)mode->driverdata)->xrandr_mode = modeID;
slouken@6548
   279
#ifdef X11MODES_DEBUG
icculus@6560
   280
            printf("XRandR mode %d: %dx%d@%dHz\n", (int) modeID, mode->w, mode->h, mode->refresh_rate);
slouken@6548
   281
#endif
slouken@6548
   282
            return SDL_TRUE;
slouken@6548
   283
        }
slouken@6537
   284
    }
slouken@6548
   285
    return SDL_FALSE;
slouken@6537
   286
}
slouken@2873
   287
#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
slouken@2873
   288
slouken@5408
   289
#if SDL_VIDEO_DRIVER_X11_XVIDMODE
slouken@2873
   290
static SDL_bool
slouken@2874
   291
CheckVidMode(Display * display, int *major, int *minor)
slouken@2873
   292
{
slouken@2873
   293
    const char *env;
slouken@2873
   294
slouken@2873
   295
    /* Default the extension not available */
slouken@2873
   296
    *major = *minor = 0;
slouken@2873
   297
slouken@2873
   298
    /* Allow environment override */
slouken@6472
   299
    env = SDL_GetHint(SDL_HINT_VIDEO_X11_XVIDMODE);
slouken@2873
   300
    if (env && !SDL_atoi(env)) {
slouken@6468
   301
#ifdef X11MODES_DEBUG
slouken@6472
   302
        printf("XVidMode disabled due to hint\n");
slouken@6468
   303
#endif
slouken@2873
   304
        return SDL_FALSE;
slouken@2873
   305
    }
slouken@2874
   306
slouken@5408
   307
    if (!SDL_X11_HAVE_XVIDMODE) {
slouken@6468
   308
#ifdef X11MODES_DEBUG
slouken@6468
   309
        printf("XVidMode support not available\n");
slouken@6468
   310
#endif
slouken@5408
   311
        return SDL_FALSE;
slouken@5408
   312
    }
slouken@5408
   313
slouken@2873
   314
    /* Query the extension version */
slouken@2873
   315
    vm_error = -1;
slouken@5408
   316
    if (!XF86VidModeQueryExtension(display, &vm_event, &vm_error)
slouken@5408
   317
        || !XF86VidModeQueryVersion(display, major, minor)) {
slouken@6468
   318
#ifdef X11MODES_DEBUG
slouken@6468
   319
        printf("XVidMode not active on the display\n");
slouken@6468
   320
#endif
slouken@2873
   321
        return SDL_FALSE;
slouken@2873
   322
    }
slouken@6468
   323
#ifdef X11MODES_DEBUG
slouken@6548
   324
    printf("XVidMode available at version %d.%d!\n", *major, *minor);
slouken@6468
   325
#endif
slouken@2873
   326
    return SDL_TRUE;
slouken@2873
   327
}
slouken@2873
   328
slouken@4518
   329
static
slouken@5408
   330
Bool XF86VidModeGetModeInfo(Display * dpy, int scr,
slouken@5408
   331
                                       XF86VidModeModeInfo* info)
slouken@2873
   332
{
slouken@2873
   333
    Bool retval;
slouken@2873
   334
    int dotclock;
slouken@5408
   335
    XF86VidModeModeLine l;
slouken@2873
   336
    SDL_zerop(info);
slouken@2873
   337
    SDL_zero(l);
slouken@5408
   338
    retval = XF86VidModeGetModeLine(dpy, scr, &dotclock, &l);
slouken@2873
   339
    info->dotclock = dotclock;
slouken@2873
   340
    info->hdisplay = l.hdisplay;
slouken@2873
   341
    info->hsyncstart = l.hsyncstart;
slouken@2873
   342
    info->hsyncend = l.hsyncend;
slouken@2873
   343
    info->htotal = l.htotal;
slouken@2873
   344
    info->hskew = l.hskew;
slouken@2873
   345
    info->vdisplay = l.vdisplay;
slouken@2873
   346
    info->vsyncstart = l.vsyncstart;
slouken@2873
   347
    info->vsyncend = l.vsyncend;
slouken@2873
   348
    info->vtotal = l.vtotal;
slouken@2873
   349
    info->flags = l.flags;
slouken@2873
   350
    info->privsize = l.privsize;
slouken@2873
   351
    info->private = l.private;
slouken@2873
   352
    return retval;
slouken@2873
   353
}
slouken@2873
   354
slouken@2873
   355
static int
slouken@6548
   356
CalculateXVidModeRefreshRate(const XF86VidModeModeInfo * info)
slouken@2873
   357
{
slouken@2874
   358
    return (info->htotal
slouken@2874
   359
            && info->vtotal) ? (1000 * info->dotclock / (info->htotal *
slouken@2874
   360
                                                         info->vtotal)) : 0;
slouken@2873
   361
}
slouken@2873
   362
slouken@6548
   363
SDL_bool
slouken@6548
   364
SetXVidModeModeInfo(const XF86VidModeModeInfo *info, SDL_DisplayMode *mode)
slouken@2873
   365
{
slouken@6548
   366
    mode->w = info->hdisplay;
slouken@6548
   367
    mode->h = info->vdisplay;
slouken@6548
   368
    mode->refresh_rate = CalculateXVidModeRefreshRate(info);
slouken@6548
   369
    ((SDL_DisplayModeData*)mode->driverdata)->vm_mode = *info;
slouken@6548
   370
    return SDL_TRUE;
slouken@2873
   371
}
slouken@6548
   372
#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
slouken@2873
   373
slouken@6548
   374
int
slouken@6548
   375
X11_InitModes(_THIS)
slouken@2873
   376
{
slouken@6548
   377
    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
slouken@6548
   378
    int screen, screencount;
slouken@6548
   379
#if SDL_VIDEO_DRIVER_X11_XINERAMA
slouken@6548
   380
    int xinerama_major, xinerama_minor;
slouken@6548
   381
    int use_xinerama = 0;
slouken@6548
   382
    XineramaScreenInfo *xinerama = NULL;
slouken@6548
   383
#endif
slouken@6548
   384
#if SDL_VIDEO_DRIVER_X11_XRANDR
slouken@6548
   385
    int xrandr_major, xrandr_minor;
slouken@6548
   386
    int use_xrandr = 0;
slouken@6548
   387
    XRRScreenResources *res = NULL;
slouken@6548
   388
#endif
slouken@6548
   389
#if SDL_VIDEO_DRIVER_X11_XVIDMODE
slouken@6548
   390
    int vm_major, vm_minor;
slouken@6548
   391
    int use_vidmode = 0;
slouken@6548
   392
#endif
slouken@2873
   393
slouken@6548
   394
#if SDL_VIDEO_DRIVER_X11_XINERAMA
slouken@6548
   395
    /* Query Xinerama extention
slouken@6548
   396
     * NOTE: This works with Nvidia Twinview correctly, but you need version 302.17 (released on June 2012)
slouken@6548
   397
     *       or newer of the Nvidia binary drivers
slouken@6548
   398
     */
slouken@6548
   399
    if (CheckXinerama(data->display, &xinerama_major, &xinerama_minor)) {
slouken@6548
   400
        xinerama = XineramaQueryScreens(data->display, &screencount);
slouken@6548
   401
        if (xinerama) {
slouken@6548
   402
            use_xinerama = xinerama_major * 100 + xinerama_minor;
slouken@2873
   403
        }
slouken@2873
   404
    }
slouken@6548
   405
    if (!xinerama) {
slouken@6548
   406
        screencount = ScreenCount(data->display);
slouken@2873
   407
    }
slouken@6548
   408
#else
slouken@6548
   409
    screencount = ScreenCount(data->display);
slouken@6548
   410
#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
slouken@6548
   411
slouken@6548
   412
#if SDL_VIDEO_DRIVER_X11_XRANDR
slouken@6548
   413
    /* require at least XRandR v1.2 */
slouken@6548
   414
    if (CheckXRandR(data->display, &xrandr_major, &xrandr_minor) &&
slouken@6548
   415
        (xrandr_major >= 2 || (xrandr_major == 1 && xrandr_minor >= 2))) {
slouken@6548
   416
        use_xrandr = xrandr_major * 100 + xrandr_minor;
slouken@6548
   417
    }
slouken@6548
   418
#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
slouken@6548
   419
slouken@6548
   420
#if SDL_VIDEO_DRIVER_X11_XVIDMODE
slouken@6548
   421
    if (CheckVidMode(data->display, &vm_major, &vm_minor)) {
slouken@6548
   422
        use_vidmode = vm_major * 100 + vm_minor;
slouken@6548
   423
    }
slouken@6548
   424
#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
slouken@6548
   425
slouken@6548
   426
    for (screen = 0; screen < screencount; ++screen) {
slouken@6548
   427
        XVisualInfo vinfo;
slouken@6548
   428
        SDL_VideoDisplay display;
slouken@6548
   429
        SDL_DisplayData *displaydata;
slouken@6548
   430
        SDL_DisplayMode mode;
slouken@6548
   431
        SDL_DisplayModeData *modedata;
slouken@6548
   432
        XPixmapFormatValues *pixmapFormats;
slouken@6796
   433
        char display_name[128];
slouken@6548
   434
        int i, n;
slouken@6548
   435
slouken@6548
   436
#if SDL_VIDEO_DRIVER_X11_XINERAMA
slouken@6548
   437
        if (xinerama) {
slouken@6548
   438
            if (get_visualinfo(data->display, 0, &vinfo) < 0) {
slouken@6548
   439
                continue;
slouken@6548
   440
            }
slouken@6548
   441
        } else {
slouken@6548
   442
            if (get_visualinfo(data->display, screen, &vinfo) < 0) {
slouken@6548
   443
                continue;
slouken@6548
   444
            }
slouken@6548
   445
        }
slouken@6548
   446
#else
slouken@6548
   447
        if (get_visualinfo(data->display, screen, &vinfo) < 0) {
slouken@6548
   448
            continue;
slouken@6548
   449
        }
slouken@6548
   450
#endif
slouken@6548
   451
slouken@6548
   452
        displaydata = (SDL_DisplayData *) SDL_calloc(1, sizeof(*displaydata));
slouken@6548
   453
        if (!displaydata) {
slouken@6548
   454
            continue;
slouken@6548
   455
        }
slouken@6796
   456
        display_name[0] = '\0';
slouken@6548
   457
slouken@6548
   458
        mode.format = X11_GetPixelFormatFromVisualInfo(data->display, &vinfo);
slouken@6548
   459
        if (SDL_ISPIXELFORMAT_INDEXED(mode.format)) {
slouken@6548
   460
            /* We don't support palettized modes now */
slouken@6548
   461
            SDL_free(displaydata);
slouken@6548
   462
            continue;
slouken@6548
   463
        }
slouken@6548
   464
#if SDL_VIDEO_DRIVER_X11_XINERAMA
slouken@6548
   465
        if (xinerama) {
slouken@6548
   466
            mode.w = xinerama[screen].width;
slouken@6548
   467
            mode.h = xinerama[screen].height;
slouken@6548
   468
        } else {
slouken@6548
   469
            mode.w = DisplayWidth(data->display, screen);
slouken@6548
   470
            mode.h = DisplayHeight(data->display, screen);
slouken@6548
   471
        }
slouken@6548
   472
#else
slouken@6548
   473
        mode.w = DisplayWidth(data->display, screen);
slouken@6548
   474
        mode.h = DisplayHeight(data->display, screen);
slouken@6548
   475
#endif
slouken@6548
   476
        mode.refresh_rate = 0;
slouken@6548
   477
slouken@6548
   478
        modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
slouken@6548
   479
        if (!modedata) {
slouken@6548
   480
            SDL_free(displaydata);
slouken@6548
   481
            continue;
slouken@6548
   482
        }
slouken@6548
   483
        mode.driverdata = modedata;
slouken@6548
   484
slouken@6548
   485
#if SDL_VIDEO_DRIVER_X11_XINERAMA
slouken@6548
   486
        /* Most of SDL's calls to X11 are unwaware of Xinerama, and to X11 standard calls, when Xinerama is active,
slouken@6548
   487
         * there's only one screen available. So we force the screen number to zero and
slouken@6548
   488
         * let Xinerama specific code handle specific functionality using displaydata->xinerama_info
slouken@6548
   489
         */
slouken@6548
   490
        if (use_xinerama) {
slouken@6548
   491
            displaydata->screen = 0;
slouken@6548
   492
            displaydata->use_xinerama = use_xinerama;
slouken@6548
   493
            displaydata->xinerama_info = xinerama[screen];
slouken@6548
   494
            displaydata->xinerama_screen = screen;
slouken@6548
   495
        }
slouken@6548
   496
        else displaydata->screen = screen;
slouken@6548
   497
#else
slouken@6548
   498
        displaydata->screen = screen;
slouken@6548
   499
#endif
slouken@6548
   500
        displaydata->visual = vinfo.visual;
slouken@6548
   501
        displaydata->depth = vinfo.depth;
slouken@6548
   502
slouken@6548
   503
        displaydata->scanline_pad = SDL_BYTESPERPIXEL(mode.format) * 8;
slouken@6548
   504
        pixmapFormats = XListPixmapFormats(data->display, &n);
slouken@6548
   505
        if (pixmapFormats) {
slouken@6548
   506
            for (i = 0; i < n; ++i) {
slouken@6548
   507
                if (pixmapFormats[i].depth == displaydata->depth) {
slouken@6548
   508
                    displaydata->scanline_pad = pixmapFormats[i].scanline_pad;
slouken@6548
   509
                    break;
slouken@6548
   510
                }
slouken@6548
   511
            }
slouken@6548
   512
            XFree(pixmapFormats);
slouken@6548
   513
        }
slouken@6548
   514
slouken@6548
   515
#if SDL_VIDEO_DRIVER_X11_XINERAMA
slouken@6548
   516
        if (use_xinerama) {
slouken@6548
   517
            displaydata->x = xinerama[screen].x_org;
slouken@6548
   518
            displaydata->y = xinerama[screen].y_org;
slouken@6548
   519
        }
slouken@6548
   520
        else
slouken@6548
   521
#endif
slouken@6548
   522
        {
slouken@6548
   523
            displaydata->x = 0;
slouken@6548
   524
            displaydata->y = 0;
slouken@6548
   525
        }
slouken@6548
   526
slouken@6548
   527
#if SDL_VIDEO_DRIVER_X11_XRANDR
slouken@6548
   528
        if (use_xrandr) {
slouken@6548
   529
            res = XRRGetScreenResources(data->display, RootWindow(data->display, displaydata->screen));
slouken@6548
   530
        }
slouken@6548
   531
        if (res) {
slouken@6548
   532
            XRROutputInfo *output_info;
slouken@6548
   533
            XRRCrtcInfo *crtc;
slouken@6548
   534
            int output;
slouken@6796
   535
            Atom EDID = XInternAtom(data->display, "EDID", False);
slouken@6796
   536
            Atom *props;
slouken@6796
   537
            int nprop;
slouken@6796
   538
            unsigned long width_mm;
slouken@6796
   539
            unsigned long height_mm;
slouken@6796
   540
            int inches = 0;
slouken@6548
   541
slouken@6548
   542
            for (output = 0; output < res->noutput; output++) {
slouken@6548
   543
                output_info = XRRGetOutputInfo(data->display, res, res->outputs[output]);
slouken@6550
   544
                if (!output_info || !output_info->crtc ||
slouken@6550
   545
                    output_info->connection == RR_Disconnected) {
slouken@6548
   546
                    XRRFreeOutputInfo(output_info);
slouken@6548
   547
                    continue;
slouken@6548
   548
                }
slouken@6548
   549
slouken@6548
   550
                /* Is this the output that corresponds to the current screen?
slouken@6548
   551
                   We're checking the crtc position, but that may not be a valid test
slouken@6548
   552
                   in all cases.  Anybody want to give this some love?
slouken@6548
   553
                 */
slouken@6548
   554
                crtc = XRRGetCrtcInfo(data->display, res, output_info->crtc);
slouken@6548
   555
                if (!crtc || crtc->x != displaydata->x || crtc->y != displaydata->y) {
slouken@6548
   556
                    XRRFreeOutputInfo(output_info);
slouken@6548
   557
                    XRRFreeCrtcInfo(crtc);
slouken@6548
   558
                    continue;
slouken@6548
   559
                }
slouken@6548
   560
slouken@6548
   561
                displaydata->use_xrandr = use_xrandr;
slouken@6548
   562
                displaydata->xrandr_output = res->outputs[output];
slouken@6548
   563
                SetXRandRModeInfo(data->display, res, output_info, crtc->mode, &mode);
slouken@6548
   564
slouken@6796
   565
                /* Get the name of this display */
slouken@6796
   566
                width_mm = output_info->mm_width;
slouken@6796
   567
                height_mm = output_info->mm_height;
slouken@6796
   568
                inches = (int)((sqrt(width_mm * width_mm +
slouken@6796
   569
                                     height_mm * height_mm) / 25.4f) + 0.5f);
slouken@6796
   570
                SDL_strlcpy(display_name, output_info->name, sizeof(display_name));
slouken@6796
   571
slouken@6796
   572
                /* See if we can get the EDID data for the real monitor name */
slouken@6796
   573
                props = XRRListOutputProperties(data->display, res->outputs[output], &nprop);
slouken@6796
   574
                for (i = 0; i < nprop; ++i) {
slouken@6796
   575
                    unsigned char *prop;
slouken@6796
   576
                    int actual_format;
slouken@6796
   577
                    unsigned long nitems, bytes_after;
slouken@6796
   578
                    Atom actual_type;
slouken@6940
   579
slouken@7191
   580
                    if (props[i] == EDID) {
slouken@6940
   581
                        if (XRRGetOutputProperty(data->display,
slouken@6940
   582
                                                 res->outputs[output], props[i],
slouken@6940
   583
                                                 0, 100, False, False,
slouken@6940
   584
                                                 AnyPropertyType,
slouken@6940
   585
                                                 &actual_type, &actual_format,
slouken@6940
   586
                                                 &nitems, &bytes_after, &prop) == Success ) {
slouken@6940
   587
                            MonitorInfo *info = decode_edid(prop);
slouken@6940
   588
                            if (info) {
slouken@6940
   589
    #ifdef X11MODES_DEBUG
slouken@6940
   590
                                printf("Found EDID data for %s\n", output_info->name);
slouken@6940
   591
                                dump_monitor_info(info);
slouken@6940
   592
    #endif
slouken@6940
   593
                                SDL_strlcpy(display_name, info->dsc_product_name, sizeof(display_name));
slouken@6940
   594
                                free(info);
slouken@6940
   595
                            }
gabomdq@6941
   596
                            XFree(prop);
slouken@6796
   597
                        }
slouken@6796
   598
                        break;
slouken@6796
   599
                    }
slouken@6796
   600
                }
slouken@6940
   601
                if (props) {
gabomdq@6941
   602
                    XFree(props);
slouken@6940
   603
                }
slouken@6796
   604
slouken@6796
   605
                if (*display_name && inches) {
slouken@6796
   606
                    size_t len = SDL_strlen(display_name);
slouken@6796
   607
                    SDL_snprintf(&display_name[len], sizeof(display_name)-len, " %d\"", inches);
slouken@6796
   608
                }
slouken@6796
   609
#ifdef X11MODES_DEBUG
slouken@6796
   610
                printf("Display name: %s\n", display_name);
slouken@6796
   611
#endif
slouken@6796
   612
slouken@6548
   613
                XRRFreeOutputInfo(output_info);
slouken@6548
   614
                XRRFreeCrtcInfo(crtc);
slouken@6548
   615
                break;
slouken@6548
   616
            }
slouken@6548
   617
#ifdef X11MODES_DEBUG
slouken@6548
   618
            if (output == res->noutput) {
slouken@6548
   619
                printf("Couldn't find XRandR CRTC at %d,%d\n", displaydata->x, displaydata->y);
slouken@6548
   620
            }
slouken@6548
   621
#endif
slouken@6548
   622
            XRRFreeScreenResources(res);
slouken@6548
   623
        }
slouken@6548
   624
#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
slouken@6548
   625
slouken@6548
   626
#if SDL_VIDEO_DRIVER_X11_XVIDMODE
slouken@6548
   627
        if (!displaydata->use_xrandr &&
slouken@6548
   628
#if SDL_VIDEO_DRIVER_X11_XINERAMA
slouken@6564
   629
            /* XVidMode only works on the screen at the origin */
slouken@6564
   630
            (!displaydata->use_xinerama ||
slouken@6564
   631
             (displaydata->x == 0 && displaydata->y == 0)) &&
slouken@6548
   632
#endif
slouken@6548
   633
            use_vidmode) {
slouken@6548
   634
            displaydata->use_vidmode = use_vidmode;
slouken@6565
   635
            if (displaydata->use_xinerama) {
slouken@6565
   636
                displaydata->vidmode_screen = 0;
slouken@6565
   637
            } else {
slouken@6565
   638
                displaydata->vidmode_screen = screen;
slouken@6565
   639
            }
slouken@6565
   640
            XF86VidModeGetModeInfo(data->display, displaydata->vidmode_screen, &modedata->vm_mode);
slouken@6548
   641
        }
slouken@6548
   642
#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
slouken@6548
   643
slouken@6548
   644
        SDL_zero(display);
slouken@6796
   645
        if (*display_name) {
slouken@6796
   646
            display.name = display_name;
slouken@6796
   647
        }
slouken@6548
   648
        display.desktop_mode = mode;
slouken@6548
   649
        display.current_mode = mode;
slouken@6548
   650
        display.driverdata = displaydata;
slouken@6548
   651
        SDL_AddVideoDisplay(&display);
slouken@6548
   652
    }
slouken@6548
   653
slouken@6548
   654
#if SDL_VIDEO_DRIVER_X11_XINERAMA
slouken@6548
   655
    if (xinerama) XFree(xinerama);
slouken@6548
   656
#endif
slouken@6548
   657
slouken@6548
   658
    if (_this->num_displays == 0) {
icculus@7037
   659
        return SDL_SetError("No available displays");
slouken@6548
   660
    }
slouken@6548
   661
    return 0;
slouken@2873
   662
}
slouken@2873
   663
slouken@1950
   664
void
slouken@3500
   665
X11_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display)
slouken@1950
   666
{
slouken@2870
   667
    Display *display = ((SDL_VideoData *) _this->driverdata)->display;
slouken@3500
   668
    SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata;
slouken@5408
   669
#if SDL_VIDEO_DRIVER_X11_XVIDMODE
slouken@2873
   670
    int nmodes;
slouken@5408
   671
    XF86VidModeModeInfo ** modes;
slouken@2873
   672
#endif
slouken@2873
   673
    int screen_w;
slouken@2873
   674
    int screen_h;
slouken@1950
   675
    SDL_DisplayMode mode;
slouken@6548
   676
    SDL_DisplayModeData *modedata;
slouken@2870
   677
slouken@2873
   678
    /* Unfortunately X11 requires the window to be created with the correct
slouken@2873
   679
     * visual and depth ahead of time, but the SDL API allows you to create
slouken@2873
   680
     * a window before setting the fullscreen display mode.  This means that
slouken@2873
   681
     * we have to use the same format for all windows and all display modes.
slouken@2873
   682
     * (or support recreating the window with a new visual behind the scenes)
slouken@2873
   683
     */
slouken@3500
   684
    mode.format = sdl_display->current_mode.format;
slouken@2873
   685
    mode.driverdata = NULL;
slouken@2873
   686
slouken@2873
   687
    screen_w = DisplayWidth(display, data->screen);
slouken@2873
   688
    screen_h = DisplayHeight(display, data->screen);
slouken@2873
   689
slouken@2873
   690
#if SDL_VIDEO_DRIVER_X11_XINERAMA
gabomdq@6331
   691
    if (data->use_xinerama) {
david@7361
   692
        if (data->use_vidmode && !data->xinerama_info.x_org && !data->xinerama_info.y_org &&
gabomdq@6331
   693
           (screen_w > data->xinerama_info.width || screen_h > data->xinerama_info.height)) {
david@7361
   694
            /* Add the full (both screens combined) xinerama mode only on the display that starts at 0,0
david@7361
   695
             * if we're using vidmode.
david@7361
   696
             */
gabomdq@6331
   697
            mode.w = screen_w;
gabomdq@6331
   698
            mode.h = screen_h;
slouken@2873
   699
            mode.refresh_rate = 0;
slouken@6548
   700
            modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
slouken@6548
   701
            if (modedata) {
slouken@6548
   702
                *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata;
slouken@6548
   703
            }
slouken@6548
   704
            mode.driverdata = modedata;
slouken@3500
   705
            SDL_AddDisplayMode(sdl_display, &mode);
slouken@2873
   706
        }
david@7431
   707
        else if (!data->use_xrandr)
david@7361
   708
        {
david@7431
   709
            /* Add the current mode of each monitor otherwise if we can't get them from xrandr */
david@7361
   710
            mode.w = data->xinerama_info.width;
david@7361
   711
            mode.h = data->xinerama_info.height;
david@7361
   712
            mode.refresh_rate = 0;
david@7361
   713
            modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
david@7361
   714
            if (modedata) {
david@7361
   715
                *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata;
david@7361
   716
            }
david@7361
   717
            mode.driverdata = modedata;
david@7361
   718
            SDL_AddDisplayMode(sdl_display, &mode);
david@7361
   719
        }
david@7361
   720
slouken@2873
   721
    }
slouken@2873
   722
#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
slouken@2873
   723
slouken@2873
   724
#if SDL_VIDEO_DRIVER_X11_XRANDR
slouken@6548
   725
    if (data->use_xrandr) {
slouken@6548
   726
        XRRScreenResources *res;
slouken@2873
   727
slouken@6548
   728
        res = XRRGetScreenResources (display, RootWindow(display, data->screen));
slouken@6548
   729
        if (res) {
slouken@6548
   730
            SDL_DisplayModeData *modedata;
slouken@6548
   731
            XRROutputInfo *output_info;
slouken@6548
   732
            int i;
slouken@2873
   733
slouken@6548
   734
            output_info = XRRGetOutputInfo(display, res, data->xrandr_output);
slouken@6548
   735
            if (output_info && output_info->connection != RR_Disconnected) {
slouken@6548
   736
                for (i = 0; i < output_info->nmode; ++i) {
slouken@6548
   737
                    modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
slouken@6548
   738
                    if (!modedata) {
slouken@6548
   739
                        continue;
slouken@6548
   740
                    }
slouken@6548
   741
                    mode.driverdata = modedata;
slouken@2873
   742
slouken@6548
   743
                    if (SetXRandRModeInfo(display, res, output_info, output_info->modes[i], &mode)) {
slouken@6548
   744
                        SDL_AddDisplayMode(sdl_display, &mode);
slouken@6548
   745
                    } else {
slouken@6548
   746
                        SDL_free(modedata);
slouken@6548
   747
                    }
slouken@2873
   748
                }
slouken@2873
   749
            }
slouken@6548
   750
            XRRFreeOutputInfo(output_info);
slouken@6548
   751
            XRRFreeScreenResources(res);
slouken@2873
   752
        }
slouken@6548
   753
        return;
slouken@2873
   754
    }
slouken@2873
   755
#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
slouken@2873
   756
slouken@5408
   757
#if SDL_VIDEO_DRIVER_X11_XVIDMODE
slouken@6548
   758
    if (data->use_vidmode &&
slouken@6565
   759
        XF86VidModeGetAllModeLines(display, data->vidmode_screen, &nmodes, &modes)) {
slouken@2873
   760
        int i;
slouken@2873
   761
slouken@2873
   762
#ifdef X11MODES_DEBUG
slouken@2873
   763
        printf("VidMode modes: (unsorted)\n");
slouken@2873
   764
        for (i = 0; i < nmodes; ++i) {
slouken@6566
   765
            printf("Mode %d: %d x %d @ %d, flags: 0x%x\n", i,
slouken@2874
   766
                   modes[i]->hdisplay, modes[i]->vdisplay,
slouken@6566
   767
                   CalculateXVidModeRefreshRate(modes[i]), modes[i]->flags);
slouken@2873
   768
        }
slouken@2873
   769
#endif
slouken@2873
   770
        for (i = 0; i < nmodes; ++i) {
slouken@6548
   771
            modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
slouken@6548
   772
            if (!modedata) {
slouken@6548
   773
                continue;
slouken@6548
   774
            }
slouken@6548
   775
            mode.driverdata = modedata;
slouken@6548
   776
slouken@6548
   777
            if (SetXVidModeModeInfo(modes[i], &mode)) {
slouken@6548
   778
                SDL_AddDisplayMode(sdl_display, &mode);
slouken@6548
   779
            } else {
slouken@6548
   780
                SDL_free(modedata);
slouken@6548
   781
            }
slouken@2873
   782
        }
slouken@2873
   783
        XFree(modes);
slouken@6548
   784
        return;
slouken@2873
   785
    }
slouken@5408
   786
#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
slouken@2873
   787
slouken@2873
   788
    if (!data->use_xrandr && !data->use_vidmode) {
slouken@6548
   789
        /* Add the desktop mode */
slouken@6548
   790
        mode = sdl_display->desktop_mode;
slouken@6548
   791
        modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
slouken@6548
   792
        if (modedata) {
slouken@6548
   793
            *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata;
slouken@6548
   794
        }
slouken@6548
   795
        mode.driverdata = modedata;
slouken@3500
   796
        SDL_AddDisplayMode(sdl_display, &mode);
slouken@2874
   797
    }
slouken@1950
   798
}
slouken@1950
   799
slouken@1950
   800
int
slouken@3500
   801
X11_SetDisplayMode(_THIS, SDL_VideoDisplay * sdl_display, SDL_DisplayMode * mode)
slouken@1950
   802
{
slouken@2873
   803
    Display *display = ((SDL_VideoData *) _this->driverdata)->display;
slouken@3500
   804
    SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata;
slouken@6548
   805
    SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata;
slouken@2873
   806
slouken@6548
   807
#if SDL_VIDEO_DRIVER_X11_XRANDR
slouken@6548
   808
    if (data->use_xrandr) {
slouken@6548
   809
        XRRScreenResources *res;
slouken@6548
   810
        XRROutputInfo *output_info;
slouken@6548
   811
        XRRCrtcInfo *crtc;
slouken@6548
   812
        Status status;
slouken@6548
   813
slouken@6548
   814
        res = XRRGetScreenResources (display, RootWindow(display, data->screen));
slouken@6548
   815
        if (!res) {
icculus@7037
   816
            return SDL_SetError("Couldn't get XRandR screen resources");
slouken@6548
   817
        }
slouken@6548
   818
slouken@6548
   819
        output_info = XRRGetOutputInfo(display, res, data->xrandr_output);
slouken@6548
   820
        if (!output_info || output_info->connection == RR_Disconnected) {
slouken@6548
   821
            XRRFreeScreenResources(res);
icculus@7037
   822
            return SDL_SetError("Couldn't get XRandR output info");
slouken@6548
   823
        }
slouken@6548
   824
slouken@6548
   825
        crtc = XRRGetCrtcInfo(display, res, output_info->crtc);
slouken@6548
   826
        if (!crtc) {
slouken@6548
   827
            XRRFreeOutputInfo(output_info);
slouken@6548
   828
            XRRFreeScreenResources(res);
icculus@7037
   829
            return SDL_SetError("Couldn't get XRandR crtc info");
slouken@6548
   830
        }
slouken@6548
   831
slouken@6548
   832
        status = XRRSetCrtcConfig (display, res, output_info->crtc, CurrentTime,
slouken@6548
   833
          crtc->x, crtc->y, modedata->xrandr_mode, crtc->rotation,
slouken@6548
   834
          &data->xrandr_output, 1);
slouken@6548
   835
slouken@6548
   836
        XRRFreeCrtcInfo(crtc);
slouken@6548
   837
        XRRFreeOutputInfo(output_info);
slouken@6548
   838
        XRRFreeScreenResources(res);
slouken@6548
   839
slouken@6548
   840
        if (status != Success) {
icculus@7037
   841
            return SDL_SetError("XRRSetCrtcConfig failed");
slouken@6548
   842
        }
slouken@6548
   843
    }
slouken@6548
   844
#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
slouken@6548
   845
slouken@6548
   846
#if SDL_VIDEO_DRIVER_X11_XVIDMODE
slouken@6548
   847
    if (data->use_vidmode) {
slouken@6565
   848
        XF86VidModeSwitchToMode(display, data->vidmode_screen, &modedata->vm_mode);
slouken@6548
   849
    }
slouken@6548
   850
#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
slouken@6548
   851
slouken@2873
   852
    return 0;
slouken@1950
   853
}
slouken@1950
   854
slouken@1950
   855
void
slouken@1950
   856
X11_QuitModes(_THIS)
slouken@1950
   857
{
slouken@1950
   858
}
slouken@1950
   859
gabomdq@6331
   860
int
gabomdq@6331
   861
X11_GetDisplayBounds(_THIS, SDL_VideoDisplay * sdl_display, SDL_Rect * rect)
gabomdq@6331
   862
{
gabomdq@6331
   863
    SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata;
slouken@6502
   864
slouken@6548
   865
    rect->x = data->x;
slouken@6548
   866
    rect->y = data->y;
slouken@6548
   867
    rect->w = sdl_display->current_mode.w;
slouken@6548
   868
    rect->h = sdl_display->current_mode.h;
gabomdq@6331
   869
gabomdq@6331
   870
#if SDL_VIDEO_DRIVER_X11_XINERAMA
slouken@6548
   871
    /* Get the real current bounds of the display */
slouken@6502
   872
    if (data->use_xinerama) {
icculus@7485
   873
        Display *display = ((SDL_VideoData *) _this->driverdata)->display;
slouken@6548
   874
        int screencount;
slouken@6548
   875
        XineramaScreenInfo *xinerama = XineramaQueryScreens(display, &screencount);
slouken@6548
   876
        if (xinerama) {
slouken@6548
   877
            rect->x = xinerama[data->xinerama_screen].x_org;
slouken@6548
   878
            rect->y = xinerama[data->xinerama_screen].y_org;
gabomdq@6906
   879
            XFree(xinerama);
slouken@6548
   880
        }
gabomdq@6331
   881
    }
slouken@6548
   882
#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
slouken@6475
   883
    return 0;
gabomdq@6331
   884
}
gabomdq@6331
   885
slouken@5481
   886
#endif /* SDL_VIDEO_DRIVER_X11 */
slouken@5481
   887
slouken@1950
   888
/* vi: set ts=4 sw=4 expandtab: */