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

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: 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
Index: remoting/host/clipboard_win.cc
diff --git a/remoting/host/clipboard_win.cc b/remoting/host/clipboard_win.cc
index d812d2f86ba71531f61e339cf41a2de64abf771c..0a4c8d24b4733a9ad08155cb69139992913f5db6 100644
--- a/remoting/host/clipboard_win.cc
+++ b/remoting/host/clipboard_win.cc
@@ -75,10 +75,47 @@ 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 uFormat) {
dcheng 2012/05/11 20:28:31 u_format or just format.
alexeypa (please no reviews) 2012/05/11 20:42:37 |uFormat| -> |format|
simonmorris 2012/05/11 22:12:58 Done.
simonmorris 2012/05/11 22:12:58 Done.
+ if (!opened_) {
+ NOTREACHED();
+ return NULL;
+ }
+ return ::GetClipboardData(uFormat);
+ }
+
private:
bool opened_;
};
+// A scoper class that wraps a lock on a global memory object.
+template <typename T>
+class ScopedGlobalLock {
dcheng 2012/05/11 20:28:31 Can you use ScopedHGlobalfrom base/win?
simonmorris 2012/05/11 22:12:58 Done.
+ public:
+ ScopedGlobalLock(HGLOBAL hGlobalMem) : hGlobalMem_(hGlobalMem) {
alexeypa (please no reviews) 2012/05/11 20:42:37 explicit
alexeypa (please no reviews) 2012/05/11 20:42:37 hGlobalMem -> global_mem. Same thing for the data
simonmorris 2012/05/11 22:12:58 Removed code.
simonmorris 2012/05/11 22:12:58 Removed code.
+ pointer_ = ::GlobalLock(hGlobalMem_);
alexeypa (please no reviews) 2012/05/11 20:42:37 Validate that the handle is valid. The check shoul
simonmorris 2012/05/11 22:12:58 Removed code.
+ }
+
+ ~ScopedGlobalLock() {
+ if (pointer_) {
+ ::GlobalUnlock(hGlobalMem_);
+ }
+ }
+
+ T GetPointer() {
alexeypa (please no reviews) 2012/05/11 20:42:37 This is the only place where T is needed. WDYT abo
simonmorris 2012/05/11 22:12:58 Removed code.
+ return reinterpret_cast<T>(pointer_);
+ }
+
+ private:
+ HGLOBAL hGlobalMem_;
alexeypa (please no reviews) 2012/05/11 20:42:37 Make it non-copyable.
simonmorris 2012/05/11 22:12:58 Removed code.
+ LPVOID pointer_;
+};
+
+typedef BOOL (WINAPI AddClipboardFormatListenerFn)(HWND);
+typedef BOOL (WINAPI RemoveClipboardFormatListenerFn)(HWND);
+
} // namespace
namespace remoting {
@@ -98,6 +135,8 @@ class ClipboardWin : public Clipboard {
static bool RegisterWindowClass();
+ void OnClipboardUpdate();
alexeypa (please no reviews) 2012/05/11 20:42:37 nit: I tend to put static members last. I'm not su
simonmorris 2012/05/11 22:12:58 Done.
+
HWND hwnd_;
DISALLOW_COPY_AND_ASSIGN(ClipboardWin);
@@ -122,10 +161,29 @@ void ClipboardWin::Start() {
LOG(FATAL) << "Couldn't create clipboard window.";
return;
}
+
+ AddClipboardFormatListenerFn* add =
+ reinterpret_cast<AddClipboardFormatListenerFn*>(
+ ::GetProcAddress(::GetModuleHandle(L"user32.dll"),
alexeypa (please no reviews) 2012/05/11 20:42:37 GetModuleHandle will increment the library referen
simonmorris 2012/05/11 22:12:58 <http://msdn.microsoft.com/en-us/library/windows/d
alexeypa (please no reviews) 2012/05/11 23:49:17 Oops. Yes, indeed. It is actually GetModuleHandleE
+ "AddClipboardFormatListener"));
+ if (add) {
+ if (!(*add)(hwnd_)) {
+ LOG(WARNING) << "AddClipboardFormatListener() failed: " << GetLastError();
+ }
+ } else {
+ LOG(WARNING) << "AddClipboardFormatListener() couldn't be loaded.";
alexeypa (please no reviews) 2012/05/11 20:42:37 This will pollute logs. We should complain in the
simonmorris 2012/05/11 22:12:58 Done (assuming you meant "greater than Vista".)
alexeypa (please no reviews) 2012/05/11 23:49:17 Yes, I meant that.
simonmorris 2012/05/12 00:16:56 I don't agree. It means something went surprisingl
alexeypa (please no reviews) 2012/05/15 15:34:59 Yes, I agree with this part. I was concerned abou
+ }
}
void ClipboardWin::Stop() {
if (hwnd_) {
+ RemoveClipboardFormatListenerFn* remove =
+ reinterpret_cast<RemoveClipboardFormatListenerFn*>(
+ ::GetProcAddress(::GetModuleHandle(L"user32.dll"),
+ "RemoveClipboardFormatListener"));
+ if (remove) {
+ (*remove)(hwnd_);
alexeypa (please no reviews) 2012/05/11 20:42:37 This should be called only if the Add function was
simonmorris 2012/05/11 22:12:58 Done.
+ }
::DestroyWindow(hwnd_);
hwnd_ = NULL;
}
@@ -168,6 +226,20 @@ void ClipboardWin::InjectClipboardEvent(
LRESULT CALLBACK ClipboardWin::WndProc(HWND hwnd, UINT msg, WPARAM wParam,
LPARAM lParam) {
+ if (msg == WM_CREATE) {
+ CREATESTRUCT* cs = reinterpret_cast<CREATESTRUCT*>(lParam);
dcheng 2012/05/11 20:28:31 avar or a_var instead of aVar.
simonmorris 2012/05/11 22:12:58 Done.
+ ::SetWindowLongPtr(hwnd,
+ GWLP_USERDATA,
+ reinterpret_cast<LONG_PTR>(cs->lpCreateParams));
+ return 0;
+ }
+ ClipboardWin* clipboardWin =
alexeypa (please no reviews) 2012/05/11 20:42:37 |clipboard_win|, or, maybe, simply |clipboard|
simonmorris 2012/05/11 22:12:58 Done.
+ reinterpret_cast<ClipboardWin*>(::GetWindowLongPtr(hwnd, GWLP_USERDATA));
+ switch (msg) {
+ case WM_CLIPBOARDUPDATE:
+ clipboardWin->OnClipboardUpdate();
+ return 0;
+ }
return ::DefWindowProc(hwnd, msg, wParam, lParam);
}
@@ -193,6 +265,46 @@ bool ClipboardWin::RegisterWindowClass() {
return true;
}
+void ClipboardWin::OnClipboardUpdate() {
+ if (!hwnd_) {
alexeypa (please no reviews) 2012/05/11 20:42:37 Make it a DCHECK. I don't think there is a way to
simonmorris 2012/05/11 22:12:58 Done.
+ return;
+ }
+
+ 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;
+ }
+
+ ScopedGlobalLock<LPWSTR> text_lock(text_global);
+ if (!text_lock.GetPointer()) {
+ LOG(WARNING) << "Couldn't lock clipboard data: " << GetLastError();
+ return;
+ }
+ string16 text_temp(text_lock.GetPointer());
dcheng 2012/05/11 20:28:31 You can just use assign instead of swapping.
simonmorris 2012/05/11 22:12:58 Done.
+ text.swap(text_temp);
alexeypa (please no reviews) 2012/05/11 20:42:37 I don't think text.swap buys anything here. text c
simonmorris 2012/05/11 22:12:58 Done.
+ }
+
+ protocol::ClipboardEvent event;
+ event.set_mime_type(kMimeTypeTextUtf8);
+ event.set_data(UTF16ToUTF8(text));
+
+ // TODO(simonmorris): Send the event to the client.
+ }
+}
+
scoped_ptr<Clipboard> Clipboard::Create() {
return scoped_ptr<Clipboard>(new ClipboardWin());
}
« remoting/host/chromoting_host_context.cc ('K') | « remoting/host/chromoting_host_context.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698