Пример #1
0
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])
Пример #2
0
    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()
Пример #3
0
    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
Пример #4
0
 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
Пример #5
0
    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
Пример #6
0
    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
Пример #7
0
     "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":
Пример #8
0
    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)
Пример #9
0
    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)
Пример #10
0
    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)
Пример #11
0
    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"
Пример #12
0
     '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.")
 },
 {
Пример #13
0
    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'
Пример #14
0
    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)
Пример #15
0
    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()
Пример #16
0
    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)
Пример #17
0
    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()
Пример #18
0
     "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",
 },
 {
Пример #19
0
    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'
Пример #20
0
    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"
Пример #21
0
    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)