Commit 72587931 authored by Alexandre Julliard's avatar Alexandre Julliard

server: Add separate requests for opening and closing the clipboard.

parent bc8f74f9
...@@ -172,33 +172,24 @@ INT WINAPI GetClipboardFormatNameA(UINT wFormat, LPSTR retStr, INT maxlen) ...@@ -172,33 +172,24 @@ INT WINAPI GetClipboardFormatNameA(UINT wFormat, LPSTR retStr, INT maxlen)
/************************************************************************** /**************************************************************************
* OpenClipboard (USER32.@) * OpenClipboard (USER32.@)
*
* Note: Netscape uses NULL hWnd to open the clipboard.
*/ */
BOOL WINAPI OpenClipboard( HWND hWnd ) BOOL WINAPI OpenClipboard( HWND hwnd )
{ {
BOOL bRet; BOOL ret;
UINT flags;
TRACE("(%p)...\n", hWnd); TRACE( "%p\n", hwnd );
SERVER_START_REQ( set_clipboard_info ) SERVER_START_REQ( open_clipboard )
{ {
req->flags = SET_CB_OPEN; req->window = wine_server_user_handle( hwnd );
req->clipboard = wine_server_user_handle( hWnd ); if ((ret = !wine_server_call( req )))
if ((bRet = !wine_server_call( req ))) {
flags = reply->flags; if (!reply->owner) bCBHasChanged = FALSE;
}
} }
SERVER_END_REQ; SERVER_END_REQ;
if (bRet && !(flags & CB_PROCESS)) return ret;
{
bCBHasChanged = FALSE;
}
TRACE(" returning %i\n", bRet);
return bRet;
} }
...@@ -208,26 +199,24 @@ BOOL WINAPI OpenClipboard( HWND hWnd ) ...@@ -208,26 +199,24 @@ BOOL WINAPI OpenClipboard( HWND hWnd )
BOOL WINAPI CloseClipboard(void) BOOL WINAPI CloseClipboard(void)
{ {
HWND viewer = 0; HWND viewer = 0;
UINT flags; BOOL ret, owner = FALSE;
BOOL ret;
TRACE("() Changed=%d\n", bCBHasChanged); TRACE("() Changed=%d\n", bCBHasChanged);
SERVER_START_REQ( set_clipboard_info ) SERVER_START_REQ( close_clipboard )
{ {
req->flags = SET_CB_CLOSE; req->changed = bCBHasChanged;
if (bCBHasChanged) req->flags |= SET_CB_SEQNO;
if ((ret = !wine_server_call_err( req ))) if ((ret = !wine_server_call_err( req )))
{ {
viewer = wine_server_ptr_handle( reply->old_viewer ); viewer = wine_server_ptr_handle( reply->viewer );
flags = reply->flags; owner = reply->owner;
} }
} }
SERVER_END_REQ; SERVER_END_REQ;
if (!ret) return FALSE; if (!ret) return FALSE;
if (bCBHasChanged && (flags & CB_PROCESS)) if (bCBHasChanged && owner)
{ {
USER_Driver->pEndClipboardUpdate(); USER_Driver->pEndClipboardUpdate();
if (viewer) SendNotifyMessageW(viewer, WM_DRAWCLIPBOARD, (WPARAM) GetClipboardOwner(), 0); if (viewer) SendNotifyMessageW(viewer, WM_DRAWCLIPBOARD, (WPARAM) GetClipboardOwner(), 0);
......
...@@ -4460,14 +4460,40 @@ struct set_class_info_reply ...@@ -4460,14 +4460,40 @@ struct set_class_info_reply
struct open_clipboard_request
{
struct request_header __header;
user_handle_t window;
};
struct open_clipboard_reply
{
struct reply_header __header;
int owner;
char __pad_12[4];
};
struct close_clipboard_request
{
struct request_header __header;
int changed;
};
struct close_clipboard_reply
{
struct reply_header __header;
user_handle_t viewer;
int owner;
};
struct set_clipboard_info_request struct set_clipboard_info_request
{ {
struct request_header __header; struct request_header __header;
unsigned int flags; unsigned int flags;
user_handle_t clipboard;
user_handle_t owner; user_handle_t owner;
user_handle_t viewer; user_handle_t viewer;
unsigned int seqno;
}; };
struct set_clipboard_info_reply struct set_clipboard_info_reply
{ {
...@@ -4480,11 +4506,9 @@ struct set_clipboard_info_reply ...@@ -4480,11 +4506,9 @@ struct set_clipboard_info_reply
char __pad_28[4]; char __pad_28[4];
}; };
#define SET_CB_OPEN 0x001
#define SET_CB_VIEWER 0x004 #define SET_CB_VIEWER 0x004
#define SET_CB_SEQNO 0x008 #define SET_CB_SEQNO 0x008
#define SET_CB_RELOWNER 0x010 #define SET_CB_RELOWNER 0x010
#define SET_CB_CLOSE 0x020
#define CB_OPEN 0x040 #define CB_OPEN 0x040
#define CB_OWNER 0x080 #define CB_OWNER 0x080
#define CB_PROCESS 0x100 #define CB_PROCESS 0x100
...@@ -5631,6 +5655,8 @@ enum request ...@@ -5631,6 +5655,8 @@ enum request
REQ_create_class, REQ_create_class,
REQ_destroy_class, REQ_destroy_class,
REQ_set_class_info, REQ_set_class_info,
REQ_open_clipboard,
REQ_close_clipboard,
REQ_set_clipboard_info, REQ_set_clipboard_info,
REQ_empty_clipboard, REQ_empty_clipboard,
REQ_open_token, REQ_open_token,
...@@ -5911,6 +5937,8 @@ union generic_request ...@@ -5911,6 +5937,8 @@ union generic_request
struct create_class_request create_class_request; struct create_class_request create_class_request;
struct destroy_class_request destroy_class_request; struct destroy_class_request destroy_class_request;
struct set_class_info_request set_class_info_request; struct set_class_info_request set_class_info_request;
struct open_clipboard_request open_clipboard_request;
struct close_clipboard_request close_clipboard_request;
struct set_clipboard_info_request set_clipboard_info_request; struct set_clipboard_info_request set_clipboard_info_request;
struct empty_clipboard_request empty_clipboard_request; struct empty_clipboard_request empty_clipboard_request;
struct open_token_request open_token_request; struct open_token_request open_token_request;
...@@ -6189,6 +6217,8 @@ union generic_reply ...@@ -6189,6 +6217,8 @@ union generic_reply
struct create_class_reply create_class_reply; struct create_class_reply create_class_reply;
struct destroy_class_reply destroy_class_reply; struct destroy_class_reply destroy_class_reply;
struct set_class_info_reply set_class_info_reply; struct set_class_info_reply set_class_info_reply;
struct open_clipboard_reply open_clipboard_reply;
struct close_clipboard_reply close_clipboard_reply;
struct set_clipboard_info_reply set_clipboard_info_reply; struct set_clipboard_info_reply set_clipboard_info_reply;
struct empty_clipboard_reply empty_clipboard_reply; struct empty_clipboard_reply empty_clipboard_reply;
struct open_token_reply open_token_reply; struct open_token_reply open_token_reply;
...@@ -6250,6 +6280,6 @@ union generic_reply ...@@ -6250,6 +6280,6 @@ union generic_reply
struct terminate_job_reply terminate_job_reply; struct terminate_job_reply terminate_job_reply;
}; };
#define SERVER_PROTOCOL_VERSION 509 #define SERVER_PROTOCOL_VERSION 510
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -137,31 +137,6 @@ void cleanup_clipboard_thread(struct thread *thread) ...@@ -137,31 +137,6 @@ void cleanup_clipboard_thread(struct thread *thread)
release_object( winstation ); release_object( winstation );
} }
static int open_clipboard( struct clipboard *clipboard, user_handle_t win )
{
win = get_user_full_handle( win );
if (clipboard->open_thread && clipboard->open_win != win)
{
set_error(STATUS_WAS_LOCKED);
return 0;
}
clipboard->open_win = win;
clipboard->open_thread = current;
return 1;
}
static int close_clipboard( struct clipboard *clipboard )
{
if (clipboard->open_thread != current)
{
set_win32_error( ERROR_CLIPBOARD_NOT_OPEN );
return 0;
}
clipboard->open_thread = NULL;
clipboard->open_win = 0;
return 1;
}
static int release_clipboard_owner( struct clipboard *clipboard, user_handle_t win ) static int release_clipboard_owner( struct clipboard *clipboard, user_handle_t win )
{ {
if ((clipboard->open_thread && clipboard->open_thread->process != current->process) || if ((clipboard->open_thread && clipboard->open_thread->process != current->process) ||
...@@ -187,24 +162,57 @@ static int get_seqno( struct clipboard *clipboard ) ...@@ -187,24 +162,57 @@ static int get_seqno( struct clipboard *clipboard )
} }
DECL_HANDLER(set_clipboard_info) /* open the clipboard */
DECL_HANDLER(open_clipboard)
{ {
struct clipboard *clipboard = get_process_clipboard(); struct clipboard *clipboard = get_process_clipboard();
user_handle_t win;
if (!clipboard) return; if (!clipboard) return;
win = get_user_full_handle( req->window );
reply->old_clipboard = clipboard->open_win; if (clipboard->open_thread && clipboard->open_win != win)
reply->old_owner = clipboard->owner_win;
reply->old_viewer = clipboard->viewer;
if (req->flags & SET_CB_OPEN)
{ {
if (!open_clipboard( clipboard, req->clipboard )) return; set_error( STATUS_WAS_LOCKED );
return;
} }
else if (req->flags & SET_CB_CLOSE) clipboard->open_win = win;
clipboard->open_thread = current;
reply->owner = (clipboard->owner_thread && clipboard->owner_thread->process == current->process);
}
/* close the clipboard */
DECL_HANDLER(close_clipboard)
{
struct clipboard *clipboard = get_process_clipboard();
if (!clipboard) return;
if (clipboard->open_thread != current)
{ {
if (!close_clipboard( clipboard )) return; set_win32_error( ERROR_CLIPBOARD_NOT_OPEN );
return;
} }
if (req->changed) clipboard->seqno++;
clipboard->open_thread = NULL;
clipboard->open_win = 0;
reply->viewer = clipboard->viewer;
reply->owner = (clipboard->owner_thread && clipboard->owner_thread->process == current->process);
}
DECL_HANDLER(set_clipboard_info)
{
struct clipboard *clipboard = get_process_clipboard();
if (!clipboard) return;
reply->old_clipboard = clipboard->open_win;
reply->old_owner = clipboard->owner_win;
reply->old_viewer = clipboard->viewer;
if (req->flags & SET_CB_RELOWNER) if (req->flags & SET_CB_RELOWNER)
{ {
......
...@@ -3158,13 +3158,28 @@ enum caret_state ...@@ -3158,13 +3158,28 @@ enum caret_state
#define SET_CLASS_EXTRA 0x0010 #define SET_CLASS_EXTRA 0x0010
/* Open the clipboard */
@REQ(open_clipboard)
user_handle_t window; /* clipboard window */
@REPLY
int owner; /* is the process already the owner? */
@END
/* Close the clipboard */
@REQ(close_clipboard)
int changed; /* did it change since the open? */
@REPLY
user_handle_t viewer; /* first clipboard viewer */
int owner; /* is the process already the owner? */
@END
/* Set/get clipboard information */ /* Set/get clipboard information */
@REQ(set_clipboard_info) @REQ(set_clipboard_info)
unsigned int flags; /* flags for fields to set (see below) */ unsigned int flags; /* flags for fields to set (see below) */
user_handle_t clipboard; /* clipboard window */
user_handle_t owner; /* clipboard owner */ user_handle_t owner; /* clipboard owner */
user_handle_t viewer; /* first clipboard viewer */ user_handle_t viewer; /* first clipboard viewer */
unsigned int seqno; /* change sequence number */
@REPLY @REPLY
unsigned int flags; /* status flags (see below) */ unsigned int flags; /* status flags (see below) */
user_handle_t old_clipboard; /* old clipboard window */ user_handle_t old_clipboard; /* old clipboard window */
...@@ -3173,11 +3188,9 @@ enum caret_state ...@@ -3173,11 +3188,9 @@ enum caret_state
unsigned int seqno; /* current sequence number */ unsigned int seqno; /* current sequence number */
@END @END
#define SET_CB_OPEN 0x001
#define SET_CB_VIEWER 0x004 #define SET_CB_VIEWER 0x004
#define SET_CB_SEQNO 0x008 #define SET_CB_SEQNO 0x008
#define SET_CB_RELOWNER 0x010 #define SET_CB_RELOWNER 0x010
#define SET_CB_CLOSE 0x020
#define CB_OPEN 0x040 #define CB_OPEN 0x040
#define CB_OWNER 0x080 #define CB_OWNER 0x080
#define CB_PROCESS 0x100 #define CB_PROCESS 0x100
......
...@@ -326,6 +326,8 @@ DECL_HANDLER(get_hook_info); ...@@ -326,6 +326,8 @@ DECL_HANDLER(get_hook_info);
DECL_HANDLER(create_class); DECL_HANDLER(create_class);
DECL_HANDLER(destroy_class); DECL_HANDLER(destroy_class);
DECL_HANDLER(set_class_info); DECL_HANDLER(set_class_info);
DECL_HANDLER(open_clipboard);
DECL_HANDLER(close_clipboard);
DECL_HANDLER(set_clipboard_info); DECL_HANDLER(set_clipboard_info);
DECL_HANDLER(empty_clipboard); DECL_HANDLER(empty_clipboard);
DECL_HANDLER(open_token); DECL_HANDLER(open_token);
...@@ -605,6 +607,8 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = ...@@ -605,6 +607,8 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_create_class, (req_handler)req_create_class,
(req_handler)req_destroy_class, (req_handler)req_destroy_class,
(req_handler)req_set_class_info, (req_handler)req_set_class_info,
(req_handler)req_open_clipboard,
(req_handler)req_close_clipboard,
(req_handler)req_set_clipboard_info, (req_handler)req_set_clipboard_info,
(req_handler)req_empty_clipboard, (req_handler)req_empty_clipboard,
(req_handler)req_open_token, (req_handler)req_open_token,
...@@ -2010,12 +2014,19 @@ C_ASSERT( FIELD_OFFSET(struct set_class_info_reply, old_win_extra) == 20 ); ...@@ -2010,12 +2014,19 @@ C_ASSERT( FIELD_OFFSET(struct set_class_info_reply, old_win_extra) == 20 );
C_ASSERT( FIELD_OFFSET(struct set_class_info_reply, old_instance) == 24 ); C_ASSERT( FIELD_OFFSET(struct set_class_info_reply, old_instance) == 24 );
C_ASSERT( FIELD_OFFSET(struct set_class_info_reply, old_extra_value) == 32 ); C_ASSERT( FIELD_OFFSET(struct set_class_info_reply, old_extra_value) == 32 );
C_ASSERT( sizeof(struct set_class_info_reply) == 40 ); C_ASSERT( sizeof(struct set_class_info_reply) == 40 );
C_ASSERT( FIELD_OFFSET(struct open_clipboard_request, window) == 12 );
C_ASSERT( sizeof(struct open_clipboard_request) == 16 );
C_ASSERT( FIELD_OFFSET(struct open_clipboard_reply, owner) == 8 );
C_ASSERT( sizeof(struct open_clipboard_reply) == 16 );
C_ASSERT( FIELD_OFFSET(struct close_clipboard_request, changed) == 12 );
C_ASSERT( sizeof(struct close_clipboard_request) == 16 );
C_ASSERT( FIELD_OFFSET(struct close_clipboard_reply, viewer) == 8 );
C_ASSERT( FIELD_OFFSET(struct close_clipboard_reply, owner) == 12 );
C_ASSERT( sizeof(struct close_clipboard_reply) == 16 );
C_ASSERT( FIELD_OFFSET(struct set_clipboard_info_request, flags) == 12 ); C_ASSERT( FIELD_OFFSET(struct set_clipboard_info_request, flags) == 12 );
C_ASSERT( FIELD_OFFSET(struct set_clipboard_info_request, clipboard) == 16 ); C_ASSERT( FIELD_OFFSET(struct set_clipboard_info_request, owner) == 16 );
C_ASSERT( FIELD_OFFSET(struct set_clipboard_info_request, owner) == 20 ); C_ASSERT( FIELD_OFFSET(struct set_clipboard_info_request, viewer) == 20 );
C_ASSERT( FIELD_OFFSET(struct set_clipboard_info_request, viewer) == 24 ); C_ASSERT( sizeof(struct set_clipboard_info_request) == 24 );
C_ASSERT( FIELD_OFFSET(struct set_clipboard_info_request, seqno) == 28 );
C_ASSERT( sizeof(struct set_clipboard_info_request) == 32 );
C_ASSERT( FIELD_OFFSET(struct set_clipboard_info_reply, flags) == 8 ); C_ASSERT( FIELD_OFFSET(struct set_clipboard_info_reply, flags) == 8 );
C_ASSERT( FIELD_OFFSET(struct set_clipboard_info_reply, old_clipboard) == 12 ); C_ASSERT( FIELD_OFFSET(struct set_clipboard_info_reply, old_clipboard) == 12 );
C_ASSERT( FIELD_OFFSET(struct set_clipboard_info_reply, old_owner) == 16 ); C_ASSERT( FIELD_OFFSET(struct set_clipboard_info_reply, old_owner) == 16 );
......
...@@ -3734,13 +3734,32 @@ static void dump_set_class_info_reply( const struct set_class_info_reply *req ) ...@@ -3734,13 +3734,32 @@ static void dump_set_class_info_reply( const struct set_class_info_reply *req )
dump_uint64( ", old_extra_value=", &req->old_extra_value ); dump_uint64( ", old_extra_value=", &req->old_extra_value );
} }
static void dump_open_clipboard_request( const struct open_clipboard_request *req )
{
fprintf( stderr, " window=%08x", req->window );
}
static void dump_open_clipboard_reply( const struct open_clipboard_reply *req )
{
fprintf( stderr, " owner=%d", req->owner );
}
static void dump_close_clipboard_request( const struct close_clipboard_request *req )
{
fprintf( stderr, " changed=%d", req->changed );
}
static void dump_close_clipboard_reply( const struct close_clipboard_reply *req )
{
fprintf( stderr, " viewer=%08x", req->viewer );
fprintf( stderr, ", owner=%d", req->owner );
}
static void dump_set_clipboard_info_request( const struct set_clipboard_info_request *req ) static void dump_set_clipboard_info_request( const struct set_clipboard_info_request *req )
{ {
fprintf( stderr, " flags=%08x", req->flags ); fprintf( stderr, " flags=%08x", req->flags );
fprintf( stderr, ", clipboard=%08x", req->clipboard );
fprintf( stderr, ", owner=%08x", req->owner ); fprintf( stderr, ", owner=%08x", req->owner );
fprintf( stderr, ", viewer=%08x", req->viewer ); fprintf( stderr, ", viewer=%08x", req->viewer );
fprintf( stderr, ", seqno=%08x", req->seqno );
} }
static void dump_set_clipboard_info_reply( const struct set_clipboard_info_reply *req ) static void dump_set_clipboard_info_reply( const struct set_clipboard_info_reply *req )
...@@ -4579,6 +4598,8 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { ...@@ -4579,6 +4598,8 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_create_class_request, (dump_func)dump_create_class_request,
(dump_func)dump_destroy_class_request, (dump_func)dump_destroy_class_request,
(dump_func)dump_set_class_info_request, (dump_func)dump_set_class_info_request,
(dump_func)dump_open_clipboard_request,
(dump_func)dump_close_clipboard_request,
(dump_func)dump_set_clipboard_info_request, (dump_func)dump_set_clipboard_info_request,
(dump_func)dump_empty_clipboard_request, (dump_func)dump_empty_clipboard_request,
(dump_func)dump_open_token_request, (dump_func)dump_open_token_request,
...@@ -4855,6 +4876,8 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { ...@@ -4855,6 +4876,8 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_create_class_reply, (dump_func)dump_create_class_reply,
(dump_func)dump_destroy_class_reply, (dump_func)dump_destroy_class_reply,
(dump_func)dump_set_class_info_reply, (dump_func)dump_set_class_info_reply,
(dump_func)dump_open_clipboard_reply,
(dump_func)dump_close_clipboard_reply,
(dump_func)dump_set_clipboard_info_reply, (dump_func)dump_set_clipboard_info_reply,
NULL, NULL,
(dump_func)dump_open_token_reply, (dump_func)dump_open_token_reply,
...@@ -5131,6 +5154,8 @@ static const char * const req_names[REQ_NB_REQUESTS] = { ...@@ -5131,6 +5154,8 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"create_class", "create_class",
"destroy_class", "destroy_class",
"set_class_info", "set_class_info",
"open_clipboard",
"close_clipboard",
"set_clipboard_info", "set_clipboard_info",
"empty_clipboard", "empty_clipboard",
"open_token", "open_token",
......
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