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)
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_XRRGetScreenResources(dpy, RootWindow(dpy, screen));
404 for (output = 0; output < res->noutput; output++) {
405 XRROutputInfo *output_info;
406 int display_x, display_y;
407 unsigned long display_mm_width, display_mm_height;
409 char display_name[128];
418 if ((looking_for_primary && (res->outputs[output] != primary)) ||
419 (!looking_for_primary && (screen == default_screen) && (res->outputs[output] == primary))) {
423 output_info = X11_XRRGetOutputInfo(dpy, res, res->outputs[output]);
424 if (!output_info || !output_info->crtc || output_info->connection == RR_Disconnected) {
425 X11_XRRFreeOutputInfo(output_info);
429 SDL_strlcpy(display_name, output_info->name,
sizeof(display_name));
430 display_mm_width = output_info->mm_width;
431 display_mm_height = output_info->mm_height;
432 output_crtc = output_info->crtc;
433 X11_XRRFreeOutputInfo(output_info);
435 crtc = X11_XRRGetCrtcInfo(dpy, res, output_crtc);
442 mode.
w = crtc->width;
443 mode.
h = crtc->height;
444 mode.
format = pixelformat;
449 X11_XRRFreeCrtcInfo(crtc);
461 modedata->xrandr_mode = modeID;
465 displaydata->
visual = vinfo.visual;
466 displaydata->
depth = vinfo.depth;
467 displaydata->
hdpi = ((float) mode.
w) * 25.4f / display_mm_width;
468 displaydata->
vdpi = ((float) mode.
h) * 25.4f / display_mm_height;
471 displaydata->
x = display_x;
472 displaydata->
y = display_y;
474 displaydata->xrandr_output = res->outputs[
output];
476 SetXRandRModeInfo(dpy, res, output_crtc, modeID, &mode);
477 SetXRandRDisplayName(dpy, EDID, display_name,
sizeof (display_name), res->outputs[output], display_mm_width, display_mm_height);
481 display.
name = display_name;
489 X11_XRRFreeScreenResources(res);
501 #if SDL_VIDEO_DRIVER_X11_XVIDMODE 503 CheckVidMode(Display * display,
int *major,
int *minor)
510 #ifdef X11MODES_DEBUG 511 printf(
"XVidMode disabled due to hint\n");
516 if (!SDL_X11_HAVE_XVIDMODE) {
517 #ifdef X11MODES_DEBUG 518 printf(
"XVidMode support not available\n");
525 if (!X11_XF86VidModeQueryExtension(display, &vm_event, &vm_error)
526 || !X11_XF86VidModeQueryVersion(display, major, minor)) {
527 #ifdef X11MODES_DEBUG 528 printf(
"XVidMode not active on the display\n");
532 #ifdef X11MODES_DEBUG 533 printf(
"XVidMode available at version %d.%d!\n", *major, *minor);
539 Bool XF86VidModeGetModeInfo(Display * dpy,
int scr,
540 XF86VidModeModeInfo* info)
544 XF86VidModeModeLine l;
547 retval = X11_XF86VidModeGetModeLine(dpy, scr, &dotclock, &l);
548 info->dotclock = dotclock;
549 info->hdisplay = l.hdisplay;
550 info->hsyncstart = l.hsyncstart;
551 info->hsyncend = l.hsyncend;
552 info->htotal = l.htotal;
553 info->hskew = l.hskew;
554 info->vdisplay = l.vdisplay;
555 info->vsyncstart = l.vsyncstart;
556 info->vsyncend = l.vsyncend;
557 info->vtotal = l.vtotal;
558 info->flags = l.flags;
559 info->privsize = l.privsize;
560 info->private = l.private;
565 CalculateXVidModeRefreshRate(
const XF86VidModeModeInfo * info)
568 && info->vtotal) ? (1000 * info->dotclock / (info->htotal *
573 SetXVidModeModeInfo(
const XF86VidModeModeInfo *info,
SDL_DisplayMode *mode)
575 mode->
w = info->hdisplay;
576 mode->
h = info->vdisplay;
577 mode->
refresh_rate = CalculateXVidModeRefreshRate(info);
587 int snum, screen, screencount;
589 int xinerama_major, xinerama_minor;
590 int use_xinerama = 0;
591 XineramaScreenInfo *xinerama =
NULL;
594 int xrandr_major, xrandr_minor;
597 int vm_major, vm_minor;
605 if (CheckXRandR(data->
display, &xrandr_major, &xrandr_minor) &&
606 (xrandr_major >= 2 || (xrandr_major == 1 && xrandr_minor >= 3))) {
607 return X11_InitModes_XRandR(
_this);
618 #if SDL_VIDEO_DRIVER_X11_XRANDR 619 return SDL_SetError(
"XRandR support is required but not available");
621 return SDL_SetError(
"XRandR support is required but not built into SDL!");
626 #if SDL_VIDEO_DRIVER_X11_XINERAMA 631 if (CheckXinerama(data->
display, &xinerama_major, &xinerama_minor)) {
632 int (*handler) (Display *, XErrorEvent *);
633 X11_XSync(data->
display, False);
634 handler = X11_XSetErrorHandler(X11_XineramaFailed);
635 xinerama = X11_XineramaQueryScreens(data->
display, &screencount);
636 X11_XSync(data->
display, False);
637 X11_XSetErrorHandler(handler);
638 if (xinerama_triggered_error) {
642 use_xinerama = xinerama_major * 100 + xinerama_minor;
646 screencount = ScreenCount(data->
display);
649 screencount = ScreenCount(data->
display);
652 #if SDL_VIDEO_DRIVER_X11_XVIDMODE 653 if (CheckVidMode(data->
display, &vm_major, &vm_minor)) {
654 use_vidmode = vm_major * 100 + vm_minor;
658 for (snum = 0; snum < screencount; ++snum) {
664 XPixmapFormatValues *pixmapFormats;
665 char display_name[128];
670 screen = DefaultScreen(data->
display);
671 }
else if (snum == DefaultScreen(data->
display)) {
677 #if SDL_VIDEO_DRIVER_X11_XINERAMA 679 if (get_visualinfo(data->
display, 0, &vinfo) < 0) {
683 if (get_visualinfo(data->
display, screen, &vinfo) < 0) {
688 if (get_visualinfo(data->
display, screen, &vinfo) < 0) {
697 display_name[0] =
'\0';
705 #if SDL_VIDEO_DRIVER_X11_XINERAMA 707 mode.
w = xinerama[
screen].width;
708 mode.
h = xinerama[
screen].height;
710 mode.
w = DisplayWidth(data->
display, screen);
711 mode.
h = DisplayHeight(data->
display, screen);
714 mode.
w = DisplayWidth(data->
display, screen);
715 mode.
h = DisplayHeight(data->
display, screen);
726 #if SDL_VIDEO_DRIVER_X11_XINERAMA 734 displaydata->xinerama_info = xinerama[
screen];
735 displaydata->xinerama_screen =
screen;
741 displaydata->
visual = vinfo.visual;
742 displaydata->
depth = vinfo.depth;
747 displaydata->
hdpi = (float)DisplayWidth(data->
display, displaydata->
screen) * 25.4f /
749 displaydata->
vdpi = (float)DisplayHeight(data->
display, displaydata->
screen) * 25.4f /
753 (
float)DisplayWidthMM(data->
display, displaydata->
screen) / 25.4f,
754 (
float)DisplayHeightMM(data->
display, displaydata->
screen) / 25.4f);
757 pixmapFormats = X11_XListPixmapFormats(data->
display, &n);
759 for (i = 0; i <
n; ++
i) {
760 if (pixmapFormats[i].depth == displaydata->
depth) {
765 X11_XFree(pixmapFormats);
768 #if SDL_VIDEO_DRIVER_X11_XINERAMA 770 displaydata->
x = xinerama[
screen].x_org;
771 displaydata->
y = xinerama[
screen].y_org;
780 #if SDL_VIDEO_DRIVER_X11_XVIDMODE 785 (displaydata->
x == 0 && displaydata->
y == 0)) &&
790 displaydata->vidmode_screen = 0;
792 displaydata->vidmode_screen =
screen;
794 XF86VidModeGetModeInfo(data->
display, displaydata->vidmode_screen, &modedata->vm_mode);
800 display.
name = display_name;
808 #if SDL_VIDEO_DRIVER_X11_XINERAMA 809 if (xinerama) X11_XFree(xinerama);
825 XF86VidModeModeInfo ** modes;
840 screen_w = DisplayWidth(display, data->
screen);
841 screen_h = DisplayHeight(display, data->
screen);
843 #if SDL_VIDEO_DRIVER_X11_XINERAMA 845 if (data->
use_vidmode && !data->xinerama_info.x_org && !data->xinerama_info.y_org &&
846 (screen_w > data->xinerama_info.width || screen_h > data->xinerama_info.height)) {
867 mode.
w = data->xinerama_info.width;
868 mode.
h = data->xinerama_info.height;
883 #if SDL_VIDEO_DRIVER_X11_XRANDR 885 XRRScreenResources *
res;
887 res = X11_XRRGetScreenResources (display, RootWindow(display, data->
screen));
890 XRROutputInfo *output_info;
893 output_info = X11_XRRGetOutputInfo(display, res, data->xrandr_output);
894 if (output_info && output_info->connection != RR_Disconnected) {
895 for (i = 0; i < output_info->nmode; ++
i) {
902 if (!SetXRandRModeInfo(display, res, output_info->crtc, output_info->modes[i], &mode) ||
908 X11_XRRFreeOutputInfo(output_info);
909 X11_XRRFreeScreenResources(res);
915 #if SDL_VIDEO_DRIVER_X11_XVIDMODE 917 X11_XF86VidModeGetAllModeLines(display, data->vidmode_screen, &nmodes, &modes)) {
921 #ifdef X11MODES_DEBUG 922 printf(
"VidMode modes: (unsorted)\n");
923 for (i = 0; i < nmodes; ++
i) {
924 printf(
"Mode %d: %d x %d @ %d, flags: 0x%x\n", i,
925 modes[i]->hdisplay, modes[i]->vdisplay,
926 CalculateXVidModeRefreshRate(modes[i]), modes[i]->
flags);
929 for (i = 0; i < nmodes; ++
i) {
936 if (!SetXVidModeModeInfo(modes[i], &mode) || !
SDL_AddDisplayMode(sdl_display, &mode)) {
964 Display *display = viddata->
display;
970 #if SDL_VIDEO_DRIVER_X11_XRANDR 972 XRRScreenResources *
res;
973 XRROutputInfo *output_info;
977 res = X11_XRRGetScreenResources (display, RootWindow(display, data->
screen));
979 return SDL_SetError(
"Couldn't get XRandR screen resources");
982 output_info = X11_XRRGetOutputInfo(display, res, data->xrandr_output);
983 if (!output_info || output_info->connection == RR_Disconnected) {
984 X11_XRRFreeScreenResources(res);
988 crtc = X11_XRRGetCrtcInfo(display, res, output_info->crtc);
990 X11_XRRFreeOutputInfo(output_info);
991 X11_XRRFreeScreenResources(res);
995 status = X11_XRRSetCrtcConfig (display, res, output_info->crtc, CurrentTime,
996 crtc->x, crtc->y, modedata->xrandr_mode, crtc->rotation,
997 &data->xrandr_output, 1);
999 X11_XRRFreeCrtcInfo(crtc);
1000 X11_XRRFreeOutputInfo(output_info);
1001 X11_XRRFreeScreenResources(res);
1003 if (status != Success) {
1009 #if SDL_VIDEO_DRIVER_X11_XVIDMODE 1011 X11_XF86VidModeSwitchToMode(display, data->vidmode_screen, &modedata->vm_mode);
1038 XineramaScreenInfo *xinerama = X11_XineramaQueryScreens(display, &screencount);
1040 rect->
x = xinerama[data->xinerama_screen].x_org;
1041 rect->
y = xinerama[data->xinerama_screen].y_org;
1042 X11_XFree(xinerama);
1071 Display *display = data->
display;
1073 int status, real_format;
1076 unsigned long items_read = 0, items_left = 0;
1077 unsigned char *propdata =
NULL;
1083 _NET_WORKAREA = X11_XInternAtom(display,
"_NET_WORKAREA", False);
1084 status = X11_XGetWindowProperty(display, DefaultRootWindow(display),
1085 _NET_WORKAREA, 0L, 4L, False, XA_CARDINAL,
1086 &real_type, &real_format, &items_read,
1087 &items_left, &propdata);
1088 if ((status == Success) && (items_read >= 4)) {
1089 const long *p = (
long*) propdata;
1090 const SDL_Rect usable = { (int)p[0], (
int)p[1], (int)p[2], (
int)p[3] };
1098 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)
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
uint32_t Uint32
An unsigned 32-bit integer type.
#define SDL_IntersectRect
int SDL_AddVideoDisplay(const SDL_VideoDisplay *display)
#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.