1 #![cfg(windows)]
2 //! This crate provide simple means to operate with Windows clipboard.
3 //!
4 //!# Note keeping Clipboard around:
5 //!
6 //! In Windows [Clipboard](struct.Clipboard.html) opens globally and only one application can set data onto format at the time.
7 //!
8 //! Therefore as soon as operations are finished, user is advised to close [Clipboard](struct.Clipboard.html).
9 //!
10 //!# Clipboard
11 //!
12 //! All read and write access to Windows clipboard requires user to open it.
13 //!
14 //! For your convenience you can use [Clipboard](struct.Clipboard.html) struct that opens it at creation
15 //! and closes on its drop.
16 //!
17 //! Alternatively you can access all functionality directly through [raw module](raw/index.html).
18 //!
19 //! Below you can find examples of usage.
20 //!
21 //!## Empty clipboard
22 //!
23 //! ```rust
24 //! use clipboard_win::Clipboard;
25 //!
26 //! fn main() {
27 //! Clipboard::new().unwrap().empty();
28 //! }
29 //! ```
30 //!## Set and get raw data
31 //! ```rust
32 //! use clipboard_win::formats;
33 //!
34 //! use clipboard_win::Clipboard;
main(String[] args)35 //!
36 //! use std::str;
37 //!
38 //! fn main() {
39 //! let text = "For my waifu!\0"; //For text we need to pass C-like string
40 //! Clipboard::new().unwrap().set(formats::CF_TEXT, text.as_bytes());
41 //!
42 //! let mut buffer = [0u8; 52];
43 //! let result = Clipboard::new().unwrap().get(formats::CF_TEXT, &mut buffer).unwrap();
44 //! assert_eq!(str::from_utf8(&buffer[..result]).unwrap(), text);
45 //! }
46 //! ```
47 //!
48 //!## Set and get String
49 //!
50 //!```rust
51 //!use clipboard_win::Clipboard;
52 //!
53 //!use std::str;
54 //!
55 //!fn main() {
56 //! let text = "For my waifu!";
57 //! Clipboard::new().unwrap().set_string(text);
58 //!
59 //! let mut result = String::new();
60 //! Clipboard::new().unwrap().get_string(&mut result).unwrap();
61 //! assert_eq!(text, result);
62 //!}
63 //!```
64 //!
65 //!## Set and get String shortcuts
66 //!
67 //!```rust
68 //!use clipboard_win::{set_clipboard_string, get_clipboard_string};
69 //!
70 //!use std::str;
71 //!
72 //!fn main() {
73 //! let text = "For my waifu!";
74 //! set_clipboard_string(text).expect("Success");
75 //!
76 //! let result = get_clipboard_string().unwrap();
77 //! assert_eq!(text, result);
78 //!}
79 //!```
80
81 #![warn(missing_docs)]
82 #![cfg_attr(feature = "cargo-clippy", allow(clippy::style))]
83
84 pub mod formats;
85 pub mod raw;
86 pub mod dib;
87 pub mod image;
88 pub mod utils;
89
90 use std::{io};
91 use std::path::PathBuf;
92
93 ///Clipboard accessor.
94 ///
95 ///# Note:
96 ///
97 ///You can have only one such accessor across your program.
98 ///
99 ///# Warning:
100 ///
101 ///In Windows Clipboard opens globally and only one application can set data
102 ///onto format at the time.
103 ///
104 ///Therefore as soon as operations are finished, user is advised to close Clipboard.
105 pub struct Clipboard {
106 inner: ()
107 }
108
109 impl Clipboard {
110 ///Initializes new clipboard accessor.
111 ///
112 ///Attempts to open clipboard.
113 #[inline]
114 pub fn new() -> io::Result<Clipboard> {
115 raw::open().map(|_| Clipboard { inner: () })
116 }
117
118 #[inline]
119 ///Attempts to initialize clipboard `num` times before giving up.
120 pub fn new_attempts(mut num: usize) -> io::Result<Clipboard> {
121 loop {
122 match raw::open() {
123 Ok(_) => break Ok(Clipboard { inner: () }),
124 Err(error) => match num {
125 0 => break Err(error),
126 _ => num -= 1
127 },
128 }
129 }
130 }
131
132 ///Empties clipboard.
133 #[inline]
134 pub fn empty(&self) -> io::Result<&Clipboard> {
135 raw::empty().map(|_| self)
136 }
137
138 ///Retrieves size of clipboard content.
139 #[inline]
140 pub fn size(&self, format: u32) -> Option<usize> {
141 raw::size(format)
142 }
143
144 ///Sets data onto clipboard with specified format.
145 ///
146 ///Wraps `raw::set()`
147 #[inline]
148 pub fn set(&self, format: u32, data: &[u8]) -> io::Result<()> {
149 raw::set(format, data)
150 }
151
152 ///Sets `str` or `String` onto clipboard as Unicode format.
153 ///
154 ///Under hood it transforms Rust `UTF-8` String into `UTF-16`
155 #[inline]
156 pub fn set_string(&self, text: &str) -> io::Result<()> {
157 raw::set_string(text)
158 }
159
160 ///Retrieves data of specified format from clipboard.
161 ///
162 ///Wraps `raw::get()`
163 #[inline]
164 pub fn get(&self, format: u32, data: &mut [u8]) -> io::Result<usize> {
165 raw::get(format, data)
166 }
167
168 ///Retrieves `String` of `CF_UNICODETEXT` format from clipboard.
169 ///
170 ///Wraps `raw::get_string()`
171 #[inline]
172 pub fn get_string(&self, storage: &mut String) -> io::Result<()> {
173 raw::get_string(storage)
174 }
175
176 /// Retrieves a list of file paths from the `CF_HDROP` format from the clipboard.
177 ///
178 /// Wraps `raw::get_file_list()`
179 #[inline]
180 pub fn get_file_list(&self) -> io::Result<Vec<PathBuf>> {
181 raw::get_file_list()
182 }
183
184 #[inline]
185 ///Retrieves `Bitmap` of `CF_DIB`
186 pub fn get_dib(&self) -> io::Result<dib::Image> {
187 raw::get_clipboard_data(formats::CF_DIB).or_else(|_| raw::get_clipboard_data(formats::CF_DIBV5))
188 .and_then(|handle| dib::Image::from_handle(handle.as_ptr()))
189 }
190
191 #[inline]
192 ///Retrieves `Bitmap` of `CF_BITMAP`
193 pub fn get_bitmap(&self) -> io::Result<image::Image> {
194 raw::get_clipboard_data(formats::CF_BITMAP).and_then(|handle| image::Image::from_handle(handle))
195 }
196
197 #[inline]
198 ///Sets bitmap image onto clipboard as `CF_BITMAP`
199 pub fn set_bitmap(&self, image: &image::Image) -> io::Result<()> {
200 image.write_to_clipboard()
201 }
202
203 ///Enumerator over all formats on clipboard..
204 #[inline]
205 pub fn enum_formats(&self) -> raw::EnumFormats {
206 raw::EnumFormats::new()
207 }
208
209 ///Returns Clipboard sequence number.
210 #[inline]
211 pub fn seq_num() -> Option<u32> {
212 raw::seq_num()
213 }
214
215 ///Determines whenever provided clipboard format is available on clipboard or not.
216 #[inline]
217 pub fn is_format_avail(format: u32) -> bool {
218 raw::is_format_avail(format)
219 }
220
221 ///Retrieves number of currently available formats on clipboard.
222 #[inline]
223 pub fn count_formats() -> io::Result<i32> {
224 raw::count_formats()
225 }
226 }
227
228 impl Drop for Clipboard {
229 fn drop(&mut self) {
230 let _ = raw::close();
231 self.inner
232 }
233 }
234
235 ///Shortcut to retrieve string from clipboard.
236 ///
237 ///It opens clipboard and gets string, if possible.
238 #[inline]
239 pub fn get_clipboard_string() -> io::Result<String> {
240 let mut data = String::new();
241 Clipboard::new_attempts(10)?.get_string(&mut data).map(|_| data)
242 }
243
244 ///Shortcut to set string onto clipboard.
245 ///
246 ///It opens clipboard and attempts to set string.
247 #[inline]
248 pub fn set_clipboard_string(data: &str) -> io::Result<()> {
249 Clipboard::new_attempts(10)?.set_string(data)
250 }
251