Package x2go :: Module pulseaudio
[frames] | no frames]

Source Code for Module x2go.pulseaudio

  1  # -*- coding: utf-8 -*- 
  2   
  3  # Copyright (C) 2010-2011 by Mike Gabriel <mike.gabriel@das-netzwerkteam.de> 
  4  # 
  5  # Python X2go is free software; you can redistribute it and/or modify 
  6  # it under the terms of the GNU General Public License as published by 
  7  # the Free Software Foundation; either version 3 of the License, or 
  8  # (at your option) any later version. 
  9  # 
 10  # Python X2go is distributed in the hope that it will be useful, 
 11  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 13  # GNU General Public License for more details. 
 14  # 
 15  # You should have received a copy of the GNU General Public License 
 16  # along with this program; if not, write to the 
 17  # Free Software Foundation, Inc., 
 18  # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. 
 19  # 
 20  # Other contributors: 
 21  #       none so far 
 22   
 23  """\ 
 24  X2goPulseAudio class - a Pulseaudio daemon guardian thread. 
 25   
 26  """ 
 27   
 28  __NAME__ = 'x2gopulseaudio-pylib' 
 29   
 30  from defaults import X2GOCLIENT_OS as _X2GOCLIENT_OS 
 31  if _X2GOCLIENT_OS == 'Windows': 
 32      import wmi 
 33      import win32process 
 34      import win32con 
 35      import win32event 
 36   
 37  # modules 
 38  import os 
 39  import subprocess 
 40  import threading 
 41  import gevent 
 42  import copy 
 43   
 44  # Python X2go modules 
 45  import log 
 46   
47 -class X2goPulseAudio(threading.Thread):
48 """ 49 This class controls the Pulse Audio daemon. 50 """ 51
52 - def __init__(self, path=None, client_instance=None, logger=None, loglevel=log.loglevel_DEFAULT):
53 """\ 54 Initialize a Pulse Audio daemon instance. 55 56 @param path: full path to pulseaudio.exe 57 @type path: C{str} 58 @param client_instance: the calling L{X2goClient} instance 59 @type client_instance: L{X2goClient} instance 60 @param logger: you can pass an L{X2goLogger} object to the L{X2goClientXConfig} constructor 61 @type logger: C{instance} 62 @param loglevel: if no L{X2goLogger} object has been supplied a new one will be 63 constructed with the given loglevel 64 @type loglevel: C{int} 65 66 """ 67 if _X2GOCLIENT_OS not in ("Windows"): 68 import exceptions 69 class OSNotSupportedException(exceptions.StandardError): pass 70 raise OSNotSupportedException('classes of x2go.pulseaudio module are for Windows only') 71 72 if logger is None: 73 self.logger = log.X2goLogger(loglevel=loglevel) 74 else: 75 self.logger = copy.deepcopy(logger) 76 self.logger.tag = __NAME__ 77 78 self.path = path 79 self.client_instance = client_instance 80 self._keepalive = None 81 82 threading.Thread.__init__(self) 83 self.daemon = True 84 self.start()
85
86 - def run(self):
87 """\ 88 This method is called once the C{X2goPulseAudio.start()} method has been called. To tear 89 down the Pulseaudio daemon call the L{X2goPulseAudio.stop_thread()} method. 90 91 """ 92 self._keepalive = True 93 cmd = 'pulseaudio.exe' 94 cmd_options = [ 95 '-n', 96 '-L module-native-protocol-tcp port=4713', 97 '-L module-esound-protocol-tcp port=16001', 98 '-L module-waveout', 99 ] 100 cmd_options = " %s" % " ".join(cmd_options) 101 self.logger('starting PulseAudio server with command line: %s%s' % (cmd, cmd_options), loglevel=log.loglevel_DEBUG) 102 103 si = win32process.STARTUPINFO() 104 p_info = win32process.CreateProcess(None, 105 '%s\\%s %s' % (self.path, cmd, cmd_options), 106 None, 107 None, 108 0, 109 win32con.CREATE_NO_WINDOW|win32process.NORMAL_PRIORITY_CLASS, 110 None, 111 None, 112 si, 113 ) 114 (hProcess, hThread, processId, threadId) = p_info 115 116 gevent.sleep(5) 117 rc = win32event.WaitForMultipleObjects([hProcess], 118 1, 119 1, # wait just one millisec 120 ) 121 _is_alive = ( rc != win32event.WAIT_OBJECT_0 ) 122 if self.client_instance and not _is_alive: 123 if os.environ.has_key('CLIENTNAME'): 124 self.client_instance.HOOK_pulseaudio_not_supported_in_RDPsession() 125 else: 126 self.client_instance.HOOK_pulseaudio_server_startup_failed() 127 128 while self._keepalive and _is_alive: 129 gevent.sleep(1) 130 rc = win32event.WaitForMultipleObjects([hProcess], 131 1, 132 1, # wait just one millisec 133 ) 134 _is_alive = ( rc != win32event.WAIT_OBJECT_0 ) 135 if self.client_instance and not _is_alive: 136 self.client_instance.HOOK_pulseaudio_server_died() 137 138 self.logger('terminating running PulseAudio server', loglevel=log.loglevel_DEBUG) 139 140 # there is no real kill command on Windows... 141 self.logger('PulseAudio process ID to terminate: %s' % processId, loglevel=log.loglevel_DEBUG) 142 try: 143 win32process.TerminateProcess(hProcess, 0) 144 except win32process.error: 145 pass
146
147 - def stop_thread(self):
148 """\ 149 Tear down a running Pulseaudio daemon. 150 151 """ 152 self.logger('stop_thread() method has been called', loglevel=log.loglevel_DEBUG) 153 self._keepalive = False
154