Revision: 25057
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=25057
Author:   jesterking
Date:     2009-12-02 01:57:12 +0100 (Wed, 02 Dec 2009)

Log Message:
-----------
Apply patch [#20145] Ghost Win32 roundup patch: Minimum Window Size, Continuous 
Grab and Drag And Drop

This nice patch by Matt D. (matd in #blendercoders) adds three nice features 
that can be seen already in the other supported OSes:

* minimum window size: to prevent some bugs with the window manager of Blender, 
system windows cannot be resized smaller than the minimum size.

* Continuous Grab is finally in Windows! Default settings since alpha 0 already 
have the feature enabled by default, so grab a new build and enjoy :)

* GHOST support for drag and drop added. This prepares Blender for drag and 
drop from OS -> Blender. Currently not very useful, since wm needs to be 
readied for that. But it does work (do BF_GHOST_DEBUG=1 build and drag a file 
onto a Blender window).

Thanks Matt D.!

Modified Paths:
--------------
    trunk/blender/config/win32-mingw-config.py
    trunk/blender/intern/ghost/SConscript
    trunk/blender/intern/ghost/intern/GHOST_Debug.h
    trunk/blender/intern/ghost/intern/GHOST_EventPrinter.cpp
    trunk/blender/intern/ghost/intern/GHOST_SystemWin32.cpp
    trunk/blender/intern/ghost/intern/GHOST_SystemWin32.h
    trunk/blender/intern/ghost/intern/GHOST_WindowWin32.cpp
    trunk/blender/intern/ghost/intern/GHOST_WindowWin32.h
    trunk/blender/source/blender/windowmanager/intern/wm_cursors.c
    trunk/blender/tools/btools.py

Added Paths:
-----------
    trunk/blender/intern/ghost/intern/GHOST_DropTargetWin32.cpp
    trunk/blender/intern/ghost/intern/GHOST_DropTargetWin32.h

Modified: trunk/blender/config/win32-mingw-config.py
===================================================================
--- trunk/blender/config/win32-mingw-config.py  2009-12-02 00:53:33 UTC (rev 
25056)
+++ trunk/blender/config/win32-mingw-config.py  2009-12-02 00:57:12 UTC (rev 
25057)
@@ -145,7 +145,7 @@
 
 CC_WARN = [ '-Wall' ]
 
-LLIBS = ['-lshell32', '-lshfolder', '-lgdi32', '-lmsvcrt', '-lwinmm', 
'-lmingw32', '-lm', '-lws2_32', '-lz', '-lstdc++']
+LLIBS = ['-lshell32', '-lshfolder', '-lgdi32', '-lmsvcrt', '-lwinmm', 
'-lmingw32', '-lm', '-lws2_32', '-lz', '-lstdc++','-lole32','-luuid']
 
 BF_DEBUG = False
 BF_DEBUG_CCFLAGS= ['-g']

Modified: trunk/blender/intern/ghost/SConscript
===================================================================
--- trunk/blender/intern/ghost/SConscript       2009-12-02 00:53:33 UTC (rev 
25056)
+++ trunk/blender/intern/ghost/SConscript       2009-12-02 00:57:12 UTC (rev 
25057)
@@ -37,8 +37,12 @@
        print "Unknown window system specified."
        Exit()
 
+defs=['_USE_MATH_DEFINES']
+if env['BF_GHOST_DEBUG']:
+       defs.append('BF_GHOST_DEBUG')
+       
 incs = '. ../string ' + env['BF_OPENGL_INC']
 if window_system in ('win32-vc', 'win32-mingw', 'cygwin', 'linuxcross', 
'win64-vc'):
        incs = env['BF_WINTAB_INC'] + ' ' + incs
-env.BlenderLib ('bf_ghost', sources, Split(incs), 
defines=['_USE_MATH_DEFINES'], libtype=['intern','player'], priority = [40,15] 
) 
+env.BlenderLib ('bf_ghost', sources, Split(incs), defines=defs, 
libtype=['intern','player'], priority = [40,15] ) 
 

Modified: trunk/blender/intern/ghost/intern/GHOST_Debug.h
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_Debug.h     2009-12-02 00:53:33 UTC 
(rev 25056)
+++ trunk/blender/intern/ghost/intern/GHOST_Debug.h     2009-12-02 00:57:12 UTC 
(rev 25057)
@@ -37,12 +37,17 @@
 #ifdef WIN32
        #ifdef _DEBUG
                #pragma warning (disable:4786) // suppress stl-MSVC debug info 
warning
-               #define GHOST_DEBUG
+               // #define GHOST_DEBUG
        #endif // _DEBUG
 #endif // WIN32
 
+#ifdef BF_GHOST_DEBUG 
+       #define GHOST_DEBUG // spit ghost events to stdout
+#endif // BF_GHOST_DEBUG 
+
 #ifdef GHOST_DEBUG
        #include <iostream>
+       #include <stdio.h> //for printf()
 #endif // GHOST_DEBUG
 
 

Added: trunk/blender/intern/ghost/intern/GHOST_DropTargetWin32.cpp
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_DropTargetWin32.cpp                 
        (rev 0)
+++ trunk/blender/intern/ghost/intern/GHOST_DropTargetWin32.cpp 2009-12-02 
00:57:12 UTC (rev 25057)
@@ -0,0 +1,426 @@
+/**
+ * $Id: $
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+ 
+#include "GHOST_Debug.h"
+#include "GHOST_DropTargetWin32.h"
+
+#ifdef GHOST_DEBUG
+// utility
+void printLastError(void);
+#endif // GHOST_DEBUG
+
+
+GHOST_DropTargetWin32::GHOST_DropTargetWin32(GHOST_WindowWin32 * window, 
GHOST_SystemWin32 * system)
+:
+m_window(window),
+m_system(system)
+{
+       m_cRef = 1;
+       m_hWnd = window->getHWND();
+       m_draggedObjectType = GHOST_kDragnDropTypeUnknown;
+       
+       // register our window as drop target
+       ::RegisterDragDrop(m_hWnd, this);
+}
+
+GHOST_DropTargetWin32::~GHOST_DropTargetWin32()
+{
+       ::RevokeDragDrop(m_hWnd);
+}
+
+
+/* 
+ *     IUnknown::QueryInterface
+ */
+HRESULT __stdcall GHOST_DropTargetWin32::QueryInterface (REFIID riid, void ** 
ppvObj)
+{
+
+       if (!ppvObj)
+               return E_INVALIDARG;
+       *ppvObj = NULL;
+
+       if(riid == IID_IUnknown || riid == IID_IDropTarget)
+       {
+               AddRef();
+               *ppvObj = (void*)this;
+               return S_OK;
+       }
+       else
+       {
+               *ppvObj = 0;
+               return E_NOINTERFACE;
+       }
+}
+
+
+/* 
+ *     IUnknown::AddRef 
+ */
+
+ULONG __stdcall GHOST_DropTargetWin32::AddRef(void)
+{
+       return ::InterlockedIncrement(&m_cRef);
+}
+
+/* 
+ * IUnknown::Release
+ */
+ULONG __stdcall GHOST_DropTargetWin32::Release(void)
+{
+       ULONG refs = ::InterlockedDecrement(&m_cRef);
+               
+       if(refs == 0)
+       {
+               delete this;
+               return 0;
+       }
+       else
+       {
+               return refs;
+       }
+}
+
+/* 
+ * Implementation of IDropTarget::DragEnter
+ */
+HRESULT __stdcall GHOST_DropTargetWin32::DragEnter(IDataObject * pDataObject, 
DWORD grfKeyState, POINTL pt, DWORD * pdwEffect)
+{
+       // we don't know yet if we accept the drop.
+       m_window->setAcceptDragOperation(false);
+       *pdwEffect = DROPEFFECT_NONE;
+       
+       m_draggedObjectType = getGhostType(pDataObject);
+       m_system->pushDragDropEvent(GHOST_kEventDraggingEntered, 
m_draggedObjectType, m_window, pt.x, pt.y, NULL);
+       return S_OK;
+}
+
+/* 
+ * Implementation of IDropTarget::DragOver
+ */
+HRESULT __stdcall GHOST_DropTargetWin32::DragOver(DWORD grfKeyState, POINTL 
pt, DWORD * pdwEffect)
+{
+       if(m_window->canAcceptDragOperation())
+       {
+               *pdwEffect = allowedDropEffect(*pdwEffect);
+       }
+       else
+       {
+               *pdwEffect = DROPEFFECT_NONE;
+               //*pdwEffect = DROPEFFECT_COPY; // XXX Uncomment to test drop. 
Drop will not be called if pdwEffect == DROPEFFECT_NONE.
+       }
+       m_system->pushDragDropEvent(GHOST_kEventDraggingUpdated, 
m_draggedObjectType, m_window, pt.x, pt.y, NULL);
+       return S_OK;
+}
+
+/* 
+ * Implementation of IDropTarget::DragLeave
+ */
+HRESULT __stdcall GHOST_DropTargetWin32::DragLeave(void)
+{
+       m_system->pushDragDropEvent(GHOST_kEventDraggingExited, 
m_draggedObjectType, m_window, 0, 0, NULL);
+       m_draggedObjectType = GHOST_kDragnDropTypeUnknown;
+       return S_OK;
+}
+
+/* Implementation of IDropTarget::Drop
+ * This function will not be called if pdwEffect is set to DROPEFFECT_NONE in 
+ * the implementation of IDropTarget::DragOver
+ */
+HRESULT __stdcall GHOST_DropTargetWin32::Drop(IDataObject * pDataObject, DWORD 
grfKeyState, POINTL pt, DWORD * pdwEffect)
+{
+       void * data = getGhostData(pDataObject);
+       if(m_window->canAcceptDragOperation())
+       {
+               *pdwEffect = allowedDropEffect(*pdwEffect);
+
+       }
+       else
+       {
+               *pdwEffect = DROPEFFECT_NONE;
+       }
+       if (data)
+               m_system->pushDragDropEvent(GHOST_kEventDraggingDropDone, 
m_draggedObjectType, m_window, pt.x, pt.y, data );
+               
+       m_draggedObjectType = GHOST_kDragnDropTypeUnknown;
+       return S_OK;
+}
+
+/* 
+ * Helpers
+ */
+ 
+DWORD GHOST_DropTargetWin32::allowedDropEffect(DWORD dwAllowed)
+{
+       DWORD dwEffect = DROPEFFECT_NONE;
+       if(dwAllowed & DROPEFFECT_COPY) 
+               dwEffect = DROPEFFECT_COPY;
+
+       return dwEffect;
+}
+
+GHOST_TDragnDropTypes GHOST_DropTargetWin32::getGhostType(IDataObject * 
pDataObject)
+{
+       /* Text
+        * Note: Unicode text is aviable as CF_TEXT too, the system can do the 
+        * conversion, but we do the conversion ourself with 
WC_NO_BEST_FIT_CHARS.
+        */
+       FORMATETC fmtetc = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
+       if(pDataObject->QueryGetData(&fmtetc) == S_OK)
+       {
+               return GHOST_kDragnDropTypeString;
+       }
+
+       // Filesnames
+       fmtetc.cfFormat = CF_HDROP;
+       if(pDataObject->QueryGetData(&fmtetc) == S_OK)
+       {
+               return GHOST_kDragnDropTypeFilenames;
+       }
+
+       return GHOST_kDragnDropTypeUnknown;
+}
+
+void * GHOST_DropTargetWin32::getGhostData(IDataObject * pDataObject)
+{
+       GHOST_TDragnDropTypes type = getGhostType(pDataObject);
+       switch(type)
+       {
+               case GHOST_kDragnDropTypeFilenames:
+                       return getDropDataAsFilenames(pDataObject);
+                       break;
+               case GHOST_kDragnDropTypeString:
+                       return getDropDataAsString(pDataObject);
+                       break;
+               case GHOST_kDragnDropTypeBitmap:
+                       //return getDropDataAsBitmap(pDataObject);
+                       break;
+               default:
+#ifdef GHOST_DEBUG
+                       ::printf("\nGHOST_kDragnDropTypeUnknown");
+#endif // GHOST_DEBUG
+                       return NULL;
+                       break;
+       }
+       return NULL;
+}
+
+void * GHOST_DropTargetWin32::getDropDataAsFilenames(IDataObject * pDataObject)
+{
+       UINT  totfiles, nvalid=0;
+       WCHAR fpath [MAX_PATH]; 
+       char * temp_path;
+       GHOST_TStringArray *strArray = NULL;
+       FORMATETC fmtetc = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
+       STGMEDIUM stgmed;
+       HDROP hdrop;
+
+       // Check if dataobject supplies the format we want.
+       // Double checking here, first in getGhostType.
+       if(pDataObject->QueryGetData(&fmtetc) == S_OK)
+       {
+               if(pDataObject->GetData(&fmtetc, &stgmed) == S_OK)
+               {
+                       hdrop = (HDROP)::GlobalLock(stgmed.hGlobal);
+
+                       totfiles = ::DragQueryFileW ( hdrop, -1, NULL, 0 );
+                       if (!totfiles)
+                       {
+                               ::GlobalUnlock(stgmed.hGlobal);
+                               return NULL;
+                       }
+
+                       strArray = (GHOST_TStringArray*) 
::malloc(sizeof(GHOST_TStringArray));
+                       strArray->count = 0;
+                       strArray->strings = (GHOST_TUns8**) 
::malloc(totfiles*sizeof(GHOST_TUns8*));
+
+                       for ( UINT nfile = 0; nfile < totfiles; nfile++ )
+                       {
+                               if ( ::DragQueryFileW ( hdrop, nfile, fpath, 
MAX_PATH ) > 0 )
+                               {
+                                       if ( !WideCharToANSI(fpath, temp_path) )
+                                       {
+                                               continue;
+                                       } 
+                                       // Just ignore paths that could not be 
converted verbatim.
+                                       if (strpbrk(temp_path, "?"))
+                                       {
+#ifdef GHOST_DEBUG
+                                               ::printf("\ndiscarding path 
that contains illegal characters: %s", temp_path);
+#endif // GHOST_DEBUG
+                                               ::free(temp_path);
+                                               temp_path = NULL;
+                                               continue;
+                                       }
+                                       strArray->strings[nvalid] = 
(GHOST_TUns8*) temp_path;
+                                       strArray->count = nvalid+1;
+                                       nvalid++;
+                               }
+                       }
+                       // Free up memory.
+                       ::GlobalUnlock(stgmed.hGlobal);
+                       ::ReleaseStgMedium(&stgmed);
+                       
+                       return strArray;
+               }
+       }
+       return NULL;
+}
+
+void * GHOST_DropTargetWin32::getDropDataAsString(IDataObject * pDataObject)
+{
+       char* tmp_string;
+       FORMATETC fmtetc = { CF_UNICODETEXT, 0, DVASPECT_CONTENT, -1, 
TYMED_HGLOBAL };
+       STGMEDIUM stgmed;
+
+       // Try unicode first.
+       // Check if dataobject supplies the format we want.
+       if(pDataObject->QueryGetData(&fmtetc) == S_OK)
+       {
+               if(pDataObject->GetData(&fmtetc, &stgmed) == S_OK)
+               {
+                       LPCWSTR wstr = (LPCWSTR)::GlobalLock(stgmed.hGlobal);
+                       if ( !WideCharToANSI(wstr, tmp_string) )
+                       {
+                               ::GlobalUnlock(stgmed.hGlobal);
+                               return NULL;

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to