misc/152232: syscons VGA screensavers don't work on some computers. Here's a patch.

crocket crockabiscuit at yahoo.com
Sun Nov 14 11:50:09 UTC 2010


>Number:         152232
>Category:       misc
>Synopsis:       syscons VGA screensavers don't work on some computers. Here's a patch.
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Nov 14 11:50:08 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     crocket
>Release:        8.1-RELEASE
>Organization:
>Environment:
FreeBSD elisa.local 8.1-RELEASE-p1 FreeBSD 8.1-RELEASE-p1 #12: Sun Nov 14 18:09:27 KST 2010     root at elisa.local:/usr/obj/usr/src/sys/ELISA  amd64
>Description:
All VGA screensaver except logo_saver.ko couldn't be executed on my desktop due to 
module_register_init: MOD_LOAD (XXXX_saver, 0xXXXXXXXX, 0) error 19.

After inspection, I found out that each VGA screensaver probed its own predefined set of video modes only and if the probe failed, they would generate that error.

A quick solution to this problem is to generate a header file that manages the video mode of all VGA screensavers.
If I managed the video mode in one place, it would be easier to change the video mode and build screensaver modules at once.
So I made a patch.
The patch is attached to this problem report.
You should apply the patch in /usr/src/sys.
For example, Execute "diff -p1 < xxx.diff" on /usr/src/sys.

This patch can be applied to 8.1-RELEASE safely.

>How-To-Repeat:
Load any of VGA screensavers(rain, fire, dragon, etc...) using kldload.
Execute the screensaver by pressing Shift+PauseBreak.
If it didn't execute, then read /var/log/messages, and you'll see the relevant errors.
>Fix:
Currently, screensavers don't detect video modes automatically.
I'd appreciate it if somebody makes a patch that makes screensavers detect video modes automatically using vidcontrol or something else.
It would be nice if we could change the video mode of screensavers with vidcontrol.

To fix this issue, first apply the attached patch in /usr/src/sys.
Change VIDEO_MODE #define macro in /usr/src/sys/dev/syscons/videomode.h to
one of 8bit video modes shown from "vidcontrol -i mode".
Screensavers, for now, assume 8bit video mode.
After changing VIDEO_MODE to any 8bit video mode, execute "make; make install clean" in /usr/src/sys/modules/syscons.
All syscons screensavers will be installed into /boot/kernel.
You don't have to worry about the currently loaded screensaver since loaded screensaver modules are already in RAM.
Overwriting those screensavers on disk would not affect screensavers loaded onto RAM.
Execute "kldunload (loaded screensaver module); kldload XXX_saver(XXX is the name of a screensaver)" as root.
To test the screensaver, press Shift + PauseBreak. You'll see the new screensaver working.

Patch attached with submission follows:

diff -Naur dev.orig/syscons/dragon/dragon_saver.c dev/syscons/dragon/dragon_saver.c
--- dev.orig/syscons/dragon/dragon_saver.c	2010-06-14 11:09:06.000000000 +0900
+++ dev/syscons/dragon/dragon_saver.c	2010-11-14 19:45:09.000000000 +0900
@@ -41,23 +41,23 @@
 #include	<dev/fb/fbreg.h>
 #include	<dev/fb/splashreg.h>
 #include	<dev/syscons/syscons.h>
+#include	<dev/syscons/videomode.h>
 
 #define SAVER_NAME	 "dragon_saver"
 
 static u_char	*vid;
-static int	blanked;
+static int	blanked, scrw=0, scrh=0;
+
+#ifndef VIDEO_MODE
 
 #ifdef PC98
 #define	VIDEO_MODE	M_PC98_EGC640x400
-#define	VIDEO_MODE_NAME	"M_PC98_EGC640x400"
-#define	SCRW	640
-#define	SCRH	400
 #else
-#define	VIDEO_MODE	M_VGA_CG320
-#define	VIDEO_MODE_NAME	"M_VGA_CG320"
-#define	SCRW	320
-#define	SCRH	200
+#define	VIDEO_MODE	M_VESA_CG640x480
 #endif
+
+#endif // #ifndef VIDEO_MODE
+
 #define	ORDER	13
 #define	CURVE	3
 #define	OUT	100
@@ -69,13 +69,13 @@
 static __inline int
 gpset(int x, int y, int val)
 {
-	if (x < 0 || y < 0 || SCRW <= x || SCRH <= y) {
+	if (x < 0 || y < 0 || scrw <= x || scrh <= y) {
 		return 0;
 	}
 #ifdef PC98
-	vid[(x + y * SCRW) >> 3] = (0x80 >> (x & 7));	/* write new dot */
+	vid[(x + y * scrw) >> 3] = (0x80 >> (x & 7));	/* write new dot */
 #else
-	vid[x + y * SCRW] = val;
+	vid[x + y * scrw] = val;
 #endif
 	return 1;
 }
@@ -143,8 +143,8 @@
 		}
 		vidd_load_palette(adp, dragon_pal);
 
-		mul = ((random() & 7) + 1) * (SCRW / 320);
-		org_x = random() % SCRW; org_y = random() % SCRH;
+		mul = ((random() & 7) + 1) * (scrw / 320);
+		org_x = random() % scrw; org_y = random() % scrh;
 
 		curve = 0;
 		order = ORDER;
@@ -231,10 +231,15 @@
 	/* check that the console is capable of running in 320x200x256 */
 	if (vidd_get_info(adp, VIDEO_MODE, &info)) {
 		log(LOG_NOTICE,
-		    "%s: the console does not support " VIDEO_MODE_NAME "\n",
+		    "%s: the console does not support any of video modes it probes\n",
 		    SAVER_NAME);
 		return ENODEV;
 	}
+	
+	printf("%d is the video mode chosen for %s\n", VIDEO_MODE, SAVER_NAME);
+
+	scrw=info.vi_width;
+	scrh=info.vi_height;
 
 	blanked = 0;
 	return 0;
diff -Naur dev.orig/syscons/fire/fire_saver.c dev/syscons/fire/fire_saver.c
--- dev.orig/syscons/fire/fire_saver.c	2010-06-14 11:09:06.000000000 +0900
+++ dev/syscons/fire/fire_saver.c	2010-11-14 19:45:23.000000000 +0900
@@ -45,6 +45,7 @@
 #include <dev/fb/fbreg.h>
 #include <dev/fb/splashreg.h>
 #include <dev/syscons/syscons.h>
+#include <dev/syscons/videomode.h>
 
 #define SAVER_NAME	 "fire_saver"
 
@@ -58,6 +59,10 @@
 	    vidd_set_win_org(adp, last_origin = oo);	\
 	} while (0)
 
+#ifndef VIDEO_MODE
+#define VIDEO_MODE M_VESA_CG640x480
+#endif
+
 static u_char		*buf;
 static u_char		*vid;
 static int		 banksize, scrmode, bpsl, scrw, scrh;
@@ -141,7 +146,9 @@
 	video_info_t info;
 	int i, red, green, blue;
 
-	if (!vidd_get_info(adp, M_VGA_CG320, &info)) {
+	if (!vidd_get_info(adp, VIDEO_MODE, &info)) {
+		scrmode = VIDEO_MODE;
+	} else if (!vidd_get_info(adp, M_VGA_CG320, &info)) {
 		scrmode = M_VGA_CG320;
 	} else if (!vidd_get_info(adp, M_PC98_PEGC640x480, &info)) {
 		scrmode = M_PC98_PEGC640x480;
@@ -149,7 +156,7 @@
 		scrmode = M_PC98_PEGC640x400;
 	} else {
 		log(LOG_NOTICE,
-		    "%s: the console does not support M_VGA_CG320\n",
+		    "%s: the console does not support any of video modes it probes.\n",
 		    SAVER_NAME);
 		return (ENODEV);
 	}
diff -Naur dev.orig/syscons/logo/logo_saver.c dev/syscons/logo/logo_saver.c
--- dev.orig/syscons/logo/logo_saver.c	2010-06-14 11:09:06.000000000 +0900
+++ dev/syscons/logo/logo_saver.c	2010-11-14 19:45:40.000000000 +0900
@@ -39,6 +39,7 @@
 #include <dev/fb/fbreg.h>
 #include <dev/fb/splashreg.h>
 #include <dev/syscons/syscons.h>
+#include <dev/syscons/videomode.h>
 
 #define SAVER_NAME	 "logo_saver"
 
@@ -48,6 +49,10 @@
 	    vidd_set_win_org(adp, last_origin = oo);	\
 	} while (0)
 
+#ifndef VIDEO_MODE
+#define VIDEO_MODE M_VESA_CG640x480
+#endif
+
 extern unsigned int	 logo_w;
 extern unsigned int	 logo_h;
 extern unsigned char	 logo_pal[];
@@ -136,7 +141,9 @@
 {
 	video_info_t info;
 	
-	if (!vidd_get_info(adp, M_VESA_CG800x600, &info)) {
+	if (!vidd_get_info(adp, VIDEO_MODE, &info)) {
+		scrmode = VIDEO_MODE;
+	} else if (!vidd_get_info(adp, M_VESA_CG800x600, &info)) {
 		scrmode = M_VESA_CG800x600;
 	} else if (!vidd_get_info(adp, M_VGA_CG320, &info)) {
 		scrmode = M_VGA_CG320;
@@ -146,7 +153,7 @@
 		scrmode = M_PC98_PEGC640x400;
 	} else {
 		log(LOG_NOTICE,
-		    "%s: the console does not support M_VGA_CG320\n",
+		    "%s: the console does not support any of video modes it probes\n",
 		    SAVER_NAME);
 		return (ENODEV);
 	}
diff -Naur dev.orig/syscons/rain/rain_saver.c dev/syscons/rain/rain_saver.c
--- dev.orig/syscons/rain/rain_saver.c	2010-06-14 11:09:06.000000000 +0900
+++ dev/syscons/rain/rain_saver.c	2010-11-14 19:46:03.000000000 +0900
@@ -39,6 +39,7 @@
 #include <dev/fb/fbreg.h>
 #include <dev/fb/splashreg.h>
 #include <dev/syscons/syscons.h>
+#include <dev/syscons/videomode.h>
 
 #define SAVER_NAME	 "rain_saver"
 #ifdef MAX
@@ -57,6 +58,10 @@
 	    vidd_set_win_org(adp, last_origin = oo);	\
 	} while (0)
 
+#ifndef VIDEO_MODE
+#define VIDEO_MODE M_VESA_CG640x480
+#endif
+
 static u_char		*vid;
 static int		 banksize, scrmode, bpsl, scrw, scrh;
 static u_char		 rain_pal[768];
@@ -141,7 +146,9 @@
 	video_info_t info;
 	int i;
 	
-	if (!vidd_get_info(adp, M_VGA_CG320, &info)) {
+	if (!vidd_get_info(adp, VIDEO_MODE, &info)) {
+		scrmode = VIDEO_MODE;
+	} else if (!vidd_get_info(adp, M_VGA_CG320, &info)) {
 		scrmode = M_VGA_CG320;
 	} else if (!vidd_get_info(adp, M_PC98_PEGC640x480, &info)) {
 		scrmode = M_PC98_PEGC640x480;
@@ -149,7 +156,7 @@
 		scrmode = M_PC98_PEGC640x400;
 	} else {
 		log(LOG_NOTICE,
-		    "%s: the console does not support M_VGA_CG320\n",
+		    "%s: the console does not support any of video modes it probes\n",
 		    SAVER_NAME);
 		return (ENODEV);
 	}
diff -Naur dev.orig/syscons/videomode.h dev/syscons/videomode.h
--- dev.orig/syscons/videomode.h	1970-01-01 09:00:00.000000000 +0900
+++ dev/syscons/videomode.h	2010-11-14 19:54:26.000000000 +0900
@@ -0,0 +1,14 @@
+#ifndef _videomode_
+#define _videomode_
+
+#include <sys/fbio.h>
+
+// VIDEO_MODE should be one of 8bit VGA modes
+// because screensavers assume 8bit mode screen.
+// The current value of VIDEO_MODE is just an example.
+// Change it to whatever 8bit mode shown in "vidcontrol -i mode"
+// Many of those numeral mode values are defined as
+// #define macros in /usr/src/sys/sys/fbio.h
+#define VIDEO_MODE M_VESA_CG640x480
+
+#endif
diff -Naur dev.orig/syscons/warp/warp_saver.c dev/syscons/warp/warp_saver.c
--- dev.orig/syscons/warp/warp_saver.c	2010-06-14 11:09:06.000000000 +0900
+++ dev/syscons/warp/warp_saver.c	2010-11-14 19:46:20.000000000 +0900
@@ -39,6 +39,7 @@
 #include <dev/fb/fbreg.h>
 #include <dev/fb/splashreg.h>
 #include <dev/syscons/syscons.h>
+#include <dev/syscons/videomode.h>
 
 #define SAVER_NAME	 "warp_saver"
 #define SPP		 15
@@ -50,6 +51,10 @@
 	    vidd_set_win_org(adp, last_origin = oo);		\
 	} while (0)
 
+#ifndef VIDEO_MODE
+#define VIDEO_MODE M_VESA_CG640x480
+#endif
+
 static u_char		*vid;
 static int		 banksize, scrmode, bpsl, scrw, scrh;
 static int		 blanked;
@@ -127,7 +132,9 @@
 	video_info_t info;
 	int i;
 	
-	if (!vidd_get_info(adp, M_VGA_CG320, &info)) {
+	if (!vidd_get_info(adp, VIDEO_MODE, &info)) {
+		scrmode = VIDEO_MODE;
+	} else if (!vidd_get_info(adp, M_VGA_CG320, &info)) {
 		scrmode = M_VGA_CG320;
 	} else if (!vidd_get_info(adp, M_PC98_PEGC640x480, &info)) {
 		scrmode = M_PC98_PEGC640x480;
@@ -135,7 +142,7 @@
 		scrmode = M_PC98_PEGC640x400;
 	} else {
 		log(LOG_NOTICE,
-		    "%s: the console does not support M_VGA_CG320\n",
+		    "%s: the console does not support any of video modes it probes\n",
 		    SAVER_NAME);
 		return (ENODEV);
 	}


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list