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 static int vm_event, vm_error = -1;
154 #if SDL_VIDEO_DRIVER_X11_XINERAMA 156 CheckXinerama(Display * display,
int *major,
int *minor)
166 #ifdef X11MODES_DEBUG 167 printf(
"Xinerama disabled due to hint\n");
172 if (!SDL_X11_HAVE_XINERAMA) {
173 #ifdef X11MODES_DEBUG 174 printf(
"Xinerama support not available\n");
180 if (!X11_XineramaQueryExtension(display, &event_base, &error_base) ||
181 !X11_XineramaQueryVersion(display, major, minor) ||
182 !X11_XineramaIsActive(display)) {
183 #ifdef X11MODES_DEBUG 184 printf(
"Xinerama not active on the display\n");
188 #ifdef X11MODES_DEBUG 189 printf(
"Xinerama available at version %d.%d!\n", *major, *minor);
199 X11_XineramaFailed(Display *
d, XErrorEvent *
e)
201 xinerama_triggered_error =
SDL_TRUE;
202 fprintf(stderr,
"XINERAMA X ERROR: type=%d serial=%lu err=%u req=%u minor=%u\n",
203 e->type, e->serial, (
unsigned int) e->error_code,
204 (
unsigned int) e->request_code, (
unsigned int) e->minor_code);
210 #if SDL_VIDEO_DRIVER_X11_XRANDR 212 CheckXRandR(Display * display,
int *major,
int *minor)
218 #ifdef XRANDR_DISABLED_BY_DEFAULT 220 #ifdef X11MODES_DEBUG 221 printf(
"XRandR disabled by default due to window manager issues\n");
227 #ifdef X11MODES_DEBUG 228 printf(
"XRandR disabled due to hint\n");
234 if (!SDL_X11_HAVE_XRANDR) {
235 #ifdef X11MODES_DEBUG 236 printf(
"XRandR support not available\n");
242 *major = 1; *minor = 3;
243 if (!X11_XRRQueryVersion(display, major, minor)) {
244 #ifdef X11MODES_DEBUG 245 printf(
"XRandR not active on the display\n");
250 #ifdef X11MODES_DEBUG 251 printf(
"XRandR available at version %d.%d!\n", *major, *minor);
256 #define XRANDR_ROTATION_LEFT (1 << 1) 257 #define XRANDR_ROTATION_RIGHT (1 << 3) 260 CalculateXRandRRefreshRate(
const XRRModeInfo *info)
262 return (info->hTotal && info->vTotal) ?
263 round(((
double)info->dotClock / (
double)(info->hTotal * info->vTotal))) : 0;
267 SetXRandRModeInfo(Display *display, XRRScreenResources *
res, RRCrtc crtc,
271 for (i = 0; i < res->nmode; ++
i) {
272 const XRRModeInfo *info = &res->modes[
i];
273 if (info->id == modeID) {
274 XRRCrtcInfo *crtcinfo;
275 Rotation rotation = 0;
277 crtcinfo = X11_XRRGetCrtcInfo(display, res, crtc);
279 rotation = crtcinfo->rotation;
280 X11_XRRFreeCrtcInfo(crtcinfo);
283 if (rotation & (XRANDR_ROTATION_LEFT|XRANDR_ROTATION_RIGHT)) {
284 mode->
w = info->height;
285 mode->
h = info->width;
287 mode->
w = info->width;
288 mode->
h = info->height;
292 #ifdef X11MODES_DEBUG 293 printf(
"XRandR mode %d: %dx%d@%dHz\n", (
int) modeID, mode->
w, mode->
h, mode->
refresh_rate);
302 SetXRandRDisplayName(Display *
dpy, Atom EDID,
char *
name,
const size_t namelen, RROutput
output,
const unsigned long widthmm,
const unsigned long heightmm)
307 Atom *
props = X11_XRRListOutputProperties(dpy, output, &nprop);
310 for (i = 0; i < nprop; ++
i) {
313 unsigned long nitems, bytes_after;
316 if (props[i] == EDID) {
317 if (X11_XRRGetOutputProperty(dpy, output, props[i], 0, 100, False,
318 False, AnyPropertyType, &actual_type,
319 &actual_format, &nitems, &bytes_after,
323 #ifdef X11MODES_DEBUG 324 printf(
"Found EDID data for %s\n", name);
340 inches = (int)((
SDL_sqrtf(widthmm * widthmm + heightmm * heightmm) / 25.4
f) + 0.5f);
341 if (*name && inches) {
346 #ifdef X11MODES_DEBUG 347 printf(
"Display name: %s\n", name);
353 X11_InitModes_XRandR(
_THIS)
357 const int screencount = ScreenCount(dpy);
358 const int default_screen = DefaultScreen(dpy);
359 RROutput primary = X11_XRRGetOutputPrimary(dpy, RootWindow(dpy, default_screen));
360 Atom EDID = X11_XInternAtom(dpy,
"EDID", False);
361 XRRScreenResources *res =
NULL;
364 XPixmapFormatValues *pixmapformats;
365 int looking_for_primary;
370 for (looking_for_primary = 1; looking_for_primary >= 0; looking_for_primary--) {
371 for (screen = 0; screen < screencount; screen++) {
374 if (looking_for_primary && (screen != default_screen)) {
378 if (get_visualinfo(dpy, screen, &vinfo) < 0) {
388 pixmapformats = X11_XListPixmapFormats(dpy, &n);
390 for (i = 0; i <
n; ++
i) {
391 if (pixmapformats[i].depth == vinfo.depth) {
392 scanline_pad = pixmapformats[
i].scanline_pad;
396 X11_XFree(pixmapformats);
399 res = X11_XRRGetScreenResourcesCurrent(dpy, RootWindow(dpy, screen));
400 if (!res || res->noutput == 0) {
402 X11_XRRFreeScreenResources(res);
405 res = X11_XRRGetScreenResources(dpy, RootWindow(dpy, screen));
411 for (output = 0; output < res->noutput; output++) {
412 XRROutputInfo *output_info;
413 int display_x, display_y;
414 unsigned long display_mm_width, display_mm_height;
416 char display_name[128];
425 if ((looking_for_primary && (res->outputs[output] != primary)) ||
426 (!looking_for_primary && (screen == default_screen) && (res->outputs[output] == primary))) {
430 output_info = X11_XRRGetOutputInfo(dpy, res, res->outputs[output]);
431 if (!output_info || !output_info->crtc || output_info->connection == RR_Disconnected) {
432 X11_XRRFreeOutputInfo(output_info);
436 SDL_strlcpy(display_name, output_info->name,
sizeof(display_name));
437 display_mm_width = output_info->mm_width;
438 display_mm_height = output_info->mm_height;
439 output_crtc = output_info->crtc;
440 X11_XRRFreeOutputInfo(output_info);
442 crtc = X11_XRRGetCrtcInfo(dpy, res, output_crtc);
449 mode.
w = crtc->width;
450 mode.
h = crtc->height;
451 mode.
format = pixelformat;
456 X11_XRRFreeCrtcInfo(crtc);
468 modedata->xrandr_mode = modeID;
472 displaydata->
visual = vinfo.visual;
473 displaydata->
depth = vinfo.depth;
474 displaydata->
hdpi = display_mm_width ? (((float) mode.
w) * 25.4f / display_mm_width) : 0.0
f;
475 displaydata->
vdpi = display_mm_height ? (((float) mode.
h) * 25.4f / display_mm_height) : 0.0
f;
478 displaydata->
x = display_x;
479 displaydata->
y = display_y;
481 displaydata->xrandr_output = res->outputs[
output];
483 SetXRandRModeInfo(dpy, res, output_crtc, modeID, &mode);
484 SetXRandRDisplayName(dpy, EDID, display_name,
sizeof (display_name), res->outputs[output], display_mm_width, display_mm_height);
488 display.
name = display_name;
496 X11_XRRFreeScreenResources(res);
508 #if SDL_VIDEO_DRIVER_X11_XVIDMODE 510 CheckVidMode(Display * display,
int *major,
int *minor)
517 #ifdef X11MODES_DEBUG 518 printf(
"XVidMode disabled due to hint\n");
523 if (!SDL_X11_HAVE_XVIDMODE) {
524 #ifdef X11MODES_DEBUG 525 printf(
"XVidMode support not available\n");
532 if (!X11_XF86VidModeQueryExtension(display, &vm_event, &vm_error)
533 || !X11_XF86VidModeQueryVersion(display, major, minor)) {
534 #ifdef X11MODES_DEBUG 535 printf(
"XVidMode not active on the display\n");
539 #ifdef X11MODES_DEBUG 540 printf(
"XVidMode available at version %d.%d!\n", *major, *minor);
546 Bool XF86VidModeGetModeInfo(Display * dpy,
int scr,
547 XF86VidModeModeInfo* info)
551 XF86VidModeModeLine l;
554 retval = X11_XF86VidModeGetModeLine(dpy, scr, &dotclock, &l);
555 info->dotclock = dotclock;
556 info->hdisplay = l.hdisplay;
557 info->hsyncstart = l.hsyncstart;
558 info->hsyncend = l.hsyncend;
559 info->htotal = l.htotal;
560 info->hskew = l.hskew;
561 info->vdisplay = l.vdisplay;
562 info->vsyncstart = l.vsyncstart;
563 info->vsyncend = l.vsyncend;
564 info->vtotal = l.vtotal;
565 info->flags = l.flags;
566 info->privsize = l.privsize;
567 info->private = l.private;
572 CalculateXVidModeRefreshRate(
const XF86VidModeModeInfo * info)
575 && info->vtotal) ? (1000 * info->dotclock / (info->htotal *
580 SetXVidModeModeInfo(
const XF86VidModeModeInfo *info,
SDL_DisplayMode *mode)
582 mode->
w = info->hdisplay;
583 mode->
h = info->vdisplay;
584 mode->
refresh_rate = CalculateXVidModeRefreshRate(info);
594 int snum, screen, screencount = 0;
596 int xinerama_major, xinerama_minor;
597 int use_xinerama = 0;
598 XineramaScreenInfo *xinerama =
NULL;
601 int xrandr_major, xrandr_minor;
604 int vm_major, vm_minor;
612 if (CheckXRandR(data->
display, &xrandr_major, &xrandr_minor) &&
613 (xrandr_major >= 2 || (xrandr_major == 1 && xrandr_minor >= 3))) {
614 if (X11_InitModes_XRandR(
_this) == 0)
626 #if SDL_VIDEO_DRIVER_X11_XRANDR 627 return SDL_SetError(
"XRandR support is required but not available");
629 return SDL_SetError(
"XRandR support is required but not built into SDL!");
634 #if SDL_VIDEO_DRIVER_X11_XINERAMA 639 if (CheckXinerama(data->
display, &xinerama_major, &xinerama_minor)) {
640 int (*handler) (Display *, XErrorEvent *);
641 X11_XSync(data->
display, False);
642 handler = X11_XSetErrorHandler(X11_XineramaFailed);
643 xinerama = X11_XineramaQueryScreens(data->
display, &screencount);
644 X11_XSync(data->
display, False);
645 X11_XSetErrorHandler(handler);
646 if (xinerama_triggered_error) {
650 use_xinerama = xinerama_major * 100 + xinerama_minor;
654 screencount = ScreenCount(data->
display);
657 screencount = ScreenCount(data->
display);
660 #if SDL_VIDEO_DRIVER_X11_XVIDMODE 661 if (CheckVidMode(data->
display, &vm_major, &vm_minor)) {
662 use_vidmode = vm_major * 100 + vm_minor;
666 for (snum = 0; snum < screencount; ++snum) {
672 XPixmapFormatValues *pixmapFormats;
673 char display_name[128];
678 screen = DefaultScreen(data->
display);
679 }
else if (snum == DefaultScreen(data->
display)) {
685 #if SDL_VIDEO_DRIVER_X11_XINERAMA 687 if (get_visualinfo(data->
display, 0, &vinfo) < 0) {
691 if (get_visualinfo(data->
display, screen, &vinfo) < 0) {
696 if (get_visualinfo(data->
display, screen, &vinfo) < 0) {
705 display_name[0] =
'\0';
713 #if SDL_VIDEO_DRIVER_X11_XINERAMA 715 mode.
w = xinerama[
screen].width;
716 mode.
h = xinerama[
screen].height;
718 mode.
w = DisplayWidth(data->
display, screen);
719 mode.
h = DisplayHeight(data->
display, screen);
722 mode.
w = DisplayWidth(data->
display, screen);
723 mode.
h = DisplayHeight(data->
display, screen);
734 #if SDL_VIDEO_DRIVER_X11_XINERAMA 742 displaydata->xinerama_info = xinerama[
screen];
743 displaydata->xinerama_screen =
screen;
749 displaydata->
visual = vinfo.visual;
750 displaydata->
depth = vinfo.depth;
755 displaydata->
hdpi = (float)DisplayWidth(data->
display, displaydata->
screen) * 25.4f /
757 displaydata->
vdpi = (float)DisplayHeight(data->
display, displaydata->
screen) * 25.4f /
761 (
float)DisplayWidthMM(data->
display, displaydata->
screen) / 25.4f,
762 (
float)DisplayHeightMM(data->
display, displaydata->
screen) / 25.4f);
765 pixmapFormats = X11_XListPixmapFormats(data->
display, &n);
767 for (i = 0; i <
n; ++
i) {
768 if (pixmapFormats[i].depth == displaydata->
depth) {
773 X11_XFree(pixmapFormats);
776 #if SDL_VIDEO_DRIVER_X11_XINERAMA 778 displaydata->
x = xinerama[
screen].x_org;
779 displaydata->
y = xinerama[
screen].y_org;
788 #if SDL_VIDEO_DRIVER_X11_XVIDMODE 793 (displaydata->
x == 0 && displaydata->
y == 0)) &&
798 displaydata->vidmode_screen = 0;
800 displaydata->vidmode_screen =
screen;
802 XF86VidModeGetModeInfo(data->
display, displaydata->vidmode_screen, &modedata->vm_mode);
808 display.
name = display_name;
816 #if SDL_VIDEO_DRIVER_X11_XINERAMA 817 if (xinerama) X11_XFree(xinerama);
833 XF86VidModeModeInfo ** modes;
851 screen_w = DisplayWidth(display, data->
screen);
852 screen_h = DisplayHeight(display, data->
screen);
854 if (data->
use_vidmode && !data->xinerama_info.x_org && !data->xinerama_info.y_org &&
855 (screen_w > data->xinerama_info.width || screen_h > data->xinerama_info.height)) {
876 mode.
w = data->xinerama_info.width;
877 mode.
h = data->xinerama_info.height;
892 #if SDL_VIDEO_DRIVER_X11_XRANDR 894 XRRScreenResources *
res;
896 res = X11_XRRGetScreenResources (display, RootWindow(display, data->
screen));
899 XRROutputInfo *output_info;
902 output_info = X11_XRRGetOutputInfo(display, res, data->xrandr_output);
903 if (output_info && output_info->connection != RR_Disconnected) {
904 for (i = 0; i < output_info->nmode; ++
i) {
911 if (!SetXRandRModeInfo(display, res, output_info->crtc, output_info->modes[i], &mode) ||
917 X11_XRRFreeOutputInfo(output_info);
918 X11_XRRFreeScreenResources(res);
924 #if SDL_VIDEO_DRIVER_X11_XVIDMODE 926 X11_XF86VidModeGetAllModeLines(display, data->vidmode_screen, &nmodes, &modes)) {
930 #ifdef X11MODES_DEBUG 931 printf(
"VidMode modes: (unsorted)\n");
932 for (i = 0; i < nmodes; ++
i) {
933 printf(
"Mode %d: %d x %d @ %d, flags: 0x%x\n", i,
934 modes[i]->hdisplay, modes[i]->vdisplay,
935 CalculateXVidModeRefreshRate(modes[i]), modes[i]->
flags);
938 for (i = 0; i < nmodes; ++
i) {
945 if (!SetXVidModeModeInfo(modes[i], &mode) || !
SDL_AddDisplayMode(sdl_display, &mode)) {
973 Display *display = viddata->
display;
979 #if SDL_VIDEO_DRIVER_X11_XRANDR 981 XRRScreenResources *
res;
982 XRROutputInfo *output_info;
986 res = X11_XRRGetScreenResources (display, RootWindow(display, data->
screen));
988 return SDL_SetError(
"Couldn't get XRandR screen resources");
991 output_info = X11_XRRGetOutputInfo(display, res, data->xrandr_output);
992 if (!output_info || output_info->connection == RR_Disconnected) {
993 X11_XRRFreeScreenResources(res);
997 crtc = X11_XRRGetCrtcInfo(display, res, output_info->crtc);
999 X11_XRRFreeOutputInfo(output_info);
1000 X11_XRRFreeScreenResources(res);
1004 status = X11_XRRSetCrtcConfig (display, res, output_info->crtc, CurrentTime,
1005 crtc->x, crtc->y, modedata->xrandr_mode, crtc->rotation,
1006 &data->xrandr_output, 1);
1008 X11_XRRFreeCrtcInfo(crtc);
1009 X11_XRRFreeOutputInfo(output_info);
1010 X11_XRRFreeScreenResources(res);
1012 if (status != Success) {
1018 #if SDL_VIDEO_DRIVER_X11_XVIDMODE 1020 X11_XF86VidModeSwitchToMode(display, data->vidmode_screen, &modedata->vm_mode);
1047 XineramaScreenInfo *xinerama = X11_XineramaQueryScreens(display, &screencount);
1049 rect->
x = xinerama[data->xinerama_screen].x_org;
1050 rect->
y = xinerama[data->xinerama_screen].y_org;
1051 X11_XFree(xinerama);
1080 Display *display = data->
display;
1082 int status, real_format;
1085 unsigned long items_read = 0, items_left = 0;
1086 unsigned char *propdata =
NULL;
1092 _NET_WORKAREA = X11_XInternAtom(display,
"_NET_WORKAREA", False);
1093 status = X11_XGetWindowProperty(display, DefaultRootWindow(display),
1094 _NET_WORKAREA, 0L, 4L, False, XA_CARDINAL,
1095 &real_type, &real_format, &items_read,
1096 &items_left, &propdata);
1097 if ((status == Success) && (items_read >= 4)) {
1098 const long *p = (
long*) propdata;
1099 const SDL_Rect usable = { (int)p[0], (
int)p[1], (int)p[2], (
int)p[3] };
1107 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
uint32_t Uint32
An unsigned 32-bit integer type.
#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 * 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
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.