messenger-gtk

Gtk+3 graphical user interfaces for GNUnet Messenger
Log | Files | Refs | Submodules | README | LICENSE

request.c (9613B)


      1 /*
      2    This file is part of GNUnet.
      3    Copyright (C) 2024 GNUnet e.V.
      4 
      5    GNUnet is free software: you can redistribute it and/or modify it
      6    under the terms of the GNU Affero General Public License as published
      7    by the Free Software Foundation, either version 3 of the License,
      8    or (at your option) any later version.
      9 
     10    GNUnet is distributed in the hope that it will be useful, but
     11    WITHOUT ANY WARRANTY; without even the implied warranty of
     12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13    Affero General Public License for more details.
     14 
     15    You should have received a copy of the GNU Affero General Public License
     16    along with this program.  If not, see <http://www.gnu.org/licenses/>.
     17 
     18    SPDX-License-Identifier: AGPL3.0-or-later
     19  */
     20 /*
     21  * @author Tobias Frisch
     22  * @file request.c
     23  */
     24 
     25 #include "request.h"
     26 
     27 #ifndef MESSENGER_APPLICATION_NO_PORTAL
     28 #include <libportal/portal.h>
     29 #endif
     30 
     31 #ifdef MESSENGER_APPLICATION_NO_PORTAL
     32 
     33 static gboolean
     34 _request_timeout_call(gpointer user_data)
     35 {
     36   g_assert(user_data);
     37 
     38   MESSENGER_Request* request = (MESSENGER_Request*) user_data;
     39 
     40   MESSENGER_Application *app = request->application;
     41   MESSENGER_RequestCallback callback = request->callback;
     42   gpointer data = request->user_data;
     43 
     44   request_cleanup(request);
     45   request_drop(request);
     46 
     47   if (callback)
     48     callback(app, TRUE, FALSE, data);
     49 
     50   return FALSE;
     51 }
     52 
     53 #endif
     54 
     55 MESSENGER_Request*
     56 request_new(MESSENGER_Application *application,
     57             MESSENGER_RequestCallback callback,
     58             GCancellable *cancellable,
     59             gpointer user_data)
     60 {
     61   g_assert((application) && (cancellable));
     62 
     63   MESSENGER_Request* request = g_malloc(sizeof(MESSENGER_Request));
     64 
     65   request->application = application;
     66   request->callback = callback;
     67   request->cancellable = cancellable;
     68   request->user_data = user_data;
     69 
     70 #ifdef MESSENGER_APPLICATION_NO_PORTAL
     71   request->timeout = util_immediate_add(
     72     G_SOURCE_FUNC(_request_timeout_call),
     73     request
     74   );
     75 #endif
     76 
     77   application->requests = g_list_append(
     78     application->requests, 
     79     request
     80   );
     81 
     82   return request;
     83 }
     84 
     85 #ifndef MESSENGER_APPLICATION_NO_PORTAL
     86 static void
     87 _request_background_callback(GObject *source_object,
     88                              GAsyncResult *result,
     89                              gpointer user_data)
     90 {
     91   g_assert((source_object) && (result) && (user_data));
     92 
     93   XdpPortal *portal = XDP_PORTAL(source_object);
     94   MESSENGER_Request *request = (MESSENGER_Request*) user_data;
     95 
     96   request_cleanup(request);
     97 
     98   MESSENGER_Application *app = request->application;
     99   MESSENGER_RequestCallback callback = request->callback;
    100   gpointer data = request->user_data;
    101   
    102   GError *error = NULL;
    103   gboolean success = xdp_portal_request_background_finish(
    104     portal, result, &error
    105   );
    106 
    107   request_drop(request);
    108 
    109   gboolean error_value = false;
    110   if (error)
    111   {
    112     g_printerr("ERROR: %s\n", error->message);
    113     g_error_free(error);
    114 
    115     error_value = true;
    116   }
    117 
    118   if (callback)
    119     callback(app, success, error_value, data);
    120 }
    121 #endif
    122 
    123 MESSENGER_Request*
    124 request_new_background(MESSENGER_Application *application,
    125                        XdpBackgroundFlags flags,
    126                        MESSENGER_RequestCallback callback,
    127                        gpointer user_data)
    128 {
    129   g_assert((application) && (callback));
    130 
    131   GCancellable* cancellable = g_cancellable_new();
    132 
    133   if (!cancellable)
    134     return NULL;
    135 
    136   MESSENGER_Request* request = request_new(
    137     application,
    138     callback,
    139     cancellable,
    140     user_data
    141   );
    142 
    143 #ifndef MESSENGER_APPLICATION_NO_PORTAL
    144   xdp_portal_request_background(
    145     application->portal,
    146     application->parent,
    147     NULL,
    148     NULL,
    149     flags,
    150     cancellable,
    151     _request_background_callback,
    152     request
    153   );
    154 #endif
    155 
    156   return request;
    157 }
    158 
    159 #ifndef MESSENGER_APPLICATION_NO_PORTAL
    160 static void
    161 _request_camera_callback(GObject *source_object,
    162                          GAsyncResult *result,
    163                          gpointer user_data)
    164 {
    165   g_assert((source_object) && (result) && (user_data));
    166 
    167   XdpPortal *portal = (XdpPortal*) source_object;
    168   MESSENGER_Request *request = (MESSENGER_Request*) user_data;
    169 
    170   request_cleanup(request);
    171 
    172   MESSENGER_Application *app = request->application;
    173   MESSENGER_RequestCallback callback = request->callback;
    174   gpointer data = request->user_data;
    175 
    176   GError *error = NULL;
    177   gboolean success = xdp_portal_access_camera_finish(
    178     portal, result, &error
    179   );
    180 
    181   request_drop(request);
    182 
    183   gboolean error_value = false;
    184   if (error)
    185   {
    186     g_printerr("ERROR: %s\n", error->message);
    187     g_error_free(error);
    188 
    189     error_value = true;
    190   }
    191 
    192   if (callback)
    193     callback(app, success, error_value, data);
    194 }
    195 #endif
    196 
    197 MESSENGER_Request*
    198 request_new_camera(MESSENGER_Application *application,
    199                    XdpCameraFlags flags,
    200                    MESSENGER_RequestCallback callback,
    201                    gpointer user_data)
    202 {
    203   g_assert((application) && (callback));
    204 
    205   GCancellable* cancellable = g_cancellable_new();
    206 
    207   if (!cancellable)
    208     return NULL;
    209 
    210   MESSENGER_Request* request = request_new(
    211     application,
    212     callback,
    213     cancellable,
    214     user_data
    215   );
    216 
    217 #ifndef MESSENGER_APPLICATION_NO_PORTAL
    218   xdp_portal_access_camera(
    219     application->portal,
    220     application->parent,
    221     flags,
    222     cancellable,
    223     _request_camera_callback,
    224     request
    225   );
    226 #endif
    227 
    228   return request;
    229 }
    230 
    231 #ifndef MESSENGER_APPLICATION_NO_PORTAL
    232 static void
    233 _request_session_start_callback(GObject *source_object,
    234                                 GAsyncResult *result,
    235                                 gpointer user_data)
    236 {
    237   g_assert((source_object) && (result) && (user_data));
    238 
    239   XdpSession *session = (XdpSession*) source_object;
    240   MESSENGER_Request *request = (MESSENGER_Request*) user_data;
    241 
    242   request_cleanup(request);
    243 
    244   MESSENGER_Application *app = request->application;
    245   MESSENGER_RequestCallback callback = request->callback;
    246   gpointer data = request->user_data;
    247 
    248   GError *error = NULL;
    249   gboolean success = xdp_session_start_finish(
    250     session,
    251     result,
    252     &error
    253   );
    254 
    255   application_set_active_session(app, success? session : NULL);
    256   request_drop(request);
    257 
    258   gboolean error_value = false;
    259   if (error)
    260   {
    261     g_printerr("ERROR: %s\n", error->message);
    262     g_error_free(error);
    263 
    264     error_value = true;
    265   }
    266 
    267   if (callback)
    268     callback(app, success, error_value, data);
    269 }
    270 
    271 static void
    272 _request_screencast_callback(GObject *source_object,
    273                              GAsyncResult *result,
    274                              gpointer user_data)
    275 {
    276   g_assert((source_object) && (result) && (user_data));
    277 
    278   XdpPortal *portal = (XdpPortal*) source_object;
    279   MESSENGER_Request *request = (MESSENGER_Request*) user_data;
    280 
    281   request_cleanup(request);
    282 
    283   MESSENGER_Application *app = request->application;
    284   MESSENGER_RequestCallback callback = request->callback;
    285   gpointer data = request->user_data;
    286 
    287   GError *error = NULL;
    288   XdpSession *session = xdp_portal_create_screencast_session_finish(
    289     portal, result, &error
    290   );
    291 
    292   if (session)
    293     application_set_active_session(app, session);
    294   request_drop(request);
    295 
    296   gboolean error_value = false;
    297   if (error)
    298   {
    299     g_printerr("ERROR: %s\n", error->message);
    300     g_error_free(error);
    301 
    302     error_value = true;
    303   }
    304 
    305   if (!session)
    306     goto skip_session_start;
    307 
    308   GCancellable* cancellable = g_cancellable_new();
    309 
    310   if (!cancellable)
    311     goto skip_session_start;
    312 
    313   request = request_new(
    314     app,
    315     callback,
    316     cancellable,
    317     data
    318   );
    319 
    320   xdp_session_start(
    321     session,
    322     app->parent,
    323     cancellable,
    324     _request_session_start_callback,
    325     request
    326   );
    327 
    328   return;
    329   
    330 skip_session_start:
    331   if (callback)
    332     callback(app, false, error_value, data);
    333 }
    334 #endif
    335 
    336 MESSENGER_Request*
    337 request_new_screencast(MESSENGER_Application *application,
    338                        XdpOutputType outputs,
    339                        XdpScreencastFlags flags,
    340                        XdpCursorMode cursor_mode,
    341                        XdpPersistMode persist_mode,
    342                        MESSENGER_RequestCallback callback,
    343                        gpointer user_data)
    344 {
    345   g_assert((application) && (callback));
    346 
    347   GCancellable* cancellable = g_cancellable_new();
    348 
    349   if (!cancellable)
    350     return NULL;
    351 
    352   MESSENGER_Request* request = request_new(
    353     application,
    354     callback,
    355     cancellable,
    356     user_data
    357   );
    358 
    359 #ifndef MESSENGER_APPLICATION_NO_PORTAL
    360   xdp_portal_create_screencast_session(
    361     application->portal,
    362     outputs,
    363     flags,
    364     cursor_mode,
    365     persist_mode,
    366     NULL,
    367     cancellable,
    368     _request_screencast_callback,
    369     request
    370   );
    371 #endif
    372 
    373   return request;
    374 }
    375 
    376 void
    377 request_cancel(MESSENGER_Request *request)
    378 {
    379   g_assert(request);
    380 
    381 #ifdef MESSENGER_APPLICATION_NO_PORTAL
    382   if (request->timeout)
    383     util_source_remove(request->timeout);
    384 
    385   request->timeout = 0;
    386 #endif
    387 
    388   if (!request->cancellable)
    389     return;
    390   
    391   if (!g_cancellable_is_cancelled(request->cancellable))
    392     g_cancellable_cancel(request->cancellable);
    393 }
    394 
    395 void
    396 request_cleanup(MESSENGER_Request *request)
    397 {
    398   g_assert(request);
    399 
    400 #ifdef MESSENGER_APPLICATION_NO_PORTAL
    401   if (request->timeout)
    402     util_source_remove(request->timeout);
    403 
    404   request->timeout = 0;
    405 #endif
    406 
    407   if (!request->cancellable)
    408     return;
    409 
    410   g_object_unref(request->cancellable);
    411   request->cancellable = NULL;
    412 }
    413 
    414 void
    415 request_drop(MESSENGER_Request *request)
    416 {
    417   g_assert(request);
    418 
    419   if (request->application->requests)
    420     request->application->requests = g_list_remove(
    421       request->application->requests,
    422       request
    423     );
    424 
    425   request_delete(request);
    426 }
    427 
    428 void
    429 request_delete(MESSENGER_Request *request)
    430 {
    431   g_assert(request);
    432 
    433   request_cleanup(request);
    434   g_free(request);
    435 }