summaryrefslogtreecommitdiffstats
path: root/app/clipboard/clipboard.h
blob: faaa00cd9f96bef1582c041ad3fdd03d4ea89641 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
// 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_

#include <map>
#include <string>
#include <vector>

#include "base/process.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   shared memory handle
  //               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,
#if defined(USE_X11)
    BUFFER_SELECTION,
#endif
  };

  static bool IsValidBuffer(int32 buffer) {
    switch (buffer) {
      case BUFFER_STANDARD:
        return true;
#if defined(USE_X11)
      case BUFFER_SELECTION:
        return true;
#endif
    }
    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.
  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();
#if defined(OS_WIN)
  static FormatType GetBitmapFormatType();
  // Firefox text/html
  static FormatType GetTextHtmlFormatType();
  static FormatType GetCFHDropFormatType();
  static FormatType GetFileDescriptorFormatType();
  static FormatType GetFileContentFormatZeroType();

  // Duplicates any remote shared memory handle embedded inside |objects| that
  // was created by |process| so that it can be used by this process.
  static void DuplicateRemoteHandles(base::ProcessHandle process,
                                     ObjectMap* objects);
#endif

 private:
  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 WriteBitmapFromSharedMemory(const char* bitmap_data,
                                   const char* size_data,
                                   base::ProcessHandle handle);

  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_