Add a test case for clipboard functionality and fix some bugs revealed
by it.
This commit is contained in:
parent
0377462460
commit
b3569e7015
|
@ -1,5 +1,6 @@
|
|||
Makefile
|
||||
class.ok
|
||||
clipboard.ok
|
||||
dde.ok
|
||||
dialog.ok
|
||||
generated.ok
|
||||
|
|
|
@ -7,6 +7,7 @@ IMPORTS = user32 gdi32 advapi32
|
|||
|
||||
CTESTS = \
|
||||
class.c \
|
||||
clipboard.c \
|
||||
dde.c \
|
||||
dialog.c \
|
||||
generated.c \
|
||||
|
|
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
* Unit test suite for clipboard functions.
|
||||
*
|
||||
* Copyright 2002 Dmitry Timoshkov
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "winuser.h"
|
||||
|
||||
static BOOL is_win9x = FALSE;
|
||||
|
||||
#define test_last_error(expected_error) \
|
||||
do \
|
||||
{ \
|
||||
if (!is_win9x) \
|
||||
ok(GetLastError() == expected_error, \
|
||||
"Last error should be set to %d, not %ld\n", \
|
||||
expected_error, GetLastError()); \
|
||||
} while (0)
|
||||
|
||||
static void test_ClipboardOwner(void)
|
||||
{
|
||||
HWND hWnd1, hWnd2;
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef,
|
||||
"could not perform clipboard test: clipboard already owned\n");
|
||||
|
||||
hWnd1 = CreateWindowExA(0, "static", NULL, WS_POPUP,
|
||||
0, 0, 10, 10, 0, 0, 0, NULL);
|
||||
ok(hWnd1 != 0, "CreateWindowExA error %ld\n", GetLastError());
|
||||
trace("hWnd1 = %p\n", hWnd1);
|
||||
|
||||
hWnd2 = CreateWindowExA(0, "static", NULL, WS_POPUP,
|
||||
0, 0, 10, 10, 0, 0, 0, NULL);
|
||||
ok(hWnd2 != 0, "CreateWindowExA error %ld\n", GetLastError());
|
||||
trace("hWnd2 = %p\n", hWnd2);
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ok(!CloseClipboard(), "CloseClipboard should fail if clipboard wasn't open\n");
|
||||
test_last_error(ERROR_CLIPBOARD_NOT_OPEN);
|
||||
|
||||
ok(OpenClipboard(0), "OpenClipboard failed\n");
|
||||
ok(!GetClipboardOwner(), "clipboard should still be not owned\n");
|
||||
ok(!OpenClipboard(hWnd1), "OpenClipboard should fail since clipboard already opened\n");
|
||||
ok(CloseClipboard(), "CloseClipboard error %ld\n", GetLastError());
|
||||
|
||||
ok(OpenClipboard(hWnd1), "OpenClipboard failed\n");
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ok(!OpenClipboard(hWnd2) && GetLastError() == 0xdeadbeef,
|
||||
"OpenClipboard should fail without setting last error value\n");
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef, "clipboard should still be not owned\n");
|
||||
ok(EmptyClipboard(), "EmptyClipboard error %ld\n", GetLastError());
|
||||
ok(GetClipboardOwner() == hWnd1, "clipboard should be owned by %p, not by %p\n", hWnd1, GetClipboardOwner());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ok(!OpenClipboard(hWnd2) && GetLastError() == 0xdeadbeef,
|
||||
"OpenClipboard should fail without setting last error value\n");
|
||||
|
||||
ok(CloseClipboard(), "CloseClipboard error %ld", GetLastError());
|
||||
ok(GetClipboardOwner() == hWnd1, "clipboard should still be owned\n");
|
||||
|
||||
ok(DestroyWindow(hWnd1), "DestroyWindow error %ld\n", GetLastError());
|
||||
ok(DestroyWindow(hWnd2), "DestroyWindow error %ld\n", GetLastError());
|
||||
SetLastError(0xdeadbeef);
|
||||
ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef, "clipboard should not be owned\n");
|
||||
}
|
||||
|
||||
static void test_RegisterClipboardFormatA(void)
|
||||
{
|
||||
ATOM atom_id;
|
||||
UINT format_id, format_id2;
|
||||
char buf[256];
|
||||
int len;
|
||||
|
||||
format_id = RegisterClipboardFormatA("my_cool_clipboard_format");
|
||||
ok(format_id > 0xc000 && format_id < 0xffff, "invalid clipboard format id %04x\n", format_id);
|
||||
|
||||
format_id2 = RegisterClipboardFormatA("MY_COOL_CLIPBOARD_FORMAT");
|
||||
ok(format_id2 == format_id, "invalid clipboard format id %04x\n", format_id2);
|
||||
|
||||
len = GetClipboardFormatNameA(format_id, buf, 256);
|
||||
ok(len == lstrlenA("my_cool_clipboard_format"), "wrong format name length %d\n", len);
|
||||
ok(!lstrcmpA(buf, "my_cool_clipboard_format"), "wrong format name \"%s\"\n", buf);
|
||||
|
||||
lstrcpyA(buf, "foo");
|
||||
SetLastError(0xdeadbeef);
|
||||
len = GetAtomNameA((ATOM)format_id, buf, 256);
|
||||
ok(len == 0, "GetAtomNameA should fail\n");
|
||||
test_last_error(ERROR_INVALID_HANDLE);
|
||||
|
||||
todo_wine
|
||||
{
|
||||
lstrcpyA(buf, "foo");
|
||||
SetLastError(0xdeadbeef);
|
||||
len = GlobalGetAtomNameA((ATOM)format_id, buf, 256);
|
||||
ok(len == 0, "GlobalGetAtomNameA should fail\n");
|
||||
test_last_error(ERROR_INVALID_HANDLE);
|
||||
}
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
atom_id = FindAtomA("my_cool_clipboard_format");
|
||||
ok(atom_id == 0, "FindAtomA should fail\n");
|
||||
test_last_error(ERROR_FILE_NOT_FOUND);
|
||||
|
||||
#if 0
|
||||
/* this relies on the clipboard and global atom table being different */
|
||||
SetLastError(0xdeadbeef);
|
||||
atom_id = GlobalFindAtomA("my_cool_clipboard_format");
|
||||
ok(atom_id == 0, "GlobalFindAtomA should fail\n");
|
||||
test_last_error(ERROR_FILE_NOT_FOUND);
|
||||
|
||||
for (format_id = 0; format_id < 0xffff; format_id++)
|
||||
{
|
||||
SetLastError(0xdeadbeef);
|
||||
len = GetClipboardFormatNameA(format_id, buf, 256);
|
||||
|
||||
if (format_id < 0xc000)
|
||||
{
|
||||
ok(!len, "GetClipboardFormatNameA should fail, but it returned %d (%s)\n", len, buf);
|
||||
test_last_error(ERROR_INVALID_PARAMETER);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (len)
|
||||
trace("%04x: %s\n", format_id, len ? buf : "");
|
||||
else
|
||||
test_last_error(ERROR_INVALID_HANDLE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ok(OpenClipboard(0), "OpenClipboard error %ld\n", GetLastError());
|
||||
|
||||
trace("# of formats available: %d\n", CountClipboardFormats());
|
||||
|
||||
format_id = 0;
|
||||
while ((format_id = EnumClipboardFormats(format_id)))
|
||||
{
|
||||
ok(IsClipboardFormatAvailable(format_id), "format %04x was listed as available\n", format_id);
|
||||
len = GetClipboardFormatNameA(format_id, buf, 256);
|
||||
trace("%04x: %s\n", format_id, len ? buf : "");
|
||||
}
|
||||
|
||||
ok(EmptyClipboard(), "EmptyClipboard error %ld\n", GetLastError());
|
||||
ok(CloseClipboard(), "CloseClipboard error %ld\n", GetLastError());
|
||||
|
||||
if (CountClipboardFormats())
|
||||
{
|
||||
SetLastError(0xdeadbeef);
|
||||
ok(!EnumClipboardFormats(0), "EnumClipboardFormats should fail if clipboard wasn't open\n");
|
||||
ok(GetLastError() == ERROR_CLIPBOARD_NOT_OPEN,
|
||||
"Last error should be set to ERROR_CLIPBOARD_NOT_OPEN, not %ld\n", GetLastError());
|
||||
}
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ok(!EmptyClipboard(), "EmptyClipboard should fail if clipboard wasn't open\n");
|
||||
test_last_error(ERROR_CLIPBOARD_NOT_OPEN);
|
||||
}
|
||||
|
||||
START_TEST(clipboard)
|
||||
{
|
||||
SetLastError(0xdeadbeef);
|
||||
FindAtomW(NULL);
|
||||
if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) is_win9x = TRUE;
|
||||
|
||||
test_RegisterClipboardFormatA();
|
||||
test_ClipboardOwner();
|
||||
}
|
|
@ -2038,24 +2038,30 @@ INT X11DRV_RegisterClipboardFormat(LPCSTR FormatName)
|
|||
*/
|
||||
INT X11DRV_GetClipboardFormatName(UINT wFormat, LPSTR retStr, INT maxlen)
|
||||
{
|
||||
INT len = 0;
|
||||
LPWINE_CLIPFORMAT lpFormat = X11DRV_CLIPBOARD_LookupFormat(wFormat);
|
||||
INT len;
|
||||
LPWINE_CLIPFORMAT lpFormat;
|
||||
|
||||
TRACE("(%04X, %p, %d) !\n", wFormat, retStr, maxlen);
|
||||
|
||||
if (wFormat < 0xc000)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
lpFormat = X11DRV_CLIPBOARD_LookupFormat(wFormat);
|
||||
|
||||
if (!lpFormat || (lpFormat->wFlags & CF_FLAG_BUILTINFMT))
|
||||
{
|
||||
TRACE("Unknown format 0x%08x!\n", wFormat);
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(retStr, lpFormat->Name, maxlen - 1);
|
||||
retStr[maxlen - 1] = 0;
|
||||
|
||||
len = strlen(retStr);
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
strncpy(retStr, lpFormat->Name, maxlen - 1);
|
||||
retStr[maxlen - 1] = 0;
|
||||
|
||||
len = strlen(retStr);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
|
|
@ -80,26 +80,22 @@ static int set_clipboard_window(user_handle_t win, int clear)
|
|||
|
||||
static int set_clipboard_owner(user_handle_t win, int clear)
|
||||
{
|
||||
if (cbthread == current)
|
||||
{
|
||||
if (!clear)
|
||||
{
|
||||
cbowner = current;
|
||||
owner = win;
|
||||
}
|
||||
else
|
||||
{
|
||||
cbowner = 0;
|
||||
owner = 0;
|
||||
}
|
||||
seqno++;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
if (cbowner && cbowner != current)
|
||||
{
|
||||
set_error(STATUS_WAS_LOCKED);
|
||||
return 0;
|
||||
}
|
||||
else if (!clear)
|
||||
{
|
||||
owner = win;
|
||||
cbowner = current;
|
||||
}
|
||||
else
|
||||
{
|
||||
owner = 0;
|
||||
cbowner = NULL;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -124,11 +120,24 @@ DECL_HANDLER(set_clipboard_info)
|
|||
|
||||
if (req->flags & SET_CB_OPEN)
|
||||
{
|
||||
if (cbthread)
|
||||
{
|
||||
/* clipboard already opened */
|
||||
set_error(STATUS_WAS_LOCKED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!set_clipboard_window(req->clipboard, 0))
|
||||
return;
|
||||
}
|
||||
else if (req->flags & SET_CB_CLOSE)
|
||||
{
|
||||
if (cbthread != current)
|
||||
{
|
||||
set_win32_error(ERROR_CLIPBOARD_NOT_OPEN);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!set_clipboard_window(0, 1))
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ BOOL CLIPBOARD_SetClipboardOwner(HWND hWnd)
|
|||
|
||||
if (wine_server_call_err( req ))
|
||||
{
|
||||
ERR("Failed to set clipboard.\n");
|
||||
ERR("Failed to set clipboard owner to %p\n", hWnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -117,7 +117,7 @@ static BOOL CLIPBOARD_GetClipboardInfo(LPCLIPBOARDINFO cbInfo)
|
|||
|
||||
if (wine_server_call_err( req ))
|
||||
{
|
||||
ERR("Failed to get clipboard owner.\n");
|
||||
ERR("Failed to get clipboard info\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -174,14 +174,8 @@ static BOOL CLIPBOARD_OpenClipboard(HWND hWnd)
|
|||
req->flags = SET_CB_OPEN;
|
||||
req->clipboard = WIN_GetFullHandle( hWnd );
|
||||
|
||||
if (wine_server_call_err( req ))
|
||||
{
|
||||
ERR("Failed to set clipboard.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!wine_server_call( req ))
|
||||
bRet = TRUE;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
|
@ -408,22 +402,20 @@ BOOL WINAPI EmptyClipboard(void)
|
|||
|
||||
/* Tell the driver to acquire the selection. The current owner
|
||||
* will be signaled to delete it's own cache. */
|
||||
if (~cbinfo.flags & CB_OWNER)
|
||||
{
|
||||
/* Assign ownership of the clipboard to the current client. We do
|
||||
* this before acquiring the selection so that when we do acquire the
|
||||
* selection and the selection loser gets notified, it can check if
|
||||
* it has lost the Wine clipboard ownership. If it did then it knows
|
||||
* that a WM_DESTORYCLIPBOARD has already been sent. Otherwise it
|
||||
* lost the selection to a X app and it should send the
|
||||
* WM_DESTROYCLIPBOARD itself. */
|
||||
CLIPBOARD_SetClipboardOwner(cbinfo.hWndOpen);
|
||||
|
||||
/* Acquire the selection. This will notify the previous owner
|
||||
* to clear it's cache. */
|
||||
if (USER_Driver.pAcquireClipboard)
|
||||
USER_Driver.pAcquireClipboard(cbinfo.hWndOpen);
|
||||
}
|
||||
/* Assign ownership of the clipboard to the current client. We do
|
||||
* this before acquiring the selection so that when we do acquire the
|
||||
* selection and the selection loser gets notified, it can check if
|
||||
* it has lost the Wine clipboard ownership. If it did then it knows
|
||||
* that a WM_DESTORYCLIPBOARD has already been sent. Otherwise it
|
||||
* lost the selection to a X app and it should send the
|
||||
* WM_DESTROYCLIPBOARD itself. */
|
||||
CLIPBOARD_SetClipboardOwner(cbinfo.hWndOpen);
|
||||
|
||||
/* Acquire the selection. This will notify the previous owner
|
||||
* to clear it's cache. */
|
||||
if (USER_Driver.pAcquireClipboard)
|
||||
USER_Driver.pAcquireClipboard(cbinfo.hWndOpen);
|
||||
|
||||
/* Empty the local cache */
|
||||
if (USER_Driver.pEmptyClipboard)
|
||||
|
|
Loading…
Reference in New Issue