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"
9 #include "nsWindowDefs.h"
15 WindowHook::AddHook(UINT nMsg
, Callback callback
, void *context
) {
16 MessageData
*data
= LookupOrCreate(nMsg
);
19 return NS_ERROR_OUT_OF_MEMORY
;
21 // Ensure we don't overwrite another hook
22 NS_ENSURE_TRUE(nullptr == data
->hook
.cb
, NS_ERROR_UNEXPECTED
);
24 data
->hook
= CallbackData(callback
, context
);
30 WindowHook::RemoveHook(UINT nMsg
, Callback callback
, void *context
) {
31 CallbackData
cbdata(callback
, context
);
32 MessageData
*data
= Lookup(nMsg
);
34 return NS_ERROR_UNEXPECTED
;
35 if (data
->hook
!= cbdata
)
36 return NS_ERROR_UNEXPECTED
;
37 data
->hook
= CallbackData();
44 WindowHook::AddMonitor(UINT nMsg
, Callback callback
, void *context
) {
45 MessageData
*data
= LookupOrCreate(nMsg
);
46 return (data
&& data
->monitors
.AppendElement(CallbackData(callback
, context
)))
47 ? NS_OK
: NS_ERROR_OUT_OF_MEMORY
;
51 WindowHook::RemoveMonitor(UINT nMsg
, Callback callback
, void *context
) {
52 CallbackData
cbdata(callback
, context
);
53 MessageData
*data
= Lookup(nMsg
);
55 return NS_ERROR_UNEXPECTED
;
56 CallbackDataArray::index_type idx
= data
->monitors
.IndexOf(cbdata
);
57 if (idx
== CallbackDataArray::NoIndex
)
58 return NS_ERROR_UNEXPECTED
;
59 data
->monitors
.RemoveElementAt(idx
);
64 WindowHook::MessageData
*
65 WindowHook::Lookup(UINT nMsg
) {
66 MessageDataArray::index_type idx
;
67 for (idx
= 0; idx
< mMessageData
.Length(); idx
++) {
68 MessageData
&data
= mMessageData
[idx
];
69 if (data
.nMsg
== nMsg
)
75 WindowHook::MessageData
*
76 WindowHook::LookupOrCreate(UINT nMsg
) {
77 MessageData
*data
= Lookup(nMsg
);
79 data
= mMessageData
.AppendElement();
90 WindowHook::DeleteIfEmpty(MessageData
*data
) {
91 // Never remove a MessageData that has still a hook or monitor entries.
92 if (data
->hook
|| !data
->monitors
.IsEmpty())
95 MessageDataArray::index_type idx
;
96 idx
= data
- mMessageData
.Elements();
97 NS_ASSERTION(idx
>= 0 && idx
< mMessageData
.Length(), "Attempted to delete MessageData that doesn't belong to this array!");
98 mMessageData
.RemoveElementAt(idx
);
102 WindowHook::Notify(HWND hWnd
, UINT nMsg
, WPARAM wParam
, LPARAM lParam
,
105 MessageData
*data
= Lookup(nMsg
);
109 uint32_t length
= data
->monitors
.Length();
110 for (uint32_t midx
= 0; midx
< length
; midx
++) {
111 data
->monitors
[midx
].Invoke(hWnd
, nMsg
, wParam
, lParam
, &aResult
.mResult
);
115 data
->hook
.Invoke(hWnd
, nMsg
, wParam
, lParam
, &aResult
.mResult
);
116 return aResult
.mConsumed
;
120 WindowHook::CallbackData::Invoke(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
124 return cb(context
, hWnd
, msg
, wParam
, lParam
, aResult
);
126 } // namespace widget
127 } // namespace mozilla