netsurf: branch master updated. release/3.5-242-g908db8a
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/908db8a51d21163e8c760...
...commit http://git.netsurf-browser.org/netsurf.git/commit/908db8a51d21163e8c76075...
...tree http://git.netsurf-browser.org/netsurf.git/tree/908db8a51d21163e8c7607538...
The branch, master has been updated
via 908db8a51d21163e8c7607538834693b4e2ae490 (commit)
via 378d975474315e98fe545a644f5499575d556f9d (commit)
via af191bbcc91512650ee5a2db5e1b25a20e410919 (commit)
via e0d531b824ce00b2b7c6f3c444f0855774c12f11 (commit)
via b939afe3fc70be446d9ffd6e6071a4af5cf98a8a (commit)
via 51725592c96b3cb94aa70761b10960c738815534 (commit)
via ca5b165c85e1e8cc7df286b6a0a9a061de99bcaa (commit)
via ea84f67035ea9899086223c540a79ffec328caef (commit)
via 0f5d7cfcd2daade443ea0695275171247e2cfc22 (commit)
via 8dbb61d2f57b32483d67434e9ac169b5f14e7460 (commit)
from 3303c005eedd67c5b973c64f2515b28f9a7f56d2 (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=908db8a51d21163e8c7...
commit 908db8a51d21163e8c7607538834693b4e2ae490
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
Add url percent escape test with minimal test vectors
diff --git a/test/Makefile b/test/Makefile
index 9fdb3f2..ea16b0a 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,7 +1,7 @@
#
# NetSurf unit tests
-TESTS := nsurl urldbtest nsoption bloom hashtable #llcache
+TESTS := nsurl urldbtest nsoption bloom hashtable urlescape #llcache
# nsurl sources
nsurl_SRCS := utils/corestrings.c utils/nsurl.c utils/idna.c \
@@ -34,6 +34,9 @@ bloom_SRCS := utils/bloom.c test/bloom.c
# hash table test sources
hashtable_SRCS := utils/hashtable.c test/log.c test/hashtable.c
+# url escape test sources
+urlescape_SRCS := utils/url.c test/log.c test/urlescape.c
+
# Coverage builds need additional flags
ifeq ($(MAKECMDGOALS),coverage)
COV_CFLAGS ?= -fprofile-arcs -ftest-coverage -O0
diff --git a/test/urlescape.c b/test/urlescape.c
new file mode 100644
index 0000000..5d9d932
--- /dev/null
+++ b/test/urlescape.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2016 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
+ * Test url percent encoding operations.
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <check.h>
+
+#include "utils/url.h"
+
+#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
+#define SLEN(x) (sizeof((x)) - 1)
+
+struct test_pairs {
+ const char* test;
+ const char* res;
+ const size_t res_len;
+};
+
+const char all_chars[] =
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff";
+
+const char all_escaped[] =
+ "%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F"
+ "%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F"
+ "%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F"
+ "0123456789%3A%3B%3C%3D%3E%3F"
+ "%40ABCDEFGHIJKLMNO"
+ "PQRSTUVWXYZ%5B%5C%5D%5E_"
+ "%60abcdefghijklmno"
+ "pqrstuvwxyz%7B%7C%7D%7E%7F"
+ "%80%81%82%83%84%85%86%87%88%89%8A%8B%8C%8D%8E%8F"
+ "%90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F"
+ "%A0%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF"
+ "%B0%B1%B2%B3%B4%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF"
+ "%C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF"
+ "%D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%DD%DE%DF"
+ "%E0%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF"
+ "%F0%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF";
+
+static const struct test_pairs url_escape_test_vec[] = {
+ { "", "" , 0 },
+ { "A.string.that.does.not.need.escaping",
+ "A.string.that.does.not.need.escaping" , 0 },
+ { " ", "%20" , 0 },
+ { &all_chars[0], &all_escaped[0], 0 },
+};
+
+
+START_TEST(url_escape_test)
+{
+ nserror err;
+ char *esc_str;
+ const struct test_pairs *tst = &url_escape_test_vec[_i];
+
+ err = url_escape(tst->test, false, "", &esc_str);
+ ck_assert(err == NSERROR_OK);
+
+ ck_assert_str_eq(esc_str, tst->res);
+}
+END_TEST
+
+static const struct test_pairs url_unescape_test_vec[] = {
+ { "", "" , 0 },
+ { "A.string.that.does.not.need.unescaping",
+ "A.string.that.does.not.need.unescaping",
+ SLEN("A.string.that.does.not.need.unescaping") },
+ { "%20", " " , 1 },
+ { &all_escaped[0], &all_chars[0], SLEN(all_chars) },
+};
+
+START_TEST(url_unescape_test)
+{
+ nserror err;
+ char *unesc_str;
+ size_t unesc_length;
+
+ const struct test_pairs *tst = &url_unescape_test_vec[_i];
+
+ err = url_unescape(tst->test, 0 , &unesc_length, &unesc_str);
+ ck_assert(err == NSERROR_OK);
+ /* ensure length */
+ ck_assert_uint_eq(unesc_length, tst->res_len);
+ /* ensure contents */
+ ck_assert_str_eq(unesc_str, tst->res);
+}
+END_TEST
+
+
+
+TCase *url_escape_case_create(void)
+{
+ TCase *tc;
+ tc = tcase_create("Escape");
+
+ tcase_add_loop_test(tc, url_escape_test,
+ 0, NELEMS(url_escape_test_vec));
+
+ return tc;
+}
+
+TCase *url_unescape_case_create(void)
+{
+ TCase *tc;
+ tc = tcase_create("Unescape");
+
+ tcase_add_loop_test(tc, url_unescape_test,
+ 0, NELEMS(url_unescape_test_vec));
+
+ return tc;
+}
+
+
+Suite *urlescape_suite_create(void)
+{
+ Suite *s;
+ s = suite_create("Percent escaping");
+
+ suite_add_tcase(s, url_escape_case_create());
+ suite_add_tcase(s, url_unescape_case_create());
+
+ return s;
+}
+
+
+
+int main(int argc, char **argv)
+{
+ int number_failed;
+ SRunner *sr;
+
+ sr = srunner_create(urlescape_suite_create());
+ //srunner_add_suite(sr, bar_suite_create());
+
+ srunner_run_all(sr, CK_ENV);
+
+ number_failed = srunner_ntests_failed(sr);
+ srunner_free(sr);
+
+ return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=378d975474315e98fe5...
commit 378d975474315e98fe545a644f5499575d556f9d
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
add basic documentation on unit testing using check
diff --git a/Docs/unit-testing b/Docs/unit-testing
new file mode 100644
index 0000000..49d82ed
--- /dev/null
+++ b/Docs/unit-testing
@@ -0,0 +1,166 @@
+NetSurf Unit Testing
+====================
+
+Overview
+--------
+
+NetSurf has unit tests integrated in the test directory. These tests
+use the check unit test framework for C [1].
+
+The tests are in a logical hierachy of "suite", "case" and individual
+"test". Historicaly we have split suites of tests into separate test
+programs although the framework does not madate this and some test
+programs contain more than one suite.
+
+
+Execution
+---------
+
+The test programs are executed by using the standard "test" target
+from the top level make invocation. The "coverage" target additionally
+generates code coverage reports allowing visibility on how much of a
+code module is being exercised.
+
+The check library must be installed to run the tests and the CI system
+automatically executes all enabled tests and generates coverage
+reports for each commit.
+
+Adding tests
+------------
+
+The test/Makefile defines each indiviadual test program that should be
+built and executed in the TESTS variable.
+
+The test program source files are defined in a xxx_SRCS variable and
+the make rules will then ensure the target program is built and
+executed.
+
+Each individual test program requires a main function which creates
+one (or more) suites. The suites are added to a test runner and then
+executed and the results reported.
+
+int main(int argc, char **argv)
+{
+ int number_failed;
+ SRunner *sr;
+
+ sr = srunner_create(foo_suite_create());
+ //srunner_add_suite(sr, bar_suite_create());
+
+ srunner_run_all(sr, CK_ENV);
+
+ number_failed = srunner_ntests_failed(sr);
+ srunner_free(sr);
+
+ return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+Suite creation is done with a sub function to logically split suite
+code into sub modules. Each suite has test cases added to it.
+
+Suite *foo_suite_create(void)
+{
+ Suite *s;
+ s = suite_create("foo");
+
+ suite_add_tcase(s, baz_case_create());
+ suite_add_tcase(s, qux_case_create());
+
+ return s;
+}
+
+Test cases include the actual tests to be performed within each case.
+
+TCase *baz_case_create(void)
+{
+ TCase *tc;
+ tc = tcase_create("Baz");
+
+ tcase_add_test(tc, xxyz_test);
+ tcase_add_test(tc, zzyx_test);
+
+ return tc;
+}
+
+A test case may optionally have a fixture which is code that is
+executed before and after each test case. Unchecked fixtures are
+executed once before the test process forks for each test whereas
+checked fixtures are executed for each and every test.
+
+static void fixture_setup(void)
+{
+}
+
+static void fixture_teardown(void)
+{
+}
+
+TCase *qux_case_create(void)
+{
+ TCase *tc;
+
+ /* Matching entry tests */
+ tc = tcase_create("Match");
+
+ tcase_add_checked_fixture(tc,
+ fixture_setup,
+ fixture_teardown);
+
+ tcase_add_test(tc, zzz_test);
+
+ return tc;
+}
+
+Additionally test cases can contain tests executed in a loop. The test
+recives a single integer as a parameter named _i which iterates
+between values specified in the case setup.
+
+TCase *baz_case_create(void)
+{
+ TCase *tc;
+ tc = tcase_create("Baz");
+
+ tcase_add_loop_test(tc, looping_test, 0, 5);
+
+ return tc;
+}
+
+It is also possible to create tests which will generate a signal. The
+most commonly used of these is to check asserts in API calls.
+
+TCase *baz_case_create(void)
+{
+ TCase *tc;
+ tc = tcase_create("Baz");
+
+ tcase_add_test_raise_signal(tc, assert_test, 6);
+
+ return tc;
+}
+
+
+Actual test code is self contained in a function which uses the
+ck_assert macros to test results. The check framework requires each
+test to use the START_TEST and END_TEST macros when definig them.
+
+/**
+ * url access leaf test
+ */
+START_TEST(nsurl_access_leaf_test)
+{
+ nserror err;
+ nsurl *res_url;
+ const struct test_triplets *tst = &access_tests[_i];
+
+ /* not testing create, this should always succeed */
+ err = nsurl_create(tst->test1, &res_url);
+ ck_assert(err == NSERROR_OK);
+
+ ck_assert_str_eq(nsurl_access_leaf(res_url), tst->res);
+
+ nsurl_unref(res_url);
+}
+END_TEST
+
+
+[1] https://libcheck.github.io/check/
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=af191bbcc91512650ee...
commit af191bbcc91512650ee5a2db5e1b25a20e410919
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
make gtk certificate viewing use gtk core window API
diff --git a/frontends/gtk/ssl_cert.c b/frontends/gtk/ssl_cert.c
index e3bc8a7..1cf0beb 100644
--- a/frontends/gtk/ssl_cert.c
+++ b/frontends/gtk/ssl_cert.c
@@ -16,122 +16,250 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+/**
+ * \file
+ * Implementation of gtk certificate viewing using gtk core windows.
+ */
+
+#include <stdint.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include "utils/log.h"
-#include "utils/nsurl.h"
-#include "desktop/tree.h"
+#include "netsurf/keypress.h"
+#include "netsurf/plotters.h"
#include "desktop/sslcert_viewer.h"
+#include "desktop/treeview.h"
-#include "gtk/treeview.h"
+#include "gtk/plotters.h"
#include "gtk/scaffolding.h"
#include "gtk/resources.h"
#include "gtk/ssl_cert.h"
+#include "gtk/corewindow.h"
+
+
+/**
+ * GTK certificate viewing window context
+ */
+struct nsgtk_crtvrfy_window {
+ /** GTK core window context */
+ struct nsgtk_corewindow core;
+ /** GTK builder for window */
+ GtkBuilder *builder;
+ /** GTK dialog window being shown */
+ GtkDialog *dlg;
+ /** SSL certificate viewer context data */
+ struct sslcert_session_data *ssl_data;
+};
+/**
+ * destroy a previously created certificate view
+ */
+static nserror nsgtk_crtvrfy_destroy(struct nsgtk_crtvrfy_window *crtvrfy_win)
+{
+ nserror res;
-static void nsgtk_ssl_accept(GtkButton *w, gpointer data)
+ res = sslcert_viewer_fini(crtvrfy_win->ssl_data);
+ if (res == NSERROR_OK) {
+ res = nsgtk_corewindow_fini(&crtvrfy_win->core);
+ gtk_widget_destroy(GTK_WIDGET(crtvrfy_win->dlg));
+ g_object_unref(G_OBJECT(crtvrfy_win->builder));
+ free(crtvrfy_win);
+ }
+ return res;
+}
+
+static void
+nsgtk_crtvrfy_accept(GtkButton *w, gpointer data)
{
- void **session = data;
- GtkBuilder *x = session[0];
- struct nsgtk_treeview *wnd = session[1];
- struct sslcert_session_data *ssl_data = session[2];
+ struct nsgtk_crtvrfy_window *crtvrfy_win;
+ crtvrfy_win = (struct nsgtk_crtvrfy_window *)data;
- sslcert_viewer_accept(ssl_data);
+ sslcert_viewer_accept(crtvrfy_win->ssl_data);
- nsgtk_treeview_destroy(wnd);
- g_object_unref(G_OBJECT(x));
- free(session);
+ nsgtk_crtvrfy_destroy(crtvrfy_win);
}
-static void nsgtk_ssl_reject(GtkWidget *w, gpointer data)
+static void
+nsgtk_crtvrfy_reject(GtkWidget *w, gpointer data)
{
- void **session = data;
- GtkBuilder *x = session[0];
- struct nsgtk_treeview *wnd = session[1];
- struct sslcert_session_data *ssl_data = session[2];
+ struct nsgtk_crtvrfy_window *crtvrfy_win;
+ crtvrfy_win = (struct nsgtk_crtvrfy_window *)data;
- sslcert_viewer_reject(ssl_data);
+ sslcert_viewer_reject(crtvrfy_win->ssl_data);
- nsgtk_treeview_destroy(wnd);
- g_object_unref(G_OBJECT(x));
- free(session);
+ nsgtk_crtvrfy_destroy(crtvrfy_win);
}
-static gboolean nsgtk_ssl_delete_event(GtkWidget *w, GdkEvent *event, gpointer data)
+static gboolean
+nsgtk_crtvrfy_delete_event(GtkWidget *w, GdkEvent *event, gpointer data)
{
- nsgtk_ssl_reject(w, data);
+ nsgtk_crtvrfy_reject(w, data);
return FALSE;
}
-nserror gtk_cert_verify(nsurl *url, const struct ssl_cert_info *certs,
- unsigned long num, nserror (*cb)(bool proceed, void *pw),
- void *cbpw)
+/**
+ * callback for mouse action for certificate verify on core window
+ *
+ * \param nsgtk_cw The nsgtk core window structure.
+ * \param mouse_state netsurf mouse state on event
+ * \param x location of event
+ * \param y location of event
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+nsgtk_crtvrfy_mouse(struct nsgtk_corewindow *nsgtk_cw,
+ browser_mouse_state mouse_state,
+ int x, int y)
+{
+ struct nsgtk_crtvrfy_window *crtvrfy_win;
+ /* technically degenerate container of */
+ crtvrfy_win = (struct nsgtk_crtvrfy_window *)nsgtk_cw;
+
+ sslcert_viewer_mouse_action(crtvrfy_win->ssl_data, mouse_state, x, y);
+
+ return NSERROR_OK;
+}
+
+/**
+ * callback for keypress for certificate verify on core window
+ *
+ * \param nsgtk_cw The nsgtk core window structure.
+ * \param nskey The netsurf key code
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+nsgtk_crtvrfy_key(struct nsgtk_corewindow *nsgtk_cw, uint32_t nskey)
{
- static struct nsgtk_treeview *ssl_window;
- struct sslcert_session_data *data;
- GtkButton *accept, *reject;
- void **session;
- GtkDialog *dlg;
- GtkScrolledWindow *scrolled;
- GtkDrawingArea *drawing_area;
- GtkBuilder *builder;
- GtkWindow *gtk_parent;
+ struct nsgtk_crtvrfy_window *crtvrfy_win;
+
+ /* technically degenerate container of */
+ crtvrfy_win = (struct nsgtk_crtvrfy_window *)nsgtk_cw;
+
+ if (sslcert_viewer_keypress(crtvrfy_win->ssl_data, nskey)) {
+ return NSERROR_OK;
+ }
+ return NSERROR_NOT_IMPLEMENTED;
+}
+
+/**
+ * callback on draw event for certificate verify on core window
+ *
+ * \param nsgtk_cw The nsgtk core window structure.
+ * \param r The rectangle of the window that needs updating.
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+nsgtk_crtvrfy_draw(struct nsgtk_corewindow *nsgtk_cw, struct rect *r)
+{
+ struct redraw_context ctx = {
+ .interactive = true,
+ .background_images = true,
+ .plot = &nsgtk_plotters
+ };
+ struct nsgtk_crtvrfy_window *crtvrfy_win;
+
+ /* technically degenerate container of */
+ crtvrfy_win = (struct nsgtk_crtvrfy_window *)nsgtk_cw;
+
+ sslcert_viewer_redraw(crtvrfy_win->ssl_data, 0, 0, r, &ctx);
+
+ return NSERROR_OK;
+}
+
+/* exported interface documented in gtk/ssl_cert.h */
+nserror gtk_cert_verify(struct nsurl *url,
+ const struct ssl_cert_info *certs,
+ unsigned long num,
+ nserror (*cb)(bool proceed, void *pw),
+ void *cbpw)
+{
+ struct nsgtk_crtvrfy_window *ncwin;
nserror res;
- /* state while dlg is open */
- session = calloc(sizeof(void *), 3);
- if (session == NULL) {
+ res = treeview_init(0);
+ if (res != NSERROR_OK) {
+ return res;
+ }
+
+ ncwin = malloc(sizeof(struct nsgtk_crtvrfy_window));
+ if (ncwin == NULL) {
return NSERROR_NOMEM;
}
- res = nsgtk_builder_new_from_resname("ssl", &builder);
+ res = nsgtk_builder_new_from_resname("ssl", &ncwin->builder);
if (res != NSERROR_OK) {
LOG("SSL UI builder init failed");
- free(session);
- return NSERROR_INIT_FAILED;
+ free(ncwin);
+ return res;
}
- gtk_builder_connect_signals(builder, NULL);
-
- sslcert_viewer_create_session_data(num, url, cb, cbpw, certs, &data);
+ gtk_builder_connect_signals(ncwin->builder, NULL);
- dlg = GTK_DIALOG(gtk_builder_get_object(builder, "wndSSLProblem"));
+ ncwin->dlg = GTK_DIALOG(gtk_builder_get_object(ncwin->builder,
+ "wndSSLProblem"));
/* set parent for transient dialog */
- gtk_parent = nsgtk_scaffolding_window(nsgtk_current_scaffolding());
- gtk_window_set_transient_for(GTK_WINDOW(dlg), gtk_parent);
-
- scrolled = GTK_SCROLLED_WINDOW(gtk_builder_get_object(builder, "SSLScrolled"));
- drawing_area = GTK_DRAWING_AREA(gtk_builder_get_object(builder, "SSLDrawingArea"));
-
- ssl_window = nsgtk_treeview_create(TREE_SSLCERT,
- GTK_WINDOW(dlg),
- scrolled,
- drawing_area,
- data);
- if (ssl_window == NULL) {
- free(session);
- g_object_unref(G_OBJECT(dlg));
- return NSERROR_INIT_FAILED;
- }
+ gtk_window_set_transient_for(GTK_WINDOW(ncwin->dlg),
+ nsgtk_scaffolding_window(nsgtk_current_scaffolding()));
+
+ ncwin->core.scrolled = GTK_SCROLLED_WINDOW(
+ gtk_builder_get_object(ncwin->builder, "SSLScrolled"));
+
+ ncwin->core.drawing_area = GTK_DRAWING_AREA(
+ gtk_builder_get_object(ncwin->builder, "SSLDrawingArea"));
+
+ /* make the delete event call our destructor */
+ g_signal_connect(G_OBJECT(ncwin->dlg),
+ "delete_event",
+ G_CALLBACK(nsgtk_crtvrfy_delete_event),
+ ncwin);
+
+ /* accept button */
+ g_signal_connect(G_OBJECT(gtk_builder_get_object(ncwin->builder,
+ "sslaccept")),
+ "clicked",
+ G_CALLBACK(nsgtk_crtvrfy_accept),
+ ncwin);
- accept = GTK_BUTTON(gtk_builder_get_object(builder, "sslaccept"));
- reject = GTK_BUTTON(gtk_builder_get_object(builder, "sslreject"));
+ /* reject button */
+ g_signal_connect(G_OBJECT(gtk_builder_get_object(ncwin->builder,
+ "sslreject")),
+ "clicked",
+ G_CALLBACK(nsgtk_crtvrfy_reject),
+ ncwin);
- session[0] = builder;
- session[1] = ssl_window;
- session[2] = data;
+ /* initialise GTK core window */
+ ncwin->core.draw = nsgtk_crtvrfy_draw;
+ ncwin->core.key = nsgtk_crtvrfy_key;
+ ncwin->core.mouse = nsgtk_crtvrfy_mouse;
-#define CONNECT(obj, sig, callback, ptr) \
- g_signal_connect(G_OBJECT(obj), (sig), G_CALLBACK(callback), (ptr))
+ res = nsgtk_corewindow_init(&ncwin->core);
+ if (res != NSERROR_OK) {
+ g_object_unref(G_OBJECT(ncwin->dlg));
+ free(ncwin);
+ return res;
+ }
- CONNECT(accept, "clicked", nsgtk_ssl_accept, session);
- CONNECT(reject, "clicked", nsgtk_ssl_reject, session);
- CONNECT(dlg, "delete_event", G_CALLBACK(nsgtk_ssl_delete_event),
- (gpointer)session);
+ /* initialise certificate viewing interface */
+ res = sslcert_viewer_create_session_data(num, url, cb, cbpw, certs,
+ &ncwin->ssl_data);
+ if (res != NSERROR_OK) {
+ g_object_unref(G_OBJECT(ncwin->dlg));
+ free(ncwin);
+ return res;
+ }
+
+ res = sslcert_viewer_init(ncwin->core.cb_table,
+ (struct core_window *)ncwin,
+ ncwin->ssl_data);
+ if (res != NSERROR_OK) {
+ g_object_unref(G_OBJECT(ncwin->dlg));
+ free(ncwin);
+ return res;
+ }
- gtk_widget_show(GTK_WIDGET(dlg));
+ gtk_widget_show(GTK_WIDGET(ncwin->dlg));
return NSERROR_OK;
}
diff --git a/frontends/gtk/ssl_cert.h b/frontends/gtk/ssl_cert.h
index 398f1cc..1712756 100644
--- a/frontends/gtk/ssl_cert.h
+++ b/frontends/gtk/ssl_cert.h
@@ -30,6 +30,7 @@ struct ssl_cert_info;
* \param num The number of certificates to be verified.
* \param cb Callback upon user decision.
* \param cbpw Context pointer passed to cb
+ * \return NSERROR_OK or error code if prompt creation failed.
*/
nserror gtk_cert_verify(struct nsurl *url, const struct ssl_cert_info *certs, unsigned long num, nserror (*cb)(bool proceed, void *pw), void *cbpw);
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=e0d531b824ce00b2b7c...
commit e0d531b824ce00b2b7c6f3c444f0855774c12f11
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
fix certificate viewer keypress consumption return
diff --git a/desktop/sslcert_viewer.c b/desktop/sslcert_viewer.c
index f3eb169..93d6919 100644
--- a/desktop/sslcert_viewer.c
+++ b/desktop/sslcert_viewer.c
@@ -516,8 +516,7 @@ void sslcert_viewer_mouse_action(struct sslcert_session_data *ssl_d,
/* Exported interface, documented in sslcert_viewer.h */
-void sslcert_viewer_keypress(struct sslcert_session_data *ssl_d,
- uint32_t key)
+bool sslcert_viewer_keypress(struct sslcert_session_data *ssl_d, uint32_t key)
{
- treeview_keypress(ssl_d->tree, key);
+ return treeview_keypress(ssl_d->tree, key);
}
diff --git a/desktop/sslcert_viewer.h b/desktop/sslcert_viewer.h
index f7c8f33..9b21cd1 100644
--- a/desktop/sslcert_viewer.h
+++ b/desktop/sslcert_viewer.h
@@ -119,7 +119,6 @@ void sslcert_viewer_mouse_action(struct sslcert_session_data *ssl_d,
* \param key The ucs4 character codepoint
* \return true if the keypress is dealt with, false otherwise.
*/
-void sslcert_viewer_keypress(struct sslcert_session_data *ssl_d,
- uint32_t key);
+bool sslcert_viewer_keypress(struct sslcert_session_data *ssl_d, uint32_t key);
#endif
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=b939afe3fc70be446d9...
commit b939afe3fc70be446d9ffd6e6071a4af5cf98a8a
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
Allow certificate verification user prompt creation to return errors
diff --git a/content/llcache.c b/content/llcache.c
index 33a9b98..e338c1f 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -2214,6 +2214,11 @@ static nserror llcache_fetch_auth(llcache_object *object, const char *realm)
error = llcache->query_cb(&query, llcache->query_cb_pw,
llcache_query_handle_response, object);
+ if (error != NSERROR_OK) {
+ /* do not continue if error querying user */
+ error = llcache_query_handle_response(false,
+ object);
+ }
} else {
llcache_event event;
@@ -2269,6 +2274,10 @@ static nserror llcache_fetch_cert_error(llcache_object *object,
error = llcache->query_cb(&query, llcache->query_cb_pw,
llcache_query_handle_response, object);
+ if (error != NSERROR_OK) {
+ /* do not continue if error querying user */
+ error = llcache_query_handle_response(false, object);
+ }
} else {
llcache_event event;
diff --git a/desktop/gui_factory.c b/desktop/gui_factory.c
index cecbe6e..88bb9ba 100644
--- a/desktop/gui_factory.c
+++ b/desktop/gui_factory.c
@@ -685,13 +685,13 @@ static nserror gui_default_launch_url(struct nsurl *url)
}
-static void gui_default_cert_verify(nsurl *url,
+static nserror gui_default_cert_verify(nsurl *url,
const struct ssl_cert_info *certs,
unsigned long num,
nserror (*cb)(bool proceed, void *pw),
void *cbpw)
{
- cb(false, cbpw);
+ return NSERROR_NOT_IMPLEMENTED;
}
static void gui_default_401login_open(nsurl *url, const char *realm,
diff --git a/desktop/netsurf.c b/desktop/netsurf.c
index ffcec04..f1daeab 100644
--- a/desktop/netsurf.c
+++ b/desktop/netsurf.c
@@ -104,21 +104,25 @@ static void netsurf_lwc_iterator(lwc_string *str, void *pw)
static nserror netsurf_llcache_query_handler(const llcache_query *query,
void *pw, llcache_query_response cb, void *cbpw)
{
+ nserror res = NSERROR_OK;
+
switch (query->type) {
case LLCACHE_QUERY_AUTH:
guit->misc->login(query->url, query->data.auth.realm, cb, cbpw);
break;
+
case LLCACHE_QUERY_REDIRECT:
/** \todo Need redirect query dialog */
/* For now, do nothing, as this query type isn't emitted yet */
break;
+
case LLCACHE_QUERY_SSL:
- guit->misc->cert_verify(query->url, query->data.ssl.certs,
+ res = guit->misc->cert_verify(query->url, query->data.ssl.certs,
query->data.ssl.num, cb, cbpw);
break;
}
- return NSERROR_OK;
+ return res;
}
/* exported interface documented in netsurf/netsurf.h */
diff --git a/frontends/amiga/sslcert.c b/frontends/amiga/sslcert.c
index ed72061..83798f2 100644
--- a/frontends/amiga/sslcert.c
+++ b/frontends/amiga/sslcert.c
@@ -27,7 +27,7 @@
#include "amiga/tree.h"
#include "amiga/sslcert.h"
-void gui_cert_verify(nsurl *url,
+nserror gui_cert_verify(nsurl *url,
const struct ssl_cert_info *certs, unsigned long num,
nserror (*cb)(bool proceed, void *pw), void *cbpw)
{
@@ -39,9 +39,13 @@ void gui_cert_verify(nsurl *url,
ssl_current_session = data;
ssl_window = ami_tree_create(TREE_SSLCERT, data);
- if(!ssl_window) return;
+ if (!ssl_window) {
+ return NSERROR_INIT_FAILED;
+ }
ami_tree_open(ssl_window, AMI_TREE_SSLCERT);
+
+ return NSERROR_OK;
}
void ami_ssl_free(struct treeview_window *twin)
diff --git a/frontends/amiga/sslcert.h b/frontends/amiga/sslcert.h
index 953142e..86ce9c4 100644
--- a/frontends/amiga/sslcert.h
+++ b/frontends/amiga/sslcert.h
@@ -19,7 +19,7 @@
#ifndef AMIGA_SSLCERT_H
#define AMIGA_SSLCERT_H
-void gui_cert_verify(nsurl *url,
+nserror gui_cert_verify(nsurl *url,
const struct ssl_cert_info *certs, unsigned long num,
nserror (*cb)(bool proceed, void *pw), void *cbpw);
diff --git a/frontends/atari/gui.c b/frontends/atari/gui.c
index 713db8b..eb15777 100644
--- a/frontends/atari/gui.c
+++ b/frontends/atari/gui.c
@@ -771,7 +771,7 @@ static void gui_401login_open(nsurl *url, const char *realm,
}
-static void
+static nserror
gui_cert_verify(nsurl *url, const struct ssl_cert_info *certs,
unsigned long num, nserror (*cb)(bool proceed, void *pw),
void *cbpw)
@@ -795,7 +795,7 @@ gui_cert_verify(nsurl *url, const struct ssl_cert_info *certs,
&data);
atari_sslcert_viewer_open(data);
}
-
+ return NSERROR_OK;
}
void gui_set_input_gui_window(struct gui_window *gw)
diff --git a/frontends/cocoa/gui.m b/frontends/cocoa/gui.m
index b1847eb..7e180fa 100644
--- a/frontends/cocoa/gui.m
+++ b/frontends/cocoa/gui.m
@@ -285,13 +285,13 @@ static nserror gui_launch_url(nsurl *url)
struct ssl_cert_info;
-static void
+static nserror
gui_cert_verify(nsurl *url,
const struct ssl_cert_info *certs,
unsigned long num,
nserror (*cb)(bool proceed,void *pw), void *cbpw)
{
- cb( false, cbpw );
+ return NSERROR_NOT_IMPLEMENTED;
}
diff --git a/frontends/gtk/ssl_cert.c b/frontends/gtk/ssl_cert.c
index 463f5cd..e3bc8a7 100644
--- a/frontends/gtk/ssl_cert.c
+++ b/frontends/gtk/ssl_cert.c
@@ -64,7 +64,7 @@ static gboolean nsgtk_ssl_delete_event(GtkWidget *w, GdkEvent *event, gpointer
return FALSE;
}
-void gtk_cert_verify(nsurl *url, const struct ssl_cert_info *certs,
+nserror gtk_cert_verify(nsurl *url, const struct ssl_cert_info *certs,
unsigned long num, nserror (*cb)(bool proceed, void *pw),
void *cbpw)
{
@@ -82,15 +82,14 @@ void gtk_cert_verify(nsurl *url, const struct ssl_cert_info *certs,
/* state while dlg is open */
session = calloc(sizeof(void *), 3);
if (session == NULL) {
- return;
+ return NSERROR_NOMEM;
}
res = nsgtk_builder_new_from_resname("ssl", &builder);
if (res != NSERROR_OK) {
LOG("SSL UI builder init failed");
free(session);
- cb(false, cbpw);
- return;
+ return NSERROR_INIT_FAILED;
}
gtk_builder_connect_signals(builder, NULL);
@@ -114,7 +113,7 @@ void gtk_cert_verify(nsurl *url, const struct ssl_cert_info *certs,
if (ssl_window == NULL) {
free(session);
g_object_unref(G_OBJECT(dlg));
- return;
+ return NSERROR_INIT_FAILED;
}
accept = GTK_BUTTON(gtk_builder_get_object(builder, "sslaccept"));
@@ -133,4 +132,6 @@ void gtk_cert_verify(nsurl *url, const struct ssl_cert_info *certs,
(gpointer)session);
gtk_widget_show(GTK_WIDGET(dlg));
+
+ return NSERROR_OK;
}
diff --git a/frontends/gtk/ssl_cert.h b/frontends/gtk/ssl_cert.h
index 48937d4..398f1cc 100644
--- a/frontends/gtk/ssl_cert.h
+++ b/frontends/gtk/ssl_cert.h
@@ -31,6 +31,6 @@ struct ssl_cert_info;
* \param cb Callback upon user decision.
* \param cbpw Context pointer passed to cb
*/
-void gtk_cert_verify(struct nsurl *url, const struct ssl_cert_info *certs, unsigned long num, nserror (*cb)(bool proceed, void *pw), void *cbpw);
+nserror gtk_cert_verify(struct nsurl *url, const struct ssl_cert_info *certs, unsigned long num, nserror (*cb)(bool proceed, void *pw), void *cbpw);
#endif
diff --git a/frontends/monkey/cert.c b/frontends/monkey/cert.c
index ec1b1ce..710e710 100644
--- a/frontends/monkey/cert.c
+++ b/frontends/monkey/cert.c
@@ -35,15 +35,14 @@ typedef struct monkey_cert {
static monkey_cert_t *cert_ring = NULL;
static uint32_t cert_ctr = 0;
-void
+nserror
gui_cert_verify(nsurl *url, const struct ssl_cert_info *certs,
unsigned long num, nserror (*cb)(bool proceed, void *pw),
void *cbpw)
{
monkey_cert_t *m4t = calloc(sizeof(*m4t), 1);
if (m4t == NULL) {
- cb(false, cbpw);
- return;
+ return NSERROR_NOMEM;
}
m4t->cb = cb;
m4t->pw = cbpw;
@@ -53,6 +52,8 @@ gui_cert_verify(nsurl *url, const struct ssl_cert_info *certs,
fprintf(stdout, "SSLCERT VERIFY CERT %u URL %s\n",
m4t->num, nsurl_access(url));
+
+ return NSERROR_OK;
}
diff --git a/frontends/monkey/cert.h b/frontends/monkey/cert.h
index 283817f..4470e2e 100644
--- a/frontends/monkey/cert.h
+++ b/frontends/monkey/cert.h
@@ -21,7 +21,7 @@
struct ssl_cert_info;
-void gui_cert_verify(nsurl *url, const struct ssl_cert_info *certs,
+nserror gui_cert_verify(nsurl *url, const struct ssl_cert_info *certs,
unsigned long num, nserror (*cb)(bool proceed, void *pw),
void *cbpw);
diff --git a/frontends/riscos/gui.h b/frontends/riscos/gui.h
index 624f9e2..505e8e7 100644
--- a/frontends/riscos/gui.h
+++ b/frontends/riscos/gui.h
@@ -212,7 +212,7 @@ extern int ro_plot_origin_y;
bool ro_gui_theme_install_apply(wimp_w w);
/* in sslcert.c */
-void gui_cert_verify(struct nsurl *url,
+nserror gui_cert_verify(struct nsurl *url,
const struct ssl_cert_info *certs, unsigned long num,
nserror (*cb)(bool proceed, void *pw), void *cbpw);
diff --git a/frontends/riscos/sslcert.c b/frontends/riscos/sslcert.c
index c7b8db4..8a8ddfb 100644
--- a/frontends/riscos/sslcert.c
+++ b/frontends/riscos/sslcert.c
@@ -101,7 +101,7 @@ void ro_gui_cert_postinitialise(void)
* \param cb Callback upon user decision.
* \param cbpw Context pointer passed to cb
*/
-void gui_cert_verify(nsurl *url,
+nserror gui_cert_verify(nsurl *url,
const struct ssl_cert_info *certs, unsigned long num,
nserror (*cb)(bool proceed, void *pw), void *cbpw)
{
@@ -117,7 +117,7 @@ void gui_cert_verify(nsurl *url,
sslcert_window = malloc(sizeof(struct ro_sslcert));
if (sslcert_window == NULL) {
LOG("Failed to allocate memory for SSL Cert Dialog");
- return;
+ return NSERROR_NOMEM;
}
/* Create the SSL window and its pane. */
@@ -127,7 +127,7 @@ void gui_cert_verify(nsurl *url,
if (error) {
LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess);
free(sslcert_window);
- return;
+ return NSERROR_INIT_FAILED;
}
error = xwimp_create_window(ro_gui_cert_tree_template,
@@ -135,7 +135,7 @@ void gui_cert_verify(nsurl *url,
if (error) {
LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess);
free(sslcert_window);
- return;
+ return NSERROR_INIT_FAILED;
}
/* Create the SSL data and build a tree from it. */
@@ -148,7 +148,7 @@ void gui_cert_verify(nsurl *url,
if (sslcert_window->tv == NULL) {
LOG("Failed to allocate treeview");
free(sslcert_window);
- return;
+ return NSERROR_NOMEM;
}
/* Set up the certificate window event handling.
@@ -182,7 +182,7 @@ void gui_cert_verify(nsurl *url,
if (error) {
ro_gui_cert_release_window(sslcert_window);
LOG("xwimp_get_window_info: 0x%x: %s", error->errnum, error->errmess);
- return;
+ return NSERROR_INIT_FAILED;
}
state.w = sslcert_window->window;
@@ -190,7 +190,7 @@ void gui_cert_verify(nsurl *url,
if (error) {
ro_gui_cert_release_window(sslcert_window);
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- return;
+ return NSERROR_INIT_FAILED;
}
istate.w = sslcert_window->window;
@@ -199,7 +199,7 @@ void gui_cert_verify(nsurl *url,
if (error) {
ro_gui_cert_release_window(sslcert_window);
LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
- return;
+ return NSERROR_INIT_FAILED;
}
state.w = sslcert_window->pane;
@@ -230,7 +230,7 @@ void gui_cert_verify(nsurl *url,
if (error) {
ro_gui_cert_release_window(sslcert_window);
LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess);
- return;
+ return NSERROR_INIT_FAILED;
}
}
@@ -248,10 +248,12 @@ void gui_cert_verify(nsurl *url,
ro_gui_cert_release_window(sslcert_window);
LOG("xwimp_open_window_nested: 0x%x: %s", error->errnum, error->errmess);
ro_gui_cert_release_window(sslcert_window);
- return;
+ return NSERROR_INIT_FAILED;
}
ro_treeview_set_origin(sslcert_window->tv, 0, 0);
+
+ return NSERROR_OK;
}
/**
diff --git a/include/netsurf/misc.h b/include/netsurf/misc.h
index 7b35495..2647b9a 100644
--- a/include/netsurf/misc.h
+++ b/include/netsurf/misc.h
@@ -89,8 +89,9 @@ struct gui_misc_table {
* \param num The number of certificates to be verified.
* \param cb Callback upon user decision.
* \param cbpw Context pointer passed to cb
+ * \return NSERROR_OK on sucess else error and cb never called
*/
- void (*cert_verify)(struct nsurl *url, const struct ssl_cert_info *certs, unsigned long num, nserror (*cb)(bool proceed, void *pw), void *cbpw);
+ nserror (*cert_verify)(struct nsurl *url, const struct ssl_cert_info *certs, unsigned long num, nserror (*cb)(bool proceed, void *pw), void *cbpw);
/**
* Prompt user for login
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=51725592c96b3cb94aa...
commit 51725592c96b3cb94aa70761b10960c738815534
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
make gtk cookies manager use core window API
diff --git a/frontends/gtk/cookies.c b/frontends/gtk/cookies.c
index f252e6b..d8f8b5d 100644
--- a/frontends/gtk/cookies.c
+++ b/frontends/gtk/cookies.c
@@ -16,28 +16,34 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/** \file
- * Cookies (implementation).
+/**
+ * \file
+ * Implementation of GTK cookie manager.
*/
-#include <gtk/gtk.h>
#include <stdint.h>
+#include <stdlib.h>
+#include <gtk/gtk.h>
#include "utils/log.h"
#include "netsurf/keypress.h"
+#include "netsurf/plotters.h"
#include "desktop/cookie_manager.h"
-#include "desktop/plot_style.h"
-#include "desktop/tree.h"
+#include "desktop/treeview.h"
#include "gtk/cookies.h"
#include "gtk/plotters.h"
#include "gtk/scaffolding.h"
-#include "gtk/treeview.h"
#include "gtk/resources.h"
+#include "gtk/corewindow.h"
+
+struct nsgtk_cookie_window {
+ struct nsgtk_corewindow core;
+ GtkBuilder *builder;
+ GtkWindow *wnd;
+};
-static struct nsgtk_treeview *cookies_treeview;
-static GtkBuilder *cookie_builder;
-static GtkWindow *wndCookies = NULL;
+static struct nsgtk_cookie_window *cookie_window = NULL;
#define MENUPROTO(x) static gboolean nsgtk_on_##x##_activate( \
GtkMenuItem *widget, gpointer g)
@@ -85,80 +91,6 @@ static struct menu_events menu_events[] = {
};
-
-/**
- * Connects menu events in the cookies window.
- */
-static void nsgtk_cookies_init_menu(void)
-{
- struct menu_events *event = menu_events;
- GtkWidget *w;
-
- while (event->widget != NULL) {
- w = GTK_WIDGET(gtk_builder_get_object(cookie_builder, event->widget));
- if (w == NULL) {
- LOG("Unable to connect menu widget ""%s""", event->widget); } else {
- g_signal_connect(G_OBJECT(w), "activate", event->handler, cookies_treeview);
- }
- event++;
- }
-}
-
-/**
- * Creates the window for the cookies tree.
- *
- * \return NSERROR_OK on success else appropriate error code on faliure.
- */
-static nserror nsgtk_cookies_init(void)
-{
- GtkScrolledWindow *scrolled;
- GtkDrawingArea *drawing_area;
- nserror res;
-
- if (wndCookies != NULL) {
- return NSERROR_OK;
- }
-
- res = nsgtk_builder_new_from_resname("cookies", &cookie_builder);
- if (res != NSERROR_OK) {
- LOG("Cookie UI builder init failed");
- return res;
- }
-
- gtk_builder_connect_signals(cookie_builder, NULL);
-
- wndCookies = GTK_WINDOW(gtk_builder_get_object(cookie_builder,
- "wndCookies"));
-
- scrolled = GTK_SCROLLED_WINDOW(gtk_builder_get_object(cookie_builder,
- "cookiesScrolled"));
-
- drawing_area = GTK_DRAWING_AREA(gtk_builder_get_object(cookie_builder,
- "cookiesDrawingArea"));
-
- cookies_treeview = nsgtk_treeview_create(TREE_COOKIES,
- wndCookies,
- scrolled,
- drawing_area,
- NULL);
- if (cookies_treeview == NULL) {
- return NSERROR_INIT_FAILED;
- }
-
-#define CONNECT(obj, sig, callback, ptr) \
- g_signal_connect(G_OBJECT(obj), (sig), G_CALLBACK(callback), (ptr))
-
- CONNECT(wndCookies, "delete_event", gtk_widget_hide_on_delete, NULL);
- CONNECT(wndCookies, "hide", nsgtk_tree_window_hide, cookies_treeview);
-
- nsgtk_cookies_init_menu();
-
- return NSERROR_OK;
-}
-
-
-
-
/* edit menu */
MENUHANDLER(delete_selected)
{
@@ -222,6 +154,162 @@ MENUHANDLER(collapse_cookies)
return TRUE;
}
+/**
+ * Connects menu events in the cookies window.
+ */
+static void nsgtk_cookies_init_menu(struct nsgtk_cookie_window *ncwin)
+{
+ struct menu_events *event = menu_events;
+ GtkWidget *w;
+
+ while (event->widget != NULL) {
+ w = GTK_WIDGET(gtk_builder_get_object(ncwin->builder,
+ event->widget));
+ if (w == NULL) {
+ LOG("Unable to connect menu widget ""%s""",
+ event->widget);
+ } else {
+ g_signal_connect(G_OBJECT(w),
+ "activate",
+ event->handler,
+ ncwin);
+ }
+ event++;
+ }
+}
+
+/**
+ * callback for mouse action on cookie window
+ *
+ * \param nsgtk_cw The nsgtk core window structure.
+ * \param mouse_state netsurf mouse state on event
+ * \param x location of event
+ * \param y location of event
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+nsgtk_cookies_mouse(struct nsgtk_corewindow *nsgtk_cw,
+ browser_mouse_state mouse_state,
+ int x, int y)
+{
+ cookie_manager_mouse_action(mouse_state, x, y);
+
+ return NSERROR_OK;
+}
+
+/**
+ * callback for keypress on cookie window
+ *
+ * \param nsgtk_cw The nsgtk core window structure.
+ * \param nskey The netsurf key code
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+nsgtk_cookies_key(struct nsgtk_corewindow *nsgtk_cw, uint32_t nskey)
+{
+ if (cookie_manager_keypress(nskey)) {
+ return NSERROR_OK;
+ }
+ return NSERROR_NOT_IMPLEMENTED;
+}
+
+/**
+ * callback on draw event for cookie window
+ *
+ * \param nsgtk_cw The nsgtk core window structure.
+ * \param r The rectangle of the window that needs updating.
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+nsgtk_cookies_draw(struct nsgtk_corewindow *nsgtk_cw, struct rect *r)
+{
+ struct redraw_context ctx = {
+ .interactive = true,
+ .background_images = true,
+ .plot = &nsgtk_plotters
+ };
+
+ cookie_manager_redraw(0, 0, r, &ctx);
+
+ return NSERROR_OK;
+}
+
+/**
+ * Creates the window for the cookies tree.
+ *
+ * \return NSERROR_OK on success else appropriate error code on faliure.
+ */
+static nserror nsgtk_cookies_init(void)
+{
+ struct nsgtk_cookie_window *ncwin;
+ nserror res;
+
+ if (cookie_window != NULL) {
+ return NSERROR_OK;
+ }
+
+ res = treeview_init(0);
+ if (res != NSERROR_OK) {
+ return res;
+ }
+
+ ncwin = malloc(sizeof(struct nsgtk_cookie_window));
+ if (ncwin == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ res = nsgtk_builder_new_from_resname("cookies", &ncwin->builder);
+ if (res != NSERROR_OK) {
+ LOG("Cookie UI builder init failed");
+ free(ncwin);
+ return res;
+ }
+
+ gtk_builder_connect_signals(ncwin->builder, NULL);
+
+ ncwin->wnd = GTK_WINDOW(gtk_builder_get_object(ncwin->builder,
+ "wndCookies"));
+
+ ncwin->core.scrolled = GTK_SCROLLED_WINDOW(
+ gtk_builder_get_object(ncwin->builder, "cookiesScrolled"));
+
+ ncwin->core.drawing_area = GTK_DRAWING_AREA(
+ gtk_builder_get_object(ncwin->builder, "cookiesDrawingArea"));
+
+ /* make the delete event hide the window */
+ g_signal_connect(G_OBJECT(ncwin->wnd),
+ "delete_event",
+ G_CALLBACK(gtk_widget_hide_on_delete),
+ NULL);
+
+ nsgtk_cookies_init_menu(ncwin);
+
+ ncwin->core.draw = nsgtk_cookies_draw;
+ ncwin->core.key = nsgtk_cookies_key;
+ ncwin->core.mouse = nsgtk_cookies_mouse;
+
+ res = nsgtk_corewindow_init(&ncwin->core);
+ if (res != NSERROR_OK) {
+ free(ncwin);
+ return res;
+ }
+
+ res = cookie_manager_init(ncwin->core.cb_table,
+ (struct core_window *)ncwin);
+ if (res != NSERROR_OK) {
+ free(ncwin);
+ return res;
+ }
+
+ /* memoise window so it can be represented when necessary
+ * instead of recreating every time.
+ */
+ cookie_window = ncwin;
+
+ return NSERROR_OK;
+}
+
+
/* exported function documented gtk/cookies.h */
nserror nsgtk_cookies_present(void)
{
@@ -229,16 +317,29 @@ nserror nsgtk_cookies_present(void)
res = nsgtk_cookies_init();
if (res == NSERROR_OK) {
- gtk_window_present(wndCookies);
+ gtk_window_present(cookie_window->wnd);
}
return res;
}
+
/* exported function documented gtk/cookies.h */
-void nsgtk_cookies_destroy(void)
+nserror nsgtk_cookies_destroy(void)
{
- /** \todo what about cookie_builder? */
- if (wndCookies != NULL) {
- nsgtk_treeview_destroy(cookies_treeview);
+ nserror res;
+
+ if (cookie_window == NULL) {
+ return NSERROR_OK;
+ }
+
+ res = cookie_manager_fini();
+ if (res == NSERROR_OK) {
+ res = nsgtk_corewindow_fini(&cookie_window->core);
+ gtk_widget_destroy(GTK_WIDGET(cookie_window->wnd));
+ g_object_unref(G_OBJECT(cookie_window->builder));
+ free(cookie_window);
+ cookie_window = NULL;
}
+
+ return res;
}
diff --git a/frontends/gtk/cookies.h b/frontends/gtk/cookies.h
index 2af05e1..c1a68b7 100644
--- a/frontends/gtk/cookies.h
+++ b/frontends/gtk/cookies.h
@@ -35,7 +35,7 @@ nserror nsgtk_cookies_present(void);
*
* \return NSERROR_OK on success else appropriate error code on faliure.
*/
-void nsgtk_cookies_destroy(void);
+nserror nsgtk_cookies_destroy(void);
#endif /* __NSGTK_COOKIES_H__ */
diff --git a/frontends/gtk/gui.c b/frontends/gtk/gui.c
index d57ebdf..0ed32e9 100644
--- a/frontends/gtk/gui.c
+++ b/frontends/gtk/gui.c
@@ -434,13 +434,21 @@ static void nsgtk_main(void)
static void gui_quit(void)
{
+ nserror res;
+
LOG("Quitting GUI");
/* Ensure all scaffoldings are destroyed before we go into exit */
nsgtk_download_destroy();
urldb_save_cookies(nsoption_charp(cookie_jar));
urldb_save(nsoption_charp(url_file));
- nsgtk_cookies_destroy();
+
+ res = nsgtk_cookies_destroy();
+ if (res != NSERROR_OK) {
+ LOG("Error finalising cookie viewer: %s",
+ messages_get_errorcode(res));
+ }
+
nsgtk_history_destroy();
nsgtk_hotlist_destroy();
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=ca5b165c85e1e8cc7df...
commit ca5b165c85e1e8cc7df286b6a0a9a061de99bcaa
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
add nsgtk support for core window API
diff --git a/frontends/gtk/Makefile b/frontends/gtk/Makefile
index aae1d44..f8f7d8c 100644
--- a/frontends/gtk/Makefile
+++ b/frontends/gtk/Makefile
@@ -163,7 +163,7 @@ S_FRONTEND := gui.c schedule.c layout_pango.c bitmap.c plotters.c \
selection.c history.c window.c fetch.c download.c menu.c \
print.c search.c tabs.c toolbar.c gettext.c \
compat.c cookies.c hotlist.c viewdata.c viewsource.c \
- preferences.c about.c ssl_cert.c resources.c
+ preferences.c about.c ssl_cert.c resources.c corewindow.c
# This is the final source build list
# Note this is deliberately *not* expanded here as common and image
diff --git a/frontends/gtk/corewindow.c b/frontends/gtk/corewindow.c
new file mode 100644
index 0000000..11dec83
--- /dev/null
+++ b/frontends/gtk/corewindow.c
@@ -0,0 +1,638 @@
+/*
+ * Copyright 2016 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 generic core window interface.
+ *
+ * Provides interface for core renderers to the gtk toolkit drawable area.
+ * \todo should the interface really be called coredrawable?
+ *
+
+ * This module is an object that must be encapsulated. Client users
+ * should embed a struct nsgtk_corewindow at the beginning of their
+ * context for this display surface, fill in relevant data and then
+ * call nsgtk_corewindow_init()
+ *
+ * The nsgtk core window structure requires the drawing area and
+ * scrollable widgets are present and the callback for draw, key and
+ * mouse operations.
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <math.h>
+#include <gtk/gtk.h>
+
+#include "utils/log.h"
+#include "utils/utils.h"
+#include "utils/messages.h"
+#include "utils/utf8.h"
+#include "netsurf/keypress.h"
+#include "netsurf/mouse.h"
+#include "desktop/plot_style.h"
+
+#include "gtk/compat.h"
+#include "gtk/gui.h" /* just for gtk_gui_gdkkey_to_nskey */
+#include "gtk/plotters.h"
+#include "gtk/corewindow.h"
+
+/**
+ * Convert GDK mouse event to netsurf mouse state
+ */
+static browser_mouse_state nsgtk_cw_gdkbutton_to_nsstate(GdkEventButton *event)
+{
+ browser_mouse_state ms;
+
+ if (event->type == GDK_2BUTTON_PRESS) {
+ ms = BROWSER_MOUSE_DOUBLE_CLICK;
+ } else {
+ ms = BROWSER_MOUSE_HOVER;
+ }
+
+ /* button state */
+ switch (event->button) {
+ case 1:
+ ms |= BROWSER_MOUSE_PRESS_1;
+ break;
+
+ case 2:
+ ms |= BROWSER_MOUSE_PRESS_2;
+ break;
+ }
+
+ /* Handle the modifiers too */
+ if (event->state & GDK_SHIFT_MASK) {
+ ms |= BROWSER_MOUSE_MOD_1;
+ }
+
+ if (event->state & GDK_CONTROL_MASK) {
+ ms |= BROWSER_MOUSE_MOD_2;
+ }
+
+ if (event->state & GDK_MOD1_MASK) {
+ ms |= BROWSER_MOUSE_MOD_3;
+ }
+
+ return ms;
+}
+
+/**
+ * gtk event on mouse button press.
+ *
+ * \param widget The gtk widget the event occoured for.
+ * \param event The event that occoured.
+ * \param g The context pointer passed when teh event was registered.
+ */
+static gboolean
+nsgtk_cw_button_press_event(GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer g)
+{
+ struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)g;
+ struct nsgtk_corewindow_mouse *mouse = &nsgtk_cw->mouse_state;
+
+ gtk_im_context_reset(nsgtk_cw->input_method);
+ gtk_widget_grab_focus(GTK_WIDGET(nsgtk_cw->drawing_area));
+
+ /* record event information for potentially starting a drag. */
+ mouse->pressed_x = mouse->last_x = event->x;
+ mouse->pressed_y = mouse->last_y = event->y;
+ mouse->pressed = true;
+
+ mouse->state = nsgtk_cw_gdkbutton_to_nsstate(event);
+
+ nsgtk_cw->mouse(nsgtk_cw, mouse->state, event->x, event->y);
+
+ return TRUE;
+}
+
+static gboolean
+nsgtk_cw_button_release_event(GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer g)
+{
+ struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)g;
+ struct nsgtk_corewindow_mouse *mouse = &nsgtk_cw->mouse_state;
+
+ /* only button 1 clicks are considered double clicks. If the
+ * mouse state is PRESS then we are waiting for a release to
+ * emit a click event, otherwise just reset the state to nothing.
+ */
+ if (mouse->state & BROWSER_MOUSE_DOUBLE_CLICK) {
+ if (mouse->state & BROWSER_MOUSE_PRESS_1) {
+ mouse->state ^= BROWSER_MOUSE_PRESS_1 |
+ BROWSER_MOUSE_CLICK_1;
+ } else if (mouse->state & BROWSER_MOUSE_PRESS_2) {
+ mouse->state ^= (BROWSER_MOUSE_PRESS_2 |
+ BROWSER_MOUSE_CLICK_2 |
+ BROWSER_MOUSE_DOUBLE_CLICK);
+ }
+ } else if (mouse->state & BROWSER_MOUSE_PRESS_1) {
+ mouse->state ^= (BROWSER_MOUSE_PRESS_1 |
+ BROWSER_MOUSE_CLICK_1);
+ } else if (mouse->state & BROWSER_MOUSE_PRESS_2) {
+ mouse->state ^= (BROWSER_MOUSE_PRESS_2 |
+ BROWSER_MOUSE_CLICK_2);
+ } else if (mouse->state & BROWSER_MOUSE_HOLDING_1) {
+ mouse->state ^= (BROWSER_MOUSE_HOLDING_1 |
+ BROWSER_MOUSE_DRAG_ON);
+ } else if (mouse->state & BROWSER_MOUSE_HOLDING_2) {
+ mouse->state ^= (BROWSER_MOUSE_HOLDING_2 |
+ BROWSER_MOUSE_DRAG_ON);
+ }
+
+ /* Handle modifiers being removed */
+ if ((mouse->state & BROWSER_MOUSE_MOD_1) &&
+ !(event->state & GDK_SHIFT_MASK)) {
+ mouse->state ^= BROWSER_MOUSE_MOD_1;
+ }
+ if ((mouse->state & BROWSER_MOUSE_MOD_2) &&
+ !(event->state & GDK_CONTROL_MASK)) {
+ mouse->state ^= BROWSER_MOUSE_MOD_2;
+ }
+ if ((mouse->state & BROWSER_MOUSE_MOD_3) &&
+ !(event->state & GDK_MOD1_MASK)) {
+ mouse->state ^= BROWSER_MOUSE_MOD_3;
+ }
+
+ /* end drag with modifiers */
+ if (mouse->state & (BROWSER_MOUSE_MOD_1 |
+ BROWSER_MOUSE_MOD_2 |
+ BROWSER_MOUSE_MOD_3)) {
+ mouse->state = BROWSER_MOUSE_HOVER;
+ }
+
+ nsgtk_cw->mouse(nsgtk_cw, mouse->state, event->x, event->y);
+
+ mouse->pressed = false;
+
+ return TRUE;
+}
+
+static gboolean
+nsgtk_cw_motion_notify_event(GtkWidget *widget,
+ GdkEventMotion *event, gpointer g)
+{
+ struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)g;
+ struct nsgtk_corewindow_mouse *mouse = &nsgtk_cw->mouse_state;
+
+ if (mouse->pressed == false) {
+ return TRUE;
+ }
+
+ if ((fabs(event->x - mouse->last_x) < 5.0) &&
+ (fabs(event->y - mouse->last_y) < 5.0)) {
+ /* Mouse hasn't moved far enough from press coordinate
+ * for this to be considered a drag.
+ */
+ return FALSE;
+ }
+
+ /* This is a drag, ensure it's always treated as such, even if
+ * we drag back over the press location.
+ */
+ mouse->last_x = INT_MIN;
+ mouse->last_y = INT_MIN;
+
+
+ if (mouse->state & BROWSER_MOUSE_PRESS_1) {
+ /* Start button 1 drag */
+ nsgtk_cw->mouse(nsgtk_cw,
+ BROWSER_MOUSE_DRAG_1,
+ mouse->pressed_x,
+ mouse->pressed_y);
+
+ /* Replace PRESS with HOLDING and declare drag in progress */
+ mouse->state ^= (BROWSER_MOUSE_PRESS_1 |
+ BROWSER_MOUSE_HOLDING_1);
+ mouse->state |= BROWSER_MOUSE_DRAG_ON;
+
+ } else if (mouse->state & BROWSER_MOUSE_PRESS_2) {
+ /* Start button 2s drag */
+ nsgtk_cw->mouse(nsgtk_cw,
+ BROWSER_MOUSE_DRAG_2,
+ mouse->pressed_x,
+ mouse->pressed_y);
+
+ /* Replace PRESS with HOLDING and declare drag in progress */
+ mouse->state ^= (BROWSER_MOUSE_PRESS_2 |
+ BROWSER_MOUSE_HOLDING_2);
+ mouse->state |= BROWSER_MOUSE_DRAG_ON;
+
+ } else {
+ /* continue drag */
+
+ /* Handle modifiers being removed */
+ if ((mouse->state & BROWSER_MOUSE_MOD_1) &&
+ !(event->state & GDK_SHIFT_MASK)) {
+ mouse->state ^= BROWSER_MOUSE_MOD_1;
+ }
+ if ((mouse->state & BROWSER_MOUSE_MOD_2) &&
+ !(event->state & GDK_CONTROL_MASK)) {
+ mouse->state ^= BROWSER_MOUSE_MOD_2;
+ }
+ if ((mouse->state & BROWSER_MOUSE_MOD_3) &&
+ !(event->state & GDK_MOD1_MASK)) {
+ mouse->state ^= BROWSER_MOUSE_MOD_3;
+ }
+
+ if (mouse->state &
+ (BROWSER_MOUSE_HOLDING_1 | BROWSER_MOUSE_HOLDING_2)) {
+ nsgtk_cw->mouse(nsgtk_cw,
+ mouse->state,
+ event->x, event->y);
+ }
+ }
+
+ return TRUE;
+}
+
+
+/**
+ * Deal with keypress events not handled but input method or callback
+ *
+ * \param nsgtk_cw nsgtk core window key event happened in.
+ * \param nskey The netsurf keycode of the event.
+ * \return NSERROR_OK on sucess otherwise an error code.
+ */
+static nserror nsgtk_cw_key(struct nsgtk_corewindow *nsgtk_cw, uint32_t nskey)
+{
+ double value;
+ GtkAdjustment *vscroll;
+ GtkAdjustment *hscroll;
+ GtkAdjustment *scroll = NULL;
+ gdouble hpage, vpage;
+
+ vscroll = gtk_scrolled_window_get_vadjustment(nsgtk_cw->scrolled);
+ hscroll = gtk_scrolled_window_get_hadjustment(nsgtk_cw->scrolled);
+ g_object_get(vscroll, "page-size", &vpage, NULL);
+ g_object_get(hscroll, "page-size", &hpage, NULL);
+
+ switch(nskey) {
+ case NS_KEY_TEXT_START:
+ scroll = vscroll;
+ value = nsgtk_adjustment_get_lower(scroll);
+ break;
+
+ case NS_KEY_TEXT_END:
+ scroll = vscroll;
+ value = nsgtk_adjustment_get_upper(scroll) - vpage;
+ if (value < nsgtk_adjustment_get_lower(scroll))
+ value = nsgtk_adjustment_get_lower(scroll);
+ break;
+
+ case NS_KEY_LEFT:
+ scroll = hscroll;
+ value = gtk_adjustment_get_value(scroll) -
+ nsgtk_adjustment_get_step_increment(scroll);
+ if (value < nsgtk_adjustment_get_lower(scroll))
+ value = nsgtk_adjustment_get_lower(scroll);
+ break;
+
+ case NS_KEY_RIGHT:
+ scroll = hscroll;
+ value = gtk_adjustment_get_value(scroll) +
+ nsgtk_adjustment_get_step_increment(scroll);
+ if (value > nsgtk_adjustment_get_upper(scroll) - hpage)
+ value = nsgtk_adjustment_get_upper(scroll) - hpage;
+ break;
+ case NS_KEY_UP:
+ scroll = vscroll;
+ value = gtk_adjustment_get_value(scroll) -
+ nsgtk_adjustment_get_step_increment(scroll);
+ if (value < nsgtk_adjustment_get_lower(scroll))
+ value = nsgtk_adjustment_get_lower(scroll);
+ break;
+
+ case NS_KEY_DOWN:
+ scroll = vscroll;
+ value = gtk_adjustment_get_value(scroll) +
+ nsgtk_adjustment_get_step_increment(scroll);
+ if (value > nsgtk_adjustment_get_upper(scroll) - vpage)
+ value = nsgtk_adjustment_get_upper(scroll) - vpage;
+ break;
+
+ case NS_KEY_PAGE_UP:
+ scroll = vscroll;
+ value = gtk_adjustment_get_value(scroll) -
+ nsgtk_adjustment_get_page_increment(scroll);
+
+ if (value < nsgtk_adjustment_get_lower(scroll))
+ value = nsgtk_adjustment_get_lower(scroll);
+
+ break;
+
+ case NS_KEY_PAGE_DOWN:
+ scroll = vscroll;
+ value = gtk_adjustment_get_value(scroll) +
+ nsgtk_adjustment_get_page_increment(scroll);
+
+ if (value > nsgtk_adjustment_get_upper(scroll) - vpage)
+ value = nsgtk_adjustment_get_upper(scroll) - vpage;
+ break;
+
+ }
+
+ if (scroll != NULL) {
+ gtk_adjustment_set_value(scroll, value);
+ }
+
+ return NSERROR_OK;
+}
+
+/**
+ * gtk event on key press.
+ *
+ * \param widget The gtk widget the event occoured for.
+ * \param event The event that occoured.
+ * \param g The context pointer passed when teh event was registered.
+ */
+static gboolean
+nsgtk_cw_keypress_event(GtkWidget *widget, GdkEventKey *event, gpointer g)
+{
+ struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)g;
+ nserror res;
+ uint32_t nskey;
+
+ /* check to see if gtk input method swallowed the keypress */
+ if (gtk_im_context_filter_keypress(nsgtk_cw->input_method, event)) {
+ return TRUE;
+ }
+
+ /* convert gtk event to nskey */
+ nskey = gtk_gui_gdkkey_to_nskey(event);
+
+ /* attempt to handle keypress in caller */
+ res = nsgtk_cw->key(nsgtk_cw, nskey);
+ if (res == NSERROR_OK) {
+ return TRUE;
+ } else if (res != NSERROR_NOT_IMPLEMENTED) {
+ LOG("%s", messages_get_errorcode(res));
+ return FALSE;
+ }
+
+ /* deal with unprocessed keypress */
+ res = nsgtk_cw_key(nsgtk_cw, nskey);
+ if (res != NSERROR_OK) {
+ LOG("%s", messages_get_errorcode(res));
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+static gboolean
+nsgtk_cw_keyrelease_event(GtkWidget *widget, GdkEventKey *event, gpointer g)
+{
+ struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)g;
+
+ return gtk_im_context_filter_keypress(nsgtk_cw->input_method, event);
+}
+
+
+static void
+nsgtk_cw_input_method_commit(GtkIMContext *ctx, const gchar *str, gpointer g)
+{
+ struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)g;
+ size_t len;
+ size_t offset = 0;
+ uint32_t nskey;
+
+ len = strlen(str);
+
+ while (offset < len) {
+ nskey = utf8_to_ucs4(str + offset, len - offset);
+
+ nsgtk_cw->key(nsgtk_cw, nskey);
+
+ offset = utf8_next(str, len, offset);
+ }
+}
+
+
+#if GTK_CHECK_VERSION(3,0,0)
+
+/* signal handler for core window redraw */
+static gboolean
+nsgtk_cw_draw_event(GtkWidget *widget, cairo_t *cr, gpointer data)
+{
+ struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)data;
+ double x1;
+ double y1;
+ double x2;
+ double y2;
+ struct rect clip;
+
+ current_widget = widget;
+ current_cr = cr;
+
+ cairo_clip_extents(cr, &x1, &y1, &x2, &y2);
+
+ if (tv->tree_flags == TREE_SSLCERT) {
+ ssl_current_session = tv->ssl_data;
+ }
+
+ clip.x0 = x1;
+ clip.y0 = y1;
+ clip.x1 = x2;
+ clip.y1 = y2;
+
+ nsgtk_cw->draw(nsgtk_cw, &clip);
+
+ current_widget = NULL;
+
+ return FALSE;
+}
+
+#else
+
+/* signal handler for core window redraw */
+static gboolean
+nsgtk_cw_draw_event(GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer g)
+{
+ struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)g;
+ struct rect clip;
+
+ clip.x0 = event->area.x;
+ clip.y0 = event->area.y;
+ clip.x1 = event->area.x + event->area.width;
+ clip.y1 = event->area.y + event->area.height;
+
+ current_widget = widget;
+ current_cr = gdk_cairo_create(nsgtk_widget_get_window(widget));
+
+ nsgtk_cw->draw(nsgtk_cw, &clip);
+
+ current_widget = NULL;
+ cairo_destroy(current_cr);
+
+ return FALSE;
+}
+
+#endif
+
+/**
+ * callback from core to request a redraw
+ */
+static void
+nsgtk_cw_redraw_request(struct core_window *cw, const struct rect *r)
+{
+ struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)cw;
+
+ gtk_widget_queue_draw_area(GTK_WIDGET(nsgtk_cw->drawing_area),
+ r->x0, r->y0,
+ r->x1 - r->x0, r->y1 - r->y0);
+}
+
+
+static void
+nsgtk_cw_update_size(struct core_window *cw, int width, int height)
+{
+ struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)cw;
+
+ gtk_widget_set_size_request(GTK_WIDGET(nsgtk_cw->drawing_area),
+ width, height);
+}
+
+
+static void
+nsgtk_cw_scroll_visible(struct core_window *cw, const struct rect *r)
+{
+ struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)cw;
+ int y = 0, height = 0, y0, y1;
+ gdouble page;
+ GtkAdjustment *vadj;
+
+ vadj = gtk_scrolled_window_get_vadjustment(nsgtk_cw->scrolled);
+
+ assert(vadj);
+
+ g_object_get(vadj, "page-size", &page, NULL);
+
+ y0 = (int)(gtk_adjustment_get_value(vadj));
+ y1 = y0 + page;
+
+ if ((y >= y0) && (y + height <= y1))
+ return;
+ if (y + height > y1)
+ y0 = y0 + (y + height - y1);
+ if (y < y0)
+ y0 = y;
+ gtk_adjustment_set_value(vadj, y0);
+}
+
+
+static void
+nsgtk_cw_get_window_dimensions(struct core_window *cw, int *width, int *height)
+{
+ struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)cw;
+ GtkAdjustment *vadj;
+ GtkAdjustment *hadj;
+ gdouble page;
+
+ if (width != NULL) {
+ hadj = gtk_scrolled_window_get_hadjustment(nsgtk_cw->scrolled);
+ g_object_get(hadj, "page-size", &page, NULL);
+ *width = page;
+ }
+
+ if (height != NULL) {
+ vadj = gtk_scrolled_window_get_vadjustment(nsgtk_cw->scrolled);
+ g_object_get(vadj, "page-size", &page, NULL);
+ *height = page;
+ }}
+
+
+static void
+nsgtk_cw_drag_status(struct core_window *cw, core_window_drag_status ds)
+{
+ struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)cw;
+ nsgtk_cw->drag_staus = ds;
+}
+
+
+struct core_window_callback_table nsgtk_cw_cb_table = {
+ .redraw_request = nsgtk_cw_redraw_request,
+ .update_size = nsgtk_cw_update_size,
+ .scroll_visible = nsgtk_cw_scroll_visible,
+ .get_window_dimensions = nsgtk_cw_get_window_dimensions,
+ .drag_status = nsgtk_cw_drag_status
+};
+
+/* exported function documented gtk/corewindow.h */
+nserror nsgtk_corewindow_init(struct nsgtk_corewindow *nsgtk_cw)
+{
+ nsgtk_cw->cb_table = &nsgtk_cw_cb_table;
+
+ /* input method setup */
+ nsgtk_cw->input_method = gtk_im_multicontext_new();
+ gtk_im_context_set_client_window(nsgtk_cw->input_method,
+ gtk_widget_get_parent_window(GTK_WIDGET(nsgtk_cw->drawing_area)));
+ gtk_im_context_set_use_preedit(nsgtk_cw->input_method, FALSE);
+
+ g_signal_connect(G_OBJECT(nsgtk_cw->input_method),
+ "commit",
+ G_CALLBACK(nsgtk_cw_input_method_commit),
+ nsgtk_cw);
+
+ nsgtk_connect_draw_event(GTK_WIDGET(nsgtk_cw->drawing_area),
+ G_CALLBACK(nsgtk_cw_draw_event),
+ nsgtk_cw);
+
+ g_signal_connect(G_OBJECT(nsgtk_cw->drawing_area),
+ "button-press-event",
+ G_CALLBACK(nsgtk_cw_button_press_event),
+ nsgtk_cw);
+
+ g_signal_connect(G_OBJECT(nsgtk_cw->drawing_area),
+ "button-release-event",
+ G_CALLBACK(nsgtk_cw_button_release_event),
+ nsgtk_cw);
+
+ g_signal_connect(G_OBJECT(nsgtk_cw->drawing_area),
+ "motion-notify-event",
+ G_CALLBACK(nsgtk_cw_motion_notify_event),
+ nsgtk_cw);
+
+ g_signal_connect(G_OBJECT(nsgtk_cw->drawing_area),
+ "key-press-event",
+ G_CALLBACK(nsgtk_cw_keypress_event),
+ nsgtk_cw);
+
+ g_signal_connect(G_OBJECT(nsgtk_cw->drawing_area),
+ "key-release-event",
+ G_CALLBACK(nsgtk_cw_keyrelease_event),
+ nsgtk_cw);
+
+ nsgtk_widget_override_background_color(
+ GTK_WIDGET(nsgtk_cw->drawing_area),
+ GTK_STATE_NORMAL,
+ 0, 0xffff, 0xffff, 0xffff);
+
+ return NSERROR_OK;
+}
+
+nserror nsgtk_corewindow_fini(struct nsgtk_corewindow *nsgtk_cw)
+{
+ g_object_unref(nsgtk_cw->input_method);
+
+ return NSERROR_OK;
+}
diff --git a/frontends/gtk/corewindow.h b/frontends/gtk/corewindow.h
new file mode 100644
index 0000000..d6f3011
--- /dev/null
+++ b/frontends/gtk/corewindow.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2016 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/>.
+ */
+
+#ifndef GTK_COREWINDOW_H
+#define GTK_COREWINDOW_H
+
+#include "desktop/core_window.h"
+
+/**
+ * nsgtk core window mouse state
+ */
+struct nsgtk_corewindow_mouse {
+ browser_mouse_state state; /**< last event status */
+ bool pressed;
+ int pressed_x;
+ int pressed_y;
+ int last_x;
+ int last_y;
+};
+
+/**
+ * nsgtk core window state
+ */
+struct nsgtk_corewindow {
+ /* public variables */
+ /** GTK drawable widget */
+ GtkDrawingArea *drawing_area;
+ /** scrollable area drawing area is within */
+ GtkScrolledWindow *scrolled;
+
+ /* private variables */
+ /** Input method */
+ GtkIMContext *input_method;
+ /** table of callbacks for core window operations */
+ struct core_window_callback_table *cb_table;
+ /** mouse state */
+ struct nsgtk_corewindow_mouse mouse_state;
+ /** drag status set by core */
+ core_window_drag_status drag_staus;
+
+ /**
+ * callback to draw on drawable area of nsgtk core window
+ *
+ * \param nsgtk_cw The nsgtk core window structure.
+ * \param r The rectangle of the window that needs updating.
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+ nserror (*draw)(struct nsgtk_corewindow *nsgtk_cw, struct rect *r);
+
+ /**
+ * callback for keypress on nsgtk core window
+ *
+ * \param nsgtk_cw The nsgtk core window structure.
+ * \param nskey The netsurf key code.
+ * \return NSERROR_OK if key processed,
+ * NSERROR_NOT_IMPLEMENTED if key not processed
+ * otherwise apropriate error code
+ */
+ nserror (*key)(struct nsgtk_corewindow *nsgtk_cw, uint32_t nskey);
+
+ /**
+ * callback for mouse event on nsgtk core window
+ *
+ * \param nsgtk_cw The nsgtk core window structure.
+ * \param mouse_state mouse state
+ * \param x location of event
+ * \param y location of event
+ * \return NSERROR_OK on sucess otherwise apropriate error code.
+ */
+ nserror (*mouse)(struct nsgtk_corewindow *nsgtk_cw, browser_mouse_state mouse_state, int x, int y);
+};
+
+/**
+ * initialise elements of gtk core window.
+ *
+ * \param nsgtk_cw A gtk core window structure to initialise
+ * \return NSERROR_OK on successful initialisation otherwise error code.
+ */
+nserror nsgtk_corewindow_init(struct nsgtk_corewindow *nsgtk_cw);
+
+/**
+ * finalise elements of gtk core window.
+ *
+ * \param nsgtk_cw A gtk core window structure to initialise
+ * \return NSERROR_OK on successful finalisation otherwise error code.
+ */
+nserror nsgtk_corewindow_fini(struct nsgtk_corewindow *nsgtk_cw);
+
+#endif
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=ea84f67035ea9899086...
commit ea84f67035ea9899086223c540a79ffec328caef
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
fix gdk to nskey mapping for home/end and missing keypad mappings
diff --git a/frontends/gtk/gui.c b/frontends/gtk/gui.c
index af24d40..d57ebdf 100644
--- a/frontends/gtk/gui.c
+++ b/frontends/gtk/gui.c
@@ -631,60 +631,93 @@ uint32_t gtk_gui_gdkkey_to_nskey(GdkEventKey *key)
return NS_KEY_DELETE_LINE_START;
else
return NS_KEY_DELETE_LEFT;
+
case GDK_KEY(Delete):
if (key->state & GDK_SHIFT_MASK)
return NS_KEY_DELETE_LINE_END;
else
return NS_KEY_DELETE_RIGHT;
- case GDK_KEY(Linefeed): return 13;
- case GDK_KEY(Return): return 10;
- case GDK_KEY(Left): return NS_KEY_LEFT;
- case GDK_KEY(Right): return NS_KEY_RIGHT;
- case GDK_KEY(Up): return NS_KEY_UP;
- case GDK_KEY(Down): return NS_KEY_DOWN;
+
+ case GDK_KEY(Linefeed):
+ return 13;
+
+ case GDK_KEY(Return):
+ return 10;
+
+ case GDK_KEY(Left):
+ case GDK_KEY(KP_Left):
+ return NS_KEY_LEFT;
+
+ case GDK_KEY(Right):
+ case GDK_KEY(KP_Right):
+ return NS_KEY_RIGHT;
+
+ case GDK_KEY(Up):
+ case GDK_KEY(KP_Up):
+ return NS_KEY_UP;
+
+ case GDK_KEY(Down):
+ case GDK_KEY(KP_Down):
+ return NS_KEY_DOWN;
+
case GDK_KEY(Home):
+ case GDK_KEY(KP_Home):
if (key->state & GDK_CONTROL_MASK)
- return NS_KEY_TEXT_START;
- else
return NS_KEY_LINE_START;
+ else
+ return NS_KEY_TEXT_START;
+
case GDK_KEY(End):
+ case GDK_KEY(KP_End):
if (key->state & GDK_CONTROL_MASK)
- return NS_KEY_TEXT_END;
- else
return NS_KEY_LINE_END;
+ else
+ return NS_KEY_TEXT_END;
+
case GDK_KEY(Page_Up):
+ case GDK_KEY(KP_Page_Up):
return NS_KEY_PAGE_UP;
+
case GDK_KEY(Page_Down):
+ case GDK_KEY(KP_Page_Down):
return NS_KEY_PAGE_DOWN;
+
case 'a':
if (key->state & GDK_CONTROL_MASK)
return NS_KEY_SELECT_ALL;
return gdk_keyval_to_unicode(key->keyval);
+
case 'u':
if (key->state & GDK_CONTROL_MASK)
return NS_KEY_DELETE_LINE;
return gdk_keyval_to_unicode(key->keyval);
+
case 'c':
if (key->state & GDK_CONTROL_MASK)
return NS_KEY_COPY_SELECTION;
return gdk_keyval_to_unicode(key->keyval);
+
case 'v':
if (key->state & GDK_CONTROL_MASK)
return NS_KEY_PASTE;
return gdk_keyval_to_unicode(key->keyval);
+
case 'x':
if (key->state & GDK_CONTROL_MASK)
return NS_KEY_CUT_SELECTION;
return gdk_keyval_to_unicode(key->keyval);
+
case 'Z':
case 'y':
if (key->state & GDK_CONTROL_MASK)
return NS_KEY_REDO;
return gdk_keyval_to_unicode(key->keyval);
+
case 'z':
if (key->state & GDK_CONTROL_MASK)
return NS_KEY_UNDO;
return gdk_keyval_to_unicode(key->keyval);
+
case GDK_KEY(Escape):
return NS_KEY_ESCAPE;
@@ -705,9 +738,8 @@ uint32_t gtk_gui_gdkkey_to_nskey(GdkEventKey *key)
case GDK_KEY(Hyper_R):
return 0;
- default:
- return gdk_keyval_to_unicode(key->keyval);
}
+ return gdk_keyval_to_unicode(key->keyval);
}
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=0f5d7cfcd2daade443e...
commit 0f5d7cfcd2daade443ea0695275171247e2cfc22
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
Fix cookie manager keypress consumption return
diff --git a/desktop/cookie_manager.c b/desktop/cookie_manager.c
index 6731e8e..082a14a 100644
--- a/desktop/cookie_manager.c
+++ b/desktop/cookie_manager.c
@@ -844,9 +844,9 @@ void cookie_manager_mouse_action(enum browser_mouse_state mouse, int x, int y)
/* Exported interface, documented in cookie_manager.h */
-void cookie_manager_keypress(uint32_t key)
+bool cookie_manager_keypress(uint32_t key)
{
- treeview_keypress(cm_ctx.tree, key);
+ return treeview_keypress(cm_ctx.tree, key);
}
diff --git a/desktop/cookie_manager.h b/desktop/cookie_manager.h
index 65690d6..4ae74a2 100644
--- a/desktop/cookie_manager.h
+++ b/desktop/cookie_manager.h
@@ -101,7 +101,7 @@ void cookie_manager_mouse_action(enum browser_mouse_state mouse, int x, int y);
* \param key The ucs4 character codepoint
* \return true if the keypress is dealt with, false otherwise.
*/
-void cookie_manager_keypress(uint32_t key);
+bool cookie_manager_keypress(uint32_t key);
/**
* Determine whether there is a selection
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=8dbb61d2f57b32483d6...
commit 8dbb61d2f57b32483d67434e9ac169b5f14e7460
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
fix documentation of mouse state enumeration
diff --git a/include/netsurf/mouse.h b/include/netsurf/mouse.h
index 19cd3ea..1b16998 100644
--- a/include/netsurf/mouse.h
+++ b/include/netsurf/mouse.h
@@ -27,56 +27,59 @@
#ifndef _NETSURF_MOUSE_H_
#define _NETSURF_MOUSE_H_
-/* Mouse state. 1 is primary mouse button (e.g. Select on RISC OS).
- * 2 is secondary mouse button (e.g. Adjust on RISC OS). */
+/**
+ * Mouse state. 1 is primary mouse button (e.g. Select on RISC OS).
+ * 2 is secondary mouse button (e.g. Adjust on RISC OS).
+ *
+ * \note click meaning is different for different front ends. On RISC
+ * OS, it is standard to act on press, so a click is fired at
+ * the same time as a mouse button is pressed. With GTK, it is
+ * standard to act on release, so a click is fired when the
+ * mouse button is released, if the operation wasn't a drag.
+ *
+ * \note double and triple clicks are fired alongside a
+ * BROWSER_MOUSE_CLICK_[1|2] to indicate which button is used.
+ */
typedef enum browser_mouse_state {
- BROWSER_MOUSE_HOVER = 0, /* No mouse buttons pressed,
- * May be used to indicate
- * hover or end of drag. */
-
- BROWSER_MOUSE_PRESS_1 = (1 << 0), /* button 1 pressed */
- BROWSER_MOUSE_PRESS_2 = (1 << 1), /* button 2 pressed */
-
- /* note: click meaning is different for
- * different front ends. On RISC OS, it
- * is standard to act on press, so a
- * click is fired at the same time as a
- * mouse button is pressed. With GTK, it
- * is standard to act on release, so a
- * click is fired when the mouse button
- * is released, if the operation wasn't
- * a drag. */
-
- BROWSER_MOUSE_CLICK_1 = (1 << 2), /* button 1 clicked. */
- BROWSER_MOUSE_CLICK_2 = (1 << 3), /* button 2 clicked. */
-
- BROWSER_MOUSE_DOUBLE_CLICK = (1 << 4), /* button double clicked */
- BROWSER_MOUSE_TRIPLE_CLICK = (1 << 5), /* button triple clicked */
-
- /* note: double and triple clicks are
- * fired alongside a
- * BROWSER_MOUSE_CLICK_[1|2]
- * to indicate which button
- * is used.
- */
-
- BROWSER_MOUSE_DRAG_1 = (1 << 6), /* start of button 1 drag */
- BROWSER_MOUSE_DRAG_2 = (1 << 7), /* start of button 2 drag */
-
- BROWSER_MOUSE_DRAG_ON = (1 << 8), /* a drag operation was started
- * and a mouse button is still
- * pressed */
-
- BROWSER_MOUSE_HOLDING_1 = (1 << 9), /* during button 1 drag */
- BROWSER_MOUSE_HOLDING_2 = (1 << 10), /* during button 2 drag */
-
-
- BROWSER_MOUSE_MOD_1 = (1 << 11), /* 1st modifier key pressed
- * (eg. Shift) */
- BROWSER_MOUSE_MOD_2 = (1 << 12), /* 2nd modifier key pressed
- * (eg. Ctrl) */
- BROWSER_MOUSE_MOD_3 = (1 << 13) /* 3rd modifier key pressed
- * (eg. Alt) */
+ /** No mouse buttons pressed, May be used to indicate hover or
+ * end of drag.
+ */
+ BROWSER_MOUSE_HOVER = 0,
+
+ /** button 1 pressed */
+ BROWSER_MOUSE_PRESS_1 = (1 << 0),
+ /** button 2 pressed */
+ BROWSER_MOUSE_PRESS_2 = (1 << 1),
+
+ /** button 1 clicked. */
+ BROWSER_MOUSE_CLICK_1 = (1 << 2),
+ /** button 2 clicked. */
+ BROWSER_MOUSE_CLICK_2 = (1 << 3),
+
+ /** button double clicked */
+ BROWSER_MOUSE_DOUBLE_CLICK = (1 << 4),
+ /** button triple clicked */
+ BROWSER_MOUSE_TRIPLE_CLICK = (1 << 5),
+
+ /** start of button 1 drag */
+ BROWSER_MOUSE_DRAG_1 = (1 << 6),
+ /** start of button 2 drag */
+ BROWSER_MOUSE_DRAG_2 = (1 << 7),
+
+ /** a drag operation was started and a mouse button is still pressed */
+ BROWSER_MOUSE_DRAG_ON = (1 << 8),
+
+ /** during button 1 drag */
+ BROWSER_MOUSE_HOLDING_1 = (1 << 9),
+ /** during button 2 drag */
+ BROWSER_MOUSE_HOLDING_2 = (1 << 10),
+
+ /** 1st modifier key pressed (eg. Shift) */
+ BROWSER_MOUSE_MOD_1 = (1 << 11),
+ /** 2nd modifier key pressed (eg. Ctrl) */
+ BROWSER_MOUSE_MOD_2 = (1 << 12),
+ /** 3rd modifier key pressed (eg. Alt) */
+ BROWSER_MOUSE_MOD_3 = (1 << 13)
} browser_mouse_state;
-----------------------------------------------------------------------
Summary of changes:
Docs/unit-testing | 166 ++++++++++++
content/llcache.c | 9 +
desktop/cookie_manager.c | 4 +-
desktop/cookie_manager.h | 2 +-
desktop/gui_factory.c | 4 +-
desktop/netsurf.c | 8 +-
desktop/sslcert_viewer.c | 5 +-
desktop/sslcert_viewer.h | 3 +-
frontends/amiga/sslcert.c | 8 +-
frontends/amiga/sslcert.h | 2 +-
frontends/atari/gui.c | 4 +-
frontends/cocoa/gui.m | 4 +-
frontends/gtk/Makefile | 2 +-
frontends/gtk/cookies.c | 277 +++++++++++++------
frontends/gtk/cookies.h | 2 +-
frontends/gtk/corewindow.c | 638 ++++++++++++++++++++++++++++++++++++++++++++
frontends/gtk/corewindow.h | 104 ++++++++
frontends/gtk/gui.c | 66 ++++-
frontends/gtk/ssl_cert.c | 279 +++++++++++++------
frontends/gtk/ssl_cert.h | 3 +-
frontends/monkey/cert.c | 7 +-
frontends/monkey/cert.h | 2 +-
frontends/riscos/gui.h | 2 +-
frontends/riscos/sslcert.c | 22 +-
include/netsurf/misc.h | 3 +-
include/netsurf/mouse.h | 101 +++----
test/Makefile | 5 +-
test/urlescape.c | 178 ++++++++++++
28 files changed, 1646 insertions(+), 264 deletions(-)
create mode 100644 Docs/unit-testing
create mode 100644 frontends/gtk/corewindow.c
create mode 100644 frontends/gtk/corewindow.h
create mode 100644 test/urlescape.c
diff --git a/Docs/unit-testing b/Docs/unit-testing
new file mode 100644
index 0000000..49d82ed
--- /dev/null
+++ b/Docs/unit-testing
@@ -0,0 +1,166 @@
+NetSurf Unit Testing
+====================
+
+Overview
+--------
+
+NetSurf has unit tests integrated in the test directory. These tests
+use the check unit test framework for C [1].
+
+The tests are in a logical hierachy of "suite", "case" and individual
+"test". Historicaly we have split suites of tests into separate test
+programs although the framework does not madate this and some test
+programs contain more than one suite.
+
+
+Execution
+---------
+
+The test programs are executed by using the standard "test" target
+from the top level make invocation. The "coverage" target additionally
+generates code coverage reports allowing visibility on how much of a
+code module is being exercised.
+
+The check library must be installed to run the tests and the CI system
+automatically executes all enabled tests and generates coverage
+reports for each commit.
+
+Adding tests
+------------
+
+The test/Makefile defines each indiviadual test program that should be
+built and executed in the TESTS variable.
+
+The test program source files are defined in a xxx_SRCS variable and
+the make rules will then ensure the target program is built and
+executed.
+
+Each individual test program requires a main function which creates
+one (or more) suites. The suites are added to a test runner and then
+executed and the results reported.
+
+int main(int argc, char **argv)
+{
+ int number_failed;
+ SRunner *sr;
+
+ sr = srunner_create(foo_suite_create());
+ //srunner_add_suite(sr, bar_suite_create());
+
+ srunner_run_all(sr, CK_ENV);
+
+ number_failed = srunner_ntests_failed(sr);
+ srunner_free(sr);
+
+ return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+Suite creation is done with a sub function to logically split suite
+code into sub modules. Each suite has test cases added to it.
+
+Suite *foo_suite_create(void)
+{
+ Suite *s;
+ s = suite_create("foo");
+
+ suite_add_tcase(s, baz_case_create());
+ suite_add_tcase(s, qux_case_create());
+
+ return s;
+}
+
+Test cases include the actual tests to be performed within each case.
+
+TCase *baz_case_create(void)
+{
+ TCase *tc;
+ tc = tcase_create("Baz");
+
+ tcase_add_test(tc, xxyz_test);
+ tcase_add_test(tc, zzyx_test);
+
+ return tc;
+}
+
+A test case may optionally have a fixture which is code that is
+executed before and after each test case. Unchecked fixtures are
+executed once before the test process forks for each test whereas
+checked fixtures are executed for each and every test.
+
+static void fixture_setup(void)
+{
+}
+
+static void fixture_teardown(void)
+{
+}
+
+TCase *qux_case_create(void)
+{
+ TCase *tc;
+
+ /* Matching entry tests */
+ tc = tcase_create("Match");
+
+ tcase_add_checked_fixture(tc,
+ fixture_setup,
+ fixture_teardown);
+
+ tcase_add_test(tc, zzz_test);
+
+ return tc;
+}
+
+Additionally test cases can contain tests executed in a loop. The test
+recives a single integer as a parameter named _i which iterates
+between values specified in the case setup.
+
+TCase *baz_case_create(void)
+{
+ TCase *tc;
+ tc = tcase_create("Baz");
+
+ tcase_add_loop_test(tc, looping_test, 0, 5);
+
+ return tc;
+}
+
+It is also possible to create tests which will generate a signal. The
+most commonly used of these is to check asserts in API calls.
+
+TCase *baz_case_create(void)
+{
+ TCase *tc;
+ tc = tcase_create("Baz");
+
+ tcase_add_test_raise_signal(tc, assert_test, 6);
+
+ return tc;
+}
+
+
+Actual test code is self contained in a function which uses the
+ck_assert macros to test results. The check framework requires each
+test to use the START_TEST and END_TEST macros when definig them.
+
+/**
+ * url access leaf test
+ */
+START_TEST(nsurl_access_leaf_test)
+{
+ nserror err;
+ nsurl *res_url;
+ const struct test_triplets *tst = &access_tests[_i];
+
+ /* not testing create, this should always succeed */
+ err = nsurl_create(tst->test1, &res_url);
+ ck_assert(err == NSERROR_OK);
+
+ ck_assert_str_eq(nsurl_access_leaf(res_url), tst->res);
+
+ nsurl_unref(res_url);
+}
+END_TEST
+
+
+[1] https://libcheck.github.io/check/
diff --git a/content/llcache.c b/content/llcache.c
index 33a9b98..e338c1f 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -2214,6 +2214,11 @@ static nserror llcache_fetch_auth(llcache_object *object, const char *realm)
error = llcache->query_cb(&query, llcache->query_cb_pw,
llcache_query_handle_response, object);
+ if (error != NSERROR_OK) {
+ /* do not continue if error querying user */
+ error = llcache_query_handle_response(false,
+ object);
+ }
} else {
llcache_event event;
@@ -2269,6 +2274,10 @@ static nserror llcache_fetch_cert_error(llcache_object *object,
error = llcache->query_cb(&query, llcache->query_cb_pw,
llcache_query_handle_response, object);
+ if (error != NSERROR_OK) {
+ /* do not continue if error querying user */
+ error = llcache_query_handle_response(false, object);
+ }
} else {
llcache_event event;
diff --git a/desktop/cookie_manager.c b/desktop/cookie_manager.c
index 6731e8e..082a14a 100644
--- a/desktop/cookie_manager.c
+++ b/desktop/cookie_manager.c
@@ -844,9 +844,9 @@ void cookie_manager_mouse_action(enum browser_mouse_state mouse, int x, int y)
/* Exported interface, documented in cookie_manager.h */
-void cookie_manager_keypress(uint32_t key)
+bool cookie_manager_keypress(uint32_t key)
{
- treeview_keypress(cm_ctx.tree, key);
+ return treeview_keypress(cm_ctx.tree, key);
}
diff --git a/desktop/cookie_manager.h b/desktop/cookie_manager.h
index 65690d6..4ae74a2 100644
--- a/desktop/cookie_manager.h
+++ b/desktop/cookie_manager.h
@@ -101,7 +101,7 @@ void cookie_manager_mouse_action(enum browser_mouse_state mouse, int x, int y);
* \param key The ucs4 character codepoint
* \return true if the keypress is dealt with, false otherwise.
*/
-void cookie_manager_keypress(uint32_t key);
+bool cookie_manager_keypress(uint32_t key);
/**
* Determine whether there is a selection
diff --git a/desktop/gui_factory.c b/desktop/gui_factory.c
index cecbe6e..88bb9ba 100644
--- a/desktop/gui_factory.c
+++ b/desktop/gui_factory.c
@@ -685,13 +685,13 @@ static nserror gui_default_launch_url(struct nsurl *url)
}
-static void gui_default_cert_verify(nsurl *url,
+static nserror gui_default_cert_verify(nsurl *url,
const struct ssl_cert_info *certs,
unsigned long num,
nserror (*cb)(bool proceed, void *pw),
void *cbpw)
{
- cb(false, cbpw);
+ return NSERROR_NOT_IMPLEMENTED;
}
static void gui_default_401login_open(nsurl *url, const char *realm,
diff --git a/desktop/netsurf.c b/desktop/netsurf.c
index ffcec04..f1daeab 100644
--- a/desktop/netsurf.c
+++ b/desktop/netsurf.c
@@ -104,21 +104,25 @@ static void netsurf_lwc_iterator(lwc_string *str, void *pw)
static nserror netsurf_llcache_query_handler(const llcache_query *query,
void *pw, llcache_query_response cb, void *cbpw)
{
+ nserror res = NSERROR_OK;
+
switch (query->type) {
case LLCACHE_QUERY_AUTH:
guit->misc->login(query->url, query->data.auth.realm, cb, cbpw);
break;
+
case LLCACHE_QUERY_REDIRECT:
/** \todo Need redirect query dialog */
/* For now, do nothing, as this query type isn't emitted yet */
break;
+
case LLCACHE_QUERY_SSL:
- guit->misc->cert_verify(query->url, query->data.ssl.certs,
+ res = guit->misc->cert_verify(query->url, query->data.ssl.certs,
query->data.ssl.num, cb, cbpw);
break;
}
- return NSERROR_OK;
+ return res;
}
/* exported interface documented in netsurf/netsurf.h */
diff --git a/desktop/sslcert_viewer.c b/desktop/sslcert_viewer.c
index f3eb169..93d6919 100644
--- a/desktop/sslcert_viewer.c
+++ b/desktop/sslcert_viewer.c
@@ -516,8 +516,7 @@ void sslcert_viewer_mouse_action(struct sslcert_session_data *ssl_d,
/* Exported interface, documented in sslcert_viewer.h */
-void sslcert_viewer_keypress(struct sslcert_session_data *ssl_d,
- uint32_t key)
+bool sslcert_viewer_keypress(struct sslcert_session_data *ssl_d, uint32_t key)
{
- treeview_keypress(ssl_d->tree, key);
+ return treeview_keypress(ssl_d->tree, key);
}
diff --git a/desktop/sslcert_viewer.h b/desktop/sslcert_viewer.h
index f7c8f33..9b21cd1 100644
--- a/desktop/sslcert_viewer.h
+++ b/desktop/sslcert_viewer.h
@@ -119,7 +119,6 @@ void sslcert_viewer_mouse_action(struct sslcert_session_data *ssl_d,
* \param key The ucs4 character codepoint
* \return true if the keypress is dealt with, false otherwise.
*/
-void sslcert_viewer_keypress(struct sslcert_session_data *ssl_d,
- uint32_t key);
+bool sslcert_viewer_keypress(struct sslcert_session_data *ssl_d, uint32_t key);
#endif
diff --git a/frontends/amiga/sslcert.c b/frontends/amiga/sslcert.c
index ed72061..83798f2 100644
--- a/frontends/amiga/sslcert.c
+++ b/frontends/amiga/sslcert.c
@@ -27,7 +27,7 @@
#include "amiga/tree.h"
#include "amiga/sslcert.h"
-void gui_cert_verify(nsurl *url,
+nserror gui_cert_verify(nsurl *url,
const struct ssl_cert_info *certs, unsigned long num,
nserror (*cb)(bool proceed, void *pw), void *cbpw)
{
@@ -39,9 +39,13 @@ void gui_cert_verify(nsurl *url,
ssl_current_session = data;
ssl_window = ami_tree_create(TREE_SSLCERT, data);
- if(!ssl_window) return;
+ if (!ssl_window) {
+ return NSERROR_INIT_FAILED;
+ }
ami_tree_open(ssl_window, AMI_TREE_SSLCERT);
+
+ return NSERROR_OK;
}
void ami_ssl_free(struct treeview_window *twin)
diff --git a/frontends/amiga/sslcert.h b/frontends/amiga/sslcert.h
index 953142e..86ce9c4 100644
--- a/frontends/amiga/sslcert.h
+++ b/frontends/amiga/sslcert.h
@@ -19,7 +19,7 @@
#ifndef AMIGA_SSLCERT_H
#define AMIGA_SSLCERT_H
-void gui_cert_verify(nsurl *url,
+nserror gui_cert_verify(nsurl *url,
const struct ssl_cert_info *certs, unsigned long num,
nserror (*cb)(bool proceed, void *pw), void *cbpw);
diff --git a/frontends/atari/gui.c b/frontends/atari/gui.c
index 713db8b..eb15777 100644
--- a/frontends/atari/gui.c
+++ b/frontends/atari/gui.c
@@ -771,7 +771,7 @@ static void gui_401login_open(nsurl *url, const char *realm,
}
-static void
+static nserror
gui_cert_verify(nsurl *url, const struct ssl_cert_info *certs,
unsigned long num, nserror (*cb)(bool proceed, void *pw),
void *cbpw)
@@ -795,7 +795,7 @@ gui_cert_verify(nsurl *url, const struct ssl_cert_info *certs,
&data);
atari_sslcert_viewer_open(data);
}
-
+ return NSERROR_OK;
}
void gui_set_input_gui_window(struct gui_window *gw)
diff --git a/frontends/cocoa/gui.m b/frontends/cocoa/gui.m
index b1847eb..7e180fa 100644
--- a/frontends/cocoa/gui.m
+++ b/frontends/cocoa/gui.m
@@ -285,13 +285,13 @@ static nserror gui_launch_url(nsurl *url)
struct ssl_cert_info;
-static void
+static nserror
gui_cert_verify(nsurl *url,
const struct ssl_cert_info *certs,
unsigned long num,
nserror (*cb)(bool proceed,void *pw), void *cbpw)
{
- cb( false, cbpw );
+ return NSERROR_NOT_IMPLEMENTED;
}
diff --git a/frontends/gtk/Makefile b/frontends/gtk/Makefile
index aae1d44..f8f7d8c 100644
--- a/frontends/gtk/Makefile
+++ b/frontends/gtk/Makefile
@@ -163,7 +163,7 @@ S_FRONTEND := gui.c schedule.c layout_pango.c bitmap.c plotters.c \
selection.c history.c window.c fetch.c download.c menu.c \
print.c search.c tabs.c toolbar.c gettext.c \
compat.c cookies.c hotlist.c viewdata.c viewsource.c \
- preferences.c about.c ssl_cert.c resources.c
+ preferences.c about.c ssl_cert.c resources.c corewindow.c
# This is the final source build list
# Note this is deliberately *not* expanded here as common and image
diff --git a/frontends/gtk/cookies.c b/frontends/gtk/cookies.c
index f252e6b..d8f8b5d 100644
--- a/frontends/gtk/cookies.c
+++ b/frontends/gtk/cookies.c
@@ -16,28 +16,34 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/** \file
- * Cookies (implementation).
+/**
+ * \file
+ * Implementation of GTK cookie manager.
*/
-#include <gtk/gtk.h>
#include <stdint.h>
+#include <stdlib.h>
+#include <gtk/gtk.h>
#include "utils/log.h"
#include "netsurf/keypress.h"
+#include "netsurf/plotters.h"
#include "desktop/cookie_manager.h"
-#include "desktop/plot_style.h"
-#include "desktop/tree.h"
+#include "desktop/treeview.h"
#include "gtk/cookies.h"
#include "gtk/plotters.h"
#include "gtk/scaffolding.h"
-#include "gtk/treeview.h"
#include "gtk/resources.h"
+#include "gtk/corewindow.h"
+
+struct nsgtk_cookie_window {
+ struct nsgtk_corewindow core;
+ GtkBuilder *builder;
+ GtkWindow *wnd;
+};
-static struct nsgtk_treeview *cookies_treeview;
-static GtkBuilder *cookie_builder;
-static GtkWindow *wndCookies = NULL;
+static struct nsgtk_cookie_window *cookie_window = NULL;
#define MENUPROTO(x) static gboolean nsgtk_on_##x##_activate( \
GtkMenuItem *widget, gpointer g)
@@ -85,80 +91,6 @@ static struct menu_events menu_events[] = {
};
-
-/**
- * Connects menu events in the cookies window.
- */
-static void nsgtk_cookies_init_menu(void)
-{
- struct menu_events *event = menu_events;
- GtkWidget *w;
-
- while (event->widget != NULL) {
- w = GTK_WIDGET(gtk_builder_get_object(cookie_builder, event->widget));
- if (w == NULL) {
- LOG("Unable to connect menu widget ""%s""", event->widget); } else {
- g_signal_connect(G_OBJECT(w), "activate", event->handler, cookies_treeview);
- }
- event++;
- }
-}
-
-/**
- * Creates the window for the cookies tree.
- *
- * \return NSERROR_OK on success else appropriate error code on faliure.
- */
-static nserror nsgtk_cookies_init(void)
-{
- GtkScrolledWindow *scrolled;
- GtkDrawingArea *drawing_area;
- nserror res;
-
- if (wndCookies != NULL) {
- return NSERROR_OK;
- }
-
- res = nsgtk_builder_new_from_resname("cookies", &cookie_builder);
- if (res != NSERROR_OK) {
- LOG("Cookie UI builder init failed");
- return res;
- }
-
- gtk_builder_connect_signals(cookie_builder, NULL);
-
- wndCookies = GTK_WINDOW(gtk_builder_get_object(cookie_builder,
- "wndCookies"));
-
- scrolled = GTK_SCROLLED_WINDOW(gtk_builder_get_object(cookie_builder,
- "cookiesScrolled"));
-
- drawing_area = GTK_DRAWING_AREA(gtk_builder_get_object(cookie_builder,
- "cookiesDrawingArea"));
-
- cookies_treeview = nsgtk_treeview_create(TREE_COOKIES,
- wndCookies,
- scrolled,
- drawing_area,
- NULL);
- if (cookies_treeview == NULL) {
- return NSERROR_INIT_FAILED;
- }
-
-#define CONNECT(obj, sig, callback, ptr) \
- g_signal_connect(G_OBJECT(obj), (sig), G_CALLBACK(callback), (ptr))
-
- CONNECT(wndCookies, "delete_event", gtk_widget_hide_on_delete, NULL);
- CONNECT(wndCookies, "hide", nsgtk_tree_window_hide, cookies_treeview);
-
- nsgtk_cookies_init_menu();
-
- return NSERROR_OK;
-}
-
-
-
-
/* edit menu */
MENUHANDLER(delete_selected)
{
@@ -222,6 +154,162 @@ MENUHANDLER(collapse_cookies)
return TRUE;
}
+/**
+ * Connects menu events in the cookies window.
+ */
+static void nsgtk_cookies_init_menu(struct nsgtk_cookie_window *ncwin)
+{
+ struct menu_events *event = menu_events;
+ GtkWidget *w;
+
+ while (event->widget != NULL) {
+ w = GTK_WIDGET(gtk_builder_get_object(ncwin->builder,
+ event->widget));
+ if (w == NULL) {
+ LOG("Unable to connect menu widget ""%s""",
+ event->widget);
+ } else {
+ g_signal_connect(G_OBJECT(w),
+ "activate",
+ event->handler,
+ ncwin);
+ }
+ event++;
+ }
+}
+
+/**
+ * callback for mouse action on cookie window
+ *
+ * \param nsgtk_cw The nsgtk core window structure.
+ * \param mouse_state netsurf mouse state on event
+ * \param x location of event
+ * \param y location of event
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+nsgtk_cookies_mouse(struct nsgtk_corewindow *nsgtk_cw,
+ browser_mouse_state mouse_state,
+ int x, int y)
+{
+ cookie_manager_mouse_action(mouse_state, x, y);
+
+ return NSERROR_OK;
+}
+
+/**
+ * callback for keypress on cookie window
+ *
+ * \param nsgtk_cw The nsgtk core window structure.
+ * \param nskey The netsurf key code
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+nsgtk_cookies_key(struct nsgtk_corewindow *nsgtk_cw, uint32_t nskey)
+{
+ if (cookie_manager_keypress(nskey)) {
+ return NSERROR_OK;
+ }
+ return NSERROR_NOT_IMPLEMENTED;
+}
+
+/**
+ * callback on draw event for cookie window
+ *
+ * \param nsgtk_cw The nsgtk core window structure.
+ * \param r The rectangle of the window that needs updating.
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+nsgtk_cookies_draw(struct nsgtk_corewindow *nsgtk_cw, struct rect *r)
+{
+ struct redraw_context ctx = {
+ .interactive = true,
+ .background_images = true,
+ .plot = &nsgtk_plotters
+ };
+
+ cookie_manager_redraw(0, 0, r, &ctx);
+
+ return NSERROR_OK;
+}
+
+/**
+ * Creates the window for the cookies tree.
+ *
+ * \return NSERROR_OK on success else appropriate error code on faliure.
+ */
+static nserror nsgtk_cookies_init(void)
+{
+ struct nsgtk_cookie_window *ncwin;
+ nserror res;
+
+ if (cookie_window != NULL) {
+ return NSERROR_OK;
+ }
+
+ res = treeview_init(0);
+ if (res != NSERROR_OK) {
+ return res;
+ }
+
+ ncwin = malloc(sizeof(struct nsgtk_cookie_window));
+ if (ncwin == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ res = nsgtk_builder_new_from_resname("cookies", &ncwin->builder);
+ if (res != NSERROR_OK) {
+ LOG("Cookie UI builder init failed");
+ free(ncwin);
+ return res;
+ }
+
+ gtk_builder_connect_signals(ncwin->builder, NULL);
+
+ ncwin->wnd = GTK_WINDOW(gtk_builder_get_object(ncwin->builder,
+ "wndCookies"));
+
+ ncwin->core.scrolled = GTK_SCROLLED_WINDOW(
+ gtk_builder_get_object(ncwin->builder, "cookiesScrolled"));
+
+ ncwin->core.drawing_area = GTK_DRAWING_AREA(
+ gtk_builder_get_object(ncwin->builder, "cookiesDrawingArea"));
+
+ /* make the delete event hide the window */
+ g_signal_connect(G_OBJECT(ncwin->wnd),
+ "delete_event",
+ G_CALLBACK(gtk_widget_hide_on_delete),
+ NULL);
+
+ nsgtk_cookies_init_menu(ncwin);
+
+ ncwin->core.draw = nsgtk_cookies_draw;
+ ncwin->core.key = nsgtk_cookies_key;
+ ncwin->core.mouse = nsgtk_cookies_mouse;
+
+ res = nsgtk_corewindow_init(&ncwin->core);
+ if (res != NSERROR_OK) {
+ free(ncwin);
+ return res;
+ }
+
+ res = cookie_manager_init(ncwin->core.cb_table,
+ (struct core_window *)ncwin);
+ if (res != NSERROR_OK) {
+ free(ncwin);
+ return res;
+ }
+
+ /* memoise window so it can be represented when necessary
+ * instead of recreating every time.
+ */
+ cookie_window = ncwin;
+
+ return NSERROR_OK;
+}
+
+
/* exported function documented gtk/cookies.h */
nserror nsgtk_cookies_present(void)
{
@@ -229,16 +317,29 @@ nserror nsgtk_cookies_present(void)
res = nsgtk_cookies_init();
if (res == NSERROR_OK) {
- gtk_window_present(wndCookies);
+ gtk_window_present(cookie_window->wnd);
}
return res;
}
+
/* exported function documented gtk/cookies.h */
-void nsgtk_cookies_destroy(void)
+nserror nsgtk_cookies_destroy(void)
{
- /** \todo what about cookie_builder? */
- if (wndCookies != NULL) {
- nsgtk_treeview_destroy(cookies_treeview);
+ nserror res;
+
+ if (cookie_window == NULL) {
+ return NSERROR_OK;
+ }
+
+ res = cookie_manager_fini();
+ if (res == NSERROR_OK) {
+ res = nsgtk_corewindow_fini(&cookie_window->core);
+ gtk_widget_destroy(GTK_WIDGET(cookie_window->wnd));
+ g_object_unref(G_OBJECT(cookie_window->builder));
+ free(cookie_window);
+ cookie_window = NULL;
}
+
+ return res;
}
diff --git a/frontends/gtk/cookies.h b/frontends/gtk/cookies.h
index 2af05e1..c1a68b7 100644
--- a/frontends/gtk/cookies.h
+++ b/frontends/gtk/cookies.h
@@ -35,7 +35,7 @@ nserror nsgtk_cookies_present(void);
*
* \return NSERROR_OK on success else appropriate error code on faliure.
*/
-void nsgtk_cookies_destroy(void);
+nserror nsgtk_cookies_destroy(void);
#endif /* __NSGTK_COOKIES_H__ */
diff --git a/frontends/gtk/corewindow.c b/frontends/gtk/corewindow.c
new file mode 100644
index 0000000..11dec83
--- /dev/null
+++ b/frontends/gtk/corewindow.c
@@ -0,0 +1,638 @@
+/*
+ * Copyright 2016 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 generic core window interface.
+ *
+ * Provides interface for core renderers to the gtk toolkit drawable area.
+ * \todo should the interface really be called coredrawable?
+ *
+
+ * This module is an object that must be encapsulated. Client users
+ * should embed a struct nsgtk_corewindow at the beginning of their
+ * context for this display surface, fill in relevant data and then
+ * call nsgtk_corewindow_init()
+ *
+ * The nsgtk core window structure requires the drawing area and
+ * scrollable widgets are present and the callback for draw, key and
+ * mouse operations.
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <math.h>
+#include <gtk/gtk.h>
+
+#include "utils/log.h"
+#include "utils/utils.h"
+#include "utils/messages.h"
+#include "utils/utf8.h"
+#include "netsurf/keypress.h"
+#include "netsurf/mouse.h"
+#include "desktop/plot_style.h"
+
+#include "gtk/compat.h"
+#include "gtk/gui.h" /* just for gtk_gui_gdkkey_to_nskey */
+#include "gtk/plotters.h"
+#include "gtk/corewindow.h"
+
+/**
+ * Convert GDK mouse event to netsurf mouse state
+ */
+static browser_mouse_state nsgtk_cw_gdkbutton_to_nsstate(GdkEventButton *event)
+{
+ browser_mouse_state ms;
+
+ if (event->type == GDK_2BUTTON_PRESS) {
+ ms = BROWSER_MOUSE_DOUBLE_CLICK;
+ } else {
+ ms = BROWSER_MOUSE_HOVER;
+ }
+
+ /* button state */
+ switch (event->button) {
+ case 1:
+ ms |= BROWSER_MOUSE_PRESS_1;
+ break;
+
+ case 2:
+ ms |= BROWSER_MOUSE_PRESS_2;
+ break;
+ }
+
+ /* Handle the modifiers too */
+ if (event->state & GDK_SHIFT_MASK) {
+ ms |= BROWSER_MOUSE_MOD_1;
+ }
+
+ if (event->state & GDK_CONTROL_MASK) {
+ ms |= BROWSER_MOUSE_MOD_2;
+ }
+
+ if (event->state & GDK_MOD1_MASK) {
+ ms |= BROWSER_MOUSE_MOD_3;
+ }
+
+ return ms;
+}
+
+/**
+ * gtk event on mouse button press.
+ *
+ * \param widget The gtk widget the event occoured for.
+ * \param event The event that occoured.
+ * \param g The context pointer passed when teh event was registered.
+ */
+static gboolean
+nsgtk_cw_button_press_event(GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer g)
+{
+ struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)g;
+ struct nsgtk_corewindow_mouse *mouse = &nsgtk_cw->mouse_state;
+
+ gtk_im_context_reset(nsgtk_cw->input_method);
+ gtk_widget_grab_focus(GTK_WIDGET(nsgtk_cw->drawing_area));
+
+ /* record event information for potentially starting a drag. */
+ mouse->pressed_x = mouse->last_x = event->x;
+ mouse->pressed_y = mouse->last_y = event->y;
+ mouse->pressed = true;
+
+ mouse->state = nsgtk_cw_gdkbutton_to_nsstate(event);
+
+ nsgtk_cw->mouse(nsgtk_cw, mouse->state, event->x, event->y);
+
+ return TRUE;
+}
+
+static gboolean
+nsgtk_cw_button_release_event(GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer g)
+{
+ struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)g;
+ struct nsgtk_corewindow_mouse *mouse = &nsgtk_cw->mouse_state;
+
+ /* only button 1 clicks are considered double clicks. If the
+ * mouse state is PRESS then we are waiting for a release to
+ * emit a click event, otherwise just reset the state to nothing.
+ */
+ if (mouse->state & BROWSER_MOUSE_DOUBLE_CLICK) {
+ if (mouse->state & BROWSER_MOUSE_PRESS_1) {
+ mouse->state ^= BROWSER_MOUSE_PRESS_1 |
+ BROWSER_MOUSE_CLICK_1;
+ } else if (mouse->state & BROWSER_MOUSE_PRESS_2) {
+ mouse->state ^= (BROWSER_MOUSE_PRESS_2 |
+ BROWSER_MOUSE_CLICK_2 |
+ BROWSER_MOUSE_DOUBLE_CLICK);
+ }
+ } else if (mouse->state & BROWSER_MOUSE_PRESS_1) {
+ mouse->state ^= (BROWSER_MOUSE_PRESS_1 |
+ BROWSER_MOUSE_CLICK_1);
+ } else if (mouse->state & BROWSER_MOUSE_PRESS_2) {
+ mouse->state ^= (BROWSER_MOUSE_PRESS_2 |
+ BROWSER_MOUSE_CLICK_2);
+ } else if (mouse->state & BROWSER_MOUSE_HOLDING_1) {
+ mouse->state ^= (BROWSER_MOUSE_HOLDING_1 |
+ BROWSER_MOUSE_DRAG_ON);
+ } else if (mouse->state & BROWSER_MOUSE_HOLDING_2) {
+ mouse->state ^= (BROWSER_MOUSE_HOLDING_2 |
+ BROWSER_MOUSE_DRAG_ON);
+ }
+
+ /* Handle modifiers being removed */
+ if ((mouse->state & BROWSER_MOUSE_MOD_1) &&
+ !(event->state & GDK_SHIFT_MASK)) {
+ mouse->state ^= BROWSER_MOUSE_MOD_1;
+ }
+ if ((mouse->state & BROWSER_MOUSE_MOD_2) &&
+ !(event->state & GDK_CONTROL_MASK)) {
+ mouse->state ^= BROWSER_MOUSE_MOD_2;
+ }
+ if ((mouse->state & BROWSER_MOUSE_MOD_3) &&
+ !(event->state & GDK_MOD1_MASK)) {
+ mouse->state ^= BROWSER_MOUSE_MOD_3;
+ }
+
+ /* end drag with modifiers */
+ if (mouse->state & (BROWSER_MOUSE_MOD_1 |
+ BROWSER_MOUSE_MOD_2 |
+ BROWSER_MOUSE_MOD_3)) {
+ mouse->state = BROWSER_MOUSE_HOVER;
+ }
+
+ nsgtk_cw->mouse(nsgtk_cw, mouse->state, event->x, event->y);
+
+ mouse->pressed = false;
+
+ return TRUE;
+}
+
+static gboolean
+nsgtk_cw_motion_notify_event(GtkWidget *widget,
+ GdkEventMotion *event, gpointer g)
+{
+ struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)g;
+ struct nsgtk_corewindow_mouse *mouse = &nsgtk_cw->mouse_state;
+
+ if (mouse->pressed == false) {
+ return TRUE;
+ }
+
+ if ((fabs(event->x - mouse->last_x) < 5.0) &&
+ (fabs(event->y - mouse->last_y) < 5.0)) {
+ /* Mouse hasn't moved far enough from press coordinate
+ * for this to be considered a drag.
+ */
+ return FALSE;
+ }
+
+ /* This is a drag, ensure it's always treated as such, even if
+ * we drag back over the press location.
+ */
+ mouse->last_x = INT_MIN;
+ mouse->last_y = INT_MIN;
+
+
+ if (mouse->state & BROWSER_MOUSE_PRESS_1) {
+ /* Start button 1 drag */
+ nsgtk_cw->mouse(nsgtk_cw,
+ BROWSER_MOUSE_DRAG_1,
+ mouse->pressed_x,
+ mouse->pressed_y);
+
+ /* Replace PRESS with HOLDING and declare drag in progress */
+ mouse->state ^= (BROWSER_MOUSE_PRESS_1 |
+ BROWSER_MOUSE_HOLDING_1);
+ mouse->state |= BROWSER_MOUSE_DRAG_ON;
+
+ } else if (mouse->state & BROWSER_MOUSE_PRESS_2) {
+ /* Start button 2s drag */
+ nsgtk_cw->mouse(nsgtk_cw,
+ BROWSER_MOUSE_DRAG_2,
+ mouse->pressed_x,
+ mouse->pressed_y);
+
+ /* Replace PRESS with HOLDING and declare drag in progress */
+ mouse->state ^= (BROWSER_MOUSE_PRESS_2 |
+ BROWSER_MOUSE_HOLDING_2);
+ mouse->state |= BROWSER_MOUSE_DRAG_ON;
+
+ } else {
+ /* continue drag */
+
+ /* Handle modifiers being removed */
+ if ((mouse->state & BROWSER_MOUSE_MOD_1) &&
+ !(event->state & GDK_SHIFT_MASK)) {
+ mouse->state ^= BROWSER_MOUSE_MOD_1;
+ }
+ if ((mouse->state & BROWSER_MOUSE_MOD_2) &&
+ !(event->state & GDK_CONTROL_MASK)) {
+ mouse->state ^= BROWSER_MOUSE_MOD_2;
+ }
+ if ((mouse->state & BROWSER_MOUSE_MOD_3) &&
+ !(event->state & GDK_MOD1_MASK)) {
+ mouse->state ^= BROWSER_MOUSE_MOD_3;
+ }
+
+ if (mouse->state &
+ (BROWSER_MOUSE_HOLDING_1 | BROWSER_MOUSE_HOLDING_2)) {
+ nsgtk_cw->mouse(nsgtk_cw,
+ mouse->state,
+ event->x, event->y);
+ }
+ }
+
+ return TRUE;
+}
+
+
+/**
+ * Deal with keypress events not handled but input method or callback
+ *
+ * \param nsgtk_cw nsgtk core window key event happened in.
+ * \param nskey The netsurf keycode of the event.
+ * \return NSERROR_OK on sucess otherwise an error code.
+ */
+static nserror nsgtk_cw_key(struct nsgtk_corewindow *nsgtk_cw, uint32_t nskey)
+{
+ double value;
+ GtkAdjustment *vscroll;
+ GtkAdjustment *hscroll;
+ GtkAdjustment *scroll = NULL;
+ gdouble hpage, vpage;
+
+ vscroll = gtk_scrolled_window_get_vadjustment(nsgtk_cw->scrolled);
+ hscroll = gtk_scrolled_window_get_hadjustment(nsgtk_cw->scrolled);
+ g_object_get(vscroll, "page-size", &vpage, NULL);
+ g_object_get(hscroll, "page-size", &hpage, NULL);
+
+ switch(nskey) {
+ case NS_KEY_TEXT_START:
+ scroll = vscroll;
+ value = nsgtk_adjustment_get_lower(scroll);
+ break;
+
+ case NS_KEY_TEXT_END:
+ scroll = vscroll;
+ value = nsgtk_adjustment_get_upper(scroll) - vpage;
+ if (value < nsgtk_adjustment_get_lower(scroll))
+ value = nsgtk_adjustment_get_lower(scroll);
+ break;
+
+ case NS_KEY_LEFT:
+ scroll = hscroll;
+ value = gtk_adjustment_get_value(scroll) -
+ nsgtk_adjustment_get_step_increment(scroll);
+ if (value < nsgtk_adjustment_get_lower(scroll))
+ value = nsgtk_adjustment_get_lower(scroll);
+ break;
+
+ case NS_KEY_RIGHT:
+ scroll = hscroll;
+ value = gtk_adjustment_get_value(scroll) +
+ nsgtk_adjustment_get_step_increment(scroll);
+ if (value > nsgtk_adjustment_get_upper(scroll) - hpage)
+ value = nsgtk_adjustment_get_upper(scroll) - hpage;
+ break;
+ case NS_KEY_UP:
+ scroll = vscroll;
+ value = gtk_adjustment_get_value(scroll) -
+ nsgtk_adjustment_get_step_increment(scroll);
+ if (value < nsgtk_adjustment_get_lower(scroll))
+ value = nsgtk_adjustment_get_lower(scroll);
+ break;
+
+ case NS_KEY_DOWN:
+ scroll = vscroll;
+ value = gtk_adjustment_get_value(scroll) +
+ nsgtk_adjustment_get_step_increment(scroll);
+ if (value > nsgtk_adjustment_get_upper(scroll) - vpage)
+ value = nsgtk_adjustment_get_upper(scroll) - vpage;
+ break;
+
+ case NS_KEY_PAGE_UP:
+ scroll = vscroll;
+ value = gtk_adjustment_get_value(scroll) -
+ nsgtk_adjustment_get_page_increment(scroll);
+
+ if (value < nsgtk_adjustment_get_lower(scroll))
+ value = nsgtk_adjustment_get_lower(scroll);
+
+ break;
+
+ case NS_KEY_PAGE_DOWN:
+ scroll = vscroll;
+ value = gtk_adjustment_get_value(scroll) +
+ nsgtk_adjustment_get_page_increment(scroll);
+
+ if (value > nsgtk_adjustment_get_upper(scroll) - vpage)
+ value = nsgtk_adjustment_get_upper(scroll) - vpage;
+ break;
+
+ }
+
+ if (scroll != NULL) {
+ gtk_adjustment_set_value(scroll, value);
+ }
+
+ return NSERROR_OK;
+}
+
+/**
+ * gtk event on key press.
+ *
+ * \param widget The gtk widget the event occoured for.
+ * \param event The event that occoured.
+ * \param g The context pointer passed when teh event was registered.
+ */
+static gboolean
+nsgtk_cw_keypress_event(GtkWidget *widget, GdkEventKey *event, gpointer g)
+{
+ struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)g;
+ nserror res;
+ uint32_t nskey;
+
+ /* check to see if gtk input method swallowed the keypress */
+ if (gtk_im_context_filter_keypress(nsgtk_cw->input_method, event)) {
+ return TRUE;
+ }
+
+ /* convert gtk event to nskey */
+ nskey = gtk_gui_gdkkey_to_nskey(event);
+
+ /* attempt to handle keypress in caller */
+ res = nsgtk_cw->key(nsgtk_cw, nskey);
+ if (res == NSERROR_OK) {
+ return TRUE;
+ } else if (res != NSERROR_NOT_IMPLEMENTED) {
+ LOG("%s", messages_get_errorcode(res));
+ return FALSE;
+ }
+
+ /* deal with unprocessed keypress */
+ res = nsgtk_cw_key(nsgtk_cw, nskey);
+ if (res != NSERROR_OK) {
+ LOG("%s", messages_get_errorcode(res));
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+static gboolean
+nsgtk_cw_keyrelease_event(GtkWidget *widget, GdkEventKey *event, gpointer g)
+{
+ struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)g;
+
+ return gtk_im_context_filter_keypress(nsgtk_cw->input_method, event);
+}
+
+
+static void
+nsgtk_cw_input_method_commit(GtkIMContext *ctx, const gchar *str, gpointer g)
+{
+ struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)g;
+ size_t len;
+ size_t offset = 0;
+ uint32_t nskey;
+
+ len = strlen(str);
+
+ while (offset < len) {
+ nskey = utf8_to_ucs4(str + offset, len - offset);
+
+ nsgtk_cw->key(nsgtk_cw, nskey);
+
+ offset = utf8_next(str, len, offset);
+ }
+}
+
+
+#if GTK_CHECK_VERSION(3,0,0)
+
+/* signal handler for core window redraw */
+static gboolean
+nsgtk_cw_draw_event(GtkWidget *widget, cairo_t *cr, gpointer data)
+{
+ struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)data;
+ double x1;
+ double y1;
+ double x2;
+ double y2;
+ struct rect clip;
+
+ current_widget = widget;
+ current_cr = cr;
+
+ cairo_clip_extents(cr, &x1, &y1, &x2, &y2);
+
+ if (tv->tree_flags == TREE_SSLCERT) {
+ ssl_current_session = tv->ssl_data;
+ }
+
+ clip.x0 = x1;
+ clip.y0 = y1;
+ clip.x1 = x2;
+ clip.y1 = y2;
+
+ nsgtk_cw->draw(nsgtk_cw, &clip);
+
+ current_widget = NULL;
+
+ return FALSE;
+}
+
+#else
+
+/* signal handler for core window redraw */
+static gboolean
+nsgtk_cw_draw_event(GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer g)
+{
+ struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)g;
+ struct rect clip;
+
+ clip.x0 = event->area.x;
+ clip.y0 = event->area.y;
+ clip.x1 = event->area.x + event->area.width;
+ clip.y1 = event->area.y + event->area.height;
+
+ current_widget = widget;
+ current_cr = gdk_cairo_create(nsgtk_widget_get_window(widget));
+
+ nsgtk_cw->draw(nsgtk_cw, &clip);
+
+ current_widget = NULL;
+ cairo_destroy(current_cr);
+
+ return FALSE;
+}
+
+#endif
+
+/**
+ * callback from core to request a redraw
+ */
+static void
+nsgtk_cw_redraw_request(struct core_window *cw, const struct rect *r)
+{
+ struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)cw;
+
+ gtk_widget_queue_draw_area(GTK_WIDGET(nsgtk_cw->drawing_area),
+ r->x0, r->y0,
+ r->x1 - r->x0, r->y1 - r->y0);
+}
+
+
+static void
+nsgtk_cw_update_size(struct core_window *cw, int width, int height)
+{
+ struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)cw;
+
+ gtk_widget_set_size_request(GTK_WIDGET(nsgtk_cw->drawing_area),
+ width, height);
+}
+
+
+static void
+nsgtk_cw_scroll_visible(struct core_window *cw, const struct rect *r)
+{
+ struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)cw;
+ int y = 0, height = 0, y0, y1;
+ gdouble page;
+ GtkAdjustment *vadj;
+
+ vadj = gtk_scrolled_window_get_vadjustment(nsgtk_cw->scrolled);
+
+ assert(vadj);
+
+ g_object_get(vadj, "page-size", &page, NULL);
+
+ y0 = (int)(gtk_adjustment_get_value(vadj));
+ y1 = y0 + page;
+
+ if ((y >= y0) && (y + height <= y1))
+ return;
+ if (y + height > y1)
+ y0 = y0 + (y + height - y1);
+ if (y < y0)
+ y0 = y;
+ gtk_adjustment_set_value(vadj, y0);
+}
+
+
+static void
+nsgtk_cw_get_window_dimensions(struct core_window *cw, int *width, int *height)
+{
+ struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)cw;
+ GtkAdjustment *vadj;
+ GtkAdjustment *hadj;
+ gdouble page;
+
+ if (width != NULL) {
+ hadj = gtk_scrolled_window_get_hadjustment(nsgtk_cw->scrolled);
+ g_object_get(hadj, "page-size", &page, NULL);
+ *width = page;
+ }
+
+ if (height != NULL) {
+ vadj = gtk_scrolled_window_get_vadjustment(nsgtk_cw->scrolled);
+ g_object_get(vadj, "page-size", &page, NULL);
+ *height = page;
+ }}
+
+
+static void
+nsgtk_cw_drag_status(struct core_window *cw, core_window_drag_status ds)
+{
+ struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)cw;
+ nsgtk_cw->drag_staus = ds;
+}
+
+
+struct core_window_callback_table nsgtk_cw_cb_table = {
+ .redraw_request = nsgtk_cw_redraw_request,
+ .update_size = nsgtk_cw_update_size,
+ .scroll_visible = nsgtk_cw_scroll_visible,
+ .get_window_dimensions = nsgtk_cw_get_window_dimensions,
+ .drag_status = nsgtk_cw_drag_status
+};
+
+/* exported function documented gtk/corewindow.h */
+nserror nsgtk_corewindow_init(struct nsgtk_corewindow *nsgtk_cw)
+{
+ nsgtk_cw->cb_table = &nsgtk_cw_cb_table;
+
+ /* input method setup */
+ nsgtk_cw->input_method = gtk_im_multicontext_new();
+ gtk_im_context_set_client_window(nsgtk_cw->input_method,
+ gtk_widget_get_parent_window(GTK_WIDGET(nsgtk_cw->drawing_area)));
+ gtk_im_context_set_use_preedit(nsgtk_cw->input_method, FALSE);
+
+ g_signal_connect(G_OBJECT(nsgtk_cw->input_method),
+ "commit",
+ G_CALLBACK(nsgtk_cw_input_method_commit),
+ nsgtk_cw);
+
+ nsgtk_connect_draw_event(GTK_WIDGET(nsgtk_cw->drawing_area),
+ G_CALLBACK(nsgtk_cw_draw_event),
+ nsgtk_cw);
+
+ g_signal_connect(G_OBJECT(nsgtk_cw->drawing_area),
+ "button-press-event",
+ G_CALLBACK(nsgtk_cw_button_press_event),
+ nsgtk_cw);
+
+ g_signal_connect(G_OBJECT(nsgtk_cw->drawing_area),
+ "button-release-event",
+ G_CALLBACK(nsgtk_cw_button_release_event),
+ nsgtk_cw);
+
+ g_signal_connect(G_OBJECT(nsgtk_cw->drawing_area),
+ "motion-notify-event",
+ G_CALLBACK(nsgtk_cw_motion_notify_event),
+ nsgtk_cw);
+
+ g_signal_connect(G_OBJECT(nsgtk_cw->drawing_area),
+ "key-press-event",
+ G_CALLBACK(nsgtk_cw_keypress_event),
+ nsgtk_cw);
+
+ g_signal_connect(G_OBJECT(nsgtk_cw->drawing_area),
+ "key-release-event",
+ G_CALLBACK(nsgtk_cw_keyrelease_event),
+ nsgtk_cw);
+
+ nsgtk_widget_override_background_color(
+ GTK_WIDGET(nsgtk_cw->drawing_area),
+ GTK_STATE_NORMAL,
+ 0, 0xffff, 0xffff, 0xffff);
+
+ return NSERROR_OK;
+}
+
+nserror nsgtk_corewindow_fini(struct nsgtk_corewindow *nsgtk_cw)
+{
+ g_object_unref(nsgtk_cw->input_method);
+
+ return NSERROR_OK;
+}
diff --git a/frontends/gtk/corewindow.h b/frontends/gtk/corewindow.h
new file mode 100644
index 0000000..d6f3011
--- /dev/null
+++ b/frontends/gtk/corewindow.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2016 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/>.
+ */
+
+#ifndef GTK_COREWINDOW_H
+#define GTK_COREWINDOW_H
+
+#include "desktop/core_window.h"
+
+/**
+ * nsgtk core window mouse state
+ */
+struct nsgtk_corewindow_mouse {
+ browser_mouse_state state; /**< last event status */
+ bool pressed;
+ int pressed_x;
+ int pressed_y;
+ int last_x;
+ int last_y;
+};
+
+/**
+ * nsgtk core window state
+ */
+struct nsgtk_corewindow {
+ /* public variables */
+ /** GTK drawable widget */
+ GtkDrawingArea *drawing_area;
+ /** scrollable area drawing area is within */
+ GtkScrolledWindow *scrolled;
+
+ /* private variables */
+ /** Input method */
+ GtkIMContext *input_method;
+ /** table of callbacks for core window operations */
+ struct core_window_callback_table *cb_table;
+ /** mouse state */
+ struct nsgtk_corewindow_mouse mouse_state;
+ /** drag status set by core */
+ core_window_drag_status drag_staus;
+
+ /**
+ * callback to draw on drawable area of nsgtk core window
+ *
+ * \param nsgtk_cw The nsgtk core window structure.
+ * \param r The rectangle of the window that needs updating.
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+ nserror (*draw)(struct nsgtk_corewindow *nsgtk_cw, struct rect *r);
+
+ /**
+ * callback for keypress on nsgtk core window
+ *
+ * \param nsgtk_cw The nsgtk core window structure.
+ * \param nskey The netsurf key code.
+ * \return NSERROR_OK if key processed,
+ * NSERROR_NOT_IMPLEMENTED if key not processed
+ * otherwise apropriate error code
+ */
+ nserror (*key)(struct nsgtk_corewindow *nsgtk_cw, uint32_t nskey);
+
+ /**
+ * callback for mouse event on nsgtk core window
+ *
+ * \param nsgtk_cw The nsgtk core window structure.
+ * \param mouse_state mouse state
+ * \param x location of event
+ * \param y location of event
+ * \return NSERROR_OK on sucess otherwise apropriate error code.
+ */
+ nserror (*mouse)(struct nsgtk_corewindow *nsgtk_cw, browser_mouse_state mouse_state, int x, int y);
+};
+
+/**
+ * initialise elements of gtk core window.
+ *
+ * \param nsgtk_cw A gtk core window structure to initialise
+ * \return NSERROR_OK on successful initialisation otherwise error code.
+ */
+nserror nsgtk_corewindow_init(struct nsgtk_corewindow *nsgtk_cw);
+
+/**
+ * finalise elements of gtk core window.
+ *
+ * \param nsgtk_cw A gtk core window structure to initialise
+ * \return NSERROR_OK on successful finalisation otherwise error code.
+ */
+nserror nsgtk_corewindow_fini(struct nsgtk_corewindow *nsgtk_cw);
+
+#endif
diff --git a/frontends/gtk/gui.c b/frontends/gtk/gui.c
index af24d40..0ed32e9 100644
--- a/frontends/gtk/gui.c
+++ b/frontends/gtk/gui.c
@@ -434,13 +434,21 @@ static void nsgtk_main(void)
static void gui_quit(void)
{
+ nserror res;
+
LOG("Quitting GUI");
/* Ensure all scaffoldings are destroyed before we go into exit */
nsgtk_download_destroy();
urldb_save_cookies(nsoption_charp(cookie_jar));
urldb_save(nsoption_charp(url_file));
- nsgtk_cookies_destroy();
+
+ res = nsgtk_cookies_destroy();
+ if (res != NSERROR_OK) {
+ LOG("Error finalising cookie viewer: %s",
+ messages_get_errorcode(res));
+ }
+
nsgtk_history_destroy();
nsgtk_hotlist_destroy();
@@ -631,60 +639,93 @@ uint32_t gtk_gui_gdkkey_to_nskey(GdkEventKey *key)
return NS_KEY_DELETE_LINE_START;
else
return NS_KEY_DELETE_LEFT;
+
case GDK_KEY(Delete):
if (key->state & GDK_SHIFT_MASK)
return NS_KEY_DELETE_LINE_END;
else
return NS_KEY_DELETE_RIGHT;
- case GDK_KEY(Linefeed): return 13;
- case GDK_KEY(Return): return 10;
- case GDK_KEY(Left): return NS_KEY_LEFT;
- case GDK_KEY(Right): return NS_KEY_RIGHT;
- case GDK_KEY(Up): return NS_KEY_UP;
- case GDK_KEY(Down): return NS_KEY_DOWN;
+
+ case GDK_KEY(Linefeed):
+ return 13;
+
+ case GDK_KEY(Return):
+ return 10;
+
+ case GDK_KEY(Left):
+ case GDK_KEY(KP_Left):
+ return NS_KEY_LEFT;
+
+ case GDK_KEY(Right):
+ case GDK_KEY(KP_Right):
+ return NS_KEY_RIGHT;
+
+ case GDK_KEY(Up):
+ case GDK_KEY(KP_Up):
+ return NS_KEY_UP;
+
+ case GDK_KEY(Down):
+ case GDK_KEY(KP_Down):
+ return NS_KEY_DOWN;
+
case GDK_KEY(Home):
+ case GDK_KEY(KP_Home):
if (key->state & GDK_CONTROL_MASK)
- return NS_KEY_TEXT_START;
- else
return NS_KEY_LINE_START;
+ else
+ return NS_KEY_TEXT_START;
+
case GDK_KEY(End):
+ case GDK_KEY(KP_End):
if (key->state & GDK_CONTROL_MASK)
- return NS_KEY_TEXT_END;
- else
return NS_KEY_LINE_END;
+ else
+ return NS_KEY_TEXT_END;
+
case GDK_KEY(Page_Up):
+ case GDK_KEY(KP_Page_Up):
return NS_KEY_PAGE_UP;
+
case GDK_KEY(Page_Down):
+ case GDK_KEY(KP_Page_Down):
return NS_KEY_PAGE_DOWN;
+
case 'a':
if (key->state & GDK_CONTROL_MASK)
return NS_KEY_SELECT_ALL;
return gdk_keyval_to_unicode(key->keyval);
+
case 'u':
if (key->state & GDK_CONTROL_MASK)
return NS_KEY_DELETE_LINE;
return gdk_keyval_to_unicode(key->keyval);
+
case 'c':
if (key->state & GDK_CONTROL_MASK)
return NS_KEY_COPY_SELECTION;
return gdk_keyval_to_unicode(key->keyval);
+
case 'v':
if (key->state & GDK_CONTROL_MASK)
return NS_KEY_PASTE;
return gdk_keyval_to_unicode(key->keyval);
+
case 'x':
if (key->state & GDK_CONTROL_MASK)
return NS_KEY_CUT_SELECTION;
return gdk_keyval_to_unicode(key->keyval);
+
case 'Z':
case 'y':
if (key->state & GDK_CONTROL_MASK)
return NS_KEY_REDO;
return gdk_keyval_to_unicode(key->keyval);
+
case 'z':
if (key->state & GDK_CONTROL_MASK)
return NS_KEY_UNDO;
return gdk_keyval_to_unicode(key->keyval);
+
case GDK_KEY(Escape):
return NS_KEY_ESCAPE;
@@ -705,9 +746,8 @@ uint32_t gtk_gui_gdkkey_to_nskey(GdkEventKey *key)
case GDK_KEY(Hyper_R):
return 0;
- default:
- return gdk_keyval_to_unicode(key->keyval);
}
+ return gdk_keyval_to_unicode(key->keyval);
}
diff --git a/frontends/gtk/ssl_cert.c b/frontends/gtk/ssl_cert.c
index 463f5cd..1cf0beb 100644
--- a/frontends/gtk/ssl_cert.c
+++ b/frontends/gtk/ssl_cert.c
@@ -16,121 +16,250 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+/**
+ * \file
+ * Implementation of gtk certificate viewing using gtk core windows.
+ */
+
+#include <stdint.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include "utils/log.h"
-#include "utils/nsurl.h"
-#include "desktop/tree.h"
+#include "netsurf/keypress.h"
+#include "netsurf/plotters.h"
#include "desktop/sslcert_viewer.h"
+#include "desktop/treeview.h"
-#include "gtk/treeview.h"
+#include "gtk/plotters.h"
#include "gtk/scaffolding.h"
#include "gtk/resources.h"
#include "gtk/ssl_cert.h"
+#include "gtk/corewindow.h"
+
+
+/**
+ * GTK certificate viewing window context
+ */
+struct nsgtk_crtvrfy_window {
+ /** GTK core window context */
+ struct nsgtk_corewindow core;
+ /** GTK builder for window */
+ GtkBuilder *builder;
+ /** GTK dialog window being shown */
+ GtkDialog *dlg;
+ /** SSL certificate viewer context data */
+ struct sslcert_session_data *ssl_data;
+};
+/**
+ * destroy a previously created certificate view
+ */
+static nserror nsgtk_crtvrfy_destroy(struct nsgtk_crtvrfy_window *crtvrfy_win)
+{
+ nserror res;
-static void nsgtk_ssl_accept(GtkButton *w, gpointer data)
+ res = sslcert_viewer_fini(crtvrfy_win->ssl_data);
+ if (res == NSERROR_OK) {
+ res = nsgtk_corewindow_fini(&crtvrfy_win->core);
+ gtk_widget_destroy(GTK_WIDGET(crtvrfy_win->dlg));
+ g_object_unref(G_OBJECT(crtvrfy_win->builder));
+ free(crtvrfy_win);
+ }
+ return res;
+}
+
+static void
+nsgtk_crtvrfy_accept(GtkButton *w, gpointer data)
{
- void **session = data;
- GtkBuilder *x = session[0];
- struct nsgtk_treeview *wnd = session[1];
- struct sslcert_session_data *ssl_data = session[2];
+ struct nsgtk_crtvrfy_window *crtvrfy_win;
+ crtvrfy_win = (struct nsgtk_crtvrfy_window *)data;
- sslcert_viewer_accept(ssl_data);
+ sslcert_viewer_accept(crtvrfy_win->ssl_data);
- nsgtk_treeview_destroy(wnd);
- g_object_unref(G_OBJECT(x));
- free(session);
+ nsgtk_crtvrfy_destroy(crtvrfy_win);
}
-static void nsgtk_ssl_reject(GtkWidget *w, gpointer data)
+static void
+nsgtk_crtvrfy_reject(GtkWidget *w, gpointer data)
{
- void **session = data;
- GtkBuilder *x = session[0];
- struct nsgtk_treeview *wnd = session[1];
- struct sslcert_session_data *ssl_data = session[2];
+ struct nsgtk_crtvrfy_window *crtvrfy_win;
+ crtvrfy_win = (struct nsgtk_crtvrfy_window *)data;
- sslcert_viewer_reject(ssl_data);
+ sslcert_viewer_reject(crtvrfy_win->ssl_data);
- nsgtk_treeview_destroy(wnd);
- g_object_unref(G_OBJECT(x));
- free(session);
+ nsgtk_crtvrfy_destroy(crtvrfy_win);
}
-static gboolean nsgtk_ssl_delete_event(GtkWidget *w, GdkEvent *event, gpointer data)
+static gboolean
+nsgtk_crtvrfy_delete_event(GtkWidget *w, GdkEvent *event, gpointer data)
{
- nsgtk_ssl_reject(w, data);
+ nsgtk_crtvrfy_reject(w, data);
return FALSE;
}
-void gtk_cert_verify(nsurl *url, const struct ssl_cert_info *certs,
- unsigned long num, nserror (*cb)(bool proceed, void *pw),
- void *cbpw)
+/**
+ * callback for mouse action for certificate verify on core window
+ *
+ * \param nsgtk_cw The nsgtk core window structure.
+ * \param mouse_state netsurf mouse state on event
+ * \param x location of event
+ * \param y location of event
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+nsgtk_crtvrfy_mouse(struct nsgtk_corewindow *nsgtk_cw,
+ browser_mouse_state mouse_state,
+ int x, int y)
+{
+ struct nsgtk_crtvrfy_window *crtvrfy_win;
+ /* technically degenerate container of */
+ crtvrfy_win = (struct nsgtk_crtvrfy_window *)nsgtk_cw;
+
+ sslcert_viewer_mouse_action(crtvrfy_win->ssl_data, mouse_state, x, y);
+
+ return NSERROR_OK;
+}
+
+/**
+ * callback for keypress for certificate verify on core window
+ *
+ * \param nsgtk_cw The nsgtk core window structure.
+ * \param nskey The netsurf key code
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+nsgtk_crtvrfy_key(struct nsgtk_corewindow *nsgtk_cw, uint32_t nskey)
{
- static struct nsgtk_treeview *ssl_window;
- struct sslcert_session_data *data;
- GtkButton *accept, *reject;
- void **session;
- GtkDialog *dlg;
- GtkScrolledWindow *scrolled;
- GtkDrawingArea *drawing_area;
- GtkBuilder *builder;
- GtkWindow *gtk_parent;
+ struct nsgtk_crtvrfy_window *crtvrfy_win;
+
+ /* technically degenerate container of */
+ crtvrfy_win = (struct nsgtk_crtvrfy_window *)nsgtk_cw;
+
+ if (sslcert_viewer_keypress(crtvrfy_win->ssl_data, nskey)) {
+ return NSERROR_OK;
+ }
+ return NSERROR_NOT_IMPLEMENTED;
+}
+
+/**
+ * callback on draw event for certificate verify on core window
+ *
+ * \param nsgtk_cw The nsgtk core window structure.
+ * \param r The rectangle of the window that needs updating.
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+nsgtk_crtvrfy_draw(struct nsgtk_corewindow *nsgtk_cw, struct rect *r)
+{
+ struct redraw_context ctx = {
+ .interactive = true,
+ .background_images = true,
+ .plot = &nsgtk_plotters
+ };
+ struct nsgtk_crtvrfy_window *crtvrfy_win;
+
+ /* technically degenerate container of */
+ crtvrfy_win = (struct nsgtk_crtvrfy_window *)nsgtk_cw;
+
+ sslcert_viewer_redraw(crtvrfy_win->ssl_data, 0, 0, r, &ctx);
+
+ return NSERROR_OK;
+}
+
+/* exported interface documented in gtk/ssl_cert.h */
+nserror gtk_cert_verify(struct nsurl *url,
+ const struct ssl_cert_info *certs,
+ unsigned long num,
+ nserror (*cb)(bool proceed, void *pw),
+ void *cbpw)
+{
+ struct nsgtk_crtvrfy_window *ncwin;
nserror res;
- /* state while dlg is open */
- session = calloc(sizeof(void *), 3);
- if (session == NULL) {
- return;
+ res = treeview_init(0);
+ if (res != NSERROR_OK) {
+ return res;
}
- res = nsgtk_builder_new_from_resname("ssl", &builder);
+ ncwin = malloc(sizeof(struct nsgtk_crtvrfy_window));
+ if (ncwin == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ res = nsgtk_builder_new_from_resname("ssl", &ncwin->builder);
if (res != NSERROR_OK) {
LOG("SSL UI builder init failed");
- free(session);
- cb(false, cbpw);
- return;
+ free(ncwin);
+ return res;
}
- gtk_builder_connect_signals(builder, NULL);
-
- sslcert_viewer_create_session_data(num, url, cb, cbpw, certs, &data);
+ gtk_builder_connect_signals(ncwin->builder, NULL);
- dlg = GTK_DIALOG(gtk_builder_get_object(builder, "wndSSLProblem"));
+ ncwin->dlg = GTK_DIALOG(gtk_builder_get_object(ncwin->builder,
+ "wndSSLProblem"));
/* set parent for transient dialog */
- gtk_parent = nsgtk_scaffolding_window(nsgtk_current_scaffolding());
- gtk_window_set_transient_for(GTK_WINDOW(dlg), gtk_parent);
-
- scrolled = GTK_SCROLLED_WINDOW(gtk_builder_get_object(builder, "SSLScrolled"));
- drawing_area = GTK_DRAWING_AREA(gtk_builder_get_object(builder, "SSLDrawingArea"));
-
- ssl_window = nsgtk_treeview_create(TREE_SSLCERT,
- GTK_WINDOW(dlg),
- scrolled,
- drawing_area,
- data);
- if (ssl_window == NULL) {
- free(session);
- g_object_unref(G_OBJECT(dlg));
- return;
- }
+ gtk_window_set_transient_for(GTK_WINDOW(ncwin->dlg),
+ nsgtk_scaffolding_window(nsgtk_current_scaffolding()));
+
+ ncwin->core.scrolled = GTK_SCROLLED_WINDOW(
+ gtk_builder_get_object(ncwin->builder, "SSLScrolled"));
+
+ ncwin->core.drawing_area = GTK_DRAWING_AREA(
+ gtk_builder_get_object(ncwin->builder, "SSLDrawingArea"));
+
+ /* make the delete event call our destructor */
+ g_signal_connect(G_OBJECT(ncwin->dlg),
+ "delete_event",
+ G_CALLBACK(nsgtk_crtvrfy_delete_event),
+ ncwin);
- accept = GTK_BUTTON(gtk_builder_get_object(builder, "sslaccept"));
- reject = GTK_BUTTON(gtk_builder_get_object(builder, "sslreject"));
+ /* accept button */
+ g_signal_connect(G_OBJECT(gtk_builder_get_object(ncwin->builder,
+ "sslaccept")),
+ "clicked",
+ G_CALLBACK(nsgtk_crtvrfy_accept),
+ ncwin);
- session[0] = builder;
- session[1] = ssl_window;
- session[2] = data;
+ /* reject button */
+ g_signal_connect(G_OBJECT(gtk_builder_get_object(ncwin->builder,
+ "sslreject")),
+ "clicked",
+ G_CALLBACK(nsgtk_crtvrfy_reject),
+ ncwin);
-#define CONNECT(obj, sig, callback, ptr) \
- g_signal_connect(G_OBJECT(obj), (sig), G_CALLBACK(callback), (ptr))
+ /* initialise GTK core window */
+ ncwin->core.draw = nsgtk_crtvrfy_draw;
+ ncwin->core.key = nsgtk_crtvrfy_key;
+ ncwin->core.mouse = nsgtk_crtvrfy_mouse;
+
+ res = nsgtk_corewindow_init(&ncwin->core);
+ if (res != NSERROR_OK) {
+ g_object_unref(G_OBJECT(ncwin->dlg));
+ free(ncwin);
+ return res;
+ }
+
+ /* initialise certificate viewing interface */
+ res = sslcert_viewer_create_session_data(num, url, cb, cbpw, certs,
+ &ncwin->ssl_data);
+ if (res != NSERROR_OK) {
+ g_object_unref(G_OBJECT(ncwin->dlg));
+ free(ncwin);
+ return res;
+ }
+
+ res = sslcert_viewer_init(ncwin->core.cb_table,
+ (struct core_window *)ncwin,
+ ncwin->ssl_data);
+ if (res != NSERROR_OK) {
+ g_object_unref(G_OBJECT(ncwin->dlg));
+ free(ncwin);
+ return res;
+ }
- CONNECT(accept, "clicked", nsgtk_ssl_accept, session);
- CONNECT(reject, "clicked", nsgtk_ssl_reject, session);
- CONNECT(dlg, "delete_event", G_CALLBACK(nsgtk_ssl_delete_event),
- (gpointer)session);
+ gtk_widget_show(GTK_WIDGET(ncwin->dlg));
- gtk_widget_show(GTK_WIDGET(dlg));
+ return NSERROR_OK;
}
diff --git a/frontends/gtk/ssl_cert.h b/frontends/gtk/ssl_cert.h
index 48937d4..1712756 100644
--- a/frontends/gtk/ssl_cert.h
+++ b/frontends/gtk/ssl_cert.h
@@ -30,7 +30,8 @@ struct ssl_cert_info;
* \param num The number of certificates to be verified.
* \param cb Callback upon user decision.
* \param cbpw Context pointer passed to cb
+ * \return NSERROR_OK or error code if prompt creation failed.
*/
-void gtk_cert_verify(struct nsurl *url, const struct ssl_cert_info *certs, unsigned long num, nserror (*cb)(bool proceed, void *pw), void *cbpw);
+nserror gtk_cert_verify(struct nsurl *url, const struct ssl_cert_info *certs, unsigned long num, nserror (*cb)(bool proceed, void *pw), void *cbpw);
#endif
diff --git a/frontends/monkey/cert.c b/frontends/monkey/cert.c
index ec1b1ce..710e710 100644
--- a/frontends/monkey/cert.c
+++ b/frontends/monkey/cert.c
@@ -35,15 +35,14 @@ typedef struct monkey_cert {
static monkey_cert_t *cert_ring = NULL;
static uint32_t cert_ctr = 0;
-void
+nserror
gui_cert_verify(nsurl *url, const struct ssl_cert_info *certs,
unsigned long num, nserror (*cb)(bool proceed, void *pw),
void *cbpw)
{
monkey_cert_t *m4t = calloc(sizeof(*m4t), 1);
if (m4t == NULL) {
- cb(false, cbpw);
- return;
+ return NSERROR_NOMEM;
}
m4t->cb = cb;
m4t->pw = cbpw;
@@ -53,6 +52,8 @@ gui_cert_verify(nsurl *url, const struct ssl_cert_info *certs,
fprintf(stdout, "SSLCERT VERIFY CERT %u URL %s\n",
m4t->num, nsurl_access(url));
+
+ return NSERROR_OK;
}
diff --git a/frontends/monkey/cert.h b/frontends/monkey/cert.h
index 283817f..4470e2e 100644
--- a/frontends/monkey/cert.h
+++ b/frontends/monkey/cert.h
@@ -21,7 +21,7 @@
struct ssl_cert_info;
-void gui_cert_verify(nsurl *url, const struct ssl_cert_info *certs,
+nserror gui_cert_verify(nsurl *url, const struct ssl_cert_info *certs,
unsigned long num, nserror (*cb)(bool proceed, void *pw),
void *cbpw);
diff --git a/frontends/riscos/gui.h b/frontends/riscos/gui.h
index 624f9e2..505e8e7 100644
--- a/frontends/riscos/gui.h
+++ b/frontends/riscos/gui.h
@@ -212,7 +212,7 @@ extern int ro_plot_origin_y;
bool ro_gui_theme_install_apply(wimp_w w);
/* in sslcert.c */
-void gui_cert_verify(struct nsurl *url,
+nserror gui_cert_verify(struct nsurl *url,
const struct ssl_cert_info *certs, unsigned long num,
nserror (*cb)(bool proceed, void *pw), void *cbpw);
diff --git a/frontends/riscos/sslcert.c b/frontends/riscos/sslcert.c
index c7b8db4..8a8ddfb 100644
--- a/frontends/riscos/sslcert.c
+++ b/frontends/riscos/sslcert.c
@@ -101,7 +101,7 @@ void ro_gui_cert_postinitialise(void)
* \param cb Callback upon user decision.
* \param cbpw Context pointer passed to cb
*/
-void gui_cert_verify(nsurl *url,
+nserror gui_cert_verify(nsurl *url,
const struct ssl_cert_info *certs, unsigned long num,
nserror (*cb)(bool proceed, void *pw), void *cbpw)
{
@@ -117,7 +117,7 @@ void gui_cert_verify(nsurl *url,
sslcert_window = malloc(sizeof(struct ro_sslcert));
if (sslcert_window == NULL) {
LOG("Failed to allocate memory for SSL Cert Dialog");
- return;
+ return NSERROR_NOMEM;
}
/* Create the SSL window and its pane. */
@@ -127,7 +127,7 @@ void gui_cert_verify(nsurl *url,
if (error) {
LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess);
free(sslcert_window);
- return;
+ return NSERROR_INIT_FAILED;
}
error = xwimp_create_window(ro_gui_cert_tree_template,
@@ -135,7 +135,7 @@ void gui_cert_verify(nsurl *url,
if (error) {
LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess);
free(sslcert_window);
- return;
+ return NSERROR_INIT_FAILED;
}
/* Create the SSL data and build a tree from it. */
@@ -148,7 +148,7 @@ void gui_cert_verify(nsurl *url,
if (sslcert_window->tv == NULL) {
LOG("Failed to allocate treeview");
free(sslcert_window);
- return;
+ return NSERROR_NOMEM;
}
/* Set up the certificate window event handling.
@@ -182,7 +182,7 @@ void gui_cert_verify(nsurl *url,
if (error) {
ro_gui_cert_release_window(sslcert_window);
LOG("xwimp_get_window_info: 0x%x: %s", error->errnum, error->errmess);
- return;
+ return NSERROR_INIT_FAILED;
}
state.w = sslcert_window->window;
@@ -190,7 +190,7 @@ void gui_cert_verify(nsurl *url,
if (error) {
ro_gui_cert_release_window(sslcert_window);
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- return;
+ return NSERROR_INIT_FAILED;
}
istate.w = sslcert_window->window;
@@ -199,7 +199,7 @@ void gui_cert_verify(nsurl *url,
if (error) {
ro_gui_cert_release_window(sslcert_window);
LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
- return;
+ return NSERROR_INIT_FAILED;
}
state.w = sslcert_window->pane;
@@ -230,7 +230,7 @@ void gui_cert_verify(nsurl *url,
if (error) {
ro_gui_cert_release_window(sslcert_window);
LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess);
- return;
+ return NSERROR_INIT_FAILED;
}
}
@@ -248,10 +248,12 @@ void gui_cert_verify(nsurl *url,
ro_gui_cert_release_window(sslcert_window);
LOG("xwimp_open_window_nested: 0x%x: %s", error->errnum, error->errmess);
ro_gui_cert_release_window(sslcert_window);
- return;
+ return NSERROR_INIT_FAILED;
}
ro_treeview_set_origin(sslcert_window->tv, 0, 0);
+
+ return NSERROR_OK;
}
/**
diff --git a/include/netsurf/misc.h b/include/netsurf/misc.h
index 7b35495..2647b9a 100644
--- a/include/netsurf/misc.h
+++ b/include/netsurf/misc.h
@@ -89,8 +89,9 @@ struct gui_misc_table {
* \param num The number of certificates to be verified.
* \param cb Callback upon user decision.
* \param cbpw Context pointer passed to cb
+ * \return NSERROR_OK on sucess else error and cb never called
*/
- void (*cert_verify)(struct nsurl *url, const struct ssl_cert_info *certs, unsigned long num, nserror (*cb)(bool proceed, void *pw), void *cbpw);
+ nserror (*cert_verify)(struct nsurl *url, const struct ssl_cert_info *certs, unsigned long num, nserror (*cb)(bool proceed, void *pw), void *cbpw);
/**
* Prompt user for login
diff --git a/include/netsurf/mouse.h b/include/netsurf/mouse.h
index 19cd3ea..1b16998 100644
--- a/include/netsurf/mouse.h
+++ b/include/netsurf/mouse.h
@@ -27,56 +27,59 @@
#ifndef _NETSURF_MOUSE_H_
#define _NETSURF_MOUSE_H_
-/* Mouse state. 1 is primary mouse button (e.g. Select on RISC OS).
- * 2 is secondary mouse button (e.g. Adjust on RISC OS). */
+/**
+ * Mouse state. 1 is primary mouse button (e.g. Select on RISC OS).
+ * 2 is secondary mouse button (e.g. Adjust on RISC OS).
+ *
+ * \note click meaning is different for different front ends. On RISC
+ * OS, it is standard to act on press, so a click is fired at
+ * the same time as a mouse button is pressed. With GTK, it is
+ * standard to act on release, so a click is fired when the
+ * mouse button is released, if the operation wasn't a drag.
+ *
+ * \note double and triple clicks are fired alongside a
+ * BROWSER_MOUSE_CLICK_[1|2] to indicate which button is used.
+ */
typedef enum browser_mouse_state {
- BROWSER_MOUSE_HOVER = 0, /* No mouse buttons pressed,
- * May be used to indicate
- * hover or end of drag. */
-
- BROWSER_MOUSE_PRESS_1 = (1 << 0), /* button 1 pressed */
- BROWSER_MOUSE_PRESS_2 = (1 << 1), /* button 2 pressed */
-
- /* note: click meaning is different for
- * different front ends. On RISC OS, it
- * is standard to act on press, so a
- * click is fired at the same time as a
- * mouse button is pressed. With GTK, it
- * is standard to act on release, so a
- * click is fired when the mouse button
- * is released, if the operation wasn't
- * a drag. */
-
- BROWSER_MOUSE_CLICK_1 = (1 << 2), /* button 1 clicked. */
- BROWSER_MOUSE_CLICK_2 = (1 << 3), /* button 2 clicked. */
-
- BROWSER_MOUSE_DOUBLE_CLICK = (1 << 4), /* button double clicked */
- BROWSER_MOUSE_TRIPLE_CLICK = (1 << 5), /* button triple clicked */
-
- /* note: double and triple clicks are
- * fired alongside a
- * BROWSER_MOUSE_CLICK_[1|2]
- * to indicate which button
- * is used.
- */
-
- BROWSER_MOUSE_DRAG_1 = (1 << 6), /* start of button 1 drag */
- BROWSER_MOUSE_DRAG_2 = (1 << 7), /* start of button 2 drag */
-
- BROWSER_MOUSE_DRAG_ON = (1 << 8), /* a drag operation was started
- * and a mouse button is still
- * pressed */
-
- BROWSER_MOUSE_HOLDING_1 = (1 << 9), /* during button 1 drag */
- BROWSER_MOUSE_HOLDING_2 = (1 << 10), /* during button 2 drag */
-
-
- BROWSER_MOUSE_MOD_1 = (1 << 11), /* 1st modifier key pressed
- * (eg. Shift) */
- BROWSER_MOUSE_MOD_2 = (1 << 12), /* 2nd modifier key pressed
- * (eg. Ctrl) */
- BROWSER_MOUSE_MOD_3 = (1 << 13) /* 3rd modifier key pressed
- * (eg. Alt) */
+ /** No mouse buttons pressed, May be used to indicate hover or
+ * end of drag.
+ */
+ BROWSER_MOUSE_HOVER = 0,
+
+ /** button 1 pressed */
+ BROWSER_MOUSE_PRESS_1 = (1 << 0),
+ /** button 2 pressed */
+ BROWSER_MOUSE_PRESS_2 = (1 << 1),
+
+ /** button 1 clicked. */
+ BROWSER_MOUSE_CLICK_1 = (1 << 2),
+ /** button 2 clicked. */
+ BROWSER_MOUSE_CLICK_2 = (1 << 3),
+
+ /** button double clicked */
+ BROWSER_MOUSE_DOUBLE_CLICK = (1 << 4),
+ /** button triple clicked */
+ BROWSER_MOUSE_TRIPLE_CLICK = (1 << 5),
+
+ /** start of button 1 drag */
+ BROWSER_MOUSE_DRAG_1 = (1 << 6),
+ /** start of button 2 drag */
+ BROWSER_MOUSE_DRAG_2 = (1 << 7),
+
+ /** a drag operation was started and a mouse button is still pressed */
+ BROWSER_MOUSE_DRAG_ON = (1 << 8),
+
+ /** during button 1 drag */
+ BROWSER_MOUSE_HOLDING_1 = (1 << 9),
+ /** during button 2 drag */
+ BROWSER_MOUSE_HOLDING_2 = (1 << 10),
+
+ /** 1st modifier key pressed (eg. Shift) */
+ BROWSER_MOUSE_MOD_1 = (1 << 11),
+ /** 2nd modifier key pressed (eg. Ctrl) */
+ BROWSER_MOUSE_MOD_2 = (1 << 12),
+ /** 3rd modifier key pressed (eg. Alt) */
+ BROWSER_MOUSE_MOD_3 = (1 << 13)
} browser_mouse_state;
diff --git a/test/Makefile b/test/Makefile
index 9fdb3f2..ea16b0a 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,7 +1,7 @@
#
# NetSurf unit tests
-TESTS := nsurl urldbtest nsoption bloom hashtable #llcache
+TESTS := nsurl urldbtest nsoption bloom hashtable urlescape #llcache
# nsurl sources
nsurl_SRCS := utils/corestrings.c utils/nsurl.c utils/idna.c \
@@ -34,6 +34,9 @@ bloom_SRCS := utils/bloom.c test/bloom.c
# hash table test sources
hashtable_SRCS := utils/hashtable.c test/log.c test/hashtable.c
+# url escape test sources
+urlescape_SRCS := utils/url.c test/log.c test/urlescape.c
+
# Coverage builds need additional flags
ifeq ($(MAKECMDGOALS),coverage)
COV_CFLAGS ?= -fprofile-arcs -ftest-coverage -O0
diff --git a/test/urlescape.c b/test/urlescape.c
new file mode 100644
index 0000000..5d9d932
--- /dev/null
+++ b/test/urlescape.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2016 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
+ * Test url percent encoding operations.
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <check.h>
+
+#include "utils/url.h"
+
+#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
+#define SLEN(x) (sizeof((x)) - 1)
+
+struct test_pairs {
+ const char* test;
+ const char* res;
+ const size_t res_len;
+};
+
+const char all_chars[] =
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff";
+
+const char all_escaped[] =
+ "%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F"
+ "%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F"
+ "%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F"
+ "0123456789%3A%3B%3C%3D%3E%3F"
+ "%40ABCDEFGHIJKLMNO"
+ "PQRSTUVWXYZ%5B%5C%5D%5E_"
+ "%60abcdefghijklmno"
+ "pqrstuvwxyz%7B%7C%7D%7E%7F"
+ "%80%81%82%83%84%85%86%87%88%89%8A%8B%8C%8D%8E%8F"
+ "%90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F"
+ "%A0%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF"
+ "%B0%B1%B2%B3%B4%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF"
+ "%C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF"
+ "%D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%DD%DE%DF"
+ "%E0%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF"
+ "%F0%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF";
+
+static const struct test_pairs url_escape_test_vec[] = {
+ { "", "" , 0 },
+ { "A.string.that.does.not.need.escaping",
+ "A.string.that.does.not.need.escaping" , 0 },
+ { " ", "%20" , 0 },
+ { &all_chars[0], &all_escaped[0], 0 },
+};
+
+
+START_TEST(url_escape_test)
+{
+ nserror err;
+ char *esc_str;
+ const struct test_pairs *tst = &url_escape_test_vec[_i];
+
+ err = url_escape(tst->test, false, "", &esc_str);
+ ck_assert(err == NSERROR_OK);
+
+ ck_assert_str_eq(esc_str, tst->res);
+}
+END_TEST
+
+static const struct test_pairs url_unescape_test_vec[] = {
+ { "", "" , 0 },
+ { "A.string.that.does.not.need.unescaping",
+ "A.string.that.does.not.need.unescaping",
+ SLEN("A.string.that.does.not.need.unescaping") },
+ { "%20", " " , 1 },
+ { &all_escaped[0], &all_chars[0], SLEN(all_chars) },
+};
+
+START_TEST(url_unescape_test)
+{
+ nserror err;
+ char *unesc_str;
+ size_t unesc_length;
+
+ const struct test_pairs *tst = &url_unescape_test_vec[_i];
+
+ err = url_unescape(tst->test, 0 , &unesc_length, &unesc_str);
+ ck_assert(err == NSERROR_OK);
+ /* ensure length */
+ ck_assert_uint_eq(unesc_length, tst->res_len);
+ /* ensure contents */
+ ck_assert_str_eq(unesc_str, tst->res);
+}
+END_TEST
+
+
+
+TCase *url_escape_case_create(void)
+{
+ TCase *tc;
+ tc = tcase_create("Escape");
+
+ tcase_add_loop_test(tc, url_escape_test,
+ 0, NELEMS(url_escape_test_vec));
+
+ return tc;
+}
+
+TCase *url_unescape_case_create(void)
+{
+ TCase *tc;
+ tc = tcase_create("Unescape");
+
+ tcase_add_loop_test(tc, url_unescape_test,
+ 0, NELEMS(url_unescape_test_vec));
+
+ return tc;
+}
+
+
+Suite *urlescape_suite_create(void)
+{
+ Suite *s;
+ s = suite_create("Percent escaping");
+
+ suite_add_tcase(s, url_escape_case_create());
+ suite_add_tcase(s, url_unescape_case_create());
+
+ return s;
+}
+
+
+
+int main(int argc, char **argv)
+{
+ int number_failed;
+ SRunner *sr;
+
+ sr = srunner_create(urlescape_suite_create());
+ //srunner_add_suite(sr, bar_suite_create());
+
+ srunner_run_all(sr, CK_ENV);
+
+ number_failed = srunner_ntests_failed(sr);
+ srunner_free(sr);
+
+ return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
--
NetSurf Browser
7 years, 1 month
netsurf: branch master updated. release/3.5-232-g3303c00
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/3303c005eedd67c5b973c...
...commit http://git.netsurf-browser.org/netsurf.git/commit/3303c005eedd67c5b973c64...
...tree http://git.netsurf-browser.org/netsurf.git/tree/3303c005eedd67c5b973c64f2...
The branch, master has been updated
via 3303c005eedd67c5b973c64f2515b28f9a7f56d2 (commit)
from 2d41d6c933cec1a0660bc71aaa115b41dcfdfbed (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=3303c005eedd67c5b97...
commit 3303c005eedd67c5b973c64f2515b28f9a7f56d2
Author: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Commit: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Remove pointless string copy
diff --git a/frontends/amiga/Makefile b/frontends/amiga/Makefile
index eb3c70b..9ef40ef 100644
--- a/frontends/amiga/Makefile
+++ b/frontends/amiga/Makefile
@@ -7,7 +7,7 @@ CFLAGS += -std=c99 -Dnsamiga
ifneq ($(SUBTARGET),os3)
CFLAGS += -O2 -finline-functions -U__STRICT_ANSI__ -D__USE_INLINE__ -D__USE_BASETYPE__
else
- CFLAGS += -msoft-float -m68020-60 -O2 -DPATH_MAX=1024 -D__m68k__
+ CFLAGS += -O2 -DPATH_MAX=1024 -D__m68k__ -m68020
endif
$(eval $(call feature_enabled,AMIGA_ICON,-DWITH_AMIGA_ICON,,Amiga icon))
diff --git a/frontends/amiga/gui.c b/frontends/amiga/gui.c
index b32e58d..8ad21b3 100644
--- a/frontends/amiga/gui.c
+++ b/frontends/amiga/gui.c
@@ -5329,7 +5329,6 @@ Object *ami_gui_splash_open(void)
struct Window *win;
struct Screen *wbscreen = LockPubScreen("Workbench");
uint32 top = 0, left = 0;
- STRPTR ver_string;
struct TextAttr tattr;
struct TextFont *tfont;
@@ -5398,12 +5397,9 @@ Object *ami_gui_splash_open(void)
if((tfont = ami_font_open_disk_font(&tattr)))
SetFont(win->RPort, tfont);
- ver_string = ASPrintf("%s", netsurf_version);
-
Move(win->RPort, left + 185, top + 220);
- Text(win->RPort, ver_string, strlen(ver_string));
+ Text(win->RPort, netsurf_version, strlen(netsurf_version));
- if(ver_string) FreeVec(ver_string);
if(tfont) ami_font_close_disk_font(tfont);
UnlockPubScreen(NULL, wbscreen);
-----------------------------------------------------------------------
Summary of changes:
frontends/amiga/Makefile | 2 +-
frontends/amiga/gui.c | 6 +-----
2 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/frontends/amiga/Makefile b/frontends/amiga/Makefile
index eb3c70b..9ef40ef 100644
--- a/frontends/amiga/Makefile
+++ b/frontends/amiga/Makefile
@@ -7,7 +7,7 @@ CFLAGS += -std=c99 -Dnsamiga
ifneq ($(SUBTARGET),os3)
CFLAGS += -O2 -finline-functions -U__STRICT_ANSI__ -D__USE_INLINE__ -D__USE_BASETYPE__
else
- CFLAGS += -msoft-float -m68020-60 -O2 -DPATH_MAX=1024 -D__m68k__
+ CFLAGS += -O2 -DPATH_MAX=1024 -D__m68k__ -m68020
endif
$(eval $(call feature_enabled,AMIGA_ICON,-DWITH_AMIGA_ICON,,Amiga icon))
diff --git a/frontends/amiga/gui.c b/frontends/amiga/gui.c
index b32e58d..8ad21b3 100644
--- a/frontends/amiga/gui.c
+++ b/frontends/amiga/gui.c
@@ -5329,7 +5329,6 @@ Object *ami_gui_splash_open(void)
struct Window *win;
struct Screen *wbscreen = LockPubScreen("Workbench");
uint32 top = 0, left = 0;
- STRPTR ver_string;
struct TextAttr tattr;
struct TextFont *tfont;
@@ -5398,12 +5397,9 @@ Object *ami_gui_splash_open(void)
if((tfont = ami_font_open_disk_font(&tattr)))
SetFont(win->RPort, tfont);
- ver_string = ASPrintf("%s", netsurf_version);
-
Move(win->RPort, left + 185, top + 220);
- Text(win->RPort, ver_string, strlen(ver_string));
+ Text(win->RPort, netsurf_version, strlen(netsurf_version));
- if(ver_string) FreeVec(ver_string);
if(tfont) ami_font_close_disk_font(tfont);
UnlockPubScreen(NULL, wbscreen);
--
NetSurf Browser
7 years, 1 month
netsurf: branch master updated. release/3.5-231-g2d41d6c
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/2d41d6c933cec1a0660bc...
...commit http://git.netsurf-browser.org/netsurf.git/commit/2d41d6c933cec1a0660bc71...
...tree http://git.netsurf-browser.org/netsurf.git/tree/2d41d6c933cec1a0660bc71aa...
The branch, master has been updated
via 2d41d6c933cec1a0660bc71aaa115b41dcfdfbed (commit)
from 0c7649d030d980755d9659574214f104368fc6a0 (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=2d41d6c933cec1a0660...
commit 2d41d6c933cec1a0660bc71aaa115b41dcfdfbed
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
cleanup gtk cookie interface
use gtk_window_present instead of gdk_window_raise and reduce exposed
variables and interfaces.
diff --git a/frontends/gtk/cookies.c b/frontends/gtk/cookies.c
index 76894fa..f252e6b 100644
--- a/frontends/gtk/cookies.c
+++ b/frontends/gtk/cookies.c
@@ -35,7 +35,11 @@
#include "gtk/treeview.h"
#include "gtk/resources.h"
-#define MENUPROTO(x) static gboolean nsgtk_on_##x##_activate( \
+static struct nsgtk_treeview *cookies_treeview;
+static GtkBuilder *cookie_builder;
+static GtkWindow *wndCookies = NULL;
+
+#define MENUPROTO(x) static gboolean nsgtk_on_##x##_activate( \
GtkMenuItem *widget, gpointer g)
#define MENUEVENT(x) { #x, G_CALLBACK(nsgtk_on_##x##_activate) }
#define MENUHANDLER(x) gboolean nsgtk_on_##x##_activate(GtkMenuItem *widget, \
@@ -80,9 +84,7 @@ static struct menu_events menu_events[] = {
{NULL, NULL}
};
-static struct nsgtk_treeview *cookies_treeview;
-static GtkBuilder *cookie_builder;
-GtkWindow *wndCookies;
+
/**
* Connects menu events in the cookies window.
@@ -102,13 +104,21 @@ static void nsgtk_cookies_init_menu(void)
}
}
-/* exported interface documented in gtk/cookies.h */
-nserror nsgtk_cookies_init(void)
+/**
+ * Creates the window for the cookies tree.
+ *
+ * \return NSERROR_OK on success else appropriate error code on faliure.
+ */
+static nserror nsgtk_cookies_init(void)
{
GtkScrolledWindow *scrolled;
GtkDrawingArea *drawing_area;
nserror res;
+ if (wndCookies != NULL) {
+ return NSERROR_OK;
+ }
+
res = nsgtk_builder_new_from_resname("cookies", &cookie_builder);
if (res != NSERROR_OK) {
LOG("Cookie UI builder init failed");
@@ -147,14 +157,6 @@ nserror nsgtk_cookies_init(void)
}
-/**
- * Destroys the cookies window and performs any other necessary cleanup actions.
- */
-void nsgtk_cookies_destroy(void)
-{
- /** \todo what about cookie_builder? */
- nsgtk_treeview_destroy(cookies_treeview);
-}
/* edit menu */
@@ -219,3 +221,24 @@ MENUHANDLER(collapse_cookies)
cookie_manager_contract(false);
return TRUE;
}
+
+/* exported function documented gtk/cookies.h */
+nserror nsgtk_cookies_present(void)
+{
+ nserror res;
+
+ res = nsgtk_cookies_init();
+ if (res == NSERROR_OK) {
+ gtk_window_present(wndCookies);
+ }
+ return res;
+}
+
+/* exported function documented gtk/cookies.h */
+void nsgtk_cookies_destroy(void)
+{
+ /** \todo what about cookie_builder? */
+ if (wndCookies != NULL) {
+ nsgtk_treeview_destroy(cookies_treeview);
+ }
+}
diff --git a/frontends/gtk/cookies.h b/frontends/gtk/cookies.h
index 2d5c56d..2af05e1 100644
--- a/frontends/gtk/cookies.h
+++ b/frontends/gtk/cookies.h
@@ -23,15 +23,19 @@
#ifndef __NSGTK_COOKIES_H__
#define __NSGTK_COOKIES_H__
-extern GtkWindow *wndCookies;
-
/**
- * Creates the window for the cookies tree.
+ * make the cookie window visible.
*
* \return NSERROR_OK on success else appropriate error code on faliure.
*/
-nserror nsgtk_cookies_init(void);
+nserror nsgtk_cookies_present(void);
+/**
+ * Free any resources allocated for the cookie window.
+ *
+ * \return NSERROR_OK on success else appropriate error code on faliure.
+ */
void nsgtk_cookies_destroy(void);
+
#endif /* __NSGTK_COOKIES_H__ */
diff --git a/frontends/gtk/gui.c b/frontends/gtk/gui.c
index e0044b5..af24d40 100644
--- a/frontends/gtk/gui.c
+++ b/frontends/gtk/gui.c
@@ -313,12 +313,6 @@ static nserror nsgtk_init(int argc, char** argv, char **respath)
return error;
}
- error = nsgtk_cookies_init();
- if (error != NSERROR_OK) {
- LOG("Unable to initialise cookies window.");
- return error;
- }
-
error = nsgtk_hotlist_init();
if (error != NSERROR_OK) {
LOG("Unable to initialise hotlist window.");
diff --git a/frontends/gtk/scaffolding.c b/frontends/gtk/scaffolding.c
index cd3779e..811c844 100644
--- a/frontends/gtk/scaffolding.c
+++ b/frontends/gtk/scaffolding.c
@@ -1523,9 +1523,11 @@ MULTIHANDLER(showbookmarks)
MULTIHANDLER(showcookies)
{
- gtk_widget_show(GTK_WIDGET(wndCookies));
- gdk_window_raise(nsgtk_widget_get_window(GTK_WIDGET(wndCookies)));
-
+ nserror res;
+ res = nsgtk_cookies_present();
+ if (res != NSERROR_OK) {
+ LOG("Unable to initialise cookies window.");
+ }
return TRUE;
}
-----------------------------------------------------------------------
Summary of changes:
frontends/gtk/cookies.c | 51 +++++++++++++++++++++++++++++++------------
frontends/gtk/cookies.h | 12 ++++++----
frontends/gtk/gui.c | 6 -----
frontends/gtk/scaffolding.c | 8 ++++---
4 files changed, 50 insertions(+), 27 deletions(-)
diff --git a/frontends/gtk/cookies.c b/frontends/gtk/cookies.c
index 76894fa..f252e6b 100644
--- a/frontends/gtk/cookies.c
+++ b/frontends/gtk/cookies.c
@@ -35,7 +35,11 @@
#include "gtk/treeview.h"
#include "gtk/resources.h"
-#define MENUPROTO(x) static gboolean nsgtk_on_##x##_activate( \
+static struct nsgtk_treeview *cookies_treeview;
+static GtkBuilder *cookie_builder;
+static GtkWindow *wndCookies = NULL;
+
+#define MENUPROTO(x) static gboolean nsgtk_on_##x##_activate( \
GtkMenuItem *widget, gpointer g)
#define MENUEVENT(x) { #x, G_CALLBACK(nsgtk_on_##x##_activate) }
#define MENUHANDLER(x) gboolean nsgtk_on_##x##_activate(GtkMenuItem *widget, \
@@ -80,9 +84,7 @@ static struct menu_events menu_events[] = {
{NULL, NULL}
};
-static struct nsgtk_treeview *cookies_treeview;
-static GtkBuilder *cookie_builder;
-GtkWindow *wndCookies;
+
/**
* Connects menu events in the cookies window.
@@ -102,13 +104,21 @@ static void nsgtk_cookies_init_menu(void)
}
}
-/* exported interface documented in gtk/cookies.h */
-nserror nsgtk_cookies_init(void)
+/**
+ * Creates the window for the cookies tree.
+ *
+ * \return NSERROR_OK on success else appropriate error code on faliure.
+ */
+static nserror nsgtk_cookies_init(void)
{
GtkScrolledWindow *scrolled;
GtkDrawingArea *drawing_area;
nserror res;
+ if (wndCookies != NULL) {
+ return NSERROR_OK;
+ }
+
res = nsgtk_builder_new_from_resname("cookies", &cookie_builder);
if (res != NSERROR_OK) {
LOG("Cookie UI builder init failed");
@@ -147,14 +157,6 @@ nserror nsgtk_cookies_init(void)
}
-/**
- * Destroys the cookies window and performs any other necessary cleanup actions.
- */
-void nsgtk_cookies_destroy(void)
-{
- /** \todo what about cookie_builder? */
- nsgtk_treeview_destroy(cookies_treeview);
-}
/* edit menu */
@@ -219,3 +221,24 @@ MENUHANDLER(collapse_cookies)
cookie_manager_contract(false);
return TRUE;
}
+
+/* exported function documented gtk/cookies.h */
+nserror nsgtk_cookies_present(void)
+{
+ nserror res;
+
+ res = nsgtk_cookies_init();
+ if (res == NSERROR_OK) {
+ gtk_window_present(wndCookies);
+ }
+ return res;
+}
+
+/* exported function documented gtk/cookies.h */
+void nsgtk_cookies_destroy(void)
+{
+ /** \todo what about cookie_builder? */
+ if (wndCookies != NULL) {
+ nsgtk_treeview_destroy(cookies_treeview);
+ }
+}
diff --git a/frontends/gtk/cookies.h b/frontends/gtk/cookies.h
index 2d5c56d..2af05e1 100644
--- a/frontends/gtk/cookies.h
+++ b/frontends/gtk/cookies.h
@@ -23,15 +23,19 @@
#ifndef __NSGTK_COOKIES_H__
#define __NSGTK_COOKIES_H__
-extern GtkWindow *wndCookies;
-
/**
- * Creates the window for the cookies tree.
+ * make the cookie window visible.
*
* \return NSERROR_OK on success else appropriate error code on faliure.
*/
-nserror nsgtk_cookies_init(void);
+nserror nsgtk_cookies_present(void);
+/**
+ * Free any resources allocated for the cookie window.
+ *
+ * \return NSERROR_OK on success else appropriate error code on faliure.
+ */
void nsgtk_cookies_destroy(void);
+
#endif /* __NSGTK_COOKIES_H__ */
diff --git a/frontends/gtk/gui.c b/frontends/gtk/gui.c
index e0044b5..af24d40 100644
--- a/frontends/gtk/gui.c
+++ b/frontends/gtk/gui.c
@@ -313,12 +313,6 @@ static nserror nsgtk_init(int argc, char** argv, char **respath)
return error;
}
- error = nsgtk_cookies_init();
- if (error != NSERROR_OK) {
- LOG("Unable to initialise cookies window.");
- return error;
- }
-
error = nsgtk_hotlist_init();
if (error != NSERROR_OK) {
LOG("Unable to initialise hotlist window.");
diff --git a/frontends/gtk/scaffolding.c b/frontends/gtk/scaffolding.c
index cd3779e..811c844 100644
--- a/frontends/gtk/scaffolding.c
+++ b/frontends/gtk/scaffolding.c
@@ -1523,9 +1523,11 @@ MULTIHANDLER(showbookmarks)
MULTIHANDLER(showcookies)
{
- gtk_widget_show(GTK_WIDGET(wndCookies));
- gdk_window_raise(nsgtk_widget_get_window(GTK_WIDGET(wndCookies)));
-
+ nserror res;
+ res = nsgtk_cookies_present();
+ if (res != NSERROR_OK) {
+ LOG("Unable to initialise cookies window.");
+ }
return TRUE;
}
--
NetSurf Browser
7 years, 1 month
netsurf: branch master updated. release/3.5-230-g0c7649d
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/0c7649d030d980755d965...
...commit http://git.netsurf-browser.org/netsurf.git/commit/0c7649d030d980755d96595...
...tree http://git.netsurf-browser.org/netsurf.git/tree/0c7649d030d980755d9659574...
The branch, master has been updated
via 0c7649d030d980755d9659574214f104368fc6a0 (commit)
via a122b94efde125202388d135e36eb86e6d25d093 (commit)
from 7bff70e7466dd80603922ba0dfdad1725cce41a6 (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=0c7649d030d980755d9...
commit 0c7649d030d980755d9659574214f104368fc6a0
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
URL escape: Improve API documentation.
diff --git a/utils/url.h b/utils/url.h
index c22c43b..b80fadd 100644
--- a/utils/url.h
+++ b/utils/url.h
@@ -31,10 +31,12 @@
/**
* Escape a string suitable for inclusion in an URL.
*
- * \param unescaped the unescaped string
- * \param sptoplus true iff spaces should be converted to +
- * \param escexceptions NULL or a string of characters excluded to be escaped
- * \param result pointer to pointer to buffer to hold escaped string
+ * \param[in] unescaped the unescaped string
+ * \param[in] sptoplus true iff spaces should be converted to +
+ * \param[in] escexceptions NULL or a string of characters to be excluded
+ * from escaping.
+ * \param[out] result Returns pointer to buffer to escaped string.
+ * Returned string is '\0' terminated.
* \return NSERROR_OK on success
*/
nserror url_escape(const char *unescaped, bool sptoplus,
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=a122b94efde12520238...
commit a122b94efde125202388d135e36eb86e6d25d093
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
URL escape: Simplify to avoid unnecessary allocation.
This removes the toskip parameter, which was only used by the RISC OS
front end. The toskip param was used to skip 8 characters which did
not need to be escaped from the start of the URL. The RISC OS front
end now orders the steps of its URL construction to avoid the need
for this.
diff --git a/desktop/searchweb.c b/desktop/searchweb.c
index 41ba062..593591c 100644
--- a/desktop/searchweb.c
+++ b/desktop/searchweb.c
@@ -240,7 +240,7 @@ make_search_nsurl(struct search_provider *provider,
size_t urlstr_len;
/* escape the search term and join it to the search url */
- ret = url_escape(term, 0, true, NULL, &eterm);
+ ret = url_escape(term, true, NULL, &eterm);
if (ret != NSERROR_OK) {
return ret;
}
diff --git a/frontends/atari/file.c b/frontends/atari/file.c
index 3816e47..235d824 100644
--- a/frontends/atari/file.c
+++ b/frontends/atari/file.c
@@ -193,7 +193,7 @@ static nserror atari_path_to_nsurl(const char *path, struct nsurl **url_out)
}
/* escape the path so it can be placed in a url */
- ret = url_escape(path, 0, false, "/", &escpath);
+ ret = url_escape(path, false, "/", &escpath);
if (ret != NSERROR_OK) {
return ret;
}
diff --git a/frontends/riscos/gui.c b/frontends/riscos/gui.c
index 72eeb62..7c52164 100644
--- a/frontends/riscos/gui.c
+++ b/frontends/riscos/gui.c
@@ -1405,7 +1405,7 @@ static nserror ro_path_to_nsurl(const char *path, struct nsurl **url_out)
int spare;
char *canonical_path; /* canonicalised RISC OS path */
char *unix_path; /* unix path */
- char *escurl;
+ char *escaped_path;
os_error *error;
nserror ret;
int urllen;
@@ -1443,31 +1443,34 @@ static nserror ro_path_to_nsurl(const char *path, struct nsurl **url_out)
}
free(canonical_path);
- /* convert the unix path into a url */
- urllen = strlen(unix_path) + FILE_SCHEME_PREFIX_LEN + 1;
+ /* url escape the unix path */
+ ret = url_escape(unix_path, false, "/", &escaped_path);
+ if (ret != NSERROR_OK) {
+ free(unix_path);
+ return ret;
+ }
+ free(unix_path);
+
+ /* convert the escaped unix path into a url */
+ urllen = strlen(escaped_path) + FILE_SCHEME_PREFIX_LEN + 1;
url = malloc(urllen);
if (url == NULL) {
LOG("Unable to allocate url");
- free(unix_path);
+ free(escaped_path);
return NSERROR_NOMEM;
}
- if (*unix_path == '/') {
- snprintf(url, urllen, "%s%s", FILE_SCHEME_PREFIX, unix_path + 1);
+ if (*escaped_path == '/') {
+ snprintf(url, urllen, "%s%s",
+ FILE_SCHEME_PREFIX, escaped_path + 1);
} else {
- snprintf(url, urllen, "%s%s", FILE_SCHEME_PREFIX, unix_path);
+ snprintf(url, urllen, "%s%s",
+ FILE_SCHEME_PREFIX, escaped_path);
}
- free(unix_path);
+ free(escaped_path);
- /* We don't want '/' to be escaped. */
- ret = url_escape(url, FILE_SCHEME_PREFIX_LEN, false, "/", &escurl);
+ ret = nsurl_create(url, url_out);
free(url);
- if (ret != NSERROR_OK) {
- return ret;
- }
-
- ret = nsurl_create(escurl, url_out);
- free(escurl);
return ret;
}
diff --git a/render/form.c b/render/form.c
index f8d0ce5..8ae59b5 100644
--- a/render/form.c
+++ b/render/form.c
@@ -912,7 +912,7 @@ static char *form_url_encode(struct form *form,
}
for (; control; control = control->next) {
- url_err = url_escape(control->name, 0, true, NULL, &name);
+ url_err = url_escape(control->name, true, NULL, &name);
if (url_err == NSERROR_NOMEM) {
free(s);
return NULL;
@@ -920,7 +920,7 @@ static char *form_url_encode(struct form *form,
assert(url_err == NSERROR_OK);
- url_err = url_escape(control->value, 0, true, NULL, &value);
+ url_err = url_escape(control->value, true, NULL, &value);
if (url_err == NSERROR_NOMEM) {
free(name);
free(s);
diff --git a/utils/file.c b/utils/file.c
index 3ec97de..cc82657 100644
--- a/utils/file.c
+++ b/utils/file.c
@@ -174,7 +174,7 @@ static nserror posix_path_to_nsurl(const char *path, struct nsurl **url_out)
}
/* escape the path so it can be placed in a url */
- ret = url_escape(path, 0, false, "/", &escpath);
+ ret = url_escape(path, false, "/", &escpath);
if (ret != NSERROR_OK) {
return ret;
}
diff --git a/utils/url.c b/utils/url.c
index d1e9ce2..861a62b 100644
--- a/utils/url.c
+++ b/utils/url.c
@@ -113,63 +113,60 @@ nserror url_unescape(const char *str, size_t length,
/* exported interface documented in utils/url.h */
-nserror url_escape(const char *unescaped, size_t toskip,
- bool sptoplus, const char *escexceptions, char **result)
+nserror url_escape(const char *unescaped, bool sptoplus,
+ const char *escexceptions, char **result)
{
- size_t len;
- char *escaped, *d, *tmpres;
+ size_t len, new_len;
+ char *escaped, *pos;
const char *c;
- if (!unescaped || !result)
+ if (unescaped == NULL || result == NULL) {
return NSERROR_NOT_FOUND;
-
- *result = NULL;
+ }
len = strlen(unescaped);
- if (len < toskip)
- return NSERROR_NOT_FOUND;
- len -= toskip;
escaped = malloc(len * 3 + 1);
- if (!escaped)
+ if (escaped == NULL) {
return NSERROR_NOMEM;
+ }
+ pos = escaped;
- for (c = unescaped + toskip, d = escaped; *c; c++) {
+ for (c = unescaped; *c != '\0'; c++) {
/* Check if we should escape this byte.
* '~' is unreserved and should not be percent encoded, if
* you believe the spec; however, leaving it unescaped
* breaks a bunch of websites, so we escape it anyway. */
- if (!isascii(*c)
- || (strchr(":/?#[]@" /* gen-delims */
- "!$&'()*+,;=" /* sub-delims */
- "<>%\"{}|\\^`~" /* others */, *c)
- && (!escexceptions || !strchr(escexceptions, *c)))
- || *c <= 0x20 || *c == 0x7f) {
+ if (!isascii(*c) ||
+ (strchr(":/?#[]@" /* gen-delims */
+ "!$&'()*+,;=" /* sub-delims */
+ "<>%\"{}|\\^`~" /* others */, *c) &&
+ (!escexceptions ||
+ !strchr(escexceptions, *c))) ||
+ *c <= 0x20 || *c == 0x7f) {
if (*c == 0x20 && sptoplus) {
- *d++ = '+';
+ *pos++ = '+';
} else {
- *d++ = '%';
- *d++ = "0123456789ABCDEF"[((*c >> 4) & 0xf)];
- *d++ = "0123456789ABCDEF"[(*c & 0xf)];
+ *pos++ = '%';
+ *pos++ = "0123456789ABCDEF"[(*c >> 4) & 0xf];
+ *pos++ = "0123456789ABCDEF"[*c & 0xf];
}
} else {
/* unreserved characters: [a-zA-Z0-9-._] */
- *d++ = *c;
+ *pos++ = *c;
}
}
- *d++ = '\0';
+ *pos = '\0';
+ new_len = pos - escaped;
- tmpres = malloc(d - escaped + toskip);
- if (!tmpres) {
- free(escaped);
- return NSERROR_NOMEM;
+ if (new_len != len) {
+ /* Shrink wrap the allocation around the escaped string */
+ char *tmp = realloc(escaped, new_len + 1);
+ if (tmp != NULL) {
+ escaped = tmp;
+ }
}
- memcpy(tmpres, unescaped, toskip);
- memcpy(tmpres + toskip, escaped, d - escaped);
- *result = tmpres;
-
- free(escaped);
-
+ *result = escaped;
return NSERROR_OK;
}
diff --git a/utils/url.h b/utils/url.h
index 5d8d154..c22c43b 100644
--- a/utils/url.h
+++ b/utils/url.h
@@ -32,13 +32,12 @@
* Escape a string suitable for inclusion in an URL.
*
* \param unescaped the unescaped string
- * \param toskip number of bytes to skip in unescaped string
* \param sptoplus true iff spaces should be converted to +
* \param escexceptions NULL or a string of characters excluded to be escaped
* \param result pointer to pointer to buffer to hold escaped string
* \return NSERROR_OK on success
*/
-nserror url_escape(const char *unescaped, size_t toskip, bool sptoplus,
+nserror url_escape(const char *unescaped, bool sptoplus,
const char *escexceptions, char **result);
-----------------------------------------------------------------------
Summary of changes:
desktop/searchweb.c | 2 +-
frontends/atari/file.c | 2 +-
frontends/riscos/gui.c | 35 ++++++++++++++------------
render/form.c | 4 +--
utils/file.c | 2 +-
utils/url.c | 65 +++++++++++++++++++++++-------------------------
utils/url.h | 13 +++++-----
7 files changed, 62 insertions(+), 61 deletions(-)
diff --git a/desktop/searchweb.c b/desktop/searchweb.c
index 41ba062..593591c 100644
--- a/desktop/searchweb.c
+++ b/desktop/searchweb.c
@@ -240,7 +240,7 @@ make_search_nsurl(struct search_provider *provider,
size_t urlstr_len;
/* escape the search term and join it to the search url */
- ret = url_escape(term, 0, true, NULL, &eterm);
+ ret = url_escape(term, true, NULL, &eterm);
if (ret != NSERROR_OK) {
return ret;
}
diff --git a/frontends/atari/file.c b/frontends/atari/file.c
index 3816e47..235d824 100644
--- a/frontends/atari/file.c
+++ b/frontends/atari/file.c
@@ -193,7 +193,7 @@ static nserror atari_path_to_nsurl(const char *path, struct nsurl **url_out)
}
/* escape the path so it can be placed in a url */
- ret = url_escape(path, 0, false, "/", &escpath);
+ ret = url_escape(path, false, "/", &escpath);
if (ret != NSERROR_OK) {
return ret;
}
diff --git a/frontends/riscos/gui.c b/frontends/riscos/gui.c
index 72eeb62..7c52164 100644
--- a/frontends/riscos/gui.c
+++ b/frontends/riscos/gui.c
@@ -1405,7 +1405,7 @@ static nserror ro_path_to_nsurl(const char *path, struct nsurl **url_out)
int spare;
char *canonical_path; /* canonicalised RISC OS path */
char *unix_path; /* unix path */
- char *escurl;
+ char *escaped_path;
os_error *error;
nserror ret;
int urllen;
@@ -1443,31 +1443,34 @@ static nserror ro_path_to_nsurl(const char *path, struct nsurl **url_out)
}
free(canonical_path);
- /* convert the unix path into a url */
- urllen = strlen(unix_path) + FILE_SCHEME_PREFIX_LEN + 1;
+ /* url escape the unix path */
+ ret = url_escape(unix_path, false, "/", &escaped_path);
+ if (ret != NSERROR_OK) {
+ free(unix_path);
+ return ret;
+ }
+ free(unix_path);
+
+ /* convert the escaped unix path into a url */
+ urllen = strlen(escaped_path) + FILE_SCHEME_PREFIX_LEN + 1;
url = malloc(urllen);
if (url == NULL) {
LOG("Unable to allocate url");
- free(unix_path);
+ free(escaped_path);
return NSERROR_NOMEM;
}
- if (*unix_path == '/') {
- snprintf(url, urllen, "%s%s", FILE_SCHEME_PREFIX, unix_path + 1);
+ if (*escaped_path == '/') {
+ snprintf(url, urllen, "%s%s",
+ FILE_SCHEME_PREFIX, escaped_path + 1);
} else {
- snprintf(url, urllen, "%s%s", FILE_SCHEME_PREFIX, unix_path);
+ snprintf(url, urllen, "%s%s",
+ FILE_SCHEME_PREFIX, escaped_path);
}
- free(unix_path);
+ free(escaped_path);
- /* We don't want '/' to be escaped. */
- ret = url_escape(url, FILE_SCHEME_PREFIX_LEN, false, "/", &escurl);
+ ret = nsurl_create(url, url_out);
free(url);
- if (ret != NSERROR_OK) {
- return ret;
- }
-
- ret = nsurl_create(escurl, url_out);
- free(escurl);
return ret;
}
diff --git a/render/form.c b/render/form.c
index f8d0ce5..8ae59b5 100644
--- a/render/form.c
+++ b/render/form.c
@@ -912,7 +912,7 @@ static char *form_url_encode(struct form *form,
}
for (; control; control = control->next) {
- url_err = url_escape(control->name, 0, true, NULL, &name);
+ url_err = url_escape(control->name, true, NULL, &name);
if (url_err == NSERROR_NOMEM) {
free(s);
return NULL;
@@ -920,7 +920,7 @@ static char *form_url_encode(struct form *form,
assert(url_err == NSERROR_OK);
- url_err = url_escape(control->value, 0, true, NULL, &value);
+ url_err = url_escape(control->value, true, NULL, &value);
if (url_err == NSERROR_NOMEM) {
free(name);
free(s);
diff --git a/utils/file.c b/utils/file.c
index 3ec97de..cc82657 100644
--- a/utils/file.c
+++ b/utils/file.c
@@ -174,7 +174,7 @@ static nserror posix_path_to_nsurl(const char *path, struct nsurl **url_out)
}
/* escape the path so it can be placed in a url */
- ret = url_escape(path, 0, false, "/", &escpath);
+ ret = url_escape(path, false, "/", &escpath);
if (ret != NSERROR_OK) {
return ret;
}
diff --git a/utils/url.c b/utils/url.c
index d1e9ce2..861a62b 100644
--- a/utils/url.c
+++ b/utils/url.c
@@ -113,63 +113,60 @@ nserror url_unescape(const char *str, size_t length,
/* exported interface documented in utils/url.h */
-nserror url_escape(const char *unescaped, size_t toskip,
- bool sptoplus, const char *escexceptions, char **result)
+nserror url_escape(const char *unescaped, bool sptoplus,
+ const char *escexceptions, char **result)
{
- size_t len;
- char *escaped, *d, *tmpres;
+ size_t len, new_len;
+ char *escaped, *pos;
const char *c;
- if (!unescaped || !result)
+ if (unescaped == NULL || result == NULL) {
return NSERROR_NOT_FOUND;
-
- *result = NULL;
+ }
len = strlen(unescaped);
- if (len < toskip)
- return NSERROR_NOT_FOUND;
- len -= toskip;
escaped = malloc(len * 3 + 1);
- if (!escaped)
+ if (escaped == NULL) {
return NSERROR_NOMEM;
+ }
+ pos = escaped;
- for (c = unescaped + toskip, d = escaped; *c; c++) {
+ for (c = unescaped; *c != '\0'; c++) {
/* Check if we should escape this byte.
* '~' is unreserved and should not be percent encoded, if
* you believe the spec; however, leaving it unescaped
* breaks a bunch of websites, so we escape it anyway. */
- if (!isascii(*c)
- || (strchr(":/?#[]@" /* gen-delims */
- "!$&'()*+,;=" /* sub-delims */
- "<>%\"{}|\\^`~" /* others */, *c)
- && (!escexceptions || !strchr(escexceptions, *c)))
- || *c <= 0x20 || *c == 0x7f) {
+ if (!isascii(*c) ||
+ (strchr(":/?#[]@" /* gen-delims */
+ "!$&'()*+,;=" /* sub-delims */
+ "<>%\"{}|\\^`~" /* others */, *c) &&
+ (!escexceptions ||
+ !strchr(escexceptions, *c))) ||
+ *c <= 0x20 || *c == 0x7f) {
if (*c == 0x20 && sptoplus) {
- *d++ = '+';
+ *pos++ = '+';
} else {
- *d++ = '%';
- *d++ = "0123456789ABCDEF"[((*c >> 4) & 0xf)];
- *d++ = "0123456789ABCDEF"[(*c & 0xf)];
+ *pos++ = '%';
+ *pos++ = "0123456789ABCDEF"[(*c >> 4) & 0xf];
+ *pos++ = "0123456789ABCDEF"[*c & 0xf];
}
} else {
/* unreserved characters: [a-zA-Z0-9-._] */
- *d++ = *c;
+ *pos++ = *c;
}
}
- *d++ = '\0';
+ *pos = '\0';
+ new_len = pos - escaped;
- tmpres = malloc(d - escaped + toskip);
- if (!tmpres) {
- free(escaped);
- return NSERROR_NOMEM;
+ if (new_len != len) {
+ /* Shrink wrap the allocation around the escaped string */
+ char *tmp = realloc(escaped, new_len + 1);
+ if (tmp != NULL) {
+ escaped = tmp;
+ }
}
- memcpy(tmpres, unescaped, toskip);
- memcpy(tmpres + toskip, escaped, d - escaped);
- *result = tmpres;
-
- free(escaped);
-
+ *result = escaped;
return NSERROR_OK;
}
diff --git a/utils/url.h b/utils/url.h
index 5d8d154..b80fadd 100644
--- a/utils/url.h
+++ b/utils/url.h
@@ -31,14 +31,15 @@
/**
* Escape a string suitable for inclusion in an URL.
*
- * \param unescaped the unescaped string
- * \param toskip number of bytes to skip in unescaped string
- * \param sptoplus true iff spaces should be converted to +
- * \param escexceptions NULL or a string of characters excluded to be escaped
- * \param result pointer to pointer to buffer to hold escaped string
+ * \param[in] unescaped the unescaped string
+ * \param[in] sptoplus true iff spaces should be converted to +
+ * \param[in] escexceptions NULL or a string of characters to be excluded
+ * from escaping.
+ * \param[out] result Returns pointer to buffer to escaped string.
+ * Returned string is '\0' terminated.
* \return NSERROR_OK on success
*/
-nserror url_escape(const char *unescaped, size_t toskip, bool sptoplus,
+nserror url_escape(const char *unescaped, bool sptoplus,
const char *escexceptions, char **result);
--
NetSurf Browser
7 years, 1 month
netsurf: branch master updated. release/3.5-228-g7bff70e
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/7bff70e7466dd80603922...
...commit http://git.netsurf-browser.org/netsurf.git/commit/7bff70e7466dd80603922ba...
...tree http://git.netsurf-browser.org/netsurf.git/tree/7bff70e7466dd80603922ba0d...
The branch, master has been updated
via 7bff70e7466dd80603922ba0dfdad1725cce41a6 (commit)
from 7417a21bb1f0e8e00958319f60d8c12a9502a353 (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=7bff70e7466dd806039...
commit 7bff70e7466dd80603922ba0dfdad1725cce41a6
Author: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Commit: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Fix TODO (writing past end of buffer)
diff --git a/frontends/amiga/misc.c b/frontends/amiga/misc.c
index f15eb48..c09b283 100755
--- a/frontends/amiga/misc.c
+++ b/frontends/amiga/misc.c
@@ -225,18 +225,19 @@ static nserror amiga_nsurl_to_path(struct nsurl *url, char **path_out)
}
colon = strchr(path, ':');
- if(colon == NULL)
- {
+ if(colon == NULL) {
slash = strchr(path, '/');
- if(slash)
- {
+ if(slash) {
*slash = ':';
- }
- else
- {
+ } else {
+ char *tmp_path = malloc(path_len + 2);
+ if(tmp_path == NULL) return NSERROR_NOMEM;
+
+ strncpy(tmp_path, path, path_len);
+ free(path);
+
+ path = tmp_path;
path[path_len] = ':';
- /* TODO: Looks like we are writing past the end of
- * path's allocation here. */
path[path_len + 1] = '\0';
}
}
-----------------------------------------------------------------------
Summary of changes:
frontends/amiga/misc.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/frontends/amiga/misc.c b/frontends/amiga/misc.c
index f15eb48..c09b283 100755
--- a/frontends/amiga/misc.c
+++ b/frontends/amiga/misc.c
@@ -225,18 +225,19 @@ static nserror amiga_nsurl_to_path(struct nsurl *url, char **path_out)
}
colon = strchr(path, ':');
- if(colon == NULL)
- {
+ if(colon == NULL) {
slash = strchr(path, '/');
- if(slash)
- {
+ if(slash) {
*slash = ':';
- }
- else
- {
+ } else {
+ char *tmp_path = malloc(path_len + 2);
+ if(tmp_path == NULL) return NSERROR_NOMEM;
+
+ strncpy(tmp_path, path, path_len);
+ free(path);
+
+ path = tmp_path;
path[path_len] = ':';
- /* TODO: Looks like we are writing past the end of
- * path's allocation here. */
path[path_len + 1] = '\0';
}
}
--
NetSurf Browser
7 years, 1 month
netsurf: branch master updated. release/3.5-227-g7417a21
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/7417a21bb1f0e8e009583...
...commit http://git.netsurf-browser.org/netsurf.git/commit/7417a21bb1f0e8e00958319...
...tree http://git.netsurf-browser.org/netsurf.git/tree/7417a21bb1f0e8e00958319f6...
The branch, master has been updated
via 7417a21bb1f0e8e00958319f60d8c12a9502a353 (commit)
from e88d82f87f8dda23fa87cf730abebff5078ee629 (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=7417a21bb1f0e8e0095...
commit 7417a21bb1f0e8e00958319f60d8c12a9502a353
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Improve comments.
diff --git a/utils/url.c b/utils/url.c
index 50059a1..d1e9ce2 100644
--- a/utils/url.c
+++ b/utils/url.c
@@ -97,7 +97,7 @@ nserror url_unescape(const char *str, size_t length,
new_len = res_pos - result;
if (new_len != length) {
- /* Shrink wrap the allocaiton around the string */
+ /* Shrink wrap the allocation around the string */
char *tmp = realloc(result, new_len + 1);
if (tmp != NULL) {
result = tmp;
diff --git a/utils/url.h b/utils/url.h
index 07ad1a7..5d8d154 100644
--- a/utils/url.h
+++ b/utils/url.h
@@ -48,9 +48,10 @@ nserror url_escape(const char *unescaped, size_t toskip, bool sptoplus,
* \param[in] str String to unescape.
* \param[in] length Length of string or 0 to use strlen.
* \param[out] length_out Iff non-NULL, value updated to length of returned
- * result_out string.
+ * result_out string (excluding trailing '\0'`).
* \param[out] result_out Returns unescaped string, owned by caller.
* Must be freed with free().
+ * Returned string has trailing '\0'.
* \return NSERROR_OK on success
*/
nserror url_unescape(const char *str, size_t length,
-----------------------------------------------------------------------
Summary of changes:
utils/url.c | 2 +-
utils/url.h | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/utils/url.c b/utils/url.c
index 50059a1..d1e9ce2 100644
--- a/utils/url.c
+++ b/utils/url.c
@@ -97,7 +97,7 @@ nserror url_unescape(const char *str, size_t length,
new_len = res_pos - result;
if (new_len != length) {
- /* Shrink wrap the allocaiton around the string */
+ /* Shrink wrap the allocation around the string */
char *tmp = realloc(result, new_len + 1);
if (tmp != NULL) {
result = tmp;
diff --git a/utils/url.h b/utils/url.h
index 07ad1a7..5d8d154 100644
--- a/utils/url.h
+++ b/utils/url.h
@@ -48,9 +48,10 @@ nserror url_escape(const char *unescaped, size_t toskip, bool sptoplus,
* \param[in] str String to unescape.
* \param[in] length Length of string or 0 to use strlen.
* \param[out] length_out Iff non-NULL, value updated to length of returned
- * result_out string.
+ * result_out string (excluding trailing '\0'`).
* \param[out] result_out Returns unescaped string, owned by caller.
* Must be freed with free().
+ * Returned string has trailing '\0'.
* \return NSERROR_OK on success
*/
nserror url_unescape(const char *str, size_t length,
--
NetSurf Browser
7 years, 2 months
netsurf: branch master updated. release/3.5-225-gb4e21b7
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/b4e21b76fd0b8b4a048f0...
...commit http://git.netsurf-browser.org/netsurf.git/commit/b4e21b76fd0b8b4a048f0d8...
...tree http://git.netsurf-browser.org/netsurf.git/tree/b4e21b76fd0b8b4a048f0d812...
The branch, master has been updated
via b4e21b76fd0b8b4a048f0d8125bc5a36c0ca8d42 (commit)
via fa2e3b778465cd496aedde8e187038835a765c4f (commit)
via cf753f20cc2a8506c831a5cedd933e3e78417261 (commit)
via a543206075d86cc7c4ea3db96b96e94a12cf8c7f (commit)
via 7202ff2f649561dd98cb721bdf88b4735127bba9 (commit)
via 90a260a2ccf33a399c87b1619d3b82e19b84020f (commit)
via f9870c41f5404be33a15fe75f8a431053782597b (commit)
from 83f95fe05e98464ffa832df6f17ca619cc173bc2 (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=b4e21b76fd0b8b4a048...
commit b4e21b76fd0b8b4a048f0d8125bc5a36c0ca8d42
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
URL unescape: Calculate new_len at end, rather than maintaining it.
diff --git a/utils/url.c b/utils/url.c
index 9294e3d..40f3708 100644
--- a/utils/url.c
+++ b/utils/url.c
@@ -71,8 +71,6 @@ nserror url_unescape(const char *str, size_t length,
return NSERROR_NOMEM;
}
- new_len = length;
-
res_pos = result;
str_end = str + length;
if (length >= 3) {
@@ -85,7 +83,6 @@ nserror url_unescape(const char *str, size_t length,
if (c == '%' && isxdigit(c1) && isxdigit(c2)) {
c = xdigit_to_hex(c1) << 4 | xdigit_to_hex(c2);
str += 2;
- new_len -= 2;
}
*res_pos++ = c;
str++;
@@ -97,7 +94,8 @@ nserror url_unescape(const char *str, size_t length,
*res_pos++ = *str++;
}
- *res_pos++ = '\0';
+ *res_pos = '\0';
+ new_len = res_pos - result;
if (new_len != length) {
/* Shrink wrap the allocaiton around the string */
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=fa2e3b778465cd496ae...
commit fa2e3b778465cd496aedde8e187038835a765c4f
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
URL unescape: return the new length to the caller.
The avoids situations were we threw away the length, only for
the caller to have to strlen the returned string.
Note, there seems to be a case of the amiga front end writing
beyond end of allocation. Added a TODO for now.
diff --git a/content/fetchers/data.c b/content/fetchers/data.c
index 6b8be8d..65d99cf 100644
--- a/content/fetchers/data.c
+++ b/content/fetchers/data.c
@@ -138,7 +138,7 @@ static bool fetch_data_process(struct fetch_data_context *c)
char *params;
char *comma;
char *unescaped;
- int unescaped_len;
+ size_t unescaped_len;
/* format of a data: URL is:
* data:[<mimetype>][;base64],<data>
@@ -193,14 +193,13 @@ static bool fetch_data_process(struct fetch_data_context *c)
/* URL unescape the data first, just incase some insane page
* decides to nest URL and base64 encoding. Like, say, Acid2.
*/
- res = url_unescape(comma + 1, 0, &unescaped);
+ res = url_unescape(comma + 1, 0, &unescaped_len, &unescaped);
if (res != NSERROR_OK) {
msg.type = FETCH_ERROR;
msg.data.error = "Unable to URL decode data: URL";
fetch_data_send_callback(&msg, c);
return false;
}
- unescaped_len = strlen(unescaped);
if (c->base64) {
base64_decode_alloc(unescaped, unescaped_len, &c->data, &c->datalen);
diff --git a/frontends/amiga/misc.c b/frontends/amiga/misc.c
index 2388651..f15eb48 100755
--- a/frontends/amiga/misc.c
+++ b/frontends/amiga/misc.c
@@ -189,6 +189,7 @@ int32 amiga_warn_user_multi(const char *body, const char *opt1, const char *opt2
static nserror amiga_nsurl_to_path(struct nsurl *url, char **path_out)
{
lwc_string *urlpath;
+ size_t path_len;
char *path;
bool match;
lwc_string *scheme;
@@ -217,7 +218,7 @@ static nserror amiga_nsurl_to_path(struct nsurl *url, char **path_out)
return NSERROR_BAD_PARAMETER;
}
- res = url_unescape(lwc_string_data(urlpath) + 1, 0, &path);
+ res = url_unescape(lwc_string_data(urlpath) + 1, 0, &path_len, &path);
lwc_string_unref(urlpath);
if (res != NSERROR_OK) {
return res;
@@ -233,9 +234,10 @@ static nserror amiga_nsurl_to_path(struct nsurl *url, char **path_out)
}
else
{
- int len = strlen(path);
- path[len] = ':';
- path[len + 1] = '\0';
+ path[path_len] = ':';
+ /* TODO: Looks like we are writing past the end of
+ * path's allocation here. */
+ path[path_len + 1] = '\0';
}
}
diff --git a/frontends/atari/file.c b/frontends/atari/file.c
index 7bc11da..3816e47 100644
--- a/frontends/atari/file.c
+++ b/frontends/atari/file.c
@@ -112,6 +112,7 @@ static nserror atari_basename(const char *path, char **str, size_t *size)
static nserror atari_nsurl_to_path(struct nsurl *url, char **path_out)
{
lwc_string *urlpath;
+ size_t path_len;
char *path;
bool match;
lwc_string *scheme;
@@ -140,6 +141,7 @@ static nserror atari_nsurl_to_path(struct nsurl *url, char **path_out)
res = url_unescape(lwc_string_data(urlpath),
lwc_string_length(urlpath),
+ &path_len,
&path);
lwc_string_unref(urlpath);
if (res != NSERROR_OK) {
@@ -153,7 +155,7 @@ static nserror atari_nsurl_to_path(struct nsurl *url, char **path_out)
* strlen is *not* copying too much data as we are
* moving the null too!
*/
- memmove(path, path + 1, strlen(path));
+ memmove(path, path + 1, path_len);
}
/* if the path does not have a drive letter we return the
* complete path.
diff --git a/frontends/beos/gui.cpp b/frontends/beos/gui.cpp
index 53387ad..8c6614d 100644
--- a/frontends/beos/gui.cpp
+++ b/frontends/beos/gui.cpp
@@ -797,7 +797,7 @@ static char *url_to_path(const char *url)
char *url_path;
char *path = NULL;
- if (url_unescape(url, 0, &url_path) == NSERROR_OK) {
+ if (url_unescape(url, 0, NULL, &url_path) == NSERROR_OK) {
/* return the absolute path including leading / */
path = strdup(url_path + (FILE_SCHEME_PREFIX_LEN - 1));
free(url_path);
diff --git a/frontends/riscos/download.c b/frontends/riscos/download.c
index 1a0249e..561409e 100644
--- a/frontends/riscos/download.c
+++ b/frontends/riscos/download.c
@@ -241,6 +241,7 @@ static nserror download_ro_filetype(download_context *ctx, bits *ftype_out)
char *raw_path;
if (url_unescape(lwc_string_data(path),
lwc_string_length(path),
+ NULL,
&raw_path) == NSERROR_OK) {
ftype = ro_filetype_from_unix_path(raw_path);
free(raw_path);
diff --git a/frontends/riscos/gui.c b/frontends/riscos/gui.c
index f55392f..72eeb62 100644
--- a/frontends/riscos/gui.c
+++ b/frontends/riscos/gui.c
@@ -1485,6 +1485,7 @@ static nserror ro_path_to_nsurl(const char *path, struct nsurl **url_out)
static nserror ro_nsurl_to_path(struct nsurl *url, char **path_out)
{
lwc_string *urlpath;
+ size_t unpath_len;
char *unpath;
char *path;
bool match;
@@ -1515,6 +1516,7 @@ static nserror ro_nsurl_to_path(struct nsurl *url, char **path_out)
res = url_unescape(lwc_string_data(urlpath),
lwc_string_length(urlpath),
+ &unpath_len,
&unpath);
lwc_string_unref(urlpath);
if (res != NSERROR_OK) {
@@ -1522,14 +1524,14 @@ static nserror ro_nsurl_to_path(struct nsurl *url, char **path_out)
}
/* RISC OS path should not be more than 100 characters longer */
- path = malloc(strlen(unpath) + 100);
+ path = malloc(unpath_len + 100);
if (path == NULL) {
free(unpath);
return NSERROR_NOMEM;
}
r = __riscosify(unpath, 0, __RISCOSIFY_NO_SUFFIX,
- path, strlen(unpath) + 100, 0);
+ path, unpath_len + 100, 0);
free(unpath);
if (r == NULL) {
free(path);
diff --git a/frontends/windows/file.c b/frontends/windows/file.c
index 7583790..90e6ef4 100644
--- a/frontends/windows/file.c
+++ b/frontends/windows/file.c
@@ -143,6 +143,7 @@ static nserror windows_nsurl_to_path(struct nsurl *url, char **path_out)
res = url_unescape(lwc_string_data(urlpath),
lwc_string_length(urlpath),
+ NULL,
&path);
lwc_string_unref(urlpath);
if (res != NSERROR_OK) {
diff --git a/test/llcache.c b/test/llcache.c
index df51386..8aae357 100644
--- a/test/llcache.c
+++ b/test/llcache.c
@@ -95,7 +95,7 @@ char *url_to_path(const char *url)
char *url_path;
char *path = NULL;
- if (url_unescape(url, 0, &url_path) == NSERROR_OK) {
+ if (url_unescape(url, 0, NULL, &url_path) == NSERROR_OK) {
/* return the absolute path including leading / */
path = strdup(url_path + (FILE_SCHEME_PREFIX_LEN - 1));
free(url_path);
diff --git a/utils/file.c b/utils/file.c
index 6224d1c..3ec97de 100644
--- a/utils/file.c
+++ b/utils/file.c
@@ -138,6 +138,7 @@ static nserror posix_nsurl_to_path(struct nsurl *url, char **path_out)
res = url_unescape(lwc_string_data(urlpath),
lwc_string_length(urlpath),
+ NULL,
&path);
lwc_string_unref(urlpath);
if (res != NSERROR_OK) {
diff --git a/utils/url.c b/utils/url.c
index 3be983d..9294e3d 100644
--- a/utils/url.c
+++ b/utils/url.c
@@ -54,7 +54,8 @@ static inline char xdigit_to_hex(char c)
/* exported interface documented in utils/url.h */
-nserror url_unescape(const char *str, size_t length, char **result_out)
+nserror url_unescape(const char *str, size_t length,
+ size_t *length_out, char **result_out)
{
const char *str_end;
size_t new_len;
@@ -106,6 +107,9 @@ nserror url_unescape(const char *str, size_t length, char **result_out)
}
}
+ if (length_out != NULL) {
+ *length_out = new_len;
+ }
*result_out = result;
return NSERROR_OK;
}
diff --git a/utils/url.h b/utils/url.h
index e67d69a..07ad1a7 100644
--- a/utils/url.h
+++ b/utils/url.h
@@ -45,11 +45,15 @@ nserror url_escape(const char *unescaped, size_t toskip, bool sptoplus,
/**
* Convert an escaped string to plain.
*
- * \param[in] str String to unescape.
- * \param[in] length Length of string or 0 to use strlen
- * \param[out] result unescaped string owned by caller must be freed with free()
+ * \param[in] str String to unescape.
+ * \param[in] length Length of string or 0 to use strlen.
+ * \param[out] length_out Iff non-NULL, value updated to length of returned
+ * result_out string.
+ * \param[out] result_out Returns unescaped string, owned by caller.
+ * Must be freed with free().
* \return NSERROR_OK on success
*/
-nserror url_unescape(const char *str, size_t length, char **result);
+nserror url_unescape(const char *str, size_t length,
+ size_t *length_out, char **result_out);
#endif
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=cf753f20cc2a8506c83...
commit cf753f20cc2a8506c831a5cedd933e3e78417261
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Avoid using curl for URL unescaping.
This moves us towards working without curl.
diff --git a/utils/url.c b/utils/url.c
index efbc769..3be983d 100644
--- a/utils/url.c
+++ b/utils/url.c
@@ -23,6 +23,7 @@
*/
#include <ctype.h>
+#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <curl/curl.h>
@@ -32,25 +33,80 @@
#include "utils/url.h"
+/**
+ * Convert a hex digit to a hex value
+ *
+ * Must be called with valid hex char, results undefined otherwise.
+ *
+ * \param[in] c char to convert yo value
+ * \return the value of c
+ */
+static inline char xdigit_to_hex(char c)
+{
+ if (c >= '0' && c <= '9') {
+ return c - '0';
+ } else if (c >= 'A' && c <= 'F') {
+ return c - 'A' + 10;
+ } else {
+ return c - 'a' + 10;
+ }
+}
+
+
/* exported interface documented in utils/url.h */
-nserror url_unescape(const char *str, size_t length, char **result)
+nserror url_unescape(const char *str, size_t length, char **result_out)
{
- char *curlstr;
- char *retstr;
+ const char *str_end;
+ size_t new_len;
+ char *res_pos;
+ char *result;
+
+ if (length == 0) {
+ length = strlen(str);
+ }
- curlstr = curl_unescape(str, length);
- if (curlstr == NULL) {
+ result = malloc(length + 1);
+ if (result == NULL) {
return NSERROR_NOMEM;
}
- retstr = strdup(curlstr);
- curl_free(curlstr);
+ new_len = length;
+
+ res_pos = result;
+ str_end = str + length;
+ if (length >= 3) {
+ str_end -= 2;
+ while (str < str_end) {
+ char c = *str;
+ char c1 = *(str + 1);
+ char c2 = *(str + 2);
+
+ if (c == '%' && isxdigit(c1) && isxdigit(c2)) {
+ c = xdigit_to_hex(c1) << 4 | xdigit_to_hex(c2);
+ str += 2;
+ new_len -= 2;
+ }
+ *res_pos++ = c;
+ str++;
+ }
+ str_end += 2;
+ }
- if (retstr == NULL) {
- return NSERROR_NOMEM;
+ while (str < str_end) {
+ *res_pos++ = *str++;
+ }
+
+ *res_pos++ = '\0';
+
+ if (new_len != length) {
+ /* Shrink wrap the allocaiton around the string */
+ char *tmp = realloc(result, new_len + 1);
+ if (tmp != NULL) {
+ result = tmp;
+ }
}
- *result = retstr;
+ *result_out = result;
return NSERROR_OK;
}
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=a543206075d86cc7c4e...
commit a543206075d86cc7c4ea3db96b96e94a12cf8c7f
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
URL unescape: Use size_t for length.
diff --git a/utils/url.c b/utils/url.c
index 4fcbccd..efbc769 100644
--- a/utils/url.c
+++ b/utils/url.c
@@ -33,7 +33,7 @@
/* exported interface documented in utils/url.h */
-nserror url_unescape(const char *str, int length, char **result)
+nserror url_unescape(const char *str, size_t length, char **result)
{
char *curlstr;
char *retstr;
diff --git a/utils/url.h b/utils/url.h
index 8bbd68d..e67d69a 100644
--- a/utils/url.h
+++ b/utils/url.h
@@ -50,6 +50,6 @@ nserror url_escape(const char *unescaped, size_t toskip, bool sptoplus,
* \param[out] result unescaped string owned by caller must be freed with free()
* \return NSERROR_OK on success
*/
-nserror url_unescape(const char *str, int length, char **result);
+nserror url_unescape(const char *str, size_t length, char **result);
#endif
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=7202ff2f649561dd98c...
commit 7202ff2f649561dd98cb721bdf88b4735127bba9
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Data URL handling: Use url_unescape rather than curl.
diff --git a/content/fetchers/data.c b/content/fetchers/data.c
index bbd4395..6b8be8d 100644
--- a/content/fetchers/data.c
+++ b/content/fetchers/data.c
@@ -24,9 +24,9 @@
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
-#include <curl/curl.h> /* for URL unescaping functions */
#include <libwapcaplet/libwapcaplet.h>
+#include "utils/url.h"
#include "utils/nsurl.h"
#include "utils/corestrings.h"
#include "utils/log.h"
@@ -54,21 +54,16 @@ struct fetch_data_context {
static struct fetch_data_context *ring = NULL;
-static CURL *curl;
-
static bool fetch_data_initialise(lwc_string *scheme)
{
LOG("fetch_data_initialise called for %s", lwc_string_data(scheme));
- if ( (curl = curl_easy_init()) == NULL)
- return false;
- else
- return true;
+
+ return true;
}
static void fetch_data_finalise(lwc_string *scheme)
{
LOG("fetch_data_finalise called for %s", lwc_string_data(scheme));
- curl_easy_cleanup(curl);
}
static bool fetch_data_can_fetch(const nsurl *url)
@@ -138,6 +133,7 @@ static void fetch_data_send_callback(const fetch_msg *msg,
static bool fetch_data_process(struct fetch_data_context *c)
{
+ nserror res;
fetch_msg msg;
char *params;
char *comma;
@@ -197,13 +193,14 @@ static bool fetch_data_process(struct fetch_data_context *c)
/* URL unescape the data first, just incase some insane page
* decides to nest URL and base64 encoding. Like, say, Acid2.
*/
- unescaped = curl_easy_unescape(curl, comma + 1, 0, &unescaped_len);
- if (unescaped == NULL) {
+ res = url_unescape(comma + 1, 0, &unescaped);
+ if (res != NSERROR_OK) {
msg.type = FETCH_ERROR;
msg.data.error = "Unable to URL decode data: URL";
fetch_data_send_callback(&msg, c);
return false;
}
+ unescaped_len = strlen(unescaped);
if (c->base64) {
base64_decode_alloc(unescaped, unescaped_len, &c->data, &c->datalen);
@@ -211,7 +208,7 @@ static bool fetch_data_process(struct fetch_data_context *c)
msg.type = FETCH_ERROR;
msg.data.error = "Unable to Base64 decode data: URL";
fetch_data_send_callback(&msg, c);
- curl_free(unescaped);
+ free(unescaped);
return false;
}
} else {
@@ -221,14 +218,14 @@ static bool fetch_data_process(struct fetch_data_context *c)
msg.data.error =
"Unable to allocate memory for data: URL";
fetch_data_send_callback(&msg, c);
- curl_free(unescaped);
+ free(unescaped);
return false;
}
c->datalen = unescaped_len;
memcpy(c->data, unescaped, unescaped_len);
}
- curl_free(unescaped);
+ free(unescaped);
return true;
}
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=90a260a2ccf33a399c8...
commit 90a260a2ccf33a399c87b1619d3b82e19b84020f
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Doxygen: Fix instance of bad function comment syntax.
diff --git a/utils/url.h b/utils/url.h
index 94579e3..8bbd68d 100644
--- a/utils/url.h
+++ b/utils/url.h
@@ -46,7 +46,7 @@ nserror url_escape(const char *unescaped, size_t toskip, bool sptoplus,
* Convert an escaped string to plain.
*
* \param[in] str String to unescape.
- * \parm[in] length Length of string or 0 to use strlen
+ * \param[in] length Length of string or 0 to use strlen
* \param[out] result unescaped string owned by caller must be freed with free()
* \return NSERROR_OK on success
*/
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=f9870c41f5404be33a1...
commit f9870c41f5404be33a15fe75f8a431053782597b
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Whitespace: Convert spaces to tab for indent.
diff --git a/content/fetchers/data.c b/content/fetchers/data.c
index 84d0aa3..bbd4395 100644
--- a/content/fetchers/data.c
+++ b/content/fetchers/data.c
@@ -142,7 +142,7 @@ static bool fetch_data_process(struct fetch_data_context *c)
char *params;
char *comma;
char *unescaped;
- int unescaped_len;
+ int unescaped_len;
/* format of a data: URL is:
* data:[<mimetype>][;base64],<data>
@@ -197,8 +197,8 @@ static bool fetch_data_process(struct fetch_data_context *c)
/* URL unescape the data first, just incase some insane page
* decides to nest URL and base64 encoding. Like, say, Acid2.
*/
- unescaped = curl_easy_unescape(curl, comma + 1, 0, &unescaped_len);
- if (unescaped == NULL) {
+ unescaped = curl_easy_unescape(curl, comma + 1, 0, &unescaped_len);
+ if (unescaped == NULL) {
msg.type = FETCH_ERROR;
msg.data.error = "Unable to URL decode data: URL";
fetch_data_send_callback(&msg, c);
-----------------------------------------------------------------------
Summary of changes:
content/fetchers/data.c | 24 ++++++-------
frontends/amiga/misc.c | 10 +++---
frontends/atari/file.c | 4 ++-
frontends/beos/gui.cpp | 2 +-
frontends/riscos/download.c | 1 +
frontends/riscos/gui.c | 6 ++--
frontends/windows/file.c | 1 +
test/llcache.c | 2 +-
utils/file.c | 1 +
utils/url.c | 78 +++++++++++++++++++++++++++++++++++++------
utils/url.h | 12 ++++---
11 files changed, 104 insertions(+), 37 deletions(-)
diff --git a/content/fetchers/data.c b/content/fetchers/data.c
index 84d0aa3..65d99cf 100644
--- a/content/fetchers/data.c
+++ b/content/fetchers/data.c
@@ -24,9 +24,9 @@
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
-#include <curl/curl.h> /* for URL unescaping functions */
#include <libwapcaplet/libwapcaplet.h>
+#include "utils/url.h"
#include "utils/nsurl.h"
#include "utils/corestrings.h"
#include "utils/log.h"
@@ -54,21 +54,16 @@ struct fetch_data_context {
static struct fetch_data_context *ring = NULL;
-static CURL *curl;
-
static bool fetch_data_initialise(lwc_string *scheme)
{
LOG("fetch_data_initialise called for %s", lwc_string_data(scheme));
- if ( (curl = curl_easy_init()) == NULL)
- return false;
- else
- return true;
+
+ return true;
}
static void fetch_data_finalise(lwc_string *scheme)
{
LOG("fetch_data_finalise called for %s", lwc_string_data(scheme));
- curl_easy_cleanup(curl);
}
static bool fetch_data_can_fetch(const nsurl *url)
@@ -138,11 +133,12 @@ static void fetch_data_send_callback(const fetch_msg *msg,
static bool fetch_data_process(struct fetch_data_context *c)
{
+ nserror res;
fetch_msg msg;
char *params;
char *comma;
char *unescaped;
- int unescaped_len;
+ size_t unescaped_len;
/* format of a data: URL is:
* data:[<mimetype>][;base64],<data>
@@ -197,8 +193,8 @@ static bool fetch_data_process(struct fetch_data_context *c)
/* URL unescape the data first, just incase some insane page
* decides to nest URL and base64 encoding. Like, say, Acid2.
*/
- unescaped = curl_easy_unescape(curl, comma + 1, 0, &unescaped_len);
- if (unescaped == NULL) {
+ res = url_unescape(comma + 1, 0, &unescaped_len, &unescaped);
+ if (res != NSERROR_OK) {
msg.type = FETCH_ERROR;
msg.data.error = "Unable to URL decode data: URL";
fetch_data_send_callback(&msg, c);
@@ -211,7 +207,7 @@ static bool fetch_data_process(struct fetch_data_context *c)
msg.type = FETCH_ERROR;
msg.data.error = "Unable to Base64 decode data: URL";
fetch_data_send_callback(&msg, c);
- curl_free(unescaped);
+ free(unescaped);
return false;
}
} else {
@@ -221,14 +217,14 @@ static bool fetch_data_process(struct fetch_data_context *c)
msg.data.error =
"Unable to allocate memory for data: URL";
fetch_data_send_callback(&msg, c);
- curl_free(unescaped);
+ free(unescaped);
return false;
}
c->datalen = unescaped_len;
memcpy(c->data, unescaped, unescaped_len);
}
- curl_free(unescaped);
+ free(unescaped);
return true;
}
diff --git a/frontends/amiga/misc.c b/frontends/amiga/misc.c
index 2388651..f15eb48 100755
--- a/frontends/amiga/misc.c
+++ b/frontends/amiga/misc.c
@@ -189,6 +189,7 @@ int32 amiga_warn_user_multi(const char *body, const char *opt1, const char *opt2
static nserror amiga_nsurl_to_path(struct nsurl *url, char **path_out)
{
lwc_string *urlpath;
+ size_t path_len;
char *path;
bool match;
lwc_string *scheme;
@@ -217,7 +218,7 @@ static nserror amiga_nsurl_to_path(struct nsurl *url, char **path_out)
return NSERROR_BAD_PARAMETER;
}
- res = url_unescape(lwc_string_data(urlpath) + 1, 0, &path);
+ res = url_unescape(lwc_string_data(urlpath) + 1, 0, &path_len, &path);
lwc_string_unref(urlpath);
if (res != NSERROR_OK) {
return res;
@@ -233,9 +234,10 @@ static nserror amiga_nsurl_to_path(struct nsurl *url, char **path_out)
}
else
{
- int len = strlen(path);
- path[len] = ':';
- path[len + 1] = '\0';
+ path[path_len] = ':';
+ /* TODO: Looks like we are writing past the end of
+ * path's allocation here. */
+ path[path_len + 1] = '\0';
}
}
diff --git a/frontends/atari/file.c b/frontends/atari/file.c
index 7bc11da..3816e47 100644
--- a/frontends/atari/file.c
+++ b/frontends/atari/file.c
@@ -112,6 +112,7 @@ static nserror atari_basename(const char *path, char **str, size_t *size)
static nserror atari_nsurl_to_path(struct nsurl *url, char **path_out)
{
lwc_string *urlpath;
+ size_t path_len;
char *path;
bool match;
lwc_string *scheme;
@@ -140,6 +141,7 @@ static nserror atari_nsurl_to_path(struct nsurl *url, char **path_out)
res = url_unescape(lwc_string_data(urlpath),
lwc_string_length(urlpath),
+ &path_len,
&path);
lwc_string_unref(urlpath);
if (res != NSERROR_OK) {
@@ -153,7 +155,7 @@ static nserror atari_nsurl_to_path(struct nsurl *url, char **path_out)
* strlen is *not* copying too much data as we are
* moving the null too!
*/
- memmove(path, path + 1, strlen(path));
+ memmove(path, path + 1, path_len);
}
/* if the path does not have a drive letter we return the
* complete path.
diff --git a/frontends/beos/gui.cpp b/frontends/beos/gui.cpp
index 53387ad..8c6614d 100644
--- a/frontends/beos/gui.cpp
+++ b/frontends/beos/gui.cpp
@@ -797,7 +797,7 @@ static char *url_to_path(const char *url)
char *url_path;
char *path = NULL;
- if (url_unescape(url, 0, &url_path) == NSERROR_OK) {
+ if (url_unescape(url, 0, NULL, &url_path) == NSERROR_OK) {
/* return the absolute path including leading / */
path = strdup(url_path + (FILE_SCHEME_PREFIX_LEN - 1));
free(url_path);
diff --git a/frontends/riscos/download.c b/frontends/riscos/download.c
index 1a0249e..561409e 100644
--- a/frontends/riscos/download.c
+++ b/frontends/riscos/download.c
@@ -241,6 +241,7 @@ static nserror download_ro_filetype(download_context *ctx, bits *ftype_out)
char *raw_path;
if (url_unescape(lwc_string_data(path),
lwc_string_length(path),
+ NULL,
&raw_path) == NSERROR_OK) {
ftype = ro_filetype_from_unix_path(raw_path);
free(raw_path);
diff --git a/frontends/riscos/gui.c b/frontends/riscos/gui.c
index f55392f..72eeb62 100644
--- a/frontends/riscos/gui.c
+++ b/frontends/riscos/gui.c
@@ -1485,6 +1485,7 @@ static nserror ro_path_to_nsurl(const char *path, struct nsurl **url_out)
static nserror ro_nsurl_to_path(struct nsurl *url, char **path_out)
{
lwc_string *urlpath;
+ size_t unpath_len;
char *unpath;
char *path;
bool match;
@@ -1515,6 +1516,7 @@ static nserror ro_nsurl_to_path(struct nsurl *url, char **path_out)
res = url_unescape(lwc_string_data(urlpath),
lwc_string_length(urlpath),
+ &unpath_len,
&unpath);
lwc_string_unref(urlpath);
if (res != NSERROR_OK) {
@@ -1522,14 +1524,14 @@ static nserror ro_nsurl_to_path(struct nsurl *url, char **path_out)
}
/* RISC OS path should not be more than 100 characters longer */
- path = malloc(strlen(unpath) + 100);
+ path = malloc(unpath_len + 100);
if (path == NULL) {
free(unpath);
return NSERROR_NOMEM;
}
r = __riscosify(unpath, 0, __RISCOSIFY_NO_SUFFIX,
- path, strlen(unpath) + 100, 0);
+ path, unpath_len + 100, 0);
free(unpath);
if (r == NULL) {
free(path);
diff --git a/frontends/windows/file.c b/frontends/windows/file.c
index 7583790..90e6ef4 100644
--- a/frontends/windows/file.c
+++ b/frontends/windows/file.c
@@ -143,6 +143,7 @@ static nserror windows_nsurl_to_path(struct nsurl *url, char **path_out)
res = url_unescape(lwc_string_data(urlpath),
lwc_string_length(urlpath),
+ NULL,
&path);
lwc_string_unref(urlpath);
if (res != NSERROR_OK) {
diff --git a/test/llcache.c b/test/llcache.c
index df51386..8aae357 100644
--- a/test/llcache.c
+++ b/test/llcache.c
@@ -95,7 +95,7 @@ char *url_to_path(const char *url)
char *url_path;
char *path = NULL;
- if (url_unescape(url, 0, &url_path) == NSERROR_OK) {
+ if (url_unescape(url, 0, NULL, &url_path) == NSERROR_OK) {
/* return the absolute path including leading / */
path = strdup(url_path + (FILE_SCHEME_PREFIX_LEN - 1));
free(url_path);
diff --git a/utils/file.c b/utils/file.c
index 6224d1c..3ec97de 100644
--- a/utils/file.c
+++ b/utils/file.c
@@ -138,6 +138,7 @@ static nserror posix_nsurl_to_path(struct nsurl *url, char **path_out)
res = url_unescape(lwc_string_data(urlpath),
lwc_string_length(urlpath),
+ NULL,
&path);
lwc_string_unref(urlpath);
if (res != NSERROR_OK) {
diff --git a/utils/url.c b/utils/url.c
index 4fcbccd..40f3708 100644
--- a/utils/url.c
+++ b/utils/url.c
@@ -23,6 +23,7 @@
*/
#include <ctype.h>
+#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <curl/curl.h>
@@ -32,25 +33,82 @@
#include "utils/url.h"
+/**
+ * Convert a hex digit to a hex value
+ *
+ * Must be called with valid hex char, results undefined otherwise.
+ *
+ * \param[in] c char to convert yo value
+ * \return the value of c
+ */
+static inline char xdigit_to_hex(char c)
+{
+ if (c >= '0' && c <= '9') {
+ return c - '0';
+ } else if (c >= 'A' && c <= 'F') {
+ return c - 'A' + 10;
+ } else {
+ return c - 'a' + 10;
+ }
+}
+
+
/* exported interface documented in utils/url.h */
-nserror url_unescape(const char *str, int length, char **result)
+nserror url_unescape(const char *str, size_t length,
+ size_t *length_out, char **result_out)
{
- char *curlstr;
- char *retstr;
+ const char *str_end;
+ size_t new_len;
+ char *res_pos;
+ char *result;
+
+ if (length == 0) {
+ length = strlen(str);
+ }
- curlstr = curl_unescape(str, length);
- if (curlstr == NULL) {
+ result = malloc(length + 1);
+ if (result == NULL) {
return NSERROR_NOMEM;
}
- retstr = strdup(curlstr);
- curl_free(curlstr);
+ res_pos = result;
+ str_end = str + length;
+ if (length >= 3) {
+ str_end -= 2;
+ while (str < str_end) {
+ char c = *str;
+ char c1 = *(str + 1);
+ char c2 = *(str + 2);
+
+ if (c == '%' && isxdigit(c1) && isxdigit(c2)) {
+ c = xdigit_to_hex(c1) << 4 | xdigit_to_hex(c2);
+ str += 2;
+ }
+ *res_pos++ = c;
+ str++;
+ }
+ str_end += 2;
+ }
- if (retstr == NULL) {
- return NSERROR_NOMEM;
+ while (str < str_end) {
+ *res_pos++ = *str++;
}
- *result = retstr;
+ *res_pos = '\0';
+ new_len = res_pos - result;
+
+ if (new_len != length) {
+ /* Shrink wrap the allocaiton around the string */
+ char *tmp = realloc(result, new_len + 1);
+ if (tmp != NULL) {
+ result = tmp;
+ }
+ }
+
+ if (length_out != NULL) {
+ *length_out = new_len;
+ }
+ *result_out = result;
return NSERROR_OK;
}
diff --git a/utils/url.h b/utils/url.h
index 94579e3..07ad1a7 100644
--- a/utils/url.h
+++ b/utils/url.h
@@ -45,11 +45,15 @@ nserror url_escape(const char *unescaped, size_t toskip, bool sptoplus,
/**
* Convert an escaped string to plain.
*
- * \param[in] str String to unescape.
- * \parm[in] length Length of string or 0 to use strlen
- * \param[out] result unescaped string owned by caller must be freed with free()
+ * \param[in] str String to unescape.
+ * \param[in] length Length of string or 0 to use strlen.
+ * \param[out] length_out Iff non-NULL, value updated to length of returned
+ * result_out string.
+ * \param[out] result_out Returns unescaped string, owned by caller.
+ * Must be freed with free().
* \return NSERROR_OK on success
*/
-nserror url_unescape(const char *str, int length, char **result);
+nserror url_unescape(const char *str, size_t length,
+ size_t *length_out, char **result_out);
#endif
--
NetSurf Browser
7 years, 2 months
netsurf: branch master updated. release/3.5-218-g83f95fe
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/83f95fe05e98464ffa832...
...commit http://git.netsurf-browser.org/netsurf.git/commit/83f95fe05e98464ffa832df...
...tree http://git.netsurf-browser.org/netsurf.git/tree/83f95fe05e98464ffa832df6f...
The branch, master has been updated
via 83f95fe05e98464ffa832df6f17ca619cc173bc2 (commit)
from 9ee6e90de5394042bdd082cc1ddc7837387ad770 (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=83f95fe05e98464ffa8...
commit 83f95fe05e98464ffa832df6f17ca619cc173bc2
Author: François Revol <revol(a)free.fr>
Commit: Vincent Sanders <vince(a)kyllikki.org>
Explicitely support http and https URI schemes in the .desktop
diff --git a/frontends/gtk/res/netsurf-gtk.desktop b/frontends/gtk/res/netsurf-gtk.desktop
index 4c21d55..6b5bc2d 100644
--- a/frontends/gtk/res/netsurf-gtk.desktop
+++ b/frontends/gtk/res/netsurf-gtk.desktop
@@ -63,6 +63,6 @@ X-MultipleArgs=false
Type=Application
Icon=netsurf.png
Categories=Network;
-MimeType=text/html;text/xml;application/xhtml+xml;application/xml;image/gif;image/jpeg;image/png
+MimeType=text/html;text/xml;application/xhtml+xml;application/xml;image/gif;image/jpeg;image/png;x-scheme-handler/http;x-scheme-handler/https
StartupWMClass=NetSurf-bin
StartupNotify=true
-----------------------------------------------------------------------
Summary of changes:
frontends/gtk/res/netsurf-gtk.desktop | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontends/gtk/res/netsurf-gtk.desktop b/frontends/gtk/res/netsurf-gtk.desktop
index 4c21d55..6b5bc2d 100644
--- a/frontends/gtk/res/netsurf-gtk.desktop
+++ b/frontends/gtk/res/netsurf-gtk.desktop
@@ -63,6 +63,6 @@ X-MultipleArgs=false
Type=Application
Icon=netsurf.png
Categories=Network;
-MimeType=text/html;text/xml;application/xhtml+xml;application/xml;image/gif;image/jpeg;image/png
+MimeType=text/html;text/xml;application/xhtml+xml;application/xml;image/gif;image/jpeg;image/png;x-scheme-handler/http;x-scheme-handler/https
StartupWMClass=NetSurf-bin
StartupNotify=true
--
NetSurf Browser
7 years, 2 months
netsurf: branch master updated. release/3.5-217-g9ee6e90
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/9ee6e90de5394042bdd08...
...commit http://git.netsurf-browser.org/netsurf.git/commit/9ee6e90de5394042bdd082c...
...tree http://git.netsurf-browser.org/netsurf.git/tree/9ee6e90de5394042bdd082cc1...
The branch, master has been updated
via 9ee6e90de5394042bdd082cc1ddc7837387ad770 (commit)
from d03f0ee04e8b2fe800bf66082c7afbbb45de9d09 (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=9ee6e90de5394042bdd...
commit 9ee6e90de5394042bdd082cc1ddc7837387ad770
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
add header for memcpy prototype
diff --git a/frontends/framebuffer/convert_image.c b/frontends/framebuffer/convert_image.c
index daa0ed2..2608328 100644
--- a/frontends/framebuffer/convert_image.c
+++ b/frontends/framebuffer/convert_image.c
@@ -21,6 +21,7 @@
#include <stdio.h>
#include <png.h>
#include <stdlib.h>
+#include <string.h>
#if PNG_LIBPNG_VER < 10209
#define png_set_expand_gray_1_2_4_to_8(png) png_set_gray_1_2_4_to_8(png)
-----------------------------------------------------------------------
Summary of changes:
frontends/framebuffer/convert_image.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/frontends/framebuffer/convert_image.c b/frontends/framebuffer/convert_image.c
index daa0ed2..2608328 100644
--- a/frontends/framebuffer/convert_image.c
+++ b/frontends/framebuffer/convert_image.c
@@ -21,6 +21,7 @@
#include <stdio.h>
#include <png.h>
#include <stdlib.h>
+#include <string.h>
#if PNG_LIBPNG_VER < 10209
#define png_set_expand_gray_1_2_4_to_8(png) png_set_gray_1_2_4_to_8(png)
--
NetSurf Browser
7 years, 2 months