1 /****************************************************************************
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
6 ** This file is part of the plugins of the Qt Toolkit.
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.
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.
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.
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.
40 ****************************************************************************/
44 #include <QtCore/QTextCodec>
45 #include <QtGui/QImageWriter>
46 #include <QtCore/QBuffer>
49 #include <X11/Xutil.h>
51 #undef XCB_ATOM_STRING
52 #undef XCB_ATOM_PIXMAP
53 #undef XCB_ATOM_BITMAP
57 #if !(defined(QT_NO_DRAGANDDROP) && defined(QT_NO_CLIPBOARD))
68 QString QXcbMime::mimeAtomToString(QXcbConnection *connection, xcb_atom_t a)
73 // special cases for string type
74 if (a == XCB_ATOM_STRING
75 || a == connection->atom(QXcbAtom::UTF8_STRING)
76 || a == connection->atom(QXcbAtom::TEXT))
77 return QLatin1String("text/plain");
79 // special case for images
80 if (a == XCB_ATOM_PIXMAP)
81 return QLatin1String("image/ppm");
83 QByteArray atomName = connection->atomName(a);
85 // special cases for uris
86 if (atomName == "text/x-moz-url")
87 atomName = "text/uri-list";
89 return QString::fromLatin1(atomName.constData());
92 bool QXcbMime::mimeDataForAtom(QXcbConnection *connection, xcb_atom_t a, QMimeData *mimeData, QByteArray *data,
93 xcb_atom_t *atomFormat, int *dataFormat)
102 if ((a == connection->atom(QXcbAtom::UTF8_STRING)
103 || a == XCB_ATOM_STRING
104 || a == connection->atom(QXcbAtom::TEXT))
105 && QInternalMimeData::hasFormatHelper(QLatin1String("text/plain"), mimeData)) {
106 if (a == connection->atom(QXcbAtom::UTF8_STRING)) {
107 *data = QInternalMimeData::renderDataHelper(QLatin1String("text/plain"), mimeData);
109 } else if (a == XCB_ATOM_STRING ||
110 a == connection->atom(QXcbAtom::TEXT)) {
111 // ICCCM says STRING is latin1
112 *data = QString::fromUtf8(QInternalMimeData::renderDataHelper(
113 QLatin1String("text/plain"), mimeData)).toLatin1();
119 QString atomName = mimeAtomToString(connection, a);
120 if (QInternalMimeData::hasFormatHelper(atomName, mimeData)) {
121 *data = QInternalMimeData::renderDataHelper(atomName, mimeData);
122 if (atomName == QLatin1String("application/x-color"))
125 } else if (atomName == QLatin1String("text/x-moz-url") &&
126 QInternalMimeData::hasFormatHelper(QLatin1String("text/uri-list"), mimeData)) {
127 QByteArray uri = QInternalMimeData::renderDataHelper(
128 QLatin1String("text/uri-list"), mimeData).split('\n').first();
129 QString mozUri = QString::fromLatin1(uri, uri.size());
130 mozUri += QLatin1Char('\n');
131 *data = QByteArray(reinterpret_cast<const char *>(mozUri.utf16()), mozUri.length() * 2);
133 } else if ((a == XCB_ATOM_PIXMAP || a == XCB_ATOM_BITMAP) && mimeData->hasImage()) {
139 QList<xcb_atom_t> QXcbMime::mimeAtomsForFormat(QXcbConnection *connection, const QString &format)
141 QList<xcb_atom_t> atoms;
142 atoms.append(connection->internAtom(format.toLatin1()));
144 // special cases for strings
145 if (format == QLatin1String("text/plain")) {
146 atoms.append(connection->atom(QXcbAtom::UTF8_STRING));
147 atoms.append(XCB_ATOM_STRING);
148 atoms.append(connection->atom(QXcbAtom::TEXT));
151 // special cases for uris
152 if (format == QLatin1String("text/uri-list"))
153 atoms.append(connection->internAtom("text/x-moz-url"));
155 //special cases for images
156 if (format == QLatin1String("image/ppm"))
157 atoms.append(XCB_ATOM_PIXMAP);
158 if (format == QLatin1String("image/pbm"))
159 atoms.append(XCB_ATOM_BITMAP);
164 QVariant QXcbMime::mimeConvertToFormat(QXcbConnection *connection, xcb_atom_t a, const QByteArray &data, const QString &format,
165 QVariant::Type requestedType, const QByteArray &encoding)
167 QString atomName = mimeAtomToString(connection, a);
168 // qDebug() << "mimeConvertDataToFormat" << format << atomName << data;
170 if (!encoding.isEmpty()
171 && atomName == format + QLatin1String(";charset=") + QString::fromLatin1(encoding)) {
173 if (requestedType == QVariant::String) {
174 QTextCodec *codec = QTextCodec::codecForName(encoding);
176 return codec->toUnicode(data);
182 // special cases for string types
183 if (format == QLatin1String("text/plain")) {
184 if (a == connection->atom(QXcbAtom::UTF8_STRING))
185 return QString::fromUtf8(data);
186 if (a == XCB_ATOM_STRING ||
187 a == connection->atom(QXcbAtom::TEXT))
188 return QString::fromLatin1(data);
191 // special case for uri types
192 if (format == QLatin1String("text/uri-list")) {
193 if (atomName == QLatin1String("text/x-moz-url")) {
194 // we expect this as utf16 <url><space><title>
195 // the first part is a url that should only contain ascci char
196 // so it should be safe to check that the second char is 0
197 // to verify that it is utf16
198 if (data.size() > 1 && data.at(1) == 0)
199 return QString::fromRawData((const QChar *)data.constData(),
200 data.size() / 2).split(QLatin1Char('\n')).first().toLatin1();
204 if (atomName == format)
208 // special case for images
209 if (format == QLatin1String("image/ppm")) {
210 if (a == XCB_ATOM_PIXMAP && data.size() == sizeof(Pixmap)) {
211 Pixmap xpm = *((Pixmap*)data.data());
222 XGetGeometry(display, xpm, &root, &x, &y, &width, &height, &border_width, &depth);
223 XImage *ximg = XGetImage(display,xpm,x,y,width,height,AllPlanes,depth==1 ? XYPixmap : ZPixmap);
224 QImage qimg = QXlibStatic::qimageFromXImage(ximg);
227 QImageWriter imageWriter;
228 imageWriter.setFormat("PPMRAW");
230 buf.open(QIODevice::WriteOnly);
231 imageWriter.setDevice(&buf);
232 imageWriter.write(qimg);
240 xcb_atom_t QXcbMime::mimeAtomForFormat(QXcbConnection *connection, const QString &format, QVariant::Type requestedType,
241 const QList<xcb_atom_t> &atoms, QByteArray *requestedEncoding)
243 requestedEncoding->clear();
245 // find matches for string types
246 if (format == QLatin1String("text/plain")) {
247 if (atoms.contains(connection->atom(QXcbAtom::UTF8_STRING)))
248 return connection->atom(QXcbAtom::UTF8_STRING);
249 if (atoms.contains(XCB_ATOM_STRING))
250 return XCB_ATOM_STRING;
251 if (atoms.contains(connection->atom(QXcbAtom::TEXT)))
252 return connection->atom(QXcbAtom::TEXT);
255 // find matches for uri types
256 if (format == QLatin1String("text/uri-list")) {
257 xcb_atom_t a = connection->internAtom(format.toLatin1());
258 if (a && atoms.contains(a))
260 a = connection->internAtom("text/x-moz-url");
261 if (a && atoms.contains(a))
265 // find match for image
266 if (format == QLatin1String("image/ppm")) {
267 if (atoms.contains(XCB_ATOM_PIXMAP))
268 return XCB_ATOM_PIXMAP;
271 // for string/text requests try to use a format with a well-defined charset
272 // first to avoid encoding problems
273 if (requestedType == QVariant::String
274 && format.startsWith(QLatin1String("text/"))
275 && !format.contains(QLatin1String("charset="))) {
277 QString formatWithCharset = format;
278 formatWithCharset.append(QLatin1String(";charset=utf-8"));
280 xcb_atom_t a = connection->internAtom(formatWithCharset.toLatin1());
281 if (a && atoms.contains(a)) {
282 *requestedEncoding = "utf-8";
287 xcb_atom_t a = connection->internAtom(format.toLatin1());
288 if (a && atoms.contains(a))
294 #endif // !(defined(QT_NO_DRAGANDDROP) && defined(QT_NO_CLIPBOARD))