fenrir/src/fenrir/screenDriver/vcsaDriver.py

170 lines
9.0 KiB
Python
Raw Normal View History

2016-09-14 18:04:52 -04:00
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
2016-09-14 18:04:52 -04:00
import difflib
2016-11-01 17:03:38 -04:00
import re
import subprocess
2016-12-15 04:31:03 -05:00
import fcntl
import termios
import time
from core import debug
from utils import screen_utils
2016-09-14 18:04:52 -04:00
class driver():
def __init__(self):
self.vcsaDevicePath = '/dev/vcsa'
def initialize(self, environment):
self.env = environment
def shutdown(self):
pass
2016-09-14 18:04:52 -04:00
def getCurrScreen(self):
self.env['screenData']['oldTTY'] = self.env['screenData']['newTTY']
2016-09-14 18:04:52 -04:00
try:
currScreenFile = open('/sys/devices/virtual/tty/tty0/active','r')
self.env['screenData']['newTTY'] = str(currScreenFile.read()[3:-1])
2016-09-14 18:04:52 -04:00
currScreenFile.close()
except Exception as e:
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
2016-12-15 04:36:10 -05:00
def injectTextToScreen(self, text, screen = None):
useScreen = "/dev/tty" + self.env['screenData']['newTTY']
if screen != None:
useScreen = screen
with open(useScreen, 'w') as fd:
2016-12-15 04:31:03 -05:00
for c in text:
fcntl.ioctl(fd, termios.TIOCSTI, c)
2016-09-27 17:17:46 -04:00
def getCurrApplication(self):
2016-09-20 12:00:22 -04:00
apps = []
try:
currScreen = self.env['screenData']['newTTY']
2016-09-23 05:25:19 -04:00
apps = subprocess.Popen('ps -t tty' + currScreen + ' -o comm,tty,stat', shell=True, stdout=subprocess.PIPE).stdout.read().decode()[:-1].split('\n')
2016-09-20 12:00:22 -04:00
except Exception as e:
2016-10-22 06:55:21 -04:00
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
return
2016-09-23 05:15:42 -04:00
try:
for i in apps:
i = i.upper()
i = i.split()
i[0] = i[0]
i[1] = i[1]
if '+' in i[2]:
if i[0] != '':
if not "GREP" == i[0] and \
not "SH" == i[0] and \
not "PS" == i[0]:
if "TTY"+currScreen in i[1]:
if self.env['screenData']['newApplication'] != i[0]:
2016-10-02 18:29:24 -04:00
self.env['screenData']['newApplication'] = i[0]
return
except Exception as e:
2016-10-22 06:58:34 -04:00
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
return
2016-09-20 12:00:22 -04:00
2016-09-14 18:04:52 -04:00
def getIgnoreScreens(self):
xlist = []
try:
2016-09-20 04:32:32 -04:00
x = subprocess.Popen('ps a -o tty,comm | grep Xorg', shell=True, stdout=subprocess.PIPE).stdout.read().decode()[:-1].split('\n')
except Exception as e:
2016-09-14 18:04:52 -04:00
return xlist
for i in x:
2016-09-20 05:11:04 -04:00
if not "grep" in i and \
2016-09-20 12:00:22 -04:00
not "ps" in i:
2016-09-20 04:32:32 -04:00
if (i[:3].lower() == 'tty'):
xlist.append(i[3])
2016-09-20 05:11:04 -04:00
return xlist
2016-09-20 12:00:22 -04:00
def update(self, trigger='onUpdate'):
2016-09-14 18:04:52 -04:00
newContentBytes = b''
try:
# read screen
vcsa = open(self.vcsaDevicePath + self.env['screenData']['newTTY'],'rb',0)
2016-09-14 18:04:52 -04:00
newContentBytes = vcsa.read()
vcsa.close()
if len(newContentBytes) < 5:
return
2016-09-14 18:04:52 -04:00
except Exception as e:
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
return
screenEncoding = self.env['runtime']['settingsManager'].getSetting('screen', 'encoding')
2016-09-14 18:04:52 -04:00
# set new "old" values
self.env['screenData']['oldContentBytes'] = self.env['screenData']['newContentBytes']
self.env['screenData']['oldContentText'] = self.env['screenData']['newContentText']
2016-10-29 19:16:07 -04:00
self.env['screenData']['oldContentAttrib'] = self.env['screenData']['newContentAttrib']
self.env['screenData']['oldCursor'] = self.env['screenData']['newCursor'].copy()
2016-11-04 19:11:54 -04:00
if self.env['screenData']['newCursorAttrib']:
self.env['screenData']['oldCursorAttrib'] = self.env['screenData']['newCursorAttrib'].copy()
self.env['screenData']['oldDelta'] = self.env['screenData']['newDelta']
self.env['screenData']['oldAttribDelta'] = self.env['screenData']['newAttribDelta']
self.env['screenData']['oldNegativeDelta'] = self.env['screenData']['newNegativeDelta']
self.env['screenData']['newContentBytes'] = newContentBytes
2016-09-14 18:04:52 -04:00
# get metadata like cursor or screensize
self.env['screenData']['lines'] = int( self.env['screenData']['newContentBytes'][0])
self.env['screenData']['columns'] = int( self.env['screenData']['newContentBytes'][1])
self.env['screenData']['newCursor']['x'] = int( self.env['screenData']['newContentBytes'][2])
self.env['screenData']['newCursor']['y'] = int( self.env['screenData']['newContentBytes'][3])
2016-09-14 18:04:52 -04:00
# analyze content
self.env['screenData']['newContentText'] = self.env['screenData']['newContentBytes'][4:][::2].decode(screenEncoding, "replace").encode('utf-8').decode('utf-8')
2016-11-04 16:25:54 -04:00
self.env['screenData']['newContentText'] = screen_utils.removeNonprintable(self.env['screenData']['newContentText'])
self.env['screenData']['newContentAttrib'] = self.env['screenData']['newContentBytes'][5:][::2]
2016-10-29 19:16:07 -04:00
self.env['screenData']['newContentText'] = screen_utils.insertNewlines(self.env['screenData']['newContentText'], self.env['screenData']['columns'])
2016-09-14 18:04:52 -04:00
if self.env['screenData']['newTTY'] != self.env['screenData']['oldTTY']:
self.env['screenData']['oldContentBytes'] = b''
self.env['screenData']['oldContentAttrib'] = b''
self.env['screenData']['oldContentText'] = ''
self.env['screenData']['oldCursor']['x'] = 0
self.env['screenData']['oldCursor']['y'] = 0
self.env['screenData']['oldDelta'] = ''
self.env['screenData']['oldAttribDelta'] = ''
self.env['screenData']['oldCursorAttrib'] = None
2016-11-04 19:11:54 -04:00
self.env['screenData']['newCursorAttrib'] = None
self.env['screenData']['oldNegativeDelta'] = ''
# initialize current deltas
self.env['screenData']['newNegativeDelta'] = ''
self.env['screenData']['newDelta'] = ''
self.env['screenData']['newAttribDelta'] = ''
2016-10-29 18:27:07 -04:00
2016-09-14 18:04:52 -04:00
# changes on the screen
oldScreenText = re.sub(' +',' ',self.env['runtime']['screenManager'].getWindowAreaInText(self.env['screenData']['oldContentText']))
newScreenText = re.sub(' +',' ',self.env['runtime']['screenManager'].getWindowAreaInText(self.env['screenData']['newContentText']))
2016-10-18 09:17:20 -04:00
typing = False
if (self.env['screenData']['oldContentText'] != self.env['screenData']['newContentText']) and \
(self.env['screenData']['newContentText'] != '' ):
if oldScreenText == '' and\
2016-09-24 17:42:16 -04:00
newScreenText != '':
self.env['screenData']['newDelta'] = newScreenText
2016-09-14 18:04:52 -04:00
else:
cursorLineStart = self.env['screenData']['newCursor']['y'] * self.env['screenData']['columns'] + self.env['screenData']['newCursor']['y']
2016-09-30 21:55:30 -04:00
cursorLineEnd = cursorLineStart + self.env['screenData']['columns']
if self.env['screenData']['oldCursor']['x'] != self.env['screenData']['newCursor']['x'] and \
self.env['screenData']['oldCursor']['y'] == self.env['screenData']['newCursor']['y'] and \
self.env['screenData']['newContentText'][:cursorLineStart] == self.env['screenData']['oldContentText'][:cursorLineStart]:
oldScreenText = self.env['screenData']['oldContentText'][cursorLineStart:cursorLineEnd]
oldScreenText = re.sub(' +',' ',oldScreenText)
newScreenText = self.env['screenData']['newContentText'][cursorLineStart:cursorLineEnd]
newScreenText = re.sub(' +',' ',newScreenText)
2016-10-18 09:17:20 -04:00
diff = difflib.ndiff(oldScreenText, newScreenText)
typing = True
2016-09-14 18:04:52 -04:00
else:
2016-09-30 17:35:12 -04:00
diff = difflib.ndiff( oldScreenText.split('\n'),\
newScreenText.split('\n'))
2016-09-14 18:04:52 -04:00
diffList = list(diff)
2016-10-18 09:17:20 -04:00
if self.env['runtime']['settingsManager'].getSetting('general', 'newLinePause') and not typing:
self.env['screenData']['newDelta'] = '\n'.join(x[2:] for x in diffList if x[0] == '+')
else:
self.env['screenData']['newDelta'] = ''.join(x[2:] for x in diffList if x[0] == '+')
2016-10-03 13:25:59 -04:00
self.env['screenData']['newNegativeDelta'] = ''.join(x[2:] for x in diffList if x[0] == '-')
2016-10-29 18:27:07 -04:00
# track highlighted
if self.env['screenData']['oldContentAttrib'] != self.env['screenData']['newContentAttrib']:
2016-11-04 19:11:54 -04:00
if self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'highlight'):
self.env['screenData']['newAttribDelta'], self.env['screenData']['newCursorAttrib'] = screen_utils.trackHighlights(self.env['screenData']['oldContentAttrib'], self.env['screenData']['newContentAttrib'], self.env['screenData']['newContentText'], self.env['screenData']['columns'])
2016-10-18 09:17:20 -04:00