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
0c468c81
Commit
0c468c81
authored
Jun 05, 2006
by
Ulrich Czekalla
Committed by
Alexandre Julliard
Jun 05, 2006
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
x11drv: Improve handling of the case where the clipboard is opened
with a window from another thread or process.
parent
00b2511b
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
82 additions
and
151 deletions
+82
-151
driver.c
dlls/user/driver.c
+4
-15
user_private.h
dlls/user/user_private.h
+1
-2
win.c
dlls/user/win.c
+0
-3
clipboard.c
dlls/x11drv/clipboard.c
+73
-127
event.c
dlls/x11drv/event.c
+1
-2
winex11.drv.spec
dlls/x11drv/winex11.drv.spec
+0
-1
x11drv.h
dlls/x11drv/x11drv.h
+2
-1
x11drv_main.c
dlls/x11drv/x11drv_main.c
+1
-0
No files found.
dlls/user/driver.c
View file @
0c468c81
...
...
@@ -102,7 +102,6 @@ static const USER_DRIVER *load_driver(void)
GET_USER_FUNC
(
RegisterClipboardFormat
);
GET_USER_FUNC
(
GetClipboardFormatName
);
GET_USER_FUNC
(
EndClipboardUpdate
);
GET_USER_FUNC
(
ResetSelectionOwner
);
GET_USER_FUNC
(
ChangeDisplaySettingsEx
);
GET_USER_FUNC
(
EnumDisplaySettingsEx
);
GET_USER_FUNC
(
CreateDesktopWindow
);
...
...
@@ -239,8 +238,9 @@ static void nulldrv_SetScreenSaveActive( BOOL on )
{
}
static
void
nulldrv_AcquireClipboard
(
HWND
hwnd
)
static
INT
nulldrv_AcquireClipboard
(
HWND
hwnd
)
{
return
0
;
}
static
BOOL
nulldrv_CountClipboardFormats
(
void
)
...
...
@@ -281,10 +281,6 @@ static UINT nulldrv_RegisterClipboardFormat( LPCWSTR name )
return
0
;
}
static
void
nulldrv_ResetSelectionOwner
(
HWND
hwnd
,
BOOL
flag
)
{
}
static
BOOL
nulldrv_SetClipboardData
(
UINT
format
,
HANDLE16
h16
,
HANDLE
h32
,
BOOL
owner
)
{
return
FALSE
;
...
...
@@ -438,7 +434,6 @@ static const USER_DRIVER null_driver =
nulldrv_GetClipboardFormatName
,
nulldrv_IsClipboardFormatAvailable
,
nulldrv_RegisterClipboardFormat
,
nulldrv_ResetSelectionOwner
,
nulldrv_SetClipboardData
,
/* display modes */
nulldrv_ChangeDisplaySettingsEx
,
...
...
@@ -563,9 +558,9 @@ static void loaderdrv_SetScreenSaveActive( BOOL on )
load_driver
()
->
pSetScreenSaveActive
(
on
);
}
static
void
loaderdrv_AcquireClipboard
(
HWND
hwnd
)
static
INT
loaderdrv_AcquireClipboard
(
HWND
hwnd
)
{
load_driver
()
->
pAcquireClipboard
(
hwnd
);
return
load_driver
()
->
pAcquireClipboard
(
hwnd
);
}
static
BOOL
loaderdrv_CountClipboardFormats
(
void
)
...
...
@@ -608,11 +603,6 @@ static UINT loaderdrv_RegisterClipboardFormat( LPCWSTR name )
return
load_driver
()
->
pRegisterClipboardFormat
(
name
);
}
static
void
loaderdrv_ResetSelectionOwner
(
HWND
hwnd
,
BOOL
flag
)
{
load_driver
()
->
pResetSelectionOwner
(
hwnd
,
flag
);
}
static
BOOL
loaderdrv_SetClipboardData
(
UINT
format
,
HANDLE16
h16
,
HANDLE
h32
,
BOOL
owner
)
{
return
load_driver
()
->
pSetClipboardData
(
format
,
h16
,
h32
,
owner
);
...
...
@@ -754,7 +744,6 @@ static const USER_DRIVER lazy_load_driver =
loaderdrv_GetClipboardFormatName
,
loaderdrv_IsClipboardFormatAvailable
,
loaderdrv_RegisterClipboardFormat
,
loaderdrv_ResetSelectionOwner
,
loaderdrv_SetClipboardData
,
/* display modes */
loaderdrv_ChangeDisplaySettingsEx
,
...
...
dlls/user/user_private.h
View file @
0c468c81
...
...
@@ -122,7 +122,7 @@ typedef struct tagUSER_DRIVER {
BOOL
(
*
pGetScreenSaveActive
)(
void
);
void
(
*
pSetScreenSaveActive
)(
BOOL
);
/* clipboard functions */
void
(
*
pAcquireClipboard
)(
HWND
);
/* Acquire selection */
INT
(
*
pAcquireClipboard
)(
HWND
);
/* Acquire selection */
BOOL
(
*
pCountClipboardFormats
)(
void
);
/* Count available clipboard formats */
void
(
*
pEmptyClipboard
)(
BOOL
);
/* Empty clipboard data */
void
(
*
pEndClipboardUpdate
)(
void
);
/* End clipboard update */
...
...
@@ -131,7 +131,6 @@ typedef struct tagUSER_DRIVER {
INT
(
*
pGetClipboardFormatName
)(
UINT
,
LPWSTR
,
UINT
);
/* Get a clipboard format name */
BOOL
(
*
pIsClipboardFormatAvailable
)(
UINT
);
/* Check if specified format is available */
UINT
(
*
pRegisterClipboardFormat
)(
LPCWSTR
);
/* Register a clipboard format */
void
(
*
pResetSelectionOwner
)(
HWND
,
BOOL
);
BOOL
(
*
pSetClipboardData
)(
UINT
,
HANDLE16
,
HANDLE
,
BOOL
);
/* Set specified selection data */
/* display modes */
LONG
(
*
pChangeDisplaySettingsEx
)(
LPCWSTR
,
LPDEVMODEW
,
HWND
,
DWORD
,
LPVOID
);
...
...
dlls/user/win.c
View file @
0c468c81
...
...
@@ -1292,7 +1292,6 @@ static void WIN_SendDestroyMsg( HWND hwnd )
if
(
hwnd
==
info
.
hwndCaret
)
DestroyCaret
();
if
(
hwnd
==
info
.
hwndActive
)
WINPOS_ActivateOtherWindow
(
hwnd
);
}
USER_Driver
->
pResetSelectionOwner
(
hwnd
,
TRUE
);
/*
* Send the WM_DESTROY to the window.
...
...
@@ -1358,8 +1357,6 @@ BOOL WINAPI DestroyWindow( HWND hwnd )
if
(
!
IsWindow
(
hwnd
))
return
TRUE
;
USER_Driver
->
pResetSelectionOwner
(
hwnd
,
FALSE
);
/* before the window is unmapped */
/* Hide the window */
if
(
GetWindowLongW
(
hwnd
,
GWL_STYLE
)
&
WS_VISIBLE
)
{
...
...
dlls/x11drv/clipboard.c
View file @
0c468c81
...
...
@@ -334,9 +334,14 @@ static Window thread_selection_wnd(void)
if
(
!
w
)
{
XSetWindowAttributes
attr
;
attr
.
event_mask
=
(
ExposureMask
|
KeyPressMask
|
KeyReleaseMask
|
PointerMotionMask
|
ButtonPressMask
|
ButtonReleaseMask
|
EnterWindowMask
);
wine_tsx11_lock
();
w
=
XCreateWindow
(
thread_display
(),
root_window
,
0
,
0
,
1
,
1
,
0
,
screen_depth
,
InputOutput
,
CopyFromParent
,
0
,
NULL
);
InputOutput
,
CopyFromParent
,
CWEventMask
,
&
attr
);
wine_tsx11_unlock
();
if
(
w
)
...
...
@@ -2304,70 +2309,67 @@ INT X11DRV_GetClipboardFormatName(UINT wFormat, LPWSTR retStr, INT maxlen)
/**************************************************************************
* AcquireClipboard (X11DRV.@)
*/
void
X11DRV_AcquireClipboard
(
HWND
hWndClipWindow
)
int
X11DRV_AcquireClipboard
(
HWND
hWndClipWindow
)
{
DWORD
procid
;
Window
owner
;
Display
*
display
=
thread_display
();
TRACE
(
" %p
\n
"
,
hWndClipWindow
);
/*
* Acquire X selection if we don't already own it.
* Note that we only acquire the selection if it hasn't been already
* acquired by us, and ignore the fact that another X window may be
* asserting ownership. The reason for this is we need *any* top level
* X window to hold selection ownership. The actual clipboard data requests
* are made via GetClipboardData from EVENT_SelectionRequest and this
* ensures that the real HWND owner services the request.
* If the owning X window gets destroyed the selection ownership is
* re-cycled to another top level X window in X11DRV_CLIPBOARD_ResetOwner.
*
* It's important that the selection get acquired from the thread
* that owns the clipboard window. The primary reason is that we know
* it is running a message loop and therefore can process the
* X selection events.
*/
if
(
!
(
selectionAcquired
==
(
S_PRIMARY
|
S_CLIPBOARD
)))
if
(
hWndClipWindow
&&
GetCurrentThreadId
()
!=
GetWindowThreadProcessId
(
hWndClipWindow
,
&
procid
))
{
Window
owner
;
if
(
!
hWndClipWindow
)
hWndClipWindow
=
GetActiveWindow
();
hWndClipWindow
=
GetAncestor
(
hWndClipWindow
,
GA_ROOT
);
if
(
GetCurrentThreadId
()
!=
GetWindowThreadProcessId
(
hWndClipWindow
,
NULL
))
if
(
procid
!=
GetCurrentProcessId
())
{
WARN
(
"Setting clipboard owner to other process is not supported
\n
"
);
hWndClipWindow
=
NULL
;
}
else
{
TRACE
(
"Thread %lx is acquiring selection with thread %lx's window %p
\n
"
,
GetCurrentThreadId
(),
GetWindowThreadProcessId
(
hWndClipWindow
,
NULL
),
hWndClipWindow
);
if
(
!
SendMessageW
(
hWndClipWindow
,
WM_X11DRV_ACQUIRE_SELECTION
,
0
,
0
))
ERR
(
"Failed to acquire selection
\n
"
);
return
;
GetWindowThreadProcessId
(
hWndClipWindow
,
NULL
),
hWndClipWindow
);
return
SendMessageW
(
hWndClipWindow
,
WM_X11DRV_ACQUIRE_SELECTION
,
0
,
0
);
}
}
owner
=
X11DRV_get_whole_window
(
hWndClipWindow
);
owner
=
thread_selection_wnd
(
);
wine_tsx11_lock
();
/* Grab PRIMARY selection if not owned */
if
(
use_primary_selection
&&
!
(
selectionAcquired
&
S_PRIMARY
))
XSetSelectionOwner
(
display
,
XA_PRIMARY
,
owner
,
CurrentTime
);
wine_tsx11_lock
();
/* Grab CLIPBOARD selection if not owned */
if
(
!
(
selectionAcquired
&
S_CLIPBOARD
))
XSetSelectionOwner
(
display
,
x11drv_atom
(
CLIPBOARD
),
owner
,
CurrentTime
);
selectionAcquired
=
0
;
selectionWindow
=
0
;
if
(
use_primary_selection
&&
XGetSelectionOwner
(
display
,
XA_PRIMARY
)
==
owner
)
selectionAcquired
|=
S_PRIMARY
;
/* Grab PRIMARY selection if not owned */
if
(
use_primary_selection
)
XSetSelectionOwner
(
display
,
XA_PRIMARY
,
owner
,
CurrentTime
);
if
(
XGetSelectionOwner
(
display
,
x11drv_atom
(
CLIPBOARD
))
==
owner
)
selectionAcquired
|=
S_CLIPBOARD
;
wine_tsx11_unlock
();
/* Grab CLIPBOARD selection if not owned */
XSetSelectionOwner
(
display
,
x11drv_atom
(
CLIPBOARD
),
owner
,
CurrentTime
);
if
(
selectionAcquired
)
{
selectionWindow
=
owner
;
TRACE
(
"Grabbed X selection, owner=(%08x)
\n
"
,
(
unsigned
)
owner
);
}
}
else
if
(
use_primary_selection
&&
XGetSelectionOwner
(
display
,
XA_PRIMARY
)
==
owner
)
selectionAcquired
|=
S_PRIMARY
;
if
(
XGetSelectionOwner
(
display
,
x11drv_atom
(
CLIPBOARD
))
==
owner
)
selectionAcquired
|=
S_CLIPBOARD
;
wine_tsx11_unlock
();
if
(
selectionAcquired
)
{
ERR
(
"Received request to acquire selection but process is already owner=(%08x)
\n
"
,
(
unsigned
)
selectionWindow
);
selectionWindow
=
owner
;
TRACE
(
"Grabbed X selection, owner=(%08x)
\n
"
,
(
unsigned
)
owner
);
}
return
1
;
}
...
...
@@ -2610,96 +2612,42 @@ BOOL X11DRV_GetClipboardData(UINT wFormat, HANDLE16* phData16, HANDLE* phData32)
/**************************************************************************
* ResetSelectionOwner
(X11DRV.@)
* ResetSelectionOwner
*
* Called from DestroyWindow() to prevent X selection from being lost when
* a top level window is destroyed, by switching ownership to another top
* level window.
* Any top level window can own the selection. See X11DRV_CLIPBOARD_Acquire
* for a more detailed description of this.
* Called when the thread owning the selection is destroyed and we need to
* preserve the selection ownership. We look for another top level window
* in this process and send it a message to acquire the selection.
*/
void
X11DRV_ResetSelectionOwner
(
HWND
hwnd
,
BOOL
bFooBar
)
void
X11DRV_ResetSelectionOwner
(
void
)
{
Display
*
display
=
thread_display
();
HWND
hWndClipOwner
=
0
;
HWND
tmp
;
Window
XWnd
=
X11DRV_get_whole_window
(
hwnd
);
BOOL
bLostSelection
=
FALSE
;
Window
selectionPrevWindow
;
/* There is nothing to do if we don't own the selection,
* or if the X window which currently owns the selection is different
* from the one passed in.
*/
if
(
!
selectionAcquired
||
XWnd
!=
selectionWindow
||
selectionWindow
==
None
)
return
;
if
((
bFooBar
&&
XWnd
)
||
(
!
bFooBar
&&
!
XWnd
))
return
;
hWndClipOwner
=
GetClipboardOwner
();
TRACE
(
"clipboard owner = %p, selection window = %08x
\n
"
,
hWndClipOwner
,
(
unsigned
)
selectionWindow
);
/* now try to salvage current selection from being destroyed by X */
TRACE
(
"checking %08x
\n
"
,
(
unsigned
)
XWnd
);
HWND
hwnd
;
DWORD
procid
;
selectionPrevWindow
=
selectionWindow
;
selectionWindow
=
None
;
TRACE
(
"
\n
"
);
if
(
!
(
tmp
=
GetWindow
(
hwnd
,
GW_HWNDNEXT
))
)
tmp
=
GetWindow
(
hwnd
,
GW_HWNDFIRST
)
;
if
(
!
selectionAcquired
||
thread_selection_wnd
()
!=
selectionWindow
)
return
;
if
(
tmp
&&
tmp
!=
hwnd
)
selectionWindow
=
X11DRV_get_whole_window
(
tmp
)
;
selectionAcquired
=
S_NOSELECTION
;
selectionWindow
=
0
;
if
(
selectionWindow
!=
None
)
hwnd
=
GetWindow
(
GetDesktopWindow
(),
GW_CHILD
);
do
{
/* We must pretend that we don't own the selection while making the switch
* since a SelectionClear event will be sent to the last owner.
* If there is no owner X11DRV_CLIPBOARD_ReleaseSelection will do nothing.
*/
int
saveSelectionState
=
selectionAcquired
;
selectionAcquired
=
S_NOSELECTION
;
TRACE
(
"
\t
switching selection from %08x to %08x
\n
"
,
(
unsigned
)
selectionPrevWindow
,
(
unsigned
)
selectionWindow
);
wine_tsx11_lock
();
/* Assume ownership for the PRIMARY and CLIPBOARD selection */
if
(
saveSelectionState
&
S_PRIMARY
)
XSetSelectionOwner
(
display
,
XA_PRIMARY
,
selectionWindow
,
CurrentTime
);
XSetSelectionOwner
(
display
,
x11drv_atom
(
CLIPBOARD
),
selectionWindow
,
CurrentTime
);
/* Restore the selection masks */
selectionAcquired
=
saveSelectionState
;
/* Lose the selection if something went wrong */
if
(((
saveSelectionState
&
S_PRIMARY
)
&&
(
XGetSelectionOwner
(
display
,
XA_PRIMARY
)
!=
selectionWindow
))
||
(
XGetSelectionOwner
(
display
,
x11drv_atom
(
CLIPBOARD
))
!=
selectionWindow
))
if
(
GetCurrentThreadId
()
!=
GetWindowThreadProcessId
(
hwnd
,
&
procid
))
{
bLostSelection
=
TRUE
;
if
(
GetCurrentProcessId
()
==
procid
)
{
if
(
SendMessageW
(
hwnd
,
WM_X11DRV_ACQUIRE_SELECTION
,
0
,
0
))
return
;
}
}
wine_tsx11_unlock
();
}
else
{
bLostSelection
=
TRUE
;
}
}
while
((
hwnd
=
GetWindow
(
hwnd
,
GW_HWNDNEXT
))
!=
NULL
);
if
(
bLostSelection
)
{
TRACE
(
"Lost the selection!
\n
"
);
WARN
(
"Failed to find another thread to take selection ownership. Clipboard data will be lost.
\n
"
);
X11DRV_CLIPBOARD_ReleaseOwnership
();
selectionAcquired
=
S_NOSELECTION
;
selectionWindow
=
0
;
}
X11DRV_CLIPBOARD_ReleaseOwnership
();
X11DRV_EmptyClipboard
(
FALSE
);
}
...
...
@@ -3091,7 +3039,6 @@ END:
*/
void
X11DRV_SelectionRequest
(
HWND
hWnd
,
XEvent
*
event
)
{
if
(
!
hWnd
)
return
;
X11DRV_HandleSelectionRequest
(
hWnd
,
&
event
->
xselectionrequest
,
FALSE
);
}
...
...
@@ -3102,7 +3049,6 @@ void X11DRV_SelectionRequest( HWND hWnd, XEvent *event )
void
X11DRV_SelectionClear
(
HWND
hWnd
,
XEvent
*
xev
)
{
XSelectionClearEvent
*
event
=
&
xev
->
xselectionclear
;
if
(
!
hWnd
)
return
;
if
(
event
->
selection
==
XA_PRIMARY
||
event
->
selection
==
x11drv_atom
(
CLIPBOARD
))
X11DRV_CLIPBOARD_ReleaseSelection
(
event
->
selection
,
event
->
window
,
hWnd
,
event
->
time
);
}
dlls/x11drv/event.c
View file @
0c468c81
...
...
@@ -937,8 +937,7 @@ LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
switch
(
msg
)
{
case
WM_X11DRV_ACQUIRE_SELECTION
:
X11DRV_AcquireClipboard
(
hwnd
);
return
0
;
return
X11DRV_AcquireClipboard
(
hwnd
);
case
WM_X11DRV_DELETE_WINDOW
:
return
SendMessageW
(
hwnd
,
WM_SYSCOMMAND
,
SC_CLOSE
,
0
);
default:
...
...
dlls/x11drv/winex11.drv.spec
View file @
0c468c81
...
...
@@ -98,7 +98,6 @@
@ cdecl MsgWaitForMultipleObjectsEx(long ptr long long long) X11DRV_MsgWaitForMultipleObjectsEx
@ cdecl RegisterClipboardFormat(wstr) X11DRV_RegisterClipboardFormat
@ cdecl ReleaseDC(long long long) X11DRV_ReleaseDC
@ cdecl ResetSelectionOwner(long long) X11DRV_ResetSelectionOwner
@ cdecl ScrollDC(long long long ptr ptr long ptr) X11DRV_ScrollDC
@ cdecl SetClipboardData(long long long long) X11DRV_SetClipboardData
@ cdecl SetFocus(long) X11DRV_SetFocus
...
...
dlls/x11drv/x11drv.h
View file @
0c468c81
...
...
@@ -662,7 +662,8 @@ extern void invalidate_dce( HWND hwnd, const RECT *rect );
extern
XContext
winContext
;
extern
void
X11DRV_InitClipboard
(
void
);
extern
void
X11DRV_AcquireClipboard
(
HWND
hWndClipWindow
);
extern
int
X11DRV_AcquireClipboard
(
HWND
hWndClipWindow
);
extern
void
X11DRV_ResetSelectionOwner
(
void
);
extern
void
X11DRV_SetFocus
(
HWND
hwnd
);
extern
Cursor
X11DRV_GetCursor
(
Display
*
display
,
struct
tagCURSORICONINFO
*
ptr
);
extern
void
X11DRV_InitKeyboard
(
void
);
...
...
dlls/x11drv/x11drv_main.c
View file @
0c468c81
...
...
@@ -457,6 +457,7 @@ static void thread_detach(void)
if
(
data
)
{
X11DRV_ResetSelectionOwner
();
CloseHandle
(
data
->
display_fd
);
wine_tsx11_lock
();
XCloseDisplay
(
data
->
display
);
...
...
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