src/video/x11/SDL_x11modes.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 08 Nov 2013 14:04:35 -0800
changeset 7914 a391318fa60f
parent 7827 a03ec8de0426
child 8093 b43765095a6f
permissions -rw-r--r--
Fixed spot where SDL was assuming that two displays having the same origin means they're the same display. Changed it to check for the same extents instead.

(Sam actually wrote this, I'm just reviewing and checking it in.)
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);
icculus@7827
    57
        vi = X11_XGetVisualInfo(display, VisualIDMask, &template, &nvis);
slouken@1950
    58
        if (vi) {
slouken@1950
    59
            *vinfo = *vi;
icculus@7827
    60
            X11_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() &&
icculus@7827
    67
         X11_XMatchVisualInfo(display, screen, depth, DirectColor, vinfo)) ||
icculus@7827
    68
        X11_XMatchVisualInfo(display, screen, depth, TrueColor, vinfo) ||
icculus@7827
    69
        X11_XMatchVisualInfo(display, screen, depth, PseudoColor, vinfo) ||
icculus@7827
    70
        X11_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
icculus@7827
    82
    vinfo->visualid = X11_XVisualIDFromVisual(visual);
icculus@7827
    83
    vi = X11_XGetVisualInfo(display, VisualIDMask, vinfo, &nvis);
slouken@5182
    84
    if (vi) {
slouken@5182
    85
        *vinfo = *vi;
icculus@7827
    86
        X11_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;
icculus@7827
   111
            XPixmapFormatValues *p = X11_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
                }
icculus@7827
   119
                X11_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@7827
   181
    if (!X11_XineramaQueryExtension(display, &event_base, &error_base) ||
icculus@7827
   182
        !X11_XineramaQueryVersion(display, major, minor) ||
icculus@7827
   183
        !X11_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 */
icculus@7827
   231
    if (!X11_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
icculus@7827
   264
            crtc = X11_XRRGetCrtcInfo(display, res, output_info->crtc);
slouken@6548
   265
            if (crtc) {
slouken@6548
   266
                rotation = crtc->rotation;
icculus@7827
   267
                X11_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;
icculus@7827
   316
    if (!X11_XF86VidModeQueryExtension(display, &vm_event, &vm_error)
icculus@7827
   317
        || !X11_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);
icculus@7827
   338
    retval = X11_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)) {
icculus@7827
   400
        xinerama = X11_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;
icculus@7827
   504
        pixmapFormats = X11_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
            }
icculus@7827
   512
            X11_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) {
icculus@7827
   529
            res = X11_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;
icculus@7827
   535
            Atom EDID = X11_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++) {
icculus@7827
   543
                output_info = X11_XRRGetOutputInfo(data->display, res, res->outputs[output]);
slouken@6550
   544
                if (!output_info || !output_info->crtc ||
slouken@6550
   545
                    output_info->connection == RR_Disconnected) {
icculus@7827
   546
                    X11_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
                 */
icculus@7827
   554
                crtc = X11_XRRGetCrtcInfo(data->display, res, output_info->crtc);
slouken@7914
   555
                if (!crtc || crtc->x != displaydata->x || crtc->y != displaydata->y ||
slouken@7914
   556
                    crtc->width != mode.w || crtc->height != mode.h) {
icculus@7827
   557
                    X11_XRRFreeOutputInfo(output_info);
icculus@7827
   558
                    X11_XRRFreeCrtcInfo(crtc);
slouken@6548
   559
                    continue;
slouken@6548
   560
                }
slouken@6548
   561
slouken@6548
   562
                displaydata->use_xrandr = use_xrandr;
slouken@6548
   563
                displaydata->xrandr_output = res->outputs[output];
slouken@6548
   564
                SetXRandRModeInfo(data->display, res, output_info, crtc->mode, &mode);
slouken@6548
   565
slouken@6796
   566
                /* Get the name of this display */
slouken@6796
   567
                width_mm = output_info->mm_width;
slouken@6796
   568
                height_mm = output_info->mm_height;
slouken@6796
   569
                inches = (int)((sqrt(width_mm * width_mm +
slouken@6796
   570
                                     height_mm * height_mm) / 25.4f) + 0.5f);
slouken@6796
   571
                SDL_strlcpy(display_name, output_info->name, sizeof(display_name));
slouken@6796
   572
slouken@6796
   573
                /* See if we can get the EDID data for the real monitor name */
icculus@7827
   574
                props = X11_XRRListOutputProperties(data->display, res->outputs[output], &nprop);
slouken@6796
   575
                for (i = 0; i < nprop; ++i) {
slouken@6796
   576
                    unsigned char *prop;
slouken@6796
   577
                    int actual_format;
slouken@6796
   578
                    unsigned long nitems, bytes_after;
slouken@6796
   579
                    Atom actual_type;
slouken@6940
   580
slouken@7191
   581
                    if (props[i] == EDID) {
icculus@7827
   582
                        if (X11_XRRGetOutputProperty(data->display,
slouken@6940
   583
                                                 res->outputs[output], props[i],
slouken@6940
   584
                                                 0, 100, False, False,
slouken@6940
   585
                                                 AnyPropertyType,
slouken@6940
   586
                                                 &actual_type, &actual_format,
slouken@6940
   587
                                                 &nitems, &bytes_after, &prop) == Success ) {
slouken@6940
   588
                            MonitorInfo *info = decode_edid(prop);
slouken@6940
   589
                            if (info) {
slouken@6940
   590
    #ifdef X11MODES_DEBUG
slouken@6940
   591
                                printf("Found EDID data for %s\n", output_info->name);
slouken@6940
   592
                                dump_monitor_info(info);
slouken@6940
   593
    #endif
slouken@6940
   594
                                SDL_strlcpy(display_name, info->dsc_product_name, sizeof(display_name));
slouken@6940
   595
                                free(info);
slouken@6940
   596
                            }
icculus@7827
   597
                            X11_XFree(prop);
slouken@6796
   598
                        }
slouken@6796
   599
                        break;
slouken@6796
   600
                    }
slouken@6796
   601
                }
slouken@6940
   602
                if (props) {
icculus@7827
   603
                    X11_XFree(props);
slouken@6940
   604
                }
slouken@6796
   605
slouken@6796
   606
                if (*display_name && inches) {
slouken@6796
   607
                    size_t len = SDL_strlen(display_name);
slouken@6796
   608
                    SDL_snprintf(&display_name[len], sizeof(display_name)-len, " %d\"", inches);
slouken@6796
   609
                }
slouken@6796
   610
#ifdef X11MODES_DEBUG
slouken@6796
   611
                printf("Display name: %s\n", display_name);
slouken@6796
   612
#endif
slouken@6796
   613
icculus@7827
   614
                X11_XRRFreeOutputInfo(output_info);
icculus@7827
   615
                X11_XRRFreeCrtcInfo(crtc);
slouken@6548
   616
                break;
slouken@6548
   617
            }
slouken@6548
   618
#ifdef X11MODES_DEBUG
slouken@6548
   619
            if (output == res->noutput) {
slouken@6548
   620
                printf("Couldn't find XRandR CRTC at %d,%d\n", displaydata->x, displaydata->y);
slouken@6548
   621
            }
slouken@6548
   622
#endif
icculus@7827
   623
            X11_XRRFreeScreenResources(res);
slouken@6548
   624
        }
slouken@6548
   625
#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
slouken@6548
   626
slouken@6548
   627
#if SDL_VIDEO_DRIVER_X11_XVIDMODE
slouken@6548
   628
        if (!displaydata->use_xrandr &&
slouken@6548
   629
#if SDL_VIDEO_DRIVER_X11_XINERAMA
slouken@6564
   630
            /* XVidMode only works on the screen at the origin */
slouken@6564
   631
            (!displaydata->use_xinerama ||
slouken@6564
   632
             (displaydata->x == 0 && displaydata->y == 0)) &&
slouken@6548
   633
#endif
slouken@6548
   634
            use_vidmode) {
slouken@6548
   635
            displaydata->use_vidmode = use_vidmode;
slouken@6565
   636
            if (displaydata->use_xinerama) {
slouken@6565
   637
                displaydata->vidmode_screen = 0;
slouken@6565
   638
            } else {
slouken@6565
   639
                displaydata->vidmode_screen = screen;
slouken@6565
   640
            }
slouken@6565
   641
            XF86VidModeGetModeInfo(data->display, displaydata->vidmode_screen, &modedata->vm_mode);
slouken@6548
   642
        }
slouken@6548
   643
#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
slouken@6548
   644
slouken@6548
   645
        SDL_zero(display);
slouken@6796
   646
        if (*display_name) {
slouken@6796
   647
            display.name = display_name;
slouken@6796
   648
        }
slouken@6548
   649
        display.desktop_mode = mode;
slouken@6548
   650
        display.current_mode = mode;
slouken@6548
   651
        display.driverdata = displaydata;
slouken@6548
   652
        SDL_AddVideoDisplay(&display);
slouken@6548
   653
    }
slouken@6548
   654
slouken@6548
   655
#if SDL_VIDEO_DRIVER_X11_XINERAMA
icculus@7827
   656
    if (xinerama) X11_XFree(xinerama);
slouken@6548
   657
#endif
slouken@6548
   658
slouken@6548
   659
    if (_this->num_displays == 0) {
icculus@7037
   660
        return SDL_SetError("No available displays");
slouken@6548
   661
    }
slouken@6548
   662
    return 0;
slouken@2873
   663
}
slouken@2873
   664
slouken@1950
   665
void
slouken@3500
   666
X11_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display)
slouken@1950
   667
{
slouken@2870
   668
    Display *display = ((SDL_VideoData *) _this->driverdata)->display;
slouken@3500
   669
    SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata;
slouken@5408
   670
#if SDL_VIDEO_DRIVER_X11_XVIDMODE
slouken@2873
   671
    int nmodes;
slouken@5408
   672
    XF86VidModeModeInfo ** modes;
slouken@2873
   673
#endif
slouken@2873
   674
    int screen_w;
slouken@2873
   675
    int screen_h;
slouken@1950
   676
    SDL_DisplayMode mode;
slouken@6548
   677
    SDL_DisplayModeData *modedata;
slouken@2870
   678
slouken@2873
   679
    /* Unfortunately X11 requires the window to be created with the correct
slouken@2873
   680
     * visual and depth ahead of time, but the SDL API allows you to create
slouken@2873
   681
     * a window before setting the fullscreen display mode.  This means that
slouken@2873
   682
     * we have to use the same format for all windows and all display modes.
slouken@2873
   683
     * (or support recreating the window with a new visual behind the scenes)
slouken@2873
   684
     */
slouken@3500
   685
    mode.format = sdl_display->current_mode.format;
slouken@2873
   686
    mode.driverdata = NULL;
slouken@2873
   687
slouken@2873
   688
    screen_w = DisplayWidth(display, data->screen);
slouken@2873
   689
    screen_h = DisplayHeight(display, data->screen);
slouken@2873
   690
slouken@2873
   691
#if SDL_VIDEO_DRIVER_X11_XINERAMA
gabomdq@6331
   692
    if (data->use_xinerama) {
david@7361
   693
        if (data->use_vidmode && !data->xinerama_info.x_org && !data->xinerama_info.y_org &&
gabomdq@6331
   694
           (screen_w > data->xinerama_info.width || screen_h > data->xinerama_info.height)) {
david@7361
   695
            /* Add the full (both screens combined) xinerama mode only on the display that starts at 0,0
david@7361
   696
             * if we're using vidmode.
david@7361
   697
             */
gabomdq@6331
   698
            mode.w = screen_w;
gabomdq@6331
   699
            mode.h = screen_h;
slouken@2873
   700
            mode.refresh_rate = 0;
slouken@6548
   701
            modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
slouken@6548
   702
            if (modedata) {
slouken@6548
   703
                *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata;
slouken@6548
   704
            }
slouken@6548
   705
            mode.driverdata = modedata;
slouken@3500
   706
            SDL_AddDisplayMode(sdl_display, &mode);
slouken@2873
   707
        }
david@7431
   708
        else if (!data->use_xrandr)
david@7361
   709
        {
david@7431
   710
            /* Add the current mode of each monitor otherwise if we can't get them from xrandr */
david@7361
   711
            mode.w = data->xinerama_info.width;
david@7361
   712
            mode.h = data->xinerama_info.height;
david@7361
   713
            mode.refresh_rate = 0;
david@7361
   714
            modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
david@7361
   715
            if (modedata) {
david@7361
   716
                *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata;
david@7361
   717
            }
david@7361
   718
            mode.driverdata = modedata;
david@7361
   719
            SDL_AddDisplayMode(sdl_display, &mode);
david@7361
   720
        }
david@7361
   721
slouken@2873
   722
    }
slouken@2873
   723
#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
slouken@2873
   724
slouken@2873
   725
#if SDL_VIDEO_DRIVER_X11_XRANDR
slouken@6548
   726
    if (data->use_xrandr) {
slouken@6548
   727
        XRRScreenResources *res;
slouken@2873
   728
icculus@7827
   729
        res = X11_XRRGetScreenResources (display, RootWindow(display, data->screen));
slouken@6548
   730
        if (res) {
slouken@6548
   731
            SDL_DisplayModeData *modedata;
slouken@6548
   732
            XRROutputInfo *output_info;
slouken@6548
   733
            int i;
slouken@2873
   734
icculus@7827
   735
            output_info = X11_XRRGetOutputInfo(display, res, data->xrandr_output);
slouken@6548
   736
            if (output_info && output_info->connection != RR_Disconnected) {
slouken@6548
   737
                for (i = 0; i < output_info->nmode; ++i) {
slouken@6548
   738
                    modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
slouken@6548
   739
                    if (!modedata) {
slouken@6548
   740
                        continue;
slouken@6548
   741
                    }
slouken@6548
   742
                    mode.driverdata = modedata;
slouken@2873
   743
slouken@6548
   744
                    if (SetXRandRModeInfo(display, res, output_info, output_info->modes[i], &mode)) {
slouken@6548
   745
                        SDL_AddDisplayMode(sdl_display, &mode);
slouken@6548
   746
                    } else {
slouken@6548
   747
                        SDL_free(modedata);
slouken@6548
   748
                    }
slouken@2873
   749
                }
slouken@2873
   750
            }
icculus@7827
   751
            X11_XRRFreeOutputInfo(output_info);
icculus@7827
   752
            X11_XRRFreeScreenResources(res);
slouken@2873
   753
        }
slouken@6548
   754
        return;
slouken@2873
   755
    }
slouken@2873
   756
#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
slouken@2873
   757
slouken@5408
   758
#if SDL_VIDEO_DRIVER_X11_XVIDMODE
slouken@6548
   759
    if (data->use_vidmode &&
icculus@7827
   760
        X11_XF86VidModeGetAllModeLines(display, data->vidmode_screen, &nmodes, &modes)) {
slouken@2873
   761
        int i;
slouken@2873
   762
slouken@2873
   763
#ifdef X11MODES_DEBUG
slouken@2873
   764
        printf("VidMode modes: (unsorted)\n");
slouken@2873
   765
        for (i = 0; i < nmodes; ++i) {
slouken@6566
   766
            printf("Mode %d: %d x %d @ %d, flags: 0x%x\n", i,
slouken@2874
   767
                   modes[i]->hdisplay, modes[i]->vdisplay,
slouken@6566
   768
                   CalculateXVidModeRefreshRate(modes[i]), modes[i]->flags);
slouken@2873
   769
        }
slouken@2873
   770
#endif
slouken@2873
   771
        for (i = 0; i < nmodes; ++i) {
slouken@6548
   772
            modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
slouken@6548
   773
            if (!modedata) {
slouken@6548
   774
                continue;
slouken@6548
   775
            }
slouken@6548
   776
            mode.driverdata = modedata;
slouken@6548
   777
slouken@6548
   778
            if (SetXVidModeModeInfo(modes[i], &mode)) {
slouken@6548
   779
                SDL_AddDisplayMode(sdl_display, &mode);
slouken@6548
   780
            } else {
slouken@6548
   781
                SDL_free(modedata);
slouken@6548
   782
            }
slouken@2873
   783
        }
icculus@7827
   784
        X11_XFree(modes);
slouken@6548
   785
        return;
slouken@2873
   786
    }
slouken@5408
   787
#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
slouken@2873
   788
slouken@2873
   789
    if (!data->use_xrandr && !data->use_vidmode) {
slouken@6548
   790
        /* Add the desktop mode */
slouken@6548
   791
        mode = sdl_display->desktop_mode;
slouken@6548
   792
        modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
slouken@6548
   793
        if (modedata) {
slouken@6548
   794
            *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata;
slouken@6548
   795
        }
slouken@6548
   796
        mode.driverdata = modedata;
slouken@3500
   797
        SDL_AddDisplayMode(sdl_display, &mode);
slouken@2874
   798
    }
slouken@1950
   799
}
slouken@1950
   800
slouken@1950
   801
int
slouken@3500
   802
X11_SetDisplayMode(_THIS, SDL_VideoDisplay * sdl_display, SDL_DisplayMode * mode)
slouken@1950
   803
{
slouken@2873
   804
    Display *display = ((SDL_VideoData *) _this->driverdata)->display;
slouken@3500
   805
    SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata;
slouken@6548
   806
    SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata;
slouken@2873
   807
slouken@6548
   808
#if SDL_VIDEO_DRIVER_X11_XRANDR
slouken@6548
   809
    if (data->use_xrandr) {
slouken@6548
   810
        XRRScreenResources *res;
slouken@6548
   811
        XRROutputInfo *output_info;
slouken@6548
   812
        XRRCrtcInfo *crtc;
slouken@6548
   813
        Status status;
slouken@6548
   814
icculus@7827
   815
        res = X11_XRRGetScreenResources (display, RootWindow(display, data->screen));
slouken@6548
   816
        if (!res) {
icculus@7037
   817
            return SDL_SetError("Couldn't get XRandR screen resources");
slouken@6548
   818
        }
slouken@6548
   819
icculus@7827
   820
        output_info = X11_XRRGetOutputInfo(display, res, data->xrandr_output);
slouken@6548
   821
        if (!output_info || output_info->connection == RR_Disconnected) {
icculus@7827
   822
            X11_XRRFreeScreenResources(res);
icculus@7037
   823
            return SDL_SetError("Couldn't get XRandR output info");
slouken@6548
   824
        }
slouken@6548
   825
icculus@7827
   826
        crtc = X11_XRRGetCrtcInfo(display, res, output_info->crtc);
slouken@6548
   827
        if (!crtc) {
icculus@7827
   828
            X11_XRRFreeOutputInfo(output_info);
icculus@7827
   829
            X11_XRRFreeScreenResources(res);
icculus@7037
   830
            return SDL_SetError("Couldn't get XRandR crtc info");
slouken@6548
   831
        }
slouken@6548
   832
icculus@7827
   833
        status = X11_XRRSetCrtcConfig (display, res, output_info->crtc, CurrentTime,
slouken@6548
   834
          crtc->x, crtc->y, modedata->xrandr_mode, crtc->rotation,
slouken@6548
   835
          &data->xrandr_output, 1);
slouken@6548
   836
icculus@7827
   837
        X11_XRRFreeCrtcInfo(crtc);
icculus@7827
   838
        X11_XRRFreeOutputInfo(output_info);
icculus@7827
   839
        X11_XRRFreeScreenResources(res);
slouken@6548
   840
slouken@6548
   841
        if (status != Success) {
icculus@7827
   842
            return SDL_SetError("X11_XRRSetCrtcConfig failed");
slouken@6548
   843
        }
slouken@6548
   844
    }
slouken@6548
   845
#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
slouken@6548
   846
slouken@6548
   847
#if SDL_VIDEO_DRIVER_X11_XVIDMODE
slouken@6548
   848
    if (data->use_vidmode) {
icculus@7827
   849
        X11_XF86VidModeSwitchToMode(display, data->vidmode_screen, &modedata->vm_mode);
slouken@6548
   850
    }
slouken@6548
   851
#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
slouken@6548
   852
slouken@2873
   853
    return 0;
slouken@1950
   854
}
slouken@1950
   855
slouken@1950
   856
void
slouken@1950
   857
X11_QuitModes(_THIS)
slouken@1950
   858
{
slouken@1950
   859
}
slouken@1950
   860
gabomdq@6331
   861
int
gabomdq@6331
   862
X11_GetDisplayBounds(_THIS, SDL_VideoDisplay * sdl_display, SDL_Rect * rect)
gabomdq@6331
   863
{
gabomdq@6331
   864
    SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata;
slouken@6502
   865
slouken@6548
   866
    rect->x = data->x;
slouken@6548
   867
    rect->y = data->y;
slouken@6548
   868
    rect->w = sdl_display->current_mode.w;
slouken@6548
   869
    rect->h = sdl_display->current_mode.h;
gabomdq@6331
   870
gabomdq@6331
   871
#if SDL_VIDEO_DRIVER_X11_XINERAMA
slouken@6548
   872
    /* Get the real current bounds of the display */
slouken@6502
   873
    if (data->use_xinerama) {
icculus@7485
   874
        Display *display = ((SDL_VideoData *) _this->driverdata)->display;
slouken@6548
   875
        int screencount;
icculus@7827
   876
        XineramaScreenInfo *xinerama = X11_XineramaQueryScreens(display, &screencount);
slouken@6548
   877
        if (xinerama) {
slouken@6548
   878
            rect->x = xinerama[data->xinerama_screen].x_org;
slouken@6548
   879
            rect->y = xinerama[data->xinerama_screen].y_org;
icculus@7827
   880
            X11_XFree(xinerama);
slouken@6548
   881
        }
gabomdq@6331
   882
    }
slouken@6548
   883
#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
slouken@6475
   884
    return 0;
gabomdq@6331
   885
}
gabomdq@6331
   886
slouken@5481
   887
#endif /* SDL_VIDEO_DRIVER_X11 */
slouken@5481
   888
slouken@1950
   889
/* vi: set ts=4 sw=4 expandtab: */