[MPlayer-dev-eng] [PATCH] 4/5 Smarten up multi-framebuffer usage

Alan Curry pacman at theworld.com
Thu Apr 20 03:47:03 CEST 2006


This patch is purely for the benefit of multi-headed machines, and I don't
have one so it's untested (except that I can confirm it doesn't screw up
single-headed operation).

If you have a multiple framebuffer devices, and your console VTs are
displayed on the one called /dev/fb0, you should be able to use
mplayer -vo fbdev:/dev/fb1 and still have normal VT switching. This patch
attempts to do that, by detecting whether mplayer's VT and vo_fbdev's output
are on the same framebuffer. If they are not, there is no reason to disable
VT switching by setting KD_GRAPHICS.

In this patch, if mplayer can't find its own VT on stdin, stdout, or stderr,
it falls back on the old behavior (assuming that the tty is on the same fb as
the movie, and setting KD_GRAPHICS).

--- libvo/vo_fbdev.c.orig	2006-04-18 14:27:38.000000000 -0500
+++ libvo/vo_fbdev.c	2006-04-18 14:09:43.000000000 -0500
@@ -15,6 +15,7 @@
 #include <errno.h>
 #include <ctype.h>
 
+#include <sys/stat.h>
 #include <sys/mman.h>
 #include <sys/ioctl.h>
 #include <sys/kd.h>
@@ -657,11 +658,99 @@
 	free(cmap);
 }
 
+#define VT_MAJOR 4
+#define FB_MAJOR 29
+
+/* return the number of the fb which we are drawing on */
+static int my_fb(void)
+{
+	static int fbnum = -2;
+	struct stat st;
+
+	if(fbnum == -2) {
+		int i;
+		struct stat st;
+
+		fbnum = -1;
+		if(!fstat(fb_dev_fd, &st) &&
+		   S_ISCHR(st.st_mode) &&
+		   major(st.st_rdev)==FB_MAJOR) {
+			int m = minor(st.st_rdev);
+			if(m>0 && m<64)
+				fbnum = m;
+		}
+	}
+
+	return fbnum;
+}
+
+/* Try to find out which VT mplayer is running on. The best way
+   to do this would be to open /dev/tty and do a VT_GETNUM to find out which
+   VT is the controlling tty of the process. Unfortunately VT_GETNUM only
+   exists in my imagination, so the actual procedure is less pretty. */
+static int my_vt(void)
+{
+	static int vtnum = -2;
+
+	if(vtnum == -2) {
+		int i;
+		struct stat st;
+
+		vtnum = -1;
+		for(i=0;i<3;++i) {
+			if(!fstat(3*!!i-i, &st) &&
+			   S_ISCHR(st.st_mode) &&
+			   major(st.st_rdev)==VT_MAJOR) {
+				int m = minor(st.st_rdev);
+				if(m>0 && m<64) {
+					vtnum = m;
+					break;
+				}
+			}
+		}
+	}
+
+	return vtnum;
+}
+
+/* Return true if mplayer's tty is on the same framebuffer device that the
+   movie is being played on. */
+static int my_vt_is_on_my_fb(void)
+{
+	struct fb_con2fbmap map;
+
+	if(my_vt()==-1)
+		/* Can't find the truth; let's use this baseless assumption: */
+		return 1;
+
+	if(my_fb()==-1)
+		/* Unreachable(?) */
+		return 1;
+
+	map.console=my_vt();
+
+	if (ioctl(fb_dev_fd, FBIOGET_CON2FBMAP, &map))
+		/* Here's the same baseless assumption again */
+		return 1;
+
+	return map.framebuffer == my_fb();
+}
+
 static void vtswitch_init(void)
 {
 	if (fb_tty_fd < 0)
 		return;
 
+#ifdef CONFIG_VIDIX
+	if (!vidix_name)
+#endif
+	{
+		if (!my_vt_is_on_my_fb()) {
+			fb_tty_fd = -1;
+			return;
+		}
+	}
+
 	if (ioctl(fb_tty_fd, KDGETMODE, &orig_kdmode) < 0) {
 		mp_msg(MSGT_VO, MSGL_V, "Can't get graphics mode: %s\n", strerror(errno));
 		close(fb_tty_fd);




More information about the MPlayer-dev-eng mailing list