#!/bin/sh
#
# Set wallpaper for fluxbox.
#
# Copyright (c) 2003 Han Boetes <han@mijncomputer.nl>
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# $Id: fbsetbg,v 1.16 2003/08/26 20:32:27 fluxgen Exp $

# Portability notes:
# To guarantee this script works on all platforms that support fluxbox
# please keep the following restrictions in mind:
#
# - don't use if ! command;, use command; if [ $? -ne 0 ];
# - don't use [ -e file ] use [ -r file ]
# - don't use $(), use ``
# - don't use ~, use ${HOME}
# - don't use id -u, use whoami
# - getopts won't work on all platforms, but the config-file can
#   compensate for that.
# - various software like grep/sed/perl may be not present or not
#   the version you have. for example grep '\W' only works on gnu-grep.
#   Keep this in mind, use bare basic defaults.
# - Do _NOT_ suggest to use #!/bin/bash. Not everybody uses bash.
#   Non portable features like getopts in this script can be achieved in
#   other ways.


# The wallpapersetter is selected in this order
wpsetters='chbg Esetroot wmsetbg display qiv xv xsri xli xsetbg' # broken icewmbg'
lastwallpaper=${HOME}/.fluxbox/lastwallpaper


WHOAMI=`whoami`
[ "$WHOAMI" = root ] && PATH=/bin:/usr/bin/:/usr/local/bin:/usr/X11R6/bin


# Functions
display_usage() {
    cat << EOF
Usage: fbsetbg [ -fFcCtTaA /path/to/wallpaper ] [ -l ] [ -h ] [ -d ] [ -p ]
EOF
}

display_help() {
    display_usage
    cat << EOF

Options:

    -f  Set fullscreen wallpaper
    -c  Set centered wallpaper
    -t  Set tiled wallpaper
    -a  Set maximized wallpaper, preserving aspect.
        ( if your bgsetter doesn't support this
          fbsetbg falls back to -f )

    -F,-C,-T,-A same as uncapsed but without remembering.

    -h  Display this help

    -l  Set previous wallpaper

    -d  Debug fbsetbg
    -p  Tips

Files:
    In this file the wallpaper you set will be stored, for the -l option:
    ~/.fluxbox/lastwallpaper

EOF
}

display_tips() {
    cat << EOF

1) To replace all occurrences of bsetbg in a file use this command:

   perl -pi -e 's,([^f]|^)bsetbg,fbsetbg,' filename

2) If you want the style to set the wallpaper and you want fbsetbg to
   remember the previous wallpaper put this in your ~/.fluxbox/init

   session.screen0.rootCommand:    fbsetbg -l

3) Use fbsetbg -d to find out what wallpapersetter fbsetbg will use and
   what he thinks about it.

EOF
}

# ugly code for solaris compat.
case `uname` in
    Linux|*BSD)
        find_it() {
            which $1 > /dev/null 2>&1 && shift && $*
        }
        ;;
    *)
        find_it() {
            file=`which $1 2> /dev/null`
            if [ -x "$file" ]; then
                if [ $# -gt 1 ]; then
                    shift
                    $*
                fi
                return 0
            else
                return 1
            fi
        }
        ;;
esac


message() {
    xmessage -center "$@"
}

remembercommand() {
    grep -vs "|${DISPLAY}$" ${lastwallpaper} > ${lastwallpaper}.tmp
    mv -f ${lastwallpaper}.tmp ${lastwallpaper}
    # Make dir/../../path/file.jpg work
    case $wallpaper in
        # no spaces allowed between the varname and '|'
        /*) echo $option'|'$wallpaper'|'$DISPLAY >> $lastwallpaper ;;
        *)  echo $option'|'$PWD/$wallpaper'|'$DISPLAY >> $lastwallpaper ;;
    esac
}

debugfbsetbg() {
    echo
    echo $debugstory
    echo
    exit 0
}

# Find the default wallpapersetter
for wpsetter in $wpsetters; do
    if find_it $wpsetter; then
        WPSETTER=$wpsetter
        break
    fi
done

standardrant=\
"$WPSETTER sets the 'wrong' wallpaper. Transparency for fluxbox and apps like aterm
and xchat won't work right with it. Consider using chbg, wmsetbg (from windowmaker)
or Esetroot (from Eterm)"

standardok=\
"$WPSETTER is a nice wallpapersetter. You won't have any problems."

case $WPSETTER in
    chbg)
        full='-once -mode maximize'
        tile='-once -mode tile'
        center='-once -mode center'
        aspect='-once -mode smart -max_grow 100 -max_size 100'
        debugstory=$standardok
        ;;
    xsri)
        full='--center-x --center-y --scale-width=100 --scale-height=100'
        tile='--tile'
        center='--center-x --center-y'
        aspect=$full
        debugstory="This is a RedHat specific app. I can't find docs about it."
        ;;
    display)
        full="`xwininfo -root|grep geom` -window root"
        tile='-window root'
        center='-backdrop -window root'
        aspect=$full
        debugstory=$standardrant
        ;;
    Esetroot)
        full='-scale'
        tile=''
        center='-c'
        aspect='-fit'
        debugstory=$standardok
        ;;
    wmsetbg)
        full='-s -S'
        tile='-t'
        center='-b black -e'
        aspect='-b black -a'
        debugstory=$standardok
        ;;
    xsetbg)
        tile='-border black'
        center='-center -border black'
        aspect='-fullscreen -border black'
        full=$aspect #broken
        debugstory="xsetbg is actually xli. The fillscreen option (-f) is broken, defaults to (-a). $standardrant"
        ;;
    xli)
        tile='-onroot -quiet -border black'
        center='-center -onroot -quiet -border black'
        aspect='-fullscreen -onroot -quiet -border black'
        full=$aspect #broken
        debugstory='The fillscreen option (-f) is broken, defaults to (-a). $standardrant'
        ;;
    qiv)
        full='--root_s'
        tile='--root_t'
        center='--root'
        aspect='-m --root'
        debugstory=$standardrant
        ;;
    xv)
        full='-max -smooth -root -quit'
        tile='-root -quit'
        center='-rmode 5 -root -quit'
        aspect='-maxpect -smooth -root -quit'
        debugstory=$standardrant
        ;;
    icewmbg)
        tile='-s'
        full=$tile
        center=$tile
        aspect=$tile
        debugstory="icewmbg does support transparency, but only tiling. And I noticed odd
errormessages with aterm. Don't use it unless you have to."
        ;;
    '')
        message \
"I can't find an app to set the wallpaper with. You can install one in
many many ways but I will give you some simple advice: install Eterm and
you're set. Eterm provides Esetroot and thats a great wallpaper setter. I
recommend you install the package provided by your distro."
        exit 1
        ;;
esac

#Get options.
getopts ":a:f:c:t:A:F:C:T:pdlh-" COMMAND_LINE_ARGUMENT
case "${COMMAND_LINE_ARGUMENT}" in
    d) debugfbsetbg
        exit 0
        ;;
    a) option=$aspect
        wallpaper=$OPTARG
        ;;
    f) option=$full
        wallpaper=$OPTARG
        ;;
    c) option=$center
        wallpaper=$OPTARG
        ;;
    t) option=$tile
        wallpaper=$OPTARG
        ;;
    A) option=$aspect
        wallpaper=$OPTARG
        remember=false
        ;;
    F) option=$full
        wallpaper=$OPTARG
        remember=false
        ;;
    C) option=$center
        wallpaper=$OPTARG
        remember=false
        ;;
    T) option=$tile
        wallpaper=$OPTARG
        remember=false
        ;;

    l)
        if [ -r $lastwallpaper ]; then
            option=`grep "|${DISPLAY}$"    $lastwallpaper|cut -d'|' -f1`
            wallpaper=`grep "|${DISPLAY}$" $lastwallpaper|cut -d'|' -f2`
        else
            message 'No previous wallpaper recorded. You have never used fbsetbg before.'
            exit 1
        fi
        remember=false
        ;;
    h) display_help ; exit 0 ;;
    p) display_tips ; exit 0 ;;
    -) echo "fbsetbg doesn't recognize -- gnu-longopts."
        echo 'Use fbsetbg -h for a long help message.'
        display_usage
        exit 1
        ;;
    *) if [ ! -r "$1" ]; then
           echo "$1 isn't an existing wallpaper or a valid option." >&2
           display_usage
           exit 1
       fi
       if [ -z "$1" ]; then
           message 'No wallpaper to set' >&2
           display_usage
           exit 1
       fi
       ;;
esac

option=${option:=$full}
wallpaper=${wallpaper:=$1}


if [ ! -r "$wallpaper" ]; then
    message "Can't find wallpaper $wallpaper"
    exit 1
fi

$WPSETTER $option "$wallpaper" || message "Something went wrong while setting the wallpaper
Run '$WPSETTER $option "$wallpaper"' from an xterm to find out what."
#remember previous wallpaper
[ ! "$remember" = false ] && remembercommand
# Off course this returns 1 most of the time.
exit 0
