Qt 4.8
qwaylandclipboard.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the plugins of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qwaylandclipboard.h"
43 #include "qwaylanddisplay.h"
44 #include "qwaylandinputdevice.h"
45 #include <QtGui/QPlatformNativeInterface>
46 #include <QtGui/QApplication>
47 #include <QtCore/QMimeData>
48 #include <QtCore/QStringList>
49 #include <QtCore/QFile>
50 #include <QtCore/QtDebug>
51 #include <QtGui/private/qdnd_p.h>
52 
54 
56 {
57 public:
58  void clearAll();
59  void setFormats(const QStringList &formatList);
60  bool hasFormat_sys(const QString &mimeType) const;
61  QStringList formats_sys() const;
62  QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type) const;
63 private:
65 };
66 
68 {
69  clear();
71 }
72 
74 {
75  mFormatList = formatList;
76 }
77 
78 bool QWaylandMimeData::hasFormat_sys(const QString &mimeType) const
79 {
80  return formats().contains(mimeType);
81 }
82 
84 {
85  return mFormatList;
86 }
87 
89 {
90  return clipboard->retrieveData(mimeType, type);
91 }
92 
94 {
95 public:
98 
99  static uint32_t getTime();
100  static void send(void *data, struct wl_selection *selection, const char *mime_type, int fd);
101  static void cancelled(void *data, struct wl_selection *selection);
102  static const struct wl_selection_listener selectionListener;
103 
105  struct wl_selection *mSelection;
106 };
107 
108 const struct wl_selection_listener QWaylandSelection::selectionListener = {
111 };
112 
114 {
115  struct timeval tv;
116  gettimeofday(&tv, 0);
117  return tv.tv_sec * 1000 + tv.tv_usec / 1000;
118 }
119 
121  : mMimeData(data), mSelection(0)
122 {
123  struct wl_shell *shell = display->wl_shell();
124  mSelection = wl_shell_create_selection(shell);
125  wl_selection_add_listener(mSelection, &selectionListener, this);
126  foreach (const QString &format, data->formats())
127  wl_selection_offer(mSelection, format.toLatin1().constData());
128  wl_selection_activate(mSelection,
129  display->inputDevices().at(0)->wl_input_device(),
130  getTime());
131 }
132 
134 {
135  if (mSelection) {
136  clipboard->unregisterSelection(this);
137  wl_selection_destroy(mSelection);
138  }
139  delete mMimeData;
140 }
141 
143  struct wl_selection *selection,
144  const char *mime_type,
145  int fd)
146 {
147  Q_UNUSED(selection);
148  QWaylandSelection *self = static_cast<QWaylandSelection *>(data);
149  QString mimeType = QString::fromLatin1(mime_type);
150  QByteArray content = self->mMimeData->data(mimeType);
151  if (!content.isEmpty()) {
152  QFile f;
153  if (f.open(fd, QIODevice::WriteOnly))
154  f.write(content);
155  }
156  close(fd);
157 }
158 
159 void QWaylandSelection::cancelled(void *data, struct wl_selection *selection)
160 {
161  Q_UNUSED(selection);
162  delete static_cast<QWaylandSelection *>(data);
163 }
164 
166  : mDisplay(display), mMimeDataIn(0), mOffer(0)
167 {
168  clipboard = this;
169 }
170 
172 {
173  if (mOffer)
174  wl_selection_offer_destroy(mOffer);
175  delete mMimeDataIn;
177 }
178 
180 {
181  mSelections.removeOne(selection);
182 }
183 
185 {
186  *static_cast<bool *>(data) = true;
187 }
188 
190 {
191  bool done = false;
192  wl_display_sync_callback(display, syncCallback, &done);
193  wl_display_iterate(display, WL_DISPLAY_WRITABLE);
194  while (!done)
195  wl_display_iterate(display, WL_DISPLAY_READABLE);
196 }
197 
199 {
200  Q_UNUSED(type);
201  if (mOfferedMimeTypes.isEmpty() || !mOffer)
202  return QVariant();
203  int pipefd[2];
204  if (pipe(pipefd) == -1) {
205  qWarning("QWaylandClipboard: pipe() failed");
206  return QVariant();
207  }
208  QByteArray mimeTypeBa = mimeType.toLatin1();
209  wl_selection_offer_receive(mOffer, mimeTypeBa.constData(), pipefd[1]);
210  QByteArray content;
212  char buf[256];
213  int n;
214  close(pipefd[1]);
215  while ((n = read(pipefd[0], &buf, sizeof buf)) > 0)
216  content.append(buf, n);
217  close(pipefd[0]);
218  return content;
219 }
220 
222 {
224  if (!mSelections.isEmpty())
225  return mSelections.last()->mMimeData;
226  if (!mMimeDataIn)
229  if (!mOfferedMimeTypes.isEmpty() && mOffer)
231  return mMimeDataIn;
232 }
233 
235 {
237  if (!mDisplay->inputDevices().isEmpty()) {
238  if (!data)
239  data = new QMimeData;
241  } else {
242  qWarning("QWaylandClipboard::setMimeData: No input devices");
243  }
244 }
245 
247 {
248  return mode == QClipboard::Clipboard;
249 }
250 
251 const struct wl_selection_offer_listener QWaylandClipboard::selectionOfferListener = {
254 };
255 
257 {
259  if (mOffer)
260  wl_selection_offer_destroy(mOffer);
261  mOffer = 0;
262  struct wl_selection_offer *offer = wl_selection_offer_create(mDisplay->wl_display(), id, 1);
263  wl_selection_offer_add_listener(offer, &selectionOfferListener, this);
264 }
265 
267  struct wl_selection_offer *selection_offer,
268  const char *type)
269 {
270  Q_UNUSED(data);
271  Q_UNUSED(selection_offer);
272  clipboard->mOfferedMimeTypes.append(QString::fromLatin1(type));
273 }
274 
276  struct wl_selection_offer *selection_offer,
277  wl_input_device *input_device)
278 {
279  Q_UNUSED(data);
280  if (!input_device) {
281  wl_selection_offer_destroy(selection_offer);
282  clipboard->mOffer = 0;
283  return;
284  }
285  clipboard->mOffer = selection_offer;
286  if (clipboard->mSelections.isEmpty())
287  QMetaObject::invokeMethod(&clipboard->mEmitter, "emitChanged", Qt::QueuedConnection);
288 }
289 
291 {
293 }
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
static void send(void *data, struct wl_selection *selection, const char *mime_type, int fd)
Mode
This enum type is used to control which part of the system clipboard is used by QClipboard::mimeData(...
Definition: qclipboard.h:71
static QWaylandClipboard * clipboard
QWaylandDisplay * mDisplay
void createSelectionOffer(uint32_t id)
int type
Definition: qmetatype.cpp:239
void clear()
Removes all the MIME type and data entries in the object.
Definition: qmimedata.cpp:613
virtual QStringList formats() const
Returns a list of formats supported by the object.
Definition: qmimedata.cpp:579
char * data()
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:429
struct wl_input_device * wl_input_device() const
bool open(OpenMode flags)
Opens the file using OpenMode mode, returning true if successful; otherwise false.
Definition: qfile.cpp:1064
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
QWaylandClipboardSignalEmitter mEmitter
QStringList formats_sys() const
QByteArray data(const QString &mimetype) const
Returns the data stored in the object in the format described by the MIME type specified by mimeType...
Definition: qmimedata.cpp:524
QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type) const
The QString class provides a Unicode character string.
Definition: qstring.h:83
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QVariant retrieveData(const QString &mimeType, QVariant::Type type) const
static void forceRoundtrip(struct wl_display *display)
QWaylandMimeData * mMimeDataIn
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
bool removeOne(const T &t)
Removes the first occurrence of value in the list and returns true on success; otherwise returns fals...
Definition: qlist.h:796
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
void setFormats(const QStringList &formatList)
Q_GUI_EXPORT EGLDisplay display()
Definition: qegl.cpp:589
QList< QWaylandSelection * > mSelections
static void cancelled(void *data, struct wl_selection *selection)
void unregisterSelection(QWaylandSelection *selection)
static uint32_t getTime()
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
QStringList mOfferedMimeTypes
QStringList formats() const
Returns a list of formats supported by the object.
Definition: qdnd.cpp:351
Q_CORE_EXPORT void qWarning(const char *,...)
static const char * data(const QByteArray &arr)
Type
This enum type defines the types of variable that a QVariant can contain.
Definition: qvariant.h:95
bool hasFormat_sys(const QString &mimeType) const
QBool contains(const QString &str, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the list contains the string str; otherwise returns false.
Definition: qstringlist.h:172
QByteArray toLatin1() const Q_REQUIRED_RESULT
Returns a Latin-1 representation of the string as a QByteArray.
Definition: qstring.cpp:3993
void clear()
Removes all items from the list.
Definition: qlist.h:764
The QMimeData class provides a container for data that records information about its MIME type...
Definition: qmimedata.h:57
void emitChanged(QClipboard::Mode mode)
static void offer(void *data, struct wl_selection_offer *selection_offer, const char *type)
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
static const struct wl_selection_offer_listener selectionOfferListener
static void syncCallback(void *data)
static const struct wl_selection_listener selectionListener
struct wl_shell * wl_shell() const
The QFile class provides an interface for reading from and writing to files.
Definition: qfile.h:65
bool supportsMode(QClipboard::Mode mode) const
struct wl_selection_offer * mOffer
void setMimeData(QMimeData *data, QClipboard::Mode mode=QClipboard::Clipboard)
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
T & last()
Returns a reference to the last item in the list.
Definition: qlist.h:284
QWaylandSelection(QWaylandDisplay *display, QMimeData *data)
QWaylandClipboard(QWaylandDisplay *display)
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(0), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
Invokes the member (a signal or a slot name) on the object obj.
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421
struct wl_selection * mSelection
qint64 write(const char *data, qint64 len)
Writes at most maxSize bytes of data from data to the device.
Definition: qiodevice.cpp:1342
static void keyboardFocus(void *data, struct wl_selection_offer *selection_offer, struct wl_input_device *input_device)
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
Q_OUTOFLINE_TEMPLATE void qDeleteAll(ForwardIterator begin, ForwardIterator end)
Definition: qalgorithms.h:319
QList< QWaylandInputDevice * > inputDevices() const
QMimeData * mimeData(QClipboard::Mode mode=QClipboard::Clipboard)
struct wl_display * wl_display() const