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 */