Home | History | Annotate | Download | only in renderer
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // This file provides the embedder's side of the Clipboard interface.
      6 
      7 #include "content/renderer/renderer_clipboard_client.h"
      8 
      9 #include "base/memory/shared_memory.h"
     10 #include "base/strings/string16.h"
     11 #include "content/common/clipboard_messages.h"
     12 #include "content/public/renderer/content_renderer_client.h"
     13 #include "content/renderer/render_thread_impl.h"
     14 #include "content/renderer/scoped_clipboard_writer_glue.h"
     15 #include "ui/base/clipboard/clipboard.h"
     16 #include "ui/gfx/size.h"
     17 
     18 namespace content {
     19 
     20 namespace {
     21 
     22 class RendererClipboardWriteContext : public ClipboardClient::WriteContext {
     23  public:
     24   RendererClipboardWriteContext();
     25   virtual ~RendererClipboardWriteContext();
     26   virtual void WriteBitmapFromPixels(ui::Clipboard::ObjectMap* objects,
     27                                      const void* pixels,
     28                                      const gfx::Size& size) OVERRIDE;
     29   virtual void Flush(const ui::Clipboard::ObjectMap& objects) OVERRIDE;
     30 
     31  private:
     32   scoped_ptr<base::SharedMemory> shared_buf_;
     33   DISALLOW_COPY_AND_ASSIGN(RendererClipboardWriteContext);
     34 };
     35 
     36 RendererClipboardWriteContext::RendererClipboardWriteContext() {
     37 }
     38 
     39 RendererClipboardWriteContext::~RendererClipboardWriteContext() {
     40 }
     41 
     42 // This definition of WriteBitmapFromPixels uses shared memory to communicate
     43 // across processes.
     44 void RendererClipboardWriteContext::WriteBitmapFromPixels(
     45     ui::Clipboard::ObjectMap* objects,
     46     const void* pixels,
     47     const gfx::Size& size) {
     48   // Do not try to write a bitmap more than once
     49   if (shared_buf_)
     50     return;
     51 
     52   uint32 buf_size = 4 * size.width() * size.height();
     53 
     54   // Allocate a shared memory buffer to hold the bitmap bits.
     55   shared_buf_.reset(ChildThread::current()->AllocateSharedMemory(buf_size));
     56   if (!shared_buf_)
     57     return;
     58 
     59   // Copy the bits into shared memory
     60   DCHECK(shared_buf_->memory());
     61   memcpy(shared_buf_->memory(), pixels, buf_size);
     62   shared_buf_->Unmap();
     63 
     64   ui::Clipboard::ObjectMapParam size_param;
     65   const char* size_data = reinterpret_cast<const char*>(&size);
     66   for (size_t i = 0; i < sizeof(gfx::Size); ++i)
     67     size_param.push_back(size_data[i]);
     68 
     69   ui::Clipboard::ObjectMapParams params;
     70 
     71   // The first parameter is replaced on the receiving end with a pointer to
     72   // a shared memory object containing the bitmap. We reserve space for it here.
     73   ui::Clipboard::ObjectMapParam place_holder_param;
     74   params.push_back(place_holder_param);
     75   params.push_back(size_param);
     76   (*objects)[ui::Clipboard::CBF_SMBITMAP] = params;
     77 }
     78 
     79 // Flushes the objects to the clipboard with an IPC.
     80 void RendererClipboardWriteContext::Flush(
     81     const ui::Clipboard::ObjectMap& objects) {
     82   if (shared_buf_) {
     83     RenderThreadImpl::current()->Send(
     84         new ClipboardHostMsg_WriteObjectsSync(objects, shared_buf_->handle()));
     85   } else {
     86     RenderThreadImpl::current()->Send(
     87         new ClipboardHostMsg_WriteObjectsAsync(objects));
     88   }
     89 }
     90 
     91 }  // anonymous namespace
     92 
     93 RendererClipboardClient::RendererClipboardClient() {
     94 }
     95 
     96 RendererClipboardClient::~RendererClipboardClient() {
     97 }
     98 
     99 ui::Clipboard* RendererClipboardClient::GetClipboard() {
    100   return NULL;
    101 }
    102 
    103 uint64 RendererClipboardClient::GetSequenceNumber(
    104     ui::Clipboard::Buffer buffer) {
    105   uint64 sequence_number = 0;
    106   RenderThreadImpl::current()->Send(
    107       new ClipboardHostMsg_GetSequenceNumber(buffer,
    108                                              &sequence_number));
    109   return sequence_number;
    110 }
    111 
    112 bool RendererClipboardClient::IsFormatAvailable(
    113     const ui::Clipboard::FormatType& format,
    114     ui::Clipboard::Buffer buffer) {
    115   bool result;
    116   RenderThreadImpl::current()->Send(
    117       new ClipboardHostMsg_IsFormatAvailable(format, buffer, &result));
    118   return result;
    119 }
    120 
    121 void RendererClipboardClient::Clear(ui::Clipboard::Buffer buffer) {
    122   RenderThreadImpl::current()->Send(new ClipboardHostMsg_Clear(buffer));
    123 }
    124 
    125 void RendererClipboardClient::ReadAvailableTypes(
    126     ui::Clipboard::Buffer buffer,
    127     std::vector<string16>* types,
    128     bool* contains_filenames) {
    129   RenderThreadImpl::current()->Send(new ClipboardHostMsg_ReadAvailableTypes(
    130       buffer, types, contains_filenames));
    131 }
    132 
    133 void RendererClipboardClient::ReadText(ui::Clipboard::Buffer buffer,
    134                                        string16* result) {
    135   RenderThreadImpl::current()->Send(
    136       new ClipboardHostMsg_ReadText(buffer, result));
    137 }
    138 
    139 void RendererClipboardClient::ReadAsciiText(ui::Clipboard::Buffer buffer,
    140                                             std::string* result) {
    141   RenderThreadImpl::current()->Send(
    142       new ClipboardHostMsg_ReadAsciiText(buffer, result));
    143 }
    144 
    145 void RendererClipboardClient::ReadHTML(ui::Clipboard::Buffer buffer,
    146                                        string16* markup,
    147                                        GURL* url, uint32* fragment_start,
    148                                        uint32* fragment_end) {
    149   RenderThreadImpl::current()->Send(
    150       new ClipboardHostMsg_ReadHTML(buffer, markup, url, fragment_start,
    151                                     fragment_end));
    152 }
    153 
    154 void RendererClipboardClient::ReadRTF(ui::Clipboard::Buffer buffer,
    155                                       std::string* result) {
    156   RenderThreadImpl::current()->Send(
    157       new ClipboardHostMsg_ReadRTF(buffer, result));
    158 }
    159 
    160 void RendererClipboardClient::ReadImage(ui::Clipboard::Buffer buffer,
    161                                         std::string* data) {
    162   base::SharedMemoryHandle image_handle;
    163   uint32 image_size;
    164   RenderThreadImpl::current()->Send(
    165       new ClipboardHostMsg_ReadImage(buffer, &image_handle, &image_size));
    166   if (base::SharedMemory::IsHandleValid(image_handle)) {
    167     base::SharedMemory buffer(image_handle, true);
    168     buffer.Map(image_size);
    169     data->append(static_cast<char*>(buffer.memory()), image_size);
    170   }
    171 }
    172 
    173 void RendererClipboardClient::ReadCustomData(ui::Clipboard::Buffer buffer,
    174                                              const string16& type,
    175                                              string16* data) {
    176   RenderThreadImpl::current()->Send(
    177       new ClipboardHostMsg_ReadCustomData(buffer, type, data));
    178 }
    179 
    180 void RendererClipboardClient::ReadData(const ui::Clipboard::FormatType& format,
    181                                        std::string* data) {
    182   RenderThreadImpl::current()->Send(
    183       new ClipboardHostMsg_ReadData(format, data));
    184 }
    185 
    186 ClipboardClient::WriteContext* RendererClipboardClient::CreateWriteContext() {
    187   return new RendererClipboardWriteContext;
    188 }
    189 
    190 }  // namespace content
    191