xdg-screensaver 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429
  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. # Permission is hereby granted, free of charge, to any person obtaining a
  14. # copy of this software and associated documentation files (the "Software"),
  15. # to deal in the Software without restriction, including without limitation
  16. # the rights to use, copy, modify, merge, publish, distribute, sublicense,
  17. # and/or sell copies of the Software, and to permit persons to whom the
  18. # Software is furnished to do so, subject to the following conditions:
  19. #
  20. # The above copyright notice and this permission notice shall be included
  21. # in all copies or substantial portions of the Software.
  22. #
  23. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  24. # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  25. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  26. # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  27. # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  28. # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  29. # OTHER DEALINGS IN THE SOFTWARE.
  30. #
  31. #---------------------------------------------
  32. manualpage()
  33. {
  34. cat << _MANUALPAGE
  35. Name
  36. xdg-screensaver -- command line tool for controlling the
  37. screensaver
  38. Synopsis
  39. xdg-screensaver suspend WindowID
  40. xdg-screensaver resume WindowID
  41. xdg-screensaver { activate | lock | reset | status }
  42. xdg-screensaver { --help | --manual | --version }
  43. Description
  44. xdg-screensaver provides commands to control the screensaver.
  45. xdg-screensaver is for use inside a desktop session only. It is
  46. not recommended to use xdg-screensaver as root.
  47. Commands
  48. suspend WindowID
  49. Suspends the screensaver and monitor power management.
  50. WindowID must be the X Window ID of an existing window
  51. of the calling application. The window must remain in
  52. existence for the duration of the suspension.
  53. WindowID can be represented as either a decimal number
  54. or as a hexadecimal number consisting of the prefix 0x
  55. followed by one or more hexadecimal digits.
  56. The screensaver can be suspended in relation to multiple
  57. windows at the same time. In that case screensaver
  58. operation is only restored once the screensaver has been
  59. resumed in relation to each of the windows
  60. resume WindowID
  61. Resume the screensaver and monitor power management
  62. after being suspended. WindowID must be the same X
  63. Window ID that was passed to a previous call of
  64. xdg-screensaver suspend
  65. activate
  66. Turns the screensaver on immediately. This may result in
  67. the screen getting locked, depending on existing system
  68. policies.
  69. lock
  70. Lock the screen immediately.
  71. reset
  72. Turns the screensaver off immediately. If the screen was
  73. locked the user may be asked to authenticate first.
  74. status
  75. Prints enabled to stdout if the screensaver is enabled
  76. to turn on after a period of inactivity and prints
  77. disabled if the screensaver is not enabled.
  78. Options
  79. --help
  80. Show command synopsis.
  81. --manual
  82. Show this manual page.
  83. --version
  84. Show the xdg-utils version information.
  85. Exit Codes
  86. An exit code of 0 indicates success while a non-zero exit code
  87. indicates failure. The following failure codes can be returned:
  88. 1
  89. Error in command line syntax.
  90. 3
  91. A required tool could not be found.
  92. 4
  93. The action failed.
  94. Examples
  95. xdg-screensaver suspend 0x1c00007
  96. Causes the screensaver to be disabled till xdg-screensaver
  97. resume 0x1c00007 is called. 0x1c00007 must be the X Window ID
  98. of an existing window.
  99. _MANUALPAGE
  100. }
  101. usage()
  102. {
  103. cat << _USAGE
  104. xdg-screensaver -- command line tool for controlling the
  105. screensaver
  106. Synopsis
  107. xdg-screensaver suspend WindowID
  108. xdg-screensaver resume WindowID
  109. xdg-screensaver { activate | lock | reset | status }
  110. xdg-screensaver { --help | --manual | --version }
  111. _USAGE
  112. }
  113. #@xdg-utils-common@
  114. #----------------------------------------------------------------------------
  115. # Common utility functions included in all XDG wrapper scripts
  116. #----------------------------------------------------------------------------
  117. DEBUG()
  118. {
  119. [ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && return 0;
  120. [ ${XDG_UTILS_DEBUG_LEVEL} -lt $1 ] && return 0;
  121. shift
  122. echo "$@" >&2
  123. }
  124. # This handles backslashes but not quote marks.
  125. first_word()
  126. {
  127. read first rest
  128. echo "$first"
  129. }
  130. #-------------------------------------------------------------
  131. # map a binary to a .desktop file
  132. binary_to_desktop_file()
  133. {
  134. search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
  135. binary="`which "$1"`"
  136. binary="`readlink -f "$binary"`"
  137. base="`basename "$binary"`"
  138. IFS=:
  139. for dir in $search; do
  140. unset IFS
  141. [ "$dir" ] || continue
  142. [ -d "$dir/applications" ] || [ -d "$dir/applnk" ] || continue
  143. for file in "$dir"/applications/*.desktop "$dir"/applications/*/*.desktop "$dir"/applnk/*.desktop "$dir"/applnk/*/*.desktop; do
  144. [ -r "$file" ] || continue
  145. # Check to make sure it's worth the processing.
  146. grep -q "^Exec.*$base" "$file" || continue
  147. # Make sure it's a visible desktop file (e.g. not "preferred-web-browser.desktop").
  148. grep -Eq "^(NoDisplay|Hidden)=true" "$file" && continue
  149. command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`"
  150. command="`which "$command"`"
  151. if [ x"`readlink -f "$command"`" = x"$binary" ]; then
  152. # Fix any double slashes that got added path composition
  153. echo "$file" | sed -e 's,//*,/,g'
  154. return
  155. fi
  156. done
  157. done
  158. }
  159. #-------------------------------------------------------------
  160. # map a .desktop file to a binary
  161. desktop_file_to_binary()
  162. {
  163. search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
  164. desktop="`basename "$1"`"
  165. IFS=:
  166. for dir in $search; do
  167. unset IFS
  168. [ "$dir" ] && [ -d "$dir/applications" ] || [ -d "$dir/applnk" ] || continue
  169. # Check if desktop file contains -
  170. if [ "${desktop#*-}" != "$desktop" ]; then
  171. vendor=${desktop%-*}
  172. app=${desktop#*-}
  173. if [ -r $dir/applications/$vendor/$app ]; then
  174. file_path=$dir/applications/$vendor/$app
  175. elif [ -r $dir/applnk/$vendor/$app ]; then
  176. file_path=$dir/applnk/$vendor/$app
  177. fi
  178. fi
  179. if test -z "$file_path" ; then
  180. for indir in "$dir"/applications/ "$dir"/applications/*/ "$dir"/applnk/ "$dir"/applnk/*/; do
  181. file="$indir/$desktop"
  182. if [ -r "$file" ]; then
  183. file_path=$file
  184. break
  185. fi
  186. done
  187. fi
  188. if [ -r "$file_path" ]; then
  189. # Remove any arguments (%F, %f, %U, %u, etc.).
  190. command="`grep -E "^Exec(\[[^]=]*])?=" "$file_path" | cut -d= -f 2- | first_word`"
  191. command="`which "$command"`"
  192. readlink -f "$command"
  193. return
  194. fi
  195. done
  196. }
  197. #-------------------------------------------------------------
  198. # Exit script on successfully completing the desired operation
  199. exit_success()
  200. {
  201. if [ $# -gt 0 ]; then
  202. echo "$@"
  203. echo
  204. fi
  205. exit 0
  206. }
  207. #-----------------------------------------
  208. # Exit script on malformed arguments, not enough arguments
  209. # or missing required option.
  210. # prints usage information
  211. exit_failure_syntax()
  212. {
  213. if [ $# -gt 0 ]; then
  214. echo "xdg-screensaver: $@" >&2
  215. echo "Try 'xdg-screensaver --help' for more information." >&2
  216. else
  217. usage
  218. echo "Use 'man xdg-screensaver' or 'xdg-screensaver --manual' for additional info."
  219. fi
  220. exit 1
  221. }
  222. #-------------------------------------------------------------
  223. # Exit script on missing file specified on command line
  224. exit_failure_file_missing()
  225. {
  226. if [ $# -gt 0 ]; then
  227. echo "xdg-screensaver: $@" >&2
  228. fi
  229. exit 2
  230. }
  231. #-------------------------------------------------------------
  232. # Exit script on failure to locate necessary tool applications
  233. exit_failure_operation_impossible()
  234. {
  235. if [ $# -gt 0 ]; then
  236. echo "xdg-screensaver: $@" >&2
  237. fi
  238. exit 3
  239. }
  240. #-------------------------------------------------------------
  241. # Exit script on failure returned by a tool application
  242. exit_failure_operation_failed()
  243. {
  244. if [ $# -gt 0 ]; then
  245. echo "xdg-screensaver: $@" >&2
  246. fi
  247. exit 4
  248. }
  249. #------------------------------------------------------------
  250. # Exit script on insufficient permission to read a specified file
  251. exit_failure_file_permission_read()
  252. {
  253. if [ $# -gt 0 ]; then
  254. echo "xdg-screensaver: $@" >&2
  255. fi
  256. exit 5
  257. }
  258. #------------------------------------------------------------
  259. # Exit script on insufficient permission to write a specified file
  260. exit_failure_file_permission_write()
  261. {
  262. if [ $# -gt 0 ]; then
  263. echo "xdg-screensaver: $@" >&2
  264. fi
  265. exit 6
  266. }
  267. check_input_file()
  268. {
  269. if [ ! -e "$1" ]; then
  270. exit_failure_file_missing "file '$1' does not exist"
  271. fi
  272. if [ ! -r "$1" ]; then
  273. exit_failure_file_permission_read "no permission to read file '$1'"
  274. fi
  275. }
  276. check_vendor_prefix()
  277. {
  278. file_label="$2"
  279. [ -n "$file_label" ] || file_label="filename"
  280. file=`basename "$1"`
  281. case "$file" in
  282. [[:alpha:]]*-*)
  283. return
  284. ;;
  285. esac
  286. echo "xdg-screensaver: $file_label '$file' does not have a proper vendor prefix" >&2
  287. echo 'A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated' >&2
  288. echo 'with a dash ("-"). An example '"$file_label"' is '"'example-$file'" >&2
  289. echo "Use --novendor to override or 'xdg-screensaver --manual' for additional info." >&2
  290. exit 1
  291. }
  292. check_output_file()
  293. {
  294. # if the file exists, check if it is writeable
  295. # if it does not exists, check if we are allowed to write on the directory
  296. if [ -e "$1" ]; then
  297. if [ ! -w "$1" ]; then
  298. exit_failure_file_permission_write "no permission to write to file '$1'"
  299. fi
  300. else
  301. DIR=`dirname "$1"`
  302. if [ ! -w "$DIR" ] || [ ! -x "$DIR" ]; then
  303. exit_failure_file_permission_write "no permission to create file '$1'"
  304. fi
  305. fi
  306. }
  307. #----------------------------------------
  308. # Checks for shared commands, e.g. --help
  309. check_common_commands()
  310. {
  311. while [ $# -gt 0 ] ; do
  312. parm="$1"
  313. shift
  314. case "$parm" in
  315. --help)
  316. usage
  317. echo "Use 'man xdg-screensaver' or 'xdg-screensaver --manual' for additional info."
  318. exit_success
  319. ;;
  320. --manual)
  321. manualpage
  322. exit_success
  323. ;;
  324. --version)
  325. echo "xdg-screensaver 1.1.3"
  326. exit_success
  327. ;;
  328. esac
  329. done
  330. }
  331. check_common_commands "$@"
  332. [ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && unset XDG_UTILS_DEBUG_LEVEL;
  333. if [ ${XDG_UTILS_DEBUG_LEVEL-0} -lt 1 ]; then
  334. # Be silent
  335. xdg_redirect_output=" > /dev/null 2> /dev/null"
  336. else
  337. # All output to stderr
  338. xdg_redirect_output=" >&2"
  339. fi
  340. #--------------------------------------
  341. # Checks for known desktop environments
  342. # set variable DE to the desktop environments name, lowercase
  343. detectDE()
  344. {
  345. # see https://bugs.freedesktop.org/show_bug.cgi?id=34164
  346. unset GREP_OPTIONS
  347. if [ -n "${XDG_CURRENT_DESKTOP}" ]; then
  348. case "${XDG_CURRENT_DESKTOP}" in
  349. # only recently added to menu-spec, pre-spec X- still in use
  350. Cinnamon|X-Cinnamon)
  351. DE=cinnamon;
  352. ;;
  353. ENLIGHTENMENT)
  354. DE=enlightenment;
  355. ;;
  356. # GNOME, GNOME-Classic:GNOME, or GNOME-Flashback:GNOME
  357. GNOME*)
  358. DE=gnome;
  359. ;;
  360. KDE)
  361. DE=kde;
  362. ;;
  363. # Deepin Desktop Environments
  364. DEEPIN|Deepin|deepin)
  365. DE=dde;
  366. ;;
  367. LXDE)
  368. DE=lxde;
  369. ;;
  370. LXQt)
  371. DE=lxqt;
  372. ;;
  373. MATE)
  374. DE=mate;
  375. ;;
  376. XFCE)
  377. DE=xfce
  378. ;;
  379. X-Generic)
  380. DE=generic
  381. ;;
  382. esac
  383. fi
  384. if [ x"$DE" = x"" ]; then
  385. # classic fallbacks
  386. if [ x"$KDE_FULL_SESSION" != x"" ]; then DE=kde;
  387. elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome;
  388. elif [ x"$MATE_DESKTOP_SESSION_ID" != x"" ]; then DE=mate;
  389. elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome;
  390. elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce;
  391. elif xprop -root 2> /dev/null | grep -i '^xfce_desktop_window' >/dev/null 2>&1; then DE=xfce
  392. elif echo $DESKTOP | grep -q '^Enlightenment'; then DE=enlightenment;
  393. elif [ x"$LXQT_SESSION_CONFIG" != x"" ]; then DE=lxqt;
  394. fi
  395. fi
  396. if [ x"$DE" = x"" ]; then
  397. # fallback to checking $DESKTOP_SESSION
  398. case "$DESKTOP_SESSION" in
  399. gnome)
  400. DE=gnome;
  401. ;;
  402. LXDE|Lubuntu)
  403. DE=lxde;
  404. ;;
  405. MATE)
  406. DE=mate;
  407. ;;
  408. xfce|xfce4|'Xfce Session')
  409. DE=xfce;
  410. ;;
  411. esac
  412. fi
  413. if [ x"$DE" = x"" ]; then
  414. # fallback to uname output for other platforms
  415. case "$(uname 2>/dev/null)" in
  416. CYGWIN*)
  417. DE=cygwin;
  418. ;;
  419. Darwin)
  420. DE=darwin;
  421. ;;
  422. esac
  423. fi
  424. if [ x"$DE" = x"gnome" ]; then
  425. # gnome-default-applications-properties is only available in GNOME 2.x
  426. # but not in GNOME 3.x
  427. which gnome-default-applications-properties > /dev/null 2>&1 || DE="gnome3"
  428. fi
  429. if [ -f "$XDG_RUNTIME_DIR/flatpak-info" ]; then
  430. DE="flatpak"
  431. fi
  432. }
  433. #----------------------------------------------------------------------------
  434. # kfmclient exec/openURL can give bogus exit value in KDE <= 3.5.4
  435. # It also always returns 1 in KDE 3.4 and earlier
  436. # Simply return 0 in such case
  437. kfmclient_fix_exit_code()
  438. {
  439. version=`LC_ALL=C.UTF-8 kde-config --version 2>/dev/null | grep '^KDE'`
  440. major=`echo $version | sed 's/KDE.*: \([0-9]\).*/\1/'`
  441. minor=`echo $version | sed 's/KDE.*: [0-9]*\.\([0-9]\).*/\1/'`
  442. release=`echo $version | sed 's/KDE.*: [0-9]*\.[0-9]*\.\([0-9]\).*/\1/'`
  443. test "$major" -gt 3 && return $1
  444. test "$minor" -gt 5 && return $1
  445. test "$release" -gt 4 && return $1
  446. return 0
  447. }
  448. #----------------------------------------------------------------------------
  449. # Returns true if there is a graphical display attached.
  450. has_display()
  451. {
  452. if [ -n "$DISPLAY" ] || [ -n "$WAYLAND_DISPLAY" ]; then
  453. return 0
  454. else
  455. return 1
  456. fi
  457. }
  458. # Check if we can use "mv -T"
  459. if mv -T ... ... 2>&1 | grep '\.\.\.' > /dev/null ; then
  460. # We can securely move files in /tmp with mv -T
  461. DEBUG 1 "mv -T available"
  462. MV="mv -T"
  463. screensaver_file="/tmp/xdg-screensaver-$USER-"`echo $DISPLAY | sed 's/:/-/g'`
  464. else
  465. # No secure moves available, use home dir
  466. DEBUG 1 "mv -T not available"
  467. MV="mv"
  468. screensaver_file="$HOME/.xdg-screensaver-"`echo $(hostname)-$DISPLAY | sed 's/:/-/g'`
  469. fi
  470. lockfile_command=`which lockfile 2> /dev/null`
  471. lockfile()
  472. {
  473. if [ -n "$lockfile_command" ] ; then
  474. $lockfile_command -1 -l 10 -s 3 "$screensaver_file".lock
  475. else
  476. # Poor man's attempt at doing a lockfile
  477. # Be careful not to facilitate a symlink attack
  478. local try
  479. try=0
  480. while ! ln -s "$screensaver_file".lock "$screensaver_file".lock 2> /dev/null;
  481. do
  482. sleep 1
  483. try=$(($try+1))
  484. if [ $try -eq 3 ] ; then
  485. rm -f "$screensaver_file".lock || return # Can't remove lockfile
  486. try=0
  487. fi
  488. done
  489. fi
  490. }
  491. unlockfile()
  492. {
  493. rm -f "$screensaver_file".lock
  494. }
  495. perform_action()
  496. {
  497. result=1
  498. if [ "$1" = "resume" ] ; then
  499. # Restore DPMS state
  500. if [ -f "$screensaver_file.dpms" ]; then
  501. rm "$screensaver_file.dpms"
  502. # Re-enable DPMS
  503. xset +dpms
  504. fi
  505. fi
  506. if [ "$1" = "reset" ] ; then
  507. if xset -q | grep 'DPMS is Enabled' > /dev/null 2> /dev/null; then
  508. xset -dpms
  509. xset +dpms
  510. xset dpms force on
  511. fi
  512. fi
  513. case "$DE" in
  514. kde)
  515. if [ -n "${KDE_SESSION_VERSION}" ]; then
  516. screensaver_freedesktop "$1"
  517. else
  518. screensaver_kde3 "$1"
  519. fi
  520. ;;
  521. gnome_screensaver)
  522. screensaver_gnome_screensaver "$1"
  523. ;;
  524. mate_screensaver)
  525. screensaver_mate_screensaver "$1"
  526. ;;
  527. cinnamon)
  528. screensaver_cinnamon_screensaver "$1"
  529. ;;
  530. xscreensaver)
  531. screensaver_xscreensaver "$1"
  532. ;;
  533. xautolock_screensaver)
  534. xautolock_screensaver "$1"
  535. ;;
  536. xfce)
  537. [ -n "$DISPLAY" ] && screensaver_xserver "$1"
  538. ;;
  539. ''|generic)
  540. [ -n "$DISPLAY" ] && screensaver_xserver "$1"
  541. ;;
  542. esac
  543. if [ -n "$DISPLAY" -a "$1" = "suspend" ] ; then
  544. # Save DPMS state
  545. if xset -q | grep 'DPMS is Enabled' > /dev/null 2> /dev/null; then
  546. test "${TMPDIR+set}" = set || TMPDIR=/tmp
  547. tmpfile=`mktemp $TMPDIR/tmp.XXXXXXXXXX`
  548. $MV "$tmpfile" "$screensaver_file.dpms"
  549. # Disable DPMS
  550. xset -dpms
  551. fi
  552. fi
  553. }
  554. cleanup_suspend()
  555. {
  556. lockfile
  557. test "${TMPDIR+set}" = set || TMPDIR=/tmp
  558. tmpfile=`mktemp $TMPDIR/tmp.XXXXXXXXXX`
  559. grep -v "$window_id:$xprop_pid\$" "$screensaver_file" > "$tmpfile" 2> /dev/null
  560. $MV "$tmpfile" "$screensaver_file"
  561. if [ ! -s "$screensaver_file" ] ; then
  562. rm "$screensaver_file"
  563. unlockfile
  564. # $screensaver_file is empty, do resume
  565. perform_action resume
  566. else
  567. unlockfile
  568. fi
  569. }
  570. do_resume()
  571. {
  572. lockfile # Obtain lockfile
  573. # Find the PID of the trackingprocess
  574. xprop_pid=`grep "$window_id:" "$screensaver_file" 2> /dev/null | cut -d ':' -f 2`
  575. unlockfile # Free lockfile
  576. if [ -n "$xprop_pid" ] && ps -p "$xprop_pid" 2> /dev/null | grep xprop > /dev/null; then
  577. # Kill the tracking process
  578. kill -s TERM $xprop_pid
  579. fi
  580. cleanup_suspend
  581. }
  582. XPROP=`which xprop 2> /dev/null`
  583. check_window_id()
  584. {
  585. if [ -z "$XPROP" ]; then
  586. DEBUG 3 "xprop not found"
  587. return
  588. fi
  589. DEBUG 2 "Running $XPROP -id $window_id"
  590. if $XPROP -id $window_id > /dev/null 2> /dev/null; then
  591. DEBUG 3 Window $window_id exists
  592. else
  593. DEBUG 3 Window $window_id does not exist
  594. exit_failure_operation_failed "Window $window_id does not exist"
  595. fi
  596. }
  597. track_window()
  598. {
  599. if [ -z "$XPROP" ]; then
  600. # Don't track window if we don't have xprop
  601. return
  602. fi
  603. lockfile
  604. test "${TMPDIR+set}" = set || TMPDIR=/tmp
  605. tmpfile=`mktemp $TMPDIR/tmp.XXXXXXXXXX`
  606. # Filter stale entries from the xdg-screensaver status file
  607. # Return if $window_id is being tracked already
  608. (
  609. already_tracked=1
  610. IFS_save="$IFS"
  611. IFS=":"
  612. while read wid pid; do
  613. if ps -p "$pid" 2> /dev/null | grep xprop > /dev/null; then
  614. echo "$wid:$pid"
  615. if [ $wid = $window_id ] ; then
  616. already_tracked=0
  617. fi
  618. fi
  619. done
  620. IFS="$IFS_save"
  621. exit $already_tracked
  622. ) < $screensaver_file > $tmpfile
  623. already_tracked=$?
  624. if [ "$already_tracked" -eq "0" ] ; then
  625. $MV "$tmpfile" "$screensaver_file"
  626. # We are already tracking $window_id, don't do anything
  627. unlockfile
  628. return
  629. fi
  630. # Start tracking $window_id
  631. $XPROP -id $window_id -spy > /dev/null &
  632. xprop_pid=$!
  633. # Add window_id and xprop_pid to the xdg-screensave status file
  634. echo "$window_id:$xprop_pid" >> $tmpfile
  635. $MV "$tmpfile" "$screensaver_file"
  636. unlockfile
  637. # Wait for xprop to exit, it means that the window disappeared
  638. wait $xprop_pid
  639. # Clean up the administration and resume the screensaver
  640. cleanup_suspend
  641. }
  642. screensaver_freedesktop()
  643. {
  644. case "$1" in
  645. suspend)
  646. dbus-send --session \
  647. --dest=org.freedesktop.ScreenSaver \
  648. --type=method_call \
  649. --print-reply \
  650. --reply-timeout=2000 \
  651. /ScreenSaver \
  652. org.freedesktop.ScreenSaver.Inhibit \
  653. string:$window_id \
  654. string:xdg-screensaver \
  655. | grep uint32 | cut -d ' ' -f 5 >| "$screensaver_file.cookie" \
  656. 2> /dev/null
  657. result=$?
  658. ;;
  659. resume)
  660. if [ -f "$screensaver_file.cookie" ] ; then
  661. value=`cat "$screensaver_file.cookie"`
  662. dbus-send --session \
  663. --dest=org.freedesktop.ScreenSaver \
  664. --type=method_call \
  665. /ScreenSaver \
  666. org.freedesktop.ScreenSaver.UnInhibit \
  667. uint32:$value \
  668. 2> /dev/null
  669. rm -f "$screensaver_file.cookie"
  670. fi
  671. result=$?
  672. ;;
  673. activate)
  674. dbus-send --session \
  675. --dest=org.freedesktop.ScreenSaver \
  676. --type=method_call \
  677. /ScreenSaver \
  678. org.freedesktop.ScreenSaver.SetActive \
  679. boolean:true \
  680. 2> /dev/null
  681. result=$?
  682. ;;
  683. lock)
  684. dbus-send --session \
  685. --dest=org.freedesktop.ScreenSaver \
  686. --type=method_call \
  687. /ScreenSaver \
  688. org.freedesktop.ScreenSaver.Lock \
  689. 2> /dev/null
  690. ;;
  691. reset)
  692. if [ -f "$screensaver_file.cookie" ] ; then
  693. value=`cat "$screensaver_file.cookie"`
  694. dbus-send --session \
  695. --dest=org.freedesktop.ScreenSaver \
  696. --type=method_call \
  697. /ScreenSaver \
  698. org.freedesktop.ScreenSaver.UnInhibit \
  699. uint32:$value \
  700. 2> /dev/null
  701. rm -f "$screensaver_file.cookie"
  702. fi
  703. result=$?
  704. ;;
  705. status)
  706. status=`dbus-send --session \
  707. --dest=org.freedesktop.ScreenSaver \
  708. --type=method_call \
  709. --print-reply \
  710. --reply-timeout=2000 \
  711. /ScreenSaver \
  712. org.freedesktop.ScreenSaver.GetActive \
  713. | grep boolean | cut -d ' ' -f 5`
  714. result=$?
  715. if [ x"$status" = "xtrue" -o x"$status" = "xfalse" ]; then
  716. echo "enabled"
  717. elif [ x"$result" != "x0" ]; then
  718. echo "ERROR: dbus org.freedesktop.ScreenSaver.GetActive returned '$status'" >&2
  719. return 1
  720. else
  721. echo "disabled"
  722. fi
  723. ;;
  724. *)
  725. echo "ERROR: Unknown command '$1'" >&2
  726. return 1
  727. ;;
  728. esac
  729. }
  730. screensaver_kde3()
  731. {
  732. case "$1" in
  733. suspend)
  734. dcop kdesktop KScreensaverIface enable false > /dev/null
  735. result=$?
  736. ;;
  737. resume)
  738. dcop kdesktop KScreensaverIface configure > /dev/null
  739. result=$?
  740. ;;
  741. activate)
  742. dcop kdesktop KScreensaverIface save > /dev/null
  743. result=$?
  744. ;;
  745. lock)
  746. dcop kdesktop KScreensaverIface lock > /dev/null
  747. result=$?
  748. ;;
  749. reset)
  750. # Turns the screensaver off right now
  751. dcop kdesktop KScreensaverIface quit > /dev/null
  752. result=$?
  753. ;;
  754. status)
  755. status=`dcop kdesktop KScreensaverIface isEnabled`
  756. result=$?
  757. if [ x"$status" = "xtrue" ]; then
  758. echo "enabled"
  759. elif [ x"$status" = "xfalse" ]; then
  760. echo "disabled"
  761. else
  762. echo "ERROR: kdesktop KScreensaverIface isEnabled returned '$status'" >&2
  763. return 1
  764. fi
  765. ;;
  766. *)
  767. echo "ERROR: Unknown command '$1'" >&2
  768. return 1
  769. ;;
  770. esac
  771. }
  772. xset_screensaver_timeout()
  773. {
  774. xset q | sed '/^Screen Saver:/,/^[^ ]/ { s/.*timeout: *\([0-9]*\).*/\1/; t }; d'
  775. }
  776. screensaver_xserver()
  777. {
  778. case "$1" in
  779. suspend)
  780. timeout=`xset_screensaver_timeout`
  781. if [ "$timeout" -gt 0 ]; then
  782. echo "$timeout" > "$screensaver_file.xset"
  783. xset s off > /dev/null
  784. fi
  785. result=$?
  786. ;;
  787. resume)
  788. if [ -f "$screensaver_file.xset" ] ; then
  789. value=`cat "$screensaver_file.xset"`
  790. xset s $value > /dev/null
  791. rm -f "$screensaver_file.xset"
  792. fi
  793. result=$?
  794. ;;
  795. activate)
  796. xset s activate > /dev/null
  797. result=$?
  798. ;;
  799. reset)
  800. xset s reset > /dev/null
  801. result=$?
  802. ;;
  803. status)
  804. timeout=`xset_screensaver_timeout`
  805. result=$?
  806. if [ "$timeout" -gt 0 ]; then
  807. echo "enabled"
  808. elif [ "$timeout" -eq 0 ]; then
  809. echo "disabled"
  810. else
  811. echo "ERROR: xset q did not report the screensaver timeout" >&2
  812. return 1
  813. fi
  814. ;;
  815. *)
  816. echo "ERROR: Unknown command '$1'" >&2
  817. return 1
  818. ;;
  819. esac
  820. }
  821. screensaver_suspend_loop()
  822. {
  823. lockfile
  824. test "${TMPDIR+set}" = set || TMPDIR=/tmp
  825. tmpfile=`mktemp $TMPDIR/tmp.XXXXXXXXXX`
  826. # Filter stale entries from the xdg-screensaver status file
  827. cat "$screensaver_file" 2> /dev/null | (
  828. IFS_save="$IFS"
  829. IFS=":"
  830. while read wid pid; do
  831. if ps -p "$pid" 2> /dev/null | grep xprop > /dev/null; then
  832. echo "$wid:$pid"
  833. fi
  834. done
  835. IFS="$IFS_save"
  836. ) > $tmpfile
  837. if [ -s "$tmpfile" ] ; then
  838. # Suspend pending, don't do a thing
  839. $MV "$tmpfile" "$screensaver_file"
  840. unlockfile
  841. return
  842. fi
  843. $MV "$tmpfile" "$screensaver_file"
  844. unlockfile
  845. (while [ -f "$screensaver_file" ]; do $*; sleep 50; done) > /dev/null 2> /dev/null &
  846. }
  847. screensaver_gnome_screensaver()
  848. {
  849. # DBUS interface for gnome-screensaver
  850. # http://people.gnome.org/~mccann/gnome-screensaver/docs/gnome-screensaver.html
  851. case "$1" in
  852. suspend)
  853. perl -e '
  854. use strict;
  855. use warnings;
  856. use IO::File;
  857. use Net::DBus;
  858. use X11::Protocol;
  859. my ($window_id, $screensaver_file) = @ARGV;
  860. # Find window name to pass to session manager.
  861. my $x = X11::Protocol->new();
  862. my $named_window_id = hex($window_id);
  863. my $window_name;
  864. while (1) {
  865. ($window_name) = $x->GetProperty($named_window_id, $x->atom("WM_NAME"),
  866. $x->atom("STRING"), 0, 1000, 0);
  867. last if defined($window_name) && $window_name ne "";
  868. (undef, $named_window_id) = $x->QueryTree($named_window_id);
  869. if (!defined($named_window_id)) {
  870. $window_name = "?";
  871. last;
  872. }
  873. }
  874. # Inhibit idle detection (flags = 8) with window name and ID.
  875. # We have no reason so just send the window name again.
  876. my $bus = Net::DBus->session();
  877. my $sm_svc = $bus->get_service("org.gnome.SessionManager");
  878. my $sm = $sm_svc->get_object("/org/gnome/SessionManager",
  879. "org.gnome.SessionManager");
  880. $sm->Inhibit($window_name, hex($window_id), $window_name, 8);
  881. # Wait until removed from the status file.
  882. while (1) {
  883. sleep(10);
  884. my $status = new IO::File($screensaver_file, "r")
  885. or exit 0;
  886. my $found;
  887. while (<$status>) {
  888. if (/^$window_id:/) {
  889. $found = 1;
  890. last;
  891. }
  892. }
  893. exit 0 unless $found;
  894. }
  895. ' $window_id $screensaver_file &
  896. result=0
  897. ;;
  898. resume)
  899. # Automatic resume when $screensaver_file disappears
  900. result=0
  901. ;;
  902. activate)
  903. dbus-send --session \
  904. --dest=org.gnome.ScreenSaver \
  905. --type=method_call \
  906. /org/gnome/ScreenSaver \
  907. org.gnome.ScreenSaver.SetActive \
  908. boolean:true \
  909. 2> /dev/null
  910. result=$?
  911. ;;
  912. lock)
  913. dbus-send --session \
  914. --dest=org.gnome.ScreenSaver \
  915. --type=method_call \
  916. /org/gnome/ScreenSaver \
  917. org.gnome.ScreenSaver.Lock \
  918. 2> /dev/null
  919. result=$?
  920. ;;
  921. reset)
  922. # Turns the screensaver off right now
  923. dbus-send --session \
  924. --dest=org.gnome.ScreenSaver \
  925. --type=method_call \
  926. /org/gnome/ScreenSaver \
  927. org.gnome.ScreenSaver.SimulateUserActivity \
  928. 2> /dev/null
  929. result=$?
  930. ;;
  931. status)
  932. status=`dbus-send --session \
  933. --dest=org.gnome.ScreenSaver \
  934. --type=method_call \
  935. --print-reply \
  936. --reply-timeout=2000 \
  937. /org/gnome/ScreenSaver \
  938. org.gnome.ScreenSaver.GetActive \
  939. | grep boolean | cut -d ' ' -f 5`
  940. result=$?
  941. if [ x"$status" = "xtrue" -o x"$status" = "xfalse" ]; then
  942. echo "enabled"
  943. elif [ x"$result" != "x0" ]; then
  944. echo "ERROR: dbus org.gnome.ScreenSaver.GetActive returned '$status'" >&2
  945. return 1
  946. else
  947. echo "disabled"
  948. fi
  949. ;;
  950. *)
  951. echo "ERROR: Unknown command '$1" >&2
  952. return 1
  953. ;;
  954. esac
  955. }
  956. screensaver_mate_screensaver()
  957. {
  958. # DBUS interface for mate-screensaver
  959. # This is same as gnome's for now but may change in the future as MATE
  960. # does not follow gnome's development necessarily.
  961. case "$1" in
  962. suspend)
  963. screensaver_suspend_loop \
  964. dbus-send --session \
  965. --dest=org.mate.ScreenSaver \
  966. --type=method_call \
  967. /org/mate/ScreenSaver \
  968. org.mate.ScreenSaver.SimulateUserActivity \
  969. 2> /dev/null
  970. result=$?
  971. ;;
  972. resume)
  973. # Automatic resume when $screensaver_file disappears
  974. result=0
  975. ;;
  976. activate)
  977. dbus-send --session \
  978. --dest=org.mate.ScreenSaver \
  979. --type=method_call \
  980. /org/mate/ScreenSaver \
  981. org.mate.ScreenSaver.SetActive \
  982. boolean:true \
  983. 2> /dev/null
  984. result=$?
  985. ;;
  986. lock)
  987. mate-screensaver-command --lock > /dev/null 2> /dev/null
  988. result=$?
  989. ;;
  990. reset)
  991. # Turns the screensaver off right now
  992. dbus-send --session \
  993. --dest=org.mate.ScreenSaver \
  994. --type=method_call \
  995. /org/mate/ScreenSaver \
  996. org.mate.ScreenSaver.SimulateUserActivity \
  997. 2> /dev/null
  998. result=$?
  999. ;;
  1000. status)
  1001. status=`dbus-send --session \
  1002. --dest=org.mate.ScreenSaver \
  1003. --type=method_call \
  1004. --print-reply \
  1005. --reply-timeout=2000 \
  1006. /org/mate/ScreenSaver \
  1007. org.mate.ScreenSaver.GetActive \
  1008. | grep boolean | cut -d ' ' -f 5`
  1009. result=$?
  1010. if [ x"$status" = "xtrue" -o x"$status" = "xfalse" ]; then
  1011. echo "enabled"
  1012. elif [ x"$result" != "x0" ]; then
  1013. echo "ERROR: dbus org.mate.ScreenSaver.GetActive returned '$status'" >&2
  1014. return 1
  1015. else
  1016. echo "disabled"
  1017. fi
  1018. ;;
  1019. *)
  1020. echo "ERROR: Unknown command '$1" >&2
  1021. return 1
  1022. ;;
  1023. esac
  1024. }
  1025. screensaver_cinnamon_screensaver()
  1026. {
  1027. # DBUS interface for cinnamon-screensaver
  1028. # https://raw.githubusercontent.com/linuxmint/cinnamon-screensaver/master/doc/dbus-interface.html
  1029. case "$1" in
  1030. suspend)
  1031. screensaver_suspend_loop \
  1032. dbus-send --session \
  1033. --dest=org.cinnamon.ScreenSaver \
  1034. --type=method_call \
  1035. /org/cinnamon/ScreenSaver \
  1036. org.cinnamon.ScreenSaver.SimulateUserActivity \
  1037. 2> /dev/null
  1038. result=$?
  1039. ;;
  1040. resume)
  1041. # Automatic resume when $screensaver_file disappears
  1042. result=0
  1043. ;;
  1044. activate)
  1045. dbus-send --session \
  1046. --dest=org.cinnamon.ScreenSaver \
  1047. --type=method_call \
  1048. /org/cinnamon/ScreenSaver \
  1049. org.cinnamon.ScreenSaver.SetActive \
  1050. boolean:true \
  1051. 2> /dev/null
  1052. result=$?
  1053. ;;
  1054. lock)
  1055. dbus-send --session \
  1056. --dest=org.cinnamon.ScreenSaver \
  1057. --type=method_call \
  1058. /org/cinnamon/ScreenSaver \
  1059. org.cinnamon.ScreenSaver.Lock \
  1060. string:"" \
  1061. 2> /dev/null
  1062. result=$?
  1063. ;;
  1064. reset)
  1065. # Turns the screensaver off right now
  1066. dbus-send --session \
  1067. --dest=org.cinnamon.ScreenSaver \
  1068. --type=method_call \
  1069. /org/cinnamon/ScreenSaver \
  1070. org.cinnamon.ScreenSaver.SimulateUserActivity \
  1071. 2> /dev/null
  1072. result=$?
  1073. ;;
  1074. status)
  1075. status=`dbus-send --session \
  1076. --dest=org.cinnamon.ScreenSaver \
  1077. --type=method_call \
  1078. --print-reply \
  1079. --reply-timeout=2000 \
  1080. /org/cinnamon/ScreenSaver \
  1081. org.cinnamon.ScreenSaver.GetActive \
  1082. | grep boolean | cut -d ' ' -f 5`
  1083. result=$?
  1084. if [ x"$status" = "xtrue" ]; then
  1085. echo "enabled"
  1086. elif [ x"$status" = "xfalse" ]; then
  1087. echo "disabled"
  1088. else
  1089. echo "ERROR: dbus org.cinnamon.ScreenSaver.GetActive returned '$status'" >&2
  1090. return 1
  1091. fi
  1092. ;;
  1093. *)
  1094. echo "ERROR: Unknown command '$1" >&2
  1095. return 1
  1096. ;;
  1097. esac
  1098. }
  1099. screensaver_xscreensaver()
  1100. {
  1101. case "$1" in
  1102. suspend)
  1103. screensaver_suspend_loop xscreensaver-command -deactivate
  1104. result=0
  1105. ;;
  1106. resume)
  1107. # Automatic resume when $screensaver_file disappears
  1108. result=0
  1109. ;;
  1110. activate)
  1111. xscreensaver-command -activate > /dev/null 2> /dev/null
  1112. result=$?
  1113. ;;
  1114. lock)
  1115. xscreensaver-command -lock > /dev/null 2> /dev/null
  1116. result=$?
  1117. ;;
  1118. reset)
  1119. # Turns the screensaver off right now
  1120. xscreensaver-command -deactivate > /dev/null 2> /dev/null
  1121. result=$?
  1122. ;;
  1123. status)
  1124. result=0
  1125. if [ -f "$screensaver_file" ] ; then
  1126. echo "disabled"
  1127. else
  1128. echo "enabled"
  1129. fi
  1130. ;;
  1131. *)
  1132. echo "ERROR: Unknown command '$1" >&2
  1133. return 1
  1134. ;;
  1135. esac
  1136. }
  1137. xautolock_screensaver()
  1138. {
  1139. case "$1" in
  1140. suspend)
  1141. xset s off && xautolock -disable > /dev/null
  1142. result=$?
  1143. ;;
  1144. resume)
  1145. xset s default && xautolock -enable > /dev/null
  1146. result=$?
  1147. ;;
  1148. activate)
  1149. xautolock -enable
  1150. result=$?
  1151. ;;
  1152. lock)
  1153. xautolock -locknow
  1154. result=$?
  1155. ;;
  1156. reset)
  1157. xautolock -restart
  1158. result=$?
  1159. ;;
  1160. status)
  1161. xautolock -unlocknow >/dev/null
  1162. result=$?
  1163. if [ $result -eq 0 ]; then
  1164. echo "enabled"
  1165. else
  1166. echo "disabled"
  1167. fi
  1168. ;;
  1169. *)
  1170. echo "ERROR: Unknown command '$1" >&2
  1171. return 1
  1172. ;;
  1173. esac
  1174. }
  1175. [ x"$1" != x"" ] || exit_failure_syntax
  1176. action=
  1177. window_id=
  1178. case $1 in
  1179. suspend)
  1180. action="$1"
  1181. shift
  1182. if [ -z "$1" ] ; then
  1183. exit_failure_syntax "WindowID argument missing"
  1184. fi
  1185. window_id="$1"
  1186. check_window_id
  1187. ;;
  1188. resume)
  1189. action="$1"
  1190. shift
  1191. if [ -z "$1" ] ; then
  1192. exit_failure_syntax "WindowID argument missing"
  1193. fi
  1194. window_id="$1"
  1195. check_window_id
  1196. ;;
  1197. activate)
  1198. action="$1"
  1199. ;;
  1200. lock)
  1201. action="$1"
  1202. ;;
  1203. reset)
  1204. action="$1"
  1205. ;;
  1206. status)
  1207. action="$1"
  1208. ;;
  1209. *)
  1210. exit_failure_syntax "unknown command '$1'"
  1211. ;;
  1212. esac
  1213. detectDE
  1214. # Consider "xscreensaver" a separate DE
  1215. xscreensaver-command -version 2> /dev/null | grep XScreenSaver > /dev/null && DE="xscreensaver"
  1216. # Consider "gnome-screensaver" a separate DE
  1217. dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.ScreenSaver > /dev/null 2>&1 && DE="gnome_screensaver"
  1218. # Consider "mate-screensaver" a separate DE
  1219. dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.mate.ScreenSaver > /dev/null 2>&1 && DE="mate_screensaver"
  1220. # Consider "xautolock" a separate DE
  1221. xautolock -enable > /dev/null 2>&1 && DE="xautolock_screensaver"
  1222. if [ "$action" = "resume" ] ; then
  1223. do_resume
  1224. exit_success
  1225. fi
  1226. perform_action "$action"
  1227. if [ "$action" = "suspend" ] ; then
  1228. # Start tracking $window_id and resume the screensaver once it disappears
  1229. ( track_window ) 2> /dev/null > /dev/null &
  1230. fi
  1231. if [ $result -eq 0 ]; then
  1232. exit_success
  1233. else
  1234. exit_failure_operation_failed
  1235. fi