Mercurial > sdl-ios-xcode
comparison src/video/x11/SDL_x11modes.c @ 614:0b4c3f5ff63d
Date: Wed, 9 Apr 2003 18:21:33 -0230
From: Stephen Anthony <stephena@roadrunner.nf.net>
Subject: [SDL] First patch concerning 4.3 and refresh rates
OK, here's my first draft of the patch for the above subject.
A short explanation:
X 4.3 introduces many more modelines than older versions. This would be
fine, except it introduces many modes with the *same* resolution but
different refresh rates. And SDL won't necessarily pick the one with the
highest refresh rate.
So this patch restores SDL to X 4.2 functionality. That is, there is only
ever one refresh rate *per* resolution, and it is the highest possible.
This functionality can be totally disabled by using the environment
variable 'SDL_VIDEO_X11_USE_ALL_MODES' set equal to 1.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 20 Apr 2003 05:36:52 +0000 |
parents | f8710950cddc |
children | 6862d4294870 |
comparison
equal
deleted
inserted
replaced
613:9c6717a1c66f | 614:0b4c3f5ff63d |
---|---|
42 #ifdef HAVE_XINERAMA | 42 #ifdef HAVE_XINERAMA |
43 #include <XFree86/extensions/Xinerama.h> | 43 #include <XFree86/extensions/Xinerama.h> |
44 #endif | 44 #endif |
45 | 45 |
46 #define MAX(a, b) (a > b ? a : b) | 46 #define MAX(a, b) (a > b ? a : b) |
47 #define V_INTERLACE 0x010 | |
48 #define V_DBLSCAN 0x020 | |
47 | 49 |
48 #ifdef XFREE86_VM | 50 #ifdef XFREE86_VM |
49 Bool SDL_NAME(XF86VidModeGetModeInfo)(Display *dpy, int scr, SDL_NAME(XF86VidModeModeInfo) *info) | 51 Bool SDL_NAME(XF86VidModeGetModeInfo)(Display *dpy, int scr, SDL_NAME(XF86VidModeModeInfo) *info) |
50 { | 52 { |
51 SDL_NAME(XF86VidModeModeLine) *l = (SDL_NAME(XF86VidModeModeLine)*)((char*)info + sizeof info->dotclock); | 53 SDL_NAME(XF86VidModeModeLine) *l = (SDL_NAME(XF86VidModeModeLine)*)((char*)info + sizeof info->dotclock); |
89 return -1; | 91 return -1; |
90 return b->vdisplay - a->vdisplay; | 92 return b->vdisplay - a->vdisplay; |
91 } | 93 } |
92 #endif | 94 #endif |
93 | 95 |
96 #ifdef XFREE86_VM | |
97 static int get_vidmode_filter(SDL_NAME(XF86VidModeModeInfo) **modes, int nmodes, char **bitmap) | |
98 { | |
99 int i, result = 0; | |
100 int use_all_modes, use_specific_mode; | |
101 const char *variable; | |
102 char *temp; | |
103 | |
104 if (!nmodes) | |
105 return 0; | |
106 | |
107 temp = (char *)malloc((nmodes)*sizeof(char)); | |
108 if (!temp) | |
109 return 0; | |
110 | |
111 for ( i = 0; i < nmodes; ++i ) | |
112 temp[i] = 0; | |
113 | |
114 variable = getenv("SDL_VIDEO_X11_USE_ALL_MODES"); | |
115 use_all_modes = variable ? atoi(variable) : 0; | |
116 variable = getenv("SDL_VIDEO_X11_USE_SPECIFIC_MODE"); | |
117 use_specific_mode = variable ? atoi(variable) : 0; | |
118 | |
119 qsort(modes, nmodes, sizeof *modes, cmpmodes); | |
120 | |
121 if ( use_all_modes ) { | |
122 for ( i = 0; i < nmodes; ++i ) | |
123 temp[i] = 1; | |
124 result = 1; | |
125 /* } else if ( use_specific_mode ) { ... */ | |
126 } else { | |
127 int previous_refresh, current_refresh; | |
128 SDL_NAME(XF86VidModeModeInfo) *previous, *current; | |
129 | |
130 previous = modes[0]; | |
131 previous_refresh = (int)(previous->dotclock * 1000.0 / | |
132 (previous->htotal * previous->vtotal)); | |
133 if ( previous->flags & V_INTERLACE ) previous_refresh *= 2; | |
134 else if ( previous->flags & V_DBLSCAN ) previous_refresh /= 2; | |
135 | |
136 temp[0] = 1; | |
137 for ( i = 1; i < nmodes; ++i ) { | |
138 current = modes[i]; | |
139 current_refresh = (int)(current->dotclock * 1000.0 / | |
140 (current->htotal * current->vtotal)); | |
141 if ( current->flags & V_INTERLACE ) current_refresh *= 2; | |
142 else if ( current->flags & V_DBLSCAN ) current_refresh /= 2; | |
143 | |
144 /* Compare this mode to the previous one */ | |
145 if ( current->hdisplay == previous->hdisplay && | |
146 current->vdisplay == previous->vdisplay ) { | |
147 #ifdef XFREE86_DEBUG | |
148 printf("Comparing %dx%d at %d Hz and %d Hz\n", | |
149 current->hdisplay, current->vdisplay, | |
150 current_refresh, previous_refresh); | |
151 #endif | |
152 if ( current_refresh > previous_refresh ) { | |
153 temp[i-1] = 0; | |
154 temp[i] = 1; | |
155 } | |
156 else | |
157 temp[i] = 0; | |
158 } | |
159 else | |
160 temp[i] = 1; | |
161 | |
162 previous = current; | |
163 previous_refresh = current_refresh; | |
164 } | |
165 result = 1; | |
166 } | |
167 *bitmap = temp; | |
168 return result; | |
169 } | |
170 #endif | |
171 | |
94 static void get_real_resolution(_THIS, int* w, int* h); | 172 static void get_real_resolution(_THIS, int* w, int* h); |
95 | 173 |
96 static void set_best_resolution(_THIS, int width, int height) | 174 static void set_best_resolution(_THIS, int width, int height) |
97 { | 175 { |
98 #ifdef XFREE86_VM | 176 #ifdef XFREE86_VM |
99 if ( use_vidmode ) { | 177 if ( use_vidmode ) { |
100 SDL_NAME(XF86VidModeModeLine) mode; | 178 SDL_NAME(XF86VidModeModeLine) mode; |
101 SDL_NAME(XF86VidModeModeInfo) **modes; | 179 SDL_NAME(XF86VidModeModeInfo) **modes; |
102 int i; | 180 int i; |
103 int nmodes; | 181 int nmodes; |
182 char *bitmap; | |
104 | 183 |
105 if ( SDL_NAME(XF86VidModeGetModeLine)(SDL_Display, SDL_Screen, &i, &mode) && | 184 if ( SDL_NAME(XF86VidModeGetModeLine)(SDL_Display, SDL_Screen, &i, &mode) && |
106 SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display,SDL_Screen,&nmodes,&modes)){ | 185 SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display,SDL_Screen,&nmodes,&modes) && |
107 qsort(modes, nmodes, sizeof *modes, cmpmodes); | 186 get_vidmode_filter(modes, nmodes, &bitmap) ) { |
108 #ifdef XFREE86_DEBUG | 187 #ifdef XFREE86_DEBUG |
109 printf("Available modes:\n"); | 188 printf("Available modes:\n"); |
110 for ( i = 0; i < nmodes; ++i ) { | 189 for ( i = 0; i < nmodes; ++i ) { |
111 printf("Mode %d: %dx%d\n", i, | 190 printf("Mode %d: %dx%d\n", i, |
112 modes[i]->hdisplay, modes[i]->vdisplay); | 191 modes[i]->hdisplay, modes[i]->vdisplay); |
113 } | 192 } |
114 #endif | 193 #endif |
115 for ( i = nmodes-1; i > 0 ; --i ) { | 194 for ( i = nmodes-1; i > 0 ; --i ) { |
116 if ( (modes[i]->hdisplay == width) && | 195 if ( (modes[i]->hdisplay == width) && |
117 (modes[i]->vdisplay == height) ) | 196 (modes[i]->vdisplay == height) && |
197 (bitmap[i] == 1) ) | |
118 goto match; | 198 goto match; |
119 } | 199 } |
120 for ( i = nmodes-1; i > 0 ; --i ) { | 200 for ( i = nmodes-1; i > 0 ; --i ) { |
121 if ( (modes[i]->hdisplay >= width) && | 201 if ( (modes[i]->hdisplay >= width) && |
122 (modes[i]->vdisplay >= height) ) | 202 (modes[i]->vdisplay >= height) && |
203 (bitmap[i] == 1) ) | |
123 break; | 204 break; |
124 } | 205 } |
125 match: | 206 match: |
126 if ( (modes[i]->hdisplay != mode.hdisplay) || | 207 if ( (modes[i]->hdisplay != mode.hdisplay) || |
127 (modes[i]->vdisplay != mode.vdisplay) ) { | 208 (modes[i]->vdisplay != mode.vdisplay) ) { |
128 SDL_NAME(XF86VidModeSwitchToMode)(SDL_Display, SDL_Screen, modes[i]); | 209 SDL_NAME(XF86VidModeSwitchToMode)(SDL_Display, SDL_Screen, modes[i]); |
129 } | 210 } |
130 XFree(modes); | 211 XFree(modes); |
212 if (bitmap) free(bitmap); | |
131 } | 213 } |
132 } | 214 } |
133 #endif /* XFREE86_VM */ | 215 #endif /* XFREE86_VM */ |
134 | 216 |
135 /* XiG */ | 217 /* XiG */ |
273 #ifdef XFREE86_VM | 355 #ifdef XFREE86_VM |
274 int buggy_X11; | 356 int buggy_X11; |
275 int vm_major, vm_minor; | 357 int vm_major, vm_minor; |
276 int nmodes; | 358 int nmodes; |
277 SDL_NAME(XF86VidModeModeInfo) **modes; | 359 SDL_NAME(XF86VidModeModeInfo) **modes; |
360 char *bitmap = (char*)0; | |
278 #endif | 361 #endif |
279 #ifdef HAVE_XIGXME | 362 #ifdef HAVE_XIGXME |
280 int xme_major, xme_minor; | 363 int xme_major, xme_minor; |
281 int ractive, nummodes; | 364 int ractive, nummodes; |
282 XiGMiscResolutionInfo *modelist; | 365 XiGMiscResolutionInfo *modelist; |
334 } else { | 417 } else { |
335 buggy_X11 = 1; | 418 buggy_X11 = 1; |
336 } | 419 } |
337 } | 420 } |
338 if ( ! buggy_X11 && | 421 if ( ! buggy_X11 && |
339 SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display, SDL_Screen,&nmodes,&modes) ) { | 422 SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display, SDL_Screen,&nmodes,&modes) && |
340 | 423 get_vidmode_filter(modes, nmodes, &bitmap) ) { |
341 qsort(modes, nmodes, sizeof *modes, cmpmodes); | 424 |
342 SDL_modelist = (SDL_Rect **)malloc((nmodes+2)*sizeof(SDL_Rect *)); | 425 SDL_modelist = (SDL_Rect **)malloc((nmodes+2)*sizeof(SDL_Rect *)); |
343 if ( SDL_modelist ) { | 426 if ( SDL_modelist ) { |
344 n = 0; | 427 n = 0; |
345 for ( i=0; i<nmodes; ++i ) { | 428 for ( i=0; i<nmodes; ++i ) { |
346 int w, h; | 429 int w, h; |
430 | |
431 /* Exclude those vidmodes that have been filtered out */ | |
432 if (!bitmap[i]) continue; | |
347 | 433 |
348 /* Check to see if we should add the screen size (Xinerama) */ | 434 /* Check to see if we should add the screen size (Xinerama) */ |
349 w = modes[i]->hdisplay; | 435 w = modes[i]->hdisplay; |
350 h = modes[i]->vdisplay; | 436 h = modes[i]->vdisplay; |
351 if ( (screen_w * screen_h) >= (w * h) ) { | 437 if ( (screen_w * screen_h) >= (w * h) ) { |
375 ++n; | 461 ++n; |
376 } | 462 } |
377 SDL_modelist[n] = NULL; | 463 SDL_modelist[n] = NULL; |
378 } | 464 } |
379 XFree(modes); | 465 XFree(modes); |
466 if (bitmap) free(bitmap); | |
380 | 467 |
381 use_vidmode = vm_major * 100 + vm_minor; | 468 use_vidmode = vm_major * 100 + vm_minor; |
382 save_mode(this); | 469 save_mode(this); |
383 } | 470 } |
384 #endif /* XFREE86_VM */ | 471 #endif /* XFREE86_VM */ |