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 /* XXX gchar**? or something better, a mime struct.. maybe
49 glib has something i can use. */
50 gchar **mime; /*!< Mime types the app can open */
52 GQuark *categories; /*!< Array of quarks representing the
53 application's categories */
54 gulong n_categories; /*!< Number of categories for the app */
56 ObtLinkAppStartup startup;
57 gchar *startup_wmclass;
67 ObtLink* obt_link_from_ddfile(const gchar *ddname, GSList *paths,
71 GHashTable *groups, *keys;
75 /* parse the file, and get a hash table of the groups */
76 groups = obt_ddparse_file(ddname, paths);
77 if (!groups) return NULL; /* parsing failed */
78 /* grab the Desktop Entry group */
79 g = g_hash_table_lookup(groups, "Desktop Entry");
81 /* grab the keys that appeared in the Desktop Entry group */
82 keys = obt_ddparse_group_keys(g);
84 /* build the ObtLink (we steal all strings from the parser) */
85 link = g_slice_new0(ObtLink);
89 v = g_hash_table_lookup(keys, "Type");
91 link->type = v->value.enumerable;
93 if ((v = g_hash_table_lookup(keys, "Hidden")))
94 link->deleted = v->value.boolean;
96 if ((v = g_hash_table_lookup(keys, "NoDisplay")))
97 link->display = !v->value.boolean;
99 if ((v = g_hash_table_lookup(keys, "GenericName")))
100 link->generic = v->value.string, v->value.string = NULL;
102 if ((v = g_hash_table_lookup(keys, "Comment")))
103 link->comment = v->value.string, v->value.string = NULL;
105 if ((v = g_hash_table_lookup(keys, "Icon")))
106 link->icon = v->value.string, v->value.string = NULL;
108 if ((v = g_hash_table_lookup(keys, "OnlyShowIn")))
109 link->env_required = v->value.environments;
111 link->env_required = 0;
113 if ((v = g_hash_table_lookup(keys, "NotShowIn")))
114 link->env_restricted = v->value.environments;
116 link->env_restricted = 0;
118 /* type-specific keys */
120 if (link->type == OBT_LINK_TYPE_APPLICATION) {
124 v = g_hash_table_lookup(keys, "Exec");
126 link->d.app.exec = v->value.string;
127 v->value.string = NULL;
129 /* parse link->d.app.exec to determine link->d.app.open */
131 for (c = link->d.app.exec; *c; ++c) {
134 case 'f': link->d.app.open = OBT_LINK_APP_SINGLE_LOCAL; break;
135 case 'F': link->d.app.open = OBT_LINK_APP_MULTI_LOCAL; break;
136 case 'u': link->d.app.open = OBT_LINK_APP_SINGLE_URL; break;
137 case 'U': link->d.app.open = OBT_LINK_APP_MULTI_URL; break;
138 default: percent = FALSE;
140 if (percent) break; /* found f/F/u/U */
142 else if (*c == '%') percent = TRUE;
145 if ((v = g_hash_table_lookup(keys, "TryExec"))) {
146 /* XXX spawn a thread to check TryExec? */
147 link->display = link->display &&
148 obt_paths_try_exec(p, v->value.string);
151 if ((v = g_hash_table_lookup(keys, "Path"))) {
152 /* steal the string */
153 link->d.app.wdir = v->value.string;
154 v->value.string = NULL;
157 if ((v = g_hash_table_lookup(keys, "Terminal")))
158 link->d.app.term = v->value.boolean;
160 if ((v = g_hash_table_lookup(keys, "StartupNotify")))
161 link->d.app.startup = v->value.boolean ?
162 OBT_LINK_APP_STARTUP_PROTOCOL_SUPPORT :
163 OBT_LINK_APP_STARTUP_NO_SUPPORT;
165 link->d.app.startup = OBT_LINK_APP_STARTUP_LEGACY_SUPPORT;
166 if ((v = g_hash_table_lookup(keys, "StartupWMClass"))) {
167 /* steal the string */
168 link->d.app.startup_wmclass = v->value.string;
169 v->value.string = NULL;
173 if ((v = g_hash_table_lookup(keys, "Categories"))) {
177 link->d.app.categories = g_new(GQuark, v->value.strings.n);
178 link->d.app.n_categories = v->value.strings.n;
180 for (i = 0; i < v->value.strings.n; ++i) {
181 link->d.app.categories[i] =
182 g_quark_from_string(v->value.strings.a[i]);
183 c = end = end+1; /* next */
187 /* XXX do something with mime types */
189 else if (link->type == OBT_LINK_TYPE_URL) {
190 v = g_hash_table_lookup(keys, "URL");
192 link->d.url.addr = v->value.string;
193 v->value.string = NULL;
196 /* destroy the parsing info */
197 g_hash_table_destroy(groups);
202 void obt_link_ref(ObtLink *dd)
207 void obt_link_unref(ObtLink *dd)
214 if (dd->type == OBT_LINK_TYPE_APPLICATION) {
215 g_free(dd->d.app.exec);
216 g_free(dd->d.app.wdir);
217 g_free(dd->d.app.categories);
218 g_free(dd->d.app.startup_wmclass);
220 else if (dd->type == OBT_LINK_TYPE_URL)
221 g_free(dd->d.url.addr);
222 g_slice_free(ObtLink, dd);
226 const GQuark* obt_link_app_categories(ObtLink *e, gulong *n)
228 g_return_val_if_fail(e != NULL, NULL);
229 g_return_val_if_fail(e->type == OBT_LINK_TYPE_APPLICATION, NULL);
230 g_return_val_if_fail(n != NULL, NULL);
232 *n = e->d.app.n_categories;
233 return e->d.app.categories;