3#include <winpr/print.h>
4#include <winpr/image.h>
5#include <winpr/clipboard.h>
6#include <winpr/stream.h>
9#define test_log(fmt, ...) test_log_fn(__FILE__, __func__, __LINE__, (fmt), ##__VA_ARGS__)
10static void test_log_fn(
const char* file,
const char* func,
size_t line,
const char* fmt, ...)
17 winpr_vasprintf(&fstr, &fslen, fmt, ap);
18 (void)fprintf(stderr,
"[%" PRIu32
":%s]: %s\n", line, func, fstr);
23#define test_ClipboardSetData(clipboard, formatId, data, size) \
24 test_ClipboardSetDataFn(__FILE__, __func__, __LINE__, (clipboard), (formatId), (data), (size))
25static BOOL test_ClipboardSetDataFn(
const char* file,
const char* func,
size_t line,
26 wClipboard* clipboard, UINT32 formatId,
const void* data,
29 const BOOL rc = ClipboardSetData(clipboard, formatId, data, size);
32 test_log_fn(file, func, line,
"ClipboardSetData %s[0x%04" PRIx32
"][%" PRIu32
"] failed",
33 ClipboardGetFormatName(clipboard, formatId), formatId, size);
38#define test_ClipboardGetData(clipboard, formatId, size) \
39 test_ClipboardGetDataFn(__FILE__, __func__, __LINE__, (clipboard), (formatId), (size))
40static void* test_ClipboardGetDataFn(
const char* file,
const char* func,
size_t line,
41 wClipboard* clipboard, UINT32 formatId, UINT32* pSize)
43 void* rc = ClipboardGetData(clipboard, formatId, pSize);
46 test_log_fn(file, func, line,
"ClipboardGetData %s[0x%04" PRIx32
"] failed",
47 ClipboardGetFormatName(clipboard, formatId), formatId);
53static BOOL test_dib_to_bmp(
const BYTE* dib,
size_t dibSize,
size_t expectedOffset)
57 wClipboard* clipboard = ClipboardCreate();
60 test_log(
"ClipboardCreate failed");
64 const UINT32 bmpId = ClipboardRegisterFormat(clipboard,
"image/bmp");
67 test_log(
"bmpId == 0");
70 if (dibSize > UINT32_MAX)
72 test_log(
"dibSize %" PRIuz
" > UINT32_MAX failed");
75 if (!test_ClipboardSetData(clipboard, CF_DIB, dib, (UINT32)dibSize))
79 BYTE* bmp = test_ClipboardGetData(clipboard, bmpId, &bmpSize);
84 wImage* image = winpr_image_new();
87 test_log(
"winpr_image_new failed");
90 rc = (winpr_image_read_buffer(image, bmp, bmpSize) > 0);
92 test_log(
"winpr_image_read_buffer failed");
93 winpr_image_free(image, TRUE);
98 ClipboardDestroy(clipboard);
102static void write_dib_info_header(
wStream* s, UINT32 size, UINT16 bpp, UINT32 compression)
106 Stream_Write_UINT32(s, size);
107 Stream_Write_INT32(s, 1);
108 Stream_Write_INT32(s, 1);
109 Stream_Write_UINT16(s, 1);
110 Stream_Write_UINT16(s, bpp);
111 Stream_Write_UINT32(s, compression);
112 Stream_Write_UINT32(s, 4);
117static BOOL test_dib_offsets(
void)
120 wStream sbuffer = WINPR_C_ARRAY_INIT;
121 wStream* s = Stream_StaticInit(&sbuffer, v4,
sizeof(v4));
124 write_dib_info_header(s,
sizeof(
BITMAPV4HEADER), 32, BI_BITFIELDS);
126 Stream_Write_UINT32(s, 0x00FF0000);
127 Stream_Write_UINT32(s, 0x0000FF00);
128 Stream_Write_UINT32(s, 0x000000FF);
129 Stream_Write_UINT32(s, 0xFF000000);
131 Stream_Write_UINT32(s, 0xFF123456);
135 BYTE bitfields[
sizeof(
BITMAPINFOHEADER) + 3 *
sizeof(DWORD) + 4] = WINPR_C_ARRAY_INIT;
136 s = Stream_StaticInit(&sbuffer, bitfields,
sizeof(bitfields));
140 Stream_Write_UINT32(s, 0x00FF0000);
141 Stream_Write_UINT32(s, 0x0000FF00);
142 Stream_Write_UINT32(s, 0x000000FF);
143 Stream_Write_UINT32(s, 0xFF123456);
144 if (!test_dib_to_bmp(bitfields,
sizeof(bitfields),
150 s = Stream_StaticInit(&sbuffer, paletted,
sizeof(paletted));
154 Stream_Zero(s, 256 *
sizeof(
RGBQUAD));
155 Stream_Write_UINT32(s, 0);
156 return test_dib_to_bmp(paletted,
sizeof(paletted),
162static BOOL test_text_leading_newline(
void)
164 const char* tests[][2] = { {
"\nfoo",
"\r\nfoo" }, {
"\n",
"\r\n" } };
167 wClipboard* clipboard = ClipboardCreate();
170 test_log(
"ClipboardCreate failed");
174 const UINT32 textId = ClipboardRegisterFormat(clipboard,
"text/plain");
175 for (
size_t x = 0; x < ARRAYSIZE(tests); x++)
177 const char** cur = tests[x];
179 if (!test_ClipboardSetData(clipboard, textId, cur[0], (UINT32)strlen(cur[0])))
183 WCHAR* wstr = test_ClipboardGetData(clipboard, CF_UNICODETEXT, &size);
184 char* str = ConvertWCharNToUtf8Alloc(wstr, size /
sizeof(WCHAR),
nullptr);
185 const BOOL match = str && (strcmp(str, cur[1]) == 0);
188 test_log(
"text/plain to CF_UNICODETEXT failed for case %" PRIuz
"[%s (%" PRIu32
189 ") %p : expect %s (%" PRIuz
") : from %s (" PRIuz
")]",
190 x, str, size, wstr, cur[1], strlen(cur[1]), cur[0], strlen(cur[0]));
200 ClipboardDestroy(clipboard);
205static BOOL test_text_conversion(
void)
207 wClipboard* clipboard = ClipboardCreate();
221 const test_case_t tests[] = {
222 { ClipboardRegisterFormat(clipboard,
"text/plain"),
223 ClipboardRegisterFormat(clipboard,
"text/plain;charset=utf-8"),
"a\nb\rc\\u1234\\u055e",
224 17,
"a\nb\ncሴ՞", 10 },
225 { ClipboardRegisterFormat(clipboard,
"text/plain;charset=utf-8"),
226 ClipboardRegisterFormat(clipboard,
"text/plain"),
"a\r\nb\nc՞՞", 10,
227 "a\r\nb\nc\\u055e\\u055e", 18 },
228 { ClipboardRegisterFormat(clipboard,
"text/plain"), CF_UNICODETEXT,
"a\nb\rc\\u1234\\u055e",
229 17,
"\x61\x00\x0d\x00\x0a\x00\x62\x00\x0d\x0\x0a\x00\x63\x00\x34\x12\x5e\x05\x00\x00\x00",
231 { CF_UNICODETEXT, ClipboardRegisterFormat(clipboard,
"text/plain"),
232 "\x61\x00\x0d\x00\x0a\x00\x62\x00\x0d\x0\x0a\x00\x63\x00\x34\x12\x5e\x05\x00\x00\x00", 18,
233 "a\nb\nc\\u1234\\u055e", 17 },
234 { ClipboardRegisterFormat(clipboard,
"text/plain"), CF_TEXT,
"a\nb\rc\\u1234\\u055e", 17,
235 "a\nb\nc\\u1234\\u055e", 17 },
236 { CF_TEXT, ClipboardRegisterFormat(clipboard,
"text/plain"),
"a\nb\nc\\u1234\\u055e", 17,
237 "a\nb\nc\\u1234\\u055e", 17 },
238 { ClipboardRegisterFormat(clipboard,
"text/plain"), CF_OEMTEXT,
"a\nb\rc\\u1234\\u055e", 17,
239 "a\nb\nc\\u1234\\u055e", 17 },
240 { CF_OEMTEXT, ClipboardRegisterFormat(clipboard,
"text/plain"),
"a\nb\rc\\u1234\\u055e", 17,
241 "a\nb\nc\\u1234\\u055e", 17 }
246 for (
size_t x = 0; x < ARRAYSIZE(tests); x++)
248 const test_case_t* cur = &tests[x];
251 if (!test_ClipboardSetData(clipboard, cur->srcFormat, cur->src, cur->srcLen))
255 BYTE* data = test_ClipboardGetData(clipboard, cur->dstFormat, &dstSize);
256 if (dstSize != cur->expectLen)
258 winpr_znfree(data, dstSize);
265 winpr_znfree(data, dstSize);
268 const int rc = memcmp(cur->expect, data, cur->expectLen);
269 winpr_znfree(data, dstSize);
274 winpr_znfree(data, dstSize);
279 ClipboardDestroy(clipboard);
283int TestClipboardFormats(
int argc,
char* argv[])
287 UINT32* pFormatIds =
nullptr;
288 const char* formatName =
nullptr;
289 UINT32 utf8StringFormatId = 0;
294 if (!test_text_leading_newline())
297 if (!test_text_conversion())
300 wClipboard* clipboard = ClipboardCreate();
304 const char* mime_types[] = {
"text/plain",
"text/plain;charset=utf-8",
305 "text/html",
"image/bmp",
306 "image/png",
"image/webp",
308 for (
size_t x = 0; x < ARRAYSIZE(mime_types); x++)
310 const char* mime = mime_types[x];
311 UINT32
id = ClipboardRegisterFormat(clipboard, mime);
312 test_log(
"ClipboardRegisterFormat(%s) -> 0x%08" PRIx32
"", mime,
id);
317 utf8StringFormatId = ClipboardRegisterFormat(clipboard,
"UTF8_STRING");
318 pFormatIds =
nullptr;
319 count = ClipboardGetRegisteredFormatIds(clipboard, &pFormatIds);
321 for (UINT32 index = 0; index < count; index++)
323 UINT32 formatId = pFormatIds[index];
324 formatName = ClipboardGetFormatName(clipboard, formatId);
325 test_log(
"Format: 0x%08" PRIX32
" %s", formatId, formatName);
332 const char pSrcData[] =
"this is a test string";
333 char* pDstData =
nullptr;
335 UINT32 SrcSize = (UINT32)(strnlen(pSrcData, ARRAYSIZE(pSrcData)) + 1);
336 const BOOL bSuccess =
337 test_ClipboardSetData(clipboard, utf8StringFormatId, pSrcData, SrcSize);
342 pDstData = (
char*)test_ClipboardGetData(clipboard, utf8StringFormatId, &DstSize);
343 const BOOL equal = (SrcSize == DstSize) && (strncmp(pSrcData, pDstData, SrcSize) == 0);
349 WCHAR* pDstData = (WCHAR*)test_ClipboardGetData(clipboard, CF_UNICODETEXT, &WDstSize);
351 size_t cmpSrcSize = 0;
353 ConvertWCharNToUtf8Alloc(pDstData, WDstSize /
sizeof(WCHAR), &cmpSrcSize);
355 (SrcSize == cmpSrcSize + 1ull) && (strncmp(pCmpData, pSrcData, SrcSize) == 0);
363 pFormatIds =
nullptr;
364 count = ClipboardGetFormatIds(clipboard, &pFormatIds);
366 for (UINT32 index = 0; index < count; index++)
368 UINT32 formatId = pFormatIds[index];
369 formatName = ClipboardGetFormatName(clipboard, formatId);
370 test_log(
"Format: 0x%08" PRIX32
" %s", formatId, formatName);
375 const char* name = TEST_CLIP_BMP;
376 BOOL bSuccess = FALSE;
377 UINT32 idBmp = ClipboardRegisterFormat(clipboard,
"image/bmp");
379 wImage* img = winpr_image_new();
383 if (winpr_image_read(img, name) <= 0)
385 winpr_image_free(img, TRUE);
390 void* data = winpr_image_write_buffer(img, WINPR_IMAGE_BITMAP, &bmpsize);
391 bSuccess = test_ClipboardSetData(clipboard, idBmp, data, bmpsize);
394 winpr_image_free(img, TRUE);
402 void* pDstData = test_ClipboardGetData(clipboard,
id, &DstSize);
405 bSuccess = test_ClipboardSetData(clipboard,
id, pDstData, DstSize);
411 const uint32_t
id = ClipboardGetFormatId(clipboard,
"HTML Format");
413 void* pDstData = test_ClipboardGetData(clipboard,
id, &DstSize);
417 FILE* fp = fopen(
"test.html",
"w");
420 (void)fwrite(pDstData, 1, DstSize, fp);
427 UINT32
id = ClipboardRegisterFormat(clipboard,
"image/bmp");
430 void* pDstData = test_ClipboardGetData(clipboard,
id, &DstSize);
434 if (DstSize != bmpsize)
438#if defined(WINPR_UTILS_IMAGE_PNG)
440 UINT32
id = ClipboardRegisterFormat(clipboard,
"image/png");
443 void* pDstData = test_ClipboardGetData(clipboard,
id, &DstSize);
449 const char* name = TEST_CLIP_PNG;
450 BOOL bSuccess = FALSE;
451 UINT32 idBmp = ClipboardRegisterFormat(clipboard,
"image/png");
453 wImage* img = winpr_image_new();
457 if (winpr_image_read(img, name) <= 0)
459 winpr_image_free(img, TRUE);
464 void* data = winpr_image_write_buffer(img, WINPR_IMAGE_PNG, &bmpsize);
465 bSuccess = test_ClipboardSetData(clipboard, idBmp, data, bmpsize);
468 winpr_image_free(img, TRUE);
476 void* pDstData = test_ClipboardGetData(clipboard,
id, &DstSize);
479 bSuccess = test_ClipboardSetData(clipboard,
id, pDstData, DstSize);
486#if defined(WINPR_UTILS_IMAGE_WEBP)
488 UINT32
id = ClipboardRegisterFormat(clipboard,
"image/webp");
491 void* pDstData = test_ClipboardGetData(clipboard,
id, &DstSize);
498#if defined(WINPR_UTILS_IMAGE_JPEG)
500 UINT32
id = ClipboardRegisterFormat(clipboard,
"image/jpeg");
503 void* pDstData = test_ClipboardGetData(clipboard,
id, &DstSize);
511 if (!test_dib_offsets())
518 ClipboardDestroy(clipboard);