fix some bad stuff
This commit is contained in:
parent
bc8bba12cc
commit
453869e9af
265
Changelog.txt
Normal file
265
Changelog.txt
Normal file
@ -0,0 +1,265 @@
|
|||||||
|
# Version 1.5
|
||||||
|
- Doku: Write a user wiki
|
||||||
|
https://wiki.linux-a11y.org/doku.php?id=fenrir_user_manual&s[]=fenrir
|
||||||
|
|
||||||
|
- initial working setup.py
|
||||||
|
|
||||||
|
- available via pip (python packet manager)
|
||||||
|
sudo pip3 install fenrir-screenreader
|
||||||
|
https://pypi.python.org/pypi/fenrir-screenreader/1.5.post5
|
||||||
|
|
||||||
|
- leave review on typing
|
||||||
|
|
||||||
|
- add dependency check (check-dependencys.py)
|
||||||
|
|
||||||
|
- Add nice dummy drivers as template or for debugging
|
||||||
|
|
||||||
|
- reimplement detection code for X11
|
||||||
|
|
||||||
|
- initial translate structure (manuelcortez Thanks!)
|
||||||
|
|
||||||
|
- add a configurable place where you can place own commands or overwrite existing commands without need to change default code
|
||||||
|
|
||||||
|
- implement autodetection of plugged and unplugged input devices
|
||||||
|
|
||||||
|
- implement speechdriver generic
|
||||||
|
|
||||||
|
- try to autodetect encoding (Easy for contribution) (Prototype "charmapTTY" in play zone)
|
||||||
|
|
||||||
|
Braille Support (WIP):
|
||||||
|
- initial BrlTTY driver
|
||||||
|
- detect device size via driver
|
||||||
|
- output to braille device
|
||||||
|
- make flushMode configurable
|
||||||
|
- make flushTimeout configurable
|
||||||
|
- flush message after X seconds and show current line (review over text)
|
||||||
|
- tweak current commands and output
|
||||||
|
- command flush_braille
|
||||||
|
- command for scroll left
|
||||||
|
- command for scroll right
|
||||||
|
- create offset for scrolling
|
||||||
|
- respect scrolling
|
||||||
|
make cursor following configurable (brailleCursorTrackingMode)
|
||||||
|
- cell
|
||||||
|
- page
|
||||||
|
follow cursor while typing
|
||||||
|
brailleFocusMode:
|
||||||
|
- review = priority to review
|
||||||
|
|
||||||
|
- move to an event based system
|
||||||
|
|
||||||
|
- add initial multithreading/ multiprocessing support
|
||||||
|
|
||||||
|
- support cli parameters
|
||||||
|
- add cli parameter for debugging "-d"
|
||||||
|
- add cli parameter to overwrite options "-o"
|
||||||
|
- add cli parameter to specify an settings.conf "-s"
|
||||||
|
|
||||||
|
- list of bound commands in Tutorial Mode. speak name, binding and description.
|
||||||
|
|
||||||
|
# Version: 1.00
|
||||||
|
|
||||||
|
- move from VCS to VCSA and parese the Attributes
|
||||||
|
http://linux.die.net/man/4/vcsa
|
||||||
|
http://man.cx/vcsa(4)/de
|
||||||
|
http://manpages.org/display-vcsa/7
|
||||||
|
https://en.wikipedia.org/wiki/Virtual_console
|
||||||
|
every second byte is a attribute others are text. fast way: c[::2],c[1::2]
|
||||||
|
http://manpages.ubuntu.com/manpages/precise/de/man4/vcs.4.html
|
||||||
|
https://docs.python.org/3/library/fcntl.html
|
||||||
|
http://rodrigorivas.serveblog.net/en/imagenes-desde-vt-con-vcsa/
|
||||||
|
good doku:
|
||||||
|
http://angband.oook.cz/d/eyangband-052/src/main-vcs.c
|
||||||
|
http://manpages.ubuntu.com/manpages/trusty/man1/screader.1.html
|
||||||
|
|
||||||
|
- implement speechdriver espeak
|
||||||
|
https://github.com/relsi/python-espeak
|
||||||
|
|
||||||
|
- detect collumns in TTYs automaticaly.
|
||||||
|
it seems we have this info in vcsa
|
||||||
|
|
||||||
|
- get current cursor
|
||||||
|
- shortcut handling
|
||||||
|
https://docs.python.org/2/library/termios.html
|
||||||
|
http://stackoverflow.com/questions/287757/pythons-configparser-unique-keys-per-section
|
||||||
|
0=down, 1=press, 2=hold
|
||||||
|
2KEY_SHIFT, 1KEY_A = say_current_line_cursor
|
||||||
|
- implement command structure
|
||||||
|
- implement speechdriver speechd
|
||||||
|
https://git.gnome.org/browse/orca/tree/src/orca/speech.py
|
||||||
|
https://git.gnome.org/browse/orca/tree/src/orca/speechdispatcherfactory.py
|
||||||
|
http://devel.freebsoft.org/doc/speechd/speech-dispatcher.html#Client-Programming
|
||||||
|
|
||||||
|
- autodetect current TTY maybe with (PAM or a sys folder)
|
||||||
|
cat /sys/devices/virtual/tty/tty0/active
|
||||||
|
http://serverfault.com/questions/306854/how-to-find-out-the-currently-active-linux-virtual-terminal-while-connected-via
|
||||||
|
|
||||||
|
- Input
|
||||||
|
http://python-evdev.readthedocs.io/en/latest/tutorial.html
|
||||||
|
http://stackoverflow.com/questions/12384772/how-can-i-capture-mouseevents-and-keyevents-using-python-in-background-on-linux
|
||||||
|
maybe TTY in RAW MODE
|
||||||
|
|
||||||
|
- Settings (make it configureable)
|
||||||
|
- improve differ speed
|
||||||
|
- lock mechanism for threads
|
||||||
|
- restructure loops to listen for events
|
||||||
|
inputloop -> does block with an select
|
||||||
|
commands -> a new thread should spawned from inputloop
|
||||||
|
updatescreen -> maybe we could watch it with inotify vsca should support polling COMMENT: sadly not possible, poll events not fired as expected
|
||||||
|
https://github.com/seb-m/pyinotify/wiki/Tutorial
|
||||||
|
<Example Code>
|
||||||
|
import pyinotify
|
||||||
|
import glob
|
||||||
|
class Identity(pyinotify.ProcessEvent):
|
||||||
|
def process_default(self, event):
|
||||||
|
p = event.pathname
|
||||||
|
print(p)
|
||||||
|
|
||||||
|
wm = pyinotify.WatchManager()
|
||||||
|
|
||||||
|
notifier = pyinotify.Notifier(wm, default_proc_fun=Identity(), timeout=5)
|
||||||
|
wm.add_watch('/sys/devices/virtual/tty/tty0/active', pyinotify.IN_CLOSE_WRITE)
|
||||||
|
for file in list(glob.glob('/dev/vcsa[0-64]')):
|
||||||
|
wm.add_watch(file, pyinotify.IN_CLOSE_WRITE)
|
||||||
|
print(file)
|
||||||
|
|
||||||
|
try:
|
||||||
|
while 1:
|
||||||
|
notifier.process_events()
|
||||||
|
if notifier.check_events( timeout=1000):
|
||||||
|
notifier.read_events()
|
||||||
|
print('events')
|
||||||
|
else:
|
||||||
|
print('timeout')
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
notifier.stop()
|
||||||
|
print('fin')
|
||||||
|
</Example Code>
|
||||||
|
|
||||||
|
https://www.infoq.com/articles/inotify-linux-file-system-event-monitoring
|
||||||
|
https://github.com/seb-m/pyinotify/wiki/Tutorial
|
||||||
|
http://www.saltycrane.com/blog/2010/04/monitoring-filesystem-python-and-pyinotify/
|
||||||
|
|
||||||
|
- add setting for ignore screens ( dont grab shortcuts from X or orca)
|
||||||
|
- soundIcons
|
||||||
|
- performance tuning
|
||||||
|
- add sound volume
|
||||||
|
- convert volume to percent in config
|
||||||
|
- convert pitch to percent in config
|
||||||
|
- convert rate to percent in config
|
||||||
|
- make screenUpdate rate configurable
|
||||||
|
- default soundIcon theme (soundfiles)
|
||||||
|
- debugging
|
||||||
|
- threading ReadContent, ReadShortcuts, executeCommands, listenNewTTYsForListen, controllThread (main)
|
||||||
|
- autoload plugins while starting
|
||||||
|
- implement sounddriver generic (use current sox and make it configurable)
|
||||||
|
- add setting for autodetect X
|
||||||
|
ps a -o tty,comm | grep -e Xorg | grep -v "grep -e Xorg"
|
||||||
|
- respect window mode in differ (getwindow code is already in place)
|
||||||
|
- parse punctuation setting file in conf/substitution
|
||||||
|
|
||||||
|
- implement commands
|
||||||
|
curr_word
|
||||||
|
curr_char
|
||||||
|
next_word
|
||||||
|
next_char
|
||||||
|
prev_word
|
||||||
|
prev_char
|
||||||
|
enable_disable_speech #enable, disable speech
|
||||||
|
enable_disable_braile #enable, disable braile
|
||||||
|
enable_disable_sound #enable, disable sound
|
||||||
|
enable_disable_output #enable, disable speech, braile and sound
|
||||||
|
next_clipboard
|
||||||
|
prev_clipboard
|
||||||
|
first_clipboard
|
||||||
|
last_clipboard
|
||||||
|
curr_clipboard
|
||||||
|
paste_clipboard
|
||||||
|
define_window
|
||||||
|
remove_window
|
||||||
|
reset_review_on_screen_change
|
||||||
|
remove_clipboard_marks
|
||||||
|
copy_marked
|
||||||
|
set_mark (this could also used for area?)
|
||||||
|
read_clipboard_mark_text
|
||||||
|
curr_screen
|
||||||
|
curr_screen_before_cursor
|
||||||
|
curr_screen_after_cursor
|
||||||
|
cursor_position
|
||||||
|
indention
|
||||||
|
add_bookmark (per application)
|
||||||
|
remove_bookmark
|
||||||
|
present_bookmark
|
||||||
|
say_char_phonetic
|
||||||
|
spell_word_phonetic
|
||||||
|
"alpha", "bravo", "charlie", "delta", "echo",
|
||||||
|
"foxtrot", "golf", "hotel", "india", "juliet",
|
||||||
|
"kilo", "lima", "mike", "november", "oscar",
|
||||||
|
"papa", "quebec", "romeo", "sierra", "tango",
|
||||||
|
"uniform", "victor", "whisky", "x ray",
|
||||||
|
"yankee", "zulu"
|
||||||
|
next_char_phonetic
|
||||||
|
prev_char_phonetic
|
||||||
|
next_word_phonetic
|
||||||
|
prev_word_phonetic
|
||||||
|
toggle_highlighted_mode
|
||||||
|
|
||||||
|
- implement onInput commands
|
||||||
|
read_line_if_cursor_change_vertical (needed if you arrow up and down, we want to announce the line)
|
||||||
|
read_char_if_cursur_change_horizontal (needed if you arrow left and right, we want to announce the char under the cursor)
|
||||||
|
echo_char (echos the last char on pressing space or return)
|
||||||
|
echo_word (echos the last word)
|
||||||
|
echo_deleted_char (echos deleted char on screen
|
||||||
|
read highlighted
|
||||||
|
|
||||||
|
- implement onScreenChange commands
|
||||||
|
promoted text
|
||||||
|
clear_marks_on_screen_change
|
||||||
|
leve_review_mode_on_screen_change
|
||||||
|
window mode (define a area and just read that changes)
|
||||||
|
|
||||||
|
- add screenManager
|
||||||
|
abstract screen driver
|
||||||
|
- pass environment instance in init and remove it from function calls
|
||||||
|
|
||||||
|
- New Triggers
|
||||||
|
onAppChange
|
||||||
|
onAppProfileChange
|
||||||
|
onScreenChange
|
||||||
|
rename current onScreenChange to onScreenUpdate
|
||||||
|
|
||||||
|
- rework inputManager
|
||||||
|
try to consume shortcuts
|
||||||
|
grab keyboard exclusive
|
||||||
|
release keyboard on error or quit
|
||||||
|
grab shortcuts with fenrir key
|
||||||
|
grab "singel key shortcuts" like numpad navigation for review
|
||||||
|
forwart nonshortcuts to system
|
||||||
|
make grabbing configuarble
|
||||||
|
possiblity to forewart shortcut [proxyshortcut]
|
||||||
|
possiblity to forewart shortcut (or use them as shortcut) [pressing twice while timeout]
|
||||||
|
cleanup inputManager
|
||||||
|
split input driver out of the handler
|
||||||
|
|
||||||
|
- dictonary for special chars and string replacements
|
||||||
|
- punctuation
|
||||||
|
- beep on cursor to capital letters in cursor and review
|
||||||
|
- add pause handling
|
||||||
|
create pause
|
||||||
|
make it configurable when the pause the pause happens
|
||||||
|
- external scripting
|
||||||
|
load scripts from a folder as subprocess
|
||||||
|
create thread
|
||||||
|
load key definition of keybindings like SOPS did
|
||||||
|
|
||||||
|
- add an daemonize mode
|
||||||
|
https://github.com/thesharp/daemonize
|
||||||
|
https://web.archive.org/web/20131017130434/http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/
|
||||||
|
|
||||||
|
- announce capslock
|
||||||
|
- anounce numlock
|
||||||
|
- anounce scroll
|
||||||
|
- add the debugging to core
|
||||||
|
|
||||||
|
- autostart systemd
|
||||||
|
https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System_Administrators_Guide/sect-Managing_Services_with_systemd-Unit_Files.html
|
85
TODO v2.0
Normal file
85
TODO v2.0
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
ToDo list for Fenrir Version 2.0
|
||||||
|
Things needing little knowledge are marked with "(Easy for contribution)". so just start with those :).
|
||||||
|
[] = ToDo
|
||||||
|
[W] = WIP
|
||||||
|
[X] = Done
|
||||||
|
[S] = Stopped
|
||||||
|
|
||||||
|
Cleanups:
|
||||||
|
[] Migrate *Data.py to classes and use getter/setter (Easy for contribution)
|
||||||
|
[] commandsData.py
|
||||||
|
[] eventData.py
|
||||||
|
[] generalData.py
|
||||||
|
[] inputData.py
|
||||||
|
[] outputData.py
|
||||||
|
[] punctuationData.py
|
||||||
|
[] runtimeData.py
|
||||||
|
[w] screenData.py
|
||||||
|
[] settingsData -> defaultSettings.py
|
||||||
|
[] Unify Key Forewarding and Sticky mode for keyboard and bytecode inputDrivers.
|
||||||
|
[] replace lines by a list insteed of and \n seperated string. (currently we need to split to often) (Easy for contribution)
|
||||||
|
General (Easy for contribution)
|
||||||
|
[w] make fenrir runnable without root permissions
|
||||||
|
[] make fenrir runable without settingsfile. fallback to defaults
|
||||||
|
[] Detect progressbars and just present percent
|
||||||
|
|=============== |100%
|
||||||
|
[=================> ] 100%
|
||||||
|
######################## 100%
|
||||||
|
Imporove attribute handling
|
||||||
|
[] beep on review by word (once for multiple, capital wins) (Easy for contribution)
|
||||||
|
[] configurable (by char, by word, none) (Easy for contribution)
|
||||||
|
https://github.com/jwilk/vcsapeek/blob/master/linuxvt.py
|
||||||
|
|
||||||
|
Improved Say all
|
||||||
|
[] speech callbacks
|
||||||
|
[] speech process by word
|
||||||
|
[] all the text of all pages
|
||||||
|
[] command to stop and place review cursor at this position
|
||||||
|
[] command to slow down speech on keypress
|
||||||
|
[] place say all at clipboard buffer
|
||||||
|
|
||||||
|
Table review mode
|
||||||
|
[] toggle table mode/ select headline
|
||||||
|
[] next line
|
||||||
|
[] prev line
|
||||||
|
[] current line
|
||||||
|
[] next cell
|
||||||
|
[] prev cell
|
||||||
|
[] current cell
|
||||||
|
[] select field separator
|
||||||
|
|
||||||
|
Braille Support:
|
||||||
|
[] brailleFocusMode:
|
||||||
|
[] manual = no automatic toggle command used
|
||||||
|
[] last = follow last used cursor
|
||||||
|
[] print cursor in review
|
||||||
|
[] print cursor in textmode
|
||||||
|
[] word wrapping (if word does not fit print it at next page)
|
||||||
|
https://docs.python.org/2/library/textwrap.html#textwrap.TextWrapper
|
||||||
|
drop_whitespace = False
|
||||||
|
replace_whitespace = False
|
||||||
|
w.fill(i).split('\n')
|
||||||
|
[] command toggle used cursor (in manual brailleFocusMode)
|
||||||
|
[] capture input from braile
|
||||||
|
[] make routing keys assignable by keyboard
|
||||||
|
[] make brailleTable configurable
|
||||||
|
[] pkg-config --variable=tablesdir liblouis
|
||||||
|
returns on Arch:/usr/share/liblouis/tables
|
||||||
|
http://mielke.cc/brltty/doc/Manual-BrlAPI/English/BrlAPI.html
|
||||||
|
https://git.gnome.org/browse/orca/tree/src/orca/braille.py
|
||||||
|
https://wiki.gnome.org/Attic/LSR/ScratchPad/Braille/BrlAPI
|
||||||
|
https://github.com/google/brailleback/blob/master/third_party/brltty/Bindings/Python/brlapi.pyx
|
||||||
|
|
||||||
|
[] ATK input driver (don't grab on graphical interface)
|
||||||
|
https://git.linux-a11y.org/AIT/pyatspi2/src/master/examples/keypress.py
|
||||||
|
|
||||||
|
Driver (speech):
|
||||||
|
[S] talkey driver ( verry unresponsive for espeak in linux)
|
||||||
|
[S] emacspeak driver (breaks for a whole screen)
|
||||||
|
https://pypi.python.org/pypi/ptyprocess#downloads
|
||||||
|
[] Dectalk SpeechDriver (Easy for contribution, device needed - i dont own one)
|
||||||
|
https://github.com/tvraman/emacspeak/blob/master/servers/obsolete/python/dectalk.py
|
||||||
|
[] MacOS speech Driver
|
||||||
|
Settings:
|
||||||
|
[] write settings (Easy for contribution)
|
||||||
|
[] menue for settings configuration (Easy for contribution)
|
22
TODOv3.0
Normal file
22
TODOv3.0
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
ToDo list for Fenrir Version 3.0
|
||||||
|
Things needing little knowledge are marked with "(Easy for contribution)". so just start with those :).
|
||||||
|
[] = ToDo
|
||||||
|
[W] = WIP
|
||||||
|
[X] = Done
|
||||||
|
[S] = Stopped
|
||||||
|
|
||||||
|
__TOD___
|
||||||
|
Application Profiles (low priority):
|
||||||
|
- reimplement process detection without subprocessing
|
||||||
|
- fenrir is not able to detect the current application inside of screen.
|
||||||
|
ps -e -H -o pid,pgrp,ppid,tty,cmd
|
||||||
|
http://stackoverflow.com/questions/24861351/how-to-detect-if-python-script-is-being-run-as-a-background-process/24862213
|
||||||
|
fd = os.open("/dev/tty5", os.O_RDONLY )
|
||||||
|
os.tcgetpgrp(fd)
|
||||||
|
- add perApplicationTrigger trigger
|
||||||
|
per application commands
|
||||||
|
per application onScreenChange
|
||||||
|
per application onInput
|
||||||
|
- per application shortcuts
|
||||||
|
|
||||||
|
___DONE___
|
1
docu/Howto Configure Pulse Systemwide.txt
Normal file
1
docu/Howto Configure Pulse Systemwide.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
https://rudd-o.com/linux-and-free-software/how-to-make-pulseaudio-run-once-at-boot-for-all-your-users
|
13
docu/create_manpage.sh
Executable file
13
docu/create_manpage.sh
Executable file
@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# needs pandoc and php installed
|
||||||
|
|
||||||
|
# remove old files
|
||||||
|
rm fenrir.1
|
||||||
|
rm user.md
|
||||||
|
|
||||||
|
# convert to markdown
|
||||||
|
php DokuWiki-to-Markdown-Converter/convert.php user.txt
|
||||||
|
|
||||||
|
# convert markdown to manpage
|
||||||
|
pandoc user.md -f markdown -t man -s -o fenrir.1
|
||||||
|
|
4
docu/development.txt
Normal file
4
docu/development.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
1. Basic
|
||||||
|
2. Commands
|
||||||
|
3. Useful API
|
||||||
|
|
2764
docu/fenrir.1
Normal file
2764
docu/fenrir.1
Normal file
File diff suppressed because it is too large
Load Diff
1590
docu/user.md
Normal file
1590
docu/user.md
Normal file
File diff suppressed because it is too large
Load Diff
1332
docu/user.txt
Normal file
1332
docu/user.txt
Normal file
File diff suppressed because it is too large
Load Diff
12
play zone/argp.py
Executable file
12
play zone/argp.py
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/python3
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description="Fenrir Help")
|
||||||
|
|
||||||
|
parser.add_argument('-s', '--setting', metavar='SETTING-FILE', default='/etc/fenrir/settings/settings.conf', help='Use a specified settingsfile')
|
||||||
|
parser.add_argument('-o', '--options', metavar='SECTION:SETTING=VALUE,..', default='', help='Overwrite options in given settings file')
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
parser.print_help()
|
||||||
|
|
||||||
|
print(args.setting)
|
88
play zone/charmapTTY.py
Executable file
88
play zone/charmapTTY.py
Executable file
@ -0,0 +1,88 @@
|
|||||||
|
import time
|
||||||
|
from fcntl import ioctl
|
||||||
|
from array import array
|
||||||
|
from struct import unpack_from
|
||||||
|
from struct import unpack
|
||||||
|
from struct import pack
|
||||||
|
import errno
|
||||||
|
import sys
|
||||||
|
charmap = {}
|
||||||
|
hichar = None
|
||||||
|
def updateCharMap(screen):
|
||||||
|
global hichar
|
||||||
|
ttyno = '4'
|
||||||
|
tty = open('/dev/tty' + screen, 'rb')
|
||||||
|
GIO_UNIMAP = 0x4B66
|
||||||
|
VT_GETHIFONTMASK = 0x560D
|
||||||
|
himask = array("H", (0,))
|
||||||
|
ioctl(tty, VT_GETHIFONTMASK, himask)
|
||||||
|
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 charmap.get(b) is None:
|
||||||
|
charmap[b] = chr(u)
|
||||||
|
|
||||||
|
|
||||||
|
def autoDecodeVCSA(allData, rows, cols):
|
||||||
|
allText = []
|
||||||
|
allAttrib = []
|
||||||
|
for y in range(rows):
|
||||||
|
lineText = ''
|
||||||
|
lineAttrib = []
|
||||||
|
i = 0
|
||||||
|
for x in range(cols):
|
||||||
|
data = allData[i: i + 2]
|
||||||
|
i += 2
|
||||||
|
if data == b' \x07':
|
||||||
|
#attr = 7
|
||||||
|
#ink = 7
|
||||||
|
#paper = 0
|
||||||
|
#ch = ' '
|
||||||
|
lineAttrib.append(7)
|
||||||
|
lineText += ' '
|
||||||
|
continue
|
||||||
|
(sh,) = 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
|
||||||
|
try:
|
||||||
|
lineText += charmap[ch]
|
||||||
|
except:
|
||||||
|
lineText += chr('?')
|
||||||
|
allText.append(lineText)
|
||||||
|
allAttrib.append(lineAttrib)
|
||||||
|
return allText, allAttrib
|
||||||
|
|
||||||
|
def m(screen):
|
||||||
|
s = time.time()
|
||||||
|
updateCharMap(str(screen))
|
||||||
|
print(time.time() -s )
|
||||||
|
vcsa = open('/dev/vcsa' + str(screen), 'rb')
|
||||||
|
head = vcsa.read(4)
|
||||||
|
rows = int(head[0])
|
||||||
|
cols = int(head[1])
|
||||||
|
text, attrib = autoDecodeVCSA(vcsa.read(), rows, cols)
|
||||||
|
print(time.time() -s )
|
||||||
|
|
39
play zone/colors.sh
Normal file
39
play zone/colors.sh
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
echo "foreground colors"
|
||||||
|
echo -e "\e[39mDefault"
|
||||||
|
echo -e "\e[30mBlack"
|
||||||
|
echo -e "\e[31mRed"
|
||||||
|
echo -e "\e[32mGreen"
|
||||||
|
echo -e "\e[33mYellow"
|
||||||
|
echo -e "\e[34mBlue"
|
||||||
|
echo -e "\e[35mMagenta"
|
||||||
|
echo -e "\e[36mCyan"
|
||||||
|
echo -e "\e[37mLight gray"
|
||||||
|
echo -e "\e[90mDark gray"
|
||||||
|
echo -e "\e[91mLight red"
|
||||||
|
echo -e "\e[92mLight green"
|
||||||
|
echo -e "\e[93mLight yellow"
|
||||||
|
echo -e "\e[94mLight blue"
|
||||||
|
echo -e "\e[95mLight magenta"
|
||||||
|
echo -e "\e[96mLight cyan"
|
||||||
|
echo -e "\e[97mWhite"
|
||||||
|
|
||||||
|
echo "background colors"
|
||||||
|
echo -e "\e[49mDefault"
|
||||||
|
echo -e "\e[40mBlack"
|
||||||
|
echo -e "\e[41mRed"
|
||||||
|
echo -e "\e[42mGreen"
|
||||||
|
echo -e "\e[43mYellow"
|
||||||
|
echo -e "\e[44mBlue"
|
||||||
|
echo -e "\e[45mMagenta"
|
||||||
|
echo -e "\e[46mCyan"
|
||||||
|
echo -e "\e[47mLight gray"
|
||||||
|
echo -e "\e[100mDark gray"
|
||||||
|
echo -e "\e[101mLight red"
|
||||||
|
echo -e "\e[102mLight green"
|
||||||
|
echo -e "\e[103mLight yellow"
|
||||||
|
echo -e "\e[104mLight blue"
|
||||||
|
echo -e "\e[105mLight magenta"
|
||||||
|
echo -e "\e[106mLight cyan"
|
||||||
|
echo -e "\e[107mWhite"
|
||||||
|
|
52
play zone/consumeEvents.py
Executable file
52
play zone/consumeEvents.py
Executable file
@ -0,0 +1,52 @@
|
|||||||
|
#!/bin/python
|
||||||
|
import evdev
|
||||||
|
from evdev import InputDevice, UInput
|
||||||
|
from select import select
|
||||||
|
import time
|
||||||
|
|
||||||
|
iDevices = map(evdev.InputDevice, (evdev.list_devices()))
|
||||||
|
iDevices = {dev.fd: dev for dev in iDevices if evdev.events.EV_KEY in dev.capabilities()}
|
||||||
|
|
||||||
|
uDevices = {}
|
||||||
|
for fd in iDevices:
|
||||||
|
dev = iDevices[fd]
|
||||||
|
cap = dev.capabilities()
|
||||||
|
del cap[0]
|
||||||
|
uDevices[fd] = UInput(
|
||||||
|
cap,
|
||||||
|
dev.name,
|
||||||
|
dev.info.vendor,
|
||||||
|
# dev.info.product,
|
||||||
|
# dev.version,
|
||||||
|
# dev.info.bustype,
|
||||||
|
# '/dev/uinput'
|
||||||
|
)
|
||||||
|
dev.grab()
|
||||||
|
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
while i < 100:
|
||||||
|
r, w, x = select(iDevices, [], [])
|
||||||
|
if r != []:
|
||||||
|
i += 1
|
||||||
|
for fd in r:
|
||||||
|
for event in iDevices[fd].read():
|
||||||
|
if event.code != 30: # a
|
||||||
|
print(event)
|
||||||
|
uDevices[fd].write_event(event)
|
||||||
|
uDevices[fd].syn()
|
||||||
|
#print('Devicename:'+ devices[fd].name + ' Devicepath:' + devices[fd].fn + ' Events:' + str(devices[fd].active_keys(verbose=True)) + ' Value:' + str(event.value))
|
||||||
|
else:
|
||||||
|
print('this key is consumed')
|
||||||
|
|
||||||
|
for fd in iDevices:
|
||||||
|
iDevices[fd].ungrab()
|
||||||
|
iDevices[fd].close()
|
||||||
|
uDevices[fd].close()
|
||||||
|
|
||||||
|
|
||||||
|
iDevices.clear()
|
||||||
|
uDevices.clear()
|
||||||
|
|
||||||
|
|
||||||
|
|
12
play zone/daemon.py
Executable file
12
play zone/daemon.py
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
from time import sleep
|
||||||
|
from daemonize import Daemonize
|
||||||
|
|
||||||
|
pid = "/tmp/test.pid"
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
while True:
|
||||||
|
sleep(5)
|
||||||
|
|
||||||
|
daemon = Daemonize(app="test_app", pid=pid, action=main)
|
||||||
|
daemon.start()
|
48
play zone/detectDevices.py
Executable file
48
play zone/detectDevices.py
Executable file
@ -0,0 +1,48 @@
|
|||||||
|
#!/bin/python
|
||||||
|
iDevices = {}
|
||||||
|
iDeviceNo = 0
|
||||||
|
def updateInputDevices(force = False, init = False):
|
||||||
|
global iDeviceNo
|
||||||
|
if init:
|
||||||
|
iDevices = {}
|
||||||
|
iDeviceNo = 0
|
||||||
|
deviceFileList = evdev.list_devices()
|
||||||
|
if not force:
|
||||||
|
if len(deviceFileList) == iDeviceNo:
|
||||||
|
return
|
||||||
|
iDeviceNo = len(deviceFileList)
|
||||||
|
mode = 'ALL'
|
||||||
|
iDevicesFiles = []
|
||||||
|
for device in iDevices:
|
||||||
|
iDevicesFiles.append(iDevices[device].fn)
|
||||||
|
print(len(iDevicesFiles),len(deviceFileList))
|
||||||
|
if len(iDevicesFiles) == len(deviceFileList):
|
||||||
|
return
|
||||||
|
for deviceFile in deviceFileList:
|
||||||
|
try:
|
||||||
|
if deviceFile in iDevicesFiles:
|
||||||
|
print('skip')
|
||||||
|
continue
|
||||||
|
open(deviceFile)
|
||||||
|
# 3 pos absolute
|
||||||
|
# 2 pos relative
|
||||||
|
# 1 Keys
|
||||||
|
currDevice = evdev.InputDevice(deviceFile)
|
||||||
|
cap = currDevice.capabilities()
|
||||||
|
if mode in ['ALL','NOMICE']:
|
||||||
|
if 1 in cap:
|
||||||
|
if 116 in cap[1] and len(cap[1]) < 5:
|
||||||
|
print('power')
|
||||||
|
continue
|
||||||
|
if mode == 'ALL':
|
||||||
|
iDevices[currDevice.fd] = currDevice
|
||||||
|
print('Device added:' + iDevices[currDevice.fd].name)
|
||||||
|
elif mode == 'NOMICE':
|
||||||
|
if not ((2 in cap) or (3 in cap)):
|
||||||
|
iDevices[currDevice.fd] = currDevice
|
||||||
|
print('Device added:' + iDevices[currDevice.fd].name)
|
||||||
|
elif currDevice.name.upper() in mode.split(','):
|
||||||
|
iDevices[currDevice.fd] = currDevice
|
||||||
|
print('Device added:' + iDevices[currDevice.fd].name)
|
||||||
|
except Exception as e:
|
||||||
|
print("Skip Inputdevice : " + deviceFile +' ' + str(e))
|
37
play zone/epollScreen.py
Normal file
37
play zone/epollScreen.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#!/bin/python
|
||||||
|
|
||||||
|
import select
|
||||||
|
import time
|
||||||
|
|
||||||
|
currScreen = '2'
|
||||||
|
vcsa = {}
|
||||||
|
for i in range(1,7):
|
||||||
|
vcsa[str(i)] = open('/dev/vcs'+str(i),'rb')
|
||||||
|
|
||||||
|
tty = open('/sys/devices/virtual/tty/tty0/active','r')
|
||||||
|
currScreen = str(tty.read()[3:-1])
|
||||||
|
oldScreen = currScreen
|
||||||
|
watchdog = select.epoll()
|
||||||
|
watchdog.register(vcsa[currScreen], select.EPOLLPRI)
|
||||||
|
watchdog.register(tty, select.EPOLLPRI)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
changes = watchdog.poll()
|
||||||
|
print('-----------------------------')
|
||||||
|
print(changes)
|
||||||
|
for change in changes:
|
||||||
|
fileno = change[0]
|
||||||
|
event = change[1]
|
||||||
|
print(change,fileno, tty.fileno())
|
||||||
|
if fileno == tty.fileno():
|
||||||
|
tty.seek(0)
|
||||||
|
currScreen = str(tty.read()[3:-1])
|
||||||
|
if currScreen != oldScreen:
|
||||||
|
watchdog.unregister(vcsa[ oldScreen ])
|
||||||
|
watchdog.register(vcsa[ currScreen ], select.EPOLLPRI)
|
||||||
|
oldScreen = currScreen
|
||||||
|
print('new screen '+ currScreen)
|
||||||
|
else:
|
||||||
|
vcsa[currScreen].seek(0)
|
||||||
|
content = vcsa[currScreen].read()
|
||||||
|
print('update '+ str(time.time()))
|
5
play zone/errorOnBrokenDevice.py
Executable file
5
play zone/errorOnBrokenDevice.py
Executable file
@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/python
|
||||||
|
|
||||||
|
# in case that event13 is still the broken device
|
||||||
|
f = open('/dev/input/event13')
|
||||||
|
print('OK /dev/input/event13')
|
48
play zone/fg.sh
Executable file
48
play zone/fg.sh
Executable file
@ -0,0 +1,48 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
echo "foreground colors"
|
||||||
|
echo -e "\e[39mDefault"
|
||||||
|
echo -e "\e[30mBlack"
|
||||||
|
echo -e "\e[31mRed"
|
||||||
|
echo -e "\e[32mGreen"
|
||||||
|
echo -e "\e[33mYellow"
|
||||||
|
echo -e "\e[34mBlue"
|
||||||
|
echo -e "\e[35mMagenta"
|
||||||
|
echo -e "\e[36mCyan"
|
||||||
|
echo -e "\e[37mLight gray"
|
||||||
|
echo -e "\e[90mDark gray"
|
||||||
|
echo -e "\e[91mLight red"
|
||||||
|
echo -e "\e[92mLight green"
|
||||||
|
echo -e "\e[93mLight yellow"
|
||||||
|
echo -e "\e[94mLight blue"
|
||||||
|
echo -e "\e[95mLight magenta"
|
||||||
|
echo -e "\e[96mLight cyan"
|
||||||
|
echo -e "\e[97mWhite"
|
||||||
|
#7: _('Default'), 0: _('Black'), 4: _('Red'), 2: _('Green'), 6: _('Yellow'), 1: _('Blue'), 5: _('Magenta'), 3: _('Cyan'), 7: _('Light gray'), 8: _('Dark gray'), 12: _('Light red'), 10: , ('Light green'), 14: _('Light yellow'), 9: _('Light blue'), 13: _('Light magenta'), 11: _('Light cyan'), 15: _('White')
|
||||||
|
|
||||||
|
echo "background colors"
|
||||||
|
echo -e "\e[49mDefault"
|
||||||
|
echo -e "\e[40mBlack"
|
||||||
|
echo -e "\e[41mRed"
|
||||||
|
echo -e "\e[42mGreen"
|
||||||
|
echo -e "\e[43mYellow"
|
||||||
|
echo -e "\e[44mBlue"
|
||||||
|
echo -e "\e[45mMagenta"
|
||||||
|
echo -e "\e[46mCyan"
|
||||||
|
echo -e "\e[47mLight gray"
|
||||||
|
echo -e "\e[100mDark gray"
|
||||||
|
echo -e "\e[101mLight red"
|
||||||
|
echo -e "\e[102mLight green"
|
||||||
|
echo -e "\e[103mLight yellow"
|
||||||
|
echo -e "\e[104mLight blue"
|
||||||
|
echo -e "\e[105mLight magenta"
|
||||||
|
echo -e "\e[106mLight cyan"
|
||||||
|
echo -e "\e[107mWhite"
|
||||||
|
|
||||||
|
echo "format"
|
||||||
|
echo -e "\e[1mBold"
|
||||||
|
echo -e "\e[2mDim"
|
||||||
|
echo -e "\e[4mUnderlined"
|
||||||
|
echo -e "\e[5mBlink"
|
||||||
|
echo -e "\e[7minverted"
|
||||||
|
echo -e "\e[8mHidden"
|
||||||
|
|
19
play zone/keypress.py
Executable file
19
play zone/keypress.py
Executable file
@ -0,0 +1,19 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
import gi
|
||||||
|
from gi.repository import GLib
|
||||||
|
gi.require_version('Gst', '1.0')
|
||||||
|
from gi.repository import Gst
|
||||||
|
import time, threading
|
||||||
|
gi.require_version('Atspi', '2.0')
|
||||||
|
import pyatspi
|
||||||
|
|
||||||
|
# Callback to print the active window on key press amd filter out the key release
|
||||||
|
def on_key_input(event):
|
||||||
|
print(event)
|
||||||
|
|
||||||
|
mainloop = GLib.MainLoop()
|
||||||
|
thread = threading.Thread(target=mainloop.run)
|
||||||
|
thread.start()
|
||||||
|
#pyatspi.Registry.registerKeystrokeListener(on_key_input, kind=(pyatspi.KEY_PRESSED_EVENT, pyatspi.KEY_RELEASED_EVENT))
|
||||||
|
pyatspi.Registry.registerKeystrokeListener(on_key_input,mask=pyatspi.allModifiers(), kind=(pyatspi.KEY_PRESS,pyatspi.KEY_RELEASE,pyatspi.KEY_PRESSRELEASE), synchronous=True, preemptive=True)
|
||||||
|
pyatspi.Registry.start()
|
23
play zone/listDevices.py
Executable file
23
play zone/listDevices.py
Executable file
@ -0,0 +1,23 @@
|
|||||||
|
#!/bin/python
|
||||||
|
import evdev
|
||||||
|
from evdev import InputDevice, UInput
|
||||||
|
from select import select
|
||||||
|
import time
|
||||||
|
|
||||||
|
iDevices = map(evdev.InputDevice, (evdev.list_devices()))
|
||||||
|
iDevices = {dev.fd: dev for dev in iDevices}
|
||||||
|
print('----------------------')
|
||||||
|
for fd in iDevices:
|
||||||
|
dev = iDevices[fd]
|
||||||
|
cap = dev.capabilities()
|
||||||
|
print('Name: ' + str(dev.name))
|
||||||
|
print('LEDs: ' + str(dev.leds()))
|
||||||
|
print('Has Keys: '+ str(evdev.events.EV_KEY in cap))
|
||||||
|
if evdev.events.EV_KEY in cap:
|
||||||
|
print('No. of keys: ' + str(len(cap[evdev.events.EV_KEY])))
|
||||||
|
print('has Key 116: ' + str(116 in cap[evdev.events.EV_KEY]))
|
||||||
|
print('Is Mouse: ' + str(((evdev.events.EV_REL in cap) or (evdev.events.EV_ABS in cap))))
|
||||||
|
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
|
||||||
|
print(dev.capabilities(verbose=True))
|
||||||
|
print('----------------------')
|
||||||
|
|
20
play zone/listSession.py
Executable file
20
play zone/listSession.py
Executable file
@ -0,0 +1,20 @@
|
|||||||
|
#!/bin/python
|
||||||
|
import dbus
|
||||||
|
try:
|
||||||
|
bus = dbus.SystemBus()
|
||||||
|
obj = bus.get_object('org.freedesktop.login1', '/org/freedesktop/login1')
|
||||||
|
inf = dbus.Interface(obj, 'org.freedesktop.login1.Manager')
|
||||||
|
ListSessions = inf.get_dbus_method('ListSessions')
|
||||||
|
sessions = ListSessions()
|
||||||
|
for session in sessions:
|
||||||
|
obj = bus.get_object('org.freedesktop.login1', session[4])
|
||||||
|
inf = dbus.Interface(obj, 'org.freedesktop.DBus.Properties')
|
||||||
|
sessionType = inf.Get('org.freedesktop.login1.Session', 'Type')
|
||||||
|
screen = str(inf.Get('org.freedesktop.login1.Session', 'VTNr'))
|
||||||
|
if screen == '':
|
||||||
|
screen = str(inf.Get('org.freedesktop.login1.Session', 'TTY'))
|
||||||
|
print('Session:', screen, 'Type:', sessionType.upper(), 'Details:', session)
|
||||||
|
else:
|
||||||
|
print('Session:', screen, 'Type:', sessionType.upper(), 'Details:', session)
|
||||||
|
except:
|
||||||
|
print('no access')
|
52
play zone/marytts.py
Executable file
52
play zone/marytts.py
Executable file
@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# HTTP + URL packages
|
||||||
|
import httplib2
|
||||||
|
from urllib.parse import urlencode, quote # For URL creation
|
||||||
|
import time
|
||||||
|
# To play wave files
|
||||||
|
import pygame
|
||||||
|
import math # For ceiling
|
||||||
|
|
||||||
|
|
||||||
|
# Mary server informations
|
||||||
|
mary_host = "127.0.0.1"
|
||||||
|
mary_port = "59125"
|
||||||
|
|
||||||
|
# Input text
|
||||||
|
input_text = "das ist ein test das ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testd"
|
||||||
|
# Build the query
|
||||||
|
query_hash = {"INPUT_TEXT":input_text,
|
||||||
|
"INPUT_TYPE":"TEXT", # Input text
|
||||||
|
"LOCALE":"de",
|
||||||
|
"VOICE":"bits3", # Voice informations (need to be compatible)
|
||||||
|
"OUTPUT_TYPE":"AUDIO",
|
||||||
|
"AUDIO":"WAVE", # Audio informations (need both)
|
||||||
|
}
|
||||||
|
starttime = time.time()
|
||||||
|
query = urlencode(query_hash)
|
||||||
|
#print("query = \"http://%s:%s/process?%s\"" % (mary_host, mary_port, query))
|
||||||
|
|
||||||
|
# Run the query to mary http server
|
||||||
|
h_mary = httplib2.Http()
|
||||||
|
#print("http://%s:%s/process?" % (mary_host, mary_port), "POST", query)
|
||||||
|
resp, content = h_mary.request("http://%s:%s/process?" % (mary_host, mary_port), "POST", query)
|
||||||
|
|
||||||
|
# Decode the wav file or raise an exception if no wav files
|
||||||
|
if (resp["content-type"] == "audio/x-wav"):
|
||||||
|
# Write the wav file
|
||||||
|
f = open("/tmp/output_wav.wav", "wb")
|
||||||
|
f.write(content)
|
||||||
|
f.close()
|
||||||
|
# Play the wav file
|
||||||
|
pygame.mixer.init(frequency=16000) # Initialise the mixer
|
||||||
|
#s = pygame.mixer.Sound(content)
|
||||||
|
s = pygame.mixer.Sound("/tmp/output_wav.wav")
|
||||||
|
print(str(time.time() -starttime))
|
||||||
|
s.play()
|
||||||
|
print(str(time.time() -starttime))
|
||||||
|
pygame.time.wait(int(math.ceil(s.get_length() * 1000)))
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise Exception(content)
|
53
play zone/parseProcessTree.py
Executable file
53
play zone/parseProcessTree.py
Executable file
@ -0,0 +1,53 @@
|
|||||||
|
#!/bin/python
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
start = time.time()
|
||||||
|
pids = [pid for pid in os.listdir('/proc') if pid.isdigit()]
|
||||||
|
#pids = ['5960']
|
||||||
|
|
||||||
|
tty = os.open('/dev/tty2', os.O_RDWR)
|
||||||
|
fg = str(os.tcgetpgrp(tty))
|
||||||
|
tty.close()
|
||||||
|
print(fg)
|
||||||
|
for pid in pids:
|
||||||
|
try:
|
||||||
|
currStat = str(open('/proc/' + pid + '/stat', 'rb').read())
|
||||||
|
currStat = currStat.split(' ')
|
||||||
|
if int(currStat[4]) == 0:
|
||||||
|
continue
|
||||||
|
#print(currStat)
|
||||||
|
#print(fg,int(currStat[4]))
|
||||||
|
if fg == currStat[4]:
|
||||||
|
print(currStat[1])
|
||||||
|
#print( currStat )
|
||||||
|
#print(currStat[0])
|
||||||
|
major = os.major(int(currStat[6]))
|
||||||
|
minor = os.minor(int(currStat[6]))
|
||||||
|
ueventContent = open('/sys/dev/char/' + str(major) + ':' + str(minor) + '/uevent','r').read().split()
|
||||||
|
#print(ueventContent)
|
||||||
|
#print(int(currStat[4]),currStat[1])
|
||||||
|
except IOError: # proc has already terminated
|
||||||
|
continue
|
||||||
|
|
||||||
|
print(time.time()-start)
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
Table 1-4: Contents of the stat files (as of 2.6.30-rc7)
|
||||||
|
..............................................................................
|
||||||
|
Field Content
|
||||||
|
pid process id
|
||||||
|
tcomm filename of the executable
|
||||||
|
state state (R is running, S is sleeping, D is sleeping in an
|
||||||
|
uninterruptible wait, Z is zombie, T is traced or stopped)
|
||||||
|
ppid process id of the parent process
|
||||||
|
pgrp pgrp of the process
|
||||||
|
sid session id
|
||||||
|
tty_nr tty the process uses
|
||||||
|
tty_pgrp pgrp of the tty
|
||||||
|
flags task flags
|
||||||
|
min_flt number of minor faults
|
||||||
|
cmin_flt number of minor faults with child's
|
||||||
|
maj_flt number of major faults
|
||||||
|
cmaj_flt number of major faults with child's
|
||||||
|
'''
|
28
play zone/passBrokenDevice.py
Executable file
28
play zone/passBrokenDevice.py
Executable file
@ -0,0 +1,28 @@
|
|||||||
|
#!/bin/python
|
||||||
|
import evdev
|
||||||
|
from evdev import InputDevice
|
||||||
|
from select import select
|
||||||
|
import time
|
||||||
|
|
||||||
|
deviceList = evdev.list_devices()
|
||||||
|
readableDevices = []
|
||||||
|
for dev in deviceList:
|
||||||
|
try:
|
||||||
|
open(dev)
|
||||||
|
readableDevices.append(dev)
|
||||||
|
print('OK '+dev)
|
||||||
|
except Exception as e:
|
||||||
|
print('skip ' + dev + ' Error ' + str(e))
|
||||||
|
|
||||||
|
|
||||||
|
devices = map(evdev.InputDevice, (readableDevices))
|
||||||
|
devices = {dev.fd: dev for dev in devices}
|
||||||
|
|
||||||
|
while True:
|
||||||
|
r, w, x = select(devices, [], [])
|
||||||
|
if r != []:
|
||||||
|
for fd in r:
|
||||||
|
for event in devices[fd].read():
|
||||||
|
print('Devicename:'+ devices[fd].name + ' Devicepath:' + devices[fd].fn + ' Events:' + str(devices[fd].active_keys(verbose=True)) + ' Value:' + str(event.value))
|
||||||
|
|
||||||
|
|
154
play zone/pdmenurc
Normal file
154
play zone/pdmenurc
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
#!/usr/bin/pdmenu
|
||||||
|
#
|
||||||
|
# Note that the above bang-path isn't required, but it lets you run this
|
||||||
|
# file directly as a sort of pdmenu script.
|
||||||
|
|
||||||
|
# F123 menu
|
||||||
|
|
||||||
|
title:Welcome to F123
|
||||||
|
|
||||||
|
# Define the main menu.
|
||||||
|
menu:main:F123 Main Menu:Please make a selection
|
||||||
|
show:_Games Menu..::games
|
||||||
|
show:_Internet menu..::internet
|
||||||
|
show:_Media menu..::media
|
||||||
|
show:_Office menu..::office
|
||||||
|
show:_System Configuration Menu..::configuration
|
||||||
|
show:_Tools Menu..::tools
|
||||||
|
nop
|
||||||
|
show:_Power Options..::power
|
||||||
|
nop
|
||||||
|
exit:_Exit
|
||||||
|
|
||||||
|
|
||||||
|
# Submenu for games.
|
||||||
|
menu:games:Games:Command line games
|
||||||
|
exec:_Adventure::clear;adventure
|
||||||
|
exec:_Arithmetic::clear;arithmetic
|
||||||
|
exec:_Air Traffic Controler (Not screen reader friendly)::clear;atc
|
||||||
|
exec:_Backgammon (Not screen reader friendly)::clear;backgammon
|
||||||
|
exec:_Battlestar::clear;battlestar
|
||||||
|
exec:_Boggle (Not screen reader friendly)::clear;boggle
|
||||||
|
exec:_Canfield (Not screen reader friendly)::clear;canfield
|
||||||
|
exec:_Cribbage (Not screen reader friendly)::clear;cribbage
|
||||||
|
exec:_Go Fish:pause:clear;go-fish
|
||||||
|
exec:_Gomoku::clear;gomoku
|
||||||
|
exec:_Hangman::clear;hangman
|
||||||
|
exec:_Hunt (Not screen reader friendly)::clear;hunt
|
||||||
|
exec:_Mille Bornes::clear;mille
|
||||||
|
exec:_Number::clear;number
|
||||||
|
exec:_Phantasia::clear;phantasia
|
||||||
|
exec:_Phase of the Moon:pause:clear;pom
|
||||||
|
exec:_Primes::clear;primes
|
||||||
|
exec:_Robots (Not screen reader friendly)::clear;robots
|
||||||
|
exec:_Sail::clear;sail
|
||||||
|
exec:_Snake (Not screen reader friendly)::clear;snake
|
||||||
|
exec:_Tetris (Not screen reader friendly)::clear;tetris-bsd
|
||||||
|
exec:_Trek::clear;trek
|
||||||
|
exec:_Worm (Not screen reader friendly)::clear;worm
|
||||||
|
exec:_Wumpus::clear;wump
|
||||||
|
|
||||||
|
nop
|
||||||
|
exit:_Main menu..
|
||||||
|
|
||||||
|
# submenu for internet applications.
|
||||||
|
menu:internet:Internet:Internet programs
|
||||||
|
exec:_E-Mail::clear;mutt
|
||||||
|
exec:_Basic Web Browser (W3M)::clear;w3m -v
|
||||||
|
group:Full _Web browser (Firefox)
|
||||||
|
exec:::clear
|
||||||
|
exec:::python /usr/share/fenrirscreenreader/tools/fenrir-ignore-screen
|
||||||
|
exec:::startx /usr/lib/F123-wrappers/xlauncher firefox
|
||||||
|
exec:::python /usr/share/fenrirscreenreader/tools/fenrir-unignore-screen
|
||||||
|
endgroup
|
||||||
|
group:_Mumble Voice Chat
|
||||||
|
exec:::clear
|
||||||
|
exec:::python /usr/share/fenrirscreenreader/tools/fenrir-ignore-screen
|
||||||
|
exec:::startx /usr/lib/F123-wrappers/xlauncher mumble
|
||||||
|
exec:::python /usr/share/fenrirscreenreader/tools/fenrir-unignore-screen
|
||||||
|
endgroup
|
||||||
|
nop
|
||||||
|
exit:_Main menu..
|
||||||
|
|
||||||
|
menu:media:Media:Multi-media applications
|
||||||
|
exec:_CD Audio Ripper (ripit)::ripit
|
||||||
|
exec:_Music Player (cmus)::cmus
|
||||||
|
exec:_Youtube (audio only)::youtube-viewer -novideo
|
||||||
|
group:Youtube (full _video)
|
||||||
|
exec:::clear
|
||||||
|
exec:::python /usr/share/fenrirscreenreader/tools/fenrir-ignore-screen
|
||||||
|
exec:::startx /usr/lib/F123-wrappers/xlauncher lxterminal -e youtube-viewer
|
||||||
|
exec:::python /usr/share/fenrirscreenreader/tools/fenrir-unignore-screen
|
||||||
|
endgroup
|
||||||
|
nop
|
||||||
|
exit:_Main menu..
|
||||||
|
|
||||||
|
menu:office:Office:Word processing, calendar, etc
|
||||||
|
exec:_Month Calendar:pause:clear;ncal
|
||||||
|
exec:_Year Calendar:pause:clear;ncal -y
|
||||||
|
exec:Text Editor::clear;${EDITOR:-nano}
|
||||||
|
nop:Office Suite
|
||||||
|
group:Database
|
||||||
|
exec:::clear
|
||||||
|
exec:::python /usr/share/fenrirscreenreader/tools/fenrir-ignore-screen
|
||||||
|
exec:::startx /usr/lib/F123-wrappers/xlauncher lobase
|
||||||
|
exec:::python /usr/share/fenrirscreenreader/tools/fenrir-unignore-screen
|
||||||
|
endgroup
|
||||||
|
group:Diagrams
|
||||||
|
exec:::clear
|
||||||
|
exec:::python /usr/share/fenrirscreenreader/tools/fenrir-ignore-screen
|
||||||
|
exec:::startx /usr/lib/F123-wrappers/xlauncher lodraw
|
||||||
|
exec:::python /usr/share/fenrirscreenreader/tools/fenrir-unignore-screen
|
||||||
|
endgroup
|
||||||
|
group:Formula Editor
|
||||||
|
exec:::clear
|
||||||
|
exec:::python /usr/share/fenrirscreenreader/tools/fenrir-ignore-screen
|
||||||
|
exec:::startx /usr/lib/F123-wrappers/xlauncher lomath
|
||||||
|
exec:::python /usr/share/fenrirscreenreader/tools/fenrir-unignore-screen
|
||||||
|
endgroup
|
||||||
|
group:Presentation
|
||||||
|
exec:::clear
|
||||||
|
exec:::python /usr/share/fenrirscreenreader/tools/fenrir-ignore-screen
|
||||||
|
exec:::startx /usr/lib/F123-wrappers/xlauncher loimpress
|
||||||
|
exec:::python /usr/share/fenrirscreenreader/tools/fenrir-unignore-screen
|
||||||
|
endgroup
|
||||||
|
group:Spreadsheet
|
||||||
|
exec:::clear
|
||||||
|
exec:::python /usr/share/fenrirscreenreader/tools/fenrir-ignore-screen
|
||||||
|
exec:::startx /usr/lib/F123-wrappers/xlauncher localc
|
||||||
|
exec:::python /usr/share/fenrirscreenreader/tools/fenrir-unignore-screen
|
||||||
|
endgroup
|
||||||
|
group:Word Processor
|
||||||
|
exec:::clear
|
||||||
|
exec:::python /usr/share/fenrirscreenreader/tools/fenrir-ignore-screen
|
||||||
|
exec:::startx /usr/lib/F123-wrappers/xlauncher lowriter
|
||||||
|
exec:::python /usr/share/fenrirscreenreader/tools/fenrir-unignore-screen
|
||||||
|
endgroup
|
||||||
|
nop
|
||||||
|
exit:_Main menu..
|
||||||
|
|
||||||
|
# submenu for configuring the computer.
|
||||||
|
menu:configuration:Configuration:System Configuration
|
||||||
|
exec:_Change Passwords::clear;/usr/lib/F123-wrappers/configure-passwords
|
||||||
|
exec:_Email Configuration::clear;fleacollar
|
||||||
|
exec:_Security Configuration::clear;/usr/lib/F123-wrappers/configure-security
|
||||||
|
exec:_Wireless Internet Connection::clear;sudo configure-wifi
|
||||||
|
nop
|
||||||
|
exit:_Main menu..
|
||||||
|
|
||||||
|
menu:tools:Tools:System Tools
|
||||||
|
group:Bluetooth manager
|
||||||
|
exec:::clear
|
||||||
|
exec:::python /usr/share/fenrirscreenreader/tools/fenrir-ignore-screen
|
||||||
|
exec:::startx /usr/lib/F123-wrappers/xlauncher blueman-assistant
|
||||||
|
exec:::python /usr/share/fenrirscreenreader/tools/fenrir-unignore-screen
|
||||||
|
endgroup
|
||||||
|
exec:_Search:edit,pause:recoll -t ~Search for what? :~
|
||||||
|
nop
|
||||||
|
exit:_Main menu..
|
||||||
|
|
||||||
|
menu:power:Shutdown or Restart Your Computer:Shutdown or restart your computer
|
||||||
|
exec:_Power Off::poweroff
|
||||||
|
exec:_Restart::reboot
|
||||||
|
nop
|
||||||
|
exit:_Main menu..
|
41
play zone/print_escape.py
Normal file
41
play zone/print_escape.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#!/bin/python3
|
||||||
|
import sys, os
|
||||||
|
import pty
|
||||||
|
import pyte
|
||||||
|
|
||||||
|
class FenrirTermStream(pyte.Stream):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
def attach(self, screen):
|
||||||
|
super().attach(screen)
|
||||||
|
def feed(self, text):
|
||||||
|
super().feed(text)
|
||||||
|
|
||||||
|
class FenrirTermEmu():
|
||||||
|
def __init__(self):
|
||||||
|
self.shell = '/bin/bash'
|
||||||
|
if 'SHELL' in os.environ:
|
||||||
|
self.shell = os.environ['SHELL']
|
||||||
|
self.screen = pyte.Screen(80,24)
|
||||||
|
self.stream = FenrirTermStream()
|
||||||
|
self.stream.attach(self.screen)
|
||||||
|
def outputCallback(self, fd):
|
||||||
|
data = os.read(fd, 1024)
|
||||||
|
self.stream.feed(data.decode('UTF8'))
|
||||||
|
# alles
|
||||||
|
#print(self.screen.display)
|
||||||
|
# input
|
||||||
|
#print(data.decode('UTF8'))
|
||||||
|
return data
|
||||||
|
def inputCallback(self, fd):
|
||||||
|
data = os.read(fd, 1024)
|
||||||
|
print('|'+str(data)+'|')
|
||||||
|
if data == b'q':
|
||||||
|
print('quit')
|
||||||
|
return b'exit\r'
|
||||||
|
return data
|
||||||
|
def startEmulator(self):
|
||||||
|
pty.spawn(self.shell, self.outputCallback, self.inputCallback)
|
||||||
|
|
||||||
|
t = FenrirTermEmu()
|
||||||
|
t.startEmulator()
|
34
play zone/pyterm.py
Executable file
34
play zone/pyterm.py
Executable file
@ -0,0 +1,34 @@
|
|||||||
|
#!/bin/python3
|
||||||
|
import sys, os
|
||||||
|
import pty
|
||||||
|
import pyte
|
||||||
|
|
||||||
|
class FenrirTermStream(pyte.Stream):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
def attach(self, screen):
|
||||||
|
super().attach(screen)
|
||||||
|
def feed(self, text):
|
||||||
|
super().feed(text)
|
||||||
|
|
||||||
|
class FenrirTermEmu():
|
||||||
|
def __init__(self):
|
||||||
|
self.shell = '/bin/bash'
|
||||||
|
if 'SHELL' in os.environ:
|
||||||
|
self.shell = os.environ['SHELL']
|
||||||
|
self.screen = pyte.Screen(80,24)
|
||||||
|
self.stream = FenrirTermStream()
|
||||||
|
self.stream.attach(self.screen)
|
||||||
|
def outputCallback(self, fd):
|
||||||
|
data = os.read(fd, 1024)
|
||||||
|
self.stream.feed(data.decode('UTF8'))
|
||||||
|
# alles
|
||||||
|
print(self.screen.display)
|
||||||
|
# input
|
||||||
|
print(data.decode('UTF8'))
|
||||||
|
return data
|
||||||
|
def inputCallback(self, fd):
|
||||||
|
data = os.read(fd, 1024)
|
||||||
|
return data
|
||||||
|
def startEmulator(self):
|
||||||
|
pty.spawn(self.shell, self.outputCallback, self.inputCallback)
|
34
play zone/split.txt
Normal file
34
play zone/split.txt
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
./play zone/wrapWord.py:21: wrappedLines = currText.split('\n')
|
||||||
|
./play zone/wrapWord.py:50: wrappedLines = currText.split('\n')
|
||||||
|
./play zone/wrapWord.py:93: wrappedLines = currText.split('\n')
|
||||||
|
./src/fenrirscreenreader/screenDriver/vcsaDriver.py:281: apps = subprocess.Popen('ps -t tty' + currScreen + ' -o comm,tty,stat', shell=True, stdout=subprocess.PIPE).stdout.read().decode()[:-1].split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/line_utils.py:14: wrappedLines = currText.split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/line_utils.py:30: wrappedLines = currText.split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/line_utils.py:41: wrappedLines = currText.split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/char_utils.py:14: wrappedLines = currText.split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/char_utils.py:35: wrappedLines = currText.split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/char_utils.py:43: wrappedLines = currText.split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/char_utils.py:58: wrappedLines = currText.split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/char_utils.py:73: wrappedLines = currText.split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/char_utils.py:85: wrappedLines = currText.split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/mark_utils.py:13: inText = inText.split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/mark_utils.py:59: inText = inText.split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/word_utils.py:20: wrappedLines = currText.split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/word_utils.py:62: wrappedLines = currText.split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/word_utils.py:91: wrappedLines = currText.split('\n')
|
||||||
|
./src/fenrirscreenreader/core/outputManager.py:173: currline = text.split('\n')[offset['y']]
|
||||||
|
./src/fenrirscreenreader/core/attributeManager.py:250: textLines = text.split('\n')
|
||||||
|
./src/fenrirscreenreader/core/screenManager.py:166: diffList = ['+ ' + self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] +'\n']
|
||||||
|
./src/fenrirscreenreader/core/screenManager.py:169: diff = self.differ.compare(oldScreenText.split('\n'),\
|
||||||
|
./src/fenrirscreenreader/core/screenManager.py:170: newScreenText.split('\n'))
|
||||||
|
./src/fenrirscreenreader/core/screenManager.py:225: windowList = text.split('\n')
|
||||||
|
./src/fenrirscreenreader/commands/onCursorChange/62000-spell_check.py:66: newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
|
||||||
|
./src/fenrirscreenreader/commands/onCursorChange/60000-word_echo_type.py:39: newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
|
||||||
|
./src/fenrirscreenreader/commands/onCursorChange/50000-present_char_if_cursor_change_horizontal.py:41: newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
|
||||||
|
./src/fenrirscreenreader/commands/onCursorChange/61000-word_echo_navigation.py:37: newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
|
||||||
|
./src/fenrirscreenreader/commands/commands/spell_check.py:47: newContent = self.env['screen']['newContentText'].split('\n')[cursorPos['y']]
|
||||||
|
./src/fenrirscreenreader/commands/commands/remove_word_from_spell_check.py:45: newContent = self.env['screen']['newContentText'].split('\n')[cursorPos['y']]
|
||||||
|
./src/fenrirscreenreader/commands/commands/add_word_to_spell_check.py:43: newContent = self.env['screen']['newContentText'].split('\n')[cursorPos['y']]
|
||||||
|
./src/fenrirscreenreader/commands/onScreenUpdate/60000-history.py:38: prevLine = self.env['screen']['oldContentText'].split('\n')[self.env['screen']['newCursor']['y']]
|
||||||
|
./src/fenrirscreenreader/commands/onScreenUpdate/60000-history.py:39: currLine = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
|
||||||
|
./TODO v2.0:72: w.fill(i).split('\n')
|
119
play zone/terminalManagement
Normal file
119
play zone/terminalManagement
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
import os
|
||||||
|
import struct
|
||||||
|
import sys
|
||||||
|
import pty
|
||||||
|
import tty
|
||||||
|
import termios
|
||||||
|
import shlex
|
||||||
|
import signal
|
||||||
|
import select
|
||||||
|
import pyte
|
||||||
|
import time
|
||||||
|
|
||||||
|
class Terminal:
|
||||||
|
def __init__(self, columns, lines, p_in):
|
||||||
|
self.screen = pyte.HistoryScreen(columns, lines)
|
||||||
|
self.screen.set_mode(pyte.modes.LNM)
|
||||||
|
self.screen.write_process_input = \
|
||||||
|
lambda data: p_in.write(data.encode())
|
||||||
|
self.stream = pyte.ByteStream()
|
||||||
|
self.stream.attach(self.screen)
|
||||||
|
def feed(self, data):
|
||||||
|
self.stream.feed(data)
|
||||||
|
def dump(self):
|
||||||
|
cursor = self.screen.cursor
|
||||||
|
lines = []
|
||||||
|
for y in self.screen.dirty:
|
||||||
|
line = self.screen.buffer[y]
|
||||||
|
data = [(char.data, char.reverse, char.fg, char.bg)
|
||||||
|
for char in (line[x] for x in range(self.screen.columns))]
|
||||||
|
lines.append((y, data))
|
||||||
|
self.screen.dirty.clear()
|
||||||
|
return {"c": (cursor.x, cursor.y), "lines": lines}
|
||||||
|
|
||||||
|
|
||||||
|
def open_terminal(command="bash", columns=80, lines=24):
|
||||||
|
p_pid, master_fd = pty.fork()
|
||||||
|
if p_pid == 0: # Child.
|
||||||
|
argv = shlex.split(command)
|
||||||
|
env = os.environ.copy()
|
||||||
|
env["TERM"] = 'vt100'
|
||||||
|
os.execvpe(argv[0], argv, env)
|
||||||
|
# File-like object for I/O with the child process aka command.
|
||||||
|
p_out = os.fdopen(master_fd, "w+b", 0)
|
||||||
|
return Terminal(columns, lines, p_out), p_pid, p_out
|
||||||
|
|
||||||
|
def HandleTerminal():
|
||||||
|
debug = False
|
||||||
|
running = True
|
||||||
|
try:
|
||||||
|
old_attr = termios.tcgetattr(sys.stdin)
|
||||||
|
tty.setraw(0)
|
||||||
|
terminal, p_pid, p_out = open_terminal()
|
||||||
|
std_out = os.fdopen(sys.stdout.fileno(), "w+b", 0)
|
||||||
|
while running:
|
||||||
|
r, w, x = select.select([sys.stdin, p_out],[],[])
|
||||||
|
if r == []:
|
||||||
|
continue
|
||||||
|
if p_out in r:
|
||||||
|
if debug:
|
||||||
|
print('pre p_out')
|
||||||
|
try:
|
||||||
|
msgBytes = read_all(p_out.fileno())
|
||||||
|
except (EOFError, OSError):
|
||||||
|
running = False
|
||||||
|
break
|
||||||
|
terminal.feed(msgBytes)
|
||||||
|
os.write(sys.stdout.fileno(), msgBytes)
|
||||||
|
if debug:
|
||||||
|
print('after p_out')
|
||||||
|
if sys.stdin in r:
|
||||||
|
if debug:
|
||||||
|
print('pre stdin')
|
||||||
|
try:
|
||||||
|
msgBytes = read_all(sys.stdin.fileno())
|
||||||
|
except (EOFError, OSError):
|
||||||
|
running = False
|
||||||
|
break
|
||||||
|
terminal.feed(msgBytes)
|
||||||
|
os.write(p_out.fileno(), msgBytes)
|
||||||
|
if debug:
|
||||||
|
print('after stdin')
|
||||||
|
except Exception as e: # Process died?
|
||||||
|
print(e)
|
||||||
|
running = False
|
||||||
|
finally:
|
||||||
|
os.kill(p_pid, signal.SIGTERM)
|
||||||
|
p_out.close()
|
||||||
|
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_attr)
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
def get_terminal_size(fd):
|
||||||
|
s = struct.pack('HHHH', 0, 0, 0, 0)
|
||||||
|
rows, cols, _, _ = struct.unpack('HHHH', fcntl.ioctl(fd, termios.TIOCGWINSZ, s))
|
||||||
|
return rows, cols
|
||||||
|
|
||||||
|
def resize_terminal(fd):
|
||||||
|
s = struct.pack('HHHH', 0, 0, 0, 0)
|
||||||
|
s = fcntl.ioctl(0, termios.TIOCGWINSZ, s)
|
||||||
|
fcntl.ioctl(fd, termios.TIOCSWINSZ, s)
|
||||||
|
rows, cols, _, _ = struct.unpack('hhhh', s)
|
||||||
|
return rows, cols
|
||||||
|
|
||||||
|
def read_all(fd):
|
||||||
|
bytes = os.read(fd, 65536)
|
||||||
|
if bytes == b'':
|
||||||
|
raise EOFError
|
||||||
|
while has_more(fd):
|
||||||
|
data = os.read(fd, 65536)
|
||||||
|
if data == b'':
|
||||||
|
raise EOFError
|
||||||
|
bytes += data
|
||||||
|
return bytes
|
||||||
|
|
||||||
|
def has_more(fd):
|
||||||
|
r, w, e = select.select([fd], [], [], 0)
|
||||||
|
return (fd in r)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
HandleTerminal()
|
92
play zone/vcsa.py
Executable file
92
play zone/vcsa.py
Executable file
@ -0,0 +1,92 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
from cairo import *
|
||||||
|
from fcntl import ioctl
|
||||||
|
from array import array
|
||||||
|
import struct
|
||||||
|
import errno
|
||||||
|
import sys
|
||||||
|
|
||||||
|
GIO_UNIMAP = 0x4B66
|
||||||
|
VT_GETHIFONTMASK = 0x560D
|
||||||
|
|
||||||
|
if len(sys.argv) != 3:
|
||||||
|
print "Usage: %s <tty-number> <output-png>" % sys.argv[0]
|
||||||
|
exit()
|
||||||
|
|
||||||
|
ttyno = int(sys.argv[1])
|
||||||
|
png = sys.argv[2]
|
||||||
|
|
||||||
|
tty = open('/dev/tty%d' % ttyno, 'rb')
|
||||||
|
himask = array("H", (0,))
|
||||||
|
ioctl(tty, VT_GETHIFONTMASK, himask)
|
||||||
|
hichar, = struct.unpack_from("@H", himask)
|
||||||
|
|
||||||
|
sz = 512
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
unipairs = array("H", [0]*(2*sz))
|
||||||
|
unimapdesc = array("B", struct.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, = 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] = unichr(u)
|
||||||
|
|
||||||
|
vcs = open('/dev/vcsa%d' % ttyno, 'rb')
|
||||||
|
|
||||||
|
head = vcs.read(4)
|
||||||
|
rows = ord(head[0])
|
||||||
|
cols = ord(head[1])
|
||||||
|
caretX = ord(head[2])
|
||||||
|
caretY = ord(head[3])
|
||||||
|
|
||||||
|
surf = ImageSurface(FORMAT_RGB24, cols * 8, rows * 16)
|
||||||
|
|
||||||
|
cr = Context(surf)
|
||||||
|
cr.set_source_rgb(1,1,1)
|
||||||
|
cr.set_font_face(ToyFontFace("Mono", FONT_SLANT_NORMAL, FONT_WEIGHT_NORMAL));
|
||||||
|
m = Matrix()
|
||||||
|
m.scale(10.0, 12.0)
|
||||||
|
cr.set_font_matrix(m)
|
||||||
|
|
||||||
|
def CairoColor(b, a):
|
||||||
|
return (b if a & 4 else 0, b if a & 2 else 0, b if a & 1 else 0)
|
||||||
|
|
||||||
|
for y in range(rows):
|
||||||
|
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
|
||||||
|
|
||||||
|
ink = attr & 0x0F
|
||||||
|
paper = (attr>>4) & 0x0F
|
||||||
|
b = 1.0 if attr & 0x80 else 0.75
|
||||||
|
if sh & hichar:
|
||||||
|
ch |= 0x100
|
||||||
|
|
||||||
|
cr.set_source_rgb(*CairoColor(b, paper))
|
||||||
|
cr.rectangle(x*8, y*16, 8, 16)
|
||||||
|
cr.fill()
|
||||||
|
|
||||||
|
cr.set_source_rgb(*CairoColor(b, ink))
|
||||||
|
cr.move_to(x*8, 12 + y*16)
|
||||||
|
cr.show_text(charmap.get(ch, u'?'))
|
||||||
|
cr.stroke()
|
||||||
|
vcs.close()
|
||||||
|
|
||||||
|
surf.write_to_png(png)
|
||||||
|
|
142
play zone/wrapWord.py
Executable file
142
play zone/wrapWord.py
Executable file
@ -0,0 +1,142 @@
|
|||||||
|
#!/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Fenrir TTY screen reader
|
||||||
|
# By Chrys, Storm Dragon, and contributers.
|
||||||
|
|
||||||
|
#from fenrirscreenreader.core import debug
|
||||||
|
import string
|
||||||
|
# X Y Word END BREAK
|
||||||
|
# -1, -1, '', True False
|
||||||
|
def getPrevWord(currX,currY, currText):
|
||||||
|
lineBreak = False
|
||||||
|
endOfScreen = False
|
||||||
|
if currText == '':
|
||||||
|
return -1, -1, '', endOfScreen, lineBreak
|
||||||
|
if currText.strip( string.whitespace) == '':
|
||||||
|
return currX, currY, '', endOfScreen, lineBreak
|
||||||
|
x, y, currWord, endOfScreen, lineBreakCurrWord = getCurrentWord(currX,currY,currText)
|
||||||
|
if endOfScreen:
|
||||||
|
return x, y, currWord, endOfScreen, lineBreak
|
||||||
|
wrappedLines = currText.split('\n')
|
||||||
|
currLine = wrappedLines[y]
|
||||||
|
if x - 1 < 0:
|
||||||
|
if y - 1 < 0:
|
||||||
|
lineBreak = False
|
||||||
|
endOfScreen = True
|
||||||
|
return currX, currY, '', endOfScreen, lineBreak
|
||||||
|
else:
|
||||||
|
y -= 1
|
||||||
|
currLine = wrappedLines[y]
|
||||||
|
x = len( wrappedLines[y]) - 1
|
||||||
|
lineBreak = True
|
||||||
|
else:
|
||||||
|
x -= 1
|
||||||
|
lineBreakCurrWord = lineBreak or lineBreakCurrWord
|
||||||
|
x, y, currWord, endOfScreen, lineBreak = getCurrentWord(x,y,currText)
|
||||||
|
lineBreak = lineBreak or lineBreakCurrWord
|
||||||
|
return x, y, currWord, endOfScreen, lineBreak
|
||||||
|
|
||||||
|
def getCurrentWord(currX,currY, currText):
|
||||||
|
lineBreak = False
|
||||||
|
endOfScreen = False
|
||||||
|
if currText == '':
|
||||||
|
return -1, -1, '', endOfScreen, lineBreak
|
||||||
|
if currText.strip( string.whitespace) == '':
|
||||||
|
return currX, currY, '', endOfScreen, lineBreak
|
||||||
|
x = currX
|
||||||
|
y = currY
|
||||||
|
currWord = ''
|
||||||
|
wrappedLines = currText.split('\n')
|
||||||
|
currLine = wrappedLines[y]
|
||||||
|
Found = False
|
||||||
|
while(not Found):
|
||||||
|
if not currLine[x] in string.whitespace:
|
||||||
|
if x == 0:
|
||||||
|
Found = True
|
||||||
|
else:
|
||||||
|
if currLine[x - 1] in string.whitespace:
|
||||||
|
Found = True
|
||||||
|
if not Found:
|
||||||
|
if x - 1 < 0:
|
||||||
|
if y - 1 < 0:
|
||||||
|
lineBreak = False
|
||||||
|
endOfScreen = True
|
||||||
|
return currX, currY, '', endOfScreen, lineBreak
|
||||||
|
else:
|
||||||
|
y -= 1
|
||||||
|
currLine = wrappedLines[y]
|
||||||
|
x = len( wrappedLines[y]) - 1
|
||||||
|
lineBreak = True
|
||||||
|
else:
|
||||||
|
x -= 1
|
||||||
|
if Found:
|
||||||
|
currWord = currLine[x:]
|
||||||
|
for d in string.whitespace:
|
||||||
|
delimiterPos = currWord.find(d)
|
||||||
|
if delimiterPos != -1:
|
||||||
|
currWord = currWord[:delimiterPos]
|
||||||
|
|
||||||
|
return x, y, currWord, endOfScreen, lineBreak
|
||||||
|
return currX, currY, '', False, False
|
||||||
|
|
||||||
|
def getNextWord(currX,currY, currText):
|
||||||
|
lineBreak = False
|
||||||
|
endOfScreen = False
|
||||||
|
if currText == '':
|
||||||
|
return -1, -1, '', endOfScreen, lineBreak
|
||||||
|
if currText.strip( string.whitespace) == '':
|
||||||
|
return currX, currY, '', endOfScreen, lineBreak
|
||||||
|
x = currX
|
||||||
|
y = currY
|
||||||
|
currWord = ''
|
||||||
|
wrappedLines = currText.split('\n')
|
||||||
|
currLine = wrappedLines[y]
|
||||||
|
Found = False
|
||||||
|
while(not Found):
|
||||||
|
if not Found:
|
||||||
|
if x + 1 > len( currLine ) - 1:
|
||||||
|
if y + 1 > len( wrappedLines ) - 1:
|
||||||
|
lineBreak = False
|
||||||
|
endOfScreen = True
|
||||||
|
return currX, currY, '', endOfScreen, lineBreak
|
||||||
|
else:
|
||||||
|
y += 1
|
||||||
|
currLine = wrappedLines[y]
|
||||||
|
x = 0
|
||||||
|
lineBreak = True
|
||||||
|
else:
|
||||||
|
x += 1
|
||||||
|
if not currLine[x] in string.whitespace:
|
||||||
|
if x == 0:
|
||||||
|
Found = True
|
||||||
|
else:
|
||||||
|
if currLine[x - 1] in string.whitespace:
|
||||||
|
Found = True
|
||||||
|
if Found:
|
||||||
|
currWord = currLine[x:]
|
||||||
|
for d in string.whitespace:
|
||||||
|
delimiterPos = currWord.find(d)
|
||||||
|
if delimiterPos != -1:
|
||||||
|
currWord = currWord[:delimiterPos]
|
||||||
|
return x, y, currWord, endOfScreen, lineBreak
|
||||||
|
return currX, currY, '', False, False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
data = """das ist ein test lol
|
||||||
|
das ist ein test l
|
||||||
|
das ist ein test
|
||||||
|
|
||||||
|
asdf asdf a
|
||||||
|
test test
|
||||||
|
te test"""
|
||||||
|
print('__DATA START__')
|
||||||
|
print(data)
|
||||||
|
print('__DATA END__\n\n')
|
||||||
|
|
||||||
|
x = 3
|
||||||
|
y = 0
|
||||||
|
x, y, currWord, endOfScreen, lineBreak = getCurrentWord(x,y,data)
|
||||||
|
print(x,y,currWord)
|
||||||
|
|
19
play zone/writeBrl.py
Executable file
19
play zone/writeBrl.py
Executable file
@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/python
|
||||||
|
|
||||||
|
import brlapi
|
||||||
|
import time
|
||||||
|
|
||||||
|
brl = brlapi.Connection()
|
||||||
|
brl.enterTtyModeWithPath()
|
||||||
|
print('display size' + str(brl.displaySize))
|
||||||
|
print('driver name'+str(brl.driverName))
|
||||||
|
|
||||||
|
t = time.time()
|
||||||
|
#while(time.time() - t <= 5):
|
||||||
|
try:
|
||||||
|
brl.writeText( 'this is a 5 second test')
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
time.sleep(5)
|
||||||
|
brl.leaveTtyMode()
|
||||||
|
|
71
realese nots/1.9
Normal file
71
realese nots/1.9
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
Cleanups:
|
||||||
|
[X] re.sub(' +,' ',text) -> text.lstrip()? check this?
|
||||||
|
- inheritation for drivers
|
||||||
|
[X] Speech (All)
|
||||||
|
[X] Braille (All)
|
||||||
|
[X] Sound (All)
|
||||||
|
[X] Input (All)
|
||||||
|
[X] Screen (All)
|
||||||
|
- generic list or see Tutorial mode list (convert clipboard management) (Easy for contribution) - core.memoryManager
|
||||||
|
[X] next item
|
||||||
|
[X] prev item
|
||||||
|
[X] curr item
|
||||||
|
[X] first item
|
||||||
|
[X] last item
|
||||||
|
General:
|
||||||
|
[X] make it runable using pypy3
|
||||||
|
[X] play sound on plugging device
|
||||||
|
[X] interrupt speech while entering an ignored screen
|
||||||
|
[X] read ignorescreens from an file to be able to halt fenrir from outside
|
||||||
|
- commands
|
||||||
|
[X] place last spoken to clipboard (Easy for contribution)
|
||||||
|
- Improvend Headline Seperator and Multible Char Support
|
||||||
|
[X]read "13 #" insteed of ###################
|
||||||
|
- autospeak indentation changes (useful for python programming)
|
||||||
|
Braille Support:
|
||||||
|
Driver:
|
||||||
|
[X] evdev InputDriver
|
||||||
|
[X] grab/ ungrab devices on ignored screens
|
||||||
|
Driver (screen, input):
|
||||||
|
[X] PTY Screen driver (to use gnome-terminal and other terminal emulators)
|
||||||
|
[X] emulation
|
||||||
|
[X] basic reading
|
||||||
|
[X] detect colum/ lines
|
||||||
|
[X] resize on colum / line change
|
||||||
|
[X] make shell command configurable (or detect it)
|
||||||
|
[X] stop emulation properly
|
||||||
|
[X] attributes
|
||||||
|
[X] unify hilgight tracking
|
||||||
|
[X] make pasteing text work again
|
||||||
|
[X] make double tap work again
|
||||||
|
[X] new event for byte shortcuts (escape sequences)
|
||||||
|
[X] create driver
|
||||||
|
[X] handle byte shortcuts
|
||||||
|
[X] detect shortcuts
|
||||||
|
[X] Load escape sequence shortcuts
|
||||||
|
[X] controll modes (vim like mode to not collide with application shortcuts)
|
||||||
|
[X] create keyboard layout
|
||||||
|
[X]set flag that it is used in emulation
|
||||||
|
[X] write/ consume them (controll it at all)
|
||||||
|
https://docs.python.org/3.2/library/pty.html
|
||||||
|
http://sqizit.bartletts.id.au/2011/02/14/pseudo-terminals-in-python/
|
||||||
|
https://blog.konpat.me/pythons-pseudo-terminal-pty-examples/
|
||||||
|
|
||||||
|
[X] make generic speech driver default
|
||||||
|
[X] pyttsx3 speech driver
|
||||||
|
- get information already in watchdogs insteed of mainloop (use eventloop to transport)
|
||||||
|
[X] InputDriver
|
||||||
|
Settings:
|
||||||
|
Application Profiles:
|
||||||
|
Translation:
|
||||||
|
- German (thanks to schulle4u and Jenny) https://robbinaer.info/index.php?article101/fenrir
|
||||||
|
Fixes:
|
||||||
|
- no shell in generic speech Driver
|
||||||
|
- imporove validity checks for speech driver
|
||||||
|
- handle thread and process shutdown more gracefully
|
||||||
|
- cleanup
|
||||||
|
- a lot more fixes
|
||||||
|
- better device detection
|
||||||
|
[X] (not conflict with other applications) find . -iname "*.py" -exec sed 's/from \(core.*\) import/from fenrir-screenreader.\1 import/g' {} \;
|
||||||
|
|
||||||
|
|
9
realese nots/1.9.2
Normal file
9
realese nots/1.9.2
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
- import clipboard from x (xclip)
|
||||||
|
- barrier mode (respect pseudo cli window borders like used in dialog or pdmenu)
|
||||||
|
- toggle for barrier mode
|
||||||
|
- soundicon for barrier mode when enter and leave the barrier detection
|
||||||
|
- imporove accuracy of speak history (arrow up/ down in bash)
|
||||||
|
- higher accuracy for hilight tracking
|
||||||
|
- soundicon for attribute
|
||||||
|
- overall improved attribute code
|
||||||
|
- variouse speedups and bugfixes
|
34
splits.txt
Normal file
34
splits.txt
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
./play zone/wrapWord.py:21: wrappedLines = currText.split('\n')
|
||||||
|
./play zone/wrapWord.py:50: wrappedLines = currText.split('\n')
|
||||||
|
./play zone/wrapWord.py:93: wrappedLines = currText.split('\n')
|
||||||
|
./src/fenrirscreenreader/screenDriver/vcsaDriver.py:281: apps = subprocess.Popen('ps -t tty' + currScreen + ' -o comm,tty,stat', shell=True, stdout=subprocess.PIPE).stdout.read().decode()[:-1].split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/line_utils.py:14: wrappedLines = currText.split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/line_utils.py:30: wrappedLines = currText.split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/line_utils.py:41: wrappedLines = currText.split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/char_utils.py:14: wrappedLines = currText.split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/char_utils.py:35: wrappedLines = currText.split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/char_utils.py:43: wrappedLines = currText.split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/char_utils.py:58: wrappedLines = currText.split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/char_utils.py:73: wrappedLines = currText.split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/char_utils.py:85: wrappedLines = currText.split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/mark_utils.py:13: inText = inText.split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/mark_utils.py:59: inText = inText.split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/word_utils.py:20: wrappedLines = currText.split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/word_utils.py:62: wrappedLines = currText.split('\n')
|
||||||
|
./src/fenrirscreenreader/utils/word_utils.py:91: wrappedLines = currText.split('\n')
|
||||||
|
./src/fenrirscreenreader/core/outputManager.py:173: currline = text.split('\n')[offset['y']]
|
||||||
|
./src/fenrirscreenreader/core/attributeManager.py:250: textLines = text.split('\n')
|
||||||
|
./src/fenrirscreenreader/core/screenManager.py:166: diffList = ['+ ' + self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] +'\n']
|
||||||
|
./src/fenrirscreenreader/core/screenManager.py:169: diff = self.differ.compare(oldScreenText.split('\n'),\
|
||||||
|
./src/fenrirscreenreader/core/screenManager.py:170: newScreenText.split('\n'))
|
||||||
|
./src/fenrirscreenreader/core/screenManager.py:225: windowList = text.split('\n')
|
||||||
|
./src/fenrirscreenreader/commands/onCursorChange/62000-spell_check.py:66: newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
|
||||||
|
./src/fenrirscreenreader/commands/onCursorChange/60000-word_echo_type.py:39: newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
|
||||||
|
./src/fenrirscreenreader/commands/onCursorChange/50000-present_char_if_cursor_change_horizontal.py:41: newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
|
||||||
|
./src/fenrirscreenreader/commands/onCursorChange/61000-word_echo_navigation.py:37: newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
|
||||||
|
./src/fenrirscreenreader/commands/commands/spell_check.py:47: newContent = self.env['screen']['newContentText'].split('\n')[cursorPos['y']]
|
||||||
|
./src/fenrirscreenreader/commands/commands/remove_word_from_spell_check.py:45: newContent = self.env['screen']['newContentText'].split('\n')[cursorPos['y']]
|
||||||
|
./src/fenrirscreenreader/commands/commands/add_word_to_spell_check.py:43: newContent = self.env['screen']['newContentText'].split('\n')[cursorPos['y']]
|
||||||
|
./src/fenrirscreenreader/commands/onScreenUpdate/60000-history.py:38: prevLine = self.env['screen']['oldContentText'].split('\n')[self.env['screen']['newCursor']['y']]
|
||||||
|
./src/fenrirscreenreader/commands/onScreenUpdate/60000-history.py:39: currLine = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
|
||||||
|
./TODO v2.0:72: w.fill(i).split('\n')
|
@ -0,0 +1,58 @@
|
|||||||
|
#!/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Fenrir TTY screen reader
|
||||||
|
# By Chrys, Storm Dragon, and contributers.
|
||||||
|
|
||||||
|
from fenrirscreenreader.core import debug
|
||||||
|
from fenrirscreenreader.utils import word_utils
|
||||||
|
import string
|
||||||
|
|
||||||
|
class command():
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
def initialize(self, environment):
|
||||||
|
self.env = environment
|
||||||
|
def shutdown(self):
|
||||||
|
pass
|
||||||
|
def getDescription(self):
|
||||||
|
return 'No Description found'
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
# is it enabled?
|
||||||
|
if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'wordEcho'):
|
||||||
|
return
|
||||||
|
# is naviation?
|
||||||
|
if self.env['screen']['newCursor']['x'] - self.env['screen']['oldCursor']['x'] != 1:
|
||||||
|
return
|
||||||
|
# just when cursor move worddetection is needed
|
||||||
|
if not self.env['runtime']['cursorManager'].isCursorHorizontalMove():
|
||||||
|
return
|
||||||
|
# for now no new line
|
||||||
|
if self.env['runtime']['cursorManager'].isCursorVerticalMove():
|
||||||
|
return
|
||||||
|
# currently writing
|
||||||
|
if self.env['runtime']['screenManager'].isDelta():
|
||||||
|
return
|
||||||
|
|
||||||
|
# get the word
|
||||||
|
newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
|
||||||
|
x, y, currWord, endOfScreen, lineBreak = \
|
||||||
|
word_utils.getCurrentWord(self.env['screen']['newCursor']['x'], 0, newContent)
|
||||||
|
|
||||||
|
# is there a word?
|
||||||
|
if currWord == '':
|
||||||
|
return
|
||||||
|
# at the end of a word
|
||||||
|
if not newContent[self.env['screen']['newCursor']['x']].isspace():
|
||||||
|
return
|
||||||
|
# at the end of a word
|
||||||
|
if (x + len(currWord) != self.env['screen']['newCursor']['x']) and \
|
||||||
|
(x + len(currWord) != self.env['screen']['newCursor']['x']-1):
|
||||||
|
return
|
||||||
|
|
||||||
|
self.env['runtime']['outputManager'].presentText(currWord, interrupt=True, flush=False)
|
||||||
|
|
||||||
|
def setCallback(self, callback):
|
||||||
|
pass
|
||||||
|
|
Loading…
Reference in New Issue
Block a user