msxml3: Don't leak an interface on failure.
[wine] / tools / wineshelllink
1 #!/bin/sh
2 #
3 # Create menu/desktop entries for an application
4 # This is used by the IShellLink interface
5 #
6 # Copyright 2000 Alexandre Julliard
7 # Copyright 2006 Vitaliy Margolen
8 #
9 # This library is free software; you can redistribute it and/or
10 # modify it under the terms of the GNU Lesser General Public
11 # License as published by the Free Software Foundation; either
12 # version 2.1 of the License, or (at your option) any later version.
13 #
14 # This library is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 # Lesser General Public License for more details.
18 #
19 # You should have received a copy of the GNU Lesser General Public
20 # License along with this library; if not, write to the Free Software
21 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #
23
24 # Note that the link is a relative unix-style path name.  Since the / character
25 # is not valid in Windows filenames it is an adequate separator to show the
26 # menu structure.
27
28 mode=""
29 args=""
30 menu=""
31 icon=""
32 descr=""
33 link=""
34 path=""
35 workdir=""
36
37 usage()
38 {
39     cat <<EOF
40 usage: wineshelllink options
41
42 options:
43   --desktop     create a desktop link
44   --menu        create a menu entry
45   --path xx     path to the application
46   --link xx     name of link to create, including path
47   --args xx     command-line arguments for the application
48   --icon xx     icon to display
49   --workdir xx  working directory for the application
50   --descr xx    application description
51
52 EOF
53     exit 2
54 }
55
56 if [ $# -eq 0 ] ; then
57     usage
58 fi
59
60 while [ $# -gt 0 ]
61 do
62   case "$1" in
63     --desktop) mode="desktop"; shift 1 ;;
64     --menu)    mode="menu"; shift 1 ;;
65     --path)    path="$2"; shift 2 ;;
66     --link)    link="$2"; shift 2 ;;
67     --args)    args="$2"; shift 2 ;;
68     --icon)    icon="$2"; shift 2 ;;
69     --descr)   descr="$2"; shift 2 ;;
70     --workdir) workdir="$2"; shift 2 ;;
71     *) usage ;;
72   esac
73 done
74
75 if [ -z "$mode" ] ; then
76     echo "Either --desktop or --menu required"
77     usage
78 fi
79
80 if [ -z "$link" ] ; then
81     echo "You must specify a link name with --link"
82     usage
83 fi
84
85 desktop_entry()
86 {
87     cat <<EOF
88 [Desktop Entry]
89 Name=$linkname
90 Exec=env WINEPREFIX="${WINEPREFIX:-$HOME/.wine}" wine "$path" $args
91 Type=Application
92 StartupWMClass=Wine
93 EOF
94     [ -z "$descr"   ] || echo "Comment=$descr"
95     [ -z "$workdir" ] || echo "Path=$workdir"
96     [ -z "$xpmicon" ] || echo "Icon=$xpmicon"
97 }
98
99 directory_entry()
100 {
101     cat <<EOF
102 [Desktop Entry]
103 Type=Directory
104 EOF
105     if [ "$1" = "wine" ] ; then
106         echo "Name=Wine"
107         echo "Icon=wine"
108     else
109         echo "Name=$1"
110         echo "Icon=folder"
111     fi
112 }
113
114 # copy the icon file to a specified dir and set xpmicon to the resulting path
115 copy_icon()
116 {
117     if [ -f "$icon" ]
118     then
119         xpmicon=`basename "$icon" .xpm`
120
121         mkdir -p "$1"
122         cp "$icon" "$1/$xpmicon.xpm"
123     else
124         xpmicon=""
125     fi
126 }
127
128 # XDG
129
130 xdg_config_dir="${XDG_CONFIG_HOME:-$HOME/.config}/menus/applications-merged"
131 xdg_data_dir="${XDG_DATA_HOME:-$HOME/.local/share}"
132
133 # Create common directories
134 mkdir -p "$xdg_config_dir"
135 mkdir -p "$xdg_data_dir/desktop-directories"
136
137 get_menu_entries()
138 {
139     tmp="$xdg_config_dir/$1.menu"
140
141     if [ -r "$tmp" ] ; then
142         awk '
143 BEGIN {  RS="<" }
144 /^Filename/ {
145   RSTART=index($0,">")
146   if (RSTART>0) {
147      print substr($0,RSTART+1)
148   }
149 }' $tmp
150     fi
151 }
152
153 # Input
154 #   menu file name
155 #   new item
156 write_menu_file()
157 {
158     menu=`echo "$1" | sed 's!/!-!g'`
159     filename=`echo "$2" | sed 's!/!-!g'`
160
161     tmpfile=`mktemp /tmp/wine.XXXXXX`
162     (
163         echo '<!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN"'
164         echo '"http://www.freedesktop.org/standards/menu-spec/menu-1.0.dtd">'
165         echo '<Menu>'
166         echo '  <Name>Applications</Name>'
167
168         IFS="/"
169
170         fullname='wine'
171         for i in $1; do
172             echo "  <Menu>"
173             echo "    <Name>$fullname-$i</Name>"
174             echo "    <Directory>$fullname-$i.directory</Directory>"
175
176             dir_file_name="$xdg_data_dir/desktop-directories/$fullname-$i.directory"
177             if [ ! -f "$dir_file_name" ] ; then
178                 directory_entry "$i" > "$dir_file_name"
179             fi
180             test "$i" = "wine" || fullname="$fullname-$i"
181         done
182
183         echo "    <Include>"
184
185         IFS="
186 "
187         for i in `get_menu_entries "$menu"`
188         do
189             test "$i" = "$filename" && continue
190             echo "      <Filename>$i</Filename>"
191         done
192
193         # New record
194         echo "      <Filename>$filename</Filename>"
195         echo "    </Include>"
196
197         IFS='/'
198         for i in $1; do
199             echo "  </Menu>"
200         done
201         echo '</Menu>'                        
202     ) > $tmpfile
203     chmod 0600 $tmpfile
204
205     mv -f $tmpfile "$xdg_config_dir/$menu.menu"
206 }
207
208
209 copy_icon "$xdg_data_dir/icons"
210
211 linkname=`basename "$link"`
212
213 if [ $mode = "menu" ] ; then
214     mkdir -p "$xdg_data_dir/applications/wine/`dirname "$link"`"
215
216     linkpath=`dirname "$link"`
217     if [ "$linkpath" = "." ] ; then
218         linkpath=""
219     else
220         linkpath="/$linkpath"
221     fi
222
223     desktop_entry > "$xdg_data_dir/applications/wine/$link.desktop"
224     write_menu_file "wine$linkpath" "wine$linkpath/$linkname.desktop"
225 else
226     if [ -d "$HOME/Desktop" ]
227     then
228       desktop_target="$HOME/Desktop/$linkname.desktop"
229     else
230       desktop_target="$HOME/$linkname.desktop"
231     fi
232     desktop_entry > "$desktop_target"
233 fi
234
235 exit 0