comparison src/video/x11/SDL_x11modes.c @ 1768:814f9f2c7a33

Fixed bug #80 Date: 21 Apr 2003 17:20:20 +0100 From: Alan Swanson <swanson@uklinux.net> Subject: [SDL] New XFree 4.3 Video Mode Patch If you look at the unsorted list of modes returned by X, here's mine; 1280 x 1024 @ 85.0 > 1024 x 768 @ 100.3 > USER 800 x 600 @ 125.5 > SET 640 x 480 @ 124.9 > 1280 x 1024 @ 75.0 ] 1280 x 1024 @ 60.0 ] 1280 x 960 @ 85.0 ] X11 1280 x 960 @ 60.0 ] AUTO 1152 x 864 @ 75.0 ]=20 1152 x 768 @ 54.8 ] 960 x 720 @ 120.0 ] ... 640 x 400 @ 85.1 ] 256k 576 x 432 @ 150.0 ] 249k PIXEL 640 x 350 @ 85.1 ] 224k COUNT 576 x 384 @ 109.6 ] 221k ... The user set modes come first followed by X set modes which are ordered by decreasing number of pixels and refresh. The reason why every other library or program not using SDL working is due to SDL scanning the modes in reverse getting X11 provided modes modes with the lowest refresh.
author Sam Lantinga <slouken@libsdl.org>
date Fri, 05 May 2006 05:50:26 +0000
parents 410b1ed7fe28
children 8d3ca155c396
comparison
equal deleted inserted replaced
1767:ae9f6be81810 1768:814f9f2c7a33
31 #include "SDL_x11video.h" 31 #include "SDL_x11video.h"
32 #include "SDL_x11wm_c.h" 32 #include "SDL_x11wm_c.h"
33 #include "SDL_x11modes_c.h" 33 #include "SDL_x11modes_c.h"
34 #include "SDL_x11image_c.h" 34 #include "SDL_x11image_c.h"
35 35
36 /*#define X11MODES_DEBUG*/
37
36 #define MAX(a, b) (a > b ? a : b) 38 #define MAX(a, b) (a > b ? a : b)
37 39
38 #if SDL_VIDEO_DRIVER_X11_XRANDR 40 #if SDL_VIDEO_DRIVER_X11_XRANDR
39 static int cmpmodelist(const void *va, const void *vb) 41 static int cmpmodelist(const void *va, const void *vb)
40 { 42 {
101 #if SDL_VIDEO_DRIVER_X11_VIDMODE 103 #if SDL_VIDEO_DRIVER_X11_VIDMODE
102 if ( use_vidmode ) { 104 if ( use_vidmode ) {
103 SDL_NAME(XF86VidModeModeLine) mode; 105 SDL_NAME(XF86VidModeModeLine) mode;
104 SDL_NAME(XF86VidModeModeInfo) **modes; 106 SDL_NAME(XF86VidModeModeInfo) **modes;
105 int i; 107 int i;
106 int best_width = 0, best_height = 0;
107 int nmodes; 108 int nmodes;
109 int best = -1;
108 110
109 if ( SDL_NAME(XF86VidModeGetModeLine)(SDL_Display, SDL_Screen, &i, &mode) && 111 if ( SDL_NAME(XF86VidModeGetModeLine)(SDL_Display, SDL_Screen, &i, &mode) &&
110 SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display,SDL_Screen,&nmodes,&modes)){ 112 SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display,SDL_Screen,&nmodes,&modes) ) {
111 #ifdef X11MODES_DEBUG
112 printf("Available modes (unsorted):\n");
113 for ( i = 0; i < nmodes; ++i ) {
114 printf("Mode %d: %d x %d @ %d\n", i,
115 modes[i]->hdisplay, modes[i]->vdisplay,
116 1000 * modes[i]->dotclock / (modes[i]->htotal *
117 modes[i]->vtotal) );
118 }
119 #endif
120 for ( i = 0; i < nmodes ; i++ ) { 113 for ( i = 0; i < nmodes ; i++ ) {
121 if ( (modes[i]->hdisplay == width) && 114 if ( (modes[i]->hdisplay == width) &&
122 (modes[i]->vdisplay == height) ) 115 (modes[i]->vdisplay == height) ) {
123 goto match; 116 best = i;
124 } 117 break;
125 qsort(modes, nmodes, sizeof *modes, cmpmodes); 118 }
126 for ( i = nmodes-1; i > 0 ; i-- ) { 119 if ( modes[i]->hdisplay >= width &&
127 if ( ! best_width ) { 120 modes[i]->vdisplay >= height ) {
128 if ( (modes[i]->hdisplay >= width) && 121 if ( best < 0 ||
129 (modes[i]->vdisplay >= height) ) { 122 (modes[i]->hdisplay < modes[best]->hdisplay &&
130 best_width = modes[i]->hdisplay; 123 modes[i]->vdisplay <= modes[best]->vdisplay) ||
131 best_height = modes[i]->vdisplay; 124 (modes[i]->vdisplay < modes[best]->vdisplay &&
132 } 125 modes[i]->hdisplay <= modes[best]->hdisplay) ) {
133 } else { 126 best = i;
134 if ( (modes[i]->hdisplay != best_width) ||
135 (modes[i]->vdisplay != best_height) ) {
136 i++;
137 break;
138 } 127 }
139 } 128 }
140 } 129 }
141 match: 130 if ( best >= 0 &&
142 if ( (modes[i]->hdisplay != mode.hdisplay) || 131 ((modes[best]->hdisplay != mode.hdisplay) ||
143 (modes[i]->vdisplay != mode.vdisplay) ) { 132 (modes[best]->vdisplay != mode.vdisplay)) ) {
144 SDL_NAME(XF86VidModeSwitchToMode)(SDL_Display, SDL_Screen, modes[i]); 133 #ifdef X11MODES_DEBUG
134 printf("Best Mode %d: %d x %d @ %d\n", best,
135 modes[best]->hdisplay, modes[best]->vdisplay,
136 (modes[best]->htotal && modes[best]->vtotal) ? (1000 * modes[best]->dotclock / (modes[best]->htotal * modes[best]->vtotal)) : 0 );
137 #endif
138 SDL_NAME(XF86VidModeSwitchToMode)(SDL_Display, SDL_Screen, modes[best]);
145 } 139 }
146 XFree(modes); 140 XFree(modes);
147 } 141 }
148 } 142 }
149 #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */ 143 #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
150 144
151 /* XiG */ 145 /* XiG */
152 #if SDL_VIDEO_DRIVER_X11_XME 146 #if SDL_VIDEO_DRIVER_X11_XME
153 #ifdef X11MODES_DEBUG 147 if ( use_xme && SDL_modelist ) {
154 fprintf(stderr, "XME: set_best_resolution(): w = %d, h = %d\n",
155 width, height);
156 #endif
157 if ( SDL_modelist ) {
158 int i; 148 int i;
159 149
150 #ifdef X11MODES_DEBUG
151 fprintf(stderr, "XME: set_best_resolution(): w = %d, h = %d\n",
152 width, height);
153 #endif
160 for ( i=0; SDL_modelist[i]; ++i ) { 154 for ( i=0; SDL_modelist[i]; ++i ) {
161 if ( (SDL_modelist[i]->w >= width) && 155 if ( (SDL_modelist[i]->w >= width) &&
162 (SDL_modelist[i]->h >= height) ) { 156 (SDL_modelist[i]->h >= height) ) {
163 break; 157 break;
164 } 158 }
172 166
173 if ( (SDL_modelist[i]->w != w) || (SDL_modelist[i]->h != h) ) { 167 if ( (SDL_modelist[i]->w != w) || (SDL_modelist[i]->h != h) ) {
174 #ifdef X11MODES_DEBUG 168 #ifdef X11MODES_DEBUG
175 fprintf(stderr, "XME: set_best_resolution: " 169 fprintf(stderr, "XME: set_best_resolution: "
176 "XiGMiscChangeResolution: %d %d\n", 170 "XiGMiscChangeResolution: %d %d\n",
177 SDL_modelist[s]->w, SDL_modelist[s]->h); 171 SDL_modelist[i]->w, SDL_modelist[i]->h);
178 # endif 172 #endif
179 XiGMiscChangeResolution(SDL_Display, 173 XiGMiscChangeResolution(SDL_Display,
180 SDL_Screen, 174 SDL_Screen,
181 0, /* view */ 175 0, /* view */
182 SDL_modelist[i]->w, 176 SDL_modelist[i]->w,
183 SDL_modelist[i]->h, 177 SDL_modelist[i]->h,
187 } 181 }
188 } 182 }
189 #endif /* SDL_VIDEO_DRIVER_X11_XME */ 183 #endif /* SDL_VIDEO_DRIVER_X11_XME */
190 184
191 #if SDL_VIDEO_DRIVER_X11_XRANDR 185 #if SDL_VIDEO_DRIVER_X11_XRANDR
192 if ( use_xrandr ) { 186 if ( use_xrandr && SDL_modelist ) {
193 #ifdef X11MODES_DEBUG 187 #ifdef X11MODES_DEBUG
194 fprintf(stderr, "XRANDR: set_best_resolution(): w = %d, h = %d\n", 188 fprintf(stderr, "XRANDR: set_best_resolution(): w = %d, h = %d\n",
195 width, height); 189 width, height);
196 #endif 190 #endif
197 if ( SDL_modelist ) { 191 int i, nsizes;
198 int i, nsizes; 192 XRRScreenSize *sizes;
199 XRRScreenSize *sizes; 193
200 194 /* find the smallest resolution that is at least as big as the user requested */
201 /* find the smallest resolution that is at least as big as the user requested */ 195 sizes = XRRConfigSizes(screen_config, &nsizes);
202 sizes = XRRConfigSizes(screen_config, &nsizes); 196 for ( i = (nsizes-1); i >= 0; i-- ) {
203 for ( i = (nsizes-1); i >= 0; i-- ) { 197 if ( (SDL_modelist[i]->w >= width) &&
204 if ( (SDL_modelist[i]->w >= width) && 198 (SDL_modelist[i]->h >= height) ) {
205 (SDL_modelist[i]->h >= height) ) { 199 break;
206 break; 200 }
201 }
202
203 if ( i >= 0 && SDL_modelist[i] ) { /* found one, lets try it */
204 int w, h;
205
206 /* check current mode so we can avoid uneccessary mode changes */
207 get_real_resolution(this, &w, &h);
208
209 if ( (SDL_modelist[i]->w != w) || (SDL_modelist[i]->h != h) ) {
210 int size_id;
211
212 #ifdef X11MODES_DEBUG
213 fprintf(stderr, "XRANDR: set_best_resolution: "
214 "XXRSetScreenConfig: %d %d\n",
215 SDL_modelist[i]->w, SDL_modelist[i]->h);
216 #endif
217
218 /* find the matching size entry index */
219 for ( size_id = 0; size_id < nsizes; ++size_id ) {
220 if ( (sizes[size_id].width == SDL_modelist[i]->w) &&
221 (sizes[size_id].height == SDL_modelist[i]->h) )
222 break;
207 } 223 }
208 } 224
209 225 XRRSetScreenConfig(SDL_Display, screen_config, SDL_Root,
210 if ( i >= 0 && SDL_modelist[i] ) { /* found one, lets try it */ 226 size_id, saved_rotation, CurrentTime);
211 int w, h;
212
213 /* check current mode so we can avoid uneccessary mode changes */
214 get_real_resolution(this, &w, &h);
215
216 if ( (SDL_modelist[i]->w != w) || (SDL_modelist[i]->h != h) ) {
217 int size_id;
218
219 #ifdef X11MODES_DEBUG
220 fprintf(stderr, "XRANDR: set_best_resolution: "
221 "XXRSetScreenConfig: %d %d\n",
222 SDL_modelist[i]->w, SDL_modelist[i]->h);
223 #endif
224
225 /* find the matching size entry index */
226 for ( size_id = 0; size_id < nsizes; ++size_id ) {
227 if ( (sizes[size_id].width == SDL_modelist[i]->w) &&
228 (sizes[size_id].height == SDL_modelist[i]->h) )
229 break;
230 }
231
232 XRRSetScreenConfig(SDL_Display, screen_config, SDL_Root,
233 size_id, saved_rotation, CurrentTime);
234 }
235 } 227 }
236 } 228 }
237 } 229 }
238 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ 230 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
239
240 } 231 }
241 232
242 static void get_real_resolution(_THIS, int* w, int* h) 233 static void get_real_resolution(_THIS, int* w, int* h)
243 { 234 {
244 #if SDL_VIDEO_DRIVER_X11_XME 235 #if SDL_VIDEO_DRIVER_X11_XME
641 (!use_xinerama || xinerama_info.screen_number == 0) && 632 (!use_xinerama || xinerama_info.screen_number == 0) &&
642 CheckVidMode(this, &vm_major, &vm_minor) && 633 CheckVidMode(this, &vm_major, &vm_minor) &&
643 SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display, SDL_Screen,&nmodes,&modes) ) 634 SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display, SDL_Screen,&nmodes,&modes) )
644 { 635 {
645 #ifdef X11MODES_DEBUG 636 #ifdef X11MODES_DEBUG
646 printf("Available modes: (sorted)\n"); 637 printf("VidMode modes: (unsorted)\n");
647 for ( i = 0; i < nmodes; ++i ) { 638 for ( i = 0; i < nmodes; ++i ) {
648 printf("Mode %d: %d x %d @ %d\n", i, 639 printf("Mode %d: %d x %d @ %d\n", i,
649 modes[i]->hdisplay, modes[i]->vdisplay, 640 modes[i]->hdisplay, modes[i]->vdisplay,
650 (modes[i]->htotal && modes[i]->vtotal) ? (1000 * modes[i]->dotclock / (modes[i]->htotal * modes[i]->vtotal)) : 0 ); 641 (modes[i]->htotal && modes[i]->vtotal) ? (1000 * modes[i]->dotclock / (modes[i]->htotal * modes[i]->vtotal)) : 0 );
651 } 642 }
836 if ( use_xrandr ) { 827 if ( use_xrandr ) {
837 printf("XRandR is enabled\n"); 828 printf("XRandR is enabled\n");
838 } 829 }
839 830
840 if ( use_vidmode ) { 831 if ( use_vidmode ) {
841 printf("XFree86 VidMode is enabled\n"); 832 printf("VidMode is enabled\n");
842 } 833 }
843 834
844 if ( use_xme ) { 835 if ( use_xme ) {
845 printf("Xi Graphics XME fullscreen is enabled\n"); 836 printf("Xi Graphics XME fullscreen is enabled\n");
846 } 837 }