pasteboard_c.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #include "pasteboard.h"
  2. #include "os.h"
  3. #if defined(IS_MACOSX)
  4. #include "png_io.h"
  5. #include <ApplicationServices/ApplicationServices.h>
  6. #elif defined(IS_WINDOWS)
  7. #include "bmp_io.h"
  8. #endif
  9. MMPasteError copyMMBitmapToPasteboard(MMBitmapRef bitmap)
  10. {
  11. #if defined(IS_MACOSX)
  12. PasteboardRef clipboard;
  13. size_t len;
  14. uint8_t *pngbuf;
  15. CFDataRef data;
  16. OSStatus err;
  17. if (PasteboardCreate(kPasteboardClipboard, &clipboard) != noErr) {
  18. return kMMPasteOpenError;
  19. }
  20. if (PasteboardClear(clipboard) != noErr) {
  21. CFRelease(clipboard);
  22. return kMMPasteClearError;
  23. }
  24. pngbuf = createPNGData(bitmap, &len);
  25. if (pngbuf == NULL) {
  26. CFRelease(clipboard);
  27. return kMMPasteDataError;
  28. }
  29. data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, pngbuf, len,
  30. kCFAllocatorNull);
  31. if (data == NULL) {
  32. CFRelease(clipboard);
  33. free(pngbuf);
  34. return kMMPasteDataError;
  35. }
  36. err = PasteboardPutItemFlavor(clipboard, bitmap, kUTTypePNG, data, 0);
  37. CFRelease(data);
  38. CFRelease(clipboard);
  39. free(pngbuf);
  40. return (err == noErr) ? kMMPasteNoError : kMMPastePasteError;
  41. #elif defined(IS_WINDOWS)
  42. MMPasteError ret = kMMPasteNoError;
  43. uint8_t *bmpData;
  44. size_t len;
  45. HGLOBAL handle;
  46. if (!OpenClipboard(NULL)) return kMMPasteOpenError;
  47. if (!EmptyClipboard()) return kMMPasteClearError;
  48. bmpData = createBitmapData(bitmap, &len);
  49. if (bmpData == NULL) return kMMPasteDataError;
  50. /* CF_DIB does not include the BITMAPFILEHEADER struct (and displays a
  51. * cryptic error if it is included). */
  52. len -= sizeof(BITMAPFILEHEADER);
  53. /* SetClipboardData() needs a "handle", not just a buffer, so we have to
  54. * allocate one with GlobalAlloc(). */
  55. if ((handle = GlobalAlloc(GMEM_MOVEABLE, len)) == NULL) {
  56. CloseClipboard();
  57. free(bmpData);
  58. return kMMPasteDataError;
  59. }
  60. memcpy(GlobalLock(handle), bmpData + sizeof(BITMAPFILEHEADER), len);
  61. GlobalUnlock(handle);
  62. free(bmpData);
  63. if (SetClipboardData(CF_DIB, handle) == NULL) {
  64. ret = kMMPastePasteError;
  65. }
  66. CloseClipboard();
  67. GlobalFree(handle);
  68. return ret;
  69. #elif defined(USE_X11)
  70. /* TODO (X11's clipboard is _weird_.) */
  71. return kMMPasteUnsupportedError;
  72. #endif
  73. }
  74. const char *MMPasteErrorString(MMPasteError err)
  75. {
  76. switch (err) {
  77. case kMMPasteOpenError:
  78. return "Could not open pasteboard";
  79. case kMMPasteClearError:
  80. return "Could not clear pasteboard";
  81. case kMMPasteDataError:
  82. return "Could not create image data from bitmap";
  83. case kMMPastePasteError:
  84. return "Could not paste data";
  85. case kMMPasteUnsupportedError:
  86. return "Unsupported platform";
  87. default:
  88. return NULL;
  89. }
  90. }