Mercurial > sdl-ios-xcode
comparison src/video/x11/SDL_x11modes.c @ 1659:14717b52abc0 SDL-1.3
Merge trunk-1.3-3
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Wed, 17 May 2006 08:18:28 +0000 |
parents | e49147870aac |
children | 782fd950bd46 |
comparison
equal
deleted
inserted
replaced
1658:e49147870aac | 1659:14717b52abc0 |
---|---|
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 #if SDL_VIDEO_DRIVER_X11_XINERAMA | 36 /*#define X11MODES_DEBUG*/ |
37 #include "../Xext/extensions/Xinerama.h" | |
38 #endif | |
39 | 37 |
40 #define MAX(a, b) (a > b ? a : b) | 38 #define MAX(a, b) (a > b ? a : b) |
39 | |
40 #if SDL_VIDEO_DRIVER_X11_XRANDR | |
41 static int cmpmodelist(const void *va, const void *vb) | |
42 { | |
43 const SDL_Rect *a = *(const SDL_Rect **)va; | |
44 const SDL_Rect *b = *(const SDL_Rect **)vb; | |
45 if ( a->w == b->w ) | |
46 return b->h - a->h; | |
47 else | |
48 return b->w - a->w; | |
49 } | |
50 #endif | |
41 | 51 |
42 #if SDL_VIDEO_DRIVER_X11_VIDMODE | 52 #if SDL_VIDEO_DRIVER_X11_VIDMODE |
43 Bool SDL_NAME(XF86VidModeGetModeInfo)(Display *dpy, int scr, SDL_NAME(XF86VidModeModeInfo) *info) | 53 Bool SDL_NAME(XF86VidModeGetModeInfo)(Display *dpy, int scr, SDL_NAME(XF86VidModeModeInfo) *info) |
44 { | 54 { |
45 SDL_NAME(XF86VidModeModeLine) *l = (SDL_NAME(XF86VidModeModeLine)*)((char*)info + sizeof info->dotclock); | 55 SDL_NAME(XF86VidModeModeLine) *l = (SDL_NAME(XF86VidModeModeLine)*)((char*)info + sizeof info->dotclock); |
84 else | 94 else |
85 return b->hdisplay - a->hdisplay; | 95 return b->hdisplay - a->hdisplay; |
86 } | 96 } |
87 #endif | 97 #endif |
88 | 98 |
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; | |
98 } | |
99 #endif | |
100 | |
101 static void get_real_resolution(_THIS, int* w, int* h); | 99 static void get_real_resolution(_THIS, int* w, int* h); |
102 | 100 |
103 static void set_best_resolution(_THIS, int width, int height) | 101 static void set_best_resolution(_THIS, int width, int height) |
104 { | 102 { |
105 #if SDL_VIDEO_DRIVER_X11_VIDMODE | 103 #if SDL_VIDEO_DRIVER_X11_VIDMODE |
106 if ( use_vidmode ) { | 104 if ( use_vidmode ) { |
107 SDL_NAME(XF86VidModeModeLine) mode; | 105 SDL_NAME(XF86VidModeModeLine) mode; |
108 SDL_NAME(XF86VidModeModeInfo) **modes; | 106 SDL_NAME(XF86VidModeModeInfo) **modes; |
109 int i; | 107 int i; |
110 int best_width = 0, best_height = 0; | |
111 int nmodes; | 108 int nmodes; |
109 int best = -1; | |
112 | 110 |
113 if ( SDL_NAME(XF86VidModeGetModeLine)(SDL_Display, SDL_Screen, &i, &mode) && | 111 if ( SDL_NAME(XF86VidModeGetModeLine)(SDL_Display, SDL_Screen, &i, &mode) && |
114 SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display,SDL_Screen,&nmodes,&modes)){ | 112 SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display,SDL_Screen,&nmodes,&modes) ) { |
115 #ifdef XFREE86_DEBUG | |
116 printf("Available modes (unsorted):\n"); | |
117 for ( i = 0; i < nmodes; ++i ) { | |
118 printf("Mode %d: %d x %d @ %d\n", i, | |
119 modes[i]->hdisplay, modes[i]->vdisplay, | |
120 1000 * modes[i]->dotclock / (modes[i]->htotal * | |
121 modes[i]->vtotal) ); | |
122 } | |
123 #endif | |
124 for ( i = 0; i < nmodes ; i++ ) { | 113 for ( i = 0; i < nmodes ; i++ ) { |
125 if ( (modes[i]->hdisplay == width) && | 114 if ( (modes[i]->hdisplay == width) && |
126 (modes[i]->vdisplay == height) ) | 115 (modes[i]->vdisplay == height) ) { |
127 goto match; | 116 best = i; |
128 } | 117 break; |
129 qsort(modes, nmodes, sizeof *modes, cmpmodes); | 118 } |
130 for ( i = nmodes-1; i > 0 ; i-- ) { | 119 if ( modes[i]->hdisplay >= width && |
131 if ( ! best_width ) { | 120 modes[i]->vdisplay >= height ) { |
132 if ( (modes[i]->hdisplay >= width) && | 121 if ( best < 0 || |
133 (modes[i]->vdisplay >= height) ) { | 122 (modes[i]->hdisplay < modes[best]->hdisplay && |
134 best_width = modes[i]->hdisplay; | 123 modes[i]->vdisplay <= modes[best]->vdisplay) || |
135 best_height = modes[i]->vdisplay; | 124 (modes[i]->vdisplay < modes[best]->vdisplay && |
136 } | 125 modes[i]->hdisplay <= modes[best]->hdisplay) ) { |
137 } else { | 126 best = i; |
138 if ( (modes[i]->hdisplay != best_width) || | |
139 (modes[i]->vdisplay != best_height) ) { | |
140 i++; | |
141 break; | |
142 } | 127 } |
143 } | 128 } |
144 } | 129 } |
145 match: | 130 if ( best >= 0 && |
146 if ( (modes[i]->hdisplay != mode.hdisplay) || | 131 ((modes[best]->hdisplay != mode.hdisplay) || |
147 (modes[i]->vdisplay != mode.vdisplay) ) { | 132 (modes[best]->vdisplay != mode.vdisplay)) ) { |
148 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]); | |
149 } | 139 } |
150 XFree(modes); | 140 XFree(modes); |
151 } | 141 } |
152 } | 142 } |
153 #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */ | 143 #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */ |
154 | 144 |
155 /* XiG */ | 145 /* XiG */ |
156 #if SDL_VIDEO_DRIVER_X11_XME | 146 #if SDL_VIDEO_DRIVER_X11_XME |
157 #ifdef XIG_DEBUG | 147 if ( use_xme && SDL_modelist ) { |
158 fprintf(stderr, "XME: set_best_resolution(): w = %d, h = %d\n", | |
159 width, height); | |
160 #endif | |
161 if ( SDL_modelist ) { | |
162 int i; | 148 int i; |
163 | 149 |
150 #ifdef X11MODES_DEBUG | |
151 fprintf(stderr, "XME: set_best_resolution(): w = %d, h = %d\n", | |
152 width, height); | |
153 #endif | |
164 for ( i=0; SDL_modelist[i]; ++i ) { | 154 for ( i=0; SDL_modelist[i]; ++i ) { |
165 if ( (SDL_modelist[i]->w >= width) && | 155 if ( (SDL_modelist[i]->w >= width) && |
166 (SDL_modelist[i]->h >= height) ) { | 156 (SDL_modelist[i]->h >= height) ) { |
167 break; | 157 break; |
168 } | 158 } |
173 | 163 |
174 /* check current mode so we can avoid uneccessary mode changes */ | 164 /* check current mode so we can avoid uneccessary mode changes */ |
175 get_real_resolution(this, &w, &h); | 165 get_real_resolution(this, &w, &h); |
176 | 166 |
177 if ( (SDL_modelist[i]->w != w) || (SDL_modelist[i]->h != h) ) { | 167 if ( (SDL_modelist[i]->w != w) || (SDL_modelist[i]->h != h) ) { |
178 # ifdef XIG_DEBUG | 168 #ifdef X11MODES_DEBUG |
179 fprintf(stderr, "XME: set_best_resolution: " | 169 fprintf(stderr, "XME: set_best_resolution: " |
180 "XiGMiscChangeResolution: %d %d\n", | 170 "XiGMiscChangeResolution: %d %d\n", |
181 SDL_modelist[s]->w, SDL_modelist[s]->h); | 171 SDL_modelist[i]->w, SDL_modelist[i]->h); |
182 # endif | 172 #endif |
183 XiGMiscChangeResolution(SDL_Display, | 173 XiGMiscChangeResolution(SDL_Display, |
184 SDL_Screen, | 174 SDL_Screen, |
185 0, /* view */ | 175 0, /* view */ |
186 SDL_modelist[i]->w, | 176 SDL_modelist[i]->w, |
187 SDL_modelist[i]->h, | 177 SDL_modelist[i]->h, |
191 } | 181 } |
192 } | 182 } |
193 #endif /* SDL_VIDEO_DRIVER_X11_XME */ | 183 #endif /* SDL_VIDEO_DRIVER_X11_XME */ |
194 | 184 |
195 #if SDL_VIDEO_DRIVER_X11_XRANDR | 185 #if SDL_VIDEO_DRIVER_X11_XRANDR |
196 if ( use_xrandr ) { | 186 if ( use_xrandr && SDL_modelist ) { |
197 #ifdef XRANDR_DEBUG | 187 #ifdef X11MODES_DEBUG |
198 fprintf(stderr, "XRANDR: set_best_resolution(): w = %d, h = %d\n", | 188 fprintf(stderr, "XRANDR: set_best_resolution(): w = %d, h = %d\n", |
199 width, height); | 189 width, height); |
200 #endif | 190 #endif |
201 if ( SDL_modelist ) { | 191 int i, nsizes; |
202 int i, nsizes; | 192 XRRScreenSize *sizes; |
203 XRRScreenSize *sizes; | 193 |
204 | 194 /* find the smallest resolution that is at least as big as the user requested */ |
205 /* find the smallest resolution that is at least as big as the user requested */ | 195 sizes = XRRConfigSizes(screen_config, &nsizes); |
206 sizes = XRRConfigSizes(screen_config, &nsizes); | 196 for ( i = (nsizes-1); i >= 0; i-- ) { |
207 for ( i = (nsizes-1); i >= 0; i-- ) { | 197 if ( (SDL_modelist[i]->w >= width) && |
208 if ( (SDL_modelist[i]->w >= width) && | 198 (SDL_modelist[i]->h >= height) ) { |
209 (SDL_modelist[i]->h >= height) ) { | 199 break; |
210 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; | |
211 } | 223 } |
212 } | 224 |
213 | 225 XRRSetScreenConfig(SDL_Display, screen_config, SDL_Root, |
214 if ( i >= 0 && SDL_modelist[i] ) { /* found one, lets try it */ | 226 size_id, saved_rotation, CurrentTime); |
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 } | 227 } |
240 } | 228 } |
241 } | 229 } |
242 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ | 230 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ |
243 | |
244 } | 231 } |
245 | 232 |
246 static void get_real_resolution(_THIS, int* w, int* h) | 233 static void get_real_resolution(_THIS, int* w, int* h) |
247 { | 234 { |
248 #if SDL_VIDEO_DRIVER_X11_VIDMODE | |
249 if ( use_vidmode ) { | |
250 SDL_NAME(XF86VidModeModeLine) mode; | |
251 int unused; | |
252 | |
253 if ( SDL_NAME(XF86VidModeGetModeLine)(SDL_Display, SDL_Screen, &unused, &mode) ) { | |
254 *w = mode.hdisplay; | |
255 *h = mode.vdisplay; | |
256 return; | |
257 } | |
258 } | |
259 #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */ | |
260 | |
261 #if SDL_VIDEO_DRIVER_X11_XME | 235 #if SDL_VIDEO_DRIVER_X11_XME |
262 if ( use_xme ) { | 236 if ( use_xme ) { |
263 int ractive; | 237 int ractive; |
264 XiGMiscResolutionInfo *modelist; | 238 XiGMiscResolutionInfo *modelist; |
265 | 239 |
266 XiGMiscQueryResolutions(SDL_Display, SDL_Screen, | 240 XiGMiscQueryResolutions(SDL_Display, SDL_Screen, |
267 0, /* view */ | 241 0, /* view */ |
268 &ractive, &modelist); | 242 &ractive, &modelist); |
269 *w = modelist[ractive].width; | 243 *w = modelist[ractive].width; |
270 *h = modelist[ractive].height; | 244 *h = modelist[ractive].height; |
271 #ifdef XIG_DEBUG | 245 #ifdef X11MODES_DEBUG |
272 fprintf(stderr, "XME: get_real_resolution: w = %d h = %d\n", *w, *h); | 246 fprintf(stderr, "XME: get_real_resolution: w = %d h = %d\n", *w, *h); |
273 #endif | 247 #endif |
274 XFree(modelist); | 248 XFree(modelist); |
275 return; | 249 return; |
276 } | 250 } |
277 #endif /* SDL_VIDEO_DRIVER_X11_XME */ | 251 #endif /* SDL_VIDEO_DRIVER_X11_XME */ |
252 | |
253 #if SDL_VIDEO_DRIVER_X11_VIDMODE | |
254 if ( use_vidmode ) { | |
255 SDL_NAME(XF86VidModeModeLine) mode; | |
256 int unused; | |
257 | |
258 if ( SDL_NAME(XF86VidModeGetModeLine)(SDL_Display, SDL_Screen, &unused, &mode) ) { | |
259 *w = mode.hdisplay; | |
260 *h = mode.vdisplay; | |
261 return; | |
262 } | |
263 } | |
264 #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */ | |
278 | 265 |
279 #if SDL_VIDEO_DRIVER_X11_XRANDR | 266 #if SDL_VIDEO_DRIVER_X11_XRANDR |
280 if ( use_xrandr ) { | 267 if ( use_xrandr ) { |
281 int nsizes; | 268 int nsizes; |
282 XRRScreenSize* sizes; | 269 XRRScreenSize* sizes; |
289 cur_size = XRRConfigCurrentConfiguration(screen_config, &cur_rotation); | 276 cur_size = XRRConfigCurrentConfiguration(screen_config, &cur_rotation); |
290 if ( cur_size >= 0 && cur_size < nsizes ) { | 277 if ( cur_size >= 0 && cur_size < nsizes ) { |
291 *w = sizes[cur_size].width; | 278 *w = sizes[cur_size].width; |
292 *h = sizes[cur_size].height; | 279 *h = sizes[cur_size].height; |
293 } | 280 } |
294 #ifdef XRANDR_DEBUG | 281 #ifdef X11MODES_DEBUG |
295 fprintf(stderr, "XRANDR: get_real_resolution: w = %d h = %d\n", *w, *h); | 282 fprintf(stderr, "XRANDR: get_real_resolution: w = %d h = %d\n", *w, *h); |
296 #endif | 283 #endif |
297 return; | 284 return; |
298 } | 285 } |
299 } | 286 } |
300 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ | 287 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ |
288 | |
289 #if SDL_VIDEO_DRIVER_X11_XINERAMA | |
290 if ( use_xinerama ) { | |
291 *w = xinerama_info.width; | |
292 *h = xinerama_info.height; | |
293 return; | |
294 } | |
295 #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */ | |
301 | 296 |
302 *w = DisplayWidth(SDL_Display, SDL_Screen); | 297 *w = DisplayWidth(SDL_Display, SDL_Screen); |
303 *h = DisplayHeight(SDL_Display, SDL_Screen); | 298 *h = DisplayHeight(SDL_Display, SDL_Screen); |
304 } | 299 } |
305 | 300 |
358 } | 353 } |
359 | 354 |
360 /* Global for the error handler */ | 355 /* Global for the error handler */ |
361 int vm_event, vm_error = -1; | 356 int vm_event, vm_error = -1; |
362 | 357 |
363 int X11_GetVideoModes(_THIS) | 358 #if SDL_VIDEO_DRIVER_X11_XINERAMA |
364 { | 359 static int CheckXinerama(_THIS, int *major, int *minor) |
365 #if SDL_VIDEO_DRIVER_X11_VIDMODE | 360 { |
366 int buggy_X11; | 361 const char *env; |
367 int vm_major, vm_minor; | 362 |
368 int nmodes; | 363 /* Default the extension not available */ |
369 SDL_NAME(XF86VidModeModeInfo) **modes; | 364 *major = *minor = 0; |
370 #endif | 365 |
371 #if SDL_VIDEO_DRIVER_X11_XME | 366 /* Allow environment override */ |
372 int xme_major, xme_minor; | 367 env = getenv("SDL_VIDEO_X11_XINERAMA"); |
373 int ractive, nummodes; | 368 if ( env && !SDL_atoi(env) ) { |
374 XiGMiscResolutionInfo *modelist; | 369 return 0; |
375 #endif | 370 } |
371 | |
372 /* Query the extension version */ | |
373 if ( !SDL_NAME(XineramaQueryExtension)(SDL_Display, major, minor) || | |
374 !SDL_NAME(XineramaIsActive)(SDL_Display) ) { | |
375 return 0; | |
376 } | |
377 return 1; | |
378 } | |
379 #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */ | |
380 | |
376 #if SDL_VIDEO_DRIVER_X11_XRANDR | 381 #if SDL_VIDEO_DRIVER_X11_XRANDR |
377 int xrandr_major, xrandr_minor; | 382 static int CheckXRandR(_THIS, int *major, int *minor) |
378 int nsizes; | 383 { |
379 XRRScreenSize *sizes; | 384 const char *env; |
380 #endif | 385 |
381 int i, n; | 386 /* Default the extension not available */ |
382 int screen_w; | 387 *major = *minor = 0; |
383 int screen_h; | 388 |
384 | 389 /* Allow environment override */ |
385 vm_error = -1; | 390 env = getenv("SDL_VIDEO_X11_XRANDR"); |
386 use_vidmode = 0; | 391 if ( env && !SDL_atoi(env) ) { |
387 use_xrandr = 0; | 392 return 0; |
388 screen_w = DisplayWidth(SDL_Display, SDL_Screen); | 393 } |
389 screen_h = DisplayHeight(SDL_Display, SDL_Screen); | 394 |
390 | 395 /* This defaults off now, due to KDE window maximize problems */ |
391 /* XRandR */ | 396 if ( !env ) { |
392 #if SDL_VIDEO_DRIVER_X11_XRANDR | 397 return 0; |
393 /* require at least XRandR v1.0 (arbitrary) */ | 398 } |
394 if ( ( SDL_X11_HAVE_XRANDR ) && | 399 |
395 ( getenv("SDL_VIDEO_X11_NO_XRANDR") == NULL ) && | 400 if ( !SDL_X11_HAVE_XRANDR ) { |
396 ( XRRQueryVersion(SDL_Display, &xrandr_major, &xrandr_minor) ) && | 401 return 0; |
397 ( xrandr_major >= 1 ) ) { | 402 } |
398 | 403 |
399 #ifdef XRANDR_DEBUG | 404 /* Query the extension version */ |
400 fprintf(stderr, "XRANDR: XRRQueryVersion: V%d.%d\n", | 405 if ( !XRRQueryVersion(SDL_Display, major, minor) ) { |
401 xrandr_major, xrandr_minor); | 406 return 0; |
402 #endif | 407 } |
403 | 408 return 1; |
404 /* save the screen configuration since we must reference it | 409 } |
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 */ | 410 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ |
438 | 411 |
439 #if SDL_VIDEO_DRIVER_X11_VIDMODE | 412 #if SDL_VIDEO_DRIVER_X11_VIDMODE |
413 static int CheckVidMode(_THIS, int *major, int *minor) | |
414 { | |
415 const char *env; | |
416 | |
417 /* Default the extension not available */ | |
418 *major = *minor = 0; | |
419 | |
420 /* Allow environment override */ | |
421 env = getenv("SDL_VIDEO_X11_VIDMODE"); | |
422 if ( env && !SDL_atoi(env) ) { | |
423 return 0; | |
424 } | |
425 | |
440 /* Metro-X 4.3.0 and earlier has a broken implementation of | 426 /* Metro-X 4.3.0 and earlier has a broken implementation of |
441 XF86VidModeGetAllModeLines() - it hangs the client. | 427 XF86VidModeGetAllModeLines() - it hangs the client. |
442 */ | 428 */ |
443 buggy_X11 = 0; | |
444 if ( SDL_strcmp(ServerVendor(SDL_Display), "Metro Link Incorporated") == 0 ) { | 429 if ( SDL_strcmp(ServerVendor(SDL_Display), "Metro Link Incorporated") == 0 ) { |
445 FILE *metro_fp; | 430 FILE *metro_fp; |
446 | 431 |
447 metro_fp = fopen("/usr/X11R6/lib/X11/Metro/.version", "r"); | 432 metro_fp = fopen("/usr/X11R6/lib/X11/Metro/.version", "r"); |
448 if ( metro_fp != NULL ) { | 433 if ( metro_fp != NULL ) { |
449 int major, minor, patch, version; | 434 int major, minor, patch, version; |
450 major = 0; minor = 0; patch = 0; | 435 major = 0; minor = 0; patch = 0; |
451 fscanf(metro_fp, "%d.%d.%d", &major, &minor, &patch); | 436 fscanf(metro_fp, "%d.%d.%d", &major, &minor, &patch); |
437 fclose(metro_fp); | |
452 version = major*100+minor*10+patch; | 438 version = major*100+minor*10+patch; |
453 if ( version < 431 ) { | 439 if ( version < 431 ) { |
454 buggy_X11 = 1; | 440 return 0; |
455 } | 441 } |
456 fclose(metro_fp); | 442 } |
457 } | 443 } |
458 } | 444 |
459 #if 0 /* Let's try this again... hopefully X servers have improved... */ | 445 /* Query the extension version */ |
460 #if defined(__alpha__) || defined(__sparc64__) || defined(__powerpc__) | 446 vm_error = -1; |
461 /* The alpha, sparc64 and PPC XFree86 servers are also buggy */ | 447 if ( !SDL_NAME(XF86VidModeQueryExtension)(SDL_Display, &vm_event, &vm_error) || |
462 buggy_X11 = 1; | 448 !SDL_NAME(XF86VidModeQueryVersion)(SDL_Display, major, minor) ) { |
463 #endif | 449 return 0; |
464 #endif | 450 } |
465 /* Enumerate the available fullscreen modes */ | 451 return 1; |
466 if ( ! buggy_X11 ) { | 452 } |
467 if ( SDL_NAME(XF86VidModeQueryExtension)(SDL_Display, &vm_event, &vm_error) && | 453 #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */ |
468 SDL_NAME(XF86VidModeQueryVersion)(SDL_Display, &vm_major, &vm_minor) ) { | 454 |
469 #ifdef BROKEN_XFREE86_4001 | 455 #if SDL_VIDEO_DRIVER_X11_XME |
470 #ifdef X_XF86VidModeGetDotClocks /* Compiled under XFree86 4.0 */ | 456 static int CheckXME(_THIS, int *major, int *minor) |
471 /* Earlier X servers hang when doing vidmode */ | 457 { |
472 if ( vm_major < 2 ) { | 458 const char *env; |
473 #ifdef XFREE86_DEBUG | 459 |
474 printf("Compiled under XFree86 4.0, server is XFree86 3.X\n"); | 460 /* Default the extension not available */ |
475 #endif | 461 *major = *minor = 0; |
476 buggy_X11 = 1; | 462 |
463 /* Allow environment override */ | |
464 env = getenv("SDL_VIDEO_X11_VIDMODE"); | |
465 if ( env && !SDL_atoi(env) ) { | |
466 return 0; | |
467 } | |
468 | |
469 /* Query the extension version */ | |
470 if ( !XiGMiscQueryVersion(SDL_Display, major, minor) ) { | |
471 return 0; | |
472 } | |
473 return 1; | |
474 } | |
475 #endif /* SDL_VIDEO_DRIVER_X11_XME */ | |
476 | |
477 int X11_GetVideoModes(_THIS) | |
478 { | |
479 #if SDL_VIDEO_DRIVER_X11_XINERAMA | |
480 int xinerama_major, xinerama_minor; | |
481 #endif | |
482 #if SDL_VIDEO_DRIVER_X11_XRANDR | |
483 int xrandr_major, xrandr_minor; | |
484 int nsizes; | |
485 XRRScreenSize *sizes; | |
486 #endif | |
487 #if SDL_VIDEO_DRIVER_X11_VIDMODE | |
488 int vm_major, vm_minor; | |
489 int nmodes; | |
490 SDL_NAME(XF86VidModeModeInfo) **modes; | |
491 #endif | |
492 #if SDL_VIDEO_DRIVER_X11_XME | |
493 int xme_major, xme_minor; | |
494 int ractive, nummodes; | |
495 XiGMiscResolutionInfo *modelist; | |
496 #endif | |
497 int i, n; | |
498 int screen_w; | |
499 int screen_h; | |
500 | |
501 use_xinerama = 0; | |
502 use_xrandr = 0; | |
503 use_vidmode = 0; | |
504 use_xme = 0; | |
505 screen_w = DisplayWidth(SDL_Display, SDL_Screen); | |
506 screen_h = DisplayHeight(SDL_Display, SDL_Screen); | |
507 | |
508 #if SDL_VIDEO_DRIVER_X11_XINERAMA | |
509 /* Query Xinerama extention */ | |
510 if ( CheckXinerama(this, &xinerama_major, &xinerama_minor) ) { | |
511 /* Find out which screen is the desired one */ | |
512 int desired = 0; | |
513 int screens; | |
514 int w, h; | |
515 SDL_NAME(XineramaScreenInfo) *xinerama; | |
516 | |
517 const char *variable = SDL_getenv("SDL_VIDEO_FULLSCREEN_HEAD"); | |
518 if ( variable ) { | |
519 desired = SDL_atoi(variable); | |
520 } | |
521 #ifdef X11MODES_DEBUG | |
522 printf("X11 detected Xinerama:\n"); | |
523 #endif | |
524 xinerama = SDL_NAME(XineramaQueryScreens)(SDL_Display, &screens); | |
525 for ( i = 0; i < screens; i++ ) { | |
526 #ifdef X11MODES_DEBUG | |
527 printf("xinerama %d: %dx%d+%d+%d\n", | |
528 xinerama[i].screen_number, | |
529 xinerama[i].width, xinerama[i].height, | |
530 xinerama[i].x_org, xinerama[i].y_org); | |
531 #endif | |
532 if ( xinerama[i].screen_number == desired ) { | |
533 use_xinerama = 1; | |
534 xinerama_info = xinerama[i]; | |
535 } | |
536 } | |
537 XFree(xinerama); | |
538 | |
539 if ( use_xinerama ) { | |
540 SDL_modelist = (SDL_Rect **)SDL_malloc(3*sizeof(SDL_Rect *)); | |
541 if ( !SDL_modelist ) { | |
542 SDL_OutOfMemory(); | |
543 return -1; | |
544 } | |
545 | |
546 /* Add the full xinerama mode */ | |
547 n = 0; | |
548 w = xinerama_info.width; | |
549 h = xinerama_info.height; | |
550 if ( screen_w > w || screen_h > h) { | |
551 SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect)); | |
552 if ( SDL_modelist[n] ) { | |
553 SDL_modelist[n]->x = 0; | |
554 SDL_modelist[n]->y = 0; | |
555 SDL_modelist[n]->w = screen_w; | |
556 SDL_modelist[n]->h = screen_h; | |
557 ++n; | |
477 } | 558 } |
478 #else | 559 } |
479 /* XFree86 3.X code works with XFree86 4.0 servers */; | 560 |
480 #endif /* XFree86 4.0 */ | 561 /* Add the head xinerama mode */ |
481 #endif /* XFree86 4.02 and newer are fixed wrt backwards compatibility */ | 562 SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect)); |
482 } else { | 563 if ( SDL_modelist[n] ) { |
483 buggy_X11 = 1; | |
484 } | |
485 } | |
486 if ( ! buggy_X11 && ! use_xrandr && | |
487 SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display, SDL_Screen,&nmodes,&modes) ) { | |
488 | |
489 #ifdef XFREE86_DEBUG | |
490 printf("Available modes: (sorted)\n"); | |
491 for ( i = 0; i < nmodes; ++i ) { | |
492 printf("Mode %d: %d x %d @ %d\n", i, | |
493 modes[i]->hdisplay, modes[i]->vdisplay, | |
494 1000 * modes[i]->dotclock / (modes[i]->htotal * | |
495 modes[i]->vtotal) ); | |
496 } | |
497 #endif | |
498 | |
499 SDL_qsort(modes, nmodes, sizeof *modes, cmpmodes); | |
500 SDL_modelist = (SDL_Rect **)SDL_malloc((nmodes+2)*sizeof(SDL_Rect *)); | |
501 if ( SDL_modelist ) { | |
502 n = 0; | |
503 for ( i=0; i<nmodes; ++i ) { | |
504 int w, h; | |
505 | |
506 /* Eliminate duplicate modes with different refresh rates */ | |
507 if ( i > 0 && | |
508 modes[i]->hdisplay == modes[i-1]->hdisplay && | |
509 modes[i]->vdisplay == modes[i-1]->vdisplay ) { | |
510 continue; | |
511 } | |
512 | |
513 /* Check to see if we should add the screen size (Xinerama) */ | |
514 w = modes[i]->hdisplay; | |
515 h = modes[i]->vdisplay; | |
516 if ( (screen_w * screen_h) >= (w * h) ) { | |
517 if ( (screen_w != w) || (screen_h != h) ) { | |
518 SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect)); | |
519 if ( SDL_modelist[n] ) { | |
520 SDL_modelist[n]->x = 0; | |
521 SDL_modelist[n]->y = 0; | |
522 SDL_modelist[n]->w = screen_w; | |
523 SDL_modelist[n]->h = screen_h; | |
524 ++n; | |
525 } | |
526 } | |
527 screen_w = 0; | |
528 screen_h = 0; | |
529 } | |
530 | |
531 /* Add the size from the video mode list */ | |
532 SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect)); | |
533 if ( SDL_modelist[n] == NULL ) { | |
534 break; | |
535 } | |
536 SDL_modelist[n]->x = 0; | 564 SDL_modelist[n]->x = 0; |
537 SDL_modelist[n]->y = 0; | 565 SDL_modelist[n]->y = 0; |
538 SDL_modelist[n]->w = w; | 566 SDL_modelist[n]->w = w; |
539 SDL_modelist[n]->h = h; | 567 SDL_modelist[n]->h = h; |
540 ++n; | 568 ++n; |
541 } | 569 } |
542 SDL_modelist[n] = NULL; | 570 SDL_modelist[n] = NULL; |
543 } | 571 } |
572 } | |
573 #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */ | |
574 | |
575 #if SDL_VIDEO_DRIVER_X11_XRANDR | |
576 /* XRandR */ | |
577 /* require at least XRandR v1.0 (arbitrary) */ | |
578 if ( CheckXRandR(this, &xrandr_major, &xrandr_minor) && (xrandr_major >= 1) ) | |
579 { | |
580 #ifdef X11MODES_DEBUG | |
581 fprintf(stderr, "XRANDR: XRRQueryVersion: V%d.%d\n", | |
582 xrandr_major, xrandr_minor); | |
583 #endif | |
584 | |
585 /* save the screen configuration since we must reference it | |
586 each time we toggle modes. | |
587 */ | |
588 screen_config = XRRGetScreenInfo(SDL_Display, SDL_Root); | |
589 | |
590 /* retrieve the list of resolution */ | |
591 sizes = XRRConfigSizes(screen_config, &nsizes); | |
592 if (nsizes > 0) { | |
593 if ( SDL_modelist ) { | |
594 for ( i = 0; SDL_modelist[i]; ++i ) { | |
595 SDL_free(SDL_modelist[i]); | |
596 } | |
597 SDL_free(SDL_modelist); | |
598 } | |
599 SDL_modelist = (SDL_Rect **)malloc((nsizes+1)*sizeof(SDL_Rect *)); | |
600 if ( !SDL_modelist ) { | |
601 SDL_OutOfMemory(); | |
602 return -1; | |
603 } | |
604 for ( i=0; i < nsizes; i++ ) { | |
605 if ((SDL_modelist[i] = | |
606 (SDL_Rect *)malloc(sizeof(SDL_Rect))) == NULL) | |
607 break; | |
608 #ifdef X11MODES_DEBUG | |
609 fprintf(stderr, "XRANDR: mode = %4d, w = %4d, h = %4d\n", | |
610 i, sizes[i].width, sizes[i].height); | |
611 #endif | |
612 | |
613 SDL_modelist[i]->x = 0; | |
614 SDL_modelist[i]->y = 0; | |
615 SDL_modelist[i]->w = sizes[i].width; | |
616 SDL_modelist[i]->h = sizes[i].height; | |
617 | |
618 } | |
619 /* sort the mode list descending as SDL expects */ | |
620 SDL_qsort(SDL_modelist, nsizes, sizeof *SDL_modelist, cmpmodelist); | |
621 SDL_modelist[i] = NULL; /* terminator */ | |
622 | |
623 use_xrandr = xrandr_major * 100 + xrandr_minor; | |
624 saved_size_id = XRRConfigCurrentConfiguration(screen_config, &saved_rotation); | |
625 } | |
626 } | |
627 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ | |
628 | |
629 #if SDL_VIDEO_DRIVER_X11_VIDMODE | |
630 /* XVidMode */ | |
631 if ( !use_xrandr && | |
632 (!use_xinerama || xinerama_info.screen_number == 0) && | |
633 CheckVidMode(this, &vm_major, &vm_minor) && | |
634 SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display, SDL_Screen,&nmodes,&modes) ) | |
635 { | |
636 #ifdef X11MODES_DEBUG | |
637 printf("VidMode modes: (unsorted)\n"); | |
638 for ( i = 0; i < nmodes; ++i ) { | |
639 printf("Mode %d: %d x %d @ %d\n", i, | |
640 modes[i]->hdisplay, modes[i]->vdisplay, | |
641 (modes[i]->htotal && modes[i]->vtotal) ? (1000 * modes[i]->dotclock / (modes[i]->htotal * modes[i]->vtotal)) : 0 ); | |
642 } | |
643 #endif | |
644 if ( SDL_modelist ) { | |
645 for ( i = 0; SDL_modelist[i]; ++i ) { | |
646 SDL_free(SDL_modelist[i]); | |
647 } | |
648 SDL_free(SDL_modelist); | |
649 } | |
650 SDL_modelist = (SDL_Rect **)SDL_malloc((nmodes+2)*sizeof(SDL_Rect *)); | |
651 if ( !SDL_modelist ) { | |
652 SDL_OutOfMemory(); | |
653 return -1; | |
654 } | |
655 SDL_qsort(modes, nmodes, sizeof *modes, cmpmodes); | |
656 n = 0; | |
657 for ( i=0; i<nmodes; ++i ) { | |
658 int w, h; | |
659 | |
660 /* Eliminate duplicate modes with different refresh rates */ | |
661 if ( i > 0 && | |
662 modes[i]->hdisplay == modes[i-1]->hdisplay && | |
663 modes[i]->vdisplay == modes[i-1]->vdisplay ) { | |
664 continue; | |
665 } | |
666 | |
667 /* Check to see if we should add the screen size (Xinerama) */ | |
668 w = modes[i]->hdisplay; | |
669 h = modes[i]->vdisplay; | |
670 if ( (screen_w * screen_h) >= (w * h) ) { | |
671 if ( (screen_w != w) || (screen_h != h) ) { | |
672 SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect)); | |
673 if ( SDL_modelist[n] ) { | |
674 SDL_modelist[n]->x = 0; | |
675 SDL_modelist[n]->y = 0; | |
676 SDL_modelist[n]->w = screen_w; | |
677 SDL_modelist[n]->h = screen_h; | |
678 ++n; | |
679 } | |
680 } | |
681 screen_w = 0; | |
682 screen_h = 0; | |
683 } | |
684 | |
685 /* Add the size from the video mode list */ | |
686 SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect)); | |
687 if ( SDL_modelist[n] == NULL ) { | |
688 break; | |
689 } | |
690 SDL_modelist[n]->x = 0; | |
691 SDL_modelist[n]->y = 0; | |
692 SDL_modelist[n]->w = w; | |
693 SDL_modelist[n]->h = h; | |
694 ++n; | |
695 } | |
696 SDL_modelist[n] = NULL; | |
544 XFree(modes); | 697 XFree(modes); |
545 | 698 |
546 use_vidmode = vm_major * 100 + vm_minor; | 699 use_vidmode = vm_major * 100 + vm_minor; |
547 save_mode(this); | 700 save_mode(this); |
548 } | 701 } |
549 #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */ | 702 #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */ |
550 | 703 |
551 /* XiG */ | |
552 #if SDL_VIDEO_DRIVER_X11_XME | 704 #if SDL_VIDEO_DRIVER_X11_XME |
705 /* XiG */ | |
706 modelist = NULL; | |
553 /* first lets make sure we have the extension, and it's at least v2.0 */ | 707 /* first lets make sure we have the extension, and it's at least v2.0 */ |
554 if (XiGMiscQueryVersion(SDL_Display, &xme_major, &xme_minor)) { | 708 if ( CheckXME(this, &xme_major, &xme_minor) && xme_major >= 2 && |
555 #ifdef XIG_DEBUG | 709 (nummodes = XiGMiscQueryResolutions(SDL_Display, SDL_Screen, |
556 fprintf(stderr, "XME: XiGMiscQueryVersion: V%d.%d\n", | 710 0, /* view */ |
557 xme_major, xme_minor); | 711 &ractive, &modelist)) > 1 ) |
558 #endif | |
559 /* work around a XiGMisc bogosity in our version of libXext */ | |
560 if (xme_major == 0 && xme_major == 0) { | |
561 /* Ideally libxme would spit this out, but the problem is that | |
562 the right Query func will never be called if using the bogus | |
563 libXext version. | |
564 */ | |
565 fprintf(stderr, | |
566 "XME: If you are using Xi Graphics CDE and a Summit server, you need to\n" | |
567 "XME: get the libXext update from Xi's ftp site before fullscreen switching\n" | |
568 "XME: will work. Fullscreen switching is only supported on Summit Servers\n"); | |
569 } | |
570 } else { | |
571 /* not there. Bummer. */ | |
572 xme_major = xme_minor = 0; | |
573 } | |
574 | |
575 modelist = NULL; | |
576 if (xme_major >= 2 && (nummodes = XiGMiscQueryResolutions(SDL_Display, | |
577 SDL_Screen, | |
578 0, /* view */ | |
579 &ractive, | |
580 &modelist)) > 1) | |
581 { /* then we actually have some */ | 712 { /* then we actually have some */ |
582 int j; | 713 int j; |
583 | 714 |
584 #ifdef XIG_DEBUG | 715 /* We get the list already sorted in descending order. |
716 We'll copy it in reverse order so SDL is happy */ | |
717 #ifdef X11MODES_DEBUG | |
585 fprintf(stderr, "XME: nummodes = %d, active mode = %d\n", | 718 fprintf(stderr, "XME: nummodes = %d, active mode = %d\n", |
586 nummodes, ractive); | 719 nummodes, ractive); |
587 #endif | 720 #endif |
588 | 721 if ( SDL_modelist ) { |
722 for ( i = 0; SDL_modelist[i]; ++i ) { | |
723 SDL_free(SDL_modelist[i]); | |
724 } | |
725 SDL_free(SDL_modelist); | |
726 } | |
589 SDL_modelist = (SDL_Rect **)SDL_malloc((nummodes+1)*sizeof(SDL_Rect *)); | 727 SDL_modelist = (SDL_Rect **)SDL_malloc((nummodes+1)*sizeof(SDL_Rect *)); |
590 | 728 if ( !SDL_modelist ) { |
591 /* we get the list already sorted in */ | 729 SDL_OutOfMemory(); |
592 /* descending order. We'll copy it in */ | 730 return -1; |
593 /* reverse order so SDL is happy */ | 731 } |
594 if (SDL_modelist) { | 732 for ( i=0, j=nummodes-1; j>=0; i++, j-- ) { |
595 for ( i=0, j=nummodes-1; j>=0; i++, j-- ) { | 733 if ((SDL_modelist[i] = |
596 if ((SDL_modelist[i] = | 734 (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect))) == NULL) |
597 (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect))) == NULL) | 735 break; |
598 break; | 736 #ifdef X11MODES_DEBUG |
599 #ifdef XIG_DEBUG | 737 fprintf(stderr, "XME: mode = %4d, w = %4d, h = %4d\n", |
600 fprintf(stderr, "XME: mode = %4d, w = %4d, h = %4d\n", | 738 i, modelist[i].width, modelist[i].height); |
601 i, modelist[i].width, modelist[i].height); | 739 #endif |
602 #endif | 740 |
603 | 741 SDL_modelist[i]->x = 0; |
604 SDL_modelist[i]->x = 0; | 742 SDL_modelist[i]->y = 0; |
605 SDL_modelist[i]->y = 0; | 743 SDL_modelist[i]->w = modelist[j].width; |
606 SDL_modelist[i]->w = modelist[j].width; | 744 SDL_modelist[i]->h = modelist[j].height; |
607 SDL_modelist[i]->h = modelist[j].height; | 745 |
608 | 746 } |
609 } | 747 SDL_modelist[i] = NULL; /* terminator */ |
610 SDL_modelist[i] = NULL; /* terminator */ | 748 |
611 } | 749 use_xme = xme_major * 100 + xme_minor; |
612 use_xme = 1; | |
613 saved_res = modelist[ractive]; /* save the current resolution */ | 750 saved_res = modelist[ractive]; /* save the current resolution */ |
614 } else { | |
615 use_xme = 0; | |
616 } | 751 } |
617 if ( modelist ) { | 752 if ( modelist ) { |
618 XFree(modelist); | 753 XFree(modelist); |
619 } | 754 } |
620 #endif /* SDL_VIDEO_DRIVER_X11_XME */ | 755 #endif /* SDL_VIDEO_DRIVER_X11_XME */ |
666 XFree(pf); | 801 XFree(pf); |
667 } | 802 } |
668 | 803 |
669 if ( SDL_modelist == NULL ) { | 804 if ( SDL_modelist == NULL ) { |
670 SDL_modelist = (SDL_Rect **)SDL_malloc((1+1)*sizeof(SDL_Rect *)); | 805 SDL_modelist = (SDL_Rect **)SDL_malloc((1+1)*sizeof(SDL_Rect *)); |
671 if ( SDL_modelist ) { | 806 if ( !SDL_modelist ) { |
672 n = 0; | 807 SDL_OutOfMemory(); |
673 SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect)); | 808 return -1; |
674 if ( SDL_modelist[n] ) { | 809 } |
675 SDL_modelist[n]->x = 0; | 810 n = 0; |
676 SDL_modelist[n]->y = 0; | 811 SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect)); |
677 SDL_modelist[n]->w = screen_w; | 812 if ( SDL_modelist[n] ) { |
678 SDL_modelist[n]->h = screen_h; | 813 SDL_modelist[n]->x = 0; |
679 ++n; | 814 SDL_modelist[n]->y = 0; |
680 } | 815 SDL_modelist[n]->w = screen_w; |
681 SDL_modelist[n] = NULL; | 816 SDL_modelist[n]->h = screen_h; |
682 } | 817 ++n; |
683 } | 818 } |
684 | 819 SDL_modelist[n] = NULL; |
685 #if defined(XFREE86_DEBUG) || defined(XIG_DEBUG) | 820 } |
821 | |
822 #ifdef X11MODES_DEBUG | |
823 if ( use_xinerama ) { | |
824 printf("Xinerama is enabled\n"); | |
825 } | |
826 | |
827 if ( use_xrandr ) { | |
828 printf("XRandR is enabled\n"); | |
829 } | |
830 | |
686 if ( use_vidmode ) { | 831 if ( use_vidmode ) { |
687 printf("XFree86 VidMode is enabled\n"); | 832 printf("VidMode is enabled\n"); |
688 } | 833 } |
689 | 834 |
690 #if SDL_VIDEO_DRIVER_X11_XME | 835 if ( use_xme ) { |
691 if ( use_xme ) | 836 printf("Xi Graphics XME fullscreen is enabled\n"); |
692 printf("Xi Graphics XME fullscreen is enabled\n"); | 837 } |
693 else | |
694 printf("Xi Graphics XME fullscreen is not available\n"); | |
695 #endif | |
696 | 838 |
697 if ( SDL_modelist ) { | 839 if ( SDL_modelist ) { |
698 printf("X11 video mode list:\n"); | 840 printf("X11 video mode list:\n"); |
699 for ( i=0; SDL_modelist[i]; ++i ) { | 841 for ( i=0; SDL_modelist[i]; ++i ) { |
700 printf("\t%dx%d\n", SDL_modelist[i]->w, SDL_modelist[i]->h); | 842 printf("\t%dx%d\n", SDL_modelist[i]->w, SDL_modelist[i]->h); |
701 } | 843 } |
702 } | 844 } |
703 #endif /* XFREE86_DEBUG || XIG_DEBUG */ | 845 #endif /* X11MODES_DEBUG */ |
704 | |
705 /* The default X/Y fullscreen offset is 0/0 */ | |
706 xinerama_x = 0; | |
707 xinerama_y = 0; | |
708 | |
709 #if SDL_VIDEO_DRIVER_X11_XINERAMA | |
710 /* Query Xinerama extention */ | |
711 if ( SDL_NAME(XineramaQueryExtension)(SDL_Display, &i, &i) && | |
712 SDL_NAME(XineramaIsActive)(SDL_Display) ) { | |
713 /* Find out which screen is the desired one */ | |
714 int desired = 0; | |
715 int screens; | |
716 SDL_NAME(XineramaScreenInfo) *xinerama; | |
717 | |
718 #ifdef XINERAMA_DEBUG | |
719 printf("X11 detected Xinerama:\n"); | |
720 #endif | |
721 #if 0 /* Apparently the vidmode extension doesn't work with Xinerama */ | |
722 const char *variable = SDL_getenv("SDL_VIDEO_X11_XINERAMA_SCREEN"); | |
723 if ( variable ) { | |
724 desired = atoi(variable); | |
725 } | |
726 #endif | |
727 xinerama = SDL_NAME(XineramaQueryScreens)(SDL_Display, &screens); | |
728 for ( i = 0; i < screens; i++ ) { | |
729 #ifdef XINERAMA_DEBUG | |
730 printf("xinerama %d: %dx%d+%d+%d\n", | |
731 xinerama[i].screen_number, | |
732 xinerama[i].width, xinerama[i].height, | |
733 xinerama[i].x_org, xinerama[i].y_org); | |
734 #endif | |
735 if ( xinerama[i].screen_number == desired ) { | |
736 xinerama_x = xinerama[i].x_org; | |
737 xinerama_y = xinerama[i].y_org; | |
738 } | |
739 } | |
740 XFree(xinerama); | |
741 } | |
742 #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */ | |
743 | 846 |
744 return 0; | 847 return 0; |
745 } | 848 } |
746 | 849 |
747 int X11_SupportedVisual(_THIS, SDL_PixelFormat *format) | 850 int X11_SupportedVisual(_THIS, SDL_PixelFormat *format) |
787 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ | 890 #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ |
788 } | 891 } |
789 | 892 |
790 int X11_ResizeFullScreen(_THIS) | 893 int X11_ResizeFullScreen(_THIS) |
791 { | 894 { |
792 int x, y; | 895 int x = 0, y = 0; |
793 int real_w, real_h; | 896 int real_w, real_h; |
794 int screen_w; | 897 int screen_w; |
795 int screen_h; | 898 int screen_h; |
796 | 899 |
797 screen_w = DisplayWidth(SDL_Display, SDL_Screen); | 900 screen_w = DisplayWidth(SDL_Display, SDL_Screen); |
798 screen_h = DisplayHeight(SDL_Display, SDL_Screen); | 901 screen_h = DisplayHeight(SDL_Display, SDL_Screen); |
799 | 902 |
800 x = xinerama_x; | 903 #if SDL_VIDEO_DRIVER_X11_VIDMODE |
801 y = xinerama_y; | 904 if ( use_xinerama && |
905 window_w <= xinerama_info.width && | |
906 window_h <= xinerama_info.height ) { | |
907 x = xinerama_info.x_org; | |
908 y = xinerama_info.y_org; | |
909 } | |
910 #endif | |
802 if ( currently_fullscreen ) { | 911 if ( currently_fullscreen ) { |
803 /* Switch resolution and cover it with the FSwindow */ | 912 /* Switch resolution and cover it with the FSwindow */ |
804 move_cursor_to(this, x, y); | 913 move_cursor_to(this, x, y); |
805 set_best_resolution(this, window_w, window_h); | 914 set_best_resolution(this, window_w, window_h); |
806 move_cursor_to(this, x, y); | 915 move_cursor_to(this, x, y); |
838 int okay; | 947 int okay; |
839 #if 0 | 948 #if 0 |
840 Window tmpwin, *windows; | 949 Window tmpwin, *windows; |
841 int i, nwindows; | 950 int i, nwindows; |
842 #endif | 951 #endif |
952 int x = 0, y = 0; | |
843 int real_w, real_h; | 953 int real_w, real_h; |
844 int screen_w; | 954 int screen_w; |
845 int screen_h; | 955 int screen_h; |
846 | 956 |
847 okay = 1; | 957 okay = 1; |
850 } | 960 } |
851 | 961 |
852 /* Ungrab the input so that we can move the mouse around */ | 962 /* Ungrab the input so that we can move the mouse around */ |
853 X11_GrabInputNoLock(this, SDL_GRAB_OFF); | 963 X11_GrabInputNoLock(this, SDL_GRAB_OFF); |
854 | 964 |
965 #if SDL_VIDEO_DRIVER_X11_VIDMODE | |
966 if ( use_xinerama && | |
967 window_w <= xinerama_info.width && | |
968 window_h <= xinerama_info.height ) { | |
969 x = xinerama_info.x_org; | |
970 y = xinerama_info.y_org; | |
971 } | |
972 #endif | |
855 /* Map the fullscreen window to blank the screen */ | 973 /* Map the fullscreen window to blank the screen */ |
856 screen_w = DisplayWidth(SDL_Display, SDL_Screen); | 974 screen_w = DisplayWidth(SDL_Display, SDL_Screen); |
857 screen_h = DisplayHeight(SDL_Display, SDL_Screen); | 975 screen_h = DisplayHeight(SDL_Display, SDL_Screen); |
858 get_real_resolution(this, &real_w, &real_h); | 976 get_real_resolution(this, &real_w, &real_h); |
859 if ( window_w > real_w ) { | 977 if ( window_w > real_w ) { |
861 } | 979 } |
862 if ( window_h > real_h ) { | 980 if ( window_h > real_h ) { |
863 real_h = MAX(real_h, screen_h); | 981 real_h = MAX(real_h, screen_h); |
864 } | 982 } |
865 XMoveResizeWindow(SDL_Display, FSwindow, | 983 XMoveResizeWindow(SDL_Display, FSwindow, |
866 xinerama_x, xinerama_y, real_w, real_h); | 984 x, y, real_w, real_h); |
867 XMapRaised(SDL_Display, FSwindow); | 985 XMapRaised(SDL_Display, FSwindow); |
868 X11_WaitMapped(this, FSwindow); | 986 X11_WaitMapped(this, FSwindow); |
869 | 987 |
870 #if 0 /* This seems to break WindowMaker in focus-follows-mouse mode */ | 988 #if 0 /* This seems to break WindowMaker in focus-follows-mouse mode */ |
871 /* Make sure we got to the top of the window stack */ | 989 /* Make sure we got to the top of the window stack */ |
906 } | 1024 } |
907 /* Set the colormap */ | 1025 /* Set the colormap */ |
908 if ( SDL_XColorMap ) { | 1026 if ( SDL_XColorMap ) { |
909 XInstallColormap(SDL_Display, SDL_XColorMap); | 1027 XInstallColormap(SDL_Display, SDL_XColorMap); |
910 } | 1028 } |
911 if ( okay ) | 1029 if ( okay ) { |
912 X11_GrabInputNoLock(this, this->input_grab | SDL_GRAB_FULLSCREEN); | 1030 X11_GrabInputNoLock(this, this->input_grab | SDL_GRAB_FULLSCREEN); |
1031 } | |
913 | 1032 |
914 /* We may need to refresh the screen at this point (no backing store) | 1033 /* We may need to refresh the screen at this point (no backing store) |
915 We also don't get an event, which is why we explicitly refresh. */ | 1034 We also don't get an event, which is why we explicitly refresh. */ |
916 if ( this->screen ) { | 1035 if ( this->screen ) { |
917 if ( this->screen->flags & SDL_INTERNALOPENGL ) { | 1036 if ( this->screen->flags & SDL_INTERNALOPENGL ) { |