blob: 570bec96aadd861cd6619c83a960bec9a299bdd5 [file] [log] [blame]
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef APP_CLIPBOARD_CLIPBOARD_H_
#define APP_CLIPBOARD_CLIPBOARD_H_
#pragma once
#include <map>
#include <string>
#include <vector>
#include "base/gtest_prod_util.h"
#include "base/process.h"
#include "base/shared_memory.h"
#include "base/string16.h"
namespace gfx {
class Size;
}
class FilePath;
class Clipboard {
public:
typedef std::string FormatType;
// ObjectType designates the type of data to be stored in the clipboard. This
// designation is shared across all OSes. The system-specific designation
// is defined by FormatType. A single ObjectType might be represented by
// several system-specific FormatTypes. For example, on Linux the CBF_TEXT
// ObjectType maps to "text/plain", "STRING", and several other formats. On
// windows it maps to CF_UNICODETEXT.
enum ObjectType {
CBF_TEXT,
CBF_HTML,
CBF_BOOKMARK,
CBF_FILES,
CBF_WEBKIT,
CBF_BITMAP,
CBF_SMBITMAP, // Bitmap from shared memory.
CBF_DATA, // Arbitrary block of bytes.
};
// ObjectMap is a map from ObjectType to associated data.
// The data is organized differently for each ObjectType. The following
// table summarizes what kind of data is stored for each key.
// * indicates an optional argument.
//
// Key Arguments Type
// -------------------------------------
// CBF_TEXT text char array
// CBF_HTML html char array
// url* char array
// CBF_BOOKMARK html char array
// url char array
// CBF_LINK html char array
// url char array
// CBF_FILES files char array representing multiple files.
// Filenames are separated by null characters and
// the final filename is double null terminated.
// The filenames are encoded in platform-specific
// encoding.
// CBF_WEBKIT none empty vector
// CBF_BITMAP pixels byte array
// size gfx::Size struct
// CBF_SMBITMAP shared_mem A pointer to an unmapped base::SharedMemory
// object containing the bitmap data.
// size gfx::Size struct
// CBF_DATA format char array
// data byte array
typedef std::vector<char> ObjectMapParam;
typedef std::vector<ObjectMapParam> ObjectMapParams;
typedef std::map<int /* ObjectType */, ObjectMapParams> ObjectMap;
// Buffer designates which clipboard the action should be applied to.
// Only platforms that use the X Window System support the selection
// buffer. Furthermore we currently only use a buffer other than the
// standard buffer when reading from the clipboard so only those
// functions accept a buffer parameter.
enum Buffer {
BUFFER_STANDARD,
BUFFER_SELECTION,
BUFFER_DRAG,
};
static bool IsValidBuffer(int32 buffer) {
switch (buffer) {
case BUFFER_STANDARD:
return true;
#if defined(USE_X11)
case BUFFER_SELECTION:
return true;
#endif
case BUFFER_DRAG:
return true;
}
return false;
}
static Buffer FromInt(int32 buffer) {
return static_cast<Buffer>(buffer);
}
Clipboard();
~Clipboard();
// Write a bunch of objects to the system clipboard. Copies are made of the
// contents of |objects|. On Windows they are copied to the system clipboard.
// On linux they are copied into a structure owned by the Clipboard object and
// kept until the system clipboard is set again.
void WriteObjects(const ObjectMap& objects);
// Behaves as above. If there is some shared memory handle passed as one of
// the objects, it came from the process designated by |process|. This will
// assist in turning it into a shared memory region that the current process
// can use.
void WriteObjects(const ObjectMap& objects, base::ProcessHandle process);
// On Linux/BSD, we need to know when the clipboard is set to a URL. Most
// platforms don't care.
#if defined(OS_WIN) || defined(OS_MACOSX)
void DidWriteURL(const std::string& utf8_text) {}
#else // !defined(OS_WIN) && !defined(OS_MACOSX)
void DidWriteURL(const std::string& utf8_text);
#endif
// Tests whether the clipboard contains a certain format
bool IsFormatAvailable(const FormatType& format, Buffer buffer) const;
// As above, but instead of interpreting |format| by some platform-specific
// definition, interpret it as a literal MIME type.
bool IsFormatAvailableByString(const std::string& format,
Buffer buffer) const;
// Reads UNICODE text from the clipboard, if available.
void ReadText(Buffer buffer, string16* result) const;
// Reads ASCII text from the clipboard, if available.
void ReadAsciiText(Buffer buffer, std::string* result) const;
// Reads HTML from the clipboard, if available.
void ReadHTML(Buffer buffer, string16* markup, std::string* src_url) const;
// Reads a bookmark from the clipboard, if available.
void ReadBookmark(string16* title, std::string* url) const;
// Reads a file or group of files from the clipboard, if available, into the
// out parameter.
void ReadFile(FilePath* file) const;
void ReadFiles(std::vector<FilePath>* files) const;
// Reads raw data from the clipboard with the given format type. Stores result
// as a byte vector.
// TODO(dcheng): Due to platform limitations on Windows, we should make sure
// format is never controlled by the user.
void ReadData(const std::string& format, std::string* result);
// Get format Identifiers for various types.
static FormatType GetUrlFormatType();
static FormatType GetUrlWFormatType();
static FormatType GetMozUrlFormatType();
static FormatType GetPlainTextFormatType();
static FormatType GetPlainTextWFormatType();
static FormatType GetFilenameFormatType();
static FormatType GetFilenameWFormatType();
static FormatType GetWebKitSmartPasteFormatType();
// Win: MS HTML Format, Other: Generic HTML format
static FormatType GetHtmlFormatType();
static FormatType GetBitmapFormatType();
// Embeds a pointer to a SharedMemory object pointed to by |bitmap_handle|
// belonging to |process| into a shared bitmap [CBF_SMBITMAP] slot in
// |objects|. The pointer is deleted by DispatchObjects().
//
// On non-Windows platforms, |process| is ignored.
static void ReplaceSharedMemHandle(ObjectMap* objects,
base::SharedMemoryHandle bitmap_handle,
base::ProcessHandle process);
#if defined(OS_WIN)
// Firefox text/html
static FormatType GetTextHtmlFormatType();
static FormatType GetCFHDropFormatType();
static FormatType GetFileDescriptorFormatType();
static FormatType GetFileContentFormatZeroType();
#endif
private:
FRIEND_TEST_ALL_PREFIXES(ClipboardTest, SharedBitmapTest);
void DispatchObject(ObjectType type, const ObjectMapParams& params);
void WriteText(const char* text_data, size_t text_len);
void WriteHTML(const char* markup_data,
size_t markup_len,
const char* url_data,
size_t url_len);
void WriteBookmark(const char* title_data,
size_t title_len,
const char* url_data,
size_t url_len);
void WriteWebSmartPaste();
void WriteBitmap(const char* pixel_data, const char* size_data);
#if !defined(OS_MACOSX)
// |format_name| is an ASCII string and should be NULL-terminated.
// TODO(estade): port to mac.
void WriteData(const char* format_name, size_t format_len,
const char* data_data, size_t data_len);
#endif
#if defined(OS_WIN)
void WriteBitmapFromHandle(HBITMAP source_hbitmap,
const gfx::Size& size);
// Safely write to system clipboard. Free |handle| on failure.
void WriteToClipboard(unsigned int format, HANDLE handle);
static void ParseBookmarkClipboardFormat(const string16& bookmark,
string16* title,
std::string* url);
// Free a handle depending on its type (as intuited from format)
static void FreeData(unsigned int format, HANDLE data);
// Return the window that should be the clipboard owner, creating it
// if neccessary. Marked const for lazily initialization by const methods.
HWND GetClipboardWindow() const;
// Mark this as mutable so const methods can still do lazy initialization.
mutable HWND clipboard_owner_;
// True if we can create a window.
bool create_window_;
#elif !defined(OS_MACOSX)
// The public API is via WriteObjects() which dispatches to multiple
// Write*() calls, but on GTK we must write all the clipboard types
// in a single GTK call. To support this we store the current set
// of data we intend to put on the clipboard on clipboard_data_ as
// WriteObjects is running, and then at the end call SetGtkClipboard
// which replaces whatever is on the system clipboard with the
// contents of clipboard_data_.
public:
typedef std::map<FormatType, std::pair<char*, size_t> > TargetMap;
private:
typedef struct _GtkClipboard GtkClipboard;
// Write changes to gtk clipboard.
void SetGtkClipboard();
// Insert a mapping into clipboard_data_.
void InsertMapping(const char* key, char* data, size_t data_len);
// Find the gtk clipboard for the passed buffer enum.
GtkClipboard* LookupBackingClipboard(Buffer clipboard) const;
TargetMap* clipboard_data_;
GtkClipboard* clipboard_;
GtkClipboard* primary_selection_;
#endif
DISALLOW_COPY_AND_ASSIGN(Clipboard);
};
#endif // APP_CLIPBOARD_CLIPBOARD_H_