void WebDragClient::startDrag(DragImageRef image, const IntPoint& imageOrigin, const IntPoint& dragPoint, DataTransfer& dataTransfer, Frame& frame, bool isLink) { //FIXME: Allow UIDelegate to override behaviour <rdar://problem/5015953> //We liberally protect everything, to protect against a load occurring mid-drag RefPtr<Frame> frameProtector = &frame; COMPtr<IDragSourceHelper> helper; COMPtr<IDataObject> dataObject; COMPtr<WebView> viewProtector = m_webView; COMPtr<IDropSource> source; if (FAILED(WebDropSource::createInstance(m_webView, &source))) return; dataObject = dataTransfer.pasteboard().dataObject(); if (source && (image || dataObject)) { if (image) { if(SUCCEEDED(CoCreateInstance(CLSID_DragDropHelper, 0, CLSCTX_INPROC_SERVER, IID_IDragSourceHelper,(LPVOID*)&helper))) { BITMAP b; GetObject(image, sizeof(BITMAP), &b); SHDRAGIMAGE sdi; sdi.sizeDragImage.cx = b.bmWidth; sdi.sizeDragImage.cy = b.bmHeight; sdi.crColorKey = 0xffffffff; sdi.hbmpDragImage = image; sdi.ptOffset.x = dragPoint.x() - imageOrigin.x(); sdi.ptOffset.y = dragPoint.y() - imageOrigin.y(); if (isLink) sdi.ptOffset.y = b.bmHeight - sdi.ptOffset.y; helper->InitializeFromBitmap(&sdi, dataObject.get()); } } DWORD okEffect = draggingSourceOperationMaskToDragCursors(m_webView->page()->dragController().sourceDragOperation()); DWORD effect = DROPEFFECT_NONE; COMPtr<IWebUIDelegate> ui; HRESULT hr = E_NOTIMPL; if (SUCCEEDED(m_webView->uiDelegate(&ui))) { COMPtr<IWebUIDelegatePrivate> uiPrivate; if (SUCCEEDED(ui->QueryInterface(IID_IWebUIDelegatePrivate, (void**)&uiPrivate))) hr = uiPrivate->doDragDrop(m_webView, dataObject.get(), source.get(), okEffect, &effect); } if (hr == E_NOTIMPL) hr = DoDragDrop(dataObject.get(), source.get(), okEffect, &effect); DragOperation operation = DragOperationNone; if (hr == DRAGDROP_S_DROP) { if (effect & DROPEFFECT_COPY) operation = DragOperationCopy; else if (effect & DROPEFFECT_LINK) operation = DragOperationLink; else if (effect & DROPEFFECT_MOVE) operation = DragOperationMove; } frame.eventHandler().dragSourceEndedAt(generateMouseEvent(m_webView, false), operation); } }
void WebPageProxy::startDragDrop(const IntPoint& imageOrigin, const IntPoint& dragPoint, uint64_t okEffect, const HashMap<UINT, Vector<String> >& dataMap, uint64_t fileSize, const String& pathname, const SharedMemory::Handle& fileContentHandle, const IntSize& dragImageSize, const SharedMemory::Handle& dragImageHandle, bool isLinkDrag) { COMPtr<WCDataObject> dataObject; WCDataObject::createInstance(&dataObject, dataMap); if (fileSize) { RefPtr<SharedMemory> fileContentBuffer = SharedMemory::create(fileContentHandle, SharedMemory::ReadOnly); setFileDescriptorData(dataObject.get(), fileSize, pathname); setFileContentData(dataObject.get(), fileSize, fileContentBuffer->data()); } RefPtr<SharedMemory> memoryBuffer = SharedMemory::create(dragImageHandle, SharedMemory::ReadOnly); if (!memoryBuffer) return; RefPtr<WebDragSource> source = WebDragSource::createInstance(); if (!source) return; COMPtr<IDragSourceHelper> helper; if (FAILED(::CoCreateInstance(CLSID_DragDropHelper, 0, CLSCTX_INPROC_SERVER, IID_IDragSourceHelper, reinterpret_cast<LPVOID*>(&helper)))) return; BitmapInfo bitmapInfo = BitmapInfo::create(dragImageSize); void* bits; OwnPtr<HBITMAP> hbmp = adoptPtr(::CreateDIBSection(0, &bitmapInfo, DIB_RGB_COLORS, &bits, 0, 0)); memcpy(bits, memoryBuffer->data(), memoryBuffer->size()); SHDRAGIMAGE sdi; sdi.sizeDragImage.cx = bitmapInfo.bmiHeader.biWidth; sdi.sizeDragImage.cy = bitmapInfo.bmiHeader.biHeight; sdi.crColorKey = 0xffffffff; sdi.hbmpDragImage = hbmp.leakPtr(); sdi.ptOffset.x = dragPoint.x() - imageOrigin.x(); sdi.ptOffset.y = dragPoint.y() - imageOrigin.y(); if (isLinkDrag) sdi.ptOffset.y = bitmapInfo.bmiHeader.biHeight - sdi.ptOffset.y; helper->InitializeFromBitmap(&sdi, dataObject.get()); DWORD effect = DROPEFFECT_NONE; DragOperation operation = DragOperationNone; if (::DoDragDrop(dataObject.get(), source.get(), okEffect, &effect) == DRAGDROP_S_DROP) { if (effect & DROPEFFECT_COPY) operation = DragOperationCopy; else if (effect & DROPEFFECT_LINK) operation = DragOperationLink; else if (effect & DROPEFFECT_MOVE) operation = DragOperationMove; } POINT globalPoint; ::GetCursorPos(&globalPoint); POINT localPoint = globalPoint; ::ScreenToClient(m_pageClient->nativeWindow(), &localPoint); dragEnded(localPoint, globalPoint, operation); }
void WebDragClient::startDrag(DragImageRef image, const IntPoint& imageOrigin, const IntPoint& dragPoint, Clipboard* clipboard, Frame* frame, bool isLink) { //FIXME: Allow UIDelegate to override behaviour <rdar://problem/5015953> //We liberally protect everything, to protect against a load occurring mid-drag RefPtr<Frame> frameProtector = frame; COMPtr<IDragSourceHelper> helper; COMPtr<IDataObject> dataObject; COMPtr<WebView> viewProtector = m_webView; COMPtr<IDropSource> source; if (FAILED(WebDropSource::createInstance(m_webView, &source))) return; dataObject = static_cast<ClipboardWin*>(clipboard)->dataObject(); if (source && (image || dataObject)) { if (image) { if(SUCCEEDED(CoCreateInstance(CLSID_DragDropHelper, 0, CLSCTX_INPROC_SERVER, IID_IDragSourceHelper,(LPVOID*)&helper))) { BITMAP b; GetObject(image, sizeof(BITMAP), &b); SHDRAGIMAGE sdi; sdi.sizeDragImage.cx = b.bmWidth; sdi.sizeDragImage.cy = b.bmHeight; sdi.crColorKey = 0xffffffff; sdi.hbmpDragImage = image; sdi.ptOffset.x = dragPoint.x() - imageOrigin.x(); sdi.ptOffset.y = dragPoint.y() - imageOrigin.y(); if (isLink) sdi.ptOffset.y = b.bmHeight - sdi.ptOffset.y; helper->InitializeFromBitmap(&sdi, dataObject.get()); } } //FIXME: Ensure correct drag ops are available <rdar://problem/5015957> DWORD okEffect = DROPEFFECT_COPY | DROPEFFECT_LINK | DROPEFFECT_MOVE; DWORD effect; COMPtr<IWebUIDelegate> ui; if (SUCCEEDED(m_webView->uiDelegate(&ui))) { COMPtr<IWebUIDelegatePrivate> uiPrivate; if (SUCCEEDED(ui->QueryInterface(IID_IWebUIDelegatePrivate, (void**)&uiPrivate))) if (SUCCEEDED(uiPrivate->doDragDrop(m_webView, dataObject.get(), source.get(), okEffect, &effect))) return; } DoDragDrop(dataObject.get(), source.get(), okEffect, &effect); } }