[BRLTTY] Working with braille characters in console mode?

Samuel Thibault samuel.thibault at ens-lyon.org
Mon Jan 21 11:56:06 EST 2008


Mario Lang, le Mon 21 Jan 2008 17:49:45 +0100, a écrit :
> Reversed (or previously applied) patch detected!  Assume -R? [n]

Grmbl, it looks like I somehow sent the same patch. Here is hopefully
the correct one.

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);
     }
Index: Programs/scr_base.c
--- 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);
   }
Index: Programs/scr_frozen.c
--- 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),
Index: Programs/brltty.c
--- 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) {
Index: Programs/scr.c
--- 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);
   }
Index: Programs/scr.h
--- 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 {
Index: ScreenDrivers/Linux/screen.c
--- 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,24 @@
          }
        }
     }
+    {
+       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;
+           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 +667,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 +939,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 +975,7 @@
           }
 
           source = line;
-          if (text) {
+          if (property == SCR_TEXT) {
             unsigned char src[box.width];
             const unsigned char *trg = target;
             int column;
@@ -964,6 +994,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) {
Index: ScreenDrivers/PcBios/screen.c
--- 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());
Index: ScreenDrivers/Screen/screen.c
--- 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;
Index: ScreenDrivers/AtSpi/screen.c
--- 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;
Index: ScreenDrivers/Windows/screen.c
--- 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