2 Simple DirectMedia Layer
3 Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
21 #include "SDL_config.h"
23 #if SDL_VIDEO_DRIVER_X11
25 #include "SDL_hints.h"
26 #include "SDL_x11video.h"
29 /*#define X11MODES_DEBUG*/
31 /* I'm becoming more and more convinced that the application should never
32 * use XRandR, and it's the window manager's responsibility to track and
33 * manage display modes for fullscreen windows. Right now XRandR is completely
34 * broken with respect to window manager behavior on every window manager that
35 * I can find. For example, on Unity 3D if you show a fullscreen window while
36 * the resolution is changing (within ~250 ms) your window will retain the
37 * fullscreen state hint but be decorated and windowed.
39 * However, many people swear by it, so let them swear at it. :)
41 /*#define XRANDR_DISABLED_BY_DEFAULT*/
45 get_visualinfo(Display * display, int screen, XVisualInfo * vinfo)
47 const char *visual_id = SDL_getenv("SDL_VIDEO_X11_VISUALID");
50 /* Look for an exact visual, if requested */
52 XVisualInfo *vi, template;
56 template.visualid = SDL_strtol(visual_id, NULL, 0);
57 vi = XGetVisualInfo(display, VisualIDMask, &template, &nvis);
65 depth = DefaultDepth(display, screen);
66 if ((X11_UseDirectColorVisuals() &&
67 XMatchVisualInfo(display, screen, depth, DirectColor, vinfo)) ||
68 XMatchVisualInfo(display, screen, depth, TrueColor, vinfo) ||
69 XMatchVisualInfo(display, screen, depth, PseudoColor, vinfo) ||
70 XMatchVisualInfo(display, screen, depth, StaticColor, vinfo)) {
77 X11_GetVisualInfoFromVisual(Display * display, Visual * visual, XVisualInfo * vinfo)
82 vinfo->visualid = XVisualIDFromVisual(visual);
83 vi = XGetVisualInfo(display, VisualIDMask, vinfo, &nvis);
93 X11_GetPixelFormatFromVisualInfo(Display * display, XVisualInfo * vinfo)
95 if (vinfo->class == DirectColor || vinfo->class == TrueColor) {
97 Uint32 Rmask, Gmask, Bmask, Amask;
99 Rmask = vinfo->visual->red_mask;
100 Gmask = vinfo->visual->green_mask;
101 Bmask = vinfo->visual->blue_mask;
102 if (vinfo->depth == 32) {
103 Amask = (0xFFFFFFFF & ~(Rmask | Gmask | Bmask));
111 XPixmapFormatValues *p = XListPixmapFormats(display, &n);
113 for (i = 0; i < n; ++i) {
114 if (p[i].depth == 24) {
115 bpp = p[i].bits_per_pixel;
123 return SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask);
126 if (vinfo->class == PseudoColor || vinfo->class == StaticColor) {
127 switch (vinfo->depth) {
129 return SDL_PIXELTYPE_INDEX8;
131 if (BitmapBitOrder(display) == LSBFirst) {
132 return SDL_PIXELFORMAT_INDEX4LSB;
134 return SDL_PIXELFORMAT_INDEX4MSB;
138 if (BitmapBitOrder(display) == LSBFirst) {
139 return SDL_PIXELFORMAT_INDEX1LSB;
141 return SDL_PIXELFORMAT_INDEX1MSB;
147 return SDL_PIXELFORMAT_UNKNOWN;
150 /* Global for the error handler */
151 int vm_event, vm_error = -1;
153 #if SDL_VIDEO_DRIVER_X11_XINERAMA
155 CheckXinerama(Display * display, int *major, int *minor)
161 /* Default the extension not available */
164 /* Allow environment override */
165 env = SDL_GetHint(SDL_HINT_VIDEO_X11_XINERAMA);
166 if (env && !SDL_atoi(env)) {
167 #ifdef X11MODES_DEBUG
168 printf("Xinerama disabled due to hint\n");
173 if (!SDL_X11_HAVE_XINERAMA) {
174 #ifdef X11MODES_DEBUG
175 printf("Xinerama support not available\n");
180 /* Query the extension version */
181 if (!XineramaQueryExtension(display, &event_base, &error_base) ||
182 !XineramaQueryVersion(display, major, minor) ||
183 !XineramaIsActive(display)) {
184 #ifdef X11MODES_DEBUG
185 printf("Xinerama not active on the display\n");
189 #ifdef X11MODES_DEBUG
190 printf("Xinerama available at version %d.%d!\n", *major, *minor);
194 #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
196 #if SDL_VIDEO_DRIVER_X11_XRANDR
198 CheckXRandR(Display * display, int *major, int *minor)
202 /* Default the extension not available */
205 /* Allow environment override */
206 env = SDL_GetHint(SDL_HINT_VIDEO_X11_XRANDR);
207 #ifdef XRANDR_DISABLED_BY_DEFAULT
208 if (!env || !SDL_atoi(env)) {
209 #ifdef X11MODES_DEBUG
210 printf("XRandR disabled by default due to window manager issues\n");
215 if (env && !SDL_atoi(env)) {
216 #ifdef X11MODES_DEBUG
217 printf("XRandR disabled due to hint\n");
221 #endif /* XRANDR_ENABLED_BY_DEFAULT */
223 if (!SDL_X11_HAVE_XRANDR) {
224 #ifdef X11MODES_DEBUG
225 printf("XRandR support not available\n");
230 /* Query the extension version */
231 if (!XRRQueryVersion(display, major, minor)) {
232 #ifdef X11MODES_DEBUG
233 printf("XRandR not active on the display\n");
237 #ifdef X11MODES_DEBUG
238 printf("XRandR available at version %d.%d!\n", *major, *minor);
243 #define XRANDR_ROTATION_LEFT (1 << 1)
244 #define XRANDR_ROTATION_RIGHT (1 << 3)
247 CalculateXRandRRefreshRate(const XRRModeInfo *info)
250 && info->vTotal) ? (info->dotClock / (info->hTotal * info->vTotal)) : 0;
254 SetXRandRModeInfo(Display *display, XRRScreenResources *res, XRROutputInfo *output_info,
255 RRMode modeID, SDL_DisplayMode *mode)
258 for (i = 0; i < res->nmode; ++i) {
259 if (res->modes[i].id == modeID) {
261 Rotation rotation = 0;
262 const XRRModeInfo *info = &res->modes[i];
264 crtc = XRRGetCrtcInfo(display, res, output_info->crtc);
266 rotation = crtc->rotation;
267 XRRFreeCrtcInfo(crtc);
270 if (rotation & (XRANDR_ROTATION_LEFT|XRANDR_ROTATION_RIGHT)) {
271 mode->w = info->height;
272 mode->h = info->width;
274 mode->w = info->width;
275 mode->h = info->height;
277 mode->refresh_rate = CalculateXRandRRefreshRate(info);
278 ((SDL_DisplayModeData*)mode->driverdata)->xrandr_mode = modeID;
279 #ifdef X11MODES_DEBUG
280 printf("XRandR mode %d: %dx%d@%dHz\n", (int) modeID, mode->w, mode->h, mode->refresh_rate);
287 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
289 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
291 CheckVidMode(Display * display, int *major, int *minor)
295 /* Default the extension not available */
298 /* Allow environment override */
299 env = SDL_GetHint(SDL_HINT_VIDEO_X11_XVIDMODE);
300 if (env && !SDL_atoi(env)) {
301 #ifdef X11MODES_DEBUG
302 printf("XVidMode disabled due to hint\n");
307 if (!SDL_X11_HAVE_XVIDMODE) {
308 #ifdef X11MODES_DEBUG
309 printf("XVidMode support not available\n");
314 /* Query the extension version */
316 if (!XF86VidModeQueryExtension(display, &vm_event, &vm_error)
317 || !XF86VidModeQueryVersion(display, major, minor)) {
318 #ifdef X11MODES_DEBUG
319 printf("XVidMode not active on the display\n");
323 #ifdef X11MODES_DEBUG
324 printf("XVidMode available at version %d.%d!\n", *major, *minor);
330 Bool XF86VidModeGetModeInfo(Display * dpy, int scr,
331 XF86VidModeModeInfo* info)
335 XF86VidModeModeLine l;
338 retval = XF86VidModeGetModeLine(dpy, scr, &dotclock, &l);
339 info->dotclock = dotclock;
340 info->hdisplay = l.hdisplay;
341 info->hsyncstart = l.hsyncstart;
342 info->hsyncend = l.hsyncend;
343 info->htotal = l.htotal;
344 info->hskew = l.hskew;
345 info->vdisplay = l.vdisplay;
346 info->vsyncstart = l.vsyncstart;
347 info->vsyncend = l.vsyncend;
348 info->vtotal = l.vtotal;
349 info->flags = l.flags;
350 info->privsize = l.privsize;
351 info->private = l.private;
356 CalculateXVidModeRefreshRate(const XF86VidModeModeInfo * info)
359 && info->vtotal) ? (1000 * info->dotclock / (info->htotal *
364 SetXVidModeModeInfo(const XF86VidModeModeInfo *info, SDL_DisplayMode *mode)
366 mode->w = info->hdisplay;
367 mode->h = info->vdisplay;
368 mode->refresh_rate = CalculateXVidModeRefreshRate(info);
369 ((SDL_DisplayModeData*)mode->driverdata)->vm_mode = *info;
372 #endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
377 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
378 int screen, screencount;
379 #if SDL_VIDEO_DRIVER_X11_XINERAMA
380 int xinerama_major, xinerama_minor;
381 int use_xinerama = 0;
382 XineramaScreenInfo *xinerama = NULL;
384 #if SDL_VIDEO_DRIVER_X11_XRANDR
385 int xrandr_major, xrandr_minor;
387 XRRScreenResources *res = NULL;
389 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
390 int vm_major, vm_minor;
394 #if SDL_VIDEO_DRIVER_X11_XINERAMA
395 /* Query Xinerama extention
396 * NOTE: This works with Nvidia Twinview correctly, but you need version 302.17 (released on June 2012)
397 * or newer of the Nvidia binary drivers
399 if (CheckXinerama(data->display, &xinerama_major, &xinerama_minor)) {
400 xinerama = XineramaQueryScreens(data->display, &screencount);
402 use_xinerama = xinerama_major * 100 + xinerama_minor;
406 screencount = ScreenCount(data->display);
409 screencount = ScreenCount(data->display);
410 #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
412 #if SDL_VIDEO_DRIVER_X11_XRANDR
413 /* require at least XRandR v1.2 */
414 if (CheckXRandR(data->display, &xrandr_major, &xrandr_minor) &&
415 (xrandr_major >= 2 || (xrandr_major == 1 && xrandr_minor >= 2))) {
416 use_xrandr = xrandr_major * 100 + xrandr_minor;
418 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
420 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
421 if (CheckVidMode(data->display, &vm_major, &vm_minor)) {
422 use_vidmode = vm_major * 100 + vm_minor;
424 #endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
426 for (screen = 0; screen < screencount; ++screen) {
428 SDL_VideoDisplay display;
429 SDL_DisplayData *displaydata;
430 SDL_DisplayMode mode;
431 SDL_DisplayModeData *modedata;
432 XPixmapFormatValues *pixmapFormats;
433 char display_name[128];
436 #if SDL_VIDEO_DRIVER_X11_XINERAMA
438 if (get_visualinfo(data->display, 0, &vinfo) < 0) {
442 if (get_visualinfo(data->display, screen, &vinfo) < 0) {
447 if (get_visualinfo(data->display, screen, &vinfo) < 0) {
452 displaydata = (SDL_DisplayData *) SDL_calloc(1, sizeof(*displaydata));
456 display_name[0] = '\0';
458 mode.format = X11_GetPixelFormatFromVisualInfo(data->display, &vinfo);
459 if (SDL_ISPIXELFORMAT_INDEXED(mode.format)) {
460 /* We don't support palettized modes now */
461 SDL_free(displaydata);
464 #if SDL_VIDEO_DRIVER_X11_XINERAMA
466 mode.w = xinerama[screen].width;
467 mode.h = xinerama[screen].height;
469 mode.w = DisplayWidth(data->display, screen);
470 mode.h = DisplayHeight(data->display, screen);
473 mode.w = DisplayWidth(data->display, screen);
474 mode.h = DisplayHeight(data->display, screen);
476 mode.refresh_rate = 0;
478 modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
480 SDL_free(displaydata);
483 mode.driverdata = modedata;
485 #if SDL_VIDEO_DRIVER_X11_XINERAMA
486 /* Most of SDL's calls to X11 are unwaware of Xinerama, and to X11 standard calls, when Xinerama is active,
487 * there's only one screen available. So we force the screen number to zero and
488 * let Xinerama specific code handle specific functionality using displaydata->xinerama_info
491 displaydata->screen = 0;
492 displaydata->use_xinerama = use_xinerama;
493 displaydata->xinerama_info = xinerama[screen];
494 displaydata->xinerama_screen = screen;
496 else displaydata->screen = screen;
498 displaydata->screen = screen;
500 displaydata->visual = vinfo.visual;
501 displaydata->depth = vinfo.depth;
503 displaydata->scanline_pad = SDL_BYTESPERPIXEL(mode.format) * 8;
504 pixmapFormats = XListPixmapFormats(data->display, &n);
506 for (i = 0; i < n; ++i) {
507 if (pixmapFormats[i].depth == displaydata->depth) {
508 displaydata->scanline_pad = pixmapFormats[i].scanline_pad;
512 XFree(pixmapFormats);
515 #if SDL_VIDEO_DRIVER_X11_XINERAMA
517 displaydata->x = xinerama[screen].x_org;
518 displaydata->y = xinerama[screen].y_org;
527 #if SDL_VIDEO_DRIVER_X11_XRANDR
529 res = XRRGetScreenResources(data->display, RootWindow(data->display, displaydata->screen));
532 XRROutputInfo *output_info;
535 Atom EDID = XInternAtom(data->display, "EDID", False);
538 unsigned long width_mm;
539 unsigned long height_mm;
542 for (output = 0; output < res->noutput; output++) {
543 output_info = XRRGetOutputInfo(data->display, res, res->outputs[output]);
544 if (!output_info || !output_info->crtc ||
545 output_info->connection == RR_Disconnected) {
546 XRRFreeOutputInfo(output_info);
550 /* Is this the output that corresponds to the current screen?
551 We're checking the crtc position, but that may not be a valid test
552 in all cases. Anybody want to give this some love?
554 crtc = XRRGetCrtcInfo(data->display, res, output_info->crtc);
555 if (!crtc || crtc->x != displaydata->x || crtc->y != displaydata->y) {
556 XRRFreeOutputInfo(output_info);
557 XRRFreeCrtcInfo(crtc);
561 displaydata->use_xrandr = use_xrandr;
562 displaydata->xrandr_output = res->outputs[output];
563 SetXRandRModeInfo(data->display, res, output_info, crtc->mode, &mode);
565 /* Get the name of this display */
566 width_mm = output_info->mm_width;
567 height_mm = output_info->mm_height;
568 inches = (int)((sqrt(width_mm * width_mm +
569 height_mm * height_mm) / 25.4f) + 0.5f);
570 SDL_strlcpy(display_name, output_info->name, sizeof(display_name));
572 /* See if we can get the EDID data for the real monitor name */
573 props = XRRListOutputProperties(data->display, res->outputs[output], &nprop);
574 for (i = 0; i < nprop; ++i) {
577 unsigned long nitems, bytes_after;
580 if (props[i] == EDID) {
581 if (XRRGetOutputProperty(data->display,
582 res->outputs[output], props[i],
583 0, 100, False, False,
585 &actual_type, &actual_format,
586 &nitems, &bytes_after, &prop) == Success ) {
587 MonitorInfo *info = decode_edid(prop);
589 #ifdef X11MODES_DEBUG
590 printf("Found EDID data for %s\n", output_info->name);
591 dump_monitor_info(info);
593 SDL_strlcpy(display_name, info->dsc_product_name, sizeof(display_name));
605 if (*display_name && inches) {
606 size_t len = SDL_strlen(display_name);
607 SDL_snprintf(&display_name[len], sizeof(display_name)-len, " %d\"", inches);
609 #ifdef X11MODES_DEBUG
610 printf("Display name: %s\n", display_name);
613 XRRFreeOutputInfo(output_info);
614 XRRFreeCrtcInfo(crtc);
617 #ifdef X11MODES_DEBUG
618 if (output == res->noutput) {
619 printf("Couldn't find XRandR CRTC at %d,%d\n", displaydata->x, displaydata->y);
622 XRRFreeScreenResources(res);
624 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
626 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
627 if (!displaydata->use_xrandr &&
628 #if SDL_VIDEO_DRIVER_X11_XINERAMA
629 /* XVidMode only works on the screen at the origin */
630 (!displaydata->use_xinerama ||
631 (displaydata->x == 0 && displaydata->y == 0)) &&
634 displaydata->use_vidmode = use_vidmode;
635 if (displaydata->use_xinerama) {
636 displaydata->vidmode_screen = 0;
638 displaydata->vidmode_screen = screen;
640 XF86VidModeGetModeInfo(data->display, displaydata->vidmode_screen, &modedata->vm_mode);
642 #endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
646 display.name = display_name;
648 display.desktop_mode = mode;
649 display.current_mode = mode;
650 display.driverdata = displaydata;
651 SDL_AddVideoDisplay(&display);
654 #if SDL_VIDEO_DRIVER_X11_XINERAMA
655 if (xinerama) XFree(xinerama);
658 if (_this->num_displays == 0) {
659 SDL_SetError("No available displays");
666 X11_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display)
668 Display *display = ((SDL_VideoData *) _this->driverdata)->display;
669 SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata;
670 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
672 XF86VidModeModeInfo ** modes;
676 SDL_DisplayMode mode;
677 SDL_DisplayModeData *modedata;
679 /* Unfortunately X11 requires the window to be created with the correct
680 * visual and depth ahead of time, but the SDL API allows you to create
681 * a window before setting the fullscreen display mode. This means that
682 * we have to use the same format for all windows and all display modes.
683 * (or support recreating the window with a new visual behind the scenes)
685 mode.format = sdl_display->current_mode.format;
686 mode.driverdata = NULL;
688 screen_w = DisplayWidth(display, data->screen);
689 screen_h = DisplayHeight(display, data->screen);
691 #if SDL_VIDEO_DRIVER_X11_XINERAMA
692 if (data->use_xinerama) {
693 /* Add the full (both screens combined) xinerama mode only on the display that starts at 0,0 */
694 if (!data->xinerama_info.x_org && !data->xinerama_info.y_org &&
695 (screen_w > data->xinerama_info.width || screen_h > data->xinerama_info.height)) {
698 mode.refresh_rate = 0;
699 modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
701 *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata;
703 mode.driverdata = modedata;
704 SDL_AddDisplayMode(sdl_display, &mode);
707 #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
709 #if SDL_VIDEO_DRIVER_X11_XRANDR
710 if (data->use_xrandr) {
711 XRRScreenResources *res;
713 res = XRRGetScreenResources (display, RootWindow(display, data->screen));
715 SDL_DisplayModeData *modedata;
716 XRROutputInfo *output_info;
719 output_info = XRRGetOutputInfo(display, res, data->xrandr_output);
720 if (output_info && output_info->connection != RR_Disconnected) {
721 for (i = 0; i < output_info->nmode; ++i) {
722 modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
726 mode.driverdata = modedata;
728 if (SetXRandRModeInfo(display, res, output_info, output_info->modes[i], &mode)) {
729 SDL_AddDisplayMode(sdl_display, &mode);
735 XRRFreeOutputInfo(output_info);
736 XRRFreeScreenResources(res);
740 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
742 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
743 if (data->use_vidmode &&
744 XF86VidModeGetAllModeLines(display, data->vidmode_screen, &nmodes, &modes)) {
747 #ifdef X11MODES_DEBUG
748 printf("VidMode modes: (unsorted)\n");
749 for (i = 0; i < nmodes; ++i) {
750 printf("Mode %d: %d x %d @ %d, flags: 0x%x\n", i,
751 modes[i]->hdisplay, modes[i]->vdisplay,
752 CalculateXVidModeRefreshRate(modes[i]), modes[i]->flags);
755 for (i = 0; i < nmodes; ++i) {
756 modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
760 mode.driverdata = modedata;
762 if (SetXVidModeModeInfo(modes[i], &mode)) {
763 SDL_AddDisplayMode(sdl_display, &mode);
771 #endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
773 if (!data->use_xrandr && !data->use_vidmode) {
774 /* Add the desktop mode */
775 mode = sdl_display->desktop_mode;
776 modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
778 *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata;
780 mode.driverdata = modedata;
781 SDL_AddDisplayMode(sdl_display, &mode);
786 X11_SetDisplayMode(_THIS, SDL_VideoDisplay * sdl_display, SDL_DisplayMode * mode)
788 Display *display = ((SDL_VideoData *) _this->driverdata)->display;
789 SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata;
790 SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata;
792 #if SDL_VIDEO_DRIVER_X11_XRANDR
793 if (data->use_xrandr) {
794 XRRScreenResources *res;
795 XRROutputInfo *output_info;
799 res = XRRGetScreenResources (display, RootWindow(display, data->screen));
801 SDL_SetError("Couldn't get XRandR screen resources");
805 output_info = XRRGetOutputInfo(display, res, data->xrandr_output);
806 if (!output_info || output_info->connection == RR_Disconnected) {
807 SDL_SetError("Couldn't get XRandR output info");
808 XRRFreeScreenResources(res);
812 crtc = XRRGetCrtcInfo(display, res, output_info->crtc);
814 SDL_SetError("Couldn't get XRandR crtc info");
815 XRRFreeOutputInfo(output_info);
816 XRRFreeScreenResources(res);
820 status = XRRSetCrtcConfig (display, res, output_info->crtc, CurrentTime,
821 crtc->x, crtc->y, modedata->xrandr_mode, crtc->rotation,
822 &data->xrandr_output, 1);
824 XRRFreeCrtcInfo(crtc);
825 XRRFreeOutputInfo(output_info);
826 XRRFreeScreenResources(res);
828 if (status != Success) {
829 SDL_SetError("XRRSetCrtcConfig failed");
833 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
835 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
836 if (data->use_vidmode) {
837 XF86VidModeSwitchToMode(display, data->vidmode_screen, &modedata->vm_mode);
839 #endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
850 X11_GetDisplayBounds(_THIS, SDL_VideoDisplay * sdl_display, SDL_Rect * rect)
852 Display *display = ((SDL_VideoData *) _this->driverdata)->display;
853 SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata;
857 rect->w = sdl_display->current_mode.w;
858 rect->h = sdl_display->current_mode.h;
860 #if SDL_VIDEO_DRIVER_X11_XINERAMA
861 /* Get the real current bounds of the display */
862 if (data->use_xinerama) {
864 XineramaScreenInfo *xinerama = XineramaQueryScreens(display, &screencount);
866 rect->x = xinerama[data->xinerama_screen].x_org;
867 rect->y = xinerama[data->xinerama_screen].y_org;
871 #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
875 #endif /* SDL_VIDEO_DRIVER_X11 */
877 /* vi: set ts=4 sw=4 expandtab: */