From 06e80017a999807eee38abe2bbf05e296fe48abc Mon Sep 17 00:00:00 2001 From: chrys Date: Tue, 18 Jul 2017 00:58:54 +0200 Subject: [PATCH] add initial autoEncodeing --- config/settings/espeak.settings.conf | 2 +- config/settings/settings.conf | 2 +- config/settings/settings.conf.storm | 2 +- play zone/charmapTTY.py | 24 ++-- src/fenrir/screenDriver/vcsaDriver.py | 158 +++++++++++++------------- 5 files changed, 98 insertions(+), 90 deletions(-) diff --git a/config/settings/espeak.settings.conf b/config/settings/espeak.settings.conf index 923ad0ea..3c7800e3 100644 --- a/config/settings/espeak.settings.conf +++ b/config/settings/espeak.settings.conf @@ -117,7 +117,7 @@ panSizeHorizontal=0 [screen] driver=vcsaDriver -encoding=UTF-8 +encoding=auto screenUpdateDelay=0.05 suspendingScreen= autodetectSuspendingScreen=True diff --git a/config/settings/settings.conf b/config/settings/settings.conf index c9565d06..f8d78ce7 100644 --- a/config/settings/settings.conf +++ b/config/settings/settings.conf @@ -119,7 +119,7 @@ panSizeHorizontal=0 [screen] driver=vcsaDriver -encoding=cp850 +encoding=auto screenUpdateDelay=0.05 suspendingScreen= autodetectSuspendingScreen=True diff --git a/config/settings/settings.conf.storm b/config/settings/settings.conf.storm index eab9ebed..db5ce8f6 100644 --- a/config/settings/settings.conf.storm +++ b/config/settings/settings.conf.storm @@ -76,7 +76,7 @@ panSizeHorizontal=0 [screen] driver=vcsaDriver -encoding=cp850 +encoding=auto screenUpdateDelay=0.05 suspendingScreen= autodetectSuspendingScreen=True diff --git a/play zone/charmapTTY.py b/play zone/charmapTTY.py index ab2b5295..981331f7 100755 --- a/play zone/charmapTTY.py +++ b/play zone/charmapTTY.py @@ -1,7 +1,9 @@ import time from fcntl import ioctl from array import array -import struct +from struct import unpack_from +from struct import unpack +from struct import pack import errno import sys charmap = {} @@ -14,13 +16,13 @@ def updateCharMap(screen): VT_GETHIFONTMASK = 0x560D himask = array("H", (0,)) ioctl(tty, VT_GETHIFONTMASK, himask) - hichar, = struct.unpack_from("@H", himask) + hichar, = unpack_from("@H", himask) sz = 512 line = '' while True: try: unipairs = array("H", [0]*(2*sz)) - unimapdesc = array("B", struct.pack("@HP", sz, unipairs.buffer_info()[0])) + unimapdesc = array("B", pack("@HP", sz, unipairs.buffer_info()[0])) ioctl(tty.fileno(), GIO_UNIMAP, unimapdesc) break except IOError as e: @@ -28,8 +30,8 @@ def updateCharMap(screen): raise sz *= 2 tty.close() - ncodes, = struct.unpack_from("@H", unimapdesc) - utable = struct.unpack_from("@%dH" % (2*ncodes), unipairs) + ncodes, = unpack_from("@H", unimapdesc) + utable = unpack_from("@%dH" % (2*ncodes), unipairs) for u, b in zip(utable[::2], utable[1::2]): if charmap.get(b) is None: charmap[b] = chr(u) @@ -53,7 +55,7 @@ def autoDecodeVCSA(allData, rows, cols): lineAttrib.append(7) lineText += ' ' continue - (sh,) = struct.unpack("=H", data) + (sh,) = unpack("=H", data) attr = (sh >> 8) & 0xFF ch = sh & 0xFF if hichar == 0x100: @@ -63,8 +65,8 @@ def autoDecodeVCSA(allData, rows, cols): paper = (attr>>4) & 0x0F #if (ink != 7) or (paper != 0): # print(ink,paper) - #if sh & hichar: - # ch |= 0x100 + if sh & hichar: + ch |= 0x100 try: lineText += charmap[ch] except: @@ -73,11 +75,11 @@ def autoDecodeVCSA(allData, rows, cols): allAttrib.append(lineAttrib) return allText, allAttrib -def m(): +def m(screen): s = time.time() - updateCharMap('4') + updateCharMap(str(screen)) print(time.time() -s ) - vcsa = open('/dev/vcsa' + '4', 'rb') + vcsa = open('/dev/vcsa' + str(screen), 'rb') head = vcsa.read(4) rows = int(head[0]) cols = int(head[1]) diff --git a/src/fenrir/screenDriver/vcsaDriver.py b/src/fenrir/screenDriver/vcsaDriver.py index 67d633cf..c6473d1b 100644 --- a/src/fenrir/screenDriver/vcsaDriver.py +++ b/src/fenrir/screenDriver/vcsaDriver.py @@ -15,91 +15,27 @@ import difflib import re import subprocess import glob, os -import fcntl import termios import time import select import dbus import fcntl from array import array -import struct import errno import sys +from utils import screen_utils +from fcntl import ioctl +from struct import unpack_from, unpack, pack from core import debug from core.eventData import fenrirEventType -from utils import screen_utils -''' -ttyno = 4 -tty = open('/dev/tty%d' % ttyno, 'rb') -vcs = open('/dev/vcsa%d' % ttyno, 'rb') - -head = vcs.read(4) -rows = int(head[0]) -cols = int(head[1]) - - -GIO_UNIMAP = 0x4B66 -VT_GETHIFONTMASK = 0x560D -himask = array("H", (0,)) -fcntl.ioctl(tty, VT_GETHIFONTMASK, himask) -hichar, = struct.unpack_from("@H", himask) - -sz = 512 -line = '' -while True: - try: - unipairs = array("H", [0]*(2*sz)) - unimapdesc = array("B", struct.pack("@HP", sz, unipairs.buffer_info()[0])) - fcntl.ioctl(tty.fileno(), GIO_UNIMAP, unimapdesc) - break - except IOError as e: - if e.errno != errno.ENOMEM: - raise - sz *= 2 - -tty.close() - -ncodes, = struct.unpack_from("@H", unimapdesc) -utable = struct.unpack_from("@%dH" % (2*ncodes), unipairs) - -charmap = {} -for u, b in zip(utable[::2], utable[1::2]): - if charmap.get(b) is None: - charmap[b] = u - -allText = [] -allAttrib = [] -for y in range(rows): - lineText = '' - lineAttrib = [] - for x in range(cols): - data = vcs.read(2) - (sh,) = struct.unpack("=H", data) - attr = (sh >> 8) & 0xFF - ch = sh & 0xFF - if hichar == 0x100: - attr >>= 1 - lineAttrib.append(attr) - ink = attr & 0x0F - paper = (attr>>4) & 0x0F - if (ink != 7) or (paper != 0): - print(ink,paper) - if sh & hichar: - ch |= 0x100 - lineText += chr(charmap.get(ch, u'?')) - allText.append(lineText) - allAttrib.append(lineAttrib) - -print(allText) -print(allAttrib) -''' - class driver(): def __init__(self): self.vcsaDevicePath = '/dev/vcsa' self.ListSessions = None + self.charmap = {} + self.hichar = None def initialize(self, environment): self.env = environment self.env['runtime']['eventManager'].addCustomEventThread(self.updateWatchdog) @@ -227,11 +163,74 @@ class driver(): lastScreenContent = screenContent except Exception as e: self.env['runtime']['debug'].writeDebugOut('VCSA:updateWatchdog:' + str(e),debug.debugLevel.ERROR) - + + def updateCharMap(self, screen): + tty = open('/dev/tty' + screen, 'rb') + GIO_UNIMAP = 0x4B66 + VT_GETHIFONTMASK = 0x560D + himask = array("H", (0,)) + ioctl(tty, VT_GETHIFONTMASK, himask) + self.hichar, = unpack_from("@H", himask) + sz = 512 + line = '' + while True: + try: + unipairs = array("H", [0]*(2*sz)) + unimapdesc = array("B", pack("@HP", sz, unipairs.buffer_info()[0])) + ioctl(tty.fileno(), GIO_UNIMAP, unimapdesc) + break + except IOError as e: + if e.errno != errno.ENOMEM: + raise + sz *= 2 + tty.close() + ncodes, = unpack_from("@H", unimapdesc) + utable = unpack_from("@%dH" % (2*ncodes), unipairs) + for u, b in zip(utable[::2], utable[1::2]): + if self.charmap.get(b) is None: + self.charmap[b] = chr(u) + + def autoDecodeVCSA(self, allData, rows, cols): + allText = '' + allAttrib = b'' + i = 0 + for y in range(rows): + lineText = '' + lineAttrib = b'' + for x in range(cols): + data = allData[i: i + 2] + i += 2 + if data == b' \x07': + #attr = 7 + #ink = 7 + #paper = 0 + #ch = ' ' + lineAttrib += b'7' + lineText += ' ' + continue + (sh,) = unpack("=H", data) + attr = (sh >> 8) & 0xFF + ch = sh & 0xFF + if self.hichar == 0x100: + attr >>= 1 + lineAttrib += bytes(attr) + ink = attr & 0x0F + paper = (attr>>4) & 0x0F + #if (ink != 7) or (paper != 0): + # print(ink,paper) + if sh & self.hichar: + ch |= 0x100 + try: + lineText += self.charmap[ch] + except: + lineText += chr('?') + allText += lineText + '\n' + allAttrib += lineAttrib + return str(allText), allAttrib + def update(self, trigger='onUpdate'): if trigger == 'onInput': # no need for an update on input for VCSA return - #print(self.env['screen']['newTTY'], self.env['screen']['oldTTY']) newContentBytes = b'' try: # read screen @@ -261,11 +260,18 @@ class driver(): self.env['screen']['newCursor']['x'] = int( self.env['screen']['newContentBytes'][2]) self.env['screen']['newCursor']['y'] = int( self.env['screen']['newContentBytes'][3]) # analyze content - self.env['screen']['newContentText'] = self.env['screen']['newContentBytes'][4:][::2].decode(screenEncoding, "replace").encode('utf-8').decode('utf-8') - self.env['screen']['newContentText'] = screen_utils.removeNonprintable(self.env['screen']['newContentText']) - self.env['screen']['newContentAttrib'] = self.env['screen']['newContentBytes'][5:][::2] - self.env['screen']['newContentText'] = screen_utils.insertNewlines(self.env['screen']['newContentText'], self.env['screen']['columns']) - + s = time.time() + if screenEncoding.upper() == 'AUTO': + self.updateCharMap(str(self.env['screen']['newTTY'])) + self.env['screen']['newContentText'], \ + self.env['screen']['newContentAttrib'] =\ + self.autoDecodeVCSA(self.env['screen']['newContentBytes'][4:], self.env['screen']['lines'], self.env['screen']['columns']) + else: + self.env['screen']['newContentText'] = self.env['screen']['newContentBytes'][4:][::2].decode(screenEncoding, "replace").encode('utf-8').decode('utf-8') + self.env['screen']['newContentText'] = screen_utils.removeNonprintable(self.env['screen']['newContentText']) + self.env['screen']['newContentAttrib'] = self.env['screen']['newContentBytes'][5:][::2] + self.env['screen']['newContentText'] = screen_utils.insertNewlines(self.env['screen']['newContentText'], self.env['screen']['columns']) + print(time.time() -s, self.env['screen']['newTTY'] ) if self.env['screen']['newTTY'] != self.env['screen']['oldTTY']: self.env['screen']['oldContentBytes'] = b'' self.env['screen']['oldContentAttrib'] = b''