Bumping manifests a=b2g-bump
[gecko.git] / widget / windows / nsWindowBase.cpp
blob28e66decade724d69a2271ced43921f1ad0ad2f1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsWindowBase.h"
8 #include "mozilla/MiscEvents.h"
9 #include "KeyboardLayout.h"
10 #include "WinUtils.h"
11 #include "npapi.h"
13 using namespace mozilla;
14 using namespace mozilla::widget;
16 static const wchar_t kUser32LibName[] = L"user32.dll";
17 bool nsWindowBase::sTouchInjectInitialized = false;
18 InjectTouchInputPtr nsWindowBase::sInjectTouchFuncPtr;
20 bool
21 nsWindowBase::DispatchPluginEvent(const MSG& aMsg)
23 if (!PluginHasFocus()) {
24 return false;
26 WidgetPluginEvent pluginEvent(true, NS_PLUGIN_INPUT_EVENT, this);
27 nsIntPoint point(0, 0);
28 InitEvent(pluginEvent, &point);
29 NPEvent npEvent;
30 npEvent.event = aMsg.message;
31 npEvent.wParam = aMsg.wParam;
32 npEvent.lParam = aMsg.lParam;
33 pluginEvent.mPluginEvent.Copy(npEvent);
34 pluginEvent.retargetToFocusedDocument = true;
35 return DispatchWindowEvent(&pluginEvent);
38 // static
39 bool
40 nsWindowBase::InitTouchInjection()
42 if (!sTouchInjectInitialized) {
43 // Initialize touch injection on the first call
44 HMODULE hMod = LoadLibraryW(kUser32LibName);
45 if (!hMod) {
46 return false;
49 InitializeTouchInjectionPtr func =
50 (InitializeTouchInjectionPtr)GetProcAddress(hMod, "InitializeTouchInjection");
51 if (!func) {
52 WinUtils::Log("InitializeTouchInjection not available.");
53 return false;
56 if (!func(TOUCH_INJECT_MAX_POINTS, TOUCH_FEEDBACK_DEFAULT)) {
57 WinUtils::Log("InitializeTouchInjection failure. GetLastError=%d", GetLastError());
58 return false;
61 sInjectTouchFuncPtr =
62 (InjectTouchInputPtr)GetProcAddress(hMod, "InjectTouchInput");
63 if (!sInjectTouchFuncPtr) {
64 WinUtils::Log("InjectTouchInput not available.");
65 return false;
67 sTouchInjectInitialized = true;
69 return true;
72 bool
73 nsWindowBase::InjectTouchPoint(uint32_t aId, nsIntPoint& aPointerScreenPoint,
74 POINTER_FLAGS aFlags, uint32_t aPressure,
75 uint32_t aOrientation)
77 if (aId > TOUCH_INJECT_MAX_POINTS) {
78 WinUtils::Log("Pointer ID exceeds maximum. See TOUCH_INJECT_MAX_POINTS.");
79 return false;
82 POINTER_TOUCH_INFO info;
83 memset(&info, 0, sizeof(POINTER_TOUCH_INFO));
85 info.touchFlags = TOUCH_FLAG_NONE;
86 info.touchMask = TOUCH_MASK_CONTACTAREA|TOUCH_MASK_ORIENTATION|TOUCH_MASK_PRESSURE;
87 info.pressure = aPressure;
88 info.orientation = aOrientation;
90 info.pointerInfo.pointerFlags = aFlags;
91 info.pointerInfo.pointerType = PT_TOUCH;
92 info.pointerInfo.pointerId = aId;
93 info.pointerInfo.ptPixelLocation.x = WinUtils::LogToPhys(aPointerScreenPoint.x);
94 info.pointerInfo.ptPixelLocation.y = WinUtils::LogToPhys(aPointerScreenPoint.y);
96 info.rcContact.top = info.pointerInfo.ptPixelLocation.y - 2;
97 info.rcContact.bottom = info.pointerInfo.ptPixelLocation.y + 2;
98 info.rcContact.left = info.pointerInfo.ptPixelLocation.x - 2;
99 info.rcContact.right = info.pointerInfo.ptPixelLocation.x + 2;
101 if (!sInjectTouchFuncPtr(1, &info)) {
102 WinUtils::Log("InjectTouchInput failure. GetLastError=%d", GetLastError());
103 return false;
105 return true;
108 nsresult
109 nsWindowBase::SynthesizeNativeTouchPoint(uint32_t aPointerId,
110 nsIWidget::TouchPointerState aPointerState,
111 nsIntPoint aPointerScreenPoint,
112 double aPointerPressure,
113 uint32_t aPointerOrientation)
115 if (!InitTouchInjection()) {
116 return NS_ERROR_NOT_IMPLEMENTED;
119 bool hover = aPointerState & TOUCH_HOVER;
120 bool contact = aPointerState & TOUCH_CONTACT;
121 bool remove = aPointerState & TOUCH_REMOVE;
122 bool cancel = aPointerState & TOUCH_CANCEL;
124 // win api expects a value from 0 to 1024. aPointerPressure is a value
125 // from 0.0 to 1.0.
126 uint32_t pressure = (uint32_t)ceil(aPointerPressure * 1024);
128 // If we already know about this pointer id get it's record
129 PointerInfo* info = mActivePointers.Get(aPointerId);
131 // We know about this pointer, send an update
132 if (info) {
133 POINTER_FLAGS flags = POINTER_FLAG_UPDATE;
134 if (hover) {
135 flags |= POINTER_FLAG_INRANGE;
136 } else if (contact) {
137 flags |= POINTER_FLAG_INCONTACT|POINTER_FLAG_INRANGE;
138 } else if (remove) {
139 flags = POINTER_FLAG_UP;
140 // Remove the pointer from our tracking list. This is nsAutPtr wrapped,
141 // so shouldn't leak.
142 mActivePointers.Remove(aPointerId);
145 if (cancel) {
146 flags |= POINTER_FLAG_CANCELED;
149 return !InjectTouchPoint(aPointerId, aPointerScreenPoint, flags,
150 pressure, aPointerOrientation) ?
151 NS_ERROR_UNEXPECTED : NS_OK;
154 // Missing init state, error out
155 if (remove || cancel) {
156 return NS_ERROR_INVALID_ARG;
159 // Create a new pointer
160 info = new PointerInfo(aPointerId, aPointerScreenPoint);
162 POINTER_FLAGS flags = POINTER_FLAG_INRANGE;
163 if (contact) {
164 flags |= POINTER_FLAG_INCONTACT|POINTER_FLAG_DOWN;
167 mActivePointers.Put(aPointerId, info);
168 return !InjectTouchPoint(aPointerId, aPointerScreenPoint, flags,
169 pressure, aPointerOrientation) ?
170 NS_ERROR_UNEXPECTED : NS_OK;
173 // static
174 PLDHashOperator
175 nsWindowBase::CancelTouchPoints(const unsigned int& aPointerId, nsAutoPtr<PointerInfo>& aInfo, void* aUserArg)
177 nsWindowBase* self = static_cast<nsWindowBase*>(aUserArg);
178 self->InjectTouchPoint(aInfo.get()->mPointerId, aInfo.get()->mPosition, POINTER_FLAG_CANCELED);
179 return (PLDHashOperator)(PL_DHASH_NEXT|PL_DHASH_REMOVE);
182 nsresult
183 nsWindowBase::ClearNativeTouchSequence()
185 if (!sTouchInjectInitialized) {
186 return NS_OK;
189 // cancel all input points
190 mActivePointers.Enumerate(CancelTouchPoints, (void*)this);
192 nsBaseWidget::ClearNativeTouchSequence();
194 return NS_OK;
197 bool
198 nsWindowBase::HandleAppCommandMsg(const MSG& aAppCommandMsg,
199 LRESULT *aRetValue)
201 ModifierKeyState modKeyState;
202 NativeKey nativeKey(this, aAppCommandMsg, modKeyState);
203 bool consumed = nativeKey.HandleAppCommandMessage();
204 *aRetValue = consumed ? 1 : 0;
205 return consumed;