background 2.56 KB
#!/bin/bash

##
# This one generates a background image for all active xrandr displays
# and sets it via ImageMagick display. The intermediate image will
# be removed as soon as the background ist set.
#
# Author: Georg Hopp <ghopp@bigpoint.net>
# Date: Tue Apr 17 17:19:56 CEST 2012
# Version: 1.0.0
#

function rand() {
	local DD="/bin/dd"
	local OD="/usr/bin/od"
	local SED="/bin/sed"

	${DD} if=/dev/urandom bs=2 count=1 2>/dev/null | \
		${OD} -i | ${SED} '2d;s/^0\+ \+//'
}

function setroot() {
	DISPLAY=${1} /usr/bin/feh --bg-center ${2}
}

function background() {
	local SED="/bin/sed"
	local XRANDR="/usr/bin/xrandr"
	local TEMPFILE="/bin/tempfile"
	local IDENTIFY="/usr/bin/identify"
	local CONVERT="/usr/bin/convert"
	local SETROOT="/usr/bin/feh"
	local ECHO="/bin/echo"
	local EXPR="/usr/bin/expr"
	local WC="/usr/bin/wc"
	local LS="/bin/ls"

	local BGDIR="${BGDIR:-${HOME}/images/backgrounds}"
	local MYDISP="${DISPLAY:-:0}"

	local XRANDR_EXP='
		/^Screen/{
			s/ //g
			s/^.*ent\([0-9x]*\).*$/\1/
		}
		/ conn/s/^.*cted[^0-9]*\([0-9x+]*\).*$/\1/
		t
		d'

	local RESOLUTIONS="`DISPLAY=${MYDISP} ${XRANDR} | ${SED} "${XRANDR_EXP}"`"
	local WHOLE="`${ECHO} "${RESOLUTIONS}" | ${SED} '1p;d'`"
	local SCREENS="`${ECHO} "${RESOLUTIONS}" | ${SED} '2,$p;d'`"

	local BGS="`${LS} -1b "${BGDIR}"`"
	local N_BGS=`${ECHO} "${BGS}" | ${WC} -l`

	local res img size ofs ofs_x ofs_y screen_asp image_asp image_geom cmd

	cmd="-size ${WHOLE} xc:black"

	for res in ${SCREENS}
	do
		img=`rand`
		img=`${EXPR} ${img} % ${N_BGS} + 1`
		img="${BGDIR}/`${ECHO} "${BGS}" | ${SED} ${img}'p;d'`"

		size=${res%%+*}
		ofs=${res#*+*}
		ofs_x=${ofs%%+*}
		ofs_y=${ofs##*+}

		screen_asp=`eval ${EXPR} ${size/x/ '\*' 100 \/ }`
		image_asp=`eval "${IDENTIFY} -format \"%w '\*' 100 \/ %h\" ${img}"`
		image_asp=`eval ${EXPR} $image_asp`

		# decide wheter to scale up to screen height or width
		# based on previously computed asp's
		if [ ${image_asp} -lt ${screen_asp} ]
		then
			# scale on height!
			image_geom="x${size##*x}"
		else
			# scale on width!
			image_geom="${size%%x*}x"
		fi

		image_geom=`eval "${CONVERT} -scale ${image_geom} ${img} jpeg:- | \
			${IDENTIFY} -format \"%wx%h\" jpeg:-"`

		ofs_x=`${EXPR} $ofs_x + \( \( ${size%%x*} - ${image_geom%%x*} \) / 2 \)`
		ofs_y=`${EXPR} $ofs_y + \( \( ${size##*x} - ${image_geom##*x} \) / 2 \)`

		cmd="${cmd} ${img} -geometry ${image_geom}+${ofs_x}+${ofs_y} -composite"
	done

	img=`${TEMPFILE} -s '.jpg'`
	eval "${CONVERT} ${cmd} ${img}"
	setroot "${MYDISP}" "${img}"
	rm ${img}
}

test "X$(basename -- "$0")" = "Xbackground" && background "$@"

# vim: set ft=sh ts=4 sw=4: