user32: Store clipboard data on the server side.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
ac005d460d
commit
79f90e4e41
|
@ -93,6 +93,76 @@ static const char *debugstr_format( UINT id )
|
|||
}
|
||||
}
|
||||
|
||||
/* build the data to send to the server in SetClipboardData */
|
||||
static HANDLE marshal_data( UINT format, HANDLE handle, data_size_t *ret_size )
|
||||
{
|
||||
SIZE_T size;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case CF_BITMAP:
|
||||
case CF_DSPBITMAP:
|
||||
{
|
||||
BITMAP bitmap, *bm;
|
||||
if (!GetObjectW( handle, sizeof(bitmap), &bitmap )) return 0;
|
||||
size = abs( bitmap.bmHeight ) * ((((bitmap.bmWidth * bitmap.bmBitsPixel) + 15) >> 3) & ~1);
|
||||
*ret_size = sizeof(bitmap) + size;
|
||||
if (!(bm = GlobalAlloc( GMEM_FIXED, *ret_size ))) return 0;
|
||||
*bm = bitmap;
|
||||
GetBitmapBits( handle, size, bm + 1 );
|
||||
return bm;
|
||||
}
|
||||
case CF_PALETTE:
|
||||
{
|
||||
LOGPALETTE *pal;
|
||||
if (!(size = GetPaletteEntries( handle, 0, 0, NULL ))) return 0;
|
||||
*ret_size = offsetof( LOGPALETTE, palPalEntry[size] );
|
||||
if (!(pal = GlobalAlloc( GMEM_FIXED, *ret_size ))) return 0;
|
||||
pal->palVersion = 0x300;
|
||||
pal->palNumEntries = size;
|
||||
GetPaletteEntries( handle, 0, size, pal->palPalEntry );
|
||||
return pal;
|
||||
}
|
||||
case CF_ENHMETAFILE:
|
||||
case CF_DSPENHMETAFILE:
|
||||
{
|
||||
BYTE *ret;
|
||||
if (!(size = GetEnhMetaFileBits( handle, 0, NULL ))) return 0;
|
||||
if (!(ret = GlobalAlloc( GMEM_FIXED, size ))) return 0;
|
||||
GetEnhMetaFileBits( handle, size, ret );
|
||||
*ret_size = size;
|
||||
return ret;
|
||||
}
|
||||
case CF_METAFILEPICT:
|
||||
case CF_DSPMETAFILEPICT:
|
||||
{
|
||||
METAFILEPICT *mf, *mfbits;
|
||||
if (!(mf = GlobalLock( handle ))) return 0;
|
||||
if (!(size = GetMetaFileBitsEx( mf->hMF, 0, NULL )))
|
||||
{
|
||||
GlobalUnlock( handle );
|
||||
return 0;
|
||||
}
|
||||
*ret_size = sizeof(*mf) + size;
|
||||
if (!(mfbits = GlobalAlloc( GMEM_FIXED, *ret_size )))
|
||||
{
|
||||
GlobalUnlock( handle );
|
||||
return 0;
|
||||
}
|
||||
*mfbits = *mf;
|
||||
GetMetaFileBitsEx( mf->hMF, size, mfbits + 1 );
|
||||
GlobalUnlock( handle );
|
||||
return mfbits;
|
||||
}
|
||||
default:
|
||||
if (!(size = GlobalSize( handle ))) return 0;
|
||||
if ((data_size_t)size != size) return 0;
|
||||
*ret_size = size;
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* formats that can be synthesized are: CF_TEXT, CF_OEMTEXT, CF_UNICODETEXT,
|
||||
CF_BITMAP, CF_DIB, CF_DIBV5, CF_ENHMETAFILE, CF_METAFILEPICT */
|
||||
|
||||
|
@ -563,7 +633,6 @@ BOOL WINAPI CloseClipboard(void)
|
|||
|
||||
SERVER_START_REQ( close_clipboard )
|
||||
{
|
||||
req->changed = bCBHasChanged;
|
||||
if ((ret = !wine_server_call_err( req )))
|
||||
{
|
||||
viewer = wine_server_ptr_handle( reply->viewer );
|
||||
|
@ -727,32 +796,38 @@ BOOL WINAPI ChangeClipboardChain( HWND hwnd, HWND next )
|
|||
*/
|
||||
HANDLE WINAPI SetClipboardData( UINT format, HANDLE data )
|
||||
{
|
||||
HANDLE hResult = 0;
|
||||
UINT flags;
|
||||
void *ptr = NULL;
|
||||
data_size_t size = 0;
|
||||
HANDLE handle = data, retval = 0;
|
||||
BOOL ret;
|
||||
|
||||
TRACE( "%s %p\n", debugstr_format( format ), data );
|
||||
|
||||
if (!format)
|
||||
if (data)
|
||||
{
|
||||
SetLastError( ERROR_CLIPBOARD_NOT_OPEN );
|
||||
return 0;
|
||||
if (!(handle = marshal_data( format, data, &size ))) return 0;
|
||||
if (!(ptr = GlobalLock( handle ))) goto done;
|
||||
}
|
||||
|
||||
flags = get_clipboard_flags();
|
||||
if (!(flags & CB_OPEN_ANY))
|
||||
SERVER_START_REQ( set_clipboard_data )
|
||||
{
|
||||
SetLastError( ERROR_CLIPBOARD_NOT_OPEN );
|
||||
return 0;
|
||||
req->format = format;
|
||||
wine_server_add_data( req, ptr, size );
|
||||
ret = !wine_server_call_err( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
if (USER_Driver->pSetClipboardData( format, data, flags & CB_OWNER))
|
||||
if (ret && USER_Driver->pSetClipboardData( format, data, TRUE ))
|
||||
{
|
||||
hResult = data;
|
||||
bCBHasChanged = TRUE;
|
||||
if (format < CF_MAX) synthesized_formats[format] = 0;
|
||||
retval = data;
|
||||
}
|
||||
|
||||
return hResult;
|
||||
done:
|
||||
if (ptr) GlobalUnlock( ptr );
|
||||
if (handle != data) GlobalFree( handle );
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -207,7 +207,7 @@ static LRESULT CALLBACK winproc_wrapper( HWND hwnd, UINT msg, WPARAM wp, LPARAM
|
|||
{
|
||||
case WM_DESTROY:
|
||||
ok( wm_renderallformats, "didn't receive WM_RENDERALLFORMATS before WM_DESTROY\n" );
|
||||
todo_wine ok( wm_drawclipboard, "didn't receive WM_DRAWCLIPBOARD before WM_DESTROY\n" );
|
||||
ok( wm_drawclipboard, "didn't receive WM_DRAWCLIPBOARD before WM_DESTROY\n" );
|
||||
break;
|
||||
case WM_DRAWCLIPBOARD:
|
||||
ok( msg_flags == ISMEX_NOSEND, "WM_DRAWCLIPBOARD wrong flags %x\n", msg_flags );
|
||||
|
@ -1092,7 +1092,7 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
if (pGetClipboardSequenceNumber)
|
||||
{
|
||||
seq = pGetClipboardSequenceNumber();
|
||||
todo_wine ok( (int)(seq - old_seq) == 1, "sequence diff %d\n", seq - old_seq );
|
||||
ok( (int)(seq - old_seq) == 1, "sequence diff %d\n", seq - old_seq );
|
||||
old_seq = seq;
|
||||
}
|
||||
if (!cross_thread)
|
||||
|
@ -1114,7 +1114,7 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
if (pGetClipboardSequenceNumber)
|
||||
{
|
||||
seq = pGetClipboardSequenceNumber();
|
||||
todo_wine ok( (int)(seq - old_seq) == 1, "sequence diff %d\n", seq - old_seq );
|
||||
ok( (int)(seq - old_seq) == 1, "sequence diff %d\n", seq - old_seq );
|
||||
old_seq = seq;
|
||||
}
|
||||
if (!cross_thread)
|
||||
|
@ -1136,7 +1136,7 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
if (pGetClipboardSequenceNumber)
|
||||
{
|
||||
seq = pGetClipboardSequenceNumber();
|
||||
todo_wine ok( (int)(seq - old_seq) == 1, "sequence diff %d\n", seq - old_seq );
|
||||
ok( (int)(seq - old_seq) == 1, "sequence diff %d\n", seq - old_seq );
|
||||
old_seq = seq;
|
||||
}
|
||||
if (!cross_thread)
|
||||
|
@ -1165,7 +1165,7 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
if (pGetClipboardSequenceNumber)
|
||||
{
|
||||
seq = pGetClipboardSequenceNumber();
|
||||
todo_wine ok( (int)(seq - old_seq) == 2, "sequence diff %d\n", seq - old_seq );
|
||||
ok( (int)(seq - old_seq) == 2, "sequence diff %d\n", seq - old_seq );
|
||||
old_seq = seq;
|
||||
}
|
||||
if (!cross_thread)
|
||||
|
@ -1222,7 +1222,7 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
if (pGetClipboardSequenceNumber)
|
||||
{
|
||||
seq = pGetClipboardSequenceNumber();
|
||||
todo_wine ok( (int)(seq - old_seq) == 1, "sequence diff %d\n", seq - old_seq );
|
||||
ok( (int)(seq - old_seq) == 1, "sequence diff %d\n", seq - old_seq );
|
||||
old_seq = seq;
|
||||
}
|
||||
if (!cross_thread)
|
||||
|
@ -1245,7 +1245,7 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
{
|
||||
/* no synthesized format, so CloseClipboard doesn't change the sequence */
|
||||
seq = pGetClipboardSequenceNumber();
|
||||
todo_wine ok( seq == old_seq, "sequence changed\n" );
|
||||
ok( seq == old_seq, "sequence changed\n" );
|
||||
old_seq = seq;
|
||||
}
|
||||
if (!cross_thread)
|
||||
|
@ -1347,7 +1347,7 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
if (pGetClipboardSequenceNumber)
|
||||
{
|
||||
seq = pGetClipboardSequenceNumber();
|
||||
todo_wine ok( seq == old_seq, "sequence changed\n" );
|
||||
ok( seq == old_seq, "sequence changed\n" );
|
||||
old_seq = seq;
|
||||
}
|
||||
if (!cross_thread)
|
||||
|
@ -1395,7 +1395,7 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
if (pGetClipboardSequenceNumber)
|
||||
{
|
||||
seq = pGetClipboardSequenceNumber();
|
||||
todo_wine ok( (int)(seq - old_seq) == 1, "sequence diff %d\n", seq - old_seq );
|
||||
ok( (int)(seq - old_seq) == 1, "sequence diff %d\n", seq - old_seq );
|
||||
old_seq = seq;
|
||||
}
|
||||
if (!cross_thread)
|
||||
|
@ -1420,7 +1420,7 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
if (pGetClipboardSequenceNumber)
|
||||
{
|
||||
seq = pGetClipboardSequenceNumber();
|
||||
todo_wine ok( seq == old_seq, "sequence changed\n" );
|
||||
ok( seq == old_seq, "sequence changed\n" );
|
||||
old_seq = seq;
|
||||
}
|
||||
if (!cross_thread)
|
||||
|
@ -1442,7 +1442,6 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
if (pGetClipboardSequenceNumber)
|
||||
{
|
||||
seq = pGetClipboardSequenceNumber();
|
||||
todo_wine_if (!cross_thread)
|
||||
ok( (int)(seq - old_seq) == 2, "sequence diff %d\n", seq - old_seq );
|
||||
old_seq = seq;
|
||||
}
|
||||
|
@ -1469,7 +1468,7 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
if (pGetClipboardSequenceNumber)
|
||||
{
|
||||
seq = pGetClipboardSequenceNumber();
|
||||
todo_wine ok( (int)(seq - old_seq) == 1, "sequence diff %d\n", seq - old_seq );
|
||||
ok( (int)(seq - old_seq) == 1, "sequence diff %d\n", seq - old_seq );
|
||||
old_seq = seq;
|
||||
}
|
||||
if (!cross_thread)
|
||||
|
@ -1494,7 +1493,7 @@ static DWORD WINAPI clipboard_thread(void *param)
|
|||
if (pGetClipboardSequenceNumber)
|
||||
{
|
||||
seq = pGetClipboardSequenceNumber();
|
||||
todo_wine ok( seq == old_seq, "sequence changed\n" );
|
||||
ok( seq == old_seq, "sequence changed\n" );
|
||||
old_seq = seq;
|
||||
}
|
||||
if (!cross_thread)
|
||||
|
@ -1670,7 +1669,7 @@ static void test_handles( HWND hwnd )
|
|||
ok( h == htext5, "got %p\n", h );
|
||||
ok( is_moveable( h ), "expected moveable mem %p\n", h );
|
||||
h = SetClipboardData( format_id2, empty_moveable );
|
||||
todo_wine ok( !h, "got %p\n", h );
|
||||
ok( !h, "got %p\n", h );
|
||||
GlobalFree( empty_moveable );
|
||||
|
||||
if (0) /* crashes on vista64 */
|
||||
|
|
|
@ -4477,7 +4477,7 @@ struct open_clipboard_reply
|
|||
struct close_clipboard_request
|
||||
{
|
||||
struct request_header __header;
|
||||
int changed;
|
||||
char __pad_12[4];
|
||||
};
|
||||
struct close_clipboard_reply
|
||||
{
|
||||
|
@ -4527,6 +4527,19 @@ struct empty_clipboard_reply
|
|||
|
||||
|
||||
|
||||
struct set_clipboard_data_request
|
||||
{
|
||||
struct request_header __header;
|
||||
unsigned int format;
|
||||
/* VARARG(data,bytes); */
|
||||
};
|
||||
struct set_clipboard_data_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct release_clipboard_request
|
||||
{
|
||||
struct request_header __header;
|
||||
|
@ -5729,6 +5742,7 @@ enum request
|
|||
REQ_close_clipboard,
|
||||
REQ_set_clipboard_info,
|
||||
REQ_empty_clipboard,
|
||||
REQ_set_clipboard_data,
|
||||
REQ_release_clipboard,
|
||||
REQ_get_clipboard_info,
|
||||
REQ_set_clipboard_viewer,
|
||||
|
@ -6016,6 +6030,7 @@ union generic_request
|
|||
struct close_clipboard_request close_clipboard_request;
|
||||
struct set_clipboard_info_request set_clipboard_info_request;
|
||||
struct empty_clipboard_request empty_clipboard_request;
|
||||
struct set_clipboard_data_request set_clipboard_data_request;
|
||||
struct release_clipboard_request release_clipboard_request;
|
||||
struct get_clipboard_info_request get_clipboard_info_request;
|
||||
struct set_clipboard_viewer_request set_clipboard_viewer_request;
|
||||
|
@ -6301,6 +6316,7 @@ union generic_reply
|
|||
struct close_clipboard_reply close_clipboard_reply;
|
||||
struct set_clipboard_info_reply set_clipboard_info_reply;
|
||||
struct empty_clipboard_reply empty_clipboard_reply;
|
||||
struct set_clipboard_data_reply set_clipboard_data_reply;
|
||||
struct release_clipboard_reply release_clipboard_reply;
|
||||
struct get_clipboard_info_reply get_clipboard_info_reply;
|
||||
struct set_clipboard_viewer_reply set_clipboard_viewer_reply;
|
||||
|
@ -6365,6 +6381,6 @@ union generic_reply
|
|||
struct terminate_job_reply terminate_job_reply;
|
||||
};
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 517
|
||||
#define SERVER_PROTOCOL_VERSION 518
|
||||
|
||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
/*
|
||||
* Server-side clipboard management
|
||||
*
|
||||
* Copyright (C) 2002 Ulrich Czekalla
|
||||
* Copyright 2002 Ulrich Czekalla
|
||||
* Copyright 2016 Alexandre Julliard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -36,6 +37,14 @@
|
|||
#include "winuser.h"
|
||||
#include "winternl.h"
|
||||
|
||||
struct clip_format
|
||||
{
|
||||
struct list entry; /* entry in format list */
|
||||
unsigned int id; /* format id */
|
||||
data_size_t size; /* size of the data block */
|
||||
void *data; /* data contents, or NULL for delay-rendered */
|
||||
};
|
||||
|
||||
struct clipboard
|
||||
{
|
||||
struct object obj; /* object header */
|
||||
|
@ -46,6 +55,8 @@ struct clipboard
|
|||
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 */
|
||||
struct list formats; /* list of data formats */
|
||||
unsigned int format_count; /* count of data formats */
|
||||
unsigned int listen_size; /* size of listeners array */
|
||||
unsigned int listen_count; /* count of listeners */
|
||||
user_handle_t *listeners; /* array of listener windows */
|
||||
|
@ -77,6 +88,45 @@ static const struct object_ops clipboard_ops =
|
|||
};
|
||||
|
||||
|
||||
/* find a data format in the clipboard */
|
||||
static struct clip_format *get_format( struct clipboard *clipboard, unsigned int id )
|
||||
{
|
||||
struct clip_format *format;
|
||||
|
||||
LIST_FOR_EACH_ENTRY( format, &clipboard->formats, struct clip_format, entry )
|
||||
if (format->id == id) return format;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* add a data format to the clipboard */
|
||||
static struct clip_format *add_format( struct clipboard *clipboard, unsigned int id )
|
||||
{
|
||||
struct clip_format *format;
|
||||
|
||||
if (!(format = mem_alloc( sizeof(*format )))) return NULL;
|
||||
format->id = id;
|
||||
format->size = 0;
|
||||
format->data = NULL;
|
||||
list_add_tail( &clipboard->formats, &format->entry );
|
||||
clipboard->format_count++;
|
||||
return format;
|
||||
}
|
||||
|
||||
/* free all clipboard formats */
|
||||
static void free_clipboard_formats( struct clipboard *clipboard )
|
||||
{
|
||||
struct clip_format *format, *next;
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE( format, next, &clipboard->formats, struct clip_format, entry )
|
||||
{
|
||||
list_remove( &format->entry );
|
||||
free( format->data );
|
||||
free( format );
|
||||
}
|
||||
clipboard->format_count = 0;
|
||||
}
|
||||
|
||||
/* dump a clipboard object */
|
||||
static void clipboard_dump( struct object *obj, int verbose )
|
||||
{
|
||||
|
@ -92,6 +142,7 @@ static void clipboard_destroy( struct object *obj )
|
|||
struct clipboard *clipboard = (struct clipboard *)obj;
|
||||
|
||||
free( clipboard->listeners );
|
||||
free_clipboard_formats( clipboard );
|
||||
}
|
||||
|
||||
/* retrieve the clipboard info for the current process, allocating it if needed */
|
||||
|
@ -112,9 +163,11 @@ static struct clipboard *get_process_clipboard(void)
|
|||
clipboard->owner_win = 0;
|
||||
clipboard->viewer = 0;
|
||||
clipboard->seqno = 0;
|
||||
clipboard->format_count = 0;
|
||||
clipboard->listen_size = 0;
|
||||
clipboard->listen_count = 0;
|
||||
clipboard->listeners = NULL;
|
||||
list_init( &clipboard->formats );
|
||||
winstation->clipboard = clipboard;
|
||||
}
|
||||
}
|
||||
|
@ -164,28 +217,47 @@ 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 )
|
||||
/* notify all listeners, and return the viewer window that should be notified if any */
|
||||
static user_handle_t notify_listeners( 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;
|
||||
}
|
||||
|
||||
/* close the clipboard, and return the viewer window that should be notified if any */
|
||||
static user_handle_t close_clipboard( struct clipboard *clipboard )
|
||||
{
|
||||
clipboard->open_win = 0;
|
||||
clipboard->open_thread = NULL;
|
||||
if (clipboard->seqno == clipboard->open_seqno) return 0; /* unchanged */
|
||||
return notify_listeners( clipboard );
|
||||
}
|
||||
|
||||
/* release the clipboard owner, and return the viewer window that should be notified if any */
|
||||
static user_handle_t release_clipboard( struct clipboard *clipboard )
|
||||
{
|
||||
struct clip_format *format, *next;
|
||||
int changed = 0;
|
||||
|
||||
clipboard->owner_win = 0;
|
||||
clipboard->owner_thread = NULL;
|
||||
/* FIXME: free delay-rendered formats if any and notify listeners */
|
||||
return 0;
|
||||
|
||||
/* free the delayed-rendered formats, since we no longer have an owner to render them */
|
||||
LIST_FOR_EACH_ENTRY_SAFE( format, next, &clipboard->formats, struct clip_format, entry )
|
||||
{
|
||||
if (format->data) continue;
|
||||
list_remove( &format->entry );
|
||||
clipboard->format_count--;
|
||||
free( format );
|
||||
changed = 1;
|
||||
}
|
||||
|
||||
if (!changed) return 0;
|
||||
clipboard->seqno++;
|
||||
return notify_listeners( clipboard );
|
||||
}
|
||||
|
||||
/* cleanup clipboard information upon window destruction */
|
||||
|
@ -275,8 +347,6 @@ DECL_HANDLER(close_clipboard)
|
|||
set_win32_error( ERROR_CLIPBOARD_NOT_OPEN );
|
||||
return;
|
||||
}
|
||||
if (req->changed) clipboard->seqno++;
|
||||
|
||||
reply->viewer = close_clipboard( clipboard );
|
||||
reply->owner = clipboard->owner_win;
|
||||
}
|
||||
|
@ -309,6 +379,38 @@ DECL_HANDLER(set_clipboard_info)
|
|||
}
|
||||
|
||||
|
||||
/* add a data format to the clipboard */
|
||||
DECL_HANDLER(set_clipboard_data)
|
||||
{
|
||||
struct clip_format *format;
|
||||
struct clipboard *clipboard = get_process_clipboard();
|
||||
void *data = NULL;
|
||||
|
||||
if (!clipboard) return;
|
||||
|
||||
if (!req->format || !clipboard->open_thread)
|
||||
{
|
||||
set_win32_error( ERROR_CLIPBOARD_NOT_OPEN );
|
||||
return;
|
||||
}
|
||||
|
||||
if (get_req_data_size() && !(data = memdup( get_req_data(), get_req_data_size() ))) return;
|
||||
|
||||
if (!(format = get_format( clipboard, req->format )))
|
||||
{
|
||||
if (!(format = add_format( clipboard, req->format )))
|
||||
{
|
||||
free( data );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
clipboard->seqno++;
|
||||
format->size = get_req_data_size();
|
||||
format->data = data;
|
||||
}
|
||||
|
||||
|
||||
/* empty the clipboard and grab ownership */
|
||||
DECL_HANDLER(empty_clipboard)
|
||||
{
|
||||
|
@ -321,6 +423,8 @@ DECL_HANDLER(empty_clipboard)
|
|||
set_win32_error( ERROR_CLIPBOARD_NOT_OPEN );
|
||||
return;
|
||||
}
|
||||
|
||||
free_clipboard_formats( clipboard );
|
||||
clipboard->owner_win = clipboard->open_win;
|
||||
clipboard->owner_thread = clipboard->open_thread;
|
||||
clipboard->seqno++;
|
||||
|
|
|
@ -3168,7 +3168,6 @@ enum caret_state
|
|||
|
||||
/* Close the clipboard */
|
||||
@REQ(close_clipboard)
|
||||
int changed; /* did it change since the open? */
|
||||
@REPLY
|
||||
user_handle_t viewer; /* first clipboard viewer */
|
||||
user_handle_t owner; /* current clipboard owner */
|
||||
|
@ -3200,6 +3199,13 @@ enum caret_state
|
|||
@END
|
||||
|
||||
|
||||
/* Add a data format to the clipboard */
|
||||
@REQ(set_clipboard_data)
|
||||
unsigned int format; /* clipboard format of the data */
|
||||
VARARG(data,bytes); /* data contents */
|
||||
@END
|
||||
|
||||
|
||||
/* Release ownership of the clipboard */
|
||||
@REQ(release_clipboard)
|
||||
user_handle_t owner; /* clipboard owner to release */
|
||||
|
|
|
@ -330,6 +330,7 @@ DECL_HANDLER(open_clipboard);
|
|||
DECL_HANDLER(close_clipboard);
|
||||
DECL_HANDLER(set_clipboard_info);
|
||||
DECL_HANDLER(empty_clipboard);
|
||||
DECL_HANDLER(set_clipboard_data);
|
||||
DECL_HANDLER(release_clipboard);
|
||||
DECL_HANDLER(get_clipboard_info);
|
||||
DECL_HANDLER(set_clipboard_viewer);
|
||||
|
@ -616,6 +617,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
|
|||
(req_handler)req_close_clipboard,
|
||||
(req_handler)req_set_clipboard_info,
|
||||
(req_handler)req_empty_clipboard,
|
||||
(req_handler)req_set_clipboard_data,
|
||||
(req_handler)req_release_clipboard,
|
||||
(req_handler)req_get_clipboard_info,
|
||||
(req_handler)req_set_clipboard_viewer,
|
||||
|
@ -2028,7 +2030,6 @@ 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 );
|
||||
|
@ -2043,6 +2044,8 @@ C_ASSERT( FIELD_OFFSET(struct set_clipboard_info_reply, old_viewer) == 20 );
|
|||
C_ASSERT( FIELD_OFFSET(struct set_clipboard_info_reply, seqno) == 24 );
|
||||
C_ASSERT( sizeof(struct set_clipboard_info_reply) == 32 );
|
||||
C_ASSERT( sizeof(struct empty_clipboard_request) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct set_clipboard_data_request, format) == 12 );
|
||||
C_ASSERT( sizeof(struct set_clipboard_data_request) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct release_clipboard_request, owner) == 12 );
|
||||
C_ASSERT( sizeof(struct release_clipboard_request) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct release_clipboard_reply, viewer) == 8 );
|
||||
|
|
|
@ -3746,7 +3746,6 @@ static void dump_open_clipboard_reply( const struct open_clipboard_reply *req )
|
|||
|
||||
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 )
|
||||
|
@ -3774,6 +3773,12 @@ static void dump_empty_clipboard_request( const struct empty_clipboard_request *
|
|||
{
|
||||
}
|
||||
|
||||
static void dump_set_clipboard_data_request( const struct set_clipboard_data_request *req )
|
||||
{
|
||||
fprintf( stderr, " format=%08x", req->format );
|
||||
dump_varargs_bytes( ", data=", cur_size );
|
||||
}
|
||||
|
||||
static void dump_release_clipboard_request( const struct release_clipboard_request *req )
|
||||
{
|
||||
fprintf( stderr, " owner=%08x", req->owner );
|
||||
|
@ -4646,6 +4651,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
|||
(dump_func)dump_close_clipboard_request,
|
||||
(dump_func)dump_set_clipboard_info_request,
|
||||
(dump_func)dump_empty_clipboard_request,
|
||||
(dump_func)dump_set_clipboard_data_request,
|
||||
(dump_func)dump_release_clipboard_request,
|
||||
(dump_func)dump_get_clipboard_info_request,
|
||||
(dump_func)dump_set_clipboard_viewer_request,
|
||||
|
@ -4929,6 +4935,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
|||
(dump_func)dump_close_clipboard_reply,
|
||||
(dump_func)dump_set_clipboard_info_reply,
|
||||
NULL,
|
||||
NULL,
|
||||
(dump_func)dump_release_clipboard_reply,
|
||||
(dump_func)dump_get_clipboard_info_reply,
|
||||
(dump_func)dump_set_clipboard_viewer_reply,
|
||||
|
@ -5212,6 +5219,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
|||
"close_clipboard",
|
||||
"set_clipboard_info",
|
||||
"empty_clipboard",
|
||||
"set_clipboard_data",
|
||||
"release_clipboard",
|
||||
"get_clipboard_info",
|
||||
"set_clipboard_viewer",
|
||||
|
|
Loading…
Reference in New Issue