meson.eclass: Don't mix host *FLAGS with build *FLAGS
[gentoo.git] / eclass / desktop.eclass
1 # Copyright 1999-2017 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3
4 # @ECLASS: desktop.eclass
5 # @MAINTAINER:
6 # base-system@gentoo.org
7 # @BLURB: support for desktop files, menus, and icons
8
9 if [[ -z ${_DESKTOP_ECLASS} ]]; then
10 _DESKTOP_ECLASS=1
11
12 # @FUNCTION: make_desktop_entry
13 # @USAGE: make_desktop_entry(<command>, [name], [icon], [type], [fields])
14 # @DESCRIPTION:
15 # Make a .desktop file.
16 #
17 # @CODE
18 # binary:   what command does the app run with ?
19 # name:     the name that will show up in the menu
20 # icon:     the icon to use in the menu entry
21 #           this can be relative (to /usr/share/pixmaps) or
22 #           a full path to an icon
23 # type:     what kind of application is this?
24 #           for categories:
25 #           https://specifications.freedesktop.org/menu-spec/latest/apa.html
26 #           if unset, function tries to guess from package's category
27 # fields:       extra fields to append to the desktop file; a printf string
28 # @CODE
29 make_desktop_entry() {
30         [[ -z $1 ]] && die "make_desktop_entry: You must specify the executable"
31
32         local exec=${1}
33         local name=${2:-${PN}}
34         local icon=${3:-${PN}}
35         local type=${4}
36         local fields=${5}
37
38         if [[ -z ${type} ]] ; then
39                 local catmaj=${CATEGORY%%-*}
40                 local catmin=${CATEGORY##*-}
41                 case ${catmaj} in
42                         app)
43                                 case ${catmin} in
44                                         accessibility) type="Utility;Accessibility";;
45                                         admin)         type=System;;
46                                         antivirus)     type=System;;
47                                         arch)          type="Utility;Archiving";;
48                                         backup)        type="Utility;Archiving";;
49                                         cdr)           type="AudioVideo;DiscBurning";;
50                                         dicts)         type="Office;Dictionary";;
51                                         doc)           type=Documentation;;
52                                         editors)       type="Utility;TextEditor";;
53                                         emacs)         type="Development;TextEditor";;
54                                         emulation)     type="System;Emulator";;
55                                         laptop)        type="Settings;HardwareSettings";;
56                                         office)        type=Office;;
57                                         pda)           type="Office;PDA";;
58                                         vim)           type="Development;TextEditor";;
59                                         xemacs)        type="Development;TextEditor";;
60                                 esac
61                                 ;;
62
63                         dev)
64                                 type="Development"
65                                 ;;
66
67                         games)
68                                 case ${catmin} in
69                                         action|fps) type=ActionGame;;
70                                         arcade)     type=ArcadeGame;;
71                                         board)      type=BoardGame;;
72                                         emulation)  type=Emulator;;
73                                         kids)       type=KidsGame;;
74                                         puzzle)     type=LogicGame;;
75                                         roguelike)  type=RolePlaying;;
76                                         rpg)        type=RolePlaying;;
77                                         simulation) type=Simulation;;
78                                         sports)     type=SportsGame;;
79                                         strategy)   type=StrategyGame;;
80                                 esac
81                                 type="Game;${type}"
82                                 ;;
83
84                         gnome)
85                                 type="Gnome;GTK"
86                                 ;;
87
88                         kde)
89                                 type="KDE;Qt"
90                                 ;;
91
92                         mail)
93                                 type="Network;Email"
94                                 ;;
95
96                         media)
97                                 case ${catmin} in
98                                         gfx)
99                                                 type=Graphics
100                                                 ;;
101                                         *)
102                                                 case ${catmin} in
103                                                         radio) type=Tuner;;
104                                                         sound) type=Audio;;
105                                                         tv)    type=TV;;
106                                                         video) type=Video;;
107                                                 esac
108                                                 type="AudioVideo;${type}"
109                                                 ;;
110                                 esac
111                                 ;;
112
113                         net)
114                                 case ${catmin} in
115                                         dialup) type=Dialup;;
116                                         ftp)    type=FileTransfer;;
117                                         im)     type=InstantMessaging;;
118                                         irc)    type=IRCClient;;
119                                         mail)   type=Email;;
120                                         news)   type=News;;
121                                         nntp)   type=News;;
122                                         p2p)    type=FileTransfer;;
123                                         voip)   type=Telephony;;
124                                 esac
125                                 type="Network;${type}"
126                                 ;;
127
128                         sci)
129                                 case ${catmin} in
130                                         astro*)  type=Astronomy;;
131                                         bio*)    type=Biology;;
132                                         calc*)   type=Calculator;;
133                                         chem*)   type=Chemistry;;
134                                         elec*)   type=Electronics;;
135                                         geo*)    type=Geology;;
136                                         math*)   type=Math;;
137                                         physics) type=Physics;;
138                                         visual*) type=DataVisualization;;
139                                 esac
140                                 type="Education;Science;${type}"
141                                 ;;
142
143                         sys)
144                                 type="System"
145                                 ;;
146
147                         www)
148                                 case ${catmin} in
149                                         client) type=WebBrowser;;
150                                 esac
151                                 type="Network;${type}"
152                                 ;;
153
154                         *)
155                                 type=
156                                 ;;
157                 esac
158         fi
159         local slot=${SLOT%/*}
160         if [[ ${slot} == "0" ]] ; then
161                 local desktop_name="${PN}"
162         else
163                 local desktop_name="${PN}-${slot}"
164         fi
165         local desktop="${T}/$(echo ${exec} | sed 's:[[:space:]/:]:_:g')-${desktop_name}.desktop"
166         #local desktop=${T}/${exec%% *:-${desktop_name}}.desktop
167
168         # Don't append another ";" when a valid category value is provided.
169         type=${type%;}${type:+;}
170
171         if [[ -n ${icon} && ${icon} != /* ]] && [[ ${icon} == *.xpm || ${icon} == *.png || ${icon} == *.svg ]]; then
172                 ewarn "As described in the Icon Theme Specification, icon file extensions are not"
173                 ewarn "allowed in .desktop files if the value is not an absolute path."
174                 icon=${icon%.*}
175         fi
176
177         cat <<-EOF > "${desktop}"
178         [Desktop Entry]
179         Name=${name}
180         Type=Application
181         Comment=${DESCRIPTION}
182         Exec=${exec}
183         TryExec=${exec%% *}
184         Icon=${icon}
185         Categories=${type}
186         EOF
187
188         if [[ ${fields:-=} != *=* ]] ; then
189                 # 5th arg used to be value to Path=
190                 ewarn "make_desktop_entry: update your 5th arg to read Path=${fields}"
191                 fields="Path=${fields}"
192         fi
193         [[ -n ${fields} ]] && printf '%b\n' "${fields}" >> "${desktop}"
194
195         (
196                 # wrap the env here so that the 'insinto' call
197                 # doesn't corrupt the env of the caller
198                 insinto /usr/share/applications
199                 doins "${desktop}"
200         ) || die "installing desktop file failed"
201 }
202
203 # @FUNCTION: make_session_desktop
204 # @USAGE: <title> <command> [command args...]
205 # @DESCRIPTION:
206 # Make a GDM/KDM Session file.  The title is the file to execute to start the
207 # Window Manager.  The command is the name of the Window Manager.
208 #
209 # You can set the name of the file via the ${wm} variable.
210 make_session_desktop() {
211         [[ -z $1 ]] && eerror "$0: You must specify the title" && return 1
212         [[ -z $2 ]] && eerror "$0: You must specify the command" && return 1
213
214         local title=$1
215         local command=$2
216         local desktop=${T}/${wm:-${PN}}.desktop
217         shift 2
218
219         cat <<-EOF > "${desktop}"
220         [Desktop Entry]
221         Name=${title}
222         Comment=This session logs you into ${title}
223         Exec=${command} $*
224         TryExec=${command}
225         Type=XSession
226         EOF
227
228         (
229         # wrap the env here so that the 'insinto' call
230         # doesn't corrupt the env of the caller
231         insinto /usr/share/xsessions
232         doins "${desktop}"
233         )
234 }
235
236 # @FUNCTION: domenu
237 # @USAGE: <menus>
238 # @DESCRIPTION:
239 # Install the list of .desktop menu files into the appropriate directory
240 # (/usr/share/applications).
241 domenu() {
242         (
243         # wrap the env here so that the 'insinto' call
244         # doesn't corrupt the env of the caller
245         local i j ret=0
246         insinto /usr/share/applications
247         for i in "$@" ; do
248                 if [[ -f ${i} ]] ; then
249                         doins "${i}"
250                         ((ret+=$?))
251                 elif [[ -d ${i} ]] ; then
252                         for j in "${i}"/*.desktop ; do
253                                 doins "${j}"
254                                 ((ret+=$?))
255                         done
256                 else
257                         ((++ret))
258                 fi
259         done
260         exit ${ret}
261         )
262 }
263
264 # @FUNCTION: newmenu
265 # @USAGE: <menu> <newname>
266 # @DESCRIPTION:
267 # Like all other new* functions, install the specified menu as newname.
268 newmenu() {
269         (
270         # wrap the env here so that the 'insinto' call
271         # doesn't corrupt the env of the caller
272         insinto /usr/share/applications
273         newins "$@"
274         )
275 }
276
277 # @FUNCTION: _iconins
278 # @INTERNAL
279 # @DESCRIPTION:
280 # function for use in doicon and newicon
281 _iconins() {
282         (
283         # wrap the env here so that the 'insinto' call
284         # doesn't corrupt the env of the caller
285         local funcname=$1; shift
286         local size dir
287         local context=apps
288         local theme=hicolor
289
290         while [[ $# -gt 0 ]] ; do
291                 case $1 in
292                 -s|--size)
293                         if [[ ${2%%x*}x${2%%x*} == "$2" ]] ; then
294                                 size=${2%%x*}
295                         else
296                                 size=${2}
297                         fi
298                         case ${size} in
299                         16|22|24|32|36|48|64|72|96|128|192|256|512)
300                                 size=${size}x${size};;
301                         scalable)
302                                 ;;
303                         *)
304                                 eerror "${size} is an unsupported icon size!"
305                                 exit 1;;
306                         esac
307                         shift 2;;
308                 -t|--theme)
309                         theme=${2}
310                         shift 2;;
311                 -c|--context)
312                         context=${2}
313                         shift 2;;
314                 *)
315                         if [[ -z ${size} ]] ; then
316                                 insinto /usr/share/pixmaps
317                         else
318                                 insinto /usr/share/icons/${theme}/${size}/${context}
319                         fi
320
321                         if [[ ${funcname} == doicon ]] ; then
322                                 if [[ -f $1 ]] ; then
323                                         doins "${1}"
324                                 elif [[ -d $1 ]] ; then
325                                         shopt -s nullglob
326                                         doins "${1}"/*.{png,svg}
327                                         shopt -u nullglob
328                                 else
329                                         eerror "${1} is not a valid file/directory!"
330                                         exit 1
331                                 fi
332                         else
333                                 break
334                         fi
335                         shift 1;;
336                 esac
337         done
338         if [[ ${funcname} == newicon ]] ; then
339                 newins "$@"
340         fi
341         ) || die
342 }
343
344 # @FUNCTION: doicon
345 # @USAGE: [options] <icons>
346 # @DESCRIPTION:
347 # Install icon into the icon directory /usr/share/icons or into
348 # /usr/share/pixmaps if "--size" is not set.
349 # This is useful in conjunction with creating desktop/menu files.
350 #
351 # @CODE
352 #  options:
353 #  -s, --size
354 #    !!! must specify to install into /usr/share/icons/... !!!
355 #    size of the icon, like 48 or 48x48
356 #    supported icon sizes are:
357 #    16 22 24 32 36 48 64 72 96 128 192 256 512 scalable
358 #  -c, --context
359 #    defaults to "apps"
360 #  -t, --theme
361 #    defaults to "hicolor"
362 #
363 # icons: list of icons
364 #
365 # example 1: doicon foobar.png fuqbar.svg suckbar.png
366 # results in: insinto /usr/share/pixmaps
367 #             doins foobar.png fuqbar.svg suckbar.png
368 #
369 # example 2: doicon -s 48 foobar.png fuqbar.png blobbar.png
370 # results in: insinto /usr/share/icons/hicolor/48x48/apps
371 #             doins foobar.png fuqbar.png blobbar.png
372 # @CODE
373 doicon() {
374         _iconins ${FUNCNAME} "$@"
375 }
376
377 # @FUNCTION: newicon
378 # @USAGE: [options] <icon> <newname>
379 # @DESCRIPTION:
380 # Like doicon, install the specified icon as newname.
381 #
382 # @CODE
383 # example 1: newicon foobar.png NEWNAME.png
384 # results in: insinto /usr/share/pixmaps
385 #             newins foobar.png NEWNAME.png
386 #
387 # example 2: newicon -s 48 foobar.png NEWNAME.png
388 # results in: insinto /usr/share/icons/hicolor/48x48/apps
389 #             newins foobar.png NEWNAME.png
390 # @CODE
391 newicon() {
392         _iconins ${FUNCNAME} "$@"
393 }
394
395 fi