Esempio n. 1
0
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);
}
Esempio n. 2
0
static void
data_device_data_offer (void                  *data,
                        struct wl_data_device *data_device,
                        struct wl_data_offer  *offer)
{
    nsRetrievalContextWayland *context =
        static_cast<nsRetrievalContextWayland*>(data);

    // We have a new fresh clipboard content
    context->ResetMIMETypeList();
    wl_data_offer_add_listener (offer, &data_offer_listener, data);
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
static void
data_device_handle_data_offer(void *data, struct wl_data_device *wl_data_device,
			                  struct wl_data_offer *id)
{
    SDL_WaylandDataOffer *data_offer = NULL;

    data_offer = SDL_calloc(1, sizeof *data_offer);
    if (data_offer == NULL) {
        SDL_OutOfMemory();
    } else {
        data_offer->offer = id;
        data_offer->data_device = data;
        WAYLAND_wl_list_init(&(data_offer->mimes));
        wl_data_offer_set_user_data(id, data_offer);
        wl_data_offer_add_listener(id, &data_offer_listener, data_offer);
    }
}
Esempio n. 5
0
void
gdk_wayland_selection_ensure_offer (GdkDisplay           *display,
                                    struct wl_data_offer *wl_offer)
{
  GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display);
  DataOfferData *info;

  info = g_hash_table_lookup (selection->offers, wl_offer);

  if (!info)
    {
      info = data_offer_data_new (wl_offer);
      g_hash_table_insert (selection->offers, wl_offer, info);
      wl_data_offer_add_listener (wl_offer,
                                  &data_offer_listener,
                                  selection);
    }
}
Esempio n. 6
0
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