383
387
return XInternAtom(display, mimeType, False);
391
QString QX11Data::xdndMimeAtomToString(Atom a)
395
char *atom = XGetAtomName(display, a);
396
atomName = QString::fromLatin1(atom);
403
Atom QX11Data::xdndMimeStringToAtom(const QString &mimeType)
405
if (mimeType.isEmpty())
407
return XInternAtom(display, mimeType.toLatin1().constData(), False);
410
//$$$ replace ccxdndAtomToString()
411
QStringList QX11Data::xdndMimeFormatsForAtom(Atom a)
415
QString atomName = xdndMimeAtomToString(a);
416
formats.append(atomName);
418
// special cases for string type
419
if (a == ATOM(UTF8_STRING) || a == XA_STRING
420
|| a == ATOM(TEXT) || a == ATOM(COMPOUND_TEXT))
421
formats.append(QLatin1String("text/plain"));
423
// special cases for uris
424
if (atomName == QLatin1String("text/x-moz-url"))
425
formats.append(QLatin1String("text/uri-list"));
427
// special case for images
429
formats.append(QLatin1String("image/ppm"));
435
bool QX11Data::xdndMimeDataForAtom(Atom a, QMimeData *mimeData, QByteArray *data, Atom *atomFormat, int *dataFormat)
440
QString atomName = xdndMimeAtomToString(a);
441
if (QInternalMimeData::hasFormatHelper(atomName, mimeData)) {
442
*data = QInternalMimeData::renderDataHelper(atomName, mimeData);
443
if (atomName == QLatin1String("application/x-color"))
447
if ((a == ATOM(UTF8_STRING) || a == XA_STRING
448
|| a == ATOM(TEXT) || a == ATOM(COMPOUND_TEXT))
449
&& QInternalMimeData::hasFormatHelper(QLatin1String("text/plain"), mimeData)) {
450
if (a == ATOM(UTF8_STRING)){
451
*data = QInternalMimeData::renderDataHelper(QLatin1String("text/plain"), mimeData);
453
} else if (a == XA_STRING) {
454
*data = QString::fromUtf8(QInternalMimeData::renderDataHelper(
455
QLatin1String("text/plain"), mimeData)).toLocal8Bit();
457
} else if (a == ATOM(TEXT) || a == ATOM(COMPOUND_TEXT)) {
458
// the ICCCM states that TEXT and COMPOUND_TEXT are in the
459
// encoding of choice, so we choose the encoding of the locale
460
QByteArray strData = QString::fromUtf8(QInternalMimeData::renderDataHelper(
461
QLatin1String("text/plain"), mimeData)).toLocal8Bit();
462
char *list[] = { strData.data(), NULL };
464
XICCEncodingStyle style = (a == ATOM(COMPOUND_TEXT))
465
? XCompoundTextStyle : XStdICCTextStyle;
466
XTextProperty textprop;
468
&& XmbTextListToTextProperty(X11->display, list, 1, style,
469
&textprop) == Success) {
470
*atomFormat = textprop.encoding;
471
*dataFormat = textprop.format;
472
*data = QByteArray((const char *) textprop.value, textprop.nitems * textprop.format / 8);
474
DEBUG(" textprop type %lx\n"
475
" textprop name '%s'\n"
480
X11->xdndMimeAtomToString(textprop.encoding).toLatin1().data(),
481
textprop.format, textprop.nitems, data->size());
483
XFree(textprop.value);
486
} else if (atomName == QLatin1String("text/x-moz-url") &&
487
QInternalMimeData::hasFormatHelper(QLatin1String("text/uri-list"), mimeData)) {
488
QByteArray uri = QInternalMimeData::renderDataHelper(
489
QLatin1String("text/uri-list"), mimeData).split('\n').first();
490
QString mozUri = QString::fromLatin1(uri, uri.size());
491
mozUri += QLatin1Char('\n');
492
*data = QByteArray(reinterpret_cast<const char *>(mozUri.utf16()), mozUri.length() * 2);
494
} else if ((a == XA_PIXMAP || a == XA_BITMAP) && mimeData->hasImage()) {
495
QPixmap pm = qvariant_cast<QPixmap>(mimeData->imageData());
496
if (a == XA_BITMAP && pm.depth() != 1) {
497
QImage img = pm.toImage();
498
img = img.convertToFormat(QImage::Format_MonoLSB);
499
pm = QPixmap::fromImage(img);
501
QDragManager *dm = QDragManager::self();
503
Pixmap handle = pm.handle();
504
*data = QByteArray((const char *) &handle, sizeof(Pixmap));
505
dm->xdndMimeTransferedPixmap[dm->xdndMimeTransferedPixmapIndex] = pm;
506
dm->xdndMimeTransferedPixmapIndex =
507
(dm->xdndMimeTransferedPixmapIndex + 1) % 2;
515
QList<Atom> QX11Data::xdndMimeAtomsForFormat(const QString &format)
518
atoms.append(xdndMimeStringToAtom(format));
520
// special cases for strings
521
if (format == QLatin1String("text/plain")) {
522
atoms.append(ATOM(UTF8_STRING));
523
atoms.append(XA_STRING);
524
atoms.append(ATOM(TEXT));
525
atoms.append(ATOM(COMPOUND_TEXT));
528
// special cases for uris
529
if (format == QLatin1String("text/uri-list")) {
530
atoms.append(xdndMimeStringToAtom(QLatin1String("text/x-moz-url")));
533
//special cases for images
534
if (format == QLatin1String("image/ppm"))
535
atoms.append(XA_PIXMAP);
536
if (format == QLatin1String("image/pbm"))
537
atoms.append(XA_BITMAP);
543
QByteArray QX11Data::xdndMimeConvertToFormat(Atom a, const QByteArray &data, const QString &format)
545
QString atomName = xdndMimeAtomToString(a);
546
if (atomName == format)
549
// special cases for string types
550
if (format == QLatin1String("text/plain")) {
551
if (a == ATOM(UTF8_STRING))
554
return QString::fromLatin1(data).toUtf8();
555
if (a == ATOM(TEXT) || a == ATOM(COMPOUND_TEXT))
556
// #### might be wrong for COMPUND_TEXT
557
return QString::fromLocal8Bit(data, data.size()).toUtf8();
560
// special case for uri types
561
if (format == QLatin1String("text/uri-list")) {
562
if (atomName == QLatin1String("text/x-moz-url")) {
563
// we expect this as utf16 <url><space><title>
564
// the first part is a url that should only contain ascci char
565
// so it should be safe to check that the second char is 0
566
// to verify that it is utf16
567
if (data.size() > 1 && data.at(1) == 0)
568
return QString::fromUtf16(reinterpret_cast<const ushort *>(data.constData()),
569
data.size() / 2).split(QLatin1Char('\n')).first().toLatin1();
573
// special cas for images
574
if (format == QLatin1String("image/ppm")) {
575
if (a == XA_PIXMAP && data.size() == sizeof(Pixmap)) {
576
Pixmap xpm = *((Pixmap*)data.data());
577
Display *dpy = display;
583
XGetGeometry(dpy,xpm, &r,&x,&y,&w,&h,&bw,&d);
584
QImageWriter imageWriter;
585
GC gc = XCreateGC(dpy, xpm, 0, 0);
589
XCopyArea(dpy,xpm,qbm.handle(),gc,0,0,w,h,0,0);
590
imageWriter.setFormat("PBMRAW");
591
imageToWrite = qbm.toImage();
594
XCopyArea(dpy,xpm,qpm.handle(),gc,0,0,w,h,0,0);
595
imageWriter.setFormat("PPMRAW");
596
imageToWrite = qpm.toImage();
600
buf.open(QIODevice::WriteOnly);
601
imageWriter.setDevice(&buf);
602
imageWriter.write(imageToWrite);
609
//$$$ middle of xdndObtainData
610
Atom QX11Data::xdndMimeAtomForFormat(const QString &format, const QList<Atom> &atoms)
612
Atom a = xdndMimeStringToAtom(format);
613
if (a && atoms.contains(a))
616
// find matches for string types
617
if (format == QLatin1String("text/plain")) {
618
if (atoms.contains(ATOM(UTF8_STRING)))
619
return ATOM(UTF8_STRING);
620
if (atoms.contains(ATOM(COMPOUND_TEXT)))
622
if (atoms.contains(ATOM(TEXT)))
624
if (atoms.contains(XA_STRING))
628
// find mathes for uri types
629
if (format == QLatin1String("text/uri-list")) {
630
Atom a = xdndMimeStringToAtom(QLatin1String("text/x-moz-url"));
631
if (a && atoms.contains(a))
635
// find match for image
636
if (format == QLatin1String("image/ppm")) {
637
if (atoms.contains(XA_PIXMAP))
387
644
void QX11Data::xdndSetup() {
388
645
QCursorData::initialize();
1517
1758
if (!qt_xdnd_current_widget || (qt_xdnd_current_widget->windowType() == Qt::Desktop))
1518
1759
tw = new QWidget;
1520
XConvertSelection(X11->display, ATOM(XdndSelection), a, ATOM(XdndSelection), tw->winId(),
1761
XConvertSelection(X11->display, ATOM(XdndSelection), a, ATOM(XdndSelection), tw->internalWinId(),
1521
1762
qt_xdnd_target_current_time);
1522
1763
XFlush(X11->display);
1525
bool got=X11->clipboardWaitForEvent(tw->winId(), SelectionNotify, &xevent, 5000);
1766
bool got=X11->clipboardWaitForEvent(tw->internalWinId(), SelectionNotify, &xevent, 5000);
1529
if (X11->clipboardReadProperty(tw->winId(), ATOM(XdndSelection), true, &result, 0, &type, 0, false)) {
1770
if (X11->clipboardReadProperty(tw->internalWinId(), ATOM(XdndSelection), true, &result, 0, &type, 0, false)) {
1530
1771
if (type == ATOM(INCR)) {
1531
1772
int nbytes = result.size() >= 4 ? *((int*)result.data()) : 0;
1532
result = X11->clipboardReadIncrementalProperty(tw->winId(), ATOM(XdndSelection), nbytes, false);
1773
result = X11->clipboardReadIncrementalProperty(tw->internalWinId(), ATOM(XdndSelection), nbytes, false);
1533
1774
} else if (type != a && type != XNone) {
1534
1775
DEBUG("Qt clipboard: unknown atom %ld", type);