Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
7993bd3d
Commit
7993bd3d
authored
Mar 13, 2013
by
Ken Thomases
Committed by
Alexandre Julliard
Mar 14, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winemac: Implement support for drag-and-drop.
parent
fb5794a7
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
780 additions
and
7 deletions
+780
-7
Makefile.in
dlls/winemac.drv/Makefile.in
+3
-1
clipboard.c
dlls/winemac.drv/clipboard.c
+4
-4
cocoa_event.m
dlls/winemac.drv/cocoa_event.m
+15
-2
cocoa_window.m
dlls/winemac.drv/cocoa_window.m
+74
-0
dragdrop.c
dlls/winemac.drv/dragdrop.c
+635
-0
event.c
dlls/winemac.drv/event.c
+12
-0
macdrv.h
dlls/winemac.drv/macdrv.h
+8
-0
macdrv_cocoa.h
dlls/winemac.drv/macdrv_cocoa.h
+29
-0
No files found.
dlls/winemac.drv/Makefile.in
View file @
7993bd3d
MODULE
=
winemac.drv
IMPORTS
=
user32 gdi32 advapi32
IMPORTS
=
uuid user32 gdi32 advapi32
DELAYIMPORTS
=
ole32 shell32
EXTRALIBS
=
-framework
AppKit
-framework
Carbon
-framework
Security
-framework
OpenGL
C_SRCS
=
\
clipboard.c
\
display.c
\
dragdrop.c
\
event.c
\
gdi.c
\
keyboard.c
\
...
...
dlls/winemac.drv/clipboard.c
View file @
7993bd3d
...
...
@@ -226,7 +226,7 @@ static const CFStringRef registered_name_type_prefix = CFSTR("org.winehq.registe
/**************************************************************************
* debugstr_format
*/
static
const
char
*
debugstr_format
(
UINT
id
)
const
char
*
debugstr_format
(
UINT
id
)
{
WCHAR
buffer
[
256
];
...
...
@@ -1259,7 +1259,7 @@ static BOOL release_ownership(void)
/**************************************************************************
* macdrv_get_pasteboard_data
*/
static
HANDLE
macdrv_get_pasteboard_data
(
CFTypeRef
pasteboard
,
UINT
desired_format
)
HANDLE
macdrv_get_pasteboard_data
(
CFTypeRef
pasteboard
,
UINT
desired_format
)
{
CFArrayRef
types
;
CFIndex
count
;
...
...
@@ -1326,7 +1326,7 @@ static HANDLE macdrv_get_pasteboard_data(CFTypeRef pasteboard, UINT desired_form
/**************************************************************************
* macdrv_pasteboard_has_format
*/
static
BOOL
macdrv_pasteboard_has_format
(
CFTypeRef
pasteboard
,
UINT
desired_format
)
BOOL
macdrv_pasteboard_has_format
(
CFTypeRef
pasteboard
,
UINT
desired_format
)
{
CFArrayRef
types
;
int
count
;
...
...
@@ -1369,7 +1369,7 @@ static BOOL macdrv_pasteboard_has_format(CFTypeRef pasteboard, UINT desired_form
/**************************************************************************
* macdrv_copy_pasteboard_formats
*/
static
CFArrayRef
macdrv_copy_pasteboard_formats
(
CFTypeRef
pasteboard
)
CFArrayRef
macdrv_copy_pasteboard_formats
(
CFTypeRef
pasteboard
)
{
CFArrayRef
types
;
CFIndex
count
;
...
...
dlls/winemac.drv/cocoa_event.m
View file @
7993bd3d
...
...
@@ -460,8 +460,21 @@ void macdrv_release_query(macdrv_query *query)
{
if
(
OSAtomicDecrement32Barrier
(
&
query
->
refs
)
<=
0
)
{
if
(
query
->
type
==
QUERY_PASTEBOARD_DATA
&&
query
->
pasteboard_data
.
type
)
CFRelease
(
query
->
pasteboard_data
.
type
);
switch
(
query
->
type
)
{
case
QUERY_DRAG_OPERATION
:
if
(
query
->
drag_operation
.
pasteboard
)
CFRelease
(
query
->
drag_operation
.
pasteboard
);
break
;
case
QUERY_DRAG_DROP
:
if
(
query
->
drag_drop
.
pasteboard
)
CFRelease
(
query
->
drag_drop
.
pasteboard
);
break
;
case
QUERY_PASTEBOARD_DATA
:
if
(
query
->
pasteboard_data
.
type
)
CFRelease
(
query
->
pasteboard_data
.
type
);
break
;
}
[(
WineWindow
*
)
query
->
window
release
];
free
(
query
);
}
...
...
dlls/winemac.drv/cocoa_window.m
View file @
7993bd3d
...
...
@@ -324,6 +324,10 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
window
.
hwnd
=
hwnd
;
window
.
queue
=
queue
;
[
window
registerForDraggedTypes
:[
NSArray
arrayWithObjects
:(
NSString
*
)
kUTTypeData
,
(
NSString
*
)
kUTTypeContent
,
nil
]];
contentView
=
[[[
WineContentView
alloc
]
initWithFrame
:
NSZeroRect
]
autorelease
];
if
(
!
contentView
)
return
nil
;
...
...
@@ -1189,6 +1193,76 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
macdrv_release_query
(
query
);
}
/*
* ---------- NSDraggingDestination methods ----------
*/
-
(
NSDragOperation
)
draggingEntered
:
(
id
<
NSDraggingInfo
>
)
sender
{
return
[
self
draggingUpdated
:
sender
];
}
-
(
void
)
draggingExited
:
(
id
<
NSDraggingInfo
>
)
sender
{
// This isn't really a query. We don't need any response. However, it
// has to be processed in a similar manner as the other drag-and-drop
// queries in order to maintain the proper order of operations.
macdrv_query
*
query
=
macdrv_create_query
();
query
->
type
=
QUERY_DRAG_EXITED
;
query
->
window
=
(
macdrv_window
)[
self
retain
];
[
self
.
queue
query
:
query
timeout
:
0
.
1
];
macdrv_release_query
(
query
);
}
-
(
NSDragOperation
)
draggingUpdated
:
(
id
<
NSDraggingInfo
>
)
sender
{
NSDragOperation
ret
;
NSPoint
pt
=
[[
self
contentView
]
convertPoint
:[
sender
draggingLocation
]
fromView
:
nil
];
NSPasteboard
*
pb
=
[
sender
draggingPasteboard
];
macdrv_query
*
query
=
macdrv_create_query
();
query
->
type
=
QUERY_DRAG_OPERATION
;
query
->
window
=
(
macdrv_window
)[
self
retain
];
query
->
drag_operation
.
x
=
pt
.
x
;
query
->
drag_operation
.
y
=
pt
.
y
;
query
->
drag_operation
.
offered_ops
=
[
sender
draggingSourceOperationMask
];
query
->
drag_operation
.
accepted_op
=
NSDragOperationNone
;
query
->
drag_operation
.
pasteboard
=
(
CFTypeRef
)[
pb
retain
];
[
self
.
queue
query
:
query
timeout
:
3
];
ret
=
query
->
status
?
query
->
drag_operation
.
accepted_op
:
NSDragOperationNone
;
macdrv_release_query
(
query
);
return
ret
;
}
-
(
BOOL
)
performDragOperation
:
(
id
<
NSDraggingInfo
>
)
sender
{
BOOL
ret
;
NSPoint
pt
=
[[
self
contentView
]
convertPoint
:[
sender
draggingLocation
]
fromView
:
nil
];
NSPasteboard
*
pb
=
[
sender
draggingPasteboard
];
macdrv_query
*
query
=
macdrv_create_query
();
query
->
type
=
QUERY_DRAG_DROP
;
query
->
window
=
(
macdrv_window
)[
self
retain
];
query
->
drag_drop
.
x
=
pt
.
x
;
query
->
drag_drop
.
y
=
pt
.
y
;
query
->
drag_drop
.
op
=
[
sender
draggingSourceOperationMask
];
query
->
drag_drop
.
pasteboard
=
(
CFTypeRef
)[
pb
retain
];
[
self
.
queue
query
:
query
timeout
:
3
*
60
processEvents
:
YES
];
ret
=
query
->
status
;
macdrv_release_query
(
query
);
return
ret
;
}
-
(
BOOL
)
wantsPeriodicDraggingUpdates
{
return
NO
;
}
@end
...
...
dlls/winemac.drv/dragdrop.c
0 → 100644
View file @
7993bd3d
/*
* MACDRV Drag and drop code
*
* Copyright 2003 Ulrich Czekalla
* Copyright 2007 Damjan Jovanovic
* Copyright 2013 Ken Thomases for CodeWeavers Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#define NONAMELESSUNION
#include "macdrv.h"
#define COBJMACROS
#include "objidl.h"
#include "shellapi.h"
#include "shlobj.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
dragdrop
);
static
IDataObject
*
active_data_object
;
static
HWND
last_droptarget_hwnd
;
typedef
struct
{
IDataObject
IDataObject_iface
;
LONG
ref
;
CFTypeRef
pasteboard
;
}
DragDropDataObject
;
static
inline
DragDropDataObject
*
impl_from_IDataObject
(
IDataObject
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
DragDropDataObject
,
IDataObject_iface
);
}
static
HRESULT
WINAPI
dddo_QueryInterface
(
IDataObject
*
iface
,
REFIID
riid
,
LPVOID
*
ppvObj
)
{
DragDropDataObject
*
This
=
impl_from_IDataObject
(
iface
);
TRACE
(
"(%p)->(%s,%p)
\n
"
,
This
,
debugstr_guid
(
riid
),
ppvObj
);
if
(
IsEqualIID
(
riid
,
&
IID_IUnknown
)
||
(
IsEqualIID
(
riid
,
&
IID_IDataObject
)))
{
*
ppvObj
=
This
;
IUnknown_AddRef
((
IUnknown
*
)
This
);
return
S_OK
;
}
*
ppvObj
=
NULL
;
return
E_NOINTERFACE
;
}
static
ULONG
WINAPI
dddo_AddRef
(
IDataObject
*
iface
)
{
DragDropDataObject
*
This
=
impl_from_IDataObject
(
iface
);
ULONG
refCount
=
InterlockedIncrement
(
&
This
->
ref
);
TRACE
(
"(%p)->(count=%u)
\n
"
,
This
,
refCount
-
1
);
return
refCount
;
}
static
ULONG
WINAPI
dddo_Release
(
IDataObject
*
iface
)
{
DragDropDataObject
*
This
=
impl_from_IDataObject
(
iface
);
ULONG
refCount
=
InterlockedDecrement
(
&
This
->
ref
);
TRACE
(
"(%p)->(count=%u)
\n
"
,
This
,
refCount
+
1
);
if
(
refCount
)
return
refCount
;
TRACE
(
"-- destroying DragDropDataObject (%p)
\n
"
,
This
);
CFRelease
(
This
->
pasteboard
);
HeapFree
(
GetProcessHeap
(),
0
,
This
);
return
0
;
}
static
HRESULT
WINAPI
dddo_GetData
(
IDataObject
*
iface
,
FORMATETC
*
formatEtc
,
STGMEDIUM
*
medium
)
{
DragDropDataObject
*
This
=
impl_from_IDataObject
(
iface
);
HRESULT
hr
;
TRACE
(
"This %p formatEtc %s
\n
"
,
This
,
debugstr_format
(
formatEtc
->
cfFormat
));
hr
=
IDataObject_QueryGetData
(
iface
,
formatEtc
);
if
(
SUCCEEDED
(
hr
))
{
medium
->
tymed
=
TYMED_HGLOBAL
;
medium
->
u
.
hGlobal
=
macdrv_get_pasteboard_data
(
This
->
pasteboard
,
formatEtc
->
cfFormat
);
medium
->
pUnkForRelease
=
NULL
;
hr
=
medium
->
u
.
hGlobal
?
S_OK
:
E_OUTOFMEMORY
;
}
return
hr
;
}
static
HRESULT
WINAPI
dddo_GetDataHere
(
IDataObject
*
iface
,
FORMATETC
*
formatEtc
,
STGMEDIUM
*
medium
)
{
FIXME
(
"iface %p formatEtc %p medium %p; stub
\n
"
,
iface
,
formatEtc
,
medium
);
return
DATA_E_FORMATETC
;
}
static
HRESULT
WINAPI
dddo_QueryGetData
(
IDataObject
*
iface
,
FORMATETC
*
formatEtc
)
{
DragDropDataObject
*
This
=
impl_from_IDataObject
(
iface
);
HRESULT
hr
=
DV_E_FORMATETC
;
TRACE
(
"This %p formatEtc %p={.tymed=0x%x, .dwAspect=%d, .cfFormat=%s}
\n
"
,
This
,
formatEtc
,
formatEtc
->
tymed
,
formatEtc
->
dwAspect
,
debugstr_format
(
formatEtc
->
cfFormat
));
if
(
formatEtc
->
tymed
&&
!
(
formatEtc
->
tymed
&
TYMED_HGLOBAL
))
{
FIXME
(
"only HGLOBAL medium types supported right now
\n
"
);
return
DV_E_TYMED
;
}
if
(
formatEtc
->
dwAspect
!=
DVASPECT_CONTENT
)
{
FIXME
(
"only the content aspect is supported right now
\n
"
);
return
E_NOTIMPL
;
}
if
(
macdrv_pasteboard_has_format
(
This
->
pasteboard
,
formatEtc
->
cfFormat
))
hr
=
S_OK
;
TRACE
(
" -> 0x%x
\n
"
,
hr
);
return
hr
;
}
static
HRESULT
WINAPI
dddo_GetConicalFormatEtc
(
IDataObject
*
iface
,
FORMATETC
*
formatEtc
,
FORMATETC
*
formatEtcOut
)
{
DragDropDataObject
*
This
=
impl_from_IDataObject
(
iface
);
TRACE
(
"This %p formatEtc %p={.tymed=0x%x, .dwAspect=%d, .cfFormat=%s}
\n
"
,
This
,
formatEtc
,
formatEtc
->
tymed
,
formatEtc
->
dwAspect
,
debugstr_format
(
formatEtc
->
cfFormat
));
*
formatEtcOut
=
*
formatEtc
;
formatEtcOut
->
ptd
=
NULL
;
return
DATA_S_SAMEFORMATETC
;
}
static
HRESULT
WINAPI
dddo_SetData
(
IDataObject
*
iface
,
FORMATETC
*
formatEtc
,
STGMEDIUM
*
medium
,
BOOL
fRelease
)
{
DragDropDataObject
*
This
=
impl_from_IDataObject
(
iface
);
TRACE
(
"This %p formatEtc %p={.tymed=0x%x, .dwAspect=%d, .cfFormat=%s} medium %p fRelease %d
\n
"
,
This
,
formatEtc
,
formatEtc
->
tymed
,
formatEtc
->
dwAspect
,
debugstr_format
(
formatEtc
->
cfFormat
),
medium
,
fRelease
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
dddo_EnumFormatEtc
(
IDataObject
*
iface
,
DWORD
direction
,
IEnumFORMATETC
**
enumFormatEtc
)
{
DragDropDataObject
*
This
=
impl_from_IDataObject
(
iface
);
CFArrayRef
formats
;
HRESULT
hr
;
TRACE
(
"This %p direction %u enumFormatEtc %p
\n
"
,
This
,
direction
,
enumFormatEtc
);
if
(
direction
!=
DATADIR_GET
)
{
WARN
(
"only the get direction is implemented
\n
"
);
return
E_NOTIMPL
;
}
formats
=
macdrv_copy_pasteboard_formats
(
This
->
pasteboard
);
if
(
formats
)
{
INT
count
=
CFArrayGetCount
(
formats
);
FORMATETC
*
formatEtcs
=
HeapAlloc
(
GetProcessHeap
(),
0
,
count
*
sizeof
(
FORMATETC
));
if
(
formatEtcs
)
{
INT
i
;
for
(
i
=
0
;
i
<
count
;
i
++
)
{
formatEtcs
[
i
].
cfFormat
=
(
UINT
)
CFArrayGetValueAtIndex
(
formats
,
i
);
formatEtcs
[
i
].
ptd
=
NULL
;
formatEtcs
[
i
].
dwAspect
=
DVASPECT_CONTENT
;
formatEtcs
[
i
].
lindex
=
-
1
;
formatEtcs
[
i
].
tymed
=
TYMED_HGLOBAL
;
}
hr
=
SHCreateStdEnumFmtEtc
(
count
,
formatEtcs
,
enumFormatEtc
);
HeapFree
(
GetProcessHeap
(),
0
,
formatEtcs
);
}
else
hr
=
E_OUTOFMEMORY
;
CFRelease
(
formats
);
}
else
hr
=
SHCreateStdEnumFmtEtc
(
0
,
NULL
,
enumFormatEtc
);
TRACE
(
" -> 0x%x
\n
"
,
hr
);
return
hr
;
}
static
HRESULT
WINAPI
dddo_DAdvise
(
IDataObject
*
iface
,
FORMATETC
*
formatEtc
,
DWORD
advf
,
IAdviseSink
*
pAdvSink
,
DWORD
*
pdwConnection
)
{
FIXME
(
"(%p, %p, %u, %p, %p): stub
\n
"
,
iface
,
formatEtc
,
advf
,
pAdvSink
,
pdwConnection
);
return
OLE_E_ADVISENOTSUPPORTED
;
}
static
HRESULT
WINAPI
dddo_DUnadvise
(
IDataObject
*
iface
,
DWORD
dwConnection
)
{
FIXME
(
"(%p, %u): stub
\n
"
,
iface
,
dwConnection
);
return
OLE_E_ADVISENOTSUPPORTED
;
}
static
HRESULT
WINAPI
dddo_EnumDAdvise
(
IDataObject
*
iface
,
IEnumSTATDATA
**
pEnumAdvise
)
{
FIXME
(
"(%p, %p): stub
\n
"
,
iface
,
pEnumAdvise
);
return
OLE_E_ADVISENOTSUPPORTED
;
}
static
const
IDataObjectVtbl
dovt
=
{
dddo_QueryInterface
,
dddo_AddRef
,
dddo_Release
,
dddo_GetData
,
dddo_GetDataHere
,
dddo_QueryGetData
,
dddo_GetConicalFormatEtc
,
dddo_SetData
,
dddo_EnumFormatEtc
,
dddo_DAdvise
,
dddo_DUnadvise
,
dddo_EnumDAdvise
};
static
IDataObject
*
create_data_object_for_pasteboard
(
CFTypeRef
pasteboard
)
{
DragDropDataObject
*
dddo
;
dddo
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
*
dddo
));
if
(
!
dddo
)
return
NULL
;
dddo
->
ref
=
1
;
dddo
->
IDataObject_iface
.
lpVtbl
=
&
dovt
;
dddo
->
pasteboard
=
CFRetain
(
pasteboard
);
return
&
dddo
->
IDataObject_iface
;
}
/**************************************************************************
* drag_operations_to_dropeffects
*/
static
DWORD
drag_operations_to_dropeffects
(
uint32_t
ops
)
{
DWORD
effects
=
DROPEFFECT_NONE
;
if
(
ops
&
(
DRAG_OP_COPY
|
DRAG_OP_GENERIC
))
effects
|=
DROPEFFECT_COPY
;
if
(
ops
&
DRAG_OP_MOVE
)
effects
|=
DROPEFFECT_MOVE
;
if
(
ops
&
(
DRAG_OP_LINK
|
DRAG_OP_GENERIC
))
effects
|=
DROPEFFECT_LINK
;
return
effects
;
}
/**************************************************************************
* dropeffect_to_drag_operation
*/
static
uint32_t
dropeffect_to_drag_operation
(
DWORD
effect
,
uint32_t
ops
)
{
switch
(
effect
)
{
case
DROPEFFECT_COPY
:
return
(
ops
&
DRAG_OP_COPY
)
?
DRAG_OP_COPY
:
DRAG_OP_GENERIC
;
case
DROPEFFECT_MOVE
:
return
DRAG_OP_MOVE
;
case
DROPEFFECT_LINK
:
return
(
ops
&
DRAG_OP_LINK
)
?
DRAG_OP_LINK
:
DRAG_OP_GENERIC
;
}
return
DRAG_OP_NONE
;
}
/* Based on functions in dlls/ole32/ole2.c */
static
HANDLE
get_droptarget_local_handle
(
HWND
hwnd
)
{
static
const
WCHAR
prop_marshalleddroptarget
[]
=
{
'W'
,
'i'
,
'n'
,
'e'
,
'M'
,
'a'
,
'r'
,
's'
,
'h'
,
'a'
,
'l'
,
'l'
,
'e'
,
'd'
,
'D'
,
'r'
,
'o'
,
'p'
,
'T'
,
'a'
,
'r'
,
'g'
,
'e'
,
't'
,
0
};
HANDLE
handle
;
HANDLE
local_handle
=
0
;
handle
=
GetPropW
(
hwnd
,
prop_marshalleddroptarget
);
if
(
handle
)
{
DWORD
pid
;
HANDLE
process
;
GetWindowThreadProcessId
(
hwnd
,
&
pid
);
process
=
OpenProcess
(
PROCESS_DUP_HANDLE
,
FALSE
,
pid
);
if
(
process
)
{
DuplicateHandle
(
process
,
handle
,
GetCurrentProcess
(),
&
local_handle
,
0
,
FALSE
,
DUPLICATE_SAME_ACCESS
);
CloseHandle
(
process
);
}
}
return
local_handle
;
}
static
HRESULT
create_stream_from_map
(
HANDLE
map
,
IStream
**
stream
)
{
HRESULT
hr
=
E_OUTOFMEMORY
;
HGLOBAL
hmem
;
void
*
data
;
MEMORY_BASIC_INFORMATION
info
;
data
=
MapViewOfFile
(
map
,
FILE_MAP_READ
,
0
,
0
,
0
);
if
(
!
data
)
return
hr
;
VirtualQuery
(
data
,
&
info
,
sizeof
(
info
));
TRACE
(
"size %d
\n
"
,
(
int
)
info
.
RegionSize
);
hmem
=
GlobalAlloc
(
GMEM_MOVEABLE
,
info
.
RegionSize
);
if
(
hmem
)
{
memcpy
(
GlobalLock
(
hmem
),
data
,
info
.
RegionSize
);
GlobalUnlock
(
hmem
);
hr
=
CreateStreamOnHGlobal
(
hmem
,
TRUE
,
stream
);
}
UnmapViewOfFile
(
data
);
return
hr
;
}
static
IDropTarget
*
get_droptarget_pointer
(
HWND
hwnd
)
{
IDropTarget
*
droptarget
=
NULL
;
HANDLE
map
;
IStream
*
stream
;
map
=
get_droptarget_local_handle
(
hwnd
);
if
(
!
map
)
return
NULL
;
if
(
SUCCEEDED
(
create_stream_from_map
(
map
,
&
stream
)))
{
CoUnmarshalInterface
(
stream
,
&
IID_IDropTarget
,
(
void
**
)
&
droptarget
);
IStream_Release
(
stream
);
}
CloseHandle
(
map
);
return
droptarget
;
}
/**************************************************************************
* query_drag_drop
*/
BOOL
query_drag_drop
(
macdrv_query
*
query
)
{
BOOL
ret
=
FALSE
;
HWND
hwnd
=
macdrv_get_window_hwnd
(
query
->
window
);
struct
macdrv_win_data
*
data
=
get_win_data
(
hwnd
);
POINT
pt
;
IDropTarget
*
droptarget
;
TRACE
(
"win %p/%p x,y %d,%d op 0x%08x pasteboard %p
\n
"
,
hwnd
,
query
->
window
,
query
->
drag_drop
.
x
,
query
->
drag_drop
.
y
,
query
->
drag_drop
.
op
,
query
->
drag_drop
.
pasteboard
);
if
(
!
data
)
{
WARN
(
"no win_data for win %p/%p
\n
"
,
hwnd
,
query
->
window
);
return
FALSE
;
}
pt
.
x
=
query
->
drag_drop
.
x
+
data
->
whole_rect
.
left
;
pt
.
y
=
query
->
drag_drop
.
y
+
data
->
whole_rect
.
top
;
release_win_data
(
data
);
droptarget
=
get_droptarget_pointer
(
last_droptarget_hwnd
);
if
(
droptarget
)
{
HRESULT
hr
;
POINTL
pointl
;
DWORD
effect
=
drag_operations_to_dropeffects
(
query
->
drag_drop
.
op
);
if
(
!
active_data_object
)
{
WARN
(
"shouldn't happen: no active IDataObject
\n
"
);
active_data_object
=
create_data_object_for_pasteboard
(
query
->
drag_drop
.
pasteboard
);
}
pointl
.
x
=
pt
.
x
;
pointl
.
y
=
pt
.
y
;
TRACE
(
"Drop hwnd %p droptarget %p pointl (%d,%d) effect 0x%08x
\n
"
,
last_droptarget_hwnd
,
droptarget
,
pointl
.
x
,
pointl
.
y
,
effect
);
hr
=
IDropTarget_Drop
(
droptarget
,
active_data_object
,
MK_LBUTTON
,
pointl
,
&
effect
);
if
(
SUCCEEDED
(
hr
))
{
if
(
effect
!=
DROPEFFECT_NONE
)
{
TRACE
(
"drop succeeded
\n
"
);
ret
=
TRUE
;
}
else
TRACE
(
"the application refused the drop
\n
"
);
}
else
WARN
(
"drop failed, error 0x%08X
\n
"
,
hr
);
IDropTarget_Release
(
droptarget
);
}
else
{
hwnd
=
WindowFromPoint
(
pt
);
while
(
hwnd
&&
!
(
GetWindowLongW
(
hwnd
,
GWL_EXSTYLE
)
&
WS_EX_ACCEPTFILES
))
hwnd
=
GetParent
(
hwnd
);
if
(
hwnd
)
{
HDROP
hdrop
=
macdrv_get_pasteboard_data
(
query
->
drag_drop
.
pasteboard
,
CF_HDROP
);
DROPFILES
*
dropfiles
=
GlobalLock
(
hdrop
);
if
(
dropfiles
)
{
dropfiles
->
pt
.
x
=
pt
.
x
;
dropfiles
->
pt
.
y
=
pt
.
y
;
dropfiles
->
fNC
=
TRUE
;
TRACE
(
"sending WM_DROPFILES: hwnd %p pt %s %s
\n
"
,
hwnd
,
wine_dbgstr_point
(
&
pt
),
debugstr_w
((
WCHAR
*
)((
char
*
)
dropfiles
+
dropfiles
->
pFiles
)));
GlobalUnlock
(
hdrop
);
ret
=
PostMessageW
(
hwnd
,
WM_DROPFILES
,
(
WPARAM
)
hdrop
,
0L
);
/* hdrop is owned by the message and freed when the recipient calls DragFinish(). */
}
else
GlobalFree
(
hdrop
);
}
}
if
(
active_data_object
)
IDataObject_Release
(
active_data_object
);
active_data_object
=
NULL
;
last_droptarget_hwnd
=
NULL
;
return
ret
;
}
/**************************************************************************
* query_drag_exited
*/
BOOL
query_drag_exited
(
macdrv_query
*
query
)
{
HWND
hwnd
=
macdrv_get_window_hwnd
(
query
->
window
);
IDropTarget
*
droptarget
;
TRACE
(
"win %p/%p
\n
"
,
hwnd
,
query
->
window
);
droptarget
=
get_droptarget_pointer
(
last_droptarget_hwnd
);
if
(
droptarget
)
{
HRESULT
hr
;
TRACE
(
"DragLeave hwnd %p droptarget %p
\n
"
,
last_droptarget_hwnd
,
droptarget
);
hr
=
IDropTarget_DragLeave
(
droptarget
);
if
(
FAILED
(
hr
))
WARN
(
"IDropTarget_DragLeave failed, error 0x%08X
\n
"
,
hr
);
IDropTarget_Release
(
droptarget
);
}
if
(
active_data_object
)
IDataObject_Release
(
active_data_object
);
active_data_object
=
NULL
;
last_droptarget_hwnd
=
NULL
;
return
TRUE
;
}
/**************************************************************************
* query_drag_operation
*/
BOOL
query_drag_operation
(
macdrv_query
*
query
)
{
BOOL
ret
=
FALSE
;
HWND
hwnd
=
macdrv_get_window_hwnd
(
query
->
window
);
struct
macdrv_win_data
*
data
=
get_win_data
(
hwnd
);
POINT
pt
;
DWORD
effect
;
IDropTarget
*
droptarget
;
HRESULT
hr
;
TRACE
(
"win %p/%p x,y %d,%d offered_ops 0x%x pasteboard %p
\n
"
,
hwnd
,
query
->
window
,
query
->
drag_operation
.
x
,
query
->
drag_operation
.
y
,
query
->
drag_operation
.
offered_ops
,
query
->
drag_operation
.
pasteboard
);
if
(
!
data
)
{
WARN
(
"no win_data for win %p/%p
\n
"
,
hwnd
,
query
->
window
);
return
FALSE
;
}
pt
.
x
=
query
->
drag_operation
.
x
+
data
->
whole_rect
.
left
;
pt
.
y
=
query
->
drag_operation
.
y
+
data
->
whole_rect
.
top
;
release_win_data
(
data
);
effect
=
drag_operations_to_dropeffects
(
query
->
drag_operation
.
offered_ops
);
/* Instead of the top-level window we got in the query, start with the deepest
child under the cursor. Travel up the hierarchy looking for a window that
has an associated IDropTarget. */
hwnd
=
WindowFromPoint
(
pt
);
do
{
droptarget
=
get_droptarget_pointer
(
hwnd
);
}
while
(
!
droptarget
&&
(
hwnd
=
GetParent
(
hwnd
)));
if
(
last_droptarget_hwnd
!=
hwnd
)
{
if
(
last_droptarget_hwnd
)
{
IDropTarget
*
old_droptarget
=
get_droptarget_pointer
(
last_droptarget_hwnd
);
if
(
old_droptarget
)
{
TRACE
(
"DragLeave hwnd %p droptarget %p
\n
"
,
last_droptarget_hwnd
,
old_droptarget
);
hr
=
IDropTarget_DragLeave
(
old_droptarget
);
if
(
FAILED
(
hr
))
WARN
(
"IDropTarget_DragLeave failed, error 0x%08X
\n
"
,
hr
);
IDropTarget_Release
(
old_droptarget
);
}
}
last_droptarget_hwnd
=
hwnd
;
if
(
droptarget
)
{
POINTL
pointl
=
{
pt
.
x
,
pt
.
y
};
if
(
!
active_data_object
)
active_data_object
=
create_data_object_for_pasteboard
(
query
->
drag_operation
.
pasteboard
);
TRACE
(
"DragEnter hwnd %p droptarget %p
\n
"
,
hwnd
,
droptarget
);
hr
=
IDropTarget_DragEnter
(
droptarget
,
active_data_object
,
MK_LBUTTON
,
pointl
,
&
effect
);
if
(
SUCCEEDED
(
hr
))
{
query
->
drag_operation
.
accepted_op
=
dropeffect_to_drag_operation
(
effect
,
query
->
drag_operation
.
offered_ops
);
TRACE
(
" effect %d accepted op %d
\n
"
,
effect
,
query
->
drag_operation
.
accepted_op
);
ret
=
TRUE
;
}
else
WARN
(
"IDropTarget_DragEnter failed, error 0x%08X
\n
"
,
hr
);
IDropTarget_Release
(
droptarget
);
}
}
else
if
(
droptarget
)
{
POINTL
pointl
=
{
pt
.
x
,
pt
.
y
};
TRACE
(
"DragOver hwnd %p droptarget %p
\n
"
,
hwnd
,
droptarget
);
hr
=
IDropTarget_DragOver
(
droptarget
,
MK_LBUTTON
,
pointl
,
&
effect
);
if
(
SUCCEEDED
(
hr
))
{
query
->
drag_operation
.
accepted_op
=
dropeffect_to_drag_operation
(
effect
,
query
->
drag_operation
.
offered_ops
);
TRACE
(
" effect %d accepted op %d
\n
"
,
effect
,
query
->
drag_operation
.
accepted_op
);
ret
=
TRUE
;
}
else
WARN
(
"IDropTarget_DragOver failed, error 0x%08X
\n
"
,
hr
);
IDropTarget_Release
(
droptarget
);
}
if
(
!
ret
)
{
hwnd
=
WindowFromPoint
(
pt
);
while
(
hwnd
&&
!
(
GetWindowLongW
(
hwnd
,
GWL_EXSTYLE
)
&
WS_EX_ACCEPTFILES
))
hwnd
=
GetParent
(
hwnd
);
if
(
hwnd
)
{
FORMATETC
formatEtc
;
if
(
!
active_data_object
)
active_data_object
=
create_data_object_for_pasteboard
(
query
->
drag_operation
.
pasteboard
);
formatEtc
.
cfFormat
=
CF_HDROP
;
formatEtc
.
ptd
=
NULL
;
formatEtc
.
dwAspect
=
DVASPECT_CONTENT
;
formatEtc
.
lindex
=
-
1
;
formatEtc
.
tymed
=
TYMED_HGLOBAL
;
if
(
SUCCEEDED
(
IDataObject_QueryGetData
(
active_data_object
,
&
formatEtc
)))
{
TRACE
(
"WS_EX_ACCEPTFILES hwnd %p
\n
"
,
hwnd
);
query
->
drag_operation
.
accepted_op
=
DRAG_OP_GENERIC
;
ret
=
TRUE
;
}
}
}
TRACE
(
" -> %s
\n
"
,
ret
?
"TRUE"
:
"FALSE"
);
return
ret
;
}
dlls/winemac.drv/event.c
View file @
7993bd3d
...
...
@@ -116,6 +116,18 @@ static void macdrv_query_event(HWND hwnd, macdrv_event *event)
switch
(
query
->
type
)
{
case
QUERY_DRAG_DROP
:
TRACE
(
"QUERY_DRAG_DROP
\n
"
);
success
=
query_drag_drop
(
query
);
break
;
case
QUERY_DRAG_EXITED
:
TRACE
(
"QUERY_DRAG_EXITED
\n
"
);
success
=
query_drag_exited
(
query
);
break
;
case
QUERY_DRAG_OPERATION
:
TRACE
(
"QUERY_DRAG_OPERATION
\n
"
);
success
=
query_drag_operation
(
query
);
break
;
case
QUERY_PASTEBOARD_DATA
:
TRACE
(
"QUERY_PASTEBOARD_DATA
\n
"
);
success
=
query_pasteboard_data
(
hwnd
,
query
->
pasteboard_data
.
type
);
...
...
dlls/winemac.drv/macdrv.h
View file @
7993bd3d
...
...
@@ -160,6 +160,14 @@ extern void macdrv_displays_changed(const macdrv_event *event) DECLSPEC_HIDDEN;
extern
void
macdrv_clipboard_process_attach
(
void
)
DECLSPEC_HIDDEN
;
extern
BOOL
query_pasteboard_data
(
HWND
hwnd
,
CFStringRef
type
)
DECLSPEC_HIDDEN
;
extern
const
char
*
debugstr_format
(
UINT
id
)
DECLSPEC_HIDDEN
;
extern
HANDLE
macdrv_get_pasteboard_data
(
CFTypeRef
pasteboard
,
UINT
desired_format
)
DECLSPEC_HIDDEN
;
extern
BOOL
CDECL
macdrv_pasteboard_has_format
(
CFTypeRef
pasteboard
,
UINT
desired_format
)
DECLSPEC_HIDDEN
;
extern
CFArrayRef
macdrv_copy_pasteboard_formats
(
CFTypeRef
pasteboard
)
DECLSPEC_HIDDEN
;
extern
BOOL
query_drag_operation
(
macdrv_query
*
query
)
DECLSPEC_HIDDEN
;
extern
BOOL
query_drag_exited
(
macdrv_query
*
query
)
DECLSPEC_HIDDEN
;
extern
BOOL
query_drag_drop
(
macdrv_query
*
query
)
DECLSPEC_HIDDEN
;
extern
struct
opengl_funcs
*
macdrv_wine_get_wgl_driver
(
PHYSDEV
dev
,
UINT
version
)
DECLSPEC_HIDDEN
;
extern
void
sync_gl_view
(
struct
macdrv_win_data
*
data
)
DECLSPEC_HIDDEN
;
...
...
dlls/winemac.drv/macdrv_cocoa.h
View file @
7993bd3d
...
...
@@ -99,6 +99,19 @@
#endif
/* Must match the values of Cocoa's NSDragOperation enum. */
enum
{
DRAG_OP_NONE
=
0
,
DRAG_OP_COPY
=
1
,
DRAG_OP_LINK
=
2
,
DRAG_OP_GENERIC
=
4
,
DRAG_OP_PRIVATE
=
8
,
DRAG_OP_MOVE
=
16
,
DRAG_OP_DELETE
=
32
,
DRAG_OP_EVERY
=
UINT32_MAX
};
typedef
struct
macdrv_opaque_window
*
macdrv_window
;
typedef
struct
macdrv_opaque_event_queue
*
macdrv_event_queue
;
typedef
struct
macdrv_opaque_view
*
macdrv_view
;
...
...
@@ -208,6 +221,9 @@ typedef struct macdrv_event {
}
macdrv_event
;
enum
{
QUERY_DRAG_DROP
,
QUERY_DRAG_EXITED
,
QUERY_DRAG_OPERATION
,
QUERY_PASTEBOARD_DATA
,
NUM_QUERY_TYPES
};
...
...
@@ -220,6 +236,19 @@ typedef struct macdrv_query {
int
done
;
union
{
struct
{
int
x
;
int
y
;
uint32_t
op
;
CFTypeRef
pasteboard
;
}
drag_drop
;
struct
{
int
x
;
int
y
;
uint32_t
offered_ops
;
uint32_t
accepted_op
;
CFTypeRef
pasteboard
;
}
drag_operation
;
struct
{
CFStringRef
type
;
}
pasteboard_data
;
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment