]> git.sesse.net Git - casparcg/blobdiff - dependencies64/cef/windows/tests/cefclient/browser/main_message_loop_multithreaded_win.cc
Upgrade CEF to 3.3029.1611.g44e39a8 / Chromium 58.0.3029.81.
[casparcg] / dependencies64 / cef / windows / tests / cefclient / browser / main_message_loop_multithreaded_win.cc
diff --git a/dependencies64/cef/windows/tests/cefclient/browser/main_message_loop_multithreaded_win.cc b/dependencies64/cef/windows/tests/cefclient/browser/main_message_loop_multithreaded_win.cc
new file mode 100644 (file)
index 0000000..887ed83
--- /dev/null
@@ -0,0 +1,167 @@
+// Copyright (c) 2015 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/cefclient/browser/main_message_loop_multithreaded_win.h"
+
+#include "include/base/cef_bind.h"
+#include "include/base/cef_logging.h"
+#include "include/cef_app.h"
+#include "tests/cefclient/browser/resource.h"
+#include "tests/shared/browser/util_win.h"
+
+namespace client {
+
+namespace {
+
+const wchar_t kWndClass[] = L"Client_MessageWindow";
+const wchar_t kTaskMessageName[] = L"Client_CustomTask";
+
+}  // namespace
+
+MainMessageLoopMultithreadedWin::MainMessageLoopMultithreadedWin()
+    : thread_id_(base::PlatformThread::CurrentId()),
+      task_message_id_(RegisterWindowMessage(kTaskMessageName)),
+      dialog_hwnd_(NULL),
+      message_hwnd_(NULL) {
+}
+
+MainMessageLoopMultithreadedWin::~MainMessageLoopMultithreadedWin() {
+  DCHECK(RunsTasksOnCurrentThread());
+  DCHECK(!message_hwnd_);
+  DCHECK(queued_tasks_.empty());
+}
+
+int MainMessageLoopMultithreadedWin::Run() {
+  DCHECK(RunsTasksOnCurrentThread());
+
+  HINSTANCE hInstance = ::GetModuleHandle(NULL);
+
+  {
+    base::AutoLock lock_scope(lock_);
+
+    // Create the hidden window for message processing.
+    message_hwnd_ = CreateMessageWindow(hInstance);
+    CHECK(message_hwnd_);
+
+    // Store a pointer to |this| in the window's user data.
+    SetUserDataPtr(message_hwnd_, this);
+
+    // Execute any tasks that are currently queued.
+    while (!queued_tasks_.empty()) {
+      PostTaskInternal(queued_tasks_.front());
+      queued_tasks_.pop();
+    }
+  }
+
+  HACCEL hAccelTable =
+      LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_CEFCLIENT));
+
+  MSG msg;
+
+  // Run the application message loop.
+  while (GetMessage(&msg, NULL, 0, 0)) {
+    // Allow processing of dialog messages.
+    if (dialog_hwnd_ && IsDialogMessage(dialog_hwnd_, &msg))
+      continue;
+
+    if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) {
+      TranslateMessage(&msg);
+      DispatchMessage(&msg);
+    }
+  }
+
+  {
+    base::AutoLock lock_scope(lock_);
+
+    // Destroy the message window.
+    DestroyWindow(message_hwnd_);
+    message_hwnd_ = NULL;
+  }
+
+  return static_cast<int>(msg.wParam);
+}
+
+void MainMessageLoopMultithreadedWin::Quit() {
+  // Execute PostQuitMessage(0) on the main thread.
+  PostClosure(base::Bind(::PostQuitMessage, 0));
+}
+
+void MainMessageLoopMultithreadedWin::PostTask(CefRefPtr<CefTask> task) {
+  base::AutoLock lock_scope(lock_);
+  PostTaskInternal(task);
+}
+
+bool MainMessageLoopMultithreadedWin::RunsTasksOnCurrentThread() const {
+  return (thread_id_ == base::PlatformThread::CurrentId());
+}
+
+void MainMessageLoopMultithreadedWin::SetCurrentModelessDialog(
+    HWND hWndDialog) {
+  DCHECK(RunsTasksOnCurrentThread());
+
+#if DCHECK_IS_ON()
+  if (hWndDialog) {
+    // A new dialog reference should not be set while one is currently set.
+    DCHECK(!dialog_hwnd_);
+  }
+#endif
+  dialog_hwnd_ = hWndDialog;
+}
+
+// static
+HWND MainMessageLoopMultithreadedWin::CreateMessageWindow(HINSTANCE hInstance) {
+  WNDCLASSEX wc = {0};
+  wc.cbSize = sizeof(wc);
+  wc.lpfnWndProc = MessageWndProc;
+  wc.hInstance = hInstance;
+  wc.lpszClassName = kWndClass;
+  RegisterClassEx(&wc);
+
+  return CreateWindow(kWndClass, 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, hInstance,
+                      0);
+}
+
+// static
+LRESULT CALLBACK MainMessageLoopMultithreadedWin::MessageWndProc(
+    HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
+  MainMessageLoopMultithreadedWin* self =
+      GetUserDataPtr<MainMessageLoopMultithreadedWin*>(hWnd);
+
+  if (self && message == self->task_message_id_) {
+    // Execute the task.
+    CefTask* task = reinterpret_cast<CefTask*>(wParam);
+    task->Execute();
+
+    // Release the reference added in PostTaskInternal. This will likely result
+    // in |task| being deleted.
+    task->Release();
+  } else switch (message) {
+    case WM_DESTROY:
+      // Clear the reference to |self|.
+      SetUserDataPtr(hWnd, NULL);
+      break;
+  }
+
+  return DefWindowProc(hWnd, message, wParam, lParam);
+}
+
+void MainMessageLoopMultithreadedWin::PostTaskInternal(
+    CefRefPtr<CefTask> task) {
+  lock_.AssertAcquired();
+
+  if (!message_hwnd_) {
+    // Queue the task until the message loop starts running.
+    queued_tasks_.push(task);
+    return;
+  }
+
+  // Add a reference that will be released in MessageWndProc.
+  task->AddRef();
+
+  // Post the task for execution by the message window.
+  PostMessage(message_hwnd_, task_message_id_,
+              reinterpret_cast<WPARAM>(task.get()), 0);
+}
+
+}  // namespace client