Preserve wine return status.
[wine] / tools / winelauncher.in
1 #!/bin/sh
2 #------------------------------------------------------------------------------
3 #   Winelauncher
4 #       This shell script attempts to intelligently manage the process
5 #   of launching a program with Wine.  It adds some level of
6 #   visual feedback to an end user.
7 #  
8 #   Usage:
9 #       winelauncher [options]  "<windows program> [program arguments]"
10 #
11 #       This script is meant to be installed to /usr/bin/wine, and
12 #   to be used to invoke a Windows executable.
13 #       The options are passed through directly to Wine, and are
14 #   documented in the Wine man page.
15 #
16 #   Copyright (c) 2000 by Jeremy White for CodeWeavers
17 #       
18 #------------------------------------------------------------------------------
19
20 #------------------------------------------------------------------------------
21 #  Primary configuration area - change this if you installed Wine to
22 #    a location other than @prefix@
23 #------------------------------------------------------------------------------
24 prefix=@prefix@
25
26 #------------------------------------------------------------------------------
27 #  Secondary configuration area; change these at your own risk.
28 #------------------------------------------------------------------------------
29 exec_prefix=@exec_prefix@
30 WINEBIN=@bindir@
31 WINELIB=@libdir@
32 WINESERVER=
33 WINELIBDLLS=@libdir@
34
35 #------------------------------------------------------------------------------
36 #  Establish Color Scheme
37 #------------------------------------------------------------------------------
38 COLOR=' -xrm *.Command.background:darkgrey
39 -xrm *.Command.foreground:black
40 -xrm *.Text.background:black
41 -xrm *.Text.foreground:green 
42 -xrm *.Form.background:grey
43 -xrm *.Form.foreground:green
44 -xrm *.foreground:green
45 -xrm *.background:black'
46
47
48 #------------------------------------------------------------------------------
49 #  Locate either xmessage or gmessage, if we can.
50 #------------------------------------------------------------------------------
51 type xmessage >/dev/null 2>/dev/null
52 if [ $? -ne 0 ] ; then
53     echo "
54 Warning:
55    The Wine launcher is unable to find xmessage.
56
57    This launcher script relies heavily on finding this tool,
58    and without it, it will behave poorly.
59
60    Most Linux distributions have one or the other of these
61    tools.
62
63    We strongly recommend that you use your distributions
64    software methods to locate xmessage."
65
66 else
67     XMESSAGE="xmessage $COLOR"
68 fi
69
70
71 #------------------------------------------------------------------------------
72 #  We're going to do a lot of fancy footwork below.
73 #    Before we get started, it would be nice to know the argv0,
74 #    of the actual script we're running (and lets remove at least
75 #    one level of symlinking).
76 #------------------------------------------------------------------------------
77 argv0_path=`which $0`
78 if [ -z $argv0_path ] ; then
79     argv0_path=$0
80 fi
81
82 real_name=`find $argv0_path -type l -printf "%l\n"`
83 if [ ! $real_name ]; then
84     real_name=$argv0_path
85 elif [ ! -x $real_name ]; then
86     real_name=`find $argv0_path -printf "%h\n"`/$real_name
87 fi
88
89 argv0_dir=`find $real_name -printf "%h\n"`
90
91 if [ -z $argv0_dir ] ; then
92     argv0_dir=.
93 fi
94
95 #------------------------------------------------------------------------------
96 #  Okay, now all that junk above was established at configure time.
97 #   However, if this is an RPM install, they may have chosen
98 #   to relocate this installation.  If so, that stuff above
99 #   is all broken and we should rejigger it.
100 #------------------------------------------------------------------------------
101 WINE_BIN_NAME=wine.bin
102 if [ ! -x $WINEBIN/$WINE_BIN_NAME ] ; then
103     WINEBIN=`find $argv0_dir -maxdepth 1 -perm +0111 -type f -name "$WINE_BIN_NAME" -printf "%h\n" | head -1`
104 fi
105
106 if [ ! -x $WINEBIN/$WINE_BIN_NAME ] ; then
107     WINEBIN=`find $argv0_dir/../ -maxdepth 1 -perm +0111 -type f -name "$WINE_BIN_NAME" -printf "%h\n" | head -1`
108 fi
109
110 if [ ! -x $WINEBIN/$WINE_BIN_NAME ] ; then
111     WINE_BIN_NAME=wine
112     if [ ! -x $WINEBIN/$WINE_BIN_NAME ] ; then
113         WINEBIN=`find $argv0_dir -maxdepth 1 -perm +0111 -type f -name "$WINE_BIN_NAME" -printf "%h\n" | head -1`
114     fi
115
116     if [ ! -x $WINEBIN/$WINE_BIN_NAME ] ; then
117         WINEBIN=`find $argv0_dir/../ -maxdepth 1 -perm +0111 -type f -name "$WINE_BIN_NAME" -printf "%h\n" | head -1`
118     fi
119 fi
120
121 if [ ! -r $WINELIB/libwine.so ] ; then
122     WINELIB=`find $argv0_dir -maxdepth 2 -name 'libwine.so' -printf "%h\n" | head -1`
123 fi
124
125 if [ ! -r $WINELIB/libwine.so ] ; then
126     WINELIB=`find $argv0_dir/../ -maxdepth 2 -name 'libwine.so' -printf "%h\n" | head -1`
127 fi
128
129 if [ -x $WINEBIN/wineserver ] ; then
130     WINESERVER=$WINEBIN/wineserver
131 fi
132
133 #------------------------------------------------------------------------------
134 #  Hey, if we built Wine from source, let's add a little extra fun to
135 #   mix it up a bit
136 #------------------------------------------------------------------------------
137 if [ -x $WINEBIN/server/wineserver ] ; then
138     WINESERVER=$WINEBIN/server/wineserver
139 fi
140
141 if [ -r $WINELIB/dlls/libntdll.so ] ; then
142     WINELIBDLLS=$WINELIB/dlls
143 fi
144
145
146 #------------------------------------------------------------------------------
147 #  Okay, set the paths and move on.
148 #------------------------------------------------------------------------------
149 export LD_LIBRARY_PATH=$WINELIB:$WINELIBDLLS:$LD_LIBRARY_PATH
150 export PATH=$WINEBIN:$PATH
151 export WINEDLLPATH=$WINELIBDLLS
152 export WINELOADER=$WINEBIN/$WINE_BIN_NAME
153
154 info_flag=~/.wine/.no_prelaunch_window_flag
155 debug_flag=~/.wine/.no_debug_window_flag
156 debug_options="-debugmsg warn+all"
157
158 if [ -f $info_flag ] ; then 
159     use_info_message=0
160 else
161     use_info_message=1
162 fi
163
164 if [ -f $debug_flag ] ; then 
165     use_debug_message=0
166 else
167     use_debug_message=1
168 fi
169
170
171 #------------------------------------------------------------------------------
172 #  Handle winelib apps going through here
173 #------------------------------------------------------------------------------
174 winelib=0
175 if [ -f $argv0_path.so ] ; then
176     winelib=1
177     export WINEPRELOAD=$argv0_path.so
178 fi
179
180
181 #------------------------------------------------------------------------------
182 #  No arguments?  Help 'em out
183 #------------------------------------------------------------------------------
184 always_see_output=0
185 no_args=0
186 if [ $# -eq 0 ] ; then
187     no_args=1
188 fi
189
190 if [ $# -eq 1 -a "$1" = "" ] ; then
191     no_args=1
192 fi
193
194 if [ $winelib -eq 1 ] ; then
195     no_args=0
196 fi
197
198 if [ $no_args -eq 1 ] ; then
199     echo "Wine called with no arguments."
200     echo "Invoking $WINEBIN/$WINE_BIN_NAME $@ ..."
201     $XMESSAGE -buttons "    Okay    ":0," See the Wine Usage Statement ":1,"  Configure Wine  ":2 \
202         -title "Welcome to Wine" \
203         "
204
205         You have started Wine without specifying any arguments.
206
207         Wine requires a least one argument - the name of the Windows
208         application you would like to run.
209
210         If you have launched this through the KDE menu system,
211         you can use the KDE file browser to select a Windows
212         exectuable and then click on it to launch Wine with
213         that application.
214
215         You can similarly use the GNOME file manager to
216         select a Windows executable and double click on it.
217
218         If you would like to see the command line arguments
219         for Wine, select the second option, below.
220
221         " 
222     welcome_rc=$?
223     if [ $welcome_rc -eq 0 ] ; then
224         exit
225     fi
226
227     if [ $welcome_rc -eq 2 ] ; then
228         which winesetup
229         if [ $? -eq 0 ] ; then
230             winesetup
231         else
232             if [ -x /opt/wine/bin/winesetup ] ; then
233                 /opt/wine/bin/winesetup
234             else
235                 $XMESSAGE -title "Error" "Error:  Unable to find winesetup in your PATH or in /opt/wine/bin"
236             fi
237         fi
238         exit
239     fi
240
241     use_info_message=0
242     always_see_output=1
243 fi
244
245 #------------------------------------------------------------------------------
246 #  No config file?  Offer to help 'em out...
247 #------------------------------------------------------------------------------
248 conf=0
249
250 while [ $conf -eq 0 ] ; do
251
252     if [ -f ~/.winerc ] ; then
253         conf=1
254     fi
255     if [ -f ~/.wine/config ] ; then
256         conf=2
257     fi
258     if [ -f /etc/wine.conf ] ; then
259         conf=3
260     fi
261
262     if [ $conf -ne 0 ] ; then
263         break;
264     fi
265
266     echo "No configuration file detected."
267     $XMESSAGE -buttons "    Cancel    ":0,"  Proceed   ":1,"  Configure Wine  ":2 \
268         -title "Welcome to Wine" \
269         "
270
271         You have started Wine but we cannot find a Wine
272         configuration file.
273
274         This is normal if you have never run Wine before.
275         If this is the case, select the 'Configure Wine'
276         option, below, to create a configuration file.
277
278         " 
279     init_rc=$?
280     if [ $init_rc -eq 0 ] ; then
281         exit
282     fi
283
284     if [ $init_rc -eq 1 ] ; then
285         break
286     fi
287
288     if [ $init_rc -eq 2 ] ; then
289         which winesetup
290         if [ $? -eq 0 ] ; then
291             winesetup
292         else
293             if [ -x /opt/wine/bin/winesetup ] ; then
294                 /opt/wine/bin/winesetup
295             else
296                 $XMESSAGE -title "Error" "Error:  Unable to find winesetup in your PATH or in /opt/wine/bin"
297             fi
298         fi
299     fi
300
301 done
302
303 #------------------------------------------------------------------------------
304 #  Optionally Warn the user we're going to be launching Wine...
305 #------------------------------------------------------------------------------
306 if [ $use_info_message -ne 0 ] ; then
307     echo "Invoking $WINEBIN/$WINE_BIN_NAME $@ ..."
308     $XMESSAGE -timeout 30 -buttons "    Dismiss    ":0," Never display this message again ":3 \
309         -title "Wine Launch Window" \
310         "Invoking $WINEBIN/$WINE_BIN_NAME $@ ...
311
312         This dialog box is a temporary status dialog to let you know
313         that Wine is attempting to launch your application.
314
315         Since Wine is still very much in a development stage, many
316         applications will fail silently.  This dialog box is your indication 
317         that we're *trying* to run your application.
318
319         This dialog box will automatically disappear after 30 seconds,
320         or after your application finishes.
321
322         You can permanently disable this dialog by selecting the option below.
323         " &
324     info_message_pid=$!
325 fi
326
327 #------------------------------------------------------------------------------
328 #  Here's a little function to clean up after that dialog...
329 #------------------------------------------------------------------------------
330 clean_up_info_message ()
331 {
332     if [ $use_info_message -ne 0 ] ; then
333
334         #------------------------------------------------------------------------------
335         #  Okay, make sure that the notice window is dead (and kill it if it ain't)
336         #------------------------------------------------------------------------------
337         ps $info_message_pid >/dev/null 2>&1
338         if [ $? -ne 0 ] ; then
339             wait $info_message_pid
340             info_return=$?
341         else
342             info_return=0
343             kill $info_message_pid
344         fi
345
346         #------------------------------------------------------------------------------
347         #  If they didn't like the warning window, turn it off
348         #------------------------------------------------------------------------------
349         if [ $info_return -eq 3 ] ; then
350             $XMESSAGE -title "Wine Prelaunch Control" \
351             "Wine will now disable the prelaunch Window you just saw.
352             You will no longer be notified when Wine is attempting
353             to start a Windows application.
354
355             You can reenable this Window by removing the $info_flag file." -buttons "  Okay  ":0," Cancel ":1
356             if [ $? -eq 0 ] ; then
357                 touch $info_flag
358             fi
359         fi
360     fi
361
362     use_info_message=0
363 }
364 #------------------------------------------------------------------------------
365 #  Generate a temporary log file name
366 #------------------------------------------------------------------------------
367 use_log_name=0
368 log_name=`mktemp /tmp/wine.log.XXXXXX`
369 if [ $? -eq 0 ] ; then
370     use_log_name=1
371 fi
372 use_status_name=0
373 status_name=`mktemp /tmp/wine.status.XXXXXX`
374 if [ $? -eq 0 ] ; then
375     use_status_name=1
376 fi
377
378 #------------------------------------------------------------------------------
379 #  Okay, really launch Wine...
380 #------------------------------------------------------------------------------
381 if [ $use_log_name -ne 0 -a $use_status_name -ne 0 ] ; then
382     ( $WINEBIN/$WINE_BIN_NAME "$@"; echo $? >$status_name ) 2>&1 | tee $log_name
383     wine_return=`cat $status_name`
384 else
385     $WINEBIN/$WINE_BIN_NAME "$@"
386     wine_return=$?
387 fi
388 if [ $use_status_name -ne 0 ] ; then
389     rm -f $status_name
390 fi
391
392 #------------------------------------------------------------------------------
393 #  Test the return code, and see if it fails
394 #------------------------------------------------------------------------------
395 if [ $always_see_output -eq 0 -a $wine_return -eq 0 ] ; then
396     echo "Wine exited with a successful status"
397     if [ $use_log_name -ne 0 ] ; then
398         rm -f $log_name
399     fi
400 else
401     if [ $always_see_output -eq 0 ] ; then
402         echo "Wine failed with return code $wine_return"
403     fi
404
405     #------------------------------------------------------------------------------
406     #  Gracefully display a debug message if they like...
407     #------------------------------------------------------------------------------
408     while [ $use_debug_message -gt 0 ] ; do
409
410         #------------------------------------------------------------------------------
411         #  Build up the menu of choices they can make...
412         #------------------------------------------------------------------------------
413         BUTTONS='    Okay    :0'
414         if [ $use_log_name -ne 0 ] ; then
415             BUTTONS="$BUTTONS"', View Log :1'
416         fi
417
418         BUTTONS="$BUTTONS"',  Debug  :2'
419         BUTTONS="$BUTTONS"',  Configure :4'
420         BUTTONS="$BUTTONS"',  Disable :3'
421
422         #------------------------------------------------------------------------------
423         #  Build an error message
424         #------------------------------------------------------------------------------
425         MESSAGE="
426 Wine has exited with a failure status of $wine_return.
427
428 Wine is still development software, so there can be many
429 explanations for this problem.  
430
431 You can choose to run Wine again with a higher level
432 of debug messages (the debug option, below).
433
434 You can attempt to reconfigure Wine to make it work better.
435 Note that one change you can make that will dramatically
436 effect Wine's behaviour is to change whether or not
437 Wine uses a true Windows partition, mounted under Linux,
438 or whether it uses an empty Windows directory.
439 The Wine Configuration program can assist you in making
440 those changes (select Configure, below, for more).
441
442 You can disable this message entirely by selecting the
443 Disable option below."
444
445         if [ $always_see_output -ne 0 -a $wine_return -eq 0 ] ; then
446             MESSAGE="
447 Wine has exited with a failure status of $wine_return.
448
449 You can disable this message entirely by selecting the
450 Disable option below."
451
452         fi
453
454         if [ $use_log_name -ne 0 ] ; then
455             MESSAGE="$MESSAGE
456
457 Wine has captured a log of the Wine output in the file $log_name.
458 You may view this file by selecting View Log, below."
459         fi
460
461         #------------------------------------------------------------------------------
462         #  Display the message
463         #------------------------------------------------------------------------------
464         $XMESSAGE -title "Wine Finished With Error" -buttons "$BUTTONS" "$MESSAGE"
465         debug_return=$?
466
467         #------------------------------------------------------------------------------
468         #  Dismiss the other window...
469         #------------------------------------------------------------------------------
470         clean_up_info_message
471
472         #------------------------------------------------------------------------------
473         #  Process a configure instruction
474         #------------------------------------------------------------------------------
475         if [ $debug_return -eq 4 ] ; then
476             which winesetup
477             if [ $? -eq 0 ] ; then
478                 winesetup
479             else
480                 if [ -x /opt/wine/bin/winesetup ] ; then
481                     /opt/wine/bin/winesetup
482                 else
483                     $XMESSAGE -title "Error" "Error:  Unable to find winesetup in your PATH or in /opt/wine/bin"
484                 fi
485             fi
486             continue;
487         fi
488
489         #------------------------------------------------------------------------------
490         #  Process a view instruction
491         #------------------------------------------------------------------------------
492         if [ $debug_return -eq 1 ] ; then
493             $XMESSAGE -title "View Wine Log" -file $log_name -buttons "  Okay  ":0,"Delete $log_name":1  
494             if [ $? -eq 1 ] ; then
495                 echo "Deleting $log_name"
496                 rm -f $log_name
497                 use_log_name=0
498             fi
499         else
500             use_debug_message=0
501         fi
502
503         #------------------------------------------------------------------------------
504         #  If they didn't like the warning window, turn it off
505         #------------------------------------------------------------------------------
506         if [ $debug_return -eq 3 ] ; then
507             $XMESSAGE -title "Wine Debug Log Control" \
508             "Wine will now disable the Wine debug output control window you just saw.
509             You will no longer be notified when Wine fails to start a
510             Windows application.
511
512             You can reenable this Window by removing the $debug_flag file." -buttons "  Okay  ":0," Cancel ":1
513
514             if [ $? -eq 0 ] ; then
515                 touch $debug_flag
516             fi
517
518         fi
519
520         #------------------------------------------------------------------------------
521         #  If they want to retry with debug, let 'em.
522         #------------------------------------------------------------------------------
523         if [ $debug_return -eq 2 ] ; then
524             echo "Rerunning $0 $debug_options $@"
525             exec $0 $debug_options "$@"
526         fi
527     done 
528 fi
529
530
531 clean_up_info_message
532
533 # killed by signal?
534 if [ $wine_return -ge 128 ]; then
535         # try to kill myself with the same signal
536         kill -$[wine_return - 128] $$
537         # if we get here the kill didn't work
538         exit 1