diff options
Diffstat (limited to 'gtk/resources.c')
-rw-r--r-- | gtk/resources.c | 318 |
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; +} |