[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--