Re: Bug#359062: debian-installer: bterm is not (yet) accessible for brltty
- To: Dave Mielke <dave@mielke.cc>, 359062@bugs.debian.org, debian-boot@lists.debian.org, mlang@debian.org, sebastien.hinderer@libertysurf.fr
- Subject: Re: Bug#359062: debian-installer: bterm is not (yet) accessible for brltty
- From: Samuel Thibault <samuel.thibault@ens-lyon.org>
- Date: Tue, 28 Mar 2006 11:47:46 +0200
- Message-id: <[🔎] 20060328094746.GC4540@implementation.labri.fr>
- Mail-followup-to: Samuel Thibault <samuel.thibault@ens-lyon.org>, Dave Mielke <dave@mielke.cc>, 359062@bugs.debian.org, debian-boot@lists.debian.org, mlang@debian.org, sebastien.hinderer@libertysurf.fr
- In-reply-to: <[🔎] 20060327232544.GY5157@bouh.residence.ens-lyon.fr>
- References: <[🔎] 20060327204458.GC13158@kitenet.net> <[🔎] 20060327205259.GH5157@bouh.residence.ens-lyon.fr> <[🔎] 20060327212647.GA16373@kitenet.net> <[🔎] 20060327213951.GK5157@bouh.residence.ens-lyon.fr> <[🔎] 20060327220409.GC16373@kitenet.net> <[🔎] 20060327221323.GV5157@bouh.residence.ens-lyon.fr> <[🔎] 20060327225048.GB4529@beta.private.mielke.cc> <[🔎] 20060327225732.GW5157@bouh.residence.ens-lyon.fr> <[🔎] 20060327231955.GC4529@beta.private.mielke.cc> <[🔎] 20060327232544.GY5157@bouh.residence.ens-lyon.fr>
Hi,
Here are quick-and-dirty-but-working implementations.
Regards,
Samuel
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 = NULL;
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 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 -ur 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 2005-12-26 13:58:05.000000000 +0100
+++ brltty-3.7.2-mine/ScreenDrivers/Linux/screen.c 2006-03-28 06:49:07.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
@@ -303,6 +315,52 @@
return 0;
}
+static int
+openBtermScreen (const char *map_path) {
+ struct map {
+ const char *name;
+ void **map;
+ ssize_t size;
+ } maps[] = {
+ { "term", (void**)&btermTerm, sizeof(*btermTerm) },
+ { "screen", (void**)&btermScreen, -sizeof(wchar_t) },
+ { "screenfg", (void**)&btermScreenFg, -sizeof(int) },
+ { "screenbg", (void**)&btermScreenBg, -sizeof(int) },
+ { "screenul", (void**)&btermScreenUl, -sizeof(int) }
+ };
+ int i, n = strlen(map_path), fd, tries;
+ char c[n + 1 + 8 + 1];
+
+ for (i=0;i<sizeof(maps)/sizeof(*maps);++i) {
+ snprintf(c, sizeof(c), "%s/%s", map_path, maps[i].name);
+ for(tries=0; ; tries++) {
+ fd = open(c, O_RDONLY);
+ if (fd >= 0)
+ break;
+ if (errno != ENOENT || tries >= 20) {
+ LogError("Opening bterm");
+ goto fixup;
+ }
+ sleep(1);
+ }
+ *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);
+ close(fd);
+ if (!*maps[i].map) {
+ LogError("Maping bterm");
+ goto fixup;
+ }
+ }
+ return 1;
+
+fixup:
+ for (--i; i>0; --i)
+ munmap(*maps[i].map, maps[i].size > 0 ? maps[i].size:
+ btermTerm->xsize * btermTerm->ysize * (-maps[i].size));
+ return 0;
+}
+
static const char *screenPath;
static int screenDescriptor;
static unsigned char virtualTerminal;
@@ -547,6 +605,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 = strdupWrapper(parameters[PARM_BTERMPATH]);
if (setScreenPath()) {
screenDescriptor = -1;
if (setConsolePath()) {
@@ -561,7 +625,9 @@
static int
open_LinuxScreen (void) {
currentConsoleNumber = 0;
- return openScreen(0);
+ if (!openScreen(0))
+ return 0;
+ return (!btermVtno || openBtermScreen(btermPath));
}
/*
@@ -728,9 +794,57 @@
}
static void
+getBtermScreenDescription(ScreenDescription *description) {
+ description->rows = btermTerm->ysize;
+ description->cols = btermTerm->xsize;
+ description->posx = btermTerm->xpos;
+ description->posy = btermTerm->ypos;
+}
+
+static int
+read_BtermScreen (ScreenBox box, unsigned char *buffer, ScreenMode mode) {
+ ScreenDescription description;
+ getBtermScreenDescription(&description);
+
+ LogPrint(LOG_DEBUG,"reading %ldx%ld bterm screen at %ld %ld : %ldx%ld+%ld%ld\n", description.cols, description.rows, description.posx, description.posy, box.width,box.height,box.left,box.top);
+ 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);
- getScreenDescription(description);
+
+ if (btermVtno && description->no == btermVtno)
+ getBtermScreenDescription(description);
+ else
+ getScreenDescription(description);
/* Periodically recalculate font mapping. I don't know any way to be
* notified when it changes, and the recalculation is not too
@@ -749,6 +863,10 @@
read_LinuxScreen (ScreenBox box, unsigned char *buffer, ScreenMode mode) {
ScreenDescription description;
describe_LinuxScreen(&description);
+
+ if (btermVtno && description.no == btermVtno)
+ return read_BtermScreen(box, buffer, mode);
+
if (validateScreenBox(&box, description.cols, description.rows)) {
int text = mode == SCR_TEXT;
Reply to: