[SDL] New XFree 4.3 Video Mode Patch

Alan Swanson sdl@libsdl.org
Mon Apr 21 09:38:03 2003


--=-mHDtWHkwYD3+hYVhggAO
Content-Type: multipart/mixed; boundary="=-ewa+t295iRw1pka1lwiZ"



--=-ewa+t295iRw1pka1lwiZ
Content-Type: text/plain
Content-Transfer-Encoding: quoted-printable


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

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!

--=20
Alan.

"One must never be purposelessnessnesslessness."

--=-ewa+t295iRw1pka1lwiZ
Content-Disposition: attachment; filename=sdl-x11-vidmode.diff
Content-Type: text/plain; name=sdl-x11-vidmode.diff; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable


--- 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;
=20
         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 =3D 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 =3D nmodes-1; i > 0 ; --i ) {
+            for ( i =3D 0; i < nmodes ; i++ ) {
                 if ( (modes[i]->hdisplay =3D=3D width) &&
                      (modes[i]->vdisplay =3D=3D height) )
                     goto match;
             }
-            for ( i =3D nmodes-1; i > 0 ; --i ) {
+            for ( i =3D nmodes-1; i >=3D 0 ; i-- ) {
                 if ( (modes[i]->hdisplay >=3D width) &&
-                     (modes[i]->vdisplay >=3D height) )
-                    break;
+                     (modes[i]->vdisplay >=3D height) ) {
+                    best_width =3D modes[i]->hdisplay;
+                    best_height =3D modes[i]->vdisplay;
+                    for ( ; i >=3D 0 ; i-- ) {
+                        if ( (modes[i]->hdisplay !=3D best_width) ||
+                             (modes[i]->vdisplay !=3D best_height) ) {
+                            i++;
+                            goto match;
+                        }
+                    }
+                }
             }
        match:
             if ( (modes[i]->hdisplay !=3D mode.hdisplay) ||
@@ -338,6 +350,16 @@
     if ( ! buggy_X11 &&
          SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display, SDL_Screen,&nmo=
des,&modes) ) {
=20
+#ifdef XFREE86_DEBUG
+        printf("Available modes (x11):\n");
+        for ( i =3D 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 =3D (SDL_Rect **)malloc((nmodes+2)*sizeof(SDL_Rect *)=
);
         if ( SDL_modelist ) {

--=-ewa+t295iRw1pka1lwiZ
Content-Disposition: attachment; filename=sdl-x11-vidmode-cvs.diff
Content-Type: text/plain; name=sdl-x11-vidmode-cvs.diff; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable


--- 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 @@
=20
 #ifdef SAVE_RCSID
 static char rcsid =3D
- "@(#) $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
=20
 /* Utilities for getting and setting the X display mode */
@@ -44,8 +44,6 @@
 #endif=20
=20
 #define MAX(a, b)        (a > b ? a : b)
-#define V_INTERLACE      0x010
-#define V_DBLSCAN        0x020
=20
 #ifdef XFREE86_VM
 Bool SDL_NAME(XF86VidModeGetModeInfo)(Display *dpy, int scr, SDL_NAME(XF86=
VidModeModeInfo) *info)
@@ -93,82 +91,6 @@
 }
 #endif
=20
-#ifdef XFREE86_VM
-static int get_vidmode_filter(SDL_NAME(XF86VidModeModeInfo) **modes, int n=
modes, char **bitmap)
-{
-    int i, result =3D 0;
-    int use_all_modes, use_specific_mode;
-    const char *variable;
-    char *temp;
-
-    if (!nmodes)
-        return 0;
-
-    temp =3D (char *)malloc((nmodes)*sizeof(char));
-    if (!temp)
-        return 0;
-
-    for ( i =3D 0; i < nmodes; ++i )
-        temp[i] =3D 0;
-
-    variable =3D getenv("SDL_VIDEO_X11_USE_ALL_MODES");
-    use_all_modes =3D variable ? atoi(variable) : 0;
-    variable =3D getenv("SDL_VIDEO_X11_USE_SPECIFIC_MODE");
-    use_specific_mode =3D variable ? atoi(variable) : 0;
-
-    qsort(modes, nmodes, sizeof *modes, cmpmodes);
-
-    if ( use_all_modes ) {
-        for ( i =3D 0; i < nmodes; ++i )
-            temp[i] =3D 1;
-        result  =3D 1;
-/*    } else if ( use_specific_mode ) { ... */
-    } else {
-        int previous_refresh, current_refresh;
-        SDL_NAME(XF86VidModeModeInfo) *previous, *current;
-
-        previous =3D modes[0];
-        previous_refresh =3D (int)(previous->dotclock * 1000.0 /
-          (previous->htotal * previous->vtotal));
-        if ( previous->flags & V_INTERLACE ) previous_refresh *=3D 2;
-        else if ( previous->flags & V_DBLSCAN ) previous_refresh /=3D 2;
-
-        temp[0] =3D 1;
-        for ( i =3D 1; i < nmodes; ++i ) {
-            current =3D modes[i];
-            current_refresh =3D (int)(current->dotclock * 1000.0 /
-              (current->htotal * current->vtotal));
-            if ( current->flags & V_INTERLACE ) current_refresh *=3D 2;
-            else if ( current->flags & V_DBLSCAN ) current_refresh /=3D 2;
-
-            /* Compare this mode to the previous one */
-            if ( current->hdisplay =3D=3D previous->hdisplay &&
-                 current->vdisplay =3D=3D 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] =3D 0;
-                    temp[i]   =3D 1;
-                }
-                else
-                    temp[i] =3D 0;
-            }
-            else
-                temp[i] =3D 1;
-
-            previous =3D current;
-            previous_refresh =3D current_refresh;
-        }
-        result =3D 1;
-    }
-    *bitmap =3D temp;
-    return result;
-}
-#endif
-
 static void get_real_resolution(_THIS, int* w, int* h);
=20
 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;
=20
         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 =3D 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 =3D nmodes-1; i > 0 ; --i ) {
+            for ( i =3D 0; i < nmodes ; i++ ) {
                 if ( (modes[i]->hdisplay =3D=3D width) &&
-                     (modes[i]->vdisplay =3D=3D height) &&
-                     (bitmap[i] =3D=3D 1) )
+                     (modes[i]->vdisplay =3D=3D height) )
                     goto match;
             }
-            for ( i =3D nmodes-1; i > 0 ; --i ) {
+            for ( i =3D nmodes-1; i >=3D 0 ; i-- ) {
                 if ( (modes[i]->hdisplay >=3D width) &&
-                     (modes[i]->vdisplay >=3D height) &&
-                     (bitmap[i] =3D=3D 1) )
-                    break;
+                     (modes[i]->vdisplay >=3D height) ) {
+                    best_width =3D modes[i]->hdisplay;
+                    best_height =3D modes[i]->vdisplay;
+                    for ( ; i >=3D 0 ; i-- ) {
+                        if ( (modes[i]->hdisplay !=3D best_width) ||
+                             (modes[i]->vdisplay !=3D best_height) ) {
+                            i++;
+                            goto match;
+                        }
+                    }
+                }
             }
        match:
             if ( (modes[i]->hdisplay !=3D 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 =3D (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,&nmo=
des,&modes) &&
-         get_vidmode_filter(modes, nmodes, &bitmap) ) {
+         SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display, SDL_Screen,&nmo=
des,&modes) ) {
=20
+#ifdef XFREE86_DEBUG
+        printf("Available modes (x11):\n");
+        for ( i =3D 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 =3D (SDL_Rect **)malloc((nmodes+2)*sizeof(SDL_Rect *)=
);
         if ( SDL_modelist ) {
             n =3D 0;
             for ( i=3D0; i<nmodes; ++i ) {
                 int w, h;
=20
-                /* Exclude those vidmodes that have been filtered out */
-                if (!bitmap[i]) continue;
-
                 /* Check to see if we should add the screen size (Xinerama=
) */
                 w =3D modes[i]->hdisplay;
                 h =3D modes[i]->vdisplay;
@@ -463,7 +399,6 @@
             SDL_modelist[n] =3D NULL;
         }
         XFree(modes);
-        if (bitmap) free(bitmap);
=20
         use_vidmode =3D vm_major * 100 + vm_minor;
         save_mode(this);

--=-ewa+t295iRw1pka1lwiZ--

--=-mHDtWHkwYD3+hYVhggAO
Content-Type: application/pgp-signature; name=signature.asc
Content-Description: This is a digitally signed message part

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2-rc1-SuSE (GNU/Linux)

iD8DBQA+pBpDczTz0N3pwGoRAkYFAKCU1Jdix97N0jvnAu6TPXXMnaxdrQCghUfT
DB0ooGvr5tcT8Lfa6i981yE=
=hRkI
-----END PGP SIGNATURE-----

--=-mHDtWHkwYD3+hYVhggAO--