r898: Applied Bernard Jungen's latest patch:
[rox-filer.git] / ROX-Filer / src / appinfo.c
blob7ead499b85d0eeef0d45de44445fca0546b16363
1 /*
2 * $Id$
4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 2001, the ROX-Filer team.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 * Place, Suite 330, Boston, MA 02111-1307 USA
22 /* appinfo.c - loading, caching and querying the AppInfo.xml files */
24 /* Any valid application directory may contain a file called AppInfo.xml.
25 * The format is:
27 * <?xml version="1.0"?>
28 * <AppInfo>
29 * <Summary>Tooltip text</Summary>
30 * <About>
31 * <Purpose>...</Purpose>
32 * <Version>...</Version>
33 * <Authors>...</Authors>
34 * <License>...</License>
35 * <Homepage>...</Homepage>
36 * ...
37 * </About>
38 * <AppMenu>
39 * <Item label="..." option="..."/>
40 * ...
41 * </AppMenu>
42 * </AppInfo>
45 #include "config.h"
47 #include <string.h>
49 #include "global.h"
51 #include "appinfo.h"
52 #include "fscache.h"
53 #include "dir.h"
54 #include "type.h"
55 #include "support.h"
57 static GFSCache *appinfo_cache = NULL;
59 /* Static prototypes */
60 static AppInfo *load(char *pathname, gpointer data);
61 static void ref(AppInfo *dir, gpointer data);
62 static void unref(AppInfo *dir, gpointer data);
63 static int getref(AppInfo *dir, gpointer data);
65 /* Stores the tree for one application's AppInfo file */
66 struct _AppInfo {
67 int ref;
68 xmlDocPtr doc; /* Parsed AppInfo file */
71 /****************************************************************
72 * EXTERNAL INTERFACE *
73 ****************************************************************/
75 void appinfo_init(void)
77 appinfo_cache = g_fscache_new((GFSLoadFunc) load,
78 (GFSRefFunc) ref,
79 (GFSRefFunc) unref,
80 (GFSGetRefFunc) getref,
81 NULL, NULL);
84 /* Load the AppInfo file for this application.
86 * Returns a pointer to the AppInfo structure, or NULL if this isn't
87 * an application with a valid AppInfo file.
89 * appinfo_unref() the result.
91 AppInfo *appinfo_get(guchar *app_dir, DirItem *item)
93 AppInfo *ai;
94 guchar *tmp;
96 /* Is it even an application directory? */
97 if (item->base_type != TYPE_DIRECTORY ||
98 !(item->flags & ITEM_FLAG_APPDIR))
99 return NULL; /* Not an application */
101 tmp = g_strconcat(app_dir, "/" APPINFO_FILENAME, NULL);
102 ai = g_fscache_lookup(appinfo_cache, tmp);
103 g_free(tmp);
105 if (!ai)
107 /* Temp: look for the old AppMenu file */
108 tmp = g_strconcat(app_dir, "/AppMenu", NULL);
109 ai = g_fscache_lookup(appinfo_cache, tmp);
110 g_free(tmp);
113 return ai;
116 void appinfo_unref(AppInfo *info)
118 g_return_if_fail(info != NULL);
120 g_fscache_data_unref(appinfo_cache, info);
123 /* Look for this section in the AppInfo document.
124 * It may be any direct child node, or the root node itself (this is for
125 * backwards compat with AppMenu; it may go soon).
127 * Returns an _xmlNode or NULL if there isn't one.
129 xmlNode *appinfo_get_section(AppInfo *ai, guchar *name)
131 xmlNode *node;
133 g_return_val_if_fail(ai != NULL, NULL);
134 g_return_val_if_fail(name != NULL, NULL);
136 node = xmlDocGetRootElement(ai->doc);
137 g_return_val_if_fail(node != NULL, NULL);
139 if (strcmp(node->name, name) == 0)
140 return node;
142 return get_subnode(node, NULL, name);
145 /****************************************************************
146 * INTERNAL FUNCTIONS *
147 ****************************************************************/
149 /* The pathname is the full path of the AppInfo file.
150 * If we get here, assume that this really is an application.
152 static AppInfo *load(char *pathname, gpointer data)
154 xmlDocPtr doc;
155 AppInfo *appinfo = NULL;
157 doc = xmlParseFile(pathname);
158 if (!doc)
159 return NULL; /* Bad XML */
161 appinfo = g_new(AppInfo, 1);
162 appinfo->ref = 1;
163 appinfo->doc = doc;
165 return appinfo;
168 static void ref(AppInfo *ai, gpointer data)
170 if (ai)
171 ai->ref++;
174 static void unref(AppInfo *ai, gpointer data)
176 if (ai && --ai->ref == 0)
178 xmlFreeDoc(ai->doc);
179 g_free(ai);
183 static int getref(AppInfo *ai, gpointer data)
185 return ai ? ai->ref : 0;