mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 941774 - Win32/winrt shared implementation. r=bbondy
This commit is contained in:
parent
10b178f798
commit
de63519aea
@ -6,9 +6,16 @@
|
||||
#include "nsWindowBase.h"
|
||||
|
||||
#include "mozilla/MiscEvents.h"
|
||||
|
||||
#include "WinUtils.h"
|
||||
#include "npapi.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::widget;
|
||||
|
||||
static const wchar_t kUser32LibName[] = L"user32.dll";
|
||||
bool nsWindowBase::sTouchInjectInitialized = false;
|
||||
InjectTouchInputPtr nsWindowBase::sInjectTouchFuncPtr;
|
||||
|
||||
bool
|
||||
nsWindowBase::DispatchPluginEvent(const MSG& aMsg)
|
||||
@ -27,3 +34,164 @@ nsWindowBase::DispatchPluginEvent(const MSG& aMsg)
|
||||
pluginEvent.retargetToFocusedDocument = true;
|
||||
return DispatchWindowEvent(&pluginEvent);
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
nsWindowBase::InitTouchInjection()
|
||||
{
|
||||
if (!sTouchInjectInitialized) {
|
||||
// Initialize touch injection on the first call
|
||||
HMODULE hMod = LoadLibraryW(kUser32LibName);
|
||||
if (!hMod) {
|
||||
return false;
|
||||
}
|
||||
|
||||
InitializeTouchInjectionPtr func =
|
||||
(InitializeTouchInjectionPtr)GetProcAddress(hMod, "InitializeTouchInjection");
|
||||
if (!func) {
|
||||
WinUtils::Log("InitializeTouchInjection not available.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!func(TOUCH_INJECT_MAX_POINTS, TOUCH_FEEDBACK_DEFAULT)) {
|
||||
WinUtils::Log("InitializeTouchInjection failure. GetLastError=%d", GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
sInjectTouchFuncPtr =
|
||||
(InjectTouchInputPtr)GetProcAddress(hMod, "InjectTouchInput");
|
||||
if (!sInjectTouchFuncPtr) {
|
||||
WinUtils::Log("InjectTouchInput not available.");
|
||||
return false;
|
||||
}
|
||||
sTouchInjectInitialized = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nsWindowBase::InjectTouchPoint(uint32_t aId, nsIntPoint& aPointerScreenPoint,
|
||||
POINTER_FLAGS aFlags, uint32_t aPressure,
|
||||
uint32_t aOrientation)
|
||||
{
|
||||
if (aId > TOUCH_INJECT_MAX_POINTS) {
|
||||
WinUtils::Log("Pointer ID exceeds maximum. See TOUCH_INJECT_MAX_POINTS.");
|
||||
return false;
|
||||
}
|
||||
|
||||
POINTER_TOUCH_INFO info;
|
||||
memset(&info, 0, sizeof(POINTER_TOUCH_INFO));
|
||||
|
||||
info.touchFlags = TOUCH_FLAG_NONE;
|
||||
info.touchMask = TOUCH_MASK_CONTACTAREA|TOUCH_MASK_ORIENTATION|TOUCH_MASK_PRESSURE;
|
||||
info.pressure = aPressure;
|
||||
info.orientation = aOrientation;
|
||||
|
||||
info.pointerInfo.pointerFlags = aFlags;
|
||||
info.pointerInfo.pointerType = PT_TOUCH;
|
||||
info.pointerInfo.pointerId = aId;
|
||||
info.pointerInfo.ptPixelLocation.x = WinUtils::LogToPhys(aPointerScreenPoint.x);
|
||||
info.pointerInfo.ptPixelLocation.y = WinUtils::LogToPhys(aPointerScreenPoint.y);
|
||||
|
||||
info.rcContact.top = info.pointerInfo.ptPixelLocation.y - 2;
|
||||
info.rcContact.bottom = info.pointerInfo.ptPixelLocation.y + 2;
|
||||
info.rcContact.left = info.pointerInfo.ptPixelLocation.x - 2;
|
||||
info.rcContact.right = info.pointerInfo.ptPixelLocation.x + 2;
|
||||
|
||||
if (!sInjectTouchFuncPtr(1, &info)) {
|
||||
WinUtils::Log("InjectTouchInput failure. GetLastError=%d", GetLastError());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsWindowBase::SynthesizeNativeTouchPoint(uint32_t aPointerId,
|
||||
nsIWidget::TouchPointerState aPointerState,
|
||||
nsIntPoint aPointerScreenPoint,
|
||||
double aPointerPressure,
|
||||
uint32_t aPointerOrientation)
|
||||
{
|
||||
if (!InitTouchInjection()) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
bool hover = aPointerState & TOUCH_HOVER;
|
||||
bool contact = aPointerState & TOUCH_CONTACT;
|
||||
bool remove = aPointerState & TOUCH_REMOVE;
|
||||
bool cancel = aPointerState & TOUCH_CANCEL;
|
||||
|
||||
// win api expects a value from 0 to 1024. aPointerPressure is a value
|
||||
// from 0.0 to 1.0.
|
||||
uint32_t pressure = (uint32_t)ceil(aPointerPressure * 1024);
|
||||
|
||||
// If we already know about this pointer id get it's record
|
||||
PointerInfo* info = mActivePointers.Get(aPointerId);
|
||||
|
||||
// We know about this pointer, send an update
|
||||
if (info) {
|
||||
POINTER_FLAGS flags = POINTER_FLAG_UPDATE;
|
||||
if (hover) {
|
||||
flags |= POINTER_FLAG_INRANGE;
|
||||
} else if (contact) {
|
||||
flags |= POINTER_FLAG_INCONTACT|POINTER_FLAG_INRANGE;
|
||||
} else if (remove) {
|
||||
flags = POINTER_FLAG_UP;
|
||||
// Remove the pointer from our tracking list. This is nsAutPtr wrapped,
|
||||
// so shouldn't leak.
|
||||
mActivePointers.Remove(aPointerId);
|
||||
}
|
||||
|
||||
if (cancel) {
|
||||
flags |= POINTER_FLAG_CANCELED;
|
||||
}
|
||||
|
||||
return !InjectTouchPoint(aPointerId, aPointerScreenPoint, flags,
|
||||
pressure, aPointerOrientation) ?
|
||||
NS_ERROR_UNEXPECTED : NS_OK;
|
||||
}
|
||||
|
||||
// Missing init state, error out
|
||||
if (remove || cancel) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// Create a new pointer
|
||||
info = new PointerInfo(aPointerId, aPointerScreenPoint);
|
||||
|
||||
POINTER_FLAGS flags = POINTER_FLAG_INRANGE;
|
||||
if (contact) {
|
||||
flags |= POINTER_FLAG_INCONTACT|POINTER_FLAG_DOWN;
|
||||
}
|
||||
|
||||
mActivePointers.Put(aPointerId, info);
|
||||
return !InjectTouchPoint(aPointerId, aPointerScreenPoint, flags,
|
||||
pressure, aPointerOrientation) ?
|
||||
NS_ERROR_UNEXPECTED : NS_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
PLDHashOperator
|
||||
nsWindowBase::CancelTouchPoints(const unsigned int& aPointerId, nsAutoPtr<PointerInfo>& aInfo, void* aUserArg)
|
||||
{
|
||||
nsWindowBase* self = static_cast<nsWindowBase*>(aUserArg);
|
||||
self->InjectTouchPoint(aInfo.get()->mPointerId, aInfo.get()->mPosition, POINTER_FLAG_CANCELED);
|
||||
return (PLDHashOperator)(PL_DHASH_NEXT|PL_DHASH_REMOVE);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsWindowBase::ClearNativeTouchSequence()
|
||||
{
|
||||
if (!sTouchInjectInitialized) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// cancel all input points
|
||||
mActivePointers.Enumerate(CancelTouchPoints, (void*)this);
|
||||
|
||||
nsBaseWidget::ClearNativeTouchSequence();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -8,7 +8,10 @@
|
||||
|
||||
#include "mozilla/EventForwards.h"
|
||||
#include "nsBaseWidget.h"
|
||||
#include "nsClassHashtable.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include "touchinjection_sdk80.h"
|
||||
|
||||
/*
|
||||
* nsWindowBase - Base class of common methods other classes need to access
|
||||
@ -75,6 +78,42 @@ public:
|
||||
return (mInputContext.mIMEState.mEnabled == IMEState::PLUGIN);
|
||||
}
|
||||
|
||||
public:
|
||||
/*
|
||||
* Touch input injection apis
|
||||
*/
|
||||
virtual nsresult SynthesizeNativeTouchPoint(uint32_t aPointerId,
|
||||
TouchPointerState aPointerState,
|
||||
nsIntPoint aPointerScreenPoint,
|
||||
double aPointerPressure,
|
||||
uint32_t aPointerOrientation);
|
||||
virtual nsresult ClearNativeTouchSequence();
|
||||
|
||||
protected:
|
||||
static bool InitTouchInjection();
|
||||
bool InjectTouchPoint(uint32_t aId, nsIntPoint& aPointerScreenPoint,
|
||||
POINTER_FLAGS aFlags, uint32_t aPressure = 1024,
|
||||
uint32_t aOrientation = 90);
|
||||
|
||||
class PointerInfo
|
||||
{
|
||||
public:
|
||||
PointerInfo(int32_t aPointerId, nsIntPoint& aPoint) :
|
||||
mPointerId(aPointerId),
|
||||
mPosition(aPoint)
|
||||
{
|
||||
}
|
||||
|
||||
int32_t mPointerId;
|
||||
nsIntPoint mPosition;
|
||||
};
|
||||
|
||||
static PLDHashOperator CancelTouchPoints(const unsigned int& aPointerId, nsAutoPtr<PointerInfo>& aInfo, void* aUserArg);
|
||||
|
||||
nsClassHashtable<nsUint32HashKey, PointerInfo> mActivePointers;
|
||||
static bool sTouchInjectInitialized;
|
||||
static InjectTouchInputPtr sInjectTouchFuncPtr;
|
||||
|
||||
protected:
|
||||
InputContext mInputContext;
|
||||
};
|
||||
|
107
widget/windows/touchinjection_sdk80.h
Normal file
107
widget/windows/touchinjection_sdk80.h
Normal file
@ -0,0 +1,107 @@
|
||||
/* 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/. */
|
||||
|
||||
#ifndef touchinjection_sdk80_h
|
||||
#define touchinjection_sdk80_h
|
||||
|
||||
// Note, this isn't inclusive of all touch injection header info.
|
||||
// You may need to add more to expand on current apis.
|
||||
|
||||
#ifndef TOUCH_FEEDBACK_DEFAULT
|
||||
|
||||
#define TOUCH_FEEDBACK_DEFAULT 0x1
|
||||
#define TOUCH_FEEDBACK_INDIRECT 0x2
|
||||
#define TOUCH_FEEDBACK_NONE 0x3
|
||||
|
||||
enum {
|
||||
PT_POINTER = 0x00000001, // Generic pointer
|
||||
PT_TOUCH = 0x00000002, // Touch
|
||||
PT_PEN = 0x00000003, // Pen
|
||||
PT_MOUSE = 0x00000004, // Mouse
|
||||
};
|
||||
|
||||
typedef DWORD POINTER_INPUT_TYPE;
|
||||
typedef UINT32 POINTER_FLAGS;
|
||||
|
||||
typedef enum {
|
||||
POINTER_CHANGE_NONE,
|
||||
POINTER_CHANGE_FIRSTBUTTON_DOWN,
|
||||
POINTER_CHANGE_FIRSTBUTTON_UP,
|
||||
POINTER_CHANGE_SECONDBUTTON_DOWN,
|
||||
POINTER_CHANGE_SECONDBUTTON_UP,
|
||||
POINTER_CHANGE_THIRDBUTTON_DOWN,
|
||||
POINTER_CHANGE_THIRDBUTTON_UP,
|
||||
POINTER_CHANGE_FOURTHBUTTON_DOWN,
|
||||
POINTER_CHANGE_FOURTHBUTTON_UP,
|
||||
POINTER_CHANGE_FIFTHBUTTON_DOWN,
|
||||
POINTER_CHANGE_FIFTHBUTTON_UP,
|
||||
} POINTER_BUTTON_CHANGE_TYPE;
|
||||
|
||||
typedef struct {
|
||||
POINTER_INPUT_TYPE pointerType;
|
||||
UINT32 pointerId;
|
||||
UINT32 frameId;
|
||||
POINTER_FLAGS pointerFlags;
|
||||
HANDLE sourceDevice;
|
||||
HWND hwndTarget;
|
||||
POINT ptPixelLocation;
|
||||
POINT ptHimetricLocation;
|
||||
POINT ptPixelLocationRaw;
|
||||
POINT ptHimetricLocationRaw;
|
||||
DWORD dwTime;
|
||||
UINT32 historyCount;
|
||||
INT32 InputData;
|
||||
DWORD dwKeyStates;
|
||||
UINT64 PerformanceCount;
|
||||
POINTER_BUTTON_CHANGE_TYPE ButtonChangeType;
|
||||
} POINTER_INFO;
|
||||
|
||||
typedef UINT32 TOUCH_FLAGS;
|
||||
typedef UINT32 TOUCH_MASK;
|
||||
|
||||
typedef struct {
|
||||
POINTER_INFO pointerInfo;
|
||||
TOUCH_FLAGS touchFlags;
|
||||
TOUCH_MASK touchMask;
|
||||
RECT rcContact;
|
||||
RECT rcContactRaw;
|
||||
UINT32 orientation;
|
||||
UINT32 pressure;
|
||||
} POINTER_TOUCH_INFO;
|
||||
|
||||
#define TOUCH_FLAG_NONE 0x00000000 // Default
|
||||
|
||||
#define TOUCH_MASK_NONE 0x00000000 // Default - none of the optional fields are valid
|
||||
#define TOUCH_MASK_CONTACTAREA 0x00000001 // The rcContact field is valid
|
||||
#define TOUCH_MASK_ORIENTATION 0x00000002 // The orientation field is valid
|
||||
#define TOUCH_MASK_PRESSURE 0x00000004 // The pressure field is valid
|
||||
|
||||
#define POINTER_FLAG_NONE 0x00000000 // Default
|
||||
#define POINTER_FLAG_NEW 0x00000001 // New pointer
|
||||
#define POINTER_FLAG_INRANGE 0x00000002 // Pointer has not departed
|
||||
#define POINTER_FLAG_INCONTACT 0x00000004 // Pointer is in contact
|
||||
#define POINTER_FLAG_FIRSTBUTTON 0x00000010 // Primary action
|
||||
#define POINTER_FLAG_SECONDBUTTON 0x00000020 // Secondary action
|
||||
#define POINTER_FLAG_THIRDBUTTON 0x00000040 // Third button
|
||||
#define POINTER_FLAG_FOURTHBUTTON 0x00000080 // Fourth button
|
||||
#define POINTER_FLAG_FIFTHBUTTON 0x00000100 // Fifth button
|
||||
#define POINTER_FLAG_PRIMARY 0x00002000 // Pointer is primary
|
||||
#define POINTER_FLAG_CONFIDENCE 0x00004000 // Pointer is considered unlikely to be accidental
|
||||
#define POINTER_FLAG_CANCELED 0x00008000 // Pointer is departing in an abnormal manner
|
||||
#define POINTER_FLAG_DOWN 0x00010000 // Pointer transitioned to down state (made contact)
|
||||
#define POINTER_FLAG_UPDATE 0x00020000 // Pointer update
|
||||
#define POINTER_FLAG_UP 0x00040000 // Pointer transitioned from down state (broke contact)
|
||||
#define POINTER_FLAG_WHEEL 0x00080000 // Vertical wheel
|
||||
#define POINTER_FLAG_HWHEEL 0x00100000 // Horizontal wheel
|
||||
#define POINTER_FLAG_CAPTURECHANGED 0x00200000 // Lost capture
|
||||
|
||||
#endif // TOUCH_FEEDBACK_DEFAULT
|
||||
|
||||
#define TOUCH_FLAGS_CONTACTUPDATE (POINTER_FLAG_UPDATE|POINTER_FLAG_INRANGE|POINTER_FLAG_INCONTACT)
|
||||
#define TOUCH_FLAGS_CONTACTDOWN (POINTER_FLAG_DOWN|POINTER_FLAG_INRANGE|POINTER_FLAG_INCONTACT)
|
||||
|
||||
typedef BOOL (WINAPI* InitializeTouchInjectionPtr)(UINT32 maxCount, DWORD dwMode);
|
||||
typedef BOOL (WINAPI* InjectTouchInputPtr)(UINT32 count, CONST POINTER_TOUCH_INFO *info);
|
||||
|
||||
#endif // touchinjection_sdk80_h
|
Loading…
Reference in New Issue
Block a user