]> git.sesse.net Git - casparcg/blobdiff - dependencies64/cef/windows/tests/shared/browser/main_message_loop_external_pump_win.cc
Upgrade CEF to 3.3029.1611.g44e39a8 / Chromium 58.0.3029.81.
[casparcg] / dependencies64 / cef / windows / tests / shared / browser / main_message_loop_external_pump_win.cc
diff --git a/dependencies64/cef/windows/tests/shared/browser/main_message_loop_external_pump_win.cc b/dependencies64/cef/windows/tests/shared/browser/main_message_loop_external_pump_win.cc
new file mode 100644 (file)
index 0000000..6df4237
--- /dev/null
@@ -0,0 +1,149 @@
+// Copyright (c) 2016 The Chromium Embedded Framework Authors. All rights
+// reserved. Use of this source code is governed by a BSD-style license that
+// can be found in the LICENSE file.
+
+#include "tests/shared/browser/main_message_loop_external_pump.h"
+
+#include <CommCtrl.h>
+
+#include "include/cef_app.h"
+#include "tests/shared/browser/util_win.h"
+
+namespace client {
+
+namespace {
+
+// Message sent to get an additional time slice for pumping (processing) another
+// task (a series of such messages creates a continuous task pump).
+static const int kMsgHaveWork = WM_USER + 1;
+
+class MainMessageLoopExternalPumpWin : public MainMessageLoopExternalPump {
+ public:
+  MainMessageLoopExternalPumpWin();
+  ~MainMessageLoopExternalPumpWin();
+
+  // MainMessageLoopStd methods:
+  void Quit() OVERRIDE;
+  int Run() OVERRIDE;
+
+  // MainMessageLoopExternalPump methods:
+  void OnScheduleMessagePumpWork(int64 delay_ms) OVERRIDE;
+
+ protected:
+  // MainMessageLoopExternalPump methods:
+  void SetTimer(int64 delay_ms) OVERRIDE;
+  void KillTimer() OVERRIDE;
+  bool IsTimerPending() OVERRIDE { return timer_pending_; }
+
+ private:
+  static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam,
+                                  LPARAM lparam);
+
+  // True if a timer event is currently pending.
+  bool timer_pending_;
+
+  // HWND owned by the thread that CefDoMessageLoopWork should be invoked on.
+  HWND main_thread_target_;
+};
+
+MainMessageLoopExternalPumpWin::MainMessageLoopExternalPumpWin()
+  : timer_pending_(false),
+    main_thread_target_(NULL) {
+  HINSTANCE hInstance = GetModuleHandle(NULL);
+  const wchar_t* const kClassName = L"CEFMainTargetHWND";
+
+  WNDCLASSEX wcex = {};
+  wcex.cbSize = sizeof(WNDCLASSEX);
+  wcex.lpfnWndProc = WndProc;
+  wcex.hInstance = hInstance;
+  wcex.lpszClassName = kClassName;
+  RegisterClassEx(&wcex);
+
+  // Create the message handling window.
+  main_thread_target_ = CreateWindowW(kClassName, NULL, WS_OVERLAPPEDWINDOW,
+      0, 0, 0, 0, HWND_MESSAGE , NULL, hInstance, NULL);
+  DCHECK(main_thread_target_);
+  SetUserDataPtr(main_thread_target_, this);
+}
+
+MainMessageLoopExternalPumpWin::~MainMessageLoopExternalPumpWin() {
+  KillTimer();
+  if (main_thread_target_)
+    DestroyWindow(main_thread_target_);
+}
+
+void MainMessageLoopExternalPumpWin::Quit() {
+  PostMessage(NULL, WM_QUIT, 0, 0);
+}
+
+int MainMessageLoopExternalPumpWin::Run() {
+  // Run the message loop.
+  MSG msg;
+  while (GetMessage(&msg, NULL, 0, 0)) {
+    TranslateMessage(&msg);
+    DispatchMessage(&msg);
+  }
+
+  KillTimer();
+
+  // We need to run the message pump until it is idle. However we don't have
+  // that information here so we run the message loop "for a while".
+  for (int i = 0; i < 10; ++i) {
+    // Do some work.
+    CefDoMessageLoopWork();
+    
+    // Sleep to allow the CEF proc to do work.
+    Sleep(50);
+  }
+  
+  return 0;
+}
+
+void MainMessageLoopExternalPumpWin::OnScheduleMessagePumpWork(int64 delay_ms) {
+  // This method may be called on any thread.
+  PostMessage(main_thread_target_, kMsgHaveWork, 0,
+              static_cast<LPARAM>(delay_ms));
+}
+
+void MainMessageLoopExternalPumpWin::SetTimer(int64 delay_ms) {
+  DCHECK(!timer_pending_);
+  DCHECK_GT(delay_ms, 0);
+  timer_pending_ = true;
+  ::SetTimer(main_thread_target_, 1, static_cast<UINT>(delay_ms), NULL);
+}
+
+void MainMessageLoopExternalPumpWin::KillTimer() {
+  if (timer_pending_) {
+    ::KillTimer(main_thread_target_, 1);
+    timer_pending_ = false;
+  }
+}
+
+// static
+LRESULT CALLBACK MainMessageLoopExternalPumpWin::WndProc(
+    HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
+  if (msg == WM_TIMER || msg == kMsgHaveWork) {
+    MainMessageLoopExternalPumpWin* message_loop =
+        GetUserDataPtr<MainMessageLoopExternalPumpWin*>(hwnd);
+    if (msg == kMsgHaveWork) {
+      // OnScheduleMessagePumpWork() request.
+      const int64 delay_ms = static_cast<int64>(lparam);
+      message_loop->OnScheduleWork(delay_ms);
+    } else {
+      // Timer timed out.
+      message_loop->OnTimerTimeout();
+    }
+  }
+  return DefWindowProc(hwnd, msg, wparam, lparam);
+}
+
+} // namespace
+
+// static
+scoped_ptr<MainMessageLoopExternalPump>
+MainMessageLoopExternalPump::Create() {
+  return scoped_ptr<MainMessageLoopExternalPump>(
+      new MainMessageLoopExternalPumpWin());
+}
+
+}  // namespace client