[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#355851: a blindunfriendly debian installer problem



Hi,

Ok, now that this whole discussion took place, here is something that
(almost) works:

http://brl.thefreecat.org/mini.iso (9ed7c3a112a6d72834f6ffeef19d615a)

I attached the patch that I applied to brltty and bogl for getting that
result (they shouldn't be considered as final of course).

You can test:

qemu -cdrom mini.iso
=> no brltty at all

qemu -cdrom mini.iso -serial stdio
and type install brltty=tt,ttyS0  at the kernel command line.
=> brltty is started from /etc/rcS.d with the given parameter: using a
TTY driver on the serial port, hence qemu's stdin/out.

qemu -cdrom mini.iso -serial stdio -usb -usbdevice mouse
=> brltty is automatically started by udev thanks to the dumb last rule
of brltty.rules (just for testing).

qemu -cdrom mini.iso -serial stdio -usb
=> no brltty, but when typing usb_add mouse in the qemu console (hence
simulating a braille device hot plug-in), brltty gets started.

Note for non- brltty-used people: press arrows (for instance)
for getting rid of the "BRLTTY 3.7.2" and "x startup problem(s)"
messages. Then you'll see brltty's reading in action! :)

I said "almost works" because it seems like udevd calls the "add" hook
for the same USB device several times more during the installation (when
probing devices), hence starting brltty a few additional times... I
don't know udev stuff enough for fixing it the "proper way".

(Note that running several instances of brltty for different braille
devices is fine: each of them drives one device ; but two brlttys for
the same braille device may lead to garbage).

Regards,
Samuel
diff -urN brltty-3.7.2/configure brltty-3.7.2-mine/configure
--- brltty-3.7.2/configure	2005-12-26 15:52:02.000000000 +0100
+++ brltty-3.7.2-mine/configure	2006-03-29 00:57:48.000000000 +0200
@@ -9400,227 +9400,6 @@
 
 
 
-for ac_header in iconv.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-else
-  # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_header_compiler=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  ac_header_preproc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-  yes:no: )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
-    ac_header_preproc=yes
-    ;;
-  no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-    (
-      cat <<\_ASBOX
-## --------------------------------------- ##
-## Report this to http://mielke.cc/brltty/ ##
-## --------------------------------------- ##
-_ASBOX
-    ) |
-      sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  eval "$as_ac_Header=\$ac_header_preproc"
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-
-echo "$as_me:$LINENO: checking for main in -liconv" >&5
-echo $ECHO_N "checking for main in -liconv... $ECHO_C" >&6
-if test "${ac_cv_lib_iconv_main+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-liconv  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-
-int
-main ()
-{
-main ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_iconv_main=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_iconv_main=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_iconv_main" >&5
-echo "${ECHO_T}$ac_cv_lib_iconv_main" >&6
-if test $ac_cv_lib_iconv_main = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBICONV 1
-_ACEOF
-
-  LIBS="-liconv $LIBS"
-
-fi
-ac_cv_lib_iconv=ac_cv_lib_iconv_main
-
-
-fi
-
-done
-
-
-
 
 
 
diff -urN brltty-3.7.2/configure.in brltty-3.7.2-mine/configure.in
--- brltty-3.7.2/configure.in	2005-12-26 14:29:33.000000000 +0100
+++ brltty-3.7.2-mine/configure.in	2006-03-28 03:41:20.000000000 +0200
@@ -485,10 +485,6 @@
 #include <linux/input.h>
 ])])
 
-AC_CHECK_HEADERS([iconv.h], [
-   AC_HAVE_LIBRARY([iconv])
-])
-
 AC_CHECK_FUNCS([fchdir fchmod gai_strerror getaddrinfo getopt_long hstrerror realpath shmget shm_open sigaction vsyslog])
 
 AC_CHECK_SIZEOF([key_t], [], [
diff -urN brltty-3.7.2/debian/brltty-udeb.dirs brltty-3.7.2-mine/debian/brltty-udeb.dirs
--- brltty-3.7.2/debian/brltty-udeb.dirs	2006-03-28 11:44:01.000000000 +0200
+++ brltty-3.7.2-mine/debian/brltty-udeb.dirs	2006-03-28 04:42:46.000000000 +0200
@@ -1,5 +1,6 @@
 etc/brltty
 etc/rcS.d
+etc/udev/rules.d
 lib/brltty
 sbin
 usr/lib/prebaseconfig.d
diff -urN brltty-3.7.2/debian/brltty-udeb.init brltty-3.7.2-mine/debian/brltty-udeb.init
--- brltty-3.7.2/debian/brltty-udeb.init	2006-03-28 11:44:01.000000000 +0200
+++ brltty-3.7.2-mine/debian/brltty-udeb.init	2006-03-28 07:30:20.000000000 +0200
@@ -1,3 +1,2 @@
 #!/bin/sh
-/sbin/brltty -E
-
+grep -q brltty /proc/cmdline && /sbin/brltty -X btermvt=1 -E &
diff -urN brltty-3.7.2/debian/brltty-udeb.rules brltty-3.7.2-mine/debian/brltty-udeb.rules
--- brltty-3.7.2/debian/brltty-udeb.rules	1970-01-01 01:00:00.000000000 +0100
+++ brltty-3.7.2-mine/debian/brltty-udeb.rules	2006-03-29 01:10:29.000000000 +0200
@@ -0,0 +1,35 @@
+# udev rules file for brltty
+#
+
+ACTION!="add", GOTO="brltty_rules_end"
+SUBSYSTEM!="usb_device", GOTO="brltty_rules_end"
+
+# Alva
+SYSFS{idVendor}=="06b0", SYSFS{idProduct}=="0001", RUN+="/sbin/brltty -b al -d usb: -X btermvt=1"
+
+# Baum
+SYSFS{idVendor}=="0403", SYSFS{idProduct}=="fe71", RUN+="/sbin/brltty -b bm -d usb: -X btermvt=1"
+SYSFS{idVendor}=="0403", SYSFS{idProduct}=="fe72", RUN+="/sbin/brltty -b bm -d usb: -X btermvt=1"
+SYSFS{idVendor}=="0403", SYSFS{idProduct}=="fe73", RUN+="/sbin/brltty -b bm -d usb: -X btermvt=1"
+SYSFS{idVendor}=="0403", SYSFS{idProduct}=="fe74", RUN+="/sbin/brltty -b bm -d usb: -X btermvt=1"
+SYSFS{idVendor}=="0403", SYSFS{idProduct}=="fe75", RUN+="/sbin/brltty -b bm -d usb: -X btermvt=1"
+
+# FreedomScientific
+SYSFS{idVendor}=="0f4e", SYSFS{idProduct}=="0100", RUN+="/sbin/brltty -b fs -d usb: -X btermvt=1"
+SYSFS{idVendor}=="0f4e", SYSFS{idProduct}=="0111", RUN+="/sbin/brltty -b fs -d usb: -X btermvt=1"
+SYSFS{idVendor}=="0f4e", SYSFS{idProduct}=="0112", RUN+="/sbin/brltty -b fs -d usb: -X btermvt=1"
+
+# HandyTech
+SYSFS{idVendor}=="0921", SYSFS{idProduct}=="1200", RUN+="/sbin/brltty -b ht -d usb: -X btermvt=1"
+SYSFS{idVendor}=="0403", SYSFS{idProduct}=="6001", RUN+="/sbin/brltty -b ht -d usb: -X btermvt=1"
+
+# Papenmeier
+SYSFS{idVendor}=="0403", SYSFS{idProduct}=="f208", RUN+="/sbin/brltty -b pm -d usb: -X btermvt=1"
+
+# Voyager
+SYSFS{idVendor}=="0798", SYSFS{idProduct}=="0001", RUN+="/sbin/brltty -b vo -d usb: -X btermvt=1"
+
+# QEMU Mouse
+SYSFS{idVendor}=="0627", SYSFS{idProduct}=="0001", RUN+="/sbin/brltty -b tt -d ttyS0 -X btermvt=1"
+
+LABEL="brltty_rules_end"
diff -urN brltty-3.7.2/debian/changelog brltty-3.7.2-mine/debian/changelog
--- brltty-3.7.2/debian/changelog	2006-03-28 11:44:01.000000000 +0200
+++ brltty-3.7.2-mine/debian/changelog	2006-03-28 05:05:42.000000000 +0200
@@ -1,3 +1,13 @@
+brltty (3.7.2-2debinst) unstable; urgency=low
+
+  * Add tt driver.
+  * Add bterm reading support.
+  * Autostart brltty only if the user set some "brltty=" parameters at the
+    kernel command line.
+  * Add udev rules for autostarting brltty when USB devices are probed.
+
+ -- Samuel Thibault <samuel.thibault@ens-lyon.org>  Wed, 29 Mar 2006 01:30:55 +0200
+
 brltty (3.7.2-2) unstable; urgency=low
 
   * Move xbrlapi to libbrlapi1-dev.
diff -urN brltty-3.7.2/debian/control brltty-3.7.2-mine/debian/control
--- brltty-3.7.2/debian/control	2006-03-28 11:44:01.000000000 +0200
+++ brltty-3.7.2-mine/debian/control	2006-03-28 04:16:29.000000000 +0200
@@ -3,7 +3,7 @@
 Priority: extra
 Maintainer: Mario Lang <mlang@debian.org>
 Build-Depends: debhelper (>= 4.2), bison, doxygen, linuxdoc-tools, groff,
- flite1-dev, libncurses5-dev, libxaw8-dev, libatspi-dev
+ flite1-dev, libncurses5-dev, libxaw8-dev, libatspi-dev, libbogl-dev
 Standards-Version: 3.6.1
 
 Package: brltty
diff -urN brltty-3.7.2/debian/rules brltty-3.7.2-mine/debian/rules
--- brltty-3.7.2/debian/rules	2006-03-28 11:44:01.000000000 +0200
+++ brltty-3.7.2-mine/debian/rules	2006-03-29 00:58:23.000000000 +0200
@@ -12,7 +12,7 @@
 UDEB_CFLAGS=-Os -fomit-frame-pointer
 UDEB_DISABLE=speech-support pcm-support midi-support fm-support contracted-braille \
 	preferences-menu api learn-mode pm-configfile
-UDEB_CONFIGURE_OPTIONS=--with-braille-driver=-tt,-vr,all \
+UDEB_CONFIGURE_OPTIONS=--with-braille-driver=-vr,all \
 	--with-braille-device=usb: --with-screen-driver=-as,-sc,all \
 	--without-init-path --without-x --without-curses \
 	$(patsubst %,--disable-%,$(UDEB_DISABLE))
@@ -138,6 +138,7 @@
 	rm debian/brltty-udeb/etc/brltty/*.hlp
 	#rm -Rf debian/brltty-udeb/lib
 	cp debian/brltty-udeb.init debian/$@/etc/rcS.d/S02brltty
+	cp debian/brltty-udeb.rules debian/$@/etc/udev/rules.d/brltty.rules
 	chmod +x debian/$@/etc/rcS.d/S02brltty
 	dh_strip -p$@
 	dh_fixperms -p$@
diff -urN brltty-3.7.2/ScreenDrivers/Linux/screen.c brltty-3.7.2-mine/ScreenDrivers/Linux/screen.c
--- brltty-3.7.2/ScreenDrivers/Linux/screen.c	2006-03-28 23:25:41.000000000 +0200
+++ brltty-3.7.2-mine/ScreenDrivers/Linux/screen.c	2006-03-29 01:03:29.000000000 +0200
@@ -25,9 +25,11 @@
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
+#include <sys/mman.h>
 #include <linux/tty.h>
 #include <linux/vt.h>
 #include <linux/kd.h>
+#include <bogl/bogl-term.h>
 
 #include "Programs/misc.h"
 #include "Programs/brldefs.h"
@@ -36,9 +38,11 @@
   PARM_ACM,
   PARM_DEBUGACM,
   PARM_DEBUGSFM,
-  PARM_DEBUGCTT
+  PARM_DEBUGCTT,
+  PARM_BTERMVT,
+  PARM_BTERMPATH
 } ScreenParameters;
-#define SCRPARMS "acm", "debugacm", "debugsfm", "debugctt"
+#define SCRPARMS "acm", "debugacm", "debugsfm", "debugctt", "btermvt", "btermpath"
 
 #include "Programs/scr_driver.h"
 #include "screen.h"
@@ -49,6 +53,14 @@
 static unsigned int debugApplicationCharacterMap = 0;
 static unsigned int debugScreenFontMap = 0;
 static unsigned int debugScreenTextTranslation = 0;
+static const char * btermPath = "/dev/bterm";
+static int btermVtno = 0;
+
+static struct bogl_term *btermTerm;
+static wchar_t *btermScreen;
+static int *btermScreenFg;
+static int *btermScreenBg;
+static int *btermScreenUl;
 
 /* Copied from linux-2.2.17/drivers/char/consolemap.c: translations[0]
  * 8-bit Latin-1 mapped to Unicode -- trivial mapping
@@ -241,11 +253,13 @@
 static int
 openDevice (const char *path, const char *description, int flags, int major, int minor) {
   int file;
+  int the_errno;
   LogPrint(LOG_DEBUG, "Opening %s device: %s", description, path);
   if ((file = open(path, flags)) == -1) {
+    the_errno = errno;
     LogPrint(LOG_ERR, "Cannot open %s device: %s: %s",
-             description, path, strerror(errno));
-    if (errno == ENOENT) {
+             description, path, strerror(the_errno));
+    if (the_errno == ENOENT) {
       mode_t mode = S_IFCHR | S_IRUSR | S_IWUSR;
       LogPrint(LOG_NOTICE, "Creating %s device: %s mode=%06o major=%d minor=%d",
                description, path, mode, major, minor);
@@ -303,6 +317,64 @@
   return 0;
 }
 
+static const struct map {
+  const char *name;
+  void ** map;
+  ssize_t size;
+} maps[] = { 
+  { "term",	(void**)(void*)&btermTerm,	sizeof(*btermTerm) },
+  { "screen",	(void**)(void*)&btermScreen,	-sizeof(wchar_t) },
+  { "screenfg",	(void**)(void*)&btermScreenFg,	-sizeof(int) },
+  { "screenbg",	(void**)(void*)&btermScreenBg,	-sizeof(int) },
+  { "screenul",	(void**)(void*)&btermScreenUl,	-sizeof(int) }
+};
+
+static void
+doCloseBtermScreen() {
+  int i;
+  for (i=sizeof(maps)/sizeof(*maps)-1; i>=0; --i) {
+    if (*maps[i].map)
+      munmap(*maps[i].map, maps[i].size > 0 ? maps[i].size:
+	  btermTerm->xsize * btermTerm->ysize * (-maps[i].size));
+    *maps[i].map = NULL;
+  }
+}
+
+static void
+closeBtermScreen() {
+  doCloseBtermScreen();
+}
+
+static int
+tryToOpenBtermScreen () {
+  int i, n = strlen(btermPath), fd;
+  char c[n + 1 + 8 + 1];
+
+  for (i=0; i<sizeof(maps)/sizeof(*maps); ++i) {
+    snprintf(c, sizeof(c), "%s/%s", btermPath, maps[i].name);
+    fd = open(c, O_RDONLY);
+    if (fd < 0) {
+      if (errno != ENOENT)
+	LogError("Opening bterm");
+      goto fixup;
+    }
+    *maps[i].map = mmap(NULL, maps[i].size > 0 ? maps[i].size:
+	btermTerm->xsize * btermTerm->ysize * (-maps[i].size),
+	PROT_READ, MAP_SHARED, fd, 0);
+    if (!*maps[i].map) {
+      LogError("Maping bterm");
+      close(fd);
+      goto fixup;
+    }
+    close(fd);
+  }
+  return 1;
+
+fixup:
+  doCloseBtermScreen();
+  return 0;
+}
+
 static const char *screenPath;
 static int screenDescriptor;
 static unsigned char virtualTerminal;
@@ -321,6 +393,7 @@
     LogPrint(LOG_DEBUG, "Screen closed: fd=%d", screenDescriptor);
     screenDescriptor = -1;
   }
+  closeBtermScreen();
 }
 
 static int
@@ -547,6 +620,12 @@
       }
     }
   }
+  {
+    static const int one = 1;
+    validateInteger(&btermVtno, "VT number of bterm", parameters[PARM_BTERMVT], &one, NULL);
+  }
+  if (parameters[PARM_BTERMPATH] && *parameters[PARM_BTERMPATH])
+    btermPath = parameters[PARM_BTERMPATH];
   if (setScreenPath()) {
     screenDescriptor = -1;
     if (setConsolePath()) {
@@ -561,7 +640,11 @@
 static int
 open_LinuxScreen (void) {
   currentConsoleNumber = 0;
-  return openScreen(0);
+  if (!openScreen(0))
+    return 0;
+  if (btermVtno)
+    tryToOpenBtermScreen();
+  return 1;
 }
 
 /* 
@@ -727,9 +810,61 @@
   }
 }
 
+static int
+getBtermScreenDescription(ScreenDescription *description) {
+  if (!btermTerm && !tryToOpenBtermScreen())
+    return 0;
+  description->rows = btermTerm->ysize;
+  description->cols = btermTerm->xsize;
+  description->posx = btermTerm->xpos;
+  description->posy = btermTerm->ypos;
+  return 1;
+}
+
+static int
+read_BtermScreen (ScreenBox box, unsigned char *buffer, ScreenMode mode) {
+  ScreenDescription description;
+  if (!getBtermScreenDescription(&description))
+    return 0;
+
+  if (validateScreenBox(&box, description.cols, description.rows)) {
+    int text = mode == SCR_TEXT;
+    wchar_t wc;
+    int row, column;
+    int offset;
+    for (row=box.top; row<box.top+box.height; ++row) {
+      for (column=box.left; column<box.left+box.width; ++column) {
+	offset = ((row+btermTerm->yorig)%btermTerm->ysize)*btermTerm->xsize+column;
+	if (text) {
+	  wc = btermScreen[offset];
+	  if (wc < 0x100)
+	    *buffer++ = wc;
+	  else
+	    *buffer++ = '?';
+	} else {
+	  *buffer++ = ((btermScreenUl[offset]&0x1)<<7)
+	    |((btermScreenBg[offset]&0x7)<<4)
+	    |((btermScreenFg[offset]&0xf));
+	}
+      }
+    }
+    return 1;
+  } else {
+    LogPrint(LOG_ERR, "Invalid screen area: cols=%d left=%d width=%d rows=%d top=%d height=%d",
+             description.cols, box.left, box.width,
+             description.rows, box.top, box.height);
+  }
+  return 0;
+}
+
 static void
 describe_LinuxScreen (ScreenDescription *description) {
   getConsoleDescription(description);
+
+  if (btermVtno && description->no == btermVtno &&
+      getBtermScreenDescription(description))
+    return;
+
   getScreenDescription(description);
 
   /* Periodically recalculate font mapping. I don't know any way to be
@@ -749,6 +884,11 @@
 read_LinuxScreen (ScreenBox box, unsigned char *buffer, ScreenMode mode) {
   ScreenDescription description;
   describe_LinuxScreen(&description);
+
+  if (btermVtno && description.no == btermVtno &&
+      read_BtermScreen(box, buffer, mode))
+    return 1;
+
   if (validateScreenBox(&box, description.cols, description.rows)) {
     int text = mode == SCR_TEXT;
 
diff -ur bogl-0.1.18/bogl-term.c bogl-0.1.18-mine/bogl-term.c
--- bogl-0.1.18/bogl-term.c	2003-11-05 05:38:22.000000000 +0100
+++ bogl-0.1.18-mine/bogl-term.c	2006-03-28 04:09:07.000000000 +0200
@@ -26,24 +26,84 @@
 
 #include "bogl.h"
 #include "bogl-term.h"
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
 
 #define MAX_CCHARS 5
 
-struct bogl_term *bogl_term_new(struct bogl_font *font)
+static void *mmaped_alloc(const char *map_path, const char *file, size_t size, int zero)
+{
+  void *ptr;
+  if (map_path) {
+    char c[strlen(map_path) + 1 + strlen(file) + 1];
+    static const char zero = 0;
+    int fd;
+    snprintf(c, sizeof(c), "%s/%s", map_path, file);
+    fd = open(c, O_RDWR|O_CREAT|O_TRUNC, 0400);
+    if (fd < 0)
+      return NULL;
+    if (lseek(fd, size - 1, SEEK_SET) < 0
+	|| write(fd, &zero, 1) < 0) {
+      close(fd);
+      unlink(c);
+      return NULL;
+    }
+    ptr = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+    close(fd);
+    if (!ptr) {
+      unlink(c);
+      return NULL;
+    }
+    if (zero)
+      memset(ptr, 0, size - 1);
+  } else {
+    if (zero)
+      ptr = calloc(size, 1);
+    else
+      ptr = malloc(size);
+  }
+  return ptr;
+}
+
+static void mmaped_free(const char *map_path, const char *file, void *ptr, size_t size)
+{
+  if (map_path) {
+    char c[strlen(map_path) + 1 + strlen(file) + 1];
+    if (!ptr)
+      return;
+    snprintf(c, sizeof(c), "%s/%s", map_path, file);
+    munmap(ptr, size);
+    unlink(c);
+  } else {
+    free(ptr);
+  }
+}
+
+struct bogl_term *bogl_term_new(struct bogl_font *font, const char *map_path)
 {
   struct bogl_term *term;
   int i;
 
-  term = calloc(sizeof(struct bogl_term), 1);
-  if (!term)
+  if (mkdir(map_path, 0755) && errno != EEXIST)
     return 0;
 
+  term = mmaped_alloc(map_path, "term", sizeof(struct bogl_term), 1);
+  if (!term) {
+    rmdir(map_path);
+    return 0;
+  }
+
   term->font = font;
   term->xbase = term->ybase = 0;
   term->xstep = bogl_font_glyph(font, ' ', 0);
   term->ystep = bogl_font_height(font);
   if (term->xstep <= 0 || term->ystep <= 0) {
-    free(term);
+    mmaped_free(map_path, "term", term, sizeof(struct bogl_term));
+    rmdir(map_path);
     return 0;
   }
 
@@ -57,20 +117,21 @@
   term->cur_visible = 1;
   memset(&term->ps, 0, sizeof(&term->ps));
 
-  term->screen = malloc(term->xsize * term->ysize * sizeof(wchar_t));
+  term->screen = mmaped_alloc(map_path, "screen", term->xsize * term->ysize * sizeof(wchar_t), 0);
   term->dirty = malloc(term->xsize * term->ysize);
-  term->screenfg = malloc(term->xsize * term->ysize * sizeof(int));
-  term->screenbg = malloc(term->xsize * term->ysize * sizeof(int));
-  term->screenul = malloc(term->xsize * term->ysize * sizeof(int));
+  term->screenfg = mmaped_alloc(map_path, "screenfg", term->xsize * term->ysize * sizeof(int), 0);
+  term->screenbg = mmaped_alloc(map_path, "screenbg", term->xsize * term->ysize * sizeof(int), 0);
+  term->screenul = mmaped_alloc(map_path, "screenul", term->xsize * term->ysize * sizeof(int), 0);
   term->cchars = malloc(term->xsize * term->ysize * sizeof(wchar_t *));
   if (!term->screen || !term->screenfg || !term->screenbg || !term->screenul || !term->cchars || !term->dirty) {
-    free(term->screen);
-    free(term->screenfg);
-    free(term->screenbg);
-    free(term->screenul);
+    mmaped_free(map_path, "screen", term->screen, term->xsize * term->ysize * sizeof(wchar_t));
+    mmaped_free(map_path, "screenfg", term->screenfg, term->xsize * term->ysize * sizeof(int));
+    mmaped_free(map_path, "screenbg", term->screenbg, term->xsize * term->ysize * sizeof(int));
+    mmaped_free(map_path, "screenul", term->screenul, term->xsize * term->ysize * sizeof(int));
     free(term->cchars);
     free(term->dirty);
-    free(term);
+    mmaped_free(map_path, "term", term, sizeof(struct bogl_term));
+    rmdir(map_path);
     return 0;
   }
   for (i = 0; i < term->xsize * term->ysize; i++) {
diff -ur bogl-0.1.18/bogl-term.h bogl-0.1.18-mine/bogl-term.h
--- bogl-0.1.18/bogl-term.h	2003-11-05 04:01:47.000000000 +0100
+++ bogl-0.1.18-mine/bogl-term.h	2006-03-28 04:02:33.000000000 +0200
@@ -26,7 +26,7 @@
   int acs;
 };
 
-struct bogl_term *bogl_term_new(struct bogl_font *font);
+struct bogl_term *bogl_term_new(struct bogl_font *font, const char *map_path);
 void bogl_term_out(struct bogl_term *term, char *s, int n);
 void bogl_term_redraw(struct bogl_term *term);
 void bogl_term_delete(struct bogl_font *font);
diff -ur bogl-0.1.18/bterm.c bogl-0.1.18-mine/bterm.c
--- bogl-0.1.18/bterm.c	2004-07-22 12:39:42.000000000 +0200
+++ bogl-0.1.18-mine/bterm.c	2006-03-28 02:12:53.000000000 +0200
@@ -217,7 +217,7 @@
   struct timeval tv;
   int ptyfd, ttyfd;
   struct bogl_font *font;
-  char *locale = "", *command = NULL;
+  char *locale = "", *command = NULL, *map_path = "/dev/bterm";
   int i;
   char o = ' ';
   int pending = 0;
@@ -228,6 +228,7 @@
           {
               case 'f':
               case 'l':
+              case 'm':
                   o = argv[i][1];
                   break;
 
@@ -250,12 +251,16 @@
                     locale = argv[i];
                     o = ' ';
                     break;
+                case 'm':
+                    map_path = argv[i];
+                    o = ' ';
+                    break;
             }
 
   setlocale(LC_CTYPE, locale);
 
   if (font_name == NULL) {
-    fprintf(stderr, "Usage: %s -f font.bgf [ -l locale ] [ program ]\n", argv[0]);
+    fprintf(stderr, "Usage: %s -f font.bgf [ -l locale ] [ -m map_path ] [ program ]\n", argv[0]);
  
     return 1;
   }
@@ -272,7 +277,7 @@
     return 1;
   }
 
-  term = bogl_term_new(font);
+  term = bogl_term_new(font, map_path);
   if (!term)
     exit(1);
 
diff -ur bogl-0.1.18/debian/changelog bogl-0.1.18-mine/debian/changelog
--- bogl-0.1.18/debian/changelog	2005-09-25 02:09:14.000000000 +0200
+++ bogl-0.1.18-mine/debian/changelog	2006-03-28 03:21:37.000000000 +0200
@@ -1,3 +1,9 @@
+bogl (0.1.18-1.4map) unstable; urgency=low
+
+  * Add support for mapping bterm's screen for brltty access.
+
+ -- Samuel Thibault <samuel.thibault@ens-lyon.org>  Wed, 29 Mar 2006 01:30:55 +0200
+
 bogl (0.1.18-1.4) unstable; urgency=low
 
   * NMU

Reply to: