1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/events/TouchEvent.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,257 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "mozilla/dom/TouchEvent.h" 1.11 +#include "mozilla/dom/Touch.h" 1.12 +#include "mozilla/dom/TouchListBinding.h" 1.13 +#include "mozilla/Preferences.h" 1.14 +#include "mozilla/TouchEvents.h" 1.15 +#include "nsContentUtils.h" 1.16 + 1.17 +namespace mozilla { 1.18 + 1.19 +#ifdef XP_WIN 1.20 +namespace widget { 1.21 +extern int32_t IsTouchDeviceSupportPresent(); 1.22 +} // namespace widget 1.23 +#endif // #ifdef XP_WIN 1.24 + 1.25 +namespace dom { 1.26 + 1.27 +/****************************************************************************** 1.28 + * TouchList 1.29 + *****************************************************************************/ 1.30 + 1.31 +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TouchList) 1.32 + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY 1.33 + NS_INTERFACE_MAP_ENTRY(nsISupports) 1.34 +NS_INTERFACE_MAP_END 1.35 + 1.36 +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(TouchList, mParent, mPoints) 1.37 + 1.38 +NS_IMPL_CYCLE_COLLECTING_ADDREF(TouchList) 1.39 +NS_IMPL_CYCLE_COLLECTING_RELEASE(TouchList) 1.40 + 1.41 +JSObject* 1.42 +TouchList::WrapObject(JSContext* aCx) 1.43 +{ 1.44 + return TouchListBinding::Wrap(aCx, this); 1.45 +} 1.46 + 1.47 +// static 1.48 +bool 1.49 +TouchList::PrefEnabled(JSContext* aCx, JSObject* aGlobal) 1.50 +{ 1.51 + return TouchEvent::PrefEnabled(aCx, aGlobal); 1.52 +} 1.53 + 1.54 +Touch* 1.55 +TouchList::IdentifiedTouch(int32_t aIdentifier) const 1.56 +{ 1.57 + for (uint32_t i = 0; i < mPoints.Length(); ++i) { 1.58 + Touch* point = mPoints[i]; 1.59 + if (point && point->Identifier() == aIdentifier) { 1.60 + return point; 1.61 + } 1.62 + } 1.63 + return nullptr; 1.64 +} 1.65 + 1.66 +/****************************************************************************** 1.67 + * TouchEvent 1.68 + *****************************************************************************/ 1.69 + 1.70 +TouchEvent::TouchEvent(EventTarget* aOwner, 1.71 + nsPresContext* aPresContext, 1.72 + WidgetTouchEvent* aEvent) 1.73 + : UIEvent(aOwner, aPresContext, 1.74 + aEvent ? aEvent : new WidgetTouchEvent(false, 0, nullptr)) 1.75 +{ 1.76 + if (aEvent) { 1.77 + mEventIsInternal = false; 1.78 + 1.79 + for (uint32_t i = 0; i < aEvent->touches.Length(); ++i) { 1.80 + Touch* touch = aEvent->touches[i]; 1.81 + touch->InitializePoints(mPresContext, aEvent); 1.82 + } 1.83 + } else { 1.84 + mEventIsInternal = true; 1.85 + mEvent->time = PR_Now(); 1.86 + } 1.87 +} 1.88 + 1.89 +NS_IMPL_CYCLE_COLLECTION_INHERITED(TouchEvent, UIEvent, 1.90 + mTouches, 1.91 + mTargetTouches, 1.92 + mChangedTouches) 1.93 + 1.94 +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TouchEvent) 1.95 +NS_INTERFACE_MAP_END_INHERITING(UIEvent) 1.96 + 1.97 +NS_IMPL_ADDREF_INHERITED(TouchEvent, UIEvent) 1.98 +NS_IMPL_RELEASE_INHERITED(TouchEvent, UIEvent) 1.99 + 1.100 +void 1.101 +TouchEvent::InitTouchEvent(const nsAString& aType, 1.102 + bool aCanBubble, 1.103 + bool aCancelable, 1.104 + nsIDOMWindow* aView, 1.105 + int32_t aDetail, 1.106 + bool aCtrlKey, 1.107 + bool aAltKey, 1.108 + bool aShiftKey, 1.109 + bool aMetaKey, 1.110 + TouchList* aTouches, 1.111 + TouchList* aTargetTouches, 1.112 + TouchList* aChangedTouches, 1.113 + ErrorResult& aRv) 1.114 +{ 1.115 + aRv = UIEvent::InitUIEvent(aType, aCanBubble, aCancelable, aView, aDetail); 1.116 + if (aRv.Failed()) { 1.117 + return; 1.118 + } 1.119 + 1.120 + mEvent->AsInputEvent()->InitBasicModifiers(aCtrlKey, aAltKey, 1.121 + aShiftKey, aMetaKey); 1.122 + mTouches = aTouches; 1.123 + mTargetTouches = aTargetTouches; 1.124 + mChangedTouches = aChangedTouches; 1.125 +} 1.126 + 1.127 +TouchList* 1.128 +TouchEvent::Touches() 1.129 +{ 1.130 + if (!mTouches) { 1.131 + WidgetTouchEvent* touchEvent = mEvent->AsTouchEvent(); 1.132 + if (mEvent->message == NS_TOUCH_END || mEvent->message == NS_TOUCH_CANCEL) { 1.133 + // for touchend events, remove any changed touches from the touches array 1.134 + nsTArray< nsRefPtr<Touch> > unchangedTouches; 1.135 + const nsTArray< nsRefPtr<Touch> >& touches = touchEvent->touches; 1.136 + for (uint32_t i = 0; i < touches.Length(); ++i) { 1.137 + if (!touches[i]->mChanged) { 1.138 + unchangedTouches.AppendElement(touches[i]); 1.139 + } 1.140 + } 1.141 + mTouches = new TouchList(ToSupports(this), unchangedTouches); 1.142 + } else { 1.143 + mTouches = new TouchList(ToSupports(this), touchEvent->touches); 1.144 + } 1.145 + } 1.146 + return mTouches; 1.147 +} 1.148 + 1.149 +TouchList* 1.150 +TouchEvent::TargetTouches() 1.151 +{ 1.152 + if (!mTargetTouches) { 1.153 + nsTArray< nsRefPtr<Touch> > targetTouches; 1.154 + WidgetTouchEvent* touchEvent = mEvent->AsTouchEvent(); 1.155 + const nsTArray< nsRefPtr<Touch> >& touches = touchEvent->touches; 1.156 + for (uint32_t i = 0; i < touches.Length(); ++i) { 1.157 + // for touchend/cancel events, don't append to the target list if this is a 1.158 + // touch that is ending 1.159 + if ((mEvent->message != NS_TOUCH_END && 1.160 + mEvent->message != NS_TOUCH_CANCEL) || !touches[i]->mChanged) { 1.161 + if (touches[i]->mTarget == mEvent->originalTarget) { 1.162 + targetTouches.AppendElement(touches[i]); 1.163 + } 1.164 + } 1.165 + } 1.166 + mTargetTouches = new TouchList(ToSupports(this), targetTouches); 1.167 + } 1.168 + return mTargetTouches; 1.169 +} 1.170 + 1.171 +TouchList* 1.172 +TouchEvent::ChangedTouches() 1.173 +{ 1.174 + if (!mChangedTouches) { 1.175 + nsTArray< nsRefPtr<Touch> > changedTouches; 1.176 + WidgetTouchEvent* touchEvent = mEvent->AsTouchEvent(); 1.177 + const nsTArray< nsRefPtr<Touch> >& touches = touchEvent->touches; 1.178 + for (uint32_t i = 0; i < touches.Length(); ++i) { 1.179 + if (touches[i]->mChanged) { 1.180 + changedTouches.AppendElement(touches[i]); 1.181 + } 1.182 + } 1.183 + mChangedTouches = new TouchList(ToSupports(this), changedTouches); 1.184 + } 1.185 + return mChangedTouches; 1.186 +} 1.187 + 1.188 +// static 1.189 +bool 1.190 +TouchEvent::PrefEnabled(JSContext* aCx, JSObject* aGlobal) 1.191 +{ 1.192 + bool prefValue = false; 1.193 + int32_t flag = 0; 1.194 + if (NS_SUCCEEDED(Preferences::GetInt("dom.w3c_touch_events.enabled", 1.195 + &flag))) { 1.196 + if (flag == 2) { 1.197 +#ifdef XP_WIN 1.198 + static bool sDidCheckTouchDeviceSupport = false; 1.199 + static bool sIsTouchDeviceSupportPresent = false; 1.200 + // On Windows we auto-detect based on device support. 1.201 + if (!sDidCheckTouchDeviceSupport) { 1.202 + sDidCheckTouchDeviceSupport = true; 1.203 + sIsTouchDeviceSupportPresent = widget::IsTouchDeviceSupportPresent(); 1.204 + } 1.205 + prefValue = sIsTouchDeviceSupportPresent; 1.206 +#else 1.207 + NS_WARNING("dom.w3c_touch_events.enabled=2 not implemented!"); 1.208 + prefValue = false; 1.209 +#endif 1.210 + } else { 1.211 + prefValue = !!flag; 1.212 + } 1.213 + } 1.214 + if (prefValue) { 1.215 + nsContentUtils::InitializeTouchEventTable(); 1.216 + } 1.217 + return prefValue; 1.218 +} 1.219 + 1.220 +bool 1.221 +TouchEvent::AltKey() 1.222 +{ 1.223 + return mEvent->AsTouchEvent()->IsAlt(); 1.224 +} 1.225 + 1.226 +bool 1.227 +TouchEvent::MetaKey() 1.228 +{ 1.229 + return mEvent->AsTouchEvent()->IsMeta(); 1.230 +} 1.231 + 1.232 +bool 1.233 +TouchEvent::CtrlKey() 1.234 +{ 1.235 + return mEvent->AsTouchEvent()->IsControl(); 1.236 +} 1.237 + 1.238 +bool 1.239 +TouchEvent::ShiftKey() 1.240 +{ 1.241 + return mEvent->AsTouchEvent()->IsShift(); 1.242 +} 1.243 + 1.244 +} // namespace dom 1.245 +} // namespace mozilla 1.246 + 1.247 +using namespace mozilla; 1.248 +using namespace mozilla::dom; 1.249 + 1.250 +nsresult 1.251 +NS_NewDOMTouchEvent(nsIDOMEvent** aInstancePtrResult, 1.252 + EventTarget* aOwner, 1.253 + nsPresContext* aPresContext, 1.254 + WidgetTouchEvent* aEvent) 1.255 +{ 1.256 + TouchEvent* it = new TouchEvent(aOwner, aPresContext, aEvent); 1.257 + NS_ADDREF(it); 1.258 + *aInstancePtrResult = static_cast<Event*>(it); 1.259 + return NS_OK; 1.260 +}