zenilib  0.5.3.0
 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);
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) {
133  } else {
135  }
136  break;
137  case 1:
138  if (BitmapBitOrder(display) == LSBFirst) {
140  } else {
142  }
143  break;
144  }
145  }
146 
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 */
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 */
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 */
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
376 {
378  int screen, screencount;
380  int xinerama_major, xinerama_minor;
381  int use_xinerama = 0;
382  XineramaScreenInfo *xinerama = NULL;
383 #endif
385  int xrandr_major, xrandr_minor;
386  int use_xrandr = 0;
387  XRRScreenResources *res = NULL;
388 #endif
390  int vm_major, vm_minor;
391  int use_vidmode = 0;
392 #endif
393 
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;
429  SDL_DisplayData *displaydata;
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 &&
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
666 {
667  Display *display = ((SDL_VideoData *) _this->driverdata)->display;
668  SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata;
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
802 {
803  Display *display = ((SDL_VideoData *) _this->driverdata)->display;
804  SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->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
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 
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: */
Uint32 X11_GetPixelFormatFromVisualInfo(Display *display, XVisualInfo *vinfo)
char dsc_product_name[14]
Definition: edid.h:160
Display * display
Definition: SDL_x11video.h:75
GLenum GLuint GLsizei const GLenum * props
Definition: glew.h:5068
DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size)
MonitorInfo * decode_edid(const uchar *edid)
Definition: edid-parse.c:521
#define NULL
Definition: ftobjs.h:61
DECLSPEC int SDLCALL SDL_snprintf(char *text, size_t maxlen, const char *fmt,...)
Definition: SDL_string.c:1277
int X11_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
GLclampf f
Definition: glew.h:3390
#define SDL_ISPIXELFORMAT_INDEXED(format)
Definition: SDL_pixels.h:129
SDL_bool
Definition: SDL_stdinc.h:116
GLclampd n
Definition: glew.h:7287
SDL_EventEntry * free
Definition: SDL_events.c:80
SDL_bool X11_UseDirectColorVisuals(void)
DECLSPEC void SDLCALL SDL_free(void *mem)
The structure that defines a display mode.
Definition: SDL_video.h:53
#define SDL_VIDEO_DRIVER_X11_XVIDMODE
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
#define SDL_BYTESPERPIXEL(X)
Definition: SDL_pixels.h:123
GLenum GLsizei len
Definition: glew.h:7035
char * display
Definition: visualinfo.c:85
if(!yyg->yy_init)
int SDL_AddVideoDisplay(const SDL_VideoDisplay *display)
Definition: SDL_video.c:568
int X11_GetDisplayBounds(_THIS, SDL_VideoDisplay *sdl_display, SDL_Rect *rect)
#define SDL_VIDEO_DRIVER_X11_XINERAMA
static SDL_VideoDevice * _this
Definition: SDL_video.c:92
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:145
DECLSPEC long SDLCALL SDL_strtol(const char *str, char **endp, int base)
Definition: SDL_string.c:793
void dump_monitor_info(MonitorInfo *info)
Definition: edid-parse.c:549
#define LSBFirst
Definition: pcf.h:168
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
void X11_GetDisplayModes(_THIS, SDL_VideoDisplay *display)
int
Definition: SDL_systhread.c:37
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl2ext.h:848
int X11_InitModes(_THIS)
#define _THIS
void * driverdata
Definition: SDL_video.h:59
GLfloat GLfloat p
Definition: glew.h:14938
DECLSPEC size_t SDLCALL SDL_strlcpy(char *dst, const char *src, size_t maxlen)
Definition: SDL_string.c:448
SDL_DisplayMode current_mode
Definition: SDL_sysvideo.h:120
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
Definition: SDL_error.c:53
GLint GLenum GLsizei GLsizei GLsizei depth
Definition: gl2ext.h:845
Visual * visual
Definition: SDL_x11modes.h:29
int x
Definition: SDL_rect.h:65
DECLSPEC const char *SDLCALL SDL_GetHint(const char *name)
Get a hint.
Definition: SDL_hints.c:104
int w
Definition: SDL_rect.h:66
jmp_buf env
Definition: jumphack.c:12
DECLSPEC size_t SDLCALL SDL_strlen(const char *str)
Definition: SDL_string.c:389
SDL_DisplayMode desktop_mode
Definition: SDL_sysvideo.h:119
GLdouble l
Definition: glew.h:8383
#define SDL_HINT_VIDEO_X11_XRANDR
A variable controlling whether the X11 XRandR extension should be used.
Definition: SDL_hints.h:162
XVisualInfo * vi
GLenum GLsizei GLsizei GLsizei GLsizei GLbitfield flags
Definition: glew.h:2767
void X11_QuitModes(_THIS)
#define SDL_VIDEO_DRIVER_X11_XRANDR
int h
Definition: SDL_rect.h:66
DECLSPEC int SDLCALL SDL_atoi(const char *str)
Definition: SDL_string.c:774
#define SDL_zerop(x)
Definition: SDL_stdinc.h:255
SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
Definition: SDL_video.c:666
DECLSPEC char *SDLCALL SDL_getenv(const char *name)
Definition: SDL_getenv.c:179
#define SDL_zero(x)
Definition: SDL_stdinc.h:254
Uint32 format
Definition: SDL_video.h:55
int i
Definition: pngrutil.c:1377
int visual
Definition: visualinfo.c:86
char Bool
Definition: ftraster.c:307
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
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.
Definition: SDL_hints.h:140
int y
Definition: SDL_rect.h:65
GLenum mode
Definition: glew.h:2394
#define SDL_HINT_VIDEO_X11_XINERAMA
A variable controlling whether the X11 Xinerama extension should be used.
Definition: SDL_hints.h:151
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:63
Display * dpy
GLuint res
Definition: glew.h:10669