STDMETHODIMP QOleDataObject::QueryGetData( FORMATETC *pformatetc ) { #ifdef DEBUG_QDND_SRC qDebug( "QOleDataObject::QueryGetData( %p )", pformatetc ); #endif if ( !pformatetc ) { return E_INVALIDARG; } if ( pformatetc->lindex != -1 ) { return DV_E_LINDEX; } if ( pformatetc->dwAspect != DVASPECT_CONTENT ) { return DV_E_DVASPECT; } int tymed = pformatetc->tymed; /* Currently we only support HGLOBAL */ if ( !( tymed & TYMED_HGLOBAL ) ) { return DV_E_TYMED; } int cf = pformatetc->cfFormat; QPtrList<QWindowsMime> all = QWindowsMime::all(); for ( QWindowsMime * c = all.first(); c ; c = all.next() ) { const char * mime = c->mimeFor( cf ); if ( mime && m_dragObj->provides( mime ) ) { return S_OK; } } return DV_E_FORMATETC; }
STDMETHODIMP QOleDataObject::GetData( FORMATETC *pformatetcIn, STGMEDIUM *pmedium ) { // is data is in our format? HRESULT hr = QueryGetData( pformatetcIn ); if ( hr != S_OK ) return hr; int cf = pformatetcIn->cfFormat; pmedium->tymed = TYMED_HGLOBAL; QPtrList<QWindowsMime> all = QWindowsMime::all(); for ( QWindowsMime * c = all.first(); c ; c = all.next() ) { const char * mime = c->mimeFor( cf ); if ( mime && m_dragObj->provides( mime ) ) { QByteArray ba = m_dragObj->encodedData( mime ); ba = c->convertFromMime( ba, mime, cf ); HGLOBAL hGlobal = GlobalAlloc ( GMEM_MOVEABLE | GMEM_SHARE, ba.size() ); if ( !hGlobal ) return E_OUTOFMEMORY; memcpy ( GlobalLock ( hGlobal ), ba.data(), ba.size() ); GlobalUnlock ( hGlobal ); pmedium->hGlobal = hGlobal; pmedium->pUnkForRelease = NULL; return S_OK; } } return E_UNEXPECTED; }
STDMETHODIMP QOleDataObject::GetDataHere( FORMATETC *pformatetc, STGMEDIUM *pmedium ) { // is data is in our format? HRESULT hr = QueryGetData( pformatetc ); if ( hr != S_OK ) return hr; if ( pmedium->tymed != TYMED_HGLOBAL ) return DV_E_TYMED; if ( !pmedium->hGlobal ) return STG_E_MEDIUMFULL; HGLOBAL hGlobal = pmedium->hGlobal; uint size = GlobalSize( hGlobal ); int cf = pformatetc->cfFormat; QPtrList<QWindowsMime> all = QWindowsMime::all(); for ( QWindowsMime * c = all.first(); c ; c = all.next() ) { const char * mime = c->mimeFor( cf ); if ( mime && m_dragObj->provides( mime ) ) { QByteArray ba = m_dragObj->encodedData( mime ); if ( ba.size() > size ) return STG_E_MEDIUMFULL; memcpy ( GlobalLock ( hGlobal ), ba.data(), ba.size() ); GlobalUnlock ( hGlobal ); return S_OK; } } return E_UNEXPECTED; }
static QByteArray qt_xdnd_obtain_data( const char * format ) { QByteArray result; QWidget* w; if ( qt_xdnd_dragsource_xid && qt_xdnd_source_object && (w=QWidget::find( qt_xdnd_dragsource_xid )) && (!w->isDesktop() || w->acceptDrops()) ) { QDragObject * o = qt_xdnd_source_object; if ( o->provides( format ) ) result = o->encodedData(format); return result; } Atom * a = qt_xdnd_str_to_atom( format ); if ( !a || !*a ) return result; if ( !qt_xdnd_target_data ) qt_xdnd_target_data = new QIntDict<QByteArray>( 17 ); if ( qt_xdnd_target_data->find( (int)*a ) ) { result = *(qt_xdnd_target_data->find( (int)*a )); } else { if ( XGetSelectionOwner( qt_xdisplay(), qt_xdnd_selection ) == None ) return result; // should never happen? QWidget* tw = qt_xdnd_current_widget; if ( !tw || qt_xdnd_current_widget->isDesktop() ) { tw = new QWidget; } XConvertSelection( qt_xdisplay(), qt_xdnd_selection, *a, qt_xdnd_selection, tw->winId(), CurrentTime ); XFlush( qt_xdisplay() ); XEvent xevent; bool got=qt_xclb_wait_for_event( qt_xdisplay(), tw->winId(), SelectionNotify, &xevent, 5000); if ( got ) { Atom type; if ( qt_xclb_read_property( qt_xdisplay(), tw->winId(), qt_xdnd_selection, TRUE, &result, 0, &type, 0, FALSE ) ) { if ( type == qt_incr_atom ) { int nbytes = result.size() >= 4 ? *((int*)result.data()) : 0; result = qt_xclb_read_incremental_property( qt_xdisplay(), tw->winId(), qt_xdnd_selection, nbytes, FALSE ); } else if ( type != *a ) { // (includes None) debug( "Qt clipboard: unknown atom %ld", type); } if ( type != None ) qt_xdnd_target_data->insert( (int)((long)a), new QByteArray(result) ); } } if ( !qt_xdnd_current_widget || qt_xdnd_current_widget->isDesktop() ) { delete tw; } } return result; }