From 98620560939a10bd7aed2cc0b7411d1912325a03 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Mon, 20 Sep 2010 15:47:10 -0400 Subject: [PATCH] Add linkbase which will keep track of available .desktop files for application launching etc. --- Makefile.am | 2 + obt/ddparse.c | 110 +++++++++++++++++++++++++++++++++---------------- obt/ddparse.h | 24 ++++++++--- obt/link.c | 8 +++- obt/link.h | 8 +++- obt/linkbase.c | 66 +++++++++++++++++++++++++++++ obt/linkbase.h | 37 +++++++++++++++++ 7 files changed, 212 insertions(+), 43 deletions(-) create mode 100644 obt/linkbase.c create mode 100644 obt/linkbase.h diff --git a/Makefile.am b/Makefile.am index 888e3451..ff887640 100644 --- a/Makefile.am +++ b/Makefile.am @@ -146,6 +146,8 @@ obt_libobt_la_SOURCES = \ obt/ddparse.c \ obt/link.h \ obt/link.c \ + obt/linkbase.h \ + obt/linkbase.c \ obt/paths.h \ obt/paths.c \ obt/prop.h \ diff --git a/obt/ddparse.c b/obt/ddparse.c index 149134d8..9c4424f1 100644 --- a/obt/ddparse.c +++ b/obt/ddparse.c @@ -45,7 +45,7 @@ enum { }; struct _ObtDDParse { - gchar *filename; + const gchar *filename; gulong lineno; gulong flags; ObtDDParseGroup *group; @@ -747,15 +747,19 @@ static gboolean parse_desktop_entry_value(gchar *key, const gchar *val, 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, @@ -769,39 +773,34 @@ GHashTable* obt_ddparse_file(const gchar *name, GSList *paths) 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); @@ -814,3 +813,44 @@ GHashTable* obt_ddparse_group_keys(ObtDDParseGroup *g) { 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; +} diff --git a/obt/ddparse.h b/obt/ddparse.h index d261f5bb..050aaa96 100644 --- a/obt/ddparse.h +++ b/obt/ddparse.h @@ -48,10 +48,24 @@ typedef struct _ObtDDParseValue { } 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); diff --git a/obt/link.c b/obt/link.c index 9cc2bac9..eb24a113 100644 --- a/obt/link.c +++ b/obt/link.c @@ -62,17 +62,21 @@ struct _ObtLink { } 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); diff --git a/obt/link.h b/obt/link.h index 9ad86cc9..dff11f3c 100644 --- a/obt/link.h +++ b/obt/link.h @@ -62,7 +62,13 @@ typedef enum { 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); diff --git a/obt/linkbase.c b/obt/linkbase.c new file mode 100644 index 00000000..1039b348 --- /dev/null +++ b/obt/linkbase.c @@ -0,0 +1,66 @@ +/* -*- 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); + } +} diff --git a/obt/linkbase.h b/obt/linkbase.h new file mode 100644 index 00000000..76bf4433 --- /dev/null +++ b/obt/linkbase.h @@ -0,0 +1,37 @@ +/* -*- 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 + +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 -- 2.39.2