summaryrefslogtreecommitdiff
path: root/src/common/desktop.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/desktop.c')
-rw-r--r--src/common/desktop.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/common/desktop.c b/src/common/desktop.c
new file mode 100644
index 0000000..23c62d7
--- /dev/null
+++ b/src/common/desktop.c
@@ -0,0 +1,81 @@
+#include "yasl/desktop.h"
+#include "common/backend.h"
+#include "common/desktop.h"
+
+#include <string.h>
+
+/* Large enough for any path the platform APIs return. */
+#define DESKTOP_STR_MAX 4096
+
+/* An RFC 3986 scheme, then ':', and no control characters anywhere. */
+static bool uri_valid(const char *uri)
+{
+ unsigned char c = (unsigned char)uri[0];
+ if ((unsigned)((c | 32) - 'a') >= 26) return false;
+ const char *p = uri + 1;
+ for (; *p != ':'; p++) {
+ c = (unsigned char)*p;
+ bool alpha = (unsigned)((c | 32) - 'a') < 26;
+ bool digit = (unsigned)(c - '0') < 10;
+ if (!alpha && !digit && c != '+' && c != '-' && c != '.') return false;
+ }
+ for (; *p; p++) {
+ c = (unsigned char)*p;
+ if (c < 0x20 || c == 0x7f) return false;
+ }
+ return true;
+}
+
+/* Copy len bytes and a NUL when they fit, and report the full length. */
+static size_t copy_out(char *out, size_t cap, const char *s, size_t len)
+{
+ if (len && len < cap) {
+ memcpy(out, s, len);
+ out[len] = '\0';
+ }
+ return len;
+}
+
+bool yasl_display_open_uri(struct yasl_display *d, const char *uri)
+{
+ if (!d || !uri || !uri_valid(uri)) return false;
+ return desktop_open_uri(uri);
+}
+
+bool yasl_display_notify(struct yasl_display *d, const char *title, const char *body)
+{
+ if (!d || !title) return false;
+ return desktop_notify(d->app_id, title, body ? body : "");
+}
+
+uint32_t yasl_display_appearance(struct yasl_display *d)
+{
+ return d ? desktop_appearance() : 0;
+}
+
+bool yasl_surface_bell(struct yasl_surface *s)
+{
+ if (!s || !s->display->ops->surface_bell) return false;
+ return s->display->ops->surface_bell(s);
+}
+
+size_t yasl_executable_path(char *out, size_t cap)
+{
+ if (!out && cap) return 0;
+ char buf[DESKTOP_STR_MAX];
+ return copy_out(out, cap, buf, desktop_executable_path(buf, sizeof(buf)));
+}
+
+size_t yasl_resource_dir(char *out, size_t cap)
+{
+ if (!out && cap) return 0;
+ char buf[DESKTOP_STR_MAX];
+ return copy_out(out, cap, buf, desktop_resource_dir(buf, sizeof(buf)));
+}
+
+size_t yasl_default_locale(char *out, size_t cap)
+{
+ if (!out && cap) return 0;
+ char buf[DESKTOP_STR_MAX];
+ return copy_out(out, cap, buf, desktop_default_locale(buf, sizeof(buf)));
+}