xdg-icon-resource 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055
  1. #!/bin/sh
  2. #---------------------------------------------
  3. # xdg-icon-resource
  4. #
  5. # Utility script to install icons on a Linux desktop.
  6. #
  7. # Refer to the usage() function below for usage.
  8. #
  9. # Copyright 2009-2010, Fathi Boudra <fabo@freedesktop.org>
  10. # Copyright 2009-2010, Rex Dieter <rdieter@fedoraproject.org>
  11. # Copyright 2006, Kevin Krammer <kevin.krammer@gmx.at>
  12. # Copyright 2006, Jeremy White <jwhite@codeweavers.com>
  13. #
  14. # LICENSE:
  15. #
  16. # Permission is hereby granted, free of charge, to any person obtaining a
  17. # copy of this software and associated documentation files (the "Software"),
  18. # to deal in the Software without restriction, including without limitation
  19. # the rights to use, copy, modify, merge, publish, distribute, sublicense,
  20. # and/or sell copies of the Software, and to permit persons to whom the
  21. # Software is furnished to do so, subject to the following conditions:
  22. #
  23. # The above copyright notice and this permission notice shall be included
  24. # in all copies or substantial portions of the Software.
  25. #
  26. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  27. # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  28. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  29. # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  30. # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  31. # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  32. # OTHER DEALINGS IN THE SOFTWARE.
  33. #
  34. #---------------------------------------------
  35. manualpage()
  36. {
  37. cat << _MANUALPAGE
  38. Name
  39. xdg-icon-resource -- command line tool for (un)installing icon
  40. resources
  41. Synopsis
  42. xdg-icon-resource install [--noupdate] [--novendor] [--theme
  43. theme] [--context context] [--mode mode] --size size icon-file
  44. [icon-name]
  45. xdg-icon-resource uninstall [--noupdate] [--theme theme]
  46. [--context context] [--mode mode] --size size icon-name
  47. xdg-icon-resource forceupdate [--theme theme] [--mode mode]
  48. xdg-icon-resource { --help | --manual | --version }
  49. Description
  50. The xdg-icon-resource program can be used to install icon
  51. resources into the desktop icon system in order to illustrate
  52. menu entries, to depict desktop icons or to graphically
  53. represent file types.
  54. The desktop icon system identifies icons by name. Depending on
  55. the required size, the choice of icon theme and the context in
  56. which the icon is used, the desktop icon system locates an
  57. appropriate icon resource to depict an icon. Icon resources can
  58. be XPM files or PNG files.
  59. The desktop icon system works according to the XDG Icon Theme
  60. Specification at
  61. http://www.freedesktop.org/wiki/Specifications/icon-theme-spec
  62. Commands
  63. install
  64. Installs the icon file indicated by icon-file to the
  65. desktop icon system under the name icon-name. Icon names
  66. do not have an extension. If icon-name is not provided
  67. the name is derived from icon-file. The icon file must
  68. have .png or .xpm as extension. If a corresponding .icon
  69. file exists in the same location as icon-file it will be
  70. installed as well.
  71. uninstall
  72. Removes the icon indicated by icon-name from the desktop
  73. icon system. Note that icon names do not have an
  74. extension.
  75. forceupdate
  76. Force an update of the desktop icon system. This is only
  77. useful if the last call to xdg-icon-resource included
  78. the --noupdate option.
  79. Options
  80. --noupdate
  81. Postpone updating the desktop icon system. If multiple
  82. icons are added in sequence this flag can be used to
  83. indicate that additional changes will follow and that it
  84. is not necessary to update the desktop icon system right
  85. away.
  86. --novendor
  87. Normally, xdg-icon-resource checks to ensure that an
  88. icon file to be installed in the apps context has a
  89. proper vendor prefix. This option can be used to disable
  90. that check.
  91. A vendor prefix consists of alpha characters ([a-zA-Z])
  92. and is terminated with a dash ("-"). Companies and
  93. organizations are encouraged to use a word or phrase,
  94. preferably the organizations name, for which they hold a
  95. trademark as their vendor prefix. The purpose of the
  96. vendor prefix is to prevent name conflicts.
  97. --theme theme
  98. Installs or removes the icon file as part of theme. If
  99. no theme is specified the icons will be installed as
  100. part of the default hicolor theme. Applications may
  101. install icons under multiple themes but should at least
  102. install icons for the default hicolor theme.
  103. --context context
  104. Specifies the context for the icon. Icons to be used in
  105. the application menu and as desktop icon should use apps
  106. as context which is the default context. Icons to be
  107. used as file icons should use mimetypes as context.
  108. Other common contexts are actions, devices, emblems,
  109. filesystems and stock.
  110. --size size
  111. Specifies the size of the icon. All icons must be
  112. square. Common sizes for icons in the apps context are:
  113. 16, 22, 32, 48, 64 and 128. Common sizes for icons in
  114. the mimetypes context are: 16, 22, 32, 48, 64 and 128
  115. --mode mode
  116. mode can be user or system. In user mode the file is
  117. (un)installed for the current user only. In system mode
  118. the file is (un)installed for all users on the system.
  119. Usually only root is allowed to install in system mode.
  120. The default is to use system mode when called by root
  121. and to use user mode when called by a non-root user.
  122. --help
  123. Show command synopsis.
  124. --manual
  125. Show this manual page.
  126. --version
  127. Show the xdg-utils version information.
  128. Environment Variables
  129. xdg-icon-resource honours the following environment variables:
  130. XDG_UTILS_DEBUG_LEVEL
  131. Setting this environment variable to a non-zero
  132. numerical value makes xdg-icon-resource do more verbose
  133. reporting on stderr. Setting a higher value increases
  134. the verbosity.
  135. XDG_UTILS_INSTALL_MODE
  136. This environment variable can be used by the user or
  137. administrator to override the installation mode. Valid
  138. values are user and system.
  139. Exit Codes
  140. An exit code of 0 indicates success while a non-zero exit code
  141. indicates failure. The following failure codes can be returned:
  142. 1
  143. Error in command line syntax.
  144. 2
  145. One of the files passed on the command line did not
  146. exist.
  147. 3
  148. A required tool could not be found.
  149. 4
  150. The action failed.
  151. 5
  152. No permission to read one of the files passed on the
  153. command line.
  154. See Also
  155. xdg-desktop-icon(1), xdg-desktop-menu(1), xdg-mime(1), Icon
  156. theme specification
  157. Examples
  158. To install an icon resource to depict a launcher for the
  159. application myfoobar, the company ShinyThings Inc. can use:
  160. xdg-icon-resource install --size 64 shinythings-myfoobar.png
  161. To install an icon for a new application/x-foobar file type one
  162. can use:
  163. xdg-icon-resource install --context mimetypes --size 48 ./mime-foobar-48
  164. .png application-x-foobar
  165. xdg-icon-resource install --context mimetypes --size 64 ./mime-foobar-64
  166. .png application-x-foobar
  167. This will install two icons with the name application-x-foobar
  168. but with different sizes.
  169. _MANUALPAGE
  170. }
  171. usage()
  172. {
  173. cat << _USAGE
  174. xdg-icon-resource -- command line tool for (un)installing icon
  175. resources
  176. Synopsis
  177. xdg-icon-resource install [--noupdate] [--novendor] [--theme
  178. theme] [--context context] [--mode mode] --size size icon-file
  179. [icon-name]
  180. xdg-icon-resource uninstall [--noupdate] [--theme theme]
  181. [--context context] [--mode mode] --size size icon-name
  182. xdg-icon-resource forceupdate [--theme theme] [--mode mode]
  183. xdg-icon-resource { --help | --manual | --version }
  184. _USAGE
  185. }
  186. #@xdg-utils-common@
  187. #----------------------------------------------------------------------------
  188. # Common utility functions included in all XDG wrapper scripts
  189. #----------------------------------------------------------------------------
  190. DEBUG()
  191. {
  192. [ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && return 0;
  193. [ ${XDG_UTILS_DEBUG_LEVEL} -lt $1 ] && return 0;
  194. shift
  195. echo "$@" >&2
  196. }
  197. # This handles backslashes but not quote marks.
  198. first_word()
  199. {
  200. read first rest
  201. echo "$first"
  202. }
  203. #-------------------------------------------------------------
  204. # map a binary to a .desktop file
  205. binary_to_desktop_file()
  206. {
  207. search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
  208. binary="`which "$1"`"
  209. binary="`readlink -f "$binary"`"
  210. base="`basename "$binary"`"
  211. IFS=:
  212. for dir in $search; do
  213. unset IFS
  214. [ "$dir" ] || continue
  215. [ -d "$dir/applications" ] || [ -d "$dir/applnk" ] || continue
  216. for file in "$dir"/applications/*.desktop "$dir"/applications/*/*.desktop "$dir"/applnk/*.desktop "$dir"/applnk/*/*.desktop; do
  217. [ -r "$file" ] || continue
  218. # Check to make sure it's worth the processing.
  219. grep -q "^Exec.*$base" "$file" || continue
  220. # Make sure it's a visible desktop file (e.g. not "preferred-web-browser.desktop").
  221. grep -Eq "^(NoDisplay|Hidden)=true" "$file" && continue
  222. command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`"
  223. command="`which "$command"`"
  224. if [ x"`readlink -f "$command"`" = x"$binary" ]; then
  225. # Fix any double slashes that got added path composition
  226. echo "$file" | sed -e 's,//*,/,g'
  227. return
  228. fi
  229. done
  230. done
  231. }
  232. #-------------------------------------------------------------
  233. # map a .desktop file to a binary
  234. desktop_file_to_binary()
  235. {
  236. search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
  237. desktop="`basename "$1"`"
  238. IFS=:
  239. for dir in $search; do
  240. unset IFS
  241. [ "$dir" ] && [ -d "$dir/applications" ] || [ -d "$dir/applnk" ] || continue
  242. # Check if desktop file contains -
  243. if [ "${desktop#*-}" != "$desktop" ]; then
  244. vendor=${desktop%-*}
  245. app=${desktop#*-}
  246. if [ -r $dir/applications/$vendor/$app ]; then
  247. file_path=$dir/applications/$vendor/$app
  248. elif [ -r $dir/applnk/$vendor/$app ]; then
  249. file_path=$dir/applnk/$vendor/$app
  250. fi
  251. fi
  252. if test -z "$file_path" ; then
  253. for indir in "$dir"/applications/ "$dir"/applications/*/ "$dir"/applnk/ "$dir"/applnk/*/; do
  254. file="$indir/$desktop"
  255. if [ -r "$file" ]; then
  256. file_path=$file
  257. break
  258. fi
  259. done
  260. fi
  261. if [ -r "$file_path" ]; then
  262. # Remove any arguments (%F, %f, %U, %u, etc.).
  263. command="`grep -E "^Exec(\[[^]=]*])?=" "$file_path" | cut -d= -f 2- | first_word`"
  264. command="`which "$command"`"
  265. readlink -f "$command"
  266. return
  267. fi
  268. done
  269. }
  270. #-------------------------------------------------------------
  271. # Exit script on successfully completing the desired operation
  272. exit_success()
  273. {
  274. if [ $# -gt 0 ]; then
  275. echo "$@"
  276. echo
  277. fi
  278. exit 0
  279. }
  280. #-----------------------------------------
  281. # Exit script on malformed arguments, not enough arguments
  282. # or missing required option.
  283. # prints usage information
  284. exit_failure_syntax()
  285. {
  286. if [ $# -gt 0 ]; then
  287. echo "xdg-icon-resource: $@" >&2
  288. echo "Try 'xdg-icon-resource --help' for more information." >&2
  289. else
  290. usage
  291. echo "Use 'man xdg-icon-resource' or 'xdg-icon-resource --manual' for additional info."
  292. fi
  293. exit 1
  294. }
  295. #-------------------------------------------------------------
  296. # Exit script on missing file specified on command line
  297. exit_failure_file_missing()
  298. {
  299. if [ $# -gt 0 ]; then
  300. echo "xdg-icon-resource: $@" >&2
  301. fi
  302. exit 2
  303. }
  304. #-------------------------------------------------------------
  305. # Exit script on failure to locate necessary tool applications
  306. exit_failure_operation_impossible()
  307. {
  308. if [ $# -gt 0 ]; then
  309. echo "xdg-icon-resource: $@" >&2
  310. fi
  311. exit 3
  312. }
  313. #-------------------------------------------------------------
  314. # Exit script on failure returned by a tool application
  315. exit_failure_operation_failed()
  316. {
  317. if [ $# -gt 0 ]; then
  318. echo "xdg-icon-resource: $@" >&2
  319. fi
  320. exit 4
  321. }
  322. #------------------------------------------------------------
  323. # Exit script on insufficient permission to read a specified file
  324. exit_failure_file_permission_read()
  325. {
  326. if [ $# -gt 0 ]; then
  327. echo "xdg-icon-resource: $@" >&2
  328. fi
  329. exit 5
  330. }
  331. #------------------------------------------------------------
  332. # Exit script on insufficient permission to write a specified file
  333. exit_failure_file_permission_write()
  334. {
  335. if [ $# -gt 0 ]; then
  336. echo "xdg-icon-resource: $@" >&2
  337. fi
  338. exit 6
  339. }
  340. check_input_file()
  341. {
  342. if [ ! -e "$1" ]; then
  343. exit_failure_file_missing "file '$1' does not exist"
  344. fi
  345. if [ ! -r "$1" ]; then
  346. exit_failure_file_permission_read "no permission to read file '$1'"
  347. fi
  348. }
  349. check_vendor_prefix()
  350. {
  351. file_label="$2"
  352. [ -n "$file_label" ] || file_label="filename"
  353. file=`basename "$1"`
  354. case "$file" in
  355. [[:alpha:]]*-*)
  356. return
  357. ;;
  358. esac
  359. echo "xdg-icon-resource: $file_label '$file' does not have a proper vendor prefix" >&2
  360. echo 'A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated' >&2
  361. echo 'with a dash ("-"). An example '"$file_label"' is '"'example-$file'" >&2
  362. echo "Use --novendor to override or 'xdg-icon-resource --manual' for additional info." >&2
  363. exit 1
  364. }
  365. check_output_file()
  366. {
  367. # if the file exists, check if it is writeable
  368. # if it does not exists, check if we are allowed to write on the directory
  369. if [ -e "$1" ]; then
  370. if [ ! -w "$1" ]; then
  371. exit_failure_file_permission_write "no permission to write to file '$1'"
  372. fi
  373. else
  374. DIR=`dirname "$1"`
  375. if [ ! -w "$DIR" ] || [ ! -x "$DIR" ]; then
  376. exit_failure_file_permission_write "no permission to create file '$1'"
  377. fi
  378. fi
  379. }
  380. #----------------------------------------
  381. # Checks for shared commands, e.g. --help
  382. check_common_commands()
  383. {
  384. while [ $# -gt 0 ] ; do
  385. parm="$1"
  386. shift
  387. case "$parm" in
  388. --help)
  389. usage
  390. echo "Use 'man xdg-icon-resource' or 'xdg-icon-resource --manual' for additional info."
  391. exit_success
  392. ;;
  393. --manual)
  394. manualpage
  395. exit_success
  396. ;;
  397. --version)
  398. echo "xdg-icon-resource 1.1.3"
  399. exit_success
  400. ;;
  401. esac
  402. done
  403. }
  404. check_common_commands "$@"
  405. [ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && unset XDG_UTILS_DEBUG_LEVEL;
  406. if [ ${XDG_UTILS_DEBUG_LEVEL-0} -lt 1 ]; then
  407. # Be silent
  408. xdg_redirect_output=" > /dev/null 2> /dev/null"
  409. else
  410. # All output to stderr
  411. xdg_redirect_output=" >&2"
  412. fi
  413. #--------------------------------------
  414. # Checks for known desktop environments
  415. # set variable DE to the desktop environments name, lowercase
  416. detectDE()
  417. {
  418. # see https://bugs.freedesktop.org/show_bug.cgi?id=34164
  419. unset GREP_OPTIONS
  420. if [ -n "${XDG_CURRENT_DESKTOP}" ]; then
  421. case "${XDG_CURRENT_DESKTOP}" in
  422. # only recently added to menu-spec, pre-spec X- still in use
  423. Cinnamon|X-Cinnamon)
  424. DE=cinnamon;
  425. ;;
  426. ENLIGHTENMENT)
  427. DE=enlightenment;
  428. ;;
  429. # GNOME, GNOME-Classic:GNOME, or GNOME-Flashback:GNOME
  430. GNOME*)
  431. DE=gnome;
  432. ;;
  433. KDE)
  434. DE=kde;
  435. ;;
  436. # Deepin Desktop Environments
  437. DEEPIN|Deepin|deepin)
  438. DE=dde;
  439. ;;
  440. LXDE)
  441. DE=lxde;
  442. ;;
  443. LXQt)
  444. DE=lxqt;
  445. ;;
  446. MATE)
  447. DE=mate;
  448. ;;
  449. XFCE)
  450. DE=xfce
  451. ;;
  452. X-Generic)
  453. DE=generic
  454. ;;
  455. esac
  456. fi
  457. if [ x"$DE" = x"" ]; then
  458. # classic fallbacks
  459. if [ x"$KDE_FULL_SESSION" != x"" ]; then DE=kde;
  460. elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome;
  461. elif [ x"$MATE_DESKTOP_SESSION_ID" != x"" ]; then DE=mate;
  462. 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;
  463. elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce;
  464. elif xprop -root 2> /dev/null | grep -i '^xfce_desktop_window' >/dev/null 2>&1; then DE=xfce
  465. elif echo $DESKTOP | grep -q '^Enlightenment'; then DE=enlightenment;
  466. elif [ x"$LXQT_SESSION_CONFIG" != x"" ]; then DE=lxqt;
  467. fi
  468. fi
  469. if [ x"$DE" = x"" ]; then
  470. # fallback to checking $DESKTOP_SESSION
  471. case "$DESKTOP_SESSION" in
  472. gnome)
  473. DE=gnome;
  474. ;;
  475. LXDE|Lubuntu)
  476. DE=lxde;
  477. ;;
  478. MATE)
  479. DE=mate;
  480. ;;
  481. xfce|xfce4|'Xfce Session')
  482. DE=xfce;
  483. ;;
  484. esac
  485. fi
  486. if [ x"$DE" = x"" ]; then
  487. # fallback to uname output for other platforms
  488. case "$(uname 2>/dev/null)" in
  489. CYGWIN*)
  490. DE=cygwin;
  491. ;;
  492. Darwin)
  493. DE=darwin;
  494. ;;
  495. esac
  496. fi
  497. if [ x"$DE" = x"gnome" ]; then
  498. # gnome-default-applications-properties is only available in GNOME 2.x
  499. # but not in GNOME 3.x
  500. which gnome-default-applications-properties > /dev/null 2>&1 || DE="gnome3"
  501. fi
  502. if [ -f "$XDG_RUNTIME_DIR/flatpak-info" ]; then
  503. DE="flatpak"
  504. fi
  505. }
  506. #----------------------------------------------------------------------------
  507. # kfmclient exec/openURL can give bogus exit value in KDE <= 3.5.4
  508. # It also always returns 1 in KDE 3.4 and earlier
  509. # Simply return 0 in such case
  510. kfmclient_fix_exit_code()
  511. {
  512. version=`LC_ALL=C.UTF-8 kde-config --version 2>/dev/null | grep '^KDE'`
  513. major=`echo $version | sed 's/KDE.*: \([0-9]\).*/\1/'`
  514. minor=`echo $version | sed 's/KDE.*: [0-9]*\.\([0-9]\).*/\1/'`
  515. release=`echo $version | sed 's/KDE.*: [0-9]*\.[0-9]*\.\([0-9]\).*/\1/'`
  516. test "$major" -gt 3 && return $1
  517. test "$minor" -gt 5 && return $1
  518. test "$release" -gt 4 && return $1
  519. return 0
  520. }
  521. #----------------------------------------------------------------------------
  522. # Returns true if there is a graphical display attached.
  523. has_display()
  524. {
  525. if [ -n "$DISPLAY" ] || [ -n "$WAYLAND_DISPLAY" ]; then
  526. return 0
  527. else
  528. return 1
  529. fi
  530. }
  531. # Set GTK_UPDATE_ICON_CACHE to gtk-update-icon-cache executable path or
  532. # to "-" if not found.
  533. GTK_UPDATE_ICON_CACHE=
  534. find_gtk_update_icon_cache()
  535. {
  536. [ -n "$GTK_UPDATE_ICON_CACHE" ] && return;
  537. GTK_UPDATE_ICON_CACHE="-"
  538. for x in `echo "$PATH:/opt/gnome/bin" | sed 's/:/ /g'`; do
  539. DEBUG 3 "Checking $x for gtk-update-icon-cache"
  540. if [ -x "$x/gtk-update-icon-cache" ] ; then
  541. DEBUG 1 "Found $x/gtk-update-icon-cache"
  542. GTK_UPDATE_ICON_CACHE="$x/gtk-update-icon-cache"
  543. return
  544. fi
  545. done
  546. }
  547. # Start GNOME legacy workaround section
  548. need_dot_icon_path()
  549. {
  550. # GTK < 2.6 uses ~/.icons but not XDG_DATA_HOME/icons
  551. # The availability of gtk-update-icon-cache is used as indication
  552. # of whether the system is using GTK 2.6 or later
  553. find_gtk_update_icon_cache
  554. [ "$GTK_UPDATE_ICON_CACHE" != "-" ] && return 1;
  555. return 0;
  556. }
  557. update_icon_database()
  558. {
  559. # Touch me, I'm dirty
  560. touch "$1/.xdg-icon-resource-dummy"
  561. rm -f "$1/.xdg-icon-resource-dummy"
  562. # Don't create a cache if there wan't one already
  563. if [ -f "$1/icon-theme.cache" ] ; then
  564. find_gtk_update_icon_cache
  565. if [ "$GTK_UPDATE_ICON_CACHE" != "-" ] ; then
  566. DEBUG 1 "Running $GTK_UPDATE_ICON_CACHE -f -t \"$1\""
  567. eval '$GTK_UPDATE_ICON_CACHE -f -t "$1"'$xdg_redirect_output
  568. return
  569. fi
  570. fi
  571. }
  572. [ x"$1" != x"" ] || exit_failure_syntax
  573. mode=
  574. action=
  575. update=yes
  576. size=
  577. theme=hicolor
  578. context=apps
  579. icon_file=
  580. icon_name=
  581. case $1 in
  582. install)
  583. action=install
  584. ;;
  585. uninstall)
  586. action=uninstall
  587. ;;
  588. forceupdate)
  589. action=forceupdate
  590. ;;
  591. *)
  592. exit_failure_syntax "unknown command '$1'"
  593. ;;
  594. esac
  595. shift
  596. vendor=true
  597. while [ $# -gt 0 ] ; do
  598. parm="$1"
  599. shift
  600. case $parm in
  601. --noupdate)
  602. update=no
  603. ;;
  604. --mode)
  605. if [ -z "$1" ] ; then
  606. exit_failure_syntax "mode argument missing for --mode"
  607. fi
  608. case "$1" in
  609. user)
  610. mode="user"
  611. ;;
  612. system)
  613. mode="system"
  614. ;;
  615. *)
  616. exit_failure_syntax "unknown mode '$1'"
  617. ;;
  618. esac
  619. shift
  620. ;;
  621. --theme)
  622. if [ -z "$1" ] ; then
  623. exit_failure_syntax "theme argument missing for --theme"
  624. fi
  625. theme="$1"
  626. shift
  627. ;;
  628. --size)
  629. if [ -z "$1" ] ; then
  630. exit_failure_syntax "size argument missing for --size"
  631. fi
  632. if echo "$1" | grep '[^0-9]' > /dev/null 2> /dev/null; then
  633. exit_failure_syntax "size argument must be numeric"
  634. fi
  635. size="$1"
  636. shift
  637. ;;
  638. --context)
  639. if [ -z "$1" ] ; then
  640. exit_failure_syntax "context argument missing for --context"
  641. fi
  642. context="$1"
  643. shift
  644. ;;
  645. --novendor)
  646. vendor=false
  647. ;;
  648. -*)
  649. exit_failure_syntax "unexpected option '$parm'"
  650. ;;
  651. *)
  652. if [ -n "$icon_name" ] ; then
  653. exit_failure_syntax "unexpected argument '$parm'"
  654. elif [ -n "$icon_file" ] ; then
  655. icon_name="$parm"
  656. else
  657. if [ "$action" = "install" ] ; then
  658. check_input_file "$parm"
  659. fi
  660. icon_file="$parm"
  661. fi
  662. ;;
  663. esac
  664. done
  665. # Shouldn't happen
  666. if [ -z "$action" ] ; then
  667. exit_failure_syntax "command argument missing"
  668. fi
  669. # Shouldn't happen
  670. if [ -z "$context" ] ; then
  671. exit_failure_syntax "context argument missing"
  672. fi
  673. if [ -n "$XDG_UTILS_INSTALL_MODE" ] ; then
  674. if [ "$XDG_UTILS_INSTALL_MODE" = "system" ] ; then
  675. mode="system"
  676. elif [ "$XDG_UTILS_INSTALL_MODE" = "user" ] ; then
  677. mode="user"
  678. fi
  679. fi
  680. if [ -z "$mode" ] ; then
  681. if [ "`whoami`" = "root" ] ; then
  682. mode="system"
  683. else
  684. mode="user"
  685. fi
  686. fi
  687. xdg_dir_name="icons/$theme"
  688. xdg_user_dir="$XDG_DATA_HOME"
  689. [ -n "$xdg_user_dir" ] || xdg_user_dir="$HOME/.local/share"
  690. xdg_user_prefix="$xdg_user_dir/icons"
  691. xdg_user_dir="$xdg_user_dir/$xdg_dir_name"
  692. xdg_global_dir=
  693. xdg_global_prefix=
  694. xdg_system_dirs="$XDG_DATA_DIRS"
  695. [ -n "$xdg_system_dirs" ] || xdg_system_dirs="/usr/local/share/:/usr/share/"
  696. for x in `echo "$xdg_system_dirs" | sed 's/:/ /g'`; do
  697. if [ -w "$x/$xdg_dir_name" ] ; then
  698. xdg_global_prefix="$x/icons"
  699. xdg_global_dir="$x/$xdg_dir_name"
  700. break
  701. fi
  702. done
  703. [ -w "$xdg_global_dir" ] || xdg_global_dir=
  704. dot_icon_dir=
  705. dot_base_dir=
  706. if [ x"$mode" = x"user" ] ; then
  707. xdg_base_dir="$xdg_user_dir"
  708. #Gnome 2.8 supports ~/.icons but not XDG_DATA_HOME
  709. if need_dot_icon_path ; then
  710. dot_icon_dir="$HOME/.icons"
  711. dot_base_dir="$dot_icon_dir/$theme"
  712. fi
  713. else
  714. xdg_base_dir="$xdg_global_dir"
  715. if [ -z "$xdg_base_dir" ] ; then
  716. exit_failure_operation_impossible "No writable system icon directory found."
  717. fi
  718. fi
  719. if [ x"$action" = x"forceupdate" ] ; then
  720. if [ -n "$icon_file" ] ; then
  721. exit_failure_syntax "unexpected argument '$icon_file'"
  722. fi
  723. update_icon_database $xdg_base_dir
  724. if [ -n "$dot_icon_dir" ] ; then
  725. if [ -d "$dot_icon_dir/" ] && [ ! -L "$dot_icon_dir" ] ; then
  726. update_icon_database "$dot_base_dir"
  727. fi
  728. fi
  729. exit_success
  730. fi
  731. if [ -z "$icon_file" ] ; then
  732. if [ x"$action" = x"install" ] ; then
  733. exit_failure_syntax "icon-file argument missing"
  734. else
  735. exit_failure_syntax "icon-name argument missing"
  736. fi
  737. fi
  738. xdg_size_name=
  739. extension=
  740. if [ -z "$size" ] ; then
  741. exit_failure_syntax "the icon size must be specified with --size"
  742. fi
  743. xdg_size_name="${size}x${size}"
  744. if [ x"$action" = x"install" ] ; then
  745. case "$icon_file" in
  746. *.xpm)
  747. extension="xpm"
  748. ;;
  749. *.png)
  750. extension="png"
  751. ;;
  752. *)
  753. exit_failure_syntax "icon file to install must be a *.png or *.xpm file"
  754. ;;
  755. esac
  756. fi
  757. if [ -n "$icon_name" ] ; then
  758. case "$icon_name" in
  759. *.png)
  760. exit_failure_syntax "icon name should not include an extension"
  761. ;;
  762. *.xpm)
  763. exit_failure_syntax "icon name should not include an extension"
  764. ;;
  765. esac
  766. fi
  767. # Start KDE legacy workaround section
  768. need_kde_icon_path()
  769. {
  770. local path
  771. path=`readlink -f "$1" 2> /dev/null` # Normalize path
  772. DEBUG 2 "need_kde_icon_path $path"
  773. if [ -z "$path" ] ; then
  774. DEBUG 2 "need_kde_icon_path RETURN 1 (not needed, no xdg icon dir)"
  775. return 1; # Not needed
  776. fi
  777. # if kde-config not found... return 0
  778. kde_icon_dirs=`kde${KDE_SESSION_VERSION}-config --path icon 2> /dev/null |sed 's/:/ /g'`
  779. DEBUG 3 "kde_icon_dirs: $kde_icon_dirs"
  780. if [ -z "$kde_icon_dirs" ] ; then
  781. DEBUG 3 "no result from kde${KDE_SESSION_VERSION}-config --path icon"
  782. DEBUG 2 "need_kde_icon_path RETURN 1 (not needed, no kde icon path)"
  783. return 1; # Not needed
  784. fi
  785. needed=0 # Needed
  786. for y in $kde_icon_dirs ; do
  787. x=`readlink -f "$y"` # Normalize path
  788. DEBUG 3 "Normalize $y --> $x"
  789. if [ -n "$x" ] ; then
  790. if [ "$x" = "$path" ] ; then
  791. needed=1 # Not needed
  792. fi
  793. if [ -w "$x" ] ; then
  794. kde_global_prefix="$x"
  795. # Take last writable dir
  796. fi
  797. fi
  798. done
  799. DEBUG 2 "kde_global_prefix: $kde_global_prefix"
  800. [ $needed -eq 1 ] && DEBUG 2 "need_kde_icon_path RETURN $needed (not needed)"
  801. [ $needed -eq 0 ] && DEBUG 2 "need_kde_icon_path RETURN $needed (needed)"
  802. return $needed
  803. }
  804. kde_dir=
  805. if [ x"$mode" = x"user" ] ; then
  806. xdg_dir="$xdg_base_dir/$xdg_size_name/$context"
  807. #KDE 3.x doesn't support XDG_DATA_HOME for icons
  808. #Check if xdg_dir prefix is listed by kde-config --path icon
  809. #If not, install additional symlink to kdedir
  810. if need_kde_icon_path "$xdg_user_prefix" ; then
  811. kde_user_icon_dir=`kde${KDE_SESSION_VERSION}-config --path icon | cut -d ':' -f 1`
  812. kde_user_dir="$kde_user_icon_dir/$theme"
  813. kde_dir="$kde_user_dir/$xdg_size_name/$context"
  814. fi
  815. #Gnome 2.8 supports ~/.icons but not XDG_DATA_HOME
  816. if [ -n "$dot_icon_dir" ] ; then
  817. if [ -L "$dot_icon_dir" ] ; then
  818. # Don't do anything
  819. dot_icon_dir=
  820. elif [ ! -d "$dot_icon_dir/" ] ; then
  821. # Symlink if it doesn't exist
  822. eval 'ln -s ".local/share/icons" "$dot_icon_dir"'$xdg_redirect_output
  823. dot_icon_dir=
  824. else
  825. dot_icon_dir="$dot_icon_dir/$theme/$xdg_size_name/$context"
  826. fi
  827. fi
  828. my_umask=077
  829. else
  830. xdg_dir="$xdg_base_dir/$xdg_size_name/$context"
  831. #KDE 3.x doesn't support XDG_DATA_DIRS for icons
  832. #Check if xdg_dir prefix is listed by kde-config --path icon
  833. #If not, install additional symlink to kdedir
  834. if need_kde_icon_path "$xdg_global_prefix" ; then
  835. kde_global_dir="$kde_global_prefix/$theme"
  836. kde_dir="$kde_global_dir/$xdg_size_name/$context"
  837. fi
  838. my_umask=022
  839. fi
  840. # End KDE legacy workaround section
  841. # Start GNOME legacy workaround section
  842. need_gnome_mime=
  843. [ "$context" = "mimetypes" ] && need_gnome_mime=true
  844. # End GNOME legacy workaround section
  845. [ -n "$icon_name" ] || icon_name=`basename "$icon_file" | sed 's/\.[a-z][a-z][a-z]$//'`
  846. if [ "$vendor" = "true" -a "$action" = "install" -a "$context" = "apps" ] ; then
  847. check_vendor_prefix "$icon_name" "icon name"
  848. fi
  849. icon_icon_file=`echo "$icon_file" | sed 's/\.[a-z][a-z][a-z]$/.icon/'`
  850. icon_icon_name="$icon_name.icon"
  851. DEBUG 1 "$action icon in $xdg_dir"
  852. [ "$action" = "install" ] && [ -f "$icon_icon_file" ] && DEBUG 1 "install $icon_icon_name meta file in $xdg_dir"
  853. [ -n "$kde_dir" ] && DEBUG 1 "$action symlink in $kde_dir (KDE 3.x support)"
  854. [ -n "$need_gnome_mime" ] && DEBUG 1 "$action gnome-mime-$icon_name symlink (GNOME 2.x support)"
  855. [ "$action" = "install" -a -n "$dot_icon_dir" ] && DEBUG 1 "$action ~/.icons symlink (GNOME 2.8 support)"
  856. case "$action" in
  857. install)
  858. save_umask=`umask`
  859. umask $my_umask
  860. for icon_dir in "$xdg_dir" "$dot_icon_dir"; do
  861. [ -z "$icon_dir" ] && continue
  862. mkdir -p "$icon_dir"
  863. eval 'cp "$icon_file" "$icon_dir/$icon_name.$extension"'$xdg_redirect_output
  864. if [ -f "$icon_icon_file" ] ; then
  865. eval 'cp "$icon_icon_file" "$icon_dir/$icon_icon_name"'$xdg_redirect_output
  866. fi
  867. if [ -n "$need_gnome_mime" ] ; then
  868. eval 'ln -s "$icon_name.$extension" "$icon_dir/gnome-mime-$icon_name.$extension"'$xdg_redirect_output
  869. fi
  870. done
  871. if [ -n "$kde_dir" ] ; then
  872. mkdir -p "$kde_dir"
  873. eval 'ln -s "$xdg_dir/$icon_name.$extension" "$kde_dir/$icon_name.$extension"'$xdg_redirect_output
  874. fi
  875. umask $save_umask
  876. ;;
  877. uninstall)
  878. for icon_dir in "$xdg_dir" "$dot_icon_dir"; do
  879. [ -z "$icon_dir" ] && continue
  880. rm -f "$icon_dir/$icon_name.xpm" "$icon_dir/$icon_name.png"
  881. rm -f "$icon_dir/$icon_icon_name"
  882. if [ -n "$need_gnome_mime" ] ; then
  883. rm -f "$icon_dir/gnome-mime-$icon_name.xpm"
  884. rm -f "$icon_dir/gnome-mime-$icon_name.png"
  885. fi
  886. done
  887. if [ -n "$kde_dir" ] ; then
  888. rm -f "$kde_dir/$icon_name.xpm" "$kde_dir/$icon_name.png"
  889. fi
  890. ;;
  891. esac
  892. if [ x"$update" = x"yes" ] ; then
  893. update_icon_database "$xdg_base_dir"
  894. if [ -n "$dot_icon_dir" ] ; then
  895. if [ -d "$dot_icon_dir/" ] && [ ! -L "$dot_icon_dir" ] ; then
  896. update_icon_database "$dot_base_dir"
  897. fi
  898. fi
  899. fi
  900. exit_success