Learn more  » Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Bower components Debian packages RPM packages NuGet packages

beebox / crossover   deb

Repository URL to install this package:

/ opt / cxoffice / bin / cxmenu

#!/usr/bin/perl
# (c) Copyright 2005-2014. CodeWeavers, Inc.
use warnings;
use strict;

my @desktop_plugins=("CXMenuWindows", "CXMenuCheck",
                     "CXMenuDebian", "CXMenuCDE",
                     "CXMenuXDG", "CXMenuDtop", "CXMenuPerm",
                     "CXMenuMacOSX",
                     "CXMenuShortcut");

my %auto_localize=("Programs"             => 1,
                   "Windows Applications" => 1,
                   "Windows Games" => 1);


# Portable which(1) implementation
sub cxwhich($$;$)
{
    my ($dirs, $app, $noexec)=@_;
    if ($app =~ /^\//)
    {
        return $app if ((-x $app or $noexec) and -f $app);
    }
    elsif ($app =~ /\//)
    {
        require Cwd;
        my $path=Cwd::cwd() . "/$app";
        return $path if ((-x $path or $noexec) and -f $path);
    }
    else
    {
        foreach my $dir (split /:/, $dirs)
        {
            return "$dir/$app" if ($dir ne "" and (-x "$dir/$app" or $noexec) and -f "$dir/$app");
        }
    }
    return undef;
}

# Fast dirname() implementation
sub _cxdirname($)
{
    my ($path)=@_;
    return undef if (!defined $path);
    return "." if ($path !~ s!/+[^/]+/*$!!s);
    return "/" if ($path eq "");
    return $path;
}

# Locate where CrossOver is installed by looking for the directory
# where the cxmenu script is located, unwinding symlinks on the way
sub locate_cx_root(;$)
{
    my ($fallback)=@_;
    my $argv0=cxwhich($ENV{PATH},$0);
    $argv0=$0 if (!defined $argv0);
    if ($argv0 !~ m+^/+)
    {
        require Cwd;
        $argv0=Cwd::cwd() . "/$argv0";
    }
    my $dir=_cxdirname($argv0);
    my $bindir=$dir;
    $bindir =~ s%/lib$%/bin%;
    while (!-x "$bindir/cxmenu" or !-f "$bindir/cxmenu")
    {
        last if (!-l $argv0);
        $argv0=readlink($argv0);
        $argv0="$dir/$argv0" if ($argv0 !~ m+^/+);
        $dir=_cxdirname($argv0);
        $bindir=$dir;
        $bindir =~ s%/lib$%/bin%;
    }
    $bindir =~ s%/(?:\./)+%/%g;
    $bindir =~ s%/\.$%%;
    $ENV{CX_ROOT}=_cxdirname($bindir);
    if ((!-x "$ENV{CX_ROOT}/bin/cxmenu" or !-f "$ENV{CX_ROOT}/bin/cxmenu") and
        $fallback)
    {
        $ENV{CX_ROOT}=$fallback;
    }
    if (!-x "$ENV{CX_ROOT}/bin/cxmenu" or !-f "$ENV{CX_ROOT}/bin/cxmenu")
    {
        my $name0=$0;
        $name0 =~ s+^.*/++;
        print STDERR "$name0:error: could not find CrossOver in '$ENV{CX_ROOT}'\n";
        exit 1;
    }
    return $ENV{CX_ROOT};
}

BEGIN {
    unshift @INC, locate_cx_root() . "/lib/perl";
}
use CXLog;
use CXUtils;
use CXMenu;

my $filters={};
sub get_filter_list($$)
{
    my ($cxmenu, $filter)=@_;

    $filter||="";
    my $filter_list=$filters->{$filter};
    if (!defined $filter_list)
    {
        my @list;
        if ($filter eq "")
        {
            @list=grep !/^Settings$/i, $cxmenu->get_section_names();
        }
        else
        {
            @list=split /:+/, $filter;
        }
        $filters->{$filter}=$filter_list=\@list;
    }
    return $filter_list;
}

sub check_menu_path($)
{
    my ($path)=@_;

    if ($path =~ /:/)
    {
        cxerr("colons are not allowed in menu path '$path'\n");
        return 0;
    }
    if ($path =~ m%/\.*/%)
    {
        # Path contains stuff like '//', '/./', '/../', etc.
        cxerr("invalid menu path '$path'\n");
        return 0;
    }
    if ($path !~ m%^(?:Desktop|StartMenu)(?:[._][^/]+)?/%)
    {
        cxerr("unknown menu root '$path'\n");
        return 0;
    }
    return 1;
}

my %menu_components;
sub path_to_components($$$$$)
{
    my ($rawpath, $cxconfig, $menu_root, $menu_strip, $tag)=@_;
    $rawpath =~ s!/+!/!g;

    my $components=$menu_components{$rawpath};
    if (!exists $menu_components{$rawpath})
    {
        # Don't give up even if the menu path or root is not valid
        # so we build a negative cache
        my $menu;
        if (check_menu_path($rawpath))
        {
            $menu->{rawpath}=$rawpath;
            my $path=$rawpath;
            $path =~ s%^(Desktop|StartMenu)(?:[._][^/]+)?/%/%;
            $menu->{root}=$1;
            $menu->{is_dir}=1 if ($path =~ s%/$%%);
            $menu->{is_desktop}=1 if ($menu->{root} eq "Desktop");
            if (!$menu->{is_desktop})
            {
                if ($menu_strip)
                {
                    my @path_items=split "/", $path;
                    if ($menu_strip+1 < @path_items)
                    {
                        splice @path_items, 0, $menu_strip+1;
                        $path=join("/", "", @path_items);
                    }
                    elsif ($menu->{is_dir})
                    {
                        # Menu folders that are not deep enough disappear
                        # entirely
                        $menu=undef;
                    }
                    else
                    {
                        # But menu entries just get moved to the root folder
                        $path="/$path_items[-1]";
                    }
                }
                $path="$menu_root$path" if (defined $menu_root);
            }
            if ($menu)
            {
                # These are the only _file_ extensions that are always hidden
                # by Windows, including in the menus
                $path =~ s%\.(?:lnk|pif|url)$%%i if (!$menu->{is_dir});
                $menu->{path}=$path;
                $menu->{dir}=$path;
                $menu->{dir}=~ s%/[^/]*$%/%;
                $menu->{name}=$path;
                $menu->{name}=~s%^.*/%%;
                $menu->{name}=~s%/$%%;
            }

            # Re-name the Windows Steam icon to distinguish
            # it from the native client.
            if ($menu && CXUtils::get_desktop_environment ne "macosx")
            {
                $menu->{name}=~s/^Steam$/Steam\ \(CrossOver\)/;
            }
        }
        if ($menu)
        {
            $menu->{tag}=$tag;
            my $path="";
            foreach my $item (split "/", $menu->{dir})
            {
                next if ($item eq "");
                $path .="/$item";
                my $component={
                    name         => $item,
                    path         => $path,
                    intermediate => 1,
                    is_dir       => 1,
                    tag          => $tag
                };
                push @$components, $component;
            }
            push @$components, $menu;
        }

        $menu_components{$rawpath}=$components;
    }
    return $components;
}

sub update_field($$$)
{
    my ($section, $name, $value)=@_;

    $value||="";
    my $oldval=$section->get($name, "");
    return 0 if ($oldval eq $value);

    if ($value eq "")
    {
        $section->remove($name);
    }
    else
    {
        $section->set($name, $value);
    }
    return 1;
}


# Process command-line options
my $opt_create;
my $opt_delete;
my $opt_purge;
my $opt_delete_filter;
my $opt_mode;
my $opt_mode_filter;
my $opt_mmenu_never;
my $opt_query;
my $opt_query_filter;
my $opt_list_files;
my $opt_list_files_filter;
my $opt_start;
my $opt_wait_children;
my $opt_enable_alt_loader;
my $opt_install;
my $opt_install_filter;
my $opt_uninstall;
my $opt_uninstall_filter;
my $opt_removeall;
my $opt_destdir;
my $opt_sync;
my $opt_sync_install_none;
my $opt_sync_uninstall_none;
my $opt_utf8;
my $opt_bottle;
my $opt_crossover;
my $opt_conf;
my $opt_menu_root;
my $opt_menu_strip;
my $opt_tag;
my $opt_pattern;
my $opt_filter;
my $opt_ignorelist;
my $opt_ro_desktopdata;
my $opt_description;
my $opt_type;
my $opt_command;
my $opt_icon;
my $opt_shortcut;
my $opt_scope;
my $opt_menu_scope;
my $opt_arch;
my $opt_arch_filter;
my $opt_verbose;
my $opt_help;
require CXOpts;
my $cxopts=CXOpts->new(["stop_on_unknown", "stop_on_non_option"]);
$cxopts->add_options(["create=s"      => \$opt_create,
                      "delete"        => \$opt_delete,
                      "purge"         => \$opt_purge,
                      "delete-filter=s" => \$opt_delete_filter,
                      "mode=s"        => \$opt_mode,
                      "mode-filter=s" => \$opt_mode_filter,
                      "mmenu-never=s"   => \$opt_mmenu_never,
                      "query"         => \$opt_query,
                      "query-filter=s" => \$opt_query_filter,
                      "list-files"    => \$opt_list_files,
                      "list-files-filter=s" => \$opt_list_files_filter,
                      "start=s"       => \$opt_start,
                      "wait-children" => \$opt_wait_children,
                      "enable-alt-loader=s" => \$opt_enable_alt_loader,
                      "install"       => \$opt_install,
                      "install-filter=s" => \$opt_install_filter,
                      "uninstall"     => \$opt_uninstall,
                      "uninstall-filter=s" => \$opt_uninstall_filter,
                      "removeall"     => \$opt_removeall,
                      "sync"          => \$opt_sync,
                      "destdir=s"     => \$opt_destdir,
                      "sync-install-none" => \$opt_sync_install_none,
                      "sync-uninstall-none" => \$opt_sync_uninstall_none,
                      "utf8"          => \$opt_utf8,
                      "bottle=s"      => \$opt_bottle,
                      "crossover"     => \$opt_crossover,
                      "conf=s"        => \$opt_conf,
                      "menu-root=s"   => \$opt_menu_root,
                      "menu-strip=s"  => \$opt_menu_strip,
                      "tag=s"         => \$opt_tag,
                      "pattern=s"     => \$opt_pattern,
                      "filter=s"      => \$opt_filter,
                      "ignorelist=s"  => \$opt_ignorelist,
                      "ro-desktopdata"=> \$opt_ro_desktopdata,
                      "description=s" => \$opt_description,
                      "type=s"        => \$opt_type,
                      "command=s"     => \$opt_command,
                      "icon=s"        => \$opt_icon,
                      "shortcut=s"    => \$opt_shortcut,
                      "scope=s"       => \$opt_scope,
                      "menu-scope=s"  => \$opt_menu_scope,
                      "arch=s"        => \$opt_arch,
                      "arch-filter=s" => \$opt_arch_filter,
Loading ...