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) {
151 #if SDL_VIDEO_DRIVER_X11_XINERAMA 153 CheckXinerama(Display * display,
int *major,
int *minor)
163 #ifdef X11MODES_DEBUG 164 printf(
"Xinerama disabled due to hint\n");
169 if (!SDL_X11_HAVE_XINERAMA) {
170 #ifdef X11MODES_DEBUG 171 printf(
"Xinerama support not available\n");
177 if (!X11_XineramaQueryExtension(display, &event_base, &error_base) ||
178 !X11_XineramaQueryVersion(display, major, minor) ||
179 !X11_XineramaIsActive(display)) {
180 #ifdef X11MODES_DEBUG 181 printf(
"Xinerama not active on the display\n");
185 #ifdef X11MODES_DEBUG 186 printf(
"Xinerama available at version %d.%d!\n", *major, *minor);
196 X11_XineramaFailed(Display *
d, XErrorEvent *
e)
198 xinerama_triggered_error =
SDL_TRUE;
199 fprintf(stderr,
"XINERAMA X ERROR: type=%d serial=%lu err=%u req=%u minor=%u\n",
200 e->type, e->serial, (
unsigned int) e->error_code,
201 (
unsigned int) e->request_code, (
unsigned int) e->minor_code);
207 #if SDL_VIDEO_DRIVER_X11_XRANDR 209 CheckXRandR(Display * display,
int *major,
int *minor)
215 #ifdef XRANDR_DISABLED_BY_DEFAULT 217 #ifdef X11MODES_DEBUG 218 printf(
"XRandR disabled by default due to window manager issues\n");
224 #ifdef X11MODES_DEBUG 225 printf(
"XRandR disabled due to hint\n");
231 if (!SDL_X11_HAVE_XRANDR) {
232 #ifdef X11MODES_DEBUG 233 printf(
"XRandR support not available\n");
239 *major = 1; *minor = 3;
240 if (!X11_XRRQueryVersion(display, major, minor)) {
241 #ifdef X11MODES_DEBUG 242 printf(
"XRandR not active on the display\n");
247 #ifdef X11MODES_DEBUG 248 printf(
"XRandR available at version %d.%d!\n", *major, *minor);
253 #define XRANDR_ROTATION_LEFT (1 << 1) 254 #define XRANDR_ROTATION_RIGHT (1 << 3) 257 CalculateXRandRRefreshRate(
const XRRModeInfo *info)
259 return (info->hTotal && info->vTotal) ?
260 round(((
double)info->dotClock / (
double)(info->hTotal * info->vTotal))) : 0;
264 SetXRandRModeInfo(Display *display, XRRScreenResources *
res, RRCrtc crtc,
268 for (i = 0; i < res->nmode; ++
i) {
269 const XRRModeInfo *info = &res->modes[
i];
270 if (info->id == modeID) {
271 XRRCrtcInfo *crtcinfo;
272 Rotation rotation = 0;
274 crtcinfo = X11_XRRGetCrtcInfo(display, res, crtc);
276 rotation = crtcinfo->rotation;
277 X11_XRRFreeCrtcInfo(crtcinfo);
280 if (rotation & (XRANDR_ROTATION_LEFT|XRANDR_ROTATION_RIGHT)) {
281 mode->
w = info->height;
282 mode->
h = info->width;
284 mode->
w = info->width;
285 mode->
h = info->height;
289 #ifdef X11MODES_DEBUG 290 printf(
"XRandR mode %d: %dx%d@%dHz\n", (
int) modeID, mode->
w, mode->
h, mode->
refresh_rate);
299 SetXRandRDisplayName(Display *
dpy, Atom EDID,
char *
name,
const size_t namelen, RROutput
output,
const unsigned long widthmm,
const unsigned long heightmm)
304 Atom *
props = X11_XRRListOutputProperties(dpy, output, &nprop);
307 for (i = 0; i < nprop; ++
i) {
310 unsigned long nitems, bytes_after;
313 if (props[i] == EDID) {
314 if (X11_XRRGetOutputProperty(dpy, output, props[i], 0, 100, False,
315 False, AnyPropertyType, &actual_type,
316 &actual_format, &nitems, &bytes_after,
320 #ifdef X11MODES_DEBUG 321 printf(
"Found EDID data for %s\n", name);
337 inches = (int)((
SDL_sqrtf(widthmm * widthmm + heightmm * heightmm) / 25.4
f) + 0.5f);
338 if (*name && inches) {
343 #ifdef X11MODES_DEBUG 344 printf(
"Display name: %s\n", name);
350 X11_InitModes_XRandR(
_THIS)
354 const int screencount = ScreenCount(dpy);
355 const int default_screen = DefaultScreen(dpy);
356 RROutput primary = X11_XRRGetOutputPrimary(dpy, RootWindow(dpy, default_screen));
357 Atom EDID = X11_XInternAtom(dpy,
"EDID", False);
358 XRRScreenResources *res =
NULL;
361 XPixmapFormatValues *pixmapformats;
362 int looking_for_primary;
367 for (looking_for_primary = 1; looking_for_primary >= 0; looking_for_primary--) {
368 for (screen = 0; screen < screencount; screen++) {
371 if (looking_for_primary && (screen != default_screen)) {
375 if (get_visualinfo(dpy, screen, &vinfo) < 0) {
385 pixmapformats = X11_XListPixmapFormats(dpy, &n);
387 for (i = 0; i <
n; ++
i) {
388 if (pixmapformats[i].depth == vinfo.depth) {
389 scanline_pad = pixmapformats[
i].scanline_pad;
393 X11_XFree(pixmapformats);
396 res = X11_XRRGetScreenResourcesCurrent(dpy, RootWindow(dpy, screen));
397 if (!res || res->noutput == 0) {
399 X11_XRRFreeScreenResources(res);
402 res = X11_XRRGetScreenResources(dpy, RootWindow(dpy, screen));
408 for (output = 0; output < res->noutput; output++) {
409 XRROutputInfo *output_info;
410 int display_x, display_y;
411 unsigned long display_mm_width, display_mm_height;
413 char display_name[128];
422 if ((looking_for_primary && (res->outputs[output] != primary)) ||
423 (!looking_for_primary && (screen == default_screen) && (res->outputs[output] == primary))) {
427 output_info = X11_XRRGetOutputInfo(dpy, res, res->outputs[output]);
428 if (!output_info || !output_info->crtc || output_info->connection == RR_Disconnected) {
429 X11_XRRFreeOutputInfo(output_info);
433 SDL_strlcpy(display_name, output_info->name,
sizeof(display_name));
434 display_mm_width = output_info->mm_width;
435 display_mm_height = output_info->mm_height;
436 output_crtc = output_info->crtc;
437 X11_XRRFreeOutputInfo(output_info);
439 crtc = X11_XRRGetCrtcInfo(dpy, res, output_crtc);
446 mode.
w = crtc->width;
447 mode.
h = crtc->height;
448 mode.
format = pixelformat;
453 X11_XRRFreeCrtcInfo(crtc);
465 modedata->xrandr_mode = modeID;
469 displaydata->
visual = vinfo.visual;
470 displaydata->
depth = vinfo.depth;
471 displaydata->
hdpi = display_mm_width ? (((float) mode.
w) * 25.4f / display_mm_width) : 0.0
f;
472 displaydata->
vdpi = display_mm_height ? (((float) mode.
h) * 25.4f / display_mm_height) : 0.0
f;
475 displaydata->
x = display_x;
476 displaydata->
y = display_y;
478 displaydata->xrandr_output = res->outputs[
output];
480 SetXRandRModeInfo(dpy, res, output_crtc, modeID, &mode);
481 SetXRandRDisplayName(dpy, EDID, display_name,
sizeof (display_name), res->outputs[output], display_mm_width, display_mm_height);
485 display.
name = display_name;
493 X11_XRRFreeScreenResources(res);
505 #if SDL_VIDEO_DRIVER_X11_XVIDMODE 507 CheckVidMode(Display * display,
int *major,
int *minor)
509 int vm_event, vm_error = -1;
515 #ifdef X11MODES_DEBUG 516 printf(
"XVidMode disabled due to hint\n");
521 if (!SDL_X11_HAVE_XVIDMODE) {
522 #ifdef X11MODES_DEBUG 523 printf(
"XVidMode support not available\n");
529 if (!X11_XF86VidModeQueryExtension(display, &vm_event, &vm_error)
530 || !X11_XF86VidModeQueryVersion(display, major, minor)) {
531 #ifdef X11MODES_DEBUG 532 printf(
"XVidMode not active on the display\n");
536 #ifdef X11MODES_DEBUG 537 printf(
"XVidMode available at version %d.%d!\n", *major, *minor);
543 Bool XF86VidModeGetModeInfo(Display * dpy,
int scr,
544 XF86VidModeModeInfo* info)
548 XF86VidModeModeLine l;
551 retval = X11_XF86VidModeGetModeLine(dpy, scr, &dotclock, &l);
552 info->dotclock = dotclock;
553 info->hdisplay = l.hdisplay;
554 info->hsyncstart = l.hsyncstart;
555 info->hsyncend = l.hsyncend;
556 info->htotal = l.htotal;
557 info->hskew = l.hskew;
558 info->vdisplay = l.vdisplay;
559 info->vsyncstart = l.vsyncstart;
560 info->vsyncend = l.vsyncend;
561 info->vtotal = l.vtotal;
562 info->flags = l.flags;
563 info->privsize = l.privsize;
564 info->private = l.private;
569 CalculateXVidModeRefreshRate(
const XF86VidModeModeInfo * info)
572 && info->vtotal) ? (1000 * info->dotclock / (info->htotal *
577 SetXVidModeModeInfo(
const XF86VidModeModeInfo *info,
SDL_DisplayMode *mode)
579 mode->
w = info->hdisplay;
580 mode->
h = info->vdisplay;
581 mode->
refresh_rate = CalculateXVidModeRefreshRate(info);
591 int snum, screen, screencount = 0;
593 int xinerama_major, xinerama_minor;
594 int use_xinerama = 0;
595 XineramaScreenInfo *xinerama =
NULL;
598 int xrandr_major, xrandr_minor;
601 int vm_major, vm_minor;
609 if (CheckXRandR(data->
display, &xrandr_major, &xrandr_minor) &&
610 (xrandr_major >= 2 || (xrandr_major == 1 && xrandr_minor >= 3))) {
611 if (X11_InitModes_XRandR(
_this) == 0)
623 #if SDL_VIDEO_DRIVER_X11_XRANDR 624 return SDL_SetError(
"XRandR support is required but not available");
626 return SDL_SetError(
"XRandR support is required but not built into SDL!");
631 #if SDL_VIDEO_DRIVER_X11_XINERAMA 636 if (CheckXinerama(data->
display, &xinerama_major, &xinerama_minor)) {
637 int (*handler) (Display *, XErrorEvent *);
638 X11_XSync(data->
display, False);
639 handler = X11_XSetErrorHandler(X11_XineramaFailed);
640 xinerama = X11_XineramaQueryScreens(data->
display, &screencount);
641 X11_XSync(data->
display, False);
642 X11_XSetErrorHandler(handler);
643 if (xinerama_triggered_error) {
647 use_xinerama = xinerama_major * 100 + xinerama_minor;
651 screencount = ScreenCount(data->
display);
654 screencount = ScreenCount(data->
display);
657 #if SDL_VIDEO_DRIVER_X11_XVIDMODE 658 if (CheckVidMode(data->
display, &vm_major, &vm_minor)) {
659 use_vidmode = vm_major * 100 + vm_minor;
663 for (snum = 0; snum < screencount; ++snum) {
669 XPixmapFormatValues *pixmapFormats;
670 char display_name[128];
675 screen = DefaultScreen(data->
display);
676 }
else if (snum == DefaultScreen(data->
display)) {
682 #if SDL_VIDEO_DRIVER_X11_XINERAMA 684 if (get_visualinfo(data->
display, 0, &vinfo) < 0) {
688 if (get_visualinfo(data->
display, screen, &vinfo) < 0) {
693 if (get_visualinfo(data->
display, screen, &vinfo) < 0) {
702 display_name[0] =
'\0';
710 #if SDL_VIDEO_DRIVER_X11_XINERAMA 712 mode.
w = xinerama[
screen].width;
713 mode.
h = xinerama[
screen].height;
715 mode.
w = DisplayWidth(data->
display, screen);
716 mode.
h = DisplayHeight(data->
display, screen);
719 mode.
w = DisplayWidth(data->
display, screen);
720 mode.
h = DisplayHeight(data->
display, screen);
731 #if SDL_VIDEO_DRIVER_X11_XINERAMA 739 displaydata->xinerama_info = xinerama[
screen];
740 displaydata->xinerama_screen =
screen;
746 displaydata->
visual = vinfo.visual;
747 displaydata->
depth = vinfo.depth;
752 displaydata->
hdpi = (float)DisplayWidth(data->
display, displaydata->
screen) * 25.4f /
754 displaydata->
vdpi = (float)DisplayHeight(data->
display, displaydata->
screen) * 25.4f /
758 (
float)DisplayWidthMM(data->
display, displaydata->
screen) / 25.4f,
759 (
float)DisplayHeightMM(data->
display, displaydata->
screen) / 25.4f);
762 pixmapFormats = X11_XListPixmapFormats(data->
display, &n);
764 for (i = 0; i <
n; ++
i) {
765 if (pixmapFormats[i].depth == displaydata->
depth) {
770 X11_XFree(pixmapFormats);
773 #if SDL_VIDEO_DRIVER_X11_XINERAMA 775 displaydata->
x = xinerama[
screen].x_org;
776 displaydata->
y = xinerama[
screen].y_org;
785 #if SDL_VIDEO_DRIVER_X11_XVIDMODE 790 (displaydata->
x == 0 && displaydata->
y == 0)) &&
795 displaydata->vidmode_screen = 0;
797 displaydata->vidmode_screen =
screen;
799 XF86VidModeGetModeInfo(data->
display, displaydata->vidmode_screen, &modedata->vm_mode);
805 display.
name = display_name;
813 #if SDL_VIDEO_DRIVER_X11_XINERAMA 814 if (xinerama) X11_XFree(xinerama);
830 XF86VidModeModeInfo ** modes;
848 screen_w = DisplayWidth(display, data->
screen);
849 screen_h = DisplayHeight(display, data->
screen);
851 if (data->
use_vidmode && !data->xinerama_info.x_org && !data->xinerama_info.y_org &&
852 (screen_w > data->xinerama_info.width || screen_h > data->xinerama_info.height)) {
873 mode.
w = data->xinerama_info.width;
874 mode.
h = data->xinerama_info.height;
889 #if SDL_VIDEO_DRIVER_X11_XRANDR 891 XRRScreenResources *
res;
893 res = X11_XRRGetScreenResources (display, RootWindow(display, data->
screen));
896 XRROutputInfo *output_info;
899 output_info = X11_XRRGetOutputInfo(display, res, data->xrandr_output);
900 if (output_info && output_info->connection != RR_Disconnected) {
901 for (i = 0; i < output_info->nmode; ++
i) {
908 if (!SetXRandRModeInfo(display, res, output_info->crtc, output_info->modes[i], &mode) ||
914 X11_XRRFreeOutputInfo(output_info);
915 X11_XRRFreeScreenResources(res);
921 #if SDL_VIDEO_DRIVER_X11_XVIDMODE 923 X11_XF86VidModeGetAllModeLines(display, data->vidmode_screen, &nmodes, &modes)) {
927 #ifdef X11MODES_DEBUG 928 printf(
"VidMode modes: (unsorted)\n");
929 for (i = 0; i < nmodes; ++
i) {
930 printf(
"Mode %d: %d x %d @ %d, flags: 0x%x\n", i,
931 modes[i]->hdisplay, modes[i]->vdisplay,
932 CalculateXVidModeRefreshRate(modes[i]), modes[i]->
flags);
935 for (i = 0; i < nmodes; ++
i) {
942 if (!SetXVidModeModeInfo(modes[i], &mode) || !
SDL_AddDisplayMode(sdl_display, &mode)) {
970 Display *display = viddata->
display;
976 #if SDL_VIDEO_DRIVER_X11_XRANDR 978 XRRScreenResources *
res;
979 XRROutputInfo *output_info;
983 res = X11_XRRGetScreenResources (display, RootWindow(display, data->
screen));
985 return SDL_SetError(
"Couldn't get XRandR screen resources");
988 output_info = X11_XRRGetOutputInfo(display, res, data->xrandr_output);
989 if (!output_info || output_info->connection == RR_Disconnected) {
990 X11_XRRFreeScreenResources(res);
994 crtc = X11_XRRGetCrtcInfo(display, res, output_info->crtc);
996 X11_XRRFreeOutputInfo(output_info);
997 X11_XRRFreeScreenResources(res);
1001 status = X11_XRRSetCrtcConfig (display, res, output_info->crtc, CurrentTime,
1002 crtc->x, crtc->y, modedata->xrandr_mode, crtc->rotation,
1003 &data->xrandr_output, 1);
1005 X11_XRRFreeCrtcInfo(crtc);
1006 X11_XRRFreeOutputInfo(output_info);
1007 X11_XRRFreeScreenResources(res);
1009 if (status != Success) {
1015 #if SDL_VIDEO_DRIVER_X11_XVIDMODE 1017 X11_XF86VidModeSwitchToMode(display, data->vidmode_screen, &modedata->vm_mode);
1044 XineramaScreenInfo *xinerama = X11_XineramaQueryScreens(display, &screencount);
1046 rect->
x = xinerama[data->xinerama_screen].x_org;
1047 rect->
y = xinerama[data->xinerama_screen].y_org;
1048 X11_XFree(xinerama);
1077 Display *display = data->
display;
1079 int status, real_format;
1082 unsigned long items_read = 0, items_left = 0;
1083 unsigned char *propdata =
NULL;
1089 _NET_WORKAREA = X11_XInternAtom(display,
"_NET_WORKAREA", False);
1090 status = X11_XGetWindowProperty(display, DefaultRootWindow(display),
1091 _NET_WORKAREA, 0L, 4L, False, XA_CARDINAL,
1092 &real_type, &real_format, &items_read,
1093 &items_left, &propdata);
1094 if ((status == Success) && (items_read >= 4)) {
1095 const long *p = (
long*) propdata;
1096 const SDL_Rect usable = { (int)p[0], (
int)p[1], (int)p[2], (
int)p[3] };
1104 X11_XFree(propdata);
Uint32 X11_GetPixelFormatFromVisualInfo(Display *display, XVisualInfo *vinfo)
char dsc_product_name[14]
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)
The structure that defines a display mode.
#define SDL_BYTESPERPIXEL(X)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
#define SDL_IntersectRect
int SDL_AddVideoDisplay(const SDL_VideoDisplay *display)
GLuint const GLchar * name
#define SDL_GetHintBoolean
int X11_GetDisplayBounds(_THIS, SDL_VideoDisplay *sdl_display, SDL_Rect *rect)
static SDL_VideoDevice * _this
void dump_monitor_info(MonitorInfo *info)
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
int X11_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay *sdl_display, SDL_Rect *rect)
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.