1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the plugins of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
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
66 QString QXcbMime::mimeAtomToString(QXcbConnection *connection, xcb_atom_t a)
71 // special cases for string type
72 if (a == XCB_ATOM_STRING
73 || a == connection->atom(QXcbAtom::UTF8_STRING)
74 || a == connection->atom(QXcbAtom::TEXT))
75 return QLatin1String("text/plain");
77 // special case for images
78 if (a == XCB_ATOM_PIXMAP)
79 return QLatin1String("image/ppm");
81 QByteArray atomName = connection->atomName(a);
83 // special cases for uris
84 if (atomName == "text/x-moz-url")
85 atomName = "text/uri-list";
87 return QString::fromLatin1(atomName.constData());
90 bool QXcbMime::mimeDataForAtom(QXcbConnection *connection, xcb_atom_t a, QMimeData *mimeData, QByteArray *data,
91 xcb_atom_t *atomFormat, int *dataFormat)
100 if ((a == connection->atom(QXcbAtom::UTF8_STRING)
101 || a == XCB_ATOM_STRING
102 || a == connection->atom(QXcbAtom::TEXT))
103 && QInternalMimeData::hasFormatHelper(QLatin1String("text/plain"), mimeData)) {
104 if (a == connection->atom(QXcbAtom::UTF8_STRING)) {
105 *data = QInternalMimeData::renderDataHelper(QLatin1String("text/plain"), mimeData);
107 } else if (a == XCB_ATOM_STRING ||
108 a == connection->atom(QXcbAtom::TEXT)) {
109 // ICCCM says STRING is latin1
110 *data = QString::fromUtf8(QInternalMimeData::renderDataHelper(
111 QLatin1String("text/plain"), mimeData)).toLatin1();
117 QString atomName = mimeAtomToString(connection, a);
118 if (QInternalMimeData::hasFormatHelper(atomName, mimeData)) {
119 *data = QInternalMimeData::renderDataHelper(atomName, mimeData);
120 if (atomName == QLatin1String("application/x-color"))
123 } else if (atomName == QLatin1String("text/x-moz-url") &&
124 QInternalMimeData::hasFormatHelper(QLatin1String("text/uri-list"), mimeData)) {
125 QByteArray uri = QInternalMimeData::renderDataHelper(
126 QLatin1String("text/uri-list"), mimeData).split('\n').first();
127 QString mozUri = QString::fromLatin1(uri, uri.size());
128 mozUri += QLatin1Char('\n');
129 *data = QByteArray(reinterpret_cast<const char *>(mozUri.utf16()), mozUri.length() * 2);
131 } else if ((a == XCB_ATOM_PIXMAP || a == XCB_ATOM_BITMAP) && mimeData->hasImage()) {
137 QList<xcb_atom_t> QXcbMime::mimeAtomsForFormat(QXcbConnection *connection, const QString &format)
139 QList<xcb_atom_t> atoms;
140 atoms.append(connection->internAtom(format.toLatin1()));
142 // special cases for strings
143 if (format == QLatin1String("text/plain")) {
144 atoms.append(connection->atom(QXcbAtom::UTF8_STRING));
145 atoms.append(XCB_ATOM_STRING);
146 atoms.append(connection->atom(QXcbAtom::TEXT));
149 // special cases for uris
150 if (format == QLatin1String("text/uri-list"))
151 atoms.append(connection->internAtom("text/x-moz-url"));
153 //special cases for images
154 if (format == QLatin1String("image/ppm"))
155 atoms.append(XCB_ATOM_PIXMAP);
156 if (format == QLatin1String("image/pbm"))
157 atoms.append(XCB_ATOM_BITMAP);
162 QVariant QXcbMime::mimeConvertToFormat(QXcbConnection *connection, xcb_atom_t a, const QByteArray &data, const QString &format,
163 QVariant::Type requestedType, const QByteArray &encoding)
165 QString atomName = mimeAtomToString(connection, a);
166 // qDebug() << "mimeConvertDataToFormat" << format << atomName << data;
168 if (!encoding.isEmpty()
169 && atomName == format + QLatin1String(";charset=") + QString::fromLatin1(encoding)) {
171 if (requestedType == QVariant::String) {
172 QTextCodec *codec = QTextCodec::codecForName(encoding);
174 return codec->toUnicode(data);
180 // special cases for string types
181 if (format == QLatin1String("text/plain")) {
182 if (a == connection->atom(QXcbAtom::UTF8_STRING))
183 return QString::fromUtf8(data);
184 if (a == XCB_ATOM_STRING ||
185 a == connection->atom(QXcbAtom::TEXT))
186 return QString::fromLatin1(data);
189 // special case for uri types
190 if (format == QLatin1String("text/uri-list")) {
191 if (atomName == QLatin1String("text/x-moz-url")) {
192 // we expect this as utf16 <url><space><title>
193 // the first part is a url that should only contain ascci char
194 // so it should be safe to check that the second char is 0
195 // to verify that it is utf16
196 if (data.size() > 1 && data.at(1) == 0)
197 return QString::fromRawData((const QChar *)data.constData(),
198 data.size() / 2).split(QLatin1Char('\n')).first().toLatin1();
202 if (atomName == format)
206 // special case for images
207 if (format == QLatin1String("image/ppm")) {
208 if (a == XCB_ATOM_PIXMAP && data.size() == sizeof(Pixmap)) {
209 Pixmap xpm = *((Pixmap*)data.data());
220 XGetGeometry(display, xpm, &root, &x, &y, &width, &height, &border_width, &depth);
221 XImage *ximg = XGetImage(display,xpm,x,y,width,height,AllPlanes,depth==1 ? XYPixmap : ZPixmap);
222 QImage qimg = QXlibStatic::qimageFromXImage(ximg);
225 QImageWriter imageWriter;
226 imageWriter.setFormat("PPMRAW");
228 buf.open(QIODevice::WriteOnly);
229 imageWriter.setDevice(&buf);
230 imageWriter.write(qimg);
238 xcb_atom_t QXcbMime::mimeAtomForFormat(QXcbConnection *connection, const QString &format, QVariant::Type requestedType,
239 const QList<xcb_atom_t> &atoms, QByteArray *requestedEncoding)
241 requestedEncoding->clear();
243 // find matches for string types
244 if (format == QLatin1String("text/plain")) {
245 if (atoms.contains(connection->atom(QXcbAtom::UTF8_STRING)))
246 return connection->atom(QXcbAtom::UTF8_STRING);
247 if (atoms.contains(XCB_ATOM_STRING))
248 return XCB_ATOM_STRING;
249 if (atoms.contains(connection->atom(QXcbAtom::TEXT)))
250 return connection->atom(QXcbAtom::TEXT);
253 // find matches for uri types
254 if (format == QLatin1String("text/uri-list")) {
255 xcb_atom_t a = connection->internAtom(format.toLatin1());
256 if (a && atoms.contains(a))
258 a = connection->internAtom("text/x-moz-url");
259 if (a && atoms.contains(a))
263 // find match for image
264 if (format == QLatin1String("image/ppm")) {
265 if (atoms.contains(XCB_ATOM_PIXMAP))
266 return XCB_ATOM_PIXMAP;
269 // for string/text requests try to use a format with a well-defined charset
270 // first to avoid encoding problems
271 if (requestedType == QVariant::String
272 && format.startsWith(QLatin1String("text/"))
273 && !format.contains(QLatin1String("charset="))) {
275 QString formatWithCharset = format;
276 formatWithCharset.append(QLatin1String(";charset=utf-8"));
278 xcb_atom_t a = connection->internAtom(formatWithCharset.toLatin1());
279 if (a && atoms.contains(a)) {
280 *requestedEncoding = "utf-8";
285 xcb_atom_t a = connection->internAtom(format.toLatin1());
286 if (a && atoms.contains(a))