Commit 7993bd3d authored by Ken Thomases's avatar Ken Thomases Committed by Alexandre Julliard

winemac: Implement support for drag-and-drop.

parent fb5794a7
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 \
......
......@@ -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;
......
......@@ -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);
}
......
......@@ -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
......
......@@ -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);
......
......@@ -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;
......
......@@ -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;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment