[libchamplain/tintou/libsoup3] Port to libsoup3




commit 065bd21dea8f90cdff901292a81b8c6a6d2efb82
Author: Corentin Noël <tintou noel tf>
Date:   Tue Aug 2 10:06:27 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 |  49 +++---
 champlain/champlain-network-tile-source.c      | 233 +++++++++++++------------
 demos/url-marker.c                             | 111 ++----------
 meson.build                                    |   6 +-
 5 files changed, 168 insertions(+), 235 deletions(-)
---
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 9f689091..ff0722cd 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,4 +1,4 @@
-image: fedora:29
+image: fedora:36
 
 stages:
   - build
@@ -6,7 +6,7 @@ stages:
 
 before_script:
   - dnf install -y gcc ccache gettext gtk-doc meson ninja-build redhat-rpm-config
-  - dnf install -y glib2-devel clutter-devel gtk3-devel clutter-gtk-devel cairo-devel sqlite-devel 
libsoup-devel gobject-introspection-devel vala-devel
+  - dnf install -y glib2-devel clutter-devel gtk3-devel clutter-gtk-devel cairo-devel sqlite-devel 
libsoup3-devel gobject-introspection-devel vala-devel
 
 .ccache-setup: &ccache-setup
   variables:
diff --git a/champlain/champlain-network-bbox-tile-source.c b/champlain/champlain-network-bbox-tile-source.c
index f6f10bac..77af19e6 100644
--- a/champlain/champlain-network-bbox-tile-source.c
+++ b/champlain/champlain-network-bbox-tile-source.c
@@ -116,8 +116,11 @@ 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);
+        {
+          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);
+        }
       break;
 
     case PROP_STATE:
@@ -253,18 +256,11 @@ 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 */
-  priv->proxy_uri = g_strdup ("");
   priv->soup_session = soup_session_new_with_options (
-        "proxy-uri", soup_uri_new (priv->proxy_uri),
-        "ssl-strict", FALSE,
-        SOUP_SESSION_ADD_FEATURE_BY_TYPE, 
-        SOUP_TYPE_PROXY_RESOLVER_DEFAULT,
-        NULL);
-  g_object_set (G_OBJECT (priv->soup_session),
-      "user-agent", 
-      "libchamplain/" CHAMPLAIN_VERSION_S,
-      "max-conns-per-host", 2, 
-      NULL);
+      "user-agent", "libchamplain/" CHAMPLAIN_VERSION_S,
+      "max-conns-per-host", 2,
+      NULL
+  );
 
   priv->state = CHAMPLAIN_STATE_NONE;
 }
@@ -314,27 +310,35 @@ champlain_network_bbox_tile_source_new_full (const gchar *id,
   return source;
 }
 
-
 static void
-load_map_data_cb (G_GNUC_UNUSED SoupSession *session, SoupMessage *msg,
+load_map_data_cb (GObject *source_object,
+    GAsyncResult *res,
     gpointer user_data)
 {
+  ChamplainRenderer *renderer;
   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 (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code))
+  if (error != NULL)
     {
-      DEBUG ("Unable to download file: %s",
-          soup_status_get_phrase (msg->status_code));
+      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));
-  champlain_renderer_set_data (renderer, (guint8*) msg->response_body->data, msg->response_body->length);
+  data = g_bytes_get_data (bytes, &size);
+  champlain_renderer_set_data (renderer, data, size);
+  g_object_unref (bytes);
 }
 
 
@@ -370,7 +374,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 +382,8 @@ champlain_network_bbox_tile_source_load_map_data (
 
   g_object_set (G_OBJECT (self), "state", CHAMPLAIN_STATE_LOADING, NULL);
 
-  soup_session_queue_message (priv->soup_session, msg, load_map_data_cb, self);
+  soup_session_send_and_read_async (priv->soup_session, msg, G_PRIORITY_DEFAULT_IDLE, NULL, 
load_map_data_cb, self);
+  g_object_unref (msg);
 }
 
 
diff --git a/champlain/champlain-network-tile-source.c b/champlain/champlain-network-tile-source.c
index 281f000a..6951dbab 100644
--- a/champlain/champlain-network-tile-source.c
+++ b/champlain/champlain-network-tile-source.c
@@ -80,17 +80,12 @@ G_DEFINE_TYPE_WITH_PRIVATE (ChamplainNetworkTileSource, champlain_network_tile_s
  */
 #define MAX_CONNS_DEFAULT 2
 
-typedef struct
-{
-  ChamplainMapSource *map_source;
-  SoupMessage *msg;
-} TileCancelledData;
-
 typedef struct
 {
   ChamplainMapSource *map_source;
   ChamplainTile *tile;
-  TileCancelledData *cancelled_data;
+  SoupMessage *msg;
+  GCancellable *cancellable;
 } TileLoadedData;
 
 typedef struct
@@ -102,9 +97,6 @@ typedef struct
 
 static void fill_tile (ChamplainMapSource *map_source,
     ChamplainTile *tile);
-static void tile_state_notify (ChamplainTile *tile,
-    G_GNUC_UNUSED GParamSpec *pspec,
-    TileCancelledData *data);
 
 static gchar *get_tile_uri (ChamplainNetworkTileSource *source,
     gint x,
@@ -185,11 +177,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);
 }
@@ -323,19 +313,11 @@ champlain_network_tile_source_init (ChamplainNetworkTileSource *tile_source)
   priv->max_conns = MAX_CONNS_DEFAULT;
 
   priv->soup_session = soup_session_new_with_options (
-        "proxy-uri", NULL,
-        "ssl-strict", FALSE,
-        SOUP_SESSION_ADD_FEATURE_BY_TYPE, 
-        SOUP_TYPE_PROXY_RESOLVER_DEFAULT,
-        SOUP_SESSION_ADD_FEATURE_BY_TYPE,
-        SOUP_TYPE_CONTENT_DECODER,
-        NULL);
-  g_object_set (G_OBJECT (priv->soup_session),
-      "user-agent", 
-      "libchamplain/" CHAMPLAIN_VERSION_S,
+      "user-agent", "libchamplain/" CHAMPLAIN_VERSION_S,
       "max-conns-per-host", MAX_CONNS_DEFAULT,
       "max-conns", MAX_CONNS_DEFAULT,
-      NULL);
+      NULL
+  );
 }
 
 
@@ -474,21 +456,16 @@ 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;
-  SoupURI *uri = NULL;
 
   g_free (priv->proxy_uri);
   priv->proxy_uri = g_strdup (proxy_uri);
 
-  if (priv->proxy_uri)
-    uri = soup_uri_new (priv->proxy_uri);
-
   if (priv->soup_session)
-    g_object_set (G_OBJECT (priv->soup_session),
-        "proxy-uri", uri,
-        NULL);
-
-  if (uri)
-    soup_uri_free (uri);
+    {
+      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);
+    }
 
   g_object_notify (G_OBJECT (tile_source), "proxy-uri");
 }
@@ -660,6 +637,23 @@ get_tile_uri (ChamplainNetworkTileSource *tile_source,
   return token;
 }
 
+static void
+tile_redered_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);
+  g_clear_object (&data->cancellable);
+  g_clear_object (&data->msg);
+  g_slice_free (TileLoadedData, data);
+}
 
 static void
 tile_rendered_cb (ChamplainTile *tile,
@@ -670,10 +664,9 @@ tile_rendered_cb (ChamplainTile *tile,
 {
   ChamplainMapSource *map_source = 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);
 
@@ -696,114 +689,131 @@ tile_rendered_cb (ChamplainTile *tile,
     champlain_map_source_fill_tile (next_source, tile);
 
   g_free (etag);
-  g_object_unref (map_source);
-  g_object_unref (tile);
 }
 
+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 (G_GNUC_UNUSED SoupSession *session,
-    SoupMessage *msg,
+tile_loaded_cb (GObject *source_object,
+    GAsyncResult *res,
     gpointer user_data)
 {
   TileLoadedData *callback_data = (TileLoadedData *) user_data;
-  ChamplainMapSource *map_source = callback_data->map_source;
-  ChamplainTileSource *tile_source = CHAMPLAIN_TILE_SOURCE (map_source);
-  ChamplainTileCache *tile_cache = champlain_tile_source_get_cache (tile_source);
-  ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source);
+  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;
-  ChamplainRenderer *renderer;
+  GInputStream *stream;
+       GOutputStream *ostream;
+  GError *error = NULL;
+  SoupStatus status;
+  SoupMessageHeaders *response_headers;
 
-  g_signal_handlers_disconnect_by_func (tile, tile_state_notify, callback_data->cancelled_data);
-  g_slice_free (TileLoadedData, callback_data);
+  stream = soup_session_send_finish (SOUP_SESSION (source_object), res, &error);
+  status = soup_message_get_status (msg);
+  DEBUG ("Got reply %d", status);
 
-  DEBUG ("Got reply %d", msg->status_code);
-
-  if (msg->status_code == SOUP_STATUS_CANCELLED)
+  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 (msg->status_code == SOUP_STATUS_NOT_MODIFIED)
+  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);
-      goto finish;
+
+      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 (msg->status_code))
+  if (!SOUP_STATUS_IS_SUCCESSFUL (status))
     {
-      DEBUG ("Unable to download tile %d, %d: %s",
+      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 (msg->status_code));
+          soup_status_get_phrase (status),
+          soup_message_get_reason_phrase (msg));
 
-      goto load_next;
+      if (next_source)
+        champlain_map_source_fill_tile (next_source, tile);
+
+      goto cleanup;
     }
 
   /* Verify if the server sent an etag and save it */
-  etag = soup_message_headers_get_one (msg->response_headers, "ETag");
+  response_headers = soup_message_get_response_headers (msg);
+  etag = soup_message_headers_get_one (response_headers, "ETag");
   DEBUG ("Received ETag %s", etag);
 
-  renderer = champlain_map_source_get_renderer (map_source);
-  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_redered_data_free, 0);
 
-  champlain_renderer_set_data (renderer, (guint8*) msg->response_body->data, msg->response_body->length);
-  champlain_renderer_render (renderer, tile);
+  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_object_unref (ostream);
+  g_object_unref (stream);
 
   return;
 
-load_next:
-  if (next_source)
-    champlain_map_source_fill_tile (next_source, tile);
-
-  goto cleanup;
-
-finish:
-  champlain_tile_set_fade_in (tile, TRUE);
-  champlain_tile_set_state (tile, CHAMPLAIN_STATE_DONE);
-  champlain_tile_display_content (tile);
-
 cleanup:
-  g_object_unref (tile);
-  g_object_unref (map_source);
-}
-
-
-static void
-destroy_cancelled_data (TileCancelledData *data,
-    G_GNUC_UNUSED GClosure *closure)
-{
-  if (data->map_source)
-    g_object_remove_weak_pointer (G_OBJECT (data->map_source), (gpointer *) &data->map_source);
-
-  if (data->msg)
-    g_object_remove_weak_pointer (G_OBJECT (data->msg), (gpointer *) &data->msg);
-
-  g_slice_free (TileCancelledData, data);
+  tile_loaded_data_free (callback_data);
+  g_clear_error (&error);
+  g_clear_object (&stream);
 }
 
 
 static void
 tile_state_notify (ChamplainTile *tile,
     G_GNUC_UNUSED GParamSpec *pspec,
-    TileCancelledData *data)
+    gpointer user_data)
 {
-  if (champlain_tile_get_state (tile) == CHAMPLAIN_STATE_DONE && data->map_source && data->msg)
+  GCancellable *cancellable = user_data;
+
+  if (champlain_tile_get_state (tile) == CHAMPLAIN_STATE_DONE && cancellable != NULL)
     {
       DEBUG ("Canceling tile download");
-      ChamplainNetworkTileSourcePrivate *priv = CHAMPLAIN_NETWORK_TILE_SOURCE (data->map_source)->priv;
-      soup_session_cancel_message (priv->soup_session, data->msg, SOUP_STATUS_CANCELLED);
+      g_cancellable_cancel (cancellable);
     }
 }
 
@@ -842,6 +852,7 @@ fill_tile (ChamplainMapSource *map_source,
 
   ChamplainNetworkTileSource *tile_source = CHAMPLAIN_NETWORK_TILE_SOURCE (map_source);
   ChamplainNetworkTileSourcePrivate *priv = tile_source->priv;
+  GCancellable *cancellable = NULL;
 
   if (champlain_tile_get_state (tile) == CHAMPLAIN_STATE_DONE)
     return;
@@ -865,6 +876,7 @@ fill_tile (ChamplainMapSource *map_source,
 
           const gchar *etag = champlain_tile_get_etag (tile);
           gchar *date = get_modified_time_string (tile);
+          SoupMessageHeaders *headers = soup_message_get_request_headers (msg);
 
           /* If an etag is available, only use it.
            * OSM servers seems to send now as the modified time for all tiles
@@ -873,40 +885,29 @@ 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);
         }
 
-      TileCancelledData *tile_cancelled_data = g_slice_new (TileCancelledData);
-      tile_cancelled_data->map_source = map_source;
-      tile_cancelled_data->msg = msg;
-
-      g_object_add_weak_pointer (G_OBJECT (msg), (gpointer *) &tile_cancelled_data->msg);
-      g_object_add_weak_pointer (G_OBJECT (map_source), (gpointer *) &tile_cancelled_data->map_source);
-
-      g_signal_connect_data (tile, "notify::state", G_CALLBACK (tile_state_notify),
-          tile_cancelled_data, (GClosureNotify) destroy_cancelled_data, 0);
+      cancellable = g_cancellable_new ();
+      g_signal_connect (tile, "notify::state", G_CALLBACK (tile_state_notify), cancellable);
 
       callback_data = g_slice_new (TileLoadedData);
-      callback_data->tile = tile;
-      callback_data->map_source = map_source;
-      callback_data->cancelled_data = tile_cancelled_data;
-
-      g_object_ref (map_source);
-      g_object_ref (tile);
+      callback_data->tile = g_object_ref (tile);
+      callback_data->map_source = g_object_ref (map_source);
+      callback_data->cancellable = g_object_ref (cancellable);
+      callback_data->msg = msg; // transfer ownership
 
-      soup_session_queue_message (priv->soup_session, msg,
-          tile_loaded_cb,
-          callback_data);
+      soup_session_send_async (priv->soup_session, msg, G_PRIORITY_DEFAULT_IDLE, cancellable, 
tile_loaded_cb, callback_data);
     }
   else
     {
diff --git a/demos/url-marker.c b/demos/url-marker.c
index 8134d665..322b9add 100644
--- a/demos/url-marker.c
+++ b/demos/url-marker.c
@@ -28,66 +28,6 @@ typedef struct
   gdouble longitude;
 } MarkerData;
 
-/**
- * Returns a GdkPixbuf from a given SoupMessage. This function assumes that the
- * message has completed successfully.
- * If there's an error building the GdkPixbuf the function will return NULL and
- * set error accordingly.
- *
- * The GdkPixbuf has to be freed with g_object_unref.
- */
-static GdkPixbuf *
-pixbuf_new_from_message (SoupMessage *message,
-    GError **error)
-{
-  const gchar *mime_type = NULL;
-  GdkPixbufLoader *loader = NULL;
-  GdkPixbuf *pixbuf = NULL;
-  gboolean pixbuf_is_open = FALSE;
-
-  *error = NULL;
-
-  /*  Use a pixbuf loader that can load images of the same mime-type as the
-      message.
-   */
-  mime_type = soup_message_headers_get_one (message->response_headers,
-        "Content-Type");
-  loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, error);
-  if (loader != NULL)
-    pixbuf_is_open = TRUE;
-  if (*error != NULL)
-    goto cleanup;
-
-
-  gdk_pixbuf_loader_write (
-      loader,
-      (guchar *) message->response_body->data,
-      message->response_body->length,
-      error);
-  if (*error != NULL)
-    goto cleanup;
-
-  gdk_pixbuf_loader_close (loader, error);
-  pixbuf_is_open = FALSE;
-  if (*error != NULL)
-    goto cleanup;
-
-  pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
-  if (pixbuf == NULL)
-    goto cleanup;
-  g_object_ref (G_OBJECT (pixbuf));
-
-cleanup:
-  if (pixbuf_is_open)
-    gdk_pixbuf_loader_close (loader, NULL);
-
-  if (loader != NULL)
-    g_object_unref (G_OBJECT (loader));
-
-  return pixbuf;
-}
-
-
 static ClutterActor *
 texture_new_from_pixbuf (GdkPixbuf *pixbuf, GError **error)
 {
@@ -126,36 +66,27 @@ texture_new_from_pixbuf (GdkPixbuf *pixbuf, GError **error)
  * This callback expects the parameter data to be a valid ChamplainMarkerLayer.
  */
 static void
-image_downloaded_cb (SoupSession *session,
-    SoupMessage *message,
-    gpointer data)
+image_downloaded_cb (GObject *source_object,
+    GAsyncResult *res,
+    gpointer user_data)
 {
-  MarkerData *marker_data = NULL;
-  SoupURI *uri = NULL;
-  char *url = NULL;
+  MarkerData *marker_data = (MarkerData *) user_data;
   GError *error = NULL;
   GdkPixbuf *pixbuf = NULL;
   ClutterActor *texture = NULL;
   ClutterActor *marker = NULL;
+  GInputStream *stream;
 
-  if (data == NULL)
+  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;
-  marker_data = (MarkerData *) data;
+  }
 
-  /* Deal only with finished messages */
-  uri = soup_message_get_uri (message);
-  url = soup_uri_to_string (uri, FALSE);
-  if (!SOUP_STATUS_IS_SUCCESSFUL (message->status_code))
-    {
-      g_print ("Download of %s failed with error code %d\n", url,
-          message->status_code);
-      goto cleanup;
-    }
-
-  pixbuf = pixbuf_new_from_message (message, &error);
+  pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, &error);
   if (error != NULL)
     {
-      g_print ("Failed to convert %s into an image: %s\n", url, error->message);
+      g_print ("Failed to parse the image: %s\n", error->message);
       goto cleanup;
     }
 
@@ -163,7 +94,7 @@ image_downloaded_cb (SoupSession *session,
   texture = texture_new_from_pixbuf (pixbuf, &error);
   if (error != NULL)
     {
-      g_print ("Failed to convert %s into a texture: %s\n", url,
+      g_print ("Failed to convert the image into a texture: %s\n",
           error->message);
       goto cleanup;
     }
@@ -179,16 +110,10 @@ cleanup:
   if (marker_data)
     g_object_unref (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_pointer (&texture, clutter_actor_destroy);
 }
 
 
@@ -212,8 +137,10 @@ create_marker_from_url (ChamplainMarkerLayer *layer,
   data->latitude = latitude;
   data->longitude = longitude;
 
-  message = soup_message_new ("GET", url);
-  soup_session_queue_message (session, message, image_downloaded_cb, data);
+  message = soup_message_new (SOUP_METHOD_GET, url);
+  soup_session_send_async (session, message, G_PRIORITY_DEFAULT_IDLE, NULL,
+      image_downloaded_cb, data);
+  g_object_unref (message);
 }
 
 
diff --git a/meson.build b/meson.build
index 8c40f52f..34ba2572 100644
--- a/meson.build
+++ b/meson.build
@@ -51,13 +51,13 @@ 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'
+libsoup_req = '>= 3.0'
 memphis_req = '>= 0.2.1'
 introspection_req = '>= 0.6.3'
 vala_req = '>= 0.11.0'
@@ -70,7 +70,7 @@ 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)
+libsoup_dep = dependency('libsoup-3.0', version: libsoup_req)
 
 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)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]