text: // Clip Library
  // Copyright (c) 2015-2018 David Capello
  //
  // This file is released under the terms of the MIT license.
  // Read LICENSE.txt for more information.
  
  #ifndef CLIP_H_INCLUDED
  #define CLIP_H_INCLUDED
  #pragma once
  
  #include <cassert>
  #include <memory>
  #include <string>
  
  namespace clip {
  
    // ======================================================================
    // Low-level API to lock the clipboard/pasteboard and modify it
    // ======================================================================
  
    // Clipboard format identifier.
    typedef size_t format;
  
    class image;
    struct image_spec;
  
    class lock {
    public:
      // You can give your current HWND as the "native_window_handle."
      // Windows clipboard functions use this handle to open/close
      // (lock/unlock) the clipboard. From the MSDN documentation we
      // need this handler so SetClipboardData() doesn't fail after a
      // EmptyClipboard() call. Anyway it looks to work just fine if we
      // call OpenClipboard() with a null HWND.
      lock(void* native_window_handle = nullptr);
      ~lock();
  
      // Returns true if we've locked the clipboard successfully in
      // lock() constructor.
      bool locked() const;
  
      // Clears the clipboard content. If you don't clear the content,
      // previous clipboard content (in unknown formats) could persist
      // after the unlock.
      bool clear();
  
      // Returns true if the clipboard can be converted to the given
      // format.
      bool is_convertible(format f) const;
      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;
  
      // For images
      bool set_image(const image& image);
      bool get_image(image& image) const;
      bool get_image_spec(image_spec& spec) const;
  
    private:
      class impl;
      std::unique_ptr<impl> p;
    };
  
    format register_format(const std::string& name);
  
    // This format is when the clipboard has no content.
    format empty_format();
  
    // When the clipboard has UTF8 text.
    format text_format();
  
    // When the clipboard has an image.
    format image_format();
  
    // Returns true if the clipboard has content of the given type.
    bool has(format f);
  
    // Clears the clipboard content.
    bool clear();
  
    // ======================================================================
    // Error handling
    // ======================================================================
  
    enum class ErrorCode {
      CannotLock,
      ImageNotSupported,
    };
  
    typedef void (*error_handler)(ErrorCode code);
  
    void set_error_handler(error_handler f);
    error_handler get_error_handler();
  
    // ======================================================================
    // Text
    // ======================================================================
  
    // High-level API to put/get UTF8 text in/from the clipboard. These
    // functions returns false in case of error.
    bool set_text(const std::string& value);
    bool get_text(std::string& value);
  
    // ======================================================================
    // Image
    // ======================================================================
  
    struct image_spec {
      unsigned long width = 0;
      unsigned long height = 0;
      unsigned long bits_per_pixel = 0;
      unsigned long bytes_per_row = 0;
      unsigned long red_mask = 0;
      unsigned long green_mask = 0;
      unsigned long blue_mask = 0;
      unsigned long alpha_mask = 0;
      unsigned long red_shift = 0;
      unsigned long green_shift = 0;
      unsigned long blue_shift = 0;
      unsigned long alpha_shift = 0;
    };
  
    // The image data must contain straight RGB values
    // (non-premultiplied by alpha). The image retrieved from the
    // clipboard will be non-premultiplied too. Basically you will be
    // always dealing with straight alpha images.
    //
    // Details: Windows expects premultiplied images on its clipboard
    // content, so the library code make the proper conversion
    // automatically. macOS handles straight alpha directly, so there is
    // no conversion at all. Linux/X11 images are transferred in
    // image/png format which are specified in straight alpha.
    class image {
    public:
      image();
      image(const image_spec& spec);
      image(const void* data, const image_spec& spec);
      image(const image& image);
      image(image&& image);
      ~image();
  
      image& operator=(const image& image);
      image& operator=(image&& image);
  
      char* data() const { return m_data; }
      const image_spec& spec() const { return m_spec; }
  
      bool is_valid() const { return m_data != nullptr; }
      void reset();
  
    private:
      void copy_image(const image& image);
      void move_image(image&& image);
  
      bool m_own_data;
      char* m_data;
      image_spec m_spec;
    };
  
    // High-level API to set/get an image in/from the clipboard. These
    // functions returns false in case of error.
    bool set_image(const image& img);
    bool get_image(image& img);
    bool get_image_spec(image_spec& spec);
  
    // ======================================================================
    // Platform-specific
    // ======================================================================
  
    // Only for X11: Sets the time (in milliseconds) that we must wait
    // for the selection/clipboard owner to receive the content. This
    // value is 1000 (one second) by default.
    void set_x11_wait_timeout(int msecs);
    int get_x11_wait_timeout();
  
  } // namespace clip
  
  #endif // CLIP_H_INCLUDED
  