static void data_offer_data_free (DataOfferData *info) { wl_data_offer_destroy (info->offer); g_list_free (info->targets); g_slice_free (DataOfferData, info); }
void gdk_wayland_selection_free (GdkWaylandSelection *selection) { g_hash_table_destroy (selection->selection_buffers); if (selection->targets) g_list_free (selection->targets); g_free (selection->stored_selection.data); if (selection->stored_selection.cancellable) { g_cancellable_cancel (selection->stored_selection.cancellable); g_object_unref (selection->stored_selection.cancellable); } if (selection->stored_selection.fd > 0) close (selection->stored_selection.fd); if (selection->offer) wl_data_offer_destroy (selection->offer); if (selection->clipboard_source) wl_data_source_destroy (selection->clipboard_source); if (selection->dnd_source) wl_data_source_destroy (selection->dnd_source); g_free (selection); }
PasteboardWayland::~PasteboardWayland() { if (m_dataDeviceData.data_offer) wl_data_offer_destroy(m_dataDeviceData.data_offer); m_dataDeviceData.dataTypes.clear(); wl_data_device_destroy(m_dataDevice); }
void nsRetrievalContextWayland::SetDataOffer(wl_data_offer *aDataOffer) { if(mDataOffer) { wl_data_offer_destroy(mDataOffer); } mDataOffer = aDataOffer; }
static void data_device_handle_leave(void *data, struct wl_data_device *wl_data_device) { struct vo_wayland_state *wl = data; if (wl->input.offer) { wl_data_offer_destroy(wl->input.offer); wl->input.offer = NULL; } // dnd fd is closed on POLLHUP }
static void dataDeviceHandleDataOffer(void* data, struct wl_data_device* dataDevice, struct wl_data_offer* id) { if (_glfw.wl.dataOffer) wl_data_offer_destroy(_glfw.wl.dataOffer); _glfw.wl.dataOffer = id; wl_data_offer_add_listener(_glfw.wl.dataOffer, &dataOfferListener, NULL); }
static void data_device_handle_data_offer(void *data, struct wl_data_device *wl_data_device, struct wl_data_offer *id) { struct vo_wayland_state *wl = data; if (wl->input.offer) { MP_ERR(wl, "There is already a dnd entry point.\n"); wl_data_offer_destroy(wl->input.offer); } wl->input.offer = id; wl_data_offer_add_listener(id, &data_offer_listener, wl); }
void gdk_wayland_selection_set_offer (GdkDisplay *display, struct wl_data_offer *wl_offer) { GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display); if (selection->offer == wl_offer) return; if (selection->offer) wl_data_offer_destroy (selection->offer); selection->offer = wl_offer; if (wl_offer) wl_data_offer_add_listener (wl_offer, &data_offer_listener, selection); /* Clear all buffers */ g_hash_table_remove_all (selection->selection_buffers); g_list_free (selection->targets); selection->targets = NULL; }
namespace Pasteboard { const struct wl_data_offer_listener g_dataOfferListener = { // offer [] (void* data, struct wl_data_offer* offer, const char* type) { auto& dataDeviceData = *static_cast<PasteboardWayland::DataDeviceData*>(data); assert(offer == dataDeviceData.data_offer); dataDeviceData.dataTypes.push_back(type); }, }; const struct wl_data_device_listener g_dataDeviceListener = { // data_offer [] (void* data, struct wl_data_device*, struct wl_data_offer* offer) { auto& dataDeviceData = *static_cast<PasteboardWayland::DataDeviceData*>(data); dataDeviceData.dataTypes.clear(); if (dataDeviceData.data_offer) wl_data_offer_destroy(dataDeviceData.data_offer); dataDeviceData.data_offer = offer; wl_data_offer_add_listener(offer, &g_dataOfferListener, data); }, // enter [] (void*, struct wl_data_device*, uint32_t, struct wl_surface*, wl_fixed_t, wl_fixed_t, struct wl_data_offer*) {}, // leave [] (void*, struct wl_data_device*) {}, // motion [] (void*, struct wl_data_device*, uint32_t, wl_fixed_t, wl_fixed_t) {}, // drop [] (void*, struct wl_data_device*) {}, // selection [] (void*, struct wl_data_device*, wl_data_offer*) {}, }; PasteboardWayland::PasteboardWayland() { ViewBackend::WaylandDisplay& display = ViewBackend::WaylandDisplay::singleton(); if (!display.interfaces().data_device_manager) return; m_dataDevice = wl_data_device_manager_get_data_device(display.interfaces().data_device_manager, display.interfaces().seat); wl_data_device_add_listener(m_dataDevice, &g_dataDeviceListener, &m_dataDeviceData); } PasteboardWayland::~PasteboardWayland() { if (m_dataDeviceData.data_offer) wl_data_offer_destroy(m_dataDeviceData.data_offer); m_dataDeviceData.dataTypes.clear(); wl_data_device_destroy(m_dataDevice); } std::vector<std::string> PasteboardWayland::getTypes() { std::vector<std::string> types; for (auto dataType: m_dataDeviceData.dataTypes) types.push_back(dataType); return types; } std::string PasteboardWayland::getString(const std::string pasteboardType) { if (!std::any_of(m_dataDeviceData.dataTypes.cbegin(), m_dataDeviceData.dataTypes.cend(), [pasteboardType](std::string str){ return str == pasteboardType;})) return std::string(); int pipefd[2]; // FIXME: Should probably handle this error somehow. if (pipe2(pipefd, O_CLOEXEC) == -1) return std::string(); wl_data_offer_receive(m_dataDeviceData.data_offer, pasteboardType.c_str(), pipefd[1]); close(pipefd[1]); wl_display_roundtrip(ViewBackend::WaylandDisplay::singleton().display()); char buf[1024]; std::string readString; ssize_t length; do { length = read(pipefd[0], buf, 1024); readString.append(buf, length); } while (length > 0); close(pipefd[0]); return readString; } const struct wl_data_source_listener g_dataSourceListener = { // target [] (void*, struct wl_data_source*, const char*) {}, // send [] (void* data, struct wl_data_source* source, const char* mime_type, int32_t fd) { auto& dataSourceData = *static_cast<PasteboardWayland::DataSourceData*>(data); assert(dataSourceData.data_source == source); assert(!dataSourceData.dataMap.count(mime_type)); if (strncmp(mime_type, "text/", 5) == 0) { std::string stringToSend = dataSourceData.dataMap[mime_type]; const char* p = stringToSend.data(); ssize_t length = stringToSend.size(); ssize_t written = 0; while (length > 0 && written != -1) { written = write(fd, p, length); p += written; length -= written; } close(fd); wl_display_roundtrip(ViewBackend::WaylandDisplay::singleton().display()); } else return; // Eventually assert if we don't have a handler for a mimetype we are offering. }, // cancelled [] (void* data, struct wl_data_source* source) { auto& dataSourceData = *static_cast<PasteboardWayland::DataSourceData*>(data); assert(dataSourceData.data_source == source); wl_data_source_destroy(source); dataSourceData.data_source = nullptr; dataSourceData.dataMap.clear(); } }; void PasteboardWayland::write(std::map<std::string, std::string>&& dataMap) { if (m_dataSourceData.data_source) wl_data_source_destroy(m_dataSourceData.data_source); m_dataSourceData.dataMap = dataMap; ViewBackend::WaylandDisplay& display = ViewBackend::WaylandDisplay::singleton(); m_dataSourceData.data_source = wl_data_device_manager_create_data_source(display.interfaces().data_device_manager); for (auto dataPair : m_dataSourceData.dataMap) wl_data_source_offer(m_dataSourceData.data_source, dataPair.first.c_str()); wl_data_source_add_listener(m_dataSourceData.data_source, &g_dataSourceListener, &m_dataSourceData); wl_data_device_set_selection(m_dataDevice, m_dataSourceData.data_source, display.singleton().serial()); } void PasteboardWayland::write(std::string&& pasteboardType, std::string&& stringToWrite) { std::map<std::string, std::string> dataMap; dataMap[pasteboardType] = stringToWrite; write(std::move(dataMap)); } } // namespace Pasteboard
void _glfwPlatformTerminate(void) { #ifdef __linux__ _glfwTerminateJoysticksLinux(); #endif _glfwTerminateEGL(); if (_glfw.wl.egl.handle) { _glfw_dlclose(_glfw.wl.egl.handle); _glfw.wl.egl.handle = NULL; } #ifdef HAVE_XKBCOMMON_COMPOSE_H if (_glfw.wl.xkb.composeState) xkb_compose_state_unref(_glfw.wl.xkb.composeState); #endif if (_glfw.wl.xkb.keymap) xkb_keymap_unref(_glfw.wl.xkb.keymap); if (_glfw.wl.xkb.state) xkb_state_unref(_glfw.wl.xkb.state); if (_glfw.wl.xkb.context) xkb_context_unref(_glfw.wl.xkb.context); if (_glfw.wl.xkb.handle) { _glfw_dlclose(_glfw.wl.xkb.handle); _glfw.wl.xkb.handle = NULL; } if (_glfw.wl.cursorTheme) wl_cursor_theme_destroy(_glfw.wl.cursorTheme); if (_glfw.wl.cursorThemeHiDPI) wl_cursor_theme_destroy(_glfw.wl.cursorThemeHiDPI); if (_glfw.wl.cursor.handle) { _glfw_dlclose(_glfw.wl.cursor.handle); _glfw.wl.cursor.handle = NULL; } if (_glfw.wl.cursorSurface) wl_surface_destroy(_glfw.wl.cursorSurface); if (_glfw.wl.subcompositor) wl_subcompositor_destroy(_glfw.wl.subcompositor); if (_glfw.wl.compositor) wl_compositor_destroy(_glfw.wl.compositor); if (_glfw.wl.shm) wl_shm_destroy(_glfw.wl.shm); if (_glfw.wl.shell) wl_shell_destroy(_glfw.wl.shell); if (_glfw.wl.viewporter) wp_viewporter_destroy(_glfw.wl.viewporter); if (_glfw.wl.decorationManager) zxdg_decoration_manager_v1_destroy(_glfw.wl.decorationManager); if (_glfw.wl.wmBase) xdg_wm_base_destroy(_glfw.wl.wmBase); if (_glfw.wl.dataSource) wl_data_source_destroy(_glfw.wl.dataSource); if (_glfw.wl.dataDevice) wl_data_device_destroy(_glfw.wl.dataDevice); if (_glfw.wl.dataOffer) wl_data_offer_destroy(_glfw.wl.dataOffer); if (_glfw.wl.dataDeviceManager) wl_data_device_manager_destroy(_glfw.wl.dataDeviceManager); if (_glfw.wl.pointer) wl_pointer_destroy(_glfw.wl.pointer); if (_glfw.wl.keyboard) wl_keyboard_destroy(_glfw.wl.keyboard); if (_glfw.wl.seat) wl_seat_destroy(_glfw.wl.seat); if (_glfw.wl.relativePointerManager) zwp_relative_pointer_manager_v1_destroy(_glfw.wl.relativePointerManager); if (_glfw.wl.pointerConstraints) zwp_pointer_constraints_v1_destroy(_glfw.wl.pointerConstraints); if (_glfw.wl.idleInhibitManager) zwp_idle_inhibit_manager_v1_destroy(_glfw.wl.idleInhibitManager); if (_glfw.wl.registry) wl_registry_destroy(_glfw.wl.registry); if (_glfw.wl.display) { wl_display_flush(_glfw.wl.display); wl_display_disconnect(_glfw.wl.display); } if (_glfw.wl.timerfd >= 0) close(_glfw.wl.timerfd); if (_glfw.wl.cursorTimerfd >= 0) close(_glfw.wl.cursorTimerfd); if (_glfw.wl.clipboardString) free(_glfw.wl.clipboardString); if (_glfw.wl.clipboardSendString) free(_glfw.wl.clipboardSendString); }