X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=obt%2Flink.c;h=9cc2bac96d7cb3bdcf180d52711d739ed6898590;hb=b1fc19711f431b68344ac471990a9f5153a875ee;hp=61369ecbfdde9aea2cab04f629c53887c6bfc8fb;hpb=0c8c9caba6f529c11b04643d24a5a503f49a245b;p=chaz%2Fopenbox diff --git a/obt/link.c b/obt/link.c index 61369ecb..9cc2bac9 100644 --- a/obt/link.c +++ b/obt/link.c @@ -45,10 +45,12 @@ struct _ObtLink { gboolean term; /*!< Run the app in a terminal or not */ ObtLinkAppOpen open; - /* XXX gchar**? or something better, a mime struct.. maybe - glib has something i can use. */ gchar **mime; /*!< Mime types the app can open */ + GQuark *categories; /*!< Array of quarks representing the + application's categories */ + gulong n_categories; /*!< Number of categories for the app */ + ObtLinkAppStartup startup; gchar *startup_wmclass; } app; @@ -66,46 +68,26 @@ ObtLink* obt_link_from_ddfile(const gchar *ddname, GSList *paths, ObtLink *link; GHashTable *groups, *keys; ObtDDParseGroup *g; - ObtDDParseValue *v, *type, *name, *target; + ObtDDParseValue *v; + /* parse the file, and get a hash table of the groups */ groups = obt_ddparse_file(ddname, paths); - if (!groups) return NULL; + if (!groups) return NULL; /* parsing failed */ + /* grab the Desktop Entry group */ g = g_hash_table_lookup(groups, "Desktop Entry"); - if (!g) { - g_hash_table_destroy(groups); - return NULL; - } - + g_assert(g != NULL); + /* grab the keys that appeared in the Desktop Entry group */ keys = obt_ddparse_group_keys(g); - /* check that required keys exist */ - - if (!(type = g_hash_table_lookup(keys, "Type"))) - { g_hash_table_destroy(groups); return NULL; } - if (!(name = g_hash_table_lookup(keys, "Name"))) - { g_hash_table_destroy(groups); return NULL; } - - if (type->value.enumerable == OBT_LINK_TYPE_APPLICATION) { - if (!(target = g_hash_table_lookup(keys, "Exec"))) - { g_hash_table_destroy(groups); return NULL; } - } - else if (type->value.enumerable == OBT_LINK_TYPE_URL) { - if (!(target = g_hash_table_lookup(keys, "URL"))) - { g_hash_table_destroy(groups); return NULL; } - } - else - target = NULL; - - /* parse all the optional keys and build ObtLink (steal the strings) */ + /* build the ObtLink (we steal all strings from the parser) */ link = g_slice_new0(ObtLink); link->ref = 1; - link->type = type->value.enumerable; - if (link->type == OBT_LINK_TYPE_APPLICATION) - link->d.app.exec = target->value.string, target->value.string = NULL; - else if (link->type == OBT_LINK_TYPE_URL) - link->d.url.addr = target->value.string, target->value.string = NULL; link->display = TRUE; + v = g_hash_table_lookup(keys, "Type"); + g_assert(v); + link->type = v->value.enumerable; + if ((v = g_hash_table_lookup(keys, "Hidden"))) link->deleted = v->value.boolean; @@ -131,20 +113,92 @@ ObtLink* obt_link_from_ddfile(const gchar *ddname, GSList *paths, else link->env_restricted = 0; + /* type-specific keys */ + if (link->type == OBT_LINK_TYPE_APPLICATION) { + gchar *c; + gboolean percent; + + v = g_hash_table_lookup(keys, "Exec"); + g_assert(v); + link->d.app.exec = v->value.string; + v->value.string = NULL; + + /* parse link->d.app.exec to determine link->d.app.open */ + percent = FALSE; + for (c = link->d.app.exec; *c; ++c) { + if (percent) { + switch (*c) { + case 'f': link->d.app.open = OBT_LINK_APP_SINGLE_LOCAL; break; + case 'F': link->d.app.open = OBT_LINK_APP_MULTI_LOCAL; break; + case 'u': link->d.app.open = OBT_LINK_APP_SINGLE_URL; break; + case 'U': link->d.app.open = OBT_LINK_APP_MULTI_URL; break; + default: percent = FALSE; + } + if (percent) break; /* found f/F/u/U */ + } + else if (*c == '%') percent = TRUE; + } + if ((v = g_hash_table_lookup(keys, "TryExec"))) { /* XXX spawn a thread to check TryExec? */ link->display = link->display && obt_paths_try_exec(p, v->value.string); } - /* XXX there's more app specific stuff */ - } + if ((v = g_hash_table_lookup(keys, "Path"))) { + /* steal the string */ + link->d.app.wdir = v->value.string; + v->value.string = NULL; + } + if ((v = g_hash_table_lookup(keys, "Terminal"))) + link->d.app.term = v->value.boolean; + + if ((v = g_hash_table_lookup(keys, "StartupNotify"))) + link->d.app.startup = v->value.boolean ? + OBT_LINK_APP_STARTUP_PROTOCOL_SUPPORT : + OBT_LINK_APP_STARTUP_NO_SUPPORT; + else { + link->d.app.startup = OBT_LINK_APP_STARTUP_LEGACY_SUPPORT; + if ((v = g_hash_table_lookup(keys, "StartupWMClass"))) { + /* steal the string */ + link->d.app.startup_wmclass = v->value.string; + v->value.string = NULL; + } + } + + if ((v = g_hash_table_lookup(keys, "Categories"))) { + gulong i; + gchar *end; + + link->d.app.categories = g_new(GQuark, v->value.strings.n); + link->d.app.n_categories = v->value.strings.n; + + for (i = 0; i < v->value.strings.n; ++i) { + link->d.app.categories[i] = + g_quark_from_string(v->value.strings.a[i]); + c = end = end+1; /* next */ + } + } + + if ((v = g_hash_table_lookup(keys, "MimeType"))) { + /* steal the string array */ + link->d.app.mime = v->value.strings.a; + v->value.strings.a = NULL; + v->value.strings.n = 0; + } + } else if (link->type == OBT_LINK_TYPE_URL) { - /* XXX there's URL specific stuff */ + v = g_hash_table_lookup(keys, "URL"); + g_assert(v); + link->d.url.addr = v->value.string; + v->value.string = NULL; } + /* destroy the parsing info */ + g_hash_table_destroy(groups); + return link; } @@ -156,6 +210,29 @@ void obt_link_ref(ObtLink *dd) void obt_link_unref(ObtLink *dd) { if (--dd->ref < 1) { + g_free(dd->name); + g_free(dd->generic); + g_free(dd->comment); + g_free(dd->icon); + if (dd->type == OBT_LINK_TYPE_APPLICATION) { + g_free(dd->d.app.exec); + g_free(dd->d.app.wdir); + g_strfreev(dd->d.app.mime); + g_free(dd->d.app.categories); + g_free(dd->d.app.startup_wmclass); + } + else if (dd->type == OBT_LINK_TYPE_URL) + g_free(dd->d.url.addr); g_slice_free(ObtLink, dd); } } + +const GQuark* obt_link_app_categories(ObtLink *e, gulong *n) +{ + g_return_val_if_fail(e != NULL, NULL); + g_return_val_if_fail(e->type == OBT_LINK_TYPE_APPLICATION, NULL); + g_return_val_if_fail(n != NULL, NULL); + + *n = e->d.app.n_categories; + return e->d.app.categories; +}