[beast: 19/20] SFI: add url_show() from Rapicorn



commit db09c0ba7d59eced5a7dbe790a3a770ad7dffb54
Author: Tim Janik <timj gnu org>
Date:   Sun Sep 17 16:12:10 2017 +0200

    SFI: add url_show() from Rapicorn
    
    Import is based on Rapicorn commit id:
        bf228016cba3f6d252ee2cc38e1ed32607f37bf0
    
    Signed-off-by: Tim Janik <timj gnu org>

 sfi/bcore.cc |   93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sfi/bcore.hh |    4 ++-
 2 files changed, 96 insertions(+), 1 deletions(-)
---
diff --git a/sfi/bcore.cc b/sfi/bcore.cc
index db6da7a..12ae613 100644
--- a/sfi/bcore.cc
+++ b/sfi/bcore.cc
@@ -124,6 +124,99 @@ feature_toggle_bool (const char *config, const char *feature)
   return false;         // just whitespace
 }
 
+// == External Helpers ==
+/**
+ * Find a suitable WWW user agent (taking user configurations into account) and
+ * start it to display @a url. Several user agents are tried before giving up.
+ * @returns @a True if a user agent could be launched successfuly.
+ */
+bool
+url_show (const char *url)
+{
+  static struct {
+    const char   *prg, *arg1, *prefix, *postfix;
+    bool          asyncronous; /* start asyncronously and check exit code to catch launch errors */
+    volatile bool disabled;
+  } www_browsers[] = {
+    /* program */               /* arg1 */      /* prefix+URL+postfix */
+    /* configurable, working browser launchers */
+    { "gnome-open",             NULL,           "", "", 0 }, /* opens in background, correct exit_code */
+    { "exo-open",               NULL,           "", "", 0 }, /* opens in background, correct exit_code */
+    /* non-configurable working browser launchers */
+    { "kfmclient",              "openURL",      "", "", 0 }, /* opens in background, correct exit_code */
+    { "gnome-moz-remote",       "--newwin",     "", "", 0 }, /* opens in background, correct exit_code */
+#if 0
+    /* broken/unpredictable browser launchers */
+    { "browser-config",         NULL,            "", "", 0 }, /* opens in background (+ sleep 5), broken 
exit_code (always 0) */
+    { "xdg-open",               NULL,            "", "", 0 }, /* opens in foreground (first browser) or 
background, correct exit_code */
+    { "sensible-browser",       NULL,            "", "", 0 }, /* opens in foreground (first browser) or 
background, correct exit_code */
+    { "htmlview",               NULL,            "", "", 0 }, /* opens in foreground (first browser) or 
background, correct exit_code */
+#endif
+    /* direct browser invocation */
+    { "x-www-browser",          NULL,           "", "", 1 }, /* opens in foreground, browser alias */
+    { "firefox",                NULL,           "", "", 1 }, /* opens in foreground, correct exit_code */
+    { "mozilla-firefox",        NULL,           "", "", 1 }, /* opens in foreground, correct exit_code */
+    { "mozilla",                NULL,           "", "", 1 }, /* opens in foreground, correct exit_code */
+    { "konqueror",              NULL,           "", "", 1 }, /* opens in foreground, correct exit_code */
+    { "opera",                  "-newwindow",   "", "", 1 }, /* opens in foreground, correct exit_code */
+    { "galeon",                 NULL,           "", "", 1 }, /* opens in foreground, correct exit_code */
+    { "epiphany",               NULL,           "", "", 1 }, /* opens in foreground, correct exit_code */
+    { "amaya",                  NULL,           "", "", 1 }, /* opens in foreground, correct exit_code */
+    { "dillo",                  NULL,           "", "", 1 }, /* opens in foreground, correct exit_code */
+  };
+  uint i;
+  for (i = 0; i < ARRAY_SIZE (www_browsers); i++)
+    if (!www_browsers[i].disabled)
+      {
+        char *args[128] = { 0, };
+        uint n = 0;
+        args[n++] = (char*) www_browsers[i].prg;
+        if (www_browsers[i].arg1)
+          args[n++] = (char*) www_browsers[i].arg1;
+        char *string = g_strconcat (www_browsers[i].prefix, url, www_browsers[i].postfix, NULL);
+        args[n] = string;
+        GError *error = NULL;
+        char fallback_error[64] = "Ok";
+        bool success;
+        if (!www_browsers[i].asyncronous) /* start syncronously and check exit code */
+          {
+            int exit_status = -1;
+            success = g_spawn_sync (NULL, /* cwd */
+                                    args,
+                                    NULL, /* envp */
+                                    G_SPAWN_SEARCH_PATH,
+                                    NULL, /* child_setup() */
+                                    NULL, /* user_data */
+                                    NULL, /* standard_output */
+                                    NULL, /* standard_error */
+                                    &exit_status,
+                                    &error);
+            success = success && !exit_status;
+            if (exit_status)
+              g_snprintf (fallback_error, sizeof (fallback_error), "exitcode: %u", exit_status);
+          }
+        else
+          success = g_spawn_async (NULL, /* cwd */
+                                   args,
+                                   NULL, /* envp */
+                                   G_SPAWN_SEARCH_PATH,
+                                   NULL, /* child_setup() */
+                                   NULL, /* user_data */
+                                   NULL, /* child_pid */
+                                   &error);
+        g_free (string);
+        RAPICORN_KEY_DEBUG ("URL", "show \"%s\": %s: %s", url, args[0], error ? error->message : 
fallback_error);
+        g_clear_error (&error);
+        if (success)
+          return true;
+        www_browsers[i].disabled = true;
+      }
+  /* reset all disabled states if no browser could be found */
+  for (i = 0; i < ARRAY_SIZE (www_browsers); i++)
+    www_browsers[i].disabled = false;
+  return false;
+}
+
 // == Internal ==
 namespace Internal {
 
diff --git a/sfi/bcore.hh b/sfi/bcore.hh
index 05fd2db..794631e 100644
--- a/sfi/bcore.hh
+++ b/sfi/bcore.hh
@@ -27,7 +27,6 @@ typedef std::string String;             ///< Convenience alias for std::string.
 typedef vector<String> StringVector;    ///< Convenience alias for a std::vector<std::string>.
 using   Aida::Any;
 using   Aida::EventFd;
-using   Rapicorn::url_show;
 using   Rapicorn::void_t;
 using   Rapicorn::Blob;
 using   Rapicorn::Res;
@@ -211,6 +210,9 @@ info (const char *format, const Args &...args)
   Internal::diagnostic ('I', string_format (format, args...));
 }
 
+// == External Helpers ==
+bool url_show (const char *url); ///< Display @a url via a suitable WWW user agent.
+
 // == Assertions ==
 /// Return from the current function if @a cond is unmet and issue an assertion warning.
 #define BSE_ASSERT_RETURN(cond, ...)     do { if (BSE_ISLIKELY (cond)) break; ::Bse::assertion_failed 
(__FILE__, __LINE__, #cond); return __VA_ARGS__; } while (0)


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