Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
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-winehq
Commits
449e2655
Commit
449e2655
authored
Mar 10, 2013
by
Ken Thomases
Committed by
Alexandre Julliard
Mar 11, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winemac: Add support for delay-rendered (a.k.a. promised) clipboard data.
parent
69e631e0
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
149 additions
and
43 deletions
+149
-43
clipboard.c
dlls/winemac.drv/clipboard.c
+115
-39
cocoa_clipboard.m
dlls/winemac.drv/cocoa_clipboard.m
+5
-3
cocoa_event.m
dlls/winemac.drv/cocoa_event.m
+2
-0
cocoa_window.m
dlls/winemac.drv/cocoa_window.m
+15
-0
event.c
dlls/winemac.drv/event.c
+4
-0
macdrv.h
dlls/winemac.drv/macdrv.h
+1
-0
macdrv_cocoa.h
dlls/winemac.drv/macdrv_cocoa.h
+7
-1
No files found.
dlls/winemac.drv/clipboard.c
View file @
449e2655
...
...
@@ -1102,18 +1102,12 @@ BOOL CDECL macdrv_SetClipboardData(UINT format_id, HANDLE data, BOOL owner)
HWND
hwnd_owner
;
macdrv_window
window
;
WINE_CLIPFORMAT
*
format
;
CFDataRef
cfdata
;
CFDataRef
cfdata
=
NULL
;
check_clipboard_ownership
(
&
hwnd_owner
);
window
=
macdrv_get_cocoa_window
(
GetAncestor
(
hwnd_owner
,
GA_ROOT
),
FALSE
);
TRACE
(
"format_id %s data %p owner %d hwnd_owner %p window %p)
\n
"
,
debugstr_format
(
format_id
),
data
,
owner
,
hwnd_owner
,
window
);
if
(
!
data
)
{
FIXME
(
"delayed rendering (promising) is not implemented yet
\n
"
);
return
FALSE
;
}
/* Find the "natural" format for this format_id (the one which isn't
synthesized from another type). */
LIST_FOR_EACH_ENTRY
(
format
,
&
format_list
,
WINE_CLIPFORMAT
,
entry
)
...
...
@@ -1126,22 +1120,25 @@ BOOL CDECL macdrv_SetClipboardData(UINT format_id, HANDLE data, BOOL owner)
}
/* Export the data to the Mac pasteboard. */
if
(
!
format
->
export_func
||
!
(
cfdata
=
format
->
export_func
(
data
))
)
if
(
data
)
{
WARN
(
"Failed to export %s data to type %s
\n
"
,
debugstr_format
(
format_id
),
debugstr_cf
(
format
->
type
));
return
FALSE
;
if
(
!
format
->
export_func
||
!
(
cfdata
=
format
->
export_func
(
data
)))
{
WARN
(
"Failed to export %s data to type %s
\n
"
,
debugstr_format
(
format_id
),
debugstr_cf
(
format
->
type
));
return
FALSE
;
}
}
if
(
macdrv_set_pasteboard_data
(
format
->
type
,
cfdata
))
if
(
macdrv_set_pasteboard_data
(
format
->
type
,
cfdata
,
window
))
TRACE
(
"Set pasteboard data for type %s: %s
\n
"
,
debugstr_cf
(
format
->
type
),
debugstr_cf
(
cfdata
));
else
{
WARN
(
"Failed to set pasteboard data for type %s: %s
\n
"
,
debugstr_cf
(
format
->
type
),
debugstr_cf
(
cfdata
));
CFRelease
(
cfdata
);
if
(
cfdata
)
CFRelease
(
cfdata
);
return
FALSE
;
}
CFRelease
(
cfdata
);
if
(
cfdata
)
CFRelease
(
cfdata
);
/* Find any other formats for this format_id (the exportable synthesized ones). */
LIST_FOR_EACH_ENTRY
(
format
,
&
format_list
,
WINE_CLIPFORMAT
,
entry
)
...
...
@@ -1151,43 +1148,51 @@ BOOL CDECL macdrv_SetClipboardData(UINT format_id, HANDLE data, BOOL owner)
/* We have a synthesized format for this format ID. Add its type to the pasteboard. */
TRACE
(
"Synthesized from format %s: type %s
\n
"
,
debugstr_format
(
format_id
),
debugstr_cf
(
format
->
type
));
cfdata
=
format
->
export_func
(
data
);
if
(
!
cfdata
)
if
(
data
)
{
WARN
(
"Failed to export %s data to type %s
\n
"
,
debugstr_format
(
format
->
format_id
),
debugstr_cf
(
format
->
type
));
continue
;
cfdata
=
format
->
export_func
(
data
);
if
(
!
cfdata
)
{
WARN
(
"Failed to export %s data to type %s
\n
"
,
debugstr_format
(
format
->
format_id
),
debugstr_cf
(
format
->
type
));
continue
;
}
}
else
cfdata
=
NULL
;
if
(
macdrv_set_pasteboard_data
(
format
->
type
,
cfdata
))
if
(
macdrv_set_pasteboard_data
(
format
->
type
,
cfdata
,
window
))
TRACE
(
" ... set pasteboard data: %s
\n
"
,
debugstr_cf
(
cfdata
));
else
WARN
(
" ... failed to set pasteboard data: %s
\n
"
,
debugstr_cf
(
cfdata
));
CFRelease
(
cfdata
);
if
(
cfdata
)
CFRelease
(
cfdata
);
}
}
/* FIXME: According to MSDN, the caller is entitled to lock and read from
data until CloseClipboard is called. So, we should defer this cleanup. */
if
((
format_id
>=
CF_GDIOBJFIRST
&&
format_id
<=
CF_GDIOBJLAST
)
||
format_id
==
CF_BITMAP
||
format_id
==
CF_DIB
||
format_id
==
CF_PALETTE
)
{
DeleteObject
(
data
);
}
else
if
(
format_id
==
CF_METAFILEPICT
)
{
DeleteMetaFile
(((
METAFILEPICT
*
)
GlobalLock
(
data
))
->
hMF
);
GlobalFree
(
data
);
}
else
if
(
format_id
==
CF_ENHMETAFILE
)
if
(
data
)
{
DeleteEnhMetaFile
(
data
);
}
else
if
(
format_id
<
CF_PRIVATEFIRST
||
CF_PRIVATELAST
<
format_id
)
{
GlobalFree
(
data
);
/* FIXME: According to MSDN, the caller is entitled to lock and read from
data until CloseClipboard is called. So, we should defer this cleanup. */
if
((
format_id
>=
CF_GDIOBJFIRST
&&
format_id
<=
CF_GDIOBJLAST
)
||
format_id
==
CF_BITMAP
||
format_id
==
CF_DIB
||
format_id
==
CF_PALETTE
)
{
DeleteObject
(
data
);
}
else
if
(
format_id
==
CF_METAFILEPICT
)
{
DeleteMetaFile
(((
METAFILEPICT
*
)
GlobalLock
(
data
))
->
hMF
);
GlobalFree
(
data
);
}
else
if
(
format_id
==
CF_ENHMETAFILE
)
{
DeleteEnhMetaFile
(
data
);
}
else
if
(
format_id
<
CF_PRIVATEFIRST
||
CF_PRIVATELAST
<
format_id
)
{
GlobalFree
(
data
);
}
}
return
TRUE
;
...
...
@@ -1220,3 +1225,74 @@ void macdrv_clipboard_process_attach(void)
list_add_tail
(
&
format_list
,
&
format
->
entry
);
}
}
/**************************************************************************
* query_pasteboard_data
*/
BOOL
query_pasteboard_data
(
HWND
hwnd
,
CFStringRef
type
)
{
BOOL
ret
=
FALSE
;
CLIPBOARDINFO
cbinfo
;
WINE_CLIPFORMAT
*
format
;
CFArrayRef
types
=
NULL
;
CFRange
range
;
TRACE
(
"hwnd %p type %s
\n
"
,
hwnd
,
debugstr_cf
(
type
));
if
(
get_clipboard_info
(
&
cbinfo
))
hwnd
=
cbinfo
.
hwnd_owner
;
format
=
NULL
;
while
((
format
=
format_for_type
(
format
,
type
)))
{
WINE_CLIPFORMAT
*
base_format
;
TRACE
(
"for type %s got format %p/%s
\n
"
,
debugstr_cf
(
type
),
format
,
debugstr_format
(
format
->
format_id
));
if
(
!
format
->
synthesized
)
{
TRACE
(
"Sending WM_RENDERFORMAT message for format %s to hwnd %p
\n
"
,
debugstr_format
(
format
->
format_id
),
hwnd
);
SendMessageW
(
hwnd
,
WM_RENDERFORMAT
,
format
->
format_id
,
0
);
ret
=
TRUE
;
goto
done
;
}
if
(
!
types
)
{
types
=
macdrv_copy_pasteboard_types
();
if
(
!
types
)
{
WARN
(
"Failed to copy pasteboard types
\n
"
);
break
;
}
range
=
CFRangeMake
(
0
,
CFArrayGetCount
(
types
));
}
/* The type maps to a synthesized format. Now look up what type that format maps to natively
(not synthesized). For example, if type is "public.utf8-plain-text", then this format may
have an ID of CF_TEXT. From CF_TEXT, we want to find "org.winehq.builtin.text" to see if
that type is present in the pasteboard. If it is, then the app must have promised it and
we can ask it to render it. (If it had put it on the clipboard immediately, then the
pasteboard would also have data for "public.utf8-plain-text" and we wouldn't be here.) If
"org.winehq.builtin.text" is not on the pasteboard, then one of the other text formats is
presumably responsible for the promise that we're trying to satisfy, so we keep looking. */
LIST_FOR_EACH_ENTRY
(
base_format
,
&
format_list
,
WINE_CLIPFORMAT
,
entry
)
{
if
(
base_format
->
format_id
==
format
->
format_id
&&
!
base_format
->
synthesized
&&
CFArrayContainsValue
(
types
,
range
,
base_format
->
type
))
{
TRACE
(
"Sending WM_RENDERFORMAT message for format %s to hwnd %p
\n
"
,
debugstr_format
(
base_format
->
format_id
),
hwnd
);
SendMessageW
(
hwnd
,
WM_RENDERFORMAT
,
base_format
->
format_id
,
0
);
ret
=
TRUE
;
goto
done
;
}
}
}
done:
if
(
types
)
CFRelease
(
types
);
return
ret
;
}
dlls/winemac.drv/cocoa_clipboard.m
View file @
449e2655
...
...
@@ -125,20 +125,22 @@ void macdrv_clear_pasteboard(void)
* macdrv_set_pasteboard_data
*
* Sets the pasteboard data for a specified type. Replaces any data of
* that type already on the pasteboard.
* that type already on the pasteboard. If data is NULL, promises the
* type.
*
* Returns 0 on error, non-zero on success.
*/
int
macdrv_set_pasteboard_data
(
CFStringRef
type
,
CFDataRef
data
)
int
macdrv_set_pasteboard_data
(
CFStringRef
type
,
CFDataRef
data
,
macdrv_window
w
)
{
__block
int
ret
=
0
;
WineWindow
*
window
=
(
WineWindow
*
)
w
;
OnMainThread
(
^
{
@try
{
NSPasteboard
*
pb
=
[
NSPasteboard
generalPasteboard
];
NSInteger
change_count
=
[
pb
addTypes
:[
NSArray
arrayWithObject
:(
NSString
*
)
type
]
owner
:
nil
];
owner
:
window
];
if
(
change_count
)
{
owned_change_count
=
change_count
;
...
...
dlls/winemac.drv/cocoa_event.m
View file @
449e2655
...
...
@@ -455,6 +455,8 @@ 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
);
[(
WineWindow
*
)
query
->
window
release
];
free
(
query
);
}
...
...
dlls/winemac.drv/cocoa_window.m
View file @
449e2655
...
...
@@ -1174,6 +1174,21 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
ignore_windowMiniaturize
=
FALSE
;
}
/*
* ---------- NSPasteboardOwner methods ----------
*/
-
(
void
)
pasteboard
:
(
NSPasteboard
*
)
sender
provideDataForType
:
(
NSString
*
)
type
{
macdrv_query
*
query
=
macdrv_create_query
();
query
->
type
=
QUERY_PASTEBOARD_DATA
;
query
->
window
=
(
macdrv_window
)[
self
retain
];
query
->
pasteboard_data
.
type
=
(
CFStringRef
)[
type
copy
];
[
self
.
queue
query
:
query
timeout
:
3
];
macdrv_release_query
(
query
);
}
@end
...
...
dlls/winemac.drv/event.c
View file @
449e2655
...
...
@@ -116,6 +116,10 @@ static void macdrv_query_event(HWND hwnd, macdrv_event *event)
switch
(
query
->
type
)
{
case
QUERY_PASTEBOARD_DATA
:
TRACE
(
"QUERY_PASTEBOARD_DATA
\n
"
);
success
=
query_pasteboard_data
(
hwnd
,
query
->
pasteboard_data
.
type
);
break
;
default:
FIXME
(
"unrecognized query type %d
\n
"
,
query
->
type
);
break
;
...
...
dlls/winemac.drv/macdrv.h
View file @
449e2655
...
...
@@ -159,6 +159,7 @@ extern void macdrv_key_event(HWND hwnd, const macdrv_event *event) DECLSPEC_HIDD
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
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 @
449e2655
...
...
@@ -208,6 +208,7 @@ typedef struct macdrv_event {
}
macdrv_event
;
enum
{
QUERY_PASTEBOARD_DATA
,
NUM_QUERY_TYPES
};
...
...
@@ -217,6 +218,11 @@ typedef struct macdrv_query {
macdrv_window
window
;
int
status
;
int
done
;
union
{
struct
{
CFStringRef
type
;
}
pasteboard_data
;
};
}
macdrv_query
;
static
inline
macdrv_event_mask
event_mask_for_type
(
int
type
)
...
...
@@ -302,7 +308,7 @@ extern CFArrayRef macdrv_copy_pasteboard_types(void) DECLSPEC_HIDDEN;
extern
CFDataRef
macdrv_copy_pasteboard_data
(
CFStringRef
type
)
DECLSPEC_HIDDEN
;
extern
int
macdrv_is_pasteboard_owner
(
void
)
DECLSPEC_HIDDEN
;
extern
void
macdrv_clear_pasteboard
(
void
)
DECLSPEC_HIDDEN
;
extern
int
macdrv_set_pasteboard_data
(
CFStringRef
type
,
CFDataRef
data
)
DECLSPEC_HIDDEN
;
extern
int
macdrv_set_pasteboard_data
(
CFStringRef
type
,
CFDataRef
data
,
macdrv_window
w
)
DECLSPEC_HIDDEN
;
/* opengl */
...
...
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