#!/usr/bin/python2 import subprocess import os import time import sys import signal import select import errno import inspect from SimpleXMLRPCServer import SimpleXMLRPCServer projection_process = None default_task = [ './brause.py', 'file://%s' % os.path.join(os.path.abspath(os.path.dirname(__file__)), 'default_page', 'index.html') ] projection_task = default_task class ChildProcess(subprocess.Popen): def __init__(self, *args, **kwargs): subprocess.Popen.__init__(self, *args, **kwargs) self._kill = os.kill def __del__(self): try: self._kill(self.pid, 9) self.poll() except EnvironmentError as e: if e.args[0] != errno.ESRCH: raise def restart_projection(dummy=None): global projection_process global projection_task print "Replacing projection_process..." projection_process = ChildProcess(projection_task) def sigchld(signum, trace): global projection_process print "Got SIGCHLD" if projection_process is not None and \ projection_process.poll() is None: # This info was not about the current projection_process... return # Current projection_process exited, fallback to default reset_projection() def display_url(url): global projection_task projection_task = [ './brause.py', url ] restart_projection() return 0 # For RPC def display_video(url): global projection_task if not (url.startswith('http://') or \ url.startswith('ftp://')): raise ValueError('URL should point to a http/ftp resource...') projection_task = [ 'mplayer', '-fs', '-vo', 'x11', '-ao', 'pulse', url ] restart_projection() return 0 # For RPC def reset_projection(): global projection_task global default_task projection_task = default_task restart_projection() return 0 # For RPC def start_vnc(port): global projection_task if type(port) is not int: raise TypeError("start_vnc expects (port:int) as arguments") # Worst Monkey Patch ever (tm) host = inspect.stack()[3][0].f_locals['self'].client_address[0] print 'Connecting vncviewer to %s:%d' % (host,port) projection_task = [ "vncviewer", "-fullscreen", "-viewonly", "%s::%d" % (host,port) ] restart_projection() return 0 def main(): global projecting subprocess.check_call("xset s off".split()) subprocess.check_call("xset -dpms".split()) signal.signal(signal.SIGCHLD, sigchld) restart_projection() server = SimpleXMLRPCServer(("0.0.0.0", 8082)) server.register_function(display_url) server.register_function(display_video) server.register_function(reset_projection) server.register_function(start_vnc) while True: try: server.serve_forever() except select.error as e: if e.args[0] == errno.EINTR: continue raise if __name__ == '__main__': main()