23 #if SDL_VIDEO_DRIVER_X11
45 get_visualinfo(Display *
display,
int screen, XVisualInfo * vinfo)
47 const char *visual_id =
SDL_getenv(
"SDL_VIDEO_X11_VISUALID");
52 XVisualInfo *
vi,
template;
57 vi = XGetVisualInfo(display, VisualIDMask, &
template, &nvis);
65 depth = DefaultDepth(display, screen);
82 vinfo->visualid = XVisualIDFromVisual(visual);
83 vi = XGetVisualInfo(display, VisualIDMask, vinfo, &nvis);
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;
126 if (vinfo->class == PseudoColor || vinfo->class == StaticColor) {
127 switch (vinfo->depth) {
131 if (BitmapBitOrder(display) ==
LSBFirst) {
138 if (BitmapBitOrder(display) ==
LSBFirst) {
151 int vm_event, vm_error = -1;
153 #if SDL_VIDEO_DRIVER_X11_XINERAMA
155 CheckXinerama(Display * display,
int *major,
int *minor)
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");
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);
196 #if SDL_VIDEO_DRIVER_X11_XRANDR
198 CheckXRandR(Display * display,
int *major,
int *minor)
207 #ifdef XRANDR_DISABLED_BY_DEFAULT
209 #ifdef X11MODES_DEBUG
210 printf(
"XRandR disabled by default due to window manager issues\n");
216 #ifdef X11MODES_DEBUG
217 printf(
"XRandR disabled due to hint\n");
223 if (!SDL_X11_HAVE_XRANDR) {
224 #ifdef X11MODES_DEBUG
225 printf(
"XRandR support not available\n");
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,
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;
279 #ifdef X11MODES_DEBUG
280 printf(
"XRandR mode %d: %dx%d@%dHz\n", (
int) modeID, mode->
w, mode->
h, mode->
refresh_rate);
289 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
291 CheckVidMode(Display * display,
int *major,
int *minor)
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");
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);
378 int screen, screencount;
380 int xinerama_major, xinerama_minor;
381 int use_xinerama = 0;
382 XineramaScreenInfo *xinerama =
NULL;
385 int xrandr_major, xrandr_minor;
387 XRRScreenResources *res =
NULL;
390 int vm_major, vm_minor;
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);
412 #if SDL_VIDEO_DRIVER_X11_XRANDR
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;
420 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
421 if (CheckVidMode(data->
display, &vm_major, &vm_minor)) {
422 use_vidmode = vm_major * 100 + vm_minor;
426 for (screen = 0; screen < screencount; ++screen) {
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) {
456 display_name[0] =
'\0';
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);
485 #if SDL_VIDEO_DRIVER_X11_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;
504 pixmapFormats = XListPixmapFormats(data->
display, &n);
506 for (i = 0; i <
n; ++
i) {
507 if (pixmapFormats[i].depth == displaydata->
depth) {
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
532 XRROutputInfo *output_info;
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);
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);
562 displaydata->xrandr_output = res->outputs[
output];
563 SetXRandRModeInfo(data->
display, res, output_info, crtc->mode, &mode);
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.4
f) + 0.5f);
570 SDL_strlcpy(display_name, output_info->name,
sizeof(display_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 ) {
589 #ifdef X11MODES_DEBUG
590 printf(
"Found EDID data for %s\n", output_info->name);
605 if (*display_name && inches) {
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);
626 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
631 (displaydata->
x == 0 && displaydata->
y == 0)) &&
636 displaydata->vidmode_screen = 0;
638 displaydata->vidmode_screen = screen;
640 XF86VidModeGetModeInfo(data->
display, displaydata->vidmode_screen, &modedata->vm_mode);
646 display.
name = display_name;
654 #if SDL_VIDEO_DRIVER_X11_XINERAMA
655 if (xinerama) XFree(xinerama);
671 XF86VidModeModeInfo ** modes;
687 screen_w = DisplayWidth(display, data->
screen);
688 screen_h = DisplayHeight(display, data->
screen);
690 #if SDL_VIDEO_DRIVER_X11_XINERAMA
692 if (data->
use_vidmode && !data->xinerama_info.x_org && !data->xinerama_info.y_org &&
693 (screen_w > data->xinerama_info.width || screen_h > data->xinerama_info.height)) {
710 mode.
w = data->xinerama_info.width;
711 mode.
h = data->xinerama_info.height;
724 #if SDL_VIDEO_DRIVER_X11_XRANDR
726 XRRScreenResources *
res;
728 res = XRRGetScreenResources (display, RootWindow(display, data->
screen));
731 XRROutputInfo *output_info;
734 output_info = XRRGetOutputInfo(display, res, data->xrandr_output);
735 if (output_info && output_info->connection != RR_Disconnected) {
736 for (i = 0; i < output_info->nmode; ++
i) {
743 if (SetXRandRModeInfo(display, res, output_info, output_info->modes[i], &mode)) {
750 XRRFreeOutputInfo(output_info);
751 XRRFreeScreenResources(res);
757 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
759 XF86VidModeGetAllModeLines(display, data->vidmode_screen, &nmodes, &modes)) {
762 #ifdef X11MODES_DEBUG
763 printf(
"VidMode modes: (unsorted)\n");
764 for (i = 0; i < nmodes; ++
i) {
765 printf(
"Mode %d: %d x %d @ %d, flags: 0x%x\n", i,
766 modes[i]->hdisplay, modes[i]->vdisplay,
767 CalculateXVidModeRefreshRate(modes[i]), modes[i]->
flags);
770 for (i = 0; i < nmodes; ++
i) {
777 if (SetXVidModeModeInfo(modes[i], &mode)) {
807 #if SDL_VIDEO_DRIVER_X11_XRANDR
809 XRRScreenResources *
res;
810 XRROutputInfo *output_info;
814 res = XRRGetScreenResources (display, RootWindow(display, data->
screen));
816 return SDL_SetError(
"Couldn't get XRandR screen resources");
819 output_info = XRRGetOutputInfo(display, res, data->xrandr_output);
820 if (!output_info || output_info->connection == RR_Disconnected) {
821 XRRFreeScreenResources(res);
825 crtc = XRRGetCrtcInfo(display, res, output_info->crtc);
827 XRRFreeOutputInfo(output_info);
828 XRRFreeScreenResources(res);
832 status = XRRSetCrtcConfig (display, res, output_info->crtc, CurrentTime,
833 crtc->x, crtc->y, modedata->xrandr_mode, crtc->rotation,
834 &data->xrandr_output, 1);
836 XRRFreeCrtcInfo(crtc);
837 XRRFreeOutputInfo(output_info);
838 XRRFreeScreenResources(res);
840 if (status != Success) {
846 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
848 XF86VidModeSwitchToMode(display, data->vidmode_screen, &modedata->vm_mode);
875 XineramaScreenInfo *xinerama = XineramaQueryScreens(display, &screencount);
877 rect->
x = xinerama[data->xinerama_screen].x_org;
878 rect->
y = xinerama[data->xinerama_screen].y_org;
Uint32 X11_GetPixelFormatFromVisualInfo(Display *display, XVisualInfo *vinfo)
char dsc_product_name[14]
GLenum GLuint GLsizei const GLenum * props
DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size)
MonitorInfo * decode_edid(const uchar *edid)
DECLSPEC int SDLCALL SDL_snprintf(char *text, size_t maxlen, const char *fmt,...)
int X11_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
#define SDL_ISPIXELFORMAT_INDEXED(format)
SDL_bool X11_UseDirectColorVisuals(void)
DECLSPEC void SDLCALL SDL_free(void *mem)
The structure that defines a display mode.
#define SDL_VIDEO_DRIVER_X11_XVIDMODE
DECLSPEC Uint32 SDLCALL SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
Convert a bpp and RGBA masks to an enumerated pixel format.
#define SDL_BYTESPERPIXEL(X)
int SDL_AddVideoDisplay(const SDL_VideoDisplay *display)
int X11_GetDisplayBounds(_THIS, SDL_VideoDisplay *sdl_display, SDL_Rect *rect)
#define SDL_VIDEO_DRIVER_X11_XINERAMA
static SDL_VideoDevice * _this
uint32_t Uint32
An unsigned 32-bit integer type.
DECLSPEC long SDLCALL SDL_strtol(const char *str, char **endp, int base)
void dump_monitor_info(MonitorInfo *info)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int int return Display Window Cursor return Display Window return Display Drawable GC int int unsigned int unsigned int return Display Drawable GC int int _Xconst char int return Display Drawable GC int int unsigned int unsigned int return Display return Display Cursor return Display GC return XModifierKeymap return char Display Window int return Display return Display Atom return Display Window XWindowAttributes return Display Window return Display XEvent Bool(*) XPointer return Display Window Bool unsigned int int int Window Cursor Time return Display Window int return KeySym retur XInternAtom)
void X11_GetDisplayModes(_THIS, SDL_VideoDisplay *display)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
DECLSPEC size_t SDLCALL SDL_strlcpy(char *dst, const char *src, size_t maxlen)
SDL_DisplayMode current_mode
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
GLint GLenum GLsizei GLsizei GLsizei depth
DECLSPEC const char *SDLCALL SDL_GetHint(const char *name)
Get a hint.
DECLSPEC size_t SDLCALL SDL_strlen(const char *str)
SDL_DisplayMode desktop_mode
#define SDL_HINT_VIDEO_X11_XRANDR
A variable controlling whether the X11 XRandR extension should be used.
GLenum GLsizei GLsizei GLsizei GLsizei GLbitfield flags
void X11_QuitModes(_THIS)
#define SDL_VIDEO_DRIVER_X11_XRANDR
DECLSPEC int SDLCALL SDL_atoi(const char *str)
SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
DECLSPEC char *SDLCALL SDL_getenv(const char *name)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int int return Display Window Cursor return Display Window return Display Drawable GC int int unsigned int unsigned int return Display Drawable GC int int _Xconst char int return Display Drawable GC int int unsigned int unsigned int return Display return Display Cursor return Display GC return XModifierKeymap return char Display Window int return Display return Display Atom return Display Window XWindowAttributes return Display Window return Display XEvent Bool(*) XPointer return Display Window Bool unsigned int int int Window Cursor Time return Display Window int return KeySym return Display _Xconst char Bool return Display _Xconst char return XKeyEvent char int KeySym XComposeStatus retur XMatchVisualInfo)
int X11_GetVisualInfoFromVisual(Display *display, Visual *visual, XVisualInfo *vinfo)
#define SDL_HINT_VIDEO_X11_XVIDMODE
A variable controlling whether the X11 VidMode extension should be used.
#define SDL_HINT_VIDEO_X11_XINERAMA
A variable controlling whether the X11 Xinerama extension should be used.
A rectangle, with the origin at the upper left.