obt/ddparse.c \
obt/link.h \
obt/link.c \
+ obt/linkbase.h \
+ obt/linkbase.c \
obt/paths.h \
obt/paths.c \
obt/prop.h \
};
struct _ObtDDParse {
- gchar *filename;
+ const gchar *filename;
gulong lineno;
gulong flags;
ObtDDParseGroup *group;
return TRUE;
}
-GHashTable* obt_ddparse_file(const gchar *name, GSList *paths)
+GHashTable* obt_ddparse_file(const gchar *filename)
{
ObtDDParse parse;
ObtDDParseGroup *desktop_entry;
- GSList *it;
FILE *f;
gboolean success;
- parse.filename = NULL;
+ if (!g_utf8_validate(filename, -1, NULL)) {
+ g_warning("Filename contains bad utf8: %s", filename);
+ return NULL;
+ }
+
+ parse.filename = filename;
parse.lineno = 0;
parse.group = NULL;
parse.group_hash = g_hash_table_new_full(g_str_hash,
g_hash_table_insert(parse.group_hash, desktop_entry->name, desktop_entry);
success = FALSE;
- for (it = paths; it && !success; it = g_slist_next(it)) {
- gchar *path = g_strdup_printf("%s/%s", (char*)it->data, name);
- if ((f = fopen(path, "r"))) {
- parse.filename = path;
- parse.lineno = 1;
- parse.flags = 0;
- if ((success = parse_file(f, &parse))) {
- /* check that required keys exist */
-
- if (!(parse.flags & DE_TYPE)) {
- g_warning("Missing Type key in %s", path);
- success = FALSE;
- }
- if (!(parse.flags & DE_NAME)) {
- g_warning("Missing Name key in %s", path);
- success = FALSE;
- }
- if (parse.flags & DE_TYPE_APPLICATION &&
- !(parse.flags & DE_EXEC))
- {
- g_warning("Missing Exec key for Application in %s",
- path);
- success = FALSE;
- }
- else if (parse.flags & DE_TYPE_LINK && !(parse.flags & DE_URL))
- {
- g_warning("Missing URL key for Link in %s", path);
- success = FALSE;
- }
+ if ((f = fopen(parse.filename, "r"))) {
+ parse.lineno = 1;
+ parse.flags = 0;
+ if ((success = parse_file(f, &parse))) {
+ /* check that required keys exist */
+
+ if (!(parse.flags & DE_TYPE)) {
+ g_warning("Missing Type key in %s", parse.filename);
+ success = FALSE;
+ }
+ if (!(parse.flags & DE_NAME)) {
+ g_warning("Missing Name key in %s", parse.filename);
+ success = FALSE;
+ }
+ if (parse.flags & DE_TYPE_APPLICATION &&
+ !(parse.flags & DE_EXEC))
+ {
+ g_warning("Missing Exec key for Application in %s",
+ parse.filename);
+ success = FALSE;
+ }
+ else if (parse.flags & DE_TYPE_LINK && !(parse.flags & DE_URL))
+ {
+ g_warning("Missing URL key for Link in %s", parse.filename);
+ success = FALSE;
}
- fclose(f);
}
- g_free(path);
+ fclose(f);
}
if (!success) {
g_hash_table_destroy(parse.group_hash);
{
return g->key_hash;
}
+
+gchar* obt_ddparse_file_to_id(const gchar *filename)
+{
+ gint len;
+ const gchar *in;
+ gchar *out;
+ gboolean sep;
+
+ if (!g_utf8_validate(filename, -1, NULL)) {
+ g_warning("Filename contains bad utf8: %s", filename);
+ return NULL;
+ }
+
+ len = strlen(filename) - 8; /* 8 = strlen(".desktop") */
+ g_assert(strcmp(filename+len, ".desktop") == 0);
+
+ out = g_new(char, len+1);
+ sep = TRUE;
+ for (in = filename; *in; ++in) {
+ gchar *next;
+
+ if (*in == '/') {
+ /* path separators becomes dashes */
+ if (!sep) {
+ *out = '-';
+ ++out;
+ }
+ sep = TRUE;
+ }
+ else {
+ /* everything else is copied as is */
+ next = g_utf8_next_char(in);
+ while (in < next) {
+ *out = *in;
+ ++out;
+ ++in;
+ }
+ }
+ }
+ return out;
+}
} value;
} ObtDDParseValue;
-/* Returns a hash table where the keys are groups, and the values are
- ObtDDParseGroups */
-GHashTable* obt_ddparse_file(const gchar *name, GSList *paths);
+/*! Parse a .desktop file.
+ @param filename The full path to the .desktop file to be read.
+ @return Returns a hash table where the keys are groups, and the values are
+ ObtDDParseGroups */
+GHashTable* obt_ddparse_file(const gchar *filename);
-/* Returns a hash table where the keys are "keys" in the .desktop file,
- and the values are "values" in the .desktop file, for the group @g. */
+/*! Get the keys in a group from a .desktop file.
+ The group comes from the hash table returned by obt_ddparse_file.
+ @return Returns a hash table where the keys are "keys" in the .desktop file,
+ represented as strings. The values are "values" in the .desktop file, for
+ the group @g. Each value will be a pointer to an ObtDDParseValue structure.
+*/
GHashTable* obt_ddparse_group_keys(ObtDDParseGroup *g);
+
+/*! Determine the id for a .desktop file.
+ @param filename The path to the .desktop file, _relative to_ some
+ basepath. filename must end with ".desktop" and be encoded in utf8.
+ @return Returns a string which is the id for the given .desktop file in its
+ current position. Returns NULL if there is an error.
+*/
+gchar* obt_ddparse_file_to_id(const gchar *filename);
} d;
};
-ObtLink* obt_link_from_ddfile(const gchar *ddname, GSList *paths,
+ObtLink* obt_link_from_ddfile(const gchar *basepath, const gchar *filename,
ObtPaths *p)
{
ObtLink *link;
GHashTable *groups, *keys;
ObtDDParseGroup *g;
ObtDDParseValue *v;
+ gchar *path;
/* parse the file, and get a hash table of the groups */
- groups = obt_ddparse_file(ddname, paths);
+ path = g_strconcat(basepath, filename, NULL);
+ groups = obt_ddparse_file(path);
+ g_free(path);
if (!groups) return NULL; /* parsing failed */
+
/* grab the Desktop Entry group */
g = g_hash_table_lookup(groups, "Desktop Entry");
g_assert(g != NULL);
typedef struct _ObtLink ObtLink;
-ObtLink* obt_link_from_ddfile(const gchar *name, GSList *paths,
+/*! Parse a .desktop (dd) file.
+ @param basepath The base directory in which to read the file.
+ @param filename The full path to the .desktop file _relative to_ basepath.
+ It must be in basepath or a subdirectory of it.
+ @param o An ObtPaths structure, which contains the executable paths.
+*/
+ObtLink* obt_link_from_ddfile(const gchar *basepath, const gchar *filename,
struct _ObtPaths *p);
void obt_link_ref(ObtLink *e);
--- /dev/null
+/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
+
+ obt/linkbase.c for the Openbox window manager
+ Copyright (c) 2010 Dana Jansens
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ See the COPYING file for a copy of the GNU General Public License.
+*/
+
+#include "obt/linkbase.h"
+#include "obt/link.h"
+#include "obt/paths.h"
+#include "obt/watch.h"
+
+struct _ObtLinkBase {
+ gint ref;
+
+ ObtWatch *watch;
+ GHashTable *base;
+};
+
+static void func(ObtWatch *w, const gchar *subpath, ObtWatchNotifyType type,
+ gpointer data)
+{
+}
+
+ObtLinkBase* obt_linkbase_new(ObtPaths *paths)
+{
+ ObtLinkBase *b;
+ GSList *it;
+
+ b = g_slice_new(ObtLinkBase);
+ b->watch = obt_watch_new();
+ b->base = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
+ (GDestroyNotify)obt_link_unref);
+
+ for (it = obt_paths_data_dirs(paths); it; it = g_slist_next(it)) {
+ gchar *p;
+ p = g_strconcat(it->data, "/applications", NULL);
+ obt_watch_add(b->watch, p, FALSE, func, b);
+ }
+ return b;
+}
+
+void obt_linkbase_ref(ObtLinkBase *lb)
+{
+ ++lb->ref;
+}
+
+void obt_linkbase_unref(ObtLinkBase *lb)
+{
+ if (--lb->ref < 1) {
+ obt_watch_unref(lb->watch);
+ g_hash_table_unref(lb->base);
+ g_slice_free(ObtLinkBase, lb);
+ }
+}
--- /dev/null
+/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
+
+ obt/linkbase.h for the Openbox window manager
+ Copyright (c) 2010 Dana Jansens
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ See the COPYING file for a copy of the GNU General Public License.
+*/
+
+#ifndef __obt_linkbase_h
+#define __obt_linkbase_h
+
+struct _ObtPaths;
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _ObtLinkBase ObtLinkBase;
+
+/*! Create a new database of ObtLinks. */
+ObtLinkBase* obt_linkbase_new(struct _ObtPaths *paths);
+void obt_linkbase_ref(ObtLinkBase *lb);
+void obt_linkbase_unref(ObtLinkBase *lb);
+
+G_END_DECLS
+
+#endif