[libchamplain/tintou/libsoup3: 1/2] Port to libsoup3
- From: Corentin Noël <corentinnoel src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libchamplain/tintou/libsoup3: 1/2] Port to libsoup3
- Date: Wed, 12 Oct 2022 09:31:26 +0000 (UTC)
commit 56a822fcc84ad15960957b079eb09b91119a6876
Author: Corentin Noël <corentin noel collabora com>
Date: Wed Oct 12 10:42:51 2022 +0200
Port to libsoup3
Allows to use libchamplain with libsoup3 libraries and applications.
.gitlab-ci.yml | 4 +-
champlain/champlain-network-bbox-tile-source.c | 61 ++++++-
champlain/champlain-network-tile-source.c | 229 ++++++++++++++++++++++---
champlain/meson.build | 9 +
demos/meson.build | 8 +
demos/url-marker.c | 77 +++++++--
meson.build | 13 +-
meson_options.txt | 4 +
8 files changed, 360 insertions(+), 45 deletions(-)
---
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 9f68909..a808d62 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,4 +1,4 @@
-image: fedora:29
+image: fedora:37
stages:
- build
@@ -19,7 +19,7 @@ build-champlain:
- mkdir -p _ccache
- ccache --zero-stats
- ccache --show-stats
- - meson -Dwidgetry=true -Ddemos=true -Dgtk_doc=true -Dintrospection=true -Dvapi=true _build .
+ - meson -Dwidgetry=true -Ddemos=true -Dgtk_doc=true -Dintrospection=true -Dvapi=true -Dlibsoup3=false
_build .
- ninja -C _build
- ninja -C _build test
- ninja -C _build champlain-0.12-doc
diff --git a/champlain/champlain-network-bbox-tile-source.c b/champlain/champlain-network-bbox-tile-source.c
index f6f10ba..ecfbeb9 100644
--- a/champlain/champlain-network-bbox-tile-source.c
+++ b/champlain/champlain-network-bbox-tile-source.c
@@ -116,8 +116,16 @@ champlain_network_bbox_tile_source_set_property (GObject *object,
priv->proxy_uri = g_value_dup_string (value);
if (priv->soup_session)
- g_object_set (G_OBJECT (priv->soup_session), "proxy-uri",
- soup_uri_new (priv->proxy_uri), NULL);
+ {
+#ifdef CHAMPLAIN_LIBSOUP_3
+ GProxyResolver *resolver = soup_session_get_proxy_resolver (priv->soup_session);
+ if (!resolver && G_IS_SIMPLE_PROXY_RESOLVER (resolver))
+ g_simple_proxy_resolver_set_default_proxy (G_SIMPLE_PROXY_RESOLVER (resolver), priv->proxy_uri);
+#else
+ g_object_set (G_OBJECT (priv->soup_session), "proxy-uri",
+ soup_uri_new (priv->proxy_uri), NULL);
+#endif
+ }
break;
case PROP_STATE:
@@ -253,6 +261,13 @@ champlain_network_bbox_tile_source_init (ChamplainNetworkBboxTileSource *self)
priv->api_uri = g_strdup ("https://www.informationfreeway.org/api/0.6");
/* informationfreeway.org is a load-balancer for different api servers */
+#ifdef CHAMPLAIN_LIBSOUP_3
+ priv->soup_session = soup_session_new_with_options (
+ "user-agent", "libchamplain/" CHAMPLAIN_VERSION_S,
+ "max-conns-per-host", 2,
+ NULL
+ );
+#else
priv->proxy_uri = g_strdup ("");
priv->soup_session = soup_session_new_with_options (
"proxy-uri", soup_uri_new (priv->proxy_uri),
@@ -265,11 +280,11 @@ champlain_network_bbox_tile_source_init (ChamplainNetworkBboxTileSource *self)
"libchamplain/" CHAMPLAIN_VERSION_S,
"max-conns-per-host", 2,
NULL);
+#endif
priv->state = CHAMPLAIN_STATE_NONE;
}
-
/**
* champlain_network_bbox_tile_source_new_full:
* @id: the map source's id
@@ -314,7 +329,39 @@ champlain_network_bbox_tile_source_new_full (const gchar *id,
return source;
}
+#ifdef CHAMPLAIN_LIBSOUP_3
+static void
+load_map_data_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ ChamplainNetworkBboxTileSource *self =
+ CHAMPLAIN_NETWORK_BBOX_TILE_SOURCE (user_data);
+ ChamplainRenderer *renderer;
+ GBytes *bytes;
+ GError *error;
+ gsize size;
+ gconstpointer data;
+
+ bytes = soup_session_send_and_read_finish (SOUP_SESSION (source_object), res, &error);
+ if (error != NULL)
+ {
+ DEBUG ("Unable to download file: %s", error->message);
+
+ g_clear_error (&error);
+ return;
+ }
+
+ g_object_set (G_OBJECT (self), "state", CHAMPLAIN_STATE_DONE, NULL);
+
+ renderer = champlain_map_source_get_renderer (CHAMPLAIN_MAP_SOURCE (self));
+ data = g_bytes_get_data (bytes, &size);
+ champlain_renderer_set_data (renderer, data, size);
+ g_object_unref (bytes);
+
+}
+#else
static void
load_map_data_cb (G_GNUC_UNUSED SoupSession *session, SoupMessage *msg,
gpointer user_data)
@@ -336,6 +383,7 @@ load_map_data_cb (G_GNUC_UNUSED SoupSession *session, SoupMessage *msg,
renderer = champlain_map_source_get_renderer (CHAMPLAIN_MAP_SOURCE (self));
champlain_renderer_set_data (renderer, (guint8*) msg->response_body->data, msg->response_body->length);
}
+#endif
/**
@@ -370,7 +418,7 @@ champlain_network_bbox_tile_source_load_map_data (
url = g_strdup_printf (
"https://api.openstreetmap.org/api/0.6/map?bbox=%f,%f,%f,%f",
bbox->left, bbox->bottom, bbox->right, bbox->top);
- msg = soup_message_new ("GET", url);
+ msg = soup_message_new (SOUP_METHOD_GET, url);
DEBUG ("Request BBox data: '%s'", url);
@@ -378,7 +426,12 @@ champlain_network_bbox_tile_source_load_map_data (
g_object_set (G_OBJECT (self), "state", CHAMPLAIN_STATE_LOADING, NULL);
+#ifdef CHAMPLAIN_LIBSOUP_3
+ soup_session_send_and_read_async (priv->soup_session, msg, G_PRIORITY_DEFAULT_IDLE, NULL,
load_map_data_cb, self);
+ g_object_unref (msg);
+#else
soup_session_queue_message (priv->soup_session, msg, load_map_data_cb, self);
+#endif
}
diff --git a/champlain/champlain-network-tile-source.c b/champlain/champlain-network-tile-source.c
index 281f000..eb75fb3 100644
--- a/champlain/champlain-network-tile-source.c
+++ b/champlain/champlain-network-tile-source.c
@@ -80,17 +80,24 @@ G_DEFINE_TYPE_WITH_PRIVATE (ChamplainNetworkTileSource, champlain_network_tile_s
*/
#define MAX_CONNS_DEFAULT 2
+#ifndef CHAMPLAIN_LIBSOUP_3
typedef struct
{
ChamplainMapSource *map_source;
SoupMessage *msg;
} TileCancelledData;
+#endif
typedef struct
{
ChamplainMapSource *map_source;
ChamplainTile *tile;
+#ifdef CHAMPLAIN_LIBSOUP_3
+ SoupMessage *msg;
+ GCancellable *cancellable;
+#else
TileCancelledData *cancelled_data;
+#endif
} TileLoadedData;
typedef struct
@@ -102,9 +109,11 @@ typedef struct
static void fill_tile (ChamplainMapSource *map_source,
ChamplainTile *tile);
+#ifndef CHAMPLAIN_LIBSOUP_3
static void tile_state_notify (ChamplainTile *tile,
G_GNUC_UNUSED GParamSpec *pspec,
TileCancelledData *data);
+#endif
static gchar *get_tile_uri (ChamplainNetworkTileSource *source,
gint x,
@@ -185,11 +194,9 @@ champlain_network_tile_source_dispose (GObject *object)
ChamplainNetworkTileSourcePrivate *priv = CHAMPLAIN_NETWORK_TILE_SOURCE (object)->priv;
if (priv->soup_session)
- {
soup_session_abort (priv->soup_session);
- g_object_unref (priv->soup_session);
- priv->soup_session = NULL;
- }
+
+ g_clear_object (&priv->soup_session);
G_OBJECT_CLASS (champlain_network_tile_source_parent_class)->dispose (object);
}
@@ -322,6 +329,13 @@ champlain_network_tile_source_init (ChamplainNetworkTileSource *tile_source)
priv->offline = FALSE;
priv->max_conns = MAX_CONNS_DEFAULT;
+#ifdef CHAMPLAIN_LIBSOUP_3
+ priv->soup_session = soup_session_new_with_options (
+ "user-agent", "libchamplain/" CHAMPLAIN_VERSION_S,
+ "max-conns-per-host", MAX_CONNS_DEFAULT,
+ "max-conns", MAX_CONNS_DEFAULT,
+ NULL);
+#else
priv->soup_session = soup_session_new_with_options (
"proxy-uri", NULL,
"ssl-strict", FALSE,
@@ -336,6 +350,7 @@ champlain_network_tile_source_init (ChamplainNetworkTileSource *tile_source)
"max-conns-per-host", MAX_CONNS_DEFAULT,
"max-conns", MAX_CONNS_DEFAULT,
NULL);
+#endif
}
@@ -474,11 +489,21 @@ champlain_network_tile_source_set_proxy_uri (ChamplainNetworkTileSource *tile_so
g_return_if_fail (CHAMPLAIN_IS_NETWORK_TILE_SOURCE (tile_source));
ChamplainNetworkTileSourcePrivate *priv = tile_source->priv;
+#ifndef CHAMPLAIN_LIBSOUP_3
SoupURI *uri = NULL;
+#endif
g_free (priv->proxy_uri);
priv->proxy_uri = g_strdup (proxy_uri);
+#ifdef CHAMPLAIN_LIBSOUP_3
+ if (priv->soup_session)
+ {
+ GProxyResolver *resolver = soup_session_get_proxy_resolver (priv->soup_session);
+ if (!resolver && G_IS_SIMPLE_PROXY_RESOLVER (resolver))
+ g_simple_proxy_resolver_set_default_proxy (G_SIMPLE_PROXY_RESOLVER (resolver), priv->proxy_uri);
+ }
+#else
if (priv->proxy_uri)
uri = soup_uri_new (priv->proxy_uri);
@@ -489,6 +514,7 @@ champlain_network_tile_source_set_proxy_uri (ChamplainNetworkTileSource *tile_so
if (uri)
soup_uri_free (uri);
+#endif
g_object_notify (G_OBJECT (tile_source), "proxy-uri");
}
@@ -660,6 +686,25 @@ get_tile_uri (ChamplainNetworkTileSource *tile_source,
return token;
}
+static void
+tile_rendered_data_free (TileRenderedData *data)
+{
+ g_clear_pointer (&data->etag, g_free);
+ g_clear_object (&data->map_source);
+ g_slice_free (TileRenderedData, data);
+}
+
+static void
+tile_loaded_data_free (TileLoadedData *data)
+{
+ g_clear_object (&data->tile);
+ g_clear_object (&data->map_source);
+#ifdef CHAMPLAIN_LIBSOUP_3
+ g_clear_object (&data->cancellable);
+ g_clear_object (&data->msg);
+#endif
+ g_slice_free (TileLoadedData, data);
+}
static void
tile_rendered_cb (ChamplainTile *tile,
@@ -668,12 +713,11 @@ tile_rendered_cb (ChamplainTile *tile,
gboolean error,
TileRenderedData *user_data)
{
- ChamplainMapSource *map_source = user_data->map_source;
+ ChamplainMapSource *map_source = g_steal_pointer (&user_data->map_source);
ChamplainMapSource *next_source;
- gchar *etag = user_data->etag;
+ gchar *etag = g_steal_pointer (&user_data->etag);
g_signal_handlers_disconnect_by_func (tile, tile_rendered_cb, user_data);
- g_slice_free (TileRenderedData, user_data);
next_source = champlain_map_source_get_next_source (map_source);
@@ -697,10 +741,119 @@ tile_rendered_cb (ChamplainTile *tile,
g_free (etag);
g_object_unref (map_source);
- g_object_unref (tile);
}
+#ifdef CHAMPLAIN_LIBSOUP_3
+static void
+tile_bytes_loaded_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ TileLoadedData *callback_data = user_data;
+ ChamplainTile *tile = callback_data->tile;
+ ChamplainMapSource *map_source = callback_data->map_source;
+ GError *error = NULL;
+
+ if (g_output_stream_splice_finish (G_OUTPUT_STREAM (source_object), res, &error) != -1) {
+ gsize size = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (source_object));
+ gconstpointer data = g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (source_object));
+ ChamplainRenderer *renderer = champlain_map_source_get_renderer (map_source);
+
+ champlain_renderer_set_data (renderer, data, size);
+ champlain_renderer_render (renderer, tile);
+ }
+
+ tile_loaded_data_free (callback_data);
+}
+
+static void
+tile_loaded_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ TileLoadedData *callback_data = (TileLoadedData *) user_data;
+ GCancellable *cancellable = callback_data->cancellable;
+ SoupMessage *msg = callback_data->msg;
+ ChamplainTile *tile = callback_data->tile;
+ ChamplainMapSource *map_source = callback_data->map_source;
+ const gchar *etag;
+ TileRenderedData *data;
+ GInputStream *stream;
+ GOutputStream *ostream;
+ GError *error = NULL;
+ SoupStatus status;
+ SoupMessageHeaders *response_headers;
+
+ stream = soup_session_send_finish (SOUP_SESSION (source_object), res, &error);
+ status = soup_message_get_status (msg);
+ DEBUG ("Got reply %d", status);
+
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ {
+ DEBUG ("Download of tile %d, %d got cancelled",
+ champlain_tile_get_x (tile), champlain_tile_get_y (tile));
+ goto cleanup;
+ }
+
+ if (status == SOUP_STATUS_NOT_MODIFIED)
+ {
+ ChamplainTileSource *tile_source = CHAMPLAIN_TILE_SOURCE (map_source);
+ ChamplainTileCache *tile_cache = champlain_tile_source_get_cache (tile_source);
+
+ if (tile_cache)
+ champlain_tile_cache_refresh_tile_time (tile_cache, tile);
+
+ champlain_tile_set_fade_in (tile, TRUE);
+ champlain_tile_set_state (tile, CHAMPLAIN_STATE_DONE);
+ champlain_tile_display_content (tile);
+ goto cleanup;
+ }
+
+ if (!SOUP_STATUS_IS_SUCCESSFUL (status))
+ {
+ ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source);
+ DEBUG ("Unable to download tile %d, %d: %s : %s",
+ champlain_tile_get_x (tile),
+ champlain_tile_get_y (tile),
+ soup_status_get_phrase (status),
+ soup_message_get_reason_phrase (msg));
+
+ if (next_source)
+ champlain_map_source_fill_tile (next_source, tile);
+ goto cleanup;
+ }
+
+ /* Verify if the server sent an etag and save it */
+ response_headers = soup_message_get_response_headers (msg);
+ etag = soup_message_headers_get_one (response_headers, "ETag");
+ DEBUG ("Received ETag %s", etag);
+
+ data = g_slice_new (TileRenderedData);
+ data->map_source = g_object_ref (map_source);
+ data->etag = g_strdup (etag);
+
+ g_signal_connect_data (tile, "render-complete", G_CALLBACK (tile_rendered_cb), data,
(GClosureNotify)tile_rendered_data_free, 0);
+
+ ostream = g_memory_output_stream_new_resizable ();
+ g_output_stream_splice_async (ostream,
+ stream,
+ G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
+ G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
+ G_PRIORITY_DEFAULT_IDLE,
+ cancellable,
+ tile_bytes_loaded_cb,
+ callback_data);
+ g_clear_object (&ostream);
+ g_clear_object (&stream);
+
+ return;
+cleanup:
+ tile_loaded_data_free (callback_data);
+ g_clear_error (&error);
+ g_clear_object (&stream);
+}
+#else
static void
tile_loaded_cb (G_GNUC_UNUSED SoupSession *session,
SoupMessage *msg,
@@ -717,7 +870,6 @@ tile_loaded_cb (G_GNUC_UNUSED SoupSession *session,
ChamplainRenderer *renderer;
g_signal_handlers_disconnect_by_func (tile, tile_state_notify, callback_data->cancelled_data);
- g_slice_free (TileLoadedData, callback_data);
DEBUG ("Got reply %d", msg->status_code);
@@ -753,16 +905,15 @@ tile_loaded_cb (G_GNUC_UNUSED SoupSession *session,
g_return_if_fail (CHAMPLAIN_IS_RENDERER (renderer));
data = g_slice_new (TileRenderedData);
- data->map_source = map_source;
+ data->map_source = g_object_ref (map_source);
data->etag = g_strdup (etag);
- g_signal_connect (tile, "render-complete", G_CALLBACK (tile_rendered_cb), data);
+ g_signal_connect_data (tile, "render-complete", G_CALLBACK (tile_rendered_cb), data,
(GClosureNotify)tile_rendered_data_free, 0);
champlain_renderer_set_data (renderer, (guint8*) msg->response_body->data, msg->response_body->length);
champlain_renderer_render (renderer, tile);
- return;
-
+ goto cleanup;
load_next:
if (next_source)
champlain_map_source_fill_tile (next_source, tile);
@@ -775,11 +926,9 @@ finish:
champlain_tile_display_content (tile);
cleanup:
- g_object_unref (tile);
- g_object_unref (map_source);
+ tile_loaded_data_free (callback_data);
}
-
static void
destroy_cancelled_data (TileCancelledData *data,
G_GNUC_UNUSED GClosure *closure)
@@ -792,8 +941,24 @@ destroy_cancelled_data (TileCancelledData *data,
g_slice_free (TileCancelledData, data);
}
+#endif
+#ifdef CHAMPLAIN_LIBSOUP_3
+static void
+tile_state_notify (ChamplainTile *tile,
+ G_GNUC_UNUSED GParamSpec *pspec,
+ gpointer user_data)
+{
+ GCancellable *cancellable = user_data;
+
+ if (champlain_tile_get_state (tile) == CHAMPLAIN_STATE_DONE)
+ {
+ DEBUG ("Canceling tile download");
+ g_cancellable_cancel (cancellable);
+ }
+}
+#else
static void
tile_state_notify (ChamplainTile *tile,
G_GNUC_UNUSED GParamSpec *pspec,
@@ -806,6 +971,7 @@ tile_state_notify (ChamplainTile *tile,
soup_session_cancel_message (priv->soup_session, data->msg, SOUP_STATUS_CANCELLED);
}
}
+#endif
static gchar *
@@ -842,6 +1008,9 @@ fill_tile (ChamplainMapSource *map_source,
ChamplainNetworkTileSource *tile_source = CHAMPLAIN_NETWORK_TILE_SOURCE (map_source);
ChamplainNetworkTileSourcePrivate *priv = tile_source->priv;
+#ifdef CHAMPLAIN_LIBSOUP_3
+ GCancellable *cancellable = NULL;
+#endif
if (champlain_tile_get_state (tile) == CHAMPLAIN_STATE_DONE)
return;
@@ -865,6 +1034,11 @@ fill_tile (ChamplainMapSource *map_source,
const gchar *etag = champlain_tile_get_etag (tile);
gchar *date = get_modified_time_string (tile);
+#ifdef CHAMPLAIN_LIBSOUP_3
+ SoupMessageHeaders *headers = soup_message_get_request_headers (msg);
+#else
+ SoupMessageHeaders *headers = msg->request_headers;
+#endif
/* If an etag is available, only use it.
* OSM servers seems to send now as the modified time for all tiles
@@ -873,19 +1047,23 @@ fill_tile (ChamplainMapSource *map_source,
if (etag)
{
DEBUG ("If-None-Match: %s", etag);
- soup_message_headers_append (msg->request_headers,
+ soup_message_headers_append (headers,
"If-None-Match", etag);
}
else if (date)
{
DEBUG ("If-Modified-Since %s", date);
- soup_message_headers_append (msg->request_headers,
+ soup_message_headers_append (headers,
"If-Modified-Since", date);
}
g_free (date);
}
+#ifdef CHAMPLAIN_LIBSOUP_3
+ cancellable = g_cancellable_new ();
+ g_signal_connect_data (tile, "notify::state", G_CALLBACK (tile_state_notify), g_object_ref
(cancellable), (GClosureNotify) g_object_unref, 0);
+#else
TileCancelledData *tile_cancelled_data = g_slice_new (TileCancelledData);
tile_cancelled_data->map_source = map_source;
tile_cancelled_data->msg = msg;
@@ -895,18 +1073,21 @@ fill_tile (ChamplainMapSource *map_source,
g_signal_connect_data (tile, "notify::state", G_CALLBACK (tile_state_notify),
tile_cancelled_data, (GClosureNotify) destroy_cancelled_data, 0);
+#endif
callback_data = g_slice_new (TileLoadedData);
- callback_data->tile = tile;
- callback_data->map_source = map_source;
+ callback_data->tile = g_object_ref (tile);
+ callback_data->map_source = g_object_ref (map_source);
+#ifdef CHAMPLAIN_LIBSOUP_3
+ callback_data->cancellable = cancellable; // transfer ownership
+ callback_data->msg = msg; // transfer ownership
+ soup_session_send_async (priv->soup_session, msg, G_PRIORITY_DEFAULT_IDLE, cancellable,
tile_loaded_cb, callback_data);
+#else
callback_data->cancelled_data = tile_cancelled_data;
-
- g_object_ref (map_source);
- g_object_ref (tile);
-
soup_session_queue_message (priv->soup_session, msg,
tile_loaded_cb,
callback_data);
+#endif
}
else
{
diff --git a/champlain/meson.build b/champlain/meson.build
index 0bf8ba5..9a7b8c7 100644
--- a/champlain/meson.build
+++ b/champlain/meson.build
@@ -112,6 +112,12 @@ libchamplain_c_args = [
'-DG_LOG_DOMAIN="@0@"'.format(meson.project_name()),
]
+if get_option('libsoup3')
+ libchamplain_c_args += [
+ '-DCHAMPLAIN_LIBSOUP_3',
+ ]
+endif
+
libchamplain_link_args = [
]
@@ -244,4 +250,7 @@ libchamplain_pc = pkg.generate(
description: 'Map View for Clutter',
subdirs: package_string,
requires: libchamplain_requires,
+ variables: [
+ 'soupapiversion=@0@'.format(libsoup_api_version),
+ ],
)
diff --git a/demos/meson.build b/demos/meson.build
index bf9b3bb..9b5ee05 100644
--- a/demos/meson.build
+++ b/demos/meson.build
@@ -7,6 +7,13 @@ libchamplain_demos = [
['create_destroy_test', 'create-destroy-test.c', []],
]
+libchamplain_demos_c_args = []
+if get_option('libsoup3')
+ libchamplain_demos_c_args += [
+ '-DCHAMPLAIN_LIBSOUP_3',
+ ]
+endif
+
foreach demo: libchamplain_demos
demo_name = demo.get(0)
demo_sources = demo.get(1)
@@ -17,6 +24,7 @@ foreach demo: libchamplain_demos
demo_sources,
install: false,
dependencies: demo_deps + [libchamplain_dep],
+ c_args: libchamplain_demos_c_args,
)
endforeach
diff --git a/demos/url-marker.c b/demos/url-marker.c
index 8134d66..8cfbebb 100644
--- a/demos/url-marker.c
+++ b/demos/url-marker.c
@@ -28,6 +28,7 @@ typedef struct
gdouble longitude;
} MarkerData;
+#ifndef CHAMPLAIN_LIBSOUP_3
/**
* Returns a GdkPixbuf from a given SoupMessage. This function assumes that the
* message has completed successfully.
@@ -86,7 +87,7 @@ cleanup:
return pixbuf;
}
-
+#endif
static ClutterActor *
texture_new_from_pixbuf (GdkPixbuf *pixbuf, GError **error)
@@ -125,6 +126,57 @@ texture_new_from_pixbuf (GdkPixbuf *pixbuf, GError **error)
*
* This callback expects the parameter data to be a valid ChamplainMarkerLayer.
*/
+#ifdef CHAMPLAIN_LIBSOUP_3
+static void
+image_downloaded_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ MarkerData *marker_data = (MarkerData *) user_data;
+ GError *error = NULL;
+ GdkPixbuf *pixbuf = NULL;
+ ClutterActor *texture = NULL;
+ ClutterActor *marker = NULL;
+ GInputStream *stream;
+
+ stream = soup_session_send_finish (SOUP_SESSION (source_object), res, &error);
+ if (error != NULL) {
+ g_print ("Failed to download image: %s\n", error->message);
+ goto cleanup;
+ }
+
+ pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, &error);
+ if (error != NULL)
+ {
+ g_print ("Failed to parse the image: %s\n", error->message);
+ goto cleanup;
+ }
+
+ /* Then transform the pixbuf into a texture */
+ texture = texture_new_from_pixbuf (pixbuf, &error);
+ if (error != NULL)
+ {
+ g_print ("Failed to convert the image into a texture: %s\n",
+ error->message);
+ goto cleanup;
+ }
+
+ /* Finally create a marker with the texture */
+ marker = champlain_label_new_with_image (texture);
+ champlain_location_set_location (CHAMPLAIN_LOCATION (marker),
+ marker_data->latitude, marker_data->longitude);
+ champlain_marker_layer_add_marker (marker_data->layer, CHAMPLAIN_MARKER (marker));
+
+cleanup:
+ if (marker_data)
+ g_clear_object (&marker_data->layer);
+ g_slice_free (MarkerData, marker_data);
+
+ g_clear_error (&error);
+ g_clear_object (&pixbuf);
+ g_clear_object (&texture);
+}
+#else
static void
image_downloaded_cb (SoupSession *session,
SoupMessage *message,
@@ -170,26 +222,21 @@ image_downloaded_cb (SoupSession *session,
/* Finally create a marker with the texture */
marker = champlain_label_new_with_image (texture);
- texture = NULL;
champlain_location_set_location (CHAMPLAIN_LOCATION (marker),
marker_data->latitude, marker_data->longitude);
champlain_marker_layer_add_marker (marker_data->layer, CHAMPLAIN_MARKER (marker));
cleanup:
if (marker_data)
- g_object_unref (marker_data->layer);
+ g_clear_object (&marker_data->layer);
g_slice_free (MarkerData, marker_data);
g_free (url);
- if (error != NULL)
- g_error_free (error);
-
- if (pixbuf != NULL)
- g_object_unref (G_OBJECT (pixbuf));
-
- if (texture != NULL)
- clutter_actor_destroy (CLUTTER_ACTOR (texture));
+ g_clear_error (&error);
+ g_clear_object (&pixbuf);
+ g_clear_object (&texture);
}
+#endif
/**
@@ -212,8 +259,14 @@ create_marker_from_url (ChamplainMarkerLayer *layer,
data->latitude = latitude;
data->longitude = longitude;
- message = soup_message_new ("GET", url);
+ message = soup_message_new (SOUP_METHOD_GET, url);
+#ifdef CHAMPLAIN_LIBSOUP_3
+ soup_session_send_async (session, message, G_PRIORITY_DEFAULT_IDLE, NULL,
+ image_downloaded_cb, data);
+ g_object_unref (message);
+#else
soup_session_queue_message (session, message, image_downloaded_cb, data);
+#endif
}
diff --git a/meson.build b/meson.build
index 8c40f52..1fee9e9 100644
--- a/meson.build
+++ b/meson.build
@@ -51,13 +51,14 @@ cc = meson.get_compiler('c')
libm_dep = cc.find_library('m', required: true)
-glib_req = '>= 2.38'
+glib_req = '>= 2.68'
gtk_req = '>= 3.0'
clutter_req = '>= 1.24'
clutter_gtk_req = '>= 1.0'
cairo_req = '>= 1.4'
sqlite_req = '>= 3.0'
-libsoup_req = '>= 2.42'
+libsoup2_req = '>= 2.42'
+libsoup3_req = '>= 3.0'
memphis_req = '>= 0.2.1'
introspection_req = '>= 0.6.3'
vala_req = '>= 0.11.0'
@@ -70,7 +71,13 @@ gdk_dep = dependency('gdk-3.0', version: gtk_req)
clutter_dep = dependency('clutter-1.0', version: clutter_req)
cairo_dep = dependency('cairo', version: cairo_req)
sqlite_dep = dependency('sqlite3', version: sqlite_req)
-libsoup_dep = dependency('libsoup-2.4', version: libsoup_req)
+if get_option('libsoup3')
+ libsoup_dep = dependency('libsoup-3.0', version: libsoup3_req)
+ libsoup_api_version = '3.0'
+else
+ libsoup_dep = dependency('libsoup-2.4', version: libsoup2_req)
+ libsoup_api_version = '2.4'
+endif
gtk_dep = dependency('gtk+-3.0', version: gtk_req, required: false)
clutter_gtk_dep = dependency('clutter-gtk-1.0', version: clutter_gtk_req, required: false)
diff --git a/meson_options.txt b/meson_options.txt
index 8713d62..98852be 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -20,3 +20,7 @@ option('gtk_doc',
option('demos',
type: 'boolean', value: false,
description: 'Build demonstration programs')
+
+option('libsoup3',
+ type: 'boolean', value: true,
+ description: 'Use libsoup 3.0')
\ No newline at end of file
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]