New XFree 4.3 Video Mode Patch

The current patch to fix the issues with XFree 4.3 it is a bit of
overkill to a simple problem.

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 ]
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.

The solution is to scan forward for the first user set mode or highest X
mode. The current qsort still keeps user set modes above higher refresh
modes set by X.

For the best match (I don’t like the goto but was following prior code)
we still search for the nearest larger size and then try to find a
higher version of it.

I’ve included two patches;

Before the current CVS showing the error : sdl-x11-vidmode.diff
The second patches the reverts CVS code : sdl-x11-vidmode-cvs.diff

Enjoy. Just in time to play Majesty too!–
Alan.

“One must never be purposelessnessnesslessness.”
-------------- next part --------------

— SDL_x11modes.c.orig 2003-04-21 15:14:07.000000000 +0100
+++ SDL_x11modes.c 2003-04-21 16:44:57.000000000 +0100
@@ -100,27 +100,39 @@
SDL_NAME(XF86VidModeModeLine) mode;
SDL_NAME(XF86VidModeModeInfo) **modes;
int i;

  •    int best_width, best_height;
       int nmodes;
    
       if ( SDL_NAME(XF86VidModeGetModeLine)(SDL_Display, SDL_Screen, &i, &mode) &&
            SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display,SDL_Screen,&nmodes,&modes)){
           qsort(modes, nmodes, sizeof *modes, cmpmodes);
    

#ifdef XFREE86_DEBUG

  •        printf("Available modes:\n");
    
  •        printf("Available modes (sdl):\n");
           for ( i = 0; i < nmodes; ++i ) {
    
  •            printf("Mode %d: %dx%d\n", i,
    
  •                    modes[i]->hdisplay, modes[i]->vdisplay);
    
  •            printf("Mode %d: %d x %d @ %d\n", i,
    
  •                    modes[i]->hdisplay, modes[i]->vdisplay,
    
  •                    1000 * modes[i]->dotclock / (modes[i]->htotal *
    
  •                    modes[i]->vtotal) );
           }
    

#endif

  •        for ( i = nmodes-1; i > 0 ; --i ) {
    
  •        for ( i = 0; i < nmodes ; i++ ) {
               if ( (modes[i]->hdisplay == width) &&
                    (modes[i]->vdisplay == height) )
                   goto match;
           }
    
  •        for ( i = nmodes-1; i > 0 ; --i ) {
    
  •        for ( i = nmodes-1; i >= 0 ; i-- ) {
               if ( (modes[i]->hdisplay >= width) &&
    
  •                 (modes[i]->vdisplay >= height) )
    
  •                break;
    
  •                 (modes[i]->vdisplay >= height) ) {
    
  •                best_width = modes[i]->hdisplay;
    
  •                best_height = modes[i]->vdisplay;
    
  •                for ( ; i >= 0 ; i-- ) {
    
  •                    if ( (modes[i]->hdisplay != best_width) ||
    
  •                         (modes[i]->vdisplay != best_height) ) {
    
  •                        i++;
    
  •                        goto match;
    
  •                    }
    
  •                }
    
  •            }
           }
      match:
           if ( (modes[i]->hdisplay != mode.hdisplay) ||
    

@@ -338,6 +350,16 @@
if ( ! buggy_X11 &&
SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display, SDL_Screen,&nmodes,&modes) ) {

+#ifdef XFREE86_DEBUG

  •    printf("Available modes (x11):\n");
    
  •    for ( i = 0; i < nmodes; ++i ) {
    
  •        printf("Mode %d: %d x %d @ %d\n", i,
    
  •                modes[i]->hdisplay, modes[i]->vdisplay,
    
  •                1000 * modes[i]->dotclock / (modes[i]->htotal *
    
  •                modes[i]->vtotal) );
    
  •    }
    

+#endif
+
qsort(modes, nmodes, sizeof *modes, cmpmodes);
SDL_modelist = (SDL_Rect **)malloc((nmodes+2)*sizeof(SDL_Rect *));
if ( SDL_modelist ) {
-------------- next part --------------

— SDL_x11modes.c.cvs 2003-04-20 14:46:24.000000000 +0100
+++ SDL_x11modes.c 2003-04-21 16:44:57.000000000 +0100
@@ -22,7 +22,7 @@

#ifdef SAVE_RCSID
static char rcsid =

  • “@(#) $Id: SDL_x11modes.c,v 1.17 2003/04/20 05:36:52 slouken Exp $”;
  • “@(#) $Id: SDL_x11modes.c,v 1.16 2003/03/06 06:22:33 slouken Exp $”;
    #endif

/* Utilities for getting and setting the X display mode */
@@ -44,8 +44,6 @@
#endif

#define MAX(a, b) (a > b ? a : b)
-#define V_INTERLACE 0x010
-#define V_DBLSCAN 0x020

#ifdef XFREE86_VM
Bool SDL_NAME(XF86VidModeGetModeInfo)(Display *dpy, int scr, SDL_NAME(XF86VidModeModeInfo) *info)
@@ -93,82 +91,6 @@
}
#endif

-#ifdef XFREE86_VM
-static int get_vidmode_filter(SDL_NAME(XF86VidModeModeInfo) **modes, int nmodes, char **bitmap)
-{

  • int i, result = 0;
  • int use_all_modes, use_specific_mode;
  • const char *variable;
  • char *temp;
  • if (!nmodes)
  •    return 0;
    
  • temp = (char *)malloc((nmodes)*sizeof(char));
  • if (!temp)
  •    return 0;
    
  • for ( i = 0; i < nmodes; ++i )
  •    temp[i] = 0;
    
  • variable = getenv(“SDL_VIDEO_X11_USE_ALL_MODES”);
  • use_all_modes = variable ? atoi(variable) : 0;
  • variable = getenv(“SDL_VIDEO_X11_USE_SPECIFIC_MODE”);
  • use_specific_mode = variable ? atoi(variable) : 0;
  • qsort(modes, nmodes, sizeof *modes, cmpmodes);
  • if ( use_all_modes ) {
  •    for ( i = 0; i < nmodes; ++i )
    
  •        temp[i] = 1;
    
  •    result  = 1;
    

-/* } else if ( use_specific_mode ) { … */

  • } else {
  •    int previous_refresh, current_refresh;
    
  •    SDL_NAME(XF86VidModeModeInfo) *previous, *current;
    
  •    previous = modes[0];
    
  •    previous_refresh = (int)(previous->dotclock * 1000.0 /
    
  •      (previous->htotal * previous->vtotal));
    
  •    if ( previous->flags & V_INTERLACE ) previous_refresh *= 2;
    
  •    else if ( previous->flags & V_DBLSCAN ) previous_refresh /= 2;
    
  •    temp[0] = 1;
    
  •    for ( i = 1; i < nmodes; ++i ) {
    
  •        current = modes[i];
    
  •        current_refresh = (int)(current->dotclock * 1000.0 /
    
  •          (current->htotal * current->vtotal));
    
  •        if ( current->flags & V_INTERLACE ) current_refresh *= 2;
    
  •        else if ( current->flags & V_DBLSCAN ) current_refresh /= 2;
    
  •        /* Compare this mode to the previous one */
    
  •        if ( current->hdisplay == previous->hdisplay &&
    
  •             current->vdisplay == previous->vdisplay ) {
    

-#ifdef XFREE86_DEBUG

  •   printf("Comparing %dx%d at %d Hz and %d Hz\n",
    
  •   	current->hdisplay, current->vdisplay,
    
  •   	current_refresh, previous_refresh);
    

-#endif

  •            if ( current_refresh > previous_refresh ) {
    
  •                temp[i-1] = 0;
    
  •                temp[i]   = 1;
    
  •            }
    
  •            else
    
  •                temp[i] = 0;
    
  •        }
    
  •        else
    
  •            temp[i] = 1;
    
  •        previous = current;
    
  •        previous_refresh = current_refresh;
    
  •    }
    
  •    result = 1;
    
  • }
  • *bitmap = temp;
  • return result;
    -}
    -#endif

static void get_real_resolution(_THIS, int* w, int* h);

static void set_best_resolution(_THIS, int width, int height)
@@ -178,30 +100,39 @@
SDL_NAME(XF86VidModeModeLine) mode;
SDL_NAME(XF86VidModeModeInfo) **modes;
int i;

  •    int best_width, best_height;
       int nmodes;
    
  •    char *bitmap;
    
       if ( SDL_NAME(XF86VidModeGetModeLine)(SDL_Display, SDL_Screen, &i, &mode) &&
    
  •         SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display,SDL_Screen,&nmodes,&modes) &&
    
  •         get_vidmode_filter(modes, nmodes, &bitmap) ) {
    
  •         SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display,SDL_Screen,&nmodes,&modes)){
    
  •        qsort(modes, nmodes, sizeof *modes, cmpmodes);
    

#ifdef XFREE86_DEBUG

  •        printf("Available modes:\n");
    
  •        printf("Available modes (sdl):\n");
           for ( i = 0; i < nmodes; ++i ) {
    
  •            printf("Mode %d: %dx%d\n", i,
    
  •                    modes[i]->hdisplay, modes[i]->vdisplay);
    
  •            printf("Mode %d: %d x %d @ %d\n", i,
    
  •                    modes[i]->hdisplay, modes[i]->vdisplay,
    
  •                    1000 * modes[i]->dotclock / (modes[i]->htotal *
    
  •                    modes[i]->vtotal) );
           }
    

#endif

  •        for ( i = nmodes-1; i > 0 ; --i ) {
    
  •        for ( i = 0; i < nmodes ; i++ ) {
               if ( (modes[i]->hdisplay == width) &&
    
  •                 (modes[i]->vdisplay == height) &&
    
  •                 (bitmap[i] == 1) )
    
  •                 (modes[i]->vdisplay == height) )
                   goto match;
           }
    
  •        for ( i = nmodes-1; i > 0 ; --i ) {
    
  •        for ( i = nmodes-1; i >= 0 ; i-- ) {
               if ( (modes[i]->hdisplay >= width) &&
    
  •                 (modes[i]->vdisplay >= height) &&
    
  •                 (bitmap[i] == 1) )
    
  •                break;
    
  •                 (modes[i]->vdisplay >= height) ) {
    
  •                best_width = modes[i]->hdisplay;
    
  •                best_height = modes[i]->vdisplay;
    
  •                for ( ; i >= 0 ; i-- ) {
    
  •                    if ( (modes[i]->hdisplay != best_width) ||
    
  •                         (modes[i]->vdisplay != best_height) ) {
    
  •                        i++;
    
  •                        goto match;
    
  •                    }
    
  •                }
    
  •            }
           }
      match:
           if ( (modes[i]->hdisplay != mode.hdisplay) ||
    

@@ -209,7 +140,6 @@
SDL_NAME(XF86VidModeSwitchToMode)(SDL_Display, SDL_Screen, modes[i]);
}
XFree(modes);

  •        if (bitmap) free(bitmap);
       }
    
    }
    #endif /* XFREE86_VM */
    @@ -357,7 +287,6 @@
    int vm_major, vm_minor;
    int nmodes;
    SDL_NAME(XF86VidModeModeInfo) **modes;
  • char bitmap = (char)0;
    #endif
    #ifdef HAVE_XIGXME
    int xme_major, xme_minor;
    @@ -419,18 +348,25 @@
    }
    }
    if ( ! buggy_X11 &&
  •     SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display, SDL_Screen,&nmodes,&modes) &&
    
  •     get_vidmode_filter(modes, nmodes, &bitmap) ) {
    
  •     SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display, SDL_Screen,&nmodes,&modes) ) {
    

+#ifdef XFREE86_DEBUG

  •    printf("Available modes (x11):\n");
    
  •    for ( i = 0; i < nmodes; ++i ) {
    
  •        printf("Mode %d: %d x %d @ %d\n", i,
    
  •                modes[i]->hdisplay, modes[i]->vdisplay,
    
  •                1000 * modes[i]->dotclock / (modes[i]->htotal *
    
  •                modes[i]->vtotal) );
    
  •    }
    

+#endif
+

  •    qsort(modes, nmodes, sizeof *modes, cmpmodes);
       SDL_modelist = (SDL_Rect **)malloc((nmodes+2)*sizeof(SDL_Rect *));
       if ( SDL_modelist ) {
           n = 0;
           for ( i=0; i<nmodes; ++i ) {
               int w, h;
    
  •            /* Exclude those vidmodes that have been filtered out */
    
  •            if (!bitmap[i]) continue;
    
  •            /* Check to see if we should add the screen size (Xinerama) */
               w = modes[i]->hdisplay;
               h = modes[i]->vdisplay;
    

@@ -463,7 +399,6 @@
SDL_modelist[n] = NULL;
}
XFree(modes);

  •    if (bitmap) free(bitmap);
    
       use_vidmode = vm_major * 100 + vm_minor;
       save_mode(this);
    

-------------- next part --------------
A non-text attachment was scrubbed…
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20030421/a65ff764/attachment.pgp