499 lines
17 KiB
Bash
Executable File
499 lines
17 KiB
Bash
Executable File
#!/bin/sh
|
|
#------------------------------------------------------------------------------
|
|
# Winelauncher
|
|
# This shell script attempts to intelligently manage the process
|
|
# of launching a program with Wine. It adds some level of
|
|
# visual feedback to an end user.
|
|
#
|
|
# Usage:
|
|
# winelauncher [options] "<windows program> [program arguments]"
|
|
#
|
|
# This script is meant to be installed to /usr/bin/wine, and
|
|
# to be used to invoke a Windows executable.
|
|
# The options are passed through directly to Wine, and are
|
|
# documented in the Wine man page.
|
|
#
|
|
# Copyright (c) 2000 by Jeremy White for CodeWeavers
|
|
#
|
|
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
#------------------------------------------------------------------------------
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Primary configuration area - change this if you installed Wine to
|
|
# a different location
|
|
#------------------------------------------------------------------------------
|
|
WINEBIN=@bindir@
|
|
WINELIB=@libdir@
|
|
WINESERVER=
|
|
WINEDLLPATH=@dlldir@
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Establish Color Scheme
|
|
#------------------------------------------------------------------------------
|
|
COLOR=' -xrm *.Command.background:darkgrey
|
|
-xrm *.Command.foreground:black
|
|
-xrm *.Text.background:black
|
|
-xrm *.Text.foreground:green
|
|
-xrm *.Form.background:grey
|
|
-xrm *.Form.foreground:green
|
|
-xrm *.foreground:green
|
|
-xrm *.background:black'
|
|
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Locate either xmessage or gmessage, if we can.
|
|
#------------------------------------------------------------------------------
|
|
type xmessage >/dev/null 2>/dev/null
|
|
if [ $? -ne 0 ] ; then
|
|
# xmessage not found; make sure the user notices this error
|
|
# (GUI users wouldn't even notice if we printed the text on console !)
|
|
MSGFILE=`mktemp "/tmp/wine.xmessage.XXXXXX"`
|
|
cat > $MSGFILE <<EOF
|
|
Warning:
|
|
The Wine launcher is unable to find the xmessage program,
|
|
which it needs to properly notify you of Wine execution status
|
|
or problems.
|
|
|
|
This launcher script relies heavily on finding this tool,
|
|
and without it, it will behave very poorly.
|
|
|
|
We strongly recommend that you use your distribution's
|
|
software methods to locate xmessage, or alternatively
|
|
use your favourite internet search engine to find out
|
|
how you are supposed to install xmessage on your system.
|
|
EOF
|
|
|
|
# try to display message file with tons of different X11 editors
|
|
# until we find one that's installed and working
|
|
for EDITPRG in nedit gedit kedit gvim xemacs; do
|
|
type $EDITPRG >/dev/null 2>/dev/null
|
|
if [ $? -eq 0 ] ; then
|
|
# execute editor and exit if successful
|
|
$EDITPRG $MSGFILE && exit
|
|
fi
|
|
done
|
|
|
|
# ok, we really give up now, this system is hosed ;-)
|
|
cat $MSGFILE
|
|
rm $MSGFILE
|
|
else
|
|
XMESSAGE="xmessage $COLOR"
|
|
fi
|
|
|
|
#------------------------------------------------------------------------------
|
|
# We're going to do a lot of fancy footwork below.
|
|
# Before we get started, it would be nice to know the argv0
|
|
# of the actual script we're running (and lets remove at least
|
|
# one level of symlinking).
|
|
#------------------------------------------------------------------------------
|
|
argv0_path=`which $0`
|
|
if [ -z $argv0_path ] ; then
|
|
argv0_path=$0
|
|
fi
|
|
|
|
real_name=`find $argv0_path -type l -printf "%l\n"`
|
|
if [ ! $real_name ]; then
|
|
real_name=$argv0_path
|
|
elif [ ! -x $real_name ]; then
|
|
real_name=`find $argv0_path -printf "%h\n"`/$real_name
|
|
fi
|
|
|
|
argv0_dir=`find $real_name -printf "%h\n"`
|
|
|
|
if [ -z $argv0_dir ] ; then
|
|
argv0_dir=.
|
|
fi
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Okay, now all that junk above was established at configure time.
|
|
# However, if this is an RPM install, they may have chosen
|
|
# to relocate this installation. If so, that stuff above
|
|
# is all broken and we should rejigger it.
|
|
#------------------------------------------------------------------------------
|
|
WINE_BIN_NAME=wine.bin
|
|
if [ ! -x $WINEBIN/$WINE_BIN_NAME ] ; then
|
|
WINEBIN=`find $argv0_dir -maxdepth 1 -perm +0111 -type f -name "$WINE_BIN_NAME" -printf "%h\n" | head -n 1`
|
|
fi
|
|
|
|
if [ ! -x $WINEBIN/$WINE_BIN_NAME ] ; then
|
|
WINEBIN=`find $argv0_dir/../ -maxdepth 1 -perm +0111 -type f -name "$WINE_BIN_NAME" -printf "%h\n" | head -n 1`
|
|
fi
|
|
|
|
if [ ! -x $WINEBIN/$WINE_BIN_NAME ] ; then
|
|
WINE_BIN_NAME=wine
|
|
if [ ! -x $WINEBIN/$WINE_BIN_NAME ] ; then
|
|
WINEBIN=`find $argv0_dir -maxdepth 1 -perm +0111 -type f -name "$WINE_BIN_NAME" -printf "%h\n" | head -n 1`
|
|
fi
|
|
|
|
if [ ! -x $WINEBIN/$WINE_BIN_NAME ] ; then
|
|
WINEBIN=`find $argv0_dir/../ -maxdepth 1 -perm +0111 -type f -name "$WINE_BIN_NAME" -printf "%h\n" | head -n 1`
|
|
fi
|
|
fi
|
|
|
|
if [ ! -r $WINELIB/libwine.so ] ; then
|
|
WINELIB=`find $argv0_dir -maxdepth 2 -name 'libwine.so' -printf "%h\n" | head -n 1`
|
|
fi
|
|
|
|
if [ ! -r $WINELIB/libwine.so ] ; then
|
|
WINELIB=`find $argv0_dir/../ -maxdepth 2 -name 'libwine.so' -printf "%h\n" | head -n 1`
|
|
fi
|
|
|
|
if [ -x $WINEBIN/wineserver ] ; then
|
|
WINESERVER=$WINEBIN/wineserver
|
|
fi
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Hey, if we built Wine from source, let's add a little extra fun to
|
|
# mix it up a bit
|
|
#------------------------------------------------------------------------------
|
|
if [ -x $WINEBIN/server/wineserver ] ; then
|
|
WINESERVER=$WINEBIN/server/wineserver
|
|
fi
|
|
|
|
if [ -r $WINELIB/dlls/ntdll.dll.so ] ; then
|
|
WINEDLLPATH=$WINELIB/dlls
|
|
fi
|
|
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Okay, set the paths and move on.
|
|
#------------------------------------------------------------------------------
|
|
if [ -n "$LD_LIBRARY_PATH" ]; then
|
|
export LD_LIBRARY_PATH=$WINELIB:$LD_LIBRARY_PATH
|
|
else
|
|
export LD_LIBRARY_PATH=$WINELIB
|
|
fi
|
|
export PATH=$WINEBIN:$PATH
|
|
export WINELOADER=$WINEBIN/$WINE_BIN_NAME
|
|
export WINEDLLPATH
|
|
export WINESERVER
|
|
|
|
info_flag=~/.wine/.no_prelaunch_window_flag
|
|
debug_flag=~/.wine/.no_debug_window_flag
|
|
debug_options="warn+all"
|
|
|
|
if [ -f $info_flag ] ; then
|
|
use_info_message=0
|
|
else
|
|
use_info_message=1
|
|
fi
|
|
|
|
if [ -f $debug_flag ] ; then
|
|
use_debug_message=0
|
|
else
|
|
use_debug_message=1
|
|
fi
|
|
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Handle winelib apps going through here
|
|
#------------------------------------------------------------------------------
|
|
winelib=0
|
|
if [ -f $argv0_path.so ] ; then
|
|
winelib=1
|
|
export WINEPRELOAD=$argv0_path.so
|
|
fi
|
|
|
|
|
|
#------------------------------------------------------------------------------
|
|
# No arguments? Help 'em out
|
|
#------------------------------------------------------------------------------
|
|
always_see_output=0
|
|
no_args=0
|
|
if [ $# -eq 0 ] ; then
|
|
no_args=1
|
|
fi
|
|
|
|
if [ $# -eq 1 -a "$1" = "" ] ; then
|
|
no_args=1
|
|
fi
|
|
|
|
if [ $winelib -eq 1 ] ; then
|
|
no_args=0
|
|
fi
|
|
|
|
if [ $no_args -eq 1 ] ; then
|
|
echo "Wine called with no arguments."
|
|
echo "Invoking $WINEBIN/$WINE_BIN_NAME $@ ..."
|
|
$XMESSAGE -buttons " Okay ":0," See the Wine Usage Statement ":1," Configure Wine ":2 \
|
|
-title "Welcome to Wine" \
|
|
"
|
|
|
|
You have started Wine without specifying any arguments.
|
|
|
|
Wine requires at least one argument - the name of the Windows
|
|
application you would like to run.
|
|
|
|
If you have launched this through the KDE menu system
|
|
and your KDE installation is specially configured for Wine,
|
|
then you can use the KDE file browser to select a Windows
|
|
executable and then click on it to launch Wine with
|
|
that application.
|
|
|
|
You can similarly use the GNOME file manager to
|
|
select a Windows executable and double click on it.
|
|
|
|
If you would like to see the command line arguments
|
|
for Wine, select the second option, below.
|
|
|
|
"
|
|
welcome_rc=$?
|
|
if [ $welcome_rc -eq 0 ] ; then
|
|
exit
|
|
fi
|
|
|
|
if [ $welcome_rc -eq 2 ] ; then
|
|
winecfg
|
|
exit
|
|
fi
|
|
|
|
use_info_message=0
|
|
always_see_output=1
|
|
fi
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Optionally Warn the user we're going to be launching Wine...
|
|
#------------------------------------------------------------------------------
|
|
if [ $use_info_message -ne 0 ] ; then
|
|
echo "Invoking $WINEBIN/$WINE_BIN_NAME $@ ..."
|
|
$XMESSAGE -timeout 30 -buttons " Dismiss ":0," Never display this message again ":3 \
|
|
-title "Wine Launch Window" \
|
|
"Invoking $WINEBIN/$WINE_BIN_NAME $@ ...
|
|
|
|
This dialog box is a temporary status dialog to let you know
|
|
that Wine is attempting to launch your application.
|
|
|
|
Since Wine is still very much in a development stage,
|
|
many applications will fail silently.
|
|
This dialog box is your indication
|
|
that we're *trying* to run your application.
|
|
|
|
This dialog box will automatically disappear after 30 seconds,
|
|
or after your application finishes.
|
|
|
|
You can permanently disable this dialog by selecting
|
|
the option below.
|
|
" &
|
|
info_message_pid=$!
|
|
fi
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Here's a little function to clean up after that dialog...
|
|
#------------------------------------------------------------------------------
|
|
clean_up_info_message ()
|
|
{
|
|
if [ $use_info_message -ne 0 ] ; then
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Okay, make sure that the notice window is dead (and kill it if it ain't)
|
|
#------------------------------------------------------------------------------
|
|
ps $info_message_pid >/dev/null 2>&1
|
|
if [ $? -ne 0 ] ; then
|
|
wait $info_message_pid
|
|
info_return=$?
|
|
else
|
|
info_return=0
|
|
kill $info_message_pid
|
|
fi
|
|
|
|
#------------------------------------------------------------------------------
|
|
# If they didn't like the warning window, turn it off
|
|
#------------------------------------------------------------------------------
|
|
if [ $info_return -eq 3 ] ; then
|
|
$XMESSAGE -title "Wine Prelaunch Control" \
|
|
"Wine will now disable the prelaunch window you just saw.
|
|
You will no longer be notified when Wine is attempting
|
|
to start a Windows application.
|
|
|
|
Please take note that you can reenable this window
|
|
by removing the $info_flag file." -buttons " Okay ":0," Cancel ":1
|
|
if [ $? -eq 0 ] ; then
|
|
touch $info_flag
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
use_info_message=0
|
|
}
|
|
#------------------------------------------------------------------------------
|
|
# Generate a temporary log file name
|
|
#------------------------------------------------------------------------------
|
|
if [ -n "$TMP" ] ; then
|
|
log_dir="$TMP"
|
|
else
|
|
log_dir="/tmp"
|
|
fi
|
|
use_log_name=0
|
|
log_name=`mktemp "$log_dir/wine.log.XXXXXX"`
|
|
if [ $? -eq 0 ] ; then
|
|
use_log_name=1
|
|
fi
|
|
use_status_name=0
|
|
status_name=`mktemp "$log_dir/wine.status.XXXXXX"`
|
|
if [ $? -eq 0 ] ; then
|
|
use_status_name=1
|
|
fi
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Okay, really launch Wine...
|
|
#------------------------------------------------------------------------------
|
|
if [ $use_log_name -ne 0 -a $use_status_name -ne 0 ] ; then
|
|
( $WINEBIN/$WINE_BIN_NAME "$@"; echo $? >$status_name ) 2>&1 | tee "$log_name"
|
|
wine_return=`cat $status_name`
|
|
else
|
|
$WINEBIN/$WINE_BIN_NAME "$@"
|
|
wine_return=$?
|
|
fi
|
|
if [ $use_status_name -ne 0 ] ; then
|
|
rm -f $status_name
|
|
fi
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Test the return code, and see if it fails
|
|
#------------------------------------------------------------------------------
|
|
if [ $always_see_output -eq 0 -a $wine_return -eq 0 ] ; then
|
|
echo "Wine exited with a successful status"
|
|
if [ $use_log_name -ne 0 ] ; then
|
|
rm -f "$log_name"
|
|
fi
|
|
else
|
|
if [ $always_see_output -eq 0 ] ; then
|
|
echo "Wine failed with return code $wine_return"
|
|
fi
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Gracefully display a debug message if they like...
|
|
#------------------------------------------------------------------------------
|
|
while [ $use_debug_message -gt 0 ] ; do
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Build up the menu of choices they can make...
|
|
#------------------------------------------------------------------------------
|
|
BUTTONS=' Okay :0'
|
|
if [ $use_log_name -ne 0 ] ; then
|
|
BUTTONS="$BUTTONS"', View Log :1'
|
|
fi
|
|
|
|
BUTTONS="$BUTTONS"', Debug :2'
|
|
BUTTONS="$BUTTONS"', Configure :4'
|
|
BUTTONS="$BUTTONS"', Disable :3'
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Build an error message
|
|
#------------------------------------------------------------------------------
|
|
MESSAGE="
|
|
Wine has exited with a failure status of $wine_return.
|
|
|
|
Wine is still development software, so there can be many
|
|
explanations for this problem.
|
|
|
|
You can choose to run Wine again with a higher level
|
|
of debug messages (the debug option, below).
|
|
|
|
You can attempt to reconfigure Wine to make it work better.
|
|
The Wine Configuration program can assist you in making
|
|
those changes (select Configure, below, for more).
|
|
|
|
You can disable this message entirely by selecting the
|
|
Disable option below."
|
|
|
|
if [ $always_see_output -ne 0 -a $wine_return -eq 0 ] ; then
|
|
MESSAGE="
|
|
Wine has exited with a failure status of $wine_return.
|
|
|
|
You can disable this message entirely by selecting the
|
|
Disable option below."
|
|
|
|
fi
|
|
|
|
if [ $use_log_name -ne 0 ] ; then
|
|
MESSAGE="$MESSAGE
|
|
|
|
Wine has captured a log of the Wine output in the file $log_name.
|
|
You may view this file by selecting View Log, below."
|
|
fi
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Display the message
|
|
#------------------------------------------------------------------------------
|
|
$XMESSAGE -title "Wine Finished With Error" -buttons "$BUTTONS" "$MESSAGE"
|
|
debug_return=$?
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Dismiss the other window...
|
|
#------------------------------------------------------------------------------
|
|
clean_up_info_message
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Process a configure instruction
|
|
#------------------------------------------------------------------------------
|
|
if [ $debug_return -eq 4 ] ; then
|
|
winecfg
|
|
continue;
|
|
fi
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Process a view instruction
|
|
#------------------------------------------------------------------------------
|
|
if [ $debug_return -eq 1 ] ; then
|
|
$XMESSAGE -title "View Wine Log" -file "$log_name" -buttons " Okay ":0,"Delete $log_name":1
|
|
if [ $? -eq 1 ] ; then
|
|
echo "Deleting $log_name"
|
|
rm -f "$log_name"
|
|
use_log_name=0
|
|
fi
|
|
else
|
|
use_debug_message=0
|
|
fi
|
|
|
|
#------------------------------------------------------------------------------
|
|
# If they didn't like the warning window, turn it off
|
|
#------------------------------------------------------------------------------
|
|
if [ $debug_return -eq 3 ] ; then
|
|
$XMESSAGE -title "Wine Debug Log Control" \
|
|
"Wine will now disable the Wine debug output control window you just saw.
|
|
You will no longer be notified when Wine fails to start a
|
|
Windows application.
|
|
|
|
Please take note that you can reenable this window
|
|
by removing the $debug_flag file." -buttons " Okay ":0," Cancel ":1
|
|
|
|
if [ $? -eq 0 ] ; then
|
|
touch $debug_flag
|
|
fi
|
|
|
|
fi
|
|
|
|
#------------------------------------------------------------------------------
|
|
# If they want to retry with debug, let 'em.
|
|
#------------------------------------------------------------------------------
|
|
if [ $debug_return -eq 2 ] ; then
|
|
echo "Rerunning WINEDEBUG=$debug_options $0 $@"
|
|
WINEDEBUG=$debug_options exec $0 "$@"
|
|
fi
|
|
done
|
|
fi
|
|
|
|
|
|
clean_up_info_message
|
|
|
|
# killed by signal?
|
|
if [ $wine_return -ge 128 ]; then
|
|
# try to kill myself with the same signal
|
|
kill -$[wine_return - 128] $$
|
|
# if we get here the kill didn't work
|
|
exit 1
|
|
fi
|