OLD | NEW |
(Empty) | |
| 1 #!/bin/sh |
| 2 #--------------------------------------------- |
| 3 # xdg-screensaver |
| 4 # |
| 5 # Utility script to control screensaver. |
| 6 # |
| 7 # Refer to the usage() function below for usage. |
| 8 # |
| 9 # Copyright 2006, Bryce Harrington <bryce@osdl.org> |
| 10 # |
| 11 # LICENSE: |
| 12 # |
| 13 #--------------------------------------------- |
| 14 |
| 15 manualpage() |
| 16 { |
| 17 cat << _MANUALPAGE |
| 18 _MANUALPAGE |
| 19 } |
| 20 |
| 21 usage() |
| 22 { |
| 23 cat << _USAGE |
| 24 _USAGE |
| 25 } |
| 26 |
| 27 #@xdg-utils-common@ |
| 28 |
| 29 # Check if we can use "mv -T" |
| 30 if mv -T ... ... 2>&1 | grep '\.\.\.' > /dev/null ; then |
| 31 # We can securely move files in /tmp with mv -T |
| 32 DEBUG 1 "mv -T available" |
| 33 MV="mv -T" |
| 34 screensaver_file="/tmp/xdg-screensaver-$USER-"`echo $DISPLAY | sed 's/:/-/g'` |
| 35 else |
| 36 # No secure moves available, use home dir |
| 37 DEBUG 1 "mv -T not available" |
| 38 MV="mv" |
| 39 screensaver_file="$HOME/.xdg-screensaver-"`echo $HOSTNAME-$DISPLAY | sed 's/:
/-/g'` |
| 40 fi |
| 41 lockfile_command=`which lockfile 2> /dev/null` |
| 42 |
| 43 lockfile() |
| 44 { |
| 45 if [ -n "$lockfile_command" ] ; then |
| 46 $lockfile_command -1 -l 10 -s 3 "$screensaver_file".lock |
| 47 else |
| 48 # Poor man's attempt at doing a lockfile |
| 49 # Be careful not to facilitate a symlink attack |
| 50 local try |
| 51 try=0 |
| 52 while ! ln -s "$screensaver_file".lock "$screensaver_file".lock 2> /dev/nul
l; |
| 53 do |
| 54 sleep 1 |
| 55 try=$(($try+1)) |
| 56 if [ $try -eq 3 ] ; then |
| 57 rm -f "$screensaver_file".lock || return # Can't remove lockfile |
| 58 try=0 |
| 59 fi |
| 60 done |
| 61 fi |
| 62 } |
| 63 |
| 64 unlockfile() |
| 65 { |
| 66 rm -f "$screensaver_file".lock |
| 67 } |
| 68 |
| 69 perform_action() |
| 70 { |
| 71 result=1 |
| 72 |
| 73 if [ "$1" = "resume" ] ; then |
| 74 # Restore DPMS state |
| 75 if [ -f "$screensaver_file.dpms" ]; then |
| 76 rm "$screensaver_file.dpms" |
| 77 # Re-enable DPMS |
| 78 xset +dpms |
| 79 fi |
| 80 fi |
| 81 if [ "$1" = "reset" ] ; then |
| 82 if xset -q | grep 'DPMS is Enabled' > /dev/null 2> /dev/null; then |
| 83 xset dpms force on |
| 84 fi |
| 85 fi |
| 86 |
| 87 case "$DE" in |
| 88 kde) |
| 89 screensaver_kde "$1" |
| 90 ;; |
| 91 |
| 92 gnome) |
| 93 screensaver_gnome "$1" |
| 94 ;; |
| 95 |
| 96 xscreensaver) |
| 97 screensaver_xscreensaver "$1" |
| 98 ;; |
| 99 esac |
| 100 |
| 101 if [ "$1" = "suspend" ] ; then |
| 102 # Save DPMS state |
| 103 if xset -q | grep 'DPMS is Enabled' > /dev/null 2> /dev/null; then |
| 104 test "${TMPDIR+set}" = set || TMPDIR=/tmp |
| 105 tmpfile=`mktemp $TMPDIR/tmp.XXXXXXXXXX` |
| 106 $MV "$tmpfile" "$screensaver_file.dpms" |
| 107 # Disable DPMS |
| 108 xset -dpms |
| 109 fi |
| 110 fi |
| 111 |
| 112 } |
| 113 |
| 114 cleanup_suspend() |
| 115 { |
| 116 lockfile |
| 117 test "${TMPDIR+set}" = set || TMPDIR=/tmp |
| 118 tmpfile=`mktemp $TMPDIR/tmp.XXXXXXXXXX` |
| 119 grep -v "$window_id:" "$screensaver_file" > "$tmpfile" 2> /dev/null |
| 120 $MV "$tmpfile" "$screensaver_file" |
| 121 if [ ! -s "$screensaver_file" ] ; then |
| 122 rm "$screensaver_file" |
| 123 unlockfile |
| 124 # $screensaver_file is empty, do resume |
| 125 perform_action resume |
| 126 else |
| 127 unlockfile |
| 128 fi |
| 129 } |
| 130 |
| 131 do_resume() |
| 132 { |
| 133 lockfile # Obtain lockfile |
| 134 # Find the PID of the trackingprocess |
| 135 xprop_pid=`grep "$window_id:" "$screensaver_file" 2> /dev/null | cut -d ':' -f
2` |
| 136 unlockfile # Free lockfile |
| 137 if [ -n "$xprop_pid" ] && ps -p "$xprop_pid" 2> /dev/null | grep xprop > /dev/
null; then |
| 138 # Kill the tracking process |
| 139 kill -TERM $xprop_pid |
| 140 fi |
| 141 cleanup_suspend |
| 142 } |
| 143 |
| 144 XPROP=`which xprop 2> /dev/null` |
| 145 |
| 146 check_window_id() |
| 147 { |
| 148 if [ -z "$XPROP" ]; then |
| 149 DEBUG 3 "xprop not found" |
| 150 return |
| 151 fi |
| 152 DEBUG 2 "Running $XPROP -id $window_id" |
| 153 if $XPROP -id $window_id > /dev/null 2> /dev/null; then |
| 154 DEBUG 3 Window $window_id exists |
| 155 else |
| 156 DEBUG 3 Window $window_id does not exist |
| 157 exit_failure_operation_failed "Window $window_id does not exist" |
| 158 fi |
| 159 } |
| 160 |
| 161 track_window() |
| 162 { |
| 163 if [ -z "$XPROP" ]; then |
| 164 # Don't track window if we don't have xprop |
| 165 return |
| 166 fi |
| 167 lockfile |
| 168 |
| 169 test "${TMPDIR+set}" = set || TMPDIR=/tmp |
| 170 tmpfile=`mktemp $TMPDIR/tmp.XXXXXXXXXX` |
| 171 # Filter stale entries from the xdg-screensaver status file |
| 172 # Return if $window_id is being tracked already |
| 173 ( |
| 174 already_tracked=1 |
| 175 IFS_save="$IFS" |
| 176 IFS=":" |
| 177 while read wid pid; do |
| 178 if ps -p "$pid" 2> /dev/null | grep xprop > /dev/null; then |
| 179 echo "$wid:$pid" |
| 180 if [ $wid = $window_id ] ; then |
| 181 already_tracked=0 |
| 182 fi |
| 183 fi |
| 184 done |
| 185 IFS="$IFS_save" |
| 186 exit $already_tracked |
| 187 ) < $screensaver_file > $tmpfile |
| 188 already_tracked=$? |
| 189 |
| 190 if [ "$already_tracked" -eq "0" ] ; then |
| 191 $MV "$tmpfile" "$screensaver_file" |
| 192 # We are already tracking $window_id, don't do anything |
| 193 unlockfile |
| 194 return |
| 195 fi |
| 196 |
| 197 # Start tracking $window_id |
| 198 $XPROP -id $window_id -spy > /dev/null & |
| 199 xprop_pid=$! |
| 200 # Add window_id and xprop_pid to the xdg-screensave status file |
| 201 echo "$window_id:$xprop_pid" >> $tmpfile |
| 202 $MV "$tmpfile" "$screensaver_file" |
| 203 unlockfile |
| 204 # Wait for xprop to edit, it means that the window disappeared |
| 205 wait $xprop_pid |
| 206 # Clean up the administration and resume the screensaver |
| 207 cleanup_suspend |
| 208 } |
| 209 |
| 210 screensaver_freedesktop() |
| 211 { |
| 212 case "$1" in |
| 213 suspend) |
| 214 #FIXME (get/store cookie) |
| 215 qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSav
er.Inhibit $window_id xdg-screensaver > /dev/null |
| 216 result=$? |
| 217 ;; |
| 218 |
| 219 resume) |
| 220 qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSav
er.SetActive true > /dev/null |
| 221 result=$? |
| 222 ;; |
| 223 |
| 224 activate) |
| 225 qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSav
er.SetActive true > /dev/null |
| 226 result=$? |
| 227 ;; |
| 228 |
| 229 lock) |
| 230 qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSav
er.Lock > /dev/null |
| 231 ;; |
| 232 |
| 233 reset) |
| 234 #FIXME (cookies?) |
| 235 qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSav
er.UnInhibit $window_id > /dev/null |
| 236 result=$? |
| 237 ;; |
| 238 |
| 239 status) |
| 240 status=`qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.S
creenSaver.GetActive` |
| 241 result=$? |
| 242 if [ x"$status" = "xtrue" ]; then |
| 243 echo "enabled" |
| 244 elif [ x"$status" = "xfalse" ]; then |
| 245 echo "disabled" |
| 246 else |
| 247 echo "ERROR: dbus org.freedesktop.ScreenSaver.GetActive returned '$s
tatus'" >&2 |
| 248 return 1 |
| 249 fi |
| 250 ;; |
| 251 |
| 252 *) |
| 253 echo "ERROR: Unknown command '$1'" >&2 |
| 254 return 1 |
| 255 ;; |
| 256 esac |
| 257 } |
| 258 |
| 259 screensaver_kde() |
| 260 { |
| 261 case "$1" in |
| 262 suspend) |
| 263 dcop kdesktop KScreensaverIface enable false > /dev/null |
| 264 result=$? |
| 265 ;; |
| 266 |
| 267 resume) |
| 268 dcop kdesktop KScreensaverIface configure > /dev/null |
| 269 result=$? |
| 270 ;; |
| 271 |
| 272 activate) |
| 273 dcop kdesktop KScreensaverIface save > /dev/null |
| 274 result=$? |
| 275 ;; |
| 276 |
| 277 lock) |
| 278 dcop kdesktop KScreensaverIface lock > /dev/null |
| 279 result=$? |
| 280 ;; |
| 281 |
| 282 reset) |
| 283 # Turns the screensaver off right now |
| 284 dcop kdesktop KScreensaverIface quit > /dev/null |
| 285 result=$? |
| 286 ;; |
| 287 |
| 288 status) |
| 289 status=`dcop kdesktop KScreensaverIface isEnabled` |
| 290 result=$? |
| 291 if [ x"$status" = "xtrue" ]; then |
| 292 echo "enabled" |
| 293 elif [ x"$status" = "xfalse" ]; then |
| 294 echo "disabled" |
| 295 else |
| 296 echo "ERROR: kdesktop KScreensaverIface isEnabled returned '$status
'" >&2 |
| 297 return 1 |
| 298 fi |
| 299 ;; |
| 300 |
| 301 *) |
| 302 echo "ERROR: Unknown command '$1'" >&2 |
| 303 return 1 |
| 304 ;; |
| 305 esac |
| 306 } |
| 307 |
| 308 screensaver_suspend_loop() |
| 309 { |
| 310 lockfile |
| 311 test "${TMPDIR+set}" = set || TMPDIR=/tmp |
| 312 tmpfile=`mktemp $TMPDIR/tmp.XXXXXXXXXX` |
| 313 # Filter stale entries from the xdg-screensaver status file |
| 314 cat "$screensaver_file" 2> /dev/null | ( |
| 315 IFS_save="$IFS" |
| 316 IFS=":" |
| 317 while read wid pid; do |
| 318 if ps -p "$pid" 2> /dev/null | grep xprop > /dev/null; then |
| 319 echo "$wid:$pid" |
| 320 fi |
| 321 done |
| 322 IFS="$IFS_save" |
| 323 ) > $tmpfile |
| 324 if [ -s "$tmpfile" ] ; then |
| 325 # Suspend pending, don't do a thing |
| 326 $MV "$tmpfile" "$screensaver_file" |
| 327 unlockfile |
| 328 return |
| 329 fi |
| 330 $MV "$tmpfile" "$screensaver_file" |
| 331 unlockfile |
| 332 (while [ -f "$screensaver_file" ]; do $*; sleep 59; done) > /dev/null 2> /dev/
null & |
| 333 } |
| 334 |
| 335 screensaver_gnome() |
| 336 { |
| 337 # TODO |
| 338 # There seems to be a DBUS interface for gnome-screensaver |
| 339 # See http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/2006-April/042579.html
and |
| 340 # http://cvs.gnome.org/viewcvs/gnome-screensaver/src/gs-listener-dbus.c?rev=1.36
&view=log |
| 341 # A problem seems to be that Inhibit is tied to the lifetime of the DBUS appname
and |
| 342 # this can not be used from a script |
| 343 case "$1" in |
| 344 suspend) |
| 345 screensaver_suspend_loop gnome-screensaver-command --poke |
| 346 result=0 |
| 347 ;; |
| 348 |
| 349 resume) |
| 350 # Automatic resume when $screensaver_file disappears |
| 351 result=0 |
| 352 ;; |
| 353 |
| 354 activate) |
| 355 gnome-screensaver-command --activate > /dev/null 2> /dev/null |
| 356 result=$? |
| 357 ;; |
| 358 |
| 359 lock) |
| 360 gnome-screensaver-command --lock > /dev/null 2> /dev/null |
| 361 result=$? |
| 362 ;; |
| 363 |
| 364 reset) |
| 365 # Turns the screensaver off right now |
| 366 gnome-screensaver-command --deactivate > /dev/null 2> /dev/null |
| 367 result=$? |
| 368 ;; |
| 369 |
| 370 status) |
| 371 result=0 |
| 372 if [ -f "$screensaver_file" ] ; then |
| 373 echo "disabled" |
| 374 elif gnome-screensaver-command --query > /dev/null 2> /dev/null; then |
| 375 echo "enabled" |
| 376 else |
| 377 # Something is wrong |
| 378 echo "disabled" |
| 379 fi |
| 380 ;; |
| 381 |
| 382 *) |
| 383 echo "ERROR: Unknown command '$1" >&2 |
| 384 return 1 |
| 385 ;; |
| 386 esac |
| 387 } |
| 388 |
| 389 screensaver_xscreensaver() |
| 390 { |
| 391 case "$1" in |
| 392 suspend) |
| 393 screensaver_suspend_loop xscreensaver-command -deactivate |
| 394 result=0 |
| 395 ;; |
| 396 |
| 397 resume) |
| 398 # Automatic resume when $screensaver_file disappears |
| 399 result=0 |
| 400 ;; |
| 401 |
| 402 activate) |
| 403 xscreensaver-command -activate > /dev/null 2> /dev/null |
| 404 result=$? |
| 405 ;; |
| 406 |
| 407 lock) |
| 408 xscreensaver-command -lock > /dev/null 2> /dev/null |
| 409 result=$? |
| 410 ;; |
| 411 |
| 412 reset) |
| 413 # Turns the screensaver off right now |
| 414 xscreensaver-command -deactivate > /dev/null 2> /dev/null |
| 415 result=$? |
| 416 ;; |
| 417 |
| 418 status) |
| 419 result=0 |
| 420 if [ -f "$screensaver_file" ] ; then |
| 421 echo "disabled" |
| 422 else |
| 423 echo "enabled" |
| 424 fi |
| 425 ;; |
| 426 |
| 427 *) |
| 428 echo "ERROR: Unknown command '$1" >&2 |
| 429 return 1 |
| 430 ;; |
| 431 esac |
| 432 } |
| 433 |
| 434 [ x"$1" != x"" ] || exit_failure_syntax |
| 435 |
| 436 action= |
| 437 window_id= |
| 438 |
| 439 case $1 in |
| 440 suspend) |
| 441 action="$1" |
| 442 |
| 443 shift |
| 444 |
| 445 if [ -z "$1" ] ; then |
| 446 exit_failure_syntax "WindowID argument missing" |
| 447 fi |
| 448 |
| 449 window_id="$1" |
| 450 check_window_id |
| 451 ;; |
| 452 |
| 453 resume) |
| 454 action="$1" |
| 455 |
| 456 shift |
| 457 |
| 458 if [ -z "$1" ] ; then |
| 459 exit_failure_syntax "WindowID argument missing" |
| 460 fi |
| 461 |
| 462 window_id="$1" |
| 463 check_window_id |
| 464 ;; |
| 465 |
| 466 activate) |
| 467 action="$1" |
| 468 ;; |
| 469 |
| 470 lock) |
| 471 action="$1" |
| 472 ;; |
| 473 |
| 474 reset) |
| 475 action="$1" |
| 476 ;; |
| 477 |
| 478 status) |
| 479 action="$1" |
| 480 ;; |
| 481 |
| 482 *) |
| 483 exit_failure_syntax "unknown command '$1'" |
| 484 ;; |
| 485 esac |
| 486 |
| 487 detectDE |
| 488 # Consider "xscreensaver" a separate DE |
| 489 xscreensaver-command -version 2> /dev/null | grep XScreenSaver > /dev/null && DE
="xscreensaver" |
| 490 |
| 491 if [ "$action" = "resume" ] ; then |
| 492 do_resume |
| 493 exit_success |
| 494 fi |
| 495 |
| 496 perform_action "$action" |
| 497 |
| 498 if [ "$action" = "suspend" ] ; then |
| 499 # Start tracking $window_id and resume the screensaver once it disappears |
| 500 ( track_window ) 2> /dev/null > /dev/null & |
| 501 fi |
| 502 |
| 503 if [ $result -eq 0 ]; then |
| 504 exit_success |
| 505 else |
| 506 exit_failure_operation_failed |
| 507 fi |
OLD | NEW |