• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 The Flutter 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 #include "flutter/shell/platform/windows/platform_handler.h"
6 
7 #include <windows.h>
8 
9 #include <iostream>
10 
11 #include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/json_method_codec.h"
12 
13 static constexpr char kChannelName[] = "flutter/platform";
14 
15 static constexpr char kGetClipboardDataMethod[] = "Clipboard.getData";
16 static constexpr char kSetClipboardDataMethod[] = "Clipboard.setData";
17 
18 static constexpr char kTextPlainFormat[] = "text/plain";
19 static constexpr char kTextKey[] = "text";
20 
21 static constexpr char kUnknownClipboardFormatError[] =
22     "Unknown clipboard format error";
23 
24 namespace flutter {
25 
PlatformHandler(flutter::BinaryMessenger * messenger,Win32FlutterWindow * window)26 PlatformHandler::PlatformHandler(flutter::BinaryMessenger* messenger,
27                                  Win32FlutterWindow* window)
28     : channel_(std::make_unique<flutter::MethodChannel<rapidjson::Document>>(
29           messenger,
30           kChannelName,
31           &flutter::JsonMethodCodec::GetInstance())),
32       window_(window) {
33   channel_->SetMethodCallHandler(
34       [this](
35           const flutter::MethodCall<rapidjson::Document>& call,
36           std::unique_ptr<flutter::MethodResult<rapidjson::Document>> result) {
37         HandleMethodCall(call, std::move(result));
38       });
39 }
40 
HandleMethodCall(const flutter::MethodCall<rapidjson::Document> & method_call,std::unique_ptr<flutter::MethodResult<rapidjson::Document>> result)41 void PlatformHandler::HandleMethodCall(
42     const flutter::MethodCall<rapidjson::Document>& method_call,
43     std::unique_ptr<flutter::MethodResult<rapidjson::Document>> result) {
44   const std::string& method = method_call.method_name();
45   if (method.compare(kGetClipboardDataMethod) == 0) {
46     // Only one string argument is expected.
47     const rapidjson::Value& format = method_call.arguments()[0];
48 
49     if (strcmp(format.GetString(), kTextPlainFormat) != 0) {
50       result->Error(kUnknownClipboardFormatError,
51                     "Windows clipboard API only supports text.");
52       return;
53     }
54 
55     auto clipboardData = GetClipboardString();
56 
57     if (clipboardData.empty()) {
58       result->Error(kUnknownClipboardFormatError,
59                     "Failed to retrieve clipboard data from win32 api.");
60       return;
61     }
62     rapidjson::Document document;
63     document.SetObject();
64     rapidjson::Document::AllocatorType& allocator = document.GetAllocator();
65     document.AddMember(rapidjson::Value(kTextKey, allocator),
66                        rapidjson::Value(clipboardData, allocator), allocator);
67     result->Success(&document);
68 
69   } else if (method.compare(kSetClipboardDataMethod) == 0) {
70     const rapidjson::Value& document = *method_call.arguments();
71     rapidjson::Value::ConstMemberIterator itr = document.FindMember(kTextKey);
72     if (itr == document.MemberEnd()) {
73       result->Error(kUnknownClipboardFormatError,
74                     "Missing text to store on clipboard.");
75       return;
76     }
77     SetClipboardString(std::string(itr->value.GetString()));
78     result->Success();
79   } else {
80     result->NotImplemented();
81   }
82 }
83 
GetClipboardString()84 std::string PlatformHandler::GetClipboardString() {
85   if (!OpenClipboard(nullptr)) {
86     return nullptr;
87   }
88 
89   HANDLE data = GetClipboardData(CF_TEXT);
90   if (data == nullptr) {
91     CloseClipboard();
92     return nullptr;
93   }
94 
95   const char* clipboardData = static_cast<char*>(GlobalLock(data));
96 
97   if (clipboardData == nullptr) {
98     CloseClipboard();
99     return nullptr;
100   }
101 
102   auto result = std::string(clipboardData);
103   GlobalUnlock(data);
104   CloseClipboard();
105   return result;
106 }
107 
SetClipboardString(std::string data)108 void PlatformHandler::SetClipboardString(std::string data) {
109   if (!OpenClipboard(nullptr)) {
110     return;
111   }
112 
113   auto htext = GlobalAlloc(GMEM_MOVEABLE, data.size());
114 
115   memcpy(GlobalLock(htext), data.c_str(), data.size());
116 
117   SetClipboardData(CF_TEXT, htext);
118 
119   CloseClipboard();
120 }
121 
122 }  // namespace flutter
123