Commit b3569e70 authored by Dmitry Timoshkov's avatar Dmitry Timoshkov Committed by Alexandre Julliard

Add a test case for clipboard functionality and fix some bugs revealed

by it.
parent 03774624
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 \
......
/*
* 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 (!lpFormat || (lpFormat->wFlags & CF_FLAG_BUILTINFMT))
if (wFormat < 0xc000)
{
TRACE("Unknown format 0x%08x!\n", wFormat);
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
else
{
strncpy(retStr, lpFormat->Name, maxlen - 1);
retStr[maxlen - 1] = 0;
len = strlen(retStr);
lpFormat = X11DRV_CLIPBOARD_LookupFormat(wFormat);
if (!lpFormat || (lpFormat->wFlags & CF_FLAG_BUILTINFMT))
{
TRACE("Unknown format 0x%08x!\n", wFormat);
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 (cbowner && cbowner != current)
{
if (!clear)
{
cbowner = current;
owner = win;
}
else
{
cbowner = 0;
owner = 0;
}
seqno++;
return 1;
set_error(STATUS_WAS_LOCKED);
return 0;
}
else if (!clear)
{
owner = win;
cbowner = current;
}
else
{
set_error(STATUS_WAS_LOCKED);
return 0;
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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment