21 #include "../../SDL_internal.h" 23 #if SDL_VIDEO_DRIVER_X11 46 get_visualinfo(Display * display,
int screen, XVisualInfo * vinfo)
48 const char *visual_id =
SDL_getenv(
"SDL_VIDEO_X11_VISUALID");
53 XVisualInfo *vi,
template;
58 vi = X11_XGetVisualInfo(display, VisualIDMask, &
template, &nvis);
66 depth = DefaultDepth(display, screen);
68 X11_XMatchVisualInfo(display, screen, depth, DirectColor, vinfo)) ||
69 X11_XMatchVisualInfo(display, screen, depth, TrueColor, vinfo) ||
70 X11_XMatchVisualInfo(display, screen, depth, PseudoColor, vinfo) ||
71 X11_XMatchVisualInfo(display, screen, depth, StaticColor, vinfo)) {
83 vinfo->visualid = X11_XVisualIDFromVisual(visual);
84 vi = X11_XGetVisualInfo(display, VisualIDMask, vinfo, &nvis);
96 if (vinfo->class == DirectColor || vinfo->class == TrueColor) {
98 Uint32 Rmask, Gmask, Bmask, Amask;
100 Rmask = vinfo->visual->red_mask;
101 Gmask = vinfo->visual->green_mask;
102 Bmask = vinfo->visual->blue_mask;
103 if (vinfo->depth == 32) {
104 Amask = (0xFFFFFFFF & ~(Rmask | Gmask | Bmask));
112 XPixmapFormatValues *
p = X11_XListPixmapFormats(display, &n);
114 for (i = 0; i <
n; ++
i) {
115 if (p[i].depth == 24) {
116 bpp = p[
i].bits_per_pixel;
127 if (vinfo->class == PseudoColor || vinfo->class == StaticColor) {
128 switch (vinfo->depth) {
132 if (BitmapBitOrder(display) == LSBFirst) {
139 if (BitmapBitOrder(display) == LSBFirst) {
152 int vm_event, vm_error = -1;
154 #if SDL_VIDEO_DRIVER_X11_XINERAMA 156 CheckXinerama(Display * display,
int *major,
int *minor)
168 #ifdef X11MODES_DEBUG 169 printf(
"Xinerama disabled due to hint\n");
174 if (!SDL_X11_HAVE_XINERAMA) {
175 #ifdef X11MODES_DEBUG 176 printf(
"Xinerama support not available\n");
182 if (!X11_XineramaQueryExtension(display, &event_base, &error_base) ||
183 !X11_XineramaQueryVersion(display, major, minor) ||
184 !X11_XineramaIsActive(display)) {
185 #ifdef X11MODES_DEBUG 186 printf(
"Xinerama not active on the display\n");
190 #ifdef X11MODES_DEBUG 191 printf(
"Xinerama available at version %d.%d!\n", *major, *minor);
201 X11_XineramaFailed(Display *
d, XErrorEvent *
e)
203 xinerama_triggered_error =
SDL_TRUE;
204 fprintf(stderr,
"XINERAMA X ERROR: type=%d serial=%lu err=%u req=%u minor=%u\n",
205 e->type, e->serial, (
unsigned int) e->error_code,
206 (
unsigned int) e->request_code, (
unsigned int) e->minor_code);
212 #if SDL_VIDEO_DRIVER_X11_XRANDR 214 CheckXRandR(Display * display,
int *major,
int *minor)
223 #ifdef XRANDR_DISABLED_BY_DEFAULT 225 #ifdef X11MODES_DEBUG 226 printf(
"XRandR disabled by default due to window manager issues\n");
232 #ifdef X11MODES_DEBUG 233 printf(
"XRandR disabled due to hint\n");
239 if (!SDL_X11_HAVE_XRANDR) {
240 #ifdef X11MODES_DEBUG 241 printf(
"XRandR support not available\n");
247 *major = 1; *minor = 3;
248 if (!X11_XRRQueryVersion(display, major, minor)) {
249 #ifdef X11MODES_DEBUG 250 printf(
"XRandR not active on the display\n");
255 #ifdef X11MODES_DEBUG 256 printf(
"XRandR available at version %d.%d!\n", *major, *minor);
261 #define XRANDR_ROTATION_LEFT (1 << 1) 262 #define XRANDR_ROTATION_RIGHT (1 << 3) 265 CalculateXRandRRefreshRate(
const XRRModeInfo *info)
268 && info->vTotal) ? (info->dotClock / (info->hTotal * info->vTotal)) : 0;
272 SetXRandRModeInfo(Display *display, XRRScreenResources *
res, RRCrtc crtc,
276 for (i = 0; i < res->nmode; ++
i) {
277 const XRRModeInfo *info = &res->modes[
i];
278 if (info->id == modeID) {
279 XRRCrtcInfo *crtcinfo;
280 Rotation rotation = 0;
282 crtcinfo = X11_XRRGetCrtcInfo(display, res, crtc);
284 rotation = crtcinfo->rotation;
285 X11_XRRFreeCrtcInfo(crtcinfo);
288 if (rotation & (XRANDR_ROTATION_LEFT|XRANDR_ROTATION_RIGHT)) {
289 mode->
w = info->height;
290 mode->
h = info->width;
292 mode->
w = info->width;
293 mode->
h = info->height;
297 #ifdef X11MODES_DEBUG 298 printf(
"XRandR mode %d: %dx%d@%dHz\n", (
int) modeID, mode->
w, mode->
h, mode->
refresh_rate);
307 SetXRandRDisplayName(Display *
dpy, Atom EDID,
char *
name,
const size_t namelen, RROutput
output,
const unsigned long widthmm,
const unsigned long heightmm)
312 Atom *
props = X11_XRRListOutputProperties(dpy, output, &nprop);
315 for (i = 0; i < nprop; ++
i) {
318 unsigned long nitems, bytes_after;
321 if (props[i] == EDID) {
322 if (X11_XRRGetOutputProperty(dpy, output, props[i], 0, 100, False,
323 False, AnyPropertyType, &actual_type,
324 &actual_format, &nitems, &bytes_after,
328 #ifdef X11MODES_DEBUG 329 printf(
"Found EDID data for %s\n", name);
345 inches = (int)((
SDL_sqrt(widthmm * widthmm + heightmm * heightmm) / 25.4
f) + 0.5f);
346 if (*name && inches) {
351 #ifdef X11MODES_DEBUG 352 printf(
"Display name: %s\n", name);
358 X11_InitModes_XRandR(
_THIS)
362 const int screencount = ScreenCount(dpy);
363 const int default_screen = DefaultScreen(dpy);
364 RROutput primary = X11_XRRGetOutputPrimary(dpy, RootWindow(dpy, default_screen));
365 Atom EDID = X11_XInternAtom(dpy,
"EDID", False);
366 XRRScreenResources *res =
NULL;
369 XPixmapFormatValues *pixmapformats;
370 int looking_for_primary;
375 for (looking_for_primary = 1; looking_for_primary >= 0; looking_for_primary--) {
376 for (screen = 0; screen < screencount; screen++) {
379 if (looking_for_primary && (screen != default_screen)) {
383 if (get_visualinfo(dpy, screen, &vinfo) < 0) {
393 pixmapformats = X11_XListPixmapFormats(dpy, &n);
395 for (i = 0; i <
n; ++
i) {
396 if (pixmapformats[i].depth == vinfo.depth) {
397 scanline_pad = pixmapformats[
i].scanline_pad;
401 X11_XFree(pixmapformats);
404 res = X11_XRRGetScreenResources(dpy, RootWindow(dpy, screen));
409 for (output = 0; output < res->noutput; output++) {
410 XRROutputInfo *output_info;
411 int display_x, display_y;
412 unsigned long display_mm_width, display_mm_height;
414 char display_name[128];
423 if ((looking_for_primary && (res->outputs[output] != primary)) ||
424 (!looking_for_primary && (screen == default_screen) && (res->outputs[output] == primary))) {
428 output_info = X11_XRRGetOutputInfo(dpy, res, res->outputs[output]);
429 if (!output_info || !output_info->crtc || output_info->connection == RR_Disconnected) {
430 X11_XRRFreeOutputInfo(output_info);
434 SDL_strlcpy(display_name, output_info->name,
sizeof(display_name));
435 display_mm_width = output_info->mm_width;
436 display_mm_height = output_info->mm_height;
437 output_crtc = output_info->crtc;
438 X11_XRRFreeOutputInfo(output_info);
440 crtc = X11_XRRGetCrtcInfo(dpy, res, output_crtc);
447 mode.
w = crtc->width;
448 mode.
h = crtc->height;
449 mode.
format = pixelformat;
454 X11_XRRFreeCrtcInfo(crtc);
466 modedata->xrandr_mode = modeID;
470 displaydata->
visual = vinfo.visual;
471 displaydata->
depth = vinfo.depth;
472 displaydata->
hdpi = ((float) mode.
w) * 25.4f / display_mm_width;
473 displaydata->
vdpi = ((float) mode.
h) * 25.4f / display_mm_height;
476 displaydata->
x = display_x;
477 displaydata->
y = display_y;
479 displaydata->xrandr_output = res->outputs[
output];
481 SetXRandRModeInfo(dpy, res, output_crtc, modeID, &mode);
482 SetXRandRDisplayName(dpy, EDID, display_name,
sizeof (display_name), res->outputs[output], display_mm_width, display_mm_height);
486 display.
name = display_name;
494 X11_XRRFreeScreenResources(res);
506 #if SDL_VIDEO_DRIVER_X11_XVIDMODE 508 CheckVidMode(Display * display,
int *major,
int *minor)
518 #ifdef X11MODES_DEBUG 519 printf(
"XVidMode disabled due to hint\n");
524 if (!SDL_X11_HAVE_XVIDMODE) {
525 #ifdef X11MODES_DEBUG 526 printf(
"XVidMode support not available\n");
533 if (!X11_XF86VidModeQueryExtension(display, &vm_event, &vm_error)
534 || !X11_XF86VidModeQueryVersion(display, major, minor)) {
535 #ifdef X11MODES_DEBUG 536 printf(
"XVidMode not active on the display\n");
540 #ifdef X11MODES_DEBUG 541 printf(
"XVidMode available at version %d.%d!\n", *major, *minor);
547 Bool XF86VidModeGetModeInfo(Display * dpy,
int scr,
548 XF86VidModeModeInfo* info)
552 XF86VidModeModeLine l;
555 retval = X11_XF86VidModeGetModeLine(dpy, scr, &dotclock, &l);
556 info->dotclock = dotclock;
557 info->hdisplay = l.hdisplay;
558 info->hsyncstart = l.hsyncstart;
559 info->hsyncend = l.hsyncend;
560 info->htotal = l.htotal;
561 info->hskew = l.hskew;
562 info->vdisplay = l.vdisplay;
563 info->vsyncstart = l.vsyncstart;
564 info->vsyncend = l.vsyncend;
565 info->vtotal = l.vtotal;
566 info->flags = l.flags;
567 info->privsize = l.privsize;
568 info->private = l.private;
573 CalculateXVidModeRefreshRate(
const XF86VidModeModeInfo * info)
576 && info->vtotal) ? (1000 * info->dotclock / (info->htotal *
581 SetXVidModeModeInfo(
const XF86VidModeModeInfo *info,
SDL_DisplayMode *mode)
583 mode->
w = info->hdisplay;
584 mode->
h = info->vdisplay;
585 mode->
refresh_rate = CalculateXVidModeRefreshRate(info);
595 int snum, screen, screencount;
597 int xinerama_major, xinerama_minor;
598 int use_xinerama = 0;
599 XineramaScreenInfo *xinerama =
NULL;
602 int xrandr_major, xrandr_minor;
605 int vm_major, vm_minor;
613 if (CheckXRandR(data->
display, &xrandr_major, &xrandr_minor) &&
614 (xrandr_major >= 2 || (xrandr_major == 1 && xrandr_minor >= 3))) {
615 return X11_InitModes_XRandR(
_this);
621 #if SDL_VIDEO_DRIVER_X11_XINERAMA 626 if (CheckXinerama(data->
display, &xinerama_major, &xinerama_minor)) {
627 int (*handler) (Display *, XErrorEvent *);
628 X11_XSync(data->
display, False);
629 handler = X11_XSetErrorHandler(X11_XineramaFailed);
630 xinerama = X11_XineramaQueryScreens(data->
display, &screencount);
631 X11_XSync(data->
display, False);
632 X11_XSetErrorHandler(handler);
633 if (xinerama_triggered_error) {
637 use_xinerama = xinerama_major * 100 + xinerama_minor;
641 screencount = ScreenCount(data->
display);
644 screencount = ScreenCount(data->
display);
647 #if SDL_VIDEO_DRIVER_X11_XVIDMODE 648 if (CheckVidMode(data->
display, &vm_major, &vm_minor)) {
649 use_vidmode = vm_major * 100 + vm_minor;
653 for (snum = 0; snum < screencount; ++snum) {
659 XPixmapFormatValues *pixmapFormats;
660 char display_name[128];
665 screen = DefaultScreen(data->
display);
666 }
else if (snum == DefaultScreen(data->
display)) {
672 #if SDL_VIDEO_DRIVER_X11_XINERAMA 674 if (get_visualinfo(data->
display, 0, &vinfo) < 0) {
678 if (get_visualinfo(data->
display, screen, &vinfo) < 0) {
683 if (get_visualinfo(data->
display, screen, &vinfo) < 0) {
692 display_name[0] =
'\0';
700 #if SDL_VIDEO_DRIVER_X11_XINERAMA 702 mode.
w = xinerama[
screen].width;
703 mode.
h = xinerama[
screen].height;
705 mode.
w = DisplayWidth(data->
display, screen);
706 mode.
h = DisplayHeight(data->
display, screen);
709 mode.
w = DisplayWidth(data->
display, screen);
710 mode.
h = DisplayHeight(data->
display, screen);
721 #if SDL_VIDEO_DRIVER_X11_XINERAMA 729 displaydata->xinerama_info = xinerama[
screen];
730 displaydata->xinerama_screen =
screen;
736 displaydata->
visual = vinfo.visual;
737 displaydata->
depth = vinfo.depth;
742 displaydata->
hdpi = (float)DisplayWidth(data->
display, displaydata->
screen) * 25.4f /
744 displaydata->
vdpi = (float)DisplayHeight(data->
display, displaydata->
screen) * 25.4f /
748 (
float)DisplayWidthMM(data->
display, displaydata->
screen) / 25.4f,
749 (
float)DisplayHeightMM(data->
display, displaydata->
screen) / 25.4f);
752 pixmapFormats = X11_XListPixmapFormats(data->
display, &n);
754 for (i = 0; i <
n; ++
i) {
755 if (pixmapFormats[i].depth == displaydata->
depth) {
760 X11_XFree(pixmapFormats);
763 #if SDL_VIDEO_DRIVER_X11_XINERAMA 765 displaydata->
x = xinerama[
screen].x_org;
766 displaydata->
y = xinerama[
screen].y_org;
775 #if SDL_VIDEO_DRIVER_X11_XVIDMODE 780 (displaydata->
x == 0 && displaydata->
y == 0)) &&
785 displaydata->vidmode_screen = 0;
787 displaydata->vidmode_screen =
screen;
789 XF86VidModeGetModeInfo(data->
display, displaydata->vidmode_screen, &modedata->vm_mode);
795 display.
name = display_name;
803 #if SDL_VIDEO_DRIVER_X11_XINERAMA 804 if (xinerama) X11_XFree(xinerama);
820 XF86VidModeModeInfo ** modes;
835 screen_w = DisplayWidth(display, data->
screen);
836 screen_h = DisplayHeight(display, data->
screen);
838 #if SDL_VIDEO_DRIVER_X11_XINERAMA 840 if (data->
use_vidmode && !data->xinerama_info.x_org && !data->xinerama_info.y_org &&
841 (screen_w > data->xinerama_info.width || screen_h > data->xinerama_info.height)) {
862 mode.
w = data->xinerama_info.width;
863 mode.
h = data->xinerama_info.height;
878 #if SDL_VIDEO_DRIVER_X11_XRANDR 880 XRRScreenResources *
res;
882 res = X11_XRRGetScreenResources (display, RootWindow(display, data->
screen));
885 XRROutputInfo *output_info;
888 output_info = X11_XRRGetOutputInfo(display, res, data->xrandr_output);
889 if (output_info && output_info->connection != RR_Disconnected) {
890 for (i = 0; i < output_info->nmode; ++
i) {
897 if (!SetXRandRModeInfo(display, res, output_info->crtc, output_info->modes[i], &mode) ||
903 X11_XRRFreeOutputInfo(output_info);
904 X11_XRRFreeScreenResources(res);
910 #if SDL_VIDEO_DRIVER_X11_XVIDMODE 912 X11_XF86VidModeGetAllModeLines(display, data->vidmode_screen, &nmodes, &modes)) {
916 #ifdef X11MODES_DEBUG 917 printf(
"VidMode modes: (unsorted)\n");
918 for (i = 0; i < nmodes; ++
i) {
919 printf(
"Mode %d: %d x %d @ %d, flags: 0x%x\n", i,
920 modes[i]->hdisplay, modes[i]->vdisplay,
921 CalculateXVidModeRefreshRate(modes[i]), modes[i]->
flags);
924 for (i = 0; i < nmodes; ++
i) {
931 if (!SetXVidModeModeInfo(modes[i], &mode) || !
SDL_AddDisplayMode(sdl_display, &mode)) {
959 Display *display = viddata->
display;
965 #if SDL_VIDEO_DRIVER_X11_XRANDR 967 XRRScreenResources *
res;
968 XRROutputInfo *output_info;
972 res = X11_XRRGetScreenResources (display, RootWindow(display, data->
screen));
974 return SDL_SetError(
"Couldn't get XRandR screen resources");
977 output_info = X11_XRRGetOutputInfo(display, res, data->xrandr_output);
978 if (!output_info || output_info->connection == RR_Disconnected) {
979 X11_XRRFreeScreenResources(res);
983 crtc = X11_XRRGetCrtcInfo(display, res, output_info->crtc);
985 X11_XRRFreeOutputInfo(output_info);
986 X11_XRRFreeScreenResources(res);
990 status = X11_XRRSetCrtcConfig (display, res, output_info->crtc, CurrentTime,
991 crtc->x, crtc->y, modedata->xrandr_mode, crtc->rotation,
992 &data->xrandr_output, 1);
994 X11_XRRFreeCrtcInfo(crtc);
995 X11_XRRFreeOutputInfo(output_info);
996 X11_XRRFreeScreenResources(res);
998 if (status != Success) {
1004 #if SDL_VIDEO_DRIVER_X11_XVIDMODE 1006 X11_XF86VidModeSwitchToMode(display, data->vidmode_screen, &modedata->vm_mode);
1033 XineramaScreenInfo *xinerama = X11_XineramaQueryScreens(display, &screencount);
1035 rect->
x = xinerama[data->xinerama_screen].x_org;
1036 rect->
y = xinerama[data->xinerama_screen].y_org;
1037 X11_XFree(xinerama);
1059 return data->
ddpi != 0.0f ? 0 : -1;
Uint32 X11_GetPixelFormatFromVisualInfo(Display *display, XVisualInfo *vinfo)
char dsc_product_name[14]
uint32_t Uint32
An unsigned 32-bit integer type.
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 SDL_AssertionHandler void SDL_SpinLock SDL_atomic_t int int return SDL_atomic_t return void void void return void return int return SDL_AudioSpec SDL_AudioSpec return int int return return int SDL_RWops int SDL_AudioSpec Uint8 Uint32 * e
MonitorInfo * decode_edid(const uchar *edid)
int X11_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
#define SDL_ISPIXELFORMAT_INDEXED(format)
#define SDL_VIDEO_DRIVER_X11_XRANDR
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display dpy)
struct wl_display * display
#define SDL_MasksToPixelFormatEnum
SDL_bool X11_UseDirectColorVisuals(void)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
The structure that defines a display mode.
#define SDL_BYTESPERPIXEL(X)
GLuint const GLchar * name
int SDL_AddVideoDisplay(const SDL_VideoDisplay *display)
int X11_GetDisplayBounds(_THIS, SDL_VideoDisplay *sdl_display, SDL_Rect *rect)
static SDL_VideoDevice * _this
void dump_monitor_info(MonitorInfo *info)
void * SDL_calloc(size_t nmemb, size_t size)
void X11_GetDisplayModes(_THIS, SDL_VideoDisplay *display)
Uint32 SDL_GetTicks(void)
Get the number of milliseconds since the SDL library initialization.
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 SDL_AssertionHandler void SDL_SpinLock SDL_atomic_t int int return SDL_atomic_t return void void void return void return int return SDL_AudioSpec SDL_AudioSpec return int int return return int SDL_RWops int SDL_AudioSpec Uint8 ** d
int X11_GetDisplayDPI(_THIS, SDL_VideoDisplay *sdl_display, float *ddpi, float *hdpi, float *vdpi)
SDL_DisplayMode current_mode
#define SDL_VIDEO_DRIVER_X11_XVIDMODE
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 in i)
#define SDL_OutOfMemory()
SDL_DisplayMode desktop_mode
#define SDL_HINT_VIDEO_X11_XRANDR
A variable controlling whether the X11 XRandR extension should be used.
GLint GLint GLsizei GLsizei GLsizei depth
void X11_QuitModes(_THIS)
#define PENDING_FOCUS_TIME
SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
#define SDL_VIDEO_DRIVER_X11_XINERAMA
Uint32 last_mode_change_deadline
GLenum GLuint GLsizei const GLenum * props
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.
float SDL_ComputeDiagonalDPI(int hpix, int vpix, float hinches, float vinches)
#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.