netsurf: branch vince/fltk created. release/3.10-122-g04900e8
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/04900e82e65f866967553...
...commit http://git.netsurf-browser.org/netsurf.git/commit/04900e82e65f8669675538a...
...tree http://git.netsurf-browser.org/netsurf.git/tree/04900e82e65f8669675538a66...
The branch, vince/fltk has been created
at 04900e82e65f8669675538a66a01b56a3e473cb2 (commit)
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=04900e82e65f8669675...
commit 04900e82e65f8669675538a66a01b56a3e473cb2
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
Initial minimal FLTK toolkit implementation
diff --git a/frontends/Makefile.hts b/frontends/Makefile.hts
index b5af240..a78e34c 100644
--- a/frontends/Makefile.hts
+++ b/frontends/Makefile.hts
@@ -114,7 +114,7 @@ else
endif
# valid values for the TARGET
-VLDTARGET := amiga atari beos framebuffer gtk monkey riscos windows
+VLDTARGET := amiga atari beos fltk framebuffer gtk monkey riscos windows
# Check for valid TARGET
ifeq ($(filter $(VLDTARGET),$(TARGET)),)
diff --git a/frontends/fltk/Makefile b/frontends/fltk/Makefile
new file mode 100644
index 0000000..1cfb278
--- /dev/null
+++ b/frontends/fltk/Makefile
@@ -0,0 +1,35 @@
+#
+# Makefile for NetSurf ftlk target
+#
+# This file is part of NetSurf
+#
+# ----------------------------------------------------------------------------
+# FLTK flag setup (using pkg-config)
+# ----------------------------------------------------------------------------
+
+CXXFLAGS += -DFLTK_RESPATH=\"$(NETSURF_FLTK_RES_PATH)\"
+
+# fltk does not ship a pkg-config file, instead it has its own program
+
+FLTKCONFIG = fltk-config
+CXXFLAGS += $(shell $(FLTKCONFIG) --cxxflags)
+LDFLAGS += -lstdc++ $(shell $(FLTKCONFIG) --ldstaticflags)
+
+# ---------------------------------------------------------------------------
+# Target setup
+# ---------------------------------------------------------------------------
+
+# The binary target.
+EXETARGET := nsfltk
+
+# ----------------------------------------------------------------------------
+# Source file setup
+# ----------------------------------------------------------------------------
+
+# S_FRONTEND are sources purely for the FLTK frontend
+S_FRONTEND := main.cpp misc.cpp window.cpp fetch.cpp bitmap.cpp layout.cpp plotters.cpp resources.cpp
+
+# This is the final source build list
+# Note this is deliberately *not* expanded here as common and image
+# are not yet available
+SOURCES = $(S_COMMON) $(S_IMAGE) $(S_BROWSER) $(S_RESOURCE) $(S_FRONTEND)
diff --git a/frontends/fltk/Makefile.defaults b/frontends/fltk/Makefile.defaults
new file mode 100644
index 0000000..ad70fb0
--- /dev/null
+++ b/frontends/fltk/Makefile.defaults
@@ -0,0 +1,28 @@
+# ----------------------------------------------------------------------------
+# FLTK-specific options
+# ----------------------------------------------------------------------------
+
+# Where to search for NetSurf's resources after looking in ~/.netsurf and
+# $NETSURFRES. It must have a trailing /
+NETSURF_FLTK_RES_PATH := $(PREFIX)/share/netsurf/:./frontends/fltk/res/
+
+# Where to install the netsurf binary
+NETSURF_FLTK_BIN := $(PREFIX)/bin/
+
+# Enable NetSurf's use of librsvg in conjunction with Cairo to display SVGs
+# Valid options: YES, NO, AUTO
+NETSURF_USE_RSVG := NO
+
+# Enable NetSurf's use of libsvgtiny for displaying SVGs
+# Valid options: YES, NO, AUTO
+NETSURF_USE_NSSVG := NO
+
+# Enable NetSurf's use of librosprite for displaying RISC OS Sprites
+# Valid options: YES, NO, AUTO
+NETSURF_USE_ROSPRITE := NO
+
+# Enable building the source object cache filesystem based backing store.
+NETSURF_FS_BACKING_STORE := NO
+
+# Optimisation levels
+CFLAGS += -O2
diff --git a/frontends/fltk/Makefile.tools b/frontends/fltk/Makefile.tools
new file mode 100644
index 0000000..460a957
--- /dev/null
+++ b/frontends/fltk/Makefile.tools
@@ -0,0 +1,8 @@
+# -*- mode: makefile-gmake -*-
+##
+## tool setup for the fltk target
+##
+
+# use native package config
+PKG_CONFIG := pkg-config
+
diff --git a/frontends/fltk/bitmap.cpp b/frontends/fltk/bitmap.cpp
new file mode 100644
index 0000000..bc41822
--- /dev/null
+++ b/frontends/fltk/bitmap.cpp
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2021 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
+ * Implementation of netsurf bitmap for fltk.
+ */
+
+#include <stddef.h>
+
+extern "C" {
+
+#include "utils/errors.h"
+#include "netsurf/bitmap.h"
+
+}
+
+#include "fltk/bitmap.h"
+
+/**
+ * Create a new bitmap.
+ *
+ * \param width width of image in pixels
+ * \param height width of image in pixels
+ * \param state The state to create the bitmap in.
+ * \return A bitmap structure or NULL on error.
+ */
+static void *nsfltk_bitmap_create(int width, int height, unsigned int state)
+{
+ return NULL;
+}
+
+/**
+ * Destroy a bitmap.
+ *
+ * \param bitmap The bitmap to destroy.
+ */
+static void nsfltk_bitmap_destroy(void *bitmap)
+{
+}
+
+/**
+ * Set the opacity of a bitmap.
+ *
+ * \param bitmap The bitmap to set opacity on.
+ * \param opaque The bitmap opacity to set.
+ */
+static void nsfltk_bitmap_set_opaque(void *bitmap, bool opaque)
+{
+}
+
+/**
+ * Get the opacity of a bitmap.
+ *
+ * \param bitmap The bitmap to examine.
+ * \return The bitmap opacity.
+ */
+static bool nsfltk_bitmap_get_opaque(void *bitmap)
+{
+ return false;
+}
+
+/**
+ * Test if a bitmap is opaque.
+ *
+ * \param bitmap The bitmap to examine.
+ * \return The bitmap opacity.
+ */
+static bool nsfltk_bitmap_test_opaque(void *bitmap)
+{
+ return false;
+}
+
+/**
+ * Get the image buffer from a bitmap
+ *
+ * \param bitmap The bitmap to get the buffer from.
+ * \return The image buffer or NULL if there is none.
+ */
+static unsigned char *nsfltk_bitmap_get_buffer(void *bitmap)
+{
+ return NULL;
+}
+
+/**
+ * Get the number of bytes per row of the image
+ *
+ * \param bitmap The bitmap
+ * \return The number of bytes for a row of the bitmap.
+ */
+static size_t nsfltk_bitmap_get_rowstride(void *bitmap)
+{
+ return 0;
+}
+
+/**
+ * Get the bitmap width
+ *
+ * \param bitmap The bitmap
+ * \return The bitmap width in pixels.
+ */
+static int nsfltk_bitmap_get_width(void *bitmap)
+{
+ return 0;
+}
+
+/**
+ * Get the bitmap height
+ *
+ * \param bitmap The bitmap
+ * \return The bitmap height in pixels.
+ */
+static int nsfltk_bitmap_get_height(void *bitmap)
+{
+ return 0;
+}
+
+/**
+ * Get the *bytes* per pixel.
+ *
+ * \param bitmap The bitmap
+ */
+static size_t nsfltk_bitmap_get_bpp(void *bitmap)
+{
+ return 4;
+}
+
+/**
+ * Save a bitmap to disc.
+ *
+ * \param bitmap The bitmap to save
+ * \param path The path to save the bitmap to.
+ * \param flags Flags affecting the save.
+ */
+static bool nsfltk_bitmap_save(void *bitmap, const char *path, unsigned flags)
+{
+ return false;
+}
+
+/**
+ * Marks a bitmap as modified.
+ *
+ * \param bitmap The bitmap set as modified.
+ */
+static void nsfltk_bitmap_modified(void *bitmap)
+{
+}
+
+/**
+ * Render content into a bitmap.
+ *
+ * \param bitmap The bitmap to render into.
+ * \param content The content to render.
+ */
+static nserror
+nsfltk_bitmap_render(struct bitmap *bitmap, struct hlcache_handle *content)
+{
+ return NSERROR_OK;
+}
+
+
+static struct gui_bitmap_table bitmap_table = {
+ .create = nsfltk_bitmap_create,
+ .destroy = nsfltk_bitmap_destroy,
+ .set_opaque = nsfltk_bitmap_set_opaque,
+ .get_opaque = nsfltk_bitmap_get_opaque,
+ .test_opaque = nsfltk_bitmap_test_opaque,
+ .get_buffer = nsfltk_bitmap_get_buffer,
+ .get_rowstride = nsfltk_bitmap_get_rowstride,
+ .get_width = nsfltk_bitmap_get_width,
+ .get_height = nsfltk_bitmap_get_height,
+ .get_bpp = nsfltk_bitmap_get_bpp,
+ .save = nsfltk_bitmap_save,
+ .modified = nsfltk_bitmap_modified,
+ .render = nsfltk_bitmap_render,
+};
+
+struct gui_bitmap_table *nsfltk_bitmap_table = &bitmap_table;
diff --git a/frontends/fltk/bitmap.h b/frontends/fltk/bitmap.h
new file mode 100644
index 0000000..e0f01a6
--- /dev/null
+++ b/frontends/fltk/bitmap.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2021 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 NETSURF_FLTK_BITMAP_H
+#define NETSURF_FLTK_BITMAP_H 1
+
+/**
+ * fltk bitmap operations table
+ */
+extern struct gui_bitmap_table *nsfltk_bitmap_table;
+
+#endif
diff --git a/frontends/fltk/fetch.cpp b/frontends/fltk/fetch.cpp
new file mode 100644
index 0000000..39c15a6
--- /dev/null
+++ b/frontends/fltk/fetch.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2021 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
+ * Implementation of netsurf fetch for fltk.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <limits.h>
+
+extern "C" {
+
+#include "utils/errors.h"
+#include "utils/log.h"
+#include "utils/filepath.h"
+#include "utils/file.h"
+#include "netsurf/fetch.h"
+
+}
+
+#include "fltk/fetch.h"
+#include "fltk/resources.h"
+
+/**
+ * Determine the MIME type of a local file.
+ *
+ * @note used in file fetcher
+ *
+ * \param unix_path Unix style path to file on disk
+ * \return Pointer to MIME type string (should not be freed) -
+ * invalidated on next call to fetch_filetype.
+ */
+static const char *nsfltk_fetch_filetype(const char *unix_path)
+{
+ int l;
+ char * res = (char*)"text/html";
+ l = strlen(unix_path);
+ NSLOG(netsurf, INFO, "unix path: %s", unix_path);
+
+
+ if (2 < l && strcasecmp(unix_path + l - 3, "f79") == 0)
+ res = (char*)"text/css";
+ else if (2 < l && strcasecmp(unix_path + l - 3, "css") == 0)
+ res = (char*)"text/css";
+ else if (2 < l && strcasecmp(unix_path + l - 3, "jpg") == 0)
+ res = (char*)"image/jpeg";
+ else if (3 < l && strcasecmp(unix_path + l - 4, "jpeg") == 0)
+ res = (char*)"image/jpeg";
+ else if (2 < l && strcasecmp(unix_path + l - 3, "gif") == 0)
+ res = (char*)"image/gif";
+ else if (2 < l && strcasecmp(unix_path + l - 3, "png") == 0)
+ res = (char*)"image/png";
+ else if (2 < l && strcasecmp(unix_path + l - 3, "jng") == 0)
+ res = (char*)"image/jng";
+ else if (2 < l && strcasecmp(unix_path + l - 3, "svg") == 0)
+ res = (char*)"image/svg";
+ else if (2 < l && strcasecmp(unix_path + l - 3, "txt") == 0)
+ res = (char*)"text/plain";
+
+ NSLOG(netsurf, INFO, "mime type: %s", res);
+ return res;
+}
+
+/**
+ * Translate resource path to full url.
+ *
+ * @note Only used in resource protocol fetcher
+ *
+ * Transforms a resource protocol path into a full URL. The returned URL
+ * is used as the target for a redirect. The caller takes ownership of
+ * the returned nsurl including unrefing it when finished with it.
+ *
+ * \param path The path of the resource to locate.
+ * \return A netsurf url object containing the full URL of the resource path
+ * or NULL if a suitable resource URL can not be generated.
+ */
+static nsurl *nsfltk_get_resource_url(const char *path)
+{
+ char buf[PATH_MAX];
+ nsurl *url = NULL;
+
+ netsurf_path_to_nsurl(filepath_sfind(respaths, buf, path), &url);
+
+ return url;
+}
+
+static struct gui_fetch_table fetch_table = {
+ .filetype = nsfltk_fetch_filetype,
+
+ .get_resource_url = nsfltk_get_resource_url,
+ .get_resource_data = NULL,
+ .release_resource_data = NULL,
+ .mimetype = NULL,
+};
+
+struct gui_fetch_table *nsfltk_fetch_table = &fetch_table;
diff --git a/frontends/fltk/fetch.h b/frontends/fltk/fetch.h
new file mode 100644
index 0000000..6f9913e
--- /dev/null
+++ b/frontends/fltk/fetch.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2021 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 NETSURF_FLTK_FETCH_H
+#define NETSURF_FLTK_FETCH_H 1
+
+/**
+ * fltk fetch operations table
+ */
+extern struct gui_fetch_table *nsfltk_fetch_table;
+
+#endif
diff --git a/frontends/fltk/layout.cpp b/frontends/fltk/layout.cpp
new file mode 100644
index 0000000..4504430
--- /dev/null
+++ b/frontends/fltk/layout.cpp
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2021 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
+ * Implementation of netsurf layout operations for fltk.
+ */
+
+#include <stddef.h>
+
+extern "C" {
+
+#include "utils/errors.h"
+#include "utils/utf8.h"
+#include "netsurf/layout.h"
+#include "netsurf/plot_style.h"
+
+}
+
+#include "fltk/layout.h"
+
+/**
+ * Measure the width of a string.
+ *
+ * \param[in] fstyle plot style for this text
+ * \param[in] string UTF-8 string to measure
+ * \param[in] length length of string, in bytes
+ * \param[out] width updated to width of string[0..length)
+ * \return NSERROR_OK and width updated or appropriate error
+ * code on faliure
+ */
+static nserror
+nsfltk_layout_width(const struct plot_font_style *fstyle,
+ const char *string,
+ size_t length,
+ int *width)
+{
+ *width = (fstyle->size * utf8_bounded_length(string, length)) / PLOT_STYLE_SCALE;
+ return NSERROR_OK;
+}
+
+
+/**
+ * Find the position in a string where an x coordinate falls.
+ *
+ * \param[in] fstyle style for this text
+ * \param[in] string UTF-8 string to measure
+ * \param[in] length length of string, in bytes
+ * \param[in] x coordinate to search for
+ * \param[out] char_offset updated to offset in string of actual_x, [0..length]
+ * \param[out] actual_x updated to x coordinate of character closest to x
+ * \return NSERROR_OK and char_offset and actual_x updated or appropriate error code on faliure
+ */
+static nserror
+nsfltk_layout_position(const struct plot_font_style *fstyle,
+ const char *string,
+ size_t length,
+ int x,
+ size_t *char_offset,
+ int *actual_x)
+{
+ *char_offset = x / (fstyle->size / PLOT_STYLE_SCALE);
+ if (*char_offset > length)
+ *char_offset = length;
+ *actual_x = *char_offset * (fstyle->size / PLOT_STYLE_SCALE);
+ return NSERROR_OK;
+}
+
+
+/**
+ * Find where to split a string to make it fit a width.
+ *
+ * \param[in] fstyle style for this text
+ * \param[in] string UTF-8 string to measure
+ * \param[in] length length of string, in bytes
+ * \param[in] x width available
+ * \param[out] char_offset updated to offset in string of actual_x, [1..length]
+ * \param[out] actual_x updated to x coordinate of character closest to x
+ * \return NSERROR_OK or appropriate error code on faliure
+ *
+ * On exit, char_offset indicates first character after split point.
+ *
+ * \note char_offset of 0 must never be returned.
+ *
+ * Returns:
+ * char_offset giving split point closest to x, where actual_x <= x
+ * else
+ * char_offset giving split point closest to x, where actual_x > x
+ *
+ * Returning char_offset == length means no split possible
+ */
+static nserror
+nsfltk_layout_split(const struct plot_font_style *fstyle,
+ const char *string,
+ size_t length,
+ int x,
+ size_t *char_offset,
+ int *actual_x)
+{
+ int c_off = *char_offset = x / (fstyle->size / PLOT_STYLE_SCALE);
+ if (*char_offset > length) {
+ *char_offset = length;
+ } else {
+ while (*char_offset > 0) {
+ if (string[*char_offset] == ' ')
+ break;
+ (*char_offset)--;
+ }
+ if (*char_offset == 0) {
+ *char_offset = c_off;
+ while (*char_offset < length && string[*char_offset] != ' ') {
+ (*char_offset)++;
+ }
+ }
+ }
+ *actual_x = *char_offset * (fstyle->size / PLOT_STYLE_SCALE);
+ return NSERROR_OK;
+}
+
+static struct gui_layout_table layout_table = {
+ .width = nsfltk_layout_width,
+ .position = nsfltk_layout_position,
+ .split = nsfltk_layout_split,
+};
+
+struct gui_layout_table *nsfltk_layout_table = &layout_table;
diff --git a/frontends/fltk/layout.h b/frontends/fltk/layout.h
new file mode 100644
index 0000000..5e19cc0
--- /dev/null
+++ b/frontends/fltk/layout.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2021 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 NETSURF_FLTK_LAYOUT_H
+#define NETSURF_FLTK_LAYOUT_H 1
+
+/**
+ * fltk layout operations table
+ */
+extern struct gui_layout_table *nsfltk_layout_table;
+
+#endif
diff --git a/frontends/fltk/main.cpp b/frontends/fltk/main.cpp
new file mode 100644
index 0000000..935bd2a
--- /dev/null
+++ b/frontends/fltk/main.cpp
@@ -0,0 +1,256 @@
+/*
+ * Copyright 2021 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/>.
+ */
+
+#include <assert.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <FL/Fl.H>
+
+extern "C" {
+
+#include "utils/utils.h"
+#include "utils/log.h"
+#include "utils/messages.h"
+#include "utils/nsoption.h"
+#include "utils/nsurl.h"
+
+#include "netsurf/netsurf.h"
+#include "netsurf/content.h"
+#include "netsurf/browser_window.h"
+
+}
+
+#include "fltk/misc.h"
+#include "fltk/window.h"
+#include "fltk/fetch.h"
+#include "fltk/bitmap.h"
+#include "fltk/layout.h"
+#include "fltk/resources.h"
+
+bool nsfltk_done = false;
+
+/**
+ * Set option defaults for fltk frontend
+ *
+ * @param defaults The option table to update.
+ * @return error status.
+ */
+static nserror set_option_defaults(struct nsoption_s *defaults)
+{
+ return NSERROR_OK;
+}
+
+
+/**
+ * Ensures output logging stream is correctly configured
+ */
+static bool nslog_stream_configure(FILE *fptr)
+{
+ /* set log stream to be non-buffering */
+ setbuf(fptr, NULL);
+
+ return true;
+}
+
+
+/**
+ * fltk frontend specific initialisation
+ */
+static nserror nsfltk_init(int *pargc, char** argv)
+{
+ nserror res;
+
+ /* Prep the resource search paths */
+ res = nsfltk_init_resource_path("${HOME}/.netsurf/:${NETSURFRES}:" FLTK_RESPATH);
+ if (res != NSERROR_OK) {
+ fprintf(stderr, "Resources failed to initialise (%s)\n",
+ messages_get_errorcode(res));
+ return res;
+ }
+
+ /* Initialise logging. Not fatal if it fails but not much we
+ * can do about it either.
+ */
+ nslog_init(nslog_stream_configure, pargc, argv);
+
+ /* override loaded options with those from commandline */
+ nsoption_commandline(pargc, argv, nsoptions);
+
+ /* Initialise user options */
+ res = nsoption_init(set_option_defaults, &nsoptions, &nsoptions_default);
+ if (res != NSERROR_OK) {
+ fprintf(stderr, "Options failed to initialise (%s)\n",
+ messages_get_errorcode(res));
+ return res;
+ }
+
+ return NSERROR_OK;
+}
+
+
+/**
+ * Start fltk browser.
+ *
+ * performs fltk specific startup including opening initial window if necessary
+ *
+ * \param argc The number of arguments on the command line
+ * \param argv A string vector of command line arguments.
+ */
+static nserror nsfltk_start(int argc, char** argv)
+{
+ char *addr = NULL;
+ nsurl *url;
+ nserror res;
+
+ /* If there is a url specified on the command line use it */
+ if (argc > 1) {
+ struct stat fs;
+ if (stat(argv[1], &fs) == 0) {
+ size_t addrlen;
+ char *rp = realpath(argv[1], NULL);
+ assert(rp != NULL);
+
+ /* calculate file url length including terminator */
+ addrlen = SLEN("file://") + strlen(rp) + 1;
+ addr = (char *)malloc(addrlen);
+ assert(addr != NULL);
+ snprintf(addr, addrlen, "file://%s", rp);
+ free(rp);
+ } else {
+ addr = strdup(argv[1]);
+ }
+ }
+ if (addr != NULL) {
+ /* managed to set up based on local launch */
+ } else if (nsoption_charp(homepage_url) != NULL) {
+ addr = strdup(nsoption_charp(homepage_url));
+ } else {
+ addr = strdup(NETSURF_HOMEPAGE);
+ }
+
+ /* create an initial browser window */
+ res = nsurl_create(addr, &url);
+ if (res == NSERROR_OK) {
+ res = browser_window_create(BW_CREATE_HISTORY,
+ url,
+ NULL,
+ NULL,
+ NULL);
+ nsurl_unref(url);
+ }
+
+ free(addr);
+
+ return res;
+}
+
+/**
+ * Run the fltk event loop.
+ *
+ */
+static void nsfltk_run(void)
+{
+ int schedtm;
+ do {
+ /* run scheduled callbacks and get the next event delta in ms */
+ schedtm = nsfltk_schedule_run();
+ if (schedtm > 0) {
+ NSLOG(netsurf, INFO, "scheduling for %d", schedtm);
+ }
+ Fl::wait(((double)schedtm/1000));
+ } while(nsfltk_done != true);
+}
+
+static nserror nsfltk_finalise(void)
+{
+ /* common finalisation */
+ netsurf_exit();
+
+ /* finalise options */
+ nsoption_finalise(nsoptions, nsoptions_default);
+
+ /* finalise logging */
+ nslog_finalise();
+
+ return NSERROR_OK;
+}
+
+/**
+ * Main entry point from OS.
+ */
+int main(int argc, char** argv)
+{
+ nserror res;
+ struct netsurf_table nsfltk_table = {
+ .misc = nsfltk_misc_table,
+ .window = nsfltk_window_table,
+ .download = NULL, /* no download functionality */
+ .clipboard = NULL, /* no clipboard functionality */
+ .fetch = nsfltk_fetch_table,
+ .file = NULL, /* use the posix default file operations */
+ .utf8 = NULL, /* use default utf-8 processing */
+ .search = NULL, /* use the default text search */
+ .search_web = NULL, /* use default web search */
+ .llcache = NULL, /* use default low level cache storage */
+ .bitmap = nsfltk_bitmap_table,
+ .layout = nsfltk_layout_table,
+ };
+
+ /* register operation tables */
+ res = netsurf_register(&nsfltk_table);
+ if (res != NSERROR_OK) {
+ fprintf(stderr,
+ "NetSurf operation table failed registration (%s)\n",
+ messages_get_errorcode(res));
+ return 1;
+ }
+
+ /* fltk specific initialisation */
+ res = nsfltk_init(&argc, argv);
+ if (res != NSERROR_OK) {
+ fprintf(stderr, "NetSurf fltk initialisation failed (%s)\n",
+ messages_get_errorcode(res));
+ return 2;
+ }
+
+ /* netsurf initialisation */
+ res = netsurf_init(NULL);
+ if (res != NSERROR_OK) {
+ fprintf(stderr, "NetSurf core failed to initialise (%s)\n",
+ messages_get_errorcode(res));
+ return 3;
+ }
+
+ /* fltk specific startup */
+ res = nsfltk_start(argc, argv);
+ if (res != NSERROR_OK) {
+ fprintf(stderr, "NetSurf fltk startup failed (%s)\n",
+ messages_get_errorcode(res));
+ nsfltk_finalise();
+ return 4;
+ }
+
+ /* startup suceeded so main run loop */
+ nsfltk_run();
+
+ /* finalise everything */
+ nsfltk_finalise();
+
+ return 0;
+
+}
diff --git a/frontends/fltk/misc.cpp b/frontends/fltk/misc.cpp
new file mode 100644
index 0000000..b86affd
--- /dev/null
+++ b/frontends/fltk/misc.cpp
@@ -0,0 +1,237 @@
+/*
+ * Copyright 2021 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
+ * Implementation of netsurf miscelaneous operations for fltk.
+ */
+
+#include <stddef.h>
+#include <time.h>
+#include <stdlib.h>
+
+extern "C" {
+
+#include "utils/errors.h"
+#include "utils/sys_time.h"
+#include "utils/log.h"
+#include "netsurf/misc.h"
+
+}
+
+#include "fltk/misc.h"
+
+/* linked list of scheduled callbacks */
+static struct nscallback *schedule_list = NULL;
+
+/**
+ * scheduled callback.
+ */
+struct nscallback
+{
+ struct nscallback *next;
+ struct timeval tv;
+ void (*callback)(void *p);
+ void *p;
+};
+
+/* exported function documented in fltk/misc.h */
+int nsfltk_schedule_run(void)
+{
+ struct timeval tv;
+ struct timeval nexttime;
+ struct timeval rettime;
+ struct nscallback *cur_nscb;
+ struct nscallback *prev_nscb;
+ struct nscallback *unlnk_nscb;
+
+ if (schedule_list == NULL)
+ return -1;
+
+ /* reset enumeration to the start of the list */
+ cur_nscb = schedule_list;
+ prev_nscb = NULL;
+ nexttime = cur_nscb->tv;
+
+ gettimeofday(&tv, NULL);
+
+ while (cur_nscb != NULL) {
+ if (timercmp(&tv, &cur_nscb->tv, >)) {
+ /* scheduled time */
+
+ /* remove callback */
+ unlnk_nscb = cur_nscb;
+
+ if (prev_nscb == NULL) {
+ schedule_list = unlnk_nscb->next;
+ } else {
+ prev_nscb->next = unlnk_nscb->next;
+ }
+
+ unlnk_nscb->callback(unlnk_nscb->p);
+
+ free(unlnk_nscb);
+
+ /* need to deal with callback modifying the list. */
+ if (schedule_list == NULL)
+ return -1; /* no more callbacks scheduled */
+
+ /* reset enumeration to the start of the list */
+ cur_nscb = schedule_list;
+ prev_nscb = NULL;
+ nexttime = cur_nscb->tv;
+ } else {
+ /* if the time to the event is sooner than the
+ * currently recorded soonest event record it
+ */
+ if (timercmp(&nexttime, &cur_nscb->tv, >)) {
+ nexttime = cur_nscb->tv;
+ }
+ /* move to next element */
+ prev_nscb = cur_nscb;
+ cur_nscb = prev_nscb->next;
+ }
+ }
+
+ /* make rettime relative to now */
+ timersub(&nexttime, &tv, &rettime);
+
+ NSLOG(schedule, DEBUG, "returning time to next event as %ldms",
+ (long)((rettime.tv_sec * 1000) + (rettime.tv_usec / 1000)));
+
+ /* return next event time in milliseconds (24days max wait) */
+ return (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000);
+}
+
+/**
+ * Unschedule a callback.
+ *
+ * \param callback callback function
+ * \param p user parameter, passed to callback function
+ * \return NSERROR_OK if callback found and removed else NSERROR_NOT_FOUND
+ *
+ * All scheduled callbacks matching both callback and p are removed.
+ */
+static nserror schedule_remove(void (*callback)(void *p), void *p)
+{
+ struct nscallback *cur_nscb;
+ struct nscallback *prev_nscb;
+ struct nscallback *unlnk_nscb;
+ bool removed = false;
+
+ /* check there is something on the list to remove */
+ if (schedule_list == NULL) {
+ return NSERROR_NOT_FOUND;
+ }
+
+ NSLOG(schedule, DEBUG, "removing %p, %p", callback, p);
+
+ cur_nscb = schedule_list;
+ prev_nscb = NULL;
+
+ while (cur_nscb != NULL) {
+ if ((cur_nscb->callback == callback) &&
+ (cur_nscb->p == p)) {
+ /* item to remove */
+
+ NSLOG(schedule, DEBUG, "callback entry %p removing %p(%p)",
+ cur_nscb, cur_nscb->callback, cur_nscb->p);
+
+ /* remove callback */
+ unlnk_nscb = cur_nscb;
+ cur_nscb = unlnk_nscb->next;
+
+ if (prev_nscb == NULL) {
+ schedule_list = cur_nscb;
+ } else {
+ prev_nscb->next = cur_nscb;
+ }
+ free (unlnk_nscb);
+ removed = true;
+ } else {
+ /* move to next element */
+ prev_nscb = cur_nscb;
+ cur_nscb = prev_nscb->next;
+ }
+ }
+
+ if (removed == false) {
+ return NSERROR_NOT_FOUND;
+ }
+ return NSERROR_OK;
+}
+
+
+/**
+ * Schedule a callback.
+ *
+ * \param tival interval before the callback should be made in ms or
+ * negative value to remove any existing callback.
+ * \param callback callback function
+ * \param p user parameter passed to callback function
+ * \return NSERROR_OK on sucess or appropriate error on faliure
+ *
+ * The callback function will be called as soon as possible
+ * after the timeout has elapsed.
+ *
+ * Additional calls with the same callback and user parameter will
+ * reset the callback time to the newly specified value.
+ *
+ */
+static nserror nsfltk_schedule(int tival, void (*callback)(void *p), void *p)
+{
+ struct nscallback *nscb;
+ struct timeval tv;
+ nserror ret;
+
+ /* ensure uniqueness of the callback and context */
+ ret = schedule_remove(callback, p);
+ if (tival < 0) {
+ return ret;
+ }
+
+ NSLOG(schedule, DEBUG, "Adding %p(%p) in %d", callback, p, tival);
+
+ tv.tv_sec = tival / 1000; /* miliseconds to seconds */
+ tv.tv_usec = (tival % 1000) * 1000; /* remainder to microseconds */
+
+ nscb = (struct nscallback*)calloc(1, sizeof(struct nscallback));
+
+ gettimeofday(&nscb->tv, NULL);
+ timeradd(&nscb->tv, &tv, &nscb->tv);
+
+ nscb->callback = callback;
+ nscb->p = p;
+
+ /* add to list front */
+ nscb->next = schedule_list;
+ schedule_list = nscb;
+
+ return NSERROR_OK;
+}
+
+static struct gui_misc_table misc_table = {
+ .schedule = nsfltk_schedule,
+ .quit = NULL,
+ .launch_url = NULL,
+ .login = NULL,
+ .pdf_password = NULL,
+ .present_cookies = NULL,
+};
+
+struct gui_misc_table *nsfltk_misc_table = &misc_table;
diff --git a/frontends/fltk/misc.h b/frontends/fltk/misc.h
new file mode 100644
index 0000000..e088043
--- /dev/null
+++ b/frontends/fltk/misc.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2021 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 NETSURF_FLTK_MISC_H
+#define NETSURF_FLTK_MISC_H 1
+
+/**
+ * fltk miscellaneous (scheduling) operations table
+ */
+extern struct gui_misc_table *nsfltk_misc_table;
+
+/**
+ * run and pending scheduling callbacks
+ *
+ * \return number of miliseconds before next scheduled event
+ */
+int nsfltk_schedule_run(void);
+
+#endif
diff --git a/frontends/fltk/plotters.cpp b/frontends/fltk/plotters.cpp
new file mode 100644
index 0000000..65268f1
--- /dev/null
+++ b/frontends/fltk/plotters.cpp
@@ -0,0 +1,300 @@
+/*
+ * Copyright 2021 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
+ * Implementation of plotters for fltk.
+ */
+
+#include <stddef.h>
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+
+extern "C" {
+
+#include "utils/errors.h"
+#include "netsurf/types.h"
+#include "netsurf/mouse.h"
+#include "netsurf/window.h"
+#include "netsurf/plotters.h"
+
+}
+
+#include "fltk/window.h"
+#include "fltk/plotters.h"
+
+
+static inline void nsfltk_set_colour(colour c)
+{
+ fl_color(fl_rgb_color((c & 0xff),
+ ((c & 0xff00) >> 8),
+ ((c & 0xff0000) >> 16)));
+}
+
+
+/**
+ * \brief Sets a clip rectangle for subsequent plot operations.
+ *
+ * \param ctx The current redraw context.
+ * \param clip The rectangle to limit all subsequent plot
+ * operations within.
+ * \return NSERROR_OK on success else error code.
+ */
+static nserror
+nsfltk_plot_clip(const struct redraw_context *ctx, const struct rect *clip)
+{
+ return NSERROR_OK;
+}
+
+
+/**
+ * Plots an arc
+ *
+ * plot an arc segment around (x,y), anticlockwise from angle1
+ * to angle2. Angles are measured anticlockwise from
+ * horizontal, in degrees.
+ *
+ * \param ctx The current redraw context.
+ * \param style Style controlling the arc plot.
+ * \param x The x coordinate of the arc.
+ * \param y The y coordinate of the arc.
+ * \param radius The radius of the arc.
+ * \param angle1 The start angle of the arc.
+ * \param angle2 The finish angle of the arc.
+ * \return NSERROR_OK on success else error code.
+ */
+static nserror
+nsfltk_plot_arc(const struct redraw_context *ctx,
+ const plot_style_t *style,
+ int x, int y, int radius, int angle1, int angle2)
+{
+ return NSERROR_OK;
+}
+
+
+/**
+ * Plots a circle
+ *
+ * Plot a circle centered on (x,y), which is optionally filled.
+ *
+ * \param ctx The current redraw context.
+ * \param style Style controlling the circle plot.
+ * \param x x coordinate of circle centre.
+ * \param y y coordinate of circle centre.
+ * \param radius circle radius.
+ * \return NSERROR_OK on success else error code.
+ */
+static nserror
+nsfltk_plot_disc(const struct redraw_context *ctx,
+ const plot_style_t *style,
+ int x, int y, int radius)
+{
+ return NSERROR_OK;
+}
+
+
+/**
+ * Plots a line
+ *
+ * plot a line from (x0,y0) to (x1,y1). Coordinates are at
+ * centre of line width/thickness.
+ *
+ * \param ctx The current redraw context.
+ * \param style Style controlling the line plot.
+ * \param line A rectangle defining the line to be drawn
+ * \return NSERROR_OK on success else error code.
+ */
+static nserror
+nsfltk_plot_line(const struct redraw_context *ctx,
+ const plot_style_t *style,
+ const struct rect *line)
+{
+ if (style->stroke_type != PLOT_OP_TYPE_NONE) {
+ nsfltk_set_colour(style->stroke_colour);
+ fl_line(line->x0, line->y0, line->x1, line->y1);
+ }
+ return NSERROR_OK;
+}
+
+
+/**
+ * Plots a rectangle.
+ *
+ * The rectangle can be filled an outline or both controlled
+ * by the plot style The line can be solid, dotted or
+ * dashed. Top left corner at (x0,y0) and rectangle has given
+ * width and height.
+ *
+ * \param ctx The current redraw context.
+ * \param style Style controlling the rectangle plot.
+ * \param rect A rectangle defining the line to be drawn
+ * \return NSERROR_OK on success else error code.
+ */
+static nserror
+nsfltk_plot_rectangle(const struct redraw_context *ctx,
+ const plot_style_t *style,
+ const struct rect *rect)
+{
+ if (style->fill_type != PLOT_OP_TYPE_NONE) {
+ nsfltk_set_colour(style->fill_colour);
+ fl_rectf(rect->x0,
+ rect->y0,
+ rect->x1 - rect->x0,
+ rect->y1 - rect->y0);
+ }
+
+ if (style->stroke_type != PLOT_OP_TYPE_NONE) {
+ nsfltk_set_colour(style->stroke_colour);
+ fl_rect(rect->x0,
+ rect->y0,
+ rect->x1 - rect->x0,
+ rect->y1 - rect->y0);
+ }
+
+ return NSERROR_OK;
+}
+
+
+/**
+ * Plot a polygon
+ *
+ * Plots a filled polygon with straight lines between
+ * points. The lines around the edge of the ploygon are not
+ * plotted. The polygon is filled with the non-zero winding
+ * rule.
+ *
+ * \param ctx The current redraw context.
+ * \param style Style controlling the polygon plot.
+ * \param p verticies of polygon
+ * \param n number of verticies.
+ * \return NSERROR_OK on success else error code.
+ */
+static nserror
+nsfltk_plot_polygon(const struct redraw_context *ctx,
+ const plot_style_t *style,
+ const int *p,
+ unsigned int n)
+{
+ return NSERROR_OK;
+}
+
+
+/**
+ * Plots a path.
+ *
+ * Path plot consisting of cubic Bezier curves. Line and fill colour is
+ * controlled by the plot style.
+ *
+ * \param ctx The current redraw context.
+ * \param pstyle Style controlling the path plot.
+ * \param p elements of path
+ * \param n nunber of elements on path
+ * \param transform A transform to apply to the path.
+ * \return NSERROR_OK on success else error code.
+ */
+static nserror
+nsfltk_plot_path(const struct redraw_context *ctx,
+ const plot_style_t *pstyle,
+ const float *p,
+ unsigned int n,
+ const float transform[6])
+{
+ return NSERROR_OK;
+}
+
+
+/**
+ * Plot a bitmap
+ *
+ * Tiled plot of a bitmap image. (x,y) gives the top left
+ * coordinate of an explicitly placed tile. From this tile the
+ * image can repeat in all four directions -- up, down, left
+ * and right -- to the extents given by the current clip
+ * rectangle.
+ *
+ * The bitmap_flags say whether to tile in the x and y
+ * directions. If not tiling in x or y directions, the single
+ * image is plotted. The width and height give the dimensions
+ * the image is to be scaled to.
+ *
+ * \param ctx The current redraw context.
+ * \param bitmap The bitmap to plot
+ * \param x The x coordinate to plot the bitmap
+ * \param y The y coordiante to plot the bitmap
+ * \param width The width of area to plot the bitmap into
+ * \param height The height of area to plot the bitmap into
+ * \param bg the background colour to alpha blend into
+ * \param flags the flags controlling the type of plot operation
+ * \return NSERROR_OK on success else error code.
+ */
+static nserror
+nsfltk_plot_bitmap(const struct redraw_context *ctx,
+ struct bitmap *bitmap,
+ int x, int y,
+ int width,
+ int height,
+ colour bg,
+ bitmap_flags_t flags)
+{
+ return NSERROR_OK;
+}
+
+
+/**
+ * Text plotting.
+ *
+ * \param ctx The current redraw context.
+ * \param fstyle plot style for this text
+ * \param x x coordinate
+ * \param y y coordinate
+ * \param text UTF-8 string to plot
+ * \param length length of string, in bytes
+ * \return NSERROR_OK on success else error code.
+ */
+static nserror
+nsfltk_plot_text(const struct redraw_context *ctx,
+ const struct plot_font_style *fstyle,
+ int x,
+ int y,
+ const char *text,
+ size_t length)
+{
+ nsfltk_set_colour(fstyle->foreground);
+ fl_draw(text,length,x,y);
+ return NSERROR_OK;
+}
+
+
+/**
+ * FLTK plotter table
+ */
+const struct plotter_table nsfltk_plotters = {
+ .clip = nsfltk_plot_clip,
+ .arc = nsfltk_plot_arc,
+ .disc = nsfltk_plot_disc,
+ .line = nsfltk_plot_line,
+ .rectangle = nsfltk_plot_rectangle,
+ .polygon = nsfltk_plot_polygon,
+ .path = nsfltk_plot_path,
+ .bitmap = nsfltk_plot_bitmap,
+ .text = nsfltk_plot_text,
+ .group_start = NULL,
+ .group_end = NULL,
+ .flush = NULL,
+ .option_knockout = true
+};
diff --git a/frontends/fltk/plotters.h b/frontends/fltk/plotters.h
new file mode 100644
index 0000000..f0c8df9
--- /dev/null
+++ b/frontends/fltk/plotters.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2021 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
+ * Target independent plotting FLGTK+ interface.
+ */
+
+#ifndef NETSURF_FLTK_PLOTTERS_H
+#define NETSURF_FLTK_PLOTTERS_H 1
+
+struct plotter_table;
+
+extern const struct plotter_table nsfltk_plotters;
+
+#endif /* NETSURF_FLTK_PLOTTERS_H */
+
diff --git a/frontends/fltk/res/adblock.css b/frontends/fltk/res/adblock.css
new file mode 120000
index 0000000..0d12aaa
--- /dev/null
+++ b/frontends/fltk/res/adblock.css
@@ -0,0 +1 @@
+../../../resources/adblock.css
\ No newline at end of file
diff --git a/frontends/fltk/res/default.css b/frontends/fltk/res/default.css
new file mode 120000
index 0000000..fa3ae6c
--- /dev/null
+++ b/frontends/fltk/res/default.css
@@ -0,0 +1 @@
+../../../resources/default.css
\ No newline at end of file
diff --git a/frontends/fltk/res/en/credits.html b/frontends/fltk/res/en/credits.html
new file mode 120000
index 0000000..f73ecd4
--- /dev/null
+++ b/frontends/fltk/res/en/credits.html
@@ -0,0 +1 @@
+../../../../resources/en/credits.html
\ No newline at end of file
diff --git a/frontends/fltk/res/en/licence.html b/frontends/fltk/res/en/licence.html
new file mode 120000
index 0000000..0c3b430
--- /dev/null
+++ b/frontends/fltk/res/en/licence.html
@@ -0,0 +1 @@
+../../../../resources/en/licence.html
\ No newline at end of file
diff --git a/frontends/fltk/res/en/welcome.html b/frontends/fltk/res/en/welcome.html
new file mode 120000
index 0000000..543f31d
--- /dev/null
+++ b/frontends/fltk/res/en/welcome.html
@@ -0,0 +1 @@
+../../../../resources/en/welcome.html
\ No newline at end of file
diff --git a/frontends/fltk/res/internal.css b/frontends/fltk/res/internal.css
new file mode 120000
index 0000000..5583a98
--- /dev/null
+++ b/frontends/fltk/res/internal.css
@@ -0,0 +1 @@
+../../../resources/internal.css
\ No newline at end of file
diff --git a/frontends/fltk/res/netsurf.png b/frontends/fltk/res/netsurf.png
new file mode 120000
index 0000000..d0ab72a
--- /dev/null
+++ b/frontends/fltk/res/netsurf.png
@@ -0,0 +1 @@
+../../../resources/netsurf.png
\ No newline at end of file
diff --git a/frontends/fltk/res/quirks.css b/frontends/fltk/res/quirks.css
new file mode 120000
index 0000000..1e752cb
--- /dev/null
+++ b/frontends/fltk/res/quirks.css
@@ -0,0 +1 @@
+../../../resources/quirks.css
\ No newline at end of file
diff --git a/frontends/fltk/resources.cpp b/frontends/fltk/resources.cpp
new file mode 100644
index 0000000..78925eb
--- /dev/null
+++ b/frontends/fltk/resources.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2021 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/>.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+extern "C" {
+
+#include "utils/errors.h"
+#include "utils/filepath.h"
+
+}
+
+#include "fltk/resources.h"
+
+/** resource search path vector */
+char **respaths;
+
+/** maximum number of languages in language vector */
+#define LANGV_SIZE 32
+/** maximum length of all strings in language vector */
+#define LANGS_SIZE 4096
+
+/**
+ * obtain language from environment
+ *
+ * start with GNU extension LANGUAGE environment variable and then try
+ * POSIX variables LC_ALL, LC_MESSAGES and LANG
+ *
+ */
+static const char *get_language(void)
+{
+ const char *lang;
+
+ lang = getenv("LANGUAGE");
+ if ((lang != NULL) && (lang[0] != '\0')) {
+ return lang;
+ }
+
+ lang = getenv("LC_ALL");
+ if ((lang != NULL) && (lang[0] != '\0')) {
+ return lang;
+ }
+
+ lang = getenv("LC_MESSAGES");
+ if ((lang != NULL) && (lang[0] != '\0')) {
+ return lang;
+ }
+
+ lang = getenv("LANG");
+ if ((lang != NULL) && (lang[0] != '\0')) {
+ return lang;
+ }
+
+ return NULL;
+}
+
+
+/** provide a string vector of languages in preference order
+ *
+ * environment variables are processed to aquire a colon separated
+ * list of languages which are converted into a string vector. The
+ * vector will always have the C language as its last entry.
+ *
+ * This implementation creates an internal static representation of
+ * the vector when first called and returns that for all subsequent
+ * calls. i.e. changing the environment does not change the returned
+ * vector on repeated calls.
+ *
+ * If the environment variables have more than LANGV_SIZE languages or
+ * LANGS_SIZE bytes of data the results list will be curtailed.
+ */
+static const char * const *get_languagev(void)
+{
+ static const char *langv[LANGV_SIZE];
+ int langidx = 0; /* index of next entry in vector */
+ static char langs[LANGS_SIZE];
+ char *curp; /* next language parameter in langs string */
+ const char *lange; /* language from environment variable */
+ int lang_len;
+ char *cln; /* colon in lange */
+
+ /* return cached vector */
+ if (langv[0] != NULL) {
+ return &langv[0];
+ }
+
+ curp = &langs[0];
+
+ lange = get_language();
+
+ if (lange != NULL) {
+ lang_len = strlen(lange) + 1;
+ if (lang_len < (LANGS_SIZE - 2)) {
+ memcpy(curp, lange, lang_len);
+ while ((curp[0] != 0) &&
+ (langidx < (LANGV_SIZE - 2))) {
+ /* avoid using strchrnul as it is not portable */
+ cln = strchr(curp, ':');
+ if (cln == NULL) {
+ langv[langidx++] = curp;
+ curp += lang_len;
+ break;
+ } else {
+ if ((cln - curp) > 1) {
+ /* only place non empty entries in vector */
+ langv[langidx++] = curp;
+ }
+ *cln++ = 0; /* null terminate */
+ lang_len -= (cln - curp);
+ curp = cln;
+ }
+ }
+ }
+ }
+
+ /* ensure C language is present */
+ langv[langidx++] = curp;
+ *curp++ = 'C';
+ *curp++ = 0;
+ langv[langidx] = NULL;
+
+ return &langv[0];
+}
+
+
+/* exported interface documented in fltk/resources.h */
+nserror nsfltk_init_resource_path(const char *resource_path)
+{
+ const char * const *langv;
+ char **pathv; /* resource path string vector */
+
+ pathv = filepath_path_to_strvec(resource_path);
+
+ langv = get_languagev();
+
+ respaths = filepath_generate(pathv, langv);
+
+ filepath_free_strvec(pathv);
+
+ return NSERROR_OK;
+}
diff --git a/frontends/fltk/resources.h b/frontends/fltk/resources.h
new file mode 100644
index 0000000..849179b
--- /dev/null
+++ b/frontends/fltk/resources.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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 NETSURF_FLTK_RESOURCES_H
+#define NETSURF_FLTK_RESOURCES_H 1
+
+/**
+ * resource search path vector
+ */
+extern char **respaths;
+
+/**
+ * Create an array of valid paths to search for resources.
+ *
+ * The idea is that all the complex path computation to find resources
+ * is performed here, once, rather than every time a resource is
+ * searched for.
+ *
+ * \param resource_path A shell style colon separated path list
+
+ * \return NSERROR_OK on success and the respaths set to a string
+ * vector of valid paths where resources can be found or appropriate
+ * error code on faliure.
+ */
+nserror nsfltk_init_resource_path(const char *resource_path);
+
+#endif
diff --git a/frontends/fltk/window.cpp b/frontends/fltk/window.cpp
new file mode 100644
index 0000000..19aa265
--- /dev/null
+++ b/frontends/fltk/window.cpp
@@ -0,0 +1,344 @@
+/*
+ * Copyright 2021 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
+ * Implementation of netsurf window (widget) for fltk.
+ */
+
+#include <stddef.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Double_Window.H>
+#include <FL/fl_draw.H>
+
+extern "C" {
+
+#include "utils/errors.h"
+#include "netsurf/types.h"
+#include "netsurf/mouse.h"
+#include "netsurf/window.h"
+#include "netsurf/plotters.h"
+#include "netsurf/content.h"
+#include "netsurf/browser_window.h"
+#include "netsurf/mouse.h"
+
+}
+
+#include "fltk/window.h"
+#include "fltk/plotters.h"
+
+extern bool nsfltk_done;
+
+class NS_Widget : public Fl_Widget
+{
+private:
+ struct browser_window *mbw;
+
+protected:
+ void draw();
+ int handle(int event);
+
+public:
+ NS_Widget(int X,int Y,int W,int H, struct browser_window *bw)
+ : Fl_Widget(X,Y,W,H), mbw(bw) {}
+};
+
+
+class NS_Window : public Fl_Double_Window
+{
+private:
+ struct browser_window *mbw;
+ NS_Widget *mnswidget;
+
+ void close_callback(Fl_Widget *w);
+ static void static_close_callback(Fl_Widget *w, void *f) { ((NS_Window *)f)->close_callback(w); }
+
+public:
+ NS_Window(int W, int H, struct browser_window *bw)
+ : Fl_Double_Window(W,H), mbw(bw) {
+ this->callback(static_close_callback, (void *)this);
+ mnswidget = new NS_Widget(0, 0, W, H, bw);
+ this->end();
+ }
+ ~NS_Window() { nsfltk_done=true; }
+
+ NS_Widget *get_nswidget() { return mnswidget; }
+};
+
+struct gui_window {
+ struct browser_window *bw;
+ NS_Window *window;
+};
+
+/**
+ * method to handle events on the netsurf browsing widget
+ */
+int NS_Widget::handle(int event)
+{
+ int state = BROWSER_MOUSE_HOVER;
+ int button;
+
+ switch (event) {
+ case FL_PUSH:
+ button = Fl::event_button();
+ if (button == FL_LEFT_MOUSE) {
+ state |= BROWSER_MOUSE_PRESS_1;
+ }
+ browser_window_mouse_click(mbw,
+ (browser_mouse_state)state,
+ Fl::event_x() - x(),
+ Fl::event_y() - y());
+ return 1;
+
+ case FL_RELEASE:
+ button = Fl::event_button();
+ if (button == FL_LEFT_MOUSE) {
+ state |= BROWSER_MOUSE_CLICK_1;
+
+ }
+ browser_window_mouse_click(mbw,
+ (browser_mouse_state)state,
+ Fl::event_x() - x(),
+ Fl::event_y() - y());
+
+ return 1;
+ default:
+ return Fl_Widget::handle(event);
+ }
+}
+
+
+/**
+ * method to redraw the netsurf browsing widget
+ */
+void NS_Widget::draw()
+{
+ struct rect clip;
+ fl_clip_box(x(), y(), w(), h(), clip.x0, clip.y0, clip.x1, clip.y1);
+ /* clip box generates width/height so convert to absolute */
+ clip.x1 += clip.x0;
+ clip.y1 += clip.y0;
+ struct redraw_context ctx = {
+ .interactive = true,
+ .background_images = true,
+ .plot = &nsfltk_plotters,
+ .priv = NULL,
+ };
+
+ browser_window_redraw(mbw, x(), y(), &clip, &ctx);
+
+}
+
+/**
+ * callback when fltk window is closed
+ */
+void NS_Window::close_callback(Fl_Widget *w)
+{
+ browser_window_destroy(mbw);
+}
+
+/**
+ * Create and open a gui window for a browsing context.
+ *
+ * The implementing front end must create a context suitable
+ * for it to display a window referred to as the "gui window".
+ *
+ * The frontend will be expected to request the core redraw
+ * areas of the gui window which have become invalidated
+ * either from toolkit expose events or as a result of a
+ * invalidate() call.
+ *
+ * Most core operations used by the frontend concerning browser
+ * windows require passing the browser window context therefor
+ * the gui window must include a reference to the browser
+ * window passed here.
+ *
+ * If GW_CREATE_CLONE flag is set existing is non-NULL.
+ *
+ * \param bw The core browsing context associated with the gui window
+ * \param existing An existing gui_window, may be NULL.
+ * \param flags flags to control the gui window creation.
+ * \return gui window, or NULL on error.
+ */
+static struct gui_window *
+nsfltk_window_create(struct browser_window *bw,
+ struct gui_window *existing,
+ gui_window_create_flags flags)
+{
+ struct gui_window *gw;
+ gw = (struct gui_window *)calloc(1, sizeof(struct gui_window));
+
+ gw->window = new NS_Window(800,600, bw);
+
+ gw->window->show();
+
+ return gw;
+}
+
+/**
+ * Destroy previously created gui window
+ *
+ * \param gw The gui window to destroy.
+ */
+static void nsfltk_window_destroy(struct gui_window *gw)
+{
+ Fl::delete_widget(gw->window);
+ free(gw);
+}
+
+
+/**
+ * Invalidate an area of a window.
+ *
+ * The specified area of the window should now be considered
+ * out of date. If the area is NULL the entire window must be
+ * invalidated. It is expected that the windowing system will
+ * then subsequently cause redraw/expose operations as
+ * necessary.
+ *
+ * \note the frontend should not attempt to actually start the
+ * redraw operations as a result of this callback because the
+ * core redraw functions may already be threaded.
+ *
+ * \param gw The gui window to invalidate.
+ * \param rect area to redraw or NULL for the entire window area
+ * \return NSERROR_OK on success or appropriate error code
+ */
+static nserror
+nsfltk_window_invalidate(struct gui_window *gw, const struct rect *rect)
+{
+ NS_Widget *nswidget;
+ nswidget = gw->window->get_nswidget();
+
+ if (rect == NULL) {
+ nswidget->damage(FL_DAMAGE_ALL);
+ } else {
+ nswidget->damage(FL_DAMAGE_ALL,
+ rect->x0,
+ rect->y0,
+ rect->x1 - rect->x0,
+ rect->y1 - rect->y0);
+ }
+ return NSERROR_OK;
+}
+
+
+/**
+ * Get the scroll position of a browser window.
+ *
+ * \param gw The gui window to obtain the scroll position from.
+ * \param sx receives x ordinate of point at top-left of window
+ * \param sy receives y ordinate of point at top-left of window
+ * \return true iff successful
+ */
+static bool nsfltk_window_get_scroll(struct gui_window *gw, int *sx, int *sy)
+{
+ return false;
+}
+
+
+/**
+ * Set the scroll position of a browser window.
+ *
+ * scrolls the viewport to ensure the specified rectangle of
+ * the content is shown.
+ * If the rectangle is of zero size i.e. x0 == x1 and y0 == y1
+ * the contents will be scrolled so the specified point in the
+ * content is at the top of the viewport.
+ * If the size of the rectangle is non zero the frontend may
+ * add padding or centre the defined area or it may simply
+ * align as in the zero size rectangle
+ *
+ * \param gw The gui window to scroll.
+ * \param rect The rectangle to ensure is shown.
+ * \return NSERROR_OK on success or appropriate error code.
+ */
+static nserror
+nsfltk_window_set_scroll(struct gui_window *gw, const struct rect *rect)
+{
+ return NSERROR_OK;
+}
+
+
+/**
+ * Find the current dimensions of a browser window's content area.
+ *
+ * This is used to determine the actual available drawing size
+ * in pixels. This allows contents that can be dynamically
+ * reformatted, such as HTML, to better use the available
+ * space.
+ *
+ * \param gw The gui window to measure content area of.
+ * \param width receives width of window
+ * \param height receives height of window
+ * \return NSERROR_OK on success and width and height updated
+ * else error code.
+ */
+static nserror
+nsfltk_window_get_dimensions(struct gui_window *gw, int *width, int *height)
+{
+ NS_Widget *nswidget;
+ nswidget = gw->window->get_nswidget();
+
+ *width = nswidget->w();
+ *height = nswidget->h();
+
+ return NSERROR_OK;
+}
+
+
+/**
+ * Miscellaneous event occurred for a window
+ *
+ * This is used to inform the frontend of window events which
+ * require no additional parameters.
+ *
+ * \param gw The gui window the event occurred for
+ * \param event Which event has occurred.
+ * \return NSERROR_OK if the event was processed else error code.
+ */
+static nserror
+nsfltk_window_event(struct gui_window *gw, enum gui_window_event event)
+{
+ return NSERROR_OK;
+}
+
+static struct gui_window_table window_table = {
+ .create = nsfltk_window_create,
+ .destroy = nsfltk_window_destroy,
+ .invalidate = nsfltk_window_invalidate,
+ .get_scroll = nsfltk_window_get_scroll,
+ .set_scroll = nsfltk_window_set_scroll,
+ .get_dimensions = nsfltk_window_get_dimensions,
+ .event = nsfltk_window_event,
+ .set_title = NULL,
+ .set_url = NULL,
+ .set_icon = NULL,
+ .set_status = NULL,
+ .set_pointer = NULL,
+ .place_caret = NULL,
+ .drag_start = NULL,
+ .save_link = NULL,
+ .create_form_select_menu = NULL,
+ .file_gadget_open = NULL,
+ .drag_save_object = NULL,
+ .drag_save_selection = NULL,
+ .console_log = NULL,
+};
+
+struct gui_window_table *nsfltk_window_table = &window_table;
diff --git a/frontends/fltk/window.h b/frontends/fltk/window.h
new file mode 100644
index 0000000..c339418
--- /dev/null
+++ b/frontends/fltk/window.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2021 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 NETSURF_FLTK_WINDOW_H
+#define NETSURF_FLTK_WINDOW_H 1
+
+/**
+ * fltk window (browser widget) operations table
+ */
+extern struct gui_window_table *nsfltk_window_table;
+
+#endif
-----------------------------------------------------------------------
--
NetSurf Browser
2 years, 6 months
netsurf: branch master updated. release/3.10-121-g5e31f04
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/5e31f045a03753e2d65c3...
...commit http://git.netsurf-browser.org/netsurf.git/commit/5e31f045a03753e2d65c3d6...
...tree http://git.netsurf-browser.org/netsurf.git/tree/5e31f045a03753e2d65c3d65e...
The branch, master has been updated
via 5e31f045a03753e2d65c3d65ef27d10919648eff (commit)
from e9f29a1002046992b347b9c1adfe07677d12e6fb (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=5e31f045a03753e2d65...
commit 5e31f045a03753e2d65c3d65ef27d10919648eff
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
Improve some documentation comments
diff --git a/frontends/monkey/main.c b/frontends/monkey/main.c
index bae8150..463f0be 100644
--- a/frontends/monkey/main.c
+++ b/frontends/monkey/main.c
@@ -73,7 +73,8 @@ static void die(const char * const error)
exit(EXIT_FAILURE);
}
-/** obtain language from environment
+/**
+ * obtain language from environment
*
* start with GNU extension LANGUAGE environment variable and then try
* POSIX variables LC_ALL, LC_MESSAGES and LANG
@@ -107,7 +108,8 @@ static const char *get_language(void)
}
-/** provide a string vector of languages in preference order
+/**
+ * provide a string vector of languages in preference order
*
* environment variables are processed to aquire a colon separated
* list of languages which are converted into a string vector. The
@@ -174,7 +176,16 @@ static const char * const *get_languagev(void)
return &langv[0];
}
-/* Stolen from gtk/gui.c */
+/**
+ * Create an array of valid paths to search for resources.
+ *
+ * The idea is that all the complex path computation to find resources
+ * is performed here, once, rather than every time a resource is
+ * searched for.
+ *
+ * \param resource_path A shell style colon separated path list
+ * \return A string vector of valid paths where resources can be found
+ */
static char **
nsmonkey_init_resource(const char *resource_path)
{
diff --git a/include/netsurf/fetch.h b/include/netsurf/fetch.h
index 6e6d653..30b2048 100644
--- a/include/netsurf/fetch.h
+++ b/include/netsurf/fetch.h
@@ -49,15 +49,15 @@ struct gui_fetch_table {
/**
* Translate resource to full url.
*
- * @note Only used in resource fetcher
+ * @note Only used in resource protocol fetcher
*
- * Transforms a resource: path into a full URL. The returned URL
+ * Transforms a resource protocol path into a full URL. The returned URL
* is used as the target for a redirect. The caller takes ownership of
* the returned nsurl including unrefing it when finished with it.
*
* \param path The path of the resource to locate.
- * \return A string containing the full URL of the target object or
- * NULL if no suitable resource can be found.
+ * \return A netsurf url object containing the full URL of the resource
+ * path or NULL if a suitable resource URL can not be generated.
*/
struct nsurl* (*get_resource_url)(const char *path);
-----------------------------------------------------------------------
Summary of changes:
frontends/monkey/main.c | 17 ++++++++++++++---
include/netsurf/fetch.h | 8 ++++----
2 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/frontends/monkey/main.c b/frontends/monkey/main.c
index bae8150..463f0be 100644
--- a/frontends/monkey/main.c
+++ b/frontends/monkey/main.c
@@ -73,7 +73,8 @@ static void die(const char * const error)
exit(EXIT_FAILURE);
}
-/** obtain language from environment
+/**
+ * obtain language from environment
*
* start with GNU extension LANGUAGE environment variable and then try
* POSIX variables LC_ALL, LC_MESSAGES and LANG
@@ -107,7 +108,8 @@ static const char *get_language(void)
}
-/** provide a string vector of languages in preference order
+/**
+ * provide a string vector of languages in preference order
*
* environment variables are processed to aquire a colon separated
* list of languages which are converted into a string vector. The
@@ -174,7 +176,16 @@ static const char * const *get_languagev(void)
return &langv[0];
}
-/* Stolen from gtk/gui.c */
+/**
+ * Create an array of valid paths to search for resources.
+ *
+ * The idea is that all the complex path computation to find resources
+ * is performed here, once, rather than every time a resource is
+ * searched for.
+ *
+ * \param resource_path A shell style colon separated path list
+ * \return A string vector of valid paths where resources can be found
+ */
static char **
nsmonkey_init_resource(const char *resource_path)
{
diff --git a/include/netsurf/fetch.h b/include/netsurf/fetch.h
index 6e6d653..30b2048 100644
--- a/include/netsurf/fetch.h
+++ b/include/netsurf/fetch.h
@@ -49,15 +49,15 @@ struct gui_fetch_table {
/**
* Translate resource to full url.
*
- * @note Only used in resource fetcher
+ * @note Only used in resource protocol fetcher
*
- * Transforms a resource: path into a full URL. The returned URL
+ * Transforms a resource protocol path into a full URL. The returned URL
* is used as the target for a redirect. The caller takes ownership of
* the returned nsurl including unrefing it when finished with it.
*
* \param path The path of the resource to locate.
- * \return A string containing the full URL of the target object or
- * NULL if no suitable resource can be found.
+ * \return A netsurf url object containing the full URL of the resource
+ * path or NULL if a suitable resource URL can not be generated.
*/
struct nsurl* (*get_resource_url)(const char *path);
--
NetSurf Browser
2 years, 6 months
netsurf: branch master updated. release/3.10-120-ge9f29a1
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/e9f29a1002046992b347b...
...commit http://git.netsurf-browser.org/netsurf.git/commit/e9f29a1002046992b347b9c...
...tree http://git.netsurf-browser.org/netsurf.git/tree/e9f29a1002046992b347b9c1a...
The branch, master has been updated
via e9f29a1002046992b347b9c1adfe07677d12e6fb (commit)
from 937446b95beb40f9f641ee27bffbeb24509cbc73 (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=e9f29a1002046992b34...
commit e9f29a1002046992b347b9c1adfe07677d12e6fb
Author: Rob Kendrick <rjek(a)netsurf-browser.org>
Commit: Rob Kendrick <rjek(a)netsurf-browser.org>
Correct indentation for previous change
diff --git a/frontends/riscos/filetype.c b/frontends/riscos/filetype.c
index d752141..b0dc949 100644
--- a/frontends/riscos/filetype.c
+++ b/frontends/riscos/filetype.c
@@ -39,7 +39,7 @@ static const struct type_entry type_map[] = {
{0x188, "application/x-shockwave-flash"},
{0x695, "image/gif"},
{0x69c, "image/x-ms-bmp"},
- {0xa66, "image/webp"},
+ {0xa66, "image/webp"},
{0xaad, "image/svg+xml"},
{0xaff, "image/x-drawfile"},
{0xb60, "image/png"},
-----------------------------------------------------------------------
Summary of changes:
frontends/riscos/filetype.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontends/riscos/filetype.c b/frontends/riscos/filetype.c
index d752141..b0dc949 100644
--- a/frontends/riscos/filetype.c
+++ b/frontends/riscos/filetype.c
@@ -39,7 +39,7 @@ static const struct type_entry type_map[] = {
{0x188, "application/x-shockwave-flash"},
{0x695, "image/gif"},
{0x69c, "image/x-ms-bmp"},
- {0xa66, "image/webp"},
+ {0xa66, "image/webp"},
{0xaad, "image/svg+xml"},
{0xaff, "image/x-drawfile"},
{0xb60, "image/png"},
--
NetSurf Browser
2 years, 7 months
netsurf: branch master updated. release/3.10-119-g937446b
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/937446b95beb40f9f641e...
...commit http://git.netsurf-browser.org/netsurf.git/commit/937446b95beb40f9f641ee2...
...tree http://git.netsurf-browser.org/netsurf.git/tree/937446b95beb40f9f641ee27b...
The branch, master has been updated
via 937446b95beb40f9f641ee27bffbeb24509cbc73 (commit)
from 84ec9c2b2a8884c7bdb7e0fa461c8b2d9c495cb3 (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=937446b95beb40f9f64...
commit 937446b95beb40f9f641ee27bffbeb24509cbc73
Author: Rob Kendrick <rjek(a)netsurf-browser.org>
Commit: Rob Kendrick <rjek(a)netsurf-browser.org>
Allow drag-and-drop loading of WebP images on RISC OS
diff --git a/frontends/riscos/filetype.c b/frontends/riscos/filetype.c
index 73651cd..d752141 100644
--- a/frontends/riscos/filetype.c
+++ b/frontends/riscos/filetype.c
@@ -39,6 +39,7 @@ static const struct type_entry type_map[] = {
{0x188, "application/x-shockwave-flash"},
{0x695, "image/gif"},
{0x69c, "image/x-ms-bmp"},
+ {0xa66, "image/webp"},
{0xaad, "image/svg+xml"},
{0xaff, "image/x-drawfile"},
{0xb60, "image/png"},
@@ -269,6 +270,7 @@ int ro_content_native_type(struct hlcache_handle *c)
case FILETYPE_BMP: /* bmp */
case FILETYPE_ICO: /* ico */
case FILETYPE_PNG: /* png */
+ case FILETYPE_WEBP: /* webp */
case 0xff9: /* sprite */
return osfile_TYPE_SPRITE;
case FILETYPE_SVG: /* svg */
diff --git a/frontends/riscos/filetype.h b/frontends/riscos/filetype.h
index 4c45e7b..b9fca4d 100644
--- a/frontends/riscos/filetype.h
+++ b/frontends/riscos/filetype.h
@@ -67,6 +67,9 @@
#ifndef FILETYPE_SVG
#define FILETYPE_SVG 0xaad
#endif
+#ifndef FILETYPE_WEBP
+#define FILETYPE_WEBP 0xa66
+#endif
/**
* Determine the MIME type of a local file.
diff --git a/frontends/riscos/gui.c b/frontends/riscos/gui.c
index b0eb232..cc12eac 100644
--- a/frontends/riscos/gui.c
+++ b/frontends/riscos/gui.c
@@ -827,6 +827,7 @@ static void ro_msg_dataload(wimp_message *message)
case osfile_TYPE_TEXT:
case FILETYPE_ARTWORKS:
case FILETYPE_SVG:
+ case FILETYPE_WEBP:
/* display the actual file */
error = netsurf_path_to_nsurl(message->data.data_xfer.file_name, &url);
break;
@@ -929,7 +930,8 @@ static void ro_msg_datasave(wimp_message *message)
case osfile_TYPE_SPRITE:
case osfile_TYPE_TEXT:
case FILETYPE_ARTWORKS:
- case FILETYPE_SVG: {
+ case FILETYPE_SVG:
+ case FILETYPE_WEBP: {
os_error *error;
dataxfer->your_ref = dataxfer->my_ref;
-----------------------------------------------------------------------
Summary of changes:
frontends/riscos/filetype.c | 2 ++
frontends/riscos/filetype.h | 3 +++
frontends/riscos/gui.c | 4 +++-
3 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/frontends/riscos/filetype.c b/frontends/riscos/filetype.c
index 73651cd..d752141 100644
--- a/frontends/riscos/filetype.c
+++ b/frontends/riscos/filetype.c
@@ -39,6 +39,7 @@ static const struct type_entry type_map[] = {
{0x188, "application/x-shockwave-flash"},
{0x695, "image/gif"},
{0x69c, "image/x-ms-bmp"},
+ {0xa66, "image/webp"},
{0xaad, "image/svg+xml"},
{0xaff, "image/x-drawfile"},
{0xb60, "image/png"},
@@ -269,6 +270,7 @@ int ro_content_native_type(struct hlcache_handle *c)
case FILETYPE_BMP: /* bmp */
case FILETYPE_ICO: /* ico */
case FILETYPE_PNG: /* png */
+ case FILETYPE_WEBP: /* webp */
case 0xff9: /* sprite */
return osfile_TYPE_SPRITE;
case FILETYPE_SVG: /* svg */
diff --git a/frontends/riscos/filetype.h b/frontends/riscos/filetype.h
index 4c45e7b..b9fca4d 100644
--- a/frontends/riscos/filetype.h
+++ b/frontends/riscos/filetype.h
@@ -67,6 +67,9 @@
#ifndef FILETYPE_SVG
#define FILETYPE_SVG 0xaad
#endif
+#ifndef FILETYPE_WEBP
+#define FILETYPE_WEBP 0xa66
+#endif
/**
* Determine the MIME type of a local file.
diff --git a/frontends/riscos/gui.c b/frontends/riscos/gui.c
index b0eb232..cc12eac 100644
--- a/frontends/riscos/gui.c
+++ b/frontends/riscos/gui.c
@@ -827,6 +827,7 @@ static void ro_msg_dataload(wimp_message *message)
case osfile_TYPE_TEXT:
case FILETYPE_ARTWORKS:
case FILETYPE_SVG:
+ case FILETYPE_WEBP:
/* display the actual file */
error = netsurf_path_to_nsurl(message->data.data_xfer.file_name, &url);
break;
@@ -929,7 +930,8 @@ static void ro_msg_datasave(wimp_message *message)
case osfile_TYPE_SPRITE:
case osfile_TYPE_TEXT:
case FILETYPE_ARTWORKS:
- case FILETYPE_SVG: {
+ case FILETYPE_SVG:
+ case FILETYPE_WEBP: {
os_error *error;
dataxfer->your_ref = dataxfer->my_ref;
--
NetSurf Browser
2 years, 7 months
netsurf: branch master updated. release/3.10-118-g84ec9c2
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/84ec9c2b2a8884c7bdb7e...
...commit http://git.netsurf-browser.org/netsurf.git/commit/84ec9c2b2a8884c7bdb7e0f...
...tree http://git.netsurf-browser.org/netsurf.git/tree/84ec9c2b2a8884c7bdb7e0fa4...
The branch, master has been updated
via 84ec9c2b2a8884c7bdb7e0fa461c8b2d9c495cb3 (commit)
via 3cf92011c27a0ae650eae61d5b7749e0a5c0f381 (commit)
from 9e3ef18255464ccf0b7e29db23a436ccdc371959 (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=84ec9c2b2a8884c7bdb...
commit 84ec9c2b2a8884c7bdb7e0fa461c8b2d9c495cb3
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
tidy up GTK frontend initialisation
diff --git a/frontends/gtk/gui.c b/frontends/gtk/gui.c
index d4b0c71..a826b05 100644
--- a/frontends/gtk/gui.c
+++ b/frontends/gtk/gui.c
@@ -75,28 +75,176 @@
bool nsgtk_complete = false;
-char *nsgtk_config_home; /* exported global defined in gtk/gui.h */
+/* exported global defined in gtk/gui.h */
+char *nsgtk_config_home;
-GdkPixbuf *favicon_pixbuf; /** favicon default pixbuf */
-GdkPixbuf *win_default_icon_pixbuf; /** default window icon pixbuf */
+/** favicon default pixbuf */
+GdkPixbuf *favicon_pixbuf;
+
+/** default window icon pixbuf */
+GdkPixbuf *win_default_icon_pixbuf;
GtkBuilder *warning_builder;
-char **respaths; /** resource search path vector */
+/** resource search path vector */
+char **respaths;
-/**
- * Cause an abnormal program termination.
- *
- * \note This never returns and is intended to terminate without any cleanup.
- *
- * \param error The message to display to the user.
- */
-static void die(const char * const error)
+
+/* exported function documented in gtk/warn.h */
+nserror nsgtk_warning(const char *warning, const char *detail)
+{
+ char buf[300]; /* 300 is the size the RISC OS GUI uses */
+ static GtkWindow *nsgtk_warning_window;
+ GtkLabel *WarningLabel;
+
+ NSLOG(netsurf, INFO, "%s %s", warning, detail ? detail : "");
+ fflush(stdout);
+
+ nsgtk_warning_window = GTK_WINDOW(gtk_builder_get_object(warning_builder, "wndWarning"));
+ WarningLabel = GTK_LABEL(gtk_builder_get_object(warning_builder,
+ "labelWarning"));
+
+ snprintf(buf, sizeof(buf), "%s %s", messages_get(warning),
+ detail ? detail : "");
+ buf[sizeof(buf) - 1] = 0;
+
+ gtk_label_set_text(WarningLabel, buf);
+
+ gtk_widget_show_all(GTK_WIDGET(nsgtk_warning_window));
+
+ return NSERROR_OK;
+}
+
+
+/* exported interface documented in gtk/gui.h */
+uint32_t gtk_gui_gdkkey_to_nskey(GdkEventKey *key)
{
- fprintf(stderr, "%s", error);
- exit(EXIT_FAILURE);
+ /* this function will need to become much more complex to support
+ * everything that the RISC OS version does. But this will do for
+ * now. I hope.
+ */
+ switch (key->keyval) {
+
+ case GDK_KEY(Tab):
+ return NS_KEY_TAB;
+
+ case GDK_KEY(BackSpace):
+ if (key->state & GDK_SHIFT_MASK)
+ 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):
+ 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_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_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;
+
+ /* Modifiers - do nothing for now */
+ case GDK_KEY(Shift_L):
+ case GDK_KEY(Shift_R):
+ case GDK_KEY(Control_L):
+ case GDK_KEY(Control_R):
+ case GDK_KEY(Caps_Lock):
+ case GDK_KEY(Shift_Lock):
+ case GDK_KEY(Meta_L):
+ case GDK_KEY(Meta_R):
+ case GDK_KEY(Alt_L):
+ case GDK_KEY(Alt_R):
+ case GDK_KEY(Super_L):
+ case GDK_KEY(Super_R):
+ case GDK_KEY(Hyper_L):
+ case GDK_KEY(Hyper_R):
+ return 0;
+
+ }
+ return gdk_keyval_to_unicode(key->keyval);
}
+
/**
* Create an array of valid paths to search for resources.
*
@@ -155,799 +303,732 @@ nsgtk_init_resource_path(const char *config_home)
/**
- * Set option defaults for gtk frontend.
- *
- * \param defaults The option table to update.
- * \return error status.
+ * create directory name and check it is acessible and a directory.
*/
-static nserror set_defaults(struct nsoption_s *defaults)
+static nserror
+check_dirname(const char *path, const char *leaf, char **dirname_out)
{
- char *fname;
- GtkSettings *settings;
- GtkIconSize tooliconsize;
- GtkToolbarStyle toolbarstyle;
-
- /* cookie file default */
- fname = NULL;
- netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "Cookies");
- if (fname != NULL) {
- nsoption_setnull_charp(cookie_file, fname);
- }
-
- /* cookie jar default */
- fname = NULL;
- netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "Cookies");
- if (fname != NULL) {
- nsoption_setnull_charp(cookie_jar, fname);
- }
+ nserror ret;
+ char *dirname = NULL;
+ struct stat dirname_stat;
- /* url database default */
- fname = NULL;
- netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "URLs");
- if (fname != NULL) {
- nsoption_setnull_charp(url_file, fname);
+ ret = netsurf_mkpath(&dirname, NULL, 2, path, leaf);
+ if (ret != NSERROR_OK) {
+ return ret;
}
- /* bookmark database default */
- fname = NULL;
- netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "Hotlist");
- if (fname != NULL) {
- nsoption_setnull_charp(hotlist_path, fname);
+ /* ensure access is possible and the entry is actualy
+ * a directory.
+ */
+ if (stat(dirname, &dirname_stat) == 0) {
+ if (S_ISDIR(dirname_stat.st_mode)) {
+ if (access(dirname, R_OK | W_OK) == 0) {
+ *dirname_out = dirname;
+ return NSERROR_OK;
+ } else {
+ ret = NSERROR_PERMISSION;
+ }
+ } else {
+ ret = NSERROR_NOT_DIRECTORY;
+ }
+ } else {
+ ret = NSERROR_NOT_FOUND;
}
- /* download directory default */
- fname = getenv("HOME");
- if (fname != NULL) {
- nsoption_setnull_charp(downloads_directory, strdup(fname));
- }
+ free(dirname);
- if ((nsoption_charp(cookie_file) == NULL) ||
- (nsoption_charp(cookie_jar) == NULL) ||
- (nsoption_charp(url_file) == NULL) ||
- (nsoption_charp(hotlist_path) == NULL) ||
- (nsoption_charp(downloads_directory) == NULL)) {
- NSLOG(netsurf, INFO,
- "Failed initialising default resource paths");
- return NSERROR_BAD_PARAMETER;
- }
+ return ret;
+}
- /* set default font names */
- nsoption_set_charp(font_sans, strdup("Sans"));
- nsoption_set_charp(font_serif, strdup("Serif"));
- nsoption_set_charp(font_mono, strdup("Monospace"));
- nsoption_set_charp(font_cursive, strdup("Serif"));
- nsoption_set_charp(font_fantasy, strdup("Serif"));
- /* Default toolbar button type to system defaults */
+/**
+ * Get the path to the config directory.
+ *
+ * @param config_home_out Path to configuration directory.
+ * @return NSERROR_OK on sucess and \a config_home_out updated else error code.
+ */
+static nserror get_config_home(char **config_home_out)
+{
+ nserror ret;
+ char *home_dir;
+ char *xdg_config_dir;
+ char *config_home;
- settings = gtk_settings_get_default();
- g_object_get(settings,
- "gtk-toolbar-icon-size", &tooliconsize,
- "gtk-toolbar-style", &toolbarstyle, NULL);
+ home_dir = getenv("HOME");
- switch (toolbarstyle) {
- case GTK_TOOLBAR_ICONS:
- if (tooliconsize == GTK_ICON_SIZE_SMALL_TOOLBAR) {
- nsoption_set_int(button_type, 1);
- } else {
- nsoption_set_int(button_type, 2);
+ /* The old $HOME/.netsurf/ directory should be used if it
+ * exists and is accessible.
+ */
+ if (home_dir != NULL) {
+ ret = check_dirname(home_dir, ".netsurf", &config_home);
+ if (ret == NSERROR_OK) {
+ NSLOG(netsurf, INFO, "\"%s\"", config_home);
+ *config_home_out = config_home;
+ return ret;
}
- break;
+ }
- case GTK_TOOLBAR_TEXT:
- nsoption_set_int(button_type, 4);
- break;
+ /* $XDG_CONFIG_HOME defines the base directory
+ * relative to which user specific configuration files
+ * should be stored.
+ */
+ xdg_config_dir = getenv("XDG_CONFIG_HOME");
- case GTK_TOOLBAR_BOTH:
- case GTK_TOOLBAR_BOTH_HORIZ:
- /* no labels in default configuration */
- default:
- /* No system default, so use large icons */
- nsoption_set_int(button_type, 2);
- break;
- }
+ if ((xdg_config_dir == NULL) || (*xdg_config_dir == 0)) {
+ /* If $XDG_CONFIG_HOME is either not set or empty, a
+ * default equal to $HOME/.config should be used.
+ */
- /* set default items in toolbar */
- nsoption_set_charp(toolbar_items,
- strdup("back/history/forward/reloadstop/url_bar/websearch/openmenu"));
+ /** @todo the meaning of empty is never defined so I
+ * am assuming it is a zero length string but is it
+ * supposed to mean "whitespace" and if so what counts
+ * as whitespace? (are tabs etc. counted or should
+ * isspace() be used)
+ */
- /* set default for menu and tool bar visibility */
- nsoption_set_charp(bar_show, strdup("tool"));
+ /* the HOME envvar is required */
+ if (home_dir == NULL) {
+ return NSERROR_NOT_DIRECTORY;
+ }
- return NSERROR_OK;
-}
+ ret = check_dirname(home_dir, ".config/netsurf", &config_home);
+ if (ret != NSERROR_OK) {
+ return ret;
+ }
+ } else {
+ ret = check_dirname(xdg_config_dir, "netsurf", &config_home);
+ if (ret != NSERROR_OK) {
+ return ret;
+ }
+ }
-#if GTK_CHECK_VERSION(3,14,0)
+ NSLOG(netsurf, INFO, "\"%s\"", config_home);
-/**
- * adds named icons into gtk theme
- */
-static nserror nsgtk_add_named_icons_to_theme(void)
-{
- gtk_icon_theme_add_resource_path(gtk_icon_theme_get_default(),
- "/org/netsurf/icons");
+ *config_home_out = config_home;
return NSERROR_OK;
}
-#else
-static nserror
-add_builtin_icon(const char *prefix, const char *name, int x, int y)
+static nserror create_config_home(char **config_home_out)
{
- GdkPixbuf *pixbuf;
- nserror res;
- char *resname;
- int resnamelen;
+ char *config_home = NULL;
+ char *home_dir;
+ char *xdg_config_dir;
+ nserror ret;
- /* resource name string length allowing for / .png and termination */
- resnamelen = strlen(prefix) + strlen(name) + 5 + 1 + 4 + 1;
- resname = malloc(resnamelen);
- if (resname == NULL) {
- return NSERROR_NOMEM;
+ NSLOG(netsurf, INFO, "Attempting to create configuration directory");
+
+ /* $XDG_CONFIG_HOME defines the base directory
+ * relative to which user specific configuration files
+ * should be stored.
+ */
+ xdg_config_dir = getenv("XDG_CONFIG_HOME");
+
+ if ((xdg_config_dir == NULL) || (*xdg_config_dir == 0)) {
+ home_dir = getenv("HOME");
+
+ if ((home_dir == NULL) || (*home_dir == 0)) {
+ return NSERROR_NOT_DIRECTORY;
+ }
+
+ ret = netsurf_mkpath(&config_home, NULL, 4, home_dir, ".config","netsurf", "/");
+ if (ret != NSERROR_OK) {
+ return ret;
+ }
+ } else {
+ ret = netsurf_mkpath(&config_home, NULL, 3, xdg_config_dir, "netsurf", "/");
+ if (ret != NSERROR_OK) {
+ return ret;
+ }
}
- snprintf(resname, resnamelen, "icons%s/%s.png", prefix, name);
- res = nsgdk_pixbuf_new_from_resname(resname, &pixbuf);
- NSLOG(netsurf, DEEPDEBUG, "%d %s", res, resname);
- free(resname);
- if (res != NSERROR_OK) {
- pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, false, 8, x, y);
+ /* ensure all elements of path exist (the trailing / is required) */
+ ret = netsurf_mkdir_all(config_home);
+ if (ret != NSERROR_OK) {
+ free(config_home);
+ return ret;
}
- gtk_icon_theme_add_builtin_icon(name, y, pixbuf);
+
+ /* strip the trailing separator */
+ config_home[strlen(config_home) - 1] = 0;
+
+ NSLOG(netsurf, INFO, "\"%s\"", config_home);
+
+ *config_home_out = config_home;
return NSERROR_OK;
}
+
/**
- * adds named icons into gtk theme
+ * Ensures output logging stream is correctly configured
*/
-static nserror nsgtk_add_named_icons_to_theme(void)
+static bool nslog_stream_configure(FILE *fptr)
{
- /* these must also be in gtk/resources.c pixbuf_resource *and*
- * gtk/res/netsurf.gresource.xml
- */
- add_builtin_icon("", "local-history", 8, 32);
- add_builtin_icon("", "show-cookie", 24, 24);
- add_builtin_icon("/24x24/actions", "page-info-insecure", 24, 24);
- add_builtin_icon("/24x24/actions", "page-info-internal", 24, 24);
- add_builtin_icon("/24x24/actions", "page-info-local", 24, 24);
- add_builtin_icon("/24x24/actions", "page-info-secure", 24, 24);
- add_builtin_icon("/24x24/actions", "page-info-warning", 24, 24);
- add_builtin_icon("/48x48/actions", "page-info-insecure", 48, 48);
- add_builtin_icon("/48x48/actions", "page-info-internal", 48, 48);
- add_builtin_icon("/48x48/actions", "page-info-local", 48, 48);
- add_builtin_icon("/48x48/actions", "page-info-secure", 48, 48);
- add_builtin_icon("/48x48/actions", "page-info-warning", 48, 48);
+ /* set log stream to be non-buffering */
+ setbuf(fptr, NULL);
- return NSERROR_OK;
+ return true;
}
-#endif
-
/**
- * setup GTK specific parts of the browser.
+ * Set option defaults for gtk frontend.
*
- * \param argc The number of arguments on the command line
- * \param argv A string vector of command line arguments.
- * \respath A string vector of the path elements of resources
+ * \param defaults The option table to update.
+ * \return error status.
*/
-static nserror nsgtk_setup(int argc, char** argv, char **respath)
+static nserror set_defaults(struct nsoption_s *defaults)
{
- char buf[PATH_MAX];
- char *resource_filename;
- char *addr = NULL;
- nsurl *url;
- nserror res;
+ char *fname;
+ GtkSettings *settings;
+ GtkIconSize tooliconsize;
+ GtkToolbarStyle toolbarstyle;
- /* Initialise gtk accelerator table */
- res = nsgtk_accelerator_init(respaths);
- if (res != NSERROR_OK) {
- NSLOG(netsurf, INFO,
- "Unable to load gtk accelerator configuration");
- /* not fatal if this does not load */
+ /* cookie file default */
+ fname = NULL;
+ netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "Cookies");
+ if (fname != NULL) {
+ nsoption_setnull_charp(cookie_file, fname);
}
- /* initialise warning dialog */
- res = nsgtk_builder_new_from_resname("warning", &warning_builder);
- if (res != NSERROR_OK) {
- NSLOG(netsurf, INFO, "Unable to initialise warning dialog");
- return res;
+ /* cookie jar default */
+ fname = NULL;
+ netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "Cookies");
+ if (fname != NULL) {
+ nsoption_setnull_charp(cookie_jar, fname);
}
- gtk_builder_connect_signals(warning_builder, NULL);
-
- /* set default icon if its available */
- res = nsgdk_pixbuf_new_from_resname("netsurf.xpm",
- &win_default_icon_pixbuf);
- if (res == NSERROR_OK) {
- NSLOG(netsurf, INFO, "Seting default window icon");
- gtk_window_set_default_icon(win_default_icon_pixbuf);
+ /* url database default */
+ fname = NULL;
+ netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "URLs");
+ if (fname != NULL) {
+ nsoption_setnull_charp(url_file, fname);
}
- /* Search engine sources */
- resource_filename = filepath_find(respath, "SearchEngines");
- search_web_init(resource_filename);
- if (resource_filename != NULL) {
- NSLOG(netsurf, INFO, "Using '%s' as Search Engines file",
- resource_filename);
- free(resource_filename);
+ /* bookmark database default */
+ fname = NULL;
+ netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "Hotlist");
+ if (fname != NULL) {
+ nsoption_setnull_charp(hotlist_path, fname);
}
- search_web_select_provider(nsoption_int(search_provider));
- /* Default favicon */
- res = nsgdk_pixbuf_new_from_resname("favicon.png", &favicon_pixbuf);
- if (res != NSERROR_OK) {
- favicon_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
- false, 8, 16, 16);
+ /* download directory default */
+ fname = getenv("HOME");
+ if (fname != NULL) {
+ nsoption_setnull_charp(downloads_directory, strdup(fname));
}
- /* add named icons to gtk theme */
- res = nsgtk_add_named_icons_to_theme();
- if (res != NSERROR_OK) {
- NSLOG(netsurf, INFO, "Unable to add named icons to GTK theme.");
- return res;
+ if ((nsoption_charp(cookie_file) == NULL) ||
+ (nsoption_charp(cookie_jar) == NULL) ||
+ (nsoption_charp(url_file) == NULL) ||
+ (nsoption_charp(hotlist_path) == NULL) ||
+ (nsoption_charp(downloads_directory) == NULL)) {
+ NSLOG(netsurf, INFO,
+ "Failed initialising default resource paths");
+ return NSERROR_BAD_PARAMETER;
}
- /* initialise throbber */
- res = nsgtk_throbber_init();
- if (res != NSERROR_OK) {
- NSLOG(netsurf, INFO, "Unable to initialise throbber.");
- return res;
- }
+ /* set default font names */
+ nsoption_set_charp(font_sans, strdup("Sans"));
+ nsoption_set_charp(font_serif, strdup("Serif"));
+ nsoption_set_charp(font_mono, strdup("Monospace"));
+ nsoption_set_charp(font_cursive, strdup("Serif"));
+ nsoption_set_charp(font_fantasy, strdup("Serif"));
- /* Initialise completions - cannot fail */
- nsgtk_completion_init();
-
- /* The tree view system needs to know the screen's DPI, so we
- * find that out here, rather than when we create a first browser
- * window.
- */
- browser_set_dpi(gdk_screen_get_resolution(gdk_screen_get_default()));
- NSLOG(netsurf, INFO, "Set CSS DPI to %d", browser_get_dpi());
-
- filepath_sfinddef(respath, buf, "mime.types", "/etc/");
- gtk_fetch_filetype_init(buf);
-
- save_complete_init();
-
- urldb_load(nsoption_charp(url_file));
- urldb_load_cookies(nsoption_charp(cookie_file));
- hotlist_init(nsoption_charp(hotlist_path),
- nsoption_charp(hotlist_path));
-
- /* Initialise top level UI elements */
- res = nsgtk_download_init();
- if (res != NSERROR_OK) {
- NSLOG(netsurf, INFO, "Unable to initialise download window.");
- return res;
- }
+ /* Default toolbar button type to system defaults */
- /* If there is a url specified on the command line use it */
- if (argc > 1) {
- struct stat fs;
- if (stat(argv[1], &fs) == 0) {
- size_t addrlen;
- char *rp = realpath(argv[1], NULL);
- assert(rp != NULL);
+ settings = gtk_settings_get_default();
+ g_object_get(settings,
+ "gtk-toolbar-icon-size", &tooliconsize,
+ "gtk-toolbar-style", &toolbarstyle, NULL);
- /* calculate file url length including terminator */
- addrlen = SLEN("file://") + strlen(rp) + 1;
- addr = malloc(addrlen);
- assert(addr != NULL);
- snprintf(addr, addrlen, "file://%s", rp);
- free(rp);
+ switch (toolbarstyle) {
+ case GTK_TOOLBAR_ICONS:
+ if (tooliconsize == GTK_ICON_SIZE_SMALL_TOOLBAR) {
+ nsoption_set_int(button_type, 1);
} else {
- addr = strdup(argv[1]);
+ nsoption_set_int(button_type, 2);
}
- }
- if (addr != NULL) {
- /* managed to set up based on local launch */
- } else if (nsoption_charp(homepage_url) != NULL) {
- addr = strdup(nsoption_charp(homepage_url));
- } else {
- addr = strdup(NETSURF_HOMEPAGE);
- }
+ break;
- /* create an initial browser window */
- res = nsurl_create(addr, &url);
- if (res == NSERROR_OK) {
- res = browser_window_create(BW_CREATE_HISTORY,
- url,
- NULL,
- NULL,
- NULL);
- nsurl_unref(url);
+ case GTK_TOOLBAR_TEXT:
+ nsoption_set_int(button_type, 4);
+ break;
+
+ case GTK_TOOLBAR_BOTH:
+ case GTK_TOOLBAR_BOTH_HORIZ:
+ /* no labels in default configuration */
+ default:
+ /* No system default, so use large icons */
+ nsoption_set_int(button_type, 2);
+ break;
}
- free(addr);
+ /* set default items in toolbar */
+ nsoption_set_charp(toolbar_items,
+ strdup("back/history/forward/reloadstop/url_bar/websearch/openmenu"));
- return res;
-}
+ /* set default for menu and tool bar visibility */
+ nsoption_set_charp(bar_show, strdup("tool"));
+ return NSERROR_OK;
+}
/**
- * Ensures output logging stream is correctly configured
+ * Initialise user options
+ *
+ * Initialise the browser configuration options. These are set by:
+ * - set generic defaults suitable for the gtk frontend
+ * - user choices loaded from Choices file
+ * - command line parameters
*/
-static bool nslog_stream_configure(FILE *fptr)
-{
- /* set log stream to be non-buffering */
- setbuf(fptr, NULL);
-
- return true;
-}
-
-
-
-
-
-
-/* exported function documented in gtk/warn.h */
-nserror nsgtk_warning(const char *warning, const char *detail)
+static nserror nsgtk_option_init(int *pargc, char** argv)
{
- char buf[300]; /* 300 is the size the RISC OS GUI uses */
- static GtkWindow *nsgtk_warning_window;
- GtkLabel *WarningLabel;
+ nserror ret;
+ char *choices = NULL;
- NSLOG(netsurf, INFO, "%s %s", warning, detail ? detail : "");
- fflush(stdout);
+ /* user options setup */
+ ret = nsoption_init(set_defaults, &nsoptions, &nsoptions_default);
+ if (ret != NSERROR_OK) {
+ return ret;
+ }
- nsgtk_warning_window = GTK_WINDOW(gtk_builder_get_object(warning_builder, "wndWarning"));
- WarningLabel = GTK_LABEL(gtk_builder_get_object(warning_builder,
- "labelWarning"));
+ /* Attempt to load the user choices */
+ ret = netsurf_mkpath(&choices, NULL, 2, nsgtk_config_home, "Choices");
+ if (ret == NSERROR_OK) {
+ nsoption_read(choices, nsoptions);
+ free(choices);
+ }
- snprintf(buf, sizeof(buf), "%s %s", messages_get(warning),
- detail ? detail : "");
- buf[sizeof(buf) - 1] = 0;
+ /* overide loaded options with those from commandline */
+ nsoption_commandline(pargc, argv, nsoptions);
- gtk_label_set_text(WarningLabel, buf);
+ /* ensure all options fall within sensible bounds */
- gtk_widget_show_all(GTK_WIDGET(nsgtk_warning_window));
+ /* Attempt to handle nonsense status bar widths. These may exist
+ * in people's Choices as the GTK front end used to abuse the
+ * status bar width option by using it for an absolute value in px.
+ * The GTK front end now correctly uses it as a proportion of window
+ * width. Here we assume that a value of less than 15% is wrong
+ * and set to the default two thirds. */
+ if (nsoption_int(toolbar_status_size) < 1500) {
+ nsoption_set_int(toolbar_status_size, 6667);
+ }
return NSERROR_OK;
}
-
-
-uint32_t gtk_gui_gdkkey_to_nskey(GdkEventKey *key)
-{
- /* this function will need to become much more complex to support
- * everything that the RISC OS version does. But this will do for
- * now. I hope.
- */
- switch (key->keyval) {
-
- case GDK_KEY(Tab):
- return NS_KEY_TAB;
-
- case GDK_KEY(BackSpace):
- if (key->state & GDK_SHIFT_MASK)
- 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):
- 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_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_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;
-
- /* Modifiers - do nothing for now */
- case GDK_KEY(Shift_L):
- case GDK_KEY(Shift_R):
- case GDK_KEY(Control_L):
- case GDK_KEY(Control_R):
- case GDK_KEY(Caps_Lock):
- case GDK_KEY(Shift_Lock):
- case GDK_KEY(Meta_L):
- case GDK_KEY(Meta_R):
- case GDK_KEY(Alt_L):
- case GDK_KEY(Alt_R):
- case GDK_KEY(Super_L):
- case GDK_KEY(Super_R):
- case GDK_KEY(Hyper_L):
- case GDK_KEY(Hyper_R):
- return 0;
-
- }
- return gdk_keyval_to_unicode(key->keyval);
-}
-
-
/**
- * create directory name and check it is acessible and a directory.
+ * initialise message translation
*/
-static nserror
-check_dirname(const char *path, const char *leaf, char **dirname_out)
+static nserror nsgtk_messages_init(char **respaths)
{
+ const char *messages;
nserror ret;
- char *dirname = NULL;
- struct stat dirname_stat;
-
- ret = netsurf_mkpath(&dirname, NULL, 2, path, leaf);
- if (ret != NSERROR_OK) {
- return ret;
- }
-
- /* ensure access is possible and the entry is actualy
- * a directory.
- */
- if (stat(dirname, &dirname_stat) == 0) {
- if (S_ISDIR(dirname_stat.st_mode)) {
- if (access(dirname, R_OK | W_OK) == 0) {
- *dirname_out = dirname;
- return NSERROR_OK;
- } else {
- ret = NSERROR_PERMISSION;
- }
- } else {
- ret = NSERROR_NOT_DIRECTORY;
- }
+ const uint8_t *data;
+ size_t data_size;
+
+ ret = nsgtk_data_from_resname("Messages", &data, &data_size);
+ if (ret == NSERROR_OK) {
+ ret = messages_add_from_inline(data, data_size);
} else {
- ret = NSERROR_NOT_FOUND;
+ /* Obtain path to messages */
+ ret = nsgtk_path_from_resname("Messages", &messages);
+ if (ret == NSERROR_OK) {
+ ret = messages_add_from_file(messages);
+ }
}
-
- free(dirname);
-
return ret;
}
+
/**
- * Get the path to the config directory.
+ * Get the path to the cache directory.
*
- * @param config_home_out Path to configuration directory.
- * @return NSERROR_OK on sucess and \a config_home_out updated else error code.
+ * @param cache_home_out Path to cache directory.
+ * @return NSERROR_OK on sucess and \a cache_home_out updated else error code.
*/
-static nserror get_config_home(char **config_home_out)
+static nserror get_cache_home(char **cache_home_out)
{
nserror ret;
+ char *xdg_cache_dir;
+ char *cache_home;
char *home_dir;
- char *xdg_config_dir;
- char *config_home;
-
- home_dir = getenv("HOME");
-
- /* The old $HOME/.netsurf/ directory should be used if it
- * exists and is accessible.
- */
- if (home_dir != NULL) {
- ret = check_dirname(home_dir, ".netsurf", &config_home);
- if (ret == NSERROR_OK) {
- NSLOG(netsurf, INFO, "\"%s\"", config_home);
- *config_home_out = config_home;
- return ret;
- }
- }
- /* $XDG_CONFIG_HOME defines the base directory
- * relative to which user specific configuration files
- * should be stored.
+ /* $XDG_CACHE_HOME defines the base directory relative to
+ * which user specific non-essential data files should be
+ * stored.
*/
- xdg_config_dir = getenv("XDG_CONFIG_HOME");
+ xdg_cache_dir = getenv("XDG_CACHE_HOME");
- if ((xdg_config_dir == NULL) || (*xdg_config_dir == 0)) {
- /* If $XDG_CONFIG_HOME is either not set or empty, a
- * default equal to $HOME/.config should be used.
+ if ((xdg_cache_dir == NULL) || (*xdg_cache_dir == 0)) {
+ /* If $XDG_CACHE_HOME is either not set or empty, a
+ * default equal to $HOME/.cache should be used.
*/
- /** @todo the meaning of empty is never defined so I
- * am assuming it is a zero length string but is it
- * supposed to mean "whitespace" and if so what counts
- * as whitespace? (are tabs etc. counted or should
- * isspace() be used)
- */
+ home_dir = getenv("HOME");
/* the HOME envvar is required */
if (home_dir == NULL) {
return NSERROR_NOT_DIRECTORY;
}
- ret = check_dirname(home_dir, ".config/netsurf", &config_home);
+ ret = check_dirname(home_dir, ".cache/netsurf", &cache_home);
if (ret != NSERROR_OK) {
return ret;
}
} else {
- ret = check_dirname(xdg_config_dir, "netsurf", &config_home);
+ ret = check_dirname(xdg_cache_dir, "netsurf", &cache_home);
if (ret != NSERROR_OK) {
return ret;
}
}
- NSLOG(netsurf, INFO, "\"%s\"", config_home);
+ NSLOG(netsurf, INFO, "\"%s\"", cache_home);
- *config_home_out = config_home;
+ *cache_home_out = cache_home;
return NSERROR_OK;
}
-static nserror create_config_home(char **config_home_out)
+
+/**
+ * create a cache directory
+ */
+static nserror create_cache_home(char **cache_home_out)
{
- char *config_home = NULL;
+ char *cache_home = NULL;
char *home_dir;
- char *xdg_config_dir;
+ char *xdg_cache_dir;
nserror ret;
- NSLOG(netsurf, INFO, "Attempting to create configuration directory");
+ NSLOG(netsurf, INFO, "Attempting to create cache directory");
- /* $XDG_CONFIG_HOME defines the base directory
- * relative to which user specific configuration files
+ /* $XDG_CACHE_HOME defines the base directory
+ * relative to which user specific cache files
* should be stored.
*/
- xdg_config_dir = getenv("XDG_CONFIG_HOME");
+ xdg_cache_dir = getenv("XDG_CACHE_HOME");
- if ((xdg_config_dir == NULL) || (*xdg_config_dir == 0)) {
+ if ((xdg_cache_dir == NULL) || (*xdg_cache_dir == 0)) {
home_dir = getenv("HOME");
if ((home_dir == NULL) || (*home_dir == 0)) {
return NSERROR_NOT_DIRECTORY;
}
- ret = netsurf_mkpath(&config_home, NULL, 4, home_dir, ".config","netsurf", "/");
+ ret = netsurf_mkpath(&cache_home, NULL, 4, home_dir, ".cache", "netsurf", "/");
if (ret != NSERROR_OK) {
return ret;
}
} else {
- ret = netsurf_mkpath(&config_home, NULL, 3, xdg_config_dir, "netsurf", "/");
+ ret = netsurf_mkpath(&cache_home, NULL, 3, xdg_cache_dir, "netsurf", "/");
if (ret != NSERROR_OK) {
return ret;
}
}
/* ensure all elements of path exist (the trailing / is required) */
- ret = netsurf_mkdir_all(config_home);
+ ret = netsurf_mkdir_all(cache_home);
if (ret != NSERROR_OK) {
- free(config_home);
+ free(cache_home);
return ret;
}
/* strip the trailing separator */
- config_home[strlen(config_home) - 1] = 0;
+ cache_home[strlen(cache_home) - 1] = 0;
- NSLOG(netsurf, INFO, "\"%s\"", config_home);
+ NSLOG(netsurf, INFO, "\"%s\"", cache_home);
- *config_home_out = config_home;
+ *cache_home_out = cache_home;
return NSERROR_OK;
}
+
/**
- * Get the path to the cache directory.
- *
- * @param cache_home_out Path to cache directory.
- * @return NSERROR_OK on sucess and \a cache_home_out updated else error code.
+ * GTK specific initialisation
*/
-static nserror get_cache_home(char **cache_home_out)
+static nserror nsgtk_init(int *pargc, char ***pargv, char **cache_home)
{
nserror ret;
- char *xdg_cache_dir;
- char *cache_home;
- char *home_dir;
- /* $XDG_CACHE_HOME defines the base directory relative to
- * which user specific non-essential data files should be
- * stored.
+ /* Locate the correct user configuration directory path */
+ ret = get_config_home(&nsgtk_config_home);
+ if (ret == NSERROR_NOT_FOUND) {
+ /* no config directory exists yet so try to create one */
+ ret = create_config_home(&nsgtk_config_home);
+ }
+ if (ret != NSERROR_OK) {
+ NSLOG(netsurf, INFO,
+ "Unable to locate a configuration directory.");
+ nsgtk_config_home = NULL;
+ }
+
+ /* Initialise gtk */
+ gtk_init(pargc, pargv);
+
+ /* initialise logging. Not fatal if it fails but not much we
+ * can do about it either.
*/
- xdg_cache_dir = getenv("XDG_CACHE_HOME");
+ nslog_init(nslog_stream_configure, pargc, *pargv);
- if ((xdg_cache_dir == NULL) || (*xdg_cache_dir == 0)) {
- /* If $XDG_CACHE_HOME is either not set or empty, a
- * default equal to $HOME/.cache should be used.
- */
+ /* build the common resource path list */
+ respaths = nsgtk_init_resource_path(nsgtk_config_home);
+ if (respaths == NULL) {
+ fprintf(stderr, "Unable to locate resources\n");
+ return 1;
+ }
- home_dir = getenv("HOME");
+ /* initialise the gtk resource handling */
+ ret = nsgtk_init_resources(respaths);
+ if (ret != NSERROR_OK) {
+ fprintf(stderr, "GTK resources failed to initialise (%s)\n",
+ messages_get_errorcode(ret));
+ return ret;
+ }
- /* the HOME envvar is required */
- if (home_dir == NULL) {
- return NSERROR_NOT_DIRECTORY;
- }
+ /* Initialise user options */
+ ret = nsgtk_option_init(pargc, *pargv);
+ if (ret != NSERROR_OK) {
+ fprintf(stderr, "Options failed to initialise (%s)\n",
+ messages_get_errorcode(ret));
+ return ret;
+ }
- ret = check_dirname(home_dir, ".cache/netsurf", &cache_home);
- if (ret != NSERROR_OK) {
- return ret;
- }
- } else {
- ret = check_dirname(xdg_cache_dir, "netsurf", &cache_home);
- if (ret != NSERROR_OK) {
- return ret;
- }
+ /* Initialise translated messages */
+ ret = nsgtk_messages_init(respaths);
+ if (ret != NSERROR_OK) {
+ fprintf(stderr, "Unable to load translated messages (%s)\n",
+ messages_get_errorcode(ret));
+ NSLOG(netsurf, INFO, "Unable to load translated messages");
+ /** \todo decide if message load faliure should be fatal */
+ }
+
+ /* Locate the correct user cache directory path */
+ ret = get_cache_home(cache_home);
+ if (ret == NSERROR_NOT_FOUND) {
+ /* no cache directory exists yet so try to create one */
+ ret = create_cache_home(cache_home);
+ }
+ if (ret != NSERROR_OK) {
+ NSLOG(netsurf, INFO, "Unable to locate a cache directory.");
}
- NSLOG(netsurf, INFO, "\"%s\"", cache_home);
- *cache_home_out = cache_home;
return NSERROR_OK;
}
-static nserror create_cache_home(char **cache_home_out)
+
+#if GTK_CHECK_VERSION(3,14,0)
+
+/**
+ * adds named icons into gtk theme
+ */
+static nserror nsgtk_add_named_icons_to_theme(void)
{
- char *cache_home = NULL;
- char *home_dir;
- char *xdg_cache_dir;
- nserror ret;
+ gtk_icon_theme_add_resource_path(gtk_icon_theme_get_default(),
+ "/org/netsurf/icons");
+ return NSERROR_OK;
+}
- NSLOG(netsurf, INFO, "Attempting to create configuration directory");
+#else
- /* $XDG_CACHE_HOME defines the base directory
- * relative to which user specific cache files
- * should be stored.
+static nserror
+add_builtin_icon(const char *prefix, const char *name, int x, int y)
+{
+ GdkPixbuf *pixbuf;
+ nserror res;
+ char *resname;
+ int resnamelen;
+
+ /* resource name string length allowing for / .png and termination */
+ resnamelen = strlen(prefix) + strlen(name) + 5 + 1 + 4 + 1;
+ resname = malloc(resnamelen);
+ if (resname == NULL) {
+ return NSERROR_NOMEM;
+ }
+ snprintf(resname, resnamelen, "icons%s/%s.png", prefix, name);
+
+ res = nsgdk_pixbuf_new_from_resname(resname, &pixbuf);
+ NSLOG(netsurf, DEEPDEBUG, "%d %s", res, resname);
+ free(resname);
+ if (res != NSERROR_OK) {
+ pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, false, 8, x, y);
+ }
+ gtk_icon_theme_add_builtin_icon(name, y, pixbuf);
+
+ return NSERROR_OK;
+}
+
+
+/**
+ * adds named icons into gtk theme
+ */
+static nserror nsgtk_add_named_icons_to_theme(void)
+{
+ /* these must also be in gtk/resources.c pixbuf_resource *and*
+ * gtk/res/netsurf.gresource.xml
*/
- xdg_cache_dir = getenv("XDG_CACHE_HOME");
+ add_builtin_icon("", "local-history", 8, 32);
+ add_builtin_icon("", "show-cookie", 24, 24);
+ add_builtin_icon("/24x24/actions", "page-info-insecure", 24, 24);
+ add_builtin_icon("/24x24/actions", "page-info-internal", 24, 24);
+ add_builtin_icon("/24x24/actions", "page-info-local", 24, 24);
+ add_builtin_icon("/24x24/actions", "page-info-secure", 24, 24);
+ add_builtin_icon("/24x24/actions", "page-info-warning", 24, 24);
+ add_builtin_icon("/48x48/actions", "page-info-insecure", 48, 48);
+ add_builtin_icon("/48x48/actions", "page-info-internal", 48, 48);
+ add_builtin_icon("/48x48/actions", "page-info-local", 48, 48);
+ add_builtin_icon("/48x48/actions", "page-info-secure", 48, 48);
+ add_builtin_icon("/48x48/actions", "page-info-warning", 48, 48);
+
+ return NSERROR_OK;
+}
+
+#endif
- if ((xdg_cache_dir == NULL) || (*xdg_cache_dir == 0)) {
- home_dir = getenv("HOME");
- if ((home_dir == NULL) || (*home_dir == 0)) {
- return NSERROR_NOT_DIRECTORY;
- }
+/**
+ * setup GTK specific parts of the browser.
+ *
+ * \param argc The number of arguments on the command line
+ * \param argv A string vector of command line arguments.
+ * \respath A string vector of the path elements of resources
+ */
+static nserror nsgtk_setup(int argc, char** argv, char **respath)
+{
+ char buf[PATH_MAX];
+ char *resource_filename;
+ char *addr = NULL;
+ nsurl *url;
+ nserror res;
- ret = netsurf_mkpath(&cache_home, NULL, 4, home_dir, ".cache", "netsurf", "/");
- if (ret != NSERROR_OK) {
- return ret;
- }
- } else {
- ret = netsurf_mkpath(&cache_home, NULL, 3, xdg_cache_dir, "netsurf", "/");
- if (ret != NSERROR_OK) {
- return ret;
- }
+ /* Initialise gtk accelerator table */
+ res = nsgtk_accelerator_init(respaths);
+ if (res != NSERROR_OK) {
+ NSLOG(netsurf, INFO,
+ "Unable to load gtk accelerator configuration");
+ /* not fatal if this does not load */
}
- /* ensure all elements of path exist (the trailing / is required) */
- ret = netsurf_mkdir_all(cache_home);
- if (ret != NSERROR_OK) {
- free(cache_home);
- return ret;
+ /* initialise warning dialog */
+ res = nsgtk_builder_new_from_resname("warning", &warning_builder);
+ if (res != NSERROR_OK) {
+ NSLOG(netsurf, INFO, "Unable to initialise warning dialog");
+ return res;
}
- /* strip the trailing separator */
- cache_home[strlen(cache_home) - 1] = 0;
-
- NSLOG(netsurf, INFO, "\"%s\"", cache_home);
+ gtk_builder_connect_signals(warning_builder, NULL);
- *cache_home_out = cache_home;
+ /* set default icon if its available */
+ res = nsgdk_pixbuf_new_from_resname("netsurf.xpm",
+ &win_default_icon_pixbuf);
+ if (res == NSERROR_OK) {
+ NSLOG(netsurf, INFO, "Seting default window icon");
+ gtk_window_set_default_icon(win_default_icon_pixbuf);
+ }
- return NSERROR_OK;
-}
+ /* Search engine sources */
+ resource_filename = filepath_find(respath, "SearchEngines");
+ search_web_init(resource_filename);
+ if (resource_filename != NULL) {
+ NSLOG(netsurf, INFO, "Using '%s' as Search Engines file",
+ resource_filename);
+ free(resource_filename);
+ }
+ search_web_select_provider(nsoption_int(search_provider));
-static nserror nsgtk_option_init(int *pargc, char** argv)
-{
- nserror ret;
- char *choices = NULL;
+ /* Default favicon */
+ res = nsgdk_pixbuf_new_from_resname("favicon.png", &favicon_pixbuf);
+ if (res != NSERROR_OK) {
+ favicon_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
+ false, 8, 16, 16);
+ }
- /* user options setup */
- ret = nsoption_init(set_defaults, &nsoptions, &nsoptions_default);
- if (ret != NSERROR_OK) {
- return ret;
+ /* add named icons to gtk theme */
+ res = nsgtk_add_named_icons_to_theme();
+ if (res != NSERROR_OK) {
+ NSLOG(netsurf, INFO, "Unable to add named icons to GTK theme.");
+ return res;
}
- /* Attempt to load the user choices */
- ret = netsurf_mkpath(&choices, NULL, 2, nsgtk_config_home, "Choices");
- if (ret == NSERROR_OK) {
- nsoption_read(choices, nsoptions);
- free(choices);
+ /* initialise throbber */
+ res = nsgtk_throbber_init();
+ if (res != NSERROR_OK) {
+ NSLOG(netsurf, INFO, "Unable to initialise throbber.");
+ return res;
}
- /* overide loaded options with those from commandline */
- nsoption_commandline(pargc, argv, nsoptions);
+ /* Initialise completions - cannot fail */
+ nsgtk_completion_init();
- /* ensure all options fall within sensible bounds */
+ /* The tree view system needs to know the screen's DPI, so we
+ * find that out here, rather than when we create a first browser
+ * window.
+ */
+ browser_set_dpi(gdk_screen_get_resolution(gdk_screen_get_default()));
+ NSLOG(netsurf, INFO, "Set CSS DPI to %d", browser_get_dpi());
- /* Attempt to handle nonsense status bar widths. These may exist
- * in people's Choices as the GTK front end used to abuse the
- * status bar width option by using it for an absolute value in px.
- * The GTK front end now correctly uses it as a proportion of window
- * width. Here we assume that a value of less than 15% is wrong
- * and set to the default two thirds. */
- if (nsoption_int(toolbar_status_size) < 1500) {
- nsoption_set_int(toolbar_status_size, 6667);
- }
+ filepath_sfinddef(respath, buf, "mime.types", "/etc/");
+ gtk_fetch_filetype_init(buf);
- return NSERROR_OK;
-}
+ save_complete_init();
+ urldb_load(nsoption_charp(url_file));
+ urldb_load_cookies(nsoption_charp(cookie_file));
+ hotlist_init(nsoption_charp(hotlist_path),
+ nsoption_charp(hotlist_path));
+ /* Initialise top level UI elements */
+ res = nsgtk_download_init();
+ if (res != NSERROR_OK) {
+ NSLOG(netsurf, INFO, "Unable to initialise download window.");
+ return res;
+ }
-static nserror nsgtk_messages_init(char **respaths)
-{
- const char *messages;
- nserror ret;
- const uint8_t *data;
- size_t data_size;
+ /* If there is a url specified on the command line use it */
+ if (argc > 1) {
+ struct stat fs;
+ if (stat(argv[1], &fs) == 0) {
+ size_t addrlen;
+ char *rp = realpath(argv[1], NULL);
+ assert(rp != NULL);
- ret = nsgtk_data_from_resname("Messages", &data, &data_size);
- if (ret == NSERROR_OK) {
- ret = messages_add_from_inline(data, data_size);
- } else {
- /* Obtain path to messages */
- ret = nsgtk_path_from_resname("Messages", &messages);
- if (ret == NSERROR_OK) {
- ret = messages_add_from_file(messages);
+ /* calculate file url length including terminator */
+ addrlen = SLEN("file://") + strlen(rp) + 1;
+ addr = malloc(addrlen);
+ assert(addr != NULL);
+ snprintf(addr, addrlen, "file://%s", rp);
+ free(rp);
+ } else {
+ addr = strdup(argv[1]);
}
}
- return ret;
+ if (addr != NULL) {
+ /* managed to set up based on local launch */
+ } else if (nsoption_charp(homepage_url) != NULL) {
+ addr = strdup(nsoption_charp(homepage_url));
+ } else {
+ addr = strdup(NETSURF_HOMEPAGE);
+ }
+
+ /* create an initial browser window */
+ res = nsurl_create(addr, &url);
+ if (res == NSERROR_OK) {
+ res = browser_window_create(BW_CREATE_HISTORY,
+ url,
+ NULL,
+ NULL,
+ NULL);
+ nsurl_unref(url);
+ }
+
+ free(addr);
+
+ return res;
}
@@ -1084,8 +1165,8 @@ static void nsgtk_finalise(void)
*/
int main(int argc, char** argv)
{
+ nserror res;
char *cache_home = NULL;
- nserror ret;
struct netsurf_table nsgtk_table = {
.misc = nsgtk_misc_table,
.window = nsgtk_window_table,
@@ -1099,94 +1180,43 @@ int main(int argc, char** argv)
.layout = nsgtk_layout_table,
};
- ret = netsurf_register(&nsgtk_table);
- if (ret != NSERROR_OK) {
- die("NetSurf operation table failed registration\n");
- }
-
- /* Locate the correct user configuration directory path */
- ret = get_config_home(&nsgtk_config_home);
- if (ret == NSERROR_NOT_FOUND) {
- /* no config directory exists yet so try to create one */
- ret = create_config_home(&nsgtk_config_home);
- }
- if (ret != NSERROR_OK) {
- NSLOG(netsurf, INFO,
- "Unable to locate a configuration directory.");
- nsgtk_config_home = NULL;
- }
-
- /* Initialise gtk */
- gtk_init(&argc, &argv);
-
- /* initialise logging. Not fatal if it fails but not much we
- * can do about it either.
- */
- nslog_init(nslog_stream_configure, &argc, argv);
-
- /* build the common resource path list */
- respaths = nsgtk_init_resource_path(nsgtk_config_home);
- if (respaths == NULL) {
- fprintf(stderr, "Unable to locate resources\n");
- return 1;
- }
-
- /* initialise the gtk resource handling */
- ret = nsgtk_init_resources(respaths);
- if (ret != NSERROR_OK) {
- fprintf(stderr, "GTK resources failed to initialise (%s)\n",
- messages_get_errorcode(ret));
- return 1;
- }
-
- /* Initialise user options */
- ret = nsgtk_option_init(&argc, argv);
- if (ret != NSERROR_OK) {
- fprintf(stderr, "Options failed to initialise (%s)\n",
- messages_get_errorcode(ret));
+ res = netsurf_register(&nsgtk_table);
+ if (res != NSERROR_OK) {
+ fprintf(stderr,
+ "NetSurf operation table failed registration (%s)\n",
+ messages_get_errorcode(res));
return 1;
}
- /* Initialise translated messages */
- ret = nsgtk_messages_init(respaths);
- if (ret != NSERROR_OK) {
- fprintf(stderr, "Unable to load translated messages (%s)\n",
- messages_get_errorcode(ret));
- NSLOG(netsurf, INFO, "Unable to load translated messages");
- /** \todo decide if message load faliure should be fatal */
- }
-
- /* Locate the correct user cache directory path */
- ret = get_cache_home(&cache_home);
- if (ret == NSERROR_NOT_FOUND) {
- /* no cache directory exists yet so try to create one */
- ret = create_cache_home(&cache_home);
- }
- if (ret != NSERROR_OK) {
- NSLOG(netsurf, INFO, "Unable to locate a cache directory.");
+ /* gtk specific initialisation */
+ res = nsgtk_init(&argc, &argv, &cache_home);
+ if (res != NSERROR_OK) {
+ fprintf(stderr, "NetSurf gtk failed to initialise (%s)\n",
+ messages_get_errorcode(res));
+ return 2;
}
/* core initialisation */
- ret = netsurf_init(cache_home);
+ res = netsurf_init(cache_home);
free(cache_home);
- if (ret != NSERROR_OK) {
+ if (res != NSERROR_OK) {
fprintf(stderr, "NetSurf core failed to initialise (%s)\n",
- messages_get_errorcode(ret));
- return 1;
+ messages_get_errorcode(res));
+ return 3;
}
/* gtk specific initalisation and main run loop */
- ret = nsgtk_setup(argc, argv, respaths);
- if (ret != NSERROR_OK) {
- fprintf(stderr, "NetSurf gtk setup failed (%s)\n",
- messages_get_errorcode(ret));
+ res = nsgtk_setup(argc, argv, respaths);
+ if (res != NSERROR_OK) {
nsgtk_finalise();
- return 2;
- }
+ fprintf(stderr, "NetSurf gtk setup failed (%s)\n",
+ messages_get_errorcode(res));
+ return 4;
+ }
nsgtk_main();
nsgtk_finalise();
-
+
return 0;
}
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=3cf92011c27a0ae650e...
commit 3cf92011c27a0ae650eae61d5b7749e0a5c0f381
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
split out gtk misc operations from gui module
diff --git a/frontends/gtk/Makefile b/frontends/gtk/Makefile
index 3bf3ea0..4f3fd5f 100644
--- a/frontends/gtk/Makefile
+++ b/frontends/gtk/Makefile
@@ -166,11 +166,11 @@ endif
# ----------------------------------------------------------------------------
# S_FRONTEND are sources purely for the GTK frontend
-S_FRONTEND := gui.c schedule.c layout_pango.c bitmap.c plotters.c \
- scaffolding.c gdk.c completion.c throbber.c accelerator.c \
- selection.c window.c fetch.c download.c menu.c print.c \
- search.c tabs.c toolbar.c gettext.c compat.c viewdata.c \
- viewsource.c preferences.c about.c resources.c corewindow.c \
+S_FRONTEND := gui.c misc.c schedule.c layout_pango.c bitmap.c plotters.c \
+ scaffolding.c gdk.c completion.c throbber.c accelerator.c \
+ selection.c window.c fetch.c download.c menu.c print.c \
+ search.c tabs.c toolbar.c gettext.c compat.c viewdata.c \
+ viewsource.c preferences.c about.c resources.c corewindow.c \
local_history.c global_history.c cookies.c hotlist.c page_info.c
# This is the final source build list
diff --git a/frontends/gtk/gui.c b/frontends/gtk/gui.c
index e5006d9..d4b0c71 100644
--- a/frontends/gtk/gui.c
+++ b/frontends/gtk/gui.c
@@ -43,12 +43,10 @@
#include "netsurf/cookie_db.h"
#include "netsurf/browser.h"
#include "netsurf/browser_window.h"
-#include "netsurf/misc.h"
#include "netsurf/netsurf.h"
#include "content/fetch.h"
#include "content/backing_store.h"
#include "desktop/save_complete.h"
-#include "desktop/save_pdf.h"
#include "desktop/searchweb.h"
#include "desktop/hotlist.h"
@@ -70,6 +68,7 @@
#include "gtk/selection.h"
#include "gtk/search.h"
#include "gtk/bitmap.h"
+#include "gtk/misc.h"
#include "gtk/resources.h"
#include "gtk/layout_pango.h"
#include "gtk/accelerator.h"
@@ -327,13 +326,13 @@ static nserror nsgtk_add_named_icons_to_theme(void)
/**
- * Initialize GTK specific parts of the browser.
+ * setup GTK specific parts of the browser.
*
* \param argc The number of arguments on the command line
* \param argv A string vector of command line arguments.
* \respath A string vector of the path elements of resources
*/
-static nserror nsgtk_init(int argc, char** argv, char **respath)
+static nserror nsgtk_setup(int argc, char** argv, char **respath)
{
char buf[PATH_MAX];
char *resource_filename;
@@ -480,136 +479,9 @@ static bool nslog_stream_configure(FILE *fptr)
}
-/**
- * Run the gtk event loop.
- *
- * The same as the standard gtk_main loop except this ensures active
- * FD are added to the gtk poll event set.
- */
-static void nsgtk_main(void)
-{
- fd_set read_fd_set, write_fd_set, exc_fd_set;
- int max_fd;
- GPollFD *fd_list[1000];
- unsigned int fd_count;
-
- while (!nsgtk_complete) {
- max_fd = -1;
- fd_count = 0;
- FD_ZERO(&read_fd_set);
- FD_ZERO(&write_fd_set);
- FD_ZERO(&exc_fd_set);
-
- while (gtk_events_pending())
- gtk_main_iteration_do(TRUE);
-
- schedule_run();
-
- fetch_fdset(&read_fd_set, &write_fd_set, &exc_fd_set, &max_fd);
- for (int i = 0; i <= max_fd; i++) {
- if (FD_ISSET(i, &read_fd_set)) {
- GPollFD *fd = malloc(sizeof *fd);
- fd->fd = i;
- fd->events = G_IO_IN | G_IO_HUP | G_IO_ERR;
- g_main_context_add_poll(0, fd, 0);
- fd_list[fd_count++] = fd;
- }
- if (FD_ISSET(i, &write_fd_set)) {
- GPollFD *fd = malloc(sizeof *fd);
- fd->fd = i;
- fd->events = G_IO_OUT | G_IO_ERR;
- g_main_context_add_poll(0, fd, 0);
- fd_list[fd_count++] = fd;
- }
- if (FD_ISSET(i, &exc_fd_set)) {
- GPollFD *fd = malloc(sizeof *fd);
- fd->fd = i;
- fd->events = G_IO_ERR;
- g_main_context_add_poll(0, fd, 0);
- fd_list[fd_count++] = fd;
- }
- }
-
- gtk_main_iteration();
-
- for (unsigned int i = 0; i != fd_count; i++) {
- g_main_context_remove_poll(0, fd_list[i]);
- free(fd_list[i]);
- }
- }
-}
-
-static void gui_quit(void)
-{
- nserror res;
-
- NSLOG(netsurf, INFO, "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));
- res = nsgtk_cookies_destroy();
- if (res != NSERROR_OK) {
- NSLOG(netsurf, INFO, "Error finalising cookie viewer: %s",
- messages_get_errorcode(res));
- }
-
- res = nsgtk_local_history_destroy();
- if (res != NSERROR_OK) {
- NSLOG(netsurf, INFO,
- "Error finalising local history viewer: %s",
- messages_get_errorcode(res));
- }
-
- res = nsgtk_global_history_destroy();
- if (res != NSERROR_OK) {
- NSLOG(netsurf, INFO,
- "Error finalising global history viewer: %s",
- messages_get_errorcode(res));
- }
-
- res = nsgtk_hotlist_destroy();
- if (res != NSERROR_OK) {
- NSLOG(netsurf, INFO, "Error finalising hotlist viewer: %s",
- messages_get_errorcode(res));
- }
-
- res = hotlist_fini();
- if (res != NSERROR_OK) {
- NSLOG(netsurf, INFO, "Error finalising hotlist: %s",
- messages_get_errorcode(res));
- }
-
- res = save_complete_finalise();
- if (res != NSERROR_OK) {
- NSLOG(netsurf, INFO, "Error finalising save complete: %s",
- messages_get_errorcode(res));
- }
-
- free(nsgtk_config_home);
-
- gtk_fetch_filetype_fin();
-}
-
-static nserror gui_launch_url(struct nsurl *url)
-{
- gboolean ok;
- GError *error = NULL;
-
- ok = nsgtk_show_uri(NULL, nsurl_access(url), GDK_CURRENT_TIME, &error);
- if (ok == TRUE) {
- return NSERROR_OK;
- }
-
- if (error) {
- nsgtk_warning(messages_get("URIOpenError"), error->message);
- g_error_free(error);
- }
- return NSERROR_NO_FETCH_HANDLER;
-}
/* exported function documented in gtk/warn.h */
nserror nsgtk_warning(const char *warning, const char *detail)
@@ -637,127 +509,6 @@ nserror nsgtk_warning(const char *warning, const char *detail)
}
-static void nsgtk_PDF_set_pass(GtkButton *w, gpointer data)
-{
- char **owner_pass = ((void **)data)[0];
- char **user_pass = ((void **)data)[1];
- GtkWindow *wnd = ((void **)data)[2];
- GtkBuilder *password_builder = ((void **)data)[3];
- char *path = ((void **)data)[4];
-
- char *op, *op1;
- char *up, *up1;
-
- op = strdup(gtk_entry_get_text(
- GTK_ENTRY(gtk_builder_get_object(password_builder,
- "entryPDFOwnerPassword"))));
- op1 = strdup(gtk_entry_get_text(
- GTK_ENTRY(gtk_builder_get_object(password_builder,
- "entryPDFOwnerPassword1"))));
- up = strdup(gtk_entry_get_text(
- GTK_ENTRY(gtk_builder_get_object(password_builder,
- "entryPDFUserPassword"))));
- up1 = strdup(gtk_entry_get_text(
- GTK_ENTRY(gtk_builder_get_object(password_builder,
- "entryPDFUserPassword1"))));
-
-
- if (op[0] == '\0') {
- gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(password_builder,
- "labelInfo")),
- "Owner password must be at least 1 character long:");
- free(op);
- free(up);
- } else if (!strcmp(op, up)) {
- gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(password_builder,
- "labelInfo")),
- "User and owner passwords must be different:");
- free(op);
- free(up);
- } else if (!strcmp(op, op1) && !strcmp(up, up1)) {
-
- *owner_pass = op;
- if (up[0] == '\0')
- free(up);
- else
- *user_pass = up;
-
- free(data);
- gtk_widget_destroy(GTK_WIDGET(wnd));
- g_object_unref(G_OBJECT(password_builder));
-
- save_pdf(path);
-
- free(path);
- } else {
- gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(password_builder,
- "labelInfo")), "Passwords not confirmed:");
- free(op);
- free(up);
- }
-
- free(op1);
- free(up1);
-}
-
-static void nsgtk_PDF_no_pass(GtkButton *w, gpointer data)
-{
- GtkWindow *wnd = ((void **)data)[2];
- GtkBuilder *password_builder = ((void **)data)[3];
- char *path = ((void **)data)[4];
-
- free(data);
-
- gtk_widget_destroy(GTK_WIDGET(wnd));
- g_object_unref(G_OBJECT(password_builder));
-
- save_pdf(path);
-
- free(path);
-}
-
-static void nsgtk_pdf_password(char **owner_pass, char **user_pass, char *path)
-{
- GtkButton *ok, *no;
- GtkWindow *wnd;
- void **data;
- GtkBuilder *password_builder;
- nserror res;
-
- res = nsgtk_builder_new_from_resname("password", &password_builder);
- if (res != NSERROR_OK) {
- NSLOG(netsurf, INFO, "Password UI builder init failed");
- return;
- }
-
- gtk_builder_connect_signals(password_builder, NULL);
-
- wnd = GTK_WINDOW(gtk_builder_get_object(password_builder,
- "wndPDFPassword"));
-
- data = malloc(5 * sizeof(void *));
-
- *owner_pass = NULL;
- *user_pass = NULL;
-
- data[0] = owner_pass;
- data[1] = user_pass;
- data[2] = wnd;
- data[3] = password_builder;
- data[4] = path;
-
- ok = GTK_BUTTON(gtk_builder_get_object(password_builder,
- "buttonPDFSetPassword"));
- no = GTK_BUTTON(gtk_builder_get_object(password_builder,
- "buttonPDFNoPassword"));
-
- g_signal_connect(G_OBJECT(ok), "clicked",
- G_CALLBACK(nsgtk_PDF_set_pass), (gpointer)data);
- g_signal_connect(G_OBJECT(no), "clicked",
- G_CALLBACK(nsgtk_PDF_no_pass), (gpointer)data);
-
- gtk_widget_show(GTK_WIDGET(wnd));
-}
uint32_t gtk_gui_gdkkey_to_nskey(GdkEventKey *key)
@@ -1177,14 +928,6 @@ static nserror nsgtk_option_init(int *pargc, char** argv)
return NSERROR_OK;
}
-static struct gui_misc_table nsgtk_misc_table = {
- .schedule = nsgtk_schedule,
-
- .quit = gui_quit,
- .launch_url = gui_launch_url,
- .pdf_password = nsgtk_pdf_password,
- .present_cookies = nsgtk_cookies_present,
-};
static nserror nsgtk_messages_init(char **respaths)
@@ -1207,6 +950,135 @@ static nserror nsgtk_messages_init(char **respaths)
return ret;
}
+
+/**
+ * Run the gtk event loop.
+ *
+ * The same as the standard gtk_main loop except this ensures active
+ * FD are added to the gtk poll event set.
+ */
+static void nsgtk_main(void)
+{
+ fd_set read_fd_set, write_fd_set, exc_fd_set;
+ int max_fd;
+ GPollFD *fd_list[1000];
+ unsigned int fd_count;
+
+ while (!nsgtk_complete) {
+ max_fd = -1;
+ fd_count = 0;
+ FD_ZERO(&read_fd_set);
+ FD_ZERO(&write_fd_set);
+ FD_ZERO(&exc_fd_set);
+
+ while (gtk_events_pending())
+ gtk_main_iteration_do(TRUE);
+
+ schedule_run();
+
+ fetch_fdset(&read_fd_set, &write_fd_set, &exc_fd_set, &max_fd);
+ for (int i = 0; i <= max_fd; i++) {
+ if (FD_ISSET(i, &read_fd_set)) {
+ GPollFD *fd = malloc(sizeof *fd);
+ fd->fd = i;
+ fd->events = G_IO_IN | G_IO_HUP | G_IO_ERR;
+ g_main_context_add_poll(0, fd, 0);
+ fd_list[fd_count++] = fd;
+ }
+ if (FD_ISSET(i, &write_fd_set)) {
+ GPollFD *fd = malloc(sizeof *fd);
+ fd->fd = i;
+ fd->events = G_IO_OUT | G_IO_ERR;
+ g_main_context_add_poll(0, fd, 0);
+ fd_list[fd_count++] = fd;
+ }
+ if (FD_ISSET(i, &exc_fd_set)) {
+ GPollFD *fd = malloc(sizeof *fd);
+ fd->fd = i;
+ fd->events = G_IO_ERR;
+ g_main_context_add_poll(0, fd, 0);
+ fd_list[fd_count++] = fd;
+ }
+ }
+
+ gtk_main_iteration();
+
+ for (unsigned int i = 0; i != fd_count; i++) {
+ g_main_context_remove_poll(0, fd_list[i]);
+ free(fd_list[i]);
+ }
+ }
+}
+
+
+/**
+ * finalise the browser
+ */
+static void nsgtk_finalise(void)
+{
+ nserror res;
+
+ NSLOG(netsurf, INFO, "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));
+
+ res = nsgtk_cookies_destroy();
+ if (res != NSERROR_OK) {
+ NSLOG(netsurf, INFO, "Error finalising cookie viewer: %s",
+ messages_get_errorcode(res));
+ }
+
+ res = nsgtk_local_history_destroy();
+ if (res != NSERROR_OK) {
+ NSLOG(netsurf, INFO,
+ "Error finalising local history viewer: %s",
+ messages_get_errorcode(res));
+ }
+
+ res = nsgtk_global_history_destroy();
+ if (res != NSERROR_OK) {
+ NSLOG(netsurf, INFO,
+ "Error finalising global history viewer: %s",
+ messages_get_errorcode(res));
+ }
+
+ res = nsgtk_hotlist_destroy();
+ if (res != NSERROR_OK) {
+ NSLOG(netsurf, INFO, "Error finalising hotlist viewer: %s",
+ messages_get_errorcode(res));
+ }
+
+ res = hotlist_fini();
+ if (res != NSERROR_OK) {
+ NSLOG(netsurf, INFO, "Error finalising hotlist: %s",
+ messages_get_errorcode(res));
+ }
+
+ res = save_complete_finalise();
+ if (res != NSERROR_OK) {
+ NSLOG(netsurf, INFO, "Error finalising save complete: %s",
+ messages_get_errorcode(res));
+ }
+
+ free(nsgtk_config_home);
+
+ gtk_fetch_filetype_fin();
+
+ /* common finalisation */
+ netsurf_exit();
+
+ /* finalise options */
+ nsoption_finalise(nsoptions, nsoptions_default);
+
+ /* finalise logging */
+ nslog_finalise();
+
+}
+
+
/**
* Main entry point from OS.
*/
@@ -1215,7 +1087,7 @@ int main(int argc, char** argv)
char *cache_home = NULL;
nserror ret;
struct netsurf_table nsgtk_table = {
- .misc = &nsgtk_misc_table,
+ .misc = nsgtk_misc_table,
.window = nsgtk_window_table,
.clipboard = nsgtk_clipboard_table,
.download = nsgtk_download_table,
@@ -1304,22 +1176,17 @@ int main(int argc, char** argv)
}
/* gtk specific initalisation and main run loop */
- ret = nsgtk_init(argc, argv, respaths);
+ ret = nsgtk_setup(argc, argv, respaths);
if (ret != NSERROR_OK) {
- fprintf(stderr, "NetSurf gtk initialise failed (%s)\n",
+ fprintf(stderr, "NetSurf gtk setup failed (%s)\n",
messages_get_errorcode(ret));
- } else {
- nsgtk_main();
- }
+ nsgtk_finalise();
+ return 2;
+ }
- /* common finalisation */
- netsurf_exit();
-
- /* finalise options */
- nsoption_finalise(nsoptions, nsoptions_default);
-
- /* finalise logging */
- nslog_finalise();
+ nsgtk_main();
+ nsgtk_finalise();
+
return 0;
}
diff --git a/frontends/gtk/misc.c b/frontends/gtk/misc.c
new file mode 100644
index 0000000..bda0dd6
--- /dev/null
+++ b/frontends/gtk/misc.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright 2021 Vincemt 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
+ * Implementation of netsurf miscellaneous operations table
+ */
+
+#include <stdbool.h>
+#include <gtk/gtk.h>
+
+#include "utils/errors.h"
+#include "utils/log.h"
+#include "utils/messages.h"
+#include "utils/nsurl.h"
+#include "netsurf/misc.h"
+#include "desktop/save_pdf.h"
+
+#include "gtk/compat.h"
+#include "gtk/warn.h"
+#include "gtk/schedule.h"
+#include "gtk/resources.h"
+#include "gtk/cookies.h"
+#include "gtk/misc.h"
+
+
+static nserror gui_launch_url(struct nsurl *url)
+{
+ gboolean ok;
+ GError *error = NULL;
+
+ ok = nsgtk_show_uri(NULL, nsurl_access(url), GDK_CURRENT_TIME, &error);
+ if (ok == TRUE) {
+ return NSERROR_OK;
+ }
+
+ if (error) {
+ nsgtk_warning(messages_get("URIOpenError"), error->message);
+ g_error_free(error);
+ }
+ return NSERROR_NO_FETCH_HANDLER;
+}
+
+static void nsgtk_PDF_set_pass(GtkButton *w, gpointer data)
+{
+ char **owner_pass = ((void **)data)[0];
+ char **user_pass = ((void **)data)[1];
+ GtkWindow *wnd = ((void **)data)[2];
+ GtkBuilder *password_builder = ((void **)data)[3];
+ char *path = ((void **)data)[4];
+
+ char *op, *op1;
+ char *up, *up1;
+
+ op = strdup(gtk_entry_get_text(
+ GTK_ENTRY(gtk_builder_get_object(password_builder,
+ "entryPDFOwnerPassword"))));
+ op1 = strdup(gtk_entry_get_text(
+ GTK_ENTRY(gtk_builder_get_object(password_builder,
+ "entryPDFOwnerPassword1"))));
+ up = strdup(gtk_entry_get_text(
+ GTK_ENTRY(gtk_builder_get_object(password_builder,
+ "entryPDFUserPassword"))));
+ up1 = strdup(gtk_entry_get_text(
+ GTK_ENTRY(gtk_builder_get_object(password_builder,
+ "entryPDFUserPassword1"))));
+
+
+ if (op[0] == '\0') {
+ gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(password_builder,
+ "labelInfo")),
+ "Owner password must be at least 1 character long:");
+ free(op);
+ free(up);
+ } else if (!strcmp(op, up)) {
+ gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(password_builder,
+ "labelInfo")),
+ "User and owner passwords must be different:");
+ free(op);
+ free(up);
+ } else if (!strcmp(op, op1) && !strcmp(up, up1)) {
+
+ *owner_pass = op;
+ if (up[0] == '\0')
+ free(up);
+ else
+ *user_pass = up;
+
+ free(data);
+ gtk_widget_destroy(GTK_WIDGET(wnd));
+ g_object_unref(G_OBJECT(password_builder));
+
+ save_pdf(path);
+
+ free(path);
+ } else {
+ gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(password_builder,
+ "labelInfo")), "Passwords not confirmed:");
+ free(op);
+ free(up);
+ }
+
+ free(op1);
+ free(up1);
+}
+
+static void nsgtk_PDF_no_pass(GtkButton *w, gpointer data)
+{
+ GtkWindow *wnd = ((void **)data)[2];
+ GtkBuilder *password_builder = ((void **)data)[3];
+ char *path = ((void **)data)[4];
+
+ free(data);
+
+ gtk_widget_destroy(GTK_WIDGET(wnd));
+ g_object_unref(G_OBJECT(password_builder));
+
+ save_pdf(path);
+
+ free(path);
+}
+
+static void nsgtk_pdf_password(char **owner_pass, char **user_pass, char *path)
+{
+ GtkButton *ok, *no;
+ GtkWindow *wnd;
+ void **data;
+ GtkBuilder *password_builder;
+ nserror res;
+
+ res = nsgtk_builder_new_from_resname("password", &password_builder);
+ if (res != NSERROR_OK) {
+ NSLOG(netsurf, INFO, "Password UI builder init failed");
+ return;
+ }
+
+ gtk_builder_connect_signals(password_builder, NULL);
+
+ wnd = GTK_WINDOW(gtk_builder_get_object(password_builder,
+ "wndPDFPassword"));
+
+ data = malloc(5 * sizeof(void *));
+
+ *owner_pass = NULL;
+ *user_pass = NULL;
+
+ data[0] = owner_pass;
+ data[1] = user_pass;
+ data[2] = wnd;
+ data[3] = password_builder;
+ data[4] = path;
+
+ ok = GTK_BUTTON(gtk_builder_get_object(password_builder,
+ "buttonPDFSetPassword"));
+ no = GTK_BUTTON(gtk_builder_get_object(password_builder,
+ "buttonPDFNoPassword"));
+
+ g_signal_connect(G_OBJECT(ok), "clicked",
+ G_CALLBACK(nsgtk_PDF_set_pass), (gpointer)data);
+ g_signal_connect(G_OBJECT(no), "clicked",
+ G_CALLBACK(nsgtk_PDF_no_pass), (gpointer)data);
+
+ gtk_widget_show(GTK_WIDGET(wnd));
+}
+
+
+static struct gui_misc_table misc_table = {
+ .schedule = nsgtk_schedule,
+
+ .launch_url = gui_launch_url,
+ .pdf_password = nsgtk_pdf_password,
+ .present_cookies = nsgtk_cookies_present,
+};
+
+struct gui_misc_table *nsgtk_misc_table = &misc_table;
diff --git a/frontends/gtk/misc.h b/frontends/gtk/misc.h
new file mode 100644
index 0000000..3a02c22
--- /dev/null
+++ b/frontends/gtk/misc.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2021 Vincemt 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 NETSURF_GTK_MISC_H
+#define NETSURF_GTK_MISC_H 1
+
+extern struct gui_misc_table *nsgtk_misc_table;
+
+#endif
diff --git a/include/netsurf/bitmap.h b/include/netsurf/bitmap.h
index a85efce..f5de514 100644
--- a/include/netsurf/bitmap.h
+++ b/include/netsurf/bitmap.h
@@ -143,14 +143,14 @@ struct gui_bitmap_table {
int (*get_height)(void *bitmap);
/**
- * The the *bytes* per pixel.
+ * Get the *bytes* per pixel.
*
* \param bitmap The bitmap
*/
size_t (*get_bpp)(void *bitmap);
/**
- * Savde a bitmap to disc.
+ * Save a bitmap to disc.
*
* \param bitmap The bitmap to save
* \param path The path to save the bitmap to.
-----------------------------------------------------------------------
Summary of changes:
frontends/gtk/Makefile | 10 +-
frontends/gtk/gui.c | 1793 +++++++++++++---------------
frontends/gtk/misc.c | 190 +++
frontends/{atari/filetype.h => gtk/misc.h} | 8 +-
include/netsurf/bitmap.h | 4 +-
5 files changed, 1046 insertions(+), 959 deletions(-)
create mode 100644 frontends/gtk/misc.c
copy frontends/{atari/filetype.h => gtk/misc.h} (80%)
diff --git a/frontends/gtk/Makefile b/frontends/gtk/Makefile
index 3bf3ea0..4f3fd5f 100644
--- a/frontends/gtk/Makefile
+++ b/frontends/gtk/Makefile
@@ -166,11 +166,11 @@ endif
# ----------------------------------------------------------------------------
# S_FRONTEND are sources purely for the GTK frontend
-S_FRONTEND := gui.c schedule.c layout_pango.c bitmap.c plotters.c \
- scaffolding.c gdk.c completion.c throbber.c accelerator.c \
- selection.c window.c fetch.c download.c menu.c print.c \
- search.c tabs.c toolbar.c gettext.c compat.c viewdata.c \
- viewsource.c preferences.c about.c resources.c corewindow.c \
+S_FRONTEND := gui.c misc.c schedule.c layout_pango.c bitmap.c plotters.c \
+ scaffolding.c gdk.c completion.c throbber.c accelerator.c \
+ selection.c window.c fetch.c download.c menu.c print.c \
+ search.c tabs.c toolbar.c gettext.c compat.c viewdata.c \
+ viewsource.c preferences.c about.c resources.c corewindow.c \
local_history.c global_history.c cookies.c hotlist.c page_info.c
# This is the final source build list
diff --git a/frontends/gtk/gui.c b/frontends/gtk/gui.c
index e5006d9..a826b05 100644
--- a/frontends/gtk/gui.c
+++ b/frontends/gtk/gui.c
@@ -43,12 +43,10 @@
#include "netsurf/cookie_db.h"
#include "netsurf/browser.h"
#include "netsurf/browser_window.h"
-#include "netsurf/misc.h"
#include "netsurf/netsurf.h"
#include "content/fetch.h"
#include "content/backing_store.h"
#include "desktop/save_complete.h"
-#include "desktop/save_pdf.h"
#include "desktop/searchweb.h"
#include "desktop/hotlist.h"
@@ -70,34 +68,183 @@
#include "gtk/selection.h"
#include "gtk/search.h"
#include "gtk/bitmap.h"
+#include "gtk/misc.h"
#include "gtk/resources.h"
#include "gtk/layout_pango.h"
#include "gtk/accelerator.h"
bool nsgtk_complete = false;
-char *nsgtk_config_home; /* exported global defined in gtk/gui.h */
+/* exported global defined in gtk/gui.h */
+char *nsgtk_config_home;
-GdkPixbuf *favicon_pixbuf; /** favicon default pixbuf */
-GdkPixbuf *win_default_icon_pixbuf; /** default window icon pixbuf */
+/** favicon default pixbuf */
+GdkPixbuf *favicon_pixbuf;
+
+/** default window icon pixbuf */
+GdkPixbuf *win_default_icon_pixbuf;
GtkBuilder *warning_builder;
-char **respaths; /** resource search path vector */
+/** resource search path vector */
+char **respaths;
-/**
- * Cause an abnormal program termination.
- *
- * \note This never returns and is intended to terminate without any cleanup.
- *
- * \param error The message to display to the user.
- */
-static void die(const char * const error)
+
+/* exported function documented in gtk/warn.h */
+nserror nsgtk_warning(const char *warning, const char *detail)
+{
+ char buf[300]; /* 300 is the size the RISC OS GUI uses */
+ static GtkWindow *nsgtk_warning_window;
+ GtkLabel *WarningLabel;
+
+ NSLOG(netsurf, INFO, "%s %s", warning, detail ? detail : "");
+ fflush(stdout);
+
+ nsgtk_warning_window = GTK_WINDOW(gtk_builder_get_object(warning_builder, "wndWarning"));
+ WarningLabel = GTK_LABEL(gtk_builder_get_object(warning_builder,
+ "labelWarning"));
+
+ snprintf(buf, sizeof(buf), "%s %s", messages_get(warning),
+ detail ? detail : "");
+ buf[sizeof(buf) - 1] = 0;
+
+ gtk_label_set_text(WarningLabel, buf);
+
+ gtk_widget_show_all(GTK_WIDGET(nsgtk_warning_window));
+
+ return NSERROR_OK;
+}
+
+
+/* exported interface documented in gtk/gui.h */
+uint32_t gtk_gui_gdkkey_to_nskey(GdkEventKey *key)
{
- fprintf(stderr, "%s", error);
- exit(EXIT_FAILURE);
+ /* this function will need to become much more complex to support
+ * everything that the RISC OS version does. But this will do for
+ * now. I hope.
+ */
+ switch (key->keyval) {
+
+ case GDK_KEY(Tab):
+ return NS_KEY_TAB;
+
+ case GDK_KEY(BackSpace):
+ if (key->state & GDK_SHIFT_MASK)
+ 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):
+ 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_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_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;
+
+ /* Modifiers - do nothing for now */
+ case GDK_KEY(Shift_L):
+ case GDK_KEY(Shift_R):
+ case GDK_KEY(Control_L):
+ case GDK_KEY(Control_R):
+ case GDK_KEY(Caps_Lock):
+ case GDK_KEY(Shift_Lock):
+ case GDK_KEY(Meta_L):
+ case GDK_KEY(Meta_R):
+ case GDK_KEY(Alt_L):
+ case GDK_KEY(Alt_R):
+ case GDK_KEY(Super_L):
+ case GDK_KEY(Super_R):
+ case GDK_KEY(Hyper_L):
+ case GDK_KEY(Hyper_R):
+ return 0;
+
+ }
+ return gdk_keyval_to_unicode(key->keyval);
}
+
/**
* Create an array of valid paths to search for resources.
*
@@ -156,1066 +303,872 @@ nsgtk_init_resource_path(const char *config_home)
/**
- * Set option defaults for gtk frontend.
- *
- * \param defaults The option table to update.
- * \return error status.
+ * create directory name and check it is acessible and a directory.
*/
-static nserror set_defaults(struct nsoption_s *defaults)
+static nserror
+check_dirname(const char *path, const char *leaf, char **dirname_out)
{
- char *fname;
- GtkSettings *settings;
- GtkIconSize tooliconsize;
- GtkToolbarStyle toolbarstyle;
-
- /* cookie file default */
- fname = NULL;
- netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "Cookies");
- if (fname != NULL) {
- nsoption_setnull_charp(cookie_file, fname);
- }
-
- /* cookie jar default */
- fname = NULL;
- netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "Cookies");
- if (fname != NULL) {
- nsoption_setnull_charp(cookie_jar, fname);
- }
+ nserror ret;
+ char *dirname = NULL;
+ struct stat dirname_stat;
- /* url database default */
- fname = NULL;
- netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "URLs");
- if (fname != NULL) {
- nsoption_setnull_charp(url_file, fname);
+ ret = netsurf_mkpath(&dirname, NULL, 2, path, leaf);
+ if (ret != NSERROR_OK) {
+ return ret;
}
- /* bookmark database default */
- fname = NULL;
- netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "Hotlist");
- if (fname != NULL) {
- nsoption_setnull_charp(hotlist_path, fname);
+ /* ensure access is possible and the entry is actualy
+ * a directory.
+ */
+ if (stat(dirname, &dirname_stat) == 0) {
+ if (S_ISDIR(dirname_stat.st_mode)) {
+ if (access(dirname, R_OK | W_OK) == 0) {
+ *dirname_out = dirname;
+ return NSERROR_OK;
+ } else {
+ ret = NSERROR_PERMISSION;
+ }
+ } else {
+ ret = NSERROR_NOT_DIRECTORY;
+ }
+ } else {
+ ret = NSERROR_NOT_FOUND;
}
- /* download directory default */
- fname = getenv("HOME");
- if (fname != NULL) {
- nsoption_setnull_charp(downloads_directory, strdup(fname));
- }
+ free(dirname);
- if ((nsoption_charp(cookie_file) == NULL) ||
- (nsoption_charp(cookie_jar) == NULL) ||
- (nsoption_charp(url_file) == NULL) ||
- (nsoption_charp(hotlist_path) == NULL) ||
- (nsoption_charp(downloads_directory) == NULL)) {
- NSLOG(netsurf, INFO,
- "Failed initialising default resource paths");
- return NSERROR_BAD_PARAMETER;
- }
+ return ret;
+}
- /* set default font names */
- nsoption_set_charp(font_sans, strdup("Sans"));
- nsoption_set_charp(font_serif, strdup("Serif"));
- nsoption_set_charp(font_mono, strdup("Monospace"));
- nsoption_set_charp(font_cursive, strdup("Serif"));
- nsoption_set_charp(font_fantasy, strdup("Serif"));
- /* Default toolbar button type to system defaults */
+/**
+ * Get the path to the config directory.
+ *
+ * @param config_home_out Path to configuration directory.
+ * @return NSERROR_OK on sucess and \a config_home_out updated else error code.
+ */
+static nserror get_config_home(char **config_home_out)
+{
+ nserror ret;
+ char *home_dir;
+ char *xdg_config_dir;
+ char *config_home;
- settings = gtk_settings_get_default();
- g_object_get(settings,
- "gtk-toolbar-icon-size", &tooliconsize,
- "gtk-toolbar-style", &toolbarstyle, NULL);
+ home_dir = getenv("HOME");
- switch (toolbarstyle) {
- case GTK_TOOLBAR_ICONS:
- if (tooliconsize == GTK_ICON_SIZE_SMALL_TOOLBAR) {
- nsoption_set_int(button_type, 1);
- } else {
- nsoption_set_int(button_type, 2);
+ /* The old $HOME/.netsurf/ directory should be used if it
+ * exists and is accessible.
+ */
+ if (home_dir != NULL) {
+ ret = check_dirname(home_dir, ".netsurf", &config_home);
+ if (ret == NSERROR_OK) {
+ NSLOG(netsurf, INFO, "\"%s\"", config_home);
+ *config_home_out = config_home;
+ return ret;
}
- break;
+ }
- case GTK_TOOLBAR_TEXT:
- nsoption_set_int(button_type, 4);
- break;
+ /* $XDG_CONFIG_HOME defines the base directory
+ * relative to which user specific configuration files
+ * should be stored.
+ */
+ xdg_config_dir = getenv("XDG_CONFIG_HOME");
- case GTK_TOOLBAR_BOTH:
- case GTK_TOOLBAR_BOTH_HORIZ:
- /* no labels in default configuration */
- default:
- /* No system default, so use large icons */
- nsoption_set_int(button_type, 2);
- break;
- }
+ if ((xdg_config_dir == NULL) || (*xdg_config_dir == 0)) {
+ /* If $XDG_CONFIG_HOME is either not set or empty, a
+ * default equal to $HOME/.config should be used.
+ */
- /* set default items in toolbar */
- nsoption_set_charp(toolbar_items,
- strdup("back/history/forward/reloadstop/url_bar/websearch/openmenu"));
+ /** @todo the meaning of empty is never defined so I
+ * am assuming it is a zero length string but is it
+ * supposed to mean "whitespace" and if so what counts
+ * as whitespace? (are tabs etc. counted or should
+ * isspace() be used)
+ */
- /* set default for menu and tool bar visibility */
- nsoption_set_charp(bar_show, strdup("tool"));
+ /* the HOME envvar is required */
+ if (home_dir == NULL) {
+ return NSERROR_NOT_DIRECTORY;
+ }
- return NSERROR_OK;
-}
+ ret = check_dirname(home_dir, ".config/netsurf", &config_home);
+ if (ret != NSERROR_OK) {
+ return ret;
+ }
+ } else {
+ ret = check_dirname(xdg_config_dir, "netsurf", &config_home);
+ if (ret != NSERROR_OK) {
+ return ret;
+ }
+ }
-#if GTK_CHECK_VERSION(3,14,0)
+ NSLOG(netsurf, INFO, "\"%s\"", config_home);
-/**
- * adds named icons into gtk theme
- */
-static nserror nsgtk_add_named_icons_to_theme(void)
-{
- gtk_icon_theme_add_resource_path(gtk_icon_theme_get_default(),
- "/org/netsurf/icons");
+ *config_home_out = config_home;
return NSERROR_OK;
}
-#else
-static nserror
-add_builtin_icon(const char *prefix, const char *name, int x, int y)
+static nserror create_config_home(char **config_home_out)
{
- GdkPixbuf *pixbuf;
- nserror res;
- char *resname;
- int resnamelen;
+ char *config_home = NULL;
+ char *home_dir;
+ char *xdg_config_dir;
+ nserror ret;
- /* resource name string length allowing for / .png and termination */
- resnamelen = strlen(prefix) + strlen(name) + 5 + 1 + 4 + 1;
- resname = malloc(resnamelen);
- if (resname == NULL) {
- return NSERROR_NOMEM;
+ NSLOG(netsurf, INFO, "Attempting to create configuration directory");
+
+ /* $XDG_CONFIG_HOME defines the base directory
+ * relative to which user specific configuration files
+ * should be stored.
+ */
+ xdg_config_dir = getenv("XDG_CONFIG_HOME");
+
+ if ((xdg_config_dir == NULL) || (*xdg_config_dir == 0)) {
+ home_dir = getenv("HOME");
+
+ if ((home_dir == NULL) || (*home_dir == 0)) {
+ return NSERROR_NOT_DIRECTORY;
+ }
+
+ ret = netsurf_mkpath(&config_home, NULL, 4, home_dir, ".config","netsurf", "/");
+ if (ret != NSERROR_OK) {
+ return ret;
+ }
+ } else {
+ ret = netsurf_mkpath(&config_home, NULL, 3, xdg_config_dir, "netsurf", "/");
+ if (ret != NSERROR_OK) {
+ return ret;
+ }
}
- snprintf(resname, resnamelen, "icons%s/%s.png", prefix, name);
- res = nsgdk_pixbuf_new_from_resname(resname, &pixbuf);
- NSLOG(netsurf, DEEPDEBUG, "%d %s", res, resname);
- free(resname);
- if (res != NSERROR_OK) {
- pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, false, 8, x, y);
+ /* ensure all elements of path exist (the trailing / is required) */
+ ret = netsurf_mkdir_all(config_home);
+ if (ret != NSERROR_OK) {
+ free(config_home);
+ return ret;
}
- gtk_icon_theme_add_builtin_icon(name, y, pixbuf);
+
+ /* strip the trailing separator */
+ config_home[strlen(config_home) - 1] = 0;
+
+ NSLOG(netsurf, INFO, "\"%s\"", config_home);
+
+ *config_home_out = config_home;
return NSERROR_OK;
}
+
/**
- * adds named icons into gtk theme
+ * Ensures output logging stream is correctly configured
*/
-static nserror nsgtk_add_named_icons_to_theme(void)
+static bool nslog_stream_configure(FILE *fptr)
{
- /* these must also be in gtk/resources.c pixbuf_resource *and*
- * gtk/res/netsurf.gresource.xml
- */
- add_builtin_icon("", "local-history", 8, 32);
- add_builtin_icon("", "show-cookie", 24, 24);
- add_builtin_icon("/24x24/actions", "page-info-insecure", 24, 24);
- add_builtin_icon("/24x24/actions", "page-info-internal", 24, 24);
- add_builtin_icon("/24x24/actions", "page-info-local", 24, 24);
- add_builtin_icon("/24x24/actions", "page-info-secure", 24, 24);
- add_builtin_icon("/24x24/actions", "page-info-warning", 24, 24);
- add_builtin_icon("/48x48/actions", "page-info-insecure", 48, 48);
- add_builtin_icon("/48x48/actions", "page-info-internal", 48, 48);
- add_builtin_icon("/48x48/actions", "page-info-local", 48, 48);
- add_builtin_icon("/48x48/actions", "page-info-secure", 48, 48);
- add_builtin_icon("/48x48/actions", "page-info-warning", 48, 48);
+ /* set log stream to be non-buffering */
+ setbuf(fptr, NULL);
- return NSERROR_OK;
+ return true;
}
-#endif
-
/**
- * Initialize GTK specific parts of the browser.
+ * Set option defaults for gtk frontend.
*
- * \param argc The number of arguments on the command line
- * \param argv A string vector of command line arguments.
- * \respath A string vector of the path elements of resources
+ * \param defaults The option table to update.
+ * \return error status.
*/
-static nserror nsgtk_init(int argc, char** argv, char **respath)
+static nserror set_defaults(struct nsoption_s *defaults)
{
- char buf[PATH_MAX];
- char *resource_filename;
- char *addr = NULL;
- nsurl *url;
- nserror res;
+ char *fname;
+ GtkSettings *settings;
+ GtkIconSize tooliconsize;
+ GtkToolbarStyle toolbarstyle;
- /* Initialise gtk accelerator table */
- res = nsgtk_accelerator_init(respaths);
- if (res != NSERROR_OK) {
- NSLOG(netsurf, INFO,
- "Unable to load gtk accelerator configuration");
- /* not fatal if this does not load */
+ /* cookie file default */
+ fname = NULL;
+ netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "Cookies");
+ if (fname != NULL) {
+ nsoption_setnull_charp(cookie_file, fname);
}
- /* initialise warning dialog */
- res = nsgtk_builder_new_from_resname("warning", &warning_builder);
- if (res != NSERROR_OK) {
- NSLOG(netsurf, INFO, "Unable to initialise warning dialog");
- return res;
+ /* cookie jar default */
+ fname = NULL;
+ netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "Cookies");
+ if (fname != NULL) {
+ nsoption_setnull_charp(cookie_jar, fname);
}
- gtk_builder_connect_signals(warning_builder, NULL);
-
- /* set default icon if its available */
- res = nsgdk_pixbuf_new_from_resname("netsurf.xpm",
- &win_default_icon_pixbuf);
- if (res == NSERROR_OK) {
- NSLOG(netsurf, INFO, "Seting default window icon");
- gtk_window_set_default_icon(win_default_icon_pixbuf);
+ /* url database default */
+ fname = NULL;
+ netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "URLs");
+ if (fname != NULL) {
+ nsoption_setnull_charp(url_file, fname);
}
- /* Search engine sources */
- resource_filename = filepath_find(respath, "SearchEngines");
- search_web_init(resource_filename);
- if (resource_filename != NULL) {
- NSLOG(netsurf, INFO, "Using '%s' as Search Engines file",
- resource_filename);
- free(resource_filename);
+ /* bookmark database default */
+ fname = NULL;
+ netsurf_mkpath(&fname, NULL, 2, nsgtk_config_home, "Hotlist");
+ if (fname != NULL) {
+ nsoption_setnull_charp(hotlist_path, fname);
}
- search_web_select_provider(nsoption_int(search_provider));
- /* Default favicon */
- res = nsgdk_pixbuf_new_from_resname("favicon.png", &favicon_pixbuf);
- if (res != NSERROR_OK) {
- favicon_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
- false, 8, 16, 16);
+ /* download directory default */
+ fname = getenv("HOME");
+ if (fname != NULL) {
+ nsoption_setnull_charp(downloads_directory, strdup(fname));
}
- /* add named icons to gtk theme */
- res = nsgtk_add_named_icons_to_theme();
- if (res != NSERROR_OK) {
- NSLOG(netsurf, INFO, "Unable to add named icons to GTK theme.");
- return res;
+ if ((nsoption_charp(cookie_file) == NULL) ||
+ (nsoption_charp(cookie_jar) == NULL) ||
+ (nsoption_charp(url_file) == NULL) ||
+ (nsoption_charp(hotlist_path) == NULL) ||
+ (nsoption_charp(downloads_directory) == NULL)) {
+ NSLOG(netsurf, INFO,
+ "Failed initialising default resource paths");
+ return NSERROR_BAD_PARAMETER;
}
- /* initialise throbber */
- res = nsgtk_throbber_init();
- if (res != NSERROR_OK) {
- NSLOG(netsurf, INFO, "Unable to initialise throbber.");
- return res;
- }
+ /* set default font names */
+ nsoption_set_charp(font_sans, strdup("Sans"));
+ nsoption_set_charp(font_serif, strdup("Serif"));
+ nsoption_set_charp(font_mono, strdup("Monospace"));
+ nsoption_set_charp(font_cursive, strdup("Serif"));
+ nsoption_set_charp(font_fantasy, strdup("Serif"));
- /* Initialise completions - cannot fail */
- nsgtk_completion_init();
+ /* Default toolbar button type to system defaults */
- /* The tree view system needs to know the screen's DPI, so we
- * find that out here, rather than when we create a first browser
- * window.
- */
- browser_set_dpi(gdk_screen_get_resolution(gdk_screen_get_default()));
- NSLOG(netsurf, INFO, "Set CSS DPI to %d", browser_get_dpi());
-
- filepath_sfinddef(respath, buf, "mime.types", "/etc/");
- gtk_fetch_filetype_init(buf);
+ settings = gtk_settings_get_default();
+ g_object_get(settings,
+ "gtk-toolbar-icon-size", &tooliconsize,
+ "gtk-toolbar-style", &toolbarstyle, NULL);
- save_complete_init();
+ switch (toolbarstyle) {
+ case GTK_TOOLBAR_ICONS:
+ if (tooliconsize == GTK_ICON_SIZE_SMALL_TOOLBAR) {
+ nsoption_set_int(button_type, 1);
+ } else {
+ nsoption_set_int(button_type, 2);
+ }
+ break;
- urldb_load(nsoption_charp(url_file));
- urldb_load_cookies(nsoption_charp(cookie_file));
- hotlist_init(nsoption_charp(hotlist_path),
- nsoption_charp(hotlist_path));
+ case GTK_TOOLBAR_TEXT:
+ nsoption_set_int(button_type, 4);
+ break;
- /* Initialise top level UI elements */
- res = nsgtk_download_init();
- if (res != NSERROR_OK) {
- NSLOG(netsurf, INFO, "Unable to initialise download window.");
- return res;
+ case GTK_TOOLBAR_BOTH:
+ case GTK_TOOLBAR_BOTH_HORIZ:
+ /* no labels in default configuration */
+ default:
+ /* No system default, so use large icons */
+ nsoption_set_int(button_type, 2);
+ break;
}
- /* If there is a url specified on the command line use it */
- if (argc > 1) {
- struct stat fs;
- if (stat(argv[1], &fs) == 0) {
- size_t addrlen;
- char *rp = realpath(argv[1], NULL);
- assert(rp != NULL);
+ /* set default items in toolbar */
+ nsoption_set_charp(toolbar_items,
+ strdup("back/history/forward/reloadstop/url_bar/websearch/openmenu"));
- /* calculate file url length including terminator */
- addrlen = SLEN("file://") + strlen(rp) + 1;
- addr = malloc(addrlen);
- assert(addr != NULL);
- snprintf(addr, addrlen, "file://%s", rp);
- free(rp);
- } else {
- addr = strdup(argv[1]);
- }
- }
- if (addr != NULL) {
- /* managed to set up based on local launch */
- } else if (nsoption_charp(homepage_url) != NULL) {
- addr = strdup(nsoption_charp(homepage_url));
- } else {
- addr = strdup(NETSURF_HOMEPAGE);
+ /* set default for menu and tool bar visibility */
+ nsoption_set_charp(bar_show, strdup("tool"));
+
+ return NSERROR_OK;
+}
+
+
+/**
+ * Initialise user options
+ *
+ * Initialise the browser configuration options. These are set by:
+ * - set generic defaults suitable for the gtk frontend
+ * - user choices loaded from Choices file
+ * - command line parameters
+ */
+static nserror nsgtk_option_init(int *pargc, char** argv)
+{
+ nserror ret;
+ char *choices = NULL;
+
+ /* user options setup */
+ ret = nsoption_init(set_defaults, &nsoptions, &nsoptions_default);
+ if (ret != NSERROR_OK) {
+ return ret;
}
- /* create an initial browser window */
- res = nsurl_create(addr, &url);
- if (res == NSERROR_OK) {
- res = browser_window_create(BW_CREATE_HISTORY,
- url,
- NULL,
- NULL,
- NULL);
- nsurl_unref(url);
+ /* Attempt to load the user choices */
+ ret = netsurf_mkpath(&choices, NULL, 2, nsgtk_config_home, "Choices");
+ if (ret == NSERROR_OK) {
+ nsoption_read(choices, nsoptions);
+ free(choices);
}
- free(addr);
+ /* overide loaded options with those from commandline */
+ nsoption_commandline(pargc, argv, nsoptions);
- return res;
-}
+ /* ensure all options fall within sensible bounds */
+
+ /* Attempt to handle nonsense status bar widths. These may exist
+ * in people's Choices as the GTK front end used to abuse the
+ * status bar width option by using it for an absolute value in px.
+ * The GTK front end now correctly uses it as a proportion of window
+ * width. Here we assume that a value of less than 15% is wrong
+ * and set to the default two thirds. */
+ if (nsoption_int(toolbar_status_size) < 1500) {
+ nsoption_set_int(toolbar_status_size, 6667);
+ }
+ return NSERROR_OK;
+}
/**
- * Ensures output logging stream is correctly configured
+ * initialise message translation
*/
-static bool nslog_stream_configure(FILE *fptr)
+static nserror nsgtk_messages_init(char **respaths)
{
- /* set log stream to be non-buffering */
- setbuf(fptr, NULL);
+ const char *messages;
+ nserror ret;
+ const uint8_t *data;
+ size_t data_size;
- return true;
+ ret = nsgtk_data_from_resname("Messages", &data, &data_size);
+ if (ret == NSERROR_OK) {
+ ret = messages_add_from_inline(data, data_size);
+ } else {
+ /* Obtain path to messages */
+ ret = nsgtk_path_from_resname("Messages", &messages);
+ if (ret == NSERROR_OK) {
+ ret = messages_add_from_file(messages);
+ }
+ }
+ return ret;
}
/**
- * Run the gtk event loop.
+ * Get the path to the cache directory.
*
- * The same as the standard gtk_main loop except this ensures active
- * FD are added to the gtk poll event set.
+ * @param cache_home_out Path to cache directory.
+ * @return NSERROR_OK on sucess and \a cache_home_out updated else error code.
*/
-static void nsgtk_main(void)
+static nserror get_cache_home(char **cache_home_out)
{
- fd_set read_fd_set, write_fd_set, exc_fd_set;
- int max_fd;
- GPollFD *fd_list[1000];
- unsigned int fd_count;
+ nserror ret;
+ char *xdg_cache_dir;
+ char *cache_home;
+ char *home_dir;
- while (!nsgtk_complete) {
- max_fd = -1;
- fd_count = 0;
- FD_ZERO(&read_fd_set);
- FD_ZERO(&write_fd_set);
- FD_ZERO(&exc_fd_set);
+ /* $XDG_CACHE_HOME defines the base directory relative to
+ * which user specific non-essential data files should be
+ * stored.
+ */
+ xdg_cache_dir = getenv("XDG_CACHE_HOME");
- while (gtk_events_pending())
- gtk_main_iteration_do(TRUE);
+ if ((xdg_cache_dir == NULL) || (*xdg_cache_dir == 0)) {
+ /* If $XDG_CACHE_HOME is either not set or empty, a
+ * default equal to $HOME/.cache should be used.
+ */
- schedule_run();
+ home_dir = getenv("HOME");
- fetch_fdset(&read_fd_set, &write_fd_set, &exc_fd_set, &max_fd);
- for (int i = 0; i <= max_fd; i++) {
- if (FD_ISSET(i, &read_fd_set)) {
- GPollFD *fd = malloc(sizeof *fd);
- fd->fd = i;
- fd->events = G_IO_IN | G_IO_HUP | G_IO_ERR;
- g_main_context_add_poll(0, fd, 0);
- fd_list[fd_count++] = fd;
- }
- if (FD_ISSET(i, &write_fd_set)) {
- GPollFD *fd = malloc(sizeof *fd);
- fd->fd = i;
- fd->events = G_IO_OUT | G_IO_ERR;
- g_main_context_add_poll(0, fd, 0);
- fd_list[fd_count++] = fd;
- }
- if (FD_ISSET(i, &exc_fd_set)) {
- GPollFD *fd = malloc(sizeof *fd);
- fd->fd = i;
- fd->events = G_IO_ERR;
- g_main_context_add_poll(0, fd, 0);
- fd_list[fd_count++] = fd;
- }
+ /* the HOME envvar is required */
+ if (home_dir == NULL) {
+ return NSERROR_NOT_DIRECTORY;
}
- gtk_main_iteration();
-
- for (unsigned int i = 0; i != fd_count; i++) {
- g_main_context_remove_poll(0, fd_list[i]);
- free(fd_list[i]);
+ ret = check_dirname(home_dir, ".cache/netsurf", &cache_home);
+ if (ret != NSERROR_OK) {
+ return ret;
+ }
+ } else {
+ ret = check_dirname(xdg_cache_dir, "netsurf", &cache_home);
+ if (ret != NSERROR_OK) {
+ return ret;
}
}
+
+ NSLOG(netsurf, INFO, "\"%s\"", cache_home);
+
+ *cache_home_out = cache_home;
+ return NSERROR_OK;
}
-static void gui_quit(void)
+/**
+ * create a cache directory
+ */
+static nserror create_cache_home(char **cache_home_out)
{
- nserror res;
+ char *cache_home = NULL;
+ char *home_dir;
+ char *xdg_cache_dir;
+ nserror ret;
- NSLOG(netsurf, INFO, "Quitting GUI");
+ NSLOG(netsurf, INFO, "Attempting to create cache directory");
- /* 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));
+ /* $XDG_CACHE_HOME defines the base directory
+ * relative to which user specific cache files
+ * should be stored.
+ */
+ xdg_cache_dir = getenv("XDG_CACHE_HOME");
- res = nsgtk_cookies_destroy();
- if (res != NSERROR_OK) {
- NSLOG(netsurf, INFO, "Error finalising cookie viewer: %s",
- messages_get_errorcode(res));
- }
+ if ((xdg_cache_dir == NULL) || (*xdg_cache_dir == 0)) {
+ home_dir = getenv("HOME");
- res = nsgtk_local_history_destroy();
- if (res != NSERROR_OK) {
- NSLOG(netsurf, INFO,
- "Error finalising local history viewer: %s",
- messages_get_errorcode(res));
- }
+ if ((home_dir == NULL) || (*home_dir == 0)) {
+ return NSERROR_NOT_DIRECTORY;
+ }
- res = nsgtk_global_history_destroy();
- if (res != NSERROR_OK) {
- NSLOG(netsurf, INFO,
- "Error finalising global history viewer: %s",
- messages_get_errorcode(res));
- }
-
- res = nsgtk_hotlist_destroy();
- if (res != NSERROR_OK) {
- NSLOG(netsurf, INFO, "Error finalising hotlist viewer: %s",
- messages_get_errorcode(res));
+ ret = netsurf_mkpath(&cache_home, NULL, 4, home_dir, ".cache", "netsurf", "/");
+ if (ret != NSERROR_OK) {
+ return ret;
+ }
+ } else {
+ ret = netsurf_mkpath(&cache_home, NULL, 3, xdg_cache_dir, "netsurf", "/");
+ if (ret != NSERROR_OK) {
+ return ret;
+ }
}
- res = hotlist_fini();
- if (res != NSERROR_OK) {
- NSLOG(netsurf, INFO, "Error finalising hotlist: %s",
- messages_get_errorcode(res));
+ /* ensure all elements of path exist (the trailing / is required) */
+ ret = netsurf_mkdir_all(cache_home);
+ if (ret != NSERROR_OK) {
+ free(cache_home);
+ return ret;
}
- res = save_complete_finalise();
- if (res != NSERROR_OK) {
- NSLOG(netsurf, INFO, "Error finalising save complete: %s",
- messages_get_errorcode(res));
- }
+ /* strip the trailing separator */
+ cache_home[strlen(cache_home) - 1] = 0;
- free(nsgtk_config_home);
+ NSLOG(netsurf, INFO, "\"%s\"", cache_home);
- gtk_fetch_filetype_fin();
+ *cache_home_out = cache_home;
+
+ return NSERROR_OK;
}
-static nserror gui_launch_url(struct nsurl *url)
+
+/**
+ * GTK specific initialisation
+ */
+static nserror nsgtk_init(int *pargc, char ***pargv, char **cache_home)
{
- gboolean ok;
- GError *error = NULL;
+ nserror ret;
- ok = nsgtk_show_uri(NULL, nsurl_access(url), GDK_CURRENT_TIME, &error);
- if (ok == TRUE) {
- return NSERROR_OK;
+ /* Locate the correct user configuration directory path */
+ ret = get_config_home(&nsgtk_config_home);
+ if (ret == NSERROR_NOT_FOUND) {
+ /* no config directory exists yet so try to create one */
+ ret = create_config_home(&nsgtk_config_home);
}
-
- if (error) {
- nsgtk_warning(messages_get("URIOpenError"), error->message);
- g_error_free(error);
+ if (ret != NSERROR_OK) {
+ NSLOG(netsurf, INFO,
+ "Unable to locate a configuration directory.");
+ nsgtk_config_home = NULL;
}
- return NSERROR_NO_FETCH_HANDLER;
-}
-/* exported function documented in gtk/warn.h */
-nserror nsgtk_warning(const char *warning, const char *detail)
-{
- char buf[300]; /* 300 is the size the RISC OS GUI uses */
- static GtkWindow *nsgtk_warning_window;
- GtkLabel *WarningLabel;
+ /* Initialise gtk */
+ gtk_init(pargc, pargv);
- NSLOG(netsurf, INFO, "%s %s", warning, detail ? detail : "");
- fflush(stdout);
+ /* initialise logging. Not fatal if it fails but not much we
+ * can do about it either.
+ */
+ nslog_init(nslog_stream_configure, pargc, *pargv);
- nsgtk_warning_window = GTK_WINDOW(gtk_builder_get_object(warning_builder, "wndWarning"));
- WarningLabel = GTK_LABEL(gtk_builder_get_object(warning_builder,
- "labelWarning"));
+ /* build the common resource path list */
+ respaths = nsgtk_init_resource_path(nsgtk_config_home);
+ if (respaths == NULL) {
+ fprintf(stderr, "Unable to locate resources\n");
+ return 1;
+ }
- snprintf(buf, sizeof(buf), "%s %s", messages_get(warning),
- detail ? detail : "");
- buf[sizeof(buf) - 1] = 0;
+ /* initialise the gtk resource handling */
+ ret = nsgtk_init_resources(respaths);
+ if (ret != NSERROR_OK) {
+ fprintf(stderr, "GTK resources failed to initialise (%s)\n",
+ messages_get_errorcode(ret));
+ return ret;
+ }
- gtk_label_set_text(WarningLabel, buf);
+ /* Initialise user options */
+ ret = nsgtk_option_init(pargc, *pargv);
+ if (ret != NSERROR_OK) {
+ fprintf(stderr, "Options failed to initialise (%s)\n",
+ messages_get_errorcode(ret));
+ return ret;
+ }
+
+ /* Initialise translated messages */
+ ret = nsgtk_messages_init(respaths);
+ if (ret != NSERROR_OK) {
+ fprintf(stderr, "Unable to load translated messages (%s)\n",
+ messages_get_errorcode(ret));
+ NSLOG(netsurf, INFO, "Unable to load translated messages");
+ /** \todo decide if message load faliure should be fatal */
+ }
+
+ /* Locate the correct user cache directory path */
+ ret = get_cache_home(cache_home);
+ if (ret == NSERROR_NOT_FOUND) {
+ /* no cache directory exists yet so try to create one */
+ ret = create_cache_home(cache_home);
+ }
+ if (ret != NSERROR_OK) {
+ NSLOG(netsurf, INFO, "Unable to locate a cache directory.");
+ }
- gtk_widget_show_all(GTK_WIDGET(nsgtk_warning_window));
return NSERROR_OK;
}
-static void nsgtk_PDF_set_pass(GtkButton *w, gpointer data)
+#if GTK_CHECK_VERSION(3,14,0)
+
+/**
+ * adds named icons into gtk theme
+ */
+static nserror nsgtk_add_named_icons_to_theme(void)
{
- char **owner_pass = ((void **)data)[0];
- char **user_pass = ((void **)data)[1];
- GtkWindow *wnd = ((void **)data)[2];
- GtkBuilder *password_builder = ((void **)data)[3];
- char *path = ((void **)data)[4];
-
- char *op, *op1;
- char *up, *up1;
-
- op = strdup(gtk_entry_get_text(
- GTK_ENTRY(gtk_builder_get_object(password_builder,
- "entryPDFOwnerPassword"))));
- op1 = strdup(gtk_entry_get_text(
- GTK_ENTRY(gtk_builder_get_object(password_builder,
- "entryPDFOwnerPassword1"))));
- up = strdup(gtk_entry_get_text(
- GTK_ENTRY(gtk_builder_get_object(password_builder,
- "entryPDFUserPassword"))));
- up1 = strdup(gtk_entry_get_text(
- GTK_ENTRY(gtk_builder_get_object(password_builder,
- "entryPDFUserPassword1"))));
-
-
- if (op[0] == '\0') {
- gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(password_builder,
- "labelInfo")),
- "Owner password must be at least 1 character long:");
- free(op);
- free(up);
- } else if (!strcmp(op, up)) {
- gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(password_builder,
- "labelInfo")),
- "User and owner passwords must be different:");
- free(op);
- free(up);
- } else if (!strcmp(op, op1) && !strcmp(up, up1)) {
-
- *owner_pass = op;
- if (up[0] == '\0')
- free(up);
- else
- *user_pass = up;
+ gtk_icon_theme_add_resource_path(gtk_icon_theme_get_default(),
+ "/org/netsurf/icons");
+ return NSERROR_OK;
+}
- free(data);
- gtk_widget_destroy(GTK_WIDGET(wnd));
- g_object_unref(G_OBJECT(password_builder));
+#else
- save_pdf(path);
+static nserror
+add_builtin_icon(const char *prefix, const char *name, int x, int y)
+{
+ GdkPixbuf *pixbuf;
+ nserror res;
+ char *resname;
+ int resnamelen;
- free(path);
- } else {
- gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(password_builder,
- "labelInfo")), "Passwords not confirmed:");
- free(op);
- free(up);
+ /* resource name string length allowing for / .png and termination */
+ resnamelen = strlen(prefix) + strlen(name) + 5 + 1 + 4 + 1;
+ resname = malloc(resnamelen);
+ if (resname == NULL) {
+ return NSERROR_NOMEM;
+ }
+ snprintf(resname, resnamelen, "icons%s/%s.png", prefix, name);
+
+ res = nsgdk_pixbuf_new_from_resname(resname, &pixbuf);
+ NSLOG(netsurf, DEEPDEBUG, "%d %s", res, resname);
+ free(resname);
+ if (res != NSERROR_OK) {
+ pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, false, 8, x, y);
}
+ gtk_icon_theme_add_builtin_icon(name, y, pixbuf);
- free(op1);
- free(up1);
+ return NSERROR_OK;
}
-static void nsgtk_PDF_no_pass(GtkButton *w, gpointer data)
-{
- GtkWindow *wnd = ((void **)data)[2];
- GtkBuilder *password_builder = ((void **)data)[3];
- char *path = ((void **)data)[4];
- free(data);
+/**
+ * adds named icons into gtk theme
+ */
+static nserror nsgtk_add_named_icons_to_theme(void)
+{
+ /* these must also be in gtk/resources.c pixbuf_resource *and*
+ * gtk/res/netsurf.gresource.xml
+ */
+ add_builtin_icon("", "local-history", 8, 32);
+ add_builtin_icon("", "show-cookie", 24, 24);
+ add_builtin_icon("/24x24/actions", "page-info-insecure", 24, 24);
+ add_builtin_icon("/24x24/actions", "page-info-internal", 24, 24);
+ add_builtin_icon("/24x24/actions", "page-info-local", 24, 24);
+ add_builtin_icon("/24x24/actions", "page-info-secure", 24, 24);
+ add_builtin_icon("/24x24/actions", "page-info-warning", 24, 24);
+ add_builtin_icon("/48x48/actions", "page-info-insecure", 48, 48);
+ add_builtin_icon("/48x48/actions", "page-info-internal", 48, 48);
+ add_builtin_icon("/48x48/actions", "page-info-local", 48, 48);
+ add_builtin_icon("/48x48/actions", "page-info-secure", 48, 48);
+ add_builtin_icon("/48x48/actions", "page-info-warning", 48, 48);
- gtk_widget_destroy(GTK_WIDGET(wnd));
- g_object_unref(G_OBJECT(password_builder));
+ return NSERROR_OK;
+}
- save_pdf(path);
+#endif
- free(path);
-}
-static void nsgtk_pdf_password(char **owner_pass, char **user_pass, char *path)
+/**
+ * setup GTK specific parts of the browser.
+ *
+ * \param argc The number of arguments on the command line
+ * \param argv A string vector of command line arguments.
+ * \respath A string vector of the path elements of resources
+ */
+static nserror nsgtk_setup(int argc, char** argv, char **respath)
{
- GtkButton *ok, *no;
- GtkWindow *wnd;
- void **data;
- GtkBuilder *password_builder;
+ char buf[PATH_MAX];
+ char *resource_filename;
+ char *addr = NULL;
+ nsurl *url;
nserror res;
- res = nsgtk_builder_new_from_resname("password", &password_builder);
+ /* Initialise gtk accelerator table */
+ res = nsgtk_accelerator_init(respaths);
if (res != NSERROR_OK) {
- NSLOG(netsurf, INFO, "Password UI builder init failed");
- return;
+ NSLOG(netsurf, INFO,
+ "Unable to load gtk accelerator configuration");
+ /* not fatal if this does not load */
}
- gtk_builder_connect_signals(password_builder, NULL);
-
- wnd = GTK_WINDOW(gtk_builder_get_object(password_builder,
- "wndPDFPassword"));
+ /* initialise warning dialog */
+ res = nsgtk_builder_new_from_resname("warning", &warning_builder);
+ if (res != NSERROR_OK) {
+ NSLOG(netsurf, INFO, "Unable to initialise warning dialog");
+ return res;
+ }
- data = malloc(5 * sizeof(void *));
+ gtk_builder_connect_signals(warning_builder, NULL);
- *owner_pass = NULL;
- *user_pass = NULL;
+ /* set default icon if its available */
+ res = nsgdk_pixbuf_new_from_resname("netsurf.xpm",
+ &win_default_icon_pixbuf);
+ if (res == NSERROR_OK) {
+ NSLOG(netsurf, INFO, "Seting default window icon");
+ gtk_window_set_default_icon(win_default_icon_pixbuf);
+ }
- data[0] = owner_pass;
- data[1] = user_pass;
- data[2] = wnd;
- data[3] = password_builder;
- data[4] = path;
+ /* Search engine sources */
+ resource_filename = filepath_find(respath, "SearchEngines");
+ search_web_init(resource_filename);
+ if (resource_filename != NULL) {
+ NSLOG(netsurf, INFO, "Using '%s' as Search Engines file",
+ resource_filename);
+ free(resource_filename);
+ }
+ search_web_select_provider(nsoption_int(search_provider));
- ok = GTK_BUTTON(gtk_builder_get_object(password_builder,
- "buttonPDFSetPassword"));
- no = GTK_BUTTON(gtk_builder_get_object(password_builder,
- "buttonPDFNoPassword"));
+ /* Default favicon */
+ res = nsgdk_pixbuf_new_from_resname("favicon.png", &favicon_pixbuf);
+ if (res != NSERROR_OK) {
+ favicon_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
+ false, 8, 16, 16);
+ }
- g_signal_connect(G_OBJECT(ok), "clicked",
- G_CALLBACK(nsgtk_PDF_set_pass), (gpointer)data);
- g_signal_connect(G_OBJECT(no), "clicked",
- G_CALLBACK(nsgtk_PDF_no_pass), (gpointer)data);
+ /* add named icons to gtk theme */
+ res = nsgtk_add_named_icons_to_theme();
+ if (res != NSERROR_OK) {
+ NSLOG(netsurf, INFO, "Unable to add named icons to GTK theme.");
+ return res;
+ }
- gtk_widget_show(GTK_WIDGET(wnd));
-}
+ /* initialise throbber */
+ res = nsgtk_throbber_init();
+ if (res != NSERROR_OK) {
+ NSLOG(netsurf, INFO, "Unable to initialise throbber.");
+ return res;
+ }
+ /* Initialise completions - cannot fail */
+ nsgtk_completion_init();
-uint32_t gtk_gui_gdkkey_to_nskey(GdkEventKey *key)
-{
- /* this function will need to become much more complex to support
- * everything that the RISC OS version does. But this will do for
- * now. I hope.
+ /* The tree view system needs to know the screen's DPI, so we
+ * find that out here, rather than when we create a first browser
+ * window.
*/
- switch (key->keyval) {
-
- case GDK_KEY(Tab):
- return NS_KEY_TAB;
+ browser_set_dpi(gdk_screen_get_resolution(gdk_screen_get_default()));
+ NSLOG(netsurf, INFO, "Set CSS DPI to %d", browser_get_dpi());
- case GDK_KEY(BackSpace):
- if (key->state & GDK_SHIFT_MASK)
- return NS_KEY_DELETE_LINE_START;
- else
- return NS_KEY_DELETE_LEFT;
+ filepath_sfinddef(respath, buf, "mime.types", "/etc/");
+ gtk_fetch_filetype_init(buf);
- case GDK_KEY(Delete):
- if (key->state & GDK_SHIFT_MASK)
- return NS_KEY_DELETE_LINE_END;
- else
- return NS_KEY_DELETE_RIGHT;
+ save_complete_init();
- 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_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_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;
-
- /* Modifiers - do nothing for now */
- case GDK_KEY(Shift_L):
- case GDK_KEY(Shift_R):
- case GDK_KEY(Control_L):
- case GDK_KEY(Control_R):
- case GDK_KEY(Caps_Lock):
- case GDK_KEY(Shift_Lock):
- case GDK_KEY(Meta_L):
- case GDK_KEY(Meta_R):
- case GDK_KEY(Alt_L):
- case GDK_KEY(Alt_R):
- case GDK_KEY(Super_L):
- case GDK_KEY(Super_R):
- case GDK_KEY(Hyper_L):
- case GDK_KEY(Hyper_R):
- return 0;
+ urldb_load(nsoption_charp(url_file));
+ urldb_load_cookies(nsoption_charp(cookie_file));
+ hotlist_init(nsoption_charp(hotlist_path),
+ nsoption_charp(hotlist_path));
+ /* Initialise top level UI elements */
+ res = nsgtk_download_init();
+ if (res != NSERROR_OK) {
+ NSLOG(netsurf, INFO, "Unable to initialise download window.");
+ return res;
}
- return gdk_keyval_to_unicode(key->keyval);
-}
-
-
-/**
- * create directory name and check it is acessible and a directory.
- */
-static nserror
-check_dirname(const char *path, const char *leaf, char **dirname_out)
-{
- nserror ret;
- char *dirname = NULL;
- struct stat dirname_stat;
- ret = netsurf_mkpath(&dirname, NULL, 2, path, leaf);
- if (ret != NSERROR_OK) {
- return ret;
- }
+ /* If there is a url specified on the command line use it */
+ if (argc > 1) {
+ struct stat fs;
+ if (stat(argv[1], &fs) == 0) {
+ size_t addrlen;
+ char *rp = realpath(argv[1], NULL);
+ assert(rp != NULL);
- /* ensure access is possible and the entry is actualy
- * a directory.
- */
- if (stat(dirname, &dirname_stat) == 0) {
- if (S_ISDIR(dirname_stat.st_mode)) {
- if (access(dirname, R_OK | W_OK) == 0) {
- *dirname_out = dirname;
- return NSERROR_OK;
- } else {
- ret = NSERROR_PERMISSION;
- }
+ /* calculate file url length including terminator */
+ addrlen = SLEN("file://") + strlen(rp) + 1;
+ addr = malloc(addrlen);
+ assert(addr != NULL);
+ snprintf(addr, addrlen, "file://%s", rp);
+ free(rp);
} else {
- ret = NSERROR_NOT_DIRECTORY;
- }
- } else {
- ret = NSERROR_NOT_FOUND;
- }
-
- free(dirname);
-
- return ret;
-}
-
-/**
- * Get the path to the config directory.
- *
- * @param config_home_out Path to configuration directory.
- * @return NSERROR_OK on sucess and \a config_home_out updated else error code.
- */
-static nserror get_config_home(char **config_home_out)
-{
- nserror ret;
- char *home_dir;
- char *xdg_config_dir;
- char *config_home;
-
- home_dir = getenv("HOME");
-
- /* The old $HOME/.netsurf/ directory should be used if it
- * exists and is accessible.
- */
- if (home_dir != NULL) {
- ret = check_dirname(home_dir, ".netsurf", &config_home);
- if (ret == NSERROR_OK) {
- NSLOG(netsurf, INFO, "\"%s\"", config_home);
- *config_home_out = config_home;
- return ret;
- }
- }
-
- /* $XDG_CONFIG_HOME defines the base directory
- * relative to which user specific configuration files
- * should be stored.
- */
- xdg_config_dir = getenv("XDG_CONFIG_HOME");
-
- if ((xdg_config_dir == NULL) || (*xdg_config_dir == 0)) {
- /* If $XDG_CONFIG_HOME is either not set or empty, a
- * default equal to $HOME/.config should be used.
- */
-
- /** @todo the meaning of empty is never defined so I
- * am assuming it is a zero length string but is it
- * supposed to mean "whitespace" and if so what counts
- * as whitespace? (are tabs etc. counted or should
- * isspace() be used)
- */
-
- /* the HOME envvar is required */
- if (home_dir == NULL) {
- return NSERROR_NOT_DIRECTORY;
- }
-
- ret = check_dirname(home_dir, ".config/netsurf", &config_home);
- if (ret != NSERROR_OK) {
- return ret;
- }
- } else {
- ret = check_dirname(xdg_config_dir, "netsurf", &config_home);
- if (ret != NSERROR_OK) {
- return ret;
+ addr = strdup(argv[1]);
}
}
-
- NSLOG(netsurf, INFO, "\"%s\"", config_home);
-
- *config_home_out = config_home;
- return NSERROR_OK;
-}
-
-static nserror create_config_home(char **config_home_out)
-{
- char *config_home = NULL;
- char *home_dir;
- char *xdg_config_dir;
- nserror ret;
-
- NSLOG(netsurf, INFO, "Attempting to create configuration directory");
-
- /* $XDG_CONFIG_HOME defines the base directory
- * relative to which user specific configuration files
- * should be stored.
- */
- xdg_config_dir = getenv("XDG_CONFIG_HOME");
-
- if ((xdg_config_dir == NULL) || (*xdg_config_dir == 0)) {
- home_dir = getenv("HOME");
-
- if ((home_dir == NULL) || (*home_dir == 0)) {
- return NSERROR_NOT_DIRECTORY;
- }
-
- ret = netsurf_mkpath(&config_home, NULL, 4, home_dir, ".config","netsurf", "/");
- if (ret != NSERROR_OK) {
- return ret;
- }
+ if (addr != NULL) {
+ /* managed to set up based on local launch */
+ } else if (nsoption_charp(homepage_url) != NULL) {
+ addr = strdup(nsoption_charp(homepage_url));
} else {
- ret = netsurf_mkpath(&config_home, NULL, 3, xdg_config_dir, "netsurf", "/");
- if (ret != NSERROR_OK) {
- return ret;
- }
- }
-
- /* ensure all elements of path exist (the trailing / is required) */
- ret = netsurf_mkdir_all(config_home);
- if (ret != NSERROR_OK) {
- free(config_home);
- return ret;
+ addr = strdup(NETSURF_HOMEPAGE);
}
- /* strip the trailing separator */
- config_home[strlen(config_home) - 1] = 0;
-
- NSLOG(netsurf, INFO, "\"%s\"", config_home);
-
- *config_home_out = config_home;
-
- return NSERROR_OK;
-}
-
-/**
- * Get the path to the cache directory.
- *
- * @param cache_home_out Path to cache directory.
- * @return NSERROR_OK on sucess and \a cache_home_out updated else error code.
- */
-static nserror get_cache_home(char **cache_home_out)
-{
- nserror ret;
- char *xdg_cache_dir;
- char *cache_home;
- char *home_dir;
-
- /* $XDG_CACHE_HOME defines the base directory relative to
- * which user specific non-essential data files should be
- * stored.
- */
- xdg_cache_dir = getenv("XDG_CACHE_HOME");
-
- if ((xdg_cache_dir == NULL) || (*xdg_cache_dir == 0)) {
- /* If $XDG_CACHE_HOME is either not set or empty, a
- * default equal to $HOME/.cache should be used.
- */
-
- home_dir = getenv("HOME");
-
- /* the HOME envvar is required */
- if (home_dir == NULL) {
- return NSERROR_NOT_DIRECTORY;
- }
-
- ret = check_dirname(home_dir, ".cache/netsurf", &cache_home);
- if (ret != NSERROR_OK) {
- return ret;
- }
- } else {
- ret = check_dirname(xdg_cache_dir, "netsurf", &cache_home);
- if (ret != NSERROR_OK) {
- return ret;
- }
+ /* create an initial browser window */
+ res = nsurl_create(addr, &url);
+ if (res == NSERROR_OK) {
+ res = browser_window_create(BW_CREATE_HISTORY,
+ url,
+ NULL,
+ NULL,
+ NULL);
+ nsurl_unref(url);
}
- NSLOG(netsurf, INFO, "\"%s\"", cache_home);
+ free(addr);
- *cache_home_out = cache_home;
- return NSERROR_OK;
+ return res;
}
-static nserror create_cache_home(char **cache_home_out)
+
+/**
+ * Run the gtk event loop.
+ *
+ * The same as the standard gtk_main loop except this ensures active
+ * FD are added to the gtk poll event set.
+ */
+static void nsgtk_main(void)
{
- char *cache_home = NULL;
- char *home_dir;
- char *xdg_cache_dir;
- nserror ret;
+ fd_set read_fd_set, write_fd_set, exc_fd_set;
+ int max_fd;
+ GPollFD *fd_list[1000];
+ unsigned int fd_count;
- NSLOG(netsurf, INFO, "Attempting to create configuration directory");
+ while (!nsgtk_complete) {
+ max_fd = -1;
+ fd_count = 0;
+ FD_ZERO(&read_fd_set);
+ FD_ZERO(&write_fd_set);
+ FD_ZERO(&exc_fd_set);
- /* $XDG_CACHE_HOME defines the base directory
- * relative to which user specific cache files
- * should be stored.
- */
- xdg_cache_dir = getenv("XDG_CACHE_HOME");
+ while (gtk_events_pending())
+ gtk_main_iteration_do(TRUE);
- if ((xdg_cache_dir == NULL) || (*xdg_cache_dir == 0)) {
- home_dir = getenv("HOME");
+ schedule_run();
- if ((home_dir == NULL) || (*home_dir == 0)) {
- return NSERROR_NOT_DIRECTORY;
+ fetch_fdset(&read_fd_set, &write_fd_set, &exc_fd_set, &max_fd);
+ for (int i = 0; i <= max_fd; i++) {
+ if (FD_ISSET(i, &read_fd_set)) {
+ GPollFD *fd = malloc(sizeof *fd);
+ fd->fd = i;
+ fd->events = G_IO_IN | G_IO_HUP | G_IO_ERR;
+ g_main_context_add_poll(0, fd, 0);
+ fd_list[fd_count++] = fd;
+ }
+ if (FD_ISSET(i, &write_fd_set)) {
+ GPollFD *fd = malloc(sizeof *fd);
+ fd->fd = i;
+ fd->events = G_IO_OUT | G_IO_ERR;
+ g_main_context_add_poll(0, fd, 0);
+ fd_list[fd_count++] = fd;
+ }
+ if (FD_ISSET(i, &exc_fd_set)) {
+ GPollFD *fd = malloc(sizeof *fd);
+ fd->fd = i;
+ fd->events = G_IO_ERR;
+ g_main_context_add_poll(0, fd, 0);
+ fd_list[fd_count++] = fd;
+ }
}
- ret = netsurf_mkpath(&cache_home, NULL, 4, home_dir, ".cache", "netsurf", "/");
- if (ret != NSERROR_OK) {
- return ret;
- }
- } else {
- ret = netsurf_mkpath(&cache_home, NULL, 3, xdg_cache_dir, "netsurf", "/");
- if (ret != NSERROR_OK) {
- return ret;
- }
- }
+ gtk_main_iteration();
- /* ensure all elements of path exist (the trailing / is required) */
- ret = netsurf_mkdir_all(cache_home);
- if (ret != NSERROR_OK) {
- free(cache_home);
- return ret;
+ for (unsigned int i = 0; i != fd_count; i++) {
+ g_main_context_remove_poll(0, fd_list[i]);
+ free(fd_list[i]);
+ }
}
+}
- /* strip the trailing separator */
- cache_home[strlen(cache_home) - 1] = 0;
- NSLOG(netsurf, INFO, "\"%s\"", cache_home);
+/**
+ * finalise the browser
+ */
+static void nsgtk_finalise(void)
+{
+ nserror res;
- *cache_home_out = cache_home;
+ NSLOG(netsurf, INFO, "Quitting GUI");
- return NSERROR_OK;
-}
+ /* 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));
-static nserror nsgtk_option_init(int *pargc, char** argv)
-{
- nserror ret;
- char *choices = NULL;
+ res = nsgtk_cookies_destroy();
+ if (res != NSERROR_OK) {
+ NSLOG(netsurf, INFO, "Error finalising cookie viewer: %s",
+ messages_get_errorcode(res));
+ }
- /* user options setup */
- ret = nsoption_init(set_defaults, &nsoptions, &nsoptions_default);
- if (ret != NSERROR_OK) {
- return ret;
+ res = nsgtk_local_history_destroy();
+ if (res != NSERROR_OK) {
+ NSLOG(netsurf, INFO,
+ "Error finalising local history viewer: %s",
+ messages_get_errorcode(res));
}
- /* Attempt to load the user choices */
- ret = netsurf_mkpath(&choices, NULL, 2, nsgtk_config_home, "Choices");
- if (ret == NSERROR_OK) {
- nsoption_read(choices, nsoptions);
- free(choices);
+ res = nsgtk_global_history_destroy();
+ if (res != NSERROR_OK) {
+ NSLOG(netsurf, INFO,
+ "Error finalising global history viewer: %s",
+ messages_get_errorcode(res));
}
- /* overide loaded options with those from commandline */
- nsoption_commandline(pargc, argv, nsoptions);
+ res = nsgtk_hotlist_destroy();
+ if (res != NSERROR_OK) {
+ NSLOG(netsurf, INFO, "Error finalising hotlist viewer: %s",
+ messages_get_errorcode(res));
+ }
- /* ensure all options fall within sensible bounds */
+ res = hotlist_fini();
+ if (res != NSERROR_OK) {
+ NSLOG(netsurf, INFO, "Error finalising hotlist: %s",
+ messages_get_errorcode(res));
+ }
- /* Attempt to handle nonsense status bar widths. These may exist
- * in people's Choices as the GTK front end used to abuse the
- * status bar width option by using it for an absolute value in px.
- * The GTK front end now correctly uses it as a proportion of window
- * width. Here we assume that a value of less than 15% is wrong
- * and set to the default two thirds. */
- if (nsoption_int(toolbar_status_size) < 1500) {
- nsoption_set_int(toolbar_status_size, 6667);
+ res = save_complete_finalise();
+ if (res != NSERROR_OK) {
+ NSLOG(netsurf, INFO, "Error finalising save complete: %s",
+ messages_get_errorcode(res));
}
- return NSERROR_OK;
-}
+ free(nsgtk_config_home);
-static struct gui_misc_table nsgtk_misc_table = {
- .schedule = nsgtk_schedule,
+ gtk_fetch_filetype_fin();
- .quit = gui_quit,
- .launch_url = gui_launch_url,
- .pdf_password = nsgtk_pdf_password,
- .present_cookies = nsgtk_cookies_present,
-};
+ /* common finalisation */
+ netsurf_exit();
+ /* finalise options */
+ nsoption_finalise(nsoptions, nsoptions_default);
-static nserror nsgtk_messages_init(char **respaths)
-{
- const char *messages;
- nserror ret;
- const uint8_t *data;
- size_t data_size;
+ /* finalise logging */
+ nslog_finalise();
- ret = nsgtk_data_from_resname("Messages", &data, &data_size);
- if (ret == NSERROR_OK) {
- ret = messages_add_from_inline(data, data_size);
- } else {
- /* Obtain path to messages */
- ret = nsgtk_path_from_resname("Messages", &messages);
- if (ret == NSERROR_OK) {
- ret = messages_add_from_file(messages);
- }
- }
- return ret;
}
+
/**
* Main entry point from OS.
*/
int main(int argc, char** argv)
{
+ nserror res;
char *cache_home = NULL;
- nserror ret;
struct netsurf_table nsgtk_table = {
- .misc = &nsgtk_misc_table,
+ .misc = nsgtk_misc_table,
.window = nsgtk_window_table,
.clipboard = nsgtk_clipboard_table,
.download = nsgtk_download_table,
@@ -1227,99 +1180,43 @@ int main(int argc, char** argv)
.layout = nsgtk_layout_table,
};
- ret = netsurf_register(&nsgtk_table);
- if (ret != NSERROR_OK) {
- die("NetSurf operation table failed registration\n");
- }
-
- /* Locate the correct user configuration directory path */
- ret = get_config_home(&nsgtk_config_home);
- if (ret == NSERROR_NOT_FOUND) {
- /* no config directory exists yet so try to create one */
- ret = create_config_home(&nsgtk_config_home);
- }
- if (ret != NSERROR_OK) {
- NSLOG(netsurf, INFO,
- "Unable to locate a configuration directory.");
- nsgtk_config_home = NULL;
- }
-
- /* Initialise gtk */
- gtk_init(&argc, &argv);
-
- /* initialise logging. Not fatal if it fails but not much we
- * can do about it either.
- */
- nslog_init(nslog_stream_configure, &argc, argv);
-
- /* build the common resource path list */
- respaths = nsgtk_init_resource_path(nsgtk_config_home);
- if (respaths == NULL) {
- fprintf(stderr, "Unable to locate resources\n");
- return 1;
- }
-
- /* initialise the gtk resource handling */
- ret = nsgtk_init_resources(respaths);
- if (ret != NSERROR_OK) {
- fprintf(stderr, "GTK resources failed to initialise (%s)\n",
- messages_get_errorcode(ret));
- return 1;
- }
-
- /* Initialise user options */
- ret = nsgtk_option_init(&argc, argv);
- if (ret != NSERROR_OK) {
- fprintf(stderr, "Options failed to initialise (%s)\n",
- messages_get_errorcode(ret));
+ res = netsurf_register(&nsgtk_table);
+ if (res != NSERROR_OK) {
+ fprintf(stderr,
+ "NetSurf operation table failed registration (%s)\n",
+ messages_get_errorcode(res));
return 1;
}
- /* Initialise translated messages */
- ret = nsgtk_messages_init(respaths);
- if (ret != NSERROR_OK) {
- fprintf(stderr, "Unable to load translated messages (%s)\n",
- messages_get_errorcode(ret));
- NSLOG(netsurf, INFO, "Unable to load translated messages");
- /** \todo decide if message load faliure should be fatal */
- }
-
- /* Locate the correct user cache directory path */
- ret = get_cache_home(&cache_home);
- if (ret == NSERROR_NOT_FOUND) {
- /* no cache directory exists yet so try to create one */
- ret = create_cache_home(&cache_home);
- }
- if (ret != NSERROR_OK) {
- NSLOG(netsurf, INFO, "Unable to locate a cache directory.");
+ /* gtk specific initialisation */
+ res = nsgtk_init(&argc, &argv, &cache_home);
+ if (res != NSERROR_OK) {
+ fprintf(stderr, "NetSurf gtk failed to initialise (%s)\n",
+ messages_get_errorcode(res));
+ return 2;
}
/* core initialisation */
- ret = netsurf_init(cache_home);
+ res = netsurf_init(cache_home);
free(cache_home);
- if (ret != NSERROR_OK) {
+ if (res != NSERROR_OK) {
fprintf(stderr, "NetSurf core failed to initialise (%s)\n",
- messages_get_errorcode(ret));
- return 1;
+ messages_get_errorcode(res));
+ return 3;
}
/* gtk specific initalisation and main run loop */
- ret = nsgtk_init(argc, argv, respaths);
- if (ret != NSERROR_OK) {
- fprintf(stderr, "NetSurf gtk initialise failed (%s)\n",
- messages_get_errorcode(ret));
- } else {
- nsgtk_main();
+ res = nsgtk_setup(argc, argv, respaths);
+ if (res != NSERROR_OK) {
+ nsgtk_finalise();
+ fprintf(stderr, "NetSurf gtk setup failed (%s)\n",
+ messages_get_errorcode(res));
+ return 4;
}
- /* common finalisation */
- netsurf_exit();
-
- /* finalise options */
- nsoption_finalise(nsoptions, nsoptions_default);
+ nsgtk_main();
- /* finalise logging */
- nslog_finalise();
+ nsgtk_finalise();
return 0;
}
diff --git a/frontends/gtk/misc.c b/frontends/gtk/misc.c
new file mode 100644
index 0000000..bda0dd6
--- /dev/null
+++ b/frontends/gtk/misc.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright 2021 Vincemt 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
+ * Implementation of netsurf miscellaneous operations table
+ */
+
+#include <stdbool.h>
+#include <gtk/gtk.h>
+
+#include "utils/errors.h"
+#include "utils/log.h"
+#include "utils/messages.h"
+#include "utils/nsurl.h"
+#include "netsurf/misc.h"
+#include "desktop/save_pdf.h"
+
+#include "gtk/compat.h"
+#include "gtk/warn.h"
+#include "gtk/schedule.h"
+#include "gtk/resources.h"
+#include "gtk/cookies.h"
+#include "gtk/misc.h"
+
+
+static nserror gui_launch_url(struct nsurl *url)
+{
+ gboolean ok;
+ GError *error = NULL;
+
+ ok = nsgtk_show_uri(NULL, nsurl_access(url), GDK_CURRENT_TIME, &error);
+ if (ok == TRUE) {
+ return NSERROR_OK;
+ }
+
+ if (error) {
+ nsgtk_warning(messages_get("URIOpenError"), error->message);
+ g_error_free(error);
+ }
+ return NSERROR_NO_FETCH_HANDLER;
+}
+
+static void nsgtk_PDF_set_pass(GtkButton *w, gpointer data)
+{
+ char **owner_pass = ((void **)data)[0];
+ char **user_pass = ((void **)data)[1];
+ GtkWindow *wnd = ((void **)data)[2];
+ GtkBuilder *password_builder = ((void **)data)[3];
+ char *path = ((void **)data)[4];
+
+ char *op, *op1;
+ char *up, *up1;
+
+ op = strdup(gtk_entry_get_text(
+ GTK_ENTRY(gtk_builder_get_object(password_builder,
+ "entryPDFOwnerPassword"))));
+ op1 = strdup(gtk_entry_get_text(
+ GTK_ENTRY(gtk_builder_get_object(password_builder,
+ "entryPDFOwnerPassword1"))));
+ up = strdup(gtk_entry_get_text(
+ GTK_ENTRY(gtk_builder_get_object(password_builder,
+ "entryPDFUserPassword"))));
+ up1 = strdup(gtk_entry_get_text(
+ GTK_ENTRY(gtk_builder_get_object(password_builder,
+ "entryPDFUserPassword1"))));
+
+
+ if (op[0] == '\0') {
+ gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(password_builder,
+ "labelInfo")),
+ "Owner password must be at least 1 character long:");
+ free(op);
+ free(up);
+ } else if (!strcmp(op, up)) {
+ gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(password_builder,
+ "labelInfo")),
+ "User and owner passwords must be different:");
+ free(op);
+ free(up);
+ } else if (!strcmp(op, op1) && !strcmp(up, up1)) {
+
+ *owner_pass = op;
+ if (up[0] == '\0')
+ free(up);
+ else
+ *user_pass = up;
+
+ free(data);
+ gtk_widget_destroy(GTK_WIDGET(wnd));
+ g_object_unref(G_OBJECT(password_builder));
+
+ save_pdf(path);
+
+ free(path);
+ } else {
+ gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(password_builder,
+ "labelInfo")), "Passwords not confirmed:");
+ free(op);
+ free(up);
+ }
+
+ free(op1);
+ free(up1);
+}
+
+static void nsgtk_PDF_no_pass(GtkButton *w, gpointer data)
+{
+ GtkWindow *wnd = ((void **)data)[2];
+ GtkBuilder *password_builder = ((void **)data)[3];
+ char *path = ((void **)data)[4];
+
+ free(data);
+
+ gtk_widget_destroy(GTK_WIDGET(wnd));
+ g_object_unref(G_OBJECT(password_builder));
+
+ save_pdf(path);
+
+ free(path);
+}
+
+static void nsgtk_pdf_password(char **owner_pass, char **user_pass, char *path)
+{
+ GtkButton *ok, *no;
+ GtkWindow *wnd;
+ void **data;
+ GtkBuilder *password_builder;
+ nserror res;
+
+ res = nsgtk_builder_new_from_resname("password", &password_builder);
+ if (res != NSERROR_OK) {
+ NSLOG(netsurf, INFO, "Password UI builder init failed");
+ return;
+ }
+
+ gtk_builder_connect_signals(password_builder, NULL);
+
+ wnd = GTK_WINDOW(gtk_builder_get_object(password_builder,
+ "wndPDFPassword"));
+
+ data = malloc(5 * sizeof(void *));
+
+ *owner_pass = NULL;
+ *user_pass = NULL;
+
+ data[0] = owner_pass;
+ data[1] = user_pass;
+ data[2] = wnd;
+ data[3] = password_builder;
+ data[4] = path;
+
+ ok = GTK_BUTTON(gtk_builder_get_object(password_builder,
+ "buttonPDFSetPassword"));
+ no = GTK_BUTTON(gtk_builder_get_object(password_builder,
+ "buttonPDFNoPassword"));
+
+ g_signal_connect(G_OBJECT(ok), "clicked",
+ G_CALLBACK(nsgtk_PDF_set_pass), (gpointer)data);
+ g_signal_connect(G_OBJECT(no), "clicked",
+ G_CALLBACK(nsgtk_PDF_no_pass), (gpointer)data);
+
+ gtk_widget_show(GTK_WIDGET(wnd));
+}
+
+
+static struct gui_misc_table misc_table = {
+ .schedule = nsgtk_schedule,
+
+ .launch_url = gui_launch_url,
+ .pdf_password = nsgtk_pdf_password,
+ .present_cookies = nsgtk_cookies_present,
+};
+
+struct gui_misc_table *nsgtk_misc_table = &misc_table;
diff --git a/frontends/atari/filetype.h b/frontends/gtk/misc.h
similarity index 80%
copy from frontends/atari/filetype.h
copy to frontends/gtk/misc.h
index 97ba75b..3a02c22 100644
--- a/frontends/atari/filetype.h
+++ b/frontends/gtk/misc.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010 Ole Loots <ole(a)monochrom.net>
+ * Copyright 2021 Vincemt Sanders <vince(a)netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -16,9 +16,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NS_ATARI_FILETYPE_H_
-#define NS_ATARI_FILETYPE_H_
+#ifndef NETSURF_GTK_MISC_H
+#define NETSURF_GTK_MISC_H 1
-const char *fetch_filetype(const char *unix_path);
+extern struct gui_misc_table *nsgtk_misc_table;
#endif
diff --git a/include/netsurf/bitmap.h b/include/netsurf/bitmap.h
index a85efce..f5de514 100644
--- a/include/netsurf/bitmap.h
+++ b/include/netsurf/bitmap.h
@@ -143,14 +143,14 @@ struct gui_bitmap_table {
int (*get_height)(void *bitmap);
/**
- * The the *bytes* per pixel.
+ * Get the *bytes* per pixel.
*
* \param bitmap The bitmap
*/
size_t (*get_bpp)(void *bitmap);
/**
- * Savde a bitmap to disc.
+ * Save a bitmap to disc.
*
* \param bitmap The bitmap to save
* \param path The path to save the bitmap to.
--
NetSurf Browser
2 years, 7 months
netsurf: branch master updated. release/3.10-116-g9e3ef18
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/9e3ef18255464ccf0b7e2...
...commit http://git.netsurf-browser.org/netsurf.git/commit/9e3ef18255464ccf0b7e29d...
...tree http://git.netsurf-browser.org/netsurf.git/tree/9e3ef18255464ccf0b7e29db2...
The branch, master has been updated
via 9e3ef18255464ccf0b7e29db23a436ccdc371959 (commit)
from 920041a13103b0b207da56d2cb9d16c9ebcaba65 (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=9e3ef18255464ccf0b7...
commit 9e3ef18255464ccf0b7e29db23a436ccdc371959
Author: Michael Drake <michael.drake(a)codethink.co.uk>
Commit: Michael Drake <michael.drake(a)codethink.co.uk>
html: layout: Cleanup dom node tag name getting with helper.
diff --git a/content/handlers/html/layout.c b/content/handlers/html/layout.c
index 082e537..c8c0127 100644
--- a/content/handlers/html/layout.c
+++ b/content/handlers/html/layout.c
@@ -4411,20 +4411,17 @@ layout_block_context(struct box *block,
return true;
}
-
/**
- * Check a node's tag type.
+ * Get a dom node's element tag type.
*
- * Assumes node is an HTML element.
- *
- * \param[in] node Node to ckeck tag type of.
- * \param[in] type Tag type to test for.
- * \return true if if node has given type, false otherwise.
+ * \param[in] node Node to get tag type of.
+ * \param[in] type Returns element tag type on success.
+ * \return true if on success, false otherwise.
*/
-static inline bool
-layout__check_element_type(
+static bool
+layout__get_element_tag(
const dom_node *node,
- dom_html_element_type type)
+ dom_html_element_type *type)
{
dom_html_element_type element_type;
dom_node_type node_type;
@@ -4441,6 +4438,29 @@ layout__check_element_type(
return false;
}
+ *type = element_type;
+ return true;
+}
+
+
+/**
+ * Check a node's tag type.
+ *
+ * \param[in] node Node to check tag type of.
+ * \param[in] type Tag type to test for.
+ * \return true if if node has given type, false otherwise.
+ */
+static inline bool
+layout__check_element_type(
+ const dom_node *node,
+ dom_html_element_type type)
+{
+ dom_html_element_type element_type;
+
+ if (!layout__get_element_tag(node, &element_type)) {
+ return false;
+ }
+
return element_type == type;
}
@@ -4566,8 +4586,7 @@ layout__get_list_item_count(
return false;
}
- exc = dom_html_element_get_tag_type(list_owner, &tag_type);
- if (exc != DOM_NO_ERR) {
+ if (!layout__get_element_tag(list_owner, &tag_type)) {
return false;
}
@@ -4634,8 +4653,7 @@ layout__ordered_list_count(
return;
}
- exc = dom_html_element_get_tag_type(box->node, &tag_type);
- if (exc != DOM_NO_ERR) {
+ if (!layout__get_element_tag(box->node, &tag_type)) {
return;
}
-----------------------------------------------------------------------
Summary of changes:
content/handlers/html/layout.c | 46 ++++++++++++++++++++++++++++------------
1 file changed, 32 insertions(+), 14 deletions(-)
diff --git a/content/handlers/html/layout.c b/content/handlers/html/layout.c
index 082e537..c8c0127 100644
--- a/content/handlers/html/layout.c
+++ b/content/handlers/html/layout.c
@@ -4411,20 +4411,17 @@ layout_block_context(struct box *block,
return true;
}
-
/**
- * Check a node's tag type.
+ * Get a dom node's element tag type.
*
- * Assumes node is an HTML element.
- *
- * \param[in] node Node to ckeck tag type of.
- * \param[in] type Tag type to test for.
- * \return true if if node has given type, false otherwise.
+ * \param[in] node Node to get tag type of.
+ * \param[in] type Returns element tag type on success.
+ * \return true if on success, false otherwise.
*/
-static inline bool
-layout__check_element_type(
+static bool
+layout__get_element_tag(
const dom_node *node,
- dom_html_element_type type)
+ dom_html_element_type *type)
{
dom_html_element_type element_type;
dom_node_type node_type;
@@ -4441,6 +4438,29 @@ layout__check_element_type(
return false;
}
+ *type = element_type;
+ return true;
+}
+
+
+/**
+ * Check a node's tag type.
+ *
+ * \param[in] node Node to check tag type of.
+ * \param[in] type Tag type to test for.
+ * \return true if if node has given type, false otherwise.
+ */
+static inline bool
+layout__check_element_type(
+ const dom_node *node,
+ dom_html_element_type type)
+{
+ dom_html_element_type element_type;
+
+ if (!layout__get_element_tag(node, &element_type)) {
+ return false;
+ }
+
return element_type == type;
}
@@ -4566,8 +4586,7 @@ layout__get_list_item_count(
return false;
}
- exc = dom_html_element_get_tag_type(list_owner, &tag_type);
- if (exc != DOM_NO_ERR) {
+ if (!layout__get_element_tag(list_owner, &tag_type)) {
return false;
}
@@ -4634,8 +4653,7 @@ layout__ordered_list_count(
return;
}
- exc = dom_html_element_get_tag_type(box->node, &tag_type);
- if (exc != DOM_NO_ERR) {
+ if (!layout__get_element_tag(box->node, &tag_type)) {
return;
}
--
NetSurf Browser
2 years, 7 months
netsurf: branch master updated. release/3.10-115-g920041a
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/920041a13103b0b207da5...
...commit http://git.netsurf-browser.org/netsurf.git/commit/920041a13103b0b207da56d...
...tree http://git.netsurf-browser.org/netsurf.git/tree/920041a13103b0b207da56d2c...
The branch, master has been updated
via 920041a13103b0b207da56d2cb9d16c9ebcaba65 (commit)
from 598629c7369c717f76f52436c27863c073e0e2c8 (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=920041a13103b0b207d...
commit 920041a13103b0b207da56d2cb9d16c9ebcaba65
Author: Michael Drake <michael.drake(a)codethink.co.uk>
Commit: Michael Drake <michael.drake(a)codethink.co.uk>
html: layout: Fix to ignore non-element children of lists.
diff --git a/content/handlers/html/layout.c b/content/handlers/html/layout.c
index 94cdf8f..082e537 100644
--- a/content/handlers/html/layout.c
+++ b/content/handlers/html/layout.c
@@ -4426,15 +4426,22 @@ layout__check_element_type(
const dom_node *node,
dom_html_element_type type)
{
- dom_html_element_type node_type;
+ dom_html_element_type element_type;
+ dom_node_type node_type;
dom_exception exc;
- exc = dom_html_element_get_tag_type(node, &node_type);
+ exc = dom_node_get_node_type(node, &node_type);
+ if (exc != DOM_NO_ERR ||
+ node_type != DOM_ELEMENT_NODE) {
+ return false;
+ }
+
+ exc = dom_html_element_get_tag_type(node, &element_type);
if (exc != DOM_NO_ERR) {
return false;
}
- return node_type == type;
+ return element_type == type;
}
-----------------------------------------------------------------------
Summary of changes:
content/handlers/html/layout.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/content/handlers/html/layout.c b/content/handlers/html/layout.c
index 94cdf8f..082e537 100644
--- a/content/handlers/html/layout.c
+++ b/content/handlers/html/layout.c
@@ -4426,15 +4426,22 @@ layout__check_element_type(
const dom_node *node,
dom_html_element_type type)
{
- dom_html_element_type node_type;
+ dom_html_element_type element_type;
+ dom_node_type node_type;
dom_exception exc;
- exc = dom_html_element_get_tag_type(node, &node_type);
+ exc = dom_node_get_node_type(node, &node_type);
+ if (exc != DOM_NO_ERR ||
+ node_type != DOM_ELEMENT_NODE) {
+ return false;
+ }
+
+ exc = dom_html_element_get_tag_type(node, &element_type);
if (exc != DOM_NO_ERR) {
return false;
}
- return node_type == type;
+ return element_type == type;
}
--
NetSurf Browser
2 years, 7 months
netsurf: branch master updated. release/3.10-114-g598629c
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/598629c7369c717f76f52...
...commit http://git.netsurf-browser.org/netsurf.git/commit/598629c7369c717f76f5243...
...tree http://git.netsurf-browser.org/netsurf.git/tree/598629c7369c717f76f52436c...
The branch, master has been updated
via 598629c7369c717f76f52436c27863c073e0e2c8 (commit)
from b765d8b46189642d488736075771724c8ef0f117 (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=598629c7369c717f76f...
commit 598629c7369c717f76f52436c27863c073e0e2c8
Author: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Commit: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
correct size
diff --git a/frontends/amiga/iff_dr2d.c b/frontends/amiga/iff_dr2d.c
index 0e7b706..624b501 100644
--- a/frontends/amiga/iff_dr2d.c
+++ b/frontends/amiga/iff_dr2d.c
@@ -283,7 +283,7 @@ bool ami_svg_to_dr2d(struct IFFHandle *iffh, const char *buffer,
if(!(PushChunk(iffh, 0, ID_FONS, IFFSIZE_UNKNOWN)))
{
WriteChunkBytes(iffh, fons, sizeof(struct fons_struct));
- WriteChunkBytes(iffh, "Helvetica\0", 6);
+ WriteChunkBytes(iffh, "Helvetica\0", 10);
PopChunk(iffh);
}
free(fons);
-----------------------------------------------------------------------
Summary of changes:
frontends/amiga/iff_dr2d.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontends/amiga/iff_dr2d.c b/frontends/amiga/iff_dr2d.c
index 0e7b706..624b501 100644
--- a/frontends/amiga/iff_dr2d.c
+++ b/frontends/amiga/iff_dr2d.c
@@ -283,7 +283,7 @@ bool ami_svg_to_dr2d(struct IFFHandle *iffh, const char *buffer,
if(!(PushChunk(iffh, 0, ID_FONS, IFFSIZE_UNKNOWN)))
{
WriteChunkBytes(iffh, fons, sizeof(struct fons_struct));
- WriteChunkBytes(iffh, "Helvetica\0", 6);
+ WriteChunkBytes(iffh, "Helvetica\0", 10);
PopChunk(iffh);
}
free(fons);
--
NetSurf Browser
2 years, 7 months
netsurf: branch master updated. release/3.10-113-gb765d8b
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/b765d8b46189642d48873...
...commit http://git.netsurf-browser.org/netsurf.git/commit/b765d8b46189642d4887360...
...tree http://git.netsurf-browser.org/netsurf.git/tree/b765d8b46189642d488736075...
The branch, master has been updated
via b765d8b46189642d488736075771724c8ef0f117 (commit)
from bc15ad5784a0e653cdc07ec9c1dbd2ea2e45f12e (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=b765d8b46189642d488...
commit b765d8b46189642d488736075771724c8ef0f117
Author: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Commit: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
AMIGA: minor IFF DR2D export changes
NULL-terminate name
Use more sensible font
diff --git a/frontends/amiga/iff_dr2d.c b/frontends/amiga/iff_dr2d.c
index 5de1463..0e7b706 100644
--- a/frontends/amiga/iff_dr2d.c
+++ b/frontends/amiga/iff_dr2d.c
@@ -120,6 +120,7 @@ bool ami_svg_to_dr2d(struct IFFHandle *iffh, const char *buffer,
if(!(PushChunk(iffh,0,ID_NAME,IFFSIZE_UNKNOWN)))
{
WriteChunkBytes(iffh,url,strlen(url));
+ WriteChunkBytes(iffh,"\0",1);
PopChunk(iffh);
}
@@ -185,6 +186,7 @@ bool ami_svg_to_dr2d(struct IFFHandle *iffh, const char *buffer,
attr->DashPattern = 1;
attr->EdgeValue = findcolour(diagram->shape[i].stroke);
}
+
attr->EdgeThick = (float) diagram->shape[i].stroke_width;
if(!(PushChunk(iffh,0,ID_ATTR,IFFSIZE_UNKNOWN)))
@@ -281,7 +283,7 @@ bool ami_svg_to_dr2d(struct IFFHandle *iffh, const char *buffer,
if(!(PushChunk(iffh, 0, ID_FONS, IFFSIZE_UNKNOWN)))
{
WriteChunkBytes(iffh, fons, sizeof(struct fons_struct));
- WriteChunkBytes(iffh, "Topaz\0", 6);
+ WriteChunkBytes(iffh, "Helvetica\0", 6);
PopChunk(iffh);
}
free(fons);
-----------------------------------------------------------------------
Summary of changes:
frontends/amiga/iff_dr2d.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/frontends/amiga/iff_dr2d.c b/frontends/amiga/iff_dr2d.c
index 5de1463..0e7b706 100644
--- a/frontends/amiga/iff_dr2d.c
+++ b/frontends/amiga/iff_dr2d.c
@@ -120,6 +120,7 @@ bool ami_svg_to_dr2d(struct IFFHandle *iffh, const char *buffer,
if(!(PushChunk(iffh,0,ID_NAME,IFFSIZE_UNKNOWN)))
{
WriteChunkBytes(iffh,url,strlen(url));
+ WriteChunkBytes(iffh,"\0",1);
PopChunk(iffh);
}
@@ -185,6 +186,7 @@ bool ami_svg_to_dr2d(struct IFFHandle *iffh, const char *buffer,
attr->DashPattern = 1;
attr->EdgeValue = findcolour(diagram->shape[i].stroke);
}
+
attr->EdgeThick = (float) diagram->shape[i].stroke_width;
if(!(PushChunk(iffh,0,ID_ATTR,IFFSIZE_UNKNOWN)))
@@ -281,7 +283,7 @@ bool ami_svg_to_dr2d(struct IFFHandle *iffh, const char *buffer,
if(!(PushChunk(iffh, 0, ID_FONS, IFFSIZE_UNKNOWN)))
{
WriteChunkBytes(iffh, fons, sizeof(struct fons_struct));
- WriteChunkBytes(iffh, "Topaz\0", 6);
+ WriteChunkBytes(iffh, "Helvetica\0", 6);
PopChunk(iffh);
}
free(fons);
--
NetSurf Browser
2 years, 7 months
netsurf: branch master updated. release/3.10-112-gbc15ad5
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/bc15ad5784a0e653cdc07...
...commit http://git.netsurf-browser.org/netsurf.git/commit/bc15ad5784a0e653cdc07ec...
...tree http://git.netsurf-browser.org/netsurf.git/tree/bc15ad5784a0e653cdc07ec9c...
The branch, master has been updated
via bc15ad5784a0e653cdc07ec9c1dbd2ea2e45f12e (commit)
from 9783296c4ffd83dfdb18e1e293ad635f214d2fd0 (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=bc15ad5784a0e653cdc...
commit bc15ad5784a0e653cdc07ec9c1dbd2ea2e45f12e
Author: Michael Drake <michael.drake(a)codethink.co.uk>
Commit: Michael Drake <michael.drake(a)codethink.co.uk>
tests: Update corestring allocation count.
diff --git a/test/corestrings.c b/test/corestrings.c
index aaa23e4..43eb513 100644
--- a/test/corestrings.c
+++ b/test/corestrings.c
@@ -40,7 +40,7 @@
*
* This is used to test all the out of memory paths in initialisation.
*/
-#define CORESTRING_TEST_COUNT 483
+#define CORESTRING_TEST_COUNT 487
START_TEST(corestrings_test)
{
-----------------------------------------------------------------------
Summary of changes:
test/corestrings.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/corestrings.c b/test/corestrings.c
index aaa23e4..43eb513 100644
--- a/test/corestrings.c
+++ b/test/corestrings.c
@@ -40,7 +40,7 @@
*
* This is used to test all the out of memory paths in initialisation.
*/
-#define CORESTRING_TEST_COUNT 483
+#define CORESTRING_TEST_COUNT 487
START_TEST(corestrings_test)
{
--
NetSurf Browser
2 years, 7 months