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 <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> Wed, 29 Mar 2006 01:30:55 +0200 + bogl (0.1.18-1.4) unstable; urgency=low * NMU