zenilib: zenilib/jni/external/sdl/src/video/x11/SDL_x11modes.c Source File

zenilib 0.5.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_x11modes.c
Go to the documentation of this file.
1 /*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "SDL_config.h"
22
23 #if SDL_VIDEO_DRIVER_X11
24
25 #include "SDL_hints.h"
26 #include "SDL_x11video.h"
27 #include "edid.h"
28
29 /* #define X11MODES_DEBUG */
30
31 /* I'm becoming more and more convinced that the application should never
32 * use XRandR, and it's the window manager's responsibility to track and
33 * manage display modes for fullscreen windows. Right now XRandR is completely
34 * broken with respect to window manager behavior on every window manager that
35 * I can find. For example, on Unity 3D if you show a fullscreen window while
36 * the resolution is changing (within ~250 ms) your window will retain the
37 * fullscreen state hint but be decorated and windowed.
38 *
39 * However, many people swear by it, so let them swear at it. :)
40 */
41 /* #define XRANDR_DISABLED_BY_DEFAULT */
42
43
44 static int
45 get_visualinfo(Display * display, int screen, XVisualInfo * vinfo)
46 {
47 const char *visual_id = SDL_getenv("SDL_VIDEO_X11_VISUALID");
48 int depth;
49
50 /* Look for an exact visual, if requested */
51 if (visual_id) {
52 XVisualInfo *vi, template;
53 int nvis;
54
55 SDL_zero(template);
56 template.visualid = SDL_strtol(visual_id, NULL, 0);
57 vi = XGetVisualInfo(display, VisualIDMask, &template, &nvis);
58 if (vi) {
59 *vinfo = *vi;
60 XFree(vi);
61 return 0;
62 }
63 }
64
65 depth = DefaultDepth(display, screen);
66 if ((X11_UseDirectColorVisuals() &&
67 XMatchVisualInfo(display, screen, depth, DirectColor, vinfo)) ||
68 XMatchVisualInfo(display, screen, depth, TrueColor, vinfo) ||
69 XMatchVisualInfo(display, screen, depth, PseudoColor, vinfo) ||
70 XMatchVisualInfo(display, screen, depth, StaticColor, vinfo)) {
71 return 0;
72 }
73 return -1;
74 }
75
76 int
77 X11_GetVisualInfoFromVisual(Display * display, Visual * visual, XVisualInfo * vinfo)
78 {
79 XVisualInfo *vi;
80 int nvis;
81
82 vinfo->visualid = XVisualIDFromVisual(visual);
83 vi = XGetVisualInfo(display, VisualIDMask, vinfo, &nvis);
84 if (vi) {
85 *vinfo = *vi;
86 XFree(vi);
87 return 0;
88 }
89 return -1;
90 }
91
92 Uint32
93 X11_GetPixelFormatFromVisualInfo(Display * display, XVisualInfo * vinfo)
94 {
95 if (vinfo->class == DirectColor || vinfo->class == TrueColor) {
96 int bpp;
97 Uint32 Rmask, Gmask, Bmask, Amask;
98
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));
104 } else {
105 Amask = 0;
106 }
107
108 bpp = vinfo->depth;
109 if (bpp == 24) {
110 int i, n;
111 XPixmapFormatValues *p = XListPixmapFormats(display, &n);
112 if (p) {
113 for (i = 0; i < n; ++i) {
114 if (p[i].depth == 24) {
115 bpp = p[i].bits_per_pixel;
116 break;
117 }
118 }
119 XFree(p);
120 }
121 }
122
123 return SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask);
124 }
125
126 if (vinfo->class == PseudoColor || vinfo->class == StaticColor) {
127 switch (vinfo->depth) {
128 case 8:
129 return SDL_PIXELTYPE_INDEX8;
130 case 4:
131 if (BitmapBitOrder(display) == LSBFirst) {
132 return SDL_PIXELFORMAT_INDEX4LSB;
133 } else {
134 return SDL_PIXELFORMAT_INDEX4MSB;
135 }
136 break;
137 case 1:
138 if (BitmapBitOrder(display) == LSBFirst) {
139 return SDL_PIXELFORMAT_INDEX1LSB;
140 } else {
141 return SDL_PIXELFORMAT_INDEX1MSB;
142 }
143 break;
144 }
145 }
146
147 return SDL_PIXELFORMAT_UNKNOWN;
148 }
149
150 /* Global for the error handler */
151 int vm_event, vm_error = -1;
152
153 #if SDL_VIDEO_DRIVER_X11_XINERAMA
154 static SDL_bool
155 CheckXinerama(Display * display, int *major, int *minor)
156 {
157 int event_base = 0;
158 int error_base = 0;
159 const char *env;
160
161 /* Default the extension not available */
162 *major = *minor = 0;
163
164 /* Allow environment override */
165 env = SDL_GetHint(SDL_HINT_VIDEO_X11_XINERAMA);
166 if (env && !SDL_atoi(env)) {
167 #ifdef X11MODES_DEBUG
168 printf("Xinerama disabled due to hint\n");
169 #endif
170 return SDL_FALSE;
171 }
172
173 if (!SDL_X11_HAVE_XINERAMA) {
174 #ifdef X11MODES_DEBUG
175 printf("Xinerama support not available\n");
176 #endif
177 return SDL_FALSE;
178 }
179
180 /* Query the extension version */
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");
186 #endif
187 return SDL_FALSE;
188 }
189 #ifdef X11MODES_DEBUG
190 printf("Xinerama available at version %d.%d!\n", *major, *minor);
191 #endif
192 return SDL_TRUE;
193 }
194 #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
195
196 #if SDL_VIDEO_DRIVER_X11_XRANDR
197 static SDL_bool
198 CheckXRandR(Display * display, int *major, int *minor)
199 {
200 const char *env;
201
202 /* Default the extension not available */
203 *major = *minor = 0;
204
205 /* Allow environment override */
206 env = SDL_GetHint(SDL_HINT_VIDEO_X11_XRANDR);
207 #ifdef XRANDR_DISABLED_BY_DEFAULT
208 if (!env || !SDL_atoi(env)) {
209 #ifdef X11MODES_DEBUG
210 printf("XRandR disabled by default due to window manager issues\n");
211 #endif
212 return SDL_FALSE;
213 }
214 #else
215 if (env && !SDL_atoi(env)) {
216 #ifdef X11MODES_DEBUG
217 printf("XRandR disabled due to hint\n");
218 #endif
219 return SDL_FALSE;
220 }
221 #endif /* XRANDR_ENABLED_BY_DEFAULT */
222
223 if (!SDL_X11_HAVE_XRANDR) {
224 #ifdef X11MODES_DEBUG
225 printf("XRandR support not available\n");
226 #endif
227 return SDL_FALSE;
228 }
229
230 /* Query the extension version */
231 if (!XRRQueryVersion(display, major, minor)) {
232 #ifdef X11MODES_DEBUG
233 printf("XRandR not active on the display\n");
234 #endif
235 return SDL_FALSE;
236 }
237 #ifdef X11MODES_DEBUG
238 printf("XRandR available at version %d.%d!\n", *major, *minor);
239 #endif
240 return SDL_TRUE;
241 }
242
243 #define XRANDR_ROTATION_LEFT (1 << 1)
244 #define XRANDR_ROTATION_RIGHT (1 << 3)
245
246 static int
247 CalculateXRandRRefreshRate(const XRRModeInfo *info)
248 {
249 return (info->hTotal
250 && info->vTotal) ? (info->dotClock / (info->hTotal * info->vTotal)) : 0;
251 }
252
253 static SDL_bool
254 SetXRandRModeInfo(Display *display, XRRScreenResources *res, XRROutputInfo *output_info,
255 RRMode modeID, SDL_DisplayMode *mode)
256 {
257 int i;
258 for (i = 0; i < res->nmode; ++i) {
259 if (res->modes[i].id == modeID) {
260 XRRCrtcInfo *crtc;
261 Rotation rotation = 0;
262 const XRRModeInfo *info = &res->modes[i];
263
264 crtc = XRRGetCrtcInfo(display, res, output_info->crtc);
265 if (crtc) {
266 rotation = crtc->rotation;
267 XRRFreeCrtcInfo(crtc);
268 }
269
270 if (rotation & (XRANDR_ROTATION_LEFT|XRANDR_ROTATION_RIGHT)) {
271 mode->w = info->height;
272 mode->h = info->width;
273 } else {
274 mode->w = info->width;
275 mode->h = info->height;
276 }
277 mode->refresh_rate = CalculateXRandRRefreshRate(info);
278 ((SDL_DisplayModeData*)mode->driverdata)->xrandr_mode = modeID;
279 #ifdef X11MODES_DEBUG
280 printf("XRandR mode %d: %dx%d@%dHz\n", (int) modeID, mode->w, mode->h, mode->refresh_rate);
281 #endif
282 return SDL_TRUE;
283 }
284 }
285 return SDL_FALSE;
286 }
287 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
288
289 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
290 static SDL_bool
291 CheckVidMode(Display * display, int *major, int *minor)
292 {
293 const char *env;
294
295 /* Default the extension not available */
296 *major = *minor = 0;
297
298 /* Allow environment override */
299 env = SDL_GetHint(SDL_HINT_VIDEO_X11_XVIDMODE);
300 if (env && !SDL_atoi(env)) {
301 #ifdef X11MODES_DEBUG
302 printf("XVidMode disabled due to hint\n");
303 #endif
304 return SDL_FALSE;
305 }
306
307 if (!SDL_X11_HAVE_XVIDMODE) {
308 #ifdef X11MODES_DEBUG
309 printf("XVidMode support not available\n");
310 #endif
311 return SDL_FALSE;
312 }
313
314 /* Query the extension version */
315 vm_error = -1;
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");
320 #endif
321 return SDL_FALSE;
322 }
323 #ifdef X11MODES_DEBUG
324 printf("XVidMode available at version %d.%d!\n", *major, *minor);
325 #endif
326 return SDL_TRUE;
327 }
328
329 static
330 Bool XF86VidModeGetModeInfo(Display * dpy, int scr,
331 XF86VidModeModeInfo* info)
332 {
333 Bool retval;
334 int dotclock;
335 XF86VidModeModeLine l;
336 SDL_zerop(info);
337 SDL_zero(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;
352 return retval;
353 }
354
355 static int
356 CalculateXVidModeRefreshRate(const XF86VidModeModeInfo * info)
357 {
358 return (info->htotal
359 && info->vtotal) ? (1000 * info->dotclock / (info->htotal *
360 info->vtotal)) : 0;
361 }
362
363 SDL_bool
364 SetXVidModeModeInfo(const XF86VidModeModeInfo *info, SDL_DisplayMode *mode)
365 {
366 mode->w = info->hdisplay;
367 mode->h = info->vdisplay;
368 mode->refresh_rate = CalculateXVidModeRefreshRate(info);
369 ((SDL_DisplayModeData*)mode->driverdata)->vm_mode = *info;
370 return SDL_TRUE;
371 }
372 #endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
373
374 int
375 X11_InitModes(_THIS)
376 {
377 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
378 int screen, screencount;
379 #if SDL_VIDEO_DRIVER_X11_XINERAMA
380 int xinerama_major, xinerama_minor;
381 int use_xinerama = 0;
382 XineramaScreenInfo *xinerama = NULL;
383 #endif
384 #if SDL_VIDEO_DRIVER_X11_XRANDR
385 int xrandr_major, xrandr_minor;
386 int use_xrandr = 0;
387 XRRScreenResources *res = NULL;
388 #endif
389 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
390 int vm_major, vm_minor;
391 int use_vidmode = 0;
392 #endif
393
394 #if SDL_VIDEO_DRIVER_X11_XINERAMA
395 /* Query Xinerama extention
396 * NOTE: This works with Nvidia Twinview correctly, but you need version 302.17 (released on June 2012)
397 * or newer of the Nvidia binary drivers
398 */
399 if (CheckXinerama(data->display, &xinerama_major, &xinerama_minor)) {
400 xinerama = XineramaQueryScreens(data->display, &screencount);
401 if (xinerama) {
402 use_xinerama = xinerama_major * 100 + xinerama_minor;
403 }
404 }
405 if (!xinerama) {
406 screencount = ScreenCount(data->display);
407 }
408 #else
409 screencount = ScreenCount(data->display);
410 #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
411
412 #if SDL_VIDEO_DRIVER_X11_XRANDR
413 /* require at least XRandR v1.2 */
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;
417 }
418 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
419
420 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
421 if (CheckVidMode(data->display, &vm_major, &vm_minor)) {
422 use_vidmode = vm_major * 100 + vm_minor;
423 }
424 #endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
425
426 for (screen = 0; screen < screencount; ++screen) {
427 XVisualInfo vinfo;
428 SDL_VideoDisplay display;
429 SDL_DisplayData *displaydata;
430 SDL_DisplayMode mode;
431 SDL_DisplayModeData *modedata;
432 XPixmapFormatValues *pixmapFormats;
433 char display_name[128];
434 int i, n;
435
436 #if SDL_VIDEO_DRIVER_X11_XINERAMA
437 if (xinerama) {
438 if (get_visualinfo(data->display, 0, &vinfo) < 0) {
439 continue;
440 }
441 } else {
442 if (get_visualinfo(data->display, screen, &vinfo) < 0) {
443 continue;
444 }
445 }
446 #else
447 if (get_visualinfo(data->display, screen, &vinfo) < 0) {
448 continue;
449 }
450 #endif
451
452 displaydata = (SDL_DisplayData *) SDL_calloc(1, sizeof(*displaydata));
453 if (!displaydata) {
454 continue;
455 }
456 display_name[0] = '\0';
457
458 mode.format = X11_GetPixelFormatFromVisualInfo(data->display, &vinfo);
459 if (SDL_ISPIXELFORMAT_INDEXED(mode.format)) {
460 /* We don't support palettized modes now */
461 SDL_free(displaydata);
462 continue;
463 }
464 #if SDL_VIDEO_DRIVER_X11_XINERAMA
465 if (xinerama) {
466 mode.w = xinerama[screen].width;
467 mode.h = xinerama[screen].height;
468 } else {
469 mode.w = DisplayWidth(data->display, screen);
470 mode.h = DisplayHeight(data->display, screen);
471 }
472 #else
473 mode.w = DisplayWidth(data->display, screen);
474 mode.h = DisplayHeight(data->display, screen);
475 #endif
476 mode.refresh_rate = 0;
477
478 modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
479 if (!modedata) {
480 SDL_free(displaydata);
481 continue;
482 }
483 mode.driverdata = modedata;
484
485 #if SDL_VIDEO_DRIVER_X11_XINERAMA
486 /* Most of SDL's calls to X11 are unwaware of Xinerama, and to X11 standard calls, when Xinerama is active,
487 * there's only one screen available. So we force the screen number to zero and
488 * let Xinerama specific code handle specific functionality using displaydata->xinerama_info
489 */
490 if (use_xinerama) {
491 displaydata->screen = 0;
492 displaydata->use_xinerama = use_xinerama;
493 displaydata->xinerama_info = xinerama[screen];
494 displaydata->xinerama_screen = screen;
495 }
496 else displaydata->screen = screen;
497 #else
498 displaydata->screen = screen;
499 #endif
500 displaydata->visual = vinfo.visual;
501 displaydata->depth = vinfo.depth;
502
503 displaydata->scanline_pad = SDL_BYTESPERPIXEL(mode.format) * 8;
504 pixmapFormats = XListPixmapFormats(data->display, &n);
505 if (pixmapFormats) {
506 for (i = 0; i < n; ++i) {
507 if (pixmapFormats[i].depth == displaydata->depth) {
508 displaydata->scanline_pad = pixmapFormats[i].scanline_pad;
509 break;
510 }
511 }
512 XFree(pixmapFormats);
513 }
514
515 #if SDL_VIDEO_DRIVER_X11_XINERAMA
516 if (use_xinerama) {
517 displaydata->x = xinerama[screen].x_org;
518 displaydata->y = xinerama[screen].y_org;
519 }
520 else
521 #endif
522 {
523 displaydata->x = 0;
524 displaydata->y = 0;
525 }
526
527 #if SDL_VIDEO_DRIVER_X11_XRANDR
528 if (use_xrandr) {
529 res = XRRGetScreenResources(data->display, RootWindow(data->display, displaydata->screen));
530 }
531 if (res) {
532 XRROutputInfo *output_info;
533 XRRCrtcInfo *crtc;
534 int output;
535 Atom EDID = XInternAtom(data->display, "EDID", False);
536 Atom *props;
537 int nprop;
538 unsigned long width_mm;
539 unsigned long height_mm;
540 int inches = 0;
541
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);
547 continue;
548 }
549
550 /* Is this the output that corresponds to the current screen?
551 We're checking the crtc position, but that may not be a valid test
552 in all cases. Anybody want to give this some love?
553 */
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);
558 continue;
559 }
560
561 displaydata->use_xrandr = use_xrandr;
562 displaydata->xrandr_output = res->outputs[output];
563 SetXRandRModeInfo(data->display, res, output_info, crtc->mode, &mode);
564
565 /* Get the name of this display */
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.4f) + 0.5f);
570 SDL_strlcpy(display_name, output_info->name, sizeof(display_name));
571
572 /* See if we can get the EDID data for the real monitor name */
573 props = XRRListOutputProperties(data->display, res->outputs[output], &nprop);
574 for (i = 0; i < nprop; ++i) {
575 unsigned char *prop;
576 int actual_format;
577 unsigned long nitems, bytes_after;
578 Atom actual_type;
579
580 if (props[i] == EDID) {
581 if (XRRGetOutputProperty(data->display,
582 res->outputs[output], props[i],
583 0, 100, False, False,
584 AnyPropertyType,
585 &actual_type, &actual_format,
586 &nitems, &bytes_after, &prop) == Success ) {
587 MonitorInfo *info = decode_edid(prop);
588 if (info) {
589 #ifdef X11MODES_DEBUG
590 printf("Found EDID data for %s\n", output_info->name);
591 dump_monitor_info(info);
592 #endif
593 SDL_strlcpy(display_name, info->dsc_product_name, sizeof(display_name));
594 free(info);
595 }
596 XFree(prop);
597 }
598 break;
599 }
600 }
601 if (props) {
602 XFree(props);
603 }
604
605 if (*display_name && inches) {
606 size_t len = SDL_strlen(display_name);
607 SDL_snprintf(&display_name[len], sizeof(display_name)-len, " %d\"", inches);
608 }
609 #ifdef X11MODES_DEBUG
610 printf("Display name: %s\n", display_name);
611 #endif
612
613 XRRFreeOutputInfo(output_info);
614 XRRFreeCrtcInfo(crtc);
615 break;
616 }
617 #ifdef X11MODES_DEBUG
618 if (output == res->noutput) {
619 printf("Couldn't find XRandR CRTC at %d,%d\n", displaydata->x, displaydata->y);
620 }
621 #endif
622 XRRFreeScreenResources(res);
623 }
624 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
625
626 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
627 if (!displaydata->use_xrandr &&
628 #if SDL_VIDEO_DRIVER_X11_XINERAMA
629 /* XVidMode only works on the screen at the origin */
630 (!displaydata->use_xinerama ||
631 (displaydata->x == 0 && displaydata->y == 0)) &&
632 #endif
633 use_vidmode) {
634 displaydata->use_vidmode = use_vidmode;
635 if (displaydata->use_xinerama) {
636 displaydata->vidmode_screen = 0;
637 } else {
638 displaydata->vidmode_screen = screen;
639 }
640 XF86VidModeGetModeInfo(data->display, displaydata->vidmode_screen, &modedata->vm_mode);
641 }
642 #endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
643
644 SDL_zero(display);
645 if (*display_name) {
646 display.name = display_name;
647 }
648 display.desktop_mode = mode;
649 display.current_mode = mode;
650 display.driverdata = displaydata;
651 SDL_AddVideoDisplay(&display);
652 }
653
654 #if SDL_VIDEO_DRIVER_X11_XINERAMA
655 if (xinerama) XFree(xinerama);
656 #endif
657
658 if (_this->num_displays == 0) {
659 return SDL_SetError("No available displays");
660 }
661 return 0;
662 }
663
664 void
665 X11_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display)
666 {
667 Display *display = ((SDL_VideoData *) _this->driverdata)->display;
668 SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata;
669 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
670 int nmodes;
671 XF86VidModeModeInfo ** modes;
672 #endif
673 int screen_w;
674 int screen_h;
675 SDL_DisplayMode mode;
676 SDL_DisplayModeData *modedata;
677
678 /* Unfortunately X11 requires the window to be created with the correct
679 * visual and depth ahead of time, but the SDL API allows you to create
680 * a window before setting the fullscreen display mode. This means that
681 * we have to use the same format for all windows and all display modes.
682 * (or support recreating the window with a new visual behind the scenes)
683 */
684 mode.format = sdl_display->current_mode.format;
685 mode.driverdata = NULL;
686
687 screen_w = DisplayWidth(display, data->screen);
688 screen_h = DisplayHeight(display, data->screen);
689
690 #if SDL_VIDEO_DRIVER_X11_XINERAMA
691 if (data->use_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)) {
694 /* Add the full (both screens combined) xinerama mode only on the display that starts at 0,0
695 * if we're using vidmode.
696 */
697 mode.w = screen_w;
698 mode.h = screen_h;
699 mode.refresh_rate = 0;
700 modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
701 if (modedata) {
702 *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata;
703 }
704 mode.driverdata = modedata;
705 SDL_AddDisplayMode(sdl_display, &mode);
706 }
707 else if (!data->use_xrandr)
708 {
709 /* Add the current mode of each monitor otherwise if we can't get them from xrandr */
710 mode.w = data->xinerama_info.width;
711 mode.h = data->xinerama_info.height;
712 mode.refresh_rate = 0;
713 modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
714 if (modedata) {
715 *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata;
716 }
717 mode.driverdata = modedata;
718 SDL_AddDisplayMode(sdl_display, &mode);
719 }
720
721 }
722 #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
723
724 #if SDL_VIDEO_DRIVER_X11_XRANDR
725 if (data->use_xrandr) {
726 XRRScreenResources *res;
727
728 res = XRRGetScreenResources (display, RootWindow(display, data->screen));
729 if (res) {
730 SDL_DisplayModeData *modedata;
731 XRROutputInfo *output_info;
732 int i;
733
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) {
737 modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
738 if (!modedata) {
739 continue;
740 }
741 mode.driverdata = modedata;
742
743 if (SetXRandRModeInfo(display, res, output_info, output_info->modes[i], &mode)) {
744 SDL_AddDisplayMode(sdl_display, &mode);
745 } else {
746 SDL_free(modedata);
747 }
748 }
749 }
750 XRRFreeOutputInfo(output_info);
751 XRRFreeScreenResources(res);
752 }
753 return;
754 }
755 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
756
757 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
758 if (data->use_vidmode &&
759 XF86VidModeGetAllModeLines(display, data->vidmode_screen, &nmodes, &modes)) {
760 int i;
761
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);
768 }
769 #endif
770 for (i = 0; i < nmodes; ++i) {
771 modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
772 if (!modedata) {
773 continue;
774 }
775 mode.driverdata = modedata;
776
777 if (SetXVidModeModeInfo(modes[i], &mode)) {
778 SDL_AddDisplayMode(sdl_display, &mode);
779 } else {
780 SDL_free(modedata);
781 }
782 }
783 XFree(modes);
784 return;
785 }
786 #endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
787
788 if (!data->use_xrandr && !data->use_vidmode) {
789 /* Add the desktop mode */
790 mode = sdl_display->desktop_mode;
791 modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
792 if (modedata) {
793 *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata;
794 }
795 mode.driverdata = modedata;
796 SDL_AddDisplayMode(sdl_display, &mode);
797 }
798 }
799
800 int
801 X11_SetDisplayMode(_THIS, SDL_VideoDisplay * sdl_display, SDL_DisplayMode * mode)
802 {
803 Display *display = ((SDL_VideoData *) _this->driverdata)->display;
804 SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata;
805 SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata;
806
807 #if SDL_VIDEO_DRIVER_X11_XRANDR
808 if (data->use_xrandr) {
809 XRRScreenResources *res;
810 XRROutputInfo *output_info;
811 XRRCrtcInfo *crtc;
812 Status status;
813
814 res = XRRGetScreenResources (display, RootWindow(display, data->screen));
815 if (!res) {
816 return SDL_SetError("Couldn't get XRandR screen resources");
817 }
818
819 output_info = XRRGetOutputInfo(display, res, data->xrandr_output);
820 if (!output_info || output_info->connection == RR_Disconnected) {
821 XRRFreeScreenResources(res);
822 return SDL_SetError("Couldn't get XRandR output info");
823 }
824
825 crtc = XRRGetCrtcInfo(display, res, output_info->crtc);
826 if (!crtc) {
827 XRRFreeOutputInfo(output_info);
828 XRRFreeScreenResources(res);
829 return SDL_SetError("Couldn't get XRandR crtc info");
830 }
831
832 status = XRRSetCrtcConfig (display, res, output_info->crtc, CurrentTime,
833 crtc->x, crtc->y, modedata->xrandr_mode, crtc->rotation,
834 &data->xrandr_output, 1);
835
836 XRRFreeCrtcInfo(crtc);
837 XRRFreeOutputInfo(output_info);
838 XRRFreeScreenResources(res);
839
840 if (status != Success) {
841 return SDL_SetError("XRRSetCrtcConfig failed");
842 }
843 }
844 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
845
846 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
847 if (data->use_vidmode) {
848 XF86VidModeSwitchToMode(display, data->vidmode_screen, &modedata->vm_mode);
849 }
850 #endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
851
852 return 0;
853 }
854
855 void
856 X11_QuitModes(_THIS)
857 {
858 }
859
860 int
861 X11_GetDisplayBounds(_THIS, SDL_VideoDisplay * sdl_display, SDL_Rect * rect)
862 {
863 SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata;
864
865 rect->x = data->x;
866 rect->y = data->y;
867 rect->w = sdl_display->current_mode.w;
868 rect->h = sdl_display->current_mode.h;
869
870 #if SDL_VIDEO_DRIVER_X11_XINERAMA
871 /* Get the real current bounds of the display */
872 if (data->use_xinerama) {
873 Display *display = ((SDL_VideoData *) _this->driverdata)->display;
874 int screencount;
875 XineramaScreenInfo *xinerama = XineramaQueryScreens(display, &screencount);
876 if (xinerama) {
877 rect->x = xinerama[data->xinerama_screen].x_org;
878 rect->y = xinerama[data->xinerama_screen].y_org;
879 XFree(xinerama);
880 }
881 }
882 #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
883 return 0;
884 }
885
886 #endif /* SDL_VIDEO_DRIVER_X11 */
887
888 /* vi: set ts=4 sw=4 expandtab: */
SDL_DisplayData::screen
int screen
Definition: SDL_x11modes.h:28
X11_GetPixelFormatFromVisualInfo
Uint32 X11_GetPixelFormatFromVisualInfo(Display *display, XVisualInfo *vinfo)
MonitorInfo::dsc_product_name
char dsc_product_name[14]
Definition: edid.h:160
SDL_VideoData::display
Display * display
Definition: SDL_x11video.h:75
props
GLenum GLuint GLsizei const GLenum * props
Definition: glew.h:5068
SDL_calloc
DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size)
decode_edid
MonitorInfo * decode_edid(const uchar *edid)
Definition: edid-parse.c:521
NULL
#define NULL
Definition: ftobjs.h:61
SDL_snprintf
DECLSPEC int SDLCALL SDL_snprintf(char *text, size_t maxlen, const char *fmt,...)
Definition: SDL_string.c:1277
X11_SetDisplayMode
int X11_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
SDL_DisplayMode::w
int w
Definition: SDL_video.h:56
f
GLclampf f
Definition: glew.h:3390
SDL_ISPIXELFORMAT_INDEXED
#define SDL_ISPIXELFORMAT_INDEXED(format)
Definition: SDL_pixels.h:129
edid.h
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:116
n
GLclampd n
Definition: glew.h:7287
SDL_VideoDisplay::name
char * name
Definition: SDL_sysvideo.h:115
SDL_TRUE
Definition: SDL_stdinc.h:119
free
SDL_EventEntry * free
Definition: SDL_events.c:80
X11_UseDirectColorVisuals
SDL_bool X11_UseDirectColorVisuals(void)
SDL_VideoDevice::driverdata
void * driverdata
Definition: SDL_sysvideo.h:314
SDL_free
DECLSPEC void SDLCALL SDL_free(void *mem)
SDL_DisplayMode
The structure that defines a display mode.
Definition: SDL_video.h:53
SDL_VIDEO_DRIVER_X11_XVIDMODE
#define SDL_VIDEO_DRIVER_X11_XVIDMODE
Definition: SDL_config_linux.h:277
SDL_PIXELFORMAT_UNKNOWN
Definition: SDL_pixels.h:149
SDL_MasksToPixelFormatEnum
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.
Definition: SDL_pixels.c:291
SDL_DisplayMode::refresh_rate
int refresh_rate
Definition: SDL_video.h:58
SDL_BYTESPERPIXEL
#define SDL_BYTESPERPIXEL(X)
Definition: SDL_pixels.h:123
SDL_PIXELFORMAT_INDEX1MSB
Definition: SDL_pixels.h:153
len
GLenum GLsizei len
Definition: glew.h:7035
display
char * display
Definition: visualinfo.c:85
if
if(!yyg->yy_init)
Definition: glslang_lex.cpp:1037
SDL_FALSE
Definition: SDL_stdinc.h:118
SDL_PIXELTYPE_INDEX8
Definition: SDL_pixels.h:53
SDL_config.h
SDL_AddVideoDisplay
int SDL_AddVideoDisplay(const SDL_VideoDisplay *display)
Definition: SDL_video.c:568
SDL_DisplayData
Definition: SDL_cocoamodes.h:26
SDL_DisplayData::scanline_pad
int scanline_pad
Definition: SDL_x11modes.h:31
X11_GetDisplayBounds
int X11_GetDisplayBounds(_THIS, SDL_VideoDisplay *sdl_display, SDL_Rect *rect)
SDL_VIDEO_DRIVER_X11_XINERAMA
#define SDL_VIDEO_DRIVER_X11_XINERAMA
Definition: SDL_config_linux.h:271
_this
static SDL_VideoDevice * _this
Definition: SDL_video.c:92
Uint32
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:145
SDL_strtol
DECLSPEC long SDLCALL SDL_strtol(const char *str, char **endp, int base)
Definition: SDL_string.c:793
dump_monitor_info
void dump_monitor_info(MonitorInfo *info)
Definition: edid-parse.c:549
SDL_DisplayModeData
Definition: SDL_cocoamodes.h:31
LSBFirst
#define LSBFirst
Definition: pcf.h:168
XInternAtom
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)
Definition: SDL_x11sym.h:82
X11_GetDisplayModes
void X11_GetDisplayModes(_THIS, SDL_VideoDisplay *display)
int
int
Definition: SDL_systhread.c:37
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl2ext.h:848
X11_InitModes
int X11_InitModes(_THIS)
_THIS
#define _THIS
Definition: SDL_alsa_audio.h:31
SDL_DisplayMode::driverdata
void * driverdata
Definition: SDL_video.h:59
p
GLfloat GLfloat p
Definition: glew.h:14938
SDL_PIXELFORMAT_INDEX4LSB
Definition: SDL_pixels.h:156
SDL_VideoDevice::num_displays
int num_displays
Definition: SDL_sysvideo.h:264
SDL_strlcpy
DECLSPEC size_t SDLCALL SDL_strlcpy(char *dst, const char *src, size_t maxlen)
Definition: SDL_string.c:448
SDL_DisplayData::use_xinerama
int use_xinerama
Definition: SDL_x11modes.h:35
SDL_VideoDisplay::current_mode
SDL_DisplayMode current_mode
Definition: SDL_sysvideo.h:120
SDL_hints.h
SDL_SetError
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
Definition: SDL_error.c:53
depth
GLint GLenum GLsizei GLsizei GLsizei depth
Definition: gl2ext.h:845
SDL_DisplayMode::h
int h
Definition: SDL_video.h:57
SDL_DisplayData::use_xrandr
int use_xrandr
Definition: SDL_x11modes.h:36
SDL_DisplayData::visual
Visual * visual
Definition: SDL_x11modes.h:29
SDL_Rect::x
int x
Definition: SDL_rect.h:65
SDL_GetHint
DECLSPEC const char *SDLCALL SDL_GetHint(const char *name)
Get a hint.
Definition: SDL_hints.c:104
SDL_Rect::w
int w
Definition: SDL_rect.h:66
env
jmp_buf env
Definition: jumphack.c:12
SDL_PIXELFORMAT_INDEX1LSB
Definition: SDL_pixels.h:150
SDL_VideoDisplay
Definition: SDL_sysvideo.h:113
SDL_strlen
DECLSPEC size_t SDLCALL SDL_strlen(const char *str)
Definition: SDL_string.c:389
SDL_PIXELFORMAT_INDEX4MSB
Definition: SDL_pixels.h:159
SDL_VideoDisplay::desktop_mode
SDL_DisplayMode desktop_mode
Definition: SDL_sysvideo.h:119
l
GLdouble l
Definition: glew.h:8383
SDL_HINT_VIDEO_X11_XRANDR
#define SDL_HINT_VIDEO_X11_XRANDR
A variable controlling whether the X11 XRandR extension should be used.
Definition: SDL_hints.h:162
vi
XVisualInfo * vi
Definition: glewinfo_tail.c:221
SDL_DisplayData::y
int y
Definition: SDL_x11modes.h:33
sort_controllers.output
tuple output
Definition: sort_controllers.py:10
flags
GLenum GLsizei GLsizei GLsizei GLsizei GLbitfield flags
Definition: glew.h:2767
X11_QuitModes
void X11_QuitModes(_THIS)
SDL_VIDEO_DRIVER_X11_XRANDR
#define SDL_VIDEO_DRIVER_X11_XRANDR
Definition: SDL_config_linux.h:274
MonitorInfo
Definition: edid.h:80
SDL_Rect::h
int h
Definition: SDL_rect.h:66
SDL_atoi
DECLSPEC int SDLCALL SDL_atoi(const char *str)
Definition: SDL_string.c:774
SDL_zerop
#define SDL_zerop(x)
Definition: SDL_stdinc.h:255
SDL_x11video.h
SDL_VideoData
Definition: SDL_androidvideo.h:35
SDL_AddDisplayMode
SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
Definition: SDL_video.c:666
SDL_getenv
DECLSPEC char *SDLCALL SDL_getenv(const char *name)
Definition: SDL_getenv.c:179
SDL_zero
#define SDL_zero(x)
Definition: SDL_stdinc.h:254
SDL_DisplayMode::format
Uint32 format
Definition: SDL_video.h:55
i
int i
Definition: pngrutil.c:1377
visual
int visual
Definition: visualinfo.c:86
SDL_DisplayData::x
int x
Definition: SDL_x11modes.h:32
Bool
char Bool
Definition: ftraster.c:307
SDL_DisplayData::use_vidmode
int use_vidmode
Definition: SDL_x11modes.h:37
XMatchVisualInfo
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)
Definition: SDL_x11sym.h:88
X11_GetVisualInfoFromVisual
int X11_GetVisualInfoFromVisual(Display *display, Visual *visual, XVisualInfo *vinfo)
SDL_HINT_VIDEO_X11_XVIDMODE
#define SDL_HINT_VIDEO_X11_XVIDMODE
A variable controlling whether the X11 VidMode extension should be used.
Definition: SDL_hints.h:140
SDL_Rect::y
int y
Definition: SDL_rect.h:65
mode
GLenum mode
Definition: glew.h:2394
SDL_DisplayData::depth
int depth
Definition: SDL_x11modes.h:30
SDL_HINT_VIDEO_X11_XINERAMA
#define SDL_HINT_VIDEO_X11_XINERAMA
A variable controlling whether the X11 Xinerama extension should be used.
Definition: SDL_hints.h:151
SDL_Rect
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:63
SDL_VideoDisplay::driverdata
void * driverdata
Definition: SDL_sysvideo.h:126
dpy
Display * dpy
Definition: glewinfo_tail.c:220
res
GLuint res
Definition: glew.h:10669