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
c6f12bd9
Commit
c6f12bd9
authored
Aug 30, 2016
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server: Notify all listeners when the contents of the clipboard have changed.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
7594afeb
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
245 additions
and
39 deletions
+245
-39
clipboard.c
dlls/user32/clipboard.c
+1
-1
clipboard.c
dlls/user32/tests/clipboard.c
+184
-23
clipboard.c
server/clipboard.c
+31
-15
queue.c
server/queue.c
+27
-0
user.h
server/user.h
+2
-0
No files found.
dlls/user32/clipboard.c
View file @
c6f12bd9
...
...
@@ -185,8 +185,8 @@ BOOL WINAPI CloseClipboard(void)
{
if
(
owner
)
USER_Driver
->
pEndClipboardUpdate
();
bCBHasChanged
=
FALSE
;
if
(
viewer
)
SendNotifyMessageW
(
viewer
,
WM_DRAWCLIPBOARD
,
(
WPARAM
)
GetClipboardOwner
(),
0
);
}
if
(
viewer
)
SendNotifyMessageW
(
viewer
,
WM_DRAWCLIPBOARD
,
(
WPARAM
)
GetClipboardOwner
(),
0
);
return
TRUE
;
}
...
...
dlls/user32/tests/clipboard.c
View file @
c6f12bd9
...
...
@@ -513,33 +513,45 @@ static void test_synthesized(void)
static
CRITICAL_SECTION
clipboard_cs
;
static
HWND
next_wnd
;
static
UINT
wm_drawclipboard
;
static
UINT
wm_clipboardupdate
;
static
UINT
wm_destroyclipboard
;
static
UINT
nb_formats
;
static
BOOL
cross_thread
;
static
LRESULT
CALLBACK
clipboard_wnd_proc
(
HWND
hwnd
,
UINT
msg
,
WPARAM
wp
,
LPARAM
lp
)
{
static
UINT
wm_drawclipboard
;
static
UINT
wm_clipboardupdate
;
static
UINT
wm_destroyclipboard
;
static
UINT
nb_formats
;
LRESULT
ret
;
DWORD
msg_flags
=
InSendMessageEx
(
NULL
);
switch
(
msg
)
{
case
WM_DRAWCLIPBOARD
:
ok
(
msg_flags
==
(
cross_thread
?
ISMEX_NOTIFY
:
ISMEX_NOSEND
),
"WM_DRAWCLIPBOARD wrong flags %x
\n
"
,
msg_flags
);
EnterCriticalSection
(
&
clipboard_cs
);
wm_drawclipboard
++
;
LeaveCriticalSection
(
&
clipboard_cs
);
break
;
case
WM_CHANGECBCHAIN
:
ok
(
msg_flags
==
(
cross_thread
?
ISMEX_SEND
:
ISMEX_NOSEND
),
"WM_CHANGECBCHAIN wrong flags %x
\n
"
,
msg_flags
);
if
(
next_wnd
==
(
HWND
)
wp
)
next_wnd
=
(
HWND
)
lp
;
else
if
(
next_wnd
)
SendMessageA
(
next_wnd
,
msg
,
wp
,
lp
);
break
;
case
WM_DESTROYCLIPBOARD
:
ok
(
msg_flags
==
(
cross_thread
?
ISMEX_SEND
:
ISMEX_NOSEND
),
"WM_DESTROYCLIPBOARD wrong flags %x
\n
"
,
msg_flags
);
wm_destroyclipboard
++
;
ok
(
GetClipboardOwner
()
==
hwnd
,
"WM_DESTROYCLIPBOARD owner %p
\n
"
,
GetClipboardOwner
()
);
nb_formats
=
CountClipboardFormats
();
break
;
case
WM_CLIPBOARDUPDATE
:
ok
(
msg_flags
==
ISMEX_NOSEND
,
"WM_CLIPBOARDUPDATE wrong flags %x
\n
"
,
msg_flags
);
EnterCriticalSection
(
&
clipboard_cs
);
wm_clipboardupdate
++
;
LeaveCriticalSection
(
&
clipboard_cs
);
break
;
case
WM_USER
:
ChangeClipboardChain
(
hwnd
,
next_wnd
);
...
...
@@ -568,9 +580,13 @@ static DWORD WINAPI clipboard_thread(void *param)
{
HWND
ret
,
win
=
param
;
BOOL
r
;
MSG
msg
;
HANDLE
handle
;
UINT
count
,
formats
,
old_seq
=
0
,
seq
;
cross_thread
=
(
GetWindowThreadProcessId
(
win
,
NULL
)
!=
GetCurrentThreadId
());
trace
(
"%s-threaded test
\n
"
,
cross_thread
?
"multi"
:
"single"
);
if
(
pGetClipboardSequenceNumber
)
old_seq
=
pGetClipboardSequenceNumber
();
EnterCriticalSection
(
&
clipboard_cs
);
...
...
@@ -615,8 +631,14 @@ static DWORD WINAPI clipboard_thread(void *param)
seq
=
pGetClipboardSequenceNumber
();
ok
(
seq
==
old_seq
,
"sequence changed
\n
"
);
}
if
(
!
cross_thread
)
{
ok
(
wm_drawclipboard
==
1
,
"WM_DRAWCLIPBOARD not received
\n
"
);
ok
(
!
wm_clipboardupdate
,
"WM_CLIPBOARDUPDATE received
\n
"
);
while
(
PeekMessageW
(
&
msg
,
0
,
0
,
0
,
PM_REMOVE
))
DispatchMessageW
(
&
msg
);
}
count
=
SendMessageA
(
win
,
WM_USER
+
1
,
0
,
0
);
ok
(
count
,
"WM_DRAWCLIPBOARD
received
\n
"
);
ok
(
count
==
1
,
"WM_DRAWCLIPBOARD not
received
\n
"
);
count
=
SendMessageA
(
win
,
WM_USER
+
2
,
0
,
0
);
ok
(
!
count
,
"WM_CLIPBOARDUPDATE received
\n
"
);
...
...
@@ -633,6 +655,12 @@ static DWORD WINAPI clipboard_thread(void *param)
seq
=
pGetClipboardSequenceNumber
();
ok
(
seq
==
old_seq
,
"sequence changed
\n
"
);
}
if
(
!
cross_thread
)
{
ok
(
!
wm_drawclipboard
,
"WM_DRAWCLIPBOARD received
\n
"
);
ok
(
!
wm_clipboardupdate
,
"WM_CLIPBOARDUPDATE received
\n
"
);
while
(
PeekMessageW
(
&
msg
,
0
,
0
,
0
,
PM_REMOVE
))
DispatchMessageW
(
&
msg
);
}
count
=
SendMessageA
(
win
,
WM_USER
+
1
,
0
,
0
);
ok
(
!
count
,
"WM_DRAWCLIPBOARD received
\n
"
);
count
=
SendMessageA
(
win
,
WM_USER
+
2
,
0
,
0
);
...
...
@@ -647,6 +675,12 @@ static DWORD WINAPI clipboard_thread(void *param)
ok
(
(
int
)(
seq
-
old_seq
)
>
0
,
"sequence unchanged
\n
"
);
old_seq
=
seq
;
}
if
(
!
cross_thread
)
{
ok
(
!
wm_drawclipboard
,
"WM_DRAWCLIPBOARD received
\n
"
);
ok
(
!
wm_clipboardupdate
,
"WM_CLIPBOARDUPDATE received
\n
"
);
while
(
PeekMessageW
(
&
msg
,
0
,
0
,
0
,
PM_REMOVE
))
DispatchMessageW
(
&
msg
);
}
count
=
SendMessageA
(
win
,
WM_USER
+
1
,
0
,
0
);
ok
(
!
count
,
"WM_DRAWCLIPBOARD received
\n
"
);
count
=
SendMessageA
(
win
,
WM_USER
+
2
,
0
,
0
);
...
...
@@ -663,6 +697,12 @@ static DWORD WINAPI clipboard_thread(void *param)
ok
(
(
int
)(
seq
-
old_seq
)
>
0
,
"sequence unchanged
\n
"
);
old_seq
=
seq
;
}
if
(
!
cross_thread
)
{
ok
(
!
wm_drawclipboard
,
"WM_DRAWCLIPBOARD received
\n
"
);
ok
(
!
wm_clipboardupdate
,
"WM_CLIPBOARDUPDATE received
\n
"
);
while
(
PeekMessageW
(
&
msg
,
0
,
0
,
0
,
PM_REMOVE
))
DispatchMessageW
(
&
msg
);
}
count
=
SendMessageA
(
win
,
WM_USER
+
1
,
0
,
0
);
ok
(
!
count
,
"WM_DRAWCLIPBOARD received
\n
"
);
count
=
SendMessageA
(
win
,
WM_USER
+
2
,
0
,
0
);
...
...
@@ -681,6 +721,12 @@ static DWORD WINAPI clipboard_thread(void *param)
todo_wine
ok
(
(
int
)(
seq
-
old_seq
)
>
0
,
"sequence unchanged
\n
"
);
old_seq
=
seq
;
}
if
(
!
cross_thread
)
{
ok
(
!
wm_drawclipboard
,
"WM_DRAWCLIPBOARD received
\n
"
);
ok
(
!
wm_clipboardupdate
,
"WM_CLIPBOARDUPDATE received
\n
"
);
while
(
PeekMessageW
(
&
msg
,
0
,
0
,
0
,
PM_REMOVE
))
DispatchMessageW
(
&
msg
);
}
count
=
SendMessageA
(
win
,
WM_USER
+
1
,
0
,
0
);
ok
(
!
count
,
"WM_DRAWCLIPBOARD received
\n
"
);
count
=
SendMessageA
(
win
,
WM_USER
+
2
,
0
,
0
);
...
...
@@ -694,6 +740,12 @@ static DWORD WINAPI clipboard_thread(void *param)
todo_wine
ok
(
(
int
)(
seq
-
old_seq
)
>
0
,
"sequence unchanged
\n
"
);
old_seq
=
seq
;
}
if
(
!
cross_thread
)
{
ok
(
!
wm_drawclipboard
,
"WM_DRAWCLIPBOARD received
\n
"
);
ok
(
!
wm_clipboardupdate
,
"WM_CLIPBOARDUPDATE received
\n
"
);
while
(
PeekMessageW
(
&
msg
,
0
,
0
,
0
,
PM_REMOVE
))
DispatchMessageW
(
&
msg
);
}
count
=
SendMessageA
(
win
,
WM_USER
+
1
,
0
,
0
);
ok
(
!
count
,
"WM_DRAWCLIPBOARD received
\n
"
);
count
=
SendMessageA
(
win
,
WM_USER
+
2
,
0
,
0
);
...
...
@@ -707,6 +759,12 @@ static DWORD WINAPI clipboard_thread(void *param)
todo_wine
ok
(
(
int
)(
seq
-
old_seq
)
>
0
,
"sequence unchanged
\n
"
);
old_seq
=
seq
;
}
if
(
!
cross_thread
)
{
ok
(
!
wm_drawclipboard
,
"WM_DRAWCLIPBOARD received
\n
"
);
ok
(
!
wm_clipboardupdate
,
"WM_CLIPBOARDUPDATE received
\n
"
);
while
(
PeekMessageW
(
&
msg
,
0
,
0
,
0
,
PM_REMOVE
))
DispatchMessageW
(
&
msg
);
}
count
=
SendMessageA
(
win
,
WM_USER
+
1
,
0
,
0
);
ok
(
!
count
,
"WM_DRAWCLIPBOARD received
\n
"
);
count
=
SendMessageA
(
win
,
WM_USER
+
2
,
0
,
0
);
...
...
@@ -723,10 +781,16 @@ static DWORD WINAPI clipboard_thread(void *param)
ok
(
(
int
)(
seq
-
old_seq
)
>
0
,
"sequence unchanged
\n
"
);
old_seq
=
seq
;
}
if
(
!
cross_thread
)
{
ok
(
wm_drawclipboard
==
1
,
"WM_DRAWCLIPBOARD not received
\n
"
);
ok
(
!
wm_clipboardupdate
,
"WM_CLIPBOARDUPDATE received
\n
"
);
while
(
PeekMessageW
(
&
msg
,
0
,
0
,
0
,
PM_REMOVE
))
DispatchMessageW
(
&
msg
);
}
count
=
SendMessageA
(
win
,
WM_USER
+
1
,
0
,
0
);
ok
(
count
,
"WM_DRAWCLIPBOARD not received
\n
"
);
ok
(
count
==
1
,
"WM_DRAWCLIPBOARD not received
\n
"
);
count
=
SendMessageA
(
win
,
WM_USER
+
2
,
0
,
0
);
todo_wine
ok
(
count
||
broken
(
!
pAddClipboardFormatListener
),
"WM_CLIPBOARDUPDATE not received
\n
"
);
ok
(
count
==
1
||
broken
(
!
pAddClipboardFormatListener
),
"WM_CLIPBOARDUPDATE not received
\n
"
);
r
=
OpenClipboard
(
win
);
ok
(
r
,
"OpenClipboard failed: %d
\n
"
,
GetLastError
());
...
...
@@ -736,6 +800,11 @@ static DWORD WINAPI clipboard_thread(void *param)
seq
=
pGetClipboardSequenceNumber
();
ok
(
seq
==
old_seq
,
"sequence changed
\n
"
);
}
if
(
!
cross_thread
)
{
ok
(
!
wm_drawclipboard
,
"WM_DRAWCLIPBOARD received
\n
"
);
ok
(
!
wm_clipboardupdate
,
"WM_CLIPBOARDUPDATE received
\n
"
);
}
count
=
SendMessageA
(
win
,
WM_USER
+
1
,
0
,
0
);
ok
(
!
count
,
"WM_DRAWCLIPBOARD received
\n
"
);
count
=
SendMessageA
(
win
,
WM_USER
+
2
,
0
,
0
);
...
...
@@ -748,6 +817,12 @@ static DWORD WINAPI clipboard_thread(void *param)
todo_wine
ok
(
(
int
)(
seq
-
old_seq
)
>
0
,
"sequence unchanged
\n
"
);
old_seq
=
seq
;
}
if
(
!
cross_thread
)
{
ok
(
!
wm_drawclipboard
,
"WM_DRAWCLIPBOARD received
\n
"
);
ok
(
!
wm_clipboardupdate
,
"WM_CLIPBOARDUPDATE received
\n
"
);
while
(
PeekMessageW
(
&
msg
,
0
,
0
,
0
,
PM_REMOVE
))
DispatchMessageW
(
&
msg
);
}
count
=
SendMessageA
(
win
,
WM_USER
+
1
,
0
,
0
);
ok
(
!
count
,
"WM_DRAWCLIPBOARD received
\n
"
);
count
=
SendMessageA
(
win
,
WM_USER
+
2
,
0
,
0
);
...
...
@@ -762,10 +837,16 @@ static DWORD WINAPI clipboard_thread(void *param)
todo_wine
ok
(
seq
==
old_seq
,
"sequence changed
\n
"
);
old_seq
=
seq
;
}
if
(
!
cross_thread
)
{
ok
(
wm_drawclipboard
==
1
,
"WM_DRAWCLIPBOARD not received
\n
"
);
ok
(
!
wm_clipboardupdate
,
"WM_CLIPBOARDUPDATE received
\n
"
);
while
(
PeekMessageW
(
&
msg
,
0
,
0
,
0
,
PM_REMOVE
))
DispatchMessageW
(
&
msg
);
}
count
=
SendMessageA
(
win
,
WM_USER
+
1
,
0
,
0
);
ok
(
count
,
"WM_DRAWCLIPBOARD not received
\n
"
);
ok
(
count
==
1
,
"WM_DRAWCLIPBOARD not received
\n
"
);
count
=
SendMessageA
(
win
,
WM_USER
+
2
,
0
,
0
);
todo_wine
ok
(
count
||
broken
(
!
pAddClipboardFormatListener
),
"WM_CLIPBOARDUPDATE not received
\n
"
);
ok
(
count
==
1
||
broken
(
!
pAddClipboardFormatListener
),
"WM_CLIPBOARDUPDATE not received
\n
"
);
r
=
OpenClipboard
(
win
);
ok
(
r
,
"OpenClipboard failed: %d
\n
"
,
GetLastError
());
...
...
@@ -777,6 +858,12 @@ static DWORD WINAPI clipboard_thread(void *param)
seq
=
pGetClipboardSequenceNumber
();
ok
(
seq
==
old_seq
,
"sequence changed
\n
"
);
}
if
(
!
cross_thread
)
{
ok
(
!
wm_drawclipboard
,
"WM_DRAWCLIPBOARD received
\n
"
);
ok
(
!
wm_clipboardupdate
,
"WM_CLIPBOARDUPDATE received
\n
"
);
while
(
PeekMessageW
(
&
msg
,
0
,
0
,
0
,
PM_REMOVE
))
DispatchMessageW
(
&
msg
);
}
count
=
SendMessageA
(
win
,
WM_USER
+
1
,
0
,
0
);
ok
(
!
count
,
"WM_DRAWCLIPBOARD received
\n
"
);
count
=
SendMessageA
(
win
,
WM_USER
+
2
,
0
,
0
);
...
...
@@ -792,12 +879,18 @@ static DWORD WINAPI clipboard_thread(void *param)
r
=
CloseClipboard
();
ok
(
r
,
"CloseClipboard failed: %d
\n
"
,
GetLastError
());
if
(
!
cross_thread
)
{
ok
(
wm_drawclipboard
==
1
,
"WM_DRAWCLIPBOARD not received
\n
"
);
ok
(
!
wm_clipboardupdate
,
"WM_CLIPBOARDUPDATE received
\n
"
);
while
(
PeekMessageW
(
&
msg
,
0
,
0
,
0
,
PM_REMOVE
))
DispatchMessageW
(
&
msg
);
}
count
=
SendMessageA
(
win
,
WM_USER
+
1
,
0
,
0
);
ok
(
count
,
"WM_DRAWCLIPBOARD not received
\n
"
);
ok
(
count
==
1
,
"WM_DRAWCLIPBOARD not received
\n
"
);
count
=
SendMessageA
(
win
,
WM_USER
+
2
,
0
,
0
);
todo_wine
ok
(
count
||
broken
(
!
pAddClipboardFormatListener
),
"WM_CLIPBOARDUPDATE not received
\n
"
);
ok
(
count
==
1
||
broken
(
!
pAddClipboardFormatListener
),
"WM_CLIPBOARDUPDATE not received
\n
"
);
count
=
SendMessageA
(
win
,
WM_USER
+
3
,
0
,
0
);
ok
(
count
,
"WM_DESTROYCLIPBOARD not received
\n
"
);
ok
(
count
==
1
,
"WM_DESTROYCLIPBOARD not received
\n
"
);
count
=
SendMessageA
(
win
,
WM_USER
+
4
,
0
,
0
);
ok
(
count
==
formats
,
"wrong format count %u on WM_DESTROYCLIPBOARD
\n
"
,
count
);
...
...
@@ -810,6 +903,14 @@ static DWORD WINAPI clipboard_thread(void *param)
ok
(
(
int
)(
seq
-
old_seq
)
>
0
,
"sequence unchanged
\n
"
);
old_seq
=
seq
;
}
if
(
!
cross_thread
)
{
ok
(
!
wm_drawclipboard
,
"WM_DRAWCLIPBOARD received
\n
"
);
ok
(
!
wm_clipboardupdate
,
"WM_CLIPBOARDUPDATE received
\n
"
);
while
(
PeekMessageW
(
&
msg
,
0
,
0
,
0
,
PM_REMOVE
))
DispatchMessageW
(
&
msg
);
}
count
=
SendMessageA
(
win
,
WM_USER
+
1
,
0
,
0
);
ok
(
!
count
,
"WM_DRAWCLIPBOARD received
\n
"
);
count
=
SendMessageA
(
win
,
WM_USER
+
2
,
0
,
0
);
ok
(
!
count
,
"WM_CLIPBOARDUPDATE received
\n
"
);
count
=
SendMessageA
(
win
,
WM_USER
+
3
,
0
,
0
);
...
...
@@ -826,10 +927,16 @@ static DWORD WINAPI clipboard_thread(void *param)
todo_wine
ok
(
seq
==
old_seq
,
"sequence changed
\n
"
);
old_seq
=
seq
;
}
if
(
!
cross_thread
)
{
ok
(
wm_drawclipboard
==
1
,
"WM_DRAWCLIPBOARD not received
\n
"
);
ok
(
!
wm_clipboardupdate
,
"WM_CLIPBOARDUPDATE received
\n
"
);
while
(
PeekMessageW
(
&
msg
,
0
,
0
,
0
,
PM_REMOVE
))
DispatchMessageW
(
&
msg
);
}
count
=
SendMessageA
(
win
,
WM_USER
+
1
,
0
,
0
);
ok
(
count
,
"WM_DRAWCLIPBOARD not received
\n
"
);
ok
(
count
==
1
,
"WM_DRAWCLIPBOARD not received
\n
"
);
count
=
SendMessageA
(
win
,
WM_USER
+
2
,
0
,
0
);
todo_wine
ok
(
count
||
broken
(
!
pAddClipboardFormatListener
),
"WM_CLIPBOARDUPDATE not received
\n
"
);
ok
(
count
==
1
||
broken
(
!
pAddClipboardFormatListener
),
"WM_CLIPBOARDUPDATE not received
\n
"
);
run_process
(
"grab_clipboard 0"
);
...
...
@@ -839,10 +946,19 @@ static DWORD WINAPI clipboard_thread(void *param)
ok
(
(
int
)(
seq
-
old_seq
)
>
0
,
"sequence unchanged
\n
"
);
old_seq
=
seq
;
}
if
(
!
cross_thread
)
{
ok
(
!
wm_drawclipboard
,
"WM_DRAWCLIPBOARD received
\n
"
);
ok
(
!
wm_clipboardupdate
,
"WM_CLIPBOARDUPDATE received
\n
"
);
/* in this case we get a cross-thread WM_DRAWCLIPBOARD */
cross_thread
=
TRUE
;
while
(
PeekMessageW
(
&
msg
,
0
,
0
,
0
,
PM_REMOVE
))
DispatchMessageW
(
&
msg
);
cross_thread
=
FALSE
;
}
count
=
SendMessageA
(
win
,
WM_USER
+
1
,
0
,
0
);
todo_wine
ok
(
count
,
"WM_DRAWCLIPBOARD not received
\n
"
);
ok
(
count
==
1
,
"WM_DRAWCLIPBOARD not received
\n
"
);
count
=
SendMessageA
(
win
,
WM_USER
+
2
,
0
,
0
);
todo_wine
ok
(
count
||
broken
(
!
pAddClipboardFormatListener
),
"WM_CLIPBOARDUPDATE not received
\n
"
);
ok
(
count
==
1
||
broken
(
!
pAddClipboardFormatListener
),
"WM_CLIPBOARDUPDATE not received
\n
"
);
r
=
OpenClipboard
(
0
);
ok
(
r
,
"OpenClipboard failed: %d
\n
"
,
GetLastError
());
...
...
@@ -853,6 +969,12 @@ static DWORD WINAPI clipboard_thread(void *param)
todo_wine
ok
(
(
int
)(
seq
-
old_seq
)
>
0
,
"sequence unchanged
\n
"
);
old_seq
=
seq
;
}
if
(
!
cross_thread
)
{
ok
(
!
wm_drawclipboard
,
"WM_DRAWCLIPBOARD received
\n
"
);
ok
(
!
wm_clipboardupdate
,
"WM_CLIPBOARDUPDATE received
\n
"
);
while
(
PeekMessageW
(
&
msg
,
0
,
0
,
0
,
PM_REMOVE
))
DispatchMessageW
(
&
msg
);
}
count
=
SendMessageA
(
win
,
WM_USER
+
1
,
0
,
0
);
ok
(
!
count
,
"WM_DRAWCLIPBOARD received
\n
"
);
count
=
SendMessageA
(
win
,
WM_USER
+
2
,
0
,
0
);
...
...
@@ -869,10 +991,16 @@ static DWORD WINAPI clipboard_thread(void *param)
todo_wine
ok
(
seq
==
old_seq
,
"sequence changed
\n
"
);
old_seq
=
seq
;
}
if
(
!
cross_thread
)
{
ok
(
wm_drawclipboard
==
1
,
"WM_DRAWCLIPBOARD received
\n
"
);
ok
(
!
wm_clipboardupdate
,
"WM_CLIPBOARDUPDATE received
\n
"
);
while
(
PeekMessageW
(
&
msg
,
0
,
0
,
0
,
PM_REMOVE
))
DispatchMessageW
(
&
msg
);
}
count
=
SendMessageA
(
win
,
WM_USER
+
1
,
0
,
0
);
ok
(
count
,
"WM_DRAWCLIPBOARD not received
\n
"
);
ok
(
count
==
1
,
"WM_DRAWCLIPBOARD not received
\n
"
);
count
=
SendMessageA
(
win
,
WM_USER
+
2
,
0
,
0
);
todo_wine
ok
(
count
||
broken
(
!
pAddClipboardFormatListener
),
"WM_CLIPBOARDUPDATE not received
\n
"
);
ok
(
count
==
1
||
broken
(
!
pAddClipboardFormatListener
),
"WM_CLIPBOARDUPDATE not received
\n
"
);
run_process
(
"grab_clipboard 1"
);
...
...
@@ -882,10 +1010,19 @@ static DWORD WINAPI clipboard_thread(void *param)
ok
(
(
int
)(
seq
-
old_seq
)
>
0
,
"sequence unchanged
\n
"
);
old_seq
=
seq
;
}
if
(
!
cross_thread
)
{
ok
(
!
wm_drawclipboard
,
"WM_DRAWCLIPBOARD received
\n
"
);
ok
(
!
wm_clipboardupdate
,
"WM_CLIPBOARDUPDATE received
\n
"
);
/* in this case we get a cross-thread WM_DRAWCLIPBOARD */
cross_thread
=
TRUE
;
while
(
PeekMessageW
(
&
msg
,
0
,
0
,
0
,
PM_REMOVE
))
DispatchMessageW
(
&
msg
);
cross_thread
=
FALSE
;
}
count
=
SendMessageA
(
win
,
WM_USER
+
1
,
0
,
0
);
todo_wine
ok
(
count
,
"WM_DRAWCLIPBOARD not received
\n
"
);
ok
(
count
==
1
,
"WM_DRAWCLIPBOARD not received
\n
"
);
count
=
SendMessageA
(
win
,
WM_USER
+
2
,
0
,
0
);
todo_wine
ok
(
count
||
broken
(
!
pAddClipboardFormatListener
),
"WM_CLIPBOARDUPDATE not received
\n
"
);
ok
(
count
==
1
||
broken
(
!
pAddClipboardFormatListener
),
"WM_CLIPBOARDUPDATE not received
\n
"
);
r
=
OpenClipboard
(
0
);
ok
(
r
,
"OpenClipboard failed: %d
\n
"
,
GetLastError
());
...
...
@@ -896,6 +1033,12 @@ static DWORD WINAPI clipboard_thread(void *param)
todo_wine
ok
(
(
int
)(
seq
-
old_seq
)
>
0
,
"sequence unchanged
\n
"
);
old_seq
=
seq
;
}
if
(
!
cross_thread
)
{
ok
(
!
wm_drawclipboard
,
"WM_DRAWCLIPBOARD received
\n
"
);
ok
(
!
wm_clipboardupdate
,
"WM_CLIPBOARDUPDATE received
\n
"
);
while
(
PeekMessageW
(
&
msg
,
0
,
0
,
0
,
PM_REMOVE
))
DispatchMessageW
(
&
msg
);
}
count
=
SendMessageA
(
win
,
WM_USER
+
1
,
0
,
0
);
ok
(
!
count
,
"WM_DRAWCLIPBOARD received
\n
"
);
count
=
SendMessageA
(
win
,
WM_USER
+
2
,
0
,
0
);
...
...
@@ -912,10 +1055,16 @@ static DWORD WINAPI clipboard_thread(void *param)
todo_wine
ok
(
seq
==
old_seq
,
"sequence changed
\n
"
);
old_seq
=
seq
;
}
if
(
!
cross_thread
)
{
ok
(
wm_drawclipboard
==
1
,
"WM_DRAWCLIPBOARD not received
\n
"
);
ok
(
!
wm_clipboardupdate
,
"WM_CLIPBOARDUPDATE received
\n
"
);
while
(
PeekMessageW
(
&
msg
,
0
,
0
,
0
,
PM_REMOVE
))
DispatchMessageW
(
&
msg
);
}
count
=
SendMessageA
(
win
,
WM_USER
+
1
,
0
,
0
);
ok
(
count
,
"WM_DRAWCLIPBOARD not received
\n
"
);
ok
(
count
==
1
,
"WM_DRAWCLIPBOARD not received
\n
"
);
count
=
SendMessageA
(
win
,
WM_USER
+
2
,
0
,
0
);
todo_wine
ok
(
count
||
broken
(
!
pAddClipboardFormatListener
),
"WM_CLIPBOARDUPDATE not received
\n
"
);
ok
(
count
==
1
||
broken
(
!
pAddClipboardFormatListener
),
"WM_CLIPBOARDUPDATE not received
\n
"
);
r
=
PostMessageA
(
win
,
WM_USER
,
0
,
0
);
ok
(
r
,
"PostMessage failed: %d
\n
"
,
GetLastError
());
...
...
@@ -958,7 +1107,9 @@ static void test_messages(void)
thread
=
CreateThread
(
NULL
,
0
,
clipboard_thread
,
(
void
*
)
win
,
0
,
&
tid
);
ok
(
thread
!=
NULL
,
"CreateThread failed: %d
\n
"
,
GetLastError
());
while
(
GetMessageA
(
&
msg
,
NULL
,
0
,
0
))
{
while
(
GetMessageA
(
&
msg
,
NULL
,
0
,
0
))
{
ok
(
msg
.
message
!=
WM_DRAWCLIPBOARD
,
"WM_DRAWCLIPBOARD was posted
\n
"
);
TranslateMessage
(
&
msg
);
DispatchMessageA
(
&
msg
);
}
...
...
@@ -966,6 +1117,16 @@ static void test_messages(void)
ok
(
WaitForSingleObject
(
thread
,
INFINITE
)
==
WAIT_OBJECT_0
,
"WaitForSingleObject failed
\n
"
);
CloseHandle
(
thread
);
DestroyWindow
(
win
);
/* same tests again but inside a single thread */
win
=
CreateWindowA
(
"clipboard_test"
,
NULL
,
0
,
0
,
0
,
0
,
0
,
NULL
,
0
,
NULL
,
0
);
ok
(
win
!=
NULL
,
"CreateWindow failed: %d
\n
"
,
GetLastError
()
);
clipboard_thread
(
win
);
DestroyWindow
(
win
);
UnregisterClassA
(
"clipboard_test"
,
GetModuleHandleA
(
NULL
));
DeleteCriticalSection
(
&
clipboard_cs
);
}
...
...
server/clipboard.c
View file @
c6f12bd9
...
...
@@ -45,6 +45,7 @@ struct clipboard
user_handle_t
owner_win
;
/* window that owns the clipboard data */
user_handle_t
viewer
;
/* first window in clipboard viewer list */
unsigned
int
seqno
;
/* clipboard change sequence number */
unsigned
int
open_seqno
;
/* sequence number at open time */
timeout_t
seqno_timestamp
;
/* time stamp of last seqno increment */
unsigned
int
listen_size
;
/* size of listeners array */
unsigned
int
listen_count
;
/* count of listeners */
...
...
@@ -167,6 +168,21 @@ static int remove_listener( struct clipboard *clipboard, user_handle_t window )
return
0
;
}
/* close the clipboard, and return the viewer window that should be notified if any */
static
user_handle_t
close_clipboard
(
struct
clipboard
*
clipboard
)
{
unsigned
int
i
;
clipboard
->
open_win
=
0
;
clipboard
->
open_thread
=
NULL
;
if
(
clipboard
->
seqno
==
clipboard
->
open_seqno
)
return
0
;
/* unchanged */
for
(
i
=
0
;
i
<
clipboard
->
listen_count
;
i
++
)
post_message
(
clipboard
->
listeners
[
i
],
WM_CLIPBOARDUPDATE
,
0
,
0
);
return
clipboard
->
viewer
;
}
/* cleanup clipboard information upon window destruction */
void
cleanup_clipboard_window
(
struct
desktop
*
desktop
,
user_handle_t
window
)
{
...
...
@@ -174,18 +190,18 @@ void cleanup_clipboard_window( struct desktop *desktop, user_handle_t window )
if
(
!
clipboard
)
return
;
if
(
clipboard
->
open_win
==
window
)
{
clipboard
->
open_win
=
0
;
clipboard
->
open_thread
=
NULL
;
}
remove_listener
(
clipboard
,
window
);
if
(
clipboard
->
viewer
==
window
)
clipboard
->
viewer
=
0
;
if
(
clipboard
->
owner_win
==
window
)
{
clipboard
->
owner_win
=
0
;
clipboard
->
owner_thread
=
NULL
;
}
if
(
clipboard
->
viewer
==
window
)
clipboard
->
viewer
=
0
;
remove_listener
(
clipboard
,
window
);
if
(
clipboard
->
open_win
==
window
)
{
user_handle_t
viewer
=
close_clipboard
(
clipboard
);
if
(
viewer
)
send_notify_message
(
viewer
,
WM_DRAWCLIPBOARD
,
clipboard
->
owner_win
,
0
);
}
}
/* Called when thread terminates to allow release of clipboard */
...
...
@@ -199,16 +215,16 @@ void cleanup_clipboard_thread(struct thread *thread)
if
((
clipboard
=
winstation
->
clipboard
))
{
if
(
thread
==
clipboard
->
open_thread
)
{
clipboard
->
open_win
=
0
;
clipboard
->
open_thread
=
NULL
;
}
if
(
thread
==
clipboard
->
owner_thread
)
{
clipboard
->
owner_win
=
0
;
clipboard
->
owner_thread
=
NULL
;
}
if
(
thread
==
clipboard
->
open_thread
)
{
user_handle_t
viewer
=
close_clipboard
(
clipboard
);
if
(
viewer
)
send_notify_message
(
viewer
,
WM_DRAWCLIPBOARD
,
clipboard
->
owner_win
,
0
);
}
}
release_object
(
winstation
);
}
...
...
@@ -256,6 +272,8 @@ DECL_HANDLER(open_clipboard)
set_error
(
STATUS_INVALID_LOCK_SEQUENCE
);
return
;
}
if
(
!
clipboard
->
open_thread
)
clipboard
->
open_seqno
=
clipboard
->
seqno
;
/* first open */
clipboard
->
open_win
=
win
;
clipboard
->
open_thread
=
current
;
...
...
@@ -276,10 +294,8 @@ DECL_HANDLER(close_clipboard)
return
;
}
if
(
req
->
changed
)
clipboard
->
seqno
++
;
clipboard
->
open_thread
=
NULL
;
clipboard
->
open_win
=
0
;
reply
->
viewer
=
cl
ipboard
->
viewer
;
reply
->
viewer
=
cl
ose_clipboard
(
clipboard
)
;
reply
->
owner
=
(
clipboard
->
owner_thread
&&
clipboard
->
owner_thread
->
process
==
current
->
process
);
}
...
...
server/queue.c
View file @
c6f12bd9
...
...
@@ -2112,6 +2112,33 @@ void post_message( user_handle_t win, unsigned int message, lparam_t wparam, lpa
release_object
(
thread
);
}
/* send a notify message to a window */
void
send_notify_message
(
user_handle_t
win
,
unsigned
int
message
,
lparam_t
wparam
,
lparam_t
lparam
)
{
struct
message
*
msg
;
struct
thread
*
thread
=
get_window_thread
(
win
);
if
(
!
thread
)
return
;
if
(
thread
->
queue
&&
(
msg
=
mem_alloc
(
sizeof
(
*
msg
)
)))
{
msg
->
type
=
MSG_NOTIFY
;
msg
->
win
=
get_user_full_handle
(
win
);
msg
->
msg
=
message
;
msg
->
wparam
=
wparam
;
msg
->
lparam
=
lparam
;
msg
->
result
=
NULL
;
msg
->
data
=
NULL
;
msg
->
data_size
=
0
;
get_message_defaults
(
thread
->
queue
,
&
msg
->
x
,
&
msg
->
y
,
&
msg
->
time
);
list_add_tail
(
&
thread
->
queue
->
msg_list
[
SEND_MESSAGE
],
&
msg
->
entry
);
set_queue_bits
(
thread
->
queue
,
QS_SENDMESSAGE
);
}
release_object
(
thread
);
}
/* post a win event */
void
post_win_event
(
struct
thread
*
thread
,
unsigned
int
event
,
user_handle_t
win
,
unsigned
int
object_id
,
...
...
server/user.h
View file @
c6f12bd9
...
...
@@ -112,6 +112,8 @@ extern int attach_thread_input( struct thread *thread_from, struct thread *threa
extern
void
detach_thread_input
(
struct
thread
*
thread_from
);
extern
void
post_message
(
user_handle_t
win
,
unsigned
int
message
,
lparam_t
wparam
,
lparam_t
lparam
);
extern
void
send_notify_message
(
user_handle_t
win
,
unsigned
int
message
,
lparam_t
wparam
,
lparam_t
lparam
);
extern
void
post_win_event
(
struct
thread
*
thread
,
unsigned
int
event
,
user_handle_t
win
,
unsigned
int
object_id
,
unsigned
int
child_id
,
client_ptr_t
proc
,
...
...
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