Bug 1861709 replace AudioCallbackDriver::ThreadRunning() assertions that mean to...
[gecko.git] / widget / windows / WindowHook.cpp
blob06773f21b75d4f547b1acd870e60800dd91f1051
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "WindowHook.h"
8 #include "nsWindow.h"
9 #include "nsWindowDefs.h"
11 namespace mozilla {
12 namespace widget {
14 nsresult WindowHook::AddHook(UINT nMsg, Callback callback, void* context) {
15 MessageData* data = LookupOrCreate(nMsg);
17 if (!data) return NS_ERROR_OUT_OF_MEMORY;
19 // Ensure we don't overwrite another hook
20 NS_ENSURE_TRUE(nullptr == data->hook.cb, NS_ERROR_UNEXPECTED);
22 data->hook = CallbackData(callback, context);
24 return NS_OK;
27 nsresult WindowHook::RemoveHook(UINT nMsg, Callback callback, void* context) {
28 CallbackData cbdata(callback, context);
29 MessageData* data = Lookup(nMsg);
30 if (!data) return NS_ERROR_UNEXPECTED;
31 if (data->hook != cbdata) return NS_ERROR_UNEXPECTED;
32 data->hook = CallbackData();
34 DeleteIfEmpty(data);
35 return NS_OK;
38 nsresult WindowHook::AddMonitor(UINT nMsg, Callback callback, void* context) {
39 MessageData* data = LookupOrCreate(nMsg);
40 return (data && data->monitors.AppendElement(CallbackData(callback, context),
41 fallible))
42 ? NS_OK
43 : NS_ERROR_OUT_OF_MEMORY;
46 nsresult WindowHook::RemoveMonitor(UINT nMsg, Callback callback,
47 void* context) {
48 CallbackData cbdata(callback, context);
49 MessageData* data = Lookup(nMsg);
50 if (!data) return NS_ERROR_UNEXPECTED;
51 CallbackDataArray::index_type idx = data->monitors.IndexOf(cbdata);
52 if (idx == CallbackDataArray::NoIndex) return NS_ERROR_UNEXPECTED;
53 data->monitors.RemoveElementAt(idx);
54 DeleteIfEmpty(data);
55 return NS_OK;
58 WindowHook::MessageData* WindowHook::Lookup(UINT nMsg) {
59 MessageDataArray::index_type idx;
60 for (idx = 0; idx < mMessageData.Length(); idx++) {
61 MessageData& data = mMessageData[idx];
62 if (data.nMsg == nMsg) return &data;
64 return nullptr;
67 WindowHook::MessageData* WindowHook::LookupOrCreate(UINT nMsg) {
68 MessageData* data = Lookup(nMsg);
69 if (!data) {
70 data = mMessageData.AppendElement();
72 if (!data) return nullptr;
74 data->nMsg = nMsg;
76 return data;
79 void WindowHook::DeleteIfEmpty(MessageData* data) {
80 // Never remove a MessageData that has still a hook or monitor entries.
81 if (data->hook || !data->monitors.IsEmpty()) return;
83 MessageDataArray::index_type idx;
84 idx = data - mMessageData.Elements();
85 NS_ASSERTION(
86 idx < mMessageData.Length(),
87 "Attempted to delete MessageData that doesn't belong to this array!");
88 mMessageData.RemoveElementAt(idx);
91 bool WindowHook::Notify(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam,
92 MSGResult& aResult) {
93 MessageData* data = Lookup(nMsg);
94 if (!data) return false;
96 uint32_t length = data->monitors.Length();
97 for (uint32_t midx = 0; midx < length; midx++) {
98 data->monitors[midx].Invoke(hWnd, nMsg, wParam, lParam, &aResult.mResult);
101 aResult.mConsumed =
102 data->hook.Invoke(hWnd, nMsg, wParam, lParam, &aResult.mResult);
103 return aResult.mConsumed;
106 bool WindowHook::CallbackData::Invoke(HWND hWnd, UINT msg, WPARAM wParam,
107 LPARAM lParam, LRESULT* aResult) {
108 if (!cb) return false;
109 return cb(context, hWnd, msg, wParam, lParam, aResult);
112 } // namespace widget
113 } // namespace mozilla