Gitweb links:
...log
http://git.netsurf-browser.org/netsurf.git/shortlog/0569fbf1709fcd7101586...
...commit
http://git.netsurf-browser.org/netsurf.git/commit/0569fbf1709fcd7101586c9...
...tree
http://git.netsurf-browser.org/netsurf.git/tree/0569fbf1709fcd7101586c9de...
The branch, master has been updated
via 0569fbf1709fcd7101586c9de5fb17686394a827 (commit)
via 2c7d24c5bc8b99738c25fce68c5b3e485530b5cc (commit)
via 43582c50552021bbced0ea11f0ff6c4b2b618529 (commit)
via d196ea7795ada760dbc243fe640769eb9bc65dff (commit)
via b94b96e272140f17a82ce0847e1634d081b5dc6c (commit)
via cfa5856eea7c0d840a19590baf1e66f6fee06b83 (commit)
from a8bf9b05aa94392b391d6015ed037e5c241ab172 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=0569fbf1709fcd71015...
commit 0569fbf1709fcd7101586c9de5fb17686394a827
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
change tab next and back accelerators
fixes bug #2581
diff --git a/frontends/gtk/res/accelerators b/frontends/gtk/res/accelerators
index e4140fc..2da229a 100644
--- a/frontends/gtk/res/accelerators
+++ b/frontends/gtk/res/accelerators
@@ -5,8 +5,8 @@
# The key names are the same as those in the gdk/gdkkeysyms.h header file
# but without the leading “GDK_KEY_”.
-gtkNextTab:<Control>Right
-gtkPrevTab:<Control>Left
+gtkNextTab:<Control>Page_Down
+gtkPrevTab:<Control>Page_Up
gtkCloseTab:<Control>w
gtkNewTab:<Control>t
gtkNewWindow:<Control>n
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=2c7d24c5bc8b99738c2...
commit 2c7d24c5bc8b99738c25fce68c5b3e485530b5cc
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
ensure stdint is included where required
diff --git a/frontends/beos/filetype.cpp b/frontends/beos/filetype.cpp
index 7a2ca97..bc988a8 100644
--- a/frontends/beos/filetype.cpp
+++ b/frontends/beos/filetype.cpp
@@ -18,6 +18,7 @@
#define __STDBOOL_H__ 1
#include <stdbool.h>
+#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
diff --git a/frontends/monkey/filetype.c b/frontends/monkey/filetype.c
index 979796b..65c84f9 100644
--- a/frontends/monkey/filetype.c
+++ b/frontends/monkey/filetype.c
@@ -32,6 +32,7 @@
#include <stdio.h>
#include <stdbool.h>
+#include <stdint.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=43582c50552021bbced...
commit 43582c50552021bbced0ea11f0ff6c4b2b618529
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
allow hash table add inline to be uncompressed
diff --git a/utils/hashtable.c b/utils/hashtable.c
index 0de6f83..4935d6b 100644
--- a/utils/hashtable.c
+++ b/utils/hashtable.c
@@ -81,6 +81,175 @@ static inline unsigned int hash_string_fnv(const char *datum, unsigned
int *len)
}
+
+/**
+ * process a line of input.
+ *
+ * \param hash The hash table to add the line to
+ * \param ln The line to process
+ * \param lnlen The length of \ln
+ * \return NSERROR_OK on success else NSERROR_INVALID
+ */
+static nserror
+process_line(struct hash_table *hash, uint8_t *ln, int lnlen)
+{
+ uint8_t *key;
+ uint8_t *value;
+ uint8_t *colon;
+
+ key = ln; /* set key to start of line */
+ value = ln + lnlen; /* set value to end of line */
+
+ /* skip leading whitespace */
+ while ((key < value) &&
+ ((*key == ' ') || (*key == '\t'))) {
+ key++;
+ }
+
+ /* empty or comment lines */
+ if ((*key == 0) || (*key == '#')) {
+ return NSERROR_OK;
+ }
+
+ /* find first colon as key/value separator */
+ for (colon = key; colon < value; colon++) {
+ if (*colon == ':') {
+ break;
+ }
+ }
+ if (colon == value) {
+ /* no colon found */
+ return NSERROR_INVALID;
+ }
+
+ *colon = 0; /* terminate key */
+ value = colon + 1;
+
+ if (hash_add(hash, (char *)key, (char *)value) == false) {
+ NSLOG(netsurf, INFO,
+ "Unable to add %s:%s to hash table", ln, value);
+ return NSERROR_INVALID;
+ }
+ return NSERROR_OK;
+}
+
+
+/**
+ * adds key/value pairs to a hash from a memory area
+ */
+static nserror
+hash_add_inline_plain(struct hash_table *ht, const uint8_t *data, size_t size)
+{
+ uint8_t s[LINE_BUFFER_SIZE]; /* line buffer */
+ unsigned int slen = 0;
+ nserror res = NSERROR_OK;
+
+ while (size > 0) {
+ s[slen] = *data;
+
+ if (s[slen] == '\n') {
+ s[slen] = 0; /* replace newline with null termination */
+ res = process_line(ht, s, slen);
+ slen = 0;
+ if (res != NSERROR_OK) {
+ break;
+ }
+ } else {
+ slen++;
+ if (slen > sizeof s) {
+ NSLOG(netsurf, INFO, "Overlength line\n");
+ slen = 0;
+ }
+ }
+
+ size--;
+ data++;
+ }
+ if (slen > 0) {
+ s[slen] = 0;
+ res = process_line(ht, s, slen);
+ }
+
+ return res;
+}
+
+/**
+ * adds key/value pairs to a hash from a compressed memory area
+ */
+static nserror
+hash_add_inline_gzip(struct hash_table *ht, const uint8_t *data, size_t size)
+{
+ nserror res;
+ int ret; /* zlib return value */
+ z_stream strm;
+ uint8_t s[LINE_BUFFER_SIZE]; /* line buffer */
+ size_t used = 0; /* number of bytes in buffer in use */
+ uint8_t *nl;
+
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+
+ strm.next_in = (uint8_t *)data;
+ strm.avail_in = size;
+
+ ret = inflateInit2(&strm, 32 + MAX_WBITS);
+ if (ret != Z_OK) {
+ NSLOG(netsurf, INFO, "inflateInit returned %d", ret);
+ return NSERROR_INVALID;
+ }
+
+ do {
+ strm.next_out = s + used;
+ strm.avail_out = sizeof(s) - used;
+
+ ret = inflate(&strm, Z_NO_FLUSH);
+ if ((ret != Z_OK) && (ret != Z_STREAM_END)) {
+ break;
+ }
+
+ used = sizeof(s) - strm.avail_out;
+ while (used > 0) {
+ /* find nl */
+ for (nl = &s[0]; nl < &s[used]; nl++) {
+ if (*nl == '\n') {
+ break;
+ }
+ }
+ if (nl == &s[used]) {
+ /* no nl found */
+ break;
+ }
+ /* found newline */
+ *nl = 0; /* null terminate line */
+ res = process_line(ht, &s[0], nl - &s[0]);
+ if (res != NSERROR_OK) {
+ inflateEnd(&strm);
+ return res;
+ }
+
+ /* move data down */
+ memmove(&s[0], nl + 1, used - ((nl + 1) - &s[0]) );
+ used -= ((nl +1) - &s[0]);
+ }
+ if (used == sizeof(s)) {
+ /* entire buffer used and no newline */
+ NSLOG(netsurf, INFO, "Overlength line");
+ used = 0;
+ }
+ } while (ret != Z_STREAM_END);
+
+ inflateEnd(&strm);
+
+ if (ret != Z_STREAM_END) {
+ NSLOG(netsurf, INFO, "inflate returned %d", ret);
+ return NSERROR_INVALID;
+ }
+ return NSERROR_OK;
+
+}
+
+
/* exported interface documented in utils/hashtable.h */
struct hash_table *hash_create(unsigned int chains)
{
@@ -187,57 +356,6 @@ const char *hash_get(struct hash_table *ht, const char *key)
}
-/**
- * process a line of input.
- *
- * \param hash The hash table to add the line to
- * \param ln The line to process
- * \param lnlen The length of \ln
- * \return NSERROR_OK on success else NSERROR_INVALID
- */
-static nserror
-process_line(struct hash_table *hash, uint8_t *ln, int lnlen)
-{
- uint8_t *key;
- uint8_t *value;
- uint8_t *colon;
-
- key = ln; /* set key to start of line */
- value = ln + lnlen; /* set value to end of line */
-
- /* skip leading whitespace */
- while ((key < value) &&
- ((*key == ' ') || (*key == '\t'))) {
- key++;
- }
-
- /* empty or comment lines */
- if ((*key == 0) || (*key == '#')) {
- return NSERROR_OK;
- }
-
- /* find first colon as key/value separator */
- for (colon = key; colon < value; colon++) {
- if (*colon == ':') {
- break;
- }
- }
- if (colon == value) {
- /* no colon found */
- return NSERROR_INVALID;
- }
-
- *colon = 0; /* terminate key */
- value = colon + 1;
-
- if (hash_add(hash, (char *)key, (char *)value) == false) {
- NSLOG(netsurf, INFO,
- "Unable to add %s:%s to hash table", ln, value);
- return NSERROR_INVALID;
- }
- return NSERROR_OK;
-}
-
/* exported interface documented in utils/hashtable.h */
nserror hash_add_file(struct hash_table *ht, const char *path)
@@ -262,7 +380,7 @@ nserror hash_add_file(struct hash_table *ht, const char *path)
while (gzgets(fp, s, sizeof s)) {
int slen = strlen(s);
s[--slen] = 0; /* remove \n at end */
-
+
res = process_line(ht, (uint8_t *)s, slen);
if (res != NSERROR_OK) {
break;
@@ -274,75 +392,13 @@ nserror hash_add_file(struct hash_table *ht, const char *path)
return res;
}
+
/* exported interface documented in utils/hashtable.h */
nserror hash_add_inline(struct hash_table *ht, const uint8_t *data, size_t size)
{
- nserror res;
- int ret; /* zlib return value */
- z_stream strm;
- uint8_t s[LINE_BUFFER_SIZE]; /* line buffer */
- size_t used = 0; /* number of bytes in buffer in use */
- uint8_t *nl;
-
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
-
- strm.next_in = (uint8_t *)data;
- strm.avail_in = size;
-
- ret = inflateInit2(&strm, 32 + MAX_WBITS);
- if (ret != Z_OK) {
- NSLOG(netsurf, INFO, "inflateInit returned %d", ret);
- return NSERROR_INVALID;
- }
-
- do {
- strm.next_out = s + used;
- strm.avail_out = sizeof(s) - used;
-
- ret = inflate(&strm, Z_NO_FLUSH);
- if ((ret != Z_OK) && (ret != Z_STREAM_END)) {
- break;
- }
-
- used = sizeof(s) - strm.avail_out;
- while (used > 0) {
- /* find nl */
- for (nl = &s[0]; nl < &s[used]; nl++) {
- if (*nl == '\n') {
- break;
- }
- }
- if (nl == &s[used]) {
- /* no nl found */
- break;
- }
- /* found newline */
- *nl = 0; /* null terminate line */
- res = process_line(ht, &s[0], nl - &s[0]);
- if (res != NSERROR_OK) {
- inflateEnd(&strm);
- return res;
- }
-
- /* move data down */
- memmove(&s[0], nl + 1, used - ((nl + 1) - &s[0]) );
- used -= ((nl +1) - &s[0]);
- }
- if (used == sizeof(s)) {
- /* entire buffer used and no newline */
- NSLOG(netsurf, INFO, "Overlength line");
- used = 0;
- }
- } while (ret != Z_STREAM_END);
-
- inflateEnd(&strm);
-
- if (ret != Z_STREAM_END) {
- NSLOG(netsurf, INFO, "inflate returned %d", ret);
- return NSERROR_INVALID;
+ if ((data[0]==0x1f) && (data[1] == 0x8b)) {
+ /* gzip header detected */
+ return hash_add_inline_gzip(ht, data, size);
}
- return NSERROR_OK;
-
+ return hash_add_inline_plain(ht, data, size);
}
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=d196ea7795ada760dbc...
commit d196ea7795ada760dbc243fe640769eb9bc65dff
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
fix gtk accelerator loading
diff --git a/frontends/gtk/accelerator.c b/frontends/gtk/accelerator.c
index 9339de8..11b7fb1 100644
--- a/frontends/gtk/accelerator.c
+++ b/frontends/gtk/accelerator.c
@@ -25,36 +25,55 @@
#include <stdint.h>
#include <gtk/gtk.h>
+#include "utils/log.h"
#include "utils/errors.h"
#include "utils/hashtable.h"
#include "gtk/resources.h"
#include "gtk/accelerator.h"
+/** acclelerators are stored in a fixed-size hash table. */
+#define HASH_SIZE 53
+
/** The hash table used to store the accelerators */
static struct hash_table *accelerators_hash = NULL;
nserror nsgtk_accelerator_init(char **respaths)
{
- nserror ret;
+ nserror res;
const uint8_t *data;
size_t data_size;
- ret = nsgtk_data_from_resname("accelerators", &data, &data_size);
- if (ret == NSERROR_OK) {
- //ret = hashtable_add_from_inline(data, data_size);
+ if (accelerators_hash == NULL) {
+ accelerators_hash = hash_create(HASH_SIZE);
+ }
+ if (accelerators_hash == NULL) {
+ NSLOG(netsurf, INFO, "Unable to create hash table");
+ return NSERROR_NOMEM;
+ }
+
+ res = nsgtk_data_from_resname("accelerators", &data, &data_size);
+ if (res == NSERROR_OK) {
+ res = hash_add_inline(accelerators_hash, data, data_size);
} else {
- const char *accelerators;
+ const char *accelerators_path;
/* Obtain path to accelerators */
- ret = nsgtk_path_from_resname("accelerators", &accelerators);
- if (ret == NSERROR_OK) {
- //ret = hashtable_add_from_file(messages);
+ res = nsgtk_path_from_resname("accelerators",
+ &accelerators_path);
+ if (res == NSERROR_OK) {
+ res = hash_add_file(accelerators_hash,
+ accelerators_path);
}
}
- return ret;
+
+ return res;
}
const char *nsgtk_accelerator_get_desc(const char *key)
{
- return NULL;
+ if ((key == NULL) ||
+ (accelerators_hash == NULL)) {
+ return NULL;
+ }
+ return hash_get(accelerators_hash, key);
}
diff --git a/frontends/gtk/fetch.c b/frontends/gtk/fetch.c
index 7286aec..b05c1bd 100644
--- a/frontends/gtk/fetch.c
+++ b/frontends/gtk/fetch.c
@@ -30,6 +30,7 @@
* ASCII hence not using locale dependant ctype functions for parsing.
*/
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
@@ -39,8 +40,8 @@
#include <strings.h>
#include <gtk/gtk.h>
-#include "utils/hashtable.h"
#include "utils/log.h"
+#include "utils/hashtable.h"
#include "utils/filepath.h"
#include "utils/file.h"
#include "utils/nsurl.h"
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=b94b96e272140f17a82...
commit b94b96e272140f17a82ce0847e1634d081b5dc6c
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
add hash table population from file or memory
diff --git a/utils/hashtable.c b/utils/hashtable.c
index 3a1711d..0de6f83 100644
--- a/utils/hashtable.c
+++ b/utils/hashtable.c
@@ -28,11 +28,15 @@
* it that has good coverage along side the other tests.
*/
+#include <stdint.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
-#include <stdbool.h>
-#include "utils/hashtable.h"
+#include <zlib.h>
+#include <errno.h>
+
#include "utils/log.h"
+#include "utils/hashtable.h"
struct hash_entry {
@@ -46,6 +50,8 @@ struct hash_table {
struct hash_entry **chain;
};
+/** maximum length of line for file or inline add */
+#define LINE_BUFFER_SIZE 512
/**
* Hash a string, returning a 32bit value. The hash algorithm used is
@@ -179,3 +185,164 @@ const char *hash_get(struct hash_table *ht, const char *key)
return NULL;
}
+
+
+/**
+ * process a line of input.
+ *
+ * \param hash The hash table to add the line to
+ * \param ln The line to process
+ * \param lnlen The length of \ln
+ * \return NSERROR_OK on success else NSERROR_INVALID
+ */
+static nserror
+process_line(struct hash_table *hash, uint8_t *ln, int lnlen)
+{
+ uint8_t *key;
+ uint8_t *value;
+ uint8_t *colon;
+
+ key = ln; /* set key to start of line */
+ value = ln + lnlen; /* set value to end of line */
+
+ /* skip leading whitespace */
+ while ((key < value) &&
+ ((*key == ' ') || (*key == '\t'))) {
+ key++;
+ }
+
+ /* empty or comment lines */
+ if ((*key == 0) || (*key == '#')) {
+ return NSERROR_OK;
+ }
+
+ /* find first colon as key/value separator */
+ for (colon = key; colon < value; colon++) {
+ if (*colon == ':') {
+ break;
+ }
+ }
+ if (colon == value) {
+ /* no colon found */
+ return NSERROR_INVALID;
+ }
+
+ *colon = 0; /* terminate key */
+ value = colon + 1;
+
+ if (hash_add(hash, (char *)key, (char *)value) == false) {
+ NSLOG(netsurf, INFO,
+ "Unable to add %s:%s to hash table", ln, value);
+ return NSERROR_INVALID;
+ }
+ return NSERROR_OK;
+}
+
+
+/* exported interface documented in utils/hashtable.h */
+nserror hash_add_file(struct hash_table *ht, const char *path)
+{
+ nserror res = NSERROR_OK;
+ char s[LINE_BUFFER_SIZE]; /* line buffer */
+ gzFile fp; /* compressed file handle */
+
+ if (path == NULL) {
+ return NSERROR_BAD_PARAMETER;
+ }
+
+ fp = gzopen(path, "r");
+ if (!fp) {
+ NSLOG(netsurf, INFO,
+ "Unable to open file \"%.100s\": %s", path,
+ strerror(errno));
+
+ return NSERROR_NOT_FOUND;
+ }
+
+ while (gzgets(fp, s, sizeof s)) {
+ int slen = strlen(s);
+ s[--slen] = 0; /* remove \n at end */
+
+ res = process_line(ht, (uint8_t *)s, slen);
+ if (res != NSERROR_OK) {
+ break;
+ }
+ }
+
+ gzclose(fp);
+
+ return res;
+}
+
+/* exported interface documented in utils/hashtable.h */
+nserror hash_add_inline(struct hash_table *ht, const uint8_t *data, size_t size)
+{
+ nserror res;
+ int ret; /* zlib return value */
+ z_stream strm;
+ uint8_t s[LINE_BUFFER_SIZE]; /* line buffer */
+ size_t used = 0; /* number of bytes in buffer in use */
+ uint8_t *nl;
+
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+
+ strm.next_in = (uint8_t *)data;
+ strm.avail_in = size;
+
+ ret = inflateInit2(&strm, 32 + MAX_WBITS);
+ if (ret != Z_OK) {
+ NSLOG(netsurf, INFO, "inflateInit returned %d", ret);
+ return NSERROR_INVALID;
+ }
+
+ do {
+ strm.next_out = s + used;
+ strm.avail_out = sizeof(s) - used;
+
+ ret = inflate(&strm, Z_NO_FLUSH);
+ if ((ret != Z_OK) && (ret != Z_STREAM_END)) {
+ break;
+ }
+
+ used = sizeof(s) - strm.avail_out;
+ while (used > 0) {
+ /* find nl */
+ for (nl = &s[0]; nl < &s[used]; nl++) {
+ if (*nl == '\n') {
+ break;
+ }
+ }
+ if (nl == &s[used]) {
+ /* no nl found */
+ break;
+ }
+ /* found newline */
+ *nl = 0; /* null terminate line */
+ res = process_line(ht, &s[0], nl - &s[0]);
+ if (res != NSERROR_OK) {
+ inflateEnd(&strm);
+ return res;
+ }
+
+ /* move data down */
+ memmove(&s[0], nl + 1, used - ((nl + 1) - &s[0]) );
+ used -= ((nl +1) - &s[0]);
+ }
+ if (used == sizeof(s)) {
+ /* entire buffer used and no newline */
+ NSLOG(netsurf, INFO, "Overlength line");
+ used = 0;
+ }
+ } while (ret != Z_STREAM_END);
+
+ inflateEnd(&strm);
+
+ if (ret != Z_STREAM_END) {
+ NSLOG(netsurf, INFO, "inflate returned %d", ret);
+ return NSERROR_INVALID;
+ }
+ return NSERROR_OK;
+
+}
diff --git a/utils/hashtable.h b/utils/hashtable.h
index b0e7392..b1c0d5c 100644
--- a/utils/hashtable.h
+++ b/utils/hashtable.h
@@ -29,8 +29,11 @@
struct hash_table;
/**
- * Create a new hash table, and return a context for it. The memory consumption
- * of a hash table is approximately 8 + (nchains * 12) bytes if it is empty.
+ * Create a new hash table
+ *
+ * Allocate a new hash table and return a context for it. The memory
+ * consumption of a hash table is approximately 8 + (nchains * 12)
+ * bytes if it is empty.
*
* \param chains Number of chains/buckets this hash table will have. This
* should be a prime number, and ideally a prime number just
@@ -41,18 +44,22 @@ struct hash_table;
struct hash_table *hash_create(unsigned int chains);
/**
- * Destroys a hash table, freeing all memory associated with it.
+ * Destroys a hash table
+ *
+ * Destroy a hash table freeing all memory associated with it.
*
* \param ht Hash table to destroy. After the function returns, this
- * will nolonger be valid.
+ * will no longer be valid.
*/
void hash_destroy(struct hash_table *ht);
/**
- * Adds a key/value pair to a hash table. If the key you're adding is already
- * in the hash table, it does not replace it, but it does take precedent over
- * it. The old key/value pair will be inaccessable but still in memory until
- * hash_destroy() is called on the hash table.
+ * Adds a key/value pair to a hash table.
+ *
+ * If the key you're adding is already in the hash table, it does not
+ * replace it, but it does take precedent over it. The old key/value
+ * pair will be inaccessable but still in memory until hash_destroy()
+ * is called on the hash table.
*
* \param ht The hash table context to add the key/value pair to.
* \param key The key to associate the value with. A copy is made.
@@ -71,4 +78,34 @@ bool hash_add(struct hash_table *ht, const char *key, const char
*value);
*/
const char *hash_get(struct hash_table *ht, const char *key);
+/**
+ * Add key/value pairs to a hash table with data from a file
+ *
+ * The file should be formatted as a series of lines terminated with
+ * newline character. Each line should contain a key/value pair
+ * separated by a colon. If a line is empty or starts with a #
+ * character it will be ignored.
+ *
+ * The file may be optionally gzip compressed.
+ *
+ * \param ht The hash table context to add the key/value pairs to.
+ * \param path Path to file with key/value pairs in.
+ * \return NSERROR_OK on success else error code
+ */
+nserror hash_add_file(struct hash_table *ht, const char *path);
+
+/**
+ * Add key/value pairs to a hash table with data from a memory buffer
+ *
+ * The data format is the same as in hash_add_file() but held in memory
+ *
+ * The data may optionally be gzip compressed.
+ *
+ * \param ht The hash table context to add the key/value pairs to.
+ * \param data Source of key/value pairs
+ * \param size length of \a data
+ * \return NSERROR_OK on success else error code
+ */
+nserror hash_add_inline(struct hash_table *ht, const uint8_t *data, size_t size);
+
#endif
diff --git a/utils/messages.c b/utils/messages.c
index e2d45e9..e1e6120 100644
--- a/utils/messages.c
+++ b/utils/messages.c
@@ -45,66 +45,19 @@
/** The hash table used to store the standard Messages file for the old API */
static struct hash_table *messages_hash = NULL;
-/**
- * process a line of input.
- */
-static nserror
-message_process_line(struct hash_table *hash, uint8_t *ln, int lnlen)
-{
- uint8_t *value;
- uint8_t *colon;
-
- /* empty or comment lines */
- if (ln[0] == 0 || ln[0] == '#') {
- return NSERROR_OK;
- }
-
- /* find first colon as key/value separator */
- for (colon = ln; colon < (ln + lnlen); colon++) {
- if (*colon == ':') {
- break;
- }
- }
- if (colon == (ln + lnlen)) {
- /* no colon found */
- return NSERROR_INVALID;
- }
-
- *colon = 0; /* terminate key */
- value = colon + 1;
-
- if (hash_add(hash, (char *)ln, (char *)value) == false) {
- NSLOG(netsurf, INFO, "Unable to add %s:%s to hash table", ln,
- value);
- return NSERROR_INVALID;
- }
- return NSERROR_OK;
-}
/**
* Read keys and values from messages file.
*
* \param path pathname of messages file
- * \param ctx reference of hash table to merge with.
+ * \param ctx reference of hash table to merge with or NULL to create one.
* \return NSERROR_OK on sucess and ctx updated or error code on faliure.
*/
static nserror messages_load_ctx(const char *path, struct hash_table **ctx)
{
- char s[400]; /* line buffer */
- gzFile fp; /* compressed file handle */
struct hash_table *nctx; /* new context */
-
- assert(path != NULL);
-
- fp = gzopen(path, "r");
- if (!fp) {
- NSLOG(netsurf, INFO,
- "Unable to open messages file \"%.100s\": %s", path,
- strerror(errno));
-
- return NSERROR_NOT_FOUND;
- }
-
+ nserror res;
+
if (*ctx == NULL) {
nctx = hash_create(HASH_SIZE);
} else {
@@ -118,40 +71,16 @@ static nserror messages_load_ctx(const char *path, struct hash_table
**ctx)
NSLOG(netsurf, INFO,
"Unable to create hash table for messages file %s",
path);
- gzclose(fp);
return NSERROR_NOMEM;
}
- while (gzgets(fp, s, sizeof s)) {
- char *colon, *value;
-
- if (s[0] == 0 || s[0] == '#')
- continue;
-
- s[strlen(s) - 1] = 0; /* remove \n at end */
- colon = strchr(s, ':');
- if (!colon)
- continue;
- *colon = 0; /* terminate key */
- value = colon + 1;
-
- if (hash_add(nctx, s, value) == false) {
- NSLOG(netsurf, INFO,
- "Unable to add %s:%s to hash table of %s", s,
- value, path);
- gzclose(fp);
- if (*ctx == NULL) {
- hash_destroy(nctx);
- }
- return NSERROR_INVALID;
- }
- }
-
- gzclose(fp);
- *ctx = nctx;
+ res = hash_add_file(nctx, path);
+ if (res == NSERROR_OK) {
+ *ctx = nctx;
+ }
- return NSERROR_OK;
+ return res;
}
@@ -203,30 +132,19 @@ static void messages_destroy_ctx(struct hash_table *ctx)
/* exported interface documented in messages.h */
nserror messages_add_from_file(const char *path)
{
- nserror err;
-
if (path == NULL) {
return NSERROR_BAD_PARAMETER;
}
NSLOG(netsurf, INFO, "Loading Messages from '%s'", path);
- err = messages_load_ctx(path, &messages_hash);
-
-
- return err;
+ return messages_load_ctx(path, &messages_hash);
}
/* exported interface documented in messages.h */
-nserror messages_add_from_inline(const uint8_t *data, size_t data_size)
+nserror messages_add_from_inline(const uint8_t *data, size_t size)
{
- z_stream strm;
- int ret;
- uint8_t s[512]; /* line buffer */
- size_t used = 0; /* number of bytes in buffer in use */
- uint8_t *nl;
-
/* ensure the hash table is initialised */
if (messages_hash == NULL) {
messages_hash = hash_create(HASH_SIZE);
@@ -235,61 +153,7 @@ nserror messages_add_from_inline(const uint8_t *data, size_t
data_size)
NSLOG(netsurf, INFO, "Unable to create hash table");
return NSERROR_NOMEM;
}
-
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
-
- strm.next_in = (uint8_t *)data;
- strm.avail_in = data_size;
-
- ret = inflateInit2(&strm, 32 + MAX_WBITS);
- if (ret != Z_OK) {
- NSLOG(netsurf, INFO, "inflateInit returned %d", ret);
- return NSERROR_INVALID;
- }
-
- do {
- strm.next_out = s + used;
- strm.avail_out = sizeof(s) - used;
-
- ret = inflate(&strm, Z_NO_FLUSH);
- if ((ret != Z_OK) && (ret != Z_STREAM_END)) {
- break;
- }
-
- used = sizeof(s) - strm.avail_out;
- while (used > 0) {
- /* find nl */
- for (nl = &s[0]; nl < &s[used]; nl++) {
- if (*nl == '\n') {
- break;
- }
- }
- if (nl == &s[used]) {
- /* no nl found */
- break;
- }
- /* found newline */
- *nl = 0; /* null terminate line */
- message_process_line(messages_hash, &s[0], nl - &s[0]);
- memmove(&s[0], nl + 1, used - ((nl + 1) - &s[0]) );
- used -= ((nl +1) - &s[0]);
- }
- if (used == sizeof(s)) {
- /* entire buffer used and no newline */
- NSLOG(netsurf, INFO, "Overlength line");
- used = 0;
- }
- } while (ret != Z_STREAM_END);
-
- inflateEnd(&strm);
-
- if (ret != Z_STREAM_END) {
- NSLOG(netsurf, INFO, "inflate returned %d", ret);
- return NSERROR_INVALID;
- }
- return NSERROR_OK;
+ return hash_add_inline(messages_hash, data, size);
}
/* exported interface documented in messages.h */
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=cfa5856eea7c0d840a1...
commit cfa5856eea7c0d840a19590baf1e66f6fee06b83
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
Initial conversion of GTK accelerators to separate config file
diff --git a/frontends/gtk/Makefile b/frontends/gtk/Makefile
index 6c2f06f..ec60ce7 100644
--- a/frontends/gtk/Makefile
+++ b/frontends/gtk/Makefile
@@ -165,7 +165,7 @@ endif
# S_FRONTEND are sources purely for the GTK frontend
S_FRONTEND := gui.c schedule.c layout_pango.c bitmap.c plotters.c \
- scaffolding.c gdk.c completion.c login.c throbber.c \
+ scaffolding.c gdk.c completion.c login.c throbber.c accelerator.c \
selection.c window.c fetch.c download.c menu.c print.c \
search.c tabs.c toolbar.c gettext.c compat.c viewdata.c \
viewsource.c preferences.c about.c resources.c corewindow.c \
diff --git a/frontends/gtk/accelerator.c b/frontends/gtk/accelerator.c
new file mode 100644
index 0000000..9339de8
--- /dev/null
+++ b/frontends/gtk/accelerator.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2018 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * NetSurf 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; version 2 of the License.
+ *
+ * NetSurf 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <
http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ * GTK accelerator support
+ *
+ */
+
+#include <stdint.h>
+#include <gtk/gtk.h>
+
+#include "utils/errors.h"
+#include "utils/hashtable.h"
+
+#include "gtk/resources.h"
+#include "gtk/accelerator.h"
+
+/** The hash table used to store the accelerators */
+static struct hash_table *accelerators_hash = NULL;
+
+nserror nsgtk_accelerator_init(char **respaths)
+{
+ nserror ret;
+ const uint8_t *data;
+ size_t data_size;
+
+ ret = nsgtk_data_from_resname("accelerators", &data, &data_size);
+ if (ret == NSERROR_OK) {
+ //ret = hashtable_add_from_inline(data, data_size);
+ } else {
+ const char *accelerators;
+ /* Obtain path to accelerators */
+ ret = nsgtk_path_from_resname("accelerators", &accelerators);
+ if (ret == NSERROR_OK) {
+ //ret = hashtable_add_from_file(messages);
+ }
+ }
+ return ret;
+}
+
+const char *nsgtk_accelerator_get_desc(const char *key)
+{
+ return NULL;
+}
diff --git a/frontends/gtk/accelerator.h b/frontends/gtk/accelerator.h
new file mode 100644
index 0000000..09c253e
--- /dev/null
+++ b/frontends/gtk/accelerator.h
@@ -0,0 +1,2 @@
+nserror nsgtk_accelerator_init(char **respaths);
+const char *nsgtk_accelerator_get_desc(const char *key);
diff --git a/frontends/gtk/gui.c b/frontends/gtk/gui.c
index 0f79a1b..3163be1 100644
--- a/frontends/gtk/gui.c
+++ b/frontends/gtk/gui.c
@@ -72,6 +72,7 @@
#include "gtk/resources.h"
#include "gtk/login.h"
#include "gtk/layout_pango.h"
+#include "gtk/accelerator.h"
bool nsgtk_complete = false;
@@ -227,7 +228,11 @@ static nserror set_defaults(struct nsoption_s *defaults)
/**
- * Initialize GTK interface.
+ * Initialize GTK specific parts of the browser.
+ *
+ * \param argc The number of arguments on the command line
+ * \param argv A string vector of command line arguments.
+ * \respath A string vector of the path elements of resources
*/
static nserror nsgtk_init(int argc, char** argv, char **respath)
{
@@ -235,20 +240,29 @@ static nserror nsgtk_init(int argc, char** argv, char **respath)
char *resource_filename;
char *addr = NULL;
nsurl *url;
- nserror error;
+ nserror res;
+
+ /* Initialise gtk accelerator table */
+ res = nsgtk_accelerator_init(respaths);
+ if (res != NSERROR_OK) {
+ NSLOG(netsurf, INFO,
+ "Unable to load gtk accelerator configuration");
+ /* not fatal if this does not load */
+ }
- error = nsgtk_builder_new_from_resname("warning", &warning_builder);
- if (error != NSERROR_OK) {
+ /* initialise warning dialog */
+ res = nsgtk_builder_new_from_resname("warning", &warning_builder);
+ if (res != NSERROR_OK) {
NSLOG(netsurf, INFO, "Unable to initialise warning dialog");
- return error;
+ return res;
}
gtk_builder_connect_signals(warning_builder, NULL);
/* set default icon if its available */
- error = nsgdk_pixbuf_new_from_resname("netsurf.xpm",
- &win_default_icon_pixbuf);
- if (error == NSERROR_OK) {
+ res = nsgdk_pixbuf_new_from_resname("netsurf.xpm",
+ &win_default_icon_pixbuf);
+ if (res == NSERROR_OK) {
NSLOG(netsurf, INFO, "Seting default window icon");
gtk_window_set_default_icon(win_default_icon_pixbuf);
}
@@ -263,25 +277,25 @@ static nserror nsgtk_init(int argc, char** argv, char **respath)
}
/* Default favicon */
- error = nsgdk_pixbuf_new_from_resname("favicon.png", &favicon_pixbuf);
- if (error != NSERROR_OK) {
+ res = nsgdk_pixbuf_new_from_resname("favicon.png", &favicon_pixbuf);
+ if (res != NSERROR_OK) {
favicon_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
false, 8, 16, 16);
}
/* arrow down icon */
- error = nsgdk_pixbuf_new_from_resname("arrow_down_8x32.png",
- &arrow_down_pixbuf);
- if (error != NSERROR_OK) {
+ res = nsgdk_pixbuf_new_from_resname("arrow_down_8x32.png",
+ &arrow_down_pixbuf);
+ if (res != NSERROR_OK) {
arrow_down_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
false, 8, 8, 32);
}
/* initialise throbber */
- error = nsgtk_throbber_init();
- if (error != NSERROR_OK) {
+ res = nsgtk_throbber_init();
+ if (res != NSERROR_OK) {
NSLOG(netsurf, INFO, "Unable to initialise throbber.");
- return error;
+ return res;
}
/* Initialise completions - cannot fail */
@@ -302,13 +316,13 @@ static nserror nsgtk_init(int argc, char** argv, char **respath)
urldb_load(nsoption_charp(url_file));
urldb_load_cookies(nsoption_charp(cookie_file));
hotlist_init(nsoption_charp(hotlist_path),
- nsoption_charp(hotlist_path));
+ nsoption_charp(hotlist_path));
/* Initialise top level UI elements */
- error = nsgtk_download_init();
- if (error != NSERROR_OK) {
+ res = nsgtk_download_init();
+ if (res != NSERROR_OK) {
NSLOG(netsurf, INFO, "Unable to initialise download window.");
- return error;
+ return res;
}
/* If there is a url specified on the command line use it */
@@ -338,19 +352,19 @@ static nserror nsgtk_init(int argc, char** argv, char **respath)
}
/* create an initial browser window */
- error = nsurl_create(addr, &url);
- if (error == NSERROR_OK) {
- error = browser_window_create(BW_CREATE_HISTORY,
- url,
- NULL,
- NULL,
- NULL);
+ res = nsurl_create(addr, &url);
+ if (res == NSERROR_OK) {
+ res = browser_window_create(BW_CREATE_HISTORY,
+ url,
+ NULL,
+ NULL,
+ NULL);
nsurl_unref(url);
}
free(addr);
- return error;
+ return res;
}
@@ -1163,7 +1177,7 @@ int main(int argc, char** argv)
NSLOG(netsurf, INFO, "Unable to load translated messages");
/** \todo decide if message load faliure should be fatal */
}
-
+
/* Locate the correct user cache directory path */
ret = get_cache_home(&cache_home);
if (ret == NSERROR_NOT_FOUND) {
@@ -1183,7 +1197,7 @@ int main(int argc, char** argv)
return 1;
}
- /* run the browser */
+ /* gtk specific initalisation and main run loop */
ret = nsgtk_init(argc, argv, respaths);
if (ret != NSERROR_OK) {
fprintf(stderr, "NetSurf gtk initialise failed (%s)\n",
diff --git a/frontends/gtk/menu.c b/frontends/gtk/menu.c
index a93ef93..6a60332 100644
--- a/frontends/gtk/menu.c
+++ b/frontends/gtk/menu.c
@@ -27,6 +27,7 @@
#include "gtk/compat.h"
#include "gtk/menu.h"
#include "gtk/warn.h"
+#include "gtk/accelerator.h"
/**
* Adds image menu item to a menu.
@@ -34,28 +35,37 @@
* \param menu the menu to add the item to
* \param item_out a pointer to the item's location in the menu struct
* \param message the menu item I18n lookup value
- * \param messageAccel the menu item accelerator I18n lookup value
* \param group the 'global' in a gtk sense accelerator group
* \return true if sucessful and \a item_out updated else false.
*/
-static bool nsgtk_menu_add_image_item(GtkMenu *menu,
- GtkWidget **item_out, const char *message,
- const char *messageAccel, GtkAccelGroup *group)
+static bool
+nsgtk_menu_add_image_item(GtkMenu *menu,
+ GtkWidget **item_out,
+ const char *message,
+ GtkAccelGroup *group)
{
unsigned int key;
GdkModifierType mod;
GtkWidget *item;
-
+ const char *accelerator_desc; /* accelerator key description */
+
item = nsgtk_image_menu_item_new_with_mnemonic(messages_get(message));
if (item == NULL) {
return false;
}
-
- gtk_accelerator_parse(messages_get(messageAccel), &key, &mod);
- if (key > 0) {
- gtk_widget_add_accelerator(item, "activate", group, key, mod,
- GTK_ACCEL_VISIBLE);
+
+ accelerator_desc = nsgtk_accelerator_get_desc(message);
+ if (accelerator_desc != NULL) {
+ gtk_accelerator_parse(accelerator_desc, &key, &mod);
+ if (key > 0) {
+ gtk_widget_add_accelerator(item,
+ "activate",
+ group,
+ key,
+ mod,
+ GTK_ACCEL_VISIBLE);
+ }
}
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
gtk_widget_show(item);
@@ -73,8 +83,7 @@ static bool nsgtk_menu_add_image_item(GtkMenu *menu,
n->m##_menu = GTK_MENU(gtk_menu_new())
#define IMAGE_ITEM(p, q, r, s, t)\
- nsgtk_menu_add_image_item(s->p##_menu, &(s->q##_menuitem), #r,\
- #r "Accel", t)
+ nsgtk_menu_add_image_item(s->p##_menu, &(s->q##_menuitem), #r, t)
#define CHECK_ITEM(p, q, r, s)\
s->q##_menuitem = GTK_CHECK_MENU_ITEM(\
@@ -130,8 +139,8 @@ static bool nsgtk_menu_add_image_item(GtkMenu *menu,
* creates an export submenu
* \param group the 'global' in a gtk sense accelerator reference
*/
-
-static struct nsgtk_export_submenu *nsgtk_menu_export_submenu(GtkAccelGroup *group)
+static struct nsgtk_export_submenu *
+nsgtk_menu_export_submenu(GtkAccelGroup *group)
{
struct nsgtk_export_submenu *ret = malloc(sizeof(struct
nsgtk_export_submenu));
@@ -157,8 +166,8 @@ static struct nsgtk_export_submenu
*nsgtk_menu_export_submenu(GtkAccelGroup *gro
* \param group the 'global' in a gtk sense accelerator reference
*/
-static struct nsgtk_scaleview_submenu *nsgtk_menu_scaleview_submenu(
- GtkAccelGroup *group)
+static struct nsgtk_scaleview_submenu *
+nsgtk_menu_scaleview_submenu(GtkAccelGroup *group)
{
struct nsgtk_scaleview_submenu *ret =
malloc(sizeof(struct nsgtk_scaleview_submenu));
@@ -185,7 +194,8 @@ static struct nsgtk_scaleview_submenu *nsgtk_menu_scaleview_submenu(
static struct nsgtk_tabs_submenu *nsgtk_menu_tabs_submenu(GtkAccelGroup *group)
{
- struct nsgtk_tabs_submenu *ret = malloc(sizeof(struct nsgtk_tabs_submenu));
+ struct nsgtk_tabs_submenu *ret;
+ ret = malloc(sizeof(struct nsgtk_tabs_submenu));
if (ret == NULL) {
nsgtk_warning(messages_get("NoMemory"), 0);
return NULL;
diff --git a/frontends/gtk/res/accelerators b/frontends/gtk/res/accelerators
new file mode 100644
index 0000000..e4140fc
--- /dev/null
+++ b/frontends/gtk/res/accelerators
@@ -0,0 +1,40 @@
+# GTK accelerator keys for menu entries
+# The keys must match those in the menus to be applied
+#
+# These are passed to gtk_accelerator_parse and must not be translated
+# The key names are the same as those in the gdk/gdkkeysyms.h header file
+# but without the leading “GDK_KEY_”.
+
+gtkNextTab:<Control>Right
+gtkPrevTab:<Control>Left
+gtkCloseTab:<Control>w
+gtkNewTab:<Control>t
+gtkNewWindow:<Control>n
+gtkOpenFile:<Control>o
+gtkCloseWindow:<Control><shift>w
+gtkSavePage:<Control>s
+gtkPrintPreview:<Control><shift>p
+gtkPrint:<Control>p
+gtkQuitMenu:<Control>q
+gtkCut:<Control>x
+gtkCopy:<Control>c
+gtkPaste:<Control>v
+gtkSelectAll:<Control>a
+gtkFind:<Control>f
+gtkStop:Escape
+gtkReload:F5
+gtkZoomPlus:<Control>plus
+gtkZoomMinus:<Control>minus
+gtkZoomNormal:<Control>0
+gtkFullScreen:F11
+gtkPageSource:<Control>U
+gtkDownloads:<Control>j
+gtkBack:<alt>Left
+gtkForward:<alt>Right
+gtkHome:<alt>Down
+gtkLocalHistory:<Control>h
+gtkGlobalHistory:<Control><shift>h
+gtkAddBookMarks:<Control>d
+gtkShowBookMarks:F6
+gtkShowCookies:F9
+gtkOpenLocation:<Control>l
diff --git a/frontends/gtk/res/netsurf.gresource.xml
b/frontends/gtk/res/netsurf.gresource.xml
index 5bae777..e824325 100644
--- a/frontends/gtk/res/netsurf.gresource.xml
+++ b/frontends/gtk/res/netsurf.gresource.xml
@@ -68,5 +68,6 @@
<file>icons/hotlist-rmv.png</file>
<file>icons/search.png</file>
<file>languages</file>
+ <file>accelerators</file>
</gresource>
</gresources>
diff --git a/frontends/gtk/resources.c b/frontends/gtk/resources.c
index ef92fef..fc3ac6f 100644
--- a/frontends/gtk/resources.c
+++ b/frontends/gtk/resources.c
@@ -129,6 +129,7 @@ static struct nsgtk_resource_s direct_resource[] = {
RES_ENTRY("icons/hotlist-rmv.png"),
RES_ENTRY("icons/search.png"),
RES_ENTRY("languages"),
+ RES_ENTRY("accelerators"),
RES_ENTRY("Messages"),
{ NULL, 0, NSGTK_RESOURCE_FILE, NULL },
};
@@ -178,11 +179,12 @@ init_resource(char **respath, struct nsgtk_resource_s *resource)
langv = g_get_language_names();
+ /* look for resource under per language paths */
while (langv[langc] != NULL) {
+ /* allocate and fill a full resource name path buffer */
resnamelen = snprintf(NULL, 0,
"/org/netsurf/%s/%s",
langv[langc], resource->name);
-
resname = malloc(resnamelen + 1);
if (resname == NULL) {
return NSERROR_NOMEM;
@@ -191,6 +193,7 @@ init_resource(char **respath, struct nsgtk_resource_s *resource)
"/org/netsurf/%s/%s",
langv[langc], resource->name);
+ /* check if resource is present */
present = g_resources_get_info(resname,
G_RESOURCE_LOOKUP_FLAGS_NONE,
NULL, NULL, NULL);
@@ -208,8 +211,9 @@ init_resource(char **respath, struct nsgtk_resource_s *resource)
langc++;
}
- resnamelen = snprintf(NULL, 0, "/org/netsurf/%s", resource->name);
+ /* allocate and fill a full resource name path buffer with no language*/
+ resnamelen = snprintf(NULL, 0, "/org/netsurf/%s", resource->name);
resname = malloc(resnamelen + 1);
if (resname == NULL) {
return NSERROR_NOMEM;
@@ -232,20 +236,22 @@ init_resource(char **respath, struct nsgtk_resource_s *resource)
#endif
+ /* look for file on disc */
resname = filepath_find(respath, resource->name);
- if (resname == NULL) {
+ if (resname != NULL) {
+ /* found an entry on the path */
+ resource->path = resname;
+ resource->type = NSGTK_RESOURCE_FILE;
+
NSLOG(netsurf, INFO,
- "Unable to find resource %s on resource path",
- resource->name);
- return NSERROR_NOT_FOUND;
+ "Found file resource path %s", resource->path);
+ return NSERROR_OK;
}
- /* found an entry on the path */
- resource->path = resname;
- resource->type = NSGTK_RESOURCE_FILE;
+ NSLOG(netsurf, INFO, "Unable to find resource %s on resource path",
+ resource->name);
- NSLOG(netsurf, INFO, "Found file resource path %s", resource->path);
- return NSERROR_OK;
+ return NSERROR_NOT_FOUND;
}
/**
@@ -381,7 +387,7 @@ find_resource_from_name(const char *resname, struct nsgtk_resource_s
*resource)
#ifdef SHOW_GRESOURCE
/**
- * Debug dump of all resources compile din via GResource.
+ * Debug dump of all resources compiled in via GResource.
*/
static void list_gresource(void)
{
diff --git a/resources/FatMessages b/resources/FatMessages
index f9a96c6..de8eed6 100644
--- a/resources/FatMessages
+++ b/resources/FatMessages
@@ -1814,51 +1814,26 @@ de.gtk.gtkNewTab:Neuer _Tab
fr.gtk.gtkNewTab:Nouvel _Onglet
it.gtk.gtkNewTab:Nuova _scheda
nl.gtk.gtkNewTab:Nieuw _Tabblad
-en.gtk.gtkNewTabAccel:<ctrl>t
-de.gtk.gtkNewTabAccel:<ctrl>t
-fr.gtk.gtkNewTabAccel:<ctrl>t
-it.gtk.gtkNewTabAccel:<ctrl>t
-nl.gtk.gtkNewTabAccel:<ctrl>t
en.gtk.gtkNewWindow:_New Window
de.gtk.gtkNewWindow:_Neues Fenster
fr.gtk.gtkNewWindow:_Nouvelle Fenêtre
it.gtk.gtkNewWindow:_Nuova finestra
nl.gtk.gtkNewWindow:_Nieuw venster
-en.gtk.gtkNewWindowAccel:<ctrl>n
-de.gtk.gtkNewWindowAccel:<ctrl>n
-fr.gtk.gtkNewWindowAccel:<ctrl>n
-it.gtk.gtkNewWindowAccel:<ctrl>n
-nl.gtk.gtkNewWindowAccel:<ctrl>n
en.gtk.gtkOpenFile:_Open File
de.gtk.gtkOpenFile:Datei öffnen
fr.gtk.gtkOpenFile:_Ouvrir un fichier
it.gtk.gtkOpenFile:_Apri file
nl.gtk.gtkOpenFile:Bestand _openen
-en.gtk.gtkOpenFileAccel:<ctrl>o
-de.gtk.gtkOpenFileAccel:<ctrl>o
-fr.gtk.gtkOpenFileAccel:<ctrl>o
-it.gtk.gtkOpenFileAccel:<ctrl>o
-nl.gtk.gtkOpenFileAccel:<ctrl>o
en.gtk.gtkCloseWindow:_Close Window
de.gtk.gtkCloseWindow:Fenster schließen
fr.gtk.gtkCloseWindow:_Fermer la fenêtre
it.gtk.gtkCloseWindow:_Chiudi finestra
nl.gtk.gtkCloseWindow:_Venster sluiten
-en.gtk.gtkCloseWindowAccel:<ctrl><shift>w
-de.gtk.gtkCloseWindowAccel:<ctrl><shift>w
-fr.gtk.gtkCloseWindowAccel:<ctrl><maj>w
-it.gtk.gtkCloseWindowAccel:<ctrl><shift>w
-nl.gtk.gtkCloseWindowAccel:<ctrl><shift>w
en.gtk.gtkSavePage:Save Page…
de.gtk.gtkSavePage:Seite speichern..
fr.gtk.gtkSavePage:Enregistrer la Page...
it.gtk.gtkSavePage:Salva pagina...
nl.gtk.gtkSavePage:Pagina bewaren...
-en.gtk.gtkSavePageAccel:<ctrl>s
-de.gtk.gtkSavePageAccel:<ctrl>s
-fr.gtk.gtkSavePageAccel:<ctrl>s
-it.gtk.gtkSavePageAccel:<ctrl>s
-nl.gtk.gtkSavePageAccel:<ctrl>s
en.gtk.gtkExport:Export
de.gtk.gtkExport:Exportieren
fr.gtk.gtkExport:Exporter
@@ -1889,62 +1864,32 @@ de.gtk.gtkPrintPreview:Druckvorschau...
fr.gtk.gtkPrintPreview:Aperçu avant impression...
it.gtk.gtkPrintPreview:Anteprima di stampa...
nl.gtk.gtkPrintPreview:Afdruk_voorbeeld...
-en.gtk.gtkPrintPreviewAccel:<ctrl><shift>p
-de.gtk.gtkPrintPreviewAccel:<ctrl><shift>p
-fr.gtk.gtkPrintPreviewAccel:<ctrl><maj>p
-it.gtk.gtkPrintPreviewAccel:<ctrl><shift>p
-nl.gtk.gtkPrintPreviewAccel:<ctrl><shift>p
en.gtk.gtkPrint:Print…
de.gtk.gtkPrint:Drucken...
fr.gtk.gtkPrint:Imprimer...
it.gtk.gtkPrint:Stampa...
nl.gtk.gtkPrint:Af_drukken...
-en.gtk.gtkPrintAccel:<ctrl>p
-de.gtk.gtkPrintAccel:<ctrl>p
-fr.gtk.gtkPrintAccel:<ctrl>p
-it.gtk.gtkPrintAccel:<ctrl>p
-nl.gtk.gtkPrintAccel:<ctrl>p
en.gtk.gtkQuitMenu:_Quit
de.gtk.gtkQuitMenu:Beenden
fr.gtk.gtkQuitMenu:_Quitter
it.gtk.gtkQuitMenu:_Esci
nl.gtk.gtkQuitMenu:A_fsluiten
-en.gtk.gtkQuitMenuAccel:<ctrl>q
-de.gtk.gtkQuitMenuAccel:<ctrl>q
-fr.gtk.gtkQuitMenuAccel:<ctrl>q
-it.gtk.gtkQuitMenuAccel:<ctrl>q
-nl.gtk.gtkQuitMenuAccel:<ctrl>q
en.gtk.gtkCut:Cu_t
de.gtk.gtkCut:Ausschneiden
fr.gtk.gtkCut:Cou_per
it.gtk.gtkCut:Ta_glia
nl.gtk.gtkCut:K_nippen
-en.gtk.gtkCutAccel:<ctrl>x
-de.gtk.gtkCutAccel:<ctrl>x
-fr.gtk.gtkCutAccel:<ctrl>x
-it.gtk.gtkCutAccel:<ctrl>x
-nl.gtk.gtkCutAccel:<ctrl>x
en.gtk.gtkCopy:_Copy
de.gtk.gtkCopy:Kopieren
fr.gtk.gtkCopy:_Copier
it.gtk.gtkCopy:_Copia
nl.gtk.gtkCopy:_Kopiëren
-en.gtk.gtkCopyAccel:<ctrl>c
-de.gtk.gtkCopyAccel:<ctrl>c
-fr.gtk.gtkCopyAccel:<ctrl>c
-it.gtk.gtkCopyAccel:<ctrl>c
-nl.gtk.gtkCopyAccel:<ctrl>c
en.gtk.gtkPaste:_Paste
de.gtk.gtkPaste:Einfügen
fr.gtk.gtkPaste:C_oller
it.gtk.gtkPaste:_Incolla
nl.gtk.gtkPaste:_Plakken
-en.gtk.gtkPasteAccel:<ctrl>v
-de.gtk.gtkPasteAccel:<ctrl>v
-fr.gtk.gtkPasteAccel:<ctrl>v
-it.gtk.gtkPasteAccel:<ctrl>v
-nl.gtk.gtkPasteAccel:<ctrl>v
en.gtk.gtkDelete:_Delete
de.gtk.gtkDelete:Löschen
fr.gtk.gtkDelete:_Supprimer
@@ -1955,21 +1900,11 @@ de.gtk.gtkSelectAll:_Alles auswählen
fr.gtk.gtkSelectAll:_Tout sélectionner
it.gtk.gtkSelectAll:Seleziona _Tutto
nl.gtk.gtkSelectAll:_Alles selecteren
-en.gtk.gtkSelectAllAccel:<ctrl>a
-de.gtk.gtkSelectAllAccel:<ctrl>a
-fr.gtk.gtkSelectAllAccel:<ctrl>a
-it.gtk.gtkSelectAllAccel:<ctrl>a
-nl.gtk.gtkSelectAllAccel:<ctrl>a
en.gtk.gtkFind:_Find…
de.gtk.gtkFind:_Finden..
fr.gtk.gtkFind:_Rechercher...
it.gtk.gtkFind:_Trova...
nl.gtk.gtkFind:_Zoeken...
-en.gtk.gtkFindAccel:<ctrl>f
-de.gtk.gtkFindAccel:<ctrl>f
-fr.gtk.gtkFindAccel:<ctrl>f
-it.gtk.gtkFindAccel:<ctrl>f
-nl.gtk.gtkFindAccel:<ctrl>f
en.gtk.gtkPreferences:P_references
de.gtk.gtkPreferences:Einstellungen
fr.gtk.gtkPreferences:P_références
@@ -1981,21 +1916,11 @@ de.gtk.gtkStop:_Stop
fr.gtk.gtkStop:_Arrêter
it.gtk.gtkStop:_Stoppa
nl.gtk.gtkStop:_Stoppen
-en.gtk.gtkStopAccel:Escape
-de.gtk.gtkStopAccel:Escape
-fr.gtk.gtkStopAccel:Échap
-it.gtk.gtkStopAccel:Escape
-nl.gtk.gtkStopAccel:Escape
en.gtk.gtkReload:_Reload
de.gtk.gtkReload:Neu laden
fr.gtk.gtkReload:_Actualiser
it.gtk.gtkReload:_Ricarica
nl.gtk.gtkReload:Ver_nieuwen
-en.gtk.gtkReloadAccel:F5
-de.gtk.gtkReloadAccel:F5
-fr.gtk.gtkReloadAccel:F5
-it.gtk.gtkReloadAccel:F5
-nl.gtk.gtkReloadAccel:F5
en.gtk.gtkScaleView:_Scale View
de.gtk.gtkScaleView:Ansicht skalieren
fr.gtk.gtkScaleView:_Zoom
@@ -2006,51 +1931,26 @@ de.gtk.gtkZoomPlus:Here_inzoomen
fr.gtk.gtkZoomPlus:Zoom _avant
it.gtk.gtkZoomPlus:_Incrementa zoom
nl.gtk.gtkZoomPlus:_Inzoomen
-en.gtk.gtkZoomPlusAccel:<ctrl>plus
-de.gtk.gtkZoomPlusAccel:<ctrl>plus
-fr.gtk.gtkZoomPlusAccel:<ctrl>+
-it.gtk.gtkZoomPlusAccel:<ctrl>più
-nl.gtk.gtkZoomPlusAccel:<ctrl>plus
en.gtk.gtkZoomMinus:Zoom _out
de.gtk.gtkZoomMinus:Herausz_oomen
fr.gtk.gtkZoomMinus:Z_oom arrière
it.gtk.gtkZoomMinus:_Diminuisci zoom
nl.gtk.gtkZoomMinus:_Uitzoomen
-en.gtk.gtkZoomMinusAccel:<ctrl>minus
-de.gtk.gtkZoomMinusAccel:<ctrl>minus
-fr.gtk.gtkZoomMinusAccel:<ctrl>-
-it.gtk.gtkZoomMinusAccel:<ctrl>meno
-nl.gtk.gtkZoomMinusAccel:<ctrl>minus
en.gtk.gtkZoomNormal:_Normal size
de.gtk.gtkZoomNormal:_Normalgröße
fr.gtk.gtkZoomNormal:_Taille Normale
it.gtk.gtkZoomNormal:Dimensione _normale
nl.gtk.gtkZoomNormal:_Originele grootte
-en.gtk.gtkZoomNormalAccel:<ctrl>0
-de.gtk.gtkZoomNormalAccel:<ctrl>0
-fr.gtk.gtkZoomNormalAccel:<ctrl>0
-it.gtk.gtkZoomNormalAccel:<ctrl>0
-nl.gtk.gtkZoomNormalAccel:<ctrl>0
en.gtk.gtkFullScreen:_Fullscreen
de.gtk.gtkFullScreen:_Vollbild
fr.gtk.gtkFullScreen:_Plein écran
it.gtk.gtkFullScreen:_Tutto schermo
nl.gtk.gtkFullScreen:_Volledig scherm
-en.gtk.gtkFullScreenAccel:F11
-de.gtk.gtkFullScreenAccel:F11
-fr.gtk.gtkFullScreenAccel:F11
-it.gtk.gtkFullScreenAccel:F11
-nl.gtk.gtkFullScreenAccel:F11
en.gtk.gtkPageSource:Page S_ource
de.gtk.gtkPageSource: Q_uelltext anzeigen
fr.gtk.gtkPageSource:Code s_ource de la page
it.gtk.gtkPageSource:Mostra s_orgente
nl.gtk.gtkPageSource:Pagina_bron
-en.gtk.gtkPageSourceAccel:<ctrl>U
-de.gtk.gtkPageSourceAccel:<ctrl>U
-fr.gtk.gtkPageSourceAccel:<ctrl>U
-it.gtk.gtkPageSourceAccel:<ctrl>U
-nl.gtk.gtkPageSourceAccel:<ctrl>U
en.gtk.gtkImages:_Images
de.gtk.gtkImages:B_ilder
fr.gtk.gtkImages:_Images
@@ -2096,11 +1996,6 @@ de.gtk.gtkDownloads:_Downloads...
fr.gtk.gtkDownloads:_Téléchargements...
it.gtk.gtkDownloads:_Trasferimenti...
nl.gtk.gtkDownloads:_Downloads...
-en.gtk.gtkDownloadsAccel:<ctrl>j
-de.gtk.gtkDownloadsAccel:<ctrl>j
-fr.gtk.gtkDownloadsAccel:<ctrl>j
-it.gtk.gtkDownloadsAccel:<ctrl>j
-nl.gtk.gtkDownloadsAccel:<ctrl>j
en.gtk.gtkSaveWindowSize:S_ave Window Size
de.gtk.gtkSaveWindowSize:Fenstergröße _speichern
fr.gtk.gtkSaveWindowSize:E_nregistrer la taille de la fenêtre
@@ -2132,122 +2027,62 @@ de.gtk.gtkBack:_Zurück
fr.gtk.gtkBack:_Précédent
it.gtk.gtkBack:_Indietro
nl.gtk.gtkBack:_Terug
-en.gtk.gtkBackAccel:<alt>Left
-de.gtk.gtkBackAccel:<alt>Left
-fr.gtk.gtkBackAccel:<alt>Gauche
-it.gtk.gtkBackAccel:<alt>Sinistra
-nl.gtk.gtkBackAccel:<alt>Linkerpijltoets
en.gtk.gtkForward:_Forward
de.gtk.gtkForward:_Vorwärts
fr.gtk.gtkForward:_Suivant
it.gtk.gtkForward:_Avanti
nl.gtk.gtkForward:_Vooruit
-en.gtk.gtkForwardAccel:<alt>Right
-de.gtk.gtkForwardAccel:<alt>Right
-fr.gtk.gtkForwardAccel:<alt>Droit
-it.gtk.gtkForwardAccel:<alt>Destra
-nl.gtk.gtkForwardAccel:<alt>Rechterpijltoets
en.gtk.gtkHome:_Home
de.gtk.gtkHome:_Startseite
fr.gtk.gtkHome:_Accueil
it.gtk.gtkHome:_Home
nl.gtk.gtkHome:_Beginpagina
-en.gtk.gtkHomeAccel:<alt>Down
-de.gtk.gtkHomeAccel:<alt>Down
-fr.gtk.gtkHomeAccel:<alt>Bas
-it.gtk.gtkHomeAccel:<alt>Giù
-nl.gtk.gtkHomeAccel:<alt>Pijl omlaag
en.gtk.gtkLocalHistory:_Local History…
de.gtk.gtkLocalHistory:_Lokaler Verlauf
fr.gtk.gtkLocalHistory:Historique _local
it.gtk.gtkLocalHistory:Cronologia _locale
nl.gtk.gtkLocalHistory:Vensterge_schiedenis
-en.gtk.gtkLocalHistoryAccel:<ctrl>h
-de.gtk.gtkLocalHistoryAccel:<ctrl>h
-fr.gtk.gtkLocalHistoryAccel:<ctrl>h
-it.gtk.gtkLocalHistoryAccel:<ctrl>h
-nl.gtk.gtkLocalHistoryAccel:<ctrl>h
en.gtk.gtkGlobalHistory:_Global History…
de.gtk.gtkGlobalHistory:_Globaler Verlauf
fr.gtk.gtkGlobalHistory:Historique _global
it.gtk.gtkGlobalHistory:Cronologia _globale
nl.gtk.gtkGlobalHistory:Browser_geschiedenis
-en.gtk.gtkGlobalHistoryAccel:<ctrl><shift>h
-de.gtk.gtkGlobalHistoryAccel:<ctrl><shift>h
-fr.gtk.gtkGlobalHistoryAccel:<ctrl><maj>h
-it.gtk.gtkGlobalHistoryAccel:<ctrl><shift>h
-nl.gtk.gtkGlobalHistoryAccel:<ctrl><shift>h
en.gtk.gtkAddBookMarks:_Add to Bookmarks…
de.gtk.gtkAddBookMarks:_Lesezeichen hinzufügen..
fr.gtk.gtkAddBookMarks:_Ajouter un marque-page..
it.gtk.gtkAddBookMarks:_Aggiungi ai segnalibri...
nl.gtk.gtkAddBookMarks:_Aan bladwijzers toevoegen...
-en.gtk.gtkAddBookMarksAccel:<ctrl>d
-de.gtk.gtkAddBookMarksAccel:<ctrl>d
-fr.gtk.gtkAddBookMarksAccel:<ctrl>d
-it.gtk.gtkAddBookMarksAccel:<ctrl>d
-nl.gtk.gtkAddBookMarksAccel:<ctrl>d
en.gtk.gtkShowBookMarks:_Show Bookmarks…
de.gtk.gtkShowBookMarks:Le_sezeichen anzeigen..
fr.gtk.gtkShowBookMarks:_Montrer les marques-pages...
it.gtk.gtkShowBookMarks:_Mostra segnalibri...
nl.gtk.gtkShowBookMarks:Bladwijzers _beheren...
-en.gtk.gtkShowBookMarksAccel:F6
-de.gtk.gtkShowBookMarksAccel:F6
-fr.gtk.gtkShowBookMarksAccel:F6
-it.gtk.gtkShowBookMarksAccel:F6
-nl.gtk.gtkShowBookMarksAccel:F6
en.gtk.gtkShowCookies:Show _Cookies…
de.gtk.gtkShowCookies:Zeige _Cookies…
fr.gtk.gtkShowCookies:Afficher _cookies...
it.gtk.gtkShowCookies:Mostra _cookie...
nl.gtk.gtkShowCookies:_Cookies beheren...
-en.gtk.gtkShowCookiesAccel:F9
-de.gtk.gtkShowCookiesAccel:F9
-fr.gtk.gtkShowCookiesAccel:F9
-it.gtk.gtkShowCookiesAccel:F9
-nl.gtk.gtkShowCookiesAccel:F9
en.gtk.gtkOpenLocation:_Open Location…
de.gtk.gtkOpenLocation:_Ort öffnen..
fr.gtk.gtkOpenLocation:_Ouvrir un site..
it.gtk.gtkOpenLocation:_Apri indirizzo...
nl.gtk.gtkOpenLocation:Locatie _openen..
-en.gtk.gtkOpenLocationAccel:<ctrl>l
-de.gtk.gtkOpenLocationAccel:<ctrl>l
-fr.gtk.gtkOpenLocationAccel:<ctrl>l
-it.gtk.gtkOpenLocationAccel:<ctrl>l
-nl.gtk.gtkOpenLocationAccel:<ctrl>l
en.gtk.gtkNextTab:_Next tab
de.gtk.gtkNextTab:_Nächster Tab
fr.gtk.gtkNextTab:O_nglet suivant
it.gtk.gtkNextTab:Scheda _successiva
nl.gtk.gtkNextTab:Vol_gende tabblad
-en.gtk.gtkNextTabAccel:<ctrl>Right
-de.gtk.gtkNextTabAccel:<ctrl>Right
-fr.gtk.gtkNextTabAccel:<ctrl>Droit
-it.gtk.gtkNextTabAccel:<ctrl>Destra
-nl.gtk.gtkNextTabAccel:<ctrl>Rechterpijltoets
en.gtk.gtkPrevTab:_Previous tab
de.gtk.gtkPrevTab:_Vorheriger Tab
fr.gtk.gtkPrevTab:Onglet _précédent
it.gtk.gtkPrevTab:Scheda _precedente
nl.gtk.gtkPrevTab:Vo_rige tabblad
-en.gtk.gtkPrevTabAccel:<ctrl>Left
-de.gtk.gtkPrevTabAccel:<ctrl>Left
-fr.gtk.gtkPrevTabAccel:<ctrl>Gauche
-it.gtk.gtkPrevTabAccel:<ctrl>Sinistra
-nl.gtk.gtkPrevTabAccel:<ctrl>Linkerpijltoets
en.gtk.gtkCloseTab:_Close tab
de.gtk.gtkCloseTab:Tab s_chliessen
fr.gtk.gtkCloseTab:_Fermer l'onglet
it.gtk.gtkCloseTab:_Chiudi scheda
nl.gtk.gtkCloseTab:Tabblad _sluiten
-en.gtk.gtkCloseTabAccel:<ctrl>w
-de.gtk.gtkCloseTabAccel:<ctrl>w
-fr.gtk.gtkCloseTabAccel:<ctrl>w
-it.gtk.gtkCloseTabAccel:<ctrl>w
-nl.gtk.gtkCloseTabAccel:<ctrl>w
en.gtk.gtkContents:_Contents…
de.gtk.gtkContents:_Inhalt
-----------------------------------------------------------------------
Summary of changes:
frontends/beos/filetype.cpp | 1 +
frontends/gtk/Makefile | 2 +-
frontends/gtk/accelerator.c | 79 +++++++++++
frontends/gtk/accelerator.h | 2 +
frontends/gtk/fetch.c | 3 +-
frontends/gtk/gui.c | 74 ++++++----
frontends/gtk/menu.c | 44 +++---
frontends/gtk/res/accelerators | 40 ++++++
frontends/gtk/res/netsurf.gresource.xml | 1 +
frontends/gtk/resources.c | 30 ++--
frontends/monkey/filetype.c | 1 +
resources/FatMessages | 165 ----------------------
utils/hashtable.c | 227 ++++++++++++++++++++++++++++++-
utils/hashtable.h | 53 ++++++--
utils/messages.c | 158 ++-------------------
15 files changed, 497 insertions(+), 383 deletions(-)
create mode 100644 frontends/gtk/accelerator.c
create mode 100644 frontends/gtk/accelerator.h
create mode 100644 frontends/gtk/res/accelerators
diff --git a/frontends/beos/filetype.cpp b/frontends/beos/filetype.cpp
index 7a2ca97..bc988a8 100644
--- a/frontends/beos/filetype.cpp
+++ b/frontends/beos/filetype.cpp
@@ -18,6 +18,7 @@
#define __STDBOOL_H__ 1
#include <stdbool.h>
+#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
diff --git a/frontends/gtk/Makefile b/frontends/gtk/Makefile
index 6c2f06f..ec60ce7 100644
--- a/frontends/gtk/Makefile
+++ b/frontends/gtk/Makefile
@@ -165,7 +165,7 @@ endif
# S_FRONTEND are sources purely for the GTK frontend
S_FRONTEND := gui.c schedule.c layout_pango.c bitmap.c plotters.c \
- scaffolding.c gdk.c completion.c login.c throbber.c \
+ scaffolding.c gdk.c completion.c login.c throbber.c accelerator.c \
selection.c window.c fetch.c download.c menu.c print.c \
search.c tabs.c toolbar.c gettext.c compat.c viewdata.c \
viewsource.c preferences.c about.c resources.c corewindow.c \
diff --git a/frontends/gtk/accelerator.c b/frontends/gtk/accelerator.c
new file mode 100644
index 0000000..11b7fb1
--- /dev/null
+++ b/frontends/gtk/accelerator.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2018 Vincent Sanders <vince(a)netsurf-browser.org>
+ *
+ * This file is part of NetSurf,
http://www.netsurf-browser.org/
+ *
+ * NetSurf 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; version 2 of the License.
+ *
+ * NetSurf 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <
http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ * GTK accelerator support
+ *
+ */
+
+#include <stdint.h>
+#include <gtk/gtk.h>
+
+#include "utils/log.h"
+#include "utils/errors.h"
+#include "utils/hashtable.h"
+
+#include "gtk/resources.h"
+#include "gtk/accelerator.h"
+
+/** acclelerators are stored in a fixed-size hash table. */
+#define HASH_SIZE 53
+
+/** The hash table used to store the accelerators */
+static struct hash_table *accelerators_hash = NULL;
+
+nserror nsgtk_accelerator_init(char **respaths)
+{
+ nserror res;
+ const uint8_t *data;
+ size_t data_size;
+
+ if (accelerators_hash == NULL) {
+ accelerators_hash = hash_create(HASH_SIZE);
+ }
+ if (accelerators_hash == NULL) {
+ NSLOG(netsurf, INFO, "Unable to create hash table");
+ return NSERROR_NOMEM;
+ }
+
+ res = nsgtk_data_from_resname("accelerators", &data, &data_size);
+ if (res == NSERROR_OK) {
+ res = hash_add_inline(accelerators_hash, data, data_size);
+ } else {
+ const char *accelerators_path;
+ /* Obtain path to accelerators */
+ res = nsgtk_path_from_resname("accelerators",
+ &accelerators_path);
+ if (res == NSERROR_OK) {
+ res = hash_add_file(accelerators_hash,
+ accelerators_path);
+ }
+ }
+
+ return res;
+}
+
+const char *nsgtk_accelerator_get_desc(const char *key)
+{
+ if ((key == NULL) ||
+ (accelerators_hash == NULL)) {
+ return NULL;
+ }
+ return hash_get(accelerators_hash, key);
+}
diff --git a/frontends/gtk/accelerator.h b/frontends/gtk/accelerator.h
new file mode 100644
index 0000000..09c253e
--- /dev/null
+++ b/frontends/gtk/accelerator.h
@@ -0,0 +1,2 @@
+nserror nsgtk_accelerator_init(char **respaths);
+const char *nsgtk_accelerator_get_desc(const char *key);
diff --git a/frontends/gtk/fetch.c b/frontends/gtk/fetch.c
index 7286aec..b05c1bd 100644
--- a/frontends/gtk/fetch.c
+++ b/frontends/gtk/fetch.c
@@ -30,6 +30,7 @@
* ASCII hence not using locale dependant ctype functions for parsing.
*/
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
@@ -39,8 +40,8 @@
#include <strings.h>
#include <gtk/gtk.h>
-#include "utils/hashtable.h"
#include "utils/log.h"
+#include "utils/hashtable.h"
#include "utils/filepath.h"
#include "utils/file.h"
#include "utils/nsurl.h"
diff --git a/frontends/gtk/gui.c b/frontends/gtk/gui.c
index 0f79a1b..3163be1 100644
--- a/frontends/gtk/gui.c
+++ b/frontends/gtk/gui.c
@@ -72,6 +72,7 @@
#include "gtk/resources.h"
#include "gtk/login.h"
#include "gtk/layout_pango.h"
+#include "gtk/accelerator.h"
bool nsgtk_complete = false;
@@ -227,7 +228,11 @@ static nserror set_defaults(struct nsoption_s *defaults)
/**
- * Initialize GTK interface.
+ * Initialize GTK specific parts of the browser.
+ *
+ * \param argc The number of arguments on the command line
+ * \param argv A string vector of command line arguments.
+ * \respath A string vector of the path elements of resources
*/
static nserror nsgtk_init(int argc, char** argv, char **respath)
{
@@ -235,20 +240,29 @@ static nserror nsgtk_init(int argc, char** argv, char **respath)
char *resource_filename;
char *addr = NULL;
nsurl *url;
- nserror error;
+ nserror res;
+
+ /* Initialise gtk accelerator table */
+ res = nsgtk_accelerator_init(respaths);
+ if (res != NSERROR_OK) {
+ NSLOG(netsurf, INFO,
+ "Unable to load gtk accelerator configuration");
+ /* not fatal if this does not load */
+ }
- error = nsgtk_builder_new_from_resname("warning", &warning_builder);
- if (error != NSERROR_OK) {
+ /* initialise warning dialog */
+ res = nsgtk_builder_new_from_resname("warning", &warning_builder);
+ if (res != NSERROR_OK) {
NSLOG(netsurf, INFO, "Unable to initialise warning dialog");
- return error;
+ return res;
}
gtk_builder_connect_signals(warning_builder, NULL);
/* set default icon if its available */
- error = nsgdk_pixbuf_new_from_resname("netsurf.xpm",
- &win_default_icon_pixbuf);
- if (error == NSERROR_OK) {
+ res = nsgdk_pixbuf_new_from_resname("netsurf.xpm",
+ &win_default_icon_pixbuf);
+ if (res == NSERROR_OK) {
NSLOG(netsurf, INFO, "Seting default window icon");
gtk_window_set_default_icon(win_default_icon_pixbuf);
}
@@ -263,25 +277,25 @@ static nserror nsgtk_init(int argc, char** argv, char **respath)
}
/* Default favicon */
- error = nsgdk_pixbuf_new_from_resname("favicon.png", &favicon_pixbuf);
- if (error != NSERROR_OK) {
+ res = nsgdk_pixbuf_new_from_resname("favicon.png", &favicon_pixbuf);
+ if (res != NSERROR_OK) {
favicon_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
false, 8, 16, 16);
}
/* arrow down icon */
- error = nsgdk_pixbuf_new_from_resname("arrow_down_8x32.png",
- &arrow_down_pixbuf);
- if (error != NSERROR_OK) {
+ res = nsgdk_pixbuf_new_from_resname("arrow_down_8x32.png",
+ &arrow_down_pixbuf);
+ if (res != NSERROR_OK) {
arrow_down_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
false, 8, 8, 32);
}
/* initialise throbber */
- error = nsgtk_throbber_init();
- if (error != NSERROR_OK) {
+ res = nsgtk_throbber_init();
+ if (res != NSERROR_OK) {
NSLOG(netsurf, INFO, "Unable to initialise throbber.");
- return error;
+ return res;
}
/* Initialise completions - cannot fail */
@@ -302,13 +316,13 @@ static nserror nsgtk_init(int argc, char** argv, char **respath)
urldb_load(nsoption_charp(url_file));
urldb_load_cookies(nsoption_charp(cookie_file));
hotlist_init(nsoption_charp(hotlist_path),
- nsoption_charp(hotlist_path));
+ nsoption_charp(hotlist_path));
/* Initialise top level UI elements */
- error = nsgtk_download_init();
- if (error != NSERROR_OK) {
+ res = nsgtk_download_init();
+ if (res != NSERROR_OK) {
NSLOG(netsurf, INFO, "Unable to initialise download window.");
- return error;
+ return res;
}
/* If there is a url specified on the command line use it */
@@ -338,19 +352,19 @@ static nserror nsgtk_init(int argc, char** argv, char **respath)
}
/* create an initial browser window */
- error = nsurl_create(addr, &url);
- if (error == NSERROR_OK) {
- error = browser_window_create(BW_CREATE_HISTORY,
- url,
- NULL,
- NULL,
- NULL);
+ res = nsurl_create(addr, &url);
+ if (res == NSERROR_OK) {
+ res = browser_window_create(BW_CREATE_HISTORY,
+ url,
+ NULL,
+ NULL,
+ NULL);
nsurl_unref(url);
}
free(addr);
- return error;
+ return res;
}
@@ -1163,7 +1177,7 @@ int main(int argc, char** argv)
NSLOG(netsurf, INFO, "Unable to load translated messages");
/** \todo decide if message load faliure should be fatal */
}
-
+
/* Locate the correct user cache directory path */
ret = get_cache_home(&cache_home);
if (ret == NSERROR_NOT_FOUND) {
@@ -1183,7 +1197,7 @@ int main(int argc, char** argv)
return 1;
}
- /* run the browser */
+ /* gtk specific initalisation and main run loop */
ret = nsgtk_init(argc, argv, respaths);
if (ret != NSERROR_OK) {
fprintf(stderr, "NetSurf gtk initialise failed (%s)\n",
diff --git a/frontends/gtk/menu.c b/frontends/gtk/menu.c
index a93ef93..6a60332 100644
--- a/frontends/gtk/menu.c
+++ b/frontends/gtk/menu.c
@@ -27,6 +27,7 @@
#include "gtk/compat.h"
#include "gtk/menu.h"
#include "gtk/warn.h"
+#include "gtk/accelerator.h"
/**
* Adds image menu item to a menu.
@@ -34,28 +35,37 @@
* \param menu the menu to add the item to
* \param item_out a pointer to the item's location in the menu struct
* \param message the menu item I18n lookup value
- * \param messageAccel the menu item accelerator I18n lookup value
* \param group the 'global' in a gtk sense accelerator group
* \return true if sucessful and \a item_out updated else false.
*/
-static bool nsgtk_menu_add_image_item(GtkMenu *menu,
- GtkWidget **item_out, const char *message,
- const char *messageAccel, GtkAccelGroup *group)
+static bool
+nsgtk_menu_add_image_item(GtkMenu *menu,
+ GtkWidget **item_out,
+ const char *message,
+ GtkAccelGroup *group)
{
unsigned int key;
GdkModifierType mod;
GtkWidget *item;
-
+ const char *accelerator_desc; /* accelerator key description */
+
item = nsgtk_image_menu_item_new_with_mnemonic(messages_get(message));
if (item == NULL) {
return false;
}
-
- gtk_accelerator_parse(messages_get(messageAccel), &key, &mod);
- if (key > 0) {
- gtk_widget_add_accelerator(item, "activate", group, key, mod,
- GTK_ACCEL_VISIBLE);
+
+ accelerator_desc = nsgtk_accelerator_get_desc(message);
+ if (accelerator_desc != NULL) {
+ gtk_accelerator_parse(accelerator_desc, &key, &mod);
+ if (key > 0) {
+ gtk_widget_add_accelerator(item,
+ "activate",
+ group,
+ key,
+ mod,
+ GTK_ACCEL_VISIBLE);
+ }
}
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
gtk_widget_show(item);
@@ -73,8 +83,7 @@ static bool nsgtk_menu_add_image_item(GtkMenu *menu,
n->m##_menu = GTK_MENU(gtk_menu_new())
#define IMAGE_ITEM(p, q, r, s, t)\
- nsgtk_menu_add_image_item(s->p##_menu, &(s->q##_menuitem), #r,\
- #r "Accel", t)
+ nsgtk_menu_add_image_item(s->p##_menu, &(s->q##_menuitem), #r, t)
#define CHECK_ITEM(p, q, r, s)\
s->q##_menuitem = GTK_CHECK_MENU_ITEM(\
@@ -130,8 +139,8 @@ static bool nsgtk_menu_add_image_item(GtkMenu *menu,
* creates an export submenu
* \param group the 'global' in a gtk sense accelerator reference
*/
-
-static struct nsgtk_export_submenu *nsgtk_menu_export_submenu(GtkAccelGroup *group)
+static struct nsgtk_export_submenu *
+nsgtk_menu_export_submenu(GtkAccelGroup *group)
{
struct nsgtk_export_submenu *ret = malloc(sizeof(struct
nsgtk_export_submenu));
@@ -157,8 +166,8 @@ static struct nsgtk_export_submenu
*nsgtk_menu_export_submenu(GtkAccelGroup *gro
* \param group the 'global' in a gtk sense accelerator reference
*/
-static struct nsgtk_scaleview_submenu *nsgtk_menu_scaleview_submenu(
- GtkAccelGroup *group)
+static struct nsgtk_scaleview_submenu *
+nsgtk_menu_scaleview_submenu(GtkAccelGroup *group)
{
struct nsgtk_scaleview_submenu *ret =
malloc(sizeof(struct nsgtk_scaleview_submenu));
@@ -185,7 +194,8 @@ static struct nsgtk_scaleview_submenu *nsgtk_menu_scaleview_submenu(
static struct nsgtk_tabs_submenu *nsgtk_menu_tabs_submenu(GtkAccelGroup *group)
{
- struct nsgtk_tabs_submenu *ret = malloc(sizeof(struct nsgtk_tabs_submenu));
+ struct nsgtk_tabs_submenu *ret;
+ ret = malloc(sizeof(struct nsgtk_tabs_submenu));
if (ret == NULL) {
nsgtk_warning(messages_get("NoMemory"), 0);
return NULL;
diff --git a/frontends/gtk/res/accelerators b/frontends/gtk/res/accelerators
new file mode 100644
index 0000000..2da229a
--- /dev/null
+++ b/frontends/gtk/res/accelerators
@@ -0,0 +1,40 @@
+# GTK accelerator keys for menu entries
+# The keys must match those in the menus to be applied
+#
+# These are passed to gtk_accelerator_parse and must not be translated
+# The key names are the same as those in the gdk/gdkkeysyms.h header file
+# but without the leading “GDK_KEY_”.
+
+gtkNextTab:<Control>Page_Down
+gtkPrevTab:<Control>Page_Up
+gtkCloseTab:<Control>w
+gtkNewTab:<Control>t
+gtkNewWindow:<Control>n
+gtkOpenFile:<Control>o
+gtkCloseWindow:<Control><shift>w
+gtkSavePage:<Control>s
+gtkPrintPreview:<Control><shift>p
+gtkPrint:<Control>p
+gtkQuitMenu:<Control>q
+gtkCut:<Control>x
+gtkCopy:<Control>c
+gtkPaste:<Control>v
+gtkSelectAll:<Control>a
+gtkFind:<Control>f
+gtkStop:Escape
+gtkReload:F5
+gtkZoomPlus:<Control>plus
+gtkZoomMinus:<Control>minus
+gtkZoomNormal:<Control>0
+gtkFullScreen:F11
+gtkPageSource:<Control>U
+gtkDownloads:<Control>j
+gtkBack:<alt>Left
+gtkForward:<alt>Right
+gtkHome:<alt>Down
+gtkLocalHistory:<Control>h
+gtkGlobalHistory:<Control><shift>h
+gtkAddBookMarks:<Control>d
+gtkShowBookMarks:F6
+gtkShowCookies:F9
+gtkOpenLocation:<Control>l
diff --git a/frontends/gtk/res/netsurf.gresource.xml
b/frontends/gtk/res/netsurf.gresource.xml
index 5bae777..e824325 100644
--- a/frontends/gtk/res/netsurf.gresource.xml
+++ b/frontends/gtk/res/netsurf.gresource.xml
@@ -68,5 +68,6 @@
<file>icons/hotlist-rmv.png</file>
<file>icons/search.png</file>
<file>languages</file>
+ <file>accelerators</file>
</gresource>
</gresources>
diff --git a/frontends/gtk/resources.c b/frontends/gtk/resources.c
index ef92fef..fc3ac6f 100644
--- a/frontends/gtk/resources.c
+++ b/frontends/gtk/resources.c
@@ -129,6 +129,7 @@ static struct nsgtk_resource_s direct_resource[] = {
RES_ENTRY("icons/hotlist-rmv.png"),
RES_ENTRY("icons/search.png"),
RES_ENTRY("languages"),
+ RES_ENTRY("accelerators"),
RES_ENTRY("Messages"),
{ NULL, 0, NSGTK_RESOURCE_FILE, NULL },
};
@@ -178,11 +179,12 @@ init_resource(char **respath, struct nsgtk_resource_s *resource)
langv = g_get_language_names();
+ /* look for resource under per language paths */
while (langv[langc] != NULL) {
+ /* allocate and fill a full resource name path buffer */
resnamelen = snprintf(NULL, 0,
"/org/netsurf/%s/%s",
langv[langc], resource->name);
-
resname = malloc(resnamelen + 1);
if (resname == NULL) {
return NSERROR_NOMEM;
@@ -191,6 +193,7 @@ init_resource(char **respath, struct nsgtk_resource_s *resource)
"/org/netsurf/%s/%s",
langv[langc], resource->name);
+ /* check if resource is present */
present = g_resources_get_info(resname,
G_RESOURCE_LOOKUP_FLAGS_NONE,
NULL, NULL, NULL);
@@ -208,8 +211,9 @@ init_resource(char **respath, struct nsgtk_resource_s *resource)
langc++;
}
- resnamelen = snprintf(NULL, 0, "/org/netsurf/%s", resource->name);
+ /* allocate and fill a full resource name path buffer with no language*/
+ resnamelen = snprintf(NULL, 0, "/org/netsurf/%s", resource->name);
resname = malloc(resnamelen + 1);
if (resname == NULL) {
return NSERROR_NOMEM;
@@ -232,20 +236,22 @@ init_resource(char **respath, struct nsgtk_resource_s *resource)
#endif
+ /* look for file on disc */
resname = filepath_find(respath, resource->name);
- if (resname == NULL) {
+ if (resname != NULL) {
+ /* found an entry on the path */
+ resource->path = resname;
+ resource->type = NSGTK_RESOURCE_FILE;
+
NSLOG(netsurf, INFO,
- "Unable to find resource %s on resource path",
- resource->name);
- return NSERROR_NOT_FOUND;
+ "Found file resource path %s", resource->path);
+ return NSERROR_OK;
}
- /* found an entry on the path */
- resource->path = resname;
- resource->type = NSGTK_RESOURCE_FILE;
+ NSLOG(netsurf, INFO, "Unable to find resource %s on resource path",
+ resource->name);
- NSLOG(netsurf, INFO, "Found file resource path %s", resource->path);
- return NSERROR_OK;
+ return NSERROR_NOT_FOUND;
}
/**
@@ -381,7 +387,7 @@ find_resource_from_name(const char *resname, struct nsgtk_resource_s
*resource)
#ifdef SHOW_GRESOURCE
/**
- * Debug dump of all resources compile din via GResource.
+ * Debug dump of all resources compiled in via GResource.
*/
static void list_gresource(void)
{
diff --git a/frontends/monkey/filetype.c b/frontends/monkey/filetype.c
index 979796b..65c84f9 100644
--- a/frontends/monkey/filetype.c
+++ b/frontends/monkey/filetype.c
@@ -32,6 +32,7 @@
#include <stdio.h>
#include <stdbool.h>
+#include <stdint.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
diff --git a/resources/FatMessages b/resources/FatMessages
index f9a96c6..de8eed6 100644
--- a/resources/FatMessages
+++ b/resources/FatMessages
@@ -1814,51 +1814,26 @@ de.gtk.gtkNewTab:Neuer _Tab
fr.gtk.gtkNewTab:Nouvel _Onglet
it.gtk.gtkNewTab:Nuova _scheda
nl.gtk.gtkNewTab:Nieuw _Tabblad
-en.gtk.gtkNewTabAccel:<ctrl>t
-de.gtk.gtkNewTabAccel:<ctrl>t
-fr.gtk.gtkNewTabAccel:<ctrl>t
-it.gtk.gtkNewTabAccel:<ctrl>t
-nl.gtk.gtkNewTabAccel:<ctrl>t
en.gtk.gtkNewWindow:_New Window
de.gtk.gtkNewWindow:_Neues Fenster
fr.gtk.gtkNewWindow:_Nouvelle Fenêtre
it.gtk.gtkNewWindow:_Nuova finestra
nl.gtk.gtkNewWindow:_Nieuw venster
-en.gtk.gtkNewWindowAccel:<ctrl>n
-de.gtk.gtkNewWindowAccel:<ctrl>n
-fr.gtk.gtkNewWindowAccel:<ctrl>n
-it.gtk.gtkNewWindowAccel:<ctrl>n
-nl.gtk.gtkNewWindowAccel:<ctrl>n
en.gtk.gtkOpenFile:_Open File
de.gtk.gtkOpenFile:Datei öffnen
fr.gtk.gtkOpenFile:_Ouvrir un fichier
it.gtk.gtkOpenFile:_Apri file
nl.gtk.gtkOpenFile:Bestand _openen
-en.gtk.gtkOpenFileAccel:<ctrl>o
-de.gtk.gtkOpenFileAccel:<ctrl>o
-fr.gtk.gtkOpenFileAccel:<ctrl>o
-it.gtk.gtkOpenFileAccel:<ctrl>o
-nl.gtk.gtkOpenFileAccel:<ctrl>o
en.gtk.gtkCloseWindow:_Close Window
de.gtk.gtkCloseWindow:Fenster schließen
fr.gtk.gtkCloseWindow:_Fermer la fenêtre
it.gtk.gtkCloseWindow:_Chiudi finestra
nl.gtk.gtkCloseWindow:_Venster sluiten
-en.gtk.gtkCloseWindowAccel:<ctrl><shift>w
-de.gtk.gtkCloseWindowAccel:<ctrl><shift>w
-fr.gtk.gtkCloseWindowAccel:<ctrl><maj>w
-it.gtk.gtkCloseWindowAccel:<ctrl><shift>w
-nl.gtk.gtkCloseWindowAccel:<ctrl><shift>w
en.gtk.gtkSavePage:Save Page…
de.gtk.gtkSavePage:Seite speichern..
fr.gtk.gtkSavePage:Enregistrer la Page...
it.gtk.gtkSavePage:Salva pagina...
nl.gtk.gtkSavePage:Pagina bewaren...
-en.gtk.gtkSavePageAccel:<ctrl>s
-de.gtk.gtkSavePageAccel:<ctrl>s
-fr.gtk.gtkSavePageAccel:<ctrl>s
-it.gtk.gtkSavePageAccel:<ctrl>s
-nl.gtk.gtkSavePageAccel:<ctrl>s
en.gtk.gtkExport:Export
de.gtk.gtkExport:Exportieren
fr.gtk.gtkExport:Exporter
@@ -1889,62 +1864,32 @@ de.gtk.gtkPrintPreview:Druckvorschau...
fr.gtk.gtkPrintPreview:Aperçu avant impression...
it.gtk.gtkPrintPreview:Anteprima di stampa...
nl.gtk.gtkPrintPreview:Afdruk_voorbeeld...
-en.gtk.gtkPrintPreviewAccel:<ctrl><shift>p
-de.gtk.gtkPrintPreviewAccel:<ctrl><shift>p
-fr.gtk.gtkPrintPreviewAccel:<ctrl><maj>p
-it.gtk.gtkPrintPreviewAccel:<ctrl><shift>p
-nl.gtk.gtkPrintPreviewAccel:<ctrl><shift>p
en.gtk.gtkPrint:Print…
de.gtk.gtkPrint:Drucken...
fr.gtk.gtkPrint:Imprimer...
it.gtk.gtkPrint:Stampa...
nl.gtk.gtkPrint:Af_drukken...
-en.gtk.gtkPrintAccel:<ctrl>p
-de.gtk.gtkPrintAccel:<ctrl>p
-fr.gtk.gtkPrintAccel:<ctrl>p
-it.gtk.gtkPrintAccel:<ctrl>p
-nl.gtk.gtkPrintAccel:<ctrl>p
en.gtk.gtkQuitMenu:_Quit
de.gtk.gtkQuitMenu:Beenden
fr.gtk.gtkQuitMenu:_Quitter
it.gtk.gtkQuitMenu:_Esci
nl.gtk.gtkQuitMenu:A_fsluiten
-en.gtk.gtkQuitMenuAccel:<ctrl>q
-de.gtk.gtkQuitMenuAccel:<ctrl>q
-fr.gtk.gtkQuitMenuAccel:<ctrl>q
-it.gtk.gtkQuitMenuAccel:<ctrl>q
-nl.gtk.gtkQuitMenuAccel:<ctrl>q
en.gtk.gtkCut:Cu_t
de.gtk.gtkCut:Ausschneiden
fr.gtk.gtkCut:Cou_per
it.gtk.gtkCut:Ta_glia
nl.gtk.gtkCut:K_nippen
-en.gtk.gtkCutAccel:<ctrl>x
-de.gtk.gtkCutAccel:<ctrl>x
-fr.gtk.gtkCutAccel:<ctrl>x
-it.gtk.gtkCutAccel:<ctrl>x
-nl.gtk.gtkCutAccel:<ctrl>x
en.gtk.gtkCopy:_Copy
de.gtk.gtkCopy:Kopieren
fr.gtk.gtkCopy:_Copier
it.gtk.gtkCopy:_Copia
nl.gtk.gtkCopy:_Kopiëren
-en.gtk.gtkCopyAccel:<ctrl>c
-de.gtk.gtkCopyAccel:<ctrl>c
-fr.gtk.gtkCopyAccel:<ctrl>c
-it.gtk.gtkCopyAccel:<ctrl>c
-nl.gtk.gtkCopyAccel:<ctrl>c
en.gtk.gtkPaste:_Paste
de.gtk.gtkPaste:Einfügen
fr.gtk.gtkPaste:C_oller
it.gtk.gtkPaste:_Incolla
nl.gtk.gtkPaste:_Plakken
-en.gtk.gtkPasteAccel:<ctrl>v
-de.gtk.gtkPasteAccel:<ctrl>v
-fr.gtk.gtkPasteAccel:<ctrl>v
-it.gtk.gtkPasteAccel:<ctrl>v
-nl.gtk.gtkPasteAccel:<ctrl>v
en.gtk.gtkDelete:_Delete
de.gtk.gtkDelete:Löschen
fr.gtk.gtkDelete:_Supprimer
@@ -1955,21 +1900,11 @@ de.gtk.gtkSelectAll:_Alles auswählen
fr.gtk.gtkSelectAll:_Tout sélectionner
it.gtk.gtkSelectAll:Seleziona _Tutto
nl.gtk.gtkSelectAll:_Alles selecteren
-en.gtk.gtkSelectAllAccel:<ctrl>a
-de.gtk.gtkSelectAllAccel:<ctrl>a
-fr.gtk.gtkSelectAllAccel:<ctrl>a
-it.gtk.gtkSelectAllAccel:<ctrl>a
-nl.gtk.gtkSelectAllAccel:<ctrl>a
en.gtk.gtkFind:_Find…
de.gtk.gtkFind:_Finden..
fr.gtk.gtkFind:_Rechercher...
it.gtk.gtkFind:_Trova...
nl.gtk.gtkFind:_Zoeken...
-en.gtk.gtkFindAccel:<ctrl>f
-de.gtk.gtkFindAccel:<ctrl>f
-fr.gtk.gtkFindAccel:<ctrl>f
-it.gtk.gtkFindAccel:<ctrl>f
-nl.gtk.gtkFindAccel:<ctrl>f
en.gtk.gtkPreferences:P_references
de.gtk.gtkPreferences:Einstellungen
fr.gtk.gtkPreferences:P_références
@@ -1981,21 +1916,11 @@ de.gtk.gtkStop:_Stop
fr.gtk.gtkStop:_Arrêter
it.gtk.gtkStop:_Stoppa
nl.gtk.gtkStop:_Stoppen
-en.gtk.gtkStopAccel:Escape
-de.gtk.gtkStopAccel:Escape
-fr.gtk.gtkStopAccel:Échap
-it.gtk.gtkStopAccel:Escape
-nl.gtk.gtkStopAccel:Escape
en.gtk.gtkReload:_Reload
de.gtk.gtkReload:Neu laden
fr.gtk.gtkReload:_Actualiser
it.gtk.gtkReload:_Ricarica
nl.gtk.gtkReload:Ver_nieuwen
-en.gtk.gtkReloadAccel:F5
-de.gtk.gtkReloadAccel:F5
-fr.gtk.gtkReloadAccel:F5
-it.gtk.gtkReloadAccel:F5
-nl.gtk.gtkReloadAccel:F5
en.gtk.gtkScaleView:_Scale View
de.gtk.gtkScaleView:Ansicht skalieren
fr.gtk.gtkScaleView:_Zoom
@@ -2006,51 +1931,26 @@ de.gtk.gtkZoomPlus:Here_inzoomen
fr.gtk.gtkZoomPlus:Zoom _avant
it.gtk.gtkZoomPlus:_Incrementa zoom
nl.gtk.gtkZoomPlus:_Inzoomen
-en.gtk.gtkZoomPlusAccel:<ctrl>plus
-de.gtk.gtkZoomPlusAccel:<ctrl>plus
-fr.gtk.gtkZoomPlusAccel:<ctrl>+
-it.gtk.gtkZoomPlusAccel:<ctrl>più
-nl.gtk.gtkZoomPlusAccel:<ctrl>plus
en.gtk.gtkZoomMinus:Zoom _out
de.gtk.gtkZoomMinus:Herausz_oomen
fr.gtk.gtkZoomMinus:Z_oom arrière
it.gtk.gtkZoomMinus:_Diminuisci zoom
nl.gtk.gtkZoomMinus:_Uitzoomen
-en.gtk.gtkZoomMinusAccel:<ctrl>minus
-de.gtk.gtkZoomMinusAccel:<ctrl>minus
-fr.gtk.gtkZoomMinusAccel:<ctrl>-
-it.gtk.gtkZoomMinusAccel:<ctrl>meno
-nl.gtk.gtkZoomMinusAccel:<ctrl>minus
en.gtk.gtkZoomNormal:_Normal size
de.gtk.gtkZoomNormal:_Normalgröße
fr.gtk.gtkZoomNormal:_Taille Normale
it.gtk.gtkZoomNormal:Dimensione _normale
nl.gtk.gtkZoomNormal:_Originele grootte
-en.gtk.gtkZoomNormalAccel:<ctrl>0
-de.gtk.gtkZoomNormalAccel:<ctrl>0
-fr.gtk.gtkZoomNormalAccel:<ctrl>0
-it.gtk.gtkZoomNormalAccel:<ctrl>0
-nl.gtk.gtkZoomNormalAccel:<ctrl>0
en.gtk.gtkFullScreen:_Fullscreen
de.gtk.gtkFullScreen:_Vollbild
fr.gtk.gtkFullScreen:_Plein écran
it.gtk.gtkFullScreen:_Tutto schermo
nl.gtk.gtkFullScreen:_Volledig scherm
-en.gtk.gtkFullScreenAccel:F11
-de.gtk.gtkFullScreenAccel:F11
-fr.gtk.gtkFullScreenAccel:F11
-it.gtk.gtkFullScreenAccel:F11
-nl.gtk.gtkFullScreenAccel:F11
en.gtk.gtkPageSource:Page S_ource
de.gtk.gtkPageSource: Q_uelltext anzeigen
fr.gtk.gtkPageSource:Code s_ource de la page
it.gtk.gtkPageSource:Mostra s_orgente
nl.gtk.gtkPageSource:Pagina_bron
-en.gtk.gtkPageSourceAccel:<ctrl>U
-de.gtk.gtkPageSourceAccel:<ctrl>U
-fr.gtk.gtkPageSourceAccel:<ctrl>U
-it.gtk.gtkPageSourceAccel:<ctrl>U
-nl.gtk.gtkPageSourceAccel:<ctrl>U
en.gtk.gtkImages:_Images
de.gtk.gtkImages:B_ilder
fr.gtk.gtkImages:_Images
@@ -2096,11 +1996,6 @@ de.gtk.gtkDownloads:_Downloads...
fr.gtk.gtkDownloads:_Téléchargements...
it.gtk.gtkDownloads:_Trasferimenti...
nl.gtk.gtkDownloads:_Downloads...
-en.gtk.gtkDownloadsAccel:<ctrl>j
-de.gtk.gtkDownloadsAccel:<ctrl>j
-fr.gtk.gtkDownloadsAccel:<ctrl>j
-it.gtk.gtkDownloadsAccel:<ctrl>j
-nl.gtk.gtkDownloadsAccel:<ctrl>j
en.gtk.gtkSaveWindowSize:S_ave Window Size
de.gtk.gtkSaveWindowSize:Fenstergröße _speichern
fr.gtk.gtkSaveWindowSize:E_nregistrer la taille de la fenêtre
@@ -2132,122 +2027,62 @@ de.gtk.gtkBack:_Zurück
fr.gtk.gtkBack:_Précédent
it.gtk.gtkBack:_Indietro
nl.gtk.gtkBack:_Terug
-en.gtk.gtkBackAccel:<alt>Left
-de.gtk.gtkBackAccel:<alt>Left
-fr.gtk.gtkBackAccel:<alt>Gauche
-it.gtk.gtkBackAccel:<alt>Sinistra
-nl.gtk.gtkBackAccel:<alt>Linkerpijltoets
en.gtk.gtkForward:_Forward
de.gtk.gtkForward:_Vorwärts
fr.gtk.gtkForward:_Suivant
it.gtk.gtkForward:_Avanti
nl.gtk.gtkForward:_Vooruit
-en.gtk.gtkForwardAccel:<alt>Right
-de.gtk.gtkForwardAccel:<alt>Right
-fr.gtk.gtkForwardAccel:<alt>Droit
-it.gtk.gtkForwardAccel:<alt>Destra
-nl.gtk.gtkForwardAccel:<alt>Rechterpijltoets
en.gtk.gtkHome:_Home
de.gtk.gtkHome:_Startseite
fr.gtk.gtkHome:_Accueil
it.gtk.gtkHome:_Home
nl.gtk.gtkHome:_Beginpagina
-en.gtk.gtkHomeAccel:<alt>Down
-de.gtk.gtkHomeAccel:<alt>Down
-fr.gtk.gtkHomeAccel:<alt>Bas
-it.gtk.gtkHomeAccel:<alt>Giù
-nl.gtk.gtkHomeAccel:<alt>Pijl omlaag
en.gtk.gtkLocalHistory:_Local History…
de.gtk.gtkLocalHistory:_Lokaler Verlauf
fr.gtk.gtkLocalHistory:Historique _local
it.gtk.gtkLocalHistory:Cronologia _locale
nl.gtk.gtkLocalHistory:Vensterge_schiedenis
-en.gtk.gtkLocalHistoryAccel:<ctrl>h
-de.gtk.gtkLocalHistoryAccel:<ctrl>h
-fr.gtk.gtkLocalHistoryAccel:<ctrl>h
-it.gtk.gtkLocalHistoryAccel:<ctrl>h
-nl.gtk.gtkLocalHistoryAccel:<ctrl>h
en.gtk.gtkGlobalHistory:_Global History…
de.gtk.gtkGlobalHistory:_Globaler Verlauf
fr.gtk.gtkGlobalHistory:Historique _global
it.gtk.gtkGlobalHistory:Cronologia _globale
nl.gtk.gtkGlobalHistory:Browser_geschiedenis
-en.gtk.gtkGlobalHistoryAccel:<ctrl><shift>h
-de.gtk.gtkGlobalHistoryAccel:<ctrl><shift>h
-fr.gtk.gtkGlobalHistoryAccel:<ctrl><maj>h
-it.gtk.gtkGlobalHistoryAccel:<ctrl><shift>h
-nl.gtk.gtkGlobalHistoryAccel:<ctrl><shift>h
en.gtk.gtkAddBookMarks:_Add to Bookmarks…
de.gtk.gtkAddBookMarks:_Lesezeichen hinzufügen..
fr.gtk.gtkAddBookMarks:_Ajouter un marque-page..
it.gtk.gtkAddBookMarks:_Aggiungi ai segnalibri...
nl.gtk.gtkAddBookMarks:_Aan bladwijzers toevoegen...
-en.gtk.gtkAddBookMarksAccel:<ctrl>d
-de.gtk.gtkAddBookMarksAccel:<ctrl>d
-fr.gtk.gtkAddBookMarksAccel:<ctrl>d
-it.gtk.gtkAddBookMarksAccel:<ctrl>d
-nl.gtk.gtkAddBookMarksAccel:<ctrl>d
en.gtk.gtkShowBookMarks:_Show Bookmarks…
de.gtk.gtkShowBookMarks:Le_sezeichen anzeigen..
fr.gtk.gtkShowBookMarks:_Montrer les marques-pages...
it.gtk.gtkShowBookMarks:_Mostra segnalibri...
nl.gtk.gtkShowBookMarks:Bladwijzers _beheren...
-en.gtk.gtkShowBookMarksAccel:F6
-de.gtk.gtkShowBookMarksAccel:F6
-fr.gtk.gtkShowBookMarksAccel:F6
-it.gtk.gtkShowBookMarksAccel:F6
-nl.gtk.gtkShowBookMarksAccel:F6
en.gtk.gtkShowCookies:Show _Cookies…
de.gtk.gtkShowCookies:Zeige _Cookies…
fr.gtk.gtkShowCookies:Afficher _cookies...
it.gtk.gtkShowCookies:Mostra _cookie...
nl.gtk.gtkShowCookies:_Cookies beheren...
-en.gtk.gtkShowCookiesAccel:F9
-de.gtk.gtkShowCookiesAccel:F9
-fr.gtk.gtkShowCookiesAccel:F9
-it.gtk.gtkShowCookiesAccel:F9
-nl.gtk.gtkShowCookiesAccel:F9
en.gtk.gtkOpenLocation:_Open Location…
de.gtk.gtkOpenLocation:_Ort öffnen..
fr.gtk.gtkOpenLocation:_Ouvrir un site..
it.gtk.gtkOpenLocation:_Apri indirizzo...
nl.gtk.gtkOpenLocation:Locatie _openen..
-en.gtk.gtkOpenLocationAccel:<ctrl>l
-de.gtk.gtkOpenLocationAccel:<ctrl>l
-fr.gtk.gtkOpenLocationAccel:<ctrl>l
-it.gtk.gtkOpenLocationAccel:<ctrl>l
-nl.gtk.gtkOpenLocationAccel:<ctrl>l
en.gtk.gtkNextTab:_Next tab
de.gtk.gtkNextTab:_Nächster Tab
fr.gtk.gtkNextTab:O_nglet suivant
it.gtk.gtkNextTab:Scheda _successiva
nl.gtk.gtkNextTab:Vol_gende tabblad
-en.gtk.gtkNextTabAccel:<ctrl>Right
-de.gtk.gtkNextTabAccel:<ctrl>Right
-fr.gtk.gtkNextTabAccel:<ctrl>Droit
-it.gtk.gtkNextTabAccel:<ctrl>Destra
-nl.gtk.gtkNextTabAccel:<ctrl>Rechterpijltoets
en.gtk.gtkPrevTab:_Previous tab
de.gtk.gtkPrevTab:_Vorheriger Tab
fr.gtk.gtkPrevTab:Onglet _précédent
it.gtk.gtkPrevTab:Scheda _precedente
nl.gtk.gtkPrevTab:Vo_rige tabblad
-en.gtk.gtkPrevTabAccel:<ctrl>Left
-de.gtk.gtkPrevTabAccel:<ctrl>Left
-fr.gtk.gtkPrevTabAccel:<ctrl>Gauche
-it.gtk.gtkPrevTabAccel:<ctrl>Sinistra
-nl.gtk.gtkPrevTabAccel:<ctrl>Linkerpijltoets
en.gtk.gtkCloseTab:_Close tab
de.gtk.gtkCloseTab:Tab s_chliessen
fr.gtk.gtkCloseTab:_Fermer l'onglet
it.gtk.gtkCloseTab:_Chiudi scheda
nl.gtk.gtkCloseTab:Tabblad _sluiten
-en.gtk.gtkCloseTabAccel:<ctrl>w
-de.gtk.gtkCloseTabAccel:<ctrl>w
-fr.gtk.gtkCloseTabAccel:<ctrl>w
-it.gtk.gtkCloseTabAccel:<ctrl>w
-nl.gtk.gtkCloseTabAccel:<ctrl>w
en.gtk.gtkContents:_Contents…
de.gtk.gtkContents:_Inhalt
diff --git a/utils/hashtable.c b/utils/hashtable.c
index 3a1711d..4935d6b 100644
--- a/utils/hashtable.c
+++ b/utils/hashtable.c
@@ -28,11 +28,15 @@
* it that has good coverage along side the other tests.
*/
+#include <stdint.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
-#include <stdbool.h>
-#include "utils/hashtable.h"
+#include <zlib.h>
+#include <errno.h>
+
#include "utils/log.h"
+#include "utils/hashtable.h"
struct hash_entry {
@@ -46,6 +50,8 @@ struct hash_table {
struct hash_entry **chain;
};
+/** maximum length of line for file or inline add */
+#define LINE_BUFFER_SIZE 512
/**
* Hash a string, returning a 32bit value. The hash algorithm used is
@@ -75,6 +81,175 @@ static inline unsigned int hash_string_fnv(const char *datum, unsigned
int *len)
}
+
+/**
+ * process a line of input.
+ *
+ * \param hash The hash table to add the line to
+ * \param ln The line to process
+ * \param lnlen The length of \ln
+ * \return NSERROR_OK on success else NSERROR_INVALID
+ */
+static nserror
+process_line(struct hash_table *hash, uint8_t *ln, int lnlen)
+{
+ uint8_t *key;
+ uint8_t *value;
+ uint8_t *colon;
+
+ key = ln; /* set key to start of line */
+ value = ln + lnlen; /* set value to end of line */
+
+ /* skip leading whitespace */
+ while ((key < value) &&
+ ((*key == ' ') || (*key == '\t'))) {
+ key++;
+ }
+
+ /* empty or comment lines */
+ if ((*key == 0) || (*key == '#')) {
+ return NSERROR_OK;
+ }
+
+ /* find first colon as key/value separator */
+ for (colon = key; colon < value; colon++) {
+ if (*colon == ':') {
+ break;
+ }
+ }
+ if (colon == value) {
+ /* no colon found */
+ return NSERROR_INVALID;
+ }
+
+ *colon = 0; /* terminate key */
+ value = colon + 1;
+
+ if (hash_add(hash, (char *)key, (char *)value) == false) {
+ NSLOG(netsurf, INFO,
+ "Unable to add %s:%s to hash table", ln, value);
+ return NSERROR_INVALID;
+ }
+ return NSERROR_OK;
+}
+
+
+/**
+ * adds key/value pairs to a hash from a memory area
+ */
+static nserror
+hash_add_inline_plain(struct hash_table *ht, const uint8_t *data, size_t size)
+{
+ uint8_t s[LINE_BUFFER_SIZE]; /* line buffer */
+ unsigned int slen = 0;
+ nserror res = NSERROR_OK;
+
+ while (size > 0) {
+ s[slen] = *data;
+
+ if (s[slen] == '\n') {
+ s[slen] = 0; /* replace newline with null termination */
+ res = process_line(ht, s, slen);
+ slen = 0;
+ if (res != NSERROR_OK) {
+ break;
+ }
+ } else {
+ slen++;
+ if (slen > sizeof s) {
+ NSLOG(netsurf, INFO, "Overlength line\n");
+ slen = 0;
+ }
+ }
+
+ size--;
+ data++;
+ }
+ if (slen > 0) {
+ s[slen] = 0;
+ res = process_line(ht, s, slen);
+ }
+
+ return res;
+}
+
+/**
+ * adds key/value pairs to a hash from a compressed memory area
+ */
+static nserror
+hash_add_inline_gzip(struct hash_table *ht, const uint8_t *data, size_t size)
+{
+ nserror res;
+ int ret; /* zlib return value */
+ z_stream strm;
+ uint8_t s[LINE_BUFFER_SIZE]; /* line buffer */
+ size_t used = 0; /* number of bytes in buffer in use */
+ uint8_t *nl;
+
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+
+ strm.next_in = (uint8_t *)data;
+ strm.avail_in = size;
+
+ ret = inflateInit2(&strm, 32 + MAX_WBITS);
+ if (ret != Z_OK) {
+ NSLOG(netsurf, INFO, "inflateInit returned %d", ret);
+ return NSERROR_INVALID;
+ }
+
+ do {
+ strm.next_out = s + used;
+ strm.avail_out = sizeof(s) - used;
+
+ ret = inflate(&strm, Z_NO_FLUSH);
+ if ((ret != Z_OK) && (ret != Z_STREAM_END)) {
+ break;
+ }
+
+ used = sizeof(s) - strm.avail_out;
+ while (used > 0) {
+ /* find nl */
+ for (nl = &s[0]; nl < &s[used]; nl++) {
+ if (*nl == '\n') {
+ break;
+ }
+ }
+ if (nl == &s[used]) {
+ /* no nl found */
+ break;
+ }
+ /* found newline */
+ *nl = 0; /* null terminate line */
+ res = process_line(ht, &s[0], nl - &s[0]);
+ if (res != NSERROR_OK) {
+ inflateEnd(&strm);
+ return res;
+ }
+
+ /* move data down */
+ memmove(&s[0], nl + 1, used - ((nl + 1) - &s[0]) );
+ used -= ((nl +1) - &s[0]);
+ }
+ if (used == sizeof(s)) {
+ /* entire buffer used and no newline */
+ NSLOG(netsurf, INFO, "Overlength line");
+ used = 0;
+ }
+ } while (ret != Z_STREAM_END);
+
+ inflateEnd(&strm);
+
+ if (ret != Z_STREAM_END) {
+ NSLOG(netsurf, INFO, "inflate returned %d", ret);
+ return NSERROR_INVALID;
+ }
+ return NSERROR_OK;
+
+}
+
+
/* exported interface documented in utils/hashtable.h */
struct hash_table *hash_create(unsigned int chains)
{
@@ -179,3 +354,51 @@ const char *hash_get(struct hash_table *ht, const char *key)
return NULL;
}
+
+
+
+/* exported interface documented in utils/hashtable.h */
+nserror hash_add_file(struct hash_table *ht, const char *path)
+{
+ nserror res = NSERROR_OK;
+ char s[LINE_BUFFER_SIZE]; /* line buffer */
+ gzFile fp; /* compressed file handle */
+
+ if (path == NULL) {
+ return NSERROR_BAD_PARAMETER;
+ }
+
+ fp = gzopen(path, "r");
+ if (!fp) {
+ NSLOG(netsurf, INFO,
+ "Unable to open file \"%.100s\": %s", path,
+ strerror(errno));
+
+ return NSERROR_NOT_FOUND;
+ }
+
+ while (gzgets(fp, s, sizeof s)) {
+ int slen = strlen(s);
+ s[--slen] = 0; /* remove \n at end */
+
+ res = process_line(ht, (uint8_t *)s, slen);
+ if (res != NSERROR_OK) {
+ break;
+ }
+ }
+
+ gzclose(fp);
+
+ return res;
+}
+
+
+/* exported interface documented in utils/hashtable.h */
+nserror hash_add_inline(struct hash_table *ht, const uint8_t *data, size_t size)
+{
+ if ((data[0]==0x1f) && (data[1] == 0x8b)) {
+ /* gzip header detected */
+ return hash_add_inline_gzip(ht, data, size);
+ }
+ return hash_add_inline_plain(ht, data, size);
+}
diff --git a/utils/hashtable.h b/utils/hashtable.h
index b0e7392..b1c0d5c 100644
--- a/utils/hashtable.h
+++ b/utils/hashtable.h
@@ -29,8 +29,11 @@
struct hash_table;
/**
- * Create a new hash table, and return a context for it. The memory consumption
- * of a hash table is approximately 8 + (nchains * 12) bytes if it is empty.
+ * Create a new hash table
+ *
+ * Allocate a new hash table and return a context for it. The memory
+ * consumption of a hash table is approximately 8 + (nchains * 12)
+ * bytes if it is empty.
*
* \param chains Number of chains/buckets this hash table will have. This
* should be a prime number, and ideally a prime number just
@@ -41,18 +44,22 @@ struct hash_table;
struct hash_table *hash_create(unsigned int chains);
/**
- * Destroys a hash table, freeing all memory associated with it.
+ * Destroys a hash table
+ *
+ * Destroy a hash table freeing all memory associated with it.
*
* \param ht Hash table to destroy. After the function returns, this
- * will nolonger be valid.
+ * will no longer be valid.
*/
void hash_destroy(struct hash_table *ht);
/**
- * Adds a key/value pair to a hash table. If the key you're adding is already
- * in the hash table, it does not replace it, but it does take precedent over
- * it. The old key/value pair will be inaccessable but still in memory until
- * hash_destroy() is called on the hash table.
+ * Adds a key/value pair to a hash table.
+ *
+ * If the key you're adding is already in the hash table, it does not
+ * replace it, but it does take precedent over it. The old key/value
+ * pair will be inaccessable but still in memory until hash_destroy()
+ * is called on the hash table.
*
* \param ht The hash table context to add the key/value pair to.
* \param key The key to associate the value with. A copy is made.
@@ -71,4 +78,34 @@ bool hash_add(struct hash_table *ht, const char *key, const char
*value);
*/
const char *hash_get(struct hash_table *ht, const char *key);
+/**
+ * Add key/value pairs to a hash table with data from a file
+ *
+ * The file should be formatted as a series of lines terminated with
+ * newline character. Each line should contain a key/value pair
+ * separated by a colon. If a line is empty or starts with a #
+ * character it will be ignored.
+ *
+ * The file may be optionally gzip compressed.
+ *
+ * \param ht The hash table context to add the key/value pairs to.
+ * \param path Path to file with key/value pairs in.
+ * \return NSERROR_OK on success else error code
+ */
+nserror hash_add_file(struct hash_table *ht, const char *path);
+
+/**
+ * Add key/value pairs to a hash table with data from a memory buffer
+ *
+ * The data format is the same as in hash_add_file() but held in memory
+ *
+ * The data may optionally be gzip compressed.
+ *
+ * \param ht The hash table context to add the key/value pairs to.
+ * \param data Source of key/value pairs
+ * \param size length of \a data
+ * \return NSERROR_OK on success else error code
+ */
+nserror hash_add_inline(struct hash_table *ht, const uint8_t *data, size_t size);
+
#endif
diff --git a/utils/messages.c b/utils/messages.c
index e2d45e9..e1e6120 100644
--- a/utils/messages.c
+++ b/utils/messages.c
@@ -45,66 +45,19 @@
/** The hash table used to store the standard Messages file for the old API */
static struct hash_table *messages_hash = NULL;
-/**
- * process a line of input.
- */
-static nserror
-message_process_line(struct hash_table *hash, uint8_t *ln, int lnlen)
-{
- uint8_t *value;
- uint8_t *colon;
-
- /* empty or comment lines */
- if (ln[0] == 0 || ln[0] == '#') {
- return NSERROR_OK;
- }
-
- /* find first colon as key/value separator */
- for (colon = ln; colon < (ln + lnlen); colon++) {
- if (*colon == ':') {
- break;
- }
- }
- if (colon == (ln + lnlen)) {
- /* no colon found */
- return NSERROR_INVALID;
- }
-
- *colon = 0; /* terminate key */
- value = colon + 1;
-
- if (hash_add(hash, (char *)ln, (char *)value) == false) {
- NSLOG(netsurf, INFO, "Unable to add %s:%s to hash table", ln,
- value);
- return NSERROR_INVALID;
- }
- return NSERROR_OK;
-}
/**
* Read keys and values from messages file.
*
* \param path pathname of messages file
- * \param ctx reference of hash table to merge with.
+ * \param ctx reference of hash table to merge with or NULL to create one.
* \return NSERROR_OK on sucess and ctx updated or error code on faliure.
*/
static nserror messages_load_ctx(const char *path, struct hash_table **ctx)
{
- char s[400]; /* line buffer */
- gzFile fp; /* compressed file handle */
struct hash_table *nctx; /* new context */
-
- assert(path != NULL);
-
- fp = gzopen(path, "r");
- if (!fp) {
- NSLOG(netsurf, INFO,
- "Unable to open messages file \"%.100s\": %s", path,
- strerror(errno));
-
- return NSERROR_NOT_FOUND;
- }
-
+ nserror res;
+
if (*ctx == NULL) {
nctx = hash_create(HASH_SIZE);
} else {
@@ -118,40 +71,16 @@ static nserror messages_load_ctx(const char *path, struct hash_table
**ctx)
NSLOG(netsurf, INFO,
"Unable to create hash table for messages file %s",
path);
- gzclose(fp);
return NSERROR_NOMEM;
}
- while (gzgets(fp, s, sizeof s)) {
- char *colon, *value;
-
- if (s[0] == 0 || s[0] == '#')
- continue;
-
- s[strlen(s) - 1] = 0; /* remove \n at end */
- colon = strchr(s, ':');
- if (!colon)
- continue;
- *colon = 0; /* terminate key */
- value = colon + 1;
-
- if (hash_add(nctx, s, value) == false) {
- NSLOG(netsurf, INFO,
- "Unable to add %s:%s to hash table of %s", s,
- value, path);
- gzclose(fp);
- if (*ctx == NULL) {
- hash_destroy(nctx);
- }
- return NSERROR_INVALID;
- }
- }
-
- gzclose(fp);
- *ctx = nctx;
+ res = hash_add_file(nctx, path);
+ if (res == NSERROR_OK) {
+ *ctx = nctx;
+ }
- return NSERROR_OK;
+ return res;
}
@@ -203,30 +132,19 @@ static void messages_destroy_ctx(struct hash_table *ctx)
/* exported interface documented in messages.h */
nserror messages_add_from_file(const char *path)
{
- nserror err;
-
if (path == NULL) {
return NSERROR_BAD_PARAMETER;
}
NSLOG(netsurf, INFO, "Loading Messages from '%s'", path);
- err = messages_load_ctx(path, &messages_hash);
-
-
- return err;
+ return messages_load_ctx(path, &messages_hash);
}
/* exported interface documented in messages.h */
-nserror messages_add_from_inline(const uint8_t *data, size_t data_size)
+nserror messages_add_from_inline(const uint8_t *data, size_t size)
{
- z_stream strm;
- int ret;
- uint8_t s[512]; /* line buffer */
- size_t used = 0; /* number of bytes in buffer in use */
- uint8_t *nl;
-
/* ensure the hash table is initialised */
if (messages_hash == NULL) {
messages_hash = hash_create(HASH_SIZE);
@@ -235,61 +153,7 @@ nserror messages_add_from_inline(const uint8_t *data, size_t
data_size)
NSLOG(netsurf, INFO, "Unable to create hash table");
return NSERROR_NOMEM;
}
-
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
-
- strm.next_in = (uint8_t *)data;
- strm.avail_in = data_size;
-
- ret = inflateInit2(&strm, 32 + MAX_WBITS);
- if (ret != Z_OK) {
- NSLOG(netsurf, INFO, "inflateInit returned %d", ret);
- return NSERROR_INVALID;
- }
-
- do {
- strm.next_out = s + used;
- strm.avail_out = sizeof(s) - used;
-
- ret = inflate(&strm, Z_NO_FLUSH);
- if ((ret != Z_OK) && (ret != Z_STREAM_END)) {
- break;
- }
-
- used = sizeof(s) - strm.avail_out;
- while (used > 0) {
- /* find nl */
- for (nl = &s[0]; nl < &s[used]; nl++) {
- if (*nl == '\n') {
- break;
- }
- }
- if (nl == &s[used]) {
- /* no nl found */
- break;
- }
- /* found newline */
- *nl = 0; /* null terminate line */
- message_process_line(messages_hash, &s[0], nl - &s[0]);
- memmove(&s[0], nl + 1, used - ((nl + 1) - &s[0]) );
- used -= ((nl +1) - &s[0]);
- }
- if (used == sizeof(s)) {
- /* entire buffer used and no newline */
- NSLOG(netsurf, INFO, "Overlength line");
- used = 0;
- }
- } while (ret != Z_STREAM_END);
-
- inflateEnd(&strm);
-
- if (ret != Z_STREAM_END) {
- NSLOG(netsurf, INFO, "inflate returned %d", ret);
- return NSERROR_INVALID;
- }
- return NSERROR_OK;
+ return hash_add_inline(messages_hash, data, size);
}
/* exported interface documented in messages.h */
--
NetSurf Browser