1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
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 "mozilla/dom/MIDIInput.h"
8 #include "mozilla/dom/Document.h"
9 #include "mozilla/dom/MIDIPortChild.h"
10 #include "mozilla/dom/MIDIInputBinding.h"
11 #include "mozilla/dom/MIDIMessageEvent.h"
12 #include "mozilla/dom/MIDIMessageEventBinding.h"
13 #include "nsGlobalWindowInner.h"
17 namespace mozilla::dom
{
19 MIDIInput::MIDIInput(nsPIDOMWindowInner
* aWindow
)
20 : MIDIPort(aWindow
), mKeepAlive(false) {}
23 RefPtr
<MIDIInput
> MIDIInput::Create(nsPIDOMWindowInner
* aWindow
,
24 MIDIAccess
* aMIDIAccessParent
,
25 const MIDIPortInfo
& aPortInfo
,
26 const bool aSysexEnabled
) {
27 MOZ_ASSERT(static_cast<MIDIPortType
>(aPortInfo
.type()) ==
29 RefPtr
<MIDIInput
> port
= new MIDIInput(aWindow
);
30 if (!port
->Initialize(aPortInfo
, aSysexEnabled
, aMIDIAccessParent
)) {
36 JSObject
* MIDIInput::WrapObject(JSContext
* aCx
,
37 JS::Handle
<JSObject
*> aGivenProto
) {
38 return MIDIInput_Binding::Wrap(aCx
, this, aGivenProto
);
41 void MIDIInput::Receive(const nsTArray
<MIDIMessage
>& aMsgs
) {
42 if (!GetOwnerWindow()) {
43 return; // Ignore messages once we've been disconnected from the owner
46 nsCOMPtr
<Document
> doc
= GetOwnerWindow()->GetDoc();
48 NS_WARNING("No document available to send MIDIMessageEvent to!");
51 for (const auto& msg
: aMsgs
) {
52 RefPtr
<MIDIMessageEvent
> event(
53 MIDIMessageEvent::Constructor(this, msg
.timestamp(), msg
.data()));
54 DispatchTrustedEvent(event
);
58 void MIDIInput::StateChange() {
59 if (Port()->ConnectionState() == MIDIPortConnectionState::Open
||
60 (Port()->DeviceState() == MIDIPortDeviceState::Connected
&&
61 Port()->ConnectionState() == MIDIPortConnectionState::Pending
)) {
62 KeepAliveOnMidimessage();
64 DontKeepAliveOnMidimessage();
68 void MIDIInput::EventListenerAdded(nsAtom
* aType
) {
69 if (aType
== nsGkAtoms::onmidimessage
) {
70 // HACK: the Web MIDI spec states that we should open a port only when
71 // setting the midimessage event handler but Chrome does it even when
72 // adding event listeners hence this.
73 if (Port()->ConnectionState() != MIDIPortConnectionState::Open
) {
74 LOG("onmidimessage event listener added, sending implicit Open");
79 DOMEventTargetHelper::EventListenerAdded(aType
);
82 void MIDIInput::DisconnectFromOwner() {
83 DontKeepAliveOnMidimessage();
85 MIDIPort::DisconnectFromOwner();
88 void MIDIInput::KeepAliveOnMidimessage() {
91 KeepAliveIfHasListenersFor(nsGkAtoms::onmidimessage
);
95 void MIDIInput::DontKeepAliveOnMidimessage() {
97 IgnoreKeepAliveIfHasListenersFor(nsGkAtoms::onmidimessage
);
102 } // namespace mozilla::dom