Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(236)

Unified Diff: remoting/host/clipboard_win.cc

Issue 10381115: [Chromoting] The Windows IT2Me host gets any new text items it finds on the clipboard. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Reviews. Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « remoting/host/chromoting_host_context.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: remoting/host/clipboard_win.cc
diff --git a/remoting/host/clipboard_win.cc b/remoting/host/clipboard_win.cc
index d812d2f86ba71531f61e339cf41a2de64abf771c..80a70aee48f5b0aebe926c3b0cad8ee4f8f3b9ee 100644
--- a/remoting/host/clipboard_win.cc
+++ b/remoting/host/clipboard_win.cc
@@ -12,6 +12,8 @@
#include "base/process_util.h"
#include "base/string16.h"
#include "base/utf_string_conversions.h"
+#include "base/win/scoped_hglobal.h"
+#include "base/win/windows_version.h"
#include "base/win/wrapped_window_proc.h"
#include "remoting/base/constants.h"
#include "remoting/proto/event.pb.h"
@@ -75,10 +77,24 @@ class ScopedClipboard {
::SetClipboardData(uFormat, hMem);
}
+ // The caller must not free the handle. The caller should lock the handle,
+ // copy the clipboard data, and unlock the handle. All this must be done
+ // before this ScopedClipboard is destroyed.
+ HANDLE GetData(UINT format) {
+ if (!opened_) {
+ NOTREACHED();
+ return NULL;
+ }
+ return ::GetClipboardData(format);
+ }
+
private:
bool opened_;
};
+typedef BOOL (WINAPI AddClipboardFormatListenerFn)(HWND);
+typedef BOOL (WINAPI RemoveClipboardFormatListenerFn)(HWND);
+
} // namespace
namespace remoting {
@@ -93,20 +109,48 @@ class ClipboardWin : public Clipboard {
virtual void Stop() OVERRIDE;
private:
- static LRESULT CALLBACK WndProc(HWND hwmd, UINT msg, WPARAM wParam,
- LPARAM lParam);
+ void OnClipboardUpdate();
static bool RegisterWindowClass();
+ static LRESULT CALLBACK WndProc(HWND hwmd, UINT msg, WPARAM wParam,
+ LPARAM lParam);
HWND hwnd_;
+ AddClipboardFormatListenerFn* add_clipboard_format_listener_;
+ RemoveClipboardFormatListenerFn* remove_clipboard_format_listener_;
+ bool load_functions_tried_;
DISALLOW_COPY_AND_ASSIGN(ClipboardWin);
};
-ClipboardWin::ClipboardWin() : hwnd_(NULL) {
+ClipboardWin::ClipboardWin()
+ : hwnd_(NULL),
+ add_clipboard_format_listener_(NULL),
+ remove_clipboard_format_listener_(NULL),
+ load_functions_tried_(false) {
}
void ClipboardWin::Start() {
+ if (!load_functions_tried_) {
+ load_functions_tried_ = true;
+ HMODULE user32_module = ::GetModuleHandle(L"user32.dll");
alexeypa (please no reviews) 2012/05/11 23:49:17 nit: Presubmit check used to frown on L"" literals
alexeypa (please no reviews) 2012/05/11 23:49:17 nit: I think it make sense to check if GetModuleHa
simonmorris 2012/05/12 00:16:56 Presubmit doesn't complain, and this seems to be t
simonmorris 2012/05/12 00:16:56 Done.
+ add_clipboard_format_listener_ =
+ reinterpret_cast<AddClipboardFormatListenerFn*>(
+ ::GetProcAddress(user32_module, "AddClipboardFormatListener"));
+ remove_clipboard_format_listener_ =
+ reinterpret_cast<RemoveClipboardFormatListenerFn*>(
+ ::GetProcAddress(user32_module, "RemoveClipboardFormatListener"));
+ // We don't expect to load these functions for OS versions before Vista.
+ if (base::win::GetVersion() >= base::win::VERSION_VISTA) {
+ if (!add_clipboard_format_listener_) {
+ LOG(WARNING) << "Couldn't load AddClipboardFormatListener.";
+ }
+ if (!remove_clipboard_format_listener_) {
alexeypa (please no reviews) 2012/05/11 23:49:17 nit: It is highly unlikely, but it is better to re
simonmorris 2012/05/12 00:16:56 Done.
+ LOG(WARNING) << "Couldn't load RemoveClipboardFormatListener.";
+ }
+ }
+ }
+
if (!RegisterWindowClass()) {
LOG(FATAL) << "Couldn't register clipboard window class.";
return;
@@ -122,10 +166,19 @@ void ClipboardWin::Start() {
LOG(FATAL) << "Couldn't create clipboard window.";
return;
}
+
+ if (add_clipboard_format_listener_) {
+ if (!(*add_clipboard_format_listener_)(hwnd_)) {
+ LOG(WARNING) << "AddClipboardFormatListener() failed: " << GetLastError();
+ }
+ }
}
void ClipboardWin::Stop() {
if (hwnd_) {
+ if (add_clipboard_format_listener_ && remove_clipboard_format_listener_) {
alexeypa (please no reviews) 2012/05/11 23:49:17 nit: This check will be simpler if you make sure t
simonmorris 2012/05/12 00:16:56 Done.
+ (*remove_clipboard_format_listener_)(hwnd_);
+ }
::DestroyWindow(hwnd_);
hwnd_ = NULL;
}
@@ -166,9 +219,41 @@ void ClipboardWin::InjectClipboardEvent(
clipboard.SetData(CF_UNICODETEXT, text_global);
}
-LRESULT CALLBACK ClipboardWin::WndProc(HWND hwnd, UINT msg, WPARAM wParam,
- LPARAM lParam) {
- return ::DefWindowProc(hwnd, msg, wParam, lParam);
+void ClipboardWin::OnClipboardUpdate() {
+ DCHECK(hwnd_);
+
+ if (::IsClipboardFormatAvailable(CF_UNICODETEXT)) {
+ string16 text;
+ // Add a scope, so that we keep the clipboard open for as short a time as
+ // possible.
+ {
+ ScopedClipboard clipboard;
+ if (!clipboard.Init(hwnd_)) {
+ LOG(WARNING) << "Couldn't open the clipboard." << GetLastError();
+ return;
+ }
+
+ HGLOBAL text_global = clipboard.GetData(CF_UNICODETEXT);
+ if (!text_global) {
+ LOG(WARNING) << "Couldn't get data from the clipboard: "
+ << GetLastError();
+ return;
+ }
+
+ base::win::ScopedHGlobal<WCHAR> text_lock(text_global);
+ if (!text_lock.get()) {
+ LOG(WARNING) << "Couldn't lock clipboard data: " << GetLastError();
+ return;
+ }
+ text.assign(text_lock.get());
+ }
+
+ protocol::ClipboardEvent event;
+ event.set_mime_type(kMimeTypeTextUtf8);
+ event.set_data(UTF16ToUTF8(text));
+
+ // TODO(simonmorris): Send the event to the client.
+ }
}
bool ClipboardWin::RegisterWindowClass() {
@@ -193,6 +278,25 @@ bool ClipboardWin::RegisterWindowClass() {
return true;
}
+LRESULT CALLBACK ClipboardWin::WndProc(HWND hwnd, UINT msg, WPARAM wparam,
+ LPARAM lparam) {
+ if (msg == WM_CREATE) {
+ CREATESTRUCT* cs = reinterpret_cast<CREATESTRUCT*>(lparam);
+ ::SetWindowLongPtr(hwnd,
+ GWLP_USERDATA,
+ reinterpret_cast<LONG_PTR>(cs->lpCreateParams));
+ return 0;
+ }
+ ClipboardWin* clipboard =
+ reinterpret_cast<ClipboardWin*>(::GetWindowLongPtr(hwnd, GWLP_USERDATA));
+ switch (msg) {
+ case WM_CLIPBOARDUPDATE:
+ clipboard->OnClipboardUpdate();
+ return 0;
+ }
+ return ::DefWindowProc(hwnd, msg, wparam, lparam);
+}
+
scoped_ptr<Clipboard> Clipboard::Create() {
return scoped_ptr<Clipboard>(new ClipboardWin());
}
« no previous file with comments | « remoting/host/chromoting_host_context.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698