1 /*
2 * barrier -- mouse and keyboard sharing utility
3 * Copyright (C) 2014-2016 Symless Ltd.
4 * Patch by Ryan Chapman
5 *
6 * This package is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * found in the file LICENSE that should have accompanied this file.
9 *
10 * This package is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "platform/OSXClipboardBMPConverter.h"
20 #include "base/Log.h"
21
22 // BMP file header structure
23 struct CBMPHeader {
24 public:
25 UInt16 type;
26 UInt32 size;
27 UInt16 reserved1;
28 UInt16 reserved2;
29 UInt32 offset;
30 };
31
32 // BMP is little-endian
33 static inline
34 UInt32
fromLEU32(const UInt8 * data)35 fromLEU32(const UInt8* data)
36 {
37 return static_cast<UInt32>(data[0]) |
38 (static_cast<UInt32>(data[1]) << 8) |
39 (static_cast<UInt32>(data[2]) << 16) |
40 (static_cast<UInt32>(data[3]) << 24);
41 }
42
43 static
44 void
toLE(UInt8 * & dst,char src)45 toLE(UInt8*& dst, char src)
46 {
47 dst[0] = static_cast<UInt8>(src);
48 dst += 1;
49 }
50
51 static
52 void
toLE(UInt8 * & dst,UInt16 src)53 toLE(UInt8*& dst, UInt16 src)
54 {
55 dst[0] = static_cast<UInt8>(src & 0xffu);
56 dst[1] = static_cast<UInt8>((src >> 8) & 0xffu);
57 dst += 2;
58 }
59
60 static
61 void
toLE(UInt8 * & dst,UInt32 src)62 toLE(UInt8*& dst, UInt32 src)
63 {
64 dst[0] = static_cast<UInt8>(src & 0xffu);
65 dst[1] = static_cast<UInt8>((src >> 8) & 0xffu);
66 dst[2] = static_cast<UInt8>((src >> 16) & 0xffu);
67 dst[3] = static_cast<UInt8>((src >> 24) & 0xffu);
68 dst += 4;
69 }
70
OSXClipboardBMPConverter()71 OSXClipboardBMPConverter::OSXClipboardBMPConverter()
72 {
73 // do nothing
74 }
75
~OSXClipboardBMPConverter()76 OSXClipboardBMPConverter::~OSXClipboardBMPConverter()
77 {
78 // do nothing
79 }
80
81 IClipboard::EFormat
getFormat() const82 OSXClipboardBMPConverter::getFormat() const
83 {
84 return IClipboard::kBitmap;
85 }
86
87 CFStringRef
getOSXFormat() const88 OSXClipboardBMPConverter::getOSXFormat() const
89 {
90 // TODO: does this only work with Windows?
91 return CFSTR("com.microsoft.bmp");
92 }
93
fromIClipboard(const std::string & bmp) const94 std::string OSXClipboardBMPConverter::fromIClipboard(const std::string& bmp) const
95 {
96 LOG((CLOG_DEBUG1 "ENTER OSXClipboardBMPConverter::doFromIClipboard()"));
97 // create BMP image
98 UInt8 header[14];
99 UInt8* dst = header;
100 toLE(dst, 'B');
101 toLE(dst, 'M');
102 toLE(dst, static_cast<UInt32>(14 + bmp.size()));
103 toLE(dst, static_cast<UInt16>(0));
104 toLE(dst, static_cast<UInt16>(0));
105 toLE(dst, static_cast<UInt32>(14 + 40));
106 return std::string(reinterpret_cast<const char*>(header), 14) + bmp;
107 }
108
toIClipboard(const std::string & bmp) const109 std::string OSXClipboardBMPConverter::toIClipboard(const std::string& bmp) const
110 {
111 // make sure data is big enough for a BMP file
112 if (bmp.size() <= 14 + 40) {
113 return {};
114 }
115
116 // check BMP file header
117 const UInt8* rawBMPHeader = reinterpret_cast<const UInt8*>(bmp.data());
118 if (rawBMPHeader[0] != 'B' || rawBMPHeader[1] != 'M') {
119 return {};
120 }
121
122 // get offset to image data
123 UInt32 offset = fromLEU32(rawBMPHeader + 10);
124
125 // construct BMP
126 if (offset == 14 + 40) {
127 return bmp.substr(14);
128 }
129 else {
130 return bmp.substr(14, 40) + bmp.substr(offset, bmp.size() - offset);
131 }
132 }
133