summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/SDL2/src/video/x11/SDL_x11modes.c
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/SDL2/src/video/x11/SDL_x11modes.c')
-rw-r--r--3rdparty/SDL2/src/video/x11/SDL_x11modes.c1106
1 files changed, 0 insertions, 1106 deletions
diff --git a/3rdparty/SDL2/src/video/x11/SDL_x11modes.c b/3rdparty/SDL2/src/video/x11/SDL_x11modes.c
deleted file mode 100644
index 29307b3a606..00000000000
--- a/3rdparty/SDL2/src/video/x11/SDL_x11modes.c
+++ /dev/null
@@ -1,1106 +0,0 @@
-/*
- Simple DirectMedia Layer
- Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-*/
-#include "../../SDL_internal.h"
-
-#if SDL_VIDEO_DRIVER_X11
-
-#include "SDL_hints.h"
-#include "SDL_x11video.h"
-#include "SDL_timer.h"
-#include "edid.h"
-
-/* #define X11MODES_DEBUG */
-
-/* I'm becoming more and more convinced that the application should never
- * use XRandR, and it's the window manager's responsibility to track and
- * manage display modes for fullscreen windows. Right now XRandR is completely
- * broken with respect to window manager behavior on every window manager that
- * I can find. For example, on Unity 3D if you show a fullscreen window while
- * the resolution is changing (within ~250 ms) your window will retain the
- * fullscreen state hint but be decorated and windowed.
- *
- * However, many people swear by it, so let them swear at it. :)
-*/
-/* #define XRANDR_DISABLED_BY_DEFAULT */
-
-
-static int
-get_visualinfo(Display * display, int screen, XVisualInfo * vinfo)
-{
- const char *visual_id = SDL_getenv("SDL_VIDEO_X11_VISUALID");
- int depth;
-
- /* Look for an exact visual, if requested */
- if (visual_id) {
- XVisualInfo *vi, template;
- int nvis;
-
- SDL_zero(template);
- template.visualid = SDL_strtol(visual_id, NULL, 0);
- vi = X11_XGetVisualInfo(display, VisualIDMask, &template, &nvis);
- if (vi) {
- *vinfo = *vi;
- X11_XFree(vi);
- return 0;
- }
- }
-
- depth = DefaultDepth(display, screen);
- if ((X11_UseDirectColorVisuals() &&
- X11_XMatchVisualInfo(display, screen, depth, DirectColor, vinfo)) ||
- X11_XMatchVisualInfo(display, screen, depth, TrueColor, vinfo) ||
- X11_XMatchVisualInfo(display, screen, depth, PseudoColor, vinfo) ||
- X11_XMatchVisualInfo(display, screen, depth, StaticColor, vinfo)) {
- return 0;
- }
- return -1;
-}
-
-int
-X11_GetVisualInfoFromVisual(Display * display, Visual * visual, XVisualInfo * vinfo)
-{
- XVisualInfo *vi;
- int nvis;
-
- vinfo->visualid = X11_XVisualIDFromVisual(visual);
- vi = X11_XGetVisualInfo(display, VisualIDMask, vinfo, &nvis);
- if (vi) {
- *vinfo = *vi;
- X11_XFree(vi);
- return 0;
- }
- return -1;
-}
-
-Uint32
-X11_GetPixelFormatFromVisualInfo(Display * display, XVisualInfo * vinfo)
-{
- if (vinfo->class == DirectColor || vinfo->class == TrueColor) {
- int bpp;
- Uint32 Rmask, Gmask, Bmask, Amask;
-
- Rmask = vinfo->visual->red_mask;
- Gmask = vinfo->visual->green_mask;
- Bmask = vinfo->visual->blue_mask;
- if (vinfo->depth == 32) {
- Amask = (0xFFFFFFFF & ~(Rmask | Gmask | Bmask));
- } else {
- Amask = 0;
- }
-
- bpp = vinfo->depth;
- if (bpp == 24) {
- int i, n;
- XPixmapFormatValues *p = X11_XListPixmapFormats(display, &n);
- if (p) {
- for (i = 0; i < n; ++i) {
- if (p[i].depth == 24) {
- bpp = p[i].bits_per_pixel;
- break;
- }
- }
- X11_XFree(p);
- }
- }
-
- return SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask);
- }
-
- if (vinfo->class == PseudoColor || vinfo->class == StaticColor) {
- switch (vinfo->depth) {
- case 8:
- return SDL_PIXELTYPE_INDEX8;
- case 4:
- if (BitmapBitOrder(display) == LSBFirst) {
- return SDL_PIXELFORMAT_INDEX4LSB;
- } else {
- return SDL_PIXELFORMAT_INDEX4MSB;
- }
- break;
- case 1:
- if (BitmapBitOrder(display) == LSBFirst) {
- return SDL_PIXELFORMAT_INDEX1LSB;
- } else {
- return SDL_PIXELFORMAT_INDEX1MSB;
- }
- break;
- }
- }
-
- return SDL_PIXELFORMAT_UNKNOWN;
-}
-
-/* Global for the error handler */
-int vm_event, vm_error = -1;
-
-#if SDL_VIDEO_DRIVER_X11_XINERAMA
-static SDL_bool
-CheckXinerama(Display * display, int *major, int *minor)
-{
- int event_base = 0;
- int error_base = 0;
-
- /* Default the extension not available */
- *major = *minor = 0;
-
- /* Allow environment override */
- if (!SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_XINERAMA, SDL_TRUE)) {
-#ifdef X11MODES_DEBUG
- printf("Xinerama disabled due to hint\n");
-#endif
- return SDL_FALSE;
- }
-
- if (!SDL_X11_HAVE_XINERAMA) {
-#ifdef X11MODES_DEBUG
- printf("Xinerama support not available\n");
-#endif
- return SDL_FALSE;
- }
-
- /* Query the extension version */
- if (!X11_XineramaQueryExtension(display, &event_base, &error_base) ||
- !X11_XineramaQueryVersion(display, major, minor) ||
- !X11_XineramaIsActive(display)) {
-#ifdef X11MODES_DEBUG
- printf("Xinerama not active on the display\n");
-#endif
- return SDL_FALSE;
- }
-#ifdef X11MODES_DEBUG
- printf("Xinerama available at version %d.%d!\n", *major, *minor);
-#endif
- return SDL_TRUE;
-}
-
-/* !!! FIXME: remove this later. */
-/* we have a weird bug where XineramaQueryScreens() throws an X error, so this
- is here to help track it down (and not crash, too!). */
-static SDL_bool xinerama_triggered_error = SDL_FALSE;
-static int
-X11_XineramaFailed(Display * d, XErrorEvent * e)
-{
- xinerama_triggered_error = SDL_TRUE;
- fprintf(stderr, "XINERAMA X ERROR: type=%d serial=%lu err=%u req=%u minor=%u\n",
- e->type, e->serial, (unsigned int) e->error_code,
- (unsigned int) e->request_code, (unsigned int) e->minor_code);
- fflush(stderr);
- return 0;
-}
-#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
-
-#if SDL_VIDEO_DRIVER_X11_XRANDR
-static SDL_bool
-CheckXRandR(Display * display, int *major, int *minor)
-{
- /* Default the extension not available */
- *major = *minor = 0;
-
- /* Allow environment override */
-#ifdef XRANDR_DISABLED_BY_DEFAULT
- if (!SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_XRANDR, SDL_FALSE)) {
-#ifdef X11MODES_DEBUG
- printf("XRandR disabled by default due to window manager issues\n");
-#endif
- return SDL_FALSE;
- }
-#else
- if (!SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_XRANDR, SDL_TRUE)) {
-#ifdef X11MODES_DEBUG
- printf("XRandR disabled due to hint\n");
-#endif
- return SDL_FALSE;
- }
-#endif /* XRANDR_ENABLED_BY_DEFAULT */
-
- if (!SDL_X11_HAVE_XRANDR) {
-#ifdef X11MODES_DEBUG
- printf("XRandR support not available\n");
-#endif
- return SDL_FALSE;
- }
-
- /* Query the extension version */
- *major = 1; *minor = 3; /* we want 1.3 */
- if (!X11_XRRQueryVersion(display, major, minor)) {
-#ifdef X11MODES_DEBUG
- printf("XRandR not active on the display\n");
-#endif
- *major = *minor = 0;
- return SDL_FALSE;
- }
-#ifdef X11MODES_DEBUG
- printf("XRandR available at version %d.%d!\n", *major, *minor);
-#endif
- return SDL_TRUE;
-}
-
-#define XRANDR_ROTATION_LEFT (1 << 1)
-#define XRANDR_ROTATION_RIGHT (1 << 3)
-
-static int
-CalculateXRandRRefreshRate(const XRRModeInfo *info)
-{
- return (info->hTotal && info->vTotal) ?
- round(((double)info->dotClock / (double)(info->hTotal * info->vTotal))) : 0;
-}
-
-static SDL_bool
-SetXRandRModeInfo(Display *display, XRRScreenResources *res, RRCrtc crtc,
- RRMode modeID, SDL_DisplayMode *mode)
-{
- int i;
- for (i = 0; i < res->nmode; ++i) {
- const XRRModeInfo *info = &res->modes[i];
- if (info->id == modeID) {
- XRRCrtcInfo *crtcinfo;
- Rotation rotation = 0;
-
- crtcinfo = X11_XRRGetCrtcInfo(display, res, crtc);
- if (crtcinfo) {
- rotation = crtcinfo->rotation;
- X11_XRRFreeCrtcInfo(crtcinfo);
- }
-
- if (rotation & (XRANDR_ROTATION_LEFT|XRANDR_ROTATION_RIGHT)) {
- mode->w = info->height;
- mode->h = info->width;
- } else {
- mode->w = info->width;
- mode->h = info->height;
- }
- mode->refresh_rate = CalculateXRandRRefreshRate(info);
- ((SDL_DisplayModeData*)mode->driverdata)->xrandr_mode = modeID;
-#ifdef X11MODES_DEBUG
- printf("XRandR mode %d: %dx%d@%dHz\n", (int) modeID, mode->w, mode->h, mode->refresh_rate);
-#endif
- return SDL_TRUE;
- }
- }
- return SDL_FALSE;
-}
-
-static void
-SetXRandRDisplayName(Display *dpy, Atom EDID, char *name, const size_t namelen, RROutput output, const unsigned long widthmm, const unsigned long heightmm)
-{
- /* See if we can get the EDID data for the real monitor name */
- int inches;
- int nprop;
- Atom *props = X11_XRRListOutputProperties(dpy, output, &nprop);
- int i;
-
- for (i = 0; i < nprop; ++i) {
- unsigned char *prop;
- int actual_format;
- unsigned long nitems, bytes_after;
- Atom actual_type;
-
- if (props[i] == EDID) {
- if (X11_XRRGetOutputProperty(dpy, output, props[i], 0, 100, False,
- False, AnyPropertyType, &actual_type,
- &actual_format, &nitems, &bytes_after,
- &prop) == Success) {
- MonitorInfo *info = decode_edid(prop);
- if (info) {
-#ifdef X11MODES_DEBUG
- printf("Found EDID data for %s\n", name);
- dump_monitor_info(info);
-#endif
- SDL_strlcpy(name, info->dsc_product_name, namelen);
- free(info);
- }
- X11_XFree(prop);
- }
- break;
- }
- }
-
- if (props) {
- X11_XFree(props);
- }
-
- inches = (int)((SDL_sqrtf(widthmm * widthmm + heightmm * heightmm) / 25.4f) + 0.5f);
- if (*name && inches) {
- const size_t len = SDL_strlen(name);
- SDL_snprintf(&name[len], namelen-len, " %d\"", inches);
- }
-
-#ifdef X11MODES_DEBUG
- printf("Display name: %s\n", name);
-#endif
-}
-
-
-int
-X11_InitModes_XRandR(_THIS)
-{
- SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
- Display *dpy = data->display;
- const int screencount = ScreenCount(dpy);
- const int default_screen = DefaultScreen(dpy);
- RROutput primary = X11_XRRGetOutputPrimary(dpy, RootWindow(dpy, default_screen));
- Atom EDID = X11_XInternAtom(dpy, "EDID", False);
- XRRScreenResources *res = NULL;
- Uint32 pixelformat;
- XVisualInfo vinfo;
- XPixmapFormatValues *pixmapformats;
- int looking_for_primary;
- int scanline_pad;
- int output;
- int screen, i, n;
-
- for (looking_for_primary = 1; looking_for_primary >= 0; looking_for_primary--) {
- for (screen = 0; screen < screencount; screen++) {
-
- /* we want the primary output first, and then skipped later. */
- if (looking_for_primary && (screen != default_screen)) {
- continue;
- }
-
- if (get_visualinfo(dpy, screen, &vinfo) < 0) {
- continue; /* uh, skip this screen? */
- }
-
- pixelformat = X11_GetPixelFormatFromVisualInfo(dpy, &vinfo);
- if (SDL_ISPIXELFORMAT_INDEXED(pixelformat)) {
- continue; /* Palettized video modes are no longer supported */
- }
-
- scanline_pad = SDL_BYTESPERPIXEL(pixelformat) * 8;
- pixmapformats = X11_XListPixmapFormats(dpy, &n);
- if (pixmapformats) {
- for (i = 0; i < n; ++i) {
- if (pixmapformats[i].depth == vinfo.depth) {
- scanline_pad = pixmapformats[i].scanline_pad;
- break;
- }
- }
- X11_XFree(pixmapformats);
- }
-
- res = X11_XRRGetScreenResources(dpy, RootWindow(dpy, screen));
- if (!res) {
- continue;
- }
-
- for (output = 0; output < res->noutput; output++) {
- XRROutputInfo *output_info;
- int display_x, display_y;
- unsigned long display_mm_width, display_mm_height;
- SDL_DisplayData *displaydata;
- char display_name[128];
- SDL_DisplayMode mode;
- SDL_DisplayModeData *modedata;
- SDL_VideoDisplay display;
- RRMode modeID;
- RRCrtc output_crtc;
- XRRCrtcInfo *crtc;
-
- /* The primary output _should_ always be sorted first, but just in case... */
- if ((looking_for_primary && (res->outputs[output] != primary)) ||
- (!looking_for_primary && (screen == default_screen) && (res->outputs[output] == primary))) {
- continue;
- }
-
- output_info = X11_XRRGetOutputInfo(dpy, res, res->outputs[output]);
- if (!output_info || !output_info->crtc || output_info->connection == RR_Disconnected) {
- X11_XRRFreeOutputInfo(output_info);
- continue;
- }
-
- SDL_strlcpy(display_name, output_info->name, sizeof(display_name));
- display_mm_width = output_info->mm_width;
- display_mm_height = output_info->mm_height;
- output_crtc = output_info->crtc;
- X11_XRRFreeOutputInfo(output_info);
-
- crtc = X11_XRRGetCrtcInfo(dpy, res, output_crtc);
- if (!crtc) {
- continue;
- }
-
- SDL_zero(mode);
- modeID = crtc->mode;
- mode.w = crtc->width;
- mode.h = crtc->height;
- mode.format = pixelformat;
-
- display_x = crtc->x;
- display_y = crtc->y;
-
- X11_XRRFreeCrtcInfo(crtc);
-
- displaydata = (SDL_DisplayData *) SDL_calloc(1, sizeof(*displaydata));
- if (!displaydata) {
- return SDL_OutOfMemory();
- }
-
- modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
- if (!modedata) {
- SDL_free(displaydata);
- return SDL_OutOfMemory();
- }
- modedata->xrandr_mode = modeID;
- mode.driverdata = modedata;
-
- displaydata->screen = screen;
- displaydata->visual = vinfo.visual;
- displaydata->depth = vinfo.depth;
- displaydata->hdpi = ((float) mode.w) * 25.4f / display_mm_width;
- displaydata->vdpi = ((float) mode.h) * 25.4f / display_mm_height;
- displaydata->ddpi = SDL_ComputeDiagonalDPI(mode.w, mode.h, ((float) display_mm_width) / 25.4f,((float) display_mm_height) / 25.4f);
- displaydata->scanline_pad = scanline_pad;
- displaydata->x = display_x;
- displaydata->y = display_y;
- displaydata->use_xrandr = 1;
- displaydata->xrandr_output = res->outputs[output];
-
- SetXRandRModeInfo(dpy, res, output_crtc, modeID, &mode);
- SetXRandRDisplayName(dpy, EDID, display_name, sizeof (display_name), res->outputs[output], display_mm_width, display_mm_height);
-
- SDL_zero(display);
- if (*display_name) {
- display.name = display_name;
- }
- display.desktop_mode = mode;
- display.current_mode = mode;
- display.driverdata = displaydata;
- SDL_AddVideoDisplay(&display);
- }
-
- X11_XRRFreeScreenResources(res);
- }
- }
-
- if (_this->num_displays == 0) {
- return SDL_SetError("No available displays");
- }
-
- return 0;
-}
-#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
-
-#if SDL_VIDEO_DRIVER_X11_XVIDMODE
-static SDL_bool
-CheckVidMode(Display * display, int *major, int *minor)
-{
- /* Default the extension not available */
- *major = *minor = 0;
-
- /* Allow environment override */
- if (!SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_XVIDMODE, SDL_TRUE)) {
-#ifdef X11MODES_DEBUG
- printf("XVidMode disabled due to hint\n");
-#endif
- return SDL_FALSE;
- }
-
- if (!SDL_X11_HAVE_XVIDMODE) {
-#ifdef X11MODES_DEBUG
- printf("XVidMode support not available\n");
-#endif
- return SDL_FALSE;
- }
-
- /* Query the extension version */
- vm_error = -1;
- if (!X11_XF86VidModeQueryExtension(display, &vm_event, &vm_error)
- || !X11_XF86VidModeQueryVersion(display, major, minor)) {
-#ifdef X11MODES_DEBUG
- printf("XVidMode not active on the display\n");
-#endif
- return SDL_FALSE;
- }
-#ifdef X11MODES_DEBUG
- printf("XVidMode available at version %d.%d!\n", *major, *minor);
-#endif
- return SDL_TRUE;
-}
-
-static
-Bool XF86VidModeGetModeInfo(Display * dpy, int scr,
- XF86VidModeModeInfo* info)
-{
- Bool retval;
- int dotclock;
- XF86VidModeModeLine l;
- SDL_zerop(info);
- SDL_zero(l);
- retval = X11_XF86VidModeGetModeLine(dpy, scr, &dotclock, &l);
- info->dotclock = dotclock;
- info->hdisplay = l.hdisplay;
- info->hsyncstart = l.hsyncstart;
- info->hsyncend = l.hsyncend;
- info->htotal = l.htotal;
- info->hskew = l.hskew;
- info->vdisplay = l.vdisplay;
- info->vsyncstart = l.vsyncstart;
- info->vsyncend = l.vsyncend;
- info->vtotal = l.vtotal;
- info->flags = l.flags;
- info->privsize = l.privsize;
- info->private = l.private;
- return retval;
-}
-
-static int
-CalculateXVidModeRefreshRate(const XF86VidModeModeInfo * info)
-{
- return (info->htotal
- && info->vtotal) ? (1000 * info->dotclock / (info->htotal *
- info->vtotal)) : 0;
-}
-
-SDL_bool
-SetXVidModeModeInfo(const XF86VidModeModeInfo *info, SDL_DisplayMode *mode)
-{
- mode->w = info->hdisplay;
- mode->h = info->vdisplay;
- mode->refresh_rate = CalculateXVidModeRefreshRate(info);
- ((SDL_DisplayModeData*)mode->driverdata)->vm_mode = *info;
- return SDL_TRUE;
-}
-#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
-
-int
-X11_InitModes(_THIS)
-{
- SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
- int snum, screen, screencount;
-#if SDL_VIDEO_DRIVER_X11_XINERAMA
- int xinerama_major, xinerama_minor;
- int use_xinerama = 0;
- XineramaScreenInfo *xinerama = NULL;
-#endif
-#if SDL_VIDEO_DRIVER_X11_XRANDR
- int xrandr_major, xrandr_minor;
-#endif
-#if SDL_VIDEO_DRIVER_X11_XVIDMODE
- int vm_major, vm_minor;
- int use_vidmode = 0;
-#endif
-
-/* XRandR is the One True Modern Way to do this on X11. If it's enabled and
- available, don't even look at other ways of doing things. */
-#if SDL_VIDEO_DRIVER_X11_XRANDR
- /* require at least XRandR v1.3 */
- if (CheckXRandR(data->display, &xrandr_major, &xrandr_minor) &&
- (xrandr_major >= 2 || (xrandr_major == 1 && xrandr_minor >= 3))) {
- return X11_InitModes_XRandR(_this);
- }
-#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
-
-/* !!! FIXME: eventually remove support for Xinerama and XVidMode (everything below here). */
-
- /* This is a workaround for some apps (UnrealEngine4, for example) until
- we sort out the ramifications of removing XVidMode support outright.
- This block should be removed with the XVidMode support. */
- {
- if (SDL_GetHintBoolean("SDL_VIDEO_X11_REQUIRE_XRANDR", SDL_FALSE)) {
- #if SDL_VIDEO_DRIVER_X11_XRANDR
- return SDL_SetError("XRandR support is required but not available");
- #else
- return SDL_SetError("XRandR support is required but not built into SDL!");
- #endif
- }
- }
-
-#if SDL_VIDEO_DRIVER_X11_XINERAMA
- /* Query Xinerama extention
- * NOTE: This works with Nvidia Twinview correctly, but you need version 302.17 (released on June 2012)
- * or newer of the Nvidia binary drivers
- */
- if (CheckXinerama(data->display, &xinerama_major, &xinerama_minor)) {
- int (*handler) (Display *, XErrorEvent *);
- X11_XSync(data->display, False);
- handler = X11_XSetErrorHandler(X11_XineramaFailed);
- xinerama = X11_XineramaQueryScreens(data->display, &screencount);
- X11_XSync(data->display, False);
- X11_XSetErrorHandler(handler);
- if (xinerama_triggered_error) {
- xinerama = 0;
- }
- if (xinerama) {
- use_xinerama = xinerama_major * 100 + xinerama_minor;
- }
- }
- if (!xinerama) {
- screencount = ScreenCount(data->display);
- }
-#else
- screencount = ScreenCount(data->display);
-#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
-
-#if SDL_VIDEO_DRIVER_X11_XVIDMODE
- if (CheckVidMode(data->display, &vm_major, &vm_minor)) {
- use_vidmode = vm_major * 100 + vm_minor;
- }
-#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
-
- for (snum = 0; snum < screencount; ++snum) {
- XVisualInfo vinfo;
- SDL_VideoDisplay display;
- SDL_DisplayData *displaydata;
- SDL_DisplayMode mode;
- SDL_DisplayModeData *modedata;
- XPixmapFormatValues *pixmapFormats;
- char display_name[128];
- int i, n;
-
- /* Re-order screens to always put default screen first */
- if (snum == 0) {
- screen = DefaultScreen(data->display);
- } else if (snum == DefaultScreen(data->display)) {
- screen = 0;
- } else {
- screen = snum;
- }
-
-#if SDL_VIDEO_DRIVER_X11_XINERAMA
- if (xinerama) {
- if (get_visualinfo(data->display, 0, &vinfo) < 0) {
- continue;
- }
- } else {
- if (get_visualinfo(data->display, screen, &vinfo) < 0) {
- continue;
- }
- }
-#else
- if (get_visualinfo(data->display, screen, &vinfo) < 0) {
- continue;
- }
-#endif
-
- displaydata = (SDL_DisplayData *) SDL_calloc(1, sizeof(*displaydata));
- if (!displaydata) {
- continue;
- }
- display_name[0] = '\0';
-
- mode.format = X11_GetPixelFormatFromVisualInfo(data->display, &vinfo);
- if (SDL_ISPIXELFORMAT_INDEXED(mode.format)) {
- /* We don't support palettized modes now */
- SDL_free(displaydata);
- continue;
- }
-#if SDL_VIDEO_DRIVER_X11_XINERAMA
- if (xinerama) {
- mode.w = xinerama[screen].width;
- mode.h = xinerama[screen].height;
- } else {
- mode.w = DisplayWidth(data->display, screen);
- mode.h = DisplayHeight(data->display, screen);
- }
-#else
- mode.w = DisplayWidth(data->display, screen);
- mode.h = DisplayHeight(data->display, screen);
-#endif
- mode.refresh_rate = 0;
-
- modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
- if (!modedata) {
- SDL_free(displaydata);
- continue;
- }
- mode.driverdata = modedata;
-
-#if SDL_VIDEO_DRIVER_X11_XINERAMA
- /* Most of SDL's calls to X11 are unwaware of Xinerama, and to X11 standard calls, when Xinerama is active,
- * there's only one screen available. So we force the screen number to zero and
- * let Xinerama specific code handle specific functionality using displaydata->xinerama_info
- */
- if (use_xinerama) {
- displaydata->screen = 0;
- displaydata->use_xinerama = use_xinerama;
- displaydata->xinerama_info = xinerama[screen];
- displaydata->xinerama_screen = screen;
- }
- else displaydata->screen = screen;
-#else
- displaydata->screen = screen;
-#endif
- displaydata->visual = vinfo.visual;
- displaydata->depth = vinfo.depth;
-
- // We use the displaydata screen index here so that this works
- // for both the Xinerama case, where we get the overall DPI,
- // and the regular X11 screen info case.
- displaydata->hdpi = (float)DisplayWidth(data->display, displaydata->screen) * 25.4f /
- DisplayWidthMM(data->display, displaydata->screen);
- displaydata->vdpi = (float)DisplayHeight(data->display, displaydata->screen) * 25.4f /
- DisplayHeightMM(data->display, displaydata->screen);
- displaydata->ddpi = SDL_ComputeDiagonalDPI(DisplayWidth(data->display, displaydata->screen),
- DisplayHeight(data->display, displaydata->screen),
- (float)DisplayWidthMM(data->display, displaydata->screen) / 25.4f,
- (float)DisplayHeightMM(data->display, displaydata->screen) / 25.4f);
-
- displaydata->scanline_pad = SDL_BYTESPERPIXEL(mode.format) * 8;
- pixmapFormats = X11_XListPixmapFormats(data->display, &n);
- if (pixmapFormats) {
- for (i = 0; i < n; ++i) {
- if (pixmapFormats[i].depth == displaydata->depth) {
- displaydata->scanline_pad = pixmapFormats[i].scanline_pad;
- break;
- }
- }
- X11_XFree(pixmapFormats);
- }
-
-#if SDL_VIDEO_DRIVER_X11_XINERAMA
- if (use_xinerama) {
- displaydata->x = xinerama[screen].x_org;
- displaydata->y = xinerama[screen].y_org;
- }
- else
-#endif
- {
- displaydata->x = 0;
- displaydata->y = 0;
- }
-
-#if SDL_VIDEO_DRIVER_X11_XVIDMODE
- if (!displaydata->use_xrandr &&
-#if SDL_VIDEO_DRIVER_X11_XINERAMA
- /* XVidMode only works on the screen at the origin */
- (!displaydata->use_xinerama ||
- (displaydata->x == 0 && displaydata->y == 0)) &&
-#endif
- use_vidmode) {
- displaydata->use_vidmode = use_vidmode;
- if (displaydata->use_xinerama) {
- displaydata->vidmode_screen = 0;
- } else {
- displaydata->vidmode_screen = screen;
- }
- XF86VidModeGetModeInfo(data->display, displaydata->vidmode_screen, &modedata->vm_mode);
- }
-#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
-
- SDL_zero(display);
- if (*display_name) {
- display.name = display_name;
- }
- display.desktop_mode = mode;
- display.current_mode = mode;
- display.driverdata = displaydata;
- SDL_AddVideoDisplay(&display);
- }
-
-#if SDL_VIDEO_DRIVER_X11_XINERAMA
- if (xinerama) X11_XFree(xinerama);
-#endif
-
- if (_this->num_displays == 0) {
- return SDL_SetError("No available displays");
- }
- return 0;
-}
-
-void
-X11_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display)
-{
- Display *display = ((SDL_VideoData *) _this->driverdata)->display;
- SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata;
-#if SDL_VIDEO_DRIVER_X11_XVIDMODE
- int nmodes;
- XF86VidModeModeInfo ** modes;
-#endif
- int screen_w;
- int screen_h;
- SDL_DisplayMode mode;
-
- /* Unfortunately X11 requires the window to be created with the correct
- * visual and depth ahead of time, but the SDL API allows you to create
- * a window before setting the fullscreen display mode. This means that
- * we have to use the same format for all windows and all display modes.
- * (or support recreating the window with a new visual behind the scenes)
- */
- mode.format = sdl_display->current_mode.format;
- mode.driverdata = NULL;
-
- screen_w = DisplayWidth(display, data->screen);
- screen_h = DisplayHeight(display, data->screen);
-
-#if SDL_VIDEO_DRIVER_X11_XINERAMA
- if (data->use_xinerama) {
- if (data->use_vidmode && !data->xinerama_info.x_org && !data->xinerama_info.y_org &&
- (screen_w > data->xinerama_info.width || screen_h > data->xinerama_info.height)) {
- SDL_DisplayModeData *modedata;
- /* Add the full (both screens combined) xinerama mode only on the display that starts at 0,0
- * if we're using vidmode.
- */
- mode.w = screen_w;
- mode.h = screen_h;
- mode.refresh_rate = 0;
- modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
- if (modedata) {
- *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata;
- }
- mode.driverdata = modedata;
- if (!SDL_AddDisplayMode(sdl_display, &mode)) {
- SDL_free(modedata);
- }
- }
- else if (!data->use_xrandr)
- {
- SDL_DisplayModeData *modedata;
- /* Add the current mode of each monitor otherwise if we can't get them from xrandr */
- mode.w = data->xinerama_info.width;
- mode.h = data->xinerama_info.height;
- mode.refresh_rate = 0;
- modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
- if (modedata) {
- *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata;
- }
- mode.driverdata = modedata;
- if (!SDL_AddDisplayMode(sdl_display, &mode)) {
- SDL_free(modedata);
- }
- }
-
- }
-#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
-
-#if SDL_VIDEO_DRIVER_X11_XRANDR
- if (data->use_xrandr) {
- XRRScreenResources *res;
-
- res = X11_XRRGetScreenResources (display, RootWindow(display, data->screen));
- if (res) {
- SDL_DisplayModeData *modedata;
- XRROutputInfo *output_info;
- int i;
-
- output_info = X11_XRRGetOutputInfo(display, res, data->xrandr_output);
- if (output_info && output_info->connection != RR_Disconnected) {
- for (i = 0; i < output_info->nmode; ++i) {
- modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
- if (!modedata) {
- continue;
- }
- mode.driverdata = modedata;
-
- if (!SetXRandRModeInfo(display, res, output_info->crtc, output_info->modes[i], &mode) ||
- !SDL_AddDisplayMode(sdl_display, &mode)) {
- SDL_free(modedata);
- }
- }
- }
- X11_XRRFreeOutputInfo(output_info);
- X11_XRRFreeScreenResources(res);
- }
- return;
- }
-#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
-
-#if SDL_VIDEO_DRIVER_X11_XVIDMODE
- if (data->use_vidmode &&
- X11_XF86VidModeGetAllModeLines(display, data->vidmode_screen, &nmodes, &modes)) {
- int i;
- SDL_DisplayModeData *modedata;
-
-#ifdef X11MODES_DEBUG
- printf("VidMode modes: (unsorted)\n");
- for (i = 0; i < nmodes; ++i) {
- printf("Mode %d: %d x %d @ %d, flags: 0x%x\n", i,
- modes[i]->hdisplay, modes[i]->vdisplay,
- CalculateXVidModeRefreshRate(modes[i]), modes[i]->flags);
- }
-#endif
- for (i = 0; i < nmodes; ++i) {
- modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
- if (!modedata) {
- continue;
- }
- mode.driverdata = modedata;
-
- if (!SetXVidModeModeInfo(modes[i], &mode) || !SDL_AddDisplayMode(sdl_display, &mode)) {
- SDL_free(modedata);
- }
- }
- X11_XFree(modes);
- return;
- }
-#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
-
- if (!data->use_xrandr && !data->use_vidmode) {
- SDL_DisplayModeData *modedata;
- /* Add the desktop mode */
- mode = sdl_display->desktop_mode;
- modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
- if (modedata) {
- *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata;
- }
- mode.driverdata = modedata;
- if (!SDL_AddDisplayMode(sdl_display, &mode)) {
- SDL_free(modedata);
- }
- }
-}
-
-int
-X11_SetDisplayMode(_THIS, SDL_VideoDisplay * sdl_display, SDL_DisplayMode * mode)
-{
- SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata;
- Display *display = viddata->display;
- SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata;
- SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata;
-
- viddata->last_mode_change_deadline = SDL_GetTicks() + (PENDING_FOCUS_TIME * 2);
-
-#if SDL_VIDEO_DRIVER_X11_XRANDR
- if (data->use_xrandr) {
- XRRScreenResources *res;
- XRROutputInfo *output_info;
- XRRCrtcInfo *crtc;
- Status status;
-
- res = X11_XRRGetScreenResources (display, RootWindow(display, data->screen));
- if (!res) {
- return SDL_SetError("Couldn't get XRandR screen resources");
- }
-
- output_info = X11_XRRGetOutputInfo(display, res, data->xrandr_output);
- if (!output_info || output_info->connection == RR_Disconnected) {
- X11_XRRFreeScreenResources(res);
- return SDL_SetError("Couldn't get XRandR output info");
- }
-
- crtc = X11_XRRGetCrtcInfo(display, res, output_info->crtc);
- if (!crtc) {
- X11_XRRFreeOutputInfo(output_info);
- X11_XRRFreeScreenResources(res);
- return SDL_SetError("Couldn't get XRandR crtc info");
- }
-
- status = X11_XRRSetCrtcConfig (display, res, output_info->crtc, CurrentTime,
- crtc->x, crtc->y, modedata->xrandr_mode, crtc->rotation,
- &data->xrandr_output, 1);
-
- X11_XRRFreeCrtcInfo(crtc);
- X11_XRRFreeOutputInfo(output_info);
- X11_XRRFreeScreenResources(res);
-
- if (status != Success) {
- return SDL_SetError("X11_XRRSetCrtcConfig failed");
- }
- }
-#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
-
-#if SDL_VIDEO_DRIVER_X11_XVIDMODE
- if (data->use_vidmode) {
- X11_XF86VidModeSwitchToMode(display, data->vidmode_screen, &modedata->vm_mode);
- }
-#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
-
- return 0;
-}
-
-void
-X11_QuitModes(_THIS)
-{
-}
-
-int
-X11_GetDisplayBounds(_THIS, SDL_VideoDisplay * sdl_display, SDL_Rect * rect)
-{
- SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata;
-
- rect->x = data->x;
- rect->y = data->y;
- rect->w = sdl_display->current_mode.w;
- rect->h = sdl_display->current_mode.h;
-
-#if SDL_VIDEO_DRIVER_X11_XINERAMA
- /* Get the real current bounds of the display */
- if (data->use_xinerama) {
- Display *display = ((SDL_VideoData *) _this->driverdata)->display;
- int screencount;
- XineramaScreenInfo *xinerama = X11_XineramaQueryScreens(display, &screencount);
- if (xinerama) {
- rect->x = xinerama[data->xinerama_screen].x_org;
- rect->y = xinerama[data->xinerama_screen].y_org;
- X11_XFree(xinerama);
- }
- }
-#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
- return 0;
-}
-
-int
-X11_GetDisplayDPI(_THIS, SDL_VideoDisplay * sdl_display, float * ddpi, float * hdpi, float * vdpi)
-{
- SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata;
-
- if (ddpi) {
- *ddpi = data->ddpi;
- }
- if (hdpi) {
- *hdpi = data->hdpi;
- }
- if (vdpi) {
- *vdpi = data->vdpi;
- }
-
- return data->ddpi != 0.0f ? 0 : SDL_SetError("Couldn't get DPI");
-}
-
-int
-X11_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * sdl_display, SDL_Rect * rect)
-{
- SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
- Display *display = data->display;
- Atom _NET_WORKAREA;
- int status, real_format;
- int retval = -1;
- Atom real_type;
- unsigned long items_read = 0, items_left = 0;
- unsigned char *propdata = NULL;
-
- if (X11_GetDisplayBounds(_this, sdl_display, rect) < 0) {
- return -1;
- }
-
- _NET_WORKAREA = X11_XInternAtom(display, "_NET_WORKAREA", False);
- status = X11_XGetWindowProperty(display, DefaultRootWindow(display),
- _NET_WORKAREA, 0L, 4L, False, XA_CARDINAL,
- &real_type, &real_format, &items_read,
- &items_left, &propdata);
- if ((status == Success) && (items_read >= 4)) {
- const long *p = (long*) propdata;
- const SDL_Rect usable = { (int)p[0], (int)p[1], (int)p[2], (int)p[3] };
- retval = 0;
- if (!SDL_IntersectRect(rect, &usable, rect)) {
- SDL_zerop(rect);
- }
- }
-
- if (propdata) {
- X11_XFree(propdata);
- }
-
- return retval;
-}
-
-#endif /* SDL_VIDEO_DRIVER_X11 */
-
-/* vi: set ts=4 sw=4 expandtab: */