mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-16 22:04:36 +00:00
![Mantaroh Yoshinaga](/assets/img/avatar_default.png)
In order to move print native dialog code to windows widget, this patch will create skeleton of PrintDialogService to windows widget. Toolkit code(i.e. nsIPrintingPrompotService) will call this PrintDialogService. Note that this PrintingDialogService suppose running on main process, so we should call this interface from main process(i.e. nsPrintingPromptService, not nsPrintingProxy). MozReview-Commit-ID: 3P6kac9I9W4 --HG-- extra : rebase_source : 5b5ecd104cf4cecd1b68a3d6d4b33aca9fea9548
246 lines
7.5 KiB
C++
246 lines
7.5 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* 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 "nsWindowBase.h"
|
|
|
|
#include "gfxPrefs.h"
|
|
#include "mozilla/MiscEvents.h"
|
|
#include "KeyboardLayout.h"
|
|
#include "WinUtils.h"
|
|
#include "npapi.h"
|
|
#include "nsAutoPtr.h"
|
|
#include "nsIPresShell.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)
|
|
{
|
|
if (!ShouldDispatchPluginEvent()) {
|
|
return false;
|
|
}
|
|
WidgetPluginEvent pluginEvent(true, ePluginInputEvent, this);
|
|
LayoutDeviceIntPoint point(0, 0);
|
|
InitEvent(pluginEvent, &point);
|
|
NPEvent npEvent;
|
|
npEvent.event = aMsg.message;
|
|
npEvent.wParam = aMsg.wParam;
|
|
npEvent.lParam = aMsg.lParam;
|
|
pluginEvent.mPluginEvent.Copy(npEvent);
|
|
pluginEvent.mRetargetToFocusedDocument = true;
|
|
return DispatchWindowEvent(&pluginEvent);
|
|
}
|
|
|
|
bool
|
|
nsWindowBase::ShouldDispatchPluginEvent()
|
|
{
|
|
return PluginHasFocus();
|
|
}
|
|
|
|
// 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, LayoutDeviceIntPoint& aPoint,
|
|
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 = aPoint.x;
|
|
info.pointerInfo.ptPixelLocation.y = aPoint.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;
|
|
}
|
|
|
|
void nsWindowBase::ChangedDPI()
|
|
{
|
|
if (mWidgetListener) {
|
|
nsIPresShell* presShell = mWidgetListener->GetPresShell();
|
|
if (presShell) {
|
|
presShell->BackingScaleFactorChanged();
|
|
}
|
|
mWidgetListener->UIResolutionChanged();
|
|
}
|
|
}
|
|
|
|
nsresult
|
|
nsWindowBase::SynthesizeNativeTouchPoint(uint32_t aPointerId,
|
|
nsIWidget::TouchPointerState aPointerState,
|
|
LayoutDeviceIntPoint aPoint,
|
|
double aPointerPressure,
|
|
uint32_t aPointerOrientation,
|
|
nsIObserver* aObserver)
|
|
{
|
|
AutoObserverNotifier notifier(aObserver, "touchpoint");
|
|
|
|
if (gfxPrefs::APZTestFailsWithNativeInjection() || !InitTouchInjection()) {
|
|
// If we don't have touch injection from the OS, or if we are running a test
|
|
// that cannot properly inject events to satisfy the OS requirements (see bug
|
|
// 1313170) we can just fake it and synthesize the events from here.
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
if (aPointerState == TOUCH_HOVER) {
|
|
return NS_ERROR_UNEXPECTED;
|
|
}
|
|
|
|
if (!mSynthesizedTouchInput) {
|
|
mSynthesizedTouchInput = MakeUnique<MultiTouchInput>();
|
|
}
|
|
|
|
WidgetEventTime time = CurrentMessageWidgetEventTime();
|
|
LayoutDeviceIntPoint pointInWindow = aPoint - WidgetToScreenOffset();
|
|
MultiTouchInput inputToDispatch = UpdateSynthesizedTouchState(
|
|
mSynthesizedTouchInput.get(), time.mTime, time.mTimeStamp,
|
|
aPointerId, aPointerState, pointInWindow, aPointerPressure,
|
|
aPointerOrientation);
|
|
DispatchTouchInput(inputToDispatch);
|
|
return NS_OK;
|
|
}
|
|
|
|
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, aPoint, 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, aPoint);
|
|
|
|
POINTER_FLAGS flags = POINTER_FLAG_INRANGE;
|
|
if (contact) {
|
|
flags |= POINTER_FLAG_INCONTACT|POINTER_FLAG_DOWN;
|
|
}
|
|
|
|
mActivePointers.Put(aPointerId, info);
|
|
return !InjectTouchPoint(aPointerId, aPoint, flags,
|
|
pressure, aPointerOrientation) ?
|
|
NS_ERROR_UNEXPECTED : NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsWindowBase::ClearNativeTouchSequence(nsIObserver* aObserver)
|
|
{
|
|
AutoObserverNotifier notifier(aObserver, "cleartouch");
|
|
if (!sTouchInjectInitialized) {
|
|
return NS_OK;
|
|
}
|
|
|
|
// cancel all input points
|
|
for (auto iter = mActivePointers.Iter(); !iter.Done(); iter.Next()) {
|
|
nsAutoPtr<PointerInfo>& info = iter.Data();
|
|
InjectTouchPoint(info.get()->mPointerId, info.get()->mPosition,
|
|
POINTER_FLAG_CANCELED);
|
|
iter.Remove();
|
|
}
|
|
|
|
nsBaseWidget::ClearNativeTouchSequence(nullptr);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
bool
|
|
nsWindowBase::HandleAppCommandMsg(const MSG& aAppCommandMsg,
|
|
LRESULT *aRetValue)
|
|
{
|
|
ModifierKeyState modKeyState;
|
|
NativeKey nativeKey(this, aAppCommandMsg, modKeyState);
|
|
bool consumed = nativeKey.HandleAppCommandMessage();
|
|
*aRetValue = consumed ? 1 : 0;
|
|
return consumed;
|
|
}
|