diff --git a/CMakeLists.txt b/CMakeLists.txt index 60db926..731779b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,9 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") endif() option(CLIP_ENABLE_IMAGE "Compile with support to copy/paste images" on) +if(WIN32) + option(CLIP_ENABLE_LIST_FORMATS "Compile with support to list clipboard formats" off) +endif() option(CLIP_EXAMPLES "Compile clip examples" on) option(CLIP_TESTS "Compile clip tests" on) if(UNIX AND NOT APPLE) @@ -28,6 +31,10 @@ if(CLIP_ENABLE_IMAGE) target_compile_definitions(clip PUBLIC -DCLIP_ENABLE_IMAGE=1) endif() +if(CLIP_ENABLE_LIST_FORMATS) + target_compile_definitions(clip PUBLIC -DCLIP_ENABLE_LIST_FORMATS=1) +endif() + if(WIN32) option(CLIP_SUPPORT_WINXP "Enable Windows XP support" OFF) diff --git a/README.md b/README.md index 338e90a..8e6b12f 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,18 @@ int main() { - To be able to copy/paste on Linux you need `libx11-dev`/`libX11-devel` package. - To copy/paste images you will need `libpng-dev`/`libpng-devel` package. +## Compilation Flags + +* `CLIP_ENABLE_IMAGE`: Enables the support to + [copy](examples/put_image.cpp)/[paste](examples/show_image.cpp) images. +* `CLIP_ENABLE_LIST_FORMATS` (only for Windows): Enables the + `clip::lock::list_formats()` API function and the + [list_clip_formats](examples/list_clip_formats.cpp) example. +* `CLIP_EXAMPLES`: Compile [examples](examples/). +* `CLIP_TESTS`: Compile [tests](tests/). +* `CLIP_X11_WITH_PNG` (only for Linux/X11): Enables support to + copy/paste images using the `libpng` library on Linux. + ## Who is using this library? [Check the wiki](https://github.com/dacap/clip/wiki#who-is-using-clip) diff --git a/clip.cpp b/clip.cpp index 2058dbe..16ead84 100644 --- a/clip.cpp +++ b/clip.cpp @@ -1,5 +1,5 @@ // Clip Library -// Copyright (c) 2015-2018 David Capello +// Copyright (c) 2015-2024 David Capello // // This file is released under the terms of the MIT license. // Read LICENSE.txt for more information. @@ -72,6 +72,14 @@ bool lock::get_image_spec(image_spec& spec) const { #endif // CLIP_ENABLE_IMAGE +#if CLIP_ENABLE_LIST_FORMATS + +std::vector lock::list_formats() const { + return p->list_formats(); +} + +#endif // CLIP_ENABLE_LIST_FORMATS + format empty_format() { return 0; } format text_format() { return 1; } #if CLIP_ENABLE_IMAGE diff --git a/clip.h b/clip.h index 100ab5f..a6f0913 100644 --- a/clip.h +++ b/clip.h @@ -11,6 +11,7 @@ #include #include #include +#include namespace clip { @@ -21,8 +22,22 @@ namespace clip { // Clipboard format identifier. typedef size_t format; +#if CLIP_ENABLE_IMAGE class image; struct image_spec; +#endif // CLIP_ENABLE_IMAGE + +#if CLIP_ENABLE_LIST_FORMATS + struct format_info { + format id = 0; + std::string name; + format_info(const format id, + const std::string& name) + : id(id), + name(name) { + } + }; +#endif // CLIP_ENABLE_LIST_FORMATS class lock { public: @@ -58,6 +73,12 @@ namespace clip { bool get_image_spec(image_spec& spec) const; #endif // CLIP_ENABLE_IMAGE +#if CLIP_ENABLE_LIST_FORMATS + // Returns the list of available formats (by name) in the + // clipboard. + std::vector list_formats() const; +#endif // CLIP_ENABLE_LIST_FORMATS + private: class impl; std::unique_ptr p; diff --git a/clip_lock_impl.h b/clip_lock_impl.h index 3f08af7..0c678e5 100644 --- a/clip_lock_impl.h +++ b/clip_lock_impl.h @@ -1,5 +1,5 @@ // Clip Library -// Copyright (c) 2015-2018 David Capello +// Copyright (c) 2015-2024 David Capello // // This file is released under the terms of the MIT license. // Read LICENSE.txt for more information. @@ -20,9 +20,16 @@ class lock::impl { bool set_data(format f, const char* buf, size_t len); bool get_data(format f, char* buf, size_t len) const; size_t get_data_length(format f) const; + +#if CLIP_ENABLE_IMAGE bool set_image(const image& image); bool get_image(image& image) const; bool get_image_spec(image_spec& spec) const; +#endif // CLIP_ENABLE_IMAGE + +#if CLIP_ENABLE_LIST_FORMATS + std::vector list_formats() const; +#endif // CLIP_ENABLE_LIST_FORMATS private: bool m_locked; diff --git a/clip_win.cpp b/clip_win.cpp index 09cdfa5..c44d3f6 100644 --- a/clip_win.cpp +++ b/clip_win.cpp @@ -1,5 +1,5 @@ // Clip Library -// Copyright (C) 2015-2020 David Capello +// Copyright (C) 2015-2024 David Capello // // This file is released under the terms of the MIT license. // Read LICENSE.txt for more information. @@ -284,6 +284,46 @@ size_t lock::impl::get_data_length(format f) const { return len; } +#if CLIP_ENABLE_LIST_FORMATS + +std::vector lock::impl::list_formats() const { + static const char* standard_formats[CF_MAX] = { + "", "CF_TEXT", "CF_BITMAP", "CF_METAFILEPICT", + "CF_SYLK", "CF_DIF", "CF_TIFF", "CF_OEMTEXT", + "CF_DIB", "CF_PALETTE", "CF_PENDATA", "CF_RIFF", + "CF_WAVE", "CF_UNICODETEXT", "CF_ENHMETAFILE", "CF_HDROP", + "CF_LOCALE", "CF_DIBV5" + }; + + std::vector formats; + std::vector format_name(512); + + formats.reserve(CountClipboardFormats()); + + UINT format_id = EnumClipboardFormats(0); + while (format_id != 0) { + if (format_id >= CF_TEXT && format_id < CF_MAX) { + // Standard clipboard format + formats.emplace_back(format_id, standard_formats[format_id]); + } + // Get user-defined format name + else { + int size = GetClipboardFormatNameA( + format_id, + format_name.data(), + format_name.size()); + + formats.emplace_back(format_id, std::string(format_name.data(), size)); + } + + format_id = EnumClipboardFormats(format_id); + } + + return formats; +} + +#endif // CLIP_ENABLE_LIST_FORMATS + #if CLIP_ENABLE_IMAGE bool lock::impl::set_image(const image& image) { diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index a53784b..360015c 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -15,3 +15,6 @@ if(CLIP_ENABLE_IMAGE) add_example(put_image) add_example(show_image) endif() +if(CLIP_ENABLE_LIST_FORMATS) + add_example(list_clip_formats) +endif() diff --git a/examples/list_clip_formats.cpp b/examples/list_clip_formats.cpp new file mode 100644 index 0000000..03954ff --- /dev/null +++ b/examples/list_clip_formats.cpp @@ -0,0 +1,12 @@ +// Clip Library +// Copyright (c) 2024 David Capello + +#include "clip.h" +#include + +int main() { + clip::lock l; + for (const clip::format_info& info : l.list_formats()) { + std::cout << "- [" << info.id << "] " << info.name << "\n"; + } +}