FreeRDP
synthetic.c
1 
20 #include <winpr/config.h>
21 
22 #include <errno.h>
23 #include <winpr/crt.h>
24 #include <winpr/user.h>
25 #include <winpr/image.h>
26 
27 #include "../utils/image.h"
28 #include "clipboard.h"
29 
30 static const char* mime_bitmap[] = { "image/bmp", "image/x-bmp", "image/x-MS-bmp",
31  "image/x-win-bitmap" };
32 
33 #if defined(WINPR_UTILS_IMAGE_WEBP)
34 static const char mime_webp[] = "image/webp";
35 #endif
36 #if defined(WINPR_UTILS_IMAGE_PNG)
37 static const char mime_png[] = "image/png";
38 #endif
39 #if defined(WINPR_UTILS_IMAGE_JPEG)
40 static const char mime_jpeg[] = "image/jpeg";
41 #endif
53 static void* clipboard_synthesize_cf_text(wClipboard* clipboard, UINT32 formatId, const void* data,
54  UINT32* pSize)
55 {
56  size_t size = 0;
57  char* pDstData = NULL;
58 
59  if (formatId == CF_UNICODETEXT)
60  {
61  char* str = ConvertWCharNToUtf8Alloc(data, *pSize / sizeof(WCHAR), &size);
62 
63  if (!str || (size > UINT32_MAX))
64  {
65  free(str);
66  return NULL;
67  }
68 
69  pDstData = ConvertLineEndingToCRLF(str, &size);
70  free(str);
71  *pSize = (UINT32)size;
72  return pDstData;
73  }
74  else if ((formatId == CF_TEXT) || (formatId == CF_OEMTEXT) ||
75  (formatId == ClipboardGetFormatId(clipboard, mime_text_plain)))
76  {
77  size = *pSize;
78  pDstData = ConvertLineEndingToCRLF(data, &size);
79 
80  if (!pDstData || (size > *pSize))
81  return NULL;
82 
83  *pSize = (UINT32)size;
84  return pDstData;
85  }
86 
87  return NULL;
88 }
89 
96 static void* clipboard_synthesize_cf_oemtext(wClipboard* clipboard, UINT32 formatId,
97  const void* data, UINT32* pSize)
98 {
99  return clipboard_synthesize_cf_text(clipboard, formatId, data, pSize);
100 }
101 
108 static void* clipboard_synthesize_cf_locale(wClipboard* clipboard, UINT32 formatId,
109  const void* data, UINT32* pSize)
110 {
111  UINT32* pDstData = NULL;
112  pDstData = (UINT32*)malloc(sizeof(UINT32));
113 
114  if (!pDstData)
115  return NULL;
116 
117  *pDstData = 0x0409; /* English - United States */
118  return (void*)pDstData;
119 }
120 
127 static void* clipboard_synthesize_cf_unicodetext(wClipboard* clipboard, UINT32 formatId,
128  const void* data, UINT32* pSize)
129 {
130  size_t size = 0;
131  char* crlfStr = NULL;
132  WCHAR* pDstData = NULL;
133 
134  if ((formatId == CF_TEXT) || (formatId == CF_OEMTEXT) ||
135  (formatId == ClipboardGetFormatId(clipboard, mime_text_plain)))
136  {
137  size_t len = 0;
138  if (!pSize || (*pSize > INT32_MAX))
139  return NULL;
140 
141  size = *pSize;
142  crlfStr = ConvertLineEndingToCRLF((const char*)data, &size);
143 
144  if (!crlfStr)
145  return NULL;
146 
147  pDstData = ConvertUtf8NToWCharAlloc(crlfStr, size, &len);
148  free(crlfStr);
149 
150  if ((len < 1) || ((len + 1) > UINT32_MAX / sizeof(WCHAR)))
151  {
152  free(pDstData);
153  return NULL;
154  }
155 
156  const size_t slen = (len + 1) * sizeof(WCHAR);
157  *pSize = (UINT32)slen;
158  }
159 
160  return (void*)pDstData;
161 }
162 
169 static void* clipboard_synthesize_utf8_string(wClipboard* clipboard, UINT32 formatId,
170  const void* data, UINT32* pSize)
171 {
172  if (formatId == CF_UNICODETEXT)
173  {
174  size_t size = 0;
175  char* pDstData = ConvertWCharNToUtf8Alloc(data, *pSize / sizeof(WCHAR), &size);
176 
177  if (!pDstData)
178  return NULL;
179 
180  const size_t rc = ConvertLineEndingToLF(pDstData, size);
181  WINPR_ASSERT(rc <= UINT32_MAX);
182  *pSize = (UINT32)rc;
183  return pDstData;
184  }
185  else if ((formatId == CF_TEXT) || (formatId == CF_OEMTEXT) ||
186  (formatId == ClipboardGetFormatId(clipboard, mime_text_plain)))
187  {
188  const size_t size = *pSize;
189  char* pDstData = calloc(size + 1, sizeof(char));
190 
191  if (!pDstData)
192  return NULL;
193 
194  CopyMemory(pDstData, data, size);
195  const size_t rc = ConvertLineEndingToLF(pDstData, size);
196  WINPR_ASSERT(rc <= UINT32_MAX);
197  *pSize = (UINT32)rc;
198  return pDstData;
199  }
200 
201  return NULL;
202 }
203 
204 static BOOL is_format_bitmap(wClipboard* clipboard, UINT32 formatId)
205 {
206  for (size_t x = 0; x < ARRAYSIZE(mime_bitmap); x++)
207  {
208  const char* mime = mime_bitmap[x];
209  const UINT32 altFormatId = ClipboardGetFormatId(clipboard, mime);
210  if (altFormatId == formatId)
211  return TRUE;
212  }
213 
214  return FALSE;
215 }
216 
223 static void* clipboard_synthesize_cf_dib(wClipboard* clipboard, UINT32 formatId, const void* data,
224  UINT32* pSize)
225 {
226  UINT32 SrcSize = 0;
227  UINT32 DstSize = 0;
228  BYTE* pDstData = NULL;
229  SrcSize = *pSize;
230 
231  if (formatId == CF_DIBV5)
232  {
233  }
234  else if (is_format_bitmap(clipboard, formatId))
235  {
236  WINPR_BITMAP_FILE_HEADER pFileHeader = { 0 };
237  wStream sbuffer = { 0 };
238  wStream* s = Stream_StaticConstInit(&sbuffer, data, SrcSize);
239  if (!readBitmapFileHeader(s, &pFileHeader))
240  return NULL;
241 
242  DstSize = SrcSize - sizeof(BITMAPFILEHEADER);
243  pDstData = (BYTE*)malloc(DstSize);
244 
245  if (!pDstData)
246  return NULL;
247 
248  data = (const void*)&((const BYTE*)data)[sizeof(BITMAPFILEHEADER)];
249  CopyMemory(pDstData, data, DstSize);
250  *pSize = DstSize;
251  return pDstData;
252  }
253 
254  return NULL;
255 }
256 
263 static void* clipboard_synthesize_cf_dibv5(wClipboard* clipboard, UINT32 formatId, const void* data,
264  UINT32* pSize)
265 {
266  if (formatId == CF_DIB)
267  {
268  }
269  else if (is_format_bitmap(clipboard, formatId))
270  {
271  }
272 
273  return NULL;
274 }
275 
276 static void* clipboard_prepend_bmp_header(const WINPR_BITMAP_INFO_HEADER* pInfoHeader,
277  const void* data, size_t size, UINT32* pSize)
278 {
279  WINPR_ASSERT(pInfoHeader);
280  WINPR_ASSERT(pSize);
281 
282  *pSize = 0;
283  if ((pInfoHeader->biBitCount < 1) || (pInfoHeader->biBitCount > 32))
284  return NULL;
285 
286  const size_t DstSize = sizeof(WINPR_BITMAP_FILE_HEADER) + size;
287  if (DstSize > UINT32_MAX)
288  return NULL;
289 
290  wStream* s = Stream_New(NULL, DstSize);
291  if (!s)
292  return NULL;
293 
294  WINPR_BITMAP_FILE_HEADER fileHeader = { 0 };
295  fileHeader.bfType[0] = 'B';
296  fileHeader.bfType[1] = 'M';
297  fileHeader.bfSize = (UINT32)DstSize;
298  fileHeader.bfOffBits = sizeof(WINPR_BITMAP_FILE_HEADER) + sizeof(WINPR_BITMAP_INFO_HEADER);
299  if (!writeBitmapFileHeader(s, &fileHeader))
300  goto fail;
301 
302  if (!Stream_EnsureRemainingCapacity(s, size))
303  goto fail;
304  Stream_Write(s, data, size);
305  const size_t len = Stream_GetPosition(s);
306  if (len != DstSize)
307  goto fail;
308  *pSize = (UINT32)DstSize;
309 
310  BYTE* dst = Stream_Buffer(s);
311  Stream_Free(s, FALSE);
312  return dst;
313 
314 fail:
315  Stream_Free(s, TRUE);
316  return NULL;
317 }
318 
325 static void* clipboard_synthesize_image_bmp(wClipboard* clipboard, UINT32 formatId,
326  const void* data, UINT32* pSize)
327 {
328  UINT32 SrcSize = *pSize;
329 
330  if (formatId == CF_DIB)
331  {
332  if (SrcSize < sizeof(BITMAPINFOHEADER))
333  return NULL;
334 
335  wStream sbuffer = { 0 };
336  size_t offset = 0;
337  WINPR_BITMAP_INFO_HEADER header = { 0 };
338  wStream* s = Stream_StaticConstInit(&sbuffer, data, SrcSize);
339  if (!readBitmapInfoHeader(s, &header, &offset))
340  return NULL;
341 
342  return clipboard_prepend_bmp_header(&header, data, SrcSize, pSize);
343  }
344  else if (formatId == CF_DIBV5)
345  {
346  }
347 
348  return NULL;
349 }
350 
351 #if defined(WINPR_UTILS_IMAGE_PNG) || defined(WINPR_UTILS_IMAGE_WEBP) || \
352  defined(WINPR_UTILS_IMAGE_JPEG)
353 static void* clipboard_synthesize_image_bmp_to_format(wClipboard* clipboard, UINT32 formatId,
354  UINT32 bmpFormat, const void* data,
355  UINT32* pSize)
356 {
357  WINPR_ASSERT(clipboard);
358  WINPR_ASSERT(data);
359  WINPR_ASSERT(pSize);
360 
361  size_t dsize = 0;
362  void* result = NULL;
363 
364  wImage* img = winpr_image_new();
365  void* bmp = clipboard_synthesize_image_bmp(clipboard, formatId, data, pSize);
366  const UINT32 SrcSize = *pSize;
367  *pSize = 0;
368 
369  if (!bmp || !img)
370  goto fail;
371 
372  if (winpr_image_read_buffer(img, bmp, SrcSize) <= 0)
373  goto fail;
374 
375  result = winpr_image_write_buffer(img, bmpFormat, &dsize);
376  if (result)
377  {
378  if (dsize <= UINT32_MAX)
379  *pSize = (UINT32)dsize;
380  else
381  {
382  free(result);
383  result = NULL;
384  }
385  }
386 
387 fail:
388  free(bmp);
389  winpr_image_free(img, TRUE);
390  return result;
391 }
392 #endif
393 
394 #if defined(WINPR_UTILS_IMAGE_PNG)
395 static void* clipboard_synthesize_image_bmp_to_png(wClipboard* clipboard, UINT32 formatId,
396  const void* data, UINT32* pSize)
397 {
398  return clipboard_synthesize_image_bmp_to_format(clipboard, formatId, WINPR_IMAGE_PNG, data,
399  pSize);
400 }
401 
402 static void* clipboard_synthesize_image_format_to_bmp(wClipboard* clipboard, UINT32 srcFormatId,
403  const void* data, UINT32* pSize)
404 {
405  WINPR_ASSERT(clipboard);
406  WINPR_ASSERT(data);
407  WINPR_ASSERT(pSize);
408 
409  BYTE* dst = NULL;
410  const UINT32 SrcSize = *pSize;
411  size_t size = 0;
412  wImage* image = winpr_image_new();
413  if (!image)
414  goto fail;
415 
416  const int res = winpr_image_read_buffer(image, data, SrcSize);
417  if (res <= 0)
418  goto fail;
419 
420  dst = winpr_image_write_buffer(image, WINPR_IMAGE_BITMAP, &size);
421  if ((size < sizeof(WINPR_BITMAP_FILE_HEADER)) || (size > UINT32_MAX))
422  {
423  free(dst);
424  dst = NULL;
425  goto fail;
426  }
427  *pSize = (UINT32)size;
428 
429 fail:
430  winpr_image_free(image, TRUE);
431 
432  if (dst)
433  memmove(dst, &dst[sizeof(WINPR_BITMAP_FILE_HEADER)],
434  size - sizeof(WINPR_BITMAP_FILE_HEADER));
435  return dst;
436 }
437 
438 static void* clipboard_synthesize_image_png_to_bmp(wClipboard* clipboard, UINT32 formatId,
439  const void* data, UINT32* pSize)
440 {
441  return clipboard_synthesize_image_format_to_bmp(clipboard, formatId, data, pSize);
442 }
443 #endif
444 
445 #if defined(WINPR_UTILS_IMAGE_WEBP)
446 static void* clipboard_synthesize_image_bmp_to_webp(wClipboard* clipboard, UINT32 formatId,
447  const void* data, UINT32* pSize)
448 {
449  return clipboard_synthesize_image_bmp_to_format(clipboard, formatId, WINPR_IMAGE_WEBP, data,
450  pSize);
451 }
452 
453 static void* clipboard_synthesize_image_webp_to_bmp(wClipboard* clipboard, UINT32 formatId,
454  const void* data, UINT32* pSize)
455 {
456  return clipboard_synthesize_image_format_to_bmp(clipboard, formatId, data, pSize);
457 }
458 #endif
459 
460 #if defined(WINPR_UTILS_IMAGE_JPEG)
461 static void* clipboard_synthesize_image_bmp_to_jpeg(wClipboard* clipboard, UINT32 formatId,
462  const void* data, UINT32* pSize)
463 {
464  return clipboard_synthesize_image_bmp_to_format(clipboard, formatId, WINPR_IMAGE_JPEG, data,
465  pSize);
466 }
467 
468 static void* clipboard_synthesize_image_jpeg_to_bmp(wClipboard* clipboard, UINT32 formatId,
469  const void* data, UINT32* pSize)
470 {
471  return clipboard_synthesize_image_format_to_bmp(clipboard, formatId, data, pSize);
472 }
473 #endif
474 
481 static void* clipboard_synthesize_html_format(wClipboard* clipboard, UINT32 formatId,
482  const void* pData, UINT32* pSize)
483 {
484  union
485  {
486  const void* cpv;
487  const char* cpc;
488  const BYTE* cpb;
489  WCHAR* pv;
490  } pSrcData;
491  char* pDstData = NULL;
492 
493  pSrcData.cpv = NULL;
494 
495  WINPR_ASSERT(clipboard);
496  WINPR_ASSERT(pSize);
497 
498  if (formatId == ClipboardGetFormatId(clipboard, "text/html"))
499  {
500  const INT64 SrcSize = (INT64)*pSize;
501  const size_t DstSize = SrcSize + 200;
502  char* body = NULL;
503  char num[20] = { 0 };
504 
505  /* Create a copy, we modify the input data */
506  pSrcData.pv = calloc(1, SrcSize + 1);
507  if (!pSrcData.pv)
508  goto fail;
509  memcpy(pSrcData.pv, pData, SrcSize);
510 
511  if (SrcSize > 2)
512  {
513  if (SrcSize > INT_MAX)
514  goto fail;
515 
516  /* Check the BOM (Byte Order Mark) */
517  if ((pSrcData.cpb[0] == 0xFE) && (pSrcData.cpb[1] == 0xFF))
518  ByteSwapUnicode(pSrcData.pv, (SrcSize / 2));
519 
520  /* Check if we have WCHAR, convert to UTF-8 */
521  if ((pSrcData.cpb[0] == 0xFF) && (pSrcData.cpb[1] == 0xFE))
522  {
523  char* utfString =
524  ConvertWCharNToUtf8Alloc(&pSrcData.pv[1], SrcSize / sizeof(WCHAR), NULL);
525  free(pSrcData.pv);
526  pSrcData.cpc = utfString;
527  if (!utfString)
528  goto fail;
529  }
530  }
531 
532  pDstData = (char*)calloc(1, DstSize);
533 
534  if (!pDstData)
535  goto fail;
536 
537  (void)sprintf_s(pDstData, DstSize,
538  "Version:0.9\r\n"
539  "StartHTML:0000000000\r\n"
540  "EndHTML:0000000000\r\n"
541  "StartFragment:0000000000\r\n"
542  "EndFragment:0000000000\r\n");
543  body = strstr(pSrcData.cpc, "<body");
544 
545  if (!body)
546  body = strstr(pSrcData.cpc, "<BODY");
547 
548  /* StartHTML */
549  (void)sprintf_s(num, sizeof(num), "%010" PRIuz "", strnlen(pDstData, DstSize));
550  CopyMemory(&pDstData[23], num, 10);
551 
552  if (!body)
553  {
554  if (!winpr_str_append("<HTML><BODY>", pDstData, DstSize, NULL))
555  goto fail;
556  }
557 
558  if (!winpr_str_append("<!--StartFragment-->", pDstData, DstSize, NULL))
559  goto fail;
560 
561  /* StartFragment */
562  (void)sprintf_s(num, sizeof(num), "%010" PRIuz "", strnlen(pDstData, SrcSize + 200));
563  CopyMemory(&pDstData[69], num, 10);
564 
565  if (!winpr_str_append(pSrcData.cpc, pDstData, DstSize, NULL))
566  goto fail;
567 
568  /* EndFragment */
569  (void)sprintf_s(num, sizeof(num), "%010" PRIuz "", strnlen(pDstData, SrcSize + 200));
570  CopyMemory(&pDstData[93], num, 10);
571 
572  if (!winpr_str_append("<!--EndFragment-->", pDstData, DstSize, NULL))
573  goto fail;
574 
575  if (!body)
576  {
577  if (!winpr_str_append("</BODY></HTML>", pDstData, DstSize, NULL))
578  goto fail;
579  }
580 
581  /* EndHTML */
582  (void)sprintf_s(num, sizeof(num), "%010" PRIuz "", strnlen(pDstData, DstSize));
583  CopyMemory(&pDstData[43], num, 10);
584  *pSize = (UINT32)strnlen(pDstData, DstSize) + 1;
585  }
586 fail:
587  free(pSrcData.pv);
588  return pDstData;
589 }
590 
597 static void* clipboard_synthesize_text_html(wClipboard* clipboard, UINT32 formatId,
598  const void* data, UINT32* pSize)
599 {
600  char* pDstData = NULL;
601 
602  if (formatId == ClipboardGetFormatId(clipboard, "HTML Format"))
603  {
604  const char* str = (const char*)data;
605  const size_t SrcSize = (INT64)*pSize;
606  const char* begStr = strstr(str, "StartHTML:");
607  const char* endStr = strstr(str, "EndHTML:");
608 
609  if (!begStr || !endStr)
610  return NULL;
611 
612  errno = 0;
613  const long beg = strtol(&begStr[10], NULL, 10);
614 
615  if (errno != 0)
616  return NULL;
617 
618  const long end = strtol(&endStr[8], NULL, 10);
619 
620  if ((beg < 0) || (end < 0) || ((size_t)beg > SrcSize) || ((size_t)end > SrcSize) ||
621  (beg >= end) || (errno != 0))
622  return NULL;
623 
624  const size_t DstSize = (size_t)(end - beg);
625  pDstData = calloc(DstSize + 1, sizeof(char));
626 
627  if (!pDstData)
628  return NULL;
629 
630  CopyMemory(pDstData, &str[beg], DstSize);
631  const size_t rc = ConvertLineEndingToLF(pDstData, DstSize);
632  WINPR_ASSERT(rc <= UINT32_MAX);
633  *pSize = (UINT32)rc;
634  }
635 
636  return pDstData;
637 }
638 
639 BOOL ClipboardInitSynthesizers(wClipboard* clipboard)
640 {
644  {
645  ClipboardRegisterSynthesizer(clipboard, CF_TEXT, CF_OEMTEXT,
646  clipboard_synthesize_cf_oemtext);
647  ClipboardRegisterSynthesizer(clipboard, CF_TEXT, CF_UNICODETEXT,
648  clipboard_synthesize_cf_unicodetext);
649  ClipboardRegisterSynthesizer(clipboard, CF_TEXT, CF_LOCALE, clipboard_synthesize_cf_locale);
650 
651  UINT32 altFormatId = ClipboardRegisterFormat(clipboard, mime_text_plain);
652  ClipboardRegisterSynthesizer(clipboard, CF_TEXT, altFormatId,
653  clipboard_synthesize_utf8_string);
654  }
658  {
659  ClipboardRegisterSynthesizer(clipboard, CF_OEMTEXT, CF_TEXT, clipboard_synthesize_cf_text);
660  ClipboardRegisterSynthesizer(clipboard, CF_OEMTEXT, CF_UNICODETEXT,
661  clipboard_synthesize_cf_unicodetext);
662  ClipboardRegisterSynthesizer(clipboard, CF_OEMTEXT, CF_LOCALE,
663  clipboard_synthesize_cf_locale);
664  UINT32 altFormatId = ClipboardRegisterFormat(clipboard, mime_text_plain);
665  ClipboardRegisterSynthesizer(clipboard, CF_OEMTEXT, altFormatId,
666  clipboard_synthesize_utf8_string);
667  }
671  {
672  ClipboardRegisterSynthesizer(clipboard, CF_UNICODETEXT, CF_TEXT,
673  clipboard_synthesize_cf_text);
674  ClipboardRegisterSynthesizer(clipboard, CF_UNICODETEXT, CF_OEMTEXT,
675  clipboard_synthesize_cf_oemtext);
676  ClipboardRegisterSynthesizer(clipboard, CF_UNICODETEXT, CF_LOCALE,
677  clipboard_synthesize_cf_locale);
678  UINT32 altFormatId = ClipboardRegisterFormat(clipboard, mime_text_plain);
679  ClipboardRegisterSynthesizer(clipboard, CF_UNICODETEXT, altFormatId,
680  clipboard_synthesize_utf8_string);
681  }
685  {
686  UINT32 formatId = ClipboardRegisterFormat(clipboard, mime_text_plain);
687 
688  if (formatId)
689  {
690  ClipboardRegisterSynthesizer(clipboard, formatId, CF_TEXT,
691  clipboard_synthesize_cf_text);
692  ClipboardRegisterSynthesizer(clipboard, formatId, CF_OEMTEXT,
693  clipboard_synthesize_cf_oemtext);
694  ClipboardRegisterSynthesizer(clipboard, formatId, CF_UNICODETEXT,
695  clipboard_synthesize_cf_unicodetext);
696  ClipboardRegisterSynthesizer(clipboard, formatId, CF_LOCALE,
697  clipboard_synthesize_cf_locale);
698  }
699  }
703  {
704  UINT32 formatId = ClipboardRegisterFormat(clipboard, mime_text_plain);
705 
706  if (formatId)
707  {
708  ClipboardRegisterSynthesizer(clipboard, formatId, CF_TEXT,
709  clipboard_synthesize_cf_text);
710  ClipboardRegisterSynthesizer(clipboard, formatId, CF_OEMTEXT,
711  clipboard_synthesize_cf_oemtext);
712  ClipboardRegisterSynthesizer(clipboard, formatId, CF_UNICODETEXT,
713  clipboard_synthesize_cf_unicodetext);
714  ClipboardRegisterSynthesizer(clipboard, formatId, CF_LOCALE,
715  clipboard_synthesize_cf_locale);
716  }
717  }
721  {
722  ClipboardRegisterSynthesizer(clipboard, CF_DIB, CF_DIBV5, clipboard_synthesize_cf_dibv5);
723  for (size_t x = 0; x < ARRAYSIZE(mime_bitmap); x++)
724  {
725  const char* mime = mime_bitmap[x];
726  const UINT32 altFormatId = ClipboardRegisterFormat(clipboard, mime);
727  if (altFormatId == 0)
728  continue;
729  ClipboardRegisterSynthesizer(clipboard, CF_DIB, altFormatId,
730  clipboard_synthesize_image_bmp);
731  }
732  }
733 
738  if (0)
739  {
740  ClipboardRegisterSynthesizer(clipboard, CF_DIBV5, CF_DIB, clipboard_synthesize_cf_dib);
741 
742  for (size_t x = 0; x < ARRAYSIZE(mime_bitmap); x++)
743  {
744  const char* mime = mime_bitmap[x];
745  const UINT32 altFormatId = ClipboardRegisterFormat(clipboard, mime);
746  if (altFormatId == 0)
747  continue;
748  ClipboardRegisterSynthesizer(clipboard, CF_DIBV5, altFormatId,
749  clipboard_synthesize_image_bmp);
750  }
751  }
752 
756  for (size_t x = 0; x < ARRAYSIZE(mime_bitmap); x++)
757  {
758  const char* mime = mime_bitmap[x];
759  const UINT32 altFormatId = ClipboardRegisterFormat(clipboard, mime);
760  if (altFormatId == 0)
761  continue;
762  ClipboardRegisterSynthesizer(clipboard, altFormatId, CF_DIB, clipboard_synthesize_cf_dib);
763  ClipboardRegisterSynthesizer(clipboard, altFormatId, CF_DIBV5,
764  clipboard_synthesize_cf_dibv5);
765  }
766 
770 #if defined(WINPR_UTILS_IMAGE_PNG)
771  {
772  const UINT32 altFormatId = ClipboardRegisterFormat(clipboard, mime_png);
773  ClipboardRegisterSynthesizer(clipboard, CF_DIB, altFormatId,
774  clipboard_synthesize_image_bmp_to_png);
775  ClipboardRegisterSynthesizer(clipboard, CF_DIBV5, altFormatId,
776  clipboard_synthesize_image_bmp_to_png);
777  ClipboardRegisterSynthesizer(clipboard, altFormatId, CF_DIB,
778  clipboard_synthesize_image_png_to_bmp);
779  ClipboardRegisterSynthesizer(clipboard, altFormatId, CF_DIBV5,
780  clipboard_synthesize_image_png_to_bmp);
781  }
782 #endif
783 
787 #if defined(WINPR_UTILS_IMAGE_WEBP)
788  {
789  const UINT32 altFormatId = ClipboardRegisterFormat(clipboard, mime_webp);
790  ClipboardRegisterSynthesizer(clipboard, CF_DIB, altFormatId,
791  clipboard_synthesize_image_bmp_to_webp);
792  ClipboardRegisterSynthesizer(clipboard, CF_DIBV5, altFormatId,
793  clipboard_synthesize_image_webp_to_bmp);
794  ClipboardRegisterSynthesizer(clipboard, altFormatId, CF_DIB,
795  clipboard_synthesize_image_bmp_to_webp);
796  ClipboardRegisterSynthesizer(clipboard, altFormatId, CF_DIBV5,
797  clipboard_synthesize_image_webp_to_bmp);
798  }
799 #endif
800 
804 #if defined(WINPR_UTILS_IMAGE_JPEG)
805  {
806  const UINT32 altFormatId = ClipboardRegisterFormat(clipboard, mime_jpeg);
807  ClipboardRegisterSynthesizer(clipboard, CF_DIB, altFormatId,
808  clipboard_synthesize_image_bmp_to_jpeg);
809  ClipboardRegisterSynthesizer(clipboard, CF_DIBV5, altFormatId,
810  clipboard_synthesize_image_jpeg_to_bmp);
811  ClipboardRegisterSynthesizer(clipboard, altFormatId, CF_DIB,
812  clipboard_synthesize_image_bmp_to_jpeg);
813  ClipboardRegisterSynthesizer(clipboard, altFormatId, CF_DIBV5,
814  clipboard_synthesize_image_jpeg_to_bmp);
815  }
816 #endif
817 
821  {
822  UINT32 formatId = ClipboardRegisterFormat(clipboard, "HTML Format");
823 
824  if (formatId)
825  {
826  const UINT32 altFormatId = ClipboardRegisterFormat(clipboard, "text/html");
827  ClipboardRegisterSynthesizer(clipboard, formatId, altFormatId,
828  clipboard_synthesize_text_html);
829  }
830  }
831 
835  {
836  UINT32 formatId = ClipboardRegisterFormat(clipboard, "text/html");
837 
838  if (formatId)
839  {
840  const UINT32 altFormatId = ClipboardRegisterFormat(clipboard, "HTML Format");
841  ClipboardRegisterSynthesizer(clipboard, formatId, altFormatId,
842  clipboard_synthesize_html_format);
843  }
844  }
845 
846  return TRUE;
847 }