Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qxcbmime.cpp
Go to the documentation of this file.
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 "qxcbmime.h"
5
6#include <QtGui/QImageWriter>
7#include <QtCore/QBuffer>
8#include <qdebug.h>
9
11
12using namespace Qt::StringLiterals;
13
17
20
21
22
24{
25 if (a == XCB_NONE)
26 return QString();
27
28 // special cases for string type
29 if (a == XCB_ATOM_STRING
31 || a == connection->atom(QXcbAtom::AtomTEXT))
32 return "text/plain"_L1;
33
34 // special case for images
35 if (a == XCB_ATOM_PIXMAP)
36 return "image/ppm"_L1;
37
38 QByteArray atomName = connection->atomName(a);
39
40 // special cases for uris
41 if (atomName == "text/x-moz-url")
42 atomName = "text/uri-list";
43
44 return QString::fromLatin1(atomName.constData());
45}
46
48 xcb_atom_t *atomFormat, int *dataFormat)
49{
50 if (!data)
51 return false;
52
53 bool ret = false;
54 *atomFormat = a;
55 *dataFormat = 8;
56
58 || a == XCB_ATOM_STRING
59 || a == connection->atom(QXcbAtom::AtomTEXT))
60 && QInternalMimeData::hasFormatHelper("text/plain"_L1, mimeData)) {
63 ret = true;
64 } else if (a == XCB_ATOM_STRING ||
66 // ICCCM says STRING is latin1
68 "text/plain"_L1, mimeData)).toLatin1();
69 ret = true;
70 }
71 return ret;
72 }
73
77 // mimeAtomToString() converts "text/x-moz-url" to "text/uri-list",
78 // so QXcbConnection::atomName() has to be used.
79 if (atomName == "text/uri-list"_L1
80 && connection->atomName(a) == "text/x-moz-url") {
81 const QString mozUri = QLatin1StringView(data->split('\n').constFirst()) + u'\n';
82 data->assign({reinterpret_cast<const char *>(mozUri.data()), mozUri.size() * 2});
83 } else if (atomName == "application/x-color"_L1)
84 *dataFormat = 16;
85 ret = true;
86 } else if ((a == XCB_ATOM_PIXMAP || a == XCB_ATOM_BITMAP) && mimeData->hasImage()) {
87 ret = true;
88 } else if (atomName == "text/plain"_L1 && mimeData->hasFormat("text/uri-list"_L1)) {
89 // Return URLs also as plain text.
91 ret = true;
92 }
93 return ret;
94}
95
97{
98 QList<xcb_atom_t> atoms;
99 atoms.reserve(7);
100 atoms.append(connection->internAtom(format.toLatin1()));
101
102 // special cases for strings
103 if (format == "text/plain"_L1) {
104 atoms.append(connection->atom(QXcbAtom::AtomUTF8_STRING));
105 atoms.append(XCB_ATOM_STRING);
106 atoms.append(connection->atom(QXcbAtom::AtomTEXT));
107 }
108
109 // special cases for uris
110 if (format == "text/uri-list"_L1) {
111 atoms.append(connection->internAtom("text/x-moz-url"));
112 atoms.append(connection->internAtom("text/plain"));
113 }
114
115 //special cases for images
116 if (format == "image/ppm"_L1)
117 atoms.append(XCB_ATOM_PIXMAP);
118 if (format == "image/pbm"_L1)
119 atoms.append(XCB_ATOM_BITMAP);
120
121 return atoms;
122}
123
125 QMetaType requestedType, bool hasUtf8)
126{
127 QByteArray data = d;
129// qDebug() << "mimeConvertDataToFormat" << format << atomName << data;
130
131 if (hasUtf8 && atomName == format + ";charset=utf-8"_L1) {
132 if (requestedType.id() == QMetaType::QString)
133 return QString::fromUtf8(data);
134 return data;
135 }
136
137 // special cases for string types
138 if (format == "text/plain"_L1) {
139 if (data.endsWith('\0'))
140 data.chop(1);
141 if (a == connection->atom(QXcbAtom::AtomUTF8_STRING)) {
142 return QString::fromUtf8(data);
143 }
144 if (a == XCB_ATOM_STRING ||
147 }
148 // If data contains UTF16 text, convert it to a string.
149 // Firefox uses UTF16 without BOM for text/x-moz-url, "text/html",
150 // Google Chrome uses UTF16 without BOM for "text/x-moz-url",
151 // UTF16 with BOM for "text/html".
152 if ((format == "text/html"_L1 || format == "text/uri-list"_L1)
153 && data.size() > 1) {
154 const quint8 byte0 = data.at(0);
155 const quint8 byte1 = data.at(1);
156 if ((byte0 == 0xff && byte1 == 0xfe) || (byte0 == 0xfe && byte1 == 0xff)
157 || (byte0 != 0 && byte1 == 0) || (byte0 == 0 && byte1 != 0)) {
158 const QStringView str(
159 reinterpret_cast<const char16_t *>(data.constData()), data.size() / 2);
160 if (!str.isNull()) {
161 if (format == "text/uri-list"_L1) {
162 const auto urls = QStringView{str}.split(u'\n');
163 QList<QVariant> list;
165 for (const QStringView &s : urls) {
166 const QUrl url(s.trimmed().toString());
167 if (url.isValid())
168 list.append(url);
169 }
170 // We expect "text/x-moz-url" as <url><space><title>.
171 // The atomName variable is not used because mimeAtomToString()
172 // converts "text/x-moz-url" to "text/uri-list".
173 if (!list.isEmpty() && connection->atomName(a) == "text/x-moz-url")
174 return list.constFirst();
175 return list;
176 } else {
177 return str.toString();
178 }
179 }
180 }
181 // 8 byte encoding, remove a possible 0 at the end
182 if (data.endsWith('\0'))
183 data.chop(1);
184 }
185
186 if (atomName == format)
187 return data;
188
189#if 0 // ###
190 // special case for images
191 if (format == "image/ppm"_L1) {
192 if (a == XCB_ATOM_PIXMAP && data.size() == sizeof(Pixmap)) {
193 Pixmap xpm = *((Pixmap*)data.data());
194 if (!xpm)
195 return QByteArray();
196 Window root;
197 int x;
198 int y;
199 uint width;
200 uint height;
201 uint border_width;
202 uint depth;
203
204 XGetGeometry(display, xpm, &root, &x, &y, &width, &height, &border_width, &depth);
205 XImage *ximg = XGetImage(display,xpm,x,y,width,height,AllPlanes,depth==1 ? XYPixmap : ZPixmap);
206 QImage qimg = QXlibStatic::qimageFromXImage(ximg);
207 XDestroyImage(ximg);
208
209 QImageWriter imageWriter;
210 imageWriter.setFormat("PPMRAW");
211 QBuffer buf;
213 imageWriter.setDevice(&buf);
214 imageWriter.write(qimg);
215 return buf.buffer();
216 }
217 }
218#endif
219 return QVariant();
220}
221
223 const QList<xcb_atom_t> &atoms, bool *hasUtf8)
224{
225 *hasUtf8 = false;
226
227 // find matches for string types
228 if (format == "text/plain"_L1) {
229 if (atoms.contains(connection->atom(QXcbAtom::AtomUTF8_STRING)))
231 if (atoms.contains(XCB_ATOM_STRING))
232 return XCB_ATOM_STRING;
233 if (atoms.contains(connection->atom(QXcbAtom::AtomTEXT)))
234 return connection->atom(QXcbAtom::AtomTEXT);
235 }
236
237 // find matches for uri types
238 if (format == "text/uri-list"_L1) {
239 xcb_atom_t a = connection->internAtom(format.toLatin1());
240 if (a && atoms.contains(a))
241 return a;
242 a = connection->internAtom("text/x-moz-url");
243 if (a && atoms.contains(a))
244 return a;
245 }
246
247 // find match for image
248 if (format == "image/ppm"_L1) {
249 if (atoms.contains(XCB_ATOM_PIXMAP))
250 return XCB_ATOM_PIXMAP;
251 }
252
253 // for string/text requests try to use a format with a well-defined charset
254 // first to avoid encoding problems
255 if (requestedType.id() == QMetaType::QString
256 && format.startsWith("text/"_L1)
257 && !format.contains("charset="_L1)) {
258
259 QString formatWithCharset = format;
260 formatWithCharset.append(";charset=utf-8"_L1);
261
262 xcb_atom_t a = connection->internAtom(std::move(formatWithCharset).toLatin1());
263 if (a && atoms.contains(a)) {
264 *hasUtf8 = true;
265 return a;
266 }
267 }
268
269 xcb_atom_t a = connection->internAtom(format.toLatin1());
270 if (a && atoms.contains(a))
271 return a;
272
273 return 0;
274}
275
277
278#include "moc_qxcbmime.cpp"
\inmodule QtCore \reentrant
Definition qbuffer.h:16
\inmodule QtCore
Definition qbytearray.h:57
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:124
The QImageWriter class provides a format independent interface for writing images to files or other d...
void setFormat(const QByteArray &format)
Sets the format QImageWriter will use when writing images, to format.
\inmodule QtGui
Definition qimage.h:37
static bool hasFormatHelper(const QString &mimeType, const QMimeData *data)
static QByteArray renderDataHelper(const QString &mimeType, const QMimeData *data)
qsizetype size() const noexcept
Definition qlist.h:397
bool isEmpty() const noexcept
Definition qlist.h:401
const T & constFirst() const noexcept
Definition qlist.h:647
void reserve(qsizetype size)
Definition qlist.h:753
void append(parameter_type t)
Definition qlist.h:458
\inmodule QtCore
Definition qmetatype.h:341
\inmodule QtCore
Definition qmimedata.h:16
bool hasImage() const
Returns true if the object can return an image; otherwise returns false.
virtual bool hasFormat(const QString &mimetype) const
Returns true if the object can return data for the MIME type specified by mimeType; otherwise returns...
QList< QUrl > urls() const
Returns a list of URLs contained within the MIME data object.
\inmodule QtCore
Definition qstringview.h:78
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
void chop(qsizetype n)
Removes n characters from the end of the string.
Definition qstring.cpp:6340
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5871
QStringList split(const QString &sep, Qt::SplitBehavior behavior=Qt::KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Splits the string into substrings wherever sep occurs, and returns the list of those strings.
Definition qstring.cpp:8218
bool isNull() const
Returns true if this string is null; otherwise returns false.
Definition qstring.h:994
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:6018
QString & append(QChar c)
Definition qstring.cpp:3252
\inmodule QtCore
Definition qurl.h:94
bool isValid() const
Returns true if the URL is non-empty and valid; otherwise returns false.
Definition qurl.cpp:1882
\inmodule QtCore
Definition qvariant.h:65
@ AtomUTF8_STRING
Definition qxcbatom.h:133
static QVariant mimeConvertToFormat(QXcbConnection *connection, xcb_atom_t a, const QByteArray &data, const QString &format, QMetaType requestedType, bool hasUtf8)
Definition qxcbmime.cpp:124
static QList< xcb_atom_t > mimeAtomsForFormat(QXcbConnection *connection, const QString &format)
Definition qxcbmime.cpp:96
static xcb_atom_t mimeAtomForFormat(QXcbConnection *connection, const QString &format, QMetaType requestedType, const QList< xcb_atom_t > &atoms, bool *hasUtf8)
Definition qxcbmime.cpp:222
static bool mimeDataForAtom(QXcbConnection *connection, xcb_atom_t a, QMimeData *mimeData, QByteArray *data, xcb_atom_t *atomFormat, int *dataFormat)
Definition qxcbmime.cpp:47
static QString mimeAtomToString(QXcbConnection *connection, xcb_atom_t a)
Definition qxcbmime.cpp:23
QString str
[2]
struct wl_display * display
Definition linuxdmabuf.h:41
Combined button and popup list for selecting options.
DBusConnection * connection
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
return ret
GLint GLint GLint GLint GLint x
[0]
GLint GLenum GLsizei GLsizei GLsizei depth
GLint GLsizei GLsizei height
GLboolean GLboolean GLboolean GLboolean a
[7]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint GLsizei width
GLenum GLuint GLenum GLsizei const GLchar * buf
GLint GLsizei GLsizei GLenum format
GLint y
GLdouble s
[6]
Definition qopenglext.h:235
XID Pixmap
unsigned int uint
Definition qtypes.h:34
unsigned char quint8
Definition qtypes.h:46
QList< int > list
[14]
QUrl url("example.com")
[constructor-url-reference]
QMimeData * mimeData