bcc94baed721f7790f280099617372b27009f0e1
[profile/ivi/qtbase.git] / src / plugins / platforms / xcb / qxcbmime.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the plugins of the Qt Toolkit.
7 **
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.
16 **
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.
20 **
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.
28 **
29 ** Other Usage
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.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qxcbmime.h"
43
44 #include <QtCore/QTextCodec>
45 #include <QtGui/QImageWriter>
46 #include <QtCore/QBuffer>
47 #include <qdebug.h>
48
49 #include <X11/Xutil.h>
50
51 #undef XCB_ATOM_STRING
52 #undef XCB_ATOM_PIXMAP
53 #undef XCB_ATOM_BITMAP
54
55 QT_BEGIN_NAMESPACE
56
57 QXcbMime::QXcbMime()
58     : QInternalMimeData()
59 { }
60
61 QXcbMime::~QXcbMime()
62 {}
63
64
65
66 QString QXcbMime::mimeAtomToString(QXcbConnection *connection, xcb_atom_t a)
67 {
68     if (a == XCB_NONE)
69         return QString();
70
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");
76
77     // special case for images
78     if (a == XCB_ATOM_PIXMAP)
79         return QLatin1String("image/ppm");
80
81     QByteArray atomName = connection->atomName(a);
82
83     // special cases for uris
84     if (atomName == "text/x-moz-url")
85         atomName = "text/uri-list";
86
87     return QString::fromLatin1(atomName.constData());
88 }
89
90 bool QXcbMime::mimeDataForAtom(QXcbConnection *connection, xcb_atom_t a, QMimeData *mimeData, QByteArray *data,
91                                xcb_atom_t *atomFormat, int *dataFormat)
92 {
93     if (!data)
94         return false;
95
96     bool ret = false;
97     *atomFormat = a;
98     *dataFormat = 8;
99
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);
106             ret = true;
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();
112             ret = true;
113         }
114         return ret;
115     }
116
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"))
121             *dataFormat = 16;
122         ret = true;
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);
130         ret = true;
131     } else if ((a == XCB_ATOM_PIXMAP || a == XCB_ATOM_BITMAP) && mimeData->hasImage()) {
132         ret = true;
133     }
134     return ret;
135 }
136
137 QList<xcb_atom_t> QXcbMime::mimeAtomsForFormat(QXcbConnection *connection, const QString &format)
138 {
139     QList<xcb_atom_t> atoms;
140     atoms.append(connection->internAtom(format.toLatin1()));
141
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));
147     }
148
149     // special cases for uris
150     if (format == QLatin1String("text/uri-list"))
151         atoms.append(connection->internAtom("text/x-moz-url"));
152
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);
158
159     return atoms;
160 }
161
162 QVariant QXcbMime::mimeConvertToFormat(QXcbConnection *connection, xcb_atom_t a, const QByteArray &data, const QString &format,
163                                        QVariant::Type requestedType, const QByteArray &encoding)
164 {
165     QString atomName = mimeAtomToString(connection, a);
166 //    qDebug() << "mimeConvertDataToFormat" << format << atomName << data;
167
168     if (!encoding.isEmpty()
169         && atomName == format + QLatin1String(";charset=") + QString::fromLatin1(encoding)) {
170
171         if (requestedType == QVariant::String) {
172             QTextCodec *codec = QTextCodec::codecForName(encoding);
173             if (codec)
174                 return codec->toUnicode(data);
175         }
176
177         return data;
178     }
179
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);
187     }
188
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();
199         }
200     }
201
202     if (atomName == format)
203         return data;
204
205 #if 0 // ###
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());
210             if (!xpm)
211                 return QByteArray();
212             Window root;
213             int x;
214             int y;
215             uint width;
216             uint height;
217             uint border_width;
218             uint depth;
219
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);
223             XDestroyImage(ximg);
224
225             QImageWriter imageWriter;
226             imageWriter.setFormat("PPMRAW");
227             QBuffer buf;
228             buf.open(QIODevice::WriteOnly);
229             imageWriter.setDevice(&buf);
230             imageWriter.write(qimg);
231             return buf.buffer();
232         }
233     }
234 #endif
235     return QVariant();
236 }
237
238 xcb_atom_t QXcbMime::mimeAtomForFormat(QXcbConnection *connection, const QString &format, QVariant::Type requestedType,
239                                  const QList<xcb_atom_t> &atoms, QByteArray *requestedEncoding)
240 {
241     requestedEncoding->clear();
242
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);
251     }
252
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))
257             return a;
258         a = connection->internAtom("text/x-moz-url");
259         if (a && atoms.contains(a))
260             return a;
261     }
262
263     // find match for image
264     if (format == QLatin1String("image/ppm")) {
265         if (atoms.contains(XCB_ATOM_PIXMAP))
266             return XCB_ATOM_PIXMAP;
267     }
268
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="))) {
274
275         QString formatWithCharset = format;
276         formatWithCharset.append(QLatin1String(";charset=utf-8"));
277
278         xcb_atom_t a = connection->internAtom(formatWithCharset.toLatin1());
279         if (a && atoms.contains(a)) {
280             *requestedEncoding = "utf-8";
281             return a;
282         }
283     }
284
285     xcb_atom_t a = connection->internAtom(format.toLatin1());
286     if (a && atoms.contains(a))
287         return a;
288
289     return 0;
290 }
291
292 QT_END_NAMESPACE