Files
palemoon27/widget/windows/InkCollector.cpp
T
roytam1 c975675694 import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1198459 - Update telemetry data based on the use of the forced enable pref. r=felipe (f33f0efc9a)
- Bug 1234210 - Restrict updates for accessibility.lastLoadDate to shutdown. r=trevor (5e484eb7ba)
- Bug 1231517 - part 3, Add ZoomToRect function to nsIWidget classes r=kats (57496a18cd)
- Bug 1229393 - Ensure that all the touch points from the original touch go to APZCCallbackHelper::SendSetTargetAPZCNotification. r=botond (45ce1737ac)
- Bug 1174323 part 1 - Add nsDOMWindowUtils::SendNativeMouseMove and EventUtils.sendNativeMouseMove. r=smaug (527439f71b)
- Bug 1180351 - Enable pointerlock tests on Windows and Linux. r=smaug (833fac9ba9)
- Bug 1180351 - Followup: Disable pointerlock tests on Windows for frequently failing tests. r=turning off tests (02525d24f4)
- Bug 1174323 part 2 - Use native mouse move to improve robustness of screenClientXYConst subtest. r=smaug (7e3fb884d3)
- Bug 1231517 - part 4, Add ZoomToFocusedInput function to nsDOMWindowUtils r=kats (a1f3e3b4fd)
- Bug 1153156 part.1 Move nsBaseWidget::OverrideSystemMouseScrollSpeed() to WidgetWheelEvent r=smaug, sr=smaug (8a95d65d55)
- bug 726265 don't activate ELAN swipe hack unless ScanCode is zero r=heycam (477a5ce06a)
- Bug 1235686 part.1 MouseScrollHandler should refresh the cache of system settings at handling wheel messages if the pref doesn't allow to cache system settings r=jimm (6cae8d2b07)
- Bug 1235686 part.2 Don't refresh the cache of system settings at handling wheel messages if the scroll amout values are initialized with prefs r=jimm (ead872b6bf)
- Bug 1235686 part.3 Don't trust system settings cache if SynTP of Synaptics is installed r=jimm (d56a034a42)
- Bug 1235686 part.4 Don't trust system settings cache if Apoint of Alps is installed r=jimm (85cb23e185)
- Bug 1153156 part.2 Make WidgetWheelEvent store if overriding system scroll speed is allowed and it shouldn't be allowed if scroll speed isn't system default settings on Windows r=smaug+jimm (3d5fc255db)
- Bug 1153156 part.3 Don't allow to override system scroll speed if the wheel event causes too fast scroll r=smaug+jimm (21e10640ac)
- Bug 1236750 - Rename ViewTransform to AsyncTransform. r=kats (1ccd8af262)
- Bug 1226826 - Record if painted displayport updates were due to repaints from the relevant layer tree or not. r=botond (e28315ec88)
- Bug 1228641. Add a initializer_list constructor to nsTArray. r=froydnj (448f69f610)
- Bug 962243 - Gtest for being able to pan after lifting a finger from a pinch. r=botond (a1687f190c)
- Bug 1031443 - Allow panning in the pinching state even if zooming is disabled;r=botond (aacb1a28bd)
- Bug 1231504 - Move some prefs from b2g.js to all.js. r=botond (c9801602ba)
- Bug 1092128 - Ensure the tests for touch action disabled actually disable touch action. r=botond (ec3fae4568)
- Bug 1014691 - Get TestAsyncPanZoomController to compile in its new location. r=kats (9dd104c6fd)
- Bug 1240244 - Split APZ gtests into several files. r=kats (0ce8bd4f80)
- Bug 1235994 - Add a flag to wheel events to track if they may have momentum following them. r=mstange (d5b2099244)
- Bug 1153156 part.4 Make APZC system scroll speed overriding aware r=mstange (f9d49eb79c)
- Bug 1233118 - implement IAccessible2_3::selectionRanges, r=yzen (d85fe6cf64)
- bug 1235965 - null check mDoc in AccessibleWrap::Shutdown() r=davidb (cb775e5c00)
- Bug 1130096 - Convert embedding/components/find/ to Gecko style. r=mccr8 (83d043e841)
- Bug 1164473 - Resolve issue when touches stop working after pen was activated. r=jimm (16ce68b032)
- Bug 1171712 - Implement separated InkColletor and InkCollectorEvent classes. r=smaug, r=jimm (8000e742b8)
- bug 1198656 interpret null ConvolverNode mBuffer as a buffer of zerosr=padenot (339e1f9904)
- bug 930257 finish Oscillator on processing last non-null block r=padenot (2719eee12b)
- Bug 1240411: P1. Clean up webaudio headers. r=cpearce (f169dc2789)
- Bug 1219711 - Don't rely on timer interval in fake audio track. r=jesup (f140fd848a)
- Bug 1223655 - Only check for track end if track exists in MediaEngineDefaultAudioSource. r=jesup (3055b4529f)
- Bug 1223655 - Also don't check time of data end if track has ended. r=jesup (bbdf7c5be5)
- Bug 1223655 - Fix opt build bustage on a CLOSED TREE. r=bustage (d546f4ba0b)
- Bug 1164463 followup: Add missing 'override' keyword to MediaEngineDefault::Shutdown(). rs=ehsan (33bf959d84)
- Bug 1240411: P2. Clean up webrtc headers. r=jesup (73c2bdf22d)
- Bug 1240411: P4. Clean up readers headers. r=cpearce (748d2bf9e8)
- Bug 1232527 - Remove GMPVideoDecoderTrialCreator and friends. r=jwwang (e0decf270f)
- Bug 1240411: P5. Clean up GMP headers. r=cpearce (0336b7fd9c)
- Bug 1240252: Add missing "mozilla::" namespace prefix before usage of type LayoutDeviceIntRegion, to fix local build bustage. r=njn (54d5a4a553)
- Bug 1245241 - part 1 - Close Shmem file handles after mapping them when possible to reduce exhaustion issues. r=billm (631c2b6da5)
2023-08-16 17:20:15 +08:00

239 lines
7.8 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: set ts=2 sw=2 et tw=78:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include "InkCollector.h"
// Msinkaut_i.c and Msinkaut.h should both be included
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms695519.aspx
#include <msinkaut_i.c>
StaticAutoPtr<InkCollector> InkCollector::sInkCollector;
InkCollector::~InkCollector()
{
Shutdown();
MOZ_ASSERT(!mCookie && !mEnabled && !mComInitialized
&& !mMarshaller && !mInkCollector
&& !mConnectionPoint && !mInkCollectorEvent);
}
void InkCollector::Initialize()
{
// Possibly, we can use mConnectionPoint for checking,
// But if errors exist (perhaps COM object is unavailable),
// Initialize() will be called more times.
static bool sInkCollectorCreated = false;
if (sInkCollectorCreated) {
return;
}
sInkCollectorCreated = true;
// COM could get uninitialized due to previous initialization.
mComInitialized = SUCCEEDED(::CoInitialize(nullptr));
// Set up instance of InkCollectorEvent.
mInkCollectorEvent = new InkCollectorEvent();
// Set up a free threaded marshaler.
if (FAILED(::CoCreateFreeThreadedMarshaler(mInkCollectorEvent, getter_AddRefs(mMarshaller)))) {
return;
}
// Create the ink collector.
if (FAILED(::CoCreateInstance(CLSID_InkCollector, NULL, CLSCTX_INPROC_SERVER,
IID_IInkCollector, getter_AddRefs(mInkCollector)))) {
return;
}
// Set up connection between sink and InkCollector.
RefPtr<IConnectionPointContainer> connPointContainer;
// Get the connection point container.
if (SUCCEEDED(mInkCollector->QueryInterface(IID_IConnectionPointContainer,
getter_AddRefs(connPointContainer)))) {
// Find the connection point for Ink Collector events.
if (SUCCEEDED(connPointContainer->FindConnectionPoint(__uuidof(_IInkCollectorEvents),
getter_AddRefs(mConnectionPoint)))) {
// Hook up sink to connection point.
if (SUCCEEDED(mConnectionPoint->Advise(mInkCollectorEvent, &mCookie))) {
OnInitialize();
}
}
}
}
void InkCollector::Shutdown()
{
Enable(false);
if (mConnectionPoint) {
// Remove the connection of the sink to the Ink Collector.
mConnectionPoint->Unadvise(mCookie);
mCookie = 0;
mConnectionPoint = nullptr;
}
mInkCollector = nullptr;
mMarshaller = nullptr;
mInkCollectorEvent = nullptr;
// Let uninitialization get handled in a place where it got inited.
if (mComInitialized) {
CoUninitialize();
mComInitialized = false;
}
}
void InkCollector::OnInitialize()
{
// Suppress all events to do not allow performance decreasing.
// https://msdn.microsoft.com/en-us/library/ms820347.aspx
mInkCollector->SetEventInterest(InkCollectorEventInterest::ICEI_AllEvents, VARIANT_FALSE);
// Sets a value that indicates whether an object or control has interest in a specified event.
mInkCollector->SetEventInterest(InkCollectorEventInterest::ICEI_CursorOutOfRange, VARIANT_TRUE);
// If the MousePointer property is set to IMP_Custom and the MouseIcon property is NULL,
// Then the ink collector no longer handles mouse cursor settings.
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms700686.aspx
mInkCollector->put_MouseIcon(nullptr);
mInkCollector->put_MousePointer(InkMousePointer::IMP_Custom);
// This mode allows an ink collector to collect ink from any tablet attached to the Tablet PC.
// The Boolean value that indicates whether to use the mouse as an input device.
// If TRUE, the mouse is used for input.
// https://msdn.microsoft.com/en-us/library/ms820346.aspx
mInkCollector->SetAllTabletsMode(VARIANT_FALSE);
// Sets the value that specifies whether ink is rendered as it is drawn.
// VARIANT_TRUE to render ink as it is drawn on the display.
// VARIANT_FALSE to not have the ink appear on the display as strokes are made.
// https://msdn.microsoft.com/en-us/library/windows/desktop/dd314598.aspx
mInkCollector->put_DynamicRendering(VARIANT_FALSE);
}
// Sets a value that specifies whether the InkCollector object collects pen input.
// This property must be set to FALSE before setting or
// calling specific properties and methods of the object.
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms701721.aspx
void InkCollector::Enable(bool aNewState)
{
if (aNewState != mEnabled) {
if (mInkCollector) {
if (SUCCEEDED(mInkCollector->put_Enabled(aNewState ? VARIANT_TRUE : VARIANT_FALSE))) {
mEnabled = aNewState;
} else {
NS_WARNING("InkCollector did not change status successfully");
}
} else {
NS_WARNING("InkCollector should be exist");
}
}
}
HWND InkCollector::GetTarget()
{
return mTargetWindow;
}
void InkCollector::SetTarget(HWND aTargetWindow)
{
NS_ASSERTION(aTargetWindow, "aTargetWindow should be exist");
if (aTargetWindow && (aTargetWindow != mTargetWindow)) {
Initialize();
if (mInkCollector) {
Enable(false);
if (SUCCEEDED(mInkCollector->put_hWnd((LONG_PTR)aTargetWindow))) {
mTargetWindow = aTargetWindow;
} else {
NS_WARNING("InkCollector did not change window property successfully");
}
Enable(true);
}
}
}
void InkCollector::ClearTarget()
{
if (mTargetWindow && mInkCollector) {
Enable(false);
if (SUCCEEDED(mInkCollector->put_hWnd(0))) {
mTargetWindow = 0;
} else {
NS_WARNING("InkCollector did not clear window property successfully");
}
}
}
// The display and the digitizer have quite different properties.
// The display has CursorMustTouch, the mouse pointer alway touches the display surface.
// The digitizer lists Integrated and HardProximity.
// When the stylus is in the proximity of the tablet its movements are also detected.
// An external tablet will only list HardProximity.
bool InkCollectorEvent::IsHardProximityTablet(IInkTablet* aTablet) const
{
if (aTablet) {
TabletHardwareCapabilities caps;
if (SUCCEEDED(aTablet->get_HardwareCapabilities(&caps))) {
return (TabletHardwareCapabilities::THWC_HardProximity & caps);
}
}
return false;
}
HRESULT __stdcall InkCollectorEvent::QueryInterface(REFIID aRiid, void **aObject)
{
// Validate the input
if (!aObject) {
return E_POINTER;
}
HRESULT result = E_NOINTERFACE;
// This object supports IUnknown/IDispatch/IInkCollectorEvents
if ((IID_IUnknown == aRiid) ||
(IID_IDispatch == aRiid) ||
(DIID__IInkCollectorEvents == aRiid)) {
*aObject = this;
// AddRef should be called when we give info about interface
NS_ADDREF_THIS();
result = S_OK;
}
return result;
}
HRESULT InkCollectorEvent::Invoke(DISPID aDispIdMember, REFIID /*aRiid*/,
LCID /*aId*/, WORD /*wFlags*/,
DISPPARAMS* aDispParams, VARIANT* /*aVarResult*/,
EXCEPINFO* /*aExcepInfo*/, UINT* /*aArgErr*/)
{
switch (aDispIdMember) {
case DISPID_ICECursorOutOfRange: {
if (aDispParams && aDispParams->cArgs) {
CursorOutOfRange(static_cast<IInkCursor*>(aDispParams->rgvarg[0].pdispVal));
}
break;
}
};
return S_OK;
}
void InkCollectorEvent::CursorOutOfRange(IInkCursor* aCursor) const
{
IInkTablet* curTablet = nullptr;
if (FAILED(aCursor->get_Tablet(&curTablet))) {
return;
}
// All events should be suppressed except
// from tablets with hard proximity.
if (!IsHardProximityTablet(curTablet)) {
return;
}
// Notify current target window.
if (HWND targetWindow = InkCollector::sInkCollector->GetTarget()) {
::SendMessage(targetWindow, MOZ_WM_PEN_LEAVES_HOVER_OF_DIGITIZER, 0, 0);
}
}