bool QXlibMime::mimeDataForAtom(Display *display, Atom a, QMimeData *mimeData, QByteArray *data, Atom *atomFormat, int *dataFormat) { bool ret = false; *atomFormat = a; *dataFormat = 8; QString atomName = mimeAtomToString(display, a); if (QInternalMimeData::hasFormatHelper(atomName, mimeData)) { *data = QInternalMimeData::renderDataHelper(atomName, mimeData); if (atomName == QLatin1String("application/x-color")) *dataFormat = 16; ret = true; } else { if ((a == QXlibStatic::atom(QXlibStatic::UTF8_STRING) || a == XA_STRING || a == QXlibStatic::atom(QXlibStatic::TEXT) || a == QXlibStatic::atom(QXlibStatic::COMPOUND_TEXT)) && QInternalMimeData::hasFormatHelper(QLatin1String("text/plain"), mimeData)) { if (a == QXlibStatic::atom(QXlibStatic::UTF8_STRING)){ *data = QInternalMimeData::renderDataHelper(QLatin1String("text/plain"), mimeData); ret = true; } else if (a == XA_STRING) { *data = QString::fromUtf8(QInternalMimeData::renderDataHelper( QLatin1String("text/plain"), mimeData)).toLocal8Bit(); ret = true; } else if (a == QXlibStatic::atom(QXlibStatic::TEXT) || a == QXlibStatic::atom(QXlibStatic::COMPOUND_TEXT)) { // the ICCCM states that TEXT and COMPOUND_TEXT are in the // encoding of choice, so we choose the encoding of the locale QByteArray strData = QString::fromUtf8(QInternalMimeData::renderDataHelper( QLatin1String("text/plain"), mimeData)).toLocal8Bit(); char *list[] = { strData.data(), NULL }; XICCEncodingStyle style = (a == QXlibStatic::atom(QXlibStatic::COMPOUND_TEXT)) ? XCompoundTextStyle : XStdICCTextStyle; XTextProperty textprop; if (list[0] != NULL && XmbTextListToTextProperty(display, list, 1, style, &textprop) == Success) { *atomFormat = textprop.encoding; *dataFormat = textprop.format; *data = QByteArray((const char *) textprop.value, textprop.nitems * textprop.format / 8); ret = true; XFree(textprop.value); } } } else if (atomName == QLatin1String("text/x-moz-url") && QInternalMimeData::hasFormatHelper(QLatin1String("text/uri-list"), mimeData)) { QByteArray uri = QInternalMimeData::renderDataHelper( QLatin1String("text/uri-list"), mimeData).split('\n').first(); QString mozUri = QString::fromLatin1(uri, uri.size()); mozUri += QLatin1Char('\n'); *data = QByteArray(reinterpret_cast<const char *>(mozUri.utf16()), mozUri.length() * 2); ret = true; } else if ((a == XA_PIXMAP || a == XA_BITMAP) && mimeData->hasImage()) { ret = true; } } return ret && data != 0; }
bool QXcbMime::mimeDataForAtom(QXcbConnection *connection, xcb_atom_t a, QMimeData *mimeData, QByteArray *data, xcb_atom_t *atomFormat, int *dataFormat) { if (!data) return false; bool ret = false; *atomFormat = a; *dataFormat = 8; if ((a == connection->atom(QXcbAtom::UTF8_STRING) || a == XCB_ATOM_STRING || a == connection->atom(QXcbAtom::TEXT)) && QInternalMimeData::hasFormatHelper(QLatin1String("text/plain"), mimeData)) { if (a == connection->atom(QXcbAtom::UTF8_STRING)) { *data = QInternalMimeData::renderDataHelper(QLatin1String("text/plain"), mimeData); ret = true; } else if (a == XCB_ATOM_STRING || a == connection->atom(QXcbAtom::TEXT)) { // ICCCM says STRING is latin1 *data = QString::fromUtf8(QInternalMimeData::renderDataHelper( QLatin1String("text/plain"), mimeData)).toLatin1(); ret = true; } return ret; } QString atomName = mimeAtomToString(connection, a); if (QInternalMimeData::hasFormatHelper(atomName, mimeData)) { *data = QInternalMimeData::renderDataHelper(atomName, mimeData); // mimeAtomToString() converts "text/x-moz-url" to "text/uri-list", // so QXcbConnection::atomName() has to be used. if (atomName == QLatin1String("text/uri-list") && connection->atomName(a) == "text/x-moz-url") { const QByteArray uri = data->split('\n').first(); QString mozUri = QString::fromLatin1(uri, uri.size()); mozUri += QLatin1Char('\n'); *data = QByteArray(reinterpret_cast<const char *>(mozUri.utf16()), mozUri.length() * 2); } else if (atomName == QLatin1String("application/x-color")) *dataFormat = 16; ret = true; } else if ((a == XCB_ATOM_PIXMAP || a == XCB_ATOM_BITMAP) && mimeData->hasImage()) { ret = true; } else if (atomName == QLatin1String("text/plain") && mimeData->hasFormat(QLatin1String("text/uri-list"))) { // Return URLs also as plain text. *data = QInternalMimeData::renderDataHelper(atomName, mimeData); ret = true; } return ret; }
QStringList QXlibMime::mimeFormatsForAtom(Display *display, Atom a) { QStringList formats; if (a) { QString atomName = mimeAtomToString(display, a); formats.append(atomName); // special cases for string type if (a == QXlibStatic::atom(QXlibStatic::UTF8_STRING) || a == XA_STRING || a == QXlibStatic::atom(QXlibStatic::TEXT) || a == QXlibStatic::atom(QXlibStatic::COMPOUND_TEXT)) formats.append(QLatin1String("text/plain")); // special cases for uris if (atomName == QLatin1String("text/x-moz-url")) formats.append(QLatin1String("text/uri-list")); // special case for images if (a == XA_PIXMAP) formats.append(QLatin1String("image/ppm")); } return formats; }
QVariant QXcbMime::mimeConvertToFormat(QXcbConnection *connection, xcb_atom_t a, const QByteArray &data, const QString &format, QVariant::Type requestedType, const QByteArray &encoding) { QString atomName = mimeAtomToString(connection, a); // qDebug() << "mimeConvertDataToFormat" << format << atomName << data; if (!encoding.isEmpty() && atomName == format + QLatin1String(";charset=") + QString::fromLatin1(encoding)) { #ifndef QT_NO_TEXTCODEC if (requestedType == QVariant::String) { QTextCodec *codec = QTextCodec::codecForName(encoding); if (codec) return codec->toUnicode(data); } #endif return data; } // special cases for string types if (format == QLatin1String("text/plain")) { if (a == connection->atom(QXcbAtom::UTF8_STRING)) return QString::fromUtf8(data); if (a == XCB_ATOM_STRING || a == connection->atom(QXcbAtom::TEXT)) return QString::fromLatin1(data); } // special case for uri types if (format == QLatin1String("text/uri-list")) { if (atomName == QLatin1String("text/x-moz-url")) { // we expect this as utf16 <url><space><title> // the first part is a url that should only contain ascci char // so it should be safe to check that the second char is 0 // to verify that it is utf16 if (data.size() > 1 && data.at(1) == 0) return QString::fromRawData((const QChar *)data.constData(), data.size() / 2).split(QLatin1Char('\n')).first().toLatin1(); } } if (atomName == format) return data; #if 0 // ### // special case for images if (format == QLatin1String("image/ppm")) { if (a == XCB_ATOM_PIXMAP && data.size() == sizeof(Pixmap)) { Pixmap xpm = *((Pixmap*)data.data()); if (!xpm) return QByteArray(); Window root; int x; int y; uint width; uint height; uint border_width; uint depth; XGetGeometry(display, xpm, &root, &x, &y, &width, &height, &border_width, &depth); XImage *ximg = XGetImage(display,xpm,x,y,width,height,AllPlanes,depth==1 ? XYPixmap : ZPixmap); QImage qimg = QXlibStatic::qimageFromXImage(ximg); XDestroyImage(ximg); QImageWriter imageWriter; imageWriter.setFormat("PPMRAW"); QBuffer buf; buf.open(QIODevice::WriteOnly); imageWriter.setDevice(&buf); imageWriter.write(qimg); return buf.buffer(); } } #endif return QVariant(); }
QVariant QXcbMime::mimeConvertToFormat(QXcbConnection *connection, xcb_atom_t a, const QByteArray &data, const QString &format, QVariant::Type requestedType, const QByteArray &encoding) { QString atomName = mimeAtomToString(connection, a); // qDebug() << "mimeConvertDataToFormat" << format << atomName << data; if (!encoding.isEmpty() && atomName == format + QLatin1String(";charset=") + QString::fromLatin1(encoding)) { #ifndef QT_NO_TEXTCODEC if (requestedType == QVariant::String) { QTextCodec *codec = QTextCodec::codecForName(encoding); if (codec) return codec->toUnicode(data); } #endif return data; } // special cases for string types if (format == QLatin1String("text/plain")) { if (a == connection->atom(QXcbAtom::UTF8_STRING)) return QString::fromUtf8(data); if (a == XCB_ATOM_STRING || a == connection->atom(QXcbAtom::TEXT)) return QString::fromLatin1(data); } // If data contains UTF16 text, convert it to a string. // Firefox uses UTF16 without BOM for text/x-moz-url, "text/html", // Google Chrome uses UTF16 without BOM for "text/x-moz-url", // UTF16 with BOM for "text/html". if ((format == QLatin1String("text/html") || format == QLatin1String("text/uri-list")) && data.size() > 1) { const quint8 byte0 = data.at(0); const quint8 byte1 = data.at(1); if ((byte0 == 0xff && byte1 == 0xfe) || (byte0 == 0xfe && byte1 == 0xff) || (byte0 != 0 && byte1 == 0) || (byte0 == 0 && byte1 != 0)) { const QString str = QString::fromUtf16( reinterpret_cast<const ushort *>(data.constData()), data.size() / 2); if (!str.isNull()) { if (format == QLatin1String("text/uri-list")) { const QStringList urls = str.split(QLatin1Char('\n')); QList<QVariant> list; foreach (const QString &s, urls) { const QUrl url(s.trimmed()); if (url.isValid()) list.append(url); } // We expect "text/x-moz-url" as <url><space><title>. // The atomName variable is not used because mimeAtomToString() // converts "text/x-moz-url" to "text/uri-list". if (!list.isEmpty() && connection->atomName(a) == "text/x-moz-url") return list.first(); return list; } else { return str; } } } }