| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "remoting/host/clipboard.h" | 5 #include "remoting/host/clipboard.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/process_util.h" | 12 #include "base/process_util.h" |
| 13 #include "base/string16.h" | 13 #include "base/string16.h" |
| 14 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
| 15 #include "base/win/scoped_hglobal.h" | 15 #include "base/win/scoped_hglobal.h" |
| 16 #include "base/win/windows_version.h" | 16 #include "base/win/windows_version.h" |
| 17 #include "base/win/wrapped_window_proc.h" | 17 #include "base/win/wrapped_window_proc.h" |
| 18 #include "remoting/base/constants.h" | 18 #include "remoting/base/constants.h" |
| 19 #include "remoting/proto/event.pb.h" | 19 #include "remoting/proto/event.pb.h" |
| 20 #include "remoting/protocol/clipboard_stub.h" |
| 20 | 21 |
| 21 namespace { | 22 namespace { |
| 22 | 23 |
| 23 const WCHAR kWindowClassName[] = L"clipboardWindowClass"; | 24 const WCHAR kWindowClassName[] = L"clipboardWindowClass"; |
| 24 const WCHAR kWindowName[] = L"clipboardWindow"; | 25 const WCHAR kWindowName[] = L"clipboardWindow"; |
| 25 | 26 |
| 26 // A scoper class that opens and closes the clipboard. | 27 // A scoper class that opens and closes the clipboard. |
| 27 // This class was adapted from the ScopedClipboard class in | 28 // This class was adapted from the ScopedClipboard class in |
| 28 // ui/base/clipboard/clipboard_win.cc. | 29 // ui/base/clipboard/clipboard_win.cc. |
| 29 class ScopedClipboard { | 30 class ScopedClipboard { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 typedef BOOL (WINAPI RemoveClipboardFormatListenerFn)(HWND); | 97 typedef BOOL (WINAPI RemoveClipboardFormatListenerFn)(HWND); |
| 97 | 98 |
| 98 } // namespace | 99 } // namespace |
| 99 | 100 |
| 100 namespace remoting { | 101 namespace remoting { |
| 101 | 102 |
| 102 class ClipboardWin : public Clipboard { | 103 class ClipboardWin : public Clipboard { |
| 103 public: | 104 public: |
| 104 ClipboardWin(); | 105 ClipboardWin(); |
| 105 | 106 |
| 106 virtual void Start() OVERRIDE; | 107 virtual void Start( |
| 108 scoped_ptr<protocol::ClipboardStub> client_clipboard) OVERRIDE; |
| 107 virtual void InjectClipboardEvent( | 109 virtual void InjectClipboardEvent( |
| 108 const protocol::ClipboardEvent& event) OVERRIDE; | 110 const protocol::ClipboardEvent& event) OVERRIDE; |
| 109 virtual void Stop() OVERRIDE; | 111 virtual void Stop() OVERRIDE; |
| 110 | 112 |
| 111 private: | 113 private: |
| 112 void OnClipboardUpdate(); | 114 void OnClipboardUpdate(); |
| 113 bool HaveClipboardListenerApi(); | 115 bool HaveClipboardListenerApi(); |
| 114 | 116 |
| 115 static bool RegisterWindowClass(); | 117 static bool RegisterWindowClass(); |
| 116 static LRESULT CALLBACK WndProc(HWND hwmd, UINT msg, WPARAM wParam, | 118 static LRESULT CALLBACK WndProc(HWND hwmd, UINT msg, WPARAM wParam, |
| 117 LPARAM lParam); | 119 LPARAM lParam); |
| 118 | 120 |
| 121 scoped_ptr<protocol::ClipboardStub> client_clipboard_; |
| 119 HWND hwnd_; | 122 HWND hwnd_; |
| 120 AddClipboardFormatListenerFn* add_clipboard_format_listener_; | 123 AddClipboardFormatListenerFn* add_clipboard_format_listener_; |
| 121 RemoveClipboardFormatListenerFn* remove_clipboard_format_listener_; | 124 RemoveClipboardFormatListenerFn* remove_clipboard_format_listener_; |
| 122 bool load_functions_tried_; | 125 bool load_functions_tried_; |
| 123 | 126 |
| 124 DISALLOW_COPY_AND_ASSIGN(ClipboardWin); | 127 DISALLOW_COPY_AND_ASSIGN(ClipboardWin); |
| 125 }; | 128 }; |
| 126 | 129 |
| 127 ClipboardWin::ClipboardWin() | 130 ClipboardWin::ClipboardWin() |
| 128 : hwnd_(NULL), | 131 : hwnd_(NULL), |
| 129 add_clipboard_format_listener_(NULL), | 132 add_clipboard_format_listener_(NULL), |
| 130 remove_clipboard_format_listener_(NULL), | 133 remove_clipboard_format_listener_(NULL), |
| 131 load_functions_tried_(false) { | 134 load_functions_tried_(false) { |
| 132 } | 135 } |
| 133 | 136 |
| 134 void ClipboardWin::Start() { | 137 void ClipboardWin::Start( |
| 138 scoped_ptr<protocol::ClipboardStub> client_clipboard) { |
| 139 client_clipboard_.swap(client_clipboard); |
| 140 |
| 135 if (!load_functions_tried_) { | 141 if (!load_functions_tried_) { |
| 136 load_functions_tried_ = true; | 142 load_functions_tried_ = true; |
| 137 HMODULE user32_module = ::GetModuleHandle(L"user32.dll"); | 143 HMODULE user32_module = ::GetModuleHandle(L"user32.dll"); |
| 138 if (!user32_module) { | 144 if (!user32_module) { |
| 139 LOG(WARNING) << "Couldn't find user32.dll."; | 145 LOG(WARNING) << "Couldn't find user32.dll."; |
| 140 } else { | 146 } else { |
| 141 add_clipboard_format_listener_ = | 147 add_clipboard_format_listener_ = |
| 142 reinterpret_cast<AddClipboardFormatListenerFn*>( | 148 reinterpret_cast<AddClipboardFormatListenerFn*>( |
| 143 ::GetProcAddress(user32_module, "AddClipboardFormatListener")); | 149 ::GetProcAddress(user32_module, "AddClipboardFormatListener")); |
| 144 remove_clipboard_format_listener_ = | 150 remove_clipboard_format_listener_ = |
| (...skipping 23 matching lines...) Expand all Loading... |
| 168 } | 174 } |
| 169 | 175 |
| 170 if (HaveClipboardListenerApi()) { | 176 if (HaveClipboardListenerApi()) { |
| 171 if (!(*add_clipboard_format_listener_)(hwnd_)) { | 177 if (!(*add_clipboard_format_listener_)(hwnd_)) { |
| 172 LOG(WARNING) << "AddClipboardFormatListener() failed: " << GetLastError(); | 178 LOG(WARNING) << "AddClipboardFormatListener() failed: " << GetLastError(); |
| 173 } | 179 } |
| 174 } | 180 } |
| 175 } | 181 } |
| 176 | 182 |
| 177 void ClipboardWin::Stop() { | 183 void ClipboardWin::Stop() { |
| 184 client_clipboard_.reset(); |
| 185 |
| 178 if (hwnd_) { | 186 if (hwnd_) { |
| 179 if (HaveClipboardListenerApi()) { | 187 if (HaveClipboardListenerApi()) { |
| 180 (*remove_clipboard_format_listener_)(hwnd_); | 188 (*remove_clipboard_format_listener_)(hwnd_); |
| 181 } | 189 } |
| 182 ::DestroyWindow(hwnd_); | 190 ::DestroyWindow(hwnd_); |
| 183 hwnd_ = NULL; | 191 hwnd_ = NULL; |
| 184 } | 192 } |
| 185 } | 193 } |
| 186 | 194 |
| 187 void ClipboardWin::InjectClipboardEvent( | 195 void ClipboardWin::InjectClipboardEvent( |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 LOG(WARNING) << "Couldn't lock clipboard data: " << GetLastError(); | 253 LOG(WARNING) << "Couldn't lock clipboard data: " << GetLastError(); |
| 246 return; | 254 return; |
| 247 } | 255 } |
| 248 text.assign(text_lock.get()); | 256 text.assign(text_lock.get()); |
| 249 } | 257 } |
| 250 | 258 |
| 251 protocol::ClipboardEvent event; | 259 protocol::ClipboardEvent event; |
| 252 event.set_mime_type(kMimeTypeTextUtf8); | 260 event.set_mime_type(kMimeTypeTextUtf8); |
| 253 event.set_data(UTF16ToUTF8(text)); | 261 event.set_data(UTF16ToUTF8(text)); |
| 254 | 262 |
| 255 // TODO(simonmorris): Send the event to the client. | 263 if (client_clipboard_.get()) { |
| 264 client_clipboard_->InjectClipboardEvent(event); |
| 265 } |
| 256 } | 266 } |
| 257 } | 267 } |
| 258 | 268 |
| 259 bool ClipboardWin::HaveClipboardListenerApi() { | 269 bool ClipboardWin::HaveClipboardListenerApi() { |
| 260 return add_clipboard_format_listener_ && remove_clipboard_format_listener_; | 270 return add_clipboard_format_listener_ && remove_clipboard_format_listener_; |
| 261 } | 271 } |
| 262 | 272 |
| 263 bool ClipboardWin::RegisterWindowClass() { | 273 bool ClipboardWin::RegisterWindowClass() { |
| 264 // This method is only called on the UI thread, so it doesn't matter | 274 // This method is only called on the UI thread, so it doesn't matter |
| 265 // that the following test is not thread-safe. | 275 // that the following test is not thread-safe. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 return 0; | 309 return 0; |
| 300 } | 310 } |
| 301 return ::DefWindowProc(hwnd, msg, wparam, lparam); | 311 return ::DefWindowProc(hwnd, msg, wparam, lparam); |
| 302 } | 312 } |
| 303 | 313 |
| 304 scoped_ptr<Clipboard> Clipboard::Create() { | 314 scoped_ptr<Clipboard> Clipboard::Create() { |
| 305 return scoped_ptr<Clipboard>(new ClipboardWin()); | 315 return scoped_ptr<Clipboard>(new ClipboardWin()); |
| 306 } | 316 } |
| 307 | 317 |
| 308 } // namespace remoting | 318 } // namespace remoting |
| OLD | NEW |