def open_wine_terminal(terminal, wine_path, prefix, env): aliases = { "wine": wine_path, "winecfg": wine_path + "cfg", "wineserver": wine_path + "server", "wineboot": wine_path + "boot", } env["WINEPREFIX"] = prefix shell_command = get_shell_command(prefix, env, aliases) terminal = terminal or system.get_default_terminal() system.execute([system.get_default_terminal(), "-e", shell_command])
def execute(self, data): """Run an executable file""" args = [] if isinstance(data, dict): self._check_required_params('file', data, 'execute') file_ref = data['file'] args_string = data.get('args', '') for arg in shlex.split(args_string): args.append(self._substitute(arg)) else: file_ref = data # Determine whether 'file' value is a file id or a path exec_path = self._get_file(file_ref) or self._substitute(file_ref) if not exec_path: raise ScriptingError("Unable to find file %s" % file_ref, file_ref) if not os.path.exists(exec_path): raise ScriptingError("Unable to find required executable", exec_path) self.chmodx(exec_path) terminal = data.get('terminal') if terminal: terminal = system.get_default_terminal() command = [exec_path] + args logger.debug("Executing %s" % command) thread = LutrisThread(command, env=get_runtime_env(), term=terminal) thread.run()
def execute(self, data): """Run an executable file.""" args = [] if isinstance(data, dict): self._check_required_params("file", data, "execute") file_ref = data["file"] args_string = data.get("args", "") for arg in shlex.split(args_string): args.append(self._substitute(arg)) else: file_ref = data # Determine whether 'file' value is a file id or a path exec_path = self._get_file(file_ref) or self._substitute(file_ref) if not exec_path: raise ScriptingError("Unable to find file %s" % file_ref, file_ref) if not os.path.exists(exec_path): raise ScriptingError("Unable to find required executable", exec_path) self.chmodx(exec_path) terminal = data.get("terminal") if terminal: terminal = system.get_default_terminal() command = [exec_path] + args logger.debug("Executing %s" % command) thread = LutrisThread(command, env=runtime.get_env(), term=terminal, cwd=self.target_path) self.abort_current_task = thread.killall thread.run() self.abort_current_task = None
def get_terminal(self): """Return the terminal used to run the game into or None if the game is not run from a terminal. Remember that only games using text mode should use the terminal. """ if self.runner.system_config.get("terminal"): terminal = self.runner.system_config.get("terminal_app", system.get_default_terminal()) if terminal and not system.find_executable(terminal): raise GameConfigError(_("The selected terminal application could not be launched:\n%s") % terminal) return terminal
def execute(self, data): """Run an executable file.""" args = [] terminal = None working_dir = None if isinstance(data, dict): self._check_required_params('file', data, 'execute') file_ref = data['file'] args_string = data.get('args', '') for arg in shlex.split(args_string): args.append(self._substitute(arg)) terminal = data.get('terminal') working_dir = data.get('working_dir') else: file_ref = data # Determine whether 'file' value is a file id or a path exec_path = self._get_file(file_ref) or self._substitute(file_ref) if not exec_path: raise ScriptingError("Unable to find file %s" % file_ref, file_ref) if not os.path.exists(exec_path): raise ScriptingError("Unable to find required executable", exec_path) if not os.access(exec_path, os.X_OK): self.chmodx(exec_path) if terminal: terminal = system.get_default_terminal() if not working_dir or not os.path.exists(working_dir): working_dir = self.target_path command = [exec_path] + args logger.debug("Executing %s" % command) thread = LutrisThread(command, env=runtime.get_env(), term=terminal, cwd=self.target_path, watch=False) self.abort_current_task = thread.killall thread.run() self.abort_current_task = None
"type": "bool", "default": False, "advanced": True, "help": "Run the game in a new terminal window.", }, { "option": "terminal_app", "label": "Terminal application", "type": "choice_with_entry", "choices": system.get_terminal_apps, "default": system.get_default_terminal(), "advanced": True, "help": ("The terminal emulator to be run with the previous option." "Choose from the list of detected terminal apps or enter " "the terminal's command or path." "Note: Not all terminal emulators are guaranteed to work."), }, { "option": "env", "type": "mapping", "label": "Environment variables", "help": "Environment variables loaded at run time", }, { "option":
def do_play(self, prelaunched, _error=None): if not prelaunched: self.state = self.STATE_STOPPED return system_config = self.runner.system_config self.original_outputs = display.get_outputs() gameplay_info = self.runner.play() env = {} logger.debug("Launching %s: %s" % (self.name, gameplay_info)) if 'error' in gameplay_info: show_error_message(gameplay_info) self.state = self.STATE_STOPPED return sdl_video_fullscreen = system_config.get('sdl_video_fullscreen') or '' env['SDL_VIDEO_FULLSCREEN_DISPLAY'] = sdl_video_fullscreen restrict_to_display = system_config.get('display') if restrict_to_display != 'off': display.turn_off_except(restrict_to_display) time.sleep(3) self.resolution_changed = True resolution = system_config.get('resolution') if resolution != 'off': display.change_resolution(resolution) time.sleep(3) self.resolution_changed = True if system_config.get('reset_pulse'): audio.reset_pulse() self.killswitch = system_config.get('killswitch') if self.killswitch and not os.path.exists(self.killswitch): # Prevent setting a killswitch to a file that doesn't exists self.killswitch = None # Command launch_arguments = gameplay_info['command'] primusrun = system_config.get('primusrun') if primusrun and system.find_executable('primusrun'): launch_arguments.insert(0, 'primusrun') xephyr = system_config.get('xephyr') or 'off' if xephyr != 'off': if xephyr == '8bpp': xephyr_depth = '8' else: xephyr_depth = '16' xephyr_resolution = system_config.get('xephyr_resolution') or '640x480' xephyr_command = ['Xephyr', ':2', '-ac', '-screen', xephyr_resolution + 'x' + xephyr_depth, '-glamor', '-reset', '-terminate', '-fullscreen'] xephyr_thread = LutrisThread(xephyr_command) xephyr_thread.start() time.sleep(3) env['DISPLAY'] = ':2' if system_config.get('use_us_layout'): setxkbmap_command = ['setxkbmap', '-model', 'pc101', 'us', '-print'] xkbcomp_command = ['xkbcomp', '-', os.environ.get('DISPLAY', ':0')] xkbcomp = subprocess.Popen(xkbcomp_command, stdin=subprocess.PIPE) subprocess.Popen(setxkbmap_command, env=os.environ, stdout=xkbcomp.stdin).communicate() xkbcomp.communicate() pulse_latency = system_config.get('pulse_latency') if pulse_latency: env['PULSE_LATENCY_MSEC'] = '60' prefix_command = system_config.get("prefix_command") or '' if prefix_command.strip(): launch_arguments.insert(0, prefix_command) single_cpu = system_config.get('single_cpu') or False if single_cpu: logger.info('The game will run on a single CPU core') launch_arguments.insert(0, '0') launch_arguments.insert(0, '-c') launch_arguments.insert(0, 'taskset') terminal = system_config.get('terminal') if terminal: terminal = system_config.get("terminal_app", system.get_default_terminal()) if terminal and not system.find_executable(terminal): dialogs.ErrorDialog("The selected terminal application " "could not be launched:\n" "%s" % terminal) self.state = self.STATE_STOPPED return # Env vars game_env = gameplay_info.get('env') or {} env.update(game_env) system_env = system_config.get('env') or {} env.update(system_env) ld_preload = gameplay_info.get('ld_preload') or '' env["LD_PRELOAD"] = ld_preload # Runtime management ld_library_path = "" if self.runner.use_runtime(): runtime_env = runtime.get_env() if 'STEAM_RUNTIME' in runtime_env and 'STEAM_RUNTIME' not in env: env['STEAM_RUNTIME'] = runtime_env['STEAM_RUNTIME'] if 'LD_LIBRARY_PATH' in runtime_env: ld_library_path = runtime_env['LD_LIBRARY_PATH'] game_ld_libary_path = gameplay_info.get('ld_library_path') if game_ld_libary_path: if not ld_library_path: ld_library_path = '$LD_LIBRARY_PATH' ld_library_path = ":".join(game_ld_libary_path, ld_library_path) env["LD_LIBRARY_PATH"] = ld_library_path # /Env vars self.game_thread = LutrisThread(launch_arguments, runner=self.runner, env=env, rootpid=gameplay_info.get('rootpid'), term=terminal) if hasattr(self.runner, 'stop'): self.game_thread.set_stop_command(self.runner.stop) self.game_thread.start() self.state = self.STATE_RUNNING if 'joy2key' in gameplay_info: self.joy2key(gameplay_info['joy2key']) xboxdrv_config = system_config.get('xboxdrv') if xboxdrv_config: self.xboxdrv_start(xboxdrv_config) self.heartbeat = GLib.timeout_add(HEARTBEAT_DELAY, self.beat)
def do_play(self, prelaunched, _error=None): if not prelaunched: self.state = self.STATE_STOPPED return system_config = self.runner.system_config self.original_outputs = display.get_outputs() gameplay_info = self.runner.play() env = {} logger.debug("Launching %s: %s" % (self.name, gameplay_info)) if 'error' in gameplay_info: self.show_error_message(gameplay_info) self.state = self.STATE_STOPPED return sdl_video_fullscreen = system_config.get('sdl_video_fullscreen') or '' env['SDL_VIDEO_FULLSCREEN_DISPLAY'] = sdl_video_fullscreen restrict_to_display = system_config.get('display') if restrict_to_display != 'off': display.turn_off_except(restrict_to_display) time.sleep(3) self.resolution_changed = True resolution = system_config.get('resolution') if resolution != 'off': display.change_resolution(resolution) time.sleep(3) self.resolution_changed = True if system_config.get('reset_pulse'): audio.reset_pulse() self.killswitch = system_config.get('killswitch') if self.killswitch and not os.path.exists(self.killswitch): # Prevent setting a killswitch to a file that doesn't exists self.killswitch = None # Command launch_arguments = gameplay_info['command'] primusrun = system_config.get('primusrun') if primusrun and system.find_executable('primusrun'): launch_arguments.insert(0, 'primusrun') xephyr = system_config.get('xephyr') or 'off' if xephyr != 'off': if xephyr == '8bpp': xephyr_depth = '8' else: xephyr_depth = '16' xephyr_resolution = system_config.get('xephyr_resolution') or '640x480' xephyr_command = ['Xephyr', ':2', '-ac', '-screen', xephyr_resolution + 'x' + xephyr_depth, '-glamor', '-reset', '-terminate', '-fullscreen'] xephyr_thread = LutrisThread(xephyr_command) xephyr_thread.start() time.sleep(3) env['DISPLAY'] = ':2' if system_config.get('use_us_layout'): setxkbmap_command = ['setxkbmap', '-model', 'pc101', 'us', '-print'] xkbcomp_command = ['xkbcomp', '-', os.environ.get('DISPLAY', ':0')] xkbcomp = subprocess.Popen(xkbcomp_command, stdin=subprocess.PIPE) subprocess.Popen(setxkbmap_command, env=os.environ, stdout=xkbcomp.stdin).communicate() xkbcomp.communicate() pulse_latency = system_config.get('pulse_latency') if pulse_latency: env['PULSE_LATENCY_MSEC'] = '60' prefix_command = system_config.get("prefix_command") or '' if prefix_command.strip(): launch_arguments.insert(0, prefix_command) single_cpu = system_config.get('single_cpu') or False if single_cpu: logger.info('The game will run on a single CPU core') launch_arguments.insert(0, '0') launch_arguments.insert(0, '-c') launch_arguments.insert(0, 'taskset') terminal = system_config.get('terminal') if terminal: terminal = system_config.get("terminal_app", system.get_default_terminal()) if terminal and not system.find_executable(terminal): dialogs.ErrorDialog("The selected terminal application " "could not be launched:\n" "%s" % terminal) self.state = self.STATE_STOPPED return # Env vars game_env = gameplay_info.get('env') or {} env.update(game_env) system_env = system_config.get('env') or {} env.update(system_env) ld_preload = gameplay_info.get('ld_preload') or '' env["LD_PRELOAD"] = ld_preload # Runtime management ld_library_path = "" if self.runner.use_runtime(): runtime_env = runtime.get_env() if 'STEAM_RUNTIME' in runtime_env and 'STEAM_RUNTIME' not in env: env['STEAM_RUNTIME'] = runtime_env['STEAM_RUNTIME'] if 'LD_LIBRARY_PATH' in runtime_env: ld_library_path = runtime_env['LD_LIBRARY_PATH'] game_ld_libary_path = gameplay_info.get('ld_library_path') if game_ld_libary_path: if not ld_library_path: ld_library_path = '$LD_LIBRARY_PATH' ld_library_path = ":".join([game_ld_libary_path, ld_library_path]) env["LD_LIBRARY_PATH"] = ld_library_path # /Env vars self.game_thread = LutrisThread(launch_arguments, runner=self.runner, env=env, rootpid=gameplay_info.get('rootpid'), term=terminal) if hasattr(self.runner, 'stop'): self.game_thread.set_stop_command(self.runner.stop) self.game_thread.start() self.state = self.STATE_RUNNING if 'joy2key' in gameplay_info: self.joy2key(gameplay_info['joy2key']) xboxdrv_config = system_config.get('xboxdrv') if xboxdrv_config: self.xboxdrv_start(xboxdrv_config) self.heartbeat = GLib.timeout_add(HEARTBEAT_DELAY, self.beat)
def do_play(self, prelaunched, _error=None): if not prelaunched: self.state = self.STATE_STOPPED return system_config = self.runner.system_config self.original_outputs = sorted( display.get_outputs(), key=lambda e: e[0] == system_config.get('display') ) gameplay_info = self.runner.play() env = {} logger.debug("Launching %s: %s" % (self.name, gameplay_info)) if 'error' in gameplay_info: self.show_error_message(gameplay_info) self.state = self.STATE_STOPPED return sdl_gamecontrollerconfig = system_config.get('sdl_gamecontrollerconfig') if sdl_gamecontrollerconfig: path = os.path.expanduser(sdl_gamecontrollerconfig) if os.path.exists(path): with open(path, "r") as f: sdl_gamecontrollerconfig = f.read() env['SDL_GAMECONTROLLERCONFIG'] = sdl_gamecontrollerconfig sdl_video_fullscreen = system_config.get('sdl_video_fullscreen') or '' env['SDL_VIDEO_FULLSCREEN_DISPLAY'] = sdl_video_fullscreen restrict_to_display = system_config.get('display') if restrict_to_display != 'off': display.turn_off_except(restrict_to_display) time.sleep(3) self.resolution_changed = True resolution = system_config.get('resolution') if resolution != 'off': display.change_resolution(resolution) time.sleep(3) self.resolution_changed = True if system_config.get('reset_pulse'): audio.reset_pulse() self.killswitch = system_config.get('killswitch') if self.killswitch and not os.path.exists(self.killswitch): # Prevent setting a killswitch to a file that doesn't exists self.killswitch = None # Command launch_arguments = gameplay_info['command'] primusrun = system_config.get('primusrun') if primusrun and system.find_executable('primusrun'): launch_arguments.insert(0, 'primusrun') xephyr = system_config.get('xephyr') or 'off' if xephyr != 'off': if xephyr == '8bpp': xephyr_depth = '8' else: xephyr_depth = '16' xephyr_resolution = system_config.get('xephyr_resolution') or '640x480' xephyr_command = ['Xephyr', ':2', '-ac', '-screen', xephyr_resolution + 'x' + xephyr_depth, '-glamor', '-reset', '-terminate', '-fullscreen'] xephyr_thread = LutrisThread(xephyr_command) xephyr_thread.start() time.sleep(3) env['DISPLAY'] = ':2' if system_config.get('use_us_layout'): setxkbmap_command = ['setxkbmap', '-model', 'pc101', 'us', '-print'] xkbcomp_command = ['xkbcomp', '-', os.environ.get('DISPLAY', ':0')] xkbcomp = subprocess.Popen(xkbcomp_command, stdin=subprocess.PIPE) subprocess.Popen(setxkbmap_command, env=os.environ, stdout=xkbcomp.stdin).communicate() xkbcomp.communicate() pulse_latency = system_config.get('pulse_latency') if pulse_latency: env['PULSE_LATENCY_MSEC'] = '60' prefix_command = system_config.get("prefix_command") or '' if prefix_command: launch_arguments = shlex.split(os.path.expandvars(prefix_command)) + launch_arguments single_cpu = system_config.get('single_cpu') or False if single_cpu: logger.info('The game will run on a single CPU core') launch_arguments.insert(0, '0') launch_arguments.insert(0, '-c') launch_arguments.insert(0, 'taskset') terminal = system_config.get('terminal') if terminal: terminal = system_config.get("terminal_app", system.get_default_terminal()) if terminal and not system.find_executable(terminal): dialogs.ErrorDialog("The selected terminal application " "could not be launched:\n" "%s" % terminal) self.state = self.STATE_STOPPED return # Env vars game_env = gameplay_info.get('env') or {} env.update(game_env) ld_preload = gameplay_info.get('ld_preload') if (ld_preload): env["LD_PRELOAD"] = ld_preload game_ld_libary_path = gameplay_info.get('ld_library_path') if game_ld_libary_path: ld_library_path = env.get("LD_LIBRARY_PATH") if not ld_library_path: ld_library_path = '$LD_LIBRARY_PATH' ld_library_path = ":".join([game_ld_libary_path, ld_library_path]) env["LD_LIBRARY_PATH"] = ld_library_path # /Env vars include_processes = shlex.split(system_config.get('include_processes', '')) exclude_processes = shlex.split(system_config.get('exclude_processes', '')) monitoring_disabled = system_config.get('disable_monitoring') process_watch = not monitoring_disabled self.game_thread = LutrisThread(launch_arguments, runner=self.runner, env=env, rootpid=gameplay_info.get('rootpid'), watch=process_watch, term=terminal, log_buffer=self.log_buffer, include_processes=include_processes, exclude_processes=exclude_processes) if hasattr(self.runner, 'stop'): self.game_thread.set_stop_command(self.runner.stop) self.game_thread.start() self.state = self.STATE_RUNNING # xboxdrv setup xboxdrv_config = system_config.get('xboxdrv') if xboxdrv_config: self.xboxdrv_start(xboxdrv_config) if monitoring_disabled: logger.info("Process monitoring disabled") else: self.heartbeat = GLib.timeout_add(HEARTBEAT_DELAY, self.beat)
def execute(self, data): """Run an executable file.""" args = [] terminal = None working_dir = None env = {} if isinstance(data, dict): self._check_required_params([("file", "command")], data, "execute") if "command" in data and "file" in data: raise ScriptingError( "Parameters file and command can't be used " "at the same time for the execute command", data, ) file_ref = data.get("file", "") command = data.get("command", "") args_string = data.get("args", "") for arg in shlex.split(args_string): args.append(self._substitute(arg)) terminal = data.get("terminal") working_dir = data.get("working_dir") if not data.get("disable_runtime"): # Possibly need to handle prefer_system_libs here env.update(runtime.get_env()) # Loading environment variables set in the script env.update(self.script_env) # Environment variables can also be passed to the execute command local_env = data.get("env") or {} env.update({key: self._substitute(value) for key, value in local_env.items()}) include_processes = shlex.split(data.get("include_processes", "")) exclude_processes = shlex.split(data.get("exclude_processes", "")) elif isinstance(data, str): command = data include_processes = [] exclude_processes = [] else: raise ScriptingError("No parameters supplied to execute command.", data) if command: file_ref = "bash" args = ["-c", self._get_file(command.strip())] include_processes.append("bash") else: # Determine whether 'file' value is a file id or a path file_ref = self._get_file(file_ref) if system.path_exists(file_ref) and not system.is_executable(file_ref): logger.warning("Making %s executable", file_ref) system.make_executable(file_ref) exec_path = system.find_executable(file_ref) if not exec_path: raise ScriptingError("Unable to find executable %s" % file_ref) if terminal: terminal = system.get_default_terminal() if not working_dir or not os.path.exists(working_dir): working_dir = self.target_path command = MonitoredCommand( [exec_path] + args, env=env, term=terminal, cwd=working_dir, include_processes=include_processes, exclude_processes=exclude_processes, ) command.start() GLib.idle_add(self.parent.attach_logger, command) self.heartbeat = GLib.timeout_add(1000, self._monitor_task, command) return "STOP"
'help': "Switch to this screen resolution while the game is running." }, { 'option': 'terminal', 'label': "Run in a terminal", 'type': 'bool', 'default': False, 'advanced': True, 'help': "Run the game in a new terminal window." }, { 'option': 'terminal_app', 'label': "Terminal application", 'type': 'choice_with_entry', 'choices': system.get_terminal_apps(), 'default': system.get_default_terminal(), 'advanced': True, 'help': ("The terminal emulator to be run with the previous option." "Choose from the list of detected terminal apps or enter " "the terminal's command or path." "Note: Not all terminal emulators are guaranteed to work.") }, { 'option': 'prefix_command', 'type': 'string', 'label': 'Command prefix', 'advanced': True, 'help': ("Command line instructions to add in front of the game's " "execution command.") }, {
def execute(self, data): """Run an executable file.""" args = [] terminal = None working_dir = None env = {} if isinstance(data, dict): self._check_required_params([('file', 'command')], data, 'execute') if 'command' in data and 'file' in data: raise ScriptingError( 'Parameters file and command can\'t be used ' 'at the same time for the execute command', data) file_ref = data.get('file', '') command = data.get('command', '') args_string = data.get('args', '') for arg in shlex.split(args_string): args.append(self._substitute(arg)) terminal = data.get('terminal') working_dir = data.get('working_dir') if not data.get('disable_runtime', False): # Possibly need to handle prefer_system_libs here env.update(runtime.get_env()) userenv = data.get('env') or {} for key in userenv: env_value = userenv[key] userenv[key] = self._get_file(env_value) env.update(userenv) include_processes = shlex.split(data.get('include_processes', '')) exclude_processes = shlex.split(data.get('exclude_processes', '')) elif isinstance(data, str): command = data include_processes = [] exclude_processes = [] else: raise ScriptingError('No parameters supplied to execute command.', data) if command: file_ref = 'bash' args = ['-c', self._get_file(command.strip())] include_processes.append('bash') else: # Determine whether 'file' value is a file id or a path file_ref = self._get_file(file_ref) exec_path = system.find_executable(file_ref) if not exec_path: raise ScriptingError("Unable to find executable %s" % file_ref) if not os.access(exec_path, os.X_OK): logger.warning("Making %s executable", exec_path) self.chmodx(exec_path) if terminal: terminal = system.get_default_terminal() if not working_dir or not os.path.exists(working_dir): working_dir = self.target_path command = [exec_path] + args logger.debug("Executing %s", command) thread = LutrisThread(command, env=env, term=terminal, cwd=working_dir, include_processes=include_processes, exclude_processes=exclude_processes) thread.start() GLib.idle_add(self.parent.attach_logger, thread) self.heartbeat = GLib.timeout_add(1000, self._monitor_task, thread) return 'STOP'
def do_play(self, prelaunched, _error=None): if not prelaunched: self.state = self.STATE_STOPPED return system_config = self.runner.system_config self.original_outputs = sorted( display.get_outputs(), key=lambda e: e[0] == system_config.get('display') ) gameplay_info = self.runner.play() logger.debug("Launching %s: %s" % (self.name, gameplay_info)) if 'error' in gameplay_info: self.show_error_message(gameplay_info) self.state = self.STATE_STOPPED return env = {} sdl_gamecontrollerconfig = system_config.get('sdl_gamecontrollerconfig') if sdl_gamecontrollerconfig: path = os.path.expanduser(sdl_gamecontrollerconfig) if os.path.exists(path): with open(path, "r") as f: sdl_gamecontrollerconfig = f.read() env['SDL_GAMECONTROLLERCONFIG'] = sdl_gamecontrollerconfig sdl_video_fullscreen = system_config.get('sdl_video_fullscreen') or '' env['SDL_VIDEO_FULLSCREEN_DISPLAY'] = sdl_video_fullscreen restrict_to_display = system_config.get('display') if restrict_to_display != 'off': display.turn_off_except(restrict_to_display) time.sleep(3) self.resolution_changed = True resolution = system_config.get('resolution') if resolution != 'off': display.change_resolution(resolution) time.sleep(3) self.resolution_changed = True if system_config.get('reset_pulse'): audio.reset_pulse() self.killswitch = system_config.get('killswitch') if self.killswitch and not os.path.exists(self.killswitch): # Prevent setting a killswitch to a file that doesn't exists self.killswitch = None # Command launch_arguments = gameplay_info['command'] optimus = system_config.get('optimus') if optimus == 'primusrun' and system.find_executable('primusrun'): launch_arguments.insert(0, 'primusrun') elif optimus == 'optirun' and system.find_executable('optirun'): launch_arguments.insert(0, 'virtualgl') launch_arguments.insert(0, '-b') launch_arguments.insert(0, 'optirun') xephyr = system_config.get('xephyr') or 'off' if xephyr != 'off': if xephyr == '8bpp': xephyr_depth = '8' else: xephyr_depth = '16' xephyr_resolution = system_config.get('xephyr_resolution') or '640x480' xephyr_command = ['Xephyr', ':2', '-ac', '-screen', xephyr_resolution + 'x' + xephyr_depth, '-glamor', '-reset', '-terminate', '-fullscreen'] xephyr_thread = LutrisThread(xephyr_command) xephyr_thread.start() time.sleep(3) env['DISPLAY'] = ':2' if system_config.get('use_us_layout'): setxkbmap_command = ['setxkbmap', '-model', 'pc101', 'us', '-print'] xkbcomp_command = ['xkbcomp', '-', os.environ.get('DISPLAY', ':0')] xkbcomp = subprocess.Popen(xkbcomp_command, stdin=subprocess.PIPE) subprocess.Popen(setxkbmap_command, env=os.environ, stdout=xkbcomp.stdin).communicate() xkbcomp.communicate() pulse_latency = system_config.get('pulse_latency') if pulse_latency: env['PULSE_LATENCY_MSEC'] = '60' prefix_command = system_config.get("prefix_command") or '' if prefix_command: launch_arguments = shlex.split(os.path.expandvars(prefix_command)) + launch_arguments single_cpu = system_config.get('single_cpu') or False if single_cpu: logger.info('The game will run on a single CPU core') launch_arguments.insert(0, '0') launch_arguments.insert(0, '-c') launch_arguments.insert(0, 'taskset') terminal = system_config.get('terminal') if terminal: terminal = system_config.get("terminal_app", system.get_default_terminal()) if terminal and not system.find_executable(terminal): dialogs.ErrorDialog("The selected terminal application " "could not be launched:\n" "%s" % terminal) self.state = self.STATE_STOPPED return # Env vars game_env = gameplay_info.get('env') or self.runner.get_env() env.update(game_env) ld_preload = gameplay_info.get('ld_preload') if ld_preload: env["LD_PRELOAD"] = ld_preload game_ld_libary_path = gameplay_info.get('ld_library_path') if game_ld_libary_path: ld_library_path = env.get("LD_LIBRARY_PATH") if not ld_library_path: ld_library_path = '$LD_LIBRARY_PATH' ld_library_path = ":".join([game_ld_libary_path, ld_library_path]) env["LD_LIBRARY_PATH"] = ld_library_path # /Env vars include_processes = shlex.split(system_config.get('include_processes', '')) exclude_processes = shlex.split(system_config.get('exclude_processes', '')) monitoring_disabled = system_config.get('disable_monitoring') if monitoring_disabled: show_obnoxious_process_monitor_message() process_watch = not monitoring_disabled if self.runner.system_config.get('disable_compositor'): self.desktop_effects(False) self.game_thread = LutrisThread(launch_arguments, runner=self.runner, env=env, rootpid=gameplay_info.get('rootpid'), watch=process_watch, term=terminal, log_buffer=self.log_buffer, include_processes=include_processes, exclude_processes=exclude_processes) if hasattr(self.runner, 'stop'): self.game_thread.set_stop_command(self.runner.stop) self.game_thread.start() self.state = self.STATE_RUNNING # xboxdrv setup xboxdrv_config = system_config.get('xboxdrv') if xboxdrv_config: self.xboxdrv_start(xboxdrv_config) if monitoring_disabled: logger.info("Process monitoring disabled") else: self.heartbeat = GLib.timeout_add(HEARTBEAT_DELAY, self.beat)
def configure_game(self, prelaunched, error=None): """Get the game ready to start, applying all the options This methods sets the game_runtime_config attribute. """ if error: logger.error(error) dialogs.ErrorDialog(str(error)) if not prelaunched: logger.error("Game prelaunch unsuccessful") dialogs.ErrorDialog("An error prevented the game from running") self.state = self.STATE_STOPPED self.emit("game-stop") return system_config = self.runner.system_config self.original_outputs = DISPLAY_MANAGER.get_config() gameplay_info = self.runner.play() if "error" in gameplay_info: self.show_error_message(gameplay_info) self.state = self.STATE_STOPPED self.emit("game-stop") return logger.debug("Launching %s: %s", self.name, gameplay_info) logger.debug("Game info: %s", json.dumps(gameplay_info, indent=2)) env = {} sdl_gamecontrollerconfig = system_config.get( "sdl_gamecontrollerconfig") if sdl_gamecontrollerconfig: path = os.path.expanduser(sdl_gamecontrollerconfig) if system.path_exists(path): with open(path, "r") as controllerdb_file: sdl_gamecontrollerconfig = controllerdb_file.read() env["SDL_GAMECONTROLLERCONFIG"] = sdl_gamecontrollerconfig sdl_video_fullscreen = system_config.get("sdl_video_fullscreen") or "" env["SDL_VIDEO_FULLSCREEN_DISPLAY"] = sdl_video_fullscreen restrict_to_display = system_config.get("display") if restrict_to_display != "off": if restrict_to_display == "primary": restrict_to_display = None for output in self.original_outputs: if output.primary: restrict_to_display = output.name break if not restrict_to_display: logger.warning("No primary display set") else: found = False for output in self.original_outputs: if output.name == restrict_to_display: found = True break if not found: logger.warning("Selected display %s not found", restrict_to_display) restrict_to_display = None if restrict_to_display: turn_off_except(restrict_to_display) time.sleep(3) self.resolution_changed = True resolution = system_config.get("resolution") if resolution != "off": DISPLAY_MANAGER.set_resolution(resolution) time.sleep(3) self.resolution_changed = True if system_config.get("reset_pulse"): audio.reset_pulse() self.killswitch = system_config.get("killswitch") if self.killswitch and not system.path_exists(self.killswitch): # Prevent setting a killswitch to a file that doesn't exists self.killswitch = None # Command launch_arguments = gameplay_info["command"] optimus = system_config.get("optimus") if optimus == "primusrun" and system.find_executable("primusrun"): launch_arguments.insert(0, "primusrun") elif optimus == "optirun" and system.find_executable("optirun"): launch_arguments.insert(0, "virtualgl") launch_arguments.insert(0, "-b") launch_arguments.insert(0, "optirun") elif optimus == "pvkrun" and system.find_executable("pvkrun"): launch_arguments.insert(0, "pvkrun") xephyr = system_config.get("xephyr") or "off" if xephyr != "off": if not system.find_executable("Xephyr"): raise GameConfigError( "Unable to find Xephyr, install it or disable the Xephyr option" ) xephyr_depth = "8" if xephyr == "8bpp" else "16" xephyr_resolution = system_config.get( "xephyr_resolution") or "640x480" xephyr_command = [ "Xephyr", ":2", "-ac", "-screen", xephyr_resolution + "x" + xephyr_depth, "-glamor", "-reset", "-terminate", ] if system_config.get("xephyr_fullscreen"): xephyr_command.append("-fullscreen") xephyr_thread = MonitoredCommand(xephyr_command) xephyr_thread.start() time.sleep(3) env["DISPLAY"] = ":2" if system_config.get("use_us_layout"): setxkbmap_command = [ "setxkbmap", "-model", "pc101", "us", "-print" ] xkbcomp_command = ["xkbcomp", "-", os.environ.get("DISPLAY", ":0")] xkbcomp = subprocess.Popen(xkbcomp_command, stdin=subprocess.PIPE) subprocess.Popen(setxkbmap_command, env=os.environ, stdout=xkbcomp.stdin).communicate() xkbcomp.communicate() if system_config.get("aco"): env["RADV_PERFTEST"] = "aco" pulse_latency = system_config.get("pulse_latency") if pulse_latency: env["PULSE_LATENCY_MSEC"] = "60" vk_icd = system_config.get("vk_icd") if vk_icd and vk_icd != "off" and system.path_exists(vk_icd): env["VK_ICD_FILENAMES"] = vk_icd fps_limit = system_config.get("fps_limit") or "" if fps_limit: strangle_cmd = system.find_executable("strangle") if strangle_cmd: launch_arguments = [strangle_cmd, fps_limit] + launch_arguments else: logger.warning( "libstrangle is not available on this system, FPS limiter disabled" ) prefix_command = system_config.get("prefix_command") or "" if prefix_command: launch_arguments = ( shlex.split(os.path.expandvars(prefix_command)) + launch_arguments) single_cpu = system_config.get("single_cpu") or False if single_cpu: logger.info("The game will run on a single CPU core") launch_arguments.insert(0, "0") launch_arguments.insert(0, "-c") launch_arguments.insert(0, "taskset") terminal = system_config.get("terminal") if terminal: terminal = system_config.get("terminal_app", system.get_default_terminal()) if terminal and not system.find_executable(terminal): dialogs.ErrorDialog("The selected terminal application " "could not be launched:\n" "%s" % terminal) self.state = self.STATE_STOPPED self.emit("game-stop") return # Env vars game_env = gameplay_info.get("env") or self.runner.get_env() env.update(game_env) env["game_name"] = self.name # Prime vars prime = system_config.get("prime") if prime: env["__NV_PRIME_RENDER_OFFLOAD"] = "1" env["__GLX_VENDOR_LIBRARY_NAME"] = "nvidia" env["__VK_LAYER_NV_optimus"] = "NVIDIA_only" # LD_PRELOAD ld_preload = gameplay_info.get("ld_preload") if ld_preload: env["LD_PRELOAD"] = ld_preload # Feral gamemode gamemode = system_config.get("gamemode") if gamemode: env["LD_PRELOAD"] = ":".join([ path for path in [ env.get("LD_PRELOAD"), "libgamemodeauto.so", ] if path ]) # LD_LIBRARY_PATH game_ld_libary_path = gameplay_info.get("ld_library_path") if game_ld_libary_path: ld_library_path = env.get("LD_LIBRARY_PATH") if not ld_library_path: ld_library_path = "$LD_LIBRARY_PATH" env["LD_LIBRARY_PATH"] = ":".join( [game_ld_libary_path, ld_library_path]) include_processes = shlex.split( system_config.get("include_processes", "")) exclude_processes = shlex.split( system_config.get("exclude_processes", "")) self.game_runtime_config = { "args": launch_arguments, "env": env, "terminal": terminal, "include_processes": include_processes, "exclude_processes": exclude_processes, } if system_config.get("disable_compositor"): self.set_desktop_compositing(False) prelaunch_command = system_config.get("prelaunch_command") if system.path_exists(prelaunch_command): self.prelaunch_executor = MonitoredCommand( [prelaunch_command], include_processes=[os.path.basename(prelaunch_command)], env=self.game_runtime_config["env"], cwd=self.directory, ) self.prelaunch_executor.start() logger.info("Running %s in the background", prelaunch_command) if system_config.get("prelaunch_wait"): self.heartbeat = GLib.timeout_add(HEARTBEAT_DELAY, self.prelaunch_beat) else: self.start_game()
def play(self): """Launch the game.""" if not self.runner: dialogs.ErrorDialog("Invalid game configuration: Missing runner") return False if not self.prelaunch(): return False system_config = self.runner.system_config self.original_outputs = display.get_outputs() gameplay_info = self.runner.play() logger.debug("Launching %s: %s" % (self.name, gameplay_info)) if 'error' in gameplay_info: show_error_message(gameplay_info) return False restrict_to_display = system_config.get('display') if restrict_to_display != 'off': display.turn_off_except(restrict_to_display) time.sleep(3) self.resolution_changed = True resolution = system_config.get('resolution') if resolution != 'off': display.change_resolution(resolution) time.sleep(3) self.resolution_changed = True if system_config.get('reset_pulse'): audio.reset_pulse() self.killswitch = system_config.get('killswitch') if self.killswitch and not os.path.exists(self.killswitch): # Prevent setting a killswitch to a file that doesn't exists self.killswitch = None # Command launch_arguments = gameplay_info['command'] primusrun = system_config.get('primusrun') if primusrun and system.find_executable('primusrun'): launch_arguments.insert(0, 'primusrun') prefix_command = system_config.get("prefix_command") or '' if prefix_command.strip(): launch_arguments.insert(0, prefix_command) terminal = system_config.get('terminal') if terminal: terminal = system_config.get("terminal_app", system.get_default_terminal()) if terminal and not system.find_executable(terminal): dialogs.ErrorDialog("The selected terminal application " "could not be launched:\n" "%s" % terminal) return False # Env vars env = {} game_env = gameplay_info.get('env') or {} env.update(game_env) ld_preload = gameplay_info.get('ld_preload') if ld_preload: env["LD_PRELOAD"] = ld_preload ld_library_path = [] if self.use_runtime(system_config): env['STEAM_RUNTIME'] = os.path.join(settings.RUNTIME_DIR, 'steam') ld_library_path += runtime.get_runtime_paths() game_ld_libary_path = gameplay_info.get('ld_library_path') if game_ld_libary_path: ld_library_path.append(game_ld_libary_path) if ld_library_path: ld_full = ':'.join(ld_library_path) env["LD_LIBRARY_PATH"] = "{}:$LD_LIBRARY_PATH".format(ld_full) # /Env vars self.game_thread = LutrisThread(launch_arguments, runner=self.runner, env=env, rootpid=gameplay_info.get('rootpid'), term=terminal) self.state = self.STATE_RUNNING if hasattr(self.runner, 'stop'): self.game_thread.set_stop_command(self.runner.stop) self.game_thread.start() if 'joy2key' in gameplay_info: self.joy2key(gameplay_info['joy2key']) xboxdrv_config = system_config.get('xboxdrv') if xboxdrv_config: self.xboxdrv_start(xboxdrv_config) if self.runner.is_watchable: # Create heartbeat every self.heartbeat = GLib.timeout_add(HEARTBEAT_DELAY, self.beat)
def configure_game(self, prelaunched, error=None): """Get the game ready to start, applying all the options This methods sets the game_runtime_config attribute. """ if error: logger.error(error) dialogs.ErrorDialog(str(error)) if not prelaunched: logger.error("Game prelaunch unsuccessful") dialogs.ErrorDialog("An error prevented the game from running") self.state = self.STATE_STOPPED self.emit('game-stop') return system_config = self.runner.system_config self.original_outputs = sorted( display.get_outputs(), key=lambda e: e.name == system_config.get("display") ) gameplay_info = self.runner.play() if "error" in gameplay_info: self.show_error_message(gameplay_info) self.state = self.STATE_STOPPED self.emit('game-stop') return logger.debug("Launching %s: %s", self.name, gameplay_info) logger.debug("Game info: %s", json.dumps(gameplay_info, indent=2)) env = {} sdl_gamecontrollerconfig = system_config.get("sdl_gamecontrollerconfig") if sdl_gamecontrollerconfig: path = os.path.expanduser(sdl_gamecontrollerconfig) if system.path_exists(path): with open(path, "r") as controllerdb_file: sdl_gamecontrollerconfig = controllerdb_file.read() env["SDL_GAMECONTROLLERCONFIG"] = sdl_gamecontrollerconfig sdl_video_fullscreen = system_config.get("sdl_video_fullscreen") or "" env["SDL_VIDEO_FULLSCREEN_DISPLAY"] = sdl_video_fullscreen restrict_to_display = system_config.get("display") if restrict_to_display != "off": if restrict_to_display == "primary": restrict_to_display = None for output in self.original_outputs: if output.primary: restrict_to_display = output.name break if not restrict_to_display: logger.warning("No primary display set") else: found = False for output in self.original_outputs: if output.name == restrict_to_display: found = True break if not found: logger.warning("Selected display %s not found", restrict_to_display) restrict_to_display = None if restrict_to_display: display.turn_off_except(restrict_to_display) time.sleep(3) self.resolution_changed = True resolution = system_config.get("resolution") if resolution != "off": display.change_resolution(resolution) time.sleep(3) self.resolution_changed = True if system_config.get("reset_pulse"): audio.reset_pulse() self.killswitch = system_config.get("killswitch") if self.killswitch and not system.path_exists(self.killswitch): # Prevent setting a killswitch to a file that doesn't exists self.killswitch = None # Command launch_arguments = gameplay_info["command"] optimus = system_config.get("optimus") if optimus == "primusrun" and system.find_executable("primusrun"): launch_arguments.insert(0, "primusrun") elif optimus == "optirun" and system.find_executable("optirun"): launch_arguments.insert(0, "virtualgl") launch_arguments.insert(0, "-b") launch_arguments.insert(0, "optirun") elif optimus == "pvkrun" and system.find_executable("pvkrun"): launch_arguments.insert(0, "pvkrun") xephyr = system_config.get("xephyr") or "off" if xephyr != "off": if not system.find_executable("Xephyr"): raise GameConfigError( "Unable to find Xephyr, install it or disable the Xephyr option" ) xephyr_depth = "8" if xephyr == "8bpp" else "16" xephyr_resolution = system_config.get("xephyr_resolution") or "640x480" xephyr_command = [ "Xephyr", ":2", "-ac", "-screen", xephyr_resolution + "x" + xephyr_depth, "-glamor", "-reset", "-terminate" ] if system_config.get("xephyr_fullscreen"): xephyr_command.append("-fullscreen") xephyr_thread = MonitoredCommand(xephyr_command) xephyr_thread.start() time.sleep(3) env["DISPLAY"] = ":2" if system_config.get("use_us_layout"): setxkbmap_command = ["setxkbmap", "-model", "pc101", "us", "-print"] xkbcomp_command = ["xkbcomp", "-", os.environ.get("DISPLAY", ":0")] xkbcomp = subprocess.Popen(xkbcomp_command, stdin=subprocess.PIPE) subprocess.Popen( setxkbmap_command, env=os.environ, stdout=xkbcomp.stdin ).communicate() xkbcomp.communicate() pulse_latency = system_config.get("pulse_latency") if pulse_latency: env["PULSE_LATENCY_MSEC"] = "60" vk_icd = system_config.get("vk_icd") if vk_icd and vk_icd != "off" and system.path_exists(vk_icd): env["VK_ICD_FILENAMES"] = vk_icd fps_limit = system_config.get("fps_limit") or "" if fps_limit: strangle_cmd = system.find_executable("strangle") launch_arguments = [strangle_cmd, fps_limit] + launch_arguments prefix_command = system_config.get("prefix_command") or "" if prefix_command: launch_arguments = ( shlex.split(os.path.expandvars(prefix_command)) + launch_arguments ) single_cpu = system_config.get("single_cpu") or False if single_cpu: logger.info("The game will run on a single CPU core") launch_arguments.insert(0, "0") launch_arguments.insert(0, "-c") launch_arguments.insert(0, "taskset") terminal = system_config.get("terminal") if terminal: terminal = system_config.get("terminal_app", system.get_default_terminal()) if terminal and not system.find_executable(terminal): dialogs.ErrorDialog( "The selected terminal application " "could not be launched:\n" "%s" % terminal ) self.state = self.STATE_STOPPED self.emit('game-stop') return # Env vars game_env = gameplay_info.get("env") or self.runner.get_env() env.update(game_env) # LD_PRELOAD ld_preload = gameplay_info.get("ld_preload") if ld_preload: env["LD_PRELOAD"] = ld_preload # Feral gamemode gamemode = system_config.get("gamemode") if gamemode: env["LD_PRELOAD"] = ":".join( [ path for path in [ env.get("LD_PRELOAD"), "/usr/$LIB/libgamemodeauto.so", ] if path ] ) # LD_LIBRARY_PATH game_ld_libary_path = gameplay_info.get("ld_library_path") if game_ld_libary_path: ld_library_path = env.get("LD_LIBRARY_PATH") if not ld_library_path: ld_library_path = "$LD_LIBRARY_PATH" env["LD_LIBRARY_PATH"] = ":".join([game_ld_libary_path, ld_library_path]) include_processes = shlex.split(system_config.get("include_processes", "")) exclude_processes = shlex.split(system_config.get("exclude_processes", "")) self.game_runtime_config = { "args": launch_arguments, "env": env, "terminal": terminal, "include_processes": include_processes, "exclude_processes": exclude_processes } if system_config.get("disable_compositor"): self.set_desktop_compositing(False) # xboxdrv setup xboxdrv_config = system_config.get("xboxdrv") if xboxdrv_config: self.xboxdrv_start(xboxdrv_config) prelaunch_command = system_config.get("prelaunch_command") if system.path_exists(prelaunch_command): self.prelaunch_executor = MonitoredCommand( [prelaunch_command], include_processes=[os.path.basename(prelaunch_command)], cwd=self.directory, ) self.prelaunch_executor.start() logger.info("Running %s in the background", prelaunch_command) if system_config.get("prelaunch_wait"): self.heartbeat = GLib.timeout_add(HEARTBEAT_DELAY, self.prelaunch_beat) else: self.start_game()
"help": "Switch to this screen resolution while the game is running.", }, { "option": "terminal", "label": "Run in a terminal", "type": "bool", "default": False, "advanced": True, "help": "Run the game in a new terminal window.", }, { "option": "terminal_app", "label": "Terminal application", "type": "choice_with_entry", "choices": system.get_terminal_apps, "default": system.get_default_terminal(), "advanced": True, "help": ( "The terminal emulator to be run with the previous option." "Choose from the list of detected terminal apps or enter " "the terminal's command or path." "Note: Not all terminal emulators are guaranteed to work." ), }, { "option": "env", "type": "mapping", "label": "Environment variables", "help": "Environment variables loaded at run time", }, {
def execute(self, data): """Run an executable file.""" args = [] terminal = None working_dir = None env = {} if isinstance(data, dict): if 'command' not in data and 'file' not in data: raise ScriptingError('Parameter file or command is mandatory ' 'for the execute command', data) elif 'command' in data and 'file' in data: raise ScriptingError('Parameters file and command can\'t be ' 'used at the same time for the execute ' 'command', data) file_ref = data.get('file', '') command = data.get('command', '') args_string = data.get('args', '') for arg in shlex.split(args_string): args.append(self._substitute(arg)) terminal = data.get('terminal') working_dir = data.get('working_dir') if not data.get('disable_runtime', False): env.update(runtime.get_env()) userenv = data.get('env', {}) for key in userenv: v = userenv[key] userenv[key] = self._get_file(v) or self._substitute(v) env.update(userenv) include_processes = shlex.split(data.get('include_processes', '')) exclude_processes = shlex.split(data.get('exclude_processes', '')) elif isinstance(data, str): command = data include_processes = [] exclude_processes = [] else: raise ScriptingError('No parameters supplied to execute command.', data) if command: command = command.strip() command = self._get_file(command) or self._substitute(command) file_ref = 'bash' args = ['-c', command] include_processes.append('bash') else: # Determine whether 'file' value is a file id or a path file_ref = self._get_file(file_ref) or self._substitute(file_ref) exec_path = system.find_executable(file_ref) if not exec_path: raise ScriptingError("Unable to find executable %s" % file_ref) if not os.access(exec_path, os.X_OK): self.chmodx(exec_path) if terminal: terminal = system.get_default_terminal() if not working_dir or not os.path.exists(working_dir): working_dir = self.target_path command = [exec_path] + args logger.debug("Executing %s" % command) thread = LutrisThread(command, env=env, term=terminal, cwd=working_dir, include_processes=include_processes, exclude_processes=exclude_processes) thread.start() GLib.idle_add(self.parent.attach_logger, thread) self.heartbeat = GLib.timeout_add(1000, self._monitor_task, thread) return 'STOP'
def execute(self, data): """Run an executable file.""" args = [] terminal = None working_dir = None env = {} if isinstance(data, dict): self._check_required_params([("file", "command")], data, "execute") if "command" in data and "file" in data: raise ScriptingError( "Parameters file and command can't be used " "at the same time for the execute command", data, ) file_ref = data.get("file", "") command = data.get("command", "") args_string = data.get("args", "") for arg in shlex.split(args_string): args.append(self._substitute(arg)) terminal = data.get("terminal") working_dir = data.get("working_dir") if not data.get("disable_runtime", False): # Possibly need to handle prefer_system_libs here env.update(runtime.get_env()) # Loading environment variables set in the script env.update(self.script_env) # Environment variables can also be passed to the execute command local_env = data.get("env") or {} env.update({ key: self._substitute(value) for key, value in local_env.items() }) include_processes = shlex.split(data.get("include_processes", "")) exclude_processes = shlex.split(data.get("exclude_processes", "")) elif isinstance(data, str): command = data include_processes = [] exclude_processes = [] else: raise ScriptingError("No parameters supplied to execute command.", data) if command: file_ref = "bash" args = ["-c", self._get_file(command.strip())] include_processes.append("bash") else: # Determine whether 'file' value is a file id or a path file_ref = self._get_file(file_ref) exec_path = system.find_executable(file_ref) if not exec_path: raise ScriptingError("Unable to find executable %s" % file_ref) if not os.access(exec_path, os.X_OK): logger.warning("Making %s executable", exec_path) self.chmodx(exec_path) if terminal: terminal = system.get_default_terminal() if not working_dir or not os.path.exists(working_dir): working_dir = self.target_path command = MonitoredCommand( [exec_path] + args, env=env, term=terminal, cwd=working_dir, include_processes=include_processes, exclude_processes=exclude_processes, ) command.start() GLib.idle_add(self.parent.attach_logger, command) self.heartbeat = GLib.timeout_add(1000, self._monitor_task, command) return "STOP"
def do_play(self, prelaunched, _error=None): if not prelaunched: self.state = self.STATE_STOPPED return system_config = self.runner.system_config self.original_outputs = display.get_outputs() gameplay_info = self.runner.play() env = {} logger.debug("Launching %s: %s" % (self.name, gameplay_info)) if 'error' in gameplay_info: show_error_message(gameplay_info) self.state = self.STATE_STOPPED return restrict_to_display = system_config.get('display') if restrict_to_display != 'off': display.turn_off_except(restrict_to_display) time.sleep(3) self.resolution_changed = True resolution = system_config.get('resolution') if resolution != 'off': display.change_resolution(resolution) time.sleep(3) self.resolution_changed = True if system_config.get('reset_pulse'): audio.reset_pulse() self.killswitch = system_config.get('killswitch') if self.killswitch and not os.path.exists(self.killswitch): # Prevent setting a killswitch to a file that doesn't exists self.killswitch = None # Command launch_arguments = gameplay_info['command'] primusrun = system_config.get('primusrun') if primusrun and system.find_executable('primusrun'): launch_arguments.insert(0, 'primusrun') xephyr = system_config.get('xephyr') or 'off' if xephyr != 'off': if xephyr == '8bpp': xephyr_depth = '8' else: xephyr_depth = '16' xephyr_resolution = system_config.get('xephyr_resolution') or '640x480' xephyr_command = ['Xephyr', ':2', '-ac', '-screen', xephyr_resolution + 'x' + xephyr_depth, '-glamor', '-reset', '-terminate', '-fullscreen'] xephyr_thread = LutrisThread(xephyr_command) xephyr_thread.start() time.sleep(3) env['DISPLAY'] = ':2' pulse_latency = system_config.get('pulse_latency') if pulse_latency: env['PULSE_LATENCY_MSEC'] = '60' prefix_command = system_config.get("prefix_command") or '' if prefix_command.strip(): launch_arguments.insert(0, prefix_command) terminal = system_config.get('terminal') if terminal: terminal = system_config.get("terminal_app", system.get_default_terminal()) if terminal and not system.find_executable(terminal): dialogs.ErrorDialog("The selected terminal application " "could not be launched:\n" "%s" % terminal) self.state = self.STATE_STOPPED return # Env vars game_env = gameplay_info.get('env') or {} env.update(game_env) system_env = system_config.get('env') or {} env.update(system_env) ld_preload = gameplay_info.get('ld_preload') if ld_preload: env["LD_PRELOAD"] = ld_preload ld_library_path = [] if self.runner.use_runtime(): env['STEAM_RUNTIME'] = os.path.join(settings.RUNTIME_DIR, 'steam') ld_library_path += runtime.get_paths() game_ld_libary_path = gameplay_info.get('ld_library_path') if game_ld_libary_path: ld_library_path.append(game_ld_libary_path) if ld_library_path: ld_full = ':'.join(ld_library_path) env["LD_LIBRARY_PATH"] = "{}:$LD_LIBRARY_PATH".format(ld_full) # /Env vars self.game_thread = LutrisThread(launch_arguments, runner=self.runner, env=env, rootpid=gameplay_info.get('rootpid'), term=terminal) if hasattr(self.runner, 'stop'): self.game_thread.set_stop_command(self.runner.stop) self.game_thread.start() self.state = self.STATE_RUNNING if 'joy2key' in gameplay_info: self.joy2key(gameplay_info['joy2key']) xboxdrv_config = system_config.get('xboxdrv') if xboxdrv_config: self.xboxdrv_start(xboxdrv_config) self.heartbeat = GLib.timeout_add(HEARTBEAT_DELAY, self.beat)