2 * WIN32 clipboard implementation
4 * Copyright 1994 Martin Ayotte
5 * Copyright 1996 Alex Korobka
6 * Copyright 1999 Noel Borthwick
7 * Copyright 2003 Ulrich Czekalla for CodeWeavers
8 * Copyright 2016 Alexandre Julliard
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
30 #include "win32u_private.h"
31 #include "wine/server.h"
32 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(clipboard
);
37 /* get a debug string for a format id */
38 static const char *debugstr_format( UINT id
)
41 DWORD le
= GetLastError();
42 BOOL r
= NtUserGetClipboardFormatName( id
, buffer
, ARRAYSIZE(buffer
) );
46 return wine_dbg_sprintf( "%04x %s", id
, debugstr_w(buffer
) );
50 #define BUILTIN(id) case id: return #id;
53 BUILTIN(CF_METAFILEPICT
)
63 BUILTIN(CF_UNICODETEXT
)
64 BUILTIN(CF_ENHMETAFILE
)
68 BUILTIN(CF_OWNERDISPLAY
)
71 BUILTIN(CF_DSPMETAFILEPICT
)
72 BUILTIN(CF_DSPENHMETAFILE
)
74 default: return wine_dbg_sprintf( "%04x", id
);
78 /**************************************************************************
79 * NtUserCountClipboardFormats (win32u.@)
81 INT WINAPI
NtUserCountClipboardFormats(void)
85 user_driver
->pUpdateClipboard();
87 SERVER_START_REQ( get_clipboard_formats
)
89 wine_server_call( req
);
94 TRACE( "returning %d\n", count
);
98 /**************************************************************************
99 * NtUserIsClipboardFormatAvailable (win32u.@)
101 BOOL WINAPI
NtUserIsClipboardFormatAvailable( UINT format
)
105 if (!format
) return FALSE
;
107 user_driver
->pUpdateClipboard();
109 SERVER_START_REQ( get_clipboard_formats
)
111 req
->format
= format
;
112 if (!wine_server_call_err( req
)) ret
= (reply
->count
> 0);
115 TRACE( "%s -> %u\n", debugstr_format( format
), ret
);
119 /**************************************************************************
120 * NtUserGetUpdatedClipboardFormats (win32u.@)
122 BOOL WINAPI
NtUserGetUpdatedClipboardFormats( UINT
*formats
, UINT size
, UINT
*out_size
)
128 SetLastError( ERROR_NOACCESS
);
132 user_driver
->pUpdateClipboard();
134 SERVER_START_REQ( get_clipboard_formats
)
136 if (formats
) wine_server_set_reply( req
, formats
, size
* sizeof(*formats
) );
137 ret
= !wine_server_call_err( req
);
138 *out_size
= reply
->count
;
142 TRACE( "%p %u returning %u formats, ret %u\n", formats
, size
, *out_size
, ret
);
143 if (!ret
&& !formats
&& *out_size
) SetLastError( ERROR_NOACCESS
);
147 /**************************************************************************
148 * NtUserGetPriorityClipboardFormat (win32u.@)
150 INT WINAPI
NtUserGetPriorityClipboardFormat( UINT
*list
, INT count
)
154 TRACE( "%p %u\n", list
, count
);
156 if (NtUserCountClipboardFormats() == 0)
159 for (i
= 0; i
< count
; i
++)
160 if (NtUserIsClipboardFormatAvailable( list
[i
] ))
166 /**************************************************************************
167 * NtUserGetClipboardFormatName (win32u.@)
169 INT WINAPI
NtUserGetClipboardFormatName( UINT format
, WCHAR
*buffer
, INT maxlen
)
171 char buf
[sizeof(ATOM_BASIC_INFORMATION
) + 255 * sizeof(WCHAR
)];
172 ATOM_BASIC_INFORMATION
*abi
= (ATOM_BASIC_INFORMATION
*)buf
;
175 if (format
< MAXINTATOM
|| format
> 0xffff) return 0;
178 SetLastError( ERROR_MORE_DATA
);
181 if (!set_ntstatus( NtQueryInformationAtom( format
, AtomBasicInformation
,
182 buf
, sizeof(buf
), NULL
)))
185 length
= min( abi
->NameLength
/ sizeof(WCHAR
), maxlen
- 1 );
186 if (length
) memcpy( buffer
, abi
->Name
, length
* sizeof(WCHAR
) );
191 /**************************************************************************
192 * NtUserGetClipboardOwner (win32u.@)
194 HWND WINAPI
NtUserGetClipboardOwner(void)
198 SERVER_START_REQ( get_clipboard_info
)
200 if (!wine_server_call_err( req
)) owner
= wine_server_ptr_handle( reply
->owner
);
204 TRACE( "returning %p\n", owner
);
208 /**************************************************************************
209 * NtUserGetClipboardViewer (win32u.@)
211 HWND WINAPI
NtUserGetClipboardViewer(void)
215 SERVER_START_REQ( get_clipboard_info
)
217 if (!wine_server_call_err( req
)) viewer
= wine_server_ptr_handle( reply
->viewer
);
221 TRACE( "returning %p\n", viewer
);
225 /**************************************************************************
226 * NtUserGetOpenClipboardWindow (win32u.@)
228 HWND WINAPI
NtUserGetOpenClipboardWindow(void)
232 SERVER_START_REQ( get_clipboard_info
)
234 if (!wine_server_call_err( req
)) window
= wine_server_ptr_handle( reply
->window
);
238 TRACE( "returning %p\n", window
);
242 /**************************************************************************
243 * NtUserGetClipboardSequenceNumber (win32u.@)
245 DWORD WINAPI
NtUserGetClipboardSequenceNumber(void)
249 SERVER_START_REQ( get_clipboard_info
)
251 if (!wine_server_call_err( req
)) seqno
= reply
->seqno
;
255 TRACE( "returning %u\n", seqno
);
259 /**************************************************************************
260 * NtUserAddClipboardFormatListener (win32u.@)
262 BOOL WINAPI
NtUserAddClipboardFormatListener( HWND hwnd
)
266 SERVER_START_REQ( add_clipboard_listener
)
268 req
->window
= wine_server_user_handle( hwnd
);
269 ret
= !wine_server_call_err( req
);
275 /**************************************************************************
276 * NtUserRemoveClipboardFormatListener (win32u.@)
278 BOOL WINAPI
NtUserRemoveClipboardFormatListener( HWND hwnd
)
282 SERVER_START_REQ( remove_clipboard_listener
)
284 req
->window
= wine_server_user_handle( hwnd
);
285 ret
= !wine_server_call_err( req
);