]> icculus.org git repositories - mikachu/openbox.git/blob - util/bsetbg
xsetbg typo
[mikachu/openbox.git] / util / bsetbg
1 #!/bin/sh
2
3 # Copyright (c) 2000-2002 Timothy M. King (tmk@lordzork.com)
4 #
5 # Permission is hereby granted, free of charge, to any person obtaining a
6 # copy of this software and associated documentation files (the "Software"),
7 # to deal in the Software without restriction, including without limitation
8 # the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 # and/or sell copies of the Software, and to permit persons to whom the 
10 # Software is furnished to do so, subject to the following conditions:
11
12 # The above copyright notice and this permission notice shall be included in 
13 # all copies or substantial portions of the Software. 
14
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
16 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
17 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL 
18 # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
19 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
20 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
21 # DEALINGS IN THE SOFTWARE.
22
23 PATH=$PATH:/usr/bin:/usr/local/bin:/usr/X11R6/bin
24
25 display_full_cmd="display -geometry 800x600 -window root"
26 display_tile_cmd="display -window root"
27 display_center_cmd="display -backdrop -window root"
28 display_default_cmd="$display_center_cmd"
29
30 Esetroot_full_cmd="Esetroot -scale"
31 Esetroot_tile_cmd="Esetroot"
32 Esetroot_center_cmd="Esetroot -c"
33 Esetroot_default_cmd="$Esetroot_center_cmd"
34
35 wmsetbg_full_cmd="wmsetbg -s -S"
36 wmsetbg_tile_cmd="wmsetbg -t"
37 wmsetbg_center_cmd="wmsetbg -e"
38 wmsetbg_default_cmd="$wmsetbg_center_cmd"
39
40 qiv_full_cmd="qiv --root_s"
41 qiv_tile_cmd="qiv --root_t"
42 qiv_center_cmd="qiv --root"
43 qiv_default_cmd="$qiv_center_cmd"
44
45 xv_full_cmd="xv -max -smooth -root -quit"
46 xv_tile_cmd="xv -root -quit"
47 xv_center_cmd="xv -rmode 5 -root -quit"
48 xv_default_cmd="$xv_center_cmd"
49
50 xli_full_cmd="xli -fullscreen -onroot -quiet"
51 xli_tile_cmd="xli -onroot -quiet"
52 xli_center_cmd="xli -center -onroot quiet"
53 xli_default_cmd="$xli_center_cmd"
54
55 xsetbg_full_cmd="xsetbg -fullscreen"
56 xsetbg_tile_cmd="xsetbg"
57 xsetbg_center_cmd="xsetbg -center"
58 xsetbg_default_cmd="$xsetbg_center_cmd"
59
60 img_apps="qiv xli xv wmsetbg Esetroot display xsetbg"
61 me=${0##*/}
62 version=2.0
63 copyright="(c) 2000-$(date +%Y) by Timothy M. King (http://lordzork.com/)"
64 config=$HOME/.bsetbgrc
65 last_cmd_file=$HOME/.bsetbg_last_cmd
66 refresh_cmd=xrefresh
67 p=$me:
68
69 quit() {
70     [ "$1" ] && rc=$1 && shift 1
71     [ "$*" ] && echo -e $*
72     exit ${rc:-0}
73 }
74
75 bool() {
76     case $1 in
77             [yY][eE][sS]|1|[yY]|[tT][rR][uU][eE]|[oO][nN]) : ;;
78             *) return 1 ;;
79     esac
80 }
81
82 check_exe_in_path() {
83     if [ -z "$1" ]; then
84         return 1
85     elif [ -x "$(which $1 2>/dev/null)" ]; then
86         return 0
87     elif [ -x "$(type $1 2>/dev/null)" ]; then
88         return 0
89     else
90         return 1
91     fi
92 }
93
94 help_msg() {
95     cat <<EOF
96 $me $version $copyright
97
98   -center <file>           center an image on the desktop
99   -tile <file>             tile an image on the desktop
100   -full <file>             stretch an image to fill the desktop
101   -exec <args> <file>      specify an external command to execute
102   
103   -post <string>           arguments to be passed to the post-command
104   -debug                   prints commands without executing them
105 EOF
106
107 # this is extremely lame, but probably more portable than grep -E   
108    bsetroot_help=$(bsetroot -help  2>&1| grep -v "^bsetroot" | grep -v "^  -help")
109    case $bsetroot_help in
110         BaseDisplay*)   echo ;;
111         *-gradient*)    echo "$bsetroot_help"
112    esac
113
114     cat <<EOF
115   -generate <string>       generate a config file
116   -help                    this message
117   -version                 output version information
118 EOF
119    quit ${1:-0}
120 }
121
122 get_apps() {
123     for a in $img_apps; do
124         if check_exe_in_path $a; then
125                 eval center_cmd=\$$a\_center_cmd
126                 eval full_cmd=\$$a\_full_cmd
127                 eval tile_cmd=\$$a\_tile_cmd
128                 eval default_cmd=\$$a\_default_cmd
129                 return 0
130         else
131                 if [ "$not_found" ]; then
132                         not_found="$not_found $a"
133                 else
134                         not_found=$a
135                 fi
136         fi
137     done
138     return 1
139 }
140
141 do_generate() {
142     echo -e "# created by $me $version on $(date)\n#"
143     echo -e "# seting NO_EXEC to a boolean value (eg true/false) will cause $me"
144     echo -e "# to never modify the root window\n#"
145     echo -e "#NO_EXEC=\n#"
146     echo -e "# POST_COMMAND can be set to a command that will be run run every time"
147     echo -e "# $me sets the root image\n#"
148     echo -e "#POST_COMMAND=\n#"
149     echo -e "# if LOG_LAST_CMD is set (boolean), bsetbg will keep a log of the last"
150     echo -e "# two successful commands.\n#"
151     echo -e "#LOG_LAST_CMD=\n#"
152     echo -e "# the LOGFILE specifies the file that bsetbg uses when LOG_LAST_CMD"
153     echo -e "# is defined. this defaults to ~/.bsetbg_last_cmd .\n#"
154     echo -e "#LOGFILE=\n#"
155     echo -e "# the following are default configuration values for the most popular image"
156     echo -e "# programs. See the man page of the respective application for more info.\n" 
157
158     [ "$*" ] && img_apps="$*"
159
160     for a in $img_apps; do
161         if check_exe_in_path $a; then
162                 if ! bool $have_match; then
163                         q='\"'
164                         [ "$(eval echo \$$a\_center_cmd)" ] &&
165                         eval echo CENTER=$q\$$a\_center_cmd$q &&
166                         
167                         [ "$(eval echo \$$a\_full_cmd)" ] &&
168                         eval echo FULL=$q\$$a\_full_cmd$q &&
169                         
170                         [ "$(eval echo \$$a\_tile_cmd)" ] &&
171                         eval echo TILE=$q\$$a\_tile_cmd$q &&
172                         
173                         [ "$(eval echo \$$a\_default_cmd)" ] &&
174                         eval echo -e DEFAULT=$q\$$a\_default_cmd$q \\\\n &&
175                         
176                         have_match=1
177                 else
178                         [ "$(eval echo \$$a\_center_cmd)" ] && 
179                         eval echo \\#CENTER=$q\$$a\_center_cmd$q
180                         
181                         [ "$(eval echo \$$a\_full_cmd)" ] &&
182                         eval echo \\#FULL=$q\$$a\_full_cmd$q
183                         
184                         [ "$(eval echo \$$a\_tile_cmd)" ] &&
185                         eval echo \\#TILE=$q\$$a\_tile_cmd$q
186                         
187                         [ "$(eval echo \$$a\_default_cmd)" ] &&
188                         eval echo -e \\#DEFAULT=$q\$$a\_default_cmd$q \\\\n
189                 fi
190         fi
191     done
192     quit 0
193 }
194
195 do_bsetroot() {
196     if check_exe_in_path bsetroot; then
197         read_config
198
199         $debug bsetroot $* 2>/dev/null; rc=$?
200                 
201         if [ "$rc" -gt 0 ]; then
202                 help_msg $rc
203         else
204                 log_cmd bsetroot $*; $refresh_cmd 2>/dev/null
205         fi
206     else
207         quit 1 "couldn't find bsetroot in $PATH"
208     fi
209 }
210
211 do_std() {
212     [ -z "$1" ] && help_msg 1
213
214     bool $noconfig || read_config
215
216     get_img_command $1
217     check_img_command $do_this
218
219     case $# in
220         1) file="$1" ;;
221         *) file="$2"
222     esac
223
224     if [ -f "$file" ]; then
225         exec_img_command $do_this $file 
226     else
227         quit 1 "$file does not exist"
228     fi
229
230
231 do_exec() {
232     [ "$#" -lt 3 ] && help_msg 3
233
234     bool $noconfig || read_config
235     
236     # check to see if -*c, -*f, or -*t were spcified, if so
237     # assume the last argument is a filename
238     b_arg=$(eval echo \$$(( $# - 1 )) )
239     app=$1
240
241     case $b_arg in
242         -c|*-center|c|-t|*-tile*|t|-f|*-full|f)
243                 eval file=\$$#
244                 f_args="$b_arg $file"
245     esac
246
247     # put the rest of the arguments into the varialbe $e_args
248     while [ "$*" ]; do
249         for a in "$*"; do
250                 case $1 in
251                         $b_arg|$file) : ;;
252                         *) e_args="$e_args "$1""
253                 esac
254                 shift 1
255         done
256     done
257
258     # with $f_args defined, check for image and do things normally
259     if [ "$f_args" ]; then
260         [ ! -f "$file" ] && quit 1 "$file does not exist"
261         
262         if check_img_command $e_args; then
263                 do_this="$e_args"
264         else
265                 read_config
266                 get_img_command $f_args
267                 check_img_command $do_this
268                 echo "$p couldn't find '$app' in path, using $type command instead"
269         fi
270    # without $f_args, run the command blindly if it's in $PATH
271     elif check_exe_in_path $e_args; then
272         do_this="$e_args"
273     else
274         quit 1 "$p unable to run the following command: $e_args"
275     fi
276
277     exec_img_command $do_this $file
278 }    
279
280 get_img_command() {
281     case $1 in
282             *-full|-f|f)        type=full; do_this="$full_cmd" ;;
283             *-tile|-t|t)        type=tile; do_this="$tile_cmd" ;;
284             *-center|-c|c)      type=center; do_this="$center_cmd" ;;
285             *)                  type=default; do_this="$default_cmd"
286     esac
287 }
288
289 check_img_command() {
290     if check_exe_in_path $1; then
291         do_this="$*"
292         rc=0
293     elif get_apps; then
294         get_img_command $*
295         rc=1
296     else
297         quit 1 "$p couldn't find a suitable image program. tried the following:\\n
298         $(for a in $not_found; do echo "    $a\\n"; done)"
299     fi
300
301     if [ "$rc" -gt 0 -a -z "$e_args" ] && bool $read_config; then
302         echo "$p couldn't find a suitable $type command in $config"
303     fi
304
305     return $rc
306 }
307
308 exec_img_command() {
309     unset rc
310     command=$*
311
312     if [ "$debug" ]; then
313         $debug $command
314     else
315         $command >/dev/null 2>&1; rc=$?
316     fi
317
318     if [ "$rc" -gt 0 ]; then
319         echo "$p '$command' exited with status $rc"
320         get_apps
321         noconfig=1
322         parse_args ${f_args:-$my_args}
323         echo "$p using '$command' as $type"
324         $debug $command >/dev/null 2>&1; rc=$?
325         [ "$rc" =  0 ] && log_cmd $do_this $file && $refresh_cmd 2>/dev/null
326     else
327         log_cmd $do_this $file; xrefresh 2>/dev/null
328     fi
329     return $rc
330 }
331
332 log_cmd() {
333     bool $LOG_LAST_CMD || return 1
334     [ "$debug" ] && return 1
335     echo -e "$prev_cmd\n$*" >$last_cmd_file
336     return $?
337 }
338
339 read_config() {
340     [ -f $config ] || return 1
341
342     if bool $read_config; then
343         unset read_config
344     else
345         read_config=1
346     fi
347
348     . $HOME/.bsetbgrc 2>/dev/null
349     check_no_exec
350
351     full_cmd=$FULL
352     center_cmd=$CENTER
353     tile_cmd=$TILE
354     default_cmd=$CENTER
355     last_cmd_file=${LOGFILE:-$last_cmd_file}
356     
357     bool $LOG_LAST_CMD && prev_cmd=$(tail -n 1 $last_cmd_file 2>/dev/null)    
358 }
359
360 check_no_exec() {
361     bool $NO_EXEC && 
362     quit 0 "$p no_exec mode. the root window will not be modified."
363 }
364
365 post_command() {
366     if [ -n "$POST_COMMAND" -a "$rc" -le 0 ]; then
367         if [ -n "$debug" ]; then
368                 $debug "running post_command: $POST_COMMAND $post_args"
369         else
370                 $POST_COMMAND $post_args 2>/dev/null; erc=$?
371                 [ "$erc" -gt 0 ] && 
372                 echo "$p post-command '$POST_COMMAND $post_args' exited with status $erc"
373         fi
374     fi
375 }
376
377 add_arg() {
378     [ "$1" ] || return 1
379     if [ "$args" ]; then
380         args="$args $1"
381     else
382         args=$1
383     fi
384 }  
385
386 add_post_arg() {
387     [ -z "$1" ] && return 1
388     if [ "$post_args" ]; then
389         post_args="$post_args $1"
390     else
391         post_args=$1
392     fi
393 }
394
395 check_cmd() {
396     if [ -z "$command" ]; then
397         command=${2:-$1}; eval ${3:-${2:-$1}}=1
398     elif bool $do_post; then
399         add_post_arg ${1}
400     else
401         finished=1
402     fi 
403 }
404
405 parse_args() {
406     case $1 in
407         -d|*-debug|d)
408                 unset refresh_cmd; debug=echo\ $me\_debug: ;;
409
410         -p|-*-post|p)                   
411                 unset finished do_std do_exec; do_post=1 ;;
412                                 
413         -c|*-center|c|-t|*-tile*|t|-f|*-full|f)
414                 case $command in
415                         do_std|do_generate|do_bsetroot)
416                                 finished=1 ;;
417                         do_exec)
418                                 if ! bool $got_fcmd; then
419                                         add_arg $1 args; got_fcmd=1
420                                 else
421                                         finished=1
422                                 fi ;;
423                         *)      
424                                 add_arg $1; do_std=1; command=do_std
425                 esac ;;         
426                 
427         -a|*-app|a|-e|*-exec|e)
428                 check_cmd "do_exec" ;;
429                 
430         -mod|-gradient|-solid|-display)
431                 check_cmd "do_bsetroot" && add_arg $1 ;;
432
433         -g|*-generate*|g)
434                 check_cmd $1 "do_generate" ;;
435                 
436         -v|*-version|v)
437                 [ -z "$command" ] && quit 0 $me $version $copyright ;;
438                 
439         -h|*-help|h)
440                 [ -z "$command" ] && help_msg ;;
441                 
442         *)      
443                 bool $finished && return 1              
444
445                 case $1 in -*)
446                         bool $do_exec || bool $do_bsetroot || bool $do_post || help_msg 1
447                 esac
448                 
449                 if bool $do_std || bool $do_exec || bool $do_bsetroot || bool $do_generate; then
450                         add_arg $1
451                 elif bool $do_post; then
452                         add_post_arg $1
453                 else
454                         add_arg $1; command=do_std; finished=1
455                 fi
456     esac
457 }
458
459 [ -z "$*" ] && help_msg 1
460
461 my_args=$*
462
463 for arg in "$@"; do
464         parse_args "$arg"
465         shift 1
466 done
467
468 [ "$debug" ] && echo
469
470 $command $args
471 post_command $rc
472
473 quit $rc