1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qwaylandclipboard_p.h"
5#include "qwaylanddisplay_p.h"
6#include "qwaylandinputdevice_p.h"
7#include "qwaylanddataoffer_p.h"
8#include "qwaylanddatasource_p.h"
9#include "qwaylanddatadevice_p.h"
10#if QT_CONFIG(wayland_client_primary_selection)
11#include "qwaylandprimaryselectionv1_p.h"
12#endif
13
14QT_BEGIN_NAMESPACE
15
16namespace QtWaylandClient {
17
18QWaylandClipboard::QWaylandClipboard(QWaylandDisplay *display)
19 : mDisplay(display)
20{
21 m_clientClipboard[QClipboard::Clipboard] = nullptr;
22 m_clientClipboard[QClipboard::Selection] = nullptr;
23}
24
25QWaylandClipboard::~QWaylandClipboard()
26{
27 if (m_clientClipboard[QClipboard::Clipboard] != m_clientClipboard[QClipboard::Selection])
28 delete m_clientClipboard[QClipboard::Clipboard];
29 delete m_clientClipboard[QClipboard::Selection];
30}
31
32QMimeData *QWaylandClipboard::mimeData(QClipboard::Mode mode)
33{
34 auto *seat = mDisplay->currentInputDevice();
35 if (!seat)
36 return &m_emptyData;
37
38 switch (mode) {
39 case QClipboard::Clipboard:
40 if (auto *dataDevice = seat->dataDevice()) {
41 if (dataDevice->selectionSource())
42 return m_clientClipboard[QClipboard::Clipboard];
43 if (auto *offer = dataDevice->selectionOffer())
44 return offer->mimeData();
45 }
46 return &m_emptyData;
47 case QClipboard::Selection:
48#if QT_CONFIG(wayland_client_primary_selection)
49 if (auto *selectionDevice = seat->primarySelectionDevice()) {
50 if (selectionDevice->selectionSource())
51 return m_clientClipboard[QClipboard::Selection];
52 if (auto *offer = selectionDevice->selectionOffer())
53 return offer->mimeData();
54 }
55#endif
56 return &m_emptyData;
57 default:
58 return &m_emptyData;
59 }
60}
61
62void QWaylandClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
63{
64 auto *seat = mDisplay->currentInputDevice();
65 if (!seat) {
66 qCWarning(lcQpaWayland) << "Can't set clipboard contents with no wl_seats available";
67 return;
68 }
69
70 static const QString plain = QStringLiteral("text/plain");
71 static const QString utf8 = QStringLiteral("text/plain;charset=utf-8");
72
73 if (data && data->hasFormat(mimetype: plain) && !data->hasFormat(mimetype: utf8))
74 data->setData(mimetype: utf8, data: data->data(mimetype: plain));
75
76 if (m_clientClipboard[mode]) {
77 if (m_clientClipboard[QClipboard::Clipboard] != m_clientClipboard[QClipboard::Selection])
78 delete m_clientClipboard[mode];
79 m_clientClipboard[mode] = nullptr;
80 }
81
82 m_clientClipboard[mode] = data;
83
84 switch (mode) {
85 case QClipboard::Clipboard:
86 if (auto *dataDevice = seat->dataDevice()) {
87 dataDevice->setSelectionSource(data ? new QWaylandDataSource(mDisplay->dndSelectionHandler(),
88 m_clientClipboard[QClipboard::Clipboard]) : nullptr);
89 emitChanged(mode);
90 }
91 break;
92 case QClipboard::Selection:
93#if QT_CONFIG(wayland_client_primary_selection)
94 if (auto *selectionDevice = seat->primarySelectionDevice()) {
95 selectionDevice->setSelectionSource(data ? new QWaylandPrimarySelectionSourceV1(mDisplay->primarySelectionManager(),
96 m_clientClipboard[QClipboard::Selection]) : nullptr);
97 emitChanged(mode);
98 }
99#endif
100 break;
101 default:
102 break;
103 }
104}
105
106bool QWaylandClipboard::supportsMode(QClipboard::Mode mode) const
107{
108#if QT_CONFIG(wayland_client_primary_selection)
109 if (mode == QClipboard::Selection) {
110 auto *seat = mDisplay->currentInputDevice();
111 return seat && seat->primarySelectionDevice();
112 }
113#endif
114 return mode == QClipboard::Clipboard;
115}
116
117bool QWaylandClipboard::ownsMode(QClipboard::Mode mode) const
118{
119 QWaylandInputDevice *seat = mDisplay->currentInputDevice();
120 if (!seat)
121 return false;
122
123 switch (mode) {
124 case QClipboard::Clipboard:
125 return seat->dataDevice() && seat->dataDevice()->selectionSource() != nullptr;
126#if QT_CONFIG(wayland_client_primary_selection)
127 case QClipboard::Selection:
128 return seat->primarySelectionDevice() && seat->primarySelectionDevice()->selectionSource() != nullptr;
129#endif
130 default:
131 return false;
132 }
133}
134
135}
136
137QT_END_NAMESPACE
138

source code of qtwayland/src/client/qwaylandclipboard.cpp