Backing out Elantech patches (bug 593372) because they broke scroll wheel functionality. a=backout

This commit is contained in:
Jim Mathies 2011-02-08 23:05:43 -06:00
Родитель afa09058fc
Коммит 53100f71b6
4 изменённых файлов: 46 добавлений и 365 удалений

Просмотреть файл

@ -1813,11 +1813,6 @@ pref("ui.trackpoint_hack.enabled", -1);
// some trackpad drivers behave better.
pref("ui.window_class_override", "");
// Enables or disables the Elantech gesture hacks. -1 is autodetect, 0 is off,
// and 1 is on. Set this to 1 if three-finger swipe gestures do not cause
// page back/forward actions, or if pinch-to-zoom does not work.
pref("ui.elantech_gesture_hacks.enabled", -1);
# WINNT
#endif

Просмотреть файл

@ -89,35 +89,29 @@ using mozilla::crashreporter::LSPAnnotate;
//-------------------------------------------------------------------------
static PRBool PeekUIMessage(MSG* aMsg)
static BOOL PeekKeyAndIMEMessage(LPMSG msg, HWND hwnd)
{
MSG keyMsg, imeMsg, mouseMsg, *pMsg = 0;
PRBool haveKeyMsg, haveIMEMsg, haveMouseMsg;
haveKeyMsg = ::PeekMessageW(&keyMsg, NULL, WM_KEYFIRST, WM_IME_KEYLAST, PM_NOREMOVE);
haveIMEMsg = ::PeekMessageW(&imeMsg, NULL, NS_WM_IMEFIRST, NS_WM_IMELAST, PM_NOREMOVE);
haveMouseMsg = ::PeekMessageW(&mouseMsg, NULL, WM_MOUSEFIRST, WM_MOUSELAST, PM_NOREMOVE);
if (haveKeyMsg) {
pMsg = &keyMsg;
}
if (haveIMEMsg && (!pMsg || imeMsg.time < pMsg->time)) {
pMsg = &imeMsg;
MSG msg1, msg2, *lpMsg;
BOOL b1, b2;
b1 = ::PeekMessageW(&msg1, NULL, WM_KEYFIRST, WM_IME_KEYLAST, PM_NOREMOVE);
b2 = ::PeekMessageW(&msg2, NULL, NS_WM_IMEFIRST, NS_WM_IMELAST, PM_NOREMOVE);
if (b1 || b2) {
if (b1 && b2) {
if (msg1.time < msg2.time)
lpMsg = &msg1;
else
lpMsg = &msg2;
} else if (b1)
lpMsg = &msg1;
else
lpMsg = &msg2;
if (!nsIMM32Handler::CanOptimizeKeyAndIMEMessages(lpMsg)) {
return false;
}
return ::PeekMessageW(msg, hwnd, lpMsg->message, lpMsg->message, PM_REMOVE);
}
if (pMsg && !nsIMM32Handler::CanOptimizeKeyAndIMEMessages(pMsg)) {
return PR_FALSE;
}
if (haveMouseMsg && (!pMsg || mouseMsg.time < pMsg->time)) {
pMsg = &mouseMsg;
}
if (!pMsg) {
return PR_FALSE;
}
return ::PeekMessageW(aMsg, NULL, pMsg->message, pMsg->message, PM_REMOVE);
return false;
}
/*static*/ LRESULT CALLBACK
@ -327,8 +321,10 @@ nsAppShell::ProcessNextNativeEvent(PRBool mayWait)
do {
MSG msg;
// Give priority to keyboard and mouse messages.
if (PeekUIMessage(&msg) ||
// Give priority to system messages (in particular keyboard, mouse, timer,
// and paint messages).
if (PeekKeyAndIMEMessage(&msg, NULL) ||
::PeekMessageW(&msg, NULL, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE) ||
::PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) {
gotMessage = PR_TRUE;
if (msg.message == WM_QUIT) {

Просмотреть файл

@ -299,8 +299,6 @@ int nsWindow::sTrimOnMinimize = 2;
PRBool nsWindow::sDefaultTrackPointHack = PR_FALSE;
// Default value for general window class (used when the pref is the empty string).
const char* nsWindow::sDefaultMainWindowClass = kClassNameGeneral;
// Whether to enable the Elantech gesture hack.
PRBool nsWindow::sUseElantechGestureHacks = PR_FALSE;
// If we're using D3D9, this will not be allowed during initial 5 seconds.
bool nsWindow::sAllowD3D9 = false;
@ -472,7 +470,7 @@ nsWindow::nsWindow() : nsBaseWidget()
#endif
#if !defined(WINCE)
InitInputWorkaroundPrefDefaults();
InitInputHackDefaults();
#endif
// Init titlebar button info for custom frames.
@ -4653,24 +4651,6 @@ nsWindow::ProcessMessageForPlugin(const MSG &aMsg,
PRBool nsWindow::ProcessMessage(UINT msg, WPARAM &wParam, LPARAM &lParam,
LRESULT *aRetValue)
{
// For the Elantech Touchpad Zoom Gesture Hack, we should check that the
// system time (32-bit milliseconds) hasn't wrapped around. Otherwise we
// might get into the situation where wheel events for the next 50 days of
// system uptime are assumed to be Ctrl+Wheel events. (It is unlikely that
// we would get into that state, because the system would already need to be
// up for 50 days and the Control key message would need to be processed just
// before the system time overflow and the wheel message just after.)
//
// We also take the chance to reset mAssumeWheelIsZoomUntil if we simply have
// passed that time.
if (mAssumeWheelIsZoomUntil) {
DWORD msgTime = ::GetMessageTime();
if (mAssumeWheelIsZoomUntil >= 0x80000000 && msgTime < 0x8000000 ||
mAssumeWheelIsZoomUntil < msgTime) {
mAssumeWheelIsZoomUntil = 0;
}
}
// (Large blocks of code should be broken out into OnEvent handlers.)
if (mWindowHook.Notify(mWnd, msg, wParam, lParam, aRetValue))
return PR_TRUE;
@ -5045,7 +5025,6 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM &wParam, LPARAM &lParam,
case WM_KEYUP:
{
MSG nativeMsg = InitMSG(msg, wParam, lParam);
nativeMsg.time = ::GetMessageTime();
result = ProcessKeyUpMessage(nativeMsg, nsnull);
DispatchPendingEvents();
}
@ -6725,18 +6704,8 @@ PRBool nsWindow::OnMouseWheel(UINT msg, WPARAM wParam, LPARAM lParam, PRBool& ge
::ReplyMessage(isVertical ? 0 : TRUE);
#endif
// Assume the Control key is down if the Elantech touchpad has sent the
// mis-ordered WM_KEYDOWN/WM_MOUSEWHEEL messages. (See the comment in
// OnKeyUp.)
PRBool isControl;
if (mAssumeWheelIsZoomUntil && ::GetMessageTime() < mAssumeWheelIsZoomUntil) {
isControl = PR_TRUE;
} else {
isControl = IS_VK_DOWN(NS_VK_CONTROL);
}
scrollEvent.isShift = IS_VK_DOWN(NS_VK_SHIFT);
scrollEvent.isControl = isControl;
scrollEvent.isControl = IS_VK_DOWN(NS_VK_CONTROL);
scrollEvent.isMeta = PR_FALSE;
scrollEvent.isAlt = IS_VK_DOWN(NS_VK_ALT);
InitEvent(scrollEvent);
@ -6784,37 +6753,6 @@ PRBool nsWindow::IsRedirectedKeyDownMessage(const MSG &aMsg)
GetScanCode(sRedirectedKeyDown.lParam) == GetScanCode(aMsg.lParam));
}
void
nsWindow::PerformElantechSwipeGestureHack(UINT& aVirtualKeyCode,
nsModifierKeyState& aModKeyState)
{
// The Elantech touchpad driver understands three-finger swipe left and
// right gestures, and translates them into Page Up and Page Down key
// events for most applications. For Firefox 3.6, it instead sends
// Alt+Left and Alt+Right to trigger browser back/forward actions. As
// with the Thinkpad Driver hack in nsWindow::Create, the change in
// HWND structure makes Firefox not trigger the driver's heuristics
// any longer.
//
// The Elantech driver actually sends these messages for a three-finger
// swipe right:
//
// WM_KEYDOWN virtual_key = 0xCC or 0xFF (depending on driver version)
// WM_KEYDOWN virtual_key = VK_NEXT
// WM_KEYUP virtual_key = VK_NEXT
// WM_KEYUP virtual_key = 0xCC or 0xFF
//
// so we use the 0xCC or 0xFF key modifier to detect whether the Page Down
// is due to the gesture rather than a regular Page Down keypress. We then
// pretend that we were went an Alt+Right keystroke instead. Similarly
// for VK_PRIOR and Alt+Left.
if ((aVirtualKeyCode == VK_NEXT || aVirtualKeyCode == VK_PRIOR) &&
(IS_VK_DOWN(0xFF) || IS_VK_DOWN(0xCC))) {
aModKeyState.mIsAltDown = true;
aVirtualKeyCode = aVirtualKeyCode == VK_NEXT ? VK_RIGHT : VK_LEFT;
}
}
/**
* nsWindow::OnKeyDown peeks into the message queue and pulls out
* WM_CHAR messages for processing. During testing we don't want to
@ -6835,10 +6773,6 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg,
gKbdLayout.OnKeyDown(virtualKeyCode);
#endif
if (sUseElantechGestureHacks) {
PerformElantechSwipeGestureHack(virtualKeyCode, aModKeyState);
}
// Use only DOMKeyCode for XP processing.
// Use virtualKeyCode for gKbdLayout and native processing.
UINT DOMKeyCode = nsIMM32Handler::IsComposingOn(this) ?
@ -7189,29 +7123,6 @@ LRESULT nsWindow::OnKeyUp(const MSG &aMsg,
{
UINT virtualKeyCode = aMsg.wParam;
if (sUseElantechGestureHacks) {
PerformElantechSwipeGestureHack(virtualKeyCode, aModKeyState);
// Version 8 of the Elantech touchpad driver sends these messages for
// zoom gestures:
//
// WM_KEYDOWN virtual_key = 0xCC time = 10
// WM_KEYDOWN virtual_key = VK_CONTROL time = 10
// WM_MOUSEWHEEL time = ::GetTickCount()
// WM_KEYUP virtual_key = VK_CONTROL time = 10
// WM_KEYUP virtual_key = 0xCC time = 10
//
// The result of this is that we process all of the WM_KEYDOWN/WM_KEYUP
// messages first because their timestamps make them appear to have
// been sent before the WM_MOUSEWHEEL message. To work around this,
// we store the current time when we process the WM_KEYUP message and
// assume that any WM_MOUSEWHEEL message with a timestamp before that
// time is one that should be processed as if the Control key was down.
if (virtualKeyCode == VK_CONTROL && aMsg.time == 10) {
mAssumeWheelIsZoomUntil = ::GetTickCount();
}
}
PR_LOG(gWindowsLog, PR_LOG_ALWAYS,
("nsWindow::OnKeyUp VK=%d\n", virtualKeyCode));
@ -7651,125 +7562,6 @@ HWND nsWindow::FindOurProcessWindow(HWND aHWND)
return nsnull;
}
static PRBool PointInWindow(HWND aHWND, const POINT& aPoint)
{
RECT bounds;
if (!::GetWindowRect(aHWND, &bounds)) {
return PR_FALSE;
}
if (aPoint.x < bounds.left
|| aPoint.x >= bounds.right
|| aPoint.y < bounds.top
|| aPoint.y >= bounds.bottom) {
return PR_FALSE;
}
return PR_TRUE;
}
static HWND FindTopmostWindowAtPoint(HWND aHWND, const POINT& aPoint)
{
if (!::IsWindowVisible(aHWND) || !PointInWindow(aHWND, aPoint)) {
return 0;
}
HWND childWnd = ::GetTopWindow(aHWND);
while (childWnd) {
HWND topmostWnd = FindTopmostWindowAtPoint(childWnd, aPoint);
if (topmostWnd) {
return topmostWnd;
}
childWnd = ::GetNextWindow(childWnd, GW_HWNDNEXT);
}
return aHWND;
}
struct FindOurWindowAtPointInfo
{
POINT mInPoint;
HWND mOutHWND;
};
/* static */
BOOL CALLBACK nsWindow::FindOurWindowAtPointCallback(HWND aHWND, LPARAM aLPARAM)
{
if (!nsWindow::IsOurProcessWindow(aHWND)) {
// This isn't one of our top-level windows; continue enumerating.
return TRUE;
}
// Get the top-most child window under the point. If there's no child
// window, and the point is within the top-level window, then the top-level
// window will be returned. (This is the usual case. A child window
// would be returned for plugins.)
FindOurWindowAtPointInfo* info = reinterpret_cast<FindOurWindowAtPointInfo*>(aLPARAM);
HWND childWnd = FindTopmostWindowAtPoint(aHWND, info->mInPoint);
if (!childWnd) {
// This window doesn't contain the point; continue enumerating.
return TRUE;
}
// Return the HWND and stop enumerating.
info->mOutHWND = childWnd;
return FALSE;
}
/* static */
HWND nsWindow::FindOurWindowAtPoint(const POINT& aPoint)
{
FindOurWindowAtPointInfo info;
info.mInPoint = aPoint;
info.mOutHWND = 0;
// This will enumerate all top-level windows in order from top to bottom.
EnumWindows(FindOurWindowAtPointCallback, reinterpret_cast<LPARAM>(&info));
return info.mOutHWND;
}
typedef DWORD (*GetProcessImageFileNameProc)(HANDLE, LPTSTR, DWORD);
// Determine whether the given HWND is the handle for the Elantech helper
// window. The helper window cannot be distinguished based on its
// window class, so we need to check if it is owned by the helper process,
// ETDCtrl.exe.
static PRBool IsElantechHelperWindow(HWND aHWND)
{
static HMODULE hPSAPI = ::LoadLibrary(L"psapi.dll");
static GetProcessImageFileNameProc pGetProcessImageFileName =
reinterpret_cast<GetProcessImageFileNameProc>(::GetProcAddress(hPSAPI, "GetProcessImageFileNameW"));
if (!pGetProcessImageFileName) {
return PR_FALSE;
}
const PRUnichar* filenameSuffix = L"\\etdctrl.exe";
const int filenameSuffixLength = 12;
DWORD pid;
::GetWindowThreadProcessId(aHWND, &pid);
PRBool result = PR_FALSE;
HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
if (hProcess) {
PRUnichar path[256];
if (pGetProcessImageFileName(hProcess, path, sizeof path)) {
path[255] = 0;
int pathLength = lstrlen(path);
if (pathLength >= filenameSuffixLength) {
if (lstrcmpi(path + pathLength - filenameSuffixLength, filenameSuffix) == 0) {
result = PR_TRUE;
}
}
}
::CloseHandle(hProcess);
}
return result;
}
// Scrolling helper function for handling plugins.
// Return value indicates whether the calling function should handle this
// aHandled indicates whether this was handled at all
@ -7824,14 +7616,6 @@ PRBool nsWindow::HandleScrollingPlugins(UINT aMsg, WPARAM aWParam,
// is another app's window or no window under the
// pointer.
if (sUseElantechGestureHacks && IsElantechHelperWindow(destWnd)) {
// The Elantech driver places a window right underneath the cursor
// when sending a WM_MOUSEWHEEL event to us as part of a pinch-to-zoom
// gesture. We detect that here, and search for our window that would
// be beneath the cursor if that window wasn't there.
destWnd = FindOurWindowAtPoint(point);
}
if (!destWnd) {
// No window is under the pointer
return PR_FALSE; // break, but continue processing
@ -9037,28 +8821,13 @@ void nsWindow::GetMainWindowClass(nsAString& aClass)
aClass.AssignASCII(sDefaultMainWindowClass);
}
/**
* Gets the Boolean value of a pref used to enable or disable an input
* workaround (like the Trackpoint hack). The pref can take values 0 (for
* disabled), 1 (for enabled) or -1 (to automatically detect whether to
* enable the workaround).
*
* @param aPrefName The name of the pref.
* @param aValueIfAutomatic Whether the given input workaround should be
* enabled by default.
*/
PRBool nsWindow::GetInputWorkaroundPref(const char* aPrefName,
PRBool aValueIfAutomatic)
PRBool nsWindow::UseTrackPointHack()
{
if (!aPrefName) {
return aValueIfAutomatic;
}
nsresult rv;
nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
if (NS_SUCCEEDED(rv) && prefs) {
PRInt32 lHackValue;
rv = prefs->GetIntPref(aPrefName, &lHackValue);
rv = prefs->GetIntPref("ui.trackpoint_hack.enabled", &lHackValue);
if (NS_SUCCEEDED(rv)) {
switch (lHackValue) {
case 0: // disabled
@ -9070,18 +8839,12 @@ PRBool nsWindow::GetInputWorkaroundPref(const char* aPrefName,
}
}
}
return aValueIfAutomatic;
}
PRBool nsWindow::UseTrackPointHack()
{
return GetInputWorkaroundPref("ui.trackpoint_hack.enabled",
sDefaultTrackPointHack);
return sDefaultTrackPointHack;
}
#if !defined(WINCE)
static PRBool
HasRegistryKey(HKEY aRoot, PRUnichar* aName)
HasRegistryKey(HKEY aRoot, LPCWSTR aName)
{
HKEY key;
LONG result = ::RegOpenKeyExW(aRoot, aName, 0, KEY_READ, &key);
@ -9091,91 +8854,28 @@ HasRegistryKey(HKEY aRoot, PRUnichar* aName)
return PR_TRUE;
}
/**
* Gets the value of a string-typed registry value.
*
* @param aRoot The registry root to search in.
* @param aKeyName The name of the registry key to open.
* @param aValueName The name of the registry value in the specified key whose
* value is to be retrieved. Can be null, to retrieve the key's unnamed/
* default value.
* @param aBuffer The buffer into which to store the string value. Can be null,
* in which case the return value indicates just whether the value exists.
* @param aBufferLength The size of aBuffer, in bytes.
* @return Whether the value exists and is a string.
*/
static PRBool
GetRegistryKey(HKEY aRoot, PRUnichar* aKeyName, PRUnichar* aValueName, PRUnichar* aBuffer, DWORD aBufferLength)
{
if (!aKeyName) {
return PR_FALSE;
}
HKEY key;
LONG result = ::RegOpenKeyExW(aRoot, aKeyName, NULL, KEY_READ, &key);
if (result != ERROR_SUCCESS)
return PR_FALSE;
DWORD type;
result = ::RegQueryValueExW(key, aValueName, NULL, &type, (BYTE*) aBuffer, &aBufferLength);
::RegCloseKey(key);
if (result != ERROR_SUCCESS || type != REG_SZ)
return PR_FALSE;
if (aBuffer)
aBuffer[aBufferLength - 1] = 0;
return PR_TRUE;
}
static PRBool
IsObsoleteSynapticsDriver()
{
PRUnichar buf[40];
PRBool foundKey = GetRegistryKey(HKEY_LOCAL_MACHINE,
L"Software\\Synaptics\\SynTP\\Install",
L"DriverVersion",
buf,
sizeof buf);
if (!foundKey)
HKEY key;
LONG result = ::RegOpenKeyExW(HKEY_LOCAL_MACHINE,
L"Software\\Synaptics\\SynTP\\Install", 0, KEY_READ, &key);
if (result != ERROR_SUCCESS)
return PR_FALSE;
DWORD type;
PRUnichar buf[40];
DWORD buflen = sizeof(buf);
result = ::RegQueryValueExW(key, L"DriverVersion", NULL, &type, (BYTE*)buf, &buflen);
::RegCloseKey(key);
if (result != ERROR_SUCCESS || type != REG_SZ)
return PR_FALSE;
buf[NS_ARRAY_LENGTH(buf) - 1] = 0;
int majorVersion = wcstol(buf, NULL, 10);
return majorVersion < 15;
}
static PRBool
IsObsoleteElantechDriver()
{
PRUnichar buf[40];
// The driver version is found in one of these two registry keys.
PRBool foundKey = GetRegistryKey(HKEY_CURRENT_USER,
L"Software\\Elantech\\MainOption",
L"DriverVersion",
buf,
sizeof buf);
if (!foundKey)
foundKey = GetRegistryKey(HKEY_CURRENT_USER,
L"Software\\Elantech",
L"DriverVersion",
buf,
sizeof buf);
if (!foundKey)
return PR_FALSE;
// Assume that the major version number can be found just after a space
// or at the start of the string.
for (PRUnichar* p = buf; *p; p++) {
if (*p >= L'0' && *p <= L'9' && (p == buf || *(p - 1) == L' ')) {
int majorVersion = wcstol(p, NULL, 10);
// Versions 7 and 8 need the hack.
if (majorVersion == 7 || majorVersion == 8)
return PR_TRUE;
}
}
return PR_FALSE;
}
void nsWindow::InitInputWorkaroundPrefDefaults()
void nsWindow::InitInputHackDefaults()
{
if (HasRegistryKey(HKEY_CURRENT_USER, L"Software\\Lenovo\\TrackPoint")) {
sDefaultTrackPointHack = PR_TRUE;
@ -9188,10 +8888,6 @@ void nsWindow::InitInputWorkaroundPrefDefaults()
IsObsoleteSynapticsDriver()) {
sDefaultTrackPointHack = PR_TRUE;
}
sUseElantechGestureHacks =
GetInputWorkaroundPref("ui.elantech_gesture_hacks.enabled",
IsObsoleteElantechDriver());
}
#endif // #if !defined(WINCE)

Просмотреть файл

@ -317,7 +317,6 @@ protected:
static BOOL CALLBACK EnumAllThreadWindowProc(HWND aWnd, LPARAM aParam);
static void AllowD3D9Callback(nsWindow *aWindow);
static void AllowD3D9WithReinitializeCallback(nsWindow *aWindow);
static BOOL CALLBACK FindOurWindowAtPointCallback(HWND aHWND, LPARAM aLPARAM);
/**
* Window utilities
@ -333,19 +332,16 @@ protected:
void InvalidateNonClientRegion();
HRGN ExcludeNonClientFromPaintRegion(HRGN aRegion);
#if !defined(WINCE)
static void InitInputWorkaroundPrefDefaults();
static void InitInputHackDefaults();
#endif
static PRBool GetInputWorkaroundPref(const char* aPrefName, PRBool aValueIfAutomatic);
static PRBool UseTrackPointHack();
static void PerformElantechSwipeGestureHack(UINT& aVirtualKeyCode, nsModifierKeyState& aModKeyState);
static void GetMainWindowClass(nsAString& aClass);
PRBool HasGlass() const {
return mTransparencyMode == eTransparencyGlass ||
mTransparencyMode == eTransparencyBorderlessGlass;
}
static PRBool IsOurProcessWindow(HWND aHWND);
static HWND FindOurProcessWindow(HWND aHWND);
static HWND FindOurWindowAtPoint(const POINT& aPoint);
PRBool IsOurProcessWindow(HWND aHWND);
HWND FindOurProcessWindow(HWND aHWND);
/**
* Event processing helpers
@ -531,7 +527,6 @@ protected:
nsPopupType mPopupType;
nsSizeMode mOldSizeMode;
WindowHook mWindowHook;
DWORD mAssumeWheelIsZoomUntil;
static PRUint32 sInstanceCount;
static TriStateBool sCanQuit;
static nsWindow* sCurrentWindow;
@ -545,7 +540,6 @@ protected:
static int sTrimOnMinimize;
static PRBool sDefaultTrackPointHack;
static const char* sDefaultMainWindowClass;
static PRBool sUseElantechGestureHacks;
static bool sAllowD3D9;
#ifdef MOZ_IPC
static PRUint32 sOOPPPluginFocusEvent;