📄 qdnd_x11.cpp
字号:
//$$$QString QX11Data::xdndMimeAtomToString(Atom a){ QString atomName; if (a) { char *atom = XGetAtomName(display, a); atomName = QString::fromLatin1(atom); XFree(atom); } return atomName;}//$$$Atom QX11Data::xdndMimeStringToAtom(const QString &mimeType){ if (mimeType.isEmpty()) return 0; return XInternAtom(display, mimeType.toLatin1().constData(), False);}//$$$ replace ccxdndAtomToString()QStringList QX11Data::xdndMimeFormatsForAtom(Atom a){ QStringList formats; if (a) { QString atomName = xdndMimeAtomToString(a); formats.append(atomName); // special cases for string type if (a == ATOM(UTF8_STRING) || a == XA_STRING || a == ATOM(TEXT) || a == ATOM(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;}//$$$bool QX11Data::xdndMimeDataForAtom(Atom a, QMimeData *mimeData, QByteArray *data, Atom *atomFormat, int *dataFormat){ bool ret = false; *atomFormat = a; *dataFormat = 8; QString atomName = xdndMimeAtomToString(a); if (QInternalMimeData::hasFormatHelper(atomName, mimeData)) { *data = QInternalMimeData::renderDataHelper(atomName, mimeData); if (atomName == QLatin1String("application/x-color")) *dataFormat = 16; ret = true; } else { if ((a == ATOM(UTF8_STRING) || a == XA_STRING || a == ATOM(TEXT) || a == ATOM(COMPOUND_TEXT)) && QInternalMimeData::hasFormatHelper(QLatin1String("text/plain"), mimeData)) { if (a == ATOM(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 == ATOM(TEXT) || a == ATOM(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 == ATOM(COMPOUND_TEXT)) ? XCompoundTextStyle : XStdICCTextStyle; XTextProperty textprop; if (list[0] != NULL && XmbTextListToTextProperty(X11->display, list, 1, style, &textprop) == Success) { *atomFormat = textprop.encoding; *dataFormat = textprop.format; *data = QByteArray((const char *) textprop.value, textprop.nitems * textprop.format / 8); DEBUG(" textprop type %lx\n" " textprop name '%s'\n" " format %d\n" " %ld items\n" " %d bytes\n", textprop.encoding, X11->xdndMimeAtomToString(textprop.encoding).toLatin1().data(), textprop.format, textprop.nitems, data->size()); 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()) { QPixmap pm = qvariant_cast<QPixmap>(mimeData->imageData()); if (a == XA_BITMAP && pm.depth() != 1) { QImage img = pm.toImage(); img = img.convertToFormat(QImage::Format_MonoLSB); pm = QPixmap::fromImage(img); } QDragManager *dm = QDragManager::self(); if (dm) { Pixmap handle = pm.handle(); *data = QByteArray((const char *) &handle, sizeof(Pixmap)); dm->xdndMimeTransferedPixmap[dm->xdndMimeTransferedPixmapIndex] = pm; dm->xdndMimeTransferedPixmapIndex = (dm->xdndMimeTransferedPixmapIndex + 1) % 2; } } } return data;}//$$$QList<Atom> QX11Data::xdndMimeAtomsForFormat(const QString &format){ QList<Atom> atoms; atoms.append(xdndMimeStringToAtom(format)); // special cases for strings if (format == QLatin1String("text/plain")) { atoms.append(ATOM(UTF8_STRING)); atoms.append(XA_STRING); atoms.append(ATOM(TEXT)); atoms.append(ATOM(COMPOUND_TEXT)); } // special cases for uris if (format == QLatin1String("text/uri-list")) { atoms.append(xdndMimeStringToAtom(QLatin1String("text/x-moz-url"))); } //special cases for images if (format == QLatin1String("image/ppm")) atoms.append(XA_PIXMAP); if (format == QLatin1String("image/pbm")) atoms.append(XA_BITMAP); return atoms;}//$$$QVariant QX11Data::xdndMimeConvertToFormat(Atom a, const QByteArray &data, const QString &format, QVariant::Type requestedType, const QByteArray &encoding){ QString atomName = xdndMimeAtomToString(a); if (atomName == format) return data; if (!encoding.isEmpty() && atomName == format + QLatin1String(";charset=") + QString::fromLatin1(encoding)) { if (requestedType == QVariant::String) { QTextCodec *codec = QTextCodec::codecForName(encoding); if (codec) return codec->toUnicode(data); } return data; } // special cases for string types if (format == QLatin1String("text/plain")) { if (a == ATOM(UTF8_STRING)) return QString::fromUtf8(data); if (a == XA_STRING) return QString::fromLatin1(data); if (a == ATOM(TEXT) || a == ATOM(COMPOUND_TEXT)) // #### might be wrong for COMPUND_TEXT return QString::fromLocal8Bit(data, data.size()); } // 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::fromUtf16(reinterpret_cast<const ushort *>(data.constData()), data.size() / 2).split(QLatin1Char('\n')).first().toLatin1(); } } // special cas for images if (format == QLatin1String("image/ppm")) { if (a == XA_PIXMAP && data.size() == sizeof(Pixmap)) { Pixmap xpm = *((Pixmap*)data.data()); Display *dpy = display; Window r; int x,y; uint w,h,bw,d; if (!xpm) return QByteArray(); XGetGeometry(dpy,xpm, &r,&x,&y,&w,&h,&bw,&d); QImageWriter imageWriter; GC gc = XCreateGC(dpy, xpm, 0, 0); QImage imageToWrite; if (d == 1) { QBitmap qbm(w,h); XCopyArea(dpy,xpm,qbm.handle(),gc,0,0,w,h,0,0); imageWriter.setFormat("PBMRAW"); imageToWrite = qbm.toImage(); } else { QPixmap qpm(w,h); XCopyArea(dpy,xpm,qpm.handle(),gc,0,0,w,h,0,0); imageWriter.setFormat("PPMRAW"); imageToWrite = qpm.toImage(); } XFreeGC(dpy,gc); QBuffer buf; buf.open(QIODevice::WriteOnly); imageWriter.setDevice(&buf); imageWriter.write(imageToWrite); return buf.buffer(); } } return QVariant();}//$$$ middle of xdndObtainDataAtom QX11Data::xdndMimeAtomForFormat(const QString &format, QVariant::Type requestedType, const QList<Atom> &atoms, QByteArray *encoding){ encoding->clear(); // find matches for string types if (format == QLatin1String("text/plain")) { if (atoms.contains(ATOM(UTF8_STRING))) return ATOM(UTF8_STRING); if (atoms.contains(ATOM(COMPOUND_TEXT))) return ATOM(COMPOUND_TEXT); if (atoms.contains(ATOM(TEXT))) return ATOM(TEXT); if (atoms.contains(XA_STRING)) return XA_STRING; } // find mathes for uri types if (format == QLatin1String("text/uri-list")) { Atom a = xdndMimeStringToAtom(QLatin1String("text/x-moz-url")); if (a && atoms.contains(a)) return a; } // find match for image if (format == QLatin1String("image/ppm")) { if (atoms.contains(XA_PIXMAP)) return XA_PIXMAP; } // for string/text requests try to use a format with a well-defined charset // first to avoid encoding problems if (requestedType == QVariant::String && format.startsWith(QLatin1String("text/")) && !format.contains(QLatin1String("charset="))) { QString formatWithCharset = format; formatWithCharset.append(QLatin1String(";charset=utf-8")); Atom a = xdndMimeStringToAtom(formatWithCharset); if (a && atoms.contains(a)) { *encoding = "utf-8"; return a; } } Atom a = xdndMimeStringToAtom(format); if (a && atoms.contains(a)) return a; return 0;}void QX11Data::xdndSetup() { QCursorData::initialize(); qAddPostRoutine(qt_xdnd_cleanup);}void qt_xdnd_cleanup(){ delete noDropCursor; noDropCursor = 0; delete copyCursor; copyCursor = 0; delete moveCursor; moveCursor = 0; delete linkCursor; linkCursor = 0; delete defaultPm; defaultPm = 0; delete xdnd_data.desktop_proxy; xdnd_data.desktop_proxy = 0; delete xdnd_data.deco; xdnd_data.deco = 0;}static QWidget *find_child(QWidget *tlw, QPoint & p){ QWidget *widget = tlw; p = widget->mapFromGlobal(p); bool done = false; while (!done) { done = true; if (((QExtraWidget*)widget)->extraData() && ((QExtraWidget*)widget)->extraData()->xDndProxy != 0) break; // stop searching for widgets under the mouse cursor if found widget is a proxy. QObjectList children = widget->children(); if (!children.isEmpty()) { for(int i = children.size(); i > 0;) { --i; QWidget *w = qobject_cast<QWidget *>(children.at(i)); if (!w) continue; if (w->isVisible() && w->geometry().contains(p) && !w->isWindow()) { widget = w; done = false; p = widget->mapFromParent(p); break; } } } } return widget;}static bool checkEmbedded(QWidget* w, const XEvent* xe){ if (!w) return false; if (current_embedding_widget != 0 && current_embedding_widget != w) { qt_xdnd_current_target = ((QExtraWidget*)current_embedding_widget)->extraData()->xDndProxy; qt_xdnd_current_proxy_target = qt_xdnd_current_target; qt_xdnd_send_leave(); qt_xdnd_current_target = 0; qt_xdnd_current_proxy_target = 0; current_embedding_widget = 0; } QWExtra* extra = ((QExtraWidget*)w)->extraData(); if (extra && extra->xDndProxy != 0) { if (current_embedding_widget != w) { last_enter_event.xany.window = extra->xDndProxy; XSendEvent(X11->display, extra->xDndProxy, False, NoEventMask, &last_enter_event); current_embedding_widget = w; } ((XEvent*)xe)->xany.window = extra->xDndProxy; XSendEvent(X11->display, extra->xDndProxy, False, NoEventMask, (XEvent*)xe); if (qt_xdnd_current_widget != w) { qt_xdnd_current_widget = w; } return true; } current_embedding_widget = 0; return false;}void QX11Data::xdndHandleEnter(QWidget *, const XEvent * xe, bool /*passive*/){ motifdnd_active = false; last_enter_event.xclient = xe->xclient; const long *l = xe->xclient.data.l; int version = (int)(((unsigned long)(l[1])) >> 24); if (version > xdnd_version) return; qt_xdnd_dragsource_xid = l[0]; int j = 0; if (l[1] & 1) { // get the types from XdndTypeList Atom type = XNone; int f; unsigned long n, a; unsigned char *retval; XGetWindowProperty(X11->display, qt_xdnd_dragsource_xid, ATOM(XdndTypelist), 0, qt_xdnd_max_type, False, XA_ATOM, &type, &f,&n,&a,&retval); Atom *data = (Atom *)retval; for (; j<qt_xdnd_max_type && j < (int)n; j++) { qt_xdnd_types[j] = data[j];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -