mirror of
https://github.com/encounter/SDL.git
synced 2025-12-08 13:15:10 +00:00
@@ -47,9 +47,6 @@ typedef struct
|
||||
#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR
|
||||
#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR NULL
|
||||
#endif
|
||||
#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA
|
||||
#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA NULL
|
||||
#endif
|
||||
#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2
|
||||
#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 NULL
|
||||
#endif
|
||||
@@ -62,20 +59,15 @@ typedef struct
|
||||
#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS
|
||||
#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS NULL
|
||||
#endif
|
||||
#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE
|
||||
#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE NULL
|
||||
#endif
|
||||
|
||||
static x11dynlib x11libs[] = {
|
||||
{NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC},
|
||||
{NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT},
|
||||
{NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR},
|
||||
{NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA},
|
||||
{NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2},
|
||||
{NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES},
|
||||
{NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR},
|
||||
{NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS},
|
||||
{NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE}
|
||||
{NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS}
|
||||
};
|
||||
|
||||
static void *
|
||||
|
||||
@@ -52,9 +52,6 @@
|
||||
#if SDL_VIDEO_DRIVER_X11_XDBE
|
||||
#include <X11/extensions/Xdbe.h>
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_X11_XINERAMA
|
||||
#include <X11/extensions/Xinerama.h>
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_X11_XINPUT2
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#endif
|
||||
@@ -70,9 +67,6 @@
|
||||
#if SDL_VIDEO_DRIVER_X11_XSHAPE
|
||||
#include <X11/extensions/shape.h>
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_X11_XVIDMODE
|
||||
#include <X11/extensions/xf86vmode.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
|
||||
@@ -148,62 +148,6 @@ X11_GetPixelFormatFromVisualInfo(Display * display, XVisualInfo * vinfo)
|
||||
return SDL_PIXELFORMAT_UNKNOWN;
|
||||
}
|
||||
|
||||
#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)
|
||||
@@ -506,7 +450,7 @@ X11_InitModes_XRandR(_THIS)
|
||||
displaydata->scanline_pad = scanline_pad;
|
||||
displaydata->x = display_x;
|
||||
displaydata->y = display_y;
|
||||
displaydata->use_xrandr = 1;
|
||||
displaydata->use_xrandr = SDL_TRUE;
|
||||
displaydata->xrandr_output = res->outputs[output];
|
||||
|
||||
SetXRandRModeInfo(dpy, res, output_crtc, modeID, &mode);
|
||||
@@ -534,331 +478,25 @@ X11_InitModes_XRandR(_THIS)
|
||||
}
|
||||
#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
|
||||
|
||||
#if SDL_VIDEO_DRIVER_X11_XVIDMODE
|
||||
static SDL_bool
|
||||
CheckVidMode(Display * display, int *major, int *minor)
|
||||
{
|
||||
int vm_event, vm_error = -1;
|
||||
/* 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 */
|
||||
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;
|
||||
}
|
||||
|
||||
static 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 = 0;
|
||||
#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. */
|
||||
/* XRandR is the One True Modern Way to do this on X11. If this
|
||||
fails, we just won't report any display modes except the current
|
||||
desktop size. */
|
||||
#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))) {
|
||||
if (X11_InitModes_XRandR(_this) == 0)
|
||||
return 0;
|
||||
{
|
||||
int xrandr_major, xrandr_minor;
|
||||
/* require at least XRandR v1.3 */
|
||||
if (CheckXRandR(data->display, &xrandr_major, &xrandr_minor) &&
|
||||
(xrandr_major >= 2 || (xrandr_major == 1 && xrandr_minor >= 3))) {
|
||||
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, SDL_FALSE);
|
||||
}
|
||||
|
||||
#if SDL_VIDEO_DRIVER_X11_XINERAMA
|
||||
if (xinerama) X11_XFree(xinerama);
|
||||
#endif
|
||||
|
||||
if (_this->num_displays == 0) {
|
||||
return SDL_SetError("No available displays");
|
||||
}
|
||||
|
||||
#if SDL_VIDEO_DRIVER_X11_XVIDMODE
|
||||
if (use_vidmode) { /* we intend to remove support for XVidMode soon. */
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "SDL is using XVidMode to manage your displays!");
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "This almost always means either SDL was misbuilt");
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "or your X server is insufficient. Please check your setup!");
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Fullscreen and/or multiple displays will not work well.");
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -867,10 +505,6 @@ 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
|
||||
SDL_DisplayMode mode;
|
||||
|
||||
/* Unfortunately X11 requires the window to be created with the correct
|
||||
@@ -882,52 +516,6 @@ X11_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display)
|
||||
mode.format = sdl_display->current_mode.format;
|
||||
mode.driverdata = NULL;
|
||||
|
||||
#if SDL_VIDEO_DRIVER_X11_XINERAMA
|
||||
if (data->use_xinerama) {
|
||||
int screen_w;
|
||||
int screen_h;
|
||||
|
||||
screen_w = DisplayWidth(display, data->screen);
|
||||
screen_h = DisplayHeight(display, data->screen);
|
||||
|
||||
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;
|
||||
@@ -960,37 +548,7 @@ X11_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display)
|
||||
}
|
||||
#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) {
|
||||
if (!data->use_xrandr) {
|
||||
SDL_DisplayModeData *modedata;
|
||||
/* Add the desktop mode */
|
||||
mode = sdl_display->desktop_mode;
|
||||
@@ -1105,12 +663,6 @@ freeInfo:
|
||||
}
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -1129,19 +681,6 @@ X11_GetDisplayBounds(_THIS, SDL_VideoDisplay * sdl_display, SDL_Rect * rect)
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,35 +35,20 @@ typedef struct
|
||||
float hdpi;
|
||||
float vdpi;
|
||||
|
||||
int use_xinerama;
|
||||
int use_xrandr;
|
||||
int use_vidmode;
|
||||
|
||||
#if SDL_VIDEO_DRIVER_X11_XINERAMA
|
||||
XineramaScreenInfo xinerama_info;
|
||||
int xinerama_screen;
|
||||
#endif
|
||||
SDL_bool use_xrandr;
|
||||
|
||||
#if SDL_VIDEO_DRIVER_X11_XRANDR
|
||||
RROutput xrandr_output;
|
||||
#endif
|
||||
|
||||
#if SDL_VIDEO_DRIVER_X11_XVIDMODE
|
||||
int vidmode_screen;
|
||||
#endif
|
||||
|
||||
} SDL_DisplayData;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
#if SDL_VIDEO_DRIVER_X11_XRANDR
|
||||
RRMode xrandr_mode;
|
||||
#else
|
||||
int unused; /* just so struct isn't empty. */
|
||||
#endif
|
||||
|
||||
#if SDL_VIDEO_DRIVER_X11_XVIDMODE
|
||||
XF86VidModeModeInfo vm_mode;
|
||||
#endif
|
||||
|
||||
} SDL_DisplayModeData;
|
||||
|
||||
extern int X11_InitModes(_THIS);
|
||||
|
||||
@@ -260,15 +260,6 @@ SDL_X11_SYM(void,XdbeFreeVisualInfo,(XdbeScreenVisualInfo *visual_info),(visual_
|
||||
SDL_X11_SYM(XdbeBackBufferAttributes*,XdbeGetBackBufferAttributes,(Display *dpy,XdbeBackBuffer buffer),(dpy,buffer),return)
|
||||
#endif
|
||||
|
||||
/* Xinerama support */
|
||||
#if SDL_VIDEO_DRIVER_X11_XINERAMA
|
||||
SDL_X11_MODULE(XINERAMA)
|
||||
SDL_X11_SYM(Bool,XineramaIsActive,(Display *a),(a),return)
|
||||
SDL_X11_SYM(Bool,XineramaQueryExtension,(Display *a,int *b,int *c),(a,b,c),return)
|
||||
SDL_X11_SYM(Status,XineramaQueryVersion,(Display *a,int *b,int *c),(a,b,c),return)
|
||||
SDL_X11_SYM(XineramaScreenInfo*,XineramaQueryScreens,(Display *a, int *b),(a,b),return)
|
||||
#endif
|
||||
|
||||
/* XInput2 support for multiple mice, tablets, etc. */
|
||||
#if SDL_VIDEO_DRIVER_X11_XINPUT2
|
||||
SDL_X11_MODULE(XINPUT2)
|
||||
@@ -321,17 +312,6 @@ SDL_X11_MODULE(XSHAPE)
|
||||
SDL_X11_SYM(void,XShapeCombineMask,(Display *dpy,Window dest,int dest_kind,int x_off,int y_off,Pixmap src,int op),(dpy,dest,dest_kind,x_off,y_off,src,op),)
|
||||
#endif
|
||||
|
||||
#if SDL_VIDEO_DRIVER_X11_XVIDMODE
|
||||
SDL_X11_MODULE(XVIDMODE)
|
||||
SDL_X11_SYM(Bool,XF86VidModeGetAllModeLines,(Display *a,int b,int *c,XF86VidModeModeInfo ***d),(a,b,c,d),return)
|
||||
SDL_X11_SYM(Bool,XF86VidModeGetModeLine,(Display *a,int b,int *c,XF86VidModeModeLine *d),(a,b,c,d),return)
|
||||
SDL_X11_SYM(Bool,XF86VidModeGetViewPort,(Display *a,int b,int *c,int *d),(a,b,c,d),return)
|
||||
SDL_X11_SYM(Bool,XF86VidModeQueryExtension,(Display *a,int *b,int *c),(a,b,c),return)
|
||||
SDL_X11_SYM(Bool,XF86VidModeQueryVersion,(Display *a,int *b,int *c),(a,b,c),return)
|
||||
SDL_X11_SYM(Bool,XF86VidModeSwitchToMode,(Display *a,int b,XF86VidModeModeInfo *c),(a,b,c),return)
|
||||
SDL_X11_SYM(Bool,XF86VidModeLockModeSwitch,(Display *a,int b,int c),(a,b,c),return)
|
||||
#endif
|
||||
|
||||
#undef SDL_X11_MODULE
|
||||
#undef SDL_X11_SYM
|
||||
|
||||
|
||||
@@ -37,9 +37,6 @@
|
||||
#if SDL_VIDEO_DRIVER_X11_XDBE
|
||||
#include <X11/extensions/Xdbe.h>
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_X11_XINERAMA
|
||||
#include <X11/extensions/Xinerama.h>
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_X11_XINPUT2
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#endif
|
||||
@@ -52,9 +49,6 @@
|
||||
#if SDL_VIDEO_DRIVER_X11_XSHAPE
|
||||
#include <X11/extensions/shape.h>
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_X11_XVIDMODE
|
||||
#include <X11/extensions/xf86vmode.h>
|
||||
#endif
|
||||
|
||||
#include "../../core/linux/SDL_dbus.h"
|
||||
#include "../../core/linux/SDL_ime.h"
|
||||
|
||||
@@ -72,13 +72,6 @@ X11_XIfEventTimeout(Display *display, XEvent *event_return, Bool (*predicate)(),
|
||||
}
|
||||
*/
|
||||
|
||||
static SDL_bool
|
||||
X11_IsWindowLegacyFullscreen(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
return (data->fswindow != 0);
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
X11_IsWindowMapped(_THIS, SDL_Window * window)
|
||||
{
|
||||
@@ -1433,161 +1426,12 @@ X11_SetWindowFullscreenViaWM(_THIS, SDL_Window * window, SDL_VideoDisplay * _dis
|
||||
X11_XFlush(display);
|
||||
}
|
||||
|
||||
/* This handles fullscreen itself, outside the Window Manager. */
|
||||
static void
|
||||
X11_BeginWindowFullscreenLegacy(_THIS, SDL_Window * window, SDL_VideoDisplay * _display)
|
||||
{
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata;
|
||||
Visual *visual = data->visual;
|
||||
Display *display = data->videodata->display;
|
||||
const int screen = displaydata->screen;
|
||||
Window root = RootWindow(display, screen);
|
||||
const int def_vis = (visual == DefaultVisual(display, screen));
|
||||
unsigned long xattrmask = 0;
|
||||
XSetWindowAttributes xattr;
|
||||
XEvent ev;
|
||||
SDL_Rect rect;
|
||||
|
||||
if ( data->fswindow ) {
|
||||
return; /* already fullscreen, I hope. */
|
||||
}
|
||||
|
||||
X11_GetDisplayBounds(_this, _display, &rect);
|
||||
|
||||
SDL_zero(xattr);
|
||||
xattr.override_redirect = True;
|
||||
xattrmask |= CWOverrideRedirect;
|
||||
xattr.background_pixel = def_vis ? BlackPixel(display, screen) : 0;
|
||||
xattrmask |= CWBackPixel;
|
||||
xattr.border_pixel = 0;
|
||||
xattrmask |= CWBorderPixel;
|
||||
xattr.colormap = data->colormap;
|
||||
xattrmask |= CWColormap;
|
||||
|
||||
data->fswindow = X11_XCreateWindow(display, root,
|
||||
rect.x, rect.y, rect.w, rect.h, 0,
|
||||
displaydata->depth, InputOutput,
|
||||
visual, xattrmask, &xattr);
|
||||
|
||||
X11_XSelectInput(display, data->fswindow, StructureNotifyMask);
|
||||
X11_XSetWindowBackground(display, data->fswindow, 0);
|
||||
X11_XInstallColormap(display, data->colormap);
|
||||
X11_XClearWindow(display, data->fswindow);
|
||||
X11_XMapRaised(display, data->fswindow);
|
||||
|
||||
/* Make sure the fswindow is in view by warping mouse to the corner */
|
||||
X11_XUngrabPointer(display, CurrentTime);
|
||||
X11_XWarpPointer(display, None, root, 0, 0, 0, 0, rect.x, rect.y);
|
||||
|
||||
/* Wait to be mapped, filter Unmap event out if it arrives. */
|
||||
X11_XIfEvent(display, &ev, &isMapNotify, (XPointer)&data->fswindow);
|
||||
X11_XCheckIfEvent(display, &ev, &isUnmapNotify, (XPointer)&data->fswindow);
|
||||
|
||||
#if SDL_VIDEO_DRIVER_X11_XVIDMODE
|
||||
if ( displaydata->use_vidmode ) {
|
||||
X11_XF86VidModeLockModeSwitch(display, screen, True);
|
||||
}
|
||||
#endif
|
||||
|
||||
SetWindowBordered(display, displaydata->screen, data->xwindow, SDL_FALSE);
|
||||
|
||||
/* Center actual window within our cover-the-screen window. */
|
||||
X11_XReparentWindow(display, data->xwindow, data->fswindow,
|
||||
(rect.w - window->w) / 2, (rect.h - window->h) / 2);
|
||||
|
||||
/* Move the mouse to the upper left to make sure it's on-screen */
|
||||
X11_XWarpPointer(display, None, root, 0, 0, 0, 0, rect.x, rect.y);
|
||||
|
||||
/* Center mouse in the fullscreen window. */
|
||||
rect.x += (rect.w / 2);
|
||||
rect.y += (rect.h / 2);
|
||||
X11_XWarpPointer(display, None, root, 0, 0, 0, 0, rect.x, rect.y);
|
||||
|
||||
/* Wait to be mapped, filter Unmap event out if it arrives. */
|
||||
X11_XIfEvent(display, &ev, &isMapNotify, (XPointer)&data->xwindow);
|
||||
X11_XCheckIfEvent(display, &ev, &isUnmapNotify, (XPointer)&data->xwindow);
|
||||
|
||||
SDL_UpdateWindowGrab(window);
|
||||
}
|
||||
|
||||
static void
|
||||
X11_EndWindowFullscreenLegacy(_THIS, SDL_Window * window, SDL_VideoDisplay * _display)
|
||||
{
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata;
|
||||
Display *display = data->videodata->display;
|
||||
const int screen = displaydata->screen;
|
||||
Window root = RootWindow(display, screen);
|
||||
Window fswindow = data->fswindow;
|
||||
XEvent ev;
|
||||
|
||||
if (!data->fswindow) {
|
||||
return; /* already not fullscreen, I hope. */
|
||||
}
|
||||
|
||||
data->fswindow = None;
|
||||
|
||||
#if SDL_VIDEO_DRIVER_X11_VIDMODE
|
||||
if ( displaydata->use_vidmode ) {
|
||||
X11_XF86VidModeLockModeSwitch(display, screen, False);
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_UpdateWindowGrab(window);
|
||||
|
||||
X11_XReparentWindow(display, data->xwindow, root, window->x, window->y);
|
||||
|
||||
/* flush these events so they don't confuse normal event handling */
|
||||
X11_XSync(display, False);
|
||||
X11_XCheckIfEvent(display, &ev, &isMapNotify, (XPointer)&data->xwindow);
|
||||
X11_XCheckIfEvent(display, &ev, &isUnmapNotify, (XPointer)&data->xwindow);
|
||||
|
||||
SetWindowBordered(display, screen, data->xwindow,
|
||||
(window->flags & SDL_WINDOW_BORDERLESS) == 0);
|
||||
|
||||
X11_XWithdrawWindow(display, fswindow, screen);
|
||||
|
||||
/* Wait to be unmapped. */
|
||||
X11_XIfEvent(display, &ev, &isUnmapNotify, (XPointer)&fswindow);
|
||||
X11_XDestroyWindow(display, fswindow);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
X11_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen)
|
||||
{
|
||||
/* !!! FIXME: SDL_Hint? */
|
||||
SDL_bool legacy = SDL_FALSE;
|
||||
const char *env = SDL_getenv("SDL_VIDEO_X11_LEGACY_FULLSCREEN");
|
||||
if (env) {
|
||||
legacy = SDL_atoi(env);
|
||||
} else {
|
||||
SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
|
||||
SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata;
|
||||
if ( displaydata->use_vidmode ) {
|
||||
legacy = SDL_TRUE; /* the new stuff only works with XRandR. */
|
||||
} else if ( !videodata->net_wm ) {
|
||||
legacy = SDL_TRUE; /* The window manager doesn't support it */
|
||||
} else {
|
||||
/* !!! FIXME: look at the window manager name, and blacklist certain ones? */
|
||||
/* http://stackoverflow.com/questions/758648/find-the-name-of-the-x-window-manager */
|
||||
legacy = SDL_FALSE; /* try the new way. */
|
||||
}
|
||||
}
|
||||
|
||||
if (legacy) {
|
||||
if (fullscreen) {
|
||||
X11_BeginWindowFullscreenLegacy(_this, window, _display);
|
||||
} else {
|
||||
X11_EndWindowFullscreenLegacy(_this, window, _display);
|
||||
}
|
||||
} else {
|
||||
X11_SetWindowFullscreenViaWM(_this, window, _display, fullscreen);
|
||||
}
|
||||
X11_SetWindowFullscreenViaWM(_this, window, _display, fullscreen);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
X11_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp)
|
||||
{
|
||||
@@ -1699,7 +1543,7 @@ X11_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size)
|
||||
unsigned long real_nitems;
|
||||
SDL_x11Prop atomProp;
|
||||
|
||||
X11_XGetWindowAttributes(display, X11_IsWindowLegacyFullscreen(_this, window) ? data->fswindow : data->xwindow, &attributes);
|
||||
X11_XGetWindowAttributes(display, data->xwindow, &attributes);
|
||||
if (X11_XScreenNumberOfScreen(attributes.screen) > 0) {
|
||||
SDL_snprintf(icc_atom_string, sizeof("_ICC_PROFILE_") + 12, "%s%d", "_ICC_PROFILE_", X11_XScreenNumberOfScreen(attributes.screen));
|
||||
} else {
|
||||
@@ -1740,7 +1584,6 @@ X11_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
|
||||
{
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
Display *display;
|
||||
SDL_bool oldstyle_fullscreen;
|
||||
|
||||
if (data == NULL) {
|
||||
return;
|
||||
@@ -1748,13 +1591,7 @@ X11_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
|
||||
|
||||
display = data->videodata->display;
|
||||
|
||||
/* ICCCM2.0-compliant window managers can handle fullscreen windows
|
||||
If we're using XVidMode to change resolution we need to confine
|
||||
the cursor so we don't pan around the virtual desktop.
|
||||
*/
|
||||
oldstyle_fullscreen = X11_IsWindowLegacyFullscreen(_this, window);
|
||||
|
||||
if (oldstyle_fullscreen || grabbed) {
|
||||
if (grabbed) {
|
||||
/* If the window is unmapped, XGrab calls return GrabNotViewable,
|
||||
so when we get a MapNotify later, we'll try to update the grab as
|
||||
appropriate. */
|
||||
@@ -1788,11 +1625,6 @@ X11_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
|
||||
|
||||
/* Raise the window if we grab the mouse */
|
||||
X11_XRaiseWindow(display, data->xwindow);
|
||||
|
||||
/* Now grab the keyboard on old-style fullscreen */
|
||||
if (oldstyle_fullscreen) {
|
||||
X11_SetWindowKeyboardGrab(_this, window, SDL_TRUE);
|
||||
}
|
||||
} else {
|
||||
X11_XUngrabPointer(display, CurrentTime);
|
||||
|
||||
|
||||
@@ -44,7 +44,6 @@ typedef struct
|
||||
{
|
||||
SDL_Window *window;
|
||||
Window xwindow;
|
||||
Window fswindow; /* used if we can't have the WM handle fullscreen. */
|
||||
Visual *visual;
|
||||
Colormap colormap;
|
||||
#ifndef NO_SHARED_MEMORY
|
||||
|
||||
Reference in New Issue
Block a user