user32: Add synthesized clipboard formats on the server side.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
3044935b0e
commit
9ed8f5e83f
|
@ -52,10 +52,6 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(clipboard);
|
WINE_DEFAULT_DEBUG_CHANNEL(clipboard);
|
||||||
|
|
||||||
/*
|
|
||||||
* Indicates if data has changed since open.
|
|
||||||
*/
|
|
||||||
static BOOL bCBHasChanged = FALSE;
|
|
||||||
|
|
||||||
/* get a debug string for a format id */
|
/* get a debug string for a format id */
|
||||||
static const char *debugstr_format( UINT id )
|
static const char *debugstr_format( UINT id )
|
||||||
|
@ -205,30 +201,6 @@ static HANDLE unmarshal_data( UINT format, void *data, data_size_t size )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* formats that can be synthesized are: CF_TEXT, CF_OEMTEXT, CF_UNICODETEXT,
|
|
||||||
CF_BITMAP, CF_DIB, CF_DIBV5, CF_ENHMETAFILE, CF_METAFILEPICT */
|
|
||||||
|
|
||||||
static UINT synthesized_formats[CF_MAX];
|
|
||||||
|
|
||||||
/* add a synthesized format to the list */
|
|
||||||
static void add_synthesized_format( UINT format, UINT from )
|
|
||||||
{
|
|
||||||
assert( format < CF_MAX );
|
|
||||||
SetClipboardData( format, 0 );
|
|
||||||
synthesized_formats[format] = from;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* store the current locale in the CF_LOCALE format */
|
|
||||||
static void set_clipboard_locale(void)
|
|
||||||
{
|
|
||||||
HANDLE data = GlobalAlloc( GMEM_FIXED, sizeof(LCID) );
|
|
||||||
|
|
||||||
if (!data) return;
|
|
||||||
*(LCID *)data = GetUserDefaultLCID();
|
|
||||||
SetClipboardData( CF_LOCALE, data );
|
|
||||||
TRACE( "added CF_LOCALE\n" );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get the clipboard locale stored in the CF_LOCALE format */
|
/* get the clipboard locale stored in the CF_LOCALE format */
|
||||||
static LCID get_clipboard_locale(void)
|
static LCID get_clipboard_locale(void)
|
||||||
{
|
{
|
||||||
|
@ -258,71 +230,6 @@ static UINT get_format_codepage( LCID lcid, UINT format )
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add synthesized text formats based on what is already in the clipboard */
|
|
||||||
static void add_synthesized_text(void)
|
|
||||||
{
|
|
||||||
BOOL has_text = IsClipboardFormatAvailable( CF_TEXT );
|
|
||||||
BOOL has_oemtext = IsClipboardFormatAvailable( CF_OEMTEXT );
|
|
||||||
BOOL has_unicode = IsClipboardFormatAvailable( CF_UNICODETEXT );
|
|
||||||
|
|
||||||
if (!has_text && !has_oemtext && !has_unicode) return; /* no text, nothing to do */
|
|
||||||
|
|
||||||
if (!IsClipboardFormatAvailable( CF_LOCALE )) set_clipboard_locale();
|
|
||||||
|
|
||||||
if (has_unicode)
|
|
||||||
{
|
|
||||||
if (!has_text) add_synthesized_format( CF_TEXT, CF_UNICODETEXT );
|
|
||||||
if (!has_oemtext) add_synthesized_format( CF_OEMTEXT, CF_UNICODETEXT );
|
|
||||||
}
|
|
||||||
else if (has_text)
|
|
||||||
{
|
|
||||||
if (!has_oemtext) add_synthesized_format( CF_OEMTEXT, CF_TEXT );
|
|
||||||
if (!has_unicode) add_synthesized_format( CF_UNICODETEXT, CF_TEXT );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!has_text) add_synthesized_format( CF_TEXT, CF_OEMTEXT );
|
|
||||||
if (!has_unicode) add_synthesized_format( CF_UNICODETEXT, CF_OEMTEXT );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* add synthesized bitmap formats based on what is already in the clipboard */
|
|
||||||
static void add_synthesized_bitmap(void)
|
|
||||||
{
|
|
||||||
BOOL has_dib = IsClipboardFormatAvailable( CF_DIB );
|
|
||||||
BOOL has_dibv5 = IsClipboardFormatAvailable( CF_DIBV5 );
|
|
||||||
BOOL has_bitmap = IsClipboardFormatAvailable( CF_BITMAP );
|
|
||||||
|
|
||||||
if (!has_bitmap && !has_dib && !has_dibv5) return; /* nothing to do */
|
|
||||||
if (has_bitmap && has_dib && has_dibv5) return; /* nothing to synthesize */
|
|
||||||
|
|
||||||
if (has_bitmap)
|
|
||||||
{
|
|
||||||
if (!has_dib) add_synthesized_format( CF_DIB, CF_BITMAP );
|
|
||||||
if (!has_dibv5) add_synthesized_format( CF_DIBV5, CF_BITMAP );
|
|
||||||
}
|
|
||||||
else if (has_dib)
|
|
||||||
{
|
|
||||||
if (!has_bitmap) add_synthesized_format( CF_BITMAP, CF_DIB );
|
|
||||||
if (!has_dibv5) add_synthesized_format( CF_DIBV5, CF_DIB );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!has_bitmap) add_synthesized_format( CF_BITMAP, CF_DIBV5 );
|
|
||||||
if (!has_dib) add_synthesized_format( CF_DIB, CF_DIBV5 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* add synthesized metafile formats based on what is already in the clipboard */
|
|
||||||
static void add_synthesized_metafile(void)
|
|
||||||
{
|
|
||||||
BOOL has_mf = IsClipboardFormatAvailable( CF_METAFILEPICT );
|
|
||||||
BOOL has_emf = IsClipboardFormatAvailable( CF_ENHMETAFILE );
|
|
||||||
|
|
||||||
if (!has_mf && has_emf) add_synthesized_format( CF_METAFILEPICT, CF_ENHMETAFILE );
|
|
||||||
else if (!has_emf && has_mf) add_synthesized_format( CF_ENHMETAFILE, CF_METAFILEPICT );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* render synthesized ANSI text based on the contents of the 'from' format */
|
/* render synthesized ANSI text based on the contents of the 'from' format */
|
||||||
static HANDLE render_synthesized_textA( HANDLE data, UINT format, UINT from )
|
static HANDLE render_synthesized_textA( HANDLE data, UINT format, UINT from )
|
||||||
{
|
{
|
||||||
|
@ -619,14 +526,7 @@ BOOL WINAPI OpenClipboard( HWND hwnd )
|
||||||
SERVER_START_REQ( open_clipboard )
|
SERVER_START_REQ( open_clipboard )
|
||||||
{
|
{
|
||||||
req->window = wine_server_user_handle( hwnd );
|
req->window = wine_server_user_handle( hwnd );
|
||||||
if ((ret = !wine_server_call_err( req )))
|
ret = !wine_server_call_err( req );
|
||||||
{
|
|
||||||
if (!reply->owner)
|
|
||||||
{
|
|
||||||
bCBHasChanged = FALSE;
|
|
||||||
memset( synthesized_formats, 0, sizeof(synthesized_formats) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
|
|
||||||
|
@ -642,15 +542,7 @@ BOOL WINAPI CloseClipboard(void)
|
||||||
HWND viewer = 0, owner = 0;
|
HWND viewer = 0, owner = 0;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
|
||||||
TRACE("() Changed=%d\n", bCBHasChanged);
|
TRACE( "\n" );
|
||||||
|
|
||||||
if (bCBHasChanged)
|
|
||||||
{
|
|
||||||
memset( synthesized_formats, 0, sizeof(synthesized_formats) );
|
|
||||||
add_synthesized_text();
|
|
||||||
add_synthesized_bitmap();
|
|
||||||
add_synthesized_metafile();
|
|
||||||
}
|
|
||||||
|
|
||||||
SERVER_START_REQ( close_clipboard )
|
SERVER_START_REQ( close_clipboard )
|
||||||
{
|
{
|
||||||
|
@ -662,12 +554,8 @@ BOOL WINAPI CloseClipboard(void)
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
|
|
||||||
if (!ret) return FALSE;
|
|
||||||
|
|
||||||
bCBHasChanged = FALSE;
|
|
||||||
|
|
||||||
if (viewer) SendNotifyMessageW( viewer, WM_DRAWCLIPBOARD, (WPARAM)owner, 0 );
|
if (viewer) SendNotifyMessageW( viewer, WM_DRAWCLIPBOARD, (WPARAM)owner, 0 );
|
||||||
return TRUE;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -690,11 +578,6 @@ BOOL WINAPI EmptyClipboard(void)
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
|
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
bCBHasChanged = TRUE;
|
|
||||||
memset( synthesized_formats, 0, sizeof(synthesized_formats) );
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -829,17 +712,14 @@ HANDLE WINAPI SetClipboardData( UINT format, HANDLE data )
|
||||||
SERVER_START_REQ( set_clipboard_data )
|
SERVER_START_REQ( set_clipboard_data )
|
||||||
{
|
{
|
||||||
req->format = format;
|
req->format = format;
|
||||||
|
req->lcid = GetUserDefaultLCID();
|
||||||
wine_server_add_data( req, ptr, size );
|
wine_server_add_data( req, ptr, size );
|
||||||
ret = !wine_server_call_err( req );
|
ret = !wine_server_call_err( req );
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
|
||||||
bCBHasChanged = TRUE;
|
|
||||||
if (format < CF_MAX) synthesized_formats[format] = 0;
|
|
||||||
retval = data;
|
retval = data;
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (ptr) GlobalUnlock( ptr );
|
if (ptr) GlobalUnlock( ptr );
|
||||||
|
@ -949,14 +829,12 @@ BOOL WINAPI GetUpdatedClipboardFormats( UINT *formats, UINT size, UINT *out_size
|
||||||
HANDLE WINAPI GetClipboardData( UINT format )
|
HANDLE WINAPI GetClipboardData( UINT format )
|
||||||
{
|
{
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
UINT from;
|
||||||
HWND owner;
|
HWND owner;
|
||||||
HANDLE data;
|
HANDLE data;
|
||||||
UINT size = 1024;
|
UINT size = 1024;
|
||||||
BOOL render = TRUE;
|
BOOL render = TRUE;
|
||||||
|
|
||||||
if (format < CF_MAX && synthesized_formats[format])
|
|
||||||
return render_synthesized_format( format, synthesized_formats[format] );
|
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (!(data = GlobalAlloc( GMEM_FIXED, size ))) return 0;
|
if (!(data = GlobalAlloc( GMEM_FIXED, size ))) return 0;
|
||||||
|
@ -966,6 +844,7 @@ HANDLE WINAPI GetClipboardData( UINT format )
|
||||||
req->format = format;
|
req->format = format;
|
||||||
wine_server_set_reply( req, data, size );
|
wine_server_set_reply( req, data, size );
|
||||||
status = wine_server_call( req );
|
status = wine_server_call( req );
|
||||||
|
from = reply->from;
|
||||||
size = reply->total;
|
size = reply->total;
|
||||||
owner = wine_server_ptr_handle( reply->owner );
|
owner = wine_server_ptr_handle( reply->owner );
|
||||||
}
|
}
|
||||||
|
@ -995,6 +874,7 @@ HANDLE WINAPI GetClipboardData( UINT format )
|
||||||
SendMessageW( owner, WM_RENDERFORMAT, format, 0 );
|
SendMessageW( owner, WM_RENDERFORMAT, format, 0 );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (from) return render_synthesized_format( format, from );
|
||||||
}
|
}
|
||||||
TRACE( "%s returning 0\n", debugstr_format( format ));
|
TRACE( "%s returning 0\n", debugstr_format( format ));
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1024,11 +904,6 @@ INT WINAPI GetPriorityClipboardFormat(UINT *list, INT nCount)
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* GetClipboardSequenceNumber (USER32.@)
|
* GetClipboardSequenceNumber (USER32.@)
|
||||||
* Supported on Win2k/Win98
|
|
||||||
* MSDN: Windows clipboard code keeps a serial number for the clipboard
|
|
||||||
* for each window station. The number is incremented whenever the
|
|
||||||
* contents change or are emptied.
|
|
||||||
* If you do not have WINSTA_ACCESSCLIPBOARD then the function returns 0
|
|
||||||
*/
|
*/
|
||||||
DWORD WINAPI GetClipboardSequenceNumber(VOID)
|
DWORD WINAPI GetClipboardSequenceNumber(VOID)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4531,7 +4531,9 @@ struct set_clipboard_data_request
|
||||||
{
|
{
|
||||||
struct request_header __header;
|
struct request_header __header;
|
||||||
unsigned int format;
|
unsigned int format;
|
||||||
|
unsigned int lcid;
|
||||||
/* VARARG(data,bytes); */
|
/* VARARG(data,bytes); */
|
||||||
|
char __pad_20[4];
|
||||||
};
|
};
|
||||||
struct set_clipboard_data_reply
|
struct set_clipboard_data_reply
|
||||||
{
|
{
|
||||||
|
@ -4548,9 +4550,11 @@ struct get_clipboard_data_request
|
||||||
struct get_clipboard_data_reply
|
struct get_clipboard_data_reply
|
||||||
{
|
{
|
||||||
struct reply_header __header;
|
struct reply_header __header;
|
||||||
|
unsigned int from;
|
||||||
user_handle_t owner;
|
user_handle_t owner;
|
||||||
data_size_t total;
|
data_size_t total;
|
||||||
/* VARARG(data,bytes); */
|
/* VARARG(data,bytes); */
|
||||||
|
char __pad_20[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -6434,6 +6438,6 @@ union generic_reply
|
||||||
struct terminate_job_reply terminate_job_reply;
|
struct terminate_job_reply terminate_job_reply;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SERVER_PROTOCOL_VERSION 520
|
#define SERVER_PROTOCOL_VERSION 521
|
||||||
|
|
||||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||||
|
|
|
@ -41,6 +41,7 @@ struct clip_format
|
||||||
{
|
{
|
||||||
struct list entry; /* entry in format list */
|
struct list entry; /* entry in format list */
|
||||||
unsigned int id; /* format id */
|
unsigned int id; /* format id */
|
||||||
|
unsigned int from; /* for synthesized data, format to generate it from */
|
||||||
data_size_t size; /* size of the data block */
|
data_size_t size; /* size of the data block */
|
||||||
void *data; /* data contents, or NULL for delay-rendered */
|
void *data; /* data contents, or NULL for delay-rendered */
|
||||||
};
|
};
|
||||||
|
@ -53,10 +54,12 @@ struct clipboard
|
||||||
struct thread *owner_thread; /* thread id that owns the clipboard */
|
struct thread *owner_thread; /* thread id that owns the clipboard */
|
||||||
user_handle_t owner_win; /* window that owns the clipboard data */
|
user_handle_t owner_win; /* window that owns the clipboard data */
|
||||||
user_handle_t viewer; /* first window in clipboard viewer list */
|
user_handle_t viewer; /* first window in clipboard viewer list */
|
||||||
|
unsigned int lcid; /* locale id to use for synthesizing text formats */
|
||||||
unsigned int seqno; /* clipboard change sequence number */
|
unsigned int seqno; /* clipboard change sequence number */
|
||||||
unsigned int open_seqno; /* sequence number at open time */
|
unsigned int open_seqno; /* sequence number at open time */
|
||||||
struct list formats; /* list of data formats */
|
struct list formats; /* list of data formats */
|
||||||
unsigned int format_count; /* count of data formats */
|
unsigned int format_count; /* count of data formats */
|
||||||
|
unsigned int format_map; /* existence bitmap for formats < CF_MAX */
|
||||||
unsigned int listen_size; /* size of listeners array */
|
unsigned int listen_size; /* size of listeners array */
|
||||||
unsigned int listen_count; /* count of listeners */
|
unsigned int listen_count; /* count of listeners */
|
||||||
user_handle_t *listeners; /* array of listener windows */
|
user_handle_t *listeners; /* array of listener windows */
|
||||||
|
@ -88,6 +91,8 @@ static const struct object_ops clipboard_ops =
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define HAS_FORMAT(map,id) ((map) & (1 << (id))) /* only for formats < CF_MAX */
|
||||||
|
|
||||||
/* find a data format in the clipboard */
|
/* find a data format in the clipboard */
|
||||||
static struct clip_format *get_format( struct clipboard *clipboard, unsigned int id )
|
static struct clip_format *get_format( struct clipboard *clipboard, unsigned int id )
|
||||||
{
|
{
|
||||||
|
@ -106,10 +111,12 @@ static struct clip_format *add_format( struct clipboard *clipboard, unsigned int
|
||||||
|
|
||||||
if (!(format = mem_alloc( sizeof(*format )))) return NULL;
|
if (!(format = mem_alloc( sizeof(*format )))) return NULL;
|
||||||
format->id = id;
|
format->id = id;
|
||||||
|
format->from = 0;
|
||||||
format->size = 0;
|
format->size = 0;
|
||||||
format->data = NULL;
|
format->data = NULL;
|
||||||
list_add_tail( &clipboard->formats, &format->entry );
|
list_add_tail( &clipboard->formats, &format->entry );
|
||||||
clipboard->format_count++;
|
clipboard->format_count++;
|
||||||
|
if (id < CF_MAX) clipboard->format_map |= 1 << id;
|
||||||
return format;
|
return format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,6 +132,7 @@ static void free_clipboard_formats( struct clipboard *clipboard )
|
||||||
free( format );
|
free( format );
|
||||||
}
|
}
|
||||||
clipboard->format_count = 0;
|
clipboard->format_count = 0;
|
||||||
|
clipboard->format_map = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dump a clipboard object */
|
/* dump a clipboard object */
|
||||||
|
@ -164,6 +172,7 @@ static struct clipboard *get_process_clipboard(void)
|
||||||
clipboard->viewer = 0;
|
clipboard->viewer = 0;
|
||||||
clipboard->seqno = 0;
|
clipboard->seqno = 0;
|
||||||
clipboard->format_count = 0;
|
clipboard->format_count = 0;
|
||||||
|
clipboard->format_map = 0;
|
||||||
clipboard->listen_size = 0;
|
clipboard->listen_size = 0;
|
||||||
clipboard->listen_count = 0;
|
clipboard->listen_count = 0;
|
||||||
clipboard->listeners = NULL;
|
clipboard->listeners = NULL;
|
||||||
|
@ -175,6 +184,49 @@ static struct clipboard *get_process_clipboard(void)
|
||||||
return clipboard;
|
return clipboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* add synthesized formats upon clipboard close */
|
||||||
|
static int synthesize_formats( struct clipboard *clipboard )
|
||||||
|
{
|
||||||
|
static const unsigned int formats[][3] =
|
||||||
|
{
|
||||||
|
{ CF_TEXT, CF_OEMTEXT, CF_UNICODETEXT },
|
||||||
|
{ CF_OEMTEXT, CF_UNICODETEXT, CF_TEXT },
|
||||||
|
{ CF_UNICODETEXT, CF_TEXT, CF_OEMTEXT },
|
||||||
|
{ CF_METAFILEPICT, CF_ENHMETAFILE },
|
||||||
|
{ CF_ENHMETAFILE, CF_METAFILEPICT },
|
||||||
|
{ CF_BITMAP, CF_DIB, CF_DIBV5 },
|
||||||
|
{ CF_DIB, CF_BITMAP, CF_DIBV5 },
|
||||||
|
{ CF_DIBV5, CF_BITMAP, CF_DIB }
|
||||||
|
};
|
||||||
|
unsigned int i, from, total = 0, map = clipboard->format_map;
|
||||||
|
struct clip_format *format;
|
||||||
|
|
||||||
|
if (!HAS_FORMAT( map, CF_LOCALE ) &&
|
||||||
|
(HAS_FORMAT( map, CF_TEXT ) || HAS_FORMAT( map, CF_OEMTEXT ) || HAS_FORMAT( map, CF_UNICODETEXT )))
|
||||||
|
{
|
||||||
|
void *data = memdup( &clipboard->lcid, sizeof(clipboard->lcid) );
|
||||||
|
if ((format = add_format( clipboard, CF_LOCALE )))
|
||||||
|
{
|
||||||
|
clipboard->seqno++;
|
||||||
|
format->data = data;
|
||||||
|
format->size = sizeof(clipboard->lcid);
|
||||||
|
}
|
||||||
|
else free( data );
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(formats) / sizeof(formats[0]); i++)
|
||||||
|
{
|
||||||
|
if (HAS_FORMAT( map, formats[i][0] )) continue;
|
||||||
|
if (HAS_FORMAT( map, formats[i][1] )) from = formats[i][1];
|
||||||
|
else if (HAS_FORMAT( map, formats[i][2] )) from = formats[i][2];
|
||||||
|
else continue;
|
||||||
|
if (!(format = add_format( clipboard, formats[i][0] ))) continue;
|
||||||
|
format->from = from;
|
||||||
|
total++;
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
/* add a clipboard listener */
|
/* add a clipboard listener */
|
||||||
static void add_listener( struct clipboard *clipboard, user_handle_t window )
|
static void add_listener( struct clipboard *clipboard, user_handle_t window )
|
||||||
{
|
{
|
||||||
|
@ -233,6 +285,7 @@ static user_handle_t close_clipboard( struct clipboard *clipboard )
|
||||||
clipboard->open_win = 0;
|
clipboard->open_win = 0;
|
||||||
clipboard->open_thread = NULL;
|
clipboard->open_thread = NULL;
|
||||||
if (clipboard->seqno == clipboard->open_seqno) return 0; /* unchanged */
|
if (clipboard->seqno == clipboard->open_seqno) return 0; /* unchanged */
|
||||||
|
if (synthesize_formats( clipboard )) clipboard->seqno++;
|
||||||
return notify_listeners( clipboard );
|
return notify_listeners( clipboard );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,8 +301,9 @@ static user_handle_t release_clipboard( struct clipboard *clipboard )
|
||||||
/* free the delayed-rendered formats, since we no longer have an owner to render them */
|
/* 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 )
|
LIST_FOR_EACH_ENTRY_SAFE( format, next, &clipboard->formats, struct clip_format, entry )
|
||||||
{
|
{
|
||||||
if (format->data) continue;
|
if (format->data || format->from) continue;
|
||||||
list_remove( &format->entry );
|
list_remove( &format->entry );
|
||||||
|
if (format->id < CF_MAX) clipboard->format_map &= ~(1 << format->id);
|
||||||
clipboard->format_count--;
|
clipboard->format_count--;
|
||||||
free( format );
|
free( format );
|
||||||
changed = 1;
|
changed = 1;
|
||||||
|
@ -406,8 +460,12 @@ DECL_HANDLER(set_clipboard_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
clipboard->seqno++;
|
clipboard->seqno++;
|
||||||
|
format->from = 0;
|
||||||
format->size = get_req_data_size();
|
format->size = get_req_data_size();
|
||||||
format->data = data;
|
format->data = data;
|
||||||
|
|
||||||
|
if (req->format == CF_TEXT || req->format == CF_OEMTEXT || req->format == CF_UNICODETEXT)
|
||||||
|
clipboard->lcid = req->lcid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -429,8 +487,9 @@ DECL_HANDLER(get_clipboard_data)
|
||||||
set_error( STATUS_OBJECT_NAME_NOT_FOUND );
|
set_error( STATUS_OBJECT_NAME_NOT_FOUND );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
reply->from = format->from;
|
||||||
reply->total = format->size;
|
reply->total = format->size;
|
||||||
if (!format->data) reply->owner = clipboard->owner_win;
|
if (!format->data && !format->from) reply->owner = clipboard->owner_win;
|
||||||
if (format->size <= get_reply_max_size()) set_reply_data( format->data, format->size );
|
if (format->size <= get_reply_max_size()) set_reply_data( format->data, format->size );
|
||||||
else set_error( STATUS_BUFFER_OVERFLOW );
|
else set_error( STATUS_BUFFER_OVERFLOW );
|
||||||
}
|
}
|
||||||
|
|
|
@ -3202,6 +3202,7 @@ enum caret_state
|
||||||
/* Add a data format to the clipboard */
|
/* Add a data format to the clipboard */
|
||||||
@REQ(set_clipboard_data)
|
@REQ(set_clipboard_data)
|
||||||
unsigned int format; /* clipboard format of the data */
|
unsigned int format; /* clipboard format of the data */
|
||||||
|
unsigned int lcid; /* locale id to use for synthesizing text formats */
|
||||||
VARARG(data,bytes); /* data contents */
|
VARARG(data,bytes); /* data contents */
|
||||||
@END
|
@END
|
||||||
|
|
||||||
|
@ -3210,6 +3211,7 @@ enum caret_state
|
||||||
@REQ(get_clipboard_data)
|
@REQ(get_clipboard_data)
|
||||||
unsigned int format; /* clipboard format of the data */
|
unsigned int format; /* clipboard format of the data */
|
||||||
@REPLY
|
@REPLY
|
||||||
|
unsigned int from; /* for synthesized data, format to generate it from */
|
||||||
user_handle_t owner; /* clipboard owner for delayed-rendered formats */
|
user_handle_t owner; /* clipboard owner for delayed-rendered formats */
|
||||||
data_size_t total; /* total data size */
|
data_size_t total; /* total data size */
|
||||||
VARARG(data,bytes); /* data contents */
|
VARARG(data,bytes); /* data contents */
|
||||||
|
|
|
@ -2051,12 +2051,14 @@ C_ASSERT( FIELD_OFFSET(struct set_clipboard_info_reply, seqno) == 24 );
|
||||||
C_ASSERT( sizeof(struct set_clipboard_info_reply) == 32 );
|
C_ASSERT( sizeof(struct set_clipboard_info_reply) == 32 );
|
||||||
C_ASSERT( sizeof(struct empty_clipboard_request) == 16 );
|
C_ASSERT( sizeof(struct empty_clipboard_request) == 16 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct set_clipboard_data_request, format) == 12 );
|
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 set_clipboard_data_request, lcid) == 16 );
|
||||||
|
C_ASSERT( sizeof(struct set_clipboard_data_request) == 24 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct get_clipboard_data_request, format) == 12 );
|
C_ASSERT( FIELD_OFFSET(struct get_clipboard_data_request, format) == 12 );
|
||||||
C_ASSERT( sizeof(struct get_clipboard_data_request) == 16 );
|
C_ASSERT( sizeof(struct get_clipboard_data_request) == 16 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct get_clipboard_data_reply, owner) == 8 );
|
C_ASSERT( FIELD_OFFSET(struct get_clipboard_data_reply, from) == 8 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct get_clipboard_data_reply, total) == 12 );
|
C_ASSERT( FIELD_OFFSET(struct get_clipboard_data_reply, owner) == 12 );
|
||||||
C_ASSERT( sizeof(struct get_clipboard_data_reply) == 16 );
|
C_ASSERT( FIELD_OFFSET(struct get_clipboard_data_reply, total) == 16 );
|
||||||
|
C_ASSERT( sizeof(struct get_clipboard_data_reply) == 24 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct get_clipboard_formats_request, format) == 12 );
|
C_ASSERT( FIELD_OFFSET(struct get_clipboard_formats_request, format) == 12 );
|
||||||
C_ASSERT( sizeof(struct get_clipboard_formats_request) == 16 );
|
C_ASSERT( sizeof(struct get_clipboard_formats_request) == 16 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct get_clipboard_formats_reply, count) == 8 );
|
C_ASSERT( FIELD_OFFSET(struct get_clipboard_formats_reply, count) == 8 );
|
||||||
|
|
|
@ -3776,6 +3776,7 @@ 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 )
|
static void dump_set_clipboard_data_request( const struct set_clipboard_data_request *req )
|
||||||
{
|
{
|
||||||
fprintf( stderr, " format=%08x", req->format );
|
fprintf( stderr, " format=%08x", req->format );
|
||||||
|
fprintf( stderr, ", lcid=%08x", req->lcid );
|
||||||
dump_varargs_bytes( ", data=", cur_size );
|
dump_varargs_bytes( ", data=", cur_size );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3786,7 +3787,8 @@ static void dump_get_clipboard_data_request( const struct get_clipboard_data_req
|
||||||
|
|
||||||
static void dump_get_clipboard_data_reply( const struct get_clipboard_data_reply *req )
|
static void dump_get_clipboard_data_reply( const struct get_clipboard_data_reply *req )
|
||||||
{
|
{
|
||||||
fprintf( stderr, " owner=%08x", req->owner );
|
fprintf( stderr, " from=%08x", req->from );
|
||||||
|
fprintf( stderr, ", owner=%08x", req->owner );
|
||||||
fprintf( stderr, ", total=%u", req->total );
|
fprintf( stderr, ", total=%u", req->total );
|
||||||
dump_varargs_bytes( ", data=", cur_size );
|
dump_varargs_bytes( ", data=", cur_size );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue