Mercurial > sdl-ios-xcode
comparison src/video/x11/SDL_x11modes.c @ 1589:34cca785be57
Xrandr support in the X11 target.
Fixes Bugzilla #109, and as a bonus, Bugzilla #145, too!
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Wed, 22 Mar 2006 11:13:58 +0000 |
parents | 3ba88cb7eb1b |
children | 5cf11b00b900 |
comparison
equal
deleted
inserted
replaced
1588:e20dcef5647c | 1589:34cca785be57 |
---|---|
81 const SDL_NAME(XF86VidModeModeInfo) *b = *(const SDL_NAME(XF86VidModeModeInfo)**)vb; | 81 const SDL_NAME(XF86VidModeModeInfo) *b = *(const SDL_NAME(XF86VidModeModeInfo)**)vb; |
82 if ( a->hdisplay == b->hdisplay ) | 82 if ( a->hdisplay == b->hdisplay ) |
83 return b->vdisplay - a->vdisplay; | 83 return b->vdisplay - a->vdisplay; |
84 else | 84 else |
85 return b->hdisplay - a->hdisplay; | 85 return b->hdisplay - a->hdisplay; |
86 } | |
87 #endif | |
88 | |
89 #if SDL_VIDEO_DRIVER_X11_XRANDR | |
90 static int cmpmodelist(const void *va, const void *vb) | |
91 { | |
92 const SDL_Rect *a = *(const SDL_Rect **)va; | |
93 const SDL_Rect *b = *(const SDL_Rect **)vb; | |
94 if ( a->w == b->w ) | |
95 return b->h - a->h; | |
96 else | |
97 return b->w - a->w; | |
86 } | 98 } |
87 #endif | 99 #endif |
88 | 100 |
89 static void get_real_resolution(_THIS, int* w, int* h); | 101 static void get_real_resolution(_THIS, int* w, int* h); |
90 | 102 |
178 } | 190 } |
179 } | 191 } |
180 } | 192 } |
181 #endif /* SDL_VIDEO_DRIVER_X11_XME */ | 193 #endif /* SDL_VIDEO_DRIVER_X11_XME */ |
182 | 194 |
195 #if SDL_VIDEO_DRIVER_X11_XRANDR | |
196 if ( use_xrandr ) { | |
197 #ifdef XRANDR_DEBUG | |
198 fprintf(stderr, "XRANDR: set_best_resolution(): w = %d, h = %d\n", | |
199 width, height); | |
200 #endif | |
201 if ( SDL_modelist ) { | |
202 int i, nsizes; | |
203 XRRScreenSize *sizes; | |
204 | |
205 /* find the smallest resolution that is at least as big as the user requested */ | |
206 sizes = XRRConfigSizes(screen_config, &nsizes); | |
207 for ( i = (nsizes-1); i >= 0; i-- ) { | |
208 if ( (SDL_modelist[i]->w >= width) && | |
209 (SDL_modelist[i]->h >= height) ) { | |
210 break; | |
211 } | |
212 } | |
213 | |
214 if ( i >= 0 && SDL_modelist[i] ) { /* found one, lets try it */ | |
215 int w, h; | |
216 | |
217 /* check current mode so we can avoid uneccessary mode changes */ | |
218 get_real_resolution(this, &w, &h); | |
219 | |
220 if ( (SDL_modelist[i]->w != w) || (SDL_modelist[i]->h != h) ) { | |
221 int size_id; | |
222 | |
223 #ifdef XRANDR_DEBUG | |
224 fprintf(stderr, "XRANDR: set_best_resolution: " | |
225 "XXRSetScreenConfig: %d %d\n", | |
226 SDL_modelist[i]->w, SDL_modelist[i]->h); | |
227 #endif | |
228 | |
229 /* find the matching size entry index */ | |
230 for ( size_id = 0; size_id < nsizes; ++size_id ) { | |
231 if ( (sizes[size_id].width == SDL_modelist[i]->w) && | |
232 (sizes[size_id].height == SDL_modelist[i]->h) ) | |
233 break; | |
234 } | |
235 | |
236 XRRSetScreenConfig(SDL_Display, screen_config, SDL_Root, | |
237 size_id, saved_rotation, CurrentTime); | |
238 } | |
239 } | |
240 } | |
241 } | |
242 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ | |
243 | |
183 } | 244 } |
184 | 245 |
185 static void get_real_resolution(_THIS, int* w, int* h) | 246 static void get_real_resolution(_THIS, int* w, int* h) |
186 { | 247 { |
187 #if SDL_VIDEO_DRIVER_X11_VIDMODE | 248 #if SDL_VIDEO_DRIVER_X11_VIDMODE |
193 *w = mode.hdisplay; | 254 *w = mode.hdisplay; |
194 *h = mode.vdisplay; | 255 *h = mode.vdisplay; |
195 return; | 256 return; |
196 } | 257 } |
197 } | 258 } |
198 #endif | 259 #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */ |
199 | 260 |
200 #if SDL_VIDEO_DRIVER_X11_XME | 261 #if SDL_VIDEO_DRIVER_X11_XME |
201 if ( use_xme ) { | 262 if ( use_xme ) { |
202 int ractive; | 263 int ractive; |
203 XiGMiscResolutionInfo *modelist; | 264 XiGMiscResolutionInfo *modelist; |
211 fprintf(stderr, "XME: get_real_resolution: w = %d h = %d\n", *w, *h); | 272 fprintf(stderr, "XME: get_real_resolution: w = %d h = %d\n", *w, *h); |
212 #endif | 273 #endif |
213 XFree(modelist); | 274 XFree(modelist); |
214 return; | 275 return; |
215 } | 276 } |
216 #endif /* XIG_XME */ | 277 #endif /* SDL_VIDEO_DRIVER_X11_XME */ |
278 | |
279 #if SDL_VIDEO_DRIVER_X11_XRANDR | |
280 if ( use_xrandr ) { | |
281 int nsizes; | |
282 XRRScreenSize* sizes; | |
283 | |
284 sizes = XRRConfigSizes(screen_config, &nsizes); | |
285 if ( nsizes > 0 ) { | |
286 int cur_size; | |
287 Rotation cur_rotation; | |
288 | |
289 cur_size = XRRConfigCurrentConfiguration(screen_config, &cur_rotation); | |
290 if ( cur_size >= 0 && cur_size < nsizes ) { | |
291 *w = sizes[cur_size].width; | |
292 *h = sizes[cur_size].height; | |
293 } | |
294 #ifdef XRANDR_DEBUG | |
295 fprintf(stderr, "XRANDR: get_real_resolution: w = %d h = %d\n", *w, *h); | |
296 #endif | |
297 return; | |
298 } | |
299 } | |
300 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ | |
217 | 301 |
218 *w = DisplayWidth(SDL_Display, SDL_Screen); | 302 *w = DisplayWidth(SDL_Display, SDL_Screen); |
219 *h = DisplayHeight(SDL_Display, SDL_Screen); | 303 *h = DisplayHeight(SDL_Display, SDL_Screen); |
220 } | 304 } |
221 | 305 |
287 #if SDL_VIDEO_DRIVER_X11_XME | 371 #if SDL_VIDEO_DRIVER_X11_XME |
288 int xme_major, xme_minor; | 372 int xme_major, xme_minor; |
289 int ractive, nummodes; | 373 int ractive, nummodes; |
290 XiGMiscResolutionInfo *modelist; | 374 XiGMiscResolutionInfo *modelist; |
291 #endif | 375 #endif |
376 #if SDL_VIDEO_DRIVER_X11_XRANDR | |
377 int xrandr_major, xrandr_minor; | |
378 int nsizes; | |
379 XRRScreenSize *sizes; | |
380 #endif | |
292 int i, n; | 381 int i, n; |
293 int screen_w; | 382 int screen_w; |
294 int screen_h; | 383 int screen_h; |
295 | 384 |
296 vm_error = -1; | 385 vm_error = -1; |
297 use_vidmode = 0; | 386 use_vidmode = 0; |
387 use_xrandr = 0; | |
298 screen_w = DisplayWidth(SDL_Display, SDL_Screen); | 388 screen_w = DisplayWidth(SDL_Display, SDL_Screen); |
299 screen_h = DisplayHeight(SDL_Display, SDL_Screen); | 389 screen_h = DisplayHeight(SDL_Display, SDL_Screen); |
390 | |
391 /* XRandR */ | |
392 #if SDL_VIDEO_DRIVER_X11_XRANDR | |
393 /* require at least XRandR v1.0 (arbitrary) */ | |
394 if ( ( SDL_X11_HAVE_XRANDR ) && | |
395 ( getenv("SDL_VIDEO_X11_NO_XRANDR") == NULL ) && | |
396 ( XRRQueryVersion(SDL_Display, &xrandr_major, &xrandr_minor) ) && | |
397 ( xrandr_major >= 1 ) ) { | |
398 | |
399 #ifdef XRANDR_DEBUG | |
400 fprintf(stderr, "XRANDR: XRRQueryVersion: V%d.%d\n", | |
401 xrandr_major, xrandr_minor); | |
402 #endif | |
403 | |
404 /* save the screen configuration since we must reference it | |
405 each time we toggle modes. | |
406 */ | |
407 screen_config = XRRGetScreenInfo(SDL_Display, SDL_Root); | |
408 | |
409 /* retrieve the list of resolution */ | |
410 sizes = XRRConfigSizes(screen_config, &nsizes); | |
411 if (nsizes > 0) { | |
412 SDL_modelist = (SDL_Rect **)malloc((nsizes+1)*sizeof(SDL_Rect *)); | |
413 if (SDL_modelist) { | |
414 for ( i=0; i < nsizes; i++ ) { | |
415 if ((SDL_modelist[i] = | |
416 (SDL_Rect *)malloc(sizeof(SDL_Rect))) == NULL) | |
417 break; | |
418 #ifdef XRANDR_DEBUG | |
419 fprintf(stderr, "XRANDR: mode = %4d, w = %4d, h = %4d\n", | |
420 i, sizes[i].width, sizes[i].height); | |
421 #endif | |
422 | |
423 SDL_modelist[i]->x = 0; | |
424 SDL_modelist[i]->y = 0; | |
425 SDL_modelist[i]->w = sizes[i].width; | |
426 SDL_modelist[i]->h = sizes[i].height; | |
427 | |
428 } | |
429 /* sort the mode list descending as SDL expects */ | |
430 qsort(SDL_modelist, nsizes, sizeof *SDL_modelist, cmpmodelist); | |
431 SDL_modelist[i] = NULL; /* terminator */ | |
432 } | |
433 use_xrandr = xrandr_major * 100 + xrandr_minor; | |
434 saved_size_id = XRRConfigCurrentConfiguration(screen_config, &saved_rotation); | |
435 } | |
436 } | |
437 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ | |
300 | 438 |
301 #if SDL_VIDEO_DRIVER_X11_VIDMODE | 439 #if SDL_VIDEO_DRIVER_X11_VIDMODE |
302 /* Metro-X 4.3.0 and earlier has a broken implementation of | 440 /* Metro-X 4.3.0 and earlier has a broken implementation of |
303 XF86VidModeGetAllModeLines() - it hangs the client. | 441 XF86VidModeGetAllModeLines() - it hangs the client. |
304 */ | 442 */ |
343 #endif /* XFree86 4.02 and newer are fixed wrt backwards compatibility */ | 481 #endif /* XFree86 4.02 and newer are fixed wrt backwards compatibility */ |
344 } else { | 482 } else { |
345 buggy_X11 = 1; | 483 buggy_X11 = 1; |
346 } | 484 } |
347 } | 485 } |
348 if ( ! buggy_X11 && | 486 if ( ! buggy_X11 && ! use_xrandr && |
349 SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display, SDL_Screen,&nmodes,&modes) ) { | 487 SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display, SDL_Screen,&nmodes,&modes) ) { |
350 | 488 |
351 #ifdef XFREE86_DEBUG | 489 #ifdef XFREE86_DEBUG |
352 printf("Available modes: (sorted)\n"); | 490 printf("Available modes: (sorted)\n"); |
353 for ( i = 0; i < nmodes; ++i ) { | 491 for ( i = 0; i < nmodes; ++i ) { |
424 the right Query func will never be called if using the bogus | 562 the right Query func will never be called if using the bogus |
425 libXext version. | 563 libXext version. |
426 */ | 564 */ |
427 fprintf(stderr, | 565 fprintf(stderr, |
428 "XME: If you are using Xi Graphics CDE and a Summit server, you need to\n" | 566 "XME: If you are using Xi Graphics CDE and a Summit server, you need to\n" |
429 "XME: get the libXext update from our ftp site before fullscreen switching\n" | 567 "XME: get the libXext update from Xi's ftp site before fullscreen switching\n" |
430 "XME: will work. Fullscreen switching is only supported on Summit Servers\n"); | 568 "XME: will work. Fullscreen switching is only supported on Summit Servers\n"); |
431 } | 569 } |
432 } else { | 570 } else { |
433 /* not there. Bummer. */ | 571 /* not there. Bummer. */ |
434 xme_major = xme_minor = 0; | 572 xme_major = xme_minor = 0; |
633 SDL_free(SDL_modelist[i]); | 771 SDL_free(SDL_modelist[i]); |
634 } | 772 } |
635 SDL_free(SDL_modelist); | 773 SDL_free(SDL_modelist); |
636 SDL_modelist = NULL; | 774 SDL_modelist = NULL; |
637 } | 775 } |
776 | |
777 #if SDL_VIDEO_DRIVER_X11_XRANDR | |
778 /* Free the Xrandr screen configuration */ | |
779 if ( screen_config ) { | |
780 XRRFreeScreenConfigInfo(screen_config); | |
781 screen_config = NULL; | |
782 } | |
783 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ | |
638 } | 784 } |
639 | 785 |
640 int X11_ResizeFullScreen(_THIS) | 786 int X11_ResizeFullScreen(_THIS) |
641 { | 787 { |
642 int x, y; | 788 int x, y; |
802 XSync(SDL_Display, False); | 948 XSync(SDL_Display, False); |
803 } | 949 } |
804 } | 950 } |
805 #endif | 951 #endif |
806 | 952 |
953 #if SDL_VIDEO_DRIVER_X11_XRANDR | |
954 if ( use_xrandr ) { | |
955 XRRSetScreenConfig(SDL_Display, screen_config, SDL_Root, | |
956 saved_size_id, saved_rotation, CurrentTime); | |
957 } | |
958 #endif | |
959 | |
807 XUnmapWindow(SDL_Display, FSwindow); | 960 XUnmapWindow(SDL_Display, FSwindow); |
808 X11_WaitUnmapped(this, FSwindow); | 961 X11_WaitUnmapped(this, FSwindow); |
809 XSync(SDL_Display, True); /* Flush spurious mode change events */ | 962 XSync(SDL_Display, True); /* Flush spurious mode change events */ |
810 currently_fullscreen = 0; | 963 currently_fullscreen = 0; |
811 } | 964 } |