winemenubuilder: Moved all wineshelllink functionality to winemenubuilder and removed wineshelllink.
This commit is contained in:
parent
45d7897c62
commit
4e2cec5aba
|
@ -12,10 +12,4 @@ C_SRCS = \
|
|||
|
||||
@MAKE_PROG_RULES@
|
||||
|
||||
install install-lib:: $(DESTDIR)$(bindir)
|
||||
$(INSTALL_SCRIPT) $(TOPSRCDIR)/tools/wineshelllink $(DESTDIR)$(bindir)/wineshelllink
|
||||
|
||||
uninstall::
|
||||
$(RM) $(DESTDIR)$(bindir)/wineshelllink
|
||||
|
||||
@DEPENDENCIES@ # everything below this line is overwritten by make depend
|
||||
|
|
|
@ -31,8 +31,7 @@
|
|||
* between the user's desktop/start menu and the "All Users" copies.
|
||||
*
|
||||
* This program will read a Windows shortcut file using the IShellLink
|
||||
* interface, then invoke wineshelllink with the appropriate arguments
|
||||
* to create a KDE/Gnome menu entry for the shortcut.
|
||||
* interface, then create a KDE/Gnome menu entry for the shortcut.
|
||||
*
|
||||
* winemenubuilder [ -w ] <shortcut.lnk>
|
||||
*
|
||||
|
@ -817,6 +816,184 @@ static BOOL write_desktop_entry(const char *location, const char *linkname, cons
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL write_directory_entry(const char *directory, const char *location)
|
||||
{
|
||||
FILE *file;
|
||||
|
||||
WINE_TRACE("(%s,%s)\n", wine_dbgstr_a(directory), wine_dbgstr_a(location));
|
||||
|
||||
file = fopen(location, "w");
|
||||
if (file == NULL)
|
||||
return FALSE;
|
||||
|
||||
fprintf(file, "[Desktop Entry]\n");
|
||||
fprintf(file, "Type=Directory\n");
|
||||
if (strcmp(directory, "wine") == 0)
|
||||
{
|
||||
fprintf(file, "Name=Wine\n");
|
||||
fprintf(file, "Icon=wine\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(file, "Name=%s\n", directory);
|
||||
fprintf(file, "Icon=folder\n");
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL write_menu_file(const char *filename)
|
||||
{
|
||||
char *tempfilename;
|
||||
FILE *tempfile = NULL;
|
||||
char *lastEntry;
|
||||
char *name = NULL;
|
||||
char *menuPath = NULL;
|
||||
int i;
|
||||
int count = 0;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
WINE_TRACE("(%s)\n", wine_dbgstr_a(filename));
|
||||
|
||||
while (1)
|
||||
{
|
||||
tempfilename = tempnam(xdg_config_dir, "_wine");
|
||||
if (tempfilename)
|
||||
{
|
||||
int tempfd = open(tempfilename, O_EXCL | O_CREAT | O_WRONLY, 0666);
|
||||
if (tempfd >= 0)
|
||||
{
|
||||
tempfile = fdopen(tempfd, "w");
|
||||
if (tempfile)
|
||||
break;
|
||||
close(tempfd);
|
||||
goto end;
|
||||
}
|
||||
else if (errno == EEXIST)
|
||||
{
|
||||
free(tempfilename);
|
||||
continue;
|
||||
}
|
||||
free(tempfilename);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fprintf(tempfile, "<!DOCTYPE Menu PUBLIC \"-//freedesktop//DTD Menu 1.0//EN\"\n");
|
||||
fprintf(tempfile, "\"http://www.freedesktop.org/standards/menu-spec/menu-1.0.dtd\">\n");
|
||||
fprintf(tempfile, "<Menu>\n");
|
||||
fprintf(tempfile, " <Name>Applications</Name>\n");
|
||||
|
||||
name = HeapAlloc(GetProcessHeap(), 0, lstrlenA(filename) + 1);
|
||||
if (name == NULL) goto end;
|
||||
lastEntry = name;
|
||||
for (i = 0; filename[i]; i++)
|
||||
{
|
||||
name[i] = filename[i];
|
||||
if (filename[i] == '/')
|
||||
{
|
||||
char *dir_file_name;
|
||||
struct stat st;
|
||||
name[i] = 0;
|
||||
fprintf(tempfile, " <Menu>\n");
|
||||
fprintf(tempfile, " <Name>%s%s</Name>\n", count ? "" : "wine-", name);
|
||||
fprintf(tempfile, " <Directory>%s%s.directory</Directory>\n", count ? "" : "wine-", name);
|
||||
dir_file_name = heap_printf("%s/desktop-directories/%s%s.directory",
|
||||
xdg_data_dir, count ? "" : "wine-", name);
|
||||
if (dir_file_name)
|
||||
{
|
||||
if (stat(dir_file_name, &st) != 0 && errno == ENOENT)
|
||||
write_directory_entry(lastEntry, dir_file_name);
|
||||
HeapFree(GetProcessHeap(), 0, dir_file_name);
|
||||
}
|
||||
name[i] = '-';
|
||||
lastEntry = &name[i+1];
|
||||
++count;
|
||||
}
|
||||
}
|
||||
name[i] = 0;
|
||||
|
||||
fprintf(tempfile, " <Include>\n");
|
||||
fprintf(tempfile, " <Filename>%s</Filename>\n", name);
|
||||
fprintf(tempfile, " </Include>\n");
|
||||
for (i = 0; i < count; i++)
|
||||
fprintf(tempfile, " </Menu>\n");
|
||||
fprintf(tempfile, "</Menu>\n");
|
||||
|
||||
menuPath = heap_printf("%s/%s", xdg_config_dir, name);
|
||||
if (menuPath == NULL) goto end;
|
||||
strcpy(menuPath + strlen(menuPath) - strlen(".desktop"), ".menu");
|
||||
ret = TRUE;
|
||||
|
||||
end:
|
||||
if (tempfile)
|
||||
fclose(tempfile);
|
||||
if (ret)
|
||||
ret = (rename(tempfilename, menuPath) == 0);
|
||||
if (!ret && tempfilename)
|
||||
remove(tempfilename);
|
||||
free(tempfilename);
|
||||
HeapFree(GetProcessHeap(), 0, name);
|
||||
HeapFree(GetProcessHeap(), 0, menuPath);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL write_menu_entry(const char *link, const char *path, const char *args,
|
||||
const char *descr, const char *workdir, const char *icon)
|
||||
{
|
||||
const char *linkname;
|
||||
char *desktopPath = NULL;
|
||||
char *desktopDir;
|
||||
char *filename = NULL;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
WINE_TRACE("(%s, %s, %s, %s, %s, %s)\n", wine_dbgstr_a(link), wine_dbgstr_a(path),
|
||||
wine_dbgstr_a(args), wine_dbgstr_a(descr), wine_dbgstr_a(workdir),
|
||||
wine_dbgstr_a(icon));
|
||||
|
||||
linkname = strrchr(link, '/');
|
||||
if (linkname == NULL)
|
||||
linkname = link;
|
||||
else
|
||||
++linkname;
|
||||
|
||||
desktopPath = heap_printf("%s/applications/wine/%s.desktop", xdg_data_dir, link);
|
||||
if (!desktopPath)
|
||||
{
|
||||
WINE_WARN("out of memory creating menu entry\n");
|
||||
ret = FALSE;
|
||||
goto end;
|
||||
}
|
||||
desktopDir = strrchr(desktopPath, '/');
|
||||
*desktopDir = 0;
|
||||
if (!create_directories(desktopPath))
|
||||
{
|
||||
WINE_WARN("couldn't make parent directories for %s\n", wine_dbgstr_a(desktopPath));
|
||||
ret = FALSE;
|
||||
goto end;
|
||||
}
|
||||
*desktopDir = '/';
|
||||
if (!write_desktop_entry(desktopPath, linkname, path, args, descr, workdir, icon))
|
||||
{
|
||||
WINE_WARN("couldn't make desktop entry %s\n", wine_dbgstr_a(desktopPath));
|
||||
ret = FALSE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
filename = heap_printf("wine/%s.desktop", link);
|
||||
if (!filename || !write_menu_file(filename))
|
||||
{
|
||||
WINE_WARN("couldn't make menu file %s\n", wine_dbgstr_a(filename));
|
||||
ret = FALSE;
|
||||
}
|
||||
|
||||
end:
|
||||
HeapFree(GetProcessHeap(), 0, desktopPath);
|
||||
HeapFree(GetProcessHeap(), 0, filename);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* This escapes \ in filenames */
|
||||
static LPSTR escape(LPCWSTR arg)
|
||||
{
|
||||
|
@ -848,53 +1025,6 @@ static LPSTR escape(LPCWSTR arg)
|
|||
return narg;
|
||||
}
|
||||
|
||||
static int fork_and_wait( const char *linker, const char *link_name, const char *path,
|
||||
int desktop, const char *args, const char *icon_name,
|
||||
const char *workdir, const char *description )
|
||||
{
|
||||
int pos = 0;
|
||||
const char *argv[20];
|
||||
int retcode;
|
||||
|
||||
WINE_TRACE( "linker app='%s' link='%s' mode=%s "
|
||||
"path='%s' args='%s' icon='%s' workdir='%s' descr='%s'\n",
|
||||
linker, link_name, desktop ? "desktop" : "menu",
|
||||
path, args, icon_name, workdir, description );
|
||||
|
||||
argv[pos++] = linker ;
|
||||
argv[pos++] = "--link";
|
||||
argv[pos++] = link_name;
|
||||
argv[pos++] = "--path";
|
||||
argv[pos++] = path;
|
||||
argv[pos++] = desktop ? "--desktop" : "--menu";
|
||||
if (args && strlen(args))
|
||||
{
|
||||
argv[pos++] = "--args";
|
||||
argv[pos++] = args;
|
||||
}
|
||||
if (icon_name)
|
||||
{
|
||||
argv[pos++] = "--icon";
|
||||
argv[pos++] = icon_name;
|
||||
}
|
||||
if (workdir && strlen(workdir))
|
||||
{
|
||||
argv[pos++] = "--workdir";
|
||||
argv[pos++] = workdir;
|
||||
}
|
||||
if (description && strlen(description))
|
||||
{
|
||||
argv[pos++] = "--descr";
|
||||
argv[pos++] = description;
|
||||
}
|
||||
argv[pos] = NULL;
|
||||
|
||||
retcode=spawnvp( _P_WAIT, linker, argv );
|
||||
if (retcode!=0)
|
||||
WINE_ERR("%s returned %d\n",linker,retcode);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
/* Return a heap-allocated copy of the unix format difference between the two
|
||||
* Windows-format paths.
|
||||
* locn is the owning location
|
||||
|
@ -1260,9 +1390,7 @@ static BOOL InvokeShellLinker( IShellLinkW *sl, LPCWSTR link, BOOL bWait )
|
|||
}
|
||||
}
|
||||
else
|
||||
r = fork_and_wait("wineshelllink", link_name, escaped_path,
|
||||
0, escaped_args, icon_name,
|
||||
work_dir ? work_dir : "", escaped_description);
|
||||
r = !write_menu_entry(link_name, escaped_path, escaped_args, escaped_description, work_dir, icon_name);
|
||||
|
||||
ReleaseSemaphore( hsem, 1, NULL );
|
||||
|
||||
|
|
|
@ -1,219 +0,0 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Create menu/desktop entries for an application
|
||||
# This is used by the IShellLink interface
|
||||
#
|
||||
# Copyright 2000 Alexandre Julliard
|
||||
# Copyright 2006 Vitaliy Margolen
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
#
|
||||
|
||||
# Note that the link is a relative unix-style path name. Since the / character
|
||||
# is not valid in Windows filenames it is an adequate separator to show the
|
||||
# menu structure.
|
||||
|
||||
mode=""
|
||||
args=""
|
||||
menu=""
|
||||
icon=""
|
||||
descr=""
|
||||
link=""
|
||||
path=""
|
||||
workdir=""
|
||||
|
||||
usage()
|
||||
{
|
||||
cat <<EOF
|
||||
usage: wineshelllink options
|
||||
|
||||
options:
|
||||
--desktop create a desktop link
|
||||
--menu create a menu entry
|
||||
--path xx path to the application
|
||||
--link xx name of link to create, including path
|
||||
--args xx command-line arguments for the application
|
||||
--icon xx icon to display
|
||||
--workdir xx working directory for the application
|
||||
--descr xx application description
|
||||
|
||||
EOF
|
||||
exit 2
|
||||
}
|
||||
|
||||
if [ $# -eq 0 ] ; then
|
||||
usage
|
||||
fi
|
||||
|
||||
while [ $# -gt 0 ]
|
||||
do
|
||||
case "$1" in
|
||||
--desktop) mode="desktop"; shift 1 ;;
|
||||
--menu) mode="menu"; shift 1 ;;
|
||||
--path) path="$2"; shift 2 ;;
|
||||
--link) link="$2"; shift 2 ;;
|
||||
--args) args="$2"; shift 2 ;;
|
||||
--icon) icon="$2"; shift 2 ;;
|
||||
--descr) descr="$2"; shift 2 ;;
|
||||
--workdir) workdir="$2"; shift 2 ;;
|
||||
*) usage ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$mode" ] ; then
|
||||
echo "Either --desktop or --menu required"
|
||||
usage
|
||||
fi
|
||||
|
||||
if [ -z "$link" ] ; then
|
||||
echo "You must specify a link name with --link"
|
||||
usage
|
||||
fi
|
||||
|
||||
desktop_entry()
|
||||
{
|
||||
cat <<EOF
|
||||
[Desktop Entry]
|
||||
Name=$linkname
|
||||
Exec=env WINEPREFIX="${WINEPREFIX:-$HOME/.wine}" wine "$path" $args
|
||||
Type=Application
|
||||
StartupWMClass=Wine
|
||||
EOF
|
||||
[ -z "$descr" ] || echo "Comment=$descr"
|
||||
[ -z "$workdir" ] || echo "Path=$workdir"
|
||||
[ -z "$icon" ] || echo "Icon=$icon"
|
||||
}
|
||||
|
||||
directory_entry()
|
||||
{
|
||||
cat <<EOF
|
||||
[Desktop Entry]
|
||||
Type=Directory
|
||||
EOF
|
||||
if [ "$1" = "wine" ] ; then
|
||||
echo "Name=Wine"
|
||||
echo "Icon=wine"
|
||||
else
|
||||
echo "Name=$1"
|
||||
echo "Icon=folder"
|
||||
fi
|
||||
}
|
||||
|
||||
# XDG
|
||||
|
||||
xdg_config_dir="${XDG_CONFIG_HOME:-$HOME/.config}/menus/applications-merged"
|
||||
xdg_data_dir="${XDG_DATA_HOME:-$HOME/.local/share}"
|
||||
|
||||
# Create common directories
|
||||
mkdir -p "$xdg_config_dir"
|
||||
mkdir -p "$xdg_data_dir/desktop-directories"
|
||||
|
||||
get_menu_entries()
|
||||
{
|
||||
tmp="$xdg_config_dir/$1.menu"
|
||||
|
||||
if [ -r "$tmp" ] ; then
|
||||
awk '
|
||||
BEGIN { RS="<" }
|
||||
/^Filename/ {
|
||||
RSTART=index($0,">")
|
||||
if (RSTART>0) {
|
||||
print substr($0,RSTART+1)
|
||||
}
|
||||
}' $tmp
|
||||
fi
|
||||
}
|
||||
|
||||
# Input
|
||||
# menu file name
|
||||
# new item
|
||||
write_menu_file()
|
||||
{
|
||||
menu=`echo "$1" | sed 's!/!-!g'`
|
||||
filename=`echo "$2" | sed 's!/!-!g'`
|
||||
|
||||
tmpfile=`mktemp /tmp/wine.XXXXXX`
|
||||
(
|
||||
echo '<!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN"'
|
||||
echo '"http://www.freedesktop.org/standards/menu-spec/menu-1.0.dtd">'
|
||||
echo '<Menu>'
|
||||
echo ' <Name>Applications</Name>'
|
||||
|
||||
IFS="/"
|
||||
|
||||
fullname='wine'
|
||||
for i in $1; do
|
||||
echo " <Menu>"
|
||||
echo " <Name>$fullname-$i</Name>"
|
||||
echo " <Directory>$fullname-$i.directory</Directory>"
|
||||
|
||||
dir_file_name="$xdg_data_dir/desktop-directories/$fullname-$i.directory"
|
||||
if [ ! -f "$dir_file_name" ] ; then
|
||||
directory_entry "$i" > "$dir_file_name"
|
||||
fi
|
||||
test "$i" = "wine" || fullname="$fullname-$i"
|
||||
done
|
||||
|
||||
echo " <Include>"
|
||||
|
||||
IFS="
|
||||
"
|
||||
for i in `get_menu_entries "$menu"`
|
||||
do
|
||||
test "$i" = "$filename" && continue
|
||||
echo " <Filename>$i</Filename>"
|
||||
done
|
||||
|
||||
# New record
|
||||
echo " <Filename>$filename</Filename>"
|
||||
echo " </Include>"
|
||||
|
||||
IFS='/'
|
||||
for i in $1; do
|
||||
echo " </Menu>"
|
||||
done
|
||||
echo '</Menu>'
|
||||
) > $tmpfile
|
||||
chmod 0600 $tmpfile
|
||||
|
||||
mv -f $tmpfile "$xdg_config_dir/$menu.menu"
|
||||
}
|
||||
|
||||
|
||||
linkname=`basename "$link"`
|
||||
|
||||
if [ $mode = "menu" ] ; then
|
||||
mkdir -p "$xdg_data_dir/applications/wine/`dirname "$link"`"
|
||||
|
||||
linkpath=`dirname "$link"`
|
||||
if [ "$linkpath" = "." ] ; then
|
||||
linkpath=""
|
||||
else
|
||||
linkpath="/$linkpath"
|
||||
fi
|
||||
|
||||
desktop_entry > "$xdg_data_dir/applications/wine/$link.desktop"
|
||||
write_menu_file "wine$linkpath" "wine$linkpath/$linkname.desktop"
|
||||
else
|
||||
if [ -d "$HOME/Desktop" ]
|
||||
then
|
||||
desktop_target="$HOME/Desktop/$linkname.desktop"
|
||||
else
|
||||
desktop_target="$HOME/$linkname.desktop"
|
||||
fi
|
||||
desktop_entry > "$desktop_target"
|
||||
fi
|
||||
|
||||
exit 0
|
Loading…
Reference in New Issue