Files
tubestation/widget/windows/WinMouseScrollHandler.cpp

225 lines
6.2 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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/. */
#ifdef MOZ_LOGGING
#define FORCE_PR_LOG /* Allow logging in the release build */
#endif // MOZ_LOGGING
#include "prlog.h"
#include "WinMouseScrollHandler.h"
#include "nsWindow.h"
#include "WinUtils.h"
#include "mozilla/Preferences.h"
namespace mozilla {
namespace widget {
#ifdef PR_LOGGING
PRLogModuleInfo* gMouseScrollLog = nsnull;
static const char* GetBoolName(bool aBool)
{
return aBool ? "TRUE" : "FALSE";
}
#endif
MouseScrollHandler* MouseScrollHandler::sInstance = nsnull;
/******************************************************************************
*
* MouseScrollHandler
*
******************************************************************************/
/* static */
void
MouseScrollHandler::Initialize()
{
#ifdef PR_LOGGING
if (!gMouseScrollLog) {
gMouseScrollLog = PR_NewLogModule("MouseScrollHandlerWidgets");
}
#endif
}
/* static */
void
MouseScrollHandler::Shutdown()
{
delete sInstance;
sInstance = nsnull;
}
/* static */
MouseScrollHandler*
MouseScrollHandler::GetInstance()
{
if (!sInstance) {
sInstance = new MouseScrollHandler();
}
return sInstance;
}
MouseScrollHandler::MouseScrollHandler()
{
PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
("MouseScroll: Creating an instance, this=%p, sInstance=%p",
this, sInstance));
}
MouseScrollHandler::~MouseScrollHandler()
{
PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
("MouseScroll: Destroying an instance, this=%p, sInstance=%p",
this, sInstance));
}
/* static */
bool
MouseScrollHandler::ProcessMessage(nsWindow* aWindow, UINT msg,
WPARAM wParam, LPARAM lParam,
LRESULT *aRetValue, bool &aEatMessage)
{
switch (msg) {
case WM_SETTINGCHANGE:
if (!sInstance) {
return false;
}
if (wParam == SPI_SETWHEELSCROLLLINES ||
wParam == SPI_SETWHEELSCROLLCHARS) {
sInstance->mSystemSettings.MarkDirty();
}
return false;
default:
return false;
}
}
/******************************************************************************
*
* SystemSettings
*
******************************************************************************/
void
MouseScrollHandler::SystemSettings::Init()
{
if (mInitialized) {
return;
}
mInitialized = true;
if (!::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &mScrollLines, 0)) {
PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
("MouseScroll::SystemSettings::Init(): ::SystemParametersInfo("
"SPI_GETWHEELSCROLLLINES) failed"));
mScrollLines = 3;
} else if (mScrollLines > WHEEL_DELTA) {
PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
("MouseScroll::SystemSettings::Init(): the result of "
"::SystemParametersInfo(SPI_GETWHEELSCROLLLINES) is too large: %d",
mScrollLines));
// sScrollLines usually equals 3 or 0 (for no scrolling)
// However, if sScrollLines > WHEEL_DELTA, we assume that
// the mouse driver wants a page scroll. The docs state that
// sScrollLines should explicitly equal WHEEL_PAGESCROLL, but
// since some mouse drivers use an arbitrary large number instead,
// we have to handle that as well.
mScrollLines = WHEEL_PAGESCROLL;
}
if (!::SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &mScrollChars, 0)) {
PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
("MouseScroll::SystemSettings::Init(): ::SystemParametersInfo("
"SPI_GETWHEELSCROLLCHARS) failed, %s",
WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION ?
"this is unexpected on Vista or later" :
"but on XP or earlier, this is not a problem"));
mScrollChars = 1;
} else if (mScrollChars > WHEEL_DELTA) {
PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
("MouseScroll::SystemSettings::Init(): the result of "
"::SystemParametersInfo(SPI_GETWHEELSCROLLCHARS) is too large: %d",
mScrollChars));
// See the comments for the case mScrollLines > WHEEL_DELTA.
mScrollChars = WHEEL_PAGESCROLL;
}
PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
("MouseScroll::SystemSettings::Init(): initialized, "
"mScrollLines=%d, mScrollChars=%d",
mScrollLines, mScrollChars));
}
void
MouseScrollHandler::SystemSettings::MarkDirty()
{
PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
("MouseScrollHandler::SystemSettings::MarkDirty(): "
"Marking SystemSettings dirty"));
mInitialized = false;
}
/******************************************************************************
*
* UserPrefs
*
******************************************************************************/
MouseScrollHandler::UserPrefs::UserPrefs() :
mInitialized(false)
{
// We need to reset mouse wheel transaction when all of mousewheel related
// prefs are changed.
DebugOnly<nsresult> rv =
Preferences::RegisterCallback(OnChange, "mousewheel.", this);
MOZ_ASSERT(NS_SUCCEEDED(rv),
"Failed to register callback for mousewheel.");
}
MouseScrollHandler::UserPrefs::~UserPrefs()
{
DebugOnly<nsresult> rv =
Preferences::UnregisterCallback(OnChange, "mousewheel.", this);
MOZ_ASSERT(NS_SUCCEEDED(rv),
"Failed to unregister callback for mousewheel.");
}
void
MouseScrollHandler::UserPrefs::Init()
{
if (mInitialized) {
return;
}
mInitialized = true;
mPixelScrollingEnabled =
Preferences::GetBool("mousewheel.enable_pixel_scrolling", true);
mScrollMessageHandledAsWheelMessage =
Preferences::GetBool("mousewheel.emulate_at_wm_scroll", false);
PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
("MouseScroll::UserPrefs::Init(): initialized, "
"mPixelScrollingEnabled=%s, mScrollMessageHandledAsWheelMessage=%s",
GetBoolName(mPixelScrollingEnabled),
GetBoolName(mScrollMessageHandledAsWheelMessage)));
}
void
MouseScrollHandler::UserPrefs::MarkDirty()
{
PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
("MouseScrollHandler::UserPrefs::MarkDirty(): Marking UserPrefs dirty"));
mInitialized = false;
}
} // namespace widget
} // namespace mozilla