/*
 * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

#include "awt.h"
#include "jlong.h"
#include "awt_DataTransferer.h"
#include "awt_DnDDS.h"
#include "awt_DnDDT.h"
#include "awt_Cursor.h"
#include "awt_Toolkit.h"
#include "awt_Component.h"

#include "java_awt_event_InputEvent.h"
#include "java_awt_dnd_DnDConstants.h"
#include "sun_awt_dnd_SunDragSourceContextPeer.h"
#include "sun_awt_windows_WDragSourceContextPeer.h"

#include <memory.h>
#include <shlobj.h>

#define GALLOCFLG (GMEM_DDESHARE | GMEM_MOVEABLE | GMEM_ZEROINIT)
#define JAVA_BUTTON_MASK (java_awt_event_InputEvent_BUTTON1_DOWN_MASK | \
                          java_awt_event_InputEvent_BUTTON2_DOWN_MASK | \
                          java_awt_event_InputEvent_BUTTON3_DOWN_MASK)

extern "C" {
DWORD __cdecl convertActionsToDROPEFFECT(jint actions);
jint  __cdecl convertDROPEFFECTToActions(DWORD effects);
}

typedef struct {
    AwtDragSource* dragSource;
    jobject        cursor;
} StartDragRec;

/**
 * StartDrag
 */

void AwtDragSource::StartDrag(AwtDragSource* self, jobject cursor) {
    StartDragRec* sdrp = new StartDragRec;
    sdrp->dragSource = self;
    sdrp->cursor = cursor;

    AwtToolkit::GetInstance().WaitForSingleObject(self->m_mutex);

    AwtToolkit::GetInstance().InvokeFunctionLater((void (*)(void *))&AwtDragSource::_DoDragDrop, (void *)sdrp);

    self->WaitUntilSignalled(FALSE);
}

/**
 * DoDragDrop - called from message pump thread
 */

void AwtDragSource::_DoDragDrop(void* param) {
    StartDragRec*  sdrp         = (StartDragRec*)param;
    AwtDragSource* dragSource   = sdrp->dragSource;
    DWORD          effects      = DROPEFFECT_NONE;
    JNIEnv*        env          = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    jobject        peer         = env->NewLocalRef(dragSource->GetPeer());

    dragSource->SetCursor(sdrp->cursor);
    env->DeleteGlobalRef(sdrp->cursor);
    delete sdrp;

    HRESULT        res;

    // StartDrag has caused dragSource->m_mutex to be held by our thread now

    AwtDropTarget::SetCurrentDnDDataObject(dragSource);

    ::GetCursorPos(&dragSource->m_dragPoint);

    dragSource->Signal();

    res = ::DoDragDrop(dragSource,
                       dragSource,
                       convertActionsToDROPEFFECT(dragSource->m_actions),
                       &effects
          );

    if (effects == DROPEFFECT_NONE && dragSource->m_dwPerformedDropEffect != DROPEFFECT_NONE) {
        effects = dragSource->m_dwPerformedDropEffect;
    }
    dragSource->m_dwPerformedDropEffect = DROPEFFECT_NONE;

    call_dSCddfinished(env, peer, res == DRAGDROP_S_DROP && effects != DROPEFFECT_NONE,
                       convertDROPEFFECTToActions(effects),
                       dragSource->m_dragPoint.x, dragSource->m_dragPoint.y);

    env->DeleteLocalRef(peer);

    DASSERT(AwtDropTarget::IsCurrentDnDDataObject(dragSource));
    AwtDropTarget::SetCurrentDnDDataObject(NULL);

    dragSource->Release();
}

/**
 * constructor
 */

AwtDragSource::AwtDragSource(JNIEnv* env, jobject peer, jobject component,
                             jobject transferable, jobject trigger,
                             jint actions, jlongArray formats,
                             jobject formatMap) {
    m_peer      = env->NewGlobalRef(peer);

    m_refs      = 1;

    m_actions   = actions;

    m_ntypes    = 0;

    m_initmods  = 0;
    m_lastmods  = 0;

    m_droptarget   = NULL;
    m_enterpending = TRUE;

    m_cursor     = NULL;

    m_mutex      = ::CreateMutex(NULL, FALSE, NULL);

    m_component     = env->NewGlobalRef(component);
    m_transferable  = env->NewGlobalRef(transferable);
    m_formatMap     = env->NewGlobalRef(formatMap);

    m_dragPoint.x = 0;
    m_dragPoint.y = 0;

    m_fNC         = TRUE;
    m_dropPoint.x = 0;
    m_dropPoint.y = 0;

    m_dwPerformedDropEffect = DROPEFFECT_NONE;
    m_bRestoreNodropCustomCursor = FALSE;

    LoadCache(formats);
}

/**
 * destructor
 */

AwtDragSource::~AwtDragSource() {
    JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    // fix for 6212440: on application shutdown, this object's
    // destruction might be suppressed due to dangling COM references.
    // On destruction, VM might be shut down already, so we should make
    // a null check on env.
    if (env) {
        env->DeleteGlobalRef(m_peer);
        env->DeleteGlobalRef(m_component);
        env->DeleteGlobalRef(m_transferable);
        env->DeleteGlobalRef(m_formatMap);
    }

    ::CloseHandle(m_mutex);

    UnloadCache();
}

/**
 * _compar
 *
 * compare format's then tymed's .... only one tymed bit may be set
 * at any time in a FORMATETC in the cache.
 */

int AwtDragSource::_compar(const void* first, const void* second) {
    FORMATETC *fp = (FORMATETC *)first;
    FORMATETC *sp = (FORMATETC *)second;
    int      r  = fp->cfFormat - sp->cfFormat;

    return r != 0 ? r : fp->tymed - sp->tymed;
}

/**
 * LoadCache
 */

void AwtDragSource::LoadCache(jlongArray formats) {
    JNIEnv*      env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    unsigned int items = 0;
    unsigned int i = 0;
    unsigned int idx = 0;

    if (m_types != (FORMATETC *)NULL) {
        UnloadCache();
    }

    items = env->GetArrayLength(formats);

    if (items == 0) {
        return;
    }

    jboolean isCopy;
    jlong *lFormats = env->GetLongArrayElements(formats, &isCopy),
        *saveFormats = lFormats;

    for (i = 0, m_ntypes = 0; i < items; i++, lFormats++) {
        // Warning C4244.
        // Cast from jlong to CLIPFORMAT (WORD).
        CLIPFORMAT fmt = (CLIPFORMAT)*lFormats;
        switch (fmt) {
        case CF_ENHMETAFILE:
            m_ntypes++;    // Only TYMED_ENHMF
            break;
        case CF_METAFILEPICT:
            m_ntypes++;    // Only TYMED_MFPICT
            break;
        case CF_HDROP:
            m_ntypes++;    // Only TYMED_HGLOBAL
            break;
        default:
            m_ntypes += 2; // TYMED_HGLOBAL and TYMED_ISTREAM
            break;
        }
    }

    try {
        m_types = (FORMATETC *)safe_Calloc(sizeof(FORMATETC), m_ntypes);
    } catch (std::bad_alloc&) {
        m_ntypes = 0;
        throw;
    }

    lFormats = saveFormats;

    for (i = 0, idx = 0; i < items; i++, lFormats++) {
        // Warning C4244.
        // Cast from jlong to CLIPFORMAT (WORD).
        CLIPFORMAT fmt = (CLIPFORMAT)*lFormats;

        m_types[idx].cfFormat = fmt;
        m_types[idx].dwAspect = DVASPECT_CONTENT;
        m_types[idx].lindex   = -1;

        switch (fmt) {
        default:
            m_types[idx].tymed = TYMED_ISTREAM;
            idx++;

            // now make a copy, but with a TYMED of HGLOBAL
            memcpy(m_types + idx, m_types + idx - 1, sizeof(FORMATETC));
        case CF_HDROP:
            m_types[idx].tymed = TYMED_HGLOBAL;
            idx++;
            break;
        case CF_ENHMETAFILE:
            m_types[idx].tymed = TYMED_ENHMF;
            idx++;
            break;
        case CF_METAFILEPICT:
            m_types[idx].tymed = TYMED_MFPICT;
            idx++;
            break;
        }
    }
    DASSERT(idx == m_ntypes);

    env->ReleaseLongArrayElements(formats, saveFormats, 0);

    // sort them in ascending order of format
    qsort((void *)m_types, (size_t)m_ntypes, (size_t)sizeof(FORMATETC),
          _compar);
}

/**
 * UnloadCache
 */

void AwtDragSource::UnloadCache() {
    if (m_ntypes == 0) {
        return;
    }

    free((void*)m_types);
    m_ntypes = 0;
    m_types  = (FORMATETC *)NULL;
}

/**
 * ChangeCursor
 */
HRESULT AwtDragSource::ChangeCursor()
{
    if (m_cursor != NULL) {
        ::SetCursor(m_cursor->GetHCursor());
        return S_OK;
    }
    return DRAGDROP_S_USEDEFAULTCURSORS;
}

/**
 * SetCursor
 */
void AwtDragSource::SetCursor(jobject cursor) {
    JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    if (JNU_IsNull(env, cursor)) {
        m_cursor = NULL;
        return;
    }

    jlong pData = env->GetLongField(cursor, AwtCursor::pDataID);
    // Warning C4312.
    // Cast jlong (__int64) to pointer.
    m_cursor = (AwtCursor*)pData;

    if (m_cursor == NULL) {
        m_cursor = AwtCursor::CreateSystemCursor(cursor);
    }
}

/**
 * MatchFormatEtc
 */

HRESULT __stdcall
AwtDragSource::MatchFormatEtc(FORMATETC __RPC_FAR *pFormatEtcIn,
                              FORMATETC *cacheEnt) {
    TRY;

    if ((pFormatEtcIn->tymed & (TYMED_HGLOBAL | TYMED_ISTREAM | TYMED_ENHMF |
                                TYMED_MFPICT)) == 0) {
        return DV_E_TYMED;
    } else if (pFormatEtcIn->lindex != -1) {
        return DV_E_LINDEX;
    } else if (pFormatEtcIn->dwAspect != DVASPECT_CONTENT) {
        return DV_E_DVASPECT;
    }

    FORMATETC tmp;
    memcpy(&tmp, pFormatEtcIn, sizeof(FORMATETC));

    static const DWORD supportedTymeds[] =
        { TYMED_ISTREAM, TYMED_HGLOBAL, TYMED_ENHMF, TYMED_MFPICT };
    static const int nSupportedTymeds = 4;

    for (int i = 0; i < nSupportedTymeds; i++) {
        /*
         * Fix for BugTraq Id 4426805.
         * Match only if the tymed is supported by the requestor.
         */
        if ((pFormatEtcIn->tymed & supportedTymeds[i]) == 0) {
            continue;
        }

        tmp.tymed = supportedTymeds[i];
        FORMATETC *cp = (FORMATETC *)bsearch((const void *)&tmp,
                                             (const void *)m_types,
                                             (size_t)      m_ntypes,
                                             (size_t)      sizeof(FORMATETC),
                                                           _compar
                                             );
        if (cp != (FORMATETC *)NULL) {
            if (cacheEnt != (FORMATETC *)NULL) {
                memcpy(cacheEnt, cp, sizeof(FORMATETC));
            }
            return S_OK;
        }
    }

    return DV_E_FORMATETC;

    CATCH_BAD_ALLOC_RET(E_OUTOFMEMORY);
}

/**
 * QueryInterface
 */

HRESULT __stdcall AwtDragSource::QueryInterface(REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject) {
    TRY;

    if (riid == IID_IUnknown) {
        *ppvObject = (void __RPC_FAR *__RPC_FAR)(IUnknown*)(IDropSource*)this;
        AddRef();
        return S_OK;
    } else if (riid == IID_IDropSource) {
        *ppvObject = (void __RPC_FAR *__RPC_FAR)(IDropSource*)this;
        AddRef();
        return S_OK;
    } else if (riid == IID_IDataObject) {
        *ppvObject = (void __RPC_FAR *__RPC_FAR)(IDataObject*)this;
        AddRef();
        return S_OK;
    } else {
        *ppvObject = (void __RPC_FAR *__RPC_FAR)NULL;
        return E_NOINTERFACE;
    }

    CATCH_BAD_ALLOC_RET(E_OUTOFMEMORY);
}

/**
 * AddRef
 */

ULONG __stdcall AwtDragSource::AddRef() {
    return (ULONG)++m_refs;
}

/**
 * Release
 */

ULONG __stdcall AwtDragSource::Release() {
    int refs;

    if ((refs = --m_refs) == 0) delete this;

    return (ULONG)refs;
}

/**
 * QueryContinueDrag
 */

HRESULT __stdcall  AwtDragSource::QueryContinueDrag(BOOL fEscapeKeyPressed, DWORD grfKeyState) {
    TRY;

    JNIEnv* env       = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    if (fEscapeKeyPressed)
        return DRAGDROP_S_CANCEL;

    jint modifiers = AwtComponent::GetJavaModifiers();

    POINT dragPoint;

    ::GetCursorPos(&dragPoint);

    if ( (dragPoint.x != m_dragPoint.x || dragPoint.y != m_dragPoint.y) &&
         m_lastmods == modifiers) {//cannot move before cursor change
        call_dSCmouseMoved(env, m_peer,
                           m_actions, modifiers, dragPoint.x, dragPoint.y);
        m_dragPoint = dragPoint;
    }

    if ((modifiers & JAVA_BUTTON_MASK) == 0) {
        return DRAGDROP_S_DROP;
    } else if (m_initmods == 0) {
        m_initmods = modifiers;
    } else if ((modifiers & JAVA_BUTTON_MASK) != (m_initmods & JAVA_BUTTON_MASK)) {
        return DRAGDROP_S_CANCEL;
    } else if (m_lastmods != modifiers) {
        call_dSCchanged(env, m_peer,
                        m_actions, modifiers, dragPoint.x, dragPoint.y);
        m_bRestoreNodropCustomCursor = TRUE;
    }

    m_lastmods = modifiers;

    //CR 6480706 - MS Bug on hold
    HCURSOR hNeedCursor;
    if(
        m_bRestoreNodropCustomCursor &&
        m_cursor != NULL &&
        (hNeedCursor = m_cursor->GetHCursor()) != ::GetCursor() )
    {
        ChangeCursor();
        m_bRestoreNodropCustomCursor = FALSE;
    }
    return S_OK;

   CATCH_BAD_ALLOC_RET(E_OUTOFMEMORY);
}

/**
 * GiveFeedback
 */

HRESULT __stdcall  AwtDragSource::GiveFeedback(DWORD dwEffect) {
    TRY;

    JNIEnv* env       = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    jint    modifiers = 0;
    SHORT   mods = 0;

    m_actions = convertDROPEFFECTToActions(dwEffect);

    if (::GetKeyState(VK_LBUTTON) & 0xff00) {
        mods |= MK_LBUTTON;
    } else if (::GetKeyState(VK_MBUTTON) & 0xff00) {
        mods |= MK_MBUTTON;
    } else if (::GetKeyState(VK_RBUTTON) & 0xff00) {
        mods |= MK_RBUTTON;
    }

    if (::GetKeyState(VK_SHIFT)   & 0xff00)
        mods |= MK_SHIFT;
    if (::GetKeyState(VK_CONTROL) & 0xff00)
        mods |= MK_CONTROL;
    if (::GetKeyState(VK_MENU) & 0xff00)
        mods |= MK_ALT;

    modifiers = AwtComponent::GetJavaModifiers();

    POINT curs;

    ::GetCursorPos(&curs);

    m_droptarget = ::WindowFromPoint(curs);

    int invalid = (dwEffect == DROPEFFECT_NONE);

    if (invalid) {
        // Don't call dragExit if dragEnter and dragOver haven't been called.
        if (!m_enterpending) {
            call_dSCexit(env, m_peer, curs.x, curs.y);
        }
        m_droptarget = (HWND)NULL;
        m_enterpending = TRUE;
    } else if (m_droptarget != NULL) {
        (*(m_enterpending ? call_dSCenter : call_dSCmotion))
            (env, m_peer, m_actions, modifiers, curs.x, curs.y);

        m_enterpending = FALSE;
    }

    if (m_droptarget != NULL) {
        RECT  rect;
        POINT client = curs;
        VERIFY(::ScreenToClient(m_droptarget, &client));
        VERIFY(::GetClientRect(m_droptarget, &rect));
        if (::PtInRect(&rect, client)) {
            m_fNC = FALSE;
            m_dropPoint = client;
        } else {
            m_fNC = TRUE;
            m_dropPoint = curs;
        }
    } else {
        m_fNC = TRUE;
        m_dropPoint.x = 0;
        m_dropPoint.y = 0;
    }

    m_bRestoreNodropCustomCursor = (dwEffect == DROPEFFECT_NONE);

    return ChangeCursor();

    CATCH_BAD_ALLOC_RET(E_OUTOFMEMORY);
}


/**
 * GetData
 */

HRESULT __stdcall AwtDragSource::GetData(FORMATETC __RPC_FAR *pFormatEtc,
                                         STGMEDIUM __RPC_FAR *pmedium) {
    TRY;

    HRESULT res = GetProcessId(pFormatEtc, pmedium);
    if (res == S_OK) {
        return res;
    }

    FORMATETC matchedFormatEtc;
    res = MatchFormatEtc(pFormatEtc, &matchedFormatEtc);
    if (res != S_OK) {
        return res;
    }

    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    if (env->PushLocalFrame(2) < 0) {
        return E_OUTOFMEMORY;
    }

    jbyteArray bytes =
        AwtDataTransferer::ConvertData(env, m_component, m_transferable,
                                       (jlong)matchedFormatEtc.cfFormat,
                                       m_formatMap);
    if (!JNU_IsNull(env, safe_ExceptionOccurred(env))) {
        env->ExceptionDescribe();
        env->ExceptionClear();
        env->PopLocalFrame(NULL);
        return E_UNEXPECTED;
    }
    if (bytes == NULL) {
        env->PopLocalFrame(NULL);
        return E_UNEXPECTED;
    }

    jint nBytes = env->GetArrayLength(bytes);

    if ((matchedFormatEtc.tymed & TYMED_ISTREAM) != 0) {
        ADSIStreamProxy *istream = new ADSIStreamProxy(this, bytes, nBytes);

        if (!JNU_IsNull(env, safe_ExceptionOccurred(env))) {
            env->ExceptionDescribe();
            env->ExceptionClear();
            env->PopLocalFrame(NULL);
            return E_UNEXPECTED;
        }

        pmedium->tymed = TYMED_ISTREAM;
        pmedium->pstm = istream;
        pmedium->pUnkForRelease = (IUnknown *)NULL;

        env->PopLocalFrame(NULL);
        return S_OK;
    } else if ((matchedFormatEtc.tymed & TYMED_HGLOBAL) != 0) {
        HGLOBAL copy = ::GlobalAlloc(GALLOCFLG, nBytes +
                                     ((matchedFormatEtc.cfFormat == CF_HDROP)
                                          ? sizeof(DROPFILES)
                                          : 0));
        if (copy == NULL) {
            env->PopLocalFrame(NULL);
            throw std::bad_alloc();
        }

        char *dataout = (char *)::GlobalLock(copy);

        if (matchedFormatEtc.cfFormat == CF_HDROP) {
            DROPFILES *dropfiles = (DROPFILES *)dataout;
            dropfiles->pFiles = sizeof(DROPFILES);
            dropfiles->pt.x = m_dropPoint.x;
            dropfiles->pt.y = m_dropPoint.y;
            dropfiles->fNC = m_fNC;
            dropfiles->fWide = TRUE; // good guess!
            dataout += sizeof(DROPFILES);
        }

        env->GetByteArrayRegion(bytes, 0, nBytes, (jbyte *)dataout);
        ::GlobalUnlock(copy);

        pmedium->tymed = TYMED_HGLOBAL;
        pmedium->hGlobal = copy;
        pmedium->pUnkForRelease = (IUnknown *)NULL;

        env->PopLocalFrame(NULL);
        return S_OK;
    } else if ((matchedFormatEtc.tymed & TYMED_ENHMF) != 0) {
        LPBYTE lpbEmfBuffer =
            (LPBYTE)env->GetPrimitiveArrayCritical(bytes, NULL);
        if (lpbEmfBuffer == NULL) {
            env->PopLocalFrame(NULL);
            throw std::bad_alloc();
        }

        HENHMETAFILE hemf = ::SetEnhMetaFileBits(nBytes, lpbEmfBuffer);

        env->ReleasePrimitiveArrayCritical(bytes, (LPVOID)lpbEmfBuffer, JNI_ABORT);

        if (hemf == NULL) {
            env->PopLocalFrame(NULL);
            return E_UNEXPECTED;
        }

        pmedium->tymed = TYMED_ENHMF;
        pmedium->hEnhMetaFile = hemf;
        pmedium->pUnkForRelease = (IUnknown *)NULL;

        env->PopLocalFrame(NULL);
        return S_OK;
    } else if ((matchedFormatEtc.tymed & TYMED_MFPICT) != 0) {
        LPBYTE lpbMfpBuffer =
            (LPBYTE)env->GetPrimitiveArrayCritical(bytes, NULL);
        if (lpbMfpBuffer == NULL) {
            env->PopLocalFrame(NULL);
            throw std::bad_alloc();
        }

        HMETAFILE hmf = ::SetMetaFileBitsEx(nBytes - sizeof(METAFILEPICT),
                                         lpbMfpBuffer + sizeof(METAFILEPICT));
        if (hmf == NULL) {
            env->ReleasePrimitiveArrayCritical(bytes, (LPVOID)lpbMfpBuffer, JNI_ABORT);
            env->PopLocalFrame(NULL);
            return E_UNEXPECTED;
        }

        LPMETAFILEPICT lpMfpOld = (LPMETAFILEPICT)lpbMfpBuffer;

        HMETAFILEPICT hmfp = ::GlobalAlloc(GALLOCFLG, sizeof(METAFILEPICT));
        if (hmfp == NULL) {
            VERIFY(::DeleteMetaFile(hmf));
            env->ReleasePrimitiveArrayCritical(bytes, (LPVOID)lpbMfpBuffer, JNI_ABORT);
            env->PopLocalFrame(NULL);
            throw std::bad_alloc();
        }

        LPMETAFILEPICT lpMfp = (LPMETAFILEPICT)::GlobalLock(hmfp);
        lpMfp->mm = lpMfpOld->mm;
        lpMfp->xExt = lpMfpOld->xExt;
        lpMfp->yExt = lpMfpOld->yExt;
        lpMfp->hMF = hmf;
        ::GlobalUnlock(hmfp);

        env->ReleasePrimitiveArrayCritical(bytes, (LPVOID)lpbMfpBuffer, JNI_ABORT);

        pmedium->tymed = TYMED_MFPICT;
        pmedium->hMetaFilePict = hmfp;
        pmedium->pUnkForRelease = (IUnknown *)NULL;

        env->PopLocalFrame(NULL);
        return S_OK;
    }

    env->PopLocalFrame(NULL);
    return DV_E_TYMED;

    CATCH_BAD_ALLOC_RET(E_OUTOFMEMORY);
}

/**
 * GetDataHere
 */

HRESULT __stdcall AwtDragSource::GetDataHere(FORMATETC __RPC_FAR *pFormatEtc,
                                             STGMEDIUM __RPC_FAR *pmedium) {
    TRY;

    if (pmedium->pUnkForRelease != (IUnknown *)NULL) {
        return E_INVALIDARG;
    }

    HRESULT res = GetProcessId(pFormatEtc, pmedium);
    if (res == S_OK) {
        return res;
    }

    FORMATETC matchedFormatEtc;
    res = MatchFormatEtc(pFormatEtc, &matchedFormatEtc);
    if (res != S_OK) {
        return res;
    }

    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    if (env->PushLocalFrame(2) < 0) {
        return E_OUTOFMEMORY;
    }

    jbyteArray bytes =
        AwtDataTransferer::ConvertData(env, m_component, m_transferable,
                                       (jlong)matchedFormatEtc.cfFormat,
                                       m_formatMap);
    if (!JNU_IsNull(env, safe_ExceptionOccurred(env))) {
        env->ExceptionDescribe();
        env->ExceptionClear();
        env->PopLocalFrame(NULL);
        return E_UNEXPECTED;
    }
    if (bytes == NULL) {
        env->PopLocalFrame(NULL);
        return E_UNEXPECTED;
    }

    jint nBytes = env->GetArrayLength(bytes);

    // NOTE: TYMED_ENHMF and TYMED_MFPICT are not valid for GetDataHere().
    if ((matchedFormatEtc.tymed & TYMED_ISTREAM) != 0) {
        jboolean isCopy;
        jbyte *bBytes = env->GetByteArrayElements(bytes, &isCopy);

        ULONG act;
        HRESULT res = pmedium->pstm->Write((const void *)bBytes, (ULONG)nBytes,
                                           &act);

        env->ReleaseByteArrayElements(bytes, bBytes, JNI_ABORT);

        env->PopLocalFrame(NULL);
        return S_OK;
    } else if ((matchedFormatEtc.tymed & TYMED_HGLOBAL) != 0) {
        ::SetLastError(0); // clear error
        // Warning C4244.
        SIZE_T mBytes = ::GlobalSize(pmedium->hGlobal);
        if (::GetLastError() != 0) {
            env->PopLocalFrame(NULL);
            return E_UNEXPECTED;
        }

        if (nBytes + ((matchedFormatEtc.cfFormat == CF_HDROP)
                        ? sizeof(DROPFILES) : 0) > mBytes) {
            env->PopLocalFrame(NULL);
            return STG_E_MEDIUMFULL;
        }

        char *dataout = (char *)::GlobalLock(pmedium->hGlobal);

        if (matchedFormatEtc.cfFormat == CF_HDROP) {
            DROPFILES *dropfiles = (DROPFILES *)dataout;
            dropfiles->pFiles = sizeof(DROPFILES);
            dropfiles->pt.x = m_dropPoint.x;
            dropfiles->pt.y = m_dropPoint.y;
            dropfiles->fNC = m_fNC;
            dropfiles->fWide = TRUE; // good guess!
            dataout += sizeof(DROPFILES);
        }

        env->GetByteArrayRegion(bytes, 0, nBytes, (jbyte *)dataout);
        ::GlobalUnlock(pmedium->hGlobal);

        env->PopLocalFrame(NULL);
        return S_OK;
    }

    env->PopLocalFrame(NULL);
    return DV_E_TYMED;

    CATCH_BAD_ALLOC_RET(E_OUTOFMEMORY);
}

/**
 * QueryGetData
 */

HRESULT __stdcall  AwtDragSource::QueryGetData(FORMATETC __RPC_FAR *pFormatEtc) {
    TRY;

    return MatchFormatEtc(pFormatEtc, (FORMATETC *)NULL);

    CATCH_BAD_ALLOC_RET(E_OUTOFMEMORY);
}


/**
 * GetCanonicalFormatEtc
 */

HRESULT __stdcall  AwtDragSource::GetCanonicalFormatEtc(FORMATETC __RPC_FAR *pFormatEtcIn, FORMATETC __RPC_FAR *pFormatEtcOut) {
    TRY;

    HRESULT   res = MatchFormatEtc(pFormatEtcIn, (FORMATETC *)NULL);

    if (res != S_OK) return res;

    *pFormatEtcOut = *pFormatEtcIn;

    pFormatEtcOut->ptd = NULL;

    return DATA_S_SAMEFORMATETC;

    CATCH_BAD_ALLOC_RET(E_OUTOFMEMORY);
}

/**
 * SetData
 */

HRESULT __stdcall AwtDragSource::SetData(FORMATETC __RPC_FAR *pFormatEtc, STGMEDIUM __RPC_FAR *pmedium, BOOL fRelease) {
    static CLIPFORMAT CF_PERFORMEDDROPEFFECT = ::RegisterClipboardFormat(CFSTR_PERFORMEDDROPEFFECT);

    if (pFormatEtc->cfFormat == CF_PERFORMEDDROPEFFECT && pmedium->tymed == TYMED_HGLOBAL) {
        m_dwPerformedDropEffect = *(DWORD*)::GlobalLock(pmedium->hGlobal);
        ::GlobalUnlock(pmedium->hGlobal);
        if (fRelease) {
            ::ReleaseStgMedium(pmedium);
        }
        return S_OK;
    }
    return E_UNEXPECTED;
}

/**
 * EnumFormatEtc
 */

HRESULT __stdcall  AwtDragSource::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC *__RPC_FAR *ppenumFormatEtc) {
    TRY;

    *ppenumFormatEtc = new ADSIEnumFormatEtc(this);
    return S_OK;

    CATCH_BAD_ALLOC_RET(E_OUTOFMEMORY);
}

/**
 * DAdvise
 */

HRESULT __stdcall  AwtDragSource::DAdvise(FORMATETC __RPC_FAR *pFormatEtc, DWORD advf, IAdviseSink __RPC_FAR *pAdvSink, DWORD __RPC_FAR *pdwConnection) {
    return E_NOTIMPL;
}

/**
 * DUnadvise
 */

HRESULT __stdcall  AwtDragSource::DUnadvise(DWORD dwConnection) {
    return OLE_E_ADVISENOTSUPPORTED;
}

/**
 * EnumAdvise
 */

HRESULT __stdcall  AwtDragSource::EnumDAdvise(IEnumSTATDATA __RPC_FAR *__RPC_FAR *ppenumAdvise) {
    return OLE_E_ADVISENOTSUPPORTED;
}

const UINT AwtDragSource::PROCESS_ID_FORMAT =
    ::RegisterClipboardFormat(TEXT("_SUNW_JAVA_AWT_PROCESS_ID"));

HRESULT __stdcall AwtDragSource::GetProcessId(FORMATETC __RPC_FAR *pFormatEtc, STGMEDIUM __RPC_FAR *pmedium) {

    if ((pFormatEtc->tymed & TYMED_HGLOBAL) == 0) {
        return DV_E_TYMED;
    } else if (pFormatEtc->lindex != -1) {
        return DV_E_LINDEX;
    } else if (pFormatEtc->dwAspect != DVASPECT_CONTENT) {
        return DV_E_DVASPECT;
    } else if (pFormatEtc->cfFormat != PROCESS_ID_FORMAT) {
        return DV_E_FORMATETC;
    }

    DWORD id = ::CoGetCurrentProcess();

    HGLOBAL copy = ::GlobalAlloc(GALLOCFLG, sizeof(id));

    if (copy == NULL) {
        throw std::bad_alloc();
    }

    char *dataout = (char *)::GlobalLock(copy);

    memcpy(dataout, &id, sizeof(id));
    ::GlobalUnlock(copy);

    pmedium->tymed = TYMED_HGLOBAL;
    pmedium->hGlobal = copy;
    pmedium->pUnkForRelease = (IUnknown *)NULL;

    return S_OK;
}

DECLARE_JAVA_CLASS(dSCClazz, "sun/awt/windows/WDragSourceContextPeer")

void
AwtDragSource::call_dSCenter(JNIEnv* env, jobject self, jint targetActions,
                             jint modifiers, jint x, jint y) {
    DECLARE_VOID_JAVA_METHOD(dSCenter, dSCClazz, "dragEnter", "(IIII)V");
    DASSERT(!JNU_IsNull(env, self));
    env->CallVoidMethod(self, dSCenter, targetActions, modifiers, x, y);
    if (!JNU_IsNull(env, safe_ExceptionOccurred(env))) {
        env->ExceptionDescribe();
        env->ExceptionClear();
    }
}

void
AwtDragSource::call_dSCmotion(JNIEnv* env, jobject self, jint targetActions,
                              jint modifiers, jint x, jint y) {
    DECLARE_VOID_JAVA_METHOD(dSCmotion, dSCClazz, "dragMotion", "(IIII)V");
    DASSERT(!JNU_IsNull(env, self));
    env->CallVoidMethod(self, dSCmotion, targetActions, modifiers, x, y);
    if (!JNU_IsNull(env, safe_ExceptionOccurred(env))) {
        env->ExceptionDescribe();
        env->ExceptionClear();
    }
}

void
AwtDragSource::call_dSCchanged(JNIEnv* env, jobject self, jint targetActions,
                               jint modifiers, jint x, jint y) {
    DECLARE_VOID_JAVA_METHOD(dSCchanged, dSCClazz, "operationChanged",
                             "(IIII)V");
    DASSERT(!JNU_IsNull(env, self));
    env->CallVoidMethod(self, dSCchanged, targetActions, modifiers, x, y);
    if (!JNU_IsNull(env, safe_ExceptionOccurred(env))) {
        env->ExceptionDescribe();
        env->ExceptionClear();
    }
}

void
AwtDragSource::call_dSCexit(JNIEnv* env, jobject self, jint x, jint y) {
    DECLARE_VOID_JAVA_METHOD(dSCexit, dSCClazz, "dragExit", "(II)V");
    DASSERT(!JNU_IsNull(env, self));
    env->CallVoidMethod(self, dSCexit, x, y);
    if (!JNU_IsNull(env, safe_ExceptionOccurred(env))) {
        env->ExceptionDescribe();
        env->ExceptionClear();
    }
}

void
AwtDragSource::call_dSCddfinished(JNIEnv* env, jobject self, jboolean success,
                                  jint operations, jint x, jint y) {
    DECLARE_VOID_JAVA_METHOD(dSCddfinished, dSCClazz, "dragDropFinished", "(ZIII)V");
    DASSERT(!JNU_IsNull(env, self));
    env->CallVoidMethod(self, dSCddfinished, success, operations, x, y);
    if (!JNU_IsNull(env, safe_ExceptionOccurred(env))) {
        env->ExceptionDescribe();
        env->ExceptionClear();
    }
}

void
AwtDragSource::call_dSCmouseMoved(JNIEnv* env, jobject self, jint targetActions,
                                  jint modifiers, jint x, jint y) {
    DECLARE_VOID_JAVA_METHOD(dSCmouseMoved, dSCClazz, "dragMouseMoved",
                             "(IIII)V");
    DASSERT(!JNU_IsNull(env, self));
    env->CallVoidMethod(self, dSCmouseMoved, targetActions, modifiers, x, y);
    if (!JNU_IsNull(env, safe_ExceptionOccurred(env))) {
        env->ExceptionDescribe();
        env->ExceptionClear();
    }
}

DECLARE_JAVA_CLASS(awtIEClazz, "java/awt/event/InputEvent")

/**
 * Constructor
 */

AwtDragSource::ADSIEnumFormatEtc::ADSIEnumFormatEtc(AwtDragSource* parent) {
    m_parent = parent;
    m_idx    = 0;

    m_refs   = 0;

    m_parent->AddRef();

    AddRef();
}

/**
 * Destructor
 */

AwtDragSource::ADSIEnumFormatEtc::~ADSIEnumFormatEtc() {
    m_parent->Release();
}

/**
 * QueryInterface
 */

HRESULT __stdcall  AwtDragSource::ADSIEnumFormatEtc::QueryInterface(REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject) {
    TRY;

    if (riid == IID_IUnknown) {
        *ppvObject = (void __RPC_FAR *__RPC_FAR)(IUnknown*)this;
        AddRef();
        return S_OK;
    } else if (riid == IID_IEnumFORMATETC) {
        *ppvObject = (void __RPC_FAR *__RPC_FAR)(IEnumFORMATETC*)this;
        AddRef();
        return S_OK;
    } else {
        *ppvObject = (void __RPC_FAR *__RPC_FAR)NULL;
        return E_NOINTERFACE;
    }

    CATCH_BAD_ALLOC_RET(E_OUTOFMEMORY);
}

/**
 * AddRef
 */

ULONG __stdcall  AwtDragSource::ADSIEnumFormatEtc::AddRef(void) {
    return (ULONG)++m_refs;
}

/**
 * Release
 */

ULONG __stdcall  AwtDragSource::ADSIEnumFormatEtc::Release(void) {
    int refs;

    if ((refs = --m_refs) == 0) delete this;

    return (ULONG)refs;
}

/**
 * Next
 */

HRESULT _stdcall AwtDragSource::ADSIEnumFormatEtc::Next(ULONG celt, FORMATETC __RPC_FAR *rgelt, ULONG __RPC_FAR *pceltFetched) {
    TRY;

    unsigned int len = m_parent->getNTypes();
    unsigned int i;

    for (i = 0; i < celt && m_idx < len; i++, m_idx++) {
        FORMATETC fetc = m_parent->getType(m_idx);
        rgelt[i] = fetc;
    }

    if (pceltFetched != NULL) *pceltFetched = i;

    return i == celt ? S_OK : S_FALSE;

    CATCH_BAD_ALLOC_RET(E_OUTOFMEMORY);
}

/**
 * Skip
 */

HRESULT __stdcall  AwtDragSource::ADSIEnumFormatEtc::Skip(ULONG celt) {
    TRY;

    unsigned int len = m_parent->getNTypes();
    unsigned int tmp = m_idx + celt;

    if (tmp < len) {
        m_idx = tmp;

        return S_OK;
    } else {
        m_idx = len;

        return S_FALSE;
    }

    CATCH_BAD_ALLOC_RET(E_OUTOFMEMORY);
}

/**
 * Reset
 */

HRESULT __stdcall  AwtDragSource::ADSIEnumFormatEtc::Reset(void) {
    m_idx = 0;

    return S_OK;
}

/**
 * Clone
 */

HRESULT __stdcall  AwtDragSource::ADSIEnumFormatEtc::Clone(IEnumFORMATETC  __RPC_FAR *__RPC_FAR *ppenum) {
    TRY;

    *ppenum = new ADSIEnumFormatEtc(m_parent);
    (*ppenum)->Skip(m_idx);
    return S_OK;

    CATCH_BAD_ALLOC_RET(E_OUTOFMEMORY);
}

/**
 * constructor
 */

AwtDragSource::ADSIStreamProxy::ADSIStreamProxy(AwtDragSource* parent, jbyteArray buffer, jint blen) {
    JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    m_parent = parent;

    m_buffer = (signed char *)safe_Calloc(sizeof(signed char), m_blen = blen);

    env->GetByteArrayRegion(buffer, 0, blen, m_buffer);

    if (!JNU_IsNull(env, safe_ExceptionOccurred(env))) return;

    m_off     = 0;

    m_cloneof = (ADSIStreamProxy*)NULL;

    m_refs    = 0;

    FILETIME now;

    ::CoFileTimeNow(&now);

    m_statstg.pwcsName          = (LPWSTR)NULL;
    m_statstg.type              = STGTY_STREAM;
    m_statstg.cbSize.HighPart   = 0;
    m_statstg.cbSize.LowPart    = m_blen;
    m_statstg.mtime             = now;
    m_statstg.ctime             = now;
    m_statstg.atime             = now;
    m_statstg.grfMode           = STGM_READ;
    m_statstg.grfLocksSupported = FALSE;
    m_statstg.clsid             = CLSID_NULL;
    m_statstg.grfStateBits      = 0;
    m_statstg.reserved          = 0;

    m_parent->AddRef();

    AddRef();
}

/**
 * constructor (clone)
 */

AwtDragSource::ADSIStreamProxy::ADSIStreamProxy(ADSIStreamProxy* cloneof) {
    m_cloneof = cloneof;

    m_parent  = cloneof->m_parent;

    m_buffer  = cloneof->m_buffer;
    m_blen    = cloneof->m_blen;
    m_off     = cloneof->m_off;

    m_statstg = cloneof->m_statstg;

    m_refs    = 0;

    m_parent->AddRef();
    m_cloneof->AddRef();
}

/**
 * destructor
 */

AwtDragSource::ADSIStreamProxy::~ADSIStreamProxy() {
    if (m_cloneof == (ADSIStreamProxy*)NULL)
        free((void *)m_buffer);
    else {
        m_cloneof->Release();
    }

    m_parent->Release();
}

/**
 * QueryInterface
 */

HRESULT __stdcall  AwtDragSource::ADSIStreamProxy::QueryInterface(REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject) {
    TRY;

    if (riid == IID_IUnknown) {
        *ppvObject = (void __RPC_FAR *__RPC_FAR)(IUnknown*)this;
        AddRef();
        return S_OK;
    } else if (riid == IID_IStream) {
        *ppvObject = (void __RPC_FAR *__RPC_FAR)(IStream*)this;
        AddRef();
        return S_OK;
    } else {
        *ppvObject = (void __RPC_FAR *__RPC_FAR)NULL;
        return E_NOINTERFACE;
    }

    CATCH_BAD_ALLOC_RET(E_OUTOFMEMORY);
}

/**
 * AddRef
 */

ULONG __stdcall  AwtDragSource::ADSIStreamProxy::AddRef(void) {
    return (ULONG)++m_refs;
}

/**
 * Release
 */

ULONG __stdcall  AwtDragSource::ADSIStreamProxy::Release(void) {
    int refs;

    if ((refs = --m_refs) == 0) delete this;

    return (ULONG)refs;
}

/**
 * Read
 */

HRESULT __stdcall  AwtDragSource::ADSIStreamProxy::Read(void __RPC_FAR *pv, ULONG cb, ULONG __RPC_FAR *pcbRead) {
    TRY;

    unsigned int rem  = m_blen - m_off;
    int          read = cb > rem ? rem : cb;

    if (read > 0) memmove(pv, (void *)(m_buffer + m_off), read);

    m_off += read;

    if (pcbRead != (ULONG __RPC_FAR *)NULL) {
        *pcbRead = read;
    }

    FILETIME now; ::CoFileTimeNow(&now); m_statstg.atime = now;

    return S_OK;

    CATCH_BAD_ALLOC_RET(E_OUTOFMEMORY);
}

/**
 * Write
 */

HRESULT __stdcall  AwtDragSource::ADSIStreamProxy::Write(const void __RPC_FAR *pv, ULONG cb, ULONG __RPC_FAR *pcbWritten) {
    TRY;

    if (pcbWritten != (ULONG __RPC_FAR *)NULL) {
        *pcbWritten = 0;
    }

    FILETIME now; ::CoFileTimeNow(&now); m_statstg.atime = now;

    return STG_E_CANTSAVE; // dont support writing

    CATCH_BAD_ALLOC_RET(E_OUTOFMEMORY);
}

/**
 * Seek
 */

HRESULT __stdcall  AwtDragSource::ADSIStreamProxy::Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER __RPC_FAR *plibNewPosition) {
    TRY;

    if (dlibMove.HighPart != 0) return STG_E_INVALIDPOINTER;

    if (plibNewPosition != (ULARGE_INTEGER __RPC_FAR *)NULL) {
        plibNewPosition->HighPart = 0;
        plibNewPosition->LowPart  = 0;
    }

    switch (dwOrigin) {
        case STREAM_SEEK_SET: {
            if (dlibMove.HighPart != 0 || dlibMove.LowPart >= m_blen) return STG_E_INVALIDPOINTER;

            m_off = dlibMove.LowPart;
        }
        break;

        case STREAM_SEEK_CUR:
        case STREAM_SEEK_END: {
            if (dlibMove.HighPart > 0) return STG_E_INVALIDPOINTER;

            long newoff = (dwOrigin == STREAM_SEEK_END ? m_blen : m_off) + dlibMove.LowPart;

            if (newoff < 0 || newoff >= (long)m_blen)
                return STG_E_INVALIDPOINTER;
            else
                m_off = newoff;
        }
        break;

        default: return STG_E_INVALIDFUNCTION;
    }

    if (plibNewPosition != (ULARGE_INTEGER __RPC_FAR *)NULL)
        plibNewPosition->LowPart = m_off;

    FILETIME now; ::CoFileTimeNow(&now); m_statstg.atime = now;

    return S_OK;

    CATCH_BAD_ALLOC_RET(E_OUTOFMEMORY);
}

/**
 * SetSize
 */

HRESULT __stdcall  AwtDragSource::ADSIStreamProxy::SetSize(ULARGE_INTEGER libNewSize) {
    return STG_E_INVALIDFUNCTION;
}

/**
 * CopyTo
 */

HRESULT __stdcall  AwtDragSource::ADSIStreamProxy::CopyTo(IStream __RPC_FAR *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER __RPC_FAR *pcbRead, ULARGE_INTEGER __RPC_FAR *pcbWritten) {
    TRY;

    ULONG written = 0;

    pcbWritten->HighPart = (ULONG)0;
    pcbWritten->LowPart  = (ULONG)0;

    pcbRead->HighPart     = (ULONG)0;

    unsigned int rem     = m_blen - m_off;
    int          ovrflow = cb.LowPart >= rem;


    if (cb.HighPart != 0) return STG_E_INVALIDPOINTER;

    ULONG nbytes = pcbRead->LowPart = (ULONG)(ovrflow ? rem : cb.LowPart);

    HRESULT res = pstm->Write((const void *)(m_buffer + m_off), nbytes, &written);

    pcbWritten->LowPart = written;

    FILETIME now; ::CoFileTimeNow(&now); m_statstg.atime = now;

    return res;

    CATCH_BAD_ALLOC_RET(E_OUTOFMEMORY);
}

/**
 * Commit
 */

HRESULT __stdcall  AwtDragSource::ADSIStreamProxy::Commit(DWORD grfCommitFlags) {
    return S_OK;
}

/**
 * Revert
 */

HRESULT __stdcall  AwtDragSource::ADSIStreamProxy::Revert() {
    return S_OK;
}

/**
 * LockRegion
 */

HRESULT __stdcall  AwtDragSource::ADSIStreamProxy::LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) {
    return STG_E_INVALIDFUNCTION;
}

/**
 * UnlockRegion
 */

HRESULT __stdcall  AwtDragSource::ADSIStreamProxy::UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) {
    return STG_E_INVALIDFUNCTION;
}

/**
 * Stat
 */

HRESULT __stdcall  AwtDragSource::ADSIStreamProxy::Stat(STATSTG __RPC_FAR *pstatstg, DWORD grfStatFlag) {
    TRY;

    *pstatstg = m_statstg;

    FILETIME now; ::CoFileTimeNow(&now); m_statstg.atime = now;

    return S_OK;

    CATCH_BAD_ALLOC_RET(E_OUTOFMEMORY);
}

/**
 * Clone
 */

HRESULT __stdcall  AwtDragSource::ADSIStreamProxy::Clone(IStream __RPC_FAR *__RPC_FAR *ppstm) {
    TRY;

    *ppstm = new ADSIStreamProxy(this);
    return S_OK;

    CATCH_BAD_ALLOC_RET(E_OUTOFMEMORY);
}

/*****************************************************************************/

extern "C" {

/**
 * setNativeCursor
 */

JNIEXPORT void JNICALL
Java_sun_awt_windows_WDragSourceContextPeer_setNativeCursor(JNIEnv* env,
                                                            jobject self,
                                                            jlong nativeCtxt,
                                                            jobject cursor,
                                                            jint type) {
    TRY;

    AwtDragSource* ds = (AwtDragSource*)nativeCtxt;
    if (ds != NULL) {
        ds->SetCursor(cursor);
    }

    CATCH_BAD_ALLOC;
}

/**
 * createDragSource
 */

JNIEXPORT jlong JNICALL
Java_sun_awt_windows_WDragSourceContextPeer_createDragSource(
    JNIEnv* env, jobject self, jobject component, jobject transferable,
    jobject trigger, jint actions,
    jlongArray formats, jobject formatMap)
{
    TRY;

    if (!AwtDropTarget::IsCurrentDnDDataObject(NULL)) {
        JNU_ThrowByName(env, "java/awt/dnd/InvalidDnDOperationException",
                        "Drag and drop is in progress");
        return (jlong)NULL;
    }

    AwtDragSource* ds = new AwtDragSource(env, self, component,
                                          transferable, trigger, actions,
                                          formats, formatMap);

    DASSERT(AwtDropTarget::IsLocalDataObject(ds));

    return (jlong)ds;

    CATCH_BAD_ALLOC_RET(0);
}

/**
 * doDragDrop
 */

JNIEXPORT void JNICALL Java_sun_awt_windows_WDragSourceContextPeer_doDragDrop(JNIEnv* env, jobject self, jlong nativeCtxt, jobject cursor) {
    TRY;

    cursor = env->NewGlobalRef(cursor);

    AwtDragSource::StartDrag((AwtDragSource*)nativeCtxt, cursor);

    CATCH_BAD_ALLOC;
}

} /* extern "C" */
