aboutsummaryrefslogtreecommitdiff
path: root/backend/rdp
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2020-01-10 11:33:21 -0500
committerSimon Ser <contact@emersion.fr>2020-01-10 19:38:39 +0100
commitebdbe177d62d3c8bab04f77b86326804ff185bef (patch)
tree6979b1fa35d43fa20a85c268854b3ac5f22ce221 /backend/rdp
parent802ef9da8a1c3fa940d76c60f5bf635afa0b16fb (diff)
Drop RDP backend
Users interested in remote access to wlroots compositors should use wayvnc: https://github.com/any1/wayvnc
Diffstat (limited to 'backend/rdp')
-rw-r--r--backend/rdp/backend.c133
-rw-r--r--backend/rdp/keyboard.c219
-rw-r--r--backend/rdp/listener.c61
-rw-r--r--backend/rdp/meson.build36
-rw-r--r--backend/rdp/output.c331
-rw-r--r--backend/rdp/peer.c360
-rw-r--r--backend/rdp/pointer.c40
7 files changed, 0 insertions, 1180 deletions
diff --git a/backend/rdp/backend.c b/backend/rdp/backend.c
deleted file mode 100644
index c0b63921..00000000
--- a/backend/rdp/backend.c
+++ /dev/null
@@ -1,133 +0,0 @@
-#define _POSIX_C_SOURCE 200809L
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <wlr/render/egl.h>
-#include <wlr/render/gles2.h>
-#include <wlr/util/log.h>
-#include "backend/rdp.h"
-#include "util/signal.h"
-
-struct wlr_rdp_backend *rdp_backend_from_backend(
- struct wlr_backend *wlr_backend) {
- assert(wlr_backend_is_rdp(wlr_backend));
- return (struct wlr_rdp_backend *)wlr_backend;
-}
-
-static bool backend_start(struct wlr_backend *wlr_backend) {
- struct wlr_rdp_backend *backend =
- rdp_backend_from_backend(wlr_backend);
- assert(backend->listener == NULL);
- wlr_log(WLR_INFO, "Starting RDP backend");
- if (!rdp_configure_listener(backend)) {
- return false;
- }
- return true;
-}
-
-void wlr_rdp_backend_set_address(struct wlr_backend *wlr_backend,
- const char *address) {
- struct wlr_rdp_backend *backend =
- rdp_backend_from_backend(wlr_backend);
- assert(backend->listener == NULL);
- backend->address = strdup(address);
-}
-
-void wlr_rdp_backend_set_port(struct wlr_backend *wlr_backend, int port) {
- struct wlr_rdp_backend *backend =
- rdp_backend_from_backend(wlr_backend);
- assert(backend->listener == NULL);
- backend->port = port;
-}
-
-static void backend_destroy(struct wlr_backend *wlr_backend) {
- struct wlr_rdp_backend *backend =
- rdp_backend_from_backend(wlr_backend);
- if (!wlr_backend) {
- return;
- }
-
- wl_list_remove(&backend->display_destroy.link);
-
- struct wlr_rdp_peer_context *client;
- wl_list_for_each(client, &backend->clients, link) {
- freerdp_peer_context_free(client->peer);
- freerdp_peer_free(client->peer);
- }
-
- wlr_signal_emit_safe(&wlr_backend->events.destroy, backend);
-
- wlr_renderer_destroy(backend->renderer);
- wlr_egl_finish(&backend->egl);
- free(backend->address);
- free(backend);
-}
-
-static struct wlr_renderer *backend_get_renderer(
- struct wlr_backend *wlr_backend) {
- struct wlr_rdp_backend *backend =
- rdp_backend_from_backend(wlr_backend);
- return backend->renderer;
-}
-
-static const struct wlr_backend_impl backend_impl = {
- .start = backend_start,
- .destroy = backend_destroy,
- .get_renderer = backend_get_renderer,
-};
-
-static void handle_display_destroy(struct wl_listener *listener, void *data) {
- struct wlr_rdp_backend *backend =
- wl_container_of(listener, backend, display_destroy);
- backend_destroy(&backend->backend);
-}
-
-struct wlr_backend *wlr_rdp_backend_create(struct wl_display *display,
- wlr_renderer_create_func_t create_renderer_func,
- const char *tls_cert_path, const char *tls_key_path) {
- wlr_log(WLR_INFO, "Creating RDP backend");
-
- struct wlr_rdp_backend *backend =
- calloc(1, sizeof(struct wlr_rdp_backend));
- if (!backend) {
- wlr_log(WLR_ERROR, "Failed to allocate wlr_rdp_backend");
- return NULL;
- }
- wlr_backend_init(&backend->backend, &backend_impl);
- backend->display = display;
- backend->tls_cert_path = tls_cert_path;
- backend->tls_key_path = tls_key_path;
- backend->address = strdup("127.0.0.1");
- backend->port = 3389;
- wl_list_init(&backend->clients);
-
- static const EGLint config_attribs[] = {
- EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
- EGL_ALPHA_SIZE, 0,
- EGL_BLUE_SIZE, 1,
- EGL_GREEN_SIZE, 1,
- EGL_RED_SIZE, 1,
- EGL_NONE,
- };
-
- if (!create_renderer_func) {
- create_renderer_func = wlr_renderer_autocreate;
- }
-
- backend->renderer = create_renderer_func(&backend->egl,
- EGL_PLATFORM_SURFACELESS_MESA, NULL, (EGLint*)config_attribs, 0);
- if (!backend->renderer) {
- wlr_log(WLR_ERROR, "Failed to create renderer");
- free(backend);
- return NULL;
- }
-
- backend->display_destroy.notify = handle_display_destroy;
- wl_display_add_destroy_listener(display, &backend->display_destroy);
-
- return &backend->backend;
-}
-
-bool wlr_backend_is_rdp(struct wlr_backend *backend) {
- return backend->impl == &backend_impl;
-}
diff --git a/backend/rdp/keyboard.c b/backend/rdp/keyboard.c
deleted file mode 100644
index 78dd8b08..00000000
--- a/backend/rdp/keyboard.c
+++ /dev/null
@@ -1,219 +0,0 @@
-#include <stdlib.h>
-#include <wayland-server-core.h>
-#include <wlr/types/wlr_input_device.h>
-#include <wlr/types/wlr_keyboard.h>
-#include <wlr/interfaces/wlr_keyboard.h>
-#include <wlr/interfaces/wlr_input_device.h>
-#include <wlr/util/log.h>
-#include <xkbcommon/xkbcommon.h>
-#include "backend/rdp.h"
-#include "util/signal.h"
-
-struct rdp_to_xkb_keyboard_layout {
- UINT32 rdp_layout_code;
- const char *xkb_layout;
- const char *xkb_variant;
-};
-
-/* table reversed from
- https://github.com/awakecoding/FreeRDP/blob/master/libfreerdp/locale/xkb_layout_ids.c#L811 */
-static struct rdp_to_xkb_keyboard_layout rdp_keyboards[] = {
- {KBD_ARABIC_101, "ara", 0},
- {KBD_BULGARIAN, 0, 0},
- {KBD_CHINESE_TRADITIONAL_US, 0, 0},
- {KBD_CZECH, "cz", 0},
- {KBD_CZECH_PROGRAMMERS, "cz", "bksl"},
- {KBD_CZECH_QWERTY, "cz", "qwerty"},
- {KBD_DANISH, "dk", 0},
- {KBD_GERMAN, "de", 0},
- {KBD_GERMAN_NEO, "de", "neo"},
- {KBD_GERMAN_IBM, "de", "qwerty"},
- {KBD_GREEK, "gr", 0},
- {KBD_GREEK_220, "gr", "simple"},
- {KBD_GREEK_319, "gr", "extended"},
- {KBD_GREEK_POLYTONIC, "gr", "polytonic"},
- {KBD_US, "us", 0},
- {KBD_US_ENGLISH_TABLE_FOR_IBM_ARABIC_238_L, "ara", "buckwalter"},
- {KBD_SPANISH, "es", 0},
- {KBD_SPANISH_VARIATION, "es", "nodeadkeys"},
- {KBD_FINNISH, "fi", 0},
- {KBD_FRENCH, "fr", 0},
- {KBD_HEBREW, "il", 0},
- {KBD_HUNGARIAN, "hu", 0},
- {KBD_HUNGARIAN_101_KEY, "hu", "standard"},
- {KBD_ICELANDIC, "is", 0},
- {KBD_ITALIAN, "it", 0},
- {KBD_ITALIAN_142, "it", "nodeadkeys"},
- {KBD_JAPANESE, "jp", 0},
- {KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002, "jp", "kana"},
- {KBD_KOREAN, "kr", 0},
- {KBD_KOREAN_INPUT_SYSTEM_IME_2000, "kr", "kr104"},
- {KBD_DUTCH, "nl", 0},
- {KBD_NORWEGIAN, "no", 0},
- {KBD_POLISH_PROGRAMMERS, "pl", 0},
- {KBD_POLISH_214, "pl", "qwertz"},
- {KBD_ROMANIAN, "ro", 0},
- {KBD_RUSSIAN, "ru", 0},
- {KBD_RUSSIAN_TYPEWRITER, "ru", "typewriter"},
- {KBD_CROATIAN, "hr", 0},
- {KBD_SLOVAK, "sk", 0},
- {KBD_SLOVAK_QWERTY, "sk", "qwerty"},
- {KBD_ALBANIAN, 0, 0},
- {KBD_SWEDISH, "se", 0},
- {KBD_THAI_KEDMANEE, "th", 0},
- {KBD_THAI_KEDMANEE_NON_SHIFTLOCK, "th", "tis"},
- {KBD_TURKISH_Q, "tr", 0},
- {KBD_TURKISH_F, "tr", "f"},
- {KBD_URDU, "in", "urd-phonetic3"},
- {KBD_UKRAINIAN, "ua", 0},
- {KBD_BELARUSIAN, "by", 0},
- {KBD_SLOVENIAN, "si", 0},
- {KBD_ESTONIAN, "ee", 0},
- {KBD_LATVIAN, "lv", 0},
- {KBD_LITHUANIAN_IBM, "lt", "ibm"},
- {KBD_FARSI, "af", 0},
- {KBD_VIETNAMESE, "vn", 0},
- {KBD_ARMENIAN_EASTERN, "am", 0},
- {KBD_AZERI_LATIN, 0, 0},
- {KBD_FYRO_MACEDONIAN, "mk", 0},
- {KBD_GEORGIAN, "ge", 0},
- {KBD_FAEROESE, 0, 0},
- {KBD_DEVANAGARI_INSCRIPT, 0, 0},
- {KBD_MALTESE_47_KEY, 0, 0},
- {KBD_NORWEGIAN_WITH_SAMI, "no", "smi"},
- {KBD_KAZAKH, "kz", 0},
- {KBD_KYRGYZ_CYRILLIC, "kg", "phonetic"},
- {KBD_TATAR, "ru", "tt"},
- {KBD_BENGALI, "bd", 0},
- {KBD_BENGALI_INSCRIPT, "bd", "probhat"},
- {KBD_PUNJABI, 0, 0},
- {KBD_GUJARATI, "in", "guj"},
- {KBD_TAMIL, "in", "tam"},
- {KBD_TELUGU, "in", "tel"},
- {KBD_KANNADA, "in", "kan"},
- {KBD_MALAYALAM, "in", "mal"},
- {KBD_HINDI_TRADITIONAL, "in", 0},
- {KBD_MARATHI, 0, 0},
- {KBD_MONGOLIAN_CYRILLIC, "mn", 0},
- {KBD_UNITED_KINGDOM_EXTENDED, "gb", "intl"},
- {KBD_SYRIAC, "syc", 0},
- {KBD_SYRIAC_PHONETIC, "syc", "syc_phonetic"},
- {KBD_NEPALI, "np", 0},
- {KBD_PASHTO, "af", "ps"},
- {KBD_DIVEHI_PHONETIC, 0, 0},
- {KBD_LUXEMBOURGISH, 0, 0},
- {KBD_MAORI, "mao", 0},
- {KBD_CHINESE_SIMPLIFIED_US, 0, 0},
- {KBD_SWISS_GERMAN, "ch", "de_nodeadkeys"},
- {KBD_UNITED_KINGDOM, "gb", 0},
- {KBD_LATIN_AMERICAN, "latam", 0},
- {KBD_BELGIAN_FRENCH, "be", 0},
- {KBD_BELGIAN_PERIOD, "be", "oss_sundeadkeys"},
- {KBD_PORTUGUESE, "pt", 0},
- {KBD_SERBIAN_LATIN, "rs", 0},
- {KBD_AZERI_CYRILLIC, "az", "cyrillic"},
- {KBD_SWEDISH_WITH_SAMI, "se", "smi"},
- {KBD_UZBEK_CYRILLIC, "af", "uz"},
- {KBD_INUKTITUT_LATIN, "ca", "ike"},
- {KBD_CANADIAN_FRENCH_LEGACY, "ca", "fr-legacy"},
- {KBD_SERBIAN_CYRILLIC, "rs", 0},
- {KBD_CANADIAN_FRENCH, "ca", "fr-legacy"},
- {KBD_SWISS_FRENCH, "ch", "fr"},
- {KBD_BOSNIAN, "ba", 0},
- {KBD_IRISH, 0, 0},
- {KBD_BOSNIAN_CYRILLIC, "ba", "us"},
- {KBD_UNITED_STATES_DVORAK, "us", "dvorak"},
- {KBD_PORTUGUESE_BRAZILIAN_ABNT2, "br", "nativo"},
- {KBD_CANADIAN_MULTILINGUAL_STANDARD, "ca", "multix"},
- {KBD_GAELIC, "ie", "CloGaelach"},
-
- {0x00000000, 0, 0},
-};
-
-/* taken from 2.2.7.1.6 Input Capability Set (TS_INPUT_CAPABILITYSET) */
-static char *rdp_keyboard_types[] = {
- "", /* 0: unused */
- "", /* 1: IBM PC/XT or compatible (83-key) keyboard */
- "", /* 2: Olivetti "ICO" (102-key) keyboard */
- "", /* 3: IBM PC/AT (84-key) or similar keyboard */
- "pc102",/* 4: IBM enhanced (101- or 102-key) keyboard */
- "", /* 5: Nokia 1050 and similar keyboards */
- "", /* 6: Nokia 9140 and similar keyboards */
- "" /* 7: Japanese keyboard */
-};
-
-static void keyboard_destroy(struct wlr_input_device *wlr_device) {
- struct wlr_rdp_keyboard *keyboard =
- (struct wlr_rdp_keyboard *)wlr_device->keyboard;
- xkb_keymap_unref(keyboard->keymap);
- free(keyboard);
-}
-
-static struct wlr_input_device_impl input_device_impl = {
- .destroy = keyboard_destroy,
-};
-
-struct wlr_rdp_input_device *wlr_rdp_keyboard_create(
- struct wlr_rdp_backend *backend, rdpSettings *settings) {
- struct wlr_rdp_input_device *device =
- calloc(1, sizeof(struct wlr_rdp_input_device));
- if (!device) {
- wlr_log(WLR_ERROR, "Failed to allcoate RDP input device");
- return NULL;
- }
-
- int vendor = 0;
- int product = 0;
- const char *name = "rdp";
- struct wlr_input_device *wlr_device = &device->wlr_input_device;
- wlr_input_device_init(wlr_device, WLR_INPUT_DEVICE_KEYBOARD,
- &input_device_impl, name, vendor, product);
-
- struct wlr_rdp_keyboard *keyboard =
- calloc(1, sizeof(struct wlr_rdp_keyboard));
- if (!keyboard) {
- wlr_log(WLR_ERROR, "Failed to allocate RDP pointer device");
- goto error;
- }
- wlr_device->keyboard = (struct wlr_keyboard *)keyboard;
- wlr_keyboard_init(wlr_device->keyboard, NULL);
-
- wlr_log(WLR_DEBUG, "RDP keyboard layout: 0x%x type: 0x%x subtype: 0x%x "
- "function_keys 0x%x", settings->KeyboardLayout,
- settings->KeyboardType, settings->KeyboardSubType,
- settings->KeyboardFunctionKey);
-
- // We need to set up an XKB context and jump through some hoops to convert
- // RDP input events into scancodes
- struct xkb_rule_names xkb_rule_names = { 0 };
- if (settings->KeyboardType <= 7) {
- xkb_rule_names.model = rdp_keyboard_types[settings->KeyboardType];
- }
- for (int i = 0; rdp_keyboards[i].rdp_layout_code; ++i) {
- if (rdp_keyboards[i].rdp_layout_code == settings->KeyboardLayout) {
- xkb_rule_names.layout = rdp_keyboards[i].xkb_layout;
- xkb_rule_names.variant = rdp_keyboards[i].xkb_variant;
- wlr_log(WLR_DEBUG, "Mapped RDP keyboard to xkb layout %s variant "
- "%s", xkb_rule_names.layout, xkb_rule_names.variant);
- break;
- }
- }
- if (xkb_rule_names.layout) {
- struct xkb_context *xkb_context = xkb_context_new(0);
- if (!xkb_context) {
- wlr_log(WLR_DEBUG, "Failed to allocate xkb context");
- goto error;
- }
- keyboard->keymap =
- xkb_keymap_new_from_names(xkb_context, &xkb_rule_names, 0);
- xkb_context_unref(xkb_context);
- }
-
- wlr_keyboard_set_keymap(wlr_device->keyboard, keyboard->keymap);
-
- wlr_signal_emit_safe(&backend->backend.events.new_input, wlr_device);
- return device;
-error:
- wlr_input_device_destroy(wlr_device);
- return NULL;
-}
diff --git a/backend/rdp/listener.c b/backend/rdp/listener.c
deleted file mode 100644
index cfbdc537..00000000
--- a/backend/rdp/listener.c
+++ /dev/null
@@ -1,61 +0,0 @@
-#include <stdlib.h>
-#include <wlr/util/log.h>
-#include "backend/rdp.h"
-
-static int rdp_incoming_peer(
- freerdp_listener *listener, freerdp_peer *client) {
- struct wlr_rdp_backend *backend =
- (struct wlr_rdp_backend *)listener->param4;
- if (rdp_peer_init(client, backend) < 0) {
- wlr_log(WLR_ERROR, "Error initializing incoming peer");
- return false;
- }
- return true;
-}
-
-static int rdp_listener_activity(int fd, uint32_t mask, void *data) {
- freerdp_listener *listener = data;
- if (!(mask & WL_EVENT_READABLE)) {
- return 0;
- }
- if (!listener->CheckFileDescriptor(listener)) {
- wlr_log(WLR_ERROR, "Failed to check FreeRDP file descriptor");
- return -1;
- }
- return 0;
-}
-
-bool rdp_configure_listener(struct wlr_rdp_backend *backend) {
- backend->listener = freerdp_listener_new();
- if (!backend->listener) {
- wlr_log(WLR_ERROR, "Failed to allocate FreeRDP listener");
- return false;
- }
- backend->listener->PeerAccepted = rdp_incoming_peer;
- backend->listener->param4 = backend;
- if (!backend->listener->Open(backend->listener,
- backend->address, backend->port)) {
- wlr_log(WLR_ERROR, "Failed to bind to RDP socket");
- return false;
- }
- int rcount = 0;
- void *rfds[MAX_FREERDP_FDS];
- if (!backend->listener->GetFileDescriptor(
- backend->listener, rfds, &rcount)) {
- wlr_log(WLR_ERROR, "Failed to get FreeRDP file descriptors");
- return false;
- }
- struct wl_event_loop *event_loop =
- wl_display_get_event_loop(backend->display);
- int i;
- for (i = 0; i < rcount; ++i) {
- int fd = (int)(long)(rfds[i]);
- backend->listener_events[i] = wl_event_loop_add_fd(
- event_loop, fd, WL_EVENT_READABLE, rdp_listener_activity,
- backend->listener);
- }
- for (; i < MAX_FREERDP_FDS; ++i) {
- backend->listener_events[i] = NULL;
- }
- return true;
-}
diff --git a/backend/rdp/meson.build b/backend/rdp/meson.build
deleted file mode 100644
index 40259c65..00000000
--- a/backend/rdp/meson.build
+++ /dev/null
@@ -1,36 +0,0 @@
-rdp_libs = []
-rdp_required = [
- 'freerdp2',
- 'winpr2',
-]
-
-msg = []
-if get_option('freerdp').enabled()
- msg += 'Install "@0@" or pass "-Dfreerdp=disabled".'
-endif
-if not get_option('freerdp').disabled()
- msg += 'Required for RDP backend support.'
-endif
-
-foreach lib : rdp_required
- dep = dependency(lib,
- required: get_option('freerdp'),
- not_found_message: '\n'.join(msg).format(lib),
- )
- if not dep.found()
- subdir_done()
- endif
-
- rdp_libs += dep
-endforeach
-
-wlr_files += files(
- 'backend.c',
- 'keyboard.c',
- 'listener.c',
- 'output.c',
- 'peer.c',
- 'pointer.c',
-)
-wlr_deps += rdp_libs
-conf_data.set10('WLR_HAS_RDP_BACKEND', true)
diff --git a/backend/rdp/output.c b/backend/rdp/output.c
deleted file mode 100644
index 3043d2c8..00000000
--- a/backend/rdp/output.c
+++ /dev/null
@@ -1,331 +0,0 @@
-#include <assert.h>
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <stdlib.h>
-#include <wayland-server-core.h>
-#include <wlr/types/wlr_output.h>
-#include <wlr/interfaces/wlr_output.h>
-#include <wlr/util/log.h>
-#include <wlr/render/wlr_renderer.h>
-#include "backend/rdp.h"
-#include "util/signal.h"
-
-static struct wlr_rdp_output *rdp_output_from_output(
- struct wlr_output *wlr_output) {
- assert(wlr_output_is_rdp(wlr_output));
- return (struct wlr_rdp_output *)wlr_output;
-}
-
-static EGLSurface egl_create_surface(struct wlr_egl *egl, unsigned int width,
- unsigned int height) {
- EGLint attribs[] = {
- EGL_WIDTH, width,
- EGL_HEIGHT, height,
- EGL_NONE,
- };
- EGLSurface surf = eglCreatePbufferSurface(egl->display, egl->config, attribs);
- if (surf == EGL_NO_SURFACE) {
- wlr_log(WLR_ERROR, "Failed to create EGL surface");
- return EGL_NO_SURFACE;
- }
- return surf;
-}
-
-static bool output_set_custom_mode(struct wlr_output *wlr_output, int32_t width,
- int32_t height, int32_t refresh) {
- struct wlr_rdp_output *output =
- rdp_output_from_output(wlr_output);
- struct wlr_rdp_backend *backend = output->backend;
-
- if (refresh <= 0) {
- refresh = 60 * 1000; // 60 Hz
- }
-
- wlr_egl_destroy_surface(&backend->egl, output->egl_surface);
-
- output->egl_surface = egl_create_surface(&backend->egl, width, height);
- if (output->egl_surface == EGL_NO_SURFACE) {
- wlr_log(WLR_ERROR, "Failed to recreate EGL surface");
- wlr_output_destroy(wlr_output);
- return false;
- }
-
- output->frame_delay = 1000000 / refresh;
-
- if (output->shadow_surface) {
- pixman_image_unref(output->shadow_surface);
- }
- output->shadow_surface = pixman_image_create_bits(PIXMAN_x8r8g8b8,
- width, height, NULL, width * 4);
-
- wlr_output_update_custom_mode(&output->wlr_output, width, height, refresh);
- return true;
-}
-
-static bool output_attach_render(struct wlr_output *wlr_output,
- int *buffer_age) {
- struct wlr_rdp_output *output =
- rdp_output_from_output(wlr_output);
- return wlr_egl_make_current(&output->backend->egl, output->egl_surface,
- buffer_age);
-}
-
-static bool rfx_swap_buffers(
- struct wlr_rdp_output *output, pixman_region32_t *damage) {
- if (!pixman_region32_not_empty(damage)) {
- return true;
- }
- struct wlr_rdp_peer_context *context = output->context;
- freerdp_peer *peer = context->peer;
- rdpUpdate *update = peer->update;
-
- Stream_Clear(context->encode_stream);
- Stream_SetPosition(context->encode_stream, 0);
- int width = damage->extents.x2 - damage->extents.x1;
- int height = damage->extents.y2 - damage->extents.y1;
-
- SURFACE_BITS_COMMAND cmd;
- cmd.skipCompression = TRUE;
- cmd.destLeft = damage->extents.x1;
- cmd.destTop = damage->extents.y1;
- cmd.destRight = damage->extents.x2;
- cmd.destBottom = damage->extents.y2;
- cmd.bmp.bpp = pixman_image_get_depth(output->shadow_surface);
- cmd.bmp.codecID = peer->settings->RemoteFxCodecId;
- cmd.bmp.width = width;
- cmd.bmp.height = height;
-
- uint32_t *ptr = pixman_image_get_data(output->shadow_surface) +
- damage->extents.x1 + damage->extents.y1 *
- (pixman_image_get_stride(output->shadow_surface) / sizeof(uint32_t));
-
- RFX_RECT *rfx_rect;
- int nrects;
- pixman_box32_t *rects =
- pixman_region32_rectangles(damage, &nrects);
- rfx_rect = realloc(context->rfx_rects, nrects * sizeof(*rfx_rect));
- if (rfx_rect == NULL) {
- wlr_log(WLR_ERROR, "RDP swap buffers failed: could not realloc rects");
- return false;
- }
- context->rfx_rects = rfx_rect;
-
- for (int i = 0; i < nrects; ++i) {
- pixman_box32_t *region = &rects[i];
- rfx_rect = &context->rfx_rects[i];
- rfx_rect->x = region->x1 - damage->extents.x1;
- rfx_rect->y = region->y1 - damage->extents.y1;
- rfx_rect->width = region->x2 - region->x1;
- rfx_rect->height = region->y2 - region->y1;
- }
-
- rfx_compose_message(context->rfx_context, context->encode_stream,
- context->rfx_rects, nrects, (BYTE *)ptr, width, height,
- pixman_image_get_stride(output->shadow_surface));
- cmd.bmp.bitmapDataLength = Stream_GetPosition(context->encode_stream);
- cmd.bmp.bitmapData = Stream_Buffer(context->encode_stream);
-
- update->SurfaceBits(update->context, &cmd);
- return true;
-}
-
-static bool nsc_swap_buffers(
- struct wlr_rdp_output *output, pixman_region32_t *damage) {
- struct wlr_rdp_peer_context *context = output->context;
- freerdp_peer *peer = context->peer;
- rdpUpdate *update = peer->update;
-
- Stream_Clear(context->encode_stream);
- Stream_SetPosition(context->encode_stream, 0);
- int width = damage->extents.x2 - damage->extents.x1;
- int height = damage->extents.y2 - damage->extents.y1;
-
- SURFACE_BITS_COMMAND cmd;
- cmd.skipCompression = TRUE;
- cmd.destLeft = damage->extents.x1;
- cmd.destTop = damage->extents.y1;
- cmd.destRight = damage->extents.x2;
- cmd.destBottom = damage->extents.y2;
- cmd.bmp.bpp = pixman_image_get_depth(output->shadow_surface);
- cmd.bmp.codecID = peer->settings->NSCodecId;
- cmd.bmp.width = width;
- cmd.bmp.height = height;
-
- uint32_t *ptr = pixman_image_get_data(output->shadow_surface) +
- damage->extents.x1 + damage->extents.y1 *
- (pixman_image_get_stride(output->shadow_surface) / sizeof(uint32_t));
-
- nsc_compose_message(context->nsc_context, context->encode_stream,
- (BYTE *)ptr, width, height,
- pixman_image_get_stride(output->shadow_surface));
-
- cmd.bmp.bitmapDataLength = Stream_GetPosition(context->encode_stream);
- cmd.bmp.bitmapData = Stream_Buffer(context->encode_stream);
-
- update->SurfaceBits(update->context, &cmd);
- return true;
-}
-
-static bool output_commit_buffer(struct wlr_rdp_output *output) {
- struct wlr_output *wlr_output = &output->wlr_output;
-
- bool ret = false;
-
- pixman_region32_t output_region;
- pixman_region32_init(&output_region);
- pixman_region32_union_rect(&output_region, &output_region,
- 0, 0, wlr_output->width, wlr_output->height);
-
- pixman_region32_t *damage = &output_region;
- if (wlr_output->pending.committed & WLR_OUTPUT_STATE_DAMAGE) {
- damage = &wlr_output->pending.damage;
- }
-
- int x = damage->extents.x1;
- int y = damage->extents.y1;
- int width = damage->extents.x2 - damage->extents.x1;
- int height = damage->extents.y2 - damage->extents.y1;
-
- // Update shadow buffer
- struct wlr_renderer *renderer =
- wlr_backend_get_renderer(&output->backend->backend);
- // TODO performance: add support for flags
- ret = wlr_renderer_read_pixels(renderer, WL_SHM_FORMAT_XRGB8888,
- NULL, pixman_image_get_stride(output->shadow_surface),
- width, height, x, y, x, y,
- pixman_image_get_data(output->shadow_surface));
- if (!ret) {
- goto out;
- }
-
- // Send along to clients
- rdpSettings *settings = output->context->peer->settings;
- if (settings->RemoteFxCodec) {
- ret = rfx_swap_buffers(output, damage);
- } else if (settings->NSCodec) {
- ret = nsc_swap_buffers(output, damage);
- } else {
- // This would perform like ass so why bother
- wlr_log(WLR_ERROR, "Raw updates are not supported; use rfx or nsc");
- ret = false;
- }
- if (!ret) {
- goto out;
- }
-
- wlr_output_send_present(wlr_output, NULL);
-
-out:
- pixman_region32_fini(&output_region);
- return ret;
-}
-
-static bool output_commit(struct wlr_output *wlr_output) {
- struct wlr_rdp_output *output = rdp_output_from_output(wlr_output);
-
- if (wlr_output->pending.committed & WLR_OUTPUT_STATE_ENABLED) {
- wlr_log(WLR_DEBUG, "Cannot disable an RDP output");
- return false;
- }
-
- if (wlr_output->pending.committed & WLR_OUTPUT_STATE_MODE) {
- assert(wlr_output->pending.mode_type == WLR_OUTPUT_STATE_MODE_CUSTOM);
- if (!output_set_custom_mode(wlr_output,
- wlr_output->pending.custom_mode.width,
- wlr_output->pending.custom_mode.height,
- wlr_output->pending.custom_mode.refresh)) {
- return false;
- }
- }
-
- if (wlr_output->pending.committed & WLR_OUTPUT_STATE_BUFFER) {
- if (!output_commit_buffer(output)) {
- return false;
- }
- }
-
- return true;
-}
-
-static void output_destroy(struct wlr_output *wlr_output) {
- struct wlr_rdp_output *output =
- rdp_output_from_output(wlr_output);
- if (output->frame_timer) {
- wl_event_source_remove(output->frame_timer);
- }
- wlr_egl_destroy_surface(&output->backend->egl, output->egl_surface);
- if (output->shadow_surface) {
- pixman_image_unref(output->shadow_surface);
- }
- free(output);
-}
-
-static const struct wlr_output_impl output_impl = {
- .destroy = output_destroy,
- .attach_render = output_attach_render,
- .commit = output_commit,
-};
-
-bool wlr_output_is_rdp(struct wlr_output *wlr_output) {
- return wlr_output->impl == &output_impl;
-}
-
-static int signal_frame(void *data) {
- struct wlr_rdp_output *output = data;
- wlr_output_send_frame(&output->wlr_output);
- wl_event_source_timer_update(output->frame_timer, output->frame_delay);
- return 0;
-}
-
-struct wlr_rdp_output *wlr_rdp_output_create(struct wlr_rdp_backend *backend,
- struct wlr_rdp_peer_context *context, unsigned int width,
- unsigned int height) {
- struct wlr_rdp_output *output =
- calloc(1, sizeof(struct wlr_rdp_output));
- if (output == NULL) {
- wlr_log(WLR_ERROR, "Failed to allocate wlr_rdp_output");
- return NULL;
- }
- output->backend = backend;
- output->context = context;
- wlr_output_init(&output->wlr_output, &backend->backend, &output_impl,
- backend->display);
- struct wlr_output *wlr_output = &output->wlr_output;
-
- output->egl_surface = egl_create_surface(&backend->egl, width, height);
- if (output->egl_surface == EGL_NO_SURFACE) {
- wlr_log(WLR_ERROR, "Failed to create EGL surface");
- goto error;
- }
-
- output_set_custom_mode(wlr_output, width, height, 0);
- strncpy(wlr_output->make, "RDP", sizeof(wlr_output->make));
- strncpy(wlr_output->model, "RDP", sizeof(wlr_output->model));
- snprintf(wlr_output->name, sizeof(wlr_output->name), "RDP-%d",
- wl_list_length(&backend->clients));
-
- char description[128];
- snprintf(description, sizeof(description),
- "RDP output %d", wl_list_length(&backend->clients));
- wlr_output_set_description(wlr_output, description);
-
- if (!wlr_egl_make_current(&output->backend->egl, output->egl_surface,
- NULL)) {
- goto error;
- }
-
- wlr_renderer_begin(backend->renderer, wlr_output->width, wlr_output->height);
- wlr_renderer_clear(backend->renderer, (float[]){ 1.0, 1.0, 1.0, 1.0 });
- wlr_renderer_end(backend->renderer);
-
- struct wl_event_loop *ev = wl_display_get_event_loop(backend->display);
- output->frame_timer = wl_event_loop_add_timer(ev, signal_frame, output);
- wl_event_source_timer_update(output->frame_timer, output->frame_delay);
- wlr_output_update_enabled(wlr_output, true);
- wlr_signal_emit_safe(&backend->backend.events.new_output, wlr_output);
- return output;
-
-error:
- wlr_output_destroy(&output->wlr_output);
- return NULL;
-}
diff --git a/backend/rdp/peer.c b/backend/rdp/peer.c
deleted file mode 100644
index 350a4721..00000000
--- a/backend/rdp/peer.c
+++ /dev/null
@@ -1,360 +0,0 @@
-#define _POSIX_C_SOURCE 200809L
-#include <linux/input.h>
-#include <stdlib.h>
-#include <string.h>
-#include <wlr/types/wlr_output.h>
-#include <wlr/interfaces/wlr_input_device.h>
-#include <wlr/interfaces/wlr_keyboard.h>
-#include <wlr/interfaces/wlr_output.h>
-#include <wlr/util/log.h>
-#include "backend/rdp.h"
-#include "util/signal.h"
-
-static BOOL xf_peer_capabilities(freerdp_peer *client) {
- return TRUE;
-}
-
-static BOOL xf_peer_post_connect(freerdp_peer *client) {
- return TRUE;
-}
-
-static BOOL xf_peer_activate(freerdp_peer *client) {
- struct wlr_rdp_peer_context *context =
- (struct wlr_rdp_peer_context *)client->context;
- struct wlr_rdp_backend *backend = context->backend;
- rdpSettings *settings = client->settings;
-
- if (!settings->SurfaceCommandsEnabled) {
- wlr_log(WLR_ERROR, "RDP peer does not support SurfaceCommands");
- return FALSE;
- }
-
- context->output = wlr_rdp_output_create(backend, context,
- (int)settings->DesktopWidth, (int)settings->DesktopHeight);
- if (!context->output) {
- wlr_log(WLR_ERROR, "Failed to allcoate output for RDP peer");
- return FALSE;
- }
- rfx_context_reset(context->rfx_context,
- context->output->wlr_output.width,
- context->output->wlr_output.height);
- nsc_context_reset(context->nsc_context,
- context->output->wlr_output.width,
- context->output->wlr_output.height);
-
- if (context->flags & RDP_PEER_ACTIVATED) {
- return TRUE;
- }
-
- context->pointer = wlr_rdp_pointer_create(backend, context);
- if (!context->pointer) {
- wlr_log(WLR_ERROR, "Failed to allocate pointer for RDP peer");
- return FALSE;
- }
-
- // Use wlroots' software cursors instead of remote cursors
- POINTER_SYSTEM_UPDATE pointer_system;
- rdpPointerUpdate *pointer = client->update->pointer;
- pointer_system.type = SYSPTR_NULL;
- pointer->PointerSystem(client->context, &pointer_system);
-
- context->keyboard = wlr_rdp_keyboard_create(backend, settings);
- if (!context->keyboard) {
- wlr_log(WLR_ERROR, "Failed to allocate keyboard for RDP peer");
- return FALSE;
- }
-
- context->flags |= RDP_PEER_ACTIVATED;
- return TRUE;
-}
-
-static int xf_suppress_output(rdpContext *context,
- BYTE allow, const RECTANGLE_16 *area) {
- struct wlr_rdp_peer_context *peer_context =
- (struct wlr_rdp_peer_context *)context;
- if (allow) {
- peer_context->flags |= RDP_PEER_OUTPUT_ENABLED;
- } else {
- peer_context->flags &= ~RDP_PEER_OUTPUT_ENABLED;
- }
- return true;
-}
-
-static int xf_input_synchronize_event(rdpInput *input, UINT32 flags) {
- struct wlr_rdp_peer_context *context =
- (struct wlr_rdp_peer_context *)input->context;
- wlr_output_damage_whole(&context->output->wlr_output);
- return true;
-}
-
-static inline int64_t timespec_to_msec(const struct timespec *a) {
- return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000;
-}
-
-static int xf_input_mouse_event(rdpInput *input,
- UINT16 flags, UINT16 x, UINT16 y) {
- struct wlr_rdp_peer_context *context =
- (struct wlr_rdp_peer_context *)input->context;
- struct wlr_input_device *wlr_device = &context->pointer->wlr_input_device;
- struct wlr_pointer *pointer = wlr_device->pointer;
- bool frame = false;
- struct timespec now;
- clock_gettime(CLOCK_MONOTONIC, &now);
-
- if (flags & PTR_FLAGS_MOVE) {
- struct wlr_event_pointer_motion_absolute event = { 0 };
- event.device = wlr_device;
- event.time_msec = timespec_to_msec(&now);
- event.x = x / (double)context->output->wlr_output.width;
- event.y = y / (double)context->output->wlr_output.height;
- wlr_signal_emit_safe(&pointer->events.motion_absolute, &event);
- frame = true;
- }
-
- uint32_t button = 0;
- if (flags & PTR_FLAGS_BUTTON1) {
- button = BTN_LEFT;
- } else if (flags & PTR_FLAGS_BUTTON2) {
- button = BTN_RIGHT;
- } else if (flags & PTR_FLAGS_BUTTON3) {
- button = BTN_MIDDLE;
- }
-
- if (button) {
- struct wlr_event_pointer_button event = { 0 };
- event.device = wlr_device;
- event.time_msec = timespec_to_msec(&now);
- event.button = button;
- event.state = (flags & PTR_FLAGS_DOWN) ?
- WLR_BUTTON_PRESSED : WLR_BUTTON_RELEASED;
- wlr_signal_emit_safe(&pointer->events.button, &event);
- frame = true;
- }
-
- if (flags & PTR_FLAGS_WHEEL) {
- double value = -(flags & 0xFF) / 120.0;
- if (flags & PTR_FLAGS_WHEEL_NEGATIVE) {
- value = -value;
- }
- struct wlr_event_pointer_axis event = { 0 };
- event.device = &context->pointer->wlr_input_device;
- event.time_msec = timespec_to_msec(&now);
- event.source = WLR_AXIS_SOURCE_WHEEL;
- event.orientation = WLR_AXIS_ORIENTATION_VERTICAL;
- event.delta = value;
- event.delta_discrete = (int32_t)value;
- wlr_signal_emit_safe(&pointer->events.axis, &event);
- frame = true;
- }
-
- if (frame) {
- wlr_signal_emit_safe(&pointer->events.frame, pointer);
- }
-
- return true;
-}
-
-static int xf_input_extended_mouse_event(
- rdpInput *input, UINT16 flags, UINT16 x, UINT16 y) {
- struct wlr_rdp_peer_context *context =
- (struct wlr_rdp_peer_context *)input->context;
- struct wlr_input_device *wlr_device = &context->pointer->wlr_input_device;
- struct wlr_pointer *pointer = wlr_device->pointer;
- struct timespec now;
- clock_gettime(CLOCK_MONOTONIC, &now);
- struct wlr_event_pointer_motion_absolute event = { 0 };
- event.device = wlr_device;
- event.time_msec = timespec_to_msec(&now);
- event.x = x / (double)context->output->wlr_output.width;
- event.y = y / (double)context->output->wlr_output.height;
- wlr_signal_emit_safe(&pointer->events.motion_absolute, &event);
- wlr_signal_emit_safe(&pointer->events.frame, pointer);
- return true;
-}
-
-static int xf_input_keyboard_event(rdpInput *input, UINT16 flags, UINT16 code) {
- struct wlr_rdp_peer_context *context =
- (struct wlr_rdp_peer_context *)input->context;
- struct wlr_input_device *wlr_device = &context->keyboard->wlr_input_device;
- struct wlr_keyboard *keyboard = wlr_device->keyboard;
- struct timespec now;
- clock_gettime(CLOCK_MONOTONIC, &now);
-
- if (!(context->flags & RDP_PEER_ACTIVATED)) {
- return true;
- }
-
- bool notify = false;
- enum wlr_key_state state;
- if ((flags & KBD_FLAGS_DOWN)) {
- state = WLR_KEY_PRESSED;
- notify = true;
- } else if ((flags & KBD_FLAGS_RELEASE)) {
- state = WLR_KEY_RELEASED;
- notify = true;
- }
-
- if (notify) {
- uint32_t full_code = code;
- if (flags & KBD_FLAGS_EXTENDED) {
- full_code |= KBD_FLAGS_EXTENDED;
- }
- uint32_t vk_code = GetVirtualKeyCodeFromVirtualScanCode(full_code, 4);
- if (flags & KBD_FLAGS_EXTENDED) {
- vk_code |= KBDEXT;
- }
- uint32_t scan_code = GetKeycodeFromVirtualKeyCode(
- vk_code, KEYCODE_TYPE_EVDEV);
- struct wlr_event_keyboard_key event = { 0 };
- event.time_msec = timespec_to_msec(&now);
- event.keycode = scan_code - 8;
- event.state = state;
- event.update_state = true;
- wlr_keyboard_notify_key(keyboard, &event);
- }
-
- return true;
-}
-
-static int xf_input_unicode_keyboard_event(rdpInput *input,
- UINT16 flags, UINT16 code) {
- wlr_log(WLR_DEBUG, "Unhandled RDP unicode keyboard event "
- "(flags:0x%X code:0x%X)\n", flags, code);
- return true;
-}
-
-static int rdp_client_activity(int fd, uint32_t mask, void *data) {
- freerdp_peer *client = (freerdp_peer *)data;
- if (!client->CheckFileDescriptor(client)) {
- wlr_log(WLR_ERROR,
- "Unable to check client file descriptor for %p", client);
- freerdp_peer_context_free(client);
- freerdp_peer_free(client);
- }
- return 0;
-}
-
-static int rdp_peer_context_new(
- freerdp_peer *client, struct wlr_rdp_peer_context *context) {
- context->peer = client;
- context->flags = RDP_PEER_OUTPUT_ENABLED;
- context->rfx_context = rfx_context_new(TRUE);
- if (!context->rfx_context) {
- return false;
- }
- context->rfx_context->mode = RLGR3;
- context->rfx_context->width = client->settings->DesktopWidth;
- context->rfx_context->height = client->settings->DesktopHeight;
- rfx_context_set_pixel_format(context->rfx_context, PIXEL_FORMAT_BGRA32);
-
- context->nsc_context = nsc_context_new();
- if (!context->nsc_context) {
- rfx_context_free(context->rfx_context);
- return false;
- }
-
- nsc_context_set_pixel_format(context->nsc_context, PIXEL_FORMAT_BGRA32);
-
- context->encode_stream = Stream_New(NULL, 65536);
- if (!context->encode_stream) {
- nsc_context_free(context->nsc_context);
- rfx_context_free(context->rfx_context);
- return false;
- }
- return true;
-}
-
-static void rdp_peer_context_free(
- freerdp_peer *client, struct wlr_rdp_peer_context *context) {
- if (!context) {
- return;
- }
-
- for (int i = 0; i < MAX_FREERDP_FDS; ++i) {
- if (context->events[i]) {
- wl_event_source_remove(context->events[i]);
- }
- }
-
- if (context->flags & RDP_PEER_ACTIVATED) {
- wlr_output_destroy(&context->output->wlr_output);
- wlr_input_device_destroy(&context->pointer->wlr_input_device);
- wlr_input_device_destroy(&context->keyboard->wlr_input_device);
- }
-
- wl_list_remove(&context->link);
- wlr_output_destroy(&context->output->wlr_output);
-
- Stream_Free(context->encode_stream, TRUE);
- nsc_context_free(context->nsc_context);
- rfx_context_free(context->rfx_context);
- free(context->rfx_rects);
-}
-
-int rdp_peer_init(freerdp_peer *client,
- struct wlr_rdp_backend *backend) {
- client->ContextSize = sizeof(struct wlr_rdp_peer_context);
- client->ContextNew = (psPeerContextNew)rdp_peer_context_new;
- client->ContextFree = (psPeerContextFree)rdp_peer_context_free;
- freerdp_peer_context_new(client);
-
- struct wlr_rdp_peer_context *peer_context =
- (struct wlr_rdp_peer_context *)client->context;
- peer_context->backend = backend;
-
- client->settings->CertificateFile = strdup(backend->tls_cert_path);
- client->settings->PrivateKeyFile = strdup(backend->tls_key_path);
- client->settings->NlaSecurity = FALSE;
-
- if (!client->Initialize(client)) {
- wlr_log(WLR_ERROR, "Failed to initialize FreeRDP peer");
- goto err_init;
- }
-
- client->settings->OsMajorType = OSMAJORTYPE_UNIX;
- client->settings->OsMinorType = OSMINORTYPE_PSEUDO_XSERVER;
- client->settings->ColorDepth = 32;
- client->settings->RefreshRect = TRUE;
- client->settings->RemoteFxCodec = TRUE;
- client->settings->NSCodec = TRUE;
- client->settings->FrameMarkerCommandEnabled = TRUE;
- client->settings->SurfaceFrameMarkerEnabled = TRUE;
-
- client->Capabilities = xf_peer_capabilities;
- client->PostConnect = xf_peer_post_connect;
- client->Activate = xf_peer_activate;
-
- client->update->SuppressOutput = (pSuppressOutput)xf_suppress_output;
-
- client->input->SynchronizeEvent = xf_input_synchronize_event;
- client->input->MouseEvent = xf_input_mouse_event;
- client->input->ExtendedMouseEvent = xf_input_extended_mouse_event;
- client->input->KeyboardEvent = xf_input_keyboard_event;
- client->input->UnicodeKeyboardEvent = xf_input_unicode_keyboard_event;
-
- int rcount = 0;
- void *rfds[MAX_FREERDP_FDS];
- if (!client->GetFileDescriptor(client, rfds, &rcount)) {
- wlr_log(WLR_ERROR, "Unable to retrieve client file descriptors");
- goto err_init;
- }
- struct wl_event_loop *event_loop =
- wl_display_get_event_loop(backend->display);
- int i;
- for (i = 0; i < rcount; ++i) {
- int fd = (int)(long)(rfds[i]);
- peer_context->events[i] = wl_event_loop_add_fd(
- event_loop, fd, WL_EVENT_READABLE, rdp_client_activity,
- client);
- }
- for (; i < MAX_FREERDP_FDS; ++i) {
- peer_context->events[i] = NULL;
- }
-
- wl_list_insert(&backend->clients, &peer_context->link);
- return 0;
-
-err_init:
- client->Close(client);
- return -1;
-}
diff --git a/backend/rdp/pointer.c b/backend/rdp/pointer.c
deleted file mode 100644
index b3fdcd73..00000000
--- a/backend/rdp/pointer.c
+++ /dev/null
@@ -1,40 +0,0 @@
-#define _POSIX_C_SOURCE 200809L
-#include <stdlib.h>
-#include <string.h>
-#include <wayland-server-core.h>
-#include <wlr/types/wlr_input_device.h>
-#include <wlr/types/wlr_pointer.h>
-#include <wlr/interfaces/wlr_pointer.h>
-#include <wlr/interfaces/wlr_input_device.h>
-#include <wlr/util/log.h>
-#include "backend/rdp.h"
-#include "util/signal.h"
-
-static struct wlr_input_device_impl input_device_impl = { 0 };
-
-struct wlr_rdp_input_device *wlr_rdp_pointer_create(
- struct wlr_rdp_backend *backend, struct wlr_rdp_peer_context *context) {
- struct wlr_rdp_input_device *device =
- calloc(1, sizeof(struct wlr_rdp_input_device));
- if (!device) {
- wlr_log(WLR_ERROR, "Failed to allocate RDP input device");
- return NULL;
- }
-
- int vendor = 0;
- int product = 0;
- const char *name = "rdp";
- struct wlr_input_device *wlr_device = &device->wlr_input_device;
- wlr_input_device_init(wlr_device, WLR_INPUT_DEVICE_POINTER,
- &input_device_impl, name, vendor, product);
-
- if (!(wlr_device->pointer = calloc(1, sizeof(struct wlr_pointer)))) {
- wlr_log(WLR_ERROR, "Failed to allocate RDP pointer device");
- return NULL;
- }
- wlr_device->output_name = strdup(context->output->wlr_output.name);
- wlr_pointer_init(wlr_device->pointer, NULL);
-
- wlr_signal_emit_safe(&backend->backend.events.new_input, wlr_device);
- return device;
-}