diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 13fe748..c1682cd 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -254,14 +254,6 @@ build-no-doxygen@fedora:37:
before_script:
- dnf remove -y doxygen
-build-no-portal@fedora:37:
- extends:
- - .fedora-build@template
- before_script:
- - dnf remove -y libsystemd-devel
- variables:
- MESON_ARGS: "-Dportal=false"
-
valgrind@fedora:37:
extends:
- .fedora-build@template
diff --git a/.gitlab-ci/ci.template b/.gitlab-ci/ci.template
index b420260..ae3fb8a 100644
--- a/.gitlab-ci/ci.template
+++ b/.gitlab-ci/ci.template
@@ -275,14 +275,6 @@ build-no-doxygen@{{distro.name}}:{{version}}:
before_script:
- dnf remove -y doxygen
-build-no-portal@{{distro.name}}:{{version}}:
- extends:
- - .{{distro.name}}-build@template
- before_script:
- - dnf remove -y libsystemd-devel
- variables:
- MESON_ARGS: "-Dportal=false"
-
valgrind@{{distro.name}}:{{version}}:
extends:
- .{{distro.name}}-build@template
diff --git a/doc/mainpage.dox b/doc/mainpage.dox
index b183d9f..435500c 100644
--- a/doc/mainpage.dox
+++ b/doc/mainpage.dox
@@ -58,10 +58,6 @@ implementation and sends events.
The `eis-demo-server` is a minimal EIS implementation that accepts all
requests and prints them to screen.
-The `eis-fake-portal` is a minimal [XDG Desktop
-Portal](https://github.com/flatpak/xdg-desktop-portal/) implementation that
-connects a portal-aware libei client with an EIS implementation.
-
@section building_against Building against libei or libeis
libei and libeis provides
diff --git a/examples/libei-client.pseudo b/examples/libei-client.pseudo
index 5fc2d38..dbc7509 100644
--- a/examples/libei-client.pseudo
+++ b/examples/libei-client.pseudo
@@ -2,7 +2,7 @@
function main():
ctx = ei_new()
- ei_portal_connect(ctx)
+ ei_connect(ctx)
ei_dispatch(ctx)
# let's say this is a blocking wait
diff --git a/examples/libeis-server.pseudo b/examples/libeis-server.pseudo
index 4a36d77..42b7040 100644
--- a/examples/libeis-server.pseudo
+++ b/examples/libeis-server.pseudo
@@ -7,7 +7,7 @@
function main():
ctx = eis_new()
- eis_portal_init(ctx)
+ eis_init(ctx)
while True:
poll(eis_get_fd()):
diff --git a/meson.build b/meson.build
index 70d885c..ec53ed9 100644
--- a/meson.build
+++ b/meson.build
@@ -94,25 +94,12 @@ src_libei = [
'src/libei-proto.h',
'src/libei-proto.c',
'src/libei-region.c',
- 'src/libei-stubs.c',
proto_headers,
]
-
-if get_option('portal')
- dep_systemd = dependency('libsystemd')
- config_h.set10('ENABLE_LIBEI_PORTAL', true)
- src_libei += [
- 'src/libei-portal.c',
- ]
-else
- dep_systemd = dependency('', required: false)
-endif
-
deps_libei = [
dep_libutil,
dep_protobuf,
- dep_systemd,
]
lib_libei = shared_library('ei',
@@ -133,7 +120,6 @@ pkgconfig.generate(lib_libei,
version: meson.project_version(),
libraries: lib_libei,
variables: [
- 'portal=' + get_option('portal').to_string(),
'protocol_version=' + protocol_version.to_string(),
],
)
@@ -238,17 +224,6 @@ executable('ei-debug-events',
dependencies: [dep_libutil, dep_libei, dep_libevdev],
install: true)
-if get_option('portal')
- executable('eis-fake-portal',
- 'tools/eis-fake-portal.c',
- include_directories: 'src',
- dependencies: [dep_libutil, dep_systemd, dep_libreis])
- executable('eis-fake-impl-portal',
- 'tools/eis-fake-impl-portal.c',
- include_directories: 'src',
- dependencies: [dep_libutil, dep_systemd, dep_libreis])
-endif
-
# tests
if get_option('tests')
subproject('munit', default_options: 'werror=false')
diff --git a/meson_options.txt b/meson_options.txt
index 0b426c3..a2862fc 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -1,3 +1,2 @@
-option('portal', type: 'boolean', value: 'true', description: 'Enable/disable org.freedesktop.portal support')
option('documentation', type: 'boolean', value: 'false', description: 'Enable/disable building the API documentation')
option('tests', type: 'boolean', value: 'true', description: 'Enable/disable tests')
diff --git a/portal/org.freedesktop.impl.portal.EmulatedInput.xml b/portal/org.freedesktop.impl.portal.EmulatedInput.xml
deleted file mode 100644
index d2daba3..0000000
--- a/portal/org.freedesktop.impl.portal.EmulatedInput.xml
+++ /dev/null
@@ -1,92 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/portal/org.freedesktop.portal.EmulatedInput.xml b/portal/org.freedesktop.portal.EmulatedInput.xml
deleted file mode 100644
index d57cb59..0000000
--- a/portal/org.freedesktop.portal.EmulatedInput.xml
+++ /dev/null
@@ -1,97 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/libei-portal.c b/src/libei-portal.c
deleted file mode 100644
index 096225d..0000000
--- a/src/libei-portal.c
+++ /dev/null
@@ -1,357 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2020 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include "config.h"
-
-#include
-#include
-#include
-#include
-
-#include "libei.h"
-#include "libei-private.h"
-
-#include "util-io.h"
-#include "util-macros.h"
-#include "util-mem.h"
-#include "util-object.h"
-#include "util-strings.h"
-
-struct ei_portal {
- struct object object;
- struct source *bus_source;
- sd_bus *bus;
- sd_bus_slot *slot;
-
- char *busname;
-};
-
-static void
-ei_portal_destroy(struct ei_portal *portal)
-{
- free(portal->busname);
- sd_bus_unref(portal->bus);
-}
-
-static
-OBJECT_IMPLEMENT_CREATE(ei_portal);
-static
-OBJECT_IMPLEMENT_PARENT(ei_portal, ei);
-static
-OBJECT_IMPLEMENT_REF(ei_portal);
-static
-OBJECT_IMPLEMENT_UNREF_CLEANUP(ei_portal);
-
-static void
-interface_portal_destroy(struct ei *ei, void *backend)
-{
- struct ei_portal *portal = backend;
- ei_portal_unref(portal);
-}
-
-static const struct ei_backend_interface interface = {
- .destroy = interface_portal_destroy,
-};
-
-static char *
-xdp_token(sd_bus *bus, char **token_out)
-{
- _cleanup_free_ char *sender = NULL;
- const char *name = NULL;
-
- if (sd_bus_get_unique_name(bus, &name) != 0)
- return NULL;
-
- sender = xstrdup(name + 1); /* drop initial : */
-
- for (unsigned i = 0; sender[i]; i++) {
- if (sender[i] == '.')
- sender[i] = '_';
- }
-
- char *token = xaprintf("ei_%d", rand());
- *token_out = token;
-
- return xaprintf("/org/freedesktop/portal/desktop/request/%s/%s", sender, token);
-}
-
-static void
-portal_connect(struct ei_portal *portal, const char *session_handle)
-{
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- _unref_(sd_bus_message) *response = NULL;
- struct sd_bus *bus = portal->bus;
- struct ei *ei = ei_portal_parent(portal);
- int eisfd;
-
- int rc = sd_bus_call_method(bus, portal->busname,
- "/org/freedesktop/portal/desktop",
- "org.freedesktop.portal.EmulatedInput",
- "ConnectToEIS",
- &error,
- &response,
- "oa{sv}",
- session_handle,
- 0);
-
- if (rc < 0) {
- log_error(ei, "Failed to call method: %s", strerror(-rc));
- goto out;
- }
-
- int status;
- rc = sd_bus_message_read(response, "u", &status);
- if (rc < 0) {
- log_error(ei, "Failed to extract status, invalid message format: %s", strerror(-rc));
- goto out;
- }
-
- if (status != 0) {
- log_info(ei, "Unable to get fd from portal");
- ei_disconnect(ei);
- return;
- }
-
- const char *key;
- rc = sd_bus_message_read(response, "a{sv}", 1, &key, "h", &eisfd);
- if (rc < 0) {
- log_error(ei, "Failed to extract fd, invalid message format: %s", strerror(-rc));
- goto out;
- }
-
- if (!streq(key, "fd")) {
- log_error(ei, "Invalid key '%s', expected 'fd'", key);
- goto out;
- }
-
- /* the fd is owned by the message */
- rc = xerrno(dup(eisfd));
- if (rc < 0) {
- log_error(ei, "Failed to dup fd: %s", strerror(-rc));
- goto out;
- } else {
- eisfd = rc;
- int flags = fcntl(eisfd, F_GETFL, 0);
- fcntl(eisfd, F_SETFL, flags | O_NONBLOCK);
- }
-
- log_debug(ei, "Initiating ei context with fd %d from portal", eisfd);
-
- /* We're done with DBus, lets clean up */
- source_remove(portal->bus_source);
- source_unref(portal->bus_source);
- portal->bus = sd_bus_unref(portal->bus);
-
- rc = ei_set_connection(ei, eisfd);
-out:
- if (rc < 0) {
- log_error(ei, "Failed to set the connection: %s", strerror(-rc));
- ei_disconnect(ei);
- }
-}
-
-static int
-portal_response_received(sd_bus_message *m, void *userdata, sd_bus_error *error)
-{
- struct ei_portal *portal = userdata;
- struct ei *ei = ei_portal_parent(portal);
- unsigned response;
-
- assert(m);
- assert(portal);
-
- /* We'll only get this signal once */
- portal->slot = sd_bus_slot_unref(portal->slot);
-
- int rc = sd_bus_message_read(m, "u", &response);
- if (rc < 0) {
- log_error(ei, "Failed to read response from signal: %s", strerror(-rc));
- ei_disconnect(ei);
- return 0;
- }
-
- log_debug(ei, "Portal CreateSession reponse is %u", response);
-
- const char *session_handle = NULL;
- if (response == 0) {
- const char *key;
- rc = sd_bus_message_read(m, "a{sv}", 1, &key, "s", &session_handle);
- if (rc < 0) {
- log_error(ei, "Failed to read session handle from signal: %s", strerror(-rc));
- ei_disconnect(ei);
- return 0;
- }
-
- if (!streq(key, "session_handle")) {
- log_error(ei, "Invalid or unhandled option: %ss", key);
- ei_disconnect(ei);
- return 0;
- }
- }
-
- /* FIXME: we need to subscribe to the sessions Close signal */
-
- if (response != 0) {
- ei_disconnect(ei);
- return 0;
- }
-
- portal_connect(portal, session_handle);
-
- return 0;
-}
-
-static int
-session_closed_received(sd_bus_message *m, void *userdata, sd_bus_error *error)
-{
- struct ei_portal *portal = userdata;
- struct ei *ei = ei_portal_parent(portal);
-
- log_error(ei, "Session closed received");
- return 0;
-}
-
-static void
-dbus_dispatch(struct source *source, void *data)
-{
- struct ei_portal *portal = data;
-
- /* We need to ref the bus here, portal_connect() may remove
- * portal->bus but that needs to stay valid here until the end of
- * the loop.
- */
- _unref_(sd_bus) *bus = sd_bus_ref(portal->bus);
-
- int rc;
- do {
- rc = sd_bus_process(bus, NULL);
- } while (rc > 0);
-
- if (rc != 0) {
- log_error(ei_portal_parent(portal), "dbus processing failed with %s", strerror(-rc));
- }
-}
-
-static int
-portal_init(struct ei *ei, const char *busname)
-{
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- _unref_(sd_bus_message) *response = NULL;
- _unref_(sd_bus) *bus = NULL;
- _unref_(sd_bus_slot) *slot = NULL;
- _unref_(ei_portal) *portal = ei_portal_create(&ei->object);
- const char *path = NULL;
-
- int rc = sd_bus_open_user(&bus);
- if (rc < 0) {
- log_error(ei, "Failed to init dbus: %s", strerror(-rc));
- return -ECONNREFUSED;
- }
-
- _cleanup_free_ char *token = NULL;
- _cleanup_free_ char *handle = xdp_token(bus, &token);
- _cleanup_free_ char *session_token = xdp_token(bus, &session_token);
- _cleanup_free_ char *session_handle = xdp_token(bus, &session_token);
-
- rc = sd_bus_match_signal(bus, &slot,
- busname,
- handle,
- "org.freedesktop.portal.Request",
- "Response",
- portal_response_received,
- portal);
- if (rc < 0) {
- log_error(ei, "Failed to subscribe to signal: %s", strerror(-rc));
- return -ECONNREFUSED;
- }
-
- rc = sd_bus_match_signal(bus, &slot,
- busname,
- session_handle,
- "org.freedesktop.portal.Session",
- "Closed",
- session_closed_received,
- portal);
- if (rc < 0) {
- log_error(ei, "Failed to subscribe to signal: %s", strerror(-rc));
- return -ECONNREFUSED;
- }
-
- rc = sd_bus_call_method(bus,
- busname,
- "/org/freedesktop/portal/desktop",
- "org.freedesktop.portal.EmulatedInput",
- "CreateSession",
- &error,
- &response,
- "a{sv}", 2,
- "handle_token", /* string key */
- "s", token, /* variant string */
- "session_handle_token", /* string key */
- "s", session_token /* variant string */
- );
-
- if (rc < 0) {
- log_error(ei, "Failed to call method: %s", strerror(-rc));
- return -ECONNREFUSED;
- }
-
- rc = sd_bus_message_read(response, "o", &path);
- if (rc < 0) {
- log_error(ei, "Failed to parse response: %s", strerror(-rc));
- return -ECONNREFUSED;
- }
-
- log_debug(ei, "portal Response object is %s", path);
-
- struct source *s = source_new(sd_bus_get_fd(bus), dbus_dispatch, portal);
- source_never_close_fd(s); /* the bus object handles the fd */
- rc = sink_add_source(ei->sink, s);
- if (rc == 0) {
- portal->bus_source = source_ref(s);
- portal->bus = sd_bus_ref(bus);
- portal->slot = sd_bus_slot_ref(slot);
- }
-
- portal->busname = xstrdup(busname);
-
- ei->backend = ei_portal_ref(portal);
- ei->backend_interface = interface;
-
- source_unref(s);
-
- return 0;
-}
-
-_public_ int
-ei_setup_backend_portal(struct ei *ei)
-{
- return portal_init(ei, "org.freedesktop.portal.Desktop");
-}
-
-_public_ int
-ei_setup_backend_portal_busname(struct ei *ei, const char *busname)
-{
- return portal_init(ei, busname);
-}
diff --git a/src/libei-stubs.c b/src/libei-stubs.c
deleted file mode 100644
index 7c934bd..0000000
--- a/src/libei-stubs.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2020 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include "config.h"
-
-#include
-
-#include "libei.h"
-
-#include "util-macros.h"
-
-#if !ENABLE_LIBEI_PORTAL
-_public_ int
-ei_setup_backend_portal(struct ei *ei)
-{
- return -ENOSYS;
-}
-#endif
diff --git a/src/libei.h b/src/libei.h
index a9a978b..5fa45af 100644
--- a/src/libei.h
+++ b/src/libei.h
@@ -581,26 +581,6 @@ ei_setup_backend_socket(struct ei *ei, const char *socketpath);
int
ei_setup_backend_fd(struct ei *ei, int fd);
-/**
- * Connect to the `org.freedesktop.portal.Desktop` portal.
- *
- * @return 0 on success or a negative errno on failure
- */
-int
-ei_setup_backend_portal(struct ei *ei);
-
-/**
- * Connect to an `org.freedesktop.portal.Desktop` implementation on the
- * given busname.
- *
- * Outside of testing environments, there is usually no reason to use
- * this function, use ei_setup_backend_portal() instead.
- *
- * @return 0 on success or a negative errno on failure
- */
-int
-ei_setup_backend_portal_busname(struct ei *ei, const char *busname);
-
/**
* Increase the refcount of this struct by one. Use ei_unref() to decrease
* the refcount.
diff --git a/tools/ei-debug-events.c b/tools/ei-debug-events.c
index 311f16e..69c5d5b 100644
--- a/tools/ei-debug-events.c
+++ b/tools/ei-debug-events.c
@@ -30,8 +30,7 @@
*
* Usually, you'd want to:
* - run the eis-demo-server (or some other EIS implementation)
- * - run the eis-fake-portal (if testing portal clients), otherwise
- * export LIBEI_SOCKET=eis-0, or whatever value was given.
+ * - export LIBEI_SOCKET=eis-0, or whatever value was given
* - run the ei-demo-client
*/
diff --git a/tools/ei-demo-client.c b/tools/ei-demo-client.c
index c02a622..88e4fc8 100644
--- a/tools/ei-demo-client.c
+++ b/tools/ei-demo-client.c
@@ -30,8 +30,7 @@
*
* Usually, you'd want to:
* - run the eis-demo-server (or some other EIS implementation)
- * - run the eis-fake-portal (if testing portal clients), otherwise
- * export LIBEI_SOCKET=eis-0, or whatever value was given.
+ * - export LIBEI_SOCKET=eis-0, or whatever value was given
* - run the ei-demo-client
*/
diff --git a/tools/eis-demo-server.c b/tools/eis-demo-server.c
index cee0e71..2279f65 100644
--- a/tools/eis-demo-server.c
+++ b/tools/eis-demo-server.c
@@ -33,8 +33,7 @@
*
* Usually, you'd want to:
* - run the eis-demo-server (or some other EIS implementation)
- * - run the eis-fake-portal (if testing portal clients), otherwise
- * export LIBEI_SOCKET=eis-0, or whatever value was given.
+ * - export LIBEI_SOCKET=eis-0, or whatever value was given
* - run the libei client
*/
diff --git a/tools/eis-fake-impl-portal.c b/tools/eis-fake-impl-portal.c
deleted file mode 100644
index 9843e13..0000000
--- a/tools/eis-fake-impl-portal.c
+++ /dev/null
@@ -1,377 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2021 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-/* A simple tool that sets up the org.freedesktop.impl.portal.EmulatedInput
- * DBus interface and provides the required functionality.
- *
- * This tool is useful for testing portals (e.g.
- * xdg-desktop-portal) that need to connect to impl.portal. It provides
- * enough data to succeed with the connection.
- *
- * This tool does not run an EIS server, use e.g. the eis-demo-server.
- *
- * Usually, you'd want to:
- * - run the eis-demo-server (or some other EIS implementation)
- * - run the eis-fake-impl-portal
- * - run xdg-desktop-portal
- * - run the libei client relying on the portal
- */
-
-#include "config.h"
-
-#include
-#include
-#include
-#include
-#include
-
-#include "util-io.h"
-#include "util-list.h"
-#include "util-mem.h"
-#include "util-logger.h"
-#include "util-strings.h"
-
-#include "libreis.h"
-
-#include
-
-DEFINE_UNREF_CLEANUP_FUNC(reis);
-
-struct session {
- unsigned int version;
- struct list link;
- struct sd_bus_slot *slot;
- char *handle;
-};
-
-struct portal {
- unsigned int version;
- struct logger *logger;
- char *busname;
-
- struct list sessions;
-} portal;
-
-
-#define call(_call) do { \
- int _rc = _call; \
- if (_rc < 0) { \
- log_error(portal, "Failed with %s %s:%d\n", strerror(-_rc), __func__, __LINE__); \
- return _rc; \
- } } while(0)
-
-static int
-session_close(sd_bus_message *m, void *userdata, sd_bus_error *ret_error)
-{
- sd_bus_reply_method_return(m, "");
- /* Not implemented */
- return 0;
-}
-
-static const sd_bus_vtable session_vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_METHOD("Close", "", "", session_close, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_PROPERTY("version", "u", NULL, offsetof(struct session, version), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_VTABLE_END,
-};
-
-static int
-create_session_object(struct portal *portal,
- sd_bus *bus,
- const char *objectpath)
-{
- struct session *session = calloc(sizeof *session, 1);
-
- session->handle = xstrdup(objectpath);
-
- call(sd_bus_add_object_vtable(bus, &session->slot,
- objectpath,
- "org.freedesktop.impl.portal.Session",
- session_vtable,
- session));
-
- list_append(&portal->sessions, &session->link);
-
- log_debug(portal, "Session created on %s\n", objectpath);
- return 0;
-}
-
-static int
-request_close(sd_bus_message *m, void *userdata, sd_bus_error *ret_error)
-{
- /* We don't live long enough for this to be called */
- return 0;
-}
-
-static const sd_bus_vtable request_vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_METHOD("Close", "", "", request_close, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_VTABLE_END,
-};
-
-static int
-create_request_object(struct portal *portal,
- sd_bus *bus,
- const char *objectpath,
- const char *session_path)
-{
- _unref_(sd_bus_slot) *slot = NULL;
-
- create_session_object(portal, bus, session_path);
-
- call(sd_bus_add_object_vtable(bus, &slot,
- objectpath,
- "org.freedesktop.impl.portal.Request",
- request_vtable,
- NULL));
-
- int response = 0;
- log_debug(portal, "emitting Response %d on %s\n", response, objectpath);
- return sd_bus_emit_signal(bus,
- objectpath,
- "org.freedesktop.impl.portal.Request",
- "Response",
- "ua{sv}",
- response,
- 1,
- "session_handle",/* string key */
- "s", session_path /* variant string */
- );
- /* note: _unref_ removes object immediately */
-}
-
-static int
-portal_create_session(sd_bus_message *m, void *userdata,
- sd_bus_error *ret_error)
-{
- struct portal *portal = userdata;
- static int session_id = 1234;
-
- const char *handle;
- const char *session_handle;
- const char *app_id;
-
- sd_bus_message_read(m, "oosa{sv}",
- &handle,
- &session_handle,
- &app_id, 0);
-
- log_debug(portal, "CreateSession: app-id %s, session %s, handle %s\n", app_id, session_handle, handle);
-
- _cleanup_free_ char *sid = xaprintf("%d", session_id++);
-
- call(sd_bus_reply_method_return(m, "ua{sv}", 0, 1, "session_id", "s", sid));
-
- return create_request_object(portal, sd_bus_message_get_bus(m), handle, session_handle);
-}
-
-static void
-set_prop_cmdline(struct reis *reis)
-{
- _cleanup_free_ char *cmdline = cmdline_as_str();
- reis_set_property_with_permissions(reis, "ei.application.cmdline", cmdline, REIS_PROPERTY_PERM_NONE);
-}
-
-static void
-set_prop_pid(struct reis *reis)
-{
- char pid[64];
-
- xsnprintf(pid, sizeof(pid), "%i", getpid());
- reis_set_property_with_permissions(reis, "ei.application.pid", pid, REIS_PROPERTY_PERM_NONE);
-}
-
-static void
-set_prop_type(struct reis *reis)
-{
- reis_set_property_with_permissions(reis, "ei.connection.type", "portal", REIS_PROPERTY_PERM_NONE);
-}
-
-static int
-portal_connect_to_eis(sd_bus_message *m, void *userdata, sd_bus_error *ret_error)
-{
- struct portal *portal = userdata;
-
- log_debug(portal, "Got a connect request\n");
-
- const char *xdg = getenv("XDG_RUNTIME_DIR");
- if (!xdg)
- return -ENOENT;
-
- const char *session_handle;
- const char *app_id;
- call(sd_bus_message_read(m, "os", &session_handle, &app_id));
-
- log_debug(portal, "Connect request session %s appid %s\n", session_handle, app_id);
-
- struct session *session;
- bool found = false;
- list_for_each_safe(session, &portal->sessions, link) {
- if (streq(session->handle, session_handle)) {
- found = true;
- break;
- }
- }
-
- /* We're aborting here because it's a client bug and this is just a
- * fake portal */
- if (!found) {
- log_error(portal, "Invalid session handle %s\n", session_handle);
- abort();
- }
-
- log_error(portal, "Valid session %s, connecting to EIS\n", session_handle);
-
- _cleanup_free_ char *sockpath = xaprintf("%s/eis-0", xdg);
- int fd = xconnect(sockpath);
- if (fd < 0) {
- log_error(portal, "Failed to connect to EIS (%s)\n", strerror(-fd));
- return sd_bus_reply_method_return(m, "ua{sv}", 1, 0);
- }
-
- _unref_(reis) *reis = reis_new(fd);
- assert(reis);
- set_prop_pid(reis);
- set_prop_cmdline(reis);
- set_prop_type(reis);
-
- log_debug(portal, "passing fd %d\n", fd);
- return sd_bus_reply_method_return(m, "ua{sv}", 0,
- 1, /* array length */
- "fd", "h", fd /* name: "fd", type handle, value fd */);
-}
-
-static const sd_bus_vtable portal_vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_METHOD("CreateSession", "oosa{sv}", "ua{sv}", portal_create_session, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("ConnectToEIS", "osa{sv}", "ua{sv}", portal_connect_to_eis, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_PROPERTY("version", "u", NULL, offsetof(struct portal, version), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_VTABLE_END,
-};
-
-static int
-run(struct portal *portal)
-{
- _unref_(sd_bus) *bus = NULL;
- _unref_(sd_bus_slot) *slot = NULL;
- int rc = sd_bus_open_user(&bus);
- if (rc < 0)
- return rc;
-
- rc = sd_bus_add_object_vtable(bus, &slot,
- "/org/freedesktop/portal/desktop",
- "org.freedesktop.impl.portal.EmulatedInput",
- portal_vtable,
- portal);
- if (rc < 0)
- return rc;
-
- sd_bus_add_object_manager(bus, NULL, "/org/freedesktop/portal/desktop");
-
- log_debug(portal, "Portal object at: /org/freedesktop/ei/EmulatedInput\n");
-
- rc = sd_bus_request_name(bus, portal->busname, 0);
- if (rc < 0)
- return rc;
-
- log_debug(portal, "Portal DBus name: %s\n", portal->busname);
-
- _unref_(sd_event) *event = NULL;
- rc = sd_event_default(&event);
- if (rc < 0)
- return rc;
-
- rc = sd_event_set_watchdog(event, true);
- if (rc < 0)
- return rc;
-
- rc = sd_bus_attach_event(bus, event, 0);
- if (rc < 0)
- return rc;
-
- return sd_event_loop(event);
-}
-
-static void
-usage(FILE *fp, const char *argv0)
-{
- fprintf(fp,
- "Usage: %s [--busname=a.b.c.d]\n"
- "\n"
- "Emulates an XDG Desktop portal for the org.freedesktop.impl.portal.EmulatedInput interface\n"
- "\n"
- "Options:\n"
- " --busname use the given busname instead of the default org.freedesktop.impl.portal.eis.EmulatedInput\n"
- "",
- basename(argv0));
-}
-
-int
-main(int argc, char **argv)
-{
- _cleanup_free_ char *busname = xstrdup("org.freedesktop.impl.portal.eis.EmulatedInput");
-
- while (1) {
- enum opts {
- OPT_BUSNAME,
- };
- static struct option long_opts[] = {
- { "busname", required_argument, 0, OPT_BUSNAME},
- { "help", no_argument, 0, 'h'},
- { .name = NULL },
- };
-
- int optind = 0;
- int c = getopt_long(argc, argv, "h", long_opts, &optind);
- if (c == -1)
- break;
-
- switch(c) {
- case 'h':
- usage(stdout, argv[0]);
- return EXIT_SUCCESS;
- case OPT_BUSNAME:
- free(busname);
- busname = xstrdup(optarg);
- break;
- default:
- usage(stderr, argv[0]);
- return EXIT_FAILURE;
- }
- }
-
- list_init(&portal.sessions);
- portal.version = 1;
- portal.busname = steal(&busname);
- portal.logger = logger_new("impl.portal", NULL);
- logger_set_priority(portal.logger, LOGGER_DEBUG);
-
- int rc = run(&portal);
- if (rc < 0)
- fprintf(stderr, "Failed to start fake portal: %s\n", strerror(-rc));
-
- logger_unref(portal.logger);
- free(portal.busname);
- return rc == 0;
-}
diff --git a/tools/eis-fake-portal.c b/tools/eis-fake-portal.c
deleted file mode 100644
index abfdf75..0000000
--- a/tools/eis-fake-portal.c
+++ /dev/null
@@ -1,417 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2020 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-/* A simple tool that sets up the org.freedesktop.portal.EmulatedInput DBus
- * interface and provides the required functionality.
- *
- * This tool is useful for testing the libei portal backend, it provides just
- * enough data to have that backend succeed with the connection.
- *
- * This tool does not run an EIS server, use e.g. the eis-demo-server.
- *
- * Usually, you'd want to:
- * - run the eis-demo-server (or some other EIS implementation)
- * - run the eis-fake-portal
- * - run the libei client relying on the portal
- */
-
-#include "config.h"
-
-#include
-#include
-#include
-#include
-#include
-
-#include "util-io.h"
-#include "util-list.h"
-#include "util-mem.h"
-#include "util-logger.h"
-#include "util-strings.h"
-
-#include "libreis.h"
-
-#include
-
-DEFINE_UNREF_CLEANUP_FUNC(reis);
-
-struct session {
- struct list link;
- struct sd_bus_slot *slot;
- char *handle;
-};
-
-struct portal {
- struct logger *logger;
- char *busname;
-
- struct list sessions;
-} portal;
-
-
-#define call(_call) do { \
- int _rc = _call; \
- if (_rc < 0) { \
- log_error(portal, "Failed with %s %s:%d\n", strerror(-_rc), __func__, __LINE__); \
- return _rc; \
- } } while(0)
-
-static int
-session_close(sd_bus_message *m, void *userdata, sd_bus_error *ret_error)
-{
- /* Not implemented */
- return 0;
-}
-
-static const sd_bus_vtable session_vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_METHOD("Close", "", "", session_close, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_SIGNAL("Closed", "ua{sv}", 0),
- SD_BUS_VTABLE_END,
-};
-
-static int
-create_session_object(struct portal *portal,
- sd_bus *bus,
- const char *objectpath)
-{
- struct session *session = calloc(sizeof *session, 1);
-
- session->handle = xstrdup(objectpath);
-
- call(sd_bus_add_object_vtable(bus, &session->slot,
- objectpath,
- "org.freedesktop.portal.Session",
- session_vtable,
- NULL));
-
- list_append(&portal->sessions, &session->link);
-
- log_debug(portal, "Session created on %s\n", objectpath);
- return 0;
-}
-
-static int
-request_close(sd_bus_message *m, void *userdata, sd_bus_error *ret_error)
-{
- /* We don't live long enough for this to be called */
- return 0;
-}
-
-static const sd_bus_vtable request_vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_METHOD("Close", "", "", request_close, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_SIGNAL("Response", "ua{sv}", 0),
- SD_BUS_VTABLE_END,
-};
-
-static int
-create_request_object(struct portal *portal,
- sd_bus *bus,
- const char *objectpath,
- const char *session_path)
-{
- _unref_(sd_bus_slot) *slot = NULL;
-
- create_session_object(portal, bus, session_path);
-
- call(sd_bus_add_object_vtable(bus, &slot,
- objectpath,
- "org.freedesktop.portal.Request",
- request_vtable,
- NULL));
-
- int response = 0;
- log_debug(portal, "emitting Response %d on %s\n", response, objectpath);
- return sd_bus_emit_signal(bus,
- objectpath,
- "org.freedesktop.portal.Request",
- "Response",
- "ua{sv}",
- response,
- 1,
- "session_handle",/* string key */
- "s", session_path /* variant string */
- );
- /* note: _unref_ removes object immediately */
-}
-
-static char *
-sender_token(const char *input)
-{
- if (!input)
- return NULL;
-
- char *token = strstrip(input, ":");
- for (size_t idx = 0; token[idx]; idx++) {
- if (token[idx] == '.')
- token[idx] = '_';
- }
-
- return token;
-}
-
-static int
-portal_create_session(sd_bus_message *m, void *userdata,
- sd_bus_error *ret_error)
-{
- struct portal *portal = userdata;
-
- call(sd_bus_message_enter_container(m, 'a', "{sv}"));
-
- const char *session_token = NULL;
- const char *handle_token = NULL;
-
- const char *key, *val;
- call(sd_bus_message_read(m, "{sv}", &key, "s", &val));
- if (streq(key, "handle_token"))
- handle_token = val;
- else if (streq(key, "session_handle_token"))
- session_token = val;
- else
- return -EINVAL;
-
- call(sd_bus_message_read(m, "{sv}", &key, "s", &val));
- if (streq(key, "handle_token"))
- handle_token = val;
- else if (streq(key, "session_handle_token"))
- session_token = val;
- else
- return -EINVAL;
-
- assert(handle_token);
- assert(session_token);
-
- call(sd_bus_message_exit_container(m));
-
- _cleanup_free_ char *sender = sender_token(sd_bus_message_get_sender(m));
- if (!sender)
- return -ENOMEM;
-
- /* Send back the object path of the object we're about to create. We
- * then create the object, so if that fails we have a problem but
- * meh, this is for testing only .*/
- _cleanup_free_ char *objpath = xaprintf("%s/request/%s/%s",
- "/org/freedesktop/portal/desktop",
- sender,
- handle_token);
- call(sd_bus_reply_method_return(m, "o", objpath));
-
- _cleanup_free_ char *session_path = xaprintf("%s/session/%s/%s",
- "/org/freedesktop/portal/desktop",
- sender,
- session_token);
-
- /* now create the object */
- return create_request_object(portal, sd_bus_message_get_bus(m), objpath, session_path);
-}
-
-static void
-set_prop_cmdline(struct reis *reis)
-{
- _cleanup_free_ char *cmdline = cmdline_as_str();
- reis_set_property_with_permissions(reis, "ei.application.cmdline", cmdline, REIS_PROPERTY_PERM_NONE);
-}
-
-static void
-set_prop_pid(struct reis *reis)
-{
- char pid[64];
-
- xsnprintf(pid, sizeof(pid), "%i", getpid());
- reis_set_property_with_permissions(reis, "ei.application.pid", pid, REIS_PROPERTY_PERM_NONE);
-}
-
-static void
-set_prop_type(struct reis *reis)
-{
- reis_set_property_with_permissions(reis, "ei.connection.type", "portal", REIS_PROPERTY_PERM_NONE);
-}
-
-static int
-portal_connect_to_eis(sd_bus_message *m, void *userdata, sd_bus_error *ret_error)
-{
- struct portal *portal = userdata;
-
- const char *xdg = getenv("XDG_RUNTIME_DIR");
- if (!xdg)
- return -ENOENT;
-
- const char *session_handle;
-
- call(sd_bus_message_read(m, "oa{sv}", &session_handle, 0));
-
- struct session *session;
- bool found = false;
- list_for_each_safe(session, &portal->sessions, link) {
- if (streq(session->handle, session_handle)) {
- found = true;
- break;
- }
- }
-
- /* We're aborting here because it's a client bug and this is just a
- * fake portal */
- if (!found) {
- log_error(portal, "Invalid session handle %s\n", session_handle);
- return sd_bus_reply_method_return(m, "ua{sv}", 1, 0);
- }
-
- log_info(portal, "Valid session %s, connecting to EIS\n", session_handle);
-
- _cleanup_free_ char *sockpath = xstrdup(getenv("LIBEI_SOCKET"));
- if (!sockpath)
- sockpath = xaprintf("%s/eis-0", xdg);
-
- int handle = xconnect(sockpath);
- if (handle < 0) {
- log_error(portal, "Failed to connect to EIS (%s)\n", strerror(-handle));
- return sd_bus_reply_method_return(m, "ua{sv}", 1, 0);
- }
-
- _unref_(reis) *reis = reis_new(handle);
- assert(reis);
- set_prop_pid(reis);
- set_prop_cmdline(reis);
- set_prop_type(reis);
-
- log_debug(portal, "passing Handle %d\n", handle);
- return sd_bus_reply_method_return(m, "ua{sv}", 0,
- 1, /* array size */
- "fd", "h", handle);
-}
-
-static const sd_bus_vtable portal_vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_METHOD("CreateSession", "a{sv}", "o", portal_create_session, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("ConnectToEIS", "oa{sv}", "ua{sv}", portal_connect_to_eis, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_VTABLE_END,
-};
-
-static int
-run(struct portal *portal)
-{
- _unref_(sd_bus) *bus = NULL;
- _unref_(sd_bus_slot) *slot = NULL;
- int rc = sd_bus_open_user(&bus);
- if (rc < 0)
- return rc;
-
- rc = sd_bus_add_object_vtable(bus, &slot,
- "/org/freedesktop/portal/desktop",
- "org.freedesktop.portal.EmulatedInput",
- portal_vtable,
- portal);
- if (rc < 0)
- return rc;
-
- log_debug(portal, "Portal object at: /org/freedesktop/portal/desktop\n");
-
- rc = sd_bus_request_name(bus, portal->busname, 0);
- if (rc < 0)
- return rc;
-
- log_debug(portal, "Portal DBus name: %s\n", portal->busname);
-
- _unref_(sd_event) *event = NULL;
- rc = sd_event_default(&event);
- if (rc < 0)
- return rc;
-
- rc = sd_event_set_watchdog(event, true);
- if (rc < 0)
- return rc;
-
- rc = sd_bus_attach_event(bus, event, 0);
- if (rc < 0)
- return rc;
-
- return sd_event_loop(event);
-}
-
-static void
-usage(FILE *fp, const char *argv0)
-{
- fprintf(fp,
- "Usage: %s [--busname=a.b.c.d]\n"
- "\n"
- "Emulates an XDG Desktop portal for the org.freedesktop.portal.EmulatedInput interface\n"
- "\n"
- "Options:\n"
- " --busname use the given busname instead of the default org.freedesktop.portal.Desktop\n"
- "\n"
- "This portal connects directly to the EIS instance at $LIBEI_SOCKET or, if unset, at \n"
- "$XDG_RUNTIME_DIR/eis-0. It does **not** use the org.freedesktop.impl.portal.EmulatedInput\n"
- "interface.\n"
- "",
- basename(argv0));
-}
-
-int
-main(int argc, char **argv)
-{
- _cleanup_free_ char *busname = xstrdup("org.freedesktop.portal.Desktop");
-
- while (1) {
- enum opts {
- OPT_BUSNAME,
- };
- static struct option long_opts[] = {
- { "busname", required_argument, 0, OPT_BUSNAME},
- { "help", no_argument, 0, 'h'},
- { .name = NULL },
- };
-
- int optind = 0;
- int c = getopt_long(argc, argv, "h", long_opts, &optind);
- if (c == -1)
- break;
-
- switch(c) {
- case 'h':
- usage(stdout, argv[0]);
- return EXIT_SUCCESS;
- case OPT_BUSNAME:
- free(busname);
- busname = xstrdup(optarg);
- break;
- default:
- usage(stderr, argv[0]);
- return EXIT_FAILURE;
- }
- }
-
- list_init(&portal.sessions);
- portal.busname = steal(&busname);
- portal.logger = logger_new("portal", NULL);
- logger_set_priority(portal.logger, LOGGER_DEBUG);
-
- int rc = run(&portal);
- if (rc < 0)
- fprintf(stderr, "Failed to start fake portal: %s\n", strerror(-rc));
-
- logger_unref(portal.logger);
- free(portal.busname);
- return rc == 0;
-}