From caa631bf5b69ef1e39989b8e1e4b3372491cb9b4 Mon Sep 17 00:00:00 2001 From: callum Date: Tue, 27 Oct 2009 17:52:04 -0700 Subject: Added IDropTarget interface. Still lots of cleanup but this works ok. You can drag over from Firefox or IE onto a prim --- indra/llwindow/lldragdropwin32.cpp | 295 +++++++++++++++++++++++++++++++++++++ 1 file changed, 295 insertions(+) create mode 100644 indra/llwindow/lldragdropwin32.cpp (limited to 'indra/llwindow/lldragdropwin32.cpp') diff --git a/indra/llwindow/lldragdropwin32.cpp b/indra/llwindow/lldragdropwin32.cpp new file mode 100644 index 0000000000..0daff85395 --- /dev/null +++ b/indra/llwindow/lldragdropwin32.cpp @@ -0,0 +1,295 @@ +/** + * @file lldragdrop32.cpp + * @brief Handler for Windows specific drag and drop (OS to client) code + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#if LL_WINDOWS + +#include "linden_common.h" + +#define WIN32_LEAN_AND_MEAN +#include + +#include "llwindowwin32.h" +#include "llkeyboardwin32.h" +#include "lldragdropwin32.h" + +#include "llwindowcallbacks.h" + +#include +#include +#include +#include +#include + +// FIXME: this should be done in CMake +#pragma comment( lib, "shlwapi.lib" ) + +class LLDragDropWin32Target: + public IDropTarget +{ + public: + LLDragDropWin32Target( HWND hWnd ) : + mWindowHandle( hWnd ), + mRefCount( 0 ) + { + strcpy(szFileDropped,""); + bDropTargetValid = false; + bTextDropped = false; + }; + + /* IUnknown methods */ + STDMETHOD_( ULONG, AddRef )( void ) + { + return ++mRefCount; + }; + + STDMETHOD_( ULONG, Release )( void ) + { + if ( --mRefCount == 0 ) + { + delete this; + return 0; + } + return mRefCount; + }; + + STDMETHOD ( QueryInterface )( REFIID iid, void ** ppvObject ) + { + if ( iid == IID_IUnknown || iid == IID_IDropTarget ) + { + *ppvObject = this; + AddRef(); + return S_OK; + }; + + *ppvObject = NULL; + return E_NOINTERFACE; + }; + + /* IDropTarget methods */ + STDMETHOD (DragEnter)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) + { + HRESULT hr = E_INVALIDARG; + bDropTargetValid = false; + bTextDropped = false; + *pdwEffect=DROPEFFECT_NONE; + + FORMATETC fmte = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; + STGMEDIUM medium; + + if (pDataObj && SUCCEEDED (pDataObj->GetData (&fmte, &medium))) + { + // We can Handle Only one File At a time !!! + if (1 == DragQueryFile ((HDROP)medium.hGlobal,0xFFFFFFFF,NULL,0 )) + { + // Get the File Name + if (DragQueryFileA((HDROP)medium.hGlobal, 0, szFileDropped,MAX_PATH)) + { + if (!PathIsDirectoryA(szFileDropped)) + { + char szTempFile[MAX_PATH]; + _splitpath(szFileDropped,NULL,NULL,NULL,szTempFile); + +// if (!stricmp(szTempFile,".lnk")) +// { +// if (ResolveLink(szFileDropped,szTempFile)) +// { +// strcpy(szFileDropped,szTempFile); +// *pdwEffect=DROPEFFECT_COPY; +// We Want to Create a Copy +// bDropTargetValid = true; +// hr = S_OK; +// } +// } +// else +// { + *pdwEffect=DROPEFFECT_COPY; + //We Want to Create a Copy + bDropTargetValid = true; + hr = S_OK; +// } + } + } + } + + if (medium.pUnkForRelease) + medium.pUnkForRelease->Release (); + else + GlobalFree (medium.hGlobal); + } + else + { + fmte.cfFormat = CF_TEXT; + fmte.ptd = NULL; + fmte.dwAspect = DVASPECT_CONTENT; + fmte.lindex = -1; + fmte.tymed = TYMED_HGLOBAL; + + // Does the drag source provide CF_TEXT ? + if (NOERROR == pDataObj->QueryGetData(&fmte)) + { + bDropTargetValid = true; + bTextDropped = true; + *pdwEffect=DROPEFFECT_COPY; + hr = S_OK; + } + } + return hr; + + + + }; + + STDMETHOD (DragOver)(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) + { + HRESULT hr = S_OK; + if (bDropTargetValid) + *pdwEffect=DROPEFFECT_COPY; + + return hr; + }; + + STDMETHOD (DragLeave)(void) + { + HRESULT hr = S_OK; + strcpy(szFileDropped,""); + return hr; + }; + + STDMETHOD (Drop)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) + { + HRESULT hr = S_OK; + if (bDropTargetValid) + { + *pdwEffect=DROPEFFECT_COPY; + + FORMATETC fmte; + STGMEDIUM medium; + + if (bTextDropped) + { + fmte.cfFormat = CF_TEXT; + fmte.ptd = NULL; + fmte.dwAspect = DVASPECT_CONTENT; + fmte.lindex = -1; + fmte.tymed = TYMED_HGLOBAL; + + hr = pDataObj->GetData(&fmte, &medium); + HGLOBAL hText = medium.hGlobal; + LPSTR lpszText = (LPSTR)GlobalLock(hText); + + LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong(mWindowHandle, GWL_USERDATA); + if (NULL != window_imp) + { + LLCoordGL gl_coord( pt.x, pt.y); + LLCoordWindow cursor_coord_window( pt.x, pt.y ); + window_imp->convertCoords(cursor_coord_window, &gl_coord); + llinfos << "### (Drop) URL is: " << lpszText << llendl; + llinfos << "### raw coords are: " << pt.x << " x " << pt.y << llendl; + llinfos << "### GL coords are: " << gl_coord.mX << " x " << gl_coord.mY << llendl; + llinfos << llendl; + + MASK mask = gKeyboard->currentMask(TRUE); + window_imp->completeDropRequest( gl_coord, mask, std::string( lpszText ) ); + }; + + GlobalUnlock(hText); + ReleaseStgMedium(&medium); + } + } + return hr; + }; + + private: + ULONG mRefCount; + HWND mWindowHandle; + char szFileDropped[1024]; + bool bDropTargetValid; + bool bTextDropped; + friend class LLWindowWin32; +}; + +LLDragDropWin32::LLDragDropWin32() : + mDropTarget( NULL ), + mDropWindowHandle( NULL ) + +{ +} + +LLDragDropWin32::~LLDragDropWin32() +{ +} + +bool LLDragDropWin32::init( HWND hWnd ) +{ + if (NOERROR != OleInitialize(NULL)) + return FALSE; + + mDropTarget = new LLDragDropWin32Target( hWnd ); + if ( mDropTarget ) + { + HRESULT result = CoLockObjectExternal( mDropTarget, TRUE, TRUE ); + if ( S_OK == result ) + { + result = RegisterDragDrop( hWnd, mDropTarget ); + if ( S_OK != result ) + { + // RegisterDragDrop failed + return false; + }; + + // all ok + mDropWindowHandle = hWnd; + } + else + { + // Unable to lock OLE object + return false; + }; + }; + + // success + return true; +} + +void LLDragDropWin32::reset() +{ + if ( mDropTarget ) + { + CoLockObjectExternal( mDropTarget, FALSE, TRUE ); + RevokeDragDrop( mDropWindowHandle ); + mDropTarget->Release(); + }; + + OleUninitialize(); +} + +#endif -- cgit v1.3 From 996740607a11ac7f8633f12b65ead0508e1435fa Mon Sep 17 00:00:00 2001 From: callum Date: Tue, 3 Nov 2009 09:33:21 -0800 Subject: Convert screen coordinates from IDropAction to window coordinates. --- indra/llwindow/lldragdropwin32.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'indra/llwindow/lldragdropwin32.cpp') diff --git a/indra/llwindow/lldragdropwin32.cpp b/indra/llwindow/lldragdropwin32.cpp index 0daff85395..d05dbf19a5 100644 --- a/indra/llwindow/lldragdropwin32.cpp +++ b/indra/llwindow/lldragdropwin32.cpp @@ -209,11 +209,18 @@ class LLDragDropWin32Target: LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong(mWindowHandle, GWL_USERDATA); if (NULL != window_imp) { - LLCoordGL gl_coord( pt.x, pt.y); - LLCoordWindow cursor_coord_window( pt.x, pt.y ); + LLCoordGL gl_coord( 0, 0 ); + + POINT pt2; + pt2.x = pt.x; + pt2.y = pt.y; + ScreenToClient( mWindowHandle, &pt2 ); + + LLCoordWindow cursor_coord_window( pt2.x, pt2.y ); window_imp->convertCoords(cursor_coord_window, &gl_coord); llinfos << "### (Drop) URL is: " << lpszText << llendl; llinfos << "### raw coords are: " << pt.x << " x " << pt.y << llendl; + llinfos << "### window coords are: " << pt2.x << " x " << pt2.y << llendl; llinfos << "### GL coords are: " << gl_coord.mX << " x " << gl_coord.mY << llendl; llinfos << llendl; -- cgit v1.3 From bf5ce0fcbd9a71ce1372db0f42395ba47747fd78 Mon Sep 17 00:00:00 2001 From: Rick Pasetto Date: Thu, 12 Nov 2009 11:06:29 -0800 Subject: Change 'handleDrop()' API to 'handleDragNDrop', which now takes a "drop" BOOL --- indra/llwindow/lldragdropwin32.cpp | 18 ++++++++++++++++- indra/llwindow/llwindowcallbacks.cpp | 2 +- indra/llwindow/llwindowcallbacks.h | 2 +- indra/llwindow/llwindowwin32.cpp | 13 ++++-------- indra/llwindow/llwindowwin32.h | 2 +- indra/newview/llviewerwindow.cpp | 39 +++++++++++++++++++++--------------- indra/newview/llviewerwindow.h | 2 +- 7 files changed, 48 insertions(+), 30 deletions(-) (limited to 'indra/llwindow/lldragdropwin32.cpp') diff --git a/indra/llwindow/lldragdropwin32.cpp b/indra/llwindow/lldragdropwin32.cpp index d05dbf19a5..879f2d2b90 100644 --- a/indra/llwindow/lldragdropwin32.cpp +++ b/indra/llwindow/lldragdropwin32.cpp @@ -171,6 +171,22 @@ class LLDragDropWin32Target: STDMETHOD (DragOver)(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) { HRESULT hr = S_OK; + // XXX MAJOR MAJOR HACK! + LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong(mWindowHandle, GWL_USERDATA); + if (NULL != window_imp) + { + LLCoordGL gl_coord( 0, 0 ); + + POINT pt2; + pt2.x = pt.x; + pt2.y = pt.y; + ScreenToClient( mWindowHandle, &pt2 ); + + LLCoordWindow cursor_coord_window( pt2.x, pt2.y ); + window_imp->convertCoords(cursor_coord_window, &gl_coord); + MASK mask = gKeyboard->currentMask(TRUE); + bDropTargetValid = window_imp->completeDragNDropRequest( gl_coord, mask, FALSE, std::string( "" ) ); + } if (bDropTargetValid) *pdwEffect=DROPEFFECT_COPY; @@ -225,7 +241,7 @@ class LLDragDropWin32Target: llinfos << llendl; MASK mask = gKeyboard->currentMask(TRUE); - window_imp->completeDropRequest( gl_coord, mask, std::string( lpszText ) ); + window_imp->completeDragNDropRequest( gl_coord, mask, TRUE, std::string( lpszText ) ); }; GlobalUnlock(hText); diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp index 1098529e1c..b8927a1ac4 100644 --- a/indra/llwindow/llwindowcallbacks.cpp +++ b/indra/llwindow/llwindowcallbacks.cpp @@ -163,7 +163,7 @@ void LLWindowCallbacks::handleDataCopy(LLWindow *window, S32 data_type, void *da { } -BOOL LLWindowCallbacks::handleDrop(LLWindow *window, LLCoordGL pos, MASK mask, std::string data ) +BOOL LLWindowCallbacks::handleDragNDrop(LLWindow *window, LLCoordGL pos, MASK mask, BOOL drop, std::string data ) { return FALSE; } diff --git a/indra/llwindow/llwindowcallbacks.h b/indra/llwindow/llwindowcallbacks.h index 3a09100168..8e7605a650 100644 --- a/indra/llwindow/llwindowcallbacks.h +++ b/indra/llwindow/llwindowcallbacks.h @@ -68,7 +68,7 @@ public: virtual void handleWindowBlock(LLWindow *window); // window is taking over CPU for a while virtual void handleWindowUnblock(LLWindow *window); // window coming back after taking over CPU for a while virtual void handleDataCopy(LLWindow *window, S32 data_type, void *data); - virtual BOOL handleDrop(LLWindow *window, LLCoordGL pos, MASK mask, std::string data); + virtual BOOL handleDragNDrop(LLWindow *window, LLCoordGL pos, MASK mask, BOOL drop, std::string data); virtual BOOL handleTimerEvent(LLWindow *window); virtual BOOL handleDeviceChange(LLWindow *window); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index da096b9a0a..eda8cf15b0 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -2401,7 +2401,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ MASK mask = gKeyboard->currentMask(TRUE); - if ( window_imp->completeDropRequest( gl_coord, mask, (char*)url ) ) + if ( window_imp->completeDragNDropRequest( gl_coord, mask, true, (char*)url ) ) { return 0; }; @@ -3578,15 +3578,10 @@ static LLWString find_context(const LLWString & wtext, S32 focus, S32 focus_leng // final stage of handling drop requests - both from WM_DROPFILES message // for files and via IDropTarget interface requests. -BOOL LLWindowWin32::completeDropRequest( const LLCoordGL gl_coord, const MASK mask, const std::string url ) +BOOL LLWindowWin32::completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, BOOL drop, const std::string url ) { - if ( mCallbacks->handleDrop( this, gl_coord, mask, url ) ) - { - return TRUE; - }; - - return FALSE; -}; + return mCallbacks->handleDragNDrop( this, gl_coord, mask, drop, url ); +} // Handle WM_IME_REQUEST message. // If it handled the message, returns TRUE. Otherwise, FALSE. diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index 1382cf93a2..e99c26b7f1 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -113,7 +113,7 @@ public: /*virtual*/ void interruptLanguageTextInput(); /*virtual*/ void spawnWebBrowser(const std::string& escaped_url); - BOOL completeDropRequest( const LLCoordGL gl_coord, const MASK mask, const std::string url ); + BOOL completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, BOOL drop, const std::string url ); static std::vector getDynamicFallbackFontList(); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 06d6819b5e..d2f81f21ac 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -819,8 +819,9 @@ BOOL LLViewerWindow::handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MAS return TRUE; } -BOOL LLViewerWindow::handleDrop( LLWindow *window, LLCoordGL pos, MASK mask, std::string data ) +BOOL LLViewerWindow::handleDragNDrop( LLWindow *window, LLCoordGL pos, MASK mask, BOOL drop, std::string data ) { + BOOL result = FALSE; if (gSavedSettings.getBOOL("PrimMediaDragNDrop")) { LLPickInfo pick_info = pickImmediate( pos.mX, pos.mY, TRUE /*BOOL pick_transparent*/ ); @@ -837,28 +838,34 @@ BOOL LLViewerWindow::handleDrop( LLWindow *window, LLCoordGL pos, MASK mask, st LLTextureEntry *te = obj->getTE(object_face); if (te) { - if (! te->hasMedia()) + if (drop) { - // Create new media entry - LLSD media_data; - // XXX Should we really do Home URL too? - media_data[LLMediaEntry::HOME_URL_KEY] = url; - media_data[LLMediaEntry::CURRENT_URL_KEY] = url; - media_data[LLMediaEntry::AUTO_PLAY_KEY] = true; - obj->syncMediaData(object_face, media_data, true, true); - // XXX This shouldn't be necessary, should it ?!? - obj->getMediaImpl(object_face)->navigateReload(); - obj->sendMediaDataUpdate(); + if (! te->hasMedia()) + { + // Create new media entry + LLSD media_data; + // XXX Should we really do Home URL too? + media_data[LLMediaEntry::HOME_URL_KEY] = url; + media_data[LLMediaEntry::CURRENT_URL_KEY] = url; + media_data[LLMediaEntry::AUTO_PLAY_KEY] = true; + obj->syncMediaData(object_face, media_data, true, true); + // XXX This shouldn't be necessary, should it ?!? + obj->getMediaImpl(object_face)->navigateReload(); + obj->sendMediaDataUpdate(); + } + else { + // just navigate to the URL + obj->getMediaImpl(object_face)->navigateTo(url); + } } else { - // just navigate to the URL - obj->getMediaImpl(object_face)->navigateTo(url); + // XXX TODO: make object glow? Hard because how do we "unglow?" } + result = TRUE; } } } - // Always handled as far as the OS is concerned. - return TRUE; + return result; } BOOL LLViewerWindow::handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index cdc9eb4786..d7cfcff925 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -170,7 +170,7 @@ public: /*virtual*/ BOOL handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask); /*virtual*/ BOOL handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask); /*virtual*/ BOOL handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask); - /*virtual*/ BOOL handleDrop(LLWindow *window, LLCoordGL pos, MASK mask, std::string data); + /*virtual*/ BOOL handleDragNDrop(LLWindow *window, LLCoordGL pos, MASK mask, BOOL drop, std::string data); void handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask); /*virtual*/ void handleMouseLeave(LLWindow *window); /*virtual*/ void handleResize(LLWindow *window, S32 x, S32 y); -- cgit v1.3 From 778005a350308d51f114ece74b4e7f3e7af3d37e Mon Sep 17 00:00:00 2001 From: callum Date: Fri, 13 Nov 2009 17:43:55 -0800 Subject: Reworked IDropTarget COM interface impl - now much cleaner and doesn't crash! --- indra/llwindow/lldragdropwin32.cpp | 287 +++++++++++++++++-------------------- indra/llwindow/lldragdropwin32.h | 8 +- 2 files changed, 135 insertions(+), 160 deletions(-) (limited to 'indra/llwindow/lldragdropwin32.cpp') diff --git a/indra/llwindow/lldragdropwin32.cpp b/indra/llwindow/lldragdropwin32.cpp index d05dbf19a5..aac68e71af 100644 --- a/indra/llwindow/lldragdropwin32.cpp +++ b/indra/llwindow/lldragdropwin32.cpp @@ -34,216 +34,183 @@ #include "linden_common.h" -#define WIN32_LEAN_AND_MEAN -#include - #include "llwindowwin32.h" #include "llkeyboardwin32.h" -#include "lldragdropwin32.h" - #include "llwindowcallbacks.h" - -#include -#include -#include -#include -#include - -// FIXME: this should be done in CMake -#pragma comment( lib, "shlwapi.lib" ) +#include "lldragdropwin32.h" class LLDragDropWin32Target: public IDropTarget { public: + //////////////////////////////////////////////////////////////////////////////// + // LLDragDropWin32Target( HWND hWnd ) : - mWindowHandle( hWnd ), - mRefCount( 0 ) + mRefCount( 1 ), + mAppWindowHandle( hWnd ), + mAllowDrop( false) { - strcpy(szFileDropped,""); - bDropTargetValid = false; - bTextDropped = false; }; - /* IUnknown methods */ - STDMETHOD_( ULONG, AddRef )( void ) + //////////////////////////////////////////////////////////////////////////////// + // + ULONG __stdcall AddRef( void ) { - return ++mRefCount; + return InterlockedIncrement( &mRefCount ); }; - STDMETHOD_( ULONG, Release )( void ) + //////////////////////////////////////////////////////////////////////////////// + // + ULONG __stdcall Release( void ) { - if ( --mRefCount == 0 ) + LONG count = InterlockedDecrement( &mRefCount ); + + if ( count == 0 ) { delete this; return 0; } - return mRefCount; + else + { + return count; + }; }; - STDMETHOD ( QueryInterface )( REFIID iid, void ** ppvObject ) + //////////////////////////////////////////////////////////////////////////////// + // + HRESULT __stdcall QueryInterface( REFIID iid, void** ppvObject ) { if ( iid == IID_IUnknown || iid == IID_IDropTarget ) { - *ppvObject = this; AddRef(); + *ppvObject = this; return S_OK; + } + else + { + *ppvObject = 0; + return E_NOINTERFACE; }; - - *ppvObject = NULL; - return E_NOINTERFACE; }; - - /* IDropTarget methods */ - STDMETHOD (DragEnter)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) + + //////////////////////////////////////////////////////////////////////////////// + // + HRESULT __stdcall DragEnter( IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect ) { - HRESULT hr = E_INVALIDARG; - bDropTargetValid = false; - bTextDropped = false; - *pdwEffect=DROPEFFECT_NONE; - - FORMATETC fmte = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; - STGMEDIUM medium; - - if (pDataObj && SUCCEEDED (pDataObj->GetData (&fmte, &medium))) - { - // We can Handle Only one File At a time !!! - if (1 == DragQueryFile ((HDROP)medium.hGlobal,0xFFFFFFFF,NULL,0 )) - { - // Get the File Name - if (DragQueryFileA((HDROP)medium.hGlobal, 0, szFileDropped,MAX_PATH)) - { - if (!PathIsDirectoryA(szFileDropped)) - { - char szTempFile[MAX_PATH]; - _splitpath(szFileDropped,NULL,NULL,NULL,szTempFile); - -// if (!stricmp(szTempFile,".lnk")) -// { -// if (ResolveLink(szFileDropped,szTempFile)) -// { -// strcpy(szFileDropped,szTempFile); -// *pdwEffect=DROPEFFECT_COPY; -// We Want to Create a Copy -// bDropTargetValid = true; -// hr = S_OK; -// } -// } -// else -// { - *pdwEffect=DROPEFFECT_COPY; - //We Want to Create a Copy - bDropTargetValid = true; - hr = S_OK; -// } - } - } - } - - if (medium.pUnkForRelease) - medium.pUnkForRelease->Release (); - else - GlobalFree (medium.hGlobal); - } - else + FORMATETC fmtetc = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; + + // support CF_TEXT using a HGLOBAL? + if ( S_OK == pDataObject->QueryGetData( &fmtetc ) ) { - fmte.cfFormat = CF_TEXT; - fmte.ptd = NULL; - fmte.dwAspect = DVASPECT_CONTENT; - fmte.lindex = -1; - fmte.tymed = TYMED_HGLOBAL; - - // Does the drag source provide CF_TEXT ? - if (NOERROR == pDataObj->QueryGetData(&fmte)) - { - bDropTargetValid = true; - bTextDropped = true; - *pdwEffect=DROPEFFECT_COPY; - hr = S_OK; - } - } - return hr; + mAllowDrop = true; + *pdwEffect = DROPEFFECT_COPY; + SetFocus( mAppWindowHandle ); + } + else + { + mAllowDrop = false; + *pdwEffect = DROPEFFECT_NONE; + }; + return S_OK; }; - STDMETHOD (DragOver)(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) + //////////////////////////////////////////////////////////////////////////////// + // + HRESULT __stdcall DragOver( DWORD grfKeyState, POINTL pt, DWORD* pdwEffect ) { - HRESULT hr = S_OK; - if (bDropTargetValid) - *pdwEffect=DROPEFFECT_COPY; + if ( mAllowDrop ) + { + *pdwEffect = DROPEFFECT_COPY; + } + else + { + *pdwEffect = DROPEFFECT_NONE; + }; - return hr; + return S_OK; }; - STDMETHOD (DragLeave)(void) + //////////////////////////////////////////////////////////////////////////////// + // + HRESULT __stdcall DragLeave( void ) { - HRESULT hr = S_OK; - strcpy(szFileDropped,""); - return hr; + return S_OK; }; - STDMETHOD (Drop)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) + //////////////////////////////////////////////////////////////////////////////// + // + HRESULT __stdcall Drop( IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect ) { - HRESULT hr = S_OK; - if (bDropTargetValid) + if ( mAllowDrop ) { - *pdwEffect=DROPEFFECT_COPY; - - FORMATETC fmte; - STGMEDIUM medium; + // construct a FORMATETC object + FORMATETC fmtetc = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; - if (bTextDropped) + // do we have text? + if( S_OK == pDataObject->QueryGetData( &fmtetc ) ) { - fmte.cfFormat = CF_TEXT; - fmte.ptd = NULL; - fmte.dwAspect = DVASPECT_CONTENT; - fmte.lindex = -1; - fmte.tymed = TYMED_HGLOBAL; - - hr = pDataObj->GetData(&fmte, &medium); - HGLOBAL hText = medium.hGlobal; - LPSTR lpszText = (LPSTR)GlobalLock(hText); - - LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong(mWindowHandle, GWL_USERDATA); - if (NULL != window_imp) + STGMEDIUM stgmed; + if( S_OK == pDataObject->GetData( &fmtetc, &stgmed ) ) { - LLCoordGL gl_coord( 0, 0 ); - - POINT pt2; - pt2.x = pt.x; - pt2.y = pt.y; - ScreenToClient( mWindowHandle, &pt2 ); - - LLCoordWindow cursor_coord_window( pt2.x, pt2.y ); - window_imp->convertCoords(cursor_coord_window, &gl_coord); - llinfos << "### (Drop) URL is: " << lpszText << llendl; - llinfos << "### raw coords are: " << pt.x << " x " << pt.y << llendl; - llinfos << "### window coords are: " << pt2.x << " x " << pt2.y << llendl; - llinfos << "### GL coords are: " << gl_coord.mX << " x " << gl_coord.mY << llendl; - llinfos << llendl; - - MASK mask = gKeyboard->currentMask(TRUE); - window_imp->completeDropRequest( gl_coord, mask, std::string( lpszText ) ); + // note: data is in an HGLOBAL - not 'regular' memory + PVOID data = GlobalLock( stgmed.hGlobal ); + + // window impl stored in Window data (neat!) + LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong( mAppWindowHandle, GWL_USERDATA ); + if ( NULL != window_imp ) + { + LLCoordGL gl_coord( 0, 0 ); + + POINT pt_client; + pt_client.x = pt.x; + pt_client.y = pt.y; + ScreenToClient( mAppWindowHandle, &pt_client ); + + LLCoordWindow cursor_coord_window( pt_client.x, pt_client.y ); + window_imp->convertCoords(cursor_coord_window, &gl_coord); + llinfos << "### (Drop) URL is: " << data << llendl; + llinfos << "### raw coords are: " << pt.x << " x " << pt.y << llendl; + llinfos << "### client coords are: " << pt_client.x << " x " << pt_client.y << llendl; + llinfos << "### GL coords are: " << gl_coord.mX << " x " << gl_coord.mY << llendl; + llinfos << llendl; + + // no keyboard modifier option yet but we could one day + MASK mask = gKeyboard->currentMask( TRUE ); + + // actually do the drop + window_imp->completeDropRequest( gl_coord, mask, std::string( (char*)data ) ); + }; + + GlobalUnlock( stgmed.hGlobal ); + + ReleaseStgMedium( &stgmed ); }; + }; - GlobalUnlock(hText); - ReleaseStgMedium(&medium); - } + *pdwEffect = DROPEFFECT_COPY; } - return hr; + else + { + *pdwEffect = DROPEFFECT_NONE; + }; + + return S_OK; }; - + + //////////////////////////////////////////////////////////////////////////////// + // private: - ULONG mRefCount; - HWND mWindowHandle; - char szFileDropped[1024]; - bool bDropTargetValid; - bool bTextDropped; + LONG mRefCount; + HWND mAppWindowHandle; + bool mAllowDrop; friend class LLWindowWin32; }; +//////////////////////////////////////////////////////////////////////////////// +// LLDragDropWin32::LLDragDropWin32() : mDropTarget( NULL ), mDropWindowHandle( NULL ) @@ -251,19 +218,23 @@ LLDragDropWin32::LLDragDropWin32() : { } +//////////////////////////////////////////////////////////////////////////////// +// LLDragDropWin32::~LLDragDropWin32() { } +//////////////////////////////////////////////////////////////////////////////// +// bool LLDragDropWin32::init( HWND hWnd ) { - if (NOERROR != OleInitialize(NULL)) + if ( NOERROR != OleInitialize( NULL ) ) return FALSE; mDropTarget = new LLDragDropWin32Target( hWnd ); if ( mDropTarget ) { - HRESULT result = CoLockObjectExternal( mDropTarget, TRUE, TRUE ); + HRESULT result = CoLockObjectExternal( mDropTarget, TRUE, FALSE ); if ( S_OK == result ) { result = RegisterDragDrop( hWnd, mDropTarget ); @@ -287,12 +258,14 @@ bool LLDragDropWin32::init( HWND hWnd ) return true; } +//////////////////////////////////////////////////////////////////////////////// +// void LLDragDropWin32::reset() { if ( mDropTarget ) { - CoLockObjectExternal( mDropTarget, FALSE, TRUE ); RevokeDragDrop( mDropWindowHandle ); + CoLockObjectExternal( mDropTarget, FALSE, TRUE ); mDropTarget->Release(); }; diff --git a/indra/llwindow/lldragdropwin32.h b/indra/llwindow/lldragdropwin32.h index 6137e5eb65..624f4ad24b 100644 --- a/indra/llwindow/lldragdropwin32.h +++ b/indra/llwindow/lldragdropwin32.h @@ -33,10 +33,10 @@ #ifndef LL_LLDRAGDROP32_H #define LL_LLDRAGDROP32_H +#if LL_WINDOWS + #include #include -#include -#include class LLDragDropWin32 { @@ -52,4 +52,6 @@ class LLDragDropWin32 HWND mDropWindowHandle; }; -#endif +#endif // LL_WINDOWS + +#endif // LL_LLDRAGDROP32_H -- cgit v1.3 From 4419e367bcbe8c1b248e88eab8096f0b8ac4707c Mon Sep 17 00:00:00 2001 From: callum Date: Wed, 18 Nov 2009 21:15:44 -0800 Subject: Add support for removing the Windows specific drag/drop code from the codebase via a new CMake file (DragDrop.cmake). --- indra/cmake/DragDrop.cmake | 25 +++++++++++++++++++++++++ indra/llwindow/CMakeLists.txt | 1 + indra/llwindow/lldragdropwin32.cpp | 7 ++++++- indra/llwindow/lldragdropwin32.h | 29 ++++++++++++++++++++++++++--- indra/newview/CMakeLists.txt | 1 + 5 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 indra/cmake/DragDrop.cmake (limited to 'indra/llwindow/lldragdropwin32.cpp') diff --git a/indra/cmake/DragDrop.cmake b/indra/cmake/DragDrop.cmake new file mode 100644 index 0000000000..a2d7df1312 --- /dev/null +++ b/indra/cmake/DragDrop.cmake @@ -0,0 +1,25 @@ +# -*- cmake -*- + +if (VIEWER) + + OPTION (OS_DRAG_DROP + "Build the viewer with OS level drag and drop turned on or off" + OFF) + + if (OS_DRAG_DROP) + + if (WINDOWS) + add_definitions(-DLL_OS_DRAGDROP_ENABLED=1) + endif (WINDOWS) + + if (DARWIN) + add_definitions(-DLL_OS_DRAGDROP_ENABLED=0) + endif (DARWIN) + + if (LINUX) + add_definitions(-DLL_OS_DRAGDROP_ENABLED=0) + endif (LINUX) + + endif (OS_DRAG_DROP) + +endif (VIEWER) diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt index b4a3f74451..77c6fa57b6 100644 --- a/indra/llwindow/CMakeLists.txt +++ b/indra/llwindow/CMakeLists.txt @@ -12,6 +12,7 @@ project(llwindow) include(00-Common) include(DirectX) +include(DragDrop) include(LLCommon) include(LLImage) include(LLMath) diff --git a/indra/llwindow/lldragdropwin32.cpp b/indra/llwindow/lldragdropwin32.cpp index aac68e71af..471c88675d 100644 --- a/indra/llwindow/lldragdropwin32.cpp +++ b/indra/llwindow/lldragdropwin32.cpp @@ -32,6 +32,8 @@ #if LL_WINDOWS +#if LL_OS_DRAGDROP_ENABLED + #include "linden_common.h" #include "llwindowwin32.h" @@ -272,4 +274,7 @@ void LLDragDropWin32::reset() OleUninitialize(); } -#endif +#endif // LL_OS_DRAGDROP_ENABLED + +#endif // LL_WINDOWS + diff --git a/indra/llwindow/lldragdropwin32.h b/indra/llwindow/lldragdropwin32.h index 624f4ad24b..26c8e4aeff 100644 --- a/indra/llwindow/lldragdropwin32.h +++ b/indra/llwindow/lldragdropwin32.h @@ -30,11 +30,13 @@ * $/LicenseInfo$ */ +#if LL_WINDOWS + +#if LL_OS_DRAGDROP_ENABLED + #ifndef LL_LLDRAGDROP32_H #define LL_LLDRAGDROP32_H -#if LL_WINDOWS - #include #include @@ -51,7 +53,28 @@ class LLDragDropWin32 IDropTarget* mDropTarget; HWND mDropWindowHandle; }; +#endif // LL_LLDRAGDROP32_H -#endif // LL_WINDOWS +#else // LL_OS_DRAGDROP_ENABLED +#ifndef LL_LLDRAGDROP32_H +#define LL_LLDRAGDROP32_H + +#include +#include + +// imposter class that does nothing +class LLDragDropWin32 +{ + public: + LLDragDropWin32() {}; + ~LLDragDropWin32() {}; + + bool init( HWND hWnd ) { return false; }; + void reset() { }; +}; #endif // LL_LLDRAGDROP32_H + +#endif // LL_OS_DRAGDROP_ENABLED + +#endif // LL_WINDOWS diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index b129bca1f3..352e9a9382 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -7,6 +7,7 @@ include(Boost) include(BuildVersion) include(DBusGlib) include(DirectX) +include(DragDrop) include(ELFIO) include(FMOD) include(OPENAL) -- cgit v1.3 From d4ba73ed721fa0811474fc53300f560539d38018 Mon Sep 17 00:00:00 2001 From: Rick Pasetto Date: Thu, 19 Nov 2009 09:24:26 -0800 Subject: Fix merge error --- indra/llwindow/lldragdropwin32.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indra/llwindow/lldragdropwin32.cpp') diff --git a/indra/llwindow/lldragdropwin32.cpp b/indra/llwindow/lldragdropwin32.cpp index 4fc64f2f69..b39cd83698 100644 --- a/indra/llwindow/lldragdropwin32.cpp +++ b/indra/llwindow/lldragdropwin32.cpp @@ -124,7 +124,7 @@ class LLDragDropWin32Target: if ( mAllowDrop ) { // XXX MAJOR MAJOR HACK! - LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong(mWindowHandle, GWL_USERDATA); + LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong(mAppWindowHandle, GWL_USERDATA); if (NULL != window_imp) { LLCoordGL gl_coord( 0, 0 ); @@ -132,12 +132,12 @@ class LLDragDropWin32Target: POINT pt2; pt2.x = pt.x; pt2.y = pt.y; - ScreenToClient( mWindowHandle, &pt2 ); + ScreenToClient( mAppWindowHandle, &pt2 ); LLCoordWindow cursor_coord_window( pt2.x, pt2.y ); window_imp->convertCoords(cursor_coord_window, &gl_coord); MASK mask = gKeyboard->currentMask(TRUE); - bDropTargetValid = window_imp->completeDragNDropRequest( gl_coord, mask, FALSE, std::string( "" ) ); + window_imp->completeDragNDropRequest( gl_coord, mask, FALSE, std::string( "" ) ); } *pdwEffect = DROPEFFECT_COPY; } -- cgit v1.3 From 8d84b7ae4062d8680aae2bb8325813bdac0335ed Mon Sep 17 00:00:00 2001 From: callum Date: Tue, 24 Nov 2009 18:31:30 -0800 Subject: Add support for changing OS cursor when mouse passes over a prim you can drop on versus one you can't. --- indra/llwindow/lldragdropwin32.cpp | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) (limited to 'indra/llwindow/lldragdropwin32.cpp') diff --git a/indra/llwindow/lldragdropwin32.cpp b/indra/llwindow/lldragdropwin32.cpp index a10cfbf12f..6024931092 100644 --- a/indra/llwindow/lldragdropwin32.cpp +++ b/indra/llwindow/lldragdropwin32.cpp @@ -125,23 +125,29 @@ class LLDragDropWin32Target: { if ( mAllowDrop ) { - // XXX MAJOR MAJOR HACK! - LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong(mAppWindowHandle, GWL_USERDATA); - if (NULL != window_imp) - { - LLCoordGL gl_coord( 0, 0 ); - - POINT pt2; - pt2.x = pt.x; - pt2.y = pt.y; - ScreenToClient( mAppWindowHandle, &pt2 ); + bool allowed_to_drop = false; - LLCoordWindow cursor_coord_window( pt2.x, pt2.y ); - window_imp->convertCoords(cursor_coord_window, &gl_coord); - MASK mask = gKeyboard->currentMask(TRUE); - window_imp->completeDragNDropRequest( gl_coord, mask, FALSE, std::string( "" ) ); - } - *pdwEffect = DROPEFFECT_COPY; + // XXX MAJOR MAJOR HACK! + LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong(mAppWindowHandle, GWL_USERDATA); + if (NULL != window_imp) + { + LLCoordGL gl_coord( 0, 0 ); + + POINT pt2; + pt2.x = pt.x; + pt2.y = pt.y; + ScreenToClient( mAppWindowHandle, &pt2 ); + + LLCoordWindow cursor_coord_window( pt2.x, pt2.y ); + window_imp->convertCoords(cursor_coord_window, &gl_coord); + MASK mask = gKeyboard->currentMask(TRUE); + allowed_to_drop = window_imp->completeDragNDropRequest( gl_coord, mask, FALSE, std::string( "" ) ); + } + + if ( allowed_to_drop ) + *pdwEffect = DROPEFFECT_COPY; + else + *pdwEffect = DROPEFFECT_NONE; } else { -- cgit v1.3 From e2e7d544b6a114e70e3b46f516a4f0e8d7db4bd1 Mon Sep 17 00:00:00 2001 From: callum Date: Tue, 24 Nov 2009 20:20:53 -0800 Subject: Added support for dropping SURLs onto viewer Does right thing when logged in - needs some work at login page Removed (commented out) WM_DROPFILES code for now --- indra/llwindow/lldragdropwin32.cpp | 103 ++++++++++++++++++---------------- indra/llwindow/llwindowcallbacks.cpp | 2 +- indra/llwindow/llwindowcallbacks.h | 2 +- indra/llwindow/llwindowwin32.cpp | 105 ++++++++++++++++++----------------- indra/llwindow/llwindowwin32.h | 2 +- indra/newview/llviewerwindow.cpp | 10 +++- indra/newview/llviewerwindow.h | 2 +- 7 files changed, 121 insertions(+), 105 deletions(-) (limited to 'indra/llwindow/lldragdropwin32.cpp') diff --git a/indra/llwindow/lldragdropwin32.cpp b/indra/llwindow/lldragdropwin32.cpp index 6024931092..74f96f6da3 100644 --- a/indra/llwindow/lldragdropwin32.cpp +++ b/indra/llwindow/lldragdropwin32.cpp @@ -54,6 +54,10 @@ class LLDragDropWin32Target: { }; + virtual ~LLDragDropWin32Target() + { + }; + //////////////////////////////////////////////////////////////////////////////// // ULONG __stdcall AddRef( void ) @@ -105,6 +109,20 @@ class LLDragDropWin32Target: if ( S_OK == pDataObject->QueryGetData( &fmtetc ) ) { mAllowDrop = true; + mDropUrl = std::string(); + mIsSlurl = false; + + STGMEDIUM stgmed; + if( S_OK == pDataObject->GetData( &fmtetc, &stgmed ) ) + { + PVOID data = GlobalLock( stgmed.hGlobal ); + mDropUrl = std::string( (char*)data ); + + mIsSlurl = ( mDropUrl.find( "slurl.com" ) != std::string::npos ); + + GlobalUnlock( stgmed.hGlobal ); + ReleaseStgMedium( &stgmed ); + }; *pdwEffect = DROPEFFECT_COPY; @@ -125,8 +143,6 @@ class LLDragDropWin32Target: { if ( mAllowDrop ) { - bool allowed_to_drop = false; - // XXX MAJOR MAJOR HACK! LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong(mAppWindowHandle, GWL_USERDATA); if (NULL != window_imp) @@ -141,13 +157,17 @@ class LLDragDropWin32Target: LLCoordWindow cursor_coord_window( pt2.x, pt2.y ); window_imp->convertCoords(cursor_coord_window, &gl_coord); MASK mask = gKeyboard->currentMask(TRUE); - allowed_to_drop = window_imp->completeDragNDropRequest( gl_coord, mask, FALSE, std::string( "" ) ); - } - if ( allowed_to_drop ) - *pdwEffect = DROPEFFECT_COPY; - else - *pdwEffect = DROPEFFECT_NONE; + bool allowed_to_drop = window_imp->completeDragNDropRequest( gl_coord, mask, FALSE, std::string( "" ), mIsSlurl ); + if ( allowed_to_drop ) + *pdwEffect = DROPEFFECT_COPY; + else + *pdwEffect = DROPEFFECT_NONE; + + // special case for SLURLs - you can always drop them on the client window and we need a different cursor + if ( mIsSlurl ) + *pdwEffect = DROPEFFECT_LINK; + }; } else { @@ -161,6 +181,7 @@ class LLDragDropWin32Target: // HRESULT __stdcall DragLeave( void ) { + mDropUrl = std::string(); return S_OK; }; @@ -170,48 +191,30 @@ class LLDragDropWin32Target: { if ( mAllowDrop ) { - // construct a FORMATETC object - FORMATETC fmtetc = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; - - // do we have text? - if( S_OK == pDataObject->QueryGetData( &fmtetc ) ) + // window impl stored in Window data (neat!) + LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong( mAppWindowHandle, GWL_USERDATA ); + if ( NULL != window_imp ) { - STGMEDIUM stgmed; - if( S_OK == pDataObject->GetData( &fmtetc, &stgmed ) ) - { - // note: data is in an HGLOBAL - not 'regular' memory - PVOID data = GlobalLock( stgmed.hGlobal ); - - // window impl stored in Window data (neat!) - LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong( mAppWindowHandle, GWL_USERDATA ); - if ( NULL != window_imp ) - { - LLCoordGL gl_coord( 0, 0 ); - - POINT pt_client; - pt_client.x = pt.x; - pt_client.y = pt.y; - ScreenToClient( mAppWindowHandle, &pt_client ); - - LLCoordWindow cursor_coord_window( pt_client.x, pt_client.y ); - window_imp->convertCoords(cursor_coord_window, &gl_coord); - llinfos << "### (Drop) URL is: " << data << llendl; - llinfos << "### raw coords are: " << pt.x << " x " << pt.y << llendl; - llinfos << "### client coords are: " << pt_client.x << " x " << pt_client.y << llendl; - llinfos << "### GL coords are: " << gl_coord.mX << " x " << gl_coord.mY << llendl; - llinfos << llendl; - - // no keyboard modifier option yet but we could one day - MASK mask = gKeyboard->currentMask( TRUE ); - - // actually do the drop - window_imp->completeDragNDropRequest( gl_coord, mask, TRUE, std::string( (char*)data ) ); - }; - - GlobalUnlock( stgmed.hGlobal ); - - ReleaseStgMedium( &stgmed ); - }; + LLCoordGL gl_coord( 0, 0 ); + + POINT pt_client; + pt_client.x = pt.x; + pt_client.y = pt.y; + ScreenToClient( mAppWindowHandle, &pt_client ); + + LLCoordWindow cursor_coord_window( pt_client.x, pt_client.y ); + window_imp->convertCoords(cursor_coord_window, &gl_coord); + llinfos << "### (Drop) URL is: " << mDropUrl << llendl; + llinfos << "### raw coords are: " << pt.x << " x " << pt.y << llendl; + llinfos << "### client coords are: " << pt_client.x << " x " << pt_client.y << llendl; + llinfos << "### GL coords are: " << gl_coord.mX << " x " << gl_coord.mY << llendl; + llinfos << llendl; + + // no keyboard modifier option yet but we could one day + MASK mask = gKeyboard->currentMask( TRUE ); + + // actually do the drop + window_imp->completeDragNDropRequest( gl_coord, mask, TRUE, mDropUrl, mIsSlurl ); }; *pdwEffect = DROPEFFECT_COPY; @@ -230,6 +233,8 @@ class LLDragDropWin32Target: LONG mRefCount; HWND mAppWindowHandle; bool mAllowDrop; + std::string mDropUrl; + bool mIsSlurl; friend class LLWindowWin32; }; diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp index b8927a1ac4..3b0aeeab1f 100644 --- a/indra/llwindow/llwindowcallbacks.cpp +++ b/indra/llwindow/llwindowcallbacks.cpp @@ -163,7 +163,7 @@ void LLWindowCallbacks::handleDataCopy(LLWindow *window, S32 data_type, void *da { } -BOOL LLWindowCallbacks::handleDragNDrop(LLWindow *window, LLCoordGL pos, MASK mask, BOOL drop, std::string data ) +BOOL LLWindowCallbacks::handleDragNDrop(LLWindow *window, LLCoordGL pos, MASK mask, BOOL drop, std::string data, BOOL is_slurl ) { return FALSE; } diff --git a/indra/llwindow/llwindowcallbacks.h b/indra/llwindow/llwindowcallbacks.h index 8e7605a650..1b4a6cbda2 100644 --- a/indra/llwindow/llwindowcallbacks.h +++ b/indra/llwindow/llwindowcallbacks.h @@ -68,7 +68,7 @@ public: virtual void handleWindowBlock(LLWindow *window); // window is taking over CPU for a while virtual void handleWindowUnblock(LLWindow *window); // window coming back after taking over CPU for a while virtual void handleDataCopy(LLWindow *window, S32 data_type, void *data); - virtual BOOL handleDragNDrop(LLWindow *window, LLCoordGL pos, MASK mask, BOOL drop, std::string data); + virtual BOOL handleDragNDrop(LLWindow *window, LLCoordGL pos, MASK mask, BOOL drop, std::string data, BOOL is_slurl); virtual BOOL handleTimerEvent(LLWindow *window); virtual BOOL handleDeviceChange(LLWindow *window); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index eda8cf15b0..78bc3b9c58 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -2355,57 +2355,60 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ }; return 0; - case WM_DROPFILES: - { - // HDROP contains what we need - HDROP hdrop = (HDROP)w_param; - - // get location in window space where drop occured and convert to OpenGL coordinate space - POINT pt; - DragQueryPoint( hdrop, &pt ); - LLCoordGL gl_coord; - LLCoordWindow cursor_coord_window( pt.x, pt.y ); - window_imp->convertCoords(cursor_coord_window, &gl_coord); - - // get payload (eventually, this needs to more advanced and grab size of payload dynamically - static char file_name[ 1024 ]; - DragQueryFileA( hdrop, 0, file_name, 1024 ); - void* url = (void*)( file_name ); - - // if it's a .URL or .lnk ("shortcut") file - if ( std::string( file_name ).find( ".lnk" ) != std::string::npos || - std::string( file_name ).find( ".URL" ) != std::string::npos ) - { - // read through file - looks like a 2 line file with second line URL= but who knows.. - std::ifstream file_handle( file_name ); - if ( file_handle.is_open() ) - { - std::string line; - while ( ! file_handle.eof() ) - { - std::getline( file_handle, line ); - if ( ! file_handle.eof() ) - { - std::string prefix( "URL=" ); - if ( line.find( prefix, 0 ) != std::string::npos ) - { - line = line.substr( 4 ); // skip off the URL= bit - strcpy( (char*)url, line.c_str() ); - break; - }; - }; - }; - file_handle.close(); - }; - }; + // only useful for droppnig files - could be used for file upload dialog one day + //case WM_DROPFILES: + // { + // // HDROP contains what we need + // HDROP hdrop = (HDROP)w_param; + + // // get location in window space where drop occured and convert to OpenGL coordinate space + // POINT pt; + // DragQueryPoint( hdrop, &pt ); + // LLCoordGL gl_coord; + // LLCoordWindow cursor_coord_window( pt.x, pt.y ); + // window_imp->convertCoords(cursor_coord_window, &gl_coord); + + // // get payload (eventually, this needs to more advanced and grab size of payload dynamically + // static char file_name[ 1024 ]; + // DragQueryFileA( hdrop, 0, file_name, 1024 ); + // void* url = (void*)( file_name ); + + // // if it's a .URL or .lnk ("shortcut") file + // if ( std::string( file_name ).find( ".lnk" ) != std::string::npos || + // std::string( file_name ).find( ".URL" ) != std::string::npos ) + // { + // // read through file - looks like a 2 line file with second line URL= but who knows.. + // std::ifstream file_handle( file_name ); + // if ( file_handle.is_open() ) + // { + // std::string line; + // while ( ! file_handle.eof() ) + // { + // std::getline( file_handle, line ); + // if ( ! file_handle.eof() ) + // { + // std::string prefix( "URL=" ); + // if ( line.find( prefix, 0 ) != std::string::npos ) + // { + // line = line.substr( 4 ); // skip off the URL= bit + // strcpy( (char*)url, line.c_str() ); + // break; + // }; + // }; + // }; + // file_handle.close(); + // }; + // }; + + // MASK mask = gKeyboard->currentMask(TRUE); + + // if ( window_imp->completeDragNDropRequest( gl_coord, mask, true, (char*)url, false ) ) + // { + // return 0; + // }; + // } - MASK mask = gKeyboard->currentMask(TRUE); - if ( window_imp->completeDragNDropRequest( gl_coord, mask, true, (char*)url ) ) - { - return 0; - }; - } break; } @@ -3578,9 +3581,9 @@ static LLWString find_context(const LLWString & wtext, S32 focus, S32 focus_leng // final stage of handling drop requests - both from WM_DROPFILES message // for files and via IDropTarget interface requests. -BOOL LLWindowWin32::completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, BOOL drop, const std::string url ) +BOOL LLWindowWin32::completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, BOOL drop, const std::string url, BOOL is_slurl ) { - return mCallbacks->handleDragNDrop( this, gl_coord, mask, drop, url ); + return mCallbacks->handleDragNDrop( this, gl_coord, mask, drop, url, is_slurl ); } // Handle WM_IME_REQUEST message. diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index e99c26b7f1..7f7acd5751 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -113,7 +113,7 @@ public: /*virtual*/ void interruptLanguageTextInput(); /*virtual*/ void spawnWebBrowser(const std::string& escaped_url); - BOOL completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, BOOL drop, const std::string url ); + BOOL completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, BOOL drop, const std::string url, BOOL is_slurl ); static std::vector getDynamicFallbackFontList(); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 17b9490f63..dd84140d5b 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -80,6 +80,7 @@ #include "llviewermenu.h" #include "lltooltip.h" #include "llmediaentry.h" +#include "llurldispatcher.h" // newview includes #include "llagent.h" @@ -819,11 +820,18 @@ BOOL LLViewerWindow::handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MAS return TRUE; } -BOOL LLViewerWindow::handleDragNDrop( LLWindow *window, LLCoordGL pos, MASK mask, BOOL drop, std::string data ) +BOOL LLViewerWindow::handleDragNDrop( LLWindow *window, LLCoordGL pos, MASK mask, BOOL drop, std::string data, BOOL slurl ) { BOOL result = FALSE; if (gSavedSettings.getBOOL("PrimMediaDragNDrop")) { + // special case SLURLs + if ( slurl ) + { + LLURLDispatcher::dispatch( data, NULL, true ); + return TRUE; + }; + LLPickInfo pick_info = pickImmediate( pos.mX, pos.mY, TRUE /*BOOL pick_transparent*/ ); LLUUID object_id = pick_info.getObjectID(); diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 428c602b73..4296495067 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -170,7 +170,7 @@ public: /*virtual*/ BOOL handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask); /*virtual*/ BOOL handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask); /*virtual*/ BOOL handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask); - /*virtual*/ BOOL handleDragNDrop(LLWindow *window, LLCoordGL pos, MASK mask, BOOL drop, std::string data); + /*virtual*/ BOOL handleDragNDrop(LLWindow *window, LLCoordGL pos, MASK mask, BOOL drop, std::string data, BOOL slurl); void handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask); /*virtual*/ void handleMouseLeave(LLWindow *window); /*virtual*/ void handleResize(LLWindow *window, S32 x, S32 y); -- cgit v1.3 From ff53d4ff9b497f4f0f30035d7e02e6df290db6a4 Mon Sep 17 00:00:00 2001 From: Rick Pasetto Date: Thu, 3 Dec 2009 12:19:02 -0800 Subject: Fix Windows build based on API change to handleDragNDrop() --- indra/llwindow/lldragdropwin32.cpp | 4 ++-- indra/llwindow/llwindowwin32.cpp | 4 ++-- indra/llwindow/llwindowwin32.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'indra/llwindow/lldragdropwin32.cpp') diff --git a/indra/llwindow/lldragdropwin32.cpp b/indra/llwindow/lldragdropwin32.cpp index 74f96f6da3..a96f04ff1f 100644 --- a/indra/llwindow/lldragdropwin32.cpp +++ b/indra/llwindow/lldragdropwin32.cpp @@ -158,7 +158,7 @@ class LLDragDropWin32Target: window_imp->convertCoords(cursor_coord_window, &gl_coord); MASK mask = gKeyboard->currentMask(TRUE); - bool allowed_to_drop = window_imp->completeDragNDropRequest( gl_coord, mask, FALSE, std::string( "" ), mIsSlurl ); + bool allowed_to_drop = window_imp->completeDragNDropRequest( gl_coord, mask, FALSE, std::string( "" ) ); if ( allowed_to_drop ) *pdwEffect = DROPEFFECT_COPY; else @@ -214,7 +214,7 @@ class LLDragDropWin32Target: MASK mask = gKeyboard->currentMask( TRUE ); // actually do the drop - window_imp->completeDragNDropRequest( gl_coord, mask, TRUE, mDropUrl, mIsSlurl ); + window_imp->completeDragNDropRequest( gl_coord, mask, TRUE, mDropUrl ); }; *pdwEffect = DROPEFFECT_COPY; diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 78bc3b9c58..dc1e2c017c 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -3581,9 +3581,9 @@ static LLWString find_context(const LLWString & wtext, S32 focus, S32 focus_leng // final stage of handling drop requests - both from WM_DROPFILES message // for files and via IDropTarget interface requests. -BOOL LLWindowWin32::completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, BOOL drop, const std::string url, BOOL is_slurl ) +BOOL LLWindowWin32::completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, BOOL drop, const std::string url ) { - return mCallbacks->handleDragNDrop( this, gl_coord, mask, drop, url, is_slurl ); + return mCallbacks->handleDragNDrop( this, gl_coord, mask, drop, url ); } // Handle WM_IME_REQUEST message. diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index 7f7acd5751..e99c26b7f1 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -113,7 +113,7 @@ public: /*virtual*/ void interruptLanguageTextInput(); /*virtual*/ void spawnWebBrowser(const std::string& escaped_url); - BOOL completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, BOOL drop, const std::string url, BOOL is_slurl ); + BOOL completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, BOOL drop, const std::string url ); static std::vector getDynamicFallbackFontList(); -- cgit v1.3 From 4c33c54ce03bffd3ad75be3dccaed2d26a68e157 Mon Sep 17 00:00:00 2001 From: Rick Pasetto Date: Thu, 3 Dec 2009 19:02:12 -0800 Subject: Fix windows build to now use DragNDropAction instead of a bool 'drop' --- indra/llwindow/lldragdropwin32.cpp | 95 +++++++++++++++++++++++++++++++------- indra/llwindow/llwindowwin32.cpp | 4 +- indra/llwindow/llwindowwin32.h | 3 +- 3 files changed, 83 insertions(+), 19 deletions(-) (limited to 'indra/llwindow/lldragdropwin32.cpp') diff --git a/indra/llwindow/lldragdropwin32.cpp b/indra/llwindow/lldragdropwin32.cpp index a96f04ff1f..4865570f07 100644 --- a/indra/llwindow/lldragdropwin32.cpp +++ b/indra/llwindow/lldragdropwin32.cpp @@ -117,15 +117,45 @@ class LLDragDropWin32Target: { PVOID data = GlobalLock( stgmed.hGlobal ); mDropUrl = std::string( (char*)data ); - - mIsSlurl = ( mDropUrl.find( "slurl.com" ) != std::string::npos ); + // XXX MAJOR MAJOR HACK! + LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong(mAppWindowHandle, GWL_USERDATA); + if (NULL != window_imp) + { + LLCoordGL gl_coord( 0, 0 ); + + POINT pt2; + pt2.x = pt.x; + pt2.y = pt.y; + ScreenToClient( mAppWindowHandle, &pt2 ); + + LLCoordWindow cursor_coord_window( pt2.x, pt2.y ); + window_imp->convertCoords(cursor_coord_window, &gl_coord); + MASK mask = gKeyboard->currentMask(TRUE); + + LLWindowCallbacks::DragNDropResult result = window_imp->completeDragNDropRequest( gl_coord, mask, + LLWindowCallbacks::DNDA_START_TRACKING, mDropUrl ); + + switch (result) + { + case LLWindowCallbacks::DND_COPY: + *pdwEffect = DROPEFFECT_COPY; + break; + case LLWindowCallbacks::DND_LINK: + *pdwEffect = DROPEFFECT_LINK; + break; + case LLWindowCallbacks::DND_MOVE: + *pdwEffect = DROPEFFECT_MOVE; + break; + case LLWindowCallbacks::DND_NONE: + default: + *pdwEffect = DROPEFFECT_NONE; + break; + } + }; GlobalUnlock( stgmed.hGlobal ); ReleaseStgMedium( &stgmed ); }; - - *pdwEffect = DROPEFFECT_COPY; - SetFocus( mAppWindowHandle ); } else @@ -158,15 +188,25 @@ class LLDragDropWin32Target: window_imp->convertCoords(cursor_coord_window, &gl_coord); MASK mask = gKeyboard->currentMask(TRUE); - bool allowed_to_drop = window_imp->completeDragNDropRequest( gl_coord, mask, FALSE, std::string( "" ) ); - if ( allowed_to_drop ) + LLWindowCallbacks::DragNDropResult result = window_imp->completeDragNDropRequest( gl_coord, mask, + LLWindowCallbacks::DNDA_TRACK, std::string( "" ) ); + + switch (result) + { + case LLWindowCallbacks::DND_COPY: *pdwEffect = DROPEFFECT_COPY; - else - *pdwEffect = DROPEFFECT_NONE; - - // special case for SLURLs - you can always drop them on the client window and we need a different cursor - if ( mIsSlurl ) + break; + case LLWindowCallbacks::DND_LINK: *pdwEffect = DROPEFFECT_LINK; + break; + case LLWindowCallbacks::DND_MOVE: + *pdwEffect = DROPEFFECT_MOVE; + break; + case LLWindowCallbacks::DND_NONE: + default: + *pdwEffect = DROPEFFECT_NONE; + break; + } }; } else @@ -181,7 +221,14 @@ class LLDragDropWin32Target: // HRESULT __stdcall DragLeave( void ) { - mDropUrl = std::string(); + // XXX MAJOR MAJOR HACK! + LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong(mAppWindowHandle, GWL_USERDATA); + if (NULL != window_imp) + { + LLCoordGL gl_coord( 0, 0 ); + MASK mask = gKeyboard->currentMask(TRUE); + window_imp->completeDragNDropRequest( gl_coord, mask, LLWindowCallbacks::DNDA_STOP_TRACKING, mDropUrl ); + }; return S_OK; }; @@ -214,10 +261,26 @@ class LLDragDropWin32Target: MASK mask = gKeyboard->currentMask( TRUE ); // actually do the drop - window_imp->completeDragNDropRequest( gl_coord, mask, TRUE, mDropUrl ); - }; + LLWindowCallbacks::DragNDropResult result = window_imp->completeDragNDropRequest( gl_coord, mask, + LLWindowCallbacks::DNDA_DROPPED, mDropUrl ); - *pdwEffect = DROPEFFECT_COPY; + switch (result) + { + case LLWindowCallbacks::DND_COPY: + *pdwEffect = DROPEFFECT_COPY; + break; + case LLWindowCallbacks::DND_LINK: + *pdwEffect = DROPEFFECT_LINK; + break; + case LLWindowCallbacks::DND_MOVE: + *pdwEffect = DROPEFFECT_MOVE; + break; + case LLWindowCallbacks::DND_NONE: + default: + *pdwEffect = DROPEFFECT_NONE; + break; + } + }; } else { diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index dc1e2c017c..322b9c9a01 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -3581,9 +3581,9 @@ static LLWString find_context(const LLWString & wtext, S32 focus, S32 focus_leng // final stage of handling drop requests - both from WM_DROPFILES message // for files and via IDropTarget interface requests. -BOOL LLWindowWin32::completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, BOOL drop, const std::string url ) +LLWindowCallbacks::DragNDropResult LLWindowWin32::completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, LLWindowCallbacks::DragNDropAction action, const std::string url ) { - return mCallbacks->handleDragNDrop( this, gl_coord, mask, drop, url ); + return mCallbacks->handleDragNDrop( this, gl_coord, mask, action, url ); } // Handle WM_IME_REQUEST message. diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index e99c26b7f1..3e907cde00 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -39,6 +39,7 @@ #include #include "llwindow.h" +#include "llwindowcallbacks.h" #include "lldragdropwin32.h" // Hack for async host by name @@ -113,7 +114,7 @@ public: /*virtual*/ void interruptLanguageTextInput(); /*virtual*/ void spawnWebBrowser(const std::string& escaped_url); - BOOL completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, BOOL drop, const std::string url ); + LLWindowCallbacks::DragNDropResult completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, LLWindowCallbacks::DragNDropAction action, const std::string url ); static std::vector getDynamicFallbackFontList(); -- cgit v1.3