Example #1
0
def get_pixbuf_for_game(game_slug, icon_type, is_installed=True):
    if icon_type.startswith("banner"):
        default_icon_path = os.path.join(datapath.get(), "media/default_banner.png")
        icon_path = resources.get_banner_path(game_slug)
    elif icon_type.startswith("icon"):
        default_icon_path = os.path.join(datapath.get(), "media/default_icon.png")
        icon_path = resources.get_icon_path(game_slug)
    else:
        logger.error("Invalid icon type '%s'", icon_type)
        return None

    size = IMAGE_SIZES[icon_type]

    pixbuf = get_pixbuf(icon_path, size, fallback=default_icon_path)
    if not is_installed:
        unavailable_game_overlay = os.path.join(datapath.get(), "media/unavailable.png")
        transparent_pixbuf = get_overlay(unavailable_game_overlay, size).copy()
        pixbuf.composite(
            transparent_pixbuf,
            0,
            0,
            size[0],
            size[1],
            0,
            0,
            1,
            1,
            GdkPixbuf.InterpType.NEAREST,
            100,
        )
        return transparent_pixbuf
    return pixbuf
Example #2
0
    def __init__(self):

        Gtk.Application.__init__(self, application_id='net.lutris.Lutris',
                                 flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE)

        gettext.bindtextdomain("lutris", "/usr/share/locale")
        gettext.textdomain("lutris")

        check_config()
        migrate()
        update_platforms()

        GLib.set_application_name(_('Lutris'))
        self.window = None
        self.css_provider = Gtk.CssProvider.new()

        try:
            self.css_provider.load_from_path(os.path.join(datapath.get(), 'ui', 'lutris.css'))
        except GLib.Error as e:
            logger.exception(e)

        if hasattr(self, 'add_main_option'):
            self.add_arguments()
        else:
            ErrorDialog("Your Linux distribution is too old, Lutris won't function properly")
Example #3
0
def convert_to_background(background_path, target_size=(320, 1080)):
    """Converts a image to a pane background"""

    coverart = Image.open(background_path)
    coverart = coverart.convert("RGBA")

    target_width, target_height = target_size
    image_height = int(target_height * 0.80)  # 80% of the mask is visible
    orig_width, orig_height = coverart.size

    # Resize and crop coverart
    width = int(orig_width * (image_height / orig_height))
    offset = int((width - target_width) / 2)
    coverart = coverart.resize((width, image_height), resample=Image.BICUBIC)
    coverart = coverart.crop((offset, 0, target_width + offset, image_height))

    # Resize canvas of coverart by putting transparent pixels on the bottom
    coverart_bg = Image.new('RGBA', (target_width, target_height), (0, 0, 0, 0))
    coverart_bg.paste(coverart, (0, 0, target_width, image_height))

    # Apply a tint to the base image
    # tint = Image.new('RGBA', (target_width, target_height), (0, 0, 0, 255))
    # coverart = Image.blend(coverart, tint, 0.6)

    # Paste coverart on transparent image while applying a gradient mask
    background = Image.new('RGBA', (target_width, target_height), (0, 0, 0, 0))
    mask = Image.open(os.path.join(datapath.get(), "media/mask.png"))
    background.paste(coverart_bg, mask=mask)

    return background
Example #4
0
    def __init__(self):
        super().__init__(
            application_id="net.lutris.Lutris",
            flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE,
        )
        init_lutris()
        gettext.bindtextdomain("lutris", "/usr/share/locale")
        gettext.textdomain("lutris")

        GLib.set_application_name(_("Lutris"))
        self.running_games = Gio.ListStore.new(Game)
        self.window = None
        self.tray = None
        self.css_provider = Gtk.CssProvider.new()
        self.run_in_background = False

        if os.geteuid() == 0:
            ErrorDialog(
                "Running Lutris as root is not recommended and may cause unexpected issues"
            )

        try:
            self.css_provider.load_from_path(
                os.path.join(datapath.get(), "ui", "lutris.css")
            )
        except GLib.Error as e:
            logger.exception(e)

        if hasattr(self, "add_main_option"):
            self.add_arguments()
        else:
            ErrorDialog(
                "Your Linux distribution is too old. Lutris won't function properly."
            )
Example #5
0
    def setup_x360ce(self, x360ce_path):
        if not os.path.isdir(x360ce_path):
            logger.error("%s is not a valid path for x360ce", x360ce_path)
            return
        mode = 'dumbxinputemu' if self.runner_config.get('dumbxinputemu') else 'x360ce'
        dll_files = ['xinput1_3.dll']
        if self.runner_config.get('x360ce-xinput9'):
            dll_files.append('xinput9_1_0.dll')

        for dll_file in dll_files:
            xinput_dest_path = os.path.join(x360ce_path, dll_file)
            xinput_arch = self.runner_config.get('xinput-arch') or self.wine_arch
            dll_path = os.path.join(datapath.get(), 'controllers/{}-{}'.format(mode, xinput_arch))
            if not os.path.exists(xinput_dest_path):
                source_file = dll_file if mode == 'dumbxinputemu' else 'xinput1_3.dll'
                shutil.copyfile(os.path.join(dll_path, source_file), xinput_dest_path)

        if mode == 'x360ce':
            if self.runner_config.get('x360ce-dinput'):
                dinput8_path = os.path.join(dll_path, 'dinput8.dll')
                dinput8_dest_path = os.path.join(x360ce_path, 'dinput8.dll')
                shutil.copyfile(dinput8_path, dinput8_dest_path)

            x360ce_config = X360ce()
            x360ce_config.populate_controllers()
            x360ce_config.write(os.path.join(x360ce_path, 'x360ce.ini'))
Example #6
0
def get_builder_from_file(glade_file):
    ui_filename = os.path.join(datapath.get(), "ui", glade_file)
    if not os.path.exists(ui_filename):
        raise ValueError("ui file does not exists: %s" % ui_filename)

    builder = Gtk.Builder()
    builder.add_from_file(ui_filename)
    return builder
Example #7
0
def get_builder_from_file(glade_file):
    ui_filename = os.path.join(datapath.get(), "ui", glade_file)
    if not os.path.exists(ui_filename):
        raise ValueError("ui file does not exists: %s" % ui_filename)

    builder = Gtk.Builder()
    builder.add_from_file(ui_filename)
    return builder
Example #8
0
    def __init__(self):
        GObject.GObject.__init__(self)
        self.set_title("Configure runners")
        self.set_size_request(570, 400)

        label = Gtk.Label()
        label.set_markup("<b>Install and configure the game runners</b>")

        scrolled_window = Gtk.ScrolledWindow()
        scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC,
                                   Gtk.PolicyType.AUTOMATIC)
        self.vbox.pack_start(label, False, True, 20)
        self.vbox.pack_start(scrolled_window, True, True, 10)

        close_button = Gtk.Button("Close")
        close_button.connect('clicked', self.close)

        self.action_area.pack_start(close_button, False, False, 10)
        runner_list = lutris.runners.__all__
        runner_vbox = Gtk.VBox()

        for runner_name in runner_list:
            # Get runner details
            runner = import_runner(runner_name)()
            platform = runner.platform
            description = runner.description

            hbox = Gtk.HBox()
            #Icon
            icon_path = os.path.join(datapath.get(), 'media/runner_icons',
                                     runner_name + '.png')
            icon = Gtk.Image()
            icon.set_from_file(icon_path)
            hbox.pack_start(icon, False, False, 10)

            #Label
            runner_label = Gtk.Label()
            runner_label.set_markup(
                "<b>%s</b>\n%s\n <i>Supported platforms : %s</i>" %
                (runner_name, description, platform)
            )
            runner_label.set_width_chars(38)
            runner_label.set_line_wrap(True)
            runner_label.set_alignment(0.0, 0.0)
            runner_label.set_padding(25, 5)
            hbox.pack_start(runner_label, True, True, 5)
            #Button
            button = Gtk.Button()
            button.set_size_request(100, 30)
            button_align = Gtk.Alignment.new(0.0, 1.0, 0.0, 0.0)
            self.configure_button(button, runner)
            button_align.add(button)
            hbox.pack_start(button_align, True, False, 5)

            runner_vbox.pack_start(hbox, True, True, 5)
        scrolled_window.add_with_viewport(runner_vbox)
        self.show_all()
Example #9
0
def get_pixbuf_for_panel(game_slug):
    """Return the pixbuf for the game panel background"""
    source_path = os.path.join(settings.COVERART_PATH, "%s.jpg" % game_slug)
    if not os.path.exists(source_path):
        source_path = os.path.join(datapath.get(), "media/generic-panel-bg.png")
    dest_path = os.path.join(settings.CACHE_DIR, "panel_bg.png")
    background = convert_to_background(source_path)
    background.save(dest_path)
    return dest_path
Example #10
0
def get_pixbuf_for_panel(game_slug):
    """Return the pixbuf for the game panel background"""
    source_path = os.path.join(settings.COVERART_PATH, "%s.jpg" % game_slug)
    if not os.path.exists(source_path):
        source_path = os.path.join(datapath.get(), "media/generic-panel-bg.png")
    dest_path = os.path.join(settings.CACHE_DIR, "panel_bg.png")
    background = convert_to_background(source_path)
    background.save(dest_path)
    return dest_path
Example #11
0
def get_runner_icon(runner_name, format='image', size=None):
    icon_path = os.path.join(datapath.get(), 'media/runner_icons',
                             runner_name + '.png')
    if format == 'image':
        icon = Gtk.Image()
        icon.set_from_file(icon_path)
    elif format == 'pixbuf' and size:
        icon = GdkPixbuf.Pixbuf.new_from_file_at_size(icon_path,
                                                      size[0], size[1])
    else:
        raise ValueError("Invalid arguments")
    return icon
Example #12
0
    def do_startup(self):
        Gtk.Application.do_startup(self)
        signal.signal(signal.SIGINT, signal.SIG_DFL)

        action = Gio.SimpleAction.new('quit')
        action.connect('activate', lambda *x: self.quit())
        self.add_action(action)
        self.add_accelerator('<Primary>q', 'app.quit')

        builder = Gtk.Builder.new_from_file(os.path.join(datapath.get(), 'ui', 'menus-traditional.ui'))
        menubar = builder.get_object('menubar')
        self.set_menubar(menubar)
Example #13
0
def get_runner_icon(runner_name, format='image', size=None):
    icon_path = os.path.join(datapath.get(), 'media/runner_icons',
                             runner_name + '.png')
    if format == 'image':
        icon = Gtk.Image()
        icon.set_from_file(icon_path)
    elif format == 'pixbuf' and size:
        icon = GdkPixbuf.Pixbuf.new_from_file_at_size(icon_path, size[0],
                                                      size[1])
    else:
        raise ValueError("Invalid arguments")
    return icon
Example #14
0
    def do_startup(self):
        Gtk.Application.do_startup(self)
        signal.signal(signal.SIGINT, signal.SIG_DFL)

        action = Gio.SimpleAction.new('quit')
        action.connect('activate', lambda *x: self.quit())
        self.add_action(action)

        builder = Gtk.Builder.new_from_file(
            os.path.join(datapath.get(), 'ui', 'menus-traditional.ui'))
        menubar = builder.get_object('menubar')
        self.set_menubar(menubar)
Example #15
0
    def __init__(self, **kwargs):
        super(GtkBuilderDialog, self).__init__()
        ui_filename = os.path.join(datapath.get(), 'ui',
                                   self.glade_file)
        if not os.path.exists(ui_filename):
            raise ValueError("ui file does not exists: %s" % ui_filename)

        self.builder = Gtk.Builder()
        self.builder.add_from_file(ui_filename)
        self.dialog = self.builder.get_object(self.dialog_object)
        self.builder.connect_signals(self)
        self.dialog.show_all()
        self.initialize(**kwargs)
Example #16
0
    def __init__(self, **kwargs):
        super(GtkBuilderDialog, self).__init__()
        ui_filename = os.path.join(datapath.get(), 'ui',
                                   self.glade_file)
        if not os.path.exists(ui_filename):
            raise ValueError("ui file does not exists: %s" % ui_filename)

        self.builder = Gtk.Builder()
        self.builder.add_from_file(ui_filename)
        self.dialog = self.builder.get_object(self.dialog_object)
        self.builder.connect_signals(self)
        self.dialog.show_all()
        self.initialize(**kwargs)
Example #17
0
def winetricks(app, prefix=None, winetricks_env=None, silent=True,
               blocking=False):
    """Execute winetricks."""
    path = (system.find_executable('winetricks')
            or os.path.join(datapath.get(), 'bin/winetricks'))
    arch = detect_prefix_arch(prefix) or 'win32'
    if not winetricks_env:
        winetricks_env = wine().get_executable()
    if str(silent).lower() in ('yes', 'on', 'true'):
        args = "-q " + app
    else:
        args = app
    wineexec(None, prefix=prefix, winetricks_env=winetricks_env,
             wine_path=path, arch=arch, args=args, blocking=blocking)
Example #18
0
def winetricks(app, prefix=None, arch=None, silent=True, wine_path=None, config=None):
    """Execute winetricks."""
    winetricks_path = os.path.join(datapath.get(), 'bin/winetricks')
    if arch not in ('win32', 'win64'):
        arch = detect_prefix_arch(prefix) or 'win32'
    if wine_path:
        winetricks_wine = wine_path
    else:
        winetricks_wine = wine().get_executable()
    args = app
    if str(silent).lower() in ('yes', 'on', 'true'):
        args = "--unattended " + args
    return wineexec(None, prefix=prefix, winetricks_wine=winetricks_wine,
                    wine_path=winetricks_path, arch=arch, args=args, config=config)
Example #19
0
def get_runner_icon(runner_name, format='image', size=None):
    icon_path = os.path.join(datapath.get(), 'media/runner_icons',
                             runner_name + '.png')
    if not os.path.exists(icon_path):
        logger.error("Unable to find icon '%s'", icon_path)
        return
    if format == 'image':
        icon = Gtk.Image()
        icon.set_from_file(icon_path)
    elif format == 'pixbuf' and size:
        icon = get_pixbuf(icon_path, None, size)
    else:
        raise ValueError("Invalid arguments")
    return icon
Example #20
0
def get_runner_icon(runner_name, format='image', size=None):
    icon_path = os.path.join(datapath.get(), 'media/runner_icons',
                             runner_name + '.png')
    if not os.path.exists(icon_path):
        logger.error("Unable to find icon '%s'", icon_path)
        return
    if format == 'image':
        icon = Gtk.Image()
        icon.set_from_file(icon_path)
    elif format == 'pixbuf' and size:
        icon = get_pixbuf(icon_path, None, size)
    else:
        raise ValueError("Invalid arguments")
    return icon
Example #21
0
File: wine.py Project: Freso/lutris
def winetricks(app, prefix=None, arch=None, silent=True, wine_path=None):
    """Execute winetricks."""
    winetricks_path = os.path.join(datapath.get(), 'bin/winetricks')
    if arch not in ('win32', 'win64'):
        arch = detect_prefix_arch(prefix) or 'win32'
    if wine_path:
        winetricks_wine = wine_path
    else:
        winetricks_wine = wine().get_executable()
    args = app
    if str(silent).lower() in ('yes', 'on', 'true'):
        args = "-q " + args
    return wineexec(None, prefix=prefix, winetricks_wine=winetricks_wine,
                    wine_path=winetricks_path, arch=arch, args=args)
Example #22
0
def get_pixbuf_for_game(game_slug, image_type, is_installed=True):
    icon_path = ""
    default_icon_path = ""

    if ImageType.banner & image_type:
        default_icon_path = os.path.join(datapath.get(),
                                         "media/default_banner.png")
        icon_path = resources.get_banner_path(game_slug)

    if ImageType.icon == image_type:
        default_icon_path = os.path.join(datapath.get(),
                                         "media/default_icon.png")
        icon_path = resources.get_icon_path(game_slug)

    size = IMAGE_SIZES[image_type]

    pixbuf = get_pixbuf(icon_path, size, fallback=default_icon_path)
    if not is_installed:
        unavailable_game_overlay = os.path.join(datapath.get(),
                                                "media/unavailable.png")
        transparent_pixbuf = get_overlay(unavailable_game_overlay, size).copy()
        pixbuf.composite(
            transparent_pixbuf,
            0,
            0,
            size[0],
            size[1],
            0,
            0,
            1,
            1,
            GdkPixbuf.InterpType.NEAREST,
            100,
        )
        return transparent_pixbuf
    return pixbuf
Example #23
0
    def __init__(self, parent=None, **kwargs):
        super().__init__()
        ui_filename = os.path.join(datapath.get(), "ui", self.glade_file)
        if not os.path.exists(ui_filename):
            raise ValueError("ui file does not exists: %s" % ui_filename)

        self.builder = Gtk.Builder()
        self.builder.add_from_file(ui_filename)
        self.dialog = self.builder.get_object(self.dialog_object)

        self.builder.connect_signals(self)
        if parent:
            self.dialog.set_transient_for(parent)
        self.dialog.show_all()
        self.dialog.connect("delete-event", lambda *x: x[0].destroy())
        self.initialize(**kwargs)
Example #24
0
def winetricks(app, prefix=None, arch=None, silent=True,
               wine_path=None, config=None, disable_runtime=False):
    """Execute winetricks."""
    winetricks_path = os.path.join(datapath.get(), 'bin/winetricks')
    if wine_path:
        winetricks_wine = wine_path
    else:
        winetricks_wine = wine().get_executable()
    if arch not in ('win32', 'win64'):
        arch = detect_arch(prefix, winetricks_wine)
    args = app
    if str(silent).lower() in ('yes', 'on', 'true'):
        args = "--unattended " + args
    return wineexec(None, prefix=prefix, winetricks_wine=winetricks_wine,
                    wine_path=winetricks_path, arch=arch, args=args,
                    config=config, disable_runtime=disable_runtime)
Example #25
0
    def __init__(self, parent=None, **kwargs):
        super().__init__()
        ui_filename = os.path.join(datapath.get(), "ui", self.glade_file)
        if not os.path.exists(ui_filename):
            raise ValueError("ui file does not exists: %s" % ui_filename)

        self.builder = Gtk.Builder()
        self.builder.add_from_file(ui_filename)
        self.dialog = self.builder.get_object(self.dialog_object)

        self.builder.connect_signals(self)
        if parent:
            self.dialog.set_transient_for(parent)
        self.dialog.show_all()
        self.dialog.connect("delete-event", lambda *x: x[0].destroy())
        self.initialize(**kwargs)
Example #26
0
    def do_startup(self):
        Gtk.Application.do_startup(self)
        signal.signal(signal.SIGINT, signal.SIG_DFL)

        action = Gio.SimpleAction.new("quit")
        action.connect("activate", lambda *x: self.quit())
        self.add_action(action)
        self.add_accelerator("<Primary>q", "app.quit")

        builder = Gtk.Builder.new_from_file(
            os.path.join(datapath.get(), "ui", "menus.ui"))
        appmenu = builder.get_object("app-menu")
        self.set_app_menu(appmenu)

        menubar = builder.get_object("menubar")
        self.set_menubar(menubar)
Example #27
0
    def setup_x360ce(self, x360ce_path):
        if not os.path.isdir(x360ce_path):
            logger.error("%s is not a valid path for x360ce", x360ce_path)
            return
        xinput_dest_path = os.path.join(x360ce_path, 'xinput1_3.dll')
        dll_path = os.path.join(datapath.get(), 'controllers/x360ce-{}'.format(self.wine_arch))
        if not os.path.exists(xinput_dest_path):
            xinput1_3_path = os.path.join(dll_path, 'xinput1_3.dll')
            shutil.copyfile(xinput1_3_path, xinput_dest_path)
        if self.runner_config.get('x360ce-dinput') and self.wine_arch == 'win32':
            dinput8_path = os.path.join(dll_path, 'dinput8.dll')
            dinput8_dest_path = os.path.join(x360ce_path, 'dinput8.dll')
            shutil.copyfile(dinput8_path, dinput8_dest_path)

        x360ce_config = X360ce()
        x360ce_config.populate_controllers()
        x360ce_config.write(os.path.join(x360ce_path, 'x360ce.ini'))
Example #28
0
    def do_startup(self):
        Gtk.Application.do_startup(self)
        signal.signal(signal.SIGINT, signal.SIG_DFL)

        action = Gio.SimpleAction.new("quit")
        action.connect("activate", lambda *x: self.quit())
        self.add_action(action)
        self.add_accelerator("<Primary>q", "app.quit")

        builder = Gtk.Builder.new_from_file(
            os.path.join(datapath.get(), "ui", "menus.ui")
        )
        appmenu = builder.get_object("app-menu")
        self.set_app_menu(appmenu)

        menubar = builder.get_object("menubar")
        self.set_menubar(menubar)
Example #29
0
    def __init__(self):
        super().__init__(
            application_id="net.lutris.Lutris",
            flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE,
        )

        GObject.add_emission_hook(Game, "game-launch", self.on_game_launch)
        GObject.add_emission_hook(Game, "game-start", self.on_game_start)
        GObject.add_emission_hook(Game, "game-stop", self.on_game_stop)
        GObject.add_emission_hook(Game, "game-install", self.on_game_install)

        GLib.set_application_name(_("Lutris"))
        self.window = None

        try:
            init_lutris()
        except RuntimeError as ex:
            ErrorDialog(str(ex))
            return

        self.running_games = Gio.ListStore.new(Game)
        self.app_windows = {}
        self.tray = None
        self.css_provider = Gtk.CssProvider.new()
        self.run_in_background = False

        if os.geteuid() == 0:
            ErrorDialog(
                _("Running Lutris as root is not recommended and may cause unexpected issues"
                  ))

        try:
            self.css_provider.load_from_path(
                os.path.join(datapath.get(), "ui", "lutris.css"))
        except GLib.Error as e:
            logger.exception(e)

        if hasattr(self, "add_main_option"):
            self.add_arguments()
        else:
            ErrorDialog(
                _("Your Linux distribution is too old. Lutris won't function properly."
                  ))
Example #30
0
def winetricks(app, prefix=None, arch=None, silent=True,
               wine_path=None, config=None, disable_runtime=False):
    """Execute winetricks."""
    winetricks_path = os.path.join(settings.RUNTIME_DIR, 'winetricks/winetricks')
    if not system.path_exists(winetricks_path):
        logger.warning("Could not find local winetricks install, falling back to bundled version")
        winetricks_path = os.path.join(datapath.get(), 'bin/winetricks')
    if wine_path:
        winetricks_wine = wine_path
    else:
        winetricks_wine = wine().get_executable()
    if arch not in ('win32', 'win64'):
        arch = detect_arch(prefix, winetricks_wine)
    args = app
    if str(silent).lower() in ('yes', 'on', 'true'):
        args = "--unattended " + args
    return wineexec(None, prefix=prefix, winetricks_wine=winetricks_wine,
                    wine_path=winetricks_path, arch=arch, args=args,
                    config=config, disable_runtime=disable_runtime)
Example #31
0
    def __init__(self):
        super().__init__(
            application_id="net.lutris.Lutris",
            flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE,
        )
        logger.info("Running Lutris %s", settings.VERSION)
        set_child_subreaper()
        gettext.bindtextdomain("lutris", "/usr/share/locale")
        gettext.textdomain("lutris")

        check_config()
        migrate()
        update_platforms()
        check_driver()
        check_libs()
        check_vulkan()

        GLib.set_application_name(_("Lutris"))
        self.running_games = []
        self.window = None
        self.help_overlay = None
        self.tray = None
        self.css_provider = Gtk.CssProvider.new()

        if os.geteuid() == 0:
            ErrorDialog(
                "Running Lutris as root is not recommended and may cause unexpected issues"
            )

        try:
            self.css_provider.load_from_path(
                os.path.join(datapath.get(), "ui", "lutris.css")
            )
        except GLib.Error as e:
            logger.exception(e)

        if hasattr(self, "add_main_option"):
            self.add_arguments()
        else:
            ErrorDialog(
                "Your Linux distribution is too old, Lutris won't function properly"
            )
Example #32
0
    def __init__(self):
        super().__init__()
        self.get_style_context().add_class("sidebar")
        self.installed_runners = []
        self.active_platforms = pga.get_used_platforms()
        self.runners = sorted(runners.__all__)
        self.platforms = sorted(platforms.__all__)

        GObject.add_emission_hook(RunnersDialog, "runner-installed",
                                  self.update)
        GObject.add_emission_hook(RunnersDialog, "runner-removed", self.update)
        GObject.add_emission_hook(Game, "game-updated", self.update)
        GObject.add_emission_hook(Game, "game-removed", self.update)

        # TODO: This should be in a more logical location
        icon_theme = Gtk.IconTheme.get_default()
        local_theme_path = os.path.join(datapath.get(), "icons")
        if local_theme_path not in icon_theme.get_search_path():
            icon_theme.prepend_search_path(local_theme_path)

        all_row = SidebarRow(None, "runner", "All", None)
        self.add(all_row)
        self.select_row(all_row)
        for runner in self.runners:
            icon = Gtk.Image.new_from_icon_name(
                runner.lower().replace(" ", "") + "-symbolic",
                Gtk.IconSize.MENU)
            name = runners.import_runner(runner).human_name
            self.add(SidebarRow(runner, "runner", name, icon))

        self.add(SidebarRow(None, "platform", "All", None))
        for platform in self.platforms:
            icon_name = (platform.lower().replace(" ", "").replace("/", "_") +
                         "-symbolic")
            icon = Gtk.Image.new_from_icon_name(icon_name, Gtk.IconSize.MENU)
            self.add(SidebarRow(platform, "platform", platform, icon))

        self.set_filter_func(self._filter_func)
        self.set_header_func(self._header_func)
        self.update()
        self.show_all()
Example #33
0
def winetricks(
        app,
        prefix=None,
        arch=None,
        silent=True,
        wine_path=None,
        config=None,
        disable_runtime=False,
):
    """Execute winetricks."""
    wine_config = config or LutrisConfig(runner_slug="wine")
    system_winetricks = wine_config.runner_config.get("system_winetricks")
    if system_winetricks:
        winetricks_path = "/usr/bin/winetricks"
    else:
        winetricks_path = os.path.join(settings.RUNTIME_DIR, "winetricks/winetricks")
        if not system.path_exists(winetricks_path):
            logger.warning(
                "Could not find local winetricks install, falling back to bundled version"
            )
            winetricks_path = os.path.join(datapath.get(), "bin/winetricks")
    if wine_path:
        winetricks_wine = wine_path
    else:
        wine = import_runner("wine")
        winetricks_wine = wine().get_executable()
    if arch not in ("win32", "win64"):
        arch = detect_arch(prefix, winetricks_wine)
    args = app
    if str(silent).lower() in ("yes", "on", "true"):
        args = "--unattended " + args
    return wineexec(
        None,
        prefix=prefix,
        winetricks_wine=winetricks_wine,
        wine_path=winetricks_path,
        arch=arch,
        args=args,
        config=config,
        disable_runtime=disable_runtime,
    )
Example #34
0
    def __init__(self):
        Gtk.Application.__init__(
            self,
            application_id='net.lutris.Lutris',
            flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE)
        GLib.set_application_name(_('Lutris'))
        self.window = None
        self.css_provider = Gtk.CssProvider.new()

        try:
            self.css_provider.load_from_path(
                os.path.join(datapath.get(), 'ui', 'log-window.css'))
        except GLib.Error as e:
            logger.exception(e)

        if hasattr(self, 'add_main_option'):
            self.add_arguments()
        else:
            ErrorDialog(
                "Your Linux distribution is too old, Lutris won't function properly"
            )
Example #35
0
    def setup_x360ce(self, x360ce_path):
        if not x360ce_path:
            return
        x360ce_path = os.path.expanduser(x360ce_path)
        if not os.path.isdir(x360ce_path):
            logger.error("%s is not a valid path for x360ce", x360ce_path)
            return
        mode = 'dumbxinputemu' if self.runner_config.get(
            'dumbxinputemu') else 'x360ce'
        dll_files = ['xinput1_3.dll']
        if self.runner_config.get('x360ce-xinput9'):
            dll_files.append('xinput9_1_0.dll')

        for dll_file in dll_files:
            xinput_dest_path = os.path.join(x360ce_path, dll_file)
            xinput_arch = self.runner_config.get(
                'xinput-arch') or self.wine_arch
            dll_path = os.path.join(
                datapath.get(), 'controllers/{}-{}'.format(mode, xinput_arch))
            if not os.path.exists(xinput_dest_path):
                source_file = dll_file if mode == 'dumbxinputemu' else 'xinput1_3.dll'
                shutil.copyfile(os.path.join(dll_path, source_file),
                                xinput_dest_path)

        if mode == 'x360ce':
            if self.runner_config.get('x360ce-dinput'):
                dinput8_path = os.path.join(dll_path, 'dinput8.dll')
                dinput8_dest_path = os.path.join(x360ce_path, 'dinput8.dll')
                shutil.copyfile(dinput8_path, dinput8_dest_path)

            x360ce_config = X360ce()
            x360ce_config.populate_controllers()
            x360ce_config.write(os.path.join(x360ce_path, 'x360ce.ini'))

        # X360 DLL handling
        self.dll_overrides['xinput1_3'] = 'native'
        if self.runner_config.get('x360ce-xinput9'):
            self.dll_overrides['xinput9_1_0'] = 'native'
        if self.runner_config.get('x360ce-dinput'):
            self.dll_overrides['dinput8'] = 'native'
Example #36
0
def get_pixbuf(image, size, fallback=None, is_installed=True):
    """Return a pixbuf from file `image` at `size` or fallback to `fallback`"""
    width, height = size
    pixbuf = None
    if system.path_exists(image, exclude_empty=True):
        try:
            pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(
                image, width, height)
            pixbuf = pixbuf.scale_simple(width, height,
                                         GdkPixbuf.InterpType.NEAREST)
        except GLib.GError:
            logger.error("Unable to load icon from image %s", image)
    else:
        if not fallback:
            fallback = get_default_icon(size)
        if system.path_exists(fallback):
            pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(
                fallback, width, height)
    if is_installed and pixbuf:
        pixbuf = pixbuf.scale_simple(width, height,
                                     GdkPixbuf.InterpType.NEAREST)
        return pixbuf
    overlay = os.path.join(datapath.get(), "media/unavailable.png")
    transparent_pixbuf = get_overlay(overlay, size).copy()
    if pixbuf:
        pixbuf.composite(
            transparent_pixbuf,
            0,
            0,
            size[0],
            size[1],
            0,
            0,
            1,
            1,
            GdkPixbuf.InterpType.NEAREST,
            100,
        )
    return transparent_pixbuf
Example #37
0
def get_pixbuf_for_game(image_abspath, size, is_installed=True):
    # icon_path = resources.get_icon_path(game_slug)
    pixbuf = get_pixbuf(image_abspath, size, fallback=get_default_icon(size))
    if not is_installed:
        unavailable_game_overlay = os.path.join(datapath.get(),
                                                "media/unavailable.png")
        transparent_pixbuf = get_overlay(unavailable_game_overlay, size).copy()
        pixbuf.composite(
            transparent_pixbuf,
            0,
            0,
            size[0],
            size[1],
            0,
            0,
            1,
            1,
            GdkPixbuf.InterpType.NEAREST,
            100,
        )
        return transparent_pixbuf
    return pixbuf
Example #38
0
    def get_runner_hbox(self, runner_name):
        # Get runner details
        runner = import_runner(runner_name)()
        platform = runner.platform
        description = runner.description

        hbox = Gtk.HBox()
        # Icon
        icon_path = os.path.join(datapath.get(), 'media/runner_icons',
                                 runner_name + '.png')
        icon = Gtk.Image()
        icon.set_from_file(icon_path)
        icon.set_alignment(0.5, 0.1)
        hbox.pack_start(icon, False, False, 10)

        # Label
        runner_label = Gtk.Label()
        if not runner.is_installed():
            runner_label.set_sensitive(False)
        runner_label.set_markup(
            "<b>%s</b>\n%s\n <i>Supported platforms : %s</i>" %
            (runner.human_name, description, platform)
        )
        runner_label.set_width_chars(40)
        runner_label.set_max_width_chars(40)
        runner_label.set_property('wrap', True)
        runner_label.set_line_wrap(True)
        runner_label.set_alignment(0.0, 0.1)
        runner_label.set_padding(5, 0)
        self.runner_labels[runner] = runner_label
        hbox.pack_start(runner_label, True, True, 5)
        # Button
        button = Gtk.Button()
        button.set_size_request(100, 30)
        button_align = Gtk.Alignment.new(1.0, 0.0, 0.0, 0.0)
        self.configure_button(button, runner)
        button_align.add(button)
        hbox.pack_start(button_align, False, False, 15)
        return hbox
Example #39
0
    def __init__(self):
        super().__init__()
        self.get_style_context().add_class("sidebar")
        self.installed_runners = []
        self.active_platforms = pga.get_used_platforms()
        self.runners = sorted(runners.__all__)
        self.platforms = sorted(platforms.__all__)

        GObject.add_emission_hook(RunnersDialog, "runner-installed", self.update)
        GObject.add_emission_hook(RunnersDialog, "runner-removed", self.update)
        GObject.add_emission_hook(Game, "game-updated", self.update)
        GObject.add_emission_hook(Game, "game-removed", self.update)

        # TODO: This should be in a more logical location
        icon_theme = Gtk.IconTheme.get_default()
        local_theme_path = os.path.join(datapath.get(), "icons")
        if local_theme_path not in icon_theme.get_search_path():
            icon_theme.prepend_search_path(local_theme_path)

        all_row = SidebarRow(None, "runner", "All", None)
        self.add(all_row)
        self.select_row(all_row)
        for runner in self.runners:
            icon = Gtk.Image.new_from_icon_name(
                runner.lower().replace(" ", "") + "-symbolic", Gtk.IconSize.MENU
            )
            name = runners.import_runner(runner).human_name
            self.add(SidebarRow(runner, "runner", name, icon))

        self.add(SidebarRow(None, "platform", "All", None))
        for platform in self.platforms:
            icon_name = platform.lower().replace(" ", "") + "-symbolic"
            icon = Gtk.Image.new_from_icon_name(icon_name, Gtk.IconSize.MENU)
            self.add(SidebarRow(platform, "platform", platform, icon))

        self.set_filter_func(self._filter_func)
        self.set_header_func(self._header_func)
        self.update()
        self.show_all()
Example #40
0
    def play(self):
        launch_info = {}
        launch_info["env"] = self.get_env(os_env=False)

        game_data = pga.get_game_by_field(self.config.game_config_id,
                                          "configpath")

        command = self.launch_args

        if self.is_native:
            if not self.runner_config.get("splore"):
                command.append("-run")
            cartPath = self.cart_path
            if not os.path.exists(cartPath):
                return {"error": "FILE_NOT_FOUND", "file": cartPath}
            command.append(cartPath)

        else:
            command.append("--name")
            command.append(game_data.get("name") + " - PICO-8")

            icon = datapath.get_icon_path(game_data.get("slug"))
            if not os.path.exists(icon):
                icon = os.path.join(datapath.get(),
                                    "media/runner_icons/pico8.png")
            command.append("--icon")
            command.append(icon)

            webargs = {
                "cartridge": self.cart_path,
                "engine": self.engine_path,
                "fullscreen": self.runner_config.get("fullscreen") is True,
            }
            command.append("--execjs")
            command.append("load_config(" + json.dumps(webargs) + ")")

        launch_info["command"] = command
        return launch_info
Example #41
0
    def __init__(self):

        Gtk.Application.__init__(
            self,
            application_id='net.lutris.Lutris',
            flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE)

        gettext.bindtextdomain("lutris", "/usr/share/locale")
        gettext.textdomain("lutris")

        check_config()
        init_dxvk_versions()
        migrate()
        update_platforms()

        GLib.set_application_name(_('Lutris'))
        self.window = None
        self.tray = None
        self.css_provider = Gtk.CssProvider.new()

        if os.geteuid() == 0:
            ErrorDialog(
                "Running Lutris as root is not recommended and may cause unexpected issues"
            )

        try:
            self.css_provider.load_from_path(
                os.path.join(datapath.get(), 'ui', 'lutris.css'))
        except GLib.Error as e:
            logger.exception(e)

        if hasattr(self, 'add_main_option'):
            self.add_arguments()
        else:
            ErrorDialog(
                "Your Linux distribution is too old, Lutris won't function properly"
            )
Example #42
0
def winetricks(
        app,
        prefix=None,
        arch=None,
        silent=True,
        wine_path=None,
        config=None,
        disable_runtime=False,
):
    """Execute winetricks."""
    winetricks_path = os.path.join(settings.RUNTIME_DIR, "winetricks/winetricks")
    if not system.path_exists(winetricks_path):
        logger.warning(
            "Could not find local winetricks install, falling back to bundled version"
        )
        winetricks_path = os.path.join(datapath.get(), "bin/winetricks")
    if wine_path:
        winetricks_wine = wine_path
    else:
        wine = import_runner("wine")
        winetricks_wine = wine().get_executable()
    if arch not in ("win32", "win64"):
        arch = detect_arch(prefix, winetricks_wine)
    args = app
    if str(silent).lower() in ("yes", "on", "true"):
        args = "--unattended " + args
    return wineexec(
        None,
        prefix=prefix,
        winetricks_wine=winetricks_wine,
        wine_path=winetricks_path,
        arch=arch,
        args=args,
        config=config,
        disable_runtime=disable_runtime,
    )
Example #43
0
class GameControllerDB:
    db_path = os.path.join(datapath.get(), 'controllers/gamecontrollerdb.txt')

    def __init__(self):
        if not system.path_exists(self.db_path):
            raise OSError(
                "Path to gamecontrollerdb.txt not provided or invalid")
        self.controllers = {}
        self.parsedb()

    def __str__(self):
        return "GameControllerDB <%s>" % self.db_path

    def __getitem__(self, value):
        return self.controllers[value]

    def parsedb(self):
        with open(self.db_path, 'r') as db:
            for line in db.readlines():
                line = line.strip()
                if not line or line.startswith('#'):
                    continue
                guid, name, mapping = line.strip().split(',', 2)
                self.controllers[guid] = ControllerMapping(guid, name, mapping)
Example #44
0
def get_icon(icon_name, format="image", size=None, icon_type="runner"):
    """Return an icon based on the given name, format, size and type.

    Keyword arguments:
    icon_name -- The name of the icon to retrieve
    format -- The format of the icon, which should be either 'image' or 'pixbuf' (default 'image')
    size -- The size for the desired image (default None)
    icon_type -- Retrieve either a 'runner' or 'platform' icon (default 'runner')
    """
    filename = icon_name.lower().replace(" ", "") + ".png"
    icon_path = os.path.join(datapath.get(), "media/" + icon_type + "_icons", filename)
    if not os.path.exists(icon_path):
        logger.error("Unable to find icon '%s'", icon_path)
        return None
    if format == "image":
        icon = Gtk.Image()
        if size:
            icon.set_from_pixbuf(get_pixbuf(icon_path, size))
        else:
            icon.set_from_file(icon_path)
        return icon
    elif format == "pixbuf" and size:
        return get_pixbuf(icon_path, size)
    raise ValueError("Invalid arguments")
Example #45
0
    def play(self):
        launch_info = {}
        launch_info["env"] = self.get_env(os_env=False)

        game_data = pga.get_game_by_field(self.config.game_config_id, "configpath")

        command = self.launch_args

        if self.is_native:
            if not self.runner_config.get("splore"):
                command.append("-run")
            cartPath = self.cart_path
            if not os.path.exists(cartPath):
                return {"error": "FILE_NOT_FOUND", "file": cartPath}
            command.append(cartPath)

        else:
            command.append("--name")
            command.append(game_data.get("name") + " - PICO-8")

            icon = datapath.get_icon_path(game_data.get("slug"))
            if not os.path.exists(icon):
                icon = os.path.join(datapath.get(), "media/runner_icons/pico8.png")
            command.append("--icon")
            command.append(icon)

            webargs = {
                "cartridge": self.cart_path,
                "engine": self.engine_path,
                "fullscreen": self.runner_config.get("fullscreen") is True,
            }
            command.append("--execjs")
            command.append("load_config(" + json.dumps(webargs) + ")")

        launch_info["command"] = command
        return launch_info
Example #46
0
def get_icon(icon_name, format="image", size=None, icon_type="runner"):
    """Return an icon based on the given name, format, size and type.

    Keyword arguments:
    icon_name -- The name of the icon to retrieve
    format -- The format of the icon, which should be either 'image' or 'pixbuf' (default 'image')
    size -- The size for the desired image (default None)
    icon_type -- Retrieve either a 'runner' or 'platform' icon (default 'runner')
    """
    filename = icon_name.lower().replace(" ", "") + ".png"
    icon_path = os.path.join(datapath.get(), "media/" + icon_type + "_icons", filename)
    if not os.path.exists(icon_path):
        logger.error("Unable to find icon '%s'", icon_path)
        return None
    if format == "image":
        icon = Gtk.Image()
        if size:
            icon.set_from_pixbuf(get_pixbuf(icon_path, size))
        else:
            icon.set_from_file(icon_path)
        return icon
    elif format == "pixbuf" and size:
        return get_pixbuf(icon_path, size)
    raise ValueError("Invalid arguments")
Example #47
0
# -*- coding:Utf-8 -*-
"""Misc widgets used in the GUI."""
import os

from gi.repository import Gtk, GObject, Pango, GdkPixbuf, GLib
from IPython.testing.decorators import make_label_dec
from gi.repository.GdkPixbuf import Pixbuf

from lutris.downloader import Downloader
from lutris.util import datapath
from lutris import settings

MISSING_ICON = os.path.join(datapath.get(), "media/banner.png")
UNAVAILABLE_GAME_OVERLAY = os.path.join(datapath.get(), "media/unavailable.png")
ICON_SIZE = (184, 69)
(COL_ID, COL_NAME, COL_ICON, COL_RUNNER, COL_INSTALLED) = range(5)


def sort_func(store, a_iter, b_iter, _user_data):
    """Default sort function"""
    a_name = store.get(a_iter, COL_NAME)
    b_name = store.get(b_iter, COL_NAME)

    if a_name > b_name:
        return 1
    elif a_name < b_name:
        return -1
    else:
        return 0

Example #48
0
    def __init__(self):

        ui_filename = os.path.join(
            datapath.get(), 'ui', 'LutrisWindow.ui'
        )
        if not os.path.exists(ui_filename):
            raise IOError('File %s not found' % ui_filename)

        self.builder = Gtk.Builder()
        self.builder.add_from_file(ui_filename)

        # load config
        width = int(settings.read_setting('width') or 800)
        height = int(settings.read_setting('height') or 600)
        self.window_size = (width, height)
        view_type = settings.read_setting('view_type') or 'icon'
        filter_installed_setting = settings.read_setting(
            'filter_installed'
        ) or 'false'
        self.filter_installed = filter_installed_setting == 'true'
        show_installed_games_menuitem = self.builder.get_object(
            'filter_installed'
        )
        show_installed_games_menuitem.set_active(self.filter_installed)
        logger.debug("Getting game list")
        game_list = get_game_list(self.filter_installed)
        logger.debug("Switching view")
        self.view = switch_to_view(view_type, game_list)
        logger.debug("Connecting signals")
        self.icon_view_menuitem = self.builder.get_object("iconview_menuitem")
        self.icon_view_menuitem.set_active(view_type == 'icon')
        self.list_view_menuitem = self.builder.get_object("listview_menuitem")
        self.list_view_menuitem.set_active(view_type == 'list')
        self.icon_view_btn = self.builder.get_object('switch_grid_view_btn')
        self.icon_view_btn.set_active(view_type == 'icon')
        self.list_view_btn = self.builder.get_object('switch_list_view_btn')
        self.list_view_btn.set_active(view_type == 'list')

        # Scroll window
        self.games_scrollwindow = self.builder.get_object('games_scrollwindow')
        self.games_scrollwindow.add(self.view)
        #Status bar
        self.status_label = self.builder.get_object('status_label')
        self.joystick_icons = []
        # Buttons
        self.stop_button = self.builder.get_object('stop_button')
        self.stop_button.set_sensitive(False)
        self.delete_button = self.builder.get_object('delete_button')
        self.delete_button.set_sensitive(False)
        self.play_button = self.builder.get_object('play_button')
        self.play_button.set_sensitive(False)

        #Contextual menu
        menu_callbacks = [
            ('play', self.on_game_clicked),
            ('install', self.on_game_clicked),
            ('add', self.add_manually),
            ('configure', self.edit_game_configuration),
            ('desktop-shortcut', self.create_desktop_shortcut),
            ('menu-shortcut', self.create_menu_shortcut),
            ('uninstall', self.on_remove_game),
        ]
        self.menu = ContextualMenu(menu_callbacks)
        self.view.contextual_menu = self.menu

        #Timer
        self.timer_id = GLib.timeout_add(2000, self.refresh_status)
        self.window = self.builder.get_object("window")
        self.window.resize_to_geometry(width, height)
        self.window.show_all()

        self.builder.connect_signals(self)
        self.connect_signals()

        if api.read_api_key():
            self.status_label.set_text("Connected to lutris.net")
            self.sync_library()
        else:
            async_call(self.sync_icons, None)
Example #49
0
from lutris.gui import dialogs
from lutris.gui.widgets.sidebar import SidebarListBox
from lutris.gui.widgets.services import SyncServiceWindow
from lutris.gui.dialogs.runners import RunnersDialog
from lutris.gui.config.add_game import AddGameDialog
from lutris.gui.config.system import SystemConfigDialog
from lutris.gui.views.list import GameListView
from lutris.gui.views.grid import GameGridView
from lutris.gui.views.menu import ContextualMenu
from lutris.gui.views.store import GameStore
from lutris.gui.views.game_panel import GamePanel, GenericPanel
from lutris.gui.widgets.utils import IMAGE_SIZES, open_uri


@GtkTemplate(ui=os.path.join(datapath.get(), "ui", "lutris-window.ui"))
class LutrisWindow(Gtk.ApplicationWindow):
    """Handler class for main window signals."""

    default_view_type = "grid"
    default_width = 800
    default_height = 600

    __gtype_name__ = "LutrisWindow"

    main_box = GtkTemplate.Child()
    games_scrollwindow = GtkTemplate.Child()
    sidebar_revealer = GtkTemplate.Child()
    sidebar_scrolled = GtkTemplate.Child()
    connection_label = GtkTemplate.Child()
    search_revealer = GtkTemplate.Child()
Example #50
0
    def __init__(self, service=None):

        Gtk.Application.__init__(
            self, application_id="net.lutris.main",
            flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE
        )
        ui_filename = os.path.join(
            datapath.get(), 'ui', 'lutris-window.ui'
        )
        if not os.path.exists(ui_filename):
            raise IOError('File %s not found' % ui_filename)

        self.service = service
        self.runtime_updater = RuntimeUpdater()
        self.running_game = None
        self.threads_stoppers = []

        # Emulate double click to workaround GTK bug #484640
        # https://bugzilla.gnome.org/show_bug.cgi?id=484640
        self.game_selection_time = 0
        self.game_launch_time = 0
        self.last_selected_game = None
        self.selected_runner = None

        self.builder = Gtk.Builder()
        self.builder.add_from_file(ui_filename)

        # Load settings
        width = int(settings.read_setting('width') or 800)
        height = int(settings.read_setting('height') or 600)
        self.window_size = (width, height)
        window = self.builder.get_object('window')
        window.resize(width, height)
        view_type = self.get_view_type()
        self.load_icon_type_from_settings(view_type)
        self.filter_installed = \
            settings.read_setting('filter_installed') == 'true'
        self.sidebar_visible = \
            settings.read_setting('sidebar_visible') in ['true', None]

        # Set theme to dark if set in the settings
        dark_theme_menuitem = self.builder.get_object('dark_theme_menuitem')
        use_dark_theme = settings.read_setting('dark_theme') == 'true'
        dark_theme_menuitem.set_active(use_dark_theme)
        self.set_dark_theme(use_dark_theme)

        self.game_list = pga.get_games()

        # Load view
        self.game_store = GameStore([], self.icon_type, self.filter_installed)
        self.view = self.get_view(view_type)

        self.main_box = self.builder.get_object('main_box')
        self.splash_box = self.builder.get_object('splash_box')
        self.connect_link = self.builder.get_object('connect_link')
        # View menu
        installed_games_only_menuitem =\
            self.builder.get_object('filter_installed')
        installed_games_only_menuitem.set_active(self.filter_installed)
        self.grid_view_menuitem = self.builder.get_object("gridview_menuitem")
        self.grid_view_menuitem.set_active(view_type == 'grid')
        self.list_view_menuitem = self.builder.get_object("listview_menuitem")
        self.list_view_menuitem.set_active(view_type == 'list')
        sidebar_menuitem = self.builder.get_object('sidebar_menuitem')
        sidebar_menuitem.set_active(self.sidebar_visible)

        # View buttons
        self.grid_view_btn = self.builder.get_object('switch_grid_view_btn')
        self.grid_view_btn.set_active(view_type == 'grid')
        self.list_view_btn = self.builder.get_object('switch_list_view_btn')
        self.list_view_btn.set_active(view_type == 'list')
        # Icon type menu
        self.banner_small_menuitem = \
            self.builder.get_object('banner_small_menuitem')
        self.banner_small_menuitem.set_active(self.icon_type == 'banner_small')
        self.banner_menuitem = self.builder.get_object('banner_menuitem')
        self.banner_menuitem.set_active(self.icon_type == 'banner')
        self.icon_menuitem = self.builder.get_object('icon_menuitem')
        self.icon_menuitem.set_active(self.icon_type == 'icon')

        self.search_entry = self.builder.get_object('search_entry')
        self.search_entry.connect('icon-press', self.on_clear_search)

        # Scroll window
        self.games_scrollwindow = self.builder.get_object('games_scrollwindow')
        self.games_scrollwindow.add(self.view)
        # Buttons
        self.stop_button = self.builder.get_object('stop_button')
        self.stop_button.set_sensitive(False)
        self.delete_button = self.builder.get_object('delete_button')
        self.delete_button.set_sensitive(False)
        self.play_button = self.builder.get_object('play_button')
        self.play_button.set_sensitive(False)

        # Contextual menu
        main_entries = [
            ('play', "Play", self.on_game_run),
            ('install', "Install", self.on_install_clicked),
            ('add', "Add manually", self.on_add_manually),
            ('configure', "Configure", self.on_edit_game_configuration),
            ('browse', "Browse files", self.on_browse_files),
            ('desktop-shortcut', "Create desktop shortcut",
             self.create_desktop_shortcut),
            ('rm-desktop-shortcut', "Delete desktop shortcut",
             self.remove_desktop_shortcut),
            ('menu-shortcut', "Create application menu shortcut",
             self.create_menu_shortcut),
            ('rm-menu-shortcut', "Delete application menu shortcut",
             self.remove_menu_shortcut),
            ('install_more', "Install (add) another version", self.on_install_clicked),
            ('remove', "Remove", self.on_remove_game),
        ]
        self.menu = ContextualMenu(main_entries)
        self.view.contextual_menu = self.menu

        # Sidebar
        self.sidebar_paned = self.builder.get_object('sidebar_paned')
        self.sidebar_treeview = SidebarTreeView()
        self.sidebar_treeview.connect('cursor-changed', self.on_sidebar_changed)
        self.sidebar_viewport = self.builder.get_object('sidebar_viewport')
        self.sidebar_viewport.add(self.sidebar_treeview)

        # Window initialization
        self.window = self.builder.get_object("window")
        self.window.resize_to_geometry(width, height)
        self.window.set_default_icon_name('lutris')
        self.window.show_all()
        self.builder.connect_signals(self)
        self.connect_signals()

        self.statusbar = self.builder.get_object("statusbar")

        # XXX Hide PGA config menu item until it actually gets implemented
        pga_menuitem = self.builder.get_object('pga_menuitem')
        pga_menuitem.hide()

        # Sync local lutris library with current Steam games before setting up
        # view
        steam.sync_with_lutris()

        self.game_store.fill_store(self.game_list)
        self.switch_splash_screen()

        self.show_sidebar()
        self.update_runtime()

        # Connect account and/or sync
        credentials = api.read_api_key()
        if credentials:
            self.on_connect_success(None, credentials)
        else:
            self.toggle_connection(False)
            self.sync_library()

        # Timers
        self.timer_ids = [GLib.timeout_add(300, self.refresh_status)]
        steamapps_paths = steam.get_steamapps_paths(flat=True)
        self.steam_watcher = steam.SteamWatcher(steamapps_paths,
                                                self.on_steam_game_changed)
Example #51
0
from lutris.gui import dialogs
from lutris.gui.sidebar import SidebarTreeView
from lutris.gui.logwindow import LogWindow
from lutris.gui.sync import SyncServiceDialog
from lutris.gui.gi_composites import GtkTemplate
from lutris.gui.runnersdialog import RunnersDialog
from lutris.gui.installerwindow import InstallerWindow
from lutris.gui.uninstallgamedialog import UninstallGameDialog
from lutris.gui.config_dialogs import (AddGameDialog, EditGameConfigDialog,
                                       SystemConfigDialog)
from lutris.gui.gameviews import (GameListView, GameGridView, ContextualMenu,
                                  GameStore)


@GtkTemplate(ui=os.path.join(datapath.get(), 'ui', 'lutris-window.ui'))
class LutrisWindow(Gtk.ApplicationWindow):
    """Handler class for main window signals."""

    __gtype_name__ = 'LutrisWindow'

    main_box = GtkTemplate.Child()
    splash_box = GtkTemplate.Child()
    connect_link = GtkTemplate.Child()
    games_scrollwindow = GtkTemplate.Child()
    sidebar_paned = GtkTemplate.Child()
    sidebar_viewport = GtkTemplate.Child()
    statusbar = GtkTemplate.Child()
    connection_label = GtkTemplate.Child()
    status_box = GtkTemplate.Child()
Example #52
0
class RunnersDialog(GtkBuilderDialog):
    """Dialog to manage the runners."""
    glade_file = "runners-dialog.ui"
    dialog_object = "runners_dialog"
    runner_entry_ui = os.path.join(datapath.get(), "ui", 'runner-entry.ui')

    __gsignals__ = {
        "runner-installed": (GObject.SIGNAL_RUN_FIRST, None, ()),
        "runner-removed": (GObject.SIGNAL_RUN_FIRST, None, ()),
    }

    def initialize(self, **kwargs):
        width = int(settings.read_setting("runners_manager_width") or 800)
        height = int(settings.read_setting("runners_manager_height") or 800)
        self.dialog_size = (width, height)
        self.dialog.resize(width, height)

        self.runner_listbox = self.builder.get_object('runners_listbox')
        self.runner_listbox.set_header_func(self._listbox_header_func)

        self.refresh_button = self.builder.get_object('refresh_button')

        self.runner_list = sorted(runners.__all__)
        # Run this after show_all, else all hidden buttons gets shown
        self.populate_runners()

    @staticmethod
    def _listbox_header_func(row, before):
        if not row.get_header() and before is not None:
            row.set_header(Gtk.Separator.new(Gtk.Orientation.HORIZONTAL))

    def get_runner_hbox(self, runner_name):
        # Get runner details
        runner = runners.import_runner(runner_name)()
        platform = ", ".join(sorted(list(set(runner.platforms))))

        builder = Gtk.Builder()
        builder.add_from_file(self.runner_entry_ui)
        hbox = builder.get_object('runner_entry')
        hbox.show()

        # Icon
        runner_icon = builder.get_object('runner_icon')
        runner_icon.set_from_pixbuf(
            get_icon(runner_name, format='pixbuf', size=ICON_SIZE))

        # Label
        runner_name = builder.get_object('runner_name')
        runner_name.set_text(runner.human_name)
        runner_description = builder.get_object('runner_description')
        runner_description.set_text(runner.description)
        runner_platform = builder.get_object('runner_platform')
        runner_platform.set_text(platform)
        runner_label = builder.get_object('runner_label')
        if not runner.is_installed():
            runner_label.set_sensitive(False)

        # Buttons
        self.versions_button = builder.get_object('manage_versions')
        self.versions_button.connect("clicked", self.on_versions_clicked,
                                     runner, runner_label)
        self.install_button = builder.get_object('install_runner')
        self.install_button.connect("clicked", self.on_install_clicked, runner,
                                    runner_label)
        self.remove_button = builder.get_object('remove_runner')
        self.remove_button.connect("clicked", self.on_remove_clicked, runner,
                                   runner_label)
        self.configure_button = builder.get_object('configure_runner')
        self.configure_button.connect("clicked", self.on_configure_clicked,
                                      runner, runner_label)
        self.set_button_display(runner)

        return hbox

    def populate_runners(self):
        for runner_name in self.runner_list:
            hbox = self.get_runner_hbox(runner_name)
            self.runner_listbox.add(hbox)

    def set_button_display(self, runner):
        if runner.multiple_versions:
            self.versions_button.show()
            self.install_button.hide()
            if runner.can_uninstall():
                self.remove_button.show()
            else:
                self.remove_button.hide()
        else:
            self.versions_button.hide()
            self.remove_button.hide()
            self.install_button.show()

        if runner.is_installed():
            self.install_button.hide()
            if runner.can_uninstall():
                self.remove_button.show()
            else:
                self.remove_button.hide()

        self.configure_button.show()

    def on_versions_clicked(self, widget, runner, runner_label):
        dlg_title = "Manage %s versions" % runner.name
        versions_dialog = RunnerInstallDialog(dlg_title, self.dialog,
                                              runner.name)
        versions_dialog.connect("destroy", self.set_install_state, runner,
                                runner_label)

    def on_install_clicked(self, widget, runner, runner_label):
        """Install a runner."""
        if runner.depends_on:
            dependency = runner.depends_on()
            dependency.install(downloader=simple_downloader)
        try:
            runner.install(downloader=simple_downloader)
        except (
                runners.RunnerInstallationError,
                runners.NonInstallableRunnerError,
        ) as ex:
            ErrorDialog(ex.message, parent=self)
        if runner.is_installed():
            self.emit("runner-installed")
            self.refresh_button.emit("clicked")

    def on_configure_clicked(self, widget, runner, runner_label):
        config_dialog = RunnerConfigDialog(runner, parent=self.dialog)
        config_dialog.connect("destroy", self.set_install_state, runner,
                              runner_label)

    def on_remove_clicked(self, widget, runner, runner_label):
        if not runner.is_installed():
            logger.warning("Runner %s is not installed", runner)
            return

        if runner.multiple_versions:
            logger.info("Removing multiple versions")
            builder = get_builder_from_file(
                'runner-remove-all-versions-dialog.ui')
            builder.connect_signals(self)
            remove_confirm_button = builder.get_object('remove_confirm_button')
            remove_confirm_button.connect("clicked",
                                          self.on_remove_all_clicked, runner,
                                          runner_label)
            all_versions_label = builder.get_object(
                'runner_all_versions_label')
            all_versions_label.set_markup(all_versions_label.get_label() %
                                          runner.human_name)
            self.all_versions_dialog = builder.get_object(
                'runner_remove_all_versions_dialog')
            self.all_versions_dialog.set_parent(self.dialog)
            self.all_versions_dialog.show()
        else:
            builder = get_builder_from_file('runner-remove-confirm-dialog.ui')
            builder.connect_signals(self)
            remove_confirm_button = builder.get_object('remove_confirm_button')
            remove_confirm_button.connect("clicked",
                                          self.on_remove_confirm_clicked,
                                          runner, runner_label)
            runner_remove_label = builder.get_object('runner_remove_label')
            runner_remove_label.set_markup(runner_remove_label.get_label() %
                                           runner.human_name)
            self.remove_confirm_dialog = builder.get_object(
                'runner_remove_confirm_dialog')
            self.remove_confirm_dialog.show()

    def on_remove_confirm_clicked(self, widget, runner, runner_label):
        runner.uninstall()
        self.refresh_button.emit("clicked")
        self.emit("runner-removed")
        self.remove_confirm_dialog.destroy()

    def on_remove_all_clicked(self, _widget, runner, _runner_label):
        runner.uninstall()
        self.refresh_button.emit("clicked")
        self.emit("runner-removed")
        self.all_versions_dialog.destroy()

    def on_cancel_confirm_clicked(self, _widget):
        self.remove_confirm_dialog.destroy()

    def on_cancel_all_clicked(self, _widget):
        self.all_versions_dialog.destroy()

    @staticmethod
    def on_folder_clicked(_widget):
        open_uri("file://" + settings.RUNNER_DIR)

    def on_refresh_clicked(self, _widget):
        for child in self.runner_listbox:
            child.destroy()
        self.populate_runners()

    def on_close_clicked(self, _widget):
        self.destroy()

    def set_install_state(self, _widget, runner, runner_label):
        if runner.is_installed():
            runner_label.set_sensitive(True)
            self.emit("runner-installed")
        else:
            runner_label.set_sensitive(False)

    def on_resize(self, _widget, *args):
        """Store the dialog's new size."""
        self.dialog_size = self.dialog.get_size()

    def on_destroy(self, _widget):
        # Save window size
        width, height = self.dialog_size
        settings.write_setting("runners_manager_width", width)
        settings.write_setting("runners_manager_height", height)
Example #53
0
"""Run web based games"""
import os
import string
from gettext import gettext as _
from urllib.parse import urlparse

from lutris import settings
from lutris.database.games import get_game_by_field
from lutris.runners.runner import Runner
from lutris.util import datapath, linux, resources, system
from lutris.util.strings import split_arguments

DEFAULT_ICON = os.path.join(datapath.get(), "media/default_icon.png")


class web(Runner):
    human_name = _("Web")
    description = _("Runs web based games")
    platforms = [_("Web")]
    game_options = [{
        "option":
        "main_file",
        "type":
        "string",
        "label":
        _("Full URL or HTML file path"),
        "help":
        _("The full address of the game's web page or path to a HTML file."),
    }]
    runner_options = [
        {
Example #54
0
from lutris.gui import dialogs
from lutris.gui.sidebar import SidebarTreeView
from lutris.gui.logwindow import LogWindow
from lutris.gui.gi_composites import GtkTemplate
from lutris.gui.runnersdialog import RunnersDialog
from lutris.gui.installgamedialog import InstallerDialog
from lutris.gui.uninstallgamedialog import UninstallGameDialog
from lutris.gui.config_dialogs import (
    AddGameDialog, EditGameConfigDialog, SystemConfigDialog
)
from lutris.gui.gameviews import (
    GameListView, GameGridView, ContextualMenu, GameStore
)


@GtkTemplate(ui=os.path.join(datapath.get(), 'ui', 'lutris-window.ui'))
class LutrisWindow(Gtk.ApplicationWindow):
    """Handler class for main window signals."""

    __gtype_name__ = 'LutrisWindow'

    main_box = GtkTemplate.Child()
    splash_box = GtkTemplate.Child()
    connect_link = GtkTemplate.Child()
    games_scrollwindow = GtkTemplate.Child()
    sidebar_paned = GtkTemplate.Child()
    sidebar_viewport = GtkTemplate.Child()
    statusbar = GtkTemplate.Child()
    connection_label = GtkTemplate.Child()
    status_box = GtkTemplate.Child()
Example #55
0
def get_default_icon(size):
    if size[0] == size[1]:
        return os.path.join(datapath.get(), "media/default_icon.png")
    return os.path.join(datapath.get(), "media/default_banner.png")
Example #56
0
    def __init__(self):

        ui_filename = os.path.join(datapath.get(), "ui", "LutrisWindow.ui")
        if not os.path.exists(ui_filename):
            raise IOError("File %s not found" % ui_filename)

        self.running_game = None
        self.threads_stoppers = []

        # Emulate double click to workaround GTK bug #484640
        # https://bugzilla.gnome.org/show_bug.cgi?id=484640
        self.game_selection_time = 0
        self.game_launch_time = 0
        self.last_selected_game = None

        self.builder = Gtk.Builder()
        self.builder.add_from_file(ui_filename)

        # Load settings
        width = int(settings.read_setting("width") or 800)
        height = int(settings.read_setting("height") or 600)
        self.window_size = (width, height)
        view_type = self.get_view_type()
        self.icon_type = self.get_icon_type(view_type)
        filter_installed_setting = settings.read_setting("filter_installed") or "false"
        filter_installed = filter_installed_setting == "true"
        show_installed_games_menuitem = self.builder.get_object("filter_installed")
        show_installed_games_menuitem.set_active(filter_installed)

        # Load view
        logger.debug("Loading view")
        self.game_store = GameStore([], self.icon_type, filter_installed)
        self.view = load_view(view_type, self.game_store)

        logger.debug("Connecting signals")
        self.main_box = self.builder.get_object("main_box")
        self.splash_box = self.builder.get_object("splash_box")
        # View menu
        self.grid_view_menuitem = self.builder.get_object("gridview_menuitem")
        self.grid_view_menuitem.set_active(view_type == "grid")
        self.list_view_menuitem = self.builder.get_object("listview_menuitem")
        self.list_view_menuitem.set_active(view_type == "list")
        # View buttons
        self.grid_view_btn = self.builder.get_object("switch_grid_view_btn")
        self.grid_view_btn.set_active(view_type == "grid")
        self.list_view_btn = self.builder.get_object("switch_list_view_btn")
        self.list_view_btn.set_active(view_type == "list")
        # Icon type menu
        self.banner_small_menuitem = self.builder.get_object("banner_small_menuitem")
        self.banner_small_menuitem.set_active(self.icon_type == "banner_small")
        self.banner_menuitem = self.builder.get_object("banner_menuitem")
        self.banner_menuitem.set_active(self.icon_type == "banner")
        self.icon_menuitem = self.builder.get_object("icon_menuitem")
        self.icon_menuitem.set_active(self.icon_type == "icon")

        self.search_entry = self.builder.get_object("search_entry")
        self.search_entry.connect("icon-press", self.on_clear_search)

        # Scroll window
        self.games_scrollwindow = self.builder.get_object("games_scrollwindow")
        self.games_scrollwindow.add(self.view)
        # Status bar
        self.status_label = self.builder.get_object("status_label")
        self.joystick_icons = []
        # Buttons
        self.stop_button = self.builder.get_object("stop_button")
        self.stop_button.set_sensitive(False)
        self.delete_button = self.builder.get_object("delete_button")
        self.delete_button.set_sensitive(False)
        self.play_button = self.builder.get_object("play_button")
        self.play_button.set_sensitive(False)

        # Contextual menu
        main_entries = [
            ("play", "Play", self.on_game_run),
            ("install", "Install", self.on_install_clicked),
            ("add", "Add manually", self.add_manually),
            ("configure", "Configure", self.edit_game_configuration),
            ("browse", "Browse files", self.on_browse_files),
            ("desktop-shortcut", "Create desktop shortcut", self.create_desktop_shortcut),
            ("rm-desktop-shortcut", "Delete desktop shortcut", self.remove_desktop_shortcut),
            ("menu-shortcut", "Create application menu shortcut", self.create_menu_shortcut),
            ("rm-menu-shortcut", "Delete application menu shortcut", self.remove_menu_shortcut),
            ("remove", "Remove", self.on_remove_game),
        ]
        self.menu = ContextualMenu(main_entries)
        self.view.contextual_menu = self.menu

        # Sidebar
        sidebar_paned = self.builder.get_object("sidebar_paned")
        sidebar_paned.set_position(150)
        self.sidebar_treeview = SidebarTreeView()
        self.sidebar_treeview.connect("cursor-changed", self.on_sidebar_changed)
        self.sidebar_viewport = self.builder.get_object("sidebar_viewport")
        self.sidebar_viewport.add(self.sidebar_treeview)

        # Window initialization
        self.window = self.builder.get_object("window")
        self.window.resize_to_geometry(width, height)
        self.window.show_all()
        self.builder.connect_signals(self)
        self.connect_signals()

        # XXX Hide PGA config menu item until it actually gets implemented
        pga_menuitem = self.builder.get_object("pga_menuitem")
        pga_menuitem.hide()

        self.init_game_store()

        # Connect account and/or sync
        credentials = api.read_api_key()
        if credentials:
            self.on_connect_success(None, credentials)
        else:
            self.toggle_connection(False)
            self.sync_library()

        # Timers
        self.timer_ids = [GLib.timeout_add(300, self.refresh_status), GLib.timeout_add(10000, self.on_sync_timer)]
Example #57
0
# -*- coding:Utf-8 -*-
"""Misc widgets used in the GUI."""
import os

from gi.repository import Gtk, GObject, Pango, GdkPixbuf, GLib
from gi.repository.GdkPixbuf import Pixbuf

from lutris.downloader import Downloader
from lutris.util import datapath
from lutris import settings

DEFAULT_BANNER = os.path.join(datapath.get(), 'media/default_banner.png')
DEFAULT_ICON = os.path.join(datapath.get(), 'media/default_icon.png')
UNAVAILABLE_GAME_OVERLAY = os.path.join(datapath.get(),
                                        'media/unavailable.png')
BANNER_SIZE = (184, 69)
BANNER_SMALL_SIZE = (120, 45)
ICON_SIZE = (32, 32)
(
    COL_ID,
    COL_NAME,
    COL_ICON,
    COL_YEAR,
    COL_RUNNER,
    COL_INSTALLED,
) = range(6)


def sort_func(store, a_iter, b_iter, _user_data):
    """Default sort function"""
    a_name = store.get(a_iter, COL_NAME)
Example #58
0
File: web.py Project: Freso/lutris
# -*- coding: utf-8 -*-

import os
import string
import shlex
from urllib.parse import urlparse

from lutris.runners.runner import Runner
from lutris.util import datapath
from lutris import pga, settings

DEFAULT_ICON = os.path.join(datapath.get(), 'media/default_icon.png')


class web(Runner):
    human_name = "Web"
    description = "Runs web based games"
    platform = "Web based games"
    description = "Runs web based games"
    game_options = [
        {
            "option": "main_file",
            "type": "string",
            "label": "Full URL or HTML file path",
            'help': ("The full address of the game's web page or path to a HTML file.")
        }
    ]
    runner_options = [
        {
            "option": "fullscreen",
            "label": "Open in fullscreen",
Example #59
0
    def __init__(self):
        GObject.GObject.__init__(self)
        self.set_title("Configure runners")
        self.set_size_request(700, 600)

        self.vbox = Gtk.VBox()
        self.vbox.set_margin_right(10)
        self.vbox.set_margin_left(10)
        self.vbox.set_margin_bottom(10)
        self.add(self.vbox)

        label = Gtk.Label()
        label.set_markup("<b>Install and configure the game runners</b>")

        scrolled_window = Gtk.ScrolledWindow()
        scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC,
                                   Gtk.PolicyType.AUTOMATIC)
        scrolled_window.set_shadow_type(Gtk.ShadowType.ETCHED_OUT)
        self.vbox.pack_start(label, False, True, 15)
        self.vbox.pack_start(scrolled_window, True, True, 0)

        runner_list = lutris.runners.__all__
        runner_vbox = Gtk.VBox()

        self.runner_labels = {}
        for runner_name in runner_list:
            # Get runner details
            runner = import_runner(runner_name)()
            platform = runner.platform
            description = runner.description

            hbox = Gtk.HBox()
            # Icon
            icon_path = os.path.join(datapath.get(), 'media/runner_icons',
                                     runner_name + '.png')
            icon = Gtk.Image()
            icon.set_from_file(icon_path)
            icon.set_alignment(0.5, 0.1)
            hbox.pack_start(icon, False, False, 10)

            # Label
            runner_label = Gtk.Label()
            if not runner.is_installed():
                runner_label.set_sensitive(False)
            runner_label.set_markup(
                "<b>%s</b>\n%s\n <i>Supported platforms : %s</i>" %
                (runner_name, description, platform)
            )
            runner_label.set_width_chars(40)
            runner_label.set_max_width_chars(40)
            runner_label.set_property('wrap', True)
            runner_label.set_line_wrap(True)
            runner_label.set_alignment(0.0, 0.1)
            runner_label.set_padding(5, 0)
            self.runner_labels[runner] = runner_label
            hbox.pack_start(runner_label, True, True, 5)
            # Button
            button = Gtk.Button()
            button.set_size_request(100, 30)
            button_align = Gtk.Alignment.new(1.0, 0.0, 0.0, 0.0)
            self.configure_button(button, runner)
            button_align.add(button)
            hbox.pack_start(button_align, False, False, 15)

            runner_vbox.pack_start(hbox, True, True, 5)
            separator = Gtk.Separator()
            runner_vbox.pack_start(separator, False, False, 5)
        scrolled_window.add_with_viewport(runner_vbox)
        self.show_all()
Example #60
0
 def show_splash(self):
     image = Gtk.Image(visible=True)
     image.set_from_file(os.path.join(datapath.get(), "media/splash.svg"))
     self.show_overlay(image, Gtk.Align.START, Gtk.Align.START)