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