comparison src/video/x11/SDL_x11modes.c @ 230:275a934573a7

Greatly improved Xinerama video mode support
author Sam Lantinga <slouken@libsdl.org>
date Sun, 04 Nov 2001 04:18:43 +0000
parents 24878c14b391
children 4bcb29d3769c
comparison
equal deleted inserted replaced
229:4d24d5a660a8 230:275a934573a7
40 #include "SDL_x11image_c.h" 40 #include "SDL_x11image_c.h"
41 41
42 #ifdef HAVE_XINERAMA 42 #ifdef HAVE_XINERAMA
43 #include <X11/extensions/Xinerama.h> 43 #include <X11/extensions/Xinerama.h>
44 #endif 44 #endif
45
46 #define MAX(a, b) (a > b ? a : b)
45 47
46 #ifdef XFREE86_VM 48 #ifdef XFREE86_VM
47 Bool XVidMode(GetModeInfo, (Display *dpy, int scr, XF86VidModeModeInfo *info)) 49 Bool XVidMode(GetModeInfo, (Display *dpy, int scr, XF86VidModeModeInfo *info))
48 { 50 {
49 XF86VidModeModeLine *l = (XF86VidModeModeLine*)((char*)info + sizeof info->dotclock); 51 XF86VidModeModeLine *l = (XF86VidModeModeLine*)((char*)info + sizeof info->dotclock);
204 int buggy_X11; 206 int buggy_X11;
205 int vm_major, vm_minor; 207 int vm_major, vm_minor;
206 int nmodes; 208 int nmodes;
207 XF86VidModeModeInfo **modes; 209 XF86VidModeModeInfo **modes;
208 #endif 210 #endif
209 int i; 211 int i, n;
212 int screen_w;
213 int screen_h;
210 214
211 vm_error = -1; 215 vm_error = -1;
212 use_vidmode = 0; 216 use_vidmode = 0;
217 screen_w = DisplayWidth(SDL_Display, SDL_Screen);
218 screen_h = DisplayHeight(SDL_Display, SDL_Screen);
219
213 #ifdef XFREE86_VM 220 #ifdef XFREE86_VM
214 /* Metro-X 4.3.0 and earlier has a broken implementation of 221 /* Metro-X 4.3.0 and earlier has a broken implementation of
215 XF86VidModeGetAllModeLines() - it hangs the client. 222 XF86VidModeGetAllModeLines() - it hangs the client.
216 */ 223 */
217 buggy_X11 = 0; 224 buggy_X11 = 0;
257 } 264 }
258 if ( ! buggy_X11 && 265 if ( ! buggy_X11 &&
259 XVidMode(GetAllModeLines, (SDL_Display, SDL_Screen,&nmodes,&modes)) ) { 266 XVidMode(GetAllModeLines, (SDL_Display, SDL_Screen,&nmodes,&modes)) ) {
260 267
261 qsort(modes, nmodes, sizeof *modes, cmpmodes); 268 qsort(modes, nmodes, sizeof *modes, cmpmodes);
262 SDL_modelist = (SDL_Rect **)malloc((nmodes+1)*sizeof(SDL_Rect *)); 269 SDL_modelist = (SDL_Rect **)malloc((nmodes+2)*sizeof(SDL_Rect *));
263 if ( SDL_modelist ) { 270 if ( SDL_modelist ) {
271 n = 0;
264 for ( i=0; i<nmodes; ++i ) { 272 for ( i=0; i<nmodes; ++i ) {
265 SDL_modelist[i] = (SDL_Rect *)malloc(sizeof(SDL_Rect)); 273 int w, h;
266 if ( SDL_modelist[i] == NULL ) { 274
275 /* Check to see if we should add the screen size (Xinerama) */
276 w = modes[i]->hdisplay;
277 h = modes[i]->vdisplay;
278 if ( (screen_w * screen_h) >= (w * h) ) {
279 if ( (screen_w != w) || (screen_h != h) ) {
280 SDL_modelist[n] = (SDL_Rect *)malloc(sizeof(SDL_Rect));
281 if ( SDL_modelist[n] ) {
282 SDL_modelist[n]->x = 0;
283 SDL_modelist[n]->y = 0;
284 SDL_modelist[n]->w = screen_w;
285 SDL_modelist[n]->h = screen_h;
286 ++n;
287 }
288 }
289 screen_w = 0;
290 screen_h = 0;
291 }
292
293 /* Add the size from the video mode list */
294 SDL_modelist[n] = (SDL_Rect *)malloc(sizeof(SDL_Rect));
295 if ( SDL_modelist[n] == NULL ) {
267 break; 296 break;
268 } 297 }
269 SDL_modelist[i]->x = 0; 298 SDL_modelist[n]->x = 0;
270 SDL_modelist[i]->y = 0; 299 SDL_modelist[n]->y = 0;
271 SDL_modelist[i]->w = modes[i]->hdisplay; 300 SDL_modelist[n]->w = w;
272 SDL_modelist[i]->h = modes[i]->vdisplay; 301 SDL_modelist[n]->h = h;
273 } 302 ++n;
274 SDL_modelist[i] = NULL; 303 }
304 SDL_modelist[n] = NULL;
275 } 305 }
276 XFree(modes); 306 XFree(modes);
277 307
278 use_vidmode = vm_major * 100 + vm_minor; 308 use_vidmode = vm_major * 100 + vm_minor;
279 save_mode(this); 309 save_mode(this);
323 XFree(pf); 353 XFree(pf);
324 } 354 }
325 355
326 if ( SDL_modelist == NULL ) { 356 if ( SDL_modelist == NULL ) {
327 SDL_modelist = (SDL_Rect **)malloc((1+1)*sizeof(SDL_Rect *)); 357 SDL_modelist = (SDL_Rect **)malloc((1+1)*sizeof(SDL_Rect *));
328 i = 0;
329 if ( SDL_modelist ) { 358 if ( SDL_modelist ) {
330 SDL_modelist[i] = (SDL_Rect *)malloc(sizeof(SDL_Rect)); 359 n = 0;
331 if ( SDL_modelist[i] ) { 360 SDL_modelist[n] = (SDL_Rect *)malloc(sizeof(SDL_Rect));
332 SDL_modelist[i]->x = 0; 361 if ( SDL_modelist[n] ) {
333 SDL_modelist[i]->y = 0; 362 SDL_modelist[n]->x = 0;
334 SDL_modelist[i]->w = DisplayWidth(SDL_Display, SDL_Screen); 363 SDL_modelist[n]->y = 0;
335 SDL_modelist[i]->h = DisplayHeight(SDL_Display, SDL_Screen); 364 SDL_modelist[n]->w = screen_w;
336 ++i; 365 SDL_modelist[n]->h = screen_h;
337 } 366 ++n;
338 SDL_modelist[i] = NULL; 367 }
368 SDL_modelist[n] = NULL;
339 } 369 }
340 } 370 }
341 371
342 #ifdef XFREE86_DEBUG 372 #ifdef XFREE86_DEBUG
343 if ( use_vidmode ) { 373 if ( use_vidmode ) {
423 453
424 int X11_ResizeFullScreen(_THIS) 454 int X11_ResizeFullScreen(_THIS)
425 { 455 {
426 int x, y; 456 int x, y;
427 int real_w, real_h; 457 int real_w, real_h;
458 int screen_w;
459 int screen_h;
460
461 screen_w = DisplayWidth(SDL_Display, SDL_Screen);
462 screen_h = DisplayHeight(SDL_Display, SDL_Screen);
428 463
429 x = xinerama_x; 464 x = xinerama_x;
430 y = xinerama_y; 465 y = xinerama_y;
431 if ( currently_fullscreen ) { 466 if ( currently_fullscreen ) {
432 /* Switch resolution and cover it with the FSwindow */ 467 /* Switch resolution and cover it with the FSwindow */
433 move_cursor_to(this, x, y); 468 move_cursor_to(this, x, y);
434 set_best_resolution(this, current_w, current_h); 469 set_best_resolution(this, current_w, current_h);
435 move_cursor_to(this, x, y); 470 move_cursor_to(this, x, y);
436 get_real_resolution(this, &real_w, &real_h); 471 get_real_resolution(this, &real_w, &real_h);
472 if ( current_w > real_w ) {
473 real_w = MAX(real_w, screen_w);
474 }
475 if ( current_h > real_h ) {
476 real_h = MAX(real_h, screen_h);
477 }
437 XMoveResizeWindow(SDL_Display, FSwindow, x, y, real_w, real_h); 478 XMoveResizeWindow(SDL_Display, FSwindow, x, y, real_w, real_h);
438 move_cursor_to(this, real_w/2, real_h/2); 479 move_cursor_to(this, real_w/2, real_h/2);
439 480
440 /* Center and reparent the drawing window */ 481 /* Center and reparent the drawing window */
441 x = (real_w - current_w)/2; 482 x = (real_w - current_w)/2;
462 #if 0 503 #if 0
463 Window tmpwin, *windows; 504 Window tmpwin, *windows;
464 int i, nwindows; 505 int i, nwindows;
465 #endif 506 #endif
466 int real_w, real_h; 507 int real_w, real_h;
508 int screen_w;
509 int screen_h;
467 510
468 okay = 1; 511 okay = 1;
469 if ( currently_fullscreen ) { 512 if ( currently_fullscreen ) {
470 return(okay); 513 return(okay);
471 } 514 }
472 515
473 /* Ungrab the input so that we can move the mouse around */ 516 /* Ungrab the input so that we can move the mouse around */
474 X11_GrabInputNoLock(this, SDL_GRAB_OFF); 517 X11_GrabInputNoLock(this, SDL_GRAB_OFF);
475 518
476 /* Map the fullscreen window to blank the screen */ 519 /* Map the fullscreen window to blank the screen */
520 screen_w = DisplayWidth(SDL_Display, SDL_Screen);
521 screen_h = DisplayHeight(SDL_Display, SDL_Screen);
477 get_real_resolution(this, &real_w, &real_h); 522 get_real_resolution(this, &real_w, &real_h);
523 if ( current_w > real_w ) {
524 real_w = MAX(real_w, screen_w);
525 }
526 if ( current_h > real_h ) {
527 real_h = MAX(real_h, screen_h);
528 }
478 XMoveResizeWindow(SDL_Display, FSwindow, 0, 0, real_w, real_h); 529 XMoveResizeWindow(SDL_Display, FSwindow, 0, 0, real_w, real_h);
479 XMapRaised(SDL_Display, FSwindow); 530 XMapRaised(SDL_Display, FSwindow);
480 X11_WaitMapped(this, FSwindow); 531 X11_WaitMapped(this, FSwindow);
481 532
482 #if 0 /* This seems to break WindowMaker in focus-follows-mouse mode */ 533 #if 0 /* This seems to break WindowMaker in focus-follows-mouse mode */