1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
3 obt/link.c for the Openbox window manager
4 Copyright (c) 2009 Dana Jansens
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 See the COPYING file for a copy of the GNU General Public License.
20 #include "obt/ddparse.h"
21 #include "obt/paths.h"
28 gchar
*name
; /*!< Specific name for the object (eg Firefox) */
29 gboolean display
; /*<! When false, do not display this link in menus or
31 gboolean deleted
; /*<! When true, the Link could exist but is deleted
32 for the current user */
33 gchar
*generic
; /*!< Generic name for the object (eg Web Browser) */
34 gchar
*comment
; /*!< Comment/description to display for the object */
35 gchar
*icon
; /*!< Name/path for an icon for the object */
36 guint env_required
; /*!< The environments that must be present to use this
38 guint env_restricted
; /*!< The environments that must _not_ be present to
43 gchar
*exec
; /*!< Executable to run for the app */
44 gchar
*wdir
; /*!< Working dir to run the app in */
45 gboolean term
; /*!< Run the app in a terminal or not */
48 gchar
**mime
; /*!< Mime types the app can open */
50 GQuark
*categories
; /*!< Array of quarks representing the
51 application's categories */
52 gulong n_categories
; /*!< Number of categories for the app */
54 ObtLinkAppStartup startup
;
55 gchar
*startup_wmclass
;
65 ObtLink
* obt_link_from_ddfile(const gchar
*ddname
, GSList
*paths
,
69 GHashTable
*groups
, *keys
;
73 /* parse the file, and get a hash table of the groups */
74 groups
= obt_ddparse_file(ddname
, paths
);
75 if (!groups
) return NULL
; /* parsing failed */
76 /* grab the Desktop Entry group */
77 g
= g_hash_table_lookup(groups
, "Desktop Entry");
79 /* grab the keys that appeared in the Desktop Entry group */
80 keys
= obt_ddparse_group_keys(g
);
82 /* build the ObtLink (we steal all strings from the parser) */
83 link
= g_slice_new0(ObtLink
);
87 v
= g_hash_table_lookup(keys
, "Type");
89 link
->type
= v
->value
.enumerable
;
91 if ((v
= g_hash_table_lookup(keys
, "Hidden")))
92 link
->deleted
= v
->value
.boolean
;
94 if ((v
= g_hash_table_lookup(keys
, "NoDisplay")))
95 link
->display
= !v
->value
.boolean
;
97 if ((v
= g_hash_table_lookup(keys
, "GenericName")))
98 link
->generic
= v
->value
.string
, v
->value
.string
= NULL
;
100 if ((v
= g_hash_table_lookup(keys
, "Comment")))
101 link
->comment
= v
->value
.string
, v
->value
.string
= NULL
;
103 if ((v
= g_hash_table_lookup(keys
, "Icon")))
104 link
->icon
= v
->value
.string
, v
->value
.string
= NULL
;
106 if ((v
= g_hash_table_lookup(keys
, "OnlyShowIn")))
107 link
->env_required
= v
->value
.environments
;
109 link
->env_required
= 0;
111 if ((v
= g_hash_table_lookup(keys
, "NotShowIn")))
112 link
->env_restricted
= v
->value
.environments
;
114 link
->env_restricted
= 0;
116 /* type-specific keys */
118 if (link
->type
== OBT_LINK_TYPE_APPLICATION
) {
122 v
= g_hash_table_lookup(keys
, "Exec");
124 link
->d
.app
.exec
= v
->value
.string
;
125 v
->value
.string
= NULL
;
127 /* parse link->d.app.exec to determine link->d.app.open */
129 for (c
= link
->d
.app
.exec
; *c
; ++c
) {
132 case 'f': link
->d
.app
.open
= OBT_LINK_APP_SINGLE_LOCAL
; break;
133 case 'F': link
->d
.app
.open
= OBT_LINK_APP_MULTI_LOCAL
; break;
134 case 'u': link
->d
.app
.open
= OBT_LINK_APP_SINGLE_URL
; break;
135 case 'U': link
->d
.app
.open
= OBT_LINK_APP_MULTI_URL
; break;
136 default: percent
= FALSE
;
138 if (percent
) break; /* found f/F/u/U */
140 else if (*c
== '%') percent
= TRUE
;
143 if ((v
= g_hash_table_lookup(keys
, "TryExec"))) {
144 /* XXX spawn a thread to check TryExec? */
145 link
->display
= link
->display
&&
146 obt_paths_try_exec(p
, v
->value
.string
);
149 if ((v
= g_hash_table_lookup(keys
, "Path"))) {
150 /* steal the string */
151 link
->d
.app
.wdir
= v
->value
.string
;
152 v
->value
.string
= NULL
;
155 if ((v
= g_hash_table_lookup(keys
, "Terminal")))
156 link
->d
.app
.term
= v
->value
.boolean
;
158 if ((v
= g_hash_table_lookup(keys
, "StartupNotify")))
159 link
->d
.app
.startup
= v
->value
.boolean
?
160 OBT_LINK_APP_STARTUP_PROTOCOL_SUPPORT
:
161 OBT_LINK_APP_STARTUP_NO_SUPPORT
;
163 link
->d
.app
.startup
= OBT_LINK_APP_STARTUP_LEGACY_SUPPORT
;
164 if ((v
= g_hash_table_lookup(keys
, "StartupWMClass"))) {
165 /* steal the string */
166 link
->d
.app
.startup_wmclass
= v
->value
.string
;
167 v
->value
.string
= NULL
;
171 if ((v
= g_hash_table_lookup(keys
, "Categories"))) {
175 link
->d
.app
.categories
= g_new(GQuark
, v
->value
.strings
.n
);
176 link
->d
.app
.n_categories
= v
->value
.strings
.n
;
178 for (i
= 0; i
< v
->value
.strings
.n
; ++i
) {
179 link
->d
.app
.categories
[i
] =
180 g_quark_from_string(v
->value
.strings
.a
[i
]);
181 c
= end
= end
+1; /* next */
185 if ((v
= g_hash_table_lookup(keys
, "MimeType"))) {
186 /* steal the string array */
187 link
->d
.app
.mime
= v
->value
.strings
.a
;
188 v
->value
.strings
.a
= NULL
;
189 v
->value
.strings
.n
= 0;
192 else if (link
->type
== OBT_LINK_TYPE_URL
) {
193 v
= g_hash_table_lookup(keys
, "URL");
195 link
->d
.url
.addr
= v
->value
.string
;
196 v
->value
.string
= NULL
;
199 /* destroy the parsing info */
200 g_hash_table_destroy(groups
);
205 void obt_link_ref(ObtLink
*dd
)
210 void obt_link_unref(ObtLink
*dd
)
217 if (dd
->type
== OBT_LINK_TYPE_APPLICATION
) {
218 g_free(dd
->d
.app
.exec
);
219 g_free(dd
->d
.app
.wdir
);
220 g_strfreev(dd
->d
.app
.mime
);
221 g_free(dd
->d
.app
.categories
);
222 g_free(dd
->d
.app
.startup_wmclass
);
224 else if (dd
->type
== OBT_LINK_TYPE_URL
)
225 g_free(dd
->d
.url
.addr
);
226 g_slice_free(ObtLink
, dd
);
230 const GQuark
* obt_link_app_categories(ObtLink
*e
, gulong
*n
)
232 g_return_val_if_fail(e
!= NULL
, NULL
);
233 g_return_val_if_fail(e
->type
== OBT_LINK_TYPE_APPLICATION
, NULL
);
234 g_return_val_if_fail(n
!= NULL
, NULL
);
236 *n
= e
->d
.app
.n_categories
;
237 return e
->d
.app
.categories
;