1// Clip Library
2// Copyright (c) 2015-2022 David Capello
3//
4// This file is released under the terms of the MIT license.
5// Read LICENSE.txt for more information.
6
7#ifndef CLIP_H_INCLUDED
8#define CLIP_H_INCLUDED
9#pragma once
10
11#include <cassert>
12#include <memory>
13#include <string>
14
15namespace clip {
16
17 // ======================================================================
18 // Low-level API to lock the clipboard/pasteboard and modify it
19 // ======================================================================
20
21 // Clipboard format identifier.
22 typedef size_t format;
23
24 class image;
25 struct image_spec;
26
27 class lock {
28 public:
29 // You can give your current HWND as the "native_window_handle."
30 // Windows clipboard functions use this handle to open/close
31 // (lock/unlock) the clipboard. From the MSDN documentation we
32 // need this handler so SetClipboardData() doesn't fail after a
33 // EmptyClipboard() call. Anyway it looks to work just fine if we
34 // call OpenClipboard() with a null HWND.
35 lock(void* native_window_handle = nullptr);
36 ~lock();
37
38 // Returns true if we've locked the clipboard successfully in
39 // lock() constructor.
40 bool locked() const;
41
42 // Clears the clipboard content. If you don't clear the content,
43 // previous clipboard content (in unknown formats) could persist
44 // after the unlock.
45 bool clear();
46
47 // Returns true if the clipboard can be converted to the given
48 // format.
49 bool is_convertible(format f) const;
50 bool set_data(format f, const char* buf, size_t len);
51 bool get_data(format f, char* buf, size_t len) const;
52 size_t get_data_length(format f) const;
53
54 // For images
55 bool set_image(const image& image);
56 bool get_image(image& image) const;
57 bool get_image_spec(image_spec& spec) const;
58
59 private:
60 class impl;
61 std::unique_ptr<impl> p;
62 };
63
64 format register_format(const std::string& name);
65
66 // This format is when the clipboard has no content.
67 format empty_format();
68
69 // When the clipboard has UTF8 text.
70 format text_format();
71
72 // When the clipboard has an image.
73 format image_format();
74
75 // Returns true if the clipboard has content of the given type.
76 bool has(format f);
77
78 // Clears the clipboard content.
79 bool clear();
80
81 // ======================================================================
82 // Error handling
83 // ======================================================================
84
85 enum class ErrorCode {
86 CannotLock,
87 ImageNotSupported,
88 };
89
90 typedef void (*error_handler)(ErrorCode code);
91
92 void set_error_handler(error_handler f);
93 error_handler get_error_handler();
94
95 // ======================================================================
96 // Text
97 // ======================================================================
98
99 // High-level API to put/get UTF8 text in/from the clipboard. These
100 // functions returns false in case of error.
101 bool set_text(const std::string& value);
102 bool get_text(std::string& value);
103
104 // ======================================================================
105 // Image
106 // ======================================================================
107
108 struct image_spec {
109 unsigned long width = 0;
110 unsigned long height = 0;
111 unsigned long bits_per_pixel = 0;
112 unsigned long bytes_per_row = 0;
113 unsigned long red_mask = 0;
114 unsigned long green_mask = 0;
115 unsigned long blue_mask = 0;
116 unsigned long alpha_mask = 0;
117 unsigned long red_shift = 0;
118 unsigned long green_shift = 0;
119 unsigned long blue_shift = 0;
120 unsigned long alpha_shift = 0;
121
122 unsigned long required_data_size() const;
123 };
124
125 // The image data must contain straight RGB values
126 // (non-premultiplied by alpha). The image retrieved from the
127 // clipboard will be non-premultiplied too. Basically you will be
128 // always dealing with straight alpha images.
129 //
130 // Details: Windows expects premultiplied images on its clipboard
131 // content, so the library code make the proper conversion
132 // automatically. macOS handles straight alpha directly, so there is
133 // no conversion at all. Linux/X11 images are transferred in
134 // image/png format which are specified in straight alpha.
135 class image {
136 public:
137 image();
138 image(const image_spec& spec);
139 image(const void* data, const image_spec& spec);
140 image(const image& image);
141 image(image&& image);
142 ~image();
143
144 image& operator=(const image& image);
145 image& operator=(image&& image);
146
147 char* data() const { return m_data; }
148 const image_spec& spec() const { return m_spec; }
149
150 bool is_valid() const { return m_data != nullptr; }
151 void reset();
152
153 private:
154 void copy_image(const image& image);
155 void move_image(image&& image);
156
157 bool m_own_data;
158 char* m_data;
159 image_spec m_spec;
160 };
161
162 // High-level API to set/get an image in/from the clipboard. These
163 // functions returns false in case of error.
164 bool set_image(const image& img);
165 bool get_image(image& img);
166 bool get_image_spec(image_spec& spec);
167
168 // ======================================================================
169 // Platform-specific
170 // ======================================================================
171
172 // Only for X11: Sets the time (in milliseconds) that we must wait
173 // for the selection/clipboard owner to receive the content. This
174 // value is 1000 (one second) by default.
175 void set_x11_wait_timeout(int msecs);
176 int get_x11_wait_timeout();
177
178} // namespace clip
179
180#endif // CLIP_H_INCLUDED
181