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