forked from albertz/music-player
-
Notifications
You must be signed in to change notification settings - Fork 0
/
stdinconsole.py
127 lines (106 loc) · 2.96 KB
/
stdinconsole.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
from utils import *
import sys, os
stdinQueue = OnRequestQueue()
def readNextInput():
ch = os.read(sys.stdin.fileno(),7)
stdinQueue.put(ch)
oldTermios = None
def setTtyNoncanonical(fd, timeout=0):
global oldTermios
import termios
old = termios.tcgetattr(fd)
if not oldTermios: oldTermios = old
new = termios.tcgetattr(fd)
new[3] = new[3] & ~termios.ICANON & ~termios.ECHO
# http://www.unixguide.net/unix/programming/3.6.2.shtml
#new[6] [termios.VMIN] = 1
#new[6] [termios.VTIME] = 0
new[6] [termios.VMIN] = 0 if timeout > 0 else 1
timeout *= 10 # 10ths of second
if timeout > 0 and timeout < 1: timeout = 1
new[6] [termios.VTIME] = timeout
termios.tcsetattr(fd, termios.TCSANOW, new)
termios.tcsendbreak(fd,0)
def restoreTty(fd):
if oldTermios:
import termios
termios.tcsetattr(fd, termios.TCSANOW, oldTermios)
termios.tcsendbreak(fd, 0)
from State import state, reloadModules
def printState():
if state.curSong:
try:
print os.path.basename(state.curSong.url) + " : " + \
formatTime(state.player.curSongPos) + " / " + \
formatTime(state.player.curSongLen)
except:
print "song ???"
else:
print "no song"
def handleInput(ch):
if ch == "q" or ch == "\0" or ch == "":
print "stdin: quit"
state.quit()
try:
if ch == "\x1b[D": # left
state.player.seekRel(-10)
printState()
elif ch == "\x1b[C": #right
state.player.seekRel(10)
printState()
elif ch == "\n": # return
state.nextSong()
elif ch == " ":
state.playPause()
elif ch == "r":
reloadModules()
except:
sys.excepthook(*sys.exc_info())
def stdinconsoleMain():
import appinfo
if appinfo.args.shell:
print "Setting up Python shell interface"
# This is hacky for now but actually I don't really know a better way.
# The problem is that the main thread might be used by the GUI.
# Thus, we can only cancel this here via the shell itself.
from better_exchook import debug_shell
from queue import queue
import utils
shellGlobals = {
"state": state,
"queue": queue,
}
shellGlobals.update(utils.__dict__)
debug_shell(
shellGlobals, shellGlobals,
execWrapper=utils.do_in_mainthread)
# The shell exited. Quit.
state.quit()
return
fd = sys.stdin.fileno()
if not os.isatty(fd): return # don't do anything
try:
# This import will fail if there is no GUI.
import gui
except: # no GUI
# the main thread is pushing stdin updates to stdinQueue.
setTtyNoncanonical(sys.stdin.fileno())
print "stdin input ready"
for ch in stdinQueue.read():
handleInput(ch)
else:
# No stdin handling when we have a GUI
return
# the GUI is handling the main thread.
# it means we dont get stdinQueue updates here.
# as we need a way to be able to cancel this,
# we only can frequently check with a timeout here.
setTtyNoncanonical(fd, timeout=1)
from threading import currentThread
thread = currentThread()
print "stdin input ready"
while not thread.cancel:
ch = os.read(fd,7)
if ch:
handleInput(ch)
restoreTty(fd)