diff --git a/dlls/user32/clipboard.c b/dlls/user32/clipboard.c index 9a7753520f5..7e5a3e0b022 100644 --- a/dlls/user32/clipboard.c +++ b/dlls/user32/clipboard.c @@ -48,17 +48,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(clipboard); -struct cached_format -{ - struct list entry; /* entry in cache list */ - UINT format; /* format id */ - UINT seqno; /* sequence number when the data was set */ - HANDLE handle; /* original data handle */ -}; - -static struct list cached_formats = LIST_INIT( cached_formats ); -static struct list formats_to_free = LIST_INIT( formats_to_free ); - static CRITICAL_SECTION clipboard_cs; static CRITICAL_SECTION_DEBUG critsect_debug = { @@ -119,7 +108,7 @@ 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 ) +static HANDLE marshal_data( UINT format, HANDLE handle, size_t *ret_size ) { SIZE_T size; @@ -258,110 +247,35 @@ static HANDLE unmarshal_data( UINT format, void *data, data_size_t size ) return handle; } -/* retrieve a data format from the cache */ -static struct cached_format *get_cached_format( UINT format ) -{ - struct cached_format *cache; - - LIST_FOR_EACH_ENTRY( cache, &cached_formats, struct cached_format, entry ) - if (cache->format == format) return cache; - return NULL; -} - -/* store data in the cache, or reuse the existing one if available */ -static HANDLE cache_data( UINT format, HANDLE data, data_size_t size, UINT seqno, - struct cached_format *cache ) -{ - if (cache) - { - if (seqno == cache->seqno) /* we can reuse the cached data */ - { - GlobalFree( data ); - return cache->handle; - } - /* cache entry is stale, remove it */ - list_remove( &cache->entry ); - list_add_tail( &formats_to_free, &cache->entry ); - } - - /* allocate new cache entry */ - if (!(cache = HeapAlloc( GetProcessHeap(), 0, sizeof(*cache) ))) - { - GlobalFree( data ); - return 0; - } - cache->format = format; - cache->seqno = seqno; - cache->handle = unmarshal_data( format, data, size ); - list_add_tail( &cached_formats, &cache->entry ); - return cache->handle; -} - /* free a single cached format */ -static void free_cached_data( struct cached_format *cache ) +void free_cached_data( UINT format, HANDLE handle ) { void *ptr; - switch (cache->format) + switch (format) { case CF_BITMAP: case CF_DSPBITMAP: case CF_PALETTE: - DeleteObject( cache->handle ); + DeleteObject( handle ); break; case CF_ENHMETAFILE: case CF_DSPENHMETAFILE: - DeleteEnhMetaFile( cache->handle ); + DeleteEnhMetaFile( handle ); break; case CF_METAFILEPICT: case CF_DSPMETAFILEPICT: - if ((ptr = GlobalLock( cache->handle ))) + if ((ptr = GlobalLock( handle ))) { DeleteMetaFile( ((METAFILEPICT *)ptr)->hMF ); - GlobalUnlock( cache->handle ); + GlobalUnlock( handle ); } - GlobalFree( cache->handle ); + GlobalFree( handle ); break; default: - GlobalFree( cache->handle ); + GlobalFree( handle ); break; } - list_remove( &cache->entry ); - HeapFree( GetProcessHeap(), 0, cache ); -} - -/* clear global memory formats; special types are freed on EmptyClipboard */ -static void invalidate_memory_formats(void) -{ - struct cached_format *cache, *next; - - LIST_FOR_EACH_ENTRY_SAFE( cache, next, &cached_formats, struct cached_format, entry ) - { - switch (cache->format) - { - case CF_BITMAP: - case CF_DSPBITMAP: - case CF_PALETTE: - case CF_ENHMETAFILE: - case CF_DSPENHMETAFILE: - case CF_METAFILEPICT: - case CF_DSPMETAFILEPICT: - continue; - default: - free_cached_data( cache ); - break; - } - } -} - -/* free all the data in the cache */ -static void free_cached_formats(void) -{ - struct list *ptr; - - list_move_tail( &formats_to_free, &cached_formats ); - while ((ptr = list_head( &formats_to_free ))) - free_cached_data( LIST_ENTRY( ptr, struct cached_format, entry )); } /* get the clipboard locale stored in the CF_LOCALE format */ @@ -576,7 +490,7 @@ static HANDLE render_synthesized_enhmetafile( HANDLE data ) } /* render a synthesized format */ -static HANDLE render_synthesized_format( UINT format, UINT from ) +HANDLE render_synthesized_format( UINT format, UINT from ) { HANDLE data = GetClipboardData( from ); @@ -650,55 +564,7 @@ INT WINAPI GetClipboardFormatNameA( UINT format, LPSTR buffer, INT maxlen ) */ BOOL WINAPI OpenClipboard( HWND hwnd ) { - BOOL ret; - HWND owner; - - TRACE( "%p\n", hwnd ); - - NtUserCallNoParam( NtUserUpdateClipboard ); - - EnterCriticalSection( &clipboard_cs ); - - SERVER_START_REQ( open_clipboard ) - { - req->window = wine_server_user_handle( hwnd ); - ret = !wine_server_call_err( req ); - owner = wine_server_ptr_handle( reply->owner ); - } - SERVER_END_REQ; - - if (ret && !WIN_IsCurrentProcess( owner )) invalidate_memory_formats(); - - LeaveCriticalSection( &clipboard_cs ); - return ret; -} - - -/************************************************************************** - * EmptyClipboard (USER32.@) - * Empties and acquires ownership of the clipboard - */ -BOOL WINAPI EmptyClipboard(void) -{ - BOOL ret; - HWND owner = NtUserGetClipboardOwner(); - - TRACE( "owner %p\n", owner ); - - if (owner) SendMessageTimeoutW( owner, WM_DESTROYCLIPBOARD, 0, 0, SMTO_ABORTIFHUNG, 5000, NULL ); - - EnterCriticalSection( &clipboard_cs ); - - SERVER_START_REQ( empty_clipboard ) - { - ret = !wine_server_call_err( req ); - } - SERVER_END_REQ; - - if (ret) free_cached_formats(); - - LeaveCriticalSection( &clipboard_cs ); - return ret; + return NtUserOpenClipboard( hwnd, 0 ); } @@ -707,55 +573,28 @@ BOOL WINAPI EmptyClipboard(void) */ HANDLE WINAPI SetClipboardData( UINT format, HANDLE data ) { - struct cached_format *cache = NULL; - void *ptr = NULL; - data_size_t size = 0; - HANDLE handle = data, retval = 0; - NTSTATUS status = STATUS_SUCCESS; + struct set_clipboard_params params = { .size = 0 }; + HANDLE handle = data; + NTSTATUS status; TRACE( "%s %p\n", debugstr_format( format ), data ); if (data) { - if (!(handle = marshal_data( format, data, &size ))) return 0; - if (!(ptr = GlobalLock( handle ))) goto done; - if (!(cache = HeapAlloc( GetProcessHeap(), 0, sizeof(*cache) ))) goto done; - cache->format = format; - cache->handle = data; + if (!(handle = marshal_data( format, data, ¶ms.size ))) return 0; + if (!(params.data = GlobalLock( handle ))) return 0; } - EnterCriticalSection( &clipboard_cs ); + status = NtUserSetClipboardData( format, data, ¶ms ); - SERVER_START_REQ( set_clipboard_data ) - { - req->format = format; - req->lcid = GetUserDefaultLCID(); - wine_server_add_data( req, ptr, size ); - if (!(status = wine_server_call( req ))) - { - if (cache) cache->seqno = reply->seqno; - } - } - SERVER_END_REQ; - - if (!status) - { - /* free the previous entry if any */ - struct cached_format *prev; - - if ((prev = get_cached_format( format ))) free_cached_data( prev ); - if (cache) list_add_tail( &cached_formats, &cache->entry ); - retval = data; - } - else HeapFree( GetProcessHeap(), 0, cache ); - - LeaveCriticalSection( &clipboard_cs ); - -done: - if (ptr) GlobalUnlock( handle ); + if (params.data) GlobalUnlock( handle ); if (handle != data) GlobalFree( handle ); - if (status) SetLastError( RtlNtStatusToDosError( status )); - return retval; + if (status) + { + SetLastError( RtlNtStatusToDosError( status )); + return 0; + } + return data; } @@ -773,73 +612,34 @@ UINT WINAPI EnumClipboardFormats( UINT format ) */ HANDLE WINAPI GetClipboardData( UINT format ) { - struct cached_format *cache; - NTSTATUS status; - UINT from, data_seqno; - HWND owner; - HANDLE data; - UINT size = 1024; - BOOL render = TRUE; + struct get_clipboard_params params = { .data_size = 1024 }; + HANDLE ret = 0; - for (;;) + EnterCriticalSection( &clipboard_cs ); + + while (params.data_size) { - if (!(data = GlobalAlloc( GMEM_FIXED, size ))) return 0; - - EnterCriticalSection( &clipboard_cs ); - cache = get_cached_format( format ); - - SERVER_START_REQ( get_clipboard_data ) + params.size = params.data_size; + params.data_size = 0; + if (!(params.data = GlobalAlloc( GMEM_FIXED, params.size ))) break; + ret = NtUserGetClipboardData( format, ¶ms ); + if (ret) break; + if (params.data_size == ~0) /* needs unmarshaling */ { - req->format = format; - req->render = render; - if (cache) - { - req->cached = 1; - req->seqno = cache->seqno; - } - wine_server_set_reply( req, data, size ); - status = wine_server_call( req ); - from = reply->from; - size = reply->total; - data_seqno = reply->seqno; - owner = wine_server_ptr_handle( reply->owner ); - } - SERVER_END_REQ; + struct set_clipboard_params set_params = { .cache_only = TRUE, .seqno = params.seqno }; - if (!status && size) - { - data = cache_data( format, data, size, data_seqno, cache ); - LeaveCriticalSection( &clipboard_cs ); - TRACE( "%s returning %p\n", debugstr_format( format ), data ); - return data; - } - LeaveCriticalSection( &clipboard_cs ); - GlobalFree( data ); + ret = unmarshal_data( format, params.data, params.size ); + if (!NtUserSetClipboardData( format, ret, &set_params )) break; - if (status == STATUS_BUFFER_OVERFLOW) continue; /* retry with the new size */ - if (status == STATUS_OBJECT_NAME_NOT_FOUND) return 0; /* no such format */ - if (status) - { - SetLastError( RtlNtStatusToDosError( status )); - TRACE( "%s error %08x\n", debugstr_format( format ), status ); - return 0; + /* data changed, retry */ + free_cached_data( format, ret ); + ret = 0; + params.data_size = 1024; + continue; } - if (render) /* try rendering it */ - { - render = FALSE; - if (from) - { - render_synthesized_format( format, from ); - continue; - } - else if (owner) - { - TRACE( "%s sending WM_RENDERFORMAT to %p\n", debugstr_format( format ), owner ); - SendMessageW( owner, WM_RENDERFORMAT, format, 0 ); - continue; - } - } - TRACE( "%s returning 0\n", debugstr_format( format )); - return 0; + GlobalFree( params.data ); } + + LeaveCriticalSection( &clipboard_cs ); + return ret; } diff --git a/dlls/user32/edit.c b/dlls/user32/edit.c index 242ef4abeb2..f15c4c8e550 100644 --- a/dlls/user32/edit.c +++ b/dlls/user32/edit.c @@ -3134,7 +3134,7 @@ static void EDIT_WM_Copy(EDITSTATE *es) TRACE("%s\n", debugstr_w(dst)); GlobalUnlock(hdst); OpenClipboard(es->hwndSelf); - EmptyClipboard(); + NtUserEmptyClipboard(); SetClipboardData(CF_UNICODETEXT, hdst); NtUserCloseClipboard(); } diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec index a7b2f7e0681..ec078cc7609 100644 --- a/dlls/user32/user32.spec +++ b/dlls/user32/user32.spec @@ -202,7 +202,7 @@ @ stdcall DrawTextExW(long wstr long ptr long ptr) @ stdcall DrawTextW(long wstr long ptr long) @ stdcall EditWndProc(long long long long) EditWndProcA -@ stdcall EmptyClipboard() +@ stdcall EmptyClipboard() NtUserEmptyClipboard @ stdcall EnableMenuItem(long long long) NtUserEnableMenuItem @ stdcall EnableMouseInPointer(long) @ stdcall EnableNonClientDpiScaling(long) diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c index 08f2833ee3f..85e22525d80 100644 --- a/dlls/user32/user_main.c +++ b/dlls/user32/user_main.c @@ -184,6 +184,20 @@ static const struct user_callbacks user_funcs = unregister_imm, }; +static NTSTATUS WINAPI User32FreeCachedClipboardData( const struct free_cached_data_params *params, + ULONG size ) +{ + free_cached_data( params->format, params->handle ); + return 0; +} + +static NTSTATUS WINAPI User32RenderSsynthesizedFormat( const struct render_synthesized_format_params *params, + ULONG size ) +{ + render_synthesized_format( params->format, params->from ); + return 0; +} + static BOOL WINAPI User32LoadDriver( const WCHAR *path, ULONG size ) { return LoadLibraryW( path ) != NULL; @@ -196,7 +210,9 @@ static const void *kernel_callback_table[NtUserCallCount] = User32CallWinEventHook, User32CallWindowProc, User32CallWindowsHook, + User32FreeCachedClipboardData, User32LoadDriver, + User32RenderSsynthesizedFormat, }; diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 54b11f2a8ef..b01c5b8bfda 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -82,6 +82,8 @@ extern BOOL process_rawinput_message( MSG *msg, UINT hw_id, const struct hardware_msg_data *msg_data ) DECLSPEC_HIDDEN; extern BOOL unpack_dde_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lparam, void **buffer, size_t size ) DECLSPEC_HIDDEN; +extern void free_cached_data( UINT format, HANDLE handle ) DECLSPEC_HIDDEN; +extern HANDLE render_synthesized_format( UINT format, UINT from ) DECLSPEC_HIDDEN; extern void CLIPBOARD_ReleaseOwner( HWND hwnd ) DECLSPEC_HIDDEN; extern BOOL FOCUS_MouseActivate( HWND hwnd ) DECLSPEC_HIDDEN; diff --git a/dlls/win32u/clipboard.c b/dlls/win32u/clipboard.c index d338f27dcc8..63306702b1c 100644 --- a/dlls/win32u/clipboard.c +++ b/dlls/win32u/clipboard.c @@ -27,6 +27,9 @@ #pragma makedep unix #endif +#include +#include "ntstatus.h" +#define WIN32_NO_STATUS #include "win32u_private.h" #include "ntuser_private.h" #include "wine/server.h" @@ -34,6 +37,19 @@ WINE_DEFAULT_DEBUG_CHANNEL(clipboard); +static pthread_mutex_t clipboard_mutex = PTHREAD_MUTEX_INITIALIZER; + +struct cached_format +{ + struct list entry; /* entry in cache list */ + UINT format; /* format id */ + UINT seqno; /* sequence number when the data was set */ + HANDLE handle; /* original data handle */ +}; + +static struct list cached_formats = LIST_INIT( cached_formats ); +static struct list formats_to_free = LIST_INIT( formats_to_free ); + /* get a debug string for a format id */ static const char *debugstr_format( UINT id ) @@ -76,13 +92,106 @@ static const char *debugstr_format( UINT id ) } } +/* retrieve a data format from the cache */ +static struct cached_format *get_cached_format( UINT format ) +{ + struct cached_format *cache; + + LIST_FOR_EACH_ENTRY( cache, &cached_formats, struct cached_format, entry ) + if (cache->format == format) return cache; + return NULL; +} + +/* free a single cached format */ +static void free_cached_data( struct cached_format *cache ) +{ + struct free_cached_data_params params; + void *ret_ptr; + ULONG ret_len; + + switch (cache->format) + { + case CF_BITMAP: + case CF_DSPBITMAP: + case CF_PALETTE: + NtGdiDeleteObjectApp( cache->handle ); + break; + + default: + params.format = cache->format; + params.handle = cache->handle; + KeUserModeCallback( NtUserFreeCachedClipboardData, ¶ms, sizeof(params), + &ret_ptr, &ret_len ); + break; + } + free( cache ); +} + +/* free all the data in the cache */ +static void free_cached_formats( struct list *list ) +{ + struct list *ptr; + + while ((ptr = list_head( list ))) + { + list_remove( ptr ); + free_cached_data( LIST_ENTRY( ptr, struct cached_format, entry )); + } +} + +/* clear global memory formats; special types are freed on EmptyClipboard */ +static void invalidate_memory_formats( struct list *free_list ) +{ + struct cached_format *cache, *next; + + LIST_FOR_EACH_ENTRY_SAFE( cache, next, &cached_formats, struct cached_format, entry ) + { + switch (cache->format) + { + case CF_BITMAP: + case CF_DSPBITMAP: + case CF_PALETTE: + case CF_ENHMETAFILE: + case CF_DSPENHMETAFILE: + case CF_METAFILEPICT: + case CF_DSPMETAFILEPICT: + continue; + default: + list_remove( &cache->entry ); + list_add_tail( free_list, &cache->entry ); + break; + } + } +} + /************************************************************************** * NtUserOpenClipboard (win32u.@) */ BOOL WINAPI NtUserOpenClipboard( HWND hwnd, ULONG unk ) { - FIXME( "\n" ); - return FALSE; + struct list free_list = LIST_INIT( free_list ); + BOOL ret; + HWND owner; + + TRACE( "%p\n", hwnd ); + + user_driver->pUpdateClipboard(); + + pthread_mutex_lock( &clipboard_mutex ); + + SERVER_START_REQ( open_clipboard ) + { + req->window = wine_server_user_handle( hwnd ); + ret = !wine_server_call_err( req ); + owner = wine_server_ptr_handle( reply->owner ); + } + SERVER_END_REQ; + + if (ret && !is_current_process_window( owner )) invalidate_memory_formats( &free_list ); + + pthread_mutex_unlock( &clipboard_mutex ); + free_cached_formats( &free_list ); + return ret; } /************************************************************************** @@ -115,8 +224,32 @@ BOOL WINAPI NtUserCloseClipboard(void) */ BOOL WINAPI NtUserEmptyClipboard(void) { - FIXME( "\n" ); - return FALSE; + BOOL ret; + HWND owner = NtUserGetClipboardOwner(); + struct list free_list = LIST_INIT( free_list ); + + TRACE( "owner %p\n", owner ); + + if (owner) send_message_timeout( owner, WM_DESTROYCLIPBOARD, 0, 0, SMTO_ABORTIFHUNG, + 5000, NULL, FALSE ); + + pthread_mutex_lock( &clipboard_mutex ); + + SERVER_START_REQ( empty_clipboard ) + { + ret = !wine_server_call_err( req ); + } + SERVER_END_REQ; + + if (ret) + { + list_move_tail( &free_list, &formats_to_free ); + list_move_tail( &free_list, &cached_formats ); + } + + pthread_mutex_unlock( &clipboard_mutex ); + free_cached_formats( &free_list ); + return ret; } /************************************************************************** @@ -432,10 +565,65 @@ void release_clipboard_owner( HWND hwnd ) /************************************************************************** * NtUserSetClipboardData (win32u.@) */ -NTSTATUS WINAPI NtUserSetClipboardData( UINT format, HANDLE handle, struct set_clipboard_params *params ) +NTSTATUS WINAPI NtUserSetClipboardData( UINT format, HANDLE data, struct set_clipboard_params *params ) { - FIXME( "\n" ); - return 0; + struct cached_format *cache = NULL, *prev = NULL; + void *ptr = NULL; + data_size_t size = 0; + NTSTATUS status = STATUS_SUCCESS; + + TRACE( "%s %p\n", debugstr_format( format ), data ); + + if (params->cache_only) + { + pthread_mutex_lock( &clipboard_mutex ); + if ((cache = get_cached_format( format )) && cache->seqno == params->seqno) + cache->handle = data; + else + status = STATUS_UNSUCCESSFUL; + pthread_mutex_unlock( &clipboard_mutex ); + return status; + } + + if (params->data) + { + ptr = params->data; + size = params->size; + if (data) + { + if (!(cache = malloc( sizeof(*cache) ))) goto done; + cache->format = format; + cache->handle = data; + } + } + + pthread_mutex_lock( &clipboard_mutex ); + + SERVER_START_REQ( set_clipboard_data ) + { + req->format = format; + NtQueryDefaultLocale( TRUE, &req->lcid ); + wine_server_add_data( req, ptr, size ); + if (!(status = wine_server_call( req ))) + { + if (cache) cache->seqno = reply->seqno; + } + } + SERVER_END_REQ; + + if (!status) + { + /* free the previous entry if any */ + if ((prev = get_cached_format( format ))) list_remove( &prev->entry ); + if (cache) list_add_tail( &cached_formats, &cache->entry ); + } + else free( cache ); + + pthread_mutex_unlock( &clipboard_mutex ); + if (prev) free_cached_data( prev ); + +done: + return status; } /************************************************************************** @@ -443,6 +631,102 @@ NTSTATUS WINAPI NtUserSetClipboardData( UINT format, HANDLE handle, struct set_c */ HANDLE WINAPI NtUserGetClipboardData( UINT format, struct get_clipboard_params *params ) { - FIXME( "\n" ); - return 0; + struct cached_format *cache; + NTSTATUS status; + UINT from, data_seqno; + size_t size; + HWND owner; + BOOL render = TRUE; + + for (;;) + { + pthread_mutex_lock( &clipboard_mutex ); + + cache = get_cached_format( format ); + + SERVER_START_REQ( get_clipboard_data ) + { + req->format = format; + req->render = render; + if (cache && cache->handle) + { + req->cached = 1; + req->seqno = cache->seqno; + } + wine_server_set_reply( req, params->data, params->size ); + status = wine_server_call( req ); + from = reply->from; + size = reply->total; + data_seqno = reply->seqno; + owner = wine_server_ptr_handle( reply->owner ); + } + SERVER_END_REQ; + + if (!status && size) + { + if (cache) + { + if (cache->handle && data_seqno == cache->seqno) /* we can reuse the cached data */ + { + HANDLE ret = cache->handle; + pthread_mutex_unlock( &clipboard_mutex ); + TRACE( "%s returning %p\n", debugstr_format( format ), ret ); + return ret; + } + + /* cache entry is stale, remove it */ + list_remove( &cache->entry ); + list_add_tail( &formats_to_free, &cache->entry ); + } + + /* allocate new cache entry */ + if (!(cache = malloc( sizeof(*cache) ))) return 0; + + cache->format = format; + cache->seqno = data_seqno; + cache->handle = NULL; + params->seqno = cache->seqno; + list_add_tail( &cached_formats, &cache->entry ); + pthread_mutex_unlock( &clipboard_mutex ); + TRACE( "%s needs unmarshaling\n", debugstr_format( format ) ); + params->data_size = ~0; + params->size = size; + return 0; + } + pthread_mutex_unlock( &clipboard_mutex ); + + if (status == STATUS_BUFFER_OVERFLOW) + { + params->data_size = size; + return 0; + } + if (status == STATUS_OBJECT_NAME_NOT_FOUND) return 0; /* no such format */ + if (status) + { + SetLastError( RtlNtStatusToDosError( status )); + TRACE( "%s error %08x\n", debugstr_format( format ), status ); + return 0; + } + if (render) /* try rendering it */ + { + render = FALSE; + if (from) + { + struct render_synthesized_format_params params = { .format = format, .from = from }; + ULONG ret_len; + void *ret_ptr; + KeUserModeCallback( NtUserRenderSynthesizedFormat, ¶ms, sizeof(params), + &ret_ptr, &ret_len ); + continue; + } + if (owner) + { + TRACE( "%s sending WM_RENDERFORMAT to %p\n", debugstr_format( format ), owner ); + send_message( owner, WM_RENDERFORMAT, format, 0 ); + continue; + } + } + TRACE( "%s returning 0\n", debugstr_format( format )); + return 0; + } } diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 3b380c017e5..6ec92552df1 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -4671,10 +4671,6 @@ ULONG_PTR WINAPI NtUserCallNoParam( ULONG code ) thread_detach(); return 0; - case NtUserUpdateClipboard: - user_driver->pUpdateClipboard(); - return 0; - default: FIXME( "invalid code %u\n", code ); return 0; diff --git a/include/ntuser.h b/include/ntuser.h index 75c44372f24..0a833d467b3 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -32,7 +32,9 @@ enum NtUserCallWinEventHook, NtUserCallWinProc, NtUserCallWindowsHook, + NtUserFreeCachedClipboardData, NtUserLoadDriver, + NtUserRenderSynthesizedFormat, /* win16 hooks */ NtUserCallFreeIcon, NtUserThunkLock, @@ -140,6 +142,20 @@ struct win_hook_params WCHAR module[MAX_PATH]; }; +/* NtUserFreeCachedClipboardData params */ +struct free_cached_data_params +{ + UINT format; + HANDLE handle; +}; + +/* NtUserRenderSynthesizedFormat params */ +struct render_synthesized_format_params +{ + UINT format; + UINT from; +}; + /* process DPI awareness contexts */ #define NTUSER_DPI_UNAWARE 0x00006010 #define NTUSER_DPI_SYSTEM_AWARE 0x00006011 @@ -237,11 +253,19 @@ struct client_menu_name /* NtUserGetClipboardData params, not compatible with Windows */ struct get_clipboard_params { + void *data; + size_t size; + size_t data_size; + UINT seqno; }; /* NtUserSetClipboardData params, not compatible with Windows */ struct set_clipboard_params { + void *data; + size_t size; + BOOL cache_only; + UINT seqno; }; /* internal messages codes */ @@ -624,7 +648,6 @@ enum /* temporary exports */ NtUserExitingThread, NtUserThreadDetach, - NtUserUpdateClipboard, }; static inline HWND NtUserGetDesktopWindow(void)