summaryrefslogtreecommitdiff
path: root/gtk/resources.c
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2015-06-17 21:29:48 +0100
committerVincent Sanders <vince@kyllikki.org>2015-06-17 21:35:45 +0100
commite1bbe4528b479881a1912f96f3160ab6e2fbb2ec (patch)
tree4e0a38e4a50ea435f7e70e52a5ad06e3e5cc51e4 /gtk/resources.c
parente9b89f776db705ee4403a2235ec21aabab12c8f6 (diff)
downloadnetsurf-e1bbe4528b479881a1912f96f3160ab6e2fbb2ec.tar.gz
netsurf-e1bbe4528b479881a1912f96f3160ab6e2fbb2ec.tar.bz2
Add direct resources to GTK
This adds API to obtain direct pointers to arrays of data from compiled in resources. Additionally it hooks this up to provide data for the resourece scheme handler.
Diffstat (limited to 'gtk/resources.c')
-rw-r--r--gtk/resources.c318
1 files changed, 246 insertions, 72 deletions
diff --git a/gtk/resources.c b/gtk/resources.c
index d1c3c86fc..1998034ff 100644
--- a/gtk/resources.c
+++ b/gtk/resources.c
@@ -36,6 +36,12 @@
#include "gtk/compat.h"
#include "gtk/resources.h"
+/** log contents of gresource /org/netsource */
+#ifdef WITH_GRESOURCE
+#define SHOW_GRESOURCE
+#undef SHOW_GRESOURCE
+#endif
+
#ifdef WITH_BUILTIN_PIXBUF
#ifdef __GNUC__
extern const guint8 menu_cursor_pixdata[] __attribute__ ((__aligned__ (4)));
@@ -44,12 +50,15 @@ extern const guint8 menu_cursor_pixdata[];
#endif
#endif
+/** type of resource entry */
enum nsgtk_resource_type_e {
- NSGTK_RESOURCE_FILE,
- NSGTK_RESOURCE_GLIB,
- NSGTK_RESOURCE_INLINE,
+ NSGTK_RESOURCE_FILE, /**< entry is a file on disc */
+ NSGTK_RESOURCE_GLIB, /**< entry is a gresource accessed by path */
+ NSGTK_RESOURCE_DIRECT, /**< entry is a gresource accesed by gbytes */
+ NSGTK_RESOURCE_INLINE, /**< entry is compiled in accessed by pointer */
};
+/** resource entry */
struct nsgtk_resource_s {
const char *name;
unsigned int len;
@@ -57,39 +66,63 @@ struct nsgtk_resource_s {
char *path;
};
+#define RES_ENTRY(name) { name, sizeof((name)) - 1, NSGTK_RESOURCE_FILE, NULL }
+
+/** resources that are used for gtk builder */
static struct nsgtk_resource_s ui_resource[] = {
- { "netsurf", 7, NSGTK_RESOURCE_FILE, NULL },
- { "tabcontents", 10, NSGTK_RESOURCE_FILE, NULL },
- { "password", 8, NSGTK_RESOURCE_FILE, NULL },
- { "login", 5, NSGTK_RESOURCE_FILE, NULL },
- { "ssl", 3, NSGTK_RESOURCE_FILE, NULL },
- { "toolbar", 7, NSGTK_RESOURCE_FILE, NULL },
- { "downloads", 9, NSGTK_RESOURCE_FILE, NULL },
- { "history", 7, NSGTK_RESOURCE_FILE, NULL },
- { "options", 7, NSGTK_RESOURCE_FILE, NULL },
- { "hotlist", 7, NSGTK_RESOURCE_FILE, NULL },
- { "cookies", 7, NSGTK_RESOURCE_FILE, NULL },
- { "viewdata", 8, NSGTK_RESOURCE_FILE, NULL },
- { "warning", 7, NSGTK_RESOURCE_FILE, NULL },
+ RES_ENTRY("netsurf"),
+ RES_ENTRY("tabcontents"),
+ RES_ENTRY("password"),
+ RES_ENTRY("login"),
+ RES_ENTRY("ssl"),
+ RES_ENTRY("toolbar"),
+ RES_ENTRY("downloads"),
+ RES_ENTRY("history"),
+ RES_ENTRY("options"),
+ RES_ENTRY("hotlist"),
+ RES_ENTRY("cookies"),
+ RES_ENTRY("viewdata"),
+ RES_ENTRY("warning"),
{ NULL, 0, NSGTK_RESOURCE_FILE, NULL },
};
-static struct nsgtk_resource_s gen_resource[] = {
- { "favicon.png", 11, NSGTK_RESOURCE_FILE, NULL },
- { "netsurf.xpm", 11, NSGTK_RESOURCE_FILE, NULL },
- { "menu_cursor.png", 15, NSGTK_RESOURCE_FILE, NULL },
- { "throbber/throbber0.png", 22, NSGTK_RESOURCE_FILE, NULL },
- { "throbber/throbber1.png", 22, NSGTK_RESOURCE_FILE, NULL },
- { "throbber/throbber2.png", 22, NSGTK_RESOURCE_FILE, NULL },
- { "throbber/throbber3.png", 22, NSGTK_RESOURCE_FILE, NULL },
- { "throbber/throbber4.png", 22, NSGTK_RESOURCE_FILE, NULL },
- { "throbber/throbber5.png", 22, NSGTK_RESOURCE_FILE, NULL },
- { "throbber/throbber6.png", 22, NSGTK_RESOURCE_FILE, NULL },
- { "throbber/throbber7.png", 22, NSGTK_RESOURCE_FILE, NULL },
- { "throbber/throbber8.png", 22, NSGTK_RESOURCE_FILE, NULL },
+/** resources that are used as pixbufs */
+static struct nsgtk_resource_s pixbuf_resource[] = {
+ RES_ENTRY("favicon.png"),
+ RES_ENTRY("netsurf.xpm"),
+ RES_ENTRY("menu_cursor.png"),
+ RES_ENTRY("throbber/throbber0.png"),
+ RES_ENTRY("throbber/throbber1.png"),
+ RES_ENTRY("throbber/throbber2.png"),
+ RES_ENTRY("throbber/throbber3.png"),
+ RES_ENTRY("throbber/throbber4.png"),
+ RES_ENTRY("throbber/throbber5.png"),
+ RES_ENTRY("throbber/throbber6.png"),
+ RES_ENTRY("throbber/throbber7.png"),
+ RES_ENTRY("throbber/throbber8.png"),
{ NULL, 0, NSGTK_RESOURCE_FILE, NULL },
};
+/** resources that are used for direct data access */
+static struct nsgtk_resource_s direct_resource[] = {
+ RES_ENTRY("welcome.html"),
+ RES_ENTRY("credits.html"),
+ RES_ENTRY("licence.html"),
+ RES_ENTRY("maps.html"),
+ RES_ENTRY("internal.css"),
+ RES_ENTRY("netsurf.png"),
+ RES_ENTRY("default.ico"),
+ RES_ENTRY("icons/arrow-l.png"),
+ RES_ENTRY("icons/content.png"),
+ RES_ENTRY("icons/directory2.png"),
+ RES_ENTRY("icons/directory.png"),
+ RES_ENTRY("icons/hotlist-add.png"),
+ RES_ENTRY("icons/hotlist-rmv.png"),
+ RES_ENTRY("icons/search.png"),
+ { NULL, 0, NSGTK_RESOURCE_FILE, NULL },
+};
+
+
/* exported interface documented in gtk/resources.h */
GdkCursor *nsgtk_create_menu_cursor(void)
{
@@ -98,7 +131,6 @@ GdkCursor *nsgtk_create_menu_cursor(void)
nserror res;
const char *resname = "menu_cursor.png";
-
res = nsgdk_pixbuf_new_from_resname(resname, &pixbuf);
if (res == NSERROR_OK) {
cursor = gdk_cursor_new_from_pixbuf(gdk_display_get_default(),
@@ -110,7 +142,7 @@ GdkCursor *nsgtk_create_menu_cursor(void)
}
-/*
+/**
* locate a resource
*
* The way GTK accesses resource files has changed greatly between
@@ -122,24 +154,48 @@ GdkCursor *nsgtk_create_menu_cursor(void)
* instead.
*
* \param respath A string vector containing the valid resource search paths
- * \param ui_res A resource entry to initialise
+ * \param resource A resource entry to initialise
*/
static nserror
init_resource(char **respath, struct nsgtk_resource_s *resource)
{
char *resname;
-#ifdef WITH_BUILTIN_PIXBUF
- if (strncmp(resource->name, "menu_cursor.png", resource->len) == 0) {
- resource->path = (char *)&menu_cursor_pixdata[0];
- resource->type = NSGTK_RESOURCE_INLINE;
- LOG("Found builtin for %s", resource->name);
- return NSERROR_OK;
- }
-#endif
#ifdef WITH_GRESOURCE
int resnamelen;
gboolean present;
+ const gchar * const *langv;
+ int langc = 0;
+
+ langv = g_get_language_names();
+
+ while (langv[langc] != NULL) {
+ resnamelen = snprintf(NULL, 0,
+ "/org/netsurf/%s/%s",
+ langv[langc], resource->name);
+
+ resname = malloc(resnamelen + 1);
+ if (resname == NULL) {
+ return NSERROR_NOMEM;
+ }
+ snprintf(resname, resnamelen + 1,
+ "/org/netsurf/%s/%s",
+ langv[langc], resource->name);
+
+ present = g_resources_get_info(resname,
+ G_RESOURCE_LOOKUP_FLAGS_NONE,
+ NULL, NULL, NULL);
+ if (present == TRUE) {
+ /* found an entry in the resources */
+ resource->path = resname;
+ resource->type = NSGTK_RESOURCE_GLIB;
+ LOG("Found gresource path %s", resource->path);
+ return NSERROR_OK;
+ }
+ /*LOG("gresource \"%s\" not found", resname);*/
+ free(resname);
+ langc++;
+ }
resnamelen = snprintf(NULL, 0, "/org/netsurf/%s", resource->name);
resname = malloc(resnamelen + 1);
@@ -158,8 +214,9 @@ init_resource(char **respath, struct nsgtk_resource_s *resource)
LOG("Found gresource path %s", resource->path);
return NSERROR_OK;
}
- LOG("gresource \"%s\" not found", resname);
+ /*LOG("gresource \"%s\" not found", resname);*/
free(resname);
+
#endif
resname = filepath_find(respath, resource->name);
@@ -177,7 +234,61 @@ init_resource(char **respath, struct nsgtk_resource_s *resource)
return NSERROR_OK;
}
-/*
+/**
+ * locate and setup a direct resource
+ *
+ * Direct resources have general type of NSGTK_RESOURCE_GLIB but have
+ * g_resources_lookup_data() applied and the result stored so the data
+ * can be directly accessed without additional processing.
+ *
+ * \param respath A string vector containing the valid resource search paths
+ * \param resource A resource entry to initialise
+ */
+static nserror
+init_direct_resource(char **respath, struct nsgtk_resource_s *resource)
+{
+ nserror res;
+ GBytes *data;
+
+ res = init_resource(respath, resource);
+ if ((res == NSERROR_OK) &&
+ (resource->type == NSGTK_RESOURCE_GLIB)) {
+ /* found gresource we can convert */
+ data = g_resources_lookup_data(resource->path,
+ G_RESOURCE_LOOKUP_FLAGS_NONE,
+ NULL);
+ if (data != NULL) {
+ resource->type = NSGTK_RESOURCE_DIRECT;
+ resource->path = (char *)data;
+ }
+ }
+
+ return res;
+}
+
+/**
+ * locate a pixbuf resource
+ *
+ * Pixbuf resources can be compiled inline
+ *
+ * \param respath A string vector containing the valid resource search paths
+ * \param resource A resource entry to initialise
+ */
+static nserror
+init_pixbuf_resource(char **respath, struct nsgtk_resource_s *resource)
+{
+#ifdef WITH_BUILTIN_PIXBUF
+ if (strncmp(resource->name, "menu_cursor.png", resource->len) == 0) {
+ resource->path = (char *)&menu_cursor_pixdata[0];
+ resource->type = NSGTK_RESOURCE_INLINE;
+ LOG("Found builtin for %s", resource->name);
+ return NSERROR_OK;
+ }
+#endif
+ return init_resource(respath, resource);
+}
+
+/**
* locate a ui resource
*
* UI resources need their resource name changing to account for gtk versions
@@ -218,38 +329,67 @@ static nserror init_ui_resource(char **respath, struct nsgtk_resource_s *ui_res)
return res;
}
-#define SHOW_GRESOURCE
-
/**
- * Initialise UI resource table
+ * Find a resource entry by name.
*
+ * \param resname The resource name to match.
+ * \param resource The list of resources entries to search.
*/
-nserror nsgtk_init_resources(char **respath)
+static struct nsgtk_resource_s *
+find_resource_from_name(const char *resname, struct nsgtk_resource_s *resource)
{
- struct nsgtk_resource_s *resource;
- nserror res;
+ /* find resource from name */
+ while ((resource->name != NULL) &&
+ ((resname[0] != resource->name[0]) ||
+ (strncmp(resource->name, resname, resource->len) != 0))) {
+ resource++;
+ }
+ return resource;
+}
#ifdef SHOW_GRESOURCE
+/**
+ * Debug dump of all resources compile din via GResource.
+ */
+static void list_gresource(void)
+{
const char *nspath = "/org/netsurf";
char **reslist;
char **cur;
GError* gerror = NULL;
- reslist = g_resources_enumerate_children(nspath,G_RESOURCE_LOOKUP_FLAGS_NONE, &gerror);
+ reslist = g_resources_enumerate_children(nspath,
+ G_RESOURCE_LOOKUP_FLAGS_NONE,
+ &gerror);
if (gerror) {
LOG("gerror %s", gerror->message);
g_error_free(gerror);
} else {
- cur = reslist;
- while (cur != NULL && *cur != NULL) {
- LOG("gres %s", *cur);
- cur++;
- }
- g_strfreev(reslist);
+ cur = reslist;
+ while (cur != NULL && *cur != NULL) {
+ LOG("gres %s", *cur);
+ cur++;
+ }
+ g_strfreev(reslist);
}
+}
#endif
- /* walk the ui resource table and initialise all its members */
+/**
+ * Initialise UI resource table
+ *
+ */
+/* exported interface documented in gtk/resources.h */
+nserror nsgtk_init_resources(char **respath)
+{
+ struct nsgtk_resource_s *resource;
+ nserror res;
+
+#ifdef SHOW_GRESOURCE
+ list_gresource();
+#endif
+
+ /* iterate the ui resource table and initialise all its members */
resource = &ui_resource[0];
while (resource->name != NULL) {
res = init_ui_resource(respath, resource);
@@ -259,31 +399,29 @@ nserror nsgtk_init_resources(char **respath)
resource++;
}
- /* walk the general resource table and initialise all its members */
- resource = &gen_resource[0];
+ /* iterate the pixbuf resource table and initialise all its members */
+ resource = &pixbuf_resource[0];
while (resource->name != NULL) {
- res = init_resource(respath, resource);
+ res = init_pixbuf_resource(respath, resource);
if (res != NSERROR_OK) {
return res;
}
resource++;
}
+ /* iterate the direct resource table and initialise all its members */
+ resource = &direct_resource[0];
+ while (resource->name != NULL) {
+ res = init_direct_resource(respath, resource);
+ if (res != NSERROR_OK) {
+ return res;
+ }
+ resource++;
+ }
return NSERROR_OK;
}
-static struct nsgtk_resource_s *
-find_resource_from_name(const char *resname, struct nsgtk_resource_s *resource)
-{
- /* find resource from name */
- while ((resource->name != NULL) &&
- ((resname[0] != resource->name[0]) ||
- (strncmp(resource->name, resname, resource->len) != 0))) {
- resource++;
- }
- return resource;
-}
/* exported interface documented in gtk/resources.h */
nserror
@@ -293,7 +431,7 @@ nsgdk_pixbuf_new_from_resname(const char *resname, GdkPixbuf **pixbuf_out)
GdkPixbuf *new_pixbuf = NULL;
GError* error = NULL;
- resource = find_resource_from_name(resname, &gen_resource[0]);
+ resource = find_resource_from_name(resname, &pixbuf_resource[0]);
if (resource->name == NULL) {
return NSERROR_NOT_FOUND;
}
@@ -309,9 +447,13 @@ nsgdk_pixbuf_new_from_resname(const char *resname, GdkPixbuf **pixbuf_out)
case NSGTK_RESOURCE_INLINE:
#ifdef WITH_BUILTIN_PIXBUF
- new_pixbuf = gdk_pixbuf_new_from_inline(-1, (const guint8 *)resource->path, FALSE, NULL);
+ new_pixbuf = gdk_pixbuf_new_from_inline(-1, (const guint8 *)resource->path, FALSE, &error);
#endif
break;
+
+ case NSGTK_RESOURCE_DIRECT:
+ /* pixbuf resources are not currently direct */
+ break;
}
if (new_pixbuf == NULL) {
LOG("Unable to create pixbuf from file for %s with path %s \"%s\"",
@@ -365,3 +507,35 @@ nsgtk_builder_new_from_resname(const char *resname, GtkBuilder **builder_out)
return NSERROR_OK;
}
+
+/* exported interface documented in gtk/resources.h */
+nserror
+nsgtk_data_from_resname(const char *resname,
+ const uint8_t ** data_out,
+ size_t *data_size_out)
+{
+ struct nsgtk_resource_s *resource;
+ GBytes *data;
+ const gchar *buffer;
+ gsize buffer_length;
+
+ resource = find_resource_from_name(resname, &direct_resource[0]);
+ if ((resource->name == NULL) ||
+ (resource->type != NSGTK_RESOURCE_DIRECT)) {
+ return NSERROR_NOT_FOUND;
+ }
+
+ data = (GBytes *)resource->path;
+
+ buffer_length = 0;
+ buffer = g_bytes_get_data(data, &buffer_length);
+
+ if (buffer == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ *data_out = (const uint8_t *)buffer;
+ *data_size_out = (size_t)buffer_length;
+
+ return NSERROR_OK;
+}