Qt 6.x
The Qt SDK
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
16{ }
17
19{}
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 = QByteArray(reinterpret_cast<const char *>(mozUri.data()),
83 mozUri.size() * 2);
84 } else if (atomName == "application/x-color"_L1)
85 *dataFormat = 16;
86 ret = true;
87 } else if ((a == XCB_ATOM_PIXMAP || a == XCB_ATOM_BITMAP) && mimeData->hasImage()) {
88 ret = true;
89 } else if (atomName == "text/plain"_L1 && mimeData->hasFormat("text/uri-list"_L1)) {
90 // Return URLs also as plain text.
92 ret = true;
93 }
94 return ret;
95}
96
98{
100 atoms.reserve(7);
101 atoms.append(connection->internAtom(format.toLatin1()));
102
103 // special cases for strings
104 if (format == "text/plain"_L1) {
106 atoms.append(XCB_ATOM_STRING);
108 }
109
110 // special cases for uris
111 if (format == "text/uri-list"_L1) {
112 atoms.append(connection->internAtom("text/x-moz-url"));
113 atoms.append(connection->internAtom("text/plain"));
114 }
115
116 //special cases for images
117 if (format == "image/ppm"_L1)
118 atoms.append(XCB_ATOM_PIXMAP);
119 if (format == "image/pbm"_L1)
120 atoms.append(XCB_ATOM_BITMAP);
121
122 return atoms;
123}
124
126 QMetaType requestedType, bool hasUtf8)
127{
128 QByteArray data = d;
130// qDebug() << "mimeConvertDataToFormat" << format << atomName << data;
131
132 if (hasUtf8 && atomName == format + ";charset=utf-8"_L1) {
133 if (requestedType.id() == QMetaType::QString)
134 return QString::fromUtf8(data);
135 return data;
136 }
137
138 // special cases for string types
139 if (format == "text/plain"_L1) {
140 if (data.endsWith('\0'))
141 data.chop(1);
142 if (a == connection->atom(QXcbAtom::AtomUTF8_STRING)) {
143 return QString::fromUtf8(data);
144 }
145 if (a == XCB_ATOM_STRING ||
148 }
149 // If data contains UTF16 text, convert it to a string.
150 // Firefox uses UTF16 without BOM for text/x-moz-url, "text/html",
151 // Google Chrome uses UTF16 without BOM for "text/x-moz-url",
152 // UTF16 with BOM for "text/html".
153 if ((format == "text/html"_L1 || format == "text/uri-list"_L1)
154 && data.size() > 1) {
155 const quint8 byte0 = data.at(0);
156 const quint8 byte1 = data.at(1);
157 if ((byte0 == 0xff && byte1 == 0xfe) || (byte0 == 0xfe && byte1 == 0xff)
158 || (byte0 != 0 && byte1 == 0) || (byte0 == 0 && byte1 != 0)) {
160 reinterpret_cast<const char16_t *>(data.constData()), data.size() / 2);
161 if (!str.isNull()) {
162 if (format == "text/uri-list"_L1) {
163 const auto urls = QStringView{str}.split(u'\n');
166 for (const QStringView &s : urls) {
167 const QUrl url(s.trimmed().toString());
168 if (url.isValid())
169 list.append(url);
170 }
171 // We expect "text/x-moz-url" as <url><space><title>.
172 // The atomName variable is not used because mimeAtomToString()
173 // converts "text/x-moz-url" to "text/uri-list".
174 if (!list.isEmpty() && connection->atomName(a) == "text/x-moz-url")
175 return list.constFirst();
176 return list;
177 } else {
178 return str;
179 }
180 }
181 }
182 // 8 byte encoding, remove a possible 0 at the end
183 if (data.endsWith('\0'))
184 data.chop(1);
185 }
186
187 if (atomName == format)
188 return data;
189
190#if 0 // ###
191 // special case for images
192 if (format == "image/ppm"_L1) {
193 if (a == XCB_ATOM_PIXMAP && data.size() == sizeof(Pixmap)) {
194 Pixmap xpm = *((Pixmap*)data.data());
195 if (!xpm)
196 return QByteArray();
197 Window root;
198 int x;
199 int y;
200 uint width;
201 uint height;
202 uint border_width;
203 uint depth;
204
205 XGetGeometry(display, xpm, &root, &x, &y, &width, &height, &border_width, &depth);
206 XImage *ximg = XGetImage(display,xpm,x,y,width,height,AllPlanes,depth==1 ? XYPixmap : ZPixmap);
207 QImage qimg = QXlibStatic::qimageFromXImage(ximg);
208 XDestroyImage(ximg);
209
210 QImageWriter imageWriter;
211 imageWriter.setFormat("PPMRAW");
212 QBuffer buf;
214 imageWriter.setDevice(&buf);
215 imageWriter.write(qimg);
216 return buf.buffer();
217 }
218 }
219#endif
220 return QVariant();
221}
222
224 const QList<xcb_atom_t> &atoms, bool *hasUtf8)
225{
226 *hasUtf8 = false;
227
228 // find matches for string types
229 if (format == "text/plain"_L1) {
232 if (atoms.contains(XCB_ATOM_STRING))
233 return XCB_ATOM_STRING;
234 if (atoms.contains(connection->atom(QXcbAtom::AtomTEXT)))
235 return connection->atom(QXcbAtom::AtomTEXT);
236 }
237
238 // find matches for uri types
239 if (format == "text/uri-list"_L1) {
240 xcb_atom_t a = connection->internAtom(format.toLatin1());
241 if (a && atoms.contains(a))
242 return a;
243 a = connection->internAtom("text/x-moz-url");
244 if (a && atoms.contains(a))
245 return a;
246 }
247
248 // find match for image
249 if (format == "image/ppm"_L1) {
250 if (atoms.contains(XCB_ATOM_PIXMAP))
251 return XCB_ATOM_PIXMAP;
252 }
253
254 // for string/text requests try to use a format with a well-defined charset
255 // first to avoid encoding problems
256 if (requestedType.id() == QMetaType::QString
257 && format.startsWith("text/"_L1)
258 && !format.contains("charset="_L1)) {
259
260 QString formatWithCharset = format;
261 formatWithCharset.append(";charset=utf-8"_L1);
262
263 xcb_atom_t a = connection->internAtom(std::move(formatWithCharset).toLatin1());
264 if (a && atoms.contains(a)) {
265 *hasUtf8 = true;
266 return a;
267 }
268 }
269
270 xcb_atom_t a = connection->internAtom(format.toLatin1());
271 if (a && atoms.contains(a))
272 return a;
273
274 return 0;
275}
276
278
279#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:122
The QImageWriter class provides a format independent interface for writing images to files or other d...
void setDevice(QIODevice *device)
Sets QImageWriter's device to device.
bool write(const QImage &image)
Writes the image image to the assigned device or file name.
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)
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
bool isEmpty() const noexcept
Definition qlist.h:390
const T & constFirst() const noexcept
Definition qlist.h:630
void reserve(qsizetype size)
Definition qlist.h:746
void append(parameter_type t)
Definition qlist.h:441
\inmodule QtCore
Definition qmetatype.h:320
int id(int=0) const
Definition qmetatype.h:454
\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:76
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
QByteArray toLatin1() const &
Definition qstring.h:559
void chop(qsizetype n)
Removes n characters from the end of the string.
Definition qstring.cpp:6180
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5710
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:7956
static QString fromUtf16(const char16_t *, qsizetype size=-1)
Definition qstring.cpp:5883
bool isNull() const
Returns true if this string is null; otherwise returns false.
Definition qstring.h:898
qsizetype size() const
Returns the number of characters in this string.
Definition qstring.h:182
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5857
QChar * data()
Returns a pointer to the data stored in the QString.
Definition qstring.h:1095
QString & append(QChar c)
Definition qstring.cpp:3227
\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:1874
\inmodule QtCore
Definition qvariant.h:64
@ AtomUTF8_STRING
Definition qxcbatom.h:132
static QVariant mimeConvertToFormat(QXcbConnection *connection, xcb_atom_t a, const QByteArray &data, const QString &format, QMetaType requestedType, bool hasUtf8)
Definition qxcbmime.cpp:125
static QList< xcb_atom_t > mimeAtomsForFormat(QXcbConnection *connection, const QString &format)
Definition qxcbmime.cpp:97
static xcb_atom_t mimeAtomForFormat(QXcbConnection *connection, const QString &format, QMetaType requestedType, const QList< xcb_atom_t > &atoms, bool *hasUtf8)
Definition qxcbmime.cpp:223
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
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 width
GLenum GLuint GLenum GLsizei const GLchar * buf
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint GLsizei GLsizei GLenum format
GLint y
GLdouble s
[6]
Definition qopenglext.h:235
XID Pixmap
unsigned int uint
Definition qtypes.h:29
unsigned char quint8
Definition qtypes.h:41
XID Window
QList< int > list
[14]
QUrl url("example.com")
[constructor-url-reference]
QMimeData * mimeData
bool contains(const AT &t) const noexcept
Definition qlist.h:44