1// Clip Library
2// Copyright (c) 2015-2018 David Capello
3//
4// This file is released under the terms of the MIT license.
5// Read LICENSE.txt for more information.
6
7#include "clip.h"
8#include "clip_lock_impl.h"
9
10#include <vector>
11#include <stdexcept>
12
13namespace clip {
14
15namespace {
16
17void default_error_handler(ErrorCode code) {
18 static const char* err[] = {
19 "Cannot lock clipboard",
20 "Image format is not supported"
21 };
22 throw std::runtime_error(err[static_cast<int>(code)]);
23}
24
25} // anonymous namespace
26
27error_handler g_error_handler = default_error_handler;
28
29lock::lock(void* native_window_handle)
30 : p(new impl(native_window_handle)) {
31}
32
33lock::~lock() = default;
34
35bool lock::locked() const {
36 return p->locked();
37}
38
39bool lock::clear() {
40 return p->clear();
41}
42
43bool lock::is_convertible(format f) const {
44 return p->is_convertible(f);
45}
46
47bool lock::set_data(format f, const char* buf, size_t length) {
48 return p->set_data(f, buf, length);
49}
50
51bool lock::get_data(format f, char* buf, size_t len) const {
52 return p->get_data(f, buf, len);
53}
54
55size_t lock::get_data_length(format f) const {
56 return p->get_data_length(f);
57}
58
59bool lock::set_image(const image& img) {
60 return p->set_image(img);
61}
62
63bool lock::get_image(image& img) const {
64 return p->get_image(img);
65}
66
67bool lock::get_image_spec(image_spec& spec) const {
68 return p->get_image_spec(spec);
69}
70
71format empty_format() { return 0; }
72format text_format() { return 1; }
73format image_format() { return 2; }
74
75bool has(format f) {
76 lock l;
77 if (l.locked())
78 return l.is_convertible(f);
79 else
80 return false;
81}
82
83bool clear() {
84 lock l;
85 if (l.locked())
86 return l.clear();
87 else
88 return false;
89}
90
91bool set_text(const std::string& value) {
92 lock l;
93 if (l.locked()) {
94 l.clear();
95 return l.set_data(text_format(), value.c_str(), value.size());
96 }
97 else
98 return false;
99}
100
101bool get_text(std::string& value) {
102 lock l;
103 if (!l.locked())
104 return false;
105
106 format f = text_format();
107 if (!l.is_convertible(f))
108 return false;
109
110 size_t len = l.get_data_length(f);
111 if (len > 0) {
112 std::vector<char> buf(len);
113 l.get_data(f, &buf[0], len);
114 value = &buf[0];
115 return true;
116 }
117 else {
118 value.clear();
119 return true;
120 }
121}
122
123bool set_image(const image& img) {
124 lock l;
125 if (l.locked()) {
126 l.clear();
127 return l.set_image(img);
128 }
129 else
130 return false;
131}
132
133bool get_image(image& img) {
134 lock l;
135 if (!l.locked())
136 return false;
137
138 format f = image_format();
139 if (!l.is_convertible(f))
140 return false;
141
142 return l.get_image(img);
143}
144
145bool get_image_spec(image_spec& spec) {
146 lock l;
147 if (!l.locked())
148 return false;
149
150 format f = image_format();
151 if (!l.is_convertible(f))
152 return false;
153
154 return l.get_image_spec(spec);
155}
156
157void set_error_handler(error_handler handler) {
158 g_error_handler = handler;
159}
160
161error_handler get_error_handler() {
162 return g_error_handler;
163}
164
165#ifdef HAVE_XCB_XLIB_H
166static int g_x11_timeout = 1000;
167void set_x11_wait_timeout(int msecs) { g_x11_timeout = msecs; }
168int get_x11_wait_timeout() { return g_x11_timeout; }
169#else
170void set_x11_wait_timeout(int) { }
171int get_x11_wait_timeout() { return 1000; }
172#endif
173
174} // namespace clip
175