[Commits] [SCM] claws branch, litehtml, updated. 3.17.0-151-g1110b8f

miras at claws-mail.org miras at claws-mail.org
Wed Nov 7 03:20:38 CET 2018


The branch, litehtml has been updated
       via  1110b8f941df04e8a6dcbc167bd39429786aa578 (commit)
      from  0d57c63a59556b35fc1fc3ef94edf7629f4879c4 (commit)

Summary of changes:
 src/plugins/litehtml_viewer/Makefile.am   |    6 +-
 src/plugins/litehtml_viewer/TODO          |    3 +
 src/plugins/litehtml_viewer/lh_viewer.c   |    1 +
 src/plugins/litehtml_viewer/lh_widget.cpp |  129 ++++++++++++++++++++++++++++-
 src/plugins/litehtml_viewer/lh_widget.h   |    6 ++
 5 files changed, 142 insertions(+), 3 deletions(-)


- Log -----------------------------------------------------------------
commit 1110b8f941df04e8a6dcbc167bd39429786aa578
Author: Michael Rasmussen <mir at datanom.net>
Date:   Wed Nov 7 03:20:11 2018 +0100

    Implement image handling
    
    Signed-off-by: Michael Rasmussen <mir at datanom.net>

diff --git a/src/plugins/litehtml_viewer/Makefile.am b/src/plugins/litehtml_viewer/Makefile.am
index 5e4e732..15cb479 100644
--- a/src/plugins/litehtml_viewer/Makefile.am
+++ b/src/plugins/litehtml_viewer/Makefile.am
@@ -53,14 +53,16 @@ litehtml_viewer_la_LDFLAGS = \
 	-avoid-version -module \
 	$(GTK_LIBS) \
 	$(FONTCONFIG_LIBS) \
-	$(CAIRO_LIBS)
+	$(CAIRO_LIBS) \
+	$(CURL_LIBS)
 
 litehtml_viewer_la_CPPFLAGS = \
 	$(IFLAGS) \
 	$(GLIB_CFLAGS) \
 	$(GTK_CFLAGS) \
 	$(FONTCONFIG_CFLAGS) \
-	$(CAIRO_CFLAGS) 
+	$(CAIRO_CFLAGS) \
+	$(CURL_FLAGS)
 
 .PHONY: test
 
diff --git a/src/plugins/litehtml_viewer/TODO b/src/plugins/litehtml_viewer/TODO
index 912078f..56e3846 100644
--- a/src/plugins/litehtml_viewer/TODO
+++ b/src/plugins/litehtml_viewer/TODO
@@ -2,3 +2,6 @@
 - Add support for printing
 - Add support for links (open in default browser)
 
+Images:
+https://developer.gnome.org/gio/unstable/GMemoryInputStream.html#g-memory-input-stream-new-from-data
+http://darcs.cielonegro.org/gtktwitter/gtktwitter.c
diff --git a/src/plugins/litehtml_viewer/lh_viewer.c b/src/plugins/litehtml_viewer/lh_viewer.c
index 73c1b69..0b3cf53 100644
--- a/src/plugins/litehtml_viewer/lh_viewer.c
+++ b/src/plugins/litehtml_viewer/lh_viewer.c
@@ -23,6 +23,7 @@
 #endif
 
 #include <codeconv.h>
+#include "common/utils.h"
 #include "lh_viewer.h"
 
 static gchar *content_types[] = { "text/html", NULL };
diff --git a/src/plugins/litehtml_viewer/lh_widget.cpp b/src/plugins/litehtml_viewer/lh_widget.cpp
index a700b63..5c90005 100644
--- a/src/plugins/litehtml_viewer/lh_widget.cpp
+++ b/src/plugins/litehtml_viewer/lh_widget.cpp
@@ -22,6 +22,12 @@
 #include "claws-features.h"
 #endif
 
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <curl/curl.h>
 #include "lh_widget.h"
 #include "lh_widget_wrapped.h"
 
@@ -29,10 +35,19 @@ char master_css[] = {
 #include "css.inc"
 };
 
+/**
+  * curl callback
+  */
+static char* response_mime = NULL;     /* response content-type. ex: "text/html" */
+static char* response_data = NULL;     /* response data from server. */
+static size_t response_size = 0;       /* response size of data */
+
 static gboolean expose_event_cb(GtkWidget *widget, GdkEvent *event,
 		gpointer user_data);
 static void size_allocate_cb(GtkWidget *widget, GdkRectangle *allocation,
 		gpointer user_data);
+static size_t handle_returned_data(char* ptr, size_t size, size_t nmemb, void* stream);
+static size_t handle_returned_header(void* ptr, size_t size, size_t nmemb, void* stream);
 
 lh_widget::lh_widget()
 {
@@ -61,6 +76,7 @@ lh_widget::lh_widget()
 	m_html = NULL;
 	m_rendered_width = 0;
 	m_context.load_master_stylesheet(master_css);
+	stream = NULL;
 }
 
 lh_widget::~lh_widget()
@@ -70,6 +86,10 @@ lh_widget::~lh_widget()
 	g_object_unref(m_scrolled_window);
 	m_scrolled_window = NULL;
 	m_html = NULL;
+	if (stream) {
+	    g_input_stream_close(stream, NULL, NULL);
+	    stream = NULL;
+	}
 }
 
 GtkWidget *lh_widget::get_widget() const
@@ -124,7 +144,34 @@ void lh_widget::get_client_rect(litehtml::position& client) const
 
 GdkPixbuf *lh_widget::get_image(const litehtml::tchar_t* url, bool redraw_on_ready)
 {
-	return NULL;
+	GError *error = NULL;
+	GdkPixbuf *pixbuf = NULL;
+
+	g_log(NULL, G_LOG_LEVEL_MESSAGE, "Loading... %s", url);
+
+	GInputStream *image = load_url(url, &error);
+	if (error) {
+		g_log(NULL, G_LOG_LEVEL_MESSAGE, "Error: %s", error->message);
+		g_error_free(error);
+		return NULL;
+	}
+
+	GdkPixbufLoader* loader = gdk_pixbuf_loader_new();
+	if (gdk_pixbuf_loader_write(loader, (const guchar*)response_data, response_size, &error)) {
+		pixbuf = gdk_pixbuf_loader_get_pixbuf(loader);
+	} else {
+		g_log(NULL, G_LOG_LEVEL_ERROR, "lh_widget::get_image: Could not create pixbuf");
+	}
+	gdk_pixbuf_loader_close(loader, NULL);
+
+        /* cleanup callback data */
+        if (response_mime) g_free(response_mime);
+        if (response_data) g_free(response_data);
+        response_data = NULL;
+        response_mime = NULL;
+        response_size = 0;
+	
+	return pixbuf;
 }
 
 void lh_widget::open_html(const gchar *contents)
@@ -235,6 +282,58 @@ void lh_widget::clear()
 	m_rendered_width = 0;
 }
 
+GInputStream *lh_widget::load_url(const gchar *url, GError **error)
+{
+	GError* _error = NULL;
+	CURL* curl = NULL;
+	CURLcode res = CURLE_OK;
+	gsize len;
+	gchar* content;
+
+	/* initialize callback data */
+	response_mime = NULL;
+	response_data = NULL;
+	response_size = 0;
+	if (stream) {
+		g_input_stream_close(stream, NULL, &_error);
+		if (_error) {
+			if (error) *error = _error;
+			return NULL;
+		}
+	}
+		
+	stream = NULL;
+
+	if (!strncmp(url, "file:///", 8) || g_file_test(url, G_FILE_TEST_EXISTS)) {
+		gchar* newurl = g_filename_from_uri(url, NULL, NULL);
+		if (g_file_get_contents(newurl ? newurl : url, &content, &len, &_error)) {
+			stream = g_memory_input_stream_new_from_data(content, len, g_free);
+		} else {
+			g_log(NULL, G_LOG_LEVEL_MESSAGE, "%s", _error->message);
+		}
+		g_free(newurl);
+	} else {
+		curl = curl_easy_init();
+		if (!curl) return NULL;
+		curl_easy_setopt(curl, CURLOPT_URL, url);
+		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, handle_returned_data);
+		curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, handle_returned_header);
+		curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
+		curl_easy_setopt(curl, CURLOPT_TIMEOUT, HTTP_GET_TIMEOUT);
+		curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
+		res = curl_easy_perform(curl);
+		curl_easy_cleanup(curl);
+		if (res == CURLE_OK) {
+			stream = g_memory_input_stream_new_from_data(content, response_size, g_free);
+		} else
+			_error = g_error_new_literal(G_FILE_ERROR, res, curl_easy_strerror(res));
+	}
+
+	if (error && _error) *error = _error;
+
+	return stream;
+}
+
 static gboolean expose_event_cb(GtkWidget *widget, GdkEvent *event,
 		gpointer user_data)
 {
@@ -255,6 +354,34 @@ static void size_allocate_cb(GtkWidget *widget, GdkRectangle *allocation,
 	w->redraw();
 }
 
+static size_t handle_returned_data(char* ptr, size_t size, size_t nmemb, void* stream) {
+	if (!response_data)
+		response_data = (char*)malloc(size*nmemb);
+	else
+		response_data = (char*)realloc(response_data, response_size+size*nmemb);
+	if (response_data) {
+		memcpy(response_data+response_size, ptr, size*nmemb);
+		response_size += size*nmemb;
+	}
+	return size*nmemb;
+}
+
+static size_t handle_returned_header(void* ptr, size_t size, size_t nmemb, void* stream) {
+	char* header = NULL;
+
+	header = (char*) malloc(size*nmemb + 1);
+	memcpy(header, ptr, size*nmemb);
+	header[size*nmemb] = 0;
+	if (strncmp(header, "Content-Type: ", 14) == 0) {
+		char* stop = header + 14;
+		stop = strpbrk(header + 14, "\r\n;");
+		if (stop) *stop = 0;
+		response_mime = strdup(header + 14);
+	}
+	free(header);
+	return size*nmemb;
+}
+
 ///////////////////////////////////////////////////////////
 extern "C" {
 
diff --git a/src/plugins/litehtml_viewer/lh_widget.h b/src/plugins/litehtml_viewer/lh_widget.h
index 4cdf8ce..b17b626 100644
--- a/src/plugins/litehtml_viewer/lh_widget.h
+++ b/src/plugins/litehtml_viewer/lh_widget.h
@@ -1,8 +1,11 @@
 #include <gtk/gtk.h>
 #include <glib.h>
+#include <gio/gio.h>
 
 #include "container_linux.h"
 
+#define HTTP_GET_TIMEOUT 60L
+
 class lh_widget : public container_linux
 {
 	public:
@@ -28,7 +31,9 @@ class lh_widget : public container_linux
 
 	private:
 		void paint_white();
+		GInputStream *load_url(const gchar *url, GError **error);
 
+		GInputStream *stream;
 		litehtml::document::ptr m_html;
 		gint m_rendered_width;
 		GtkWidget *m_drawing_area;
@@ -36,4 +41,5 @@ class lh_widget : public container_linux
 		GtkWidget *m_viewport;
 		litehtml::context m_context;
 		gint m_height;
+
 };

-----------------------------------------------------------------------


hooks/post-receive
-- 
Claws Mail


More information about the Commits mailing list