[BRLTTY] Working with braille characters in console mode?
Samuel Thibault
samuel.thibault at ens-lyon.org
Mon Jan 21 18:32:07 EST 2008
Hello,
Mario Lang, le Tue 22 Jan 2008 00:21:10 +0100, a écrit :
> There is just one bug I can immediately see, if I enter 2800,
> I see a question mark ('?').
Augh, right, that's the result of my hackish way to do it. The attached
patch should hopefully fix it.
> Also, I am not really sure bit I guess cut&paste is also not working.
> This is understandable and I can live with it, but ultimately it would
> of course be cool to work too.
The brltty cut & paste? Little wonder indeed.
> lynx and links both seem to have problems printing the unicode braille
> correctly,
lynx and links simply don't support unicode...
> Dave, any chance of this patch getting accepted? Although it probably
> feels like a hack, it is indeed very useful IMO.
Dave is working on the screen driver interface overhaul I preferred to
avoid doing myself :) Then cut&paste & everything should hopefully work.
Samuel
-------------- next part --------------
Index: Programs/scr_help.c
===================================================================
--- Programs/scr_help.c (r?vision 3469)
+++ Programs/scr_help.c (copie de travail)
@@ -246,6 +246,8 @@
pages[pageNumber] + ((box.top + row) * getBigEndian(description->width)) + box.left,
box.width);
}
+ } else if (property == SCR_DOTS) {
+ memset(buffer, 0X00, box.width*box.height);
} else {
memset(buffer, 0X07, box.width*box.height);
}
--- Programs/scr_base.c (r?vision 3469)
+++ Programs/scr_base.c (copie de travail)
@@ -57,6 +57,8 @@
if (!validateScreenBox(&box, description.cols, description.rows)) return 0;
if (property == SCR_TEXT) {
memcpy(buffer, text_BaseScreen+box.left, box.width);
+ } else if (property == SCR_DOTS) {
+ memset(buffer, 0X00, box.width);
} else {
memset(buffer, 0X07, box.width);
}
--- Programs/scr_frozen.c (r?vision 3469)
+++ Programs/scr_frozen.c (copie de travail)
@@ -27,6 +27,7 @@
static ScreenDescription screenDescription;
static unsigned char *screenText;
static unsigned char *screenAttributes;
+static unsigned char *screenDots;
static int
construct_FrozenScreen (BaseScreen *source) {
@@ -35,7 +36,9 @@
if ((screenAttributes = calloc(screenDescription.rows*screenDescription.cols, sizeof(*screenAttributes)))) {
if (source->read((ScreenBox){0, 0, screenDescription.cols, screenDescription.rows}, screenText, SCR_TEXT)) {
if (source->read((ScreenBox){0, 0, screenDescription.cols, screenDescription.rows}, screenAttributes, SCR_ATTRIB)) {
- return 1;
+ if (source->read((ScreenBox){0, 0, screenDescription.cols, screenDescription.rows}, screenDots, SCR_DOTS)) {
+ return 1;
+ }
}
}
free(screenAttributes);
@@ -71,7 +74,7 @@
static int
read_FrozenScreen (ScreenBox box, unsigned char *buffer, ScreenCharacterProperty property) {
if (validateScreenBox(&box, screenDescription.cols, screenDescription.rows)) {
- unsigned char *screen = (property == SCR_TEXT)? screenText: screenAttributes;
+ unsigned char *screen = (property == SCR_TEXT)? screenText: (property == SCR_DOTS)? screenDots: screenAttributes;
int row;
for (row=0; row<box.height; row++)
memcpy(buffer + (row * box.width),
--- Programs/brltty.c (r?vision 3469)
+++ Programs/brltty.c (copie de travail)
@@ -2488,6 +2488,21 @@
readScreen(p->winx, p->winy, winlen, brl.y, attrbuf, SCR_ATTRIB);
overlayAttributes(attrbuf, winlen, brl.y);
}
+
+ /* Mix raw U+28uv dots */
+ if (!p->showAttributes) {
+ unsigned char buf[brl.x*brl.y];
+ readScreen(p->winx, p->winy, winlen, brl.y, buf, SCR_DOTS);
+ int i;
+ if (winlen < brl.x) {
+ for (i=brl.y-1; i>0; i--)
+ memmove(buf+i*brl.x, buf+i*winlen, winlen);
+ for (i=0; i<brl.y; i++)
+ memset(buf+i*brl.x+winlen, 0, brl.x-winlen);
+ }
+ for (i=0; i<brl.x*brl.y; i++)
+ if (buf[i]) brl.buffer[i] = buf[i];
+ }
}
if (brl.cursor >= 0) {
--- Programs/scr.c (r?vision 3469)
+++ Programs/scr.c (copie de travail)
@@ -205,6 +205,8 @@
memset(buffer, ' ', count);
if (length) memcpy(buffer, message+box->left, length);
+ } else if (property == SCR_DOTS) {
+ memset(buffer, 0X00, count);
} else {
memset(buffer, 0X07, count);
}
--- Programs/scr.h (r?vision 3469)
+++ Programs/scr.h (copie de travail)
@@ -27,7 +27,8 @@
/* mode argument for readScreen() */
typedef enum {
SCR_TEXT, /* get screen text */
- SCR_ATTRIB /* get screen attributes */
+ SCR_ATTRIB, /* get screen attributes */
+ SCR_DOTS /* get dots, if any */
} ScreenCharacterProperty;
typedef struct {
--- ScreenDrivers/Linux/screen.c (r?vision 3469)
+++ ScreenDrivers/Linux/screen.c (copie de travail)
@@ -581,6 +581,37 @@
* the expected character set.
*/
static unsigned char translationTable[0X200];
+static unsigned char dotsTranslationTable[0X200];
+
+static int findPosition(unsigned short unicode) {
+ unsigned short directPosition = 0XFF;
+ int position = -1;
+
+ if (vgaLargeTable) directPosition |= 0X100;
+
+ if (!screenFontMapCount) {
+ if (unicode < 0X100) position = unicode;
+ } else if ((unicode & ~directPosition) == 0XF000) {
+ position = unicode & directPosition;
+ } else {
+ int first = 0;
+ int last = screenFontMapCount-1;
+ while (first <= last) {
+ int current = (first + last) / 2;
+ struct unipair *map = &screenFontMapTable[current];
+ if (map->unicode < unicode)
+ first = current + 1;
+ else if (map->unicode > unicode)
+ last = current - 1;
+ else {
+ if (map->fontpos < vgaCharacterCount) position = map->fontpos;
+ break;
+ }
+ }
+ }
+ return position;
+}
+
static int
setTranslationTable (int force) {
int acmChanged = setApplicationCharacterMap && setApplicationCharacterMap(force);
@@ -590,35 +621,13 @@
if (vccChanged || force) determineAttributesMasks();
if (acmChanged || sfmChanged || vccChanged) {
- unsigned short directPosition = 0XFF;
- if (vgaLargeTable) directPosition |= 0X100;
-
memset(translationTable, '?', sizeof(translationTable));
+ memset(dotsTranslationTable, 0, sizeof(dotsTranslationTable));
{
int character;
for (character=0XFF; character>=0; --character) {
unsigned short unicode = applicationCharacterMap[character];
- int position = -1;
- if (!screenFontMapCount) {
- if (unicode < 0X100) position = unicode;
- } else if ((unicode & ~directPosition) == 0XF000) {
- position = unicode & directPosition;
- } else {
- int first = 0;
- int last = screenFontMapCount-1;
- while (first <= last) {
- int current = (first + last) / 2;
- struct unipair *map = &screenFontMapTable[current];
- if (map->unicode < unicode)
- first = current + 1;
- else if (map->unicode > unicode)
- last = current - 1;
- else {
- if (map->fontpos < vgaCharacterCount) position = map->fontpos;
- break;
- }
- }
- }
+ int position = findPosition(unicode);
if (position < 0) {
if (debugCharacterTranslationTable) {
LogPrint(LOG_DEBUG, "no character mapping: char=%2.2X unum=%4.4X", character, unicode);
@@ -632,6 +641,25 @@
}
}
}
+ {
+ int dots;
+ for (dots=0XFF; dots>=0; --dots) {
+ unsigned short unicode = BRL_UC_ROW|dots;
+ int position = findPosition(unicode);
+ if (position < 0) {
+ if (debugCharacterTranslationTable) {
+ LogPrint(LOG_DEBUG, "no dots mapping: dots=%2.2X unum=%4.4X", dots, unicode);
+ }
+ } else {
+ dotsTranslationTable[position] = dots;
+ translationTable[position] = ' ';
+ if (debugCharacterTranslationTable) {
+ LogPrint(LOG_DEBUG, "dots mapping: dots=%2.2X unum=%4.4X fpos=%2.2X",
+ dots, unicode, position);
+ }
+ }
+ }
+ }
if (debugCharacterTranslationTable) {
const unsigned int count = 0X10;
int position;
@@ -640,6 +668,11 @@
sprintf(description, "c2f[%02X]", position);
LogBytes(LOG_DEBUG, description, &translationTable[position], count);
}
+ for (position=0; position<vgaCharacterCount; position+=count) {
+ char description[0X20];
+ sprintf(description, "c2f[%02X]", position);
+ LogBytes(LOG_DEBUG, description, &dotsTranslationTable[position], count);
+ }
}
return 1;
}
@@ -907,8 +940,6 @@
ScreenDescription description;
describe_LinuxScreen(&description);
if (validateScreenBox(&box, description.cols, description.rows)) {
- int text = property == SCR_TEXT;
-
if (problemText) {
setScreenMessage(&box, buffer, property, problemText);
return 1;
@@ -945,7 +976,7 @@
}
source = line;
- if (text) {
+ if (property == SCR_TEXT) {
unsigned char src[box.width];
const unsigned char *trg = target;
int column;
@@ -964,6 +995,25 @@
memcpy(desc, "char", 4);
LogBytes(LOG_DEBUG, desc, trg, box.width);
}
+ } else if (property == SCR_DOTS) {
+ unsigned char src[box.width];
+ const unsigned char *trg = target;
+ int column;
+ for (column=0; column<box.width; ++column) {
+ const unsigned char byte = *source & 0XFF;
+ int position = byte;
+ if (*source & fontAttributesMask) position |= 0X100;
+ src[column] = byte;
+ *target++ = dotsTranslationTable[position];
+ source++;
+ }
+ if (debugScreenTextTranslation) {
+ char desc[0X20];
+ sprintf(desc, "fpos[%03d,%03d]", box.left, box.top+row);
+ LogBytes(LOG_DEBUG, desc, src, box.width);
+ memcpy(desc, "dots", 4);
+ LogBytes(LOG_DEBUG, desc, trg, box.width);
+ }
} else {
int column;
for (column=0; column<box.width; ++column) {
--- ScreenDrivers/PcBios/screen.c (r?vision 3469)
+++ ScreenDrivers/PcBios/screen.c (copie de travail)
@@ -59,6 +59,10 @@
unsigned offset = ScreenPrimary;
ScreenDescription description;
describe_PcBiosScreen(&description);
+ if (property == SCR_DOTS) {
+ memset(buffer, 0, box.width * box.height);
+ return 1;
+ }
if (validateScreenBox(&box, description.cols, description.rows)) {
int row, col;
_farsetsel(_go32_conventional_mem_selector());
--- ScreenDrivers/Screen/screen.c (r?vision 3469)
+++ ScreenDrivers/Screen/screen.c (copie de travail)
@@ -176,6 +176,10 @@
read_ScreenScreen (ScreenBox box, unsigned char *buffer, ScreenCharacterProperty property) {
ScreenDescription description; /* screen statistics */
describe_ScreenScreen(&description);
+ if (property == SCR_DOTS) {
+ memset(buffer, 0, box.width * box.height);
+ return 1;
+ }
if (validateScreenBox(&box, description.cols, description.rows)) {
off_t start = 4 + (((property == SCR_TEXT)? 0: 1) * description.cols * description.rows) + (box.top * description.cols) + box.left;
int row;
--- ScreenDrivers/AtSpi/screen.c (r?vision 3469)
+++ ScreenDrivers/AtSpi/screen.c (copie de travail)
@@ -608,7 +608,10 @@
memset(buffer,0x07,box.height*box.width);
return 1;
}
- memset(buffer,' ',box.height*box.width);
+ if (property == SCR_TEXT)
+ memset(buffer,' ',box.height*box.width);
+ else
+ memset(buffer,0,box.height*box.width);
pthread_mutex_lock(&updateMutex);
if (!curTerm) {
setScreenMessage(&box, buffer, property, nonatspi);
@@ -621,8 +624,15 @@
if (curRowLengths[box.top+y])
for (x=0; x<box.width; x++) {
if (box.left+x<curRowLengths[box.top+y] - (curRows[box.top+y][curRowLengths[box.top+y]-1]=='\n')) {
- if ((c = convertWcharToChar(curRows[box.top+y][box.left+x])) == EOF)
- c = '?';
+ if (property == SCR_TEXT) {
+ if ((c = convertWcharToChar(curRows[box.top+y][box.left+x])) == EOF)
+ c = '?';
+ } else {
+ if (((curRows[box.top+y][box.left+x]) & ~0xFF) == BRL_UC_ROW)
+ c = curRows[box.top+y][box.left+x] & 0xFF;
+ else
+ c = 0;
+ }
buffer[y*box.width+x] = c;
}
}
--- ScreenDrivers/Hurd/screen.c (r?vision 3469)
+++ ScreenDrivers/Hurd/screen.c (copie de travail)
@@ -214,13 +214,21 @@
}
if (validateScreenBox(&box, description.cols, description.rows)) {
uint32_t lines, start, row, col;
- const int which = property == SCR_TEXT ? offsetof(conchar_t,chr):offsetof(conchar_t,attr);
+ const int which = property != SCR_ATTRIB ? offsetof(conchar_t,chr):offsetof(conchar_t,attr);
lines = screenMap->screen.lines;
start = screenMap->screen.cur_line;
for (row=start+box.top; row<start+box.top+box.height; ++row)
for (col=box.left; col<box.left+box.width; ++col) {
- if ((c = convertWcharToChar(*(uint32_t *)(((unsigned char *) &screenDisplay[(row%lines)*description.cols+col])+which))) == EOF)
- c = '?';
+ if (property == SCR_DOTS) {
+ uint32_t wc = *(uint32_t *)(((unsigned char *) &screenDisplay[(row%lines)*description.cols+col])+which);
+ if ((wc & ~0xFF) == BRL_UC_ROW)
+ c = wc & 0xFF;
+ else
+ c = 0;
+ } else {
+ if ((c = convertWcharToChar(*(uint32_t *)(((unsigned char *) &screenDisplay[(row%lines)*description.cols+col])+which))) == EOF)
+ c = '?';
+ }
*buffer++ = c;
}
return 1;
--- ScreenDrivers/Windows/screen.c (r?vision 3469)
+++ ScreenDrivers/Windows/screen.c (copie de travail)
@@ -193,7 +193,7 @@
static int
read_WindowsScreen (ScreenBox box, unsigned char *buffer, ScreenCharacterProperty property) {
/* TODO: GetConsoleCP */
- int text = property == SCR_TEXT;
+ int text = property != SCR_ATTRIB;
int x, y;
static int wide;
COORD coord;
@@ -269,7 +269,14 @@
if (wide > 0) {
for (x=0; x<box.width; x++) {
wchar_t c = ((wchar_t *)buf)[x];
- if (c >= 0X100) c = '?';
+ if (property == SCR_DOTS) {
+ if ((c & ~0xFF) == BRL_UC_ROW)
+ c &= 0xFF;
+ else
+ c = 0;
+ } else {
+ if (c >= 0X100) c = '?';
+ }
buffer[y*box.width+x] = c;
}
} else {
More information about the BRLTTY
mailing list