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(ui::ClipboardType type) {
    104   uint64 sequence_number = 0;
    105   RenderThreadImpl::current()->Send(
    106       new ClipboardHostMsg_GetSequenceNumber(type, &sequence_number));
    107   return sequence_number;
    108 }
    109 
    110 bool RendererClipboardClient::IsFormatAvailable(
    111     const ui::Clipboard::FormatType& format,
    112     ui::ClipboardType type) {
    113   bool result;
    114   RenderThreadImpl::current()->Send(
    115       new ClipboardHostMsg_IsFormatAvailable(format, type, &result));
    116   return result;
    117 }
    118 
    119 void RendererClipboardClient::Clear(ui::ClipboardType type) {
    120   RenderThreadImpl::current()->Send(new ClipboardHostMsg_Clear(type));
    121 }
    122 
    123 void RendererClipboardClient::ReadAvailableTypes(
    124     ui::ClipboardType type,
    125     std::vector<base::string16>* types,
    126     bool* contains_filenames) {
    127   RenderThreadImpl::current()->Send(new ClipboardHostMsg_ReadAvailableTypes(
    128       type, types, contains_filenames));
    129 }
    130 
    131 void RendererClipboardClient::ReadText(ui::ClipboardType type,
    132                                        base::string16* result) {
    133   RenderThreadImpl::current()->Send(
    134       new ClipboardHostMsg_ReadText(type, result));
    135 }
    136 
    137 void RendererClipboardClient::ReadAsciiText(ui::ClipboardType type,
    138                                             std::string* result) {
    139   RenderThreadImpl::current()->Send(
    140       new ClipboardHostMsg_ReadAsciiText(type, result));
    141 }
    142 
    143 void RendererClipboardClient::ReadHTML(ui::ClipboardType type,
    144                                        base::string16* markup,
    145                                        GURL* url, uint32* fragment_start,
    146                                        uint32* fragment_end) {
    147   RenderThreadImpl::current()->Send(new ClipboardHostMsg_ReadHTML(
    148       type, markup, url, fragment_start, fragment_end));
    149 }
    150 
    151 void RendererClipboardClient::ReadRTF(ui::ClipboardType type,
    152                                       std::string* result) {
    153   RenderThreadImpl::current()->Send(new ClipboardHostMsg_ReadRTF(type, result));
    154 }
    155 
    156 void RendererClipboardClient::ReadImage(ui::ClipboardType type,
    157                                         std::string* data) {
    158   base::SharedMemoryHandle image_handle;
    159   uint32 image_size;
    160   RenderThreadImpl::current()->Send(
    161       new ClipboardHostMsg_ReadImage(type, &image_handle, &image_size));
    162   if (base::SharedMemory::IsHandleValid(image_handle)) {
    163     base::SharedMemory buffer(image_handle, true);
    164     buffer.Map(image_size);
    165     data->append(static_cast<char*>(buffer.memory()), image_size);
    166   }
    167 }
    168 
    169 void RendererClipboardClient::ReadCustomData(ui::ClipboardType clipboard_type,
    170                                              const base::string16& type,
    171                                              base::string16* data) {
    172   RenderThreadImpl::current()->Send(
    173       new ClipboardHostMsg_ReadCustomData(clipboard_type, type, data));
    174 }
    175 
    176 void RendererClipboardClient::ReadData(const ui::Clipboard::FormatType& format,
    177                                        std::string* data) {
    178   RenderThreadImpl::current()->Send(
    179       new ClipboardHostMsg_ReadData(format, data));
    180 }
    181 
    182 ClipboardClient::WriteContext* RendererClipboardClient::CreateWriteContext() {
    183   return new RendererClipboardWriteContext;
    184 }
    185 
    186 }  // namespace content
    187