Bug 712483 Implement mozilla::widget::WinUtils r=jimm
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 04 Jan 2012 19:21:44 +0900
changeset 83750 43f76a0051889e5c07dac4dab2e090e03ce2be16
parent 83749 ad98a08690cb7329ee47bda90ab8f9ea28c3e186
child 83751 ae7a421e7fdbd6d70e6de9314c72f56f4a5c993b
push id21790
push userbmo@edmorley.co.uk
push dateThu, 05 Jan 2012 01:00:04 +0000
treeherdermozilla-central@0cdaf0773073 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm
bugs712483
milestone12.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 712483 Implement mozilla::widget::WinUtils r=jimm
widget/windows/Makefile.in
widget/windows/TaskbarPreview.cpp
widget/windows/TaskbarTabPreview.cpp
widget/windows/WinTaskbar.cpp
widget/windows/WinUtils.cpp
widget/windows/WinUtils.h
widget/windows/nsFilePicker.cpp
widget/windows/nsIMM32Handler.cpp
widget/windows/nsNativeThemeWin.cpp
widget/windows/nsUXThemeData.cpp
widget/windows/nsWindow.cpp
widget/windows/nsWindow.h
widget/windows/nsWindowDefs.h
widget/windows/nsWindowGfx.cpp
--- a/widget/windows/Makefile.in
+++ b/widget/windows/Makefile.in
@@ -73,16 +73,17 @@ CPPSRCS = \
   TaskbarWindowPreview.cpp \
   TaskbarPreviewButton.cpp \
   JumpListBuilder.cpp \
   JumpListItem.cpp \
   GfxInfo.cpp \
   WidgetTraceEvent.cpp \
   AudioSession.cpp \
   nsWidgetFactory.cpp \
+  WinUtils.cpp \
   $(NULL)
 
 ifdef MOZ_CRASHREPORTER
 CPPSRCS += LSPAnnotator.cpp
 endif
 
 ifdef NS_PRINTING
 CPPSRCS		+= \
--- a/widget/windows/TaskbarPreview.cpp
+++ b/widget/windows/TaskbarPreview.cpp
@@ -51,16 +51,17 @@
 #include <nsIBaseWindow.h>
 #include <nsIObserverService.h>
 #include <nsServiceManagerUtils.h>
 
 #include "nsUXThemeData.h"
 #include "nsWindow.h"
 #include "nsAppShell.h"
 #include "TaskbarPreviewButton.h"
+#include "WinUtils.h"
 
 #include <nsIBaseWindow.h>
 #include <nsICanvasRenderingContextInternal.h>
 #include <nsIDOMCanvasRenderingContext2D.h>
 #include <imgIContainer.h>
 #include <nsIDocShell.h>
 
 // Defined in dwmapi in a header that needs a higher numbered _WINNT #define
@@ -280,17 +281,17 @@ TaskbarPreview::Disable() {
   (void) hook.RemoveMonitor(nsAppShell::GetTaskbarButtonCreatedMessage(), MainWindowHook, this);
 
   return NS_OK;
 }
 
 bool
 TaskbarPreview::IsWindowAvailable() const {
   if (mWnd) {
-    nsWindow* win = nsWindow::GetNSWindowPtr(mWnd);
+    nsWindow* win = WinUtils::GetNSWindowPtr(mWnd);
     if(win && !win->HasDestroyStarted()) {
       return true;
     }
   }
   return false;
 }
 
 void
@@ -351,26 +352,26 @@ TaskbarPreview::CanMakeTaskbarCalls() {
   // clearly doesn't so we can't make any calls.
   if (!mWnd)
     return false;
   // Certain functions like SetTabOrder seem to require a visible window. During
   // window close, the window seems to be hidden before being destroyed.
   if (!::IsWindowVisible(mWnd))
     return false;
   if (mVisible) {
-    nsWindow *window = nsWindow::GetNSWindowPtr(mWnd);
+    nsWindow *window = WinUtils::GetNSWindowPtr(mWnd);
     NS_ASSERTION(window, "Could not get nsWindow from HWND");
     return window->HasTaskbarIconBeenCreated();
   }
   return false;
 }
 
 WindowHook&
 TaskbarPreview::GetWindowHook() {
-  nsWindow *window = nsWindow::GetNSWindowPtr(mWnd);
+  nsWindow *window = WinUtils::GetNSWindowPtr(mWnd);
   NS_ASSERTION(window, "Cannot use taskbar previews in an embedded context!");
 
   return window->GetWindowHook();
 }
 
 void
 TaskbarPreview::EnableCustomDrawing(HWND aHWND, bool aEnable) {
   BOOL enabled = aEnable;
@@ -444,17 +445,17 @@ TaskbarPreview::MainWindowHook(void *aCo
                nMsg == WM_DESTROY,
                "Window hook proc called with wrong message");
   TaskbarPreview *preview = reinterpret_cast<TaskbarPreview*>(aContext);
   if (nMsg == WM_DESTROY) {
     // nsWindow is being destroyed
     // We can't really do anything at this point including removing hooks
     preview->mWnd = NULL;
   } else {
-    nsWindow *window = nsWindow::GetNSWindowPtr(preview->mWnd);
+    nsWindow *window = WinUtils::GetNSWindowPtr(preview->mWnd);
     NS_ASSERTION(window, "Cannot use taskbar previews in an embedded context!");
 
     window->SetHasTaskbarIconBeenCreated();
 
     if (preview->mVisible)
       preview->UpdateTaskbarProperties();
   }
   return false;
--- a/widget/windows/TaskbarTabPreview.cpp
+++ b/widget/windows/TaskbarTabPreview.cpp
@@ -38,16 +38,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_WIN7
 
 #include "TaskbarTabPreview.h"
 #include "nsWindowGfx.h"
 #include "nsUXThemeData.h"
+#include "WinUtils.h"
 #include <nsITaskbarPreviewController.h>
 
 #define TASKBARPREVIEW_HWNDID L"TaskbarTabPreviewHwnd"
 
 namespace mozilla {
 namespace widget {
 
 NS_IMPL_ISUPPORTS1(TaskbarTabPreview, nsITaskbarTabPreview)
@@ -179,17 +180,17 @@ TaskbarTabPreview::WndProc(UINT nMsg, WP
       return 0;
     case WM_ACTIVATE:
       if (LOWORD(wParam) == WA_ACTIVE) {
         // Activate the tab the user selected then restore the main window,
         // keeping normal/max window state intact.
         bool activateWindow;
         nsresult rv = mController->OnActivate(&activateWindow);
         if (NS_SUCCEEDED(rv) && activateWindow) {
-          nsWindow* win = nsWindow::GetNSWindowPtr(mWnd);
+          nsWindow* win = WinUtils::GetNSWindowPtr(mWnd);
           if (win) {
             nsWindow * parent = win->GetTopLevelWindow(true);
             if (parent) {
               parent->Show(true);
             }
           }
         }
       }
--- a/widget/windows/WinTaskbar.cpp
+++ b/widget/windows/WinTaskbar.cpp
@@ -51,16 +51,17 @@
 #include <nsIBaseWindow.h>
 #include <nsIObserverService.h>
 #include <nsServiceManagerUtils.h>
 #include <nsAutoPtr.h>
 #include "nsIXULAppInfo.h"
 #include "nsIJumpListBuilder.h"
 #include "nsUXThemeData.h"
 #include "nsWindow.h"
+#include "WinUtils.h"
 #include "TaskbarTabPreview.h"
 #include "TaskbarWindowPreview.h"
 #include "JumpListBuilder.h"
 #include "nsWidgetsCID.h"
 #include "nsPIDOMWindow.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "mozilla/Preferences.h"
 #include <io.h>
@@ -323,23 +324,23 @@ WinTaskbar::GetAppUserModelID(nsAString 
     PRUnichar* slash = wcsrchr(path, '\\');
     if (!slash)
       return false;
     *slash = '\0'; // no trailing slash
 
     // The hash is short, but users may customize this, so use a respectable
     // string buffer.
     PRUnichar buf[256];
-    if (nsWindow::GetRegistryKey(HKEY_LOCAL_MACHINE,
+    if (WinUtils::GetRegistryKey(HKEY_LOCAL_MACHINE,
                                  regKey.get(),
                                  path,
                                  buf,
                                  sizeof buf)) {
       aDefaultGroupId.Assign(buf);
-    } else if (nsWindow::GetRegistryKey(HKEY_CURRENT_USER,
+    } else if (WinUtils::GetRegistryKey(HKEY_CURRENT_USER,
                                         regKey.get(),
                                         path,
                                         buf,
                                         sizeof buf)) {
       aDefaultGroupId.Assign(buf);
     }
   }
 
@@ -355,17 +356,17 @@ WinTaskbar::GetDefaultGroupId(nsAString 
     return NS_ERROR_UNEXPECTED;
 
   return NS_OK;
 }
 
 // (static) Called from AppShell
 bool
 WinTaskbar::RegisterAppUserModelID() {
-  if (nsWindow::GetWindowsVersion() < WIN7_VERSION)
+  if (WinUtils::GetWindowsVersion() < WinUtils::WIN7_VERSION)
     return false;
 
   SetCurrentProcessExplicitAppUserModelIDPtr funcAppUserModelID = nsnull;
   bool retVal = false;
 
   nsAutoString uid;
   if (!GetAppUserModelID(uid))
     return false;
@@ -387,17 +388,17 @@ WinTaskbar::RegisterAppUserModelID() {
     ::FreeLibrary(hDLL);
 
   return retVal;
 }
 
 NS_IMETHODIMP
 WinTaskbar::GetAvailable(bool *aAvailable) {
   *aAvailable = 
-    nsWindow::GetWindowsVersion() < WIN7_VERSION ?
+    WinUtils::GetWindowsVersion() < WinUtils::WIN7_VERSION ?
     false : true;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 WinTaskbar::CreateTaskbarTabPreview(nsIDocShell *shell, nsITaskbarPreviewController *controller, nsITaskbarTabPreview **_retval) {
   if (!Initialize())
@@ -427,17 +428,17 @@ WinTaskbar::GetTaskbarWindowPreview(nsID
 
   NS_ENSURE_ARG_POINTER(shell);
 
   HWND toplevelHWND = ::GetAncestor(GetHWNDFromDocShell(shell), GA_ROOT);
 
   if (!toplevelHWND)
     return NS_ERROR_INVALID_ARG;
 
-  nsWindow *window = nsWindow::GetNSWindowPtr(toplevelHWND);
+  nsWindow *window = WinUtils::GetNSWindowPtr(toplevelHWND);
 
   if (!window)
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsITaskbarWindowPreview> preview = window->GetTaskbarPreview();
   if (!preview) {
     nsRefPtr<DefaultController> defaultController = new DefaultController(toplevelHWND);
     preview = new TaskbarWindowPreview(mTaskbar, defaultController, toplevelHWND, shell);
new file mode 100644
--- /dev/null
+++ b/widget/windows/WinUtils.cpp
@@ -0,0 +1,367 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sts=2 sw=2 et cin: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Masayuki Nakano <masayuki@d-toybox.com>
+ *
+ * Original nsWindow.cpp Contributor(s):
+ *   Dean Tessman <dean_tessman@hotmail.com>
+ *   Ere Maijala <emaijala@kolumbus.fi>
+ *   Mark Hammond <markh@activestate.com>
+ *   Michael Lowe <michael.lowe@bigfoot.com>
+ *   Peter Bajusz <hyp-x@inf.bme.hu>
+ *   Pierre Phaneuf <pp@ludusdesign.com>
+ *   Robert O'Callahan <roc+moz@cs.cmu.edu>
+ *   Roy Yokoyama <yokoyama@netscape.com>
+ *   Makoto Kato  <m_kato@ga2.so-net.ne.jp>
+ *   Masayuki Nakano <masayuki@d-toybox.com>
+ *   Dainis Jonitis <Dainis_Jonitis@swh-t.lv>
+ *   Christian Biesinger <cbiesinger@web.de>
+ *   Mats Palmgren <matspal@gmail.com>
+ *   Ningjie Chen <chenn@email.uc.edu>
+ *   Jim Mathies <jmathies@mozilla.com>
+ *   Kyle Huey <me@kylehuey.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "WinUtils.h"
+#include "nsWindow.h"
+#include "nsWindowDefs.h"
+#include "nsGUIEvent.h"
+#include "nsIDOMMouseEvent.h"
+#include "mozilla/Preferences.h"
+
+namespace mozilla {
+namespace widget {
+
+/* static */ 
+WinUtils::WinVersion
+WinUtils::GetWindowsVersion()
+{
+  static PRInt32 version = 0;
+
+  if (version) {
+    return static_cast<WinVersion>(version);
+  }
+
+  OSVERSIONINFOEX osInfo;
+  osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+  // This cast is safe and supposed to be here, don't worry
+  ::GetVersionEx((OSVERSIONINFO*)&osInfo);
+  version =
+    (osInfo.dwMajorVersion & 0xff) << 8 | (osInfo.dwMinorVersion & 0xff);
+  return static_cast<WinVersion>(version);
+}
+
+/* static */
+bool
+WinUtils::GetRegistryKey(HKEY aRoot,
+                         const PRUnichar* aKeyName,
+                         const PRUnichar* aValueName,
+                         PRUnichar* aBuffer,
+                         DWORD aBufferLength)
+{
+  NS_PRECONDITION(aKeyName, "The key name is NULL");
+
+  HKEY key;
+  LONG result =
+    ::RegOpenKeyExW(aRoot, aKeyName, NULL, KEY_READ | KEY_WOW64_32KEY, &key);
+  if (result != ERROR_SUCCESS) {
+    result =
+      ::RegOpenKeyExW(aRoot, aKeyName, NULL, KEY_READ | KEY_WOW64_64KEY, &key);
+    if (result != ERROR_SUCCESS) {
+      return false;
+    }
+  }
+
+  DWORD type;
+  result =
+    ::RegQueryValueExW(key, aValueName, NULL, &type, (BYTE*) aBuffer,
+                       &aBufferLength);
+  ::RegCloseKey(key);
+  if (result != ERROR_SUCCESS || type != REG_SZ) {
+    return false;
+  }
+  if (aBuffer) {
+    aBuffer[aBufferLength / sizeof(*aBuffer) - 1] = 0;
+  }
+  return true;
+}
+
+/* static */
+HWND
+WinUtils::GetTopLevelHWND(HWND aWnd,
+                          bool aStopIfNotChild,
+                          bool aStopIfNotPopup)
+{
+  HWND curWnd = aWnd;
+  HWND topWnd = NULL;
+
+  while (curWnd) {
+    topWnd = curWnd;
+
+    if (aStopIfNotChild) {
+      DWORD_PTR style = ::GetWindowLongPtrW(curWnd, GWL_STYLE);
+
+      VERIFY_WINDOW_STYLE(style);
+
+      if (!(style & WS_CHILD)) // first top-level window
+        break;
+    }
+
+    HWND upWnd = ::GetParent(curWnd); // Parent or owner (if has no parent)
+
+    // GetParent will only return the owner if the passed in window 
+    // has the WS_POPUP style.
+    if (!upWnd && !aStopIfNotPopup) {
+      upWnd = ::GetWindow(curWnd, GW_OWNER);
+    }
+    curWnd = upWnd;
+  }
+
+  return topWnd;
+}
+
+static PRUnichar*
+GetNSWindowPropName()
+{
+  static PRUnichar sPropName[40] = L"";
+  if (!*sPropName) {
+    _snwprintf(sPropName, 39, L"MozillansIWidgetPtr%p",
+               ::GetCurrentProcessId());
+    sPropName[39] = '\0';
+  }
+  return sPropName;
+}
+
+/* static */
+bool
+WinUtils::SetNSWindowPtr(HWND aWnd, nsWindow* aWindow)
+{
+  if (!aWindow) {
+    ::RemovePropW(aWnd, GetNSWindowPropName());
+    return true;
+  }
+  return ::SetPropW(aWnd, GetNSWindowPropName(), (HANDLE)aWindow);
+}
+
+/* static */
+nsWindow*
+WinUtils::GetNSWindowPtr(HWND aWnd)
+{
+  return static_cast<nsWindow*>(::GetPropW(aWnd, GetNSWindowPropName()));
+}
+
+static BOOL CALLBACK
+AddMonitor(HMONITOR, HDC, LPRECT, LPARAM aParam)
+{
+  (*(PRInt32*)aParam)++;
+  return TRUE;
+}
+
+/* static */
+PRInt32
+WinUtils::GetMonitorCount()
+{
+  PRInt32 monitorCount = 0;
+  EnumDisplayMonitors(NULL, NULL, AddMonitor, (LPARAM)&monitorCount);
+  return monitorCount;
+}
+
+/* static */
+bool
+WinUtils::IsOurProcessWindow(HWND aWnd)
+{
+  if (!aWnd) {
+    return false;
+  }
+  DWORD processId = 0;
+  ::GetWindowThreadProcessId(aWnd, &processId);
+  return (processId == ::GetCurrentProcessId());
+}
+
+/* static */
+HWND
+WinUtils::FindOurProcessWindow(HWND aWnd)
+{
+  for (HWND wnd = ::GetParent(aWnd); wnd; wnd = ::GetParent(wnd)) {
+    if (IsOurProcessWindow(wnd)) {
+      return wnd;
+    }
+  }
+  return NULL;
+}
+
+static bool
+IsPointInWindow(HWND aWnd, const POINT& aPointInScreen)
+{
+  RECT bounds;
+  if (!::GetWindowRect(aWnd, &bounds)) {
+    return false;
+  }
+
+  return (aPointInScreen.x >= bounds.left && aPointInScreen.x < bounds.right &&
+          aPointInScreen.y >= bounds.top && aPointInScreen.y < bounds.bottom);
+}
+
+/**
+ * FindTopmostWindowAtPoint() returns the topmost child window (topmost means
+ * forground in this context) of aWnd.
+ */
+
+static HWND
+FindTopmostWindowAtPoint(HWND aWnd, const POINT& aPointInScreen)
+{
+  if (!::IsWindowVisible(aWnd) || !IsPointInWindow(aWnd, aPointInScreen)) {
+    return NULL;
+  }
+
+  HWND childWnd = ::GetTopWindow(aWnd);
+  while (childWnd) {
+    HWND topmostWnd = FindTopmostWindowAtPoint(childWnd, aPointInScreen);
+    if (topmostWnd) {
+      return topmostWnd;
+    }
+    childWnd = ::GetNextWindow(childWnd, GW_HWNDNEXT);
+  }
+
+  return aWnd;
+}
+
+struct FindOurWindowAtPointInfo
+{
+  POINT mInPointInScreen;
+  HWND mOutWnd;
+};
+
+static BOOL CALLBACK
+FindOurWindowAtPointCallback(HWND aWnd, LPARAM aLPARAM)
+{
+  if (!WinUtils::IsOurProcessWindow(aWnd)) {
+    // 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(aWnd, info->mInPointInScreen);
+  if (!childWnd) {
+    // This window doesn't contain the point; continue enumerating.
+    return TRUE;
+  }
+
+  // Return the HWND and stop enumerating.
+  info->mOutWnd = childWnd;
+  return FALSE;
+}
+
+/* static */
+HWND
+WinUtils::FindOurWindowAtPoint(const POINT& aPointInScreen)
+{
+  FindOurWindowAtPointInfo info;
+  info.mInPointInScreen = aPointInScreen;
+  info.mOutWnd = NULL;
+
+  // This will enumerate all top-level windows in order from top to bottom.
+  EnumWindows(FindOurWindowAtPointCallback, reinterpret_cast<LPARAM>(&info));
+  return info.mOutWnd;
+}
+
+/* static */
+UINT
+WinUtils::GetInternalMessage(UINT aNativeMessage)
+{
+  switch (aNativeMessage) {
+    case WM_MOUSEWHEEL:
+      return MOZ_WM_MOUSEVWHEEL;
+    case WM_MOUSEHWHEEL:
+      return MOZ_WM_MOUSEHWHEEL;
+    case WM_VSCROLL:
+      return MOZ_WM_VSCROLL;
+    case WM_HSCROLL:
+      return MOZ_WM_HSCROLL;
+    default:
+      return aNativeMessage;
+  }
+}
+
+/* static */
+UINT
+WinUtils::GetNativeMessage(UINT aInternalMessage)
+{
+  switch (aInternalMessage) {
+    case MOZ_WM_MOUSEVWHEEL:
+      return WM_MOUSEWHEEL;
+    case MOZ_WM_MOUSEHWHEEL:
+      return WM_MOUSEHWHEEL;
+    case MOZ_WM_VSCROLL:
+      return WM_VSCROLL;
+    case MOZ_WM_HSCROLL:
+      return WM_HSCROLL;
+    default:
+      return aInternalMessage;
+  }
+}
+
+/* static */
+PRUint16
+WinUtils::GetMouseInputSource()
+{
+  PRInt32 inputSource = nsIDOMMouseEvent::MOZ_SOURCE_MOUSE;
+  LPARAM lParamExtraInfo = ::GetMessageExtraInfo();
+  if ((lParamExtraInfo & TABLET_INK_SIGNATURE) == TABLET_INK_CHECK) {
+    inputSource = (lParamExtraInfo & TABLET_INK_TOUCH) ?
+      nsIDOMMouseEvent::MOZ_SOURCE_TOUCH : nsIDOMMouseEvent::MOZ_SOURCE_PEN;
+  }
+  return static_cast<PRUint16>(inputSource);
+}
+
+/* static */
+MSG
+WinUtils::InitMSG(UINT aMessage, WPARAM wParam, LPARAM lParam)
+{
+  MSG msg;
+  msg.message = aMessage;
+  msg.wParam  = wParam;
+  msg.lParam  = lParam;
+  return msg;
+}
+
+} // namespace widget
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/widget/windows/WinUtils.h
@@ -0,0 +1,206 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Masayuki Nakano <masayuki@d-toybox.com>
+ *
+ * Original nsWindow.cpp Contributor(s):
+ *   Robert O'Callahan <roc+moz@cs.cmu.edu>
+ *   Dean Tessman <dean_tessman@hotmail.com>
+ *   Makoto Kato  <m_kato@ga2.so-net.ne.jp>
+ *   Dainis Jonitis <Dainis_Jonitis@swh-t.lv>
+ *   Masayuki Nakano <masayuki@d-toybox.com>
+ *   Ningjie Chen <chenn@email.uc.edu>
+ *   Jim Mathies <jmathies@mozilla.com>.
+ *   Mats Palmgren <matspal@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_widget_WinUtils_h__
+#define mozilla_widget_WinUtils_h__
+
+#include "nscore.h"
+#include <windows.h>
+
+class nsWindow;
+
+namespace mozilla {
+namespace widget {
+
+class WinUtils {
+public:
+  enum WinVersion {
+    WIN2K_VERSION     = 0x500,
+    WINXP_VERSION     = 0x501,
+    WIN2K3_VERSION    = 0x502,
+    VISTA_VERSION     = 0x600,
+    // WIN2K8_VERSION    = VISTA_VERSION,
+    WIN7_VERSION      = 0x601
+    // WIN2K8R2_VERSION  = WIN7_VERSION
+    // WIN8_VERSION      = 0x602
+  };
+  static WinVersion GetWindowsVersion();
+
+  /**
+   * 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 bool GetRegistryKey(HKEY aRoot,
+                             const PRUnichar* aKeyName,
+                             const PRUnichar* aValueName,
+                             PRUnichar* aBuffer,
+                             DWORD aBufferLength);
+
+  /**
+   * GetTopLevelHWND() returns a window handle of the top level window which
+   * aWnd belongs to.  Note that the result may not be our window, i.e., it
+   * may not be managed by nsWindow.
+   *
+   * See follwing table for the detail of the result window type.
+   *
+   * +-------------------------+-----------------------------------------------+
+   * |                         |                aStopIfNotPopup                |
+   * +-------------------------+-----------------------+-----------------------+
+   * |                         |         TRUE          |         FALSE         |
+   + +-----------------+-------+-----------------------+-----------------------+
+   * |                 |       |  * an independent top level window            |
+   * |                 | TRUE  |  * a pupup window (WS_POPUP)                  |
+   * |                 |       |  * an owned top level window (like dialog)    |
+   * | aStopIfNotChild +-------+-----------------------+-----------------------+
+   * |                 |       |  * independent window | * only an independent |
+   * |                 | FALSE |  * non-popup-owned-   |   top level window    |
+   * |                 |       |    window like dialog |                       |
+   * +-----------------+-------+-----------------------+-----------------------+
+   */
+  static HWND GetTopLevelHWND(HWND aWnd, 
+                              bool aStopIfNotChild = false, 
+                              bool aStopIfNotPopup = true);
+
+  /**
+   * SetNSWindowPtr() associates an nsWindow to aWnd.  If aWindow is NULL,
+   * it dissociate any nsWindow pointer from aWnd.
+   * GetNSWindowPtr() returns an nsWindow pointer which was associated by
+   * SetNSWindowPtr().
+   */
+  static bool SetNSWindowPtr(HWND aWnd, nsWindow* aWindow);
+  static nsWindow* GetNSWindowPtr(HWND aWnd);
+
+  /**
+   * GetMonitorCount() returns count of monitors on the environment.
+   */
+  static PRInt32 GetMonitorCount();
+
+  /**
+   * IsOurProcessWindow() returns TRUE if aWnd belongs our process.
+   * Otherwise, FALSE.
+   */
+  static bool IsOurProcessWindow(HWND aWnd);
+
+  /**
+   * FindOurProcessWindow() returns the nearest ancestor window which
+   * belongs to our process.  If it fails to find our process's window by the
+   * top level window, returns NULL.  And note that this is using ::GetParent()
+   * for climbing the window hierarchy, therefore, it gives up at an owned top
+   * level window except popup window (e.g., dialog).
+   */
+  static HWND FindOurProcessWindow(HWND aWnd);
+
+  /**
+   * FindOurWindowAtPoint() returns the topmost child window which belongs to
+   * our process's top level window.
+   *
+   * NOTE: the topmost child window may NOT be our process's window like a
+   *       plugin's window.
+   */
+  static HWND FindOurWindowAtPoint(const POINT& aPointInScreen);
+
+  /**
+   * InitMSG() returns an MSG struct which was initialized by the params.
+   * Don't trust the other members in the result.
+   */
+  static MSG InitMSG(UINT aMessage, WPARAM wParam, LPARAM lParam);
+
+  /**
+   * GetScanCode() returns a scan code for the LPARAM of WM_KEYDOWN, WM_KEYUP,
+   * WM_CHAR and WM_UNICHAR.
+   *
+   */
+  static WORD GetScanCode(LPARAM aLParam)
+  {
+    return (aLParam >> 16) & 0xFF;
+  }
+
+  /**
+   * IsExtendedScanCode() returns TRUE if the LPARAM indicates the key message
+   * is an extended key event.
+   */
+  static bool IsExtendedScanCode(LPARAM aLParam)
+  {
+    return (aLParam & 0x1000000) != 0;
+  }
+
+  /**
+   * GetInternalMessage() converts a native message to an internal message.
+   * If there is no internal message for the given native message, returns
+   * the native message itself.
+   */
+  static UINT GetInternalMessage(UINT aNativeMessage);
+
+  /**
+   * GetNativeMessage() converts an internal message to a native message.
+   * If aInternalMessage is a native message, returns the native message itself.
+   */
+  static UINT GetNativeMessage(UINT aInternalMessage);
+
+  /**
+   * GetMouseInputSource() returns a pointing device information.  The value is
+   * one of nsIDOMMouseEvent::MOZ_SOURCE_*.  This method MUST be called during
+   * mouse message handling.
+   */
+  static PRUint16 GetMouseInputSource();
+};
+
+} // namespace widget
+} // namespace mozilla
+
+#endif // mozilla_widget_WinUtils_h__
--- a/widget/windows/nsFilePicker.cpp
+++ b/widget/windows/nsFilePicker.cpp
@@ -54,16 +54,19 @@
 #include "nsICharsetConverterManager.h"
 #include "nsIPrivateBrowsingService.h"
 #include "nsIURL.h"
 #include "nsIStringBundle.h"
 #include "nsEnumeratorUtils.h"
 #include "nsCRT.h"
 #include "nsString.h"
 #include "nsToolkit.h"
+#include "WinUtils.h"
+
+using namespace mozilla::widget;
 
 PRUnichar *nsFilePicker::mLastUsedUnicodeDirectory;
 char nsFilePicker::mLastUsedDirectory[MAX_PATH+1] = { 0 };
 
 static const PRUnichar kDialogPtrProp[] = L"DialogPtrProperty";
 static const DWORD kDialogTimerID = 9999;
 static const unsigned long kDialogTimerTimeout = 300;
 
@@ -701,17 +704,17 @@ nsFilePicker::ShowXPFilePicker(const nsS
   ofn.Flags = OFN_SHAREAWARE | OFN_LONGNAMES | OFN_OVERWRITEPROMPT |
               OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_ENABLESIZING | 
               OFN_EXPLORER;
 
   // Windows Vista and up won't allow you to use the new looking dialogs with
   // a hook procedure.  The hook procedure fixes a problem on XP dialogs for
   // file picker visibility.  Vista and up automatically ensures the file 
   // picker is always visible.
-  if (nsWindow::GetWindowsVersion() < VISTA_VERSION) {
+  if (WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION) {
     ofn.lpfnHook = FilePickerHook;
     ofn.Flags |= OFN_ENABLEHOOK;
   }
 
   // Handle add to recent docs settings
   if (IsPrivacyModeEnabled() || !mAddToRecentDocs) {
     ofn.Flags |= OFN_DONTADDTORECENT;
   }
@@ -760,17 +763,17 @@ nsFilePicker::ShowXPFilePicker(const nsS
       // value of ofn.lpstrFile and deallocate the old buffer that it pointed
       // to (fileBuffer). The hook assumes that the passed in value is heap 
       // allocated and that the returned value should be freed by the caller.
       // If the hook changes the buffer, it will deallocate the old buffer.
       // This fix would be nice to have in Vista and up, but it would force
       // the file picker to use the old style dialogs because hooks are not
       // allowed in the new file picker UI.  We need to eventually move to
       // the new Common File Dialogs for Vista and up.
-      if (nsWindow::GetWindowsVersion() < VISTA_VERSION) {
+      if (WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION) {
         ofn.lpfnHook = MultiFilePickerHook;
         fileBuffer.forget();
         result = FilePickerWrapper(&ofn, PICKER_TYPE_OPEN);
         fileBuffer = ofn.lpstrFile;
       } else {
         result = FilePickerWrapper(&ofn, PICKER_TYPE_OPEN);
       }
       break;
@@ -1048,26 +1051,26 @@ nsFilePicker::ShowW(PRInt16 *aReturnVal)
 
   // Clear previous file selections
   mUnicodeFile.Truncate();
   mFiles.Clear();
 
   bool result = false;
    if (mMode == modeGetFolder) {
 #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
-    if (nsWindow::GetWindowsVersion() >= VISTA_VERSION)
+    if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION)
       result = ShowFolderPicker(initialDir);
     else
       result = ShowXPFolderPicker(initialDir);
 #else
     result = ShowXPFolderPicker(initialDir);
 #endif  
    } else {
 #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
-    if (nsWindow::GetWindowsVersion() >= VISTA_VERSION)
+    if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION)
       result = ShowFilePicker(initialDir);
     else
       result = ShowXPFilePicker(initialDir);
 #else
     result = ShowXPFilePicker(initialDir);
 #endif  
    }
 
@@ -1254,17 +1257,17 @@ nsFilePicker::AppendXPFilter(const nsASt
 
   mFilterList.Append(PRUnichar('\0'));
 }
 
 NS_IMETHODIMP
 nsFilePicker::AppendFilter(const nsAString& aTitle, const nsAString& aFilter)
 {
 #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
-  if (nsWindow::GetWindowsVersion() >= VISTA_VERSION) {
+  if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION) {
     mComFilterList.Append(aTitle, aFilter);
   } else {
     AppendXPFilter(aTitle, aFilter);
   }
 #else
   AppendXPFilter(aTitle, aFilter);
 #endif
   return NS_OK;
--- a/widget/windows/nsIMM32Handler.cpp
+++ b/widget/windows/nsIMM32Handler.cpp
@@ -55,16 +55,19 @@
 
 #ifdef MOZ_LOGGING
 #define FORCE_PR_LOG /* Allow logging in the release build */
 #endif // MOZ_LOGGING
 #include "prlog.h"
 
 #include "nsIMM32Handler.h"
 #include "nsWindow.h"
+#include "WinUtils.h"
+
+using namespace mozilla::widget;
 
 static nsIMM32Handler* gIMM32Handler = nsnull;
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* gIMM32Log = nsnull;
 #endif
 
 static UINT sWM_MSIME_MOUSE = 0; // mouse message for MSIME 98/2000
@@ -143,17 +146,17 @@ nsIMM32Handler::IsComposingWindow(nsWind
 
 /* static */ bool
 nsIMM32Handler::IsTopLevelWindowOfComposition(nsWindow* aWindow)
 {
   if (!gIMM32Handler || !gIMM32Handler->mComposingWindow) {
     return false;
   }
   HWND wnd = gIMM32Handler->mComposingWindow->GetWindowHandle();
-  return nsWindow::GetTopLevelHWND(wnd, true) == aWindow->GetWindowHandle();
+  return WinUtils::GetTopLevelHWND(wnd, true) == aWindow->GetWindowHandle();
 }
 
 /* static */ bool
 nsIMM32Handler::IsDoingKakuteiUndo(HWND aWnd)
 {
   // This message pattern is "Kakutei-Undo" on ATOK and WXG.
   // In this case, the message queue has following messages:
   // ---------------------------------------------------------------------------
--- a/widget/windows/nsNativeThemeWin.cpp
+++ b/widget/windows/nsNativeThemeWin.cpp
@@ -55,27 +55,30 @@
 #include "nsINameSpaceManager.h"
 #include "nsIDOMHTMLInputElement.h"
 #include "nsMenuFrame.h"
 #include "nsGkAtoms.h"
 #include <malloc.h>
 #include "nsWindow.h"
 #include "nsIComboboxControlFrame.h"
 #include "prinrval.h"
+#include "WinUtils.h"
 
 #include "gfxPlatform.h"
 #include "gfxContext.h"
 #include "gfxMatrix.h"
 #include "gfxWindowsPlatform.h"
 #include "gfxWindowsSurface.h"
 #include "gfxWindowsNativeDrawing.h"
 
 #include "nsUXThemeData.h"
 #include "nsUXThemeConstants.h"
 
+using namespace mozilla::widget;
+
 #ifdef PR_LOGGING
 extern PRLogModuleInfo* gWindowsLog;
 #endif
 
 NS_IMPL_ISUPPORTS_INHERITED1(nsNativeThemeWin, nsNativeTheme, nsITheme)
 
 static inline bool IsHTMLContent(nsIFrame *frame)
 {
@@ -377,31 +380,31 @@ static const PRInt32 kProgressDetermined
 
 // Adds "hot" caption button padding to minimum widget size.
 static void AddPaddingRect(nsIntSize* aSize, CaptionButton button) {
   if (!aSize)
     return;
   RECT offset;
   if (!nsUXThemeData::IsAppThemed())
     offset = buttonData[CAPTION_CLASSIC].hotPadding[button];
-  else if (nsWindow::GetWindowsVersion() == WINXP_VERSION)
+  else if (WinUtils::GetWindowsVersion() == WinUtils::WINXP_VERSION)
     offset = buttonData[CAPTION_XPTHEME].hotPadding[button];
   else
     offset = buttonData[CAPTION_BASIC].hotPadding[button];
   aSize->width += offset.left + offset.right;
   aSize->height += offset.top + offset.bottom;
 }
 
 // If we've added padding to the minimum widget size, offset
 // the area we draw into to compensate.
 static void OffsetBackgroundRect(RECT& rect, CaptionButton button) {
   RECT offset;
   if (!nsUXThemeData::IsAppThemed())
     offset = buttonData[CAPTION_CLASSIC].hotPadding[button];
-  else if (nsWindow::GetWindowsVersion() == WINXP_VERSION)
+  else if (WinUtils::GetWindowsVersion() == WinUtils::WINXP_VERSION)
     offset = buttonData[CAPTION_XPTHEME].hotPadding[button];
   else
     offset = buttonData[CAPTION_BASIC].hotPadding[button];
   rect.left += offset.left;
   rect.top += offset.top;
   rect.right -= offset.right;
   rect.bottom -= offset.bottom;
 }
@@ -2072,41 +2075,41 @@ nsNativeThemeWin::GetMinimumWidgetSize(n
     case NS_THEME_WINDOW_BUTTON_RESTORE:
       // The only way to get accurate titlebar button info is to query a
       // window w/buttons when it's visible. nsWindow takes care of this and
       // stores that info in nsUXThemeData.
       QueryForButtonData(aFrame);
       aResult->width = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_RESTORE].cx;
       aResult->height = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_RESTORE].cy;
       // For XP, subtract 4 from system metrics dimensions.
-      if (nsWindow::GetWindowsVersion() == WINXP_VERSION) {
+      if (WinUtils::GetWindowsVersion() == WinUtils::WINXP_VERSION) {
         aResult->width -= 4;
         aResult->height -= 4;
       }
       AddPaddingRect(aResult, CAPTIONBUTTON_RESTORE);
       *aIsOverridable = false;
       return NS_OK;
 
     case NS_THEME_WINDOW_BUTTON_MINIMIZE:
       QueryForButtonData(aFrame);
       aResult->width = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_MINIMIZE].cx;
       aResult->height = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_MINIMIZE].cy;
-      if (nsWindow::GetWindowsVersion() == WINXP_VERSION) {
+      if (WinUtils::GetWindowsVersion() == WinUtils::WINXP_VERSION) {
         aResult->width -= 4;
         aResult->height -= 4;
       }
       AddPaddingRect(aResult, CAPTIONBUTTON_MINIMIZE);
       *aIsOverridable = false;
       return NS_OK;
 
     case NS_THEME_WINDOW_BUTTON_CLOSE:
       QueryForButtonData(aFrame);
       aResult->width = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_CLOSE].cx;
       aResult->height = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_CLOSE].cy;
-      if (nsWindow::GetWindowsVersion() == WINXP_VERSION) {
+      if (WinUtils::GetWindowsVersion() == WinUtils::WINXP_VERSION) {
         aResult->width -= 4;
         aResult->height -= 4;
       }
       AddPaddingRect(aResult, CAPTIONBUTTON_CLOSE);
       *aIsOverridable = false;
       return NS_OK;
 
     case NS_THEME_WINDOW_TITLEBAR:
--- a/widget/windows/nsUXThemeData.cpp
+++ b/widget/windows/nsUXThemeData.cpp
@@ -38,21 +38,22 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/Util.h"
 
 #include "nsUXThemeData.h"
 #include "nsDebug.h"
-// For GetWindowsVersion
-#include "nsWindow.h"
+#include "nsToolkit.h"
+#include "WinUtils.h"
 #include "nsUXThemeConstants.h"
 
 using namespace mozilla;
+using namespace mozilla::widget;
 
 const PRUnichar
 nsUXThemeData::kThemeLibraryName[] = L"uxtheme.dll";
 #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
 const PRUnichar
 nsUXThemeData::kDwmLibraryName[] = L"dwmapi.dll";
 #endif
 
@@ -115,19 +116,19 @@ nsUXThemeData::Teardown() {
 }
 
 void
 nsUXThemeData::Initialize()
 {
   ::ZeroMemory(sThemes, sizeof(sThemes));
   NS_ASSERTION(!sThemeDLL, "nsUXThemeData being initialized twice!");
 
-  PRInt32 version = nsWindow::GetWindowsVersion();
-  sIsXPOrLater = version >= WINXP_VERSION;
-  sIsVistaOrLater = version >= VISTA_VERSION;
+  WinUtils::WinVersion version = WinUtils::GetWindowsVersion();
+  sIsXPOrLater = version >= WinUtils::WINXP_VERSION;
+  sIsVistaOrLater = version >= WinUtils::VISTA_VERSION;
 
   if (GetThemeDLL()) {
     openTheme = (OpenThemeDataPtr)GetProcAddress(sThemeDLL, "OpenThemeData");
     closeTheme = (CloseThemeDataPtr)GetProcAddress(sThemeDLL, "CloseThemeData");
     drawThemeBG = (DrawThemeBackgroundPtr)GetProcAddress(sThemeDLL, "DrawThemeBackground");
     drawThemeEdge = (DrawThemeEdgePtr)GetProcAddress(sThemeDLL, "DrawThemeEdge");
     getThemeContentRect = (GetThemeContentRectPtr)GetProcAddress(sThemeDLL, "GetThemeBackgroundContentRect");
     getThemeBackgroundRegion = (GetThemeBackgroundRegionPtr)GetProcAddress(sThemeDLL, "GetThemeBackgroundRegion");
@@ -267,17 +268,17 @@ nsUXThemeData::InitTitlebarInfo()
   sCommandButtons[1].cx = sCommandButtons[2].cx = sCommandButtons[0].cx;
   sCommandButtons[1].cy = sCommandButtons[2].cy = sCommandButtons[0].cy;
   sCommandButtons[3].cx = sCommandButtons[0].cx * 3;
   sCommandButtons[3].cy = sCommandButtons[0].cy;
 
   // Use system metrics for pre-vista, otherwise trigger a
   // refresh on the next layout.
   sTitlebarInfoPopulatedAero = sTitlebarInfoPopulatedThemed =
-    (nsWindow::GetWindowsVersion() < VISTA_VERSION);
+    (WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION);
 }
 
 // static
 void
 nsUXThemeData::UpdateTitlebarInfo(HWND aWnd)
 {
   if (!aWnd)
     return;
@@ -395,17 +396,18 @@ bool nsUXThemeData::IsDefaultWindowTheme
   return sIsDefaultWindowsTheme;
 }
 
 // static
 void
 nsUXThemeData::UpdateNativeThemeInfo()
 {
   // Trigger a refresh of themed button metrics if needed
-  sTitlebarInfoPopulatedThemed = (nsWindow::GetWindowsVersion() < VISTA_VERSION);
+  sTitlebarInfoPopulatedThemed =
+    (WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION);
 
   sIsDefaultWindowsTheme = false;
   sThemeId = LookAndFeel::eWindowsTheme_Generic;
 
   if (!IsAppThemed() || !getCurrentThemeName) {
     sThemeId = LookAndFeel::eWindowsTheme_Classic;
     return;
   }
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -156,16 +156,17 @@
 #include "nsIServiceManager.h"
 #include "nsWindowGfx.h"
 #include "gfxWindowsPlatform.h"
 #include "Layers.h"
 #include "nsPrintfCString.h"
 #include "mozilla/Preferences.h"
 #include "nsISound.h"
 #include "WinTaskbar.h"
+#include "WinUtils.h"
 
 #ifdef MOZ_ENABLE_D3D9_LAYER
 #include "LayerManagerD3D9.h"
 #endif
 
 #ifdef MOZ_ENABLE_D3D10_LAYER
 #include "LayerManagerD3D10.h"
 #endif
@@ -538,17 +539,18 @@ nsWindow::Create(nsIWidget *aParent,
   BaseCreate(baseParent, aRect, aHandleEventFunction, aContext, aInitData);
 
   HWND parent;
   if (aParent) { // has a nsIWidget parent
     parent = aParent ? (HWND)aParent->GetNativeData(NS_NATIVE_WINDOW) : NULL;
     mParent = aParent;
   } else { // has a nsNative parent
     parent = (HWND)aNativeParent;
-    mParent = aNativeParent ? GetNSWindowPtr((HWND)aNativeParent) : nsnull;
+    mParent = aNativeParent ?
+      WinUtils::GetNSWindowPtr((HWND)aNativeParent) : nsnull;
   }
 
   mPopupType = aInitData->mPopupHint;
   mIsRTL = aInitData->mRTL;
 
   DWORD style = WindowStyle();
   DWORD extendedStyle = WindowExStyle();
 
@@ -672,17 +674,17 @@ nsWindow::Create(nsIWidget *aParent,
   // do some initialization work.
   if (sTrimOnMinimize == 2 && mWindowType == eWindowType_invisible) {
     // Our internal trim prevention logic is effective on 2K/XP at maintaining
     // the working set when windows are minimized, but on Vista and up it has
     // little to no effect. Since this feature has been the source of numerous
     // bugs over the years, disable it (sTrimOnMinimize=1) on Vista and up.
     sTrimOnMinimize =
       Preferences::GetBool("config.trim_on_minimize",
-                           (GetWindowsVersion() >= VISTA_VERSION)) ? 1 : 0;
+        (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION)) ? 1 : 0;
     sSwitchKeyboardLayout =
       Preferences::GetBool("intl.keyboard.per_window_layout", false);
     gDisableNativeTheme =
       Preferences::GetBool("mozilla.widget.disable-native-theme", false);
   }
 
   return NS_OK;
 }
@@ -944,78 +946,31 @@ void nsWindow::SubclassWindow(BOOL bStat
       if (mUnicodeWidget)
         mPrevWndProc = (WNDPROC)::SetWindowLongPtrW(mWnd, GWLP_WNDPROC,
                                                 (LONG_PTR)nsWindow::WindowProc);
       else
         mPrevWndProc = (WNDPROC)::SetWindowLongPtrA(mWnd, GWLP_WNDPROC,
                                                 (LONG_PTR)nsWindow::WindowProc);
       NS_ASSERTION(mPrevWndProc, "Null standard window procedure");
       // connect the this pointer to the nsWindow handle
-      SetNSWindowPtr(mWnd, this);
+      WinUtils::SetNSWindowPtr(mWnd, this);
     }
     else {
       if (mUnicodeWidget)
         ::SetWindowLongPtrW(mWnd, GWLP_WNDPROC, (LONG_PTR)mPrevWndProc);
       else
         ::SetWindowLongPtrA(mWnd, GWLP_WNDPROC, (LONG_PTR)mPrevWndProc);
-      SetNSWindowPtr(mWnd, NULL);
+      WinUtils::SetNSWindowPtr(mWnd, NULL);
       mPrevWndProc = NULL;
     }
   }
 }
 
 /**************************************************************
  *
- * SECTION: Window properties
- *
- * Set and clear native window properties.
- *
- **************************************************************/
-
-static PRUnichar sPropName[40] = L"";
-static PRUnichar* GetNSWindowPropName()
-{
-  if (!*sPropName)
-  {
-    _snwprintf(sPropName, 39, L"MozillansIWidgetPtr%p", GetCurrentProcessId());
-    sPropName[39] = '\0';
-  }
-  return sPropName;
-}
-
-nsWindow * nsWindow::GetNSWindowPtr(HWND aWnd)
-{
-  return (nsWindow *) ::GetPropW(aWnd, GetNSWindowPropName());
-}
-
-BOOL nsWindow::SetNSWindowPtr(HWND aWnd, nsWindow * ptr)
-{
-  if (ptr == NULL) {
-    ::RemovePropW(aWnd, GetNSWindowPropName());
-    return TRUE;
-  } else {
-    return ::SetPropW(aWnd, GetNSWindowPropName(), (HANDLE)ptr);
-  }
-}
-
-static BOOL CALLBACK AddMonitor(HMONITOR, HDC, LPRECT, LPARAM aParam)
-{
-  (*(PRInt32*)aParam)++;
-  return TRUE;
-}
-
-PRInt32 nsWindow::GetMonitorCount()
-{
-  PRInt32 monitorCount = 0;
-  EnumDisplayMonitors(NULL, NULL, AddMonitor, (LPARAM)&monitorCount);
-  return monitorCount;
-}
-
-/**************************************************************
- *
  * SECTION: nsIWidget::SetParent, nsIWidget::GetParent
  *
  * Set or clear the parent widgets using window properties, and
  * handles calculating native parent handles.
  *
  **************************************************************/
 
 // Get and set parent widgets
@@ -1101,44 +1056,44 @@ nsWindow* nsWindow::GetParentWindow(bool
   if (mWnd) {
     HWND parent = nsnull;
     if (aIncludeOwner)
       parent = ::GetParent(mWnd);
     else
       parent = ::GetAncestor(mWnd, GA_PARENT);
 
     if (parent) {
-      widget = GetNSWindowPtr(parent);
+      widget = WinUtils::GetNSWindowPtr(parent);
       if (widget) {
         // If the widget is in the process of being destroyed then
         // do NOT return it
         if (widget->mInDtor) {
           widget = nsnull;
         }
       }
     }
   }
 
   return widget;
 }
  
 BOOL CALLBACK
 nsWindow::EnumAllChildWindProc(HWND aWnd, LPARAM aParam)
 {
-  nsWindow *wnd = nsWindow::GetNSWindowPtr(aWnd);
+  nsWindow *wnd = WinUtils::GetNSWindowPtr(aWnd);
   if (wnd) {
     ((nsWindow::WindowEnumCallback*)aParam)(wnd);
   }
   return TRUE;
 }
 
 BOOL CALLBACK
 nsWindow::EnumAllThreadWindowProc(HWND aWnd, LPARAM aParam)
 {
-  nsWindow *wnd = nsWindow::GetNSWindowPtr(aWnd);
+  nsWindow *wnd = WinUtils::GetNSWindowPtr(aWnd);
   if (wnd) {
     ((nsWindow::WindowEnumCallback*)aParam)(wnd);
   }
   EnumChildWindows(aWnd, EnumAllChildWindProc, aParam);
   return TRUE;
 }
 
 void
@@ -1161,17 +1116,17 @@ NS_METHOD nsWindow::Show(bool bState)
 {
   if (mWindowType == eWindowType_popup) {
     // See bug 603793. When we try to draw D3D9/10 windows with a drop shadow
     // without the DWM on a secondary monitor, windows fails to composite
     // our windows correctly. We therefor switch off the drop shadow for
     // pop-up windows when the DWM is disabled and two monitors are
     // connected.
     if (HasBogusPopupsDropShadowOnMultiMonitor() &&
-        GetMonitorCount() > 1 &&
+        WinUtils::GetMonitorCount() > 1 &&
         !nsUXThemeData::CheckForCompositor())
     {
       if (sDropShadowEnabled) {
         ::SetClassLongA(mWnd, GCL_STYLE, 0);
         sDropShadowEnabled = false;
       }
     } else {
       if (!sDropShadowEnabled) {
@@ -1364,24 +1319,24 @@ NS_METHOD nsWindow::RegisterTouchWindow(
 NS_METHOD nsWindow::UnregisterTouchWindow() {
   mTouchWindow = false;
   mGesture.UnregisterTouchWindow(mWnd);
   ::EnumChildWindows(mWnd, nsWindow::UnregisterTouchForDescendants, 0);
   return NS_OK;
 }
 
 BOOL CALLBACK nsWindow::RegisterTouchForDescendants(HWND aWnd, LPARAM aMsg) {
-  nsWindow* win = GetNSWindowPtr(aWnd);
+  nsWindow* win = WinUtils::GetNSWindowPtr(aWnd);
   if (win)
     win->mGesture.RegisterTouchWindow(aWnd);
   return TRUE;
 }
 
 BOOL CALLBACK nsWindow::UnregisterTouchForDescendants(HWND aWnd, LPARAM aMsg) {
-  nsWindow* win = GetNSWindowPtr(aWnd);
+  nsWindow* win = WinUtils::GetNSWindowPtr(aWnd);
   if (win)
     win->mGesture.UnregisterTouchWindow(aWnd);
   return TRUE;
 }
 
 /**************************************************************
  *
  * SECTION: nsIWidget::Move, nsIWidget::Resize,
@@ -1574,17 +1529,17 @@ nsWindow::BeginResizeDrag(nsGUIEvent* aE
       syscommand = SC_SIZE | WMSZ_BOTTOMRIGHT;
     }
   }
 
   // resizing doesn't work if the mouse is already captured
   CaptureMouse(false);
 
   // find the top-level window
-  HWND toplevelWnd = GetTopLevelHWND(mWnd, true);
+  HWND toplevelWnd = WinUtils::GetTopLevelHWND(mWnd, true);
 
   // tell Windows to start the resize
   ::PostMessage(toplevelWnd, WM_SYSCOMMAND, syscommand,
                 POINTTOPOINTS(aEvent->refPoint));
 
   return NS_OK;
 }
 
@@ -1801,26 +1756,26 @@ NS_METHOD nsWindow::IsEnabled(bool *aSta
  * Give the focus to this widget.
  *
  **************************************************************/
 
 NS_METHOD nsWindow::SetFocus(bool aRaise)
 {
   if (mWnd) {
 #ifdef WINSTATE_DEBUG_OUTPUT
-    if (mWnd == GetTopLevelHWND(mWnd)) {
+    if (mWnd == WinUtils::GetTopLevelHWND(mWnd)) {
       PR_LOG(gWindowsLog, PR_LOG_ALWAYS,
              ("*** SetFocus: [  top] raise=%d\n", aRaise));
     } else {
       PR_LOG(gWindowsLog, PR_LOG_ALWAYS,
              ("*** SetFocus: [child] raise=%d\n", aRaise));
     }
 #endif
     // Uniconify, if necessary
-    HWND toplevelWnd = GetTopLevelHWND(mWnd);
+    HWND toplevelWnd = WinUtils::GetTopLevelHWND(mWnd);
     if (aRaise && ::IsIconic(toplevelWnd)) {
       ::ShowWindow(toplevelWnd, SW_RESTORE);
     }
     ::SetFocus(mWnd);
   }
   return NS_OK;
 }
 
@@ -2599,18 +2554,18 @@ void nsWindow::UpdateGlass()
  * SECTION: nsIWidget::HideWindowChrome
  *
  * Show or hide window chrome.
  *
  **************************************************************/
 
 NS_IMETHODIMP nsWindow::HideWindowChrome(bool aShouldHide)
 {
-  HWND hwnd = GetTopLevelHWND(mWnd, true);
-  if (!GetNSWindowPtr(hwnd))
+  HWND hwnd = WinUtils::GetTopLevelHWND(mWnd, true);
+  if (!WinUtils::GetNSWindowPtr(hwnd))
   {
     NS_WARNING("Trying to hide window decorations in an embedded context");
     return NS_ERROR_FAILURE;
   }
 
   if (mHideChrome == aShouldHide)
     return NS_OK;
 
@@ -3101,23 +3056,23 @@ NS_IMETHODIMP nsWindow::CaptureRollupEve
 // Draw user's attention to this window until it comes to foreground.
 NS_IMETHODIMP
 nsWindow::GetAttention(PRInt32 aCycleCount)
 {
   // Got window?
   if (!mWnd)
     return NS_ERROR_NOT_INITIALIZED;
 
-  HWND flashWnd = GetTopLevelHWND(mWnd, false, false);
+  HWND flashWnd = WinUtils::GetTopLevelHWND(mWnd, false, false);
   HWND fgWnd = ::GetForegroundWindow();
   // Don't flash if the flash count is 0 or if the foreground window is our
   // window handle or that of our owned-most window.
   if (aCycleCount == 0 || 
       flashWnd == fgWnd ||
-      flashWnd == GetTopLevelHWND(fgWnd, false, false)) {
+      flashWnd == WinUtils::GetTopLevelHWND(fgWnd, false, false)) {
     return NS_OK;
   }
 
   DWORD defaultCycleCount = 0;
   ::SystemParametersInfo(SPI_GETFOREGROUNDFLASHCOUNT, 0, &defaultCycleCount, 0);
 
   FLASHWINFO flashInfo = { sizeof(FLASHWINFO), flashWnd,
     FLASHW_ALL, aCycleCount > 0 ? aCycleCount : defaultCycleCount, 0 };
@@ -3369,17 +3324,18 @@ NS_IMETHODIMP
 nsWindow::OnDefaultButtonLoaded(const nsIntRect &aButtonRect)
 {
   if (aButtonRect.IsEmpty())
     return NS_OK;
 
   // Don't snap when we are not active.
   HWND activeWnd = ::GetActiveWindow();
   if (activeWnd != ::GetForegroundWindow() ||
-      GetTopLevelHWND(mWnd, true) != GetTopLevelHWND(activeWnd, true)) {
+      WinUtils::GetTopLevelHWND(mWnd, true) !=
+        WinUtils::GetTopLevelHWND(activeWnd, true)) {
     return NS_OK;
   }
 
   bool isAlwaysSnapCursor =
     Preferences::GetBool("ui.cursor_snapping.always_enabled", false);
 
   if (!isAlwaysSnapCursor) {
     BOOL snapDefaultButton;
@@ -3442,17 +3398,17 @@ nsWindow::OverrideSystemMouseScrollSpeed
   // The default vertical scrolling speed is 3, this is defined on the document
   // of SystemParametersInfo in MSDN.
   if (systemSpeed != kSystemDefaultScrollingSpeed) {
     return NS_OK;
   }
 
   // Only Vista and later, Windows has the system setting of horizontal
   // scrolling by the mouse wheel.
-  if (GetWindowsVersion() >= VISTA_VERSION) {
+  if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION) {
     if (!::SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &systemSpeed, 0)) {
       return NS_ERROR_FAILURE;
     }
     // The default horizontal scrolling speed is 3, this is defined on the
     // document of SystemParametersInfo in MSDN.
     if (systemSpeed != kSystemDefaultScrollingSpeed) {
       return NS_OK;
     }
@@ -3496,25 +3452,16 @@ nsWindow::OverrideSystemMouseScrollSpeed
  *
  * SECTION: Mozilla event initialization
  *
  * Helpers for initializing moz events.
  *
  **************************************************************/
 
 // Event intialization
-MSG nsWindow::InitMSG(UINT aMessage, WPARAM wParam, LPARAM lParam)
-{
-  MSG msg;
-  msg.message = aMessage;
-  msg.wParam  = wParam;
-  msg.lParam  = lParam;
-  return msg;
-}
-
 void nsWindow::InitEvent(nsGUIEvent& event, nsIntPoint* aPoint)
 {
   if (nsnull == aPoint) {     // use the point from the event
     // get the message position in client coordinates
     if (mWnd != NULL) {
 
       DWORD pos = ::GetMessagePos();
       POINT cpos;
@@ -3761,17 +3708,17 @@ void nsWindow::DispatchPendingEvents()
     NS_ProcessPendingEvents(nsnull, PR_MillisecondsToInterval(100));
     --recursionBlocker;
   }
 
   // Quickly check to see if there are any
   // paint events pending.
   if (::GetQueueStatus(QS_PAINT)) {
     // Find the top level window.
-    HWND topWnd = GetTopLevelHWND(mWnd);
+    HWND topWnd = WinUtils::GetTopLevelHWND(mWnd);
 
     // Dispatch pending paints for topWnd and all its descendant windows.
     // Note: EnumChildWindows enumerates all descendant windows not just
     // the children (but not the window itself).
     nsWindow::DispatchStarvedPaints(topWnd, 0);
     ::EnumChildWindows(topWnd, nsWindow::DispatchStarvedPaints, 0);
   }
 }
@@ -3794,17 +3741,17 @@ bool nsWindow::DispatchPluginEvent(const
   return DispatchWindowEvent(&event);
 }
 
 bool nsWindow::DispatchPluginEvent(UINT aMessage,
                                      WPARAM aWParam,
                                      LPARAM aLParam,
                                      bool aDispatchPendingEvents)
 {
-  bool ret = DispatchPluginEvent(InitMSG(aMessage, aWParam, aLParam));
+  bool ret = DispatchPluginEvent(WinUtils::InitMSG(aMessage, aWParam, aLParam));
   if (aDispatchPendingEvents) {
     DispatchPendingEvents();
   }
   return ret;
 }
 
 void nsWindow::RemoveMessageAndDispatchPluginEvent(UINT aFirstMsg,
                  UINT aLastMsg, nsFakeCharMessage* aFakeCharMessage)
@@ -4092,29 +4039,29 @@ bool nsWindow::DispatchFocusToTopLevelWi
   sJustGotDeactivate = false;
 
   // retrive the toplevel window or dialog
   HWND curWnd = mWnd;
   HWND toplevelWnd = NULL;
   while (curWnd) {
     toplevelWnd = curWnd;
 
-    nsWindow *win = GetNSWindowPtr(curWnd);
+    nsWindow *win = WinUtils::GetNSWindowPtr(curWnd);
     if (win) {
       nsWindowType wintype;
       win->GetWindowType(wintype);
       if (wintype == eWindowType_toplevel || wintype == eWindowType_dialog)
         break;
     }
 
     curWnd = ::GetParent(curWnd); // Parent or owner (if has no parent)
   }
 
   if (toplevelWnd) {
-    nsWindow *win = GetNSWindowPtr(toplevelWnd);
+    nsWindow *win = WinUtils::GetNSWindowPtr(toplevelWnd);
     if (win)
       return win->DispatchFocus(aEventType);
   }
 
   return false;
 }
 
 // Deal with focus messages
@@ -4156,36 +4103,36 @@ bool nsWindow::DispatchFocus(PRUint32 aE
 bool nsWindow::IsTopLevelMouseExit(HWND aWnd)
 {
   DWORD pos = ::GetMessagePos();
   POINT mp;
   mp.x = GET_X_LPARAM(pos);
   mp.y = GET_Y_LPARAM(pos);
   HWND mouseWnd = ::WindowFromPoint(mp);
 
-  // GetTopLevelHWND will return a HWND for the window frame (which includes
-  // the non-client area).  If the mouse has moved into the non-client area,
-  // we should treat it as a top-level exit.
-  HWND mouseTopLevel = nsWindow::GetTopLevelHWND(mouseWnd);
+  // WinUtils::GetTopLevelHWND() will return a HWND for the window frame
+  // (which includes the non-client area).  If the mouse has moved into
+  // the non-client area, we should treat it as a top-level exit.
+  HWND mouseTopLevel = WinUtils::GetTopLevelHWND(mouseWnd);
   if (mouseWnd == mouseTopLevel)
     return true;
 
-  return nsWindow::GetTopLevelHWND(aWnd) != mouseTopLevel;
+  return WinUtils::GetTopLevelHWND(aWnd) != mouseTopLevel;
 }
 
 bool nsWindow::BlurEventsSuppressed()
 {
   // are they suppressed in this window?
   if (mBlurSuppressLevel > 0)
     return true;
 
   // are they suppressed by any container widget?
   HWND parentWnd = ::GetParent(mWnd);
   if (parentWnd) {
-    nsWindow *parent = GetNSWindowPtr(parentWnd);
+    nsWindow *parent = WinUtils::GetNSWindowPtr(parentWnd);
     if (parent)
       return parent->BlurEventsSuppressed();
   }
   return false;
 }
 
 // In some circumstances (opening dependent windows) it makes more sense
 // (and fixes a crash bug) to not blur the parent window. Called from
@@ -4285,17 +4232,17 @@ nsWindow::IPCWindowProcHandler(UINT& msg
         // helper window and ignore. Fixes an annoying focus problem.
         if ((InSendMessageEx(NULL)&(ISMEX_REPLIED|ISMEX_SEND)) == ISMEX_SEND) {
           PRUnichar szClass[10];
           HWND focusWnd = (HWND)lParam;
           if (IsWindowVisible(focusWnd) &&
               GetClassNameW(focusWnd, szClass,
                             sizeof(szClass)/sizeof(PRUnichar)) &&
               !wcscmp(szClass, L"Edit") &&
-              !IsOurProcessWindow(focusWnd)) {
+              !WinUtils::IsOurProcessWindow(focusWnd)) {
             break;
           }
         }
         handled = true;
       }
     break;
     // Plugins taking or losing focus triggering focus app messages.
     case WM_SETFOCUS:
@@ -4416,17 +4363,17 @@ LRESULT CALLBACK nsWindow::WindowProcInt
   if (msg == MOZ_WM_TRACE) {
     // This is a tracer event for measuring event loop latency.
     // See WidgetTraceEvent.cpp for more details.
     mozilla::SignalTracerThread();
     return 0;
   }
 
   // Get the window which caused the event and ask it to process the message
-  nsWindow *someWindow = GetNSWindowPtr(hWnd);
+  nsWindow *someWindow = WinUtils::GetNSWindowPtr(hWnd);
 
   if (someWindow)
     someWindow->IPCWindowProcHandler(msg, wParam, lParam);
 
   // create this here so that we store the last rolled up popup until after
   // the event has been processed.
   nsAutoRollup autoRollup;
 
@@ -4574,17 +4521,17 @@ bool nsWindow::ProcessMessage(UINT msg, 
   bool eatMessage;
   if (nsIMM32Handler::ProcessMessage(this, msg, wParam, lParam, aRetValue,
                                      eatMessage)) {
     return mWnd ? eatMessage : true;
   }
 
   if (PluginHasFocus()) {
     bool callDefaultWndProc;
-    MSG nativeMsg = InitMSG(msg, wParam, lParam);
+    MSG nativeMsg = WinUtils::InitMSG(msg, wParam, lParam);
     if (ProcessMessageForPlugin(nativeMsg, aRetValue, callDefaultWndProc)) {
       return mWnd ? !callDefaultWndProc : true;
     }
   }
 
   bool result = false;    // call the default nsWindow proc
   *aRetValue = 0;
 
@@ -4892,36 +4839,36 @@ bool nsWindow::ProcessMessage(UINT msg, 
 
     case WM_HOTKEY:
       result = OnHotKey(wParam, lParam);
       break;
 
     case WM_SYSCHAR:
     case WM_CHAR:
     {
-      MSG nativeMsg = InitMSG(msg, wParam, lParam);
+      MSG nativeMsg = WinUtils::InitMSG(msg, wParam, lParam);
       result = ProcessCharMessage(nativeMsg, nsnull);
       DispatchPendingEvents();
     }
     break;
 
     case WM_SYSKEYUP:
     case WM_KEYUP:
     {
-      MSG nativeMsg = InitMSG(msg, wParam, lParam);
+      MSG nativeMsg = WinUtils::InitMSG(msg, wParam, lParam);
       nativeMsg.time = ::GetMessageTime();
       result = ProcessKeyUpMessage(nativeMsg, nsnull);
       DispatchPendingEvents();
     }
     break;
 
     case WM_SYSKEYDOWN:
     case WM_KEYDOWN:
     {
-      MSG nativeMsg = InitMSG(msg, wParam, lParam);
+      MSG nativeMsg = WinUtils::InitMSG(msg, wParam, lParam);
       result = ProcessKeyDownMessage(nativeMsg, nsnull);
       DispatchPendingEvents();
     }
     break;
 
     // say we've dealt with erase background if widget does
     // not need auto-erasing
     case WM_ERASEBKGND:
@@ -5153,17 +5100,17 @@ bool nsWindow::ProcessMessage(UINT msg, 
     case WM_VSCROLL:
       *aRetValue = 0;
       result = OnScroll(msg, wParam, lParam);
       break;
 
     case MOZ_WM_HSCROLL:
     case MOZ_WM_VSCROLL:
       *aRetValue = 0;
-      OnScrollInternal(GetNativeMessage(msg), wParam, lParam);
+      OnScrollInternal(WinUtils::GetNativeMessage(msg), wParam, lParam);
       // Doesn't need to call next wndproc for internal message.
       return true;
 
     // The WM_ACTIVATE event is fired when a window is raised or lowered,
     // and the loword of wParam specifies which. But we don't want to tell
     // the focus system about this until the WM_SETFOCUS or WM_KILLFOCUS
     // events are fired. Instead, set either the sJustGotActivate or
     // gJustGotDeativate flags and fire the NS_ACTIVATE or NS_DEACTIVATE
@@ -5217,17 +5164,17 @@ bool nsWindow::ProcessMessage(UINT msg, 
       LPWINDOWPOS info = (LPWINDOWPOS) lParam;
       OnWindowPosChanging(info);
     }
     break;
 
     case WM_SETFOCUS:
       // If previous focused window isn't ours, it must have received the
       // redirected message.  So, we should forget it.
-      if (!IsOurProcessWindow(HWND(wParam))) {
+      if (!WinUtils::IsOurProcessWindow(HWND(wParam))) {
         ForgetRedirectedKeyDownMessage();
       }
       if (sJustGotActivate) {
         result = DispatchFocusToTopLevelWindow(NS_ACTIVATE);
       }
 
 #ifdef ACCESSIBILITY
       if (nsWindow::sIsAccessibilityOn) {
@@ -5332,17 +5279,17 @@ bool nsWindow::ProcessMessage(UINT msg, 
     // We don't need to call next wndproc WM_MOUSEWHEEL and WM_MOUSEHWHEEL.
     // We should consume them always.  If the messages would be handled by
     // our window again, it causes making infinite message loop.
     return true;
 
   case MOZ_WM_MOUSEVWHEEL:
   case MOZ_WM_MOUSEHWHEEL:
     {
-      UINT nativeMessage = GetNativeMessage(msg);
+      UINT nativeMessage = WinUtils::GetNativeMessage(msg);
       // If OnMouseWheel returns true, the event was forwarded directly to another
       // mozilla window message handler (ProcessMessage). In this case the return
       // value of the forwarded event is in 'result' which we should return immediately.
       // If OnMouseWheel returns false, OnMouseWheel processed the event internally.
       // 'result' and 'aRetValue' will be set based on what we did with the event, so
       // we should fall through.
       OnMouseWheelInternal(nativeMessage, wParam, lParam, aRetValue);
       // Doesn't need to call next wndproc for internal message.
@@ -5875,17 +5822,17 @@ nsWindow::SynthesizeNativeKeyEvent(PRInt
     PRUint8 key = keySequence[i].mGeneral;
     PRUint8 keySpecific = keySequence[i].mSpecific;
     kbdState[key] = 0x81; // key is down and toggled on if appropriate
     if (keySpecific) {
       kbdState[keySpecific] = 0x81;
     }
     ::SetKeyboardState(kbdState);
     nsModifierKeyState modKeyState;
-    MSG msg = InitMSG(WM_KEYDOWN, key, 0);
+    MSG msg = WinUtils::InitMSG(WM_KEYDOWN, key, 0);
     if (i == keySequence.Length() - 1 && aCharacters.Length() > 0) {
       UINT scanCode = ::MapVirtualKeyEx(aNativeKeyCode, MAPVK_VK_TO_VSC,
                                         gKbdLayout.GetLayout());
       nsFakeCharMessage fakeMsg = { aCharacters.CharAt(0), scanCode };
       OnKeyDown(msg, modKeyState, nsnull, &fakeMsg);
     } else {
       OnKeyDown(msg, modKeyState, nsnull, nsnull);
     }
@@ -5894,17 +5841,17 @@ nsWindow::SynthesizeNativeKeyEvent(PRInt
     PRUint8 key = keySequence[i - 1].mGeneral;
     PRUint8 keySpecific = keySequence[i - 1].mSpecific;
     kbdState[key] = 0; // key is up and toggled off if appropriate
     if (keySpecific) {
       kbdState[keySpecific] = 0;
     }
     ::SetKeyboardState(kbdState);
     nsModifierKeyState modKeyState;
-    MSG msg = InitMSG(WM_KEYUP, key, 0);
+    MSG msg = WinUtils::InitMSG(WM_KEYUP, key, 0);
     OnKeyUp(msg, modKeyState, nsnull);
   }
 
   // Restore old key state and layout
   ::SetKeyboardState(originalKbdState);
   gKbdLayout.LoadLayout(oldLayout);
 
   UnloadKeyboardLayout(loadedLayout);
@@ -5949,17 +5896,17 @@ BOOL nsWindow::OnInputLangChange(HKL aHK
 }
 
 void nsWindow::OnWindowPosChanged(WINDOWPOS *wp, bool& result)
 {
   if (wp == nsnull)
     return;
 
 #ifdef WINSTATE_DEBUG_OUTPUT
-  if (mWnd == GetTopLevelHWND(mWnd)) {
+  if (mWnd == WinUtils::GetTopLevelHWND(mWnd)) {
     PR_LOG(gWindowsLog, PR_LOG_ALWAYS, ("*** OnWindowPosChanged: [  top] "));
   } else {
     PR_LOG(gWindowsLog, PR_LOG_ALWAYS, ("*** OnWindowPosChanged: [child] "));
   }
   PR_LOG(gWindowsLog, PR_LOG_ALWAYS, ("WINDOWPOS flags:"));
   if (wp->flags & SWP_FRAMECHANGED) {
     PR_LOG(gWindowsLog, PR_LOG_ALWAYS, ("SWP_FRAMECHANGED "));
   }
@@ -6201,17 +6148,17 @@ void nsWindow::OnWindowPosChanging(LPWIN
     InitEvent(event);
 
     if (hwndAfter == HWND_BOTTOM)
       event.mPlacement = nsWindowZBottom;
     else if (hwndAfter == HWND_TOP || hwndAfter == HWND_TOPMOST || hwndAfter == HWND_NOTOPMOST)
       event.mPlacement = nsWindowZTop;
     else {
       event.mPlacement = nsWindowZRelative;
-      aboveWindow = GetNSWindowPtr(hwndAfter);
+      aboveWindow = WinUtils::GetNSWindowPtr(hwndAfter);
     }
     event.mReqBelow = aboveWindow;
     event.mActualBelow = nsnull;
 
     event.mImmediate = false;
     event.mAdjusted = false;
     DispatchWindowEvent(&event);
 
@@ -6351,27 +6298,16 @@ bool nsWindow::OnGesture(WPARAM wParam, 
   }
 
   // Only close this if we process and return true.
   mGesture.CloseGestureInfoHandle((HGESTUREINFO)lParam);
 
   return true; // Handled
 }
 
-PRUint16 nsWindow::GetMouseInputSource()
-{
-  PRUint16 inputSource = nsIDOMMouseEvent::MOZ_SOURCE_MOUSE;
-  LPARAM lParamExtraInfo = ::GetMessageExtraInfo();
-  if ((lParamExtraInfo & TABLET_INK_SIGNATURE) == TABLET_INK_CHECK) {
-    inputSource = (lParamExtraInfo & TABLET_INK_TOUCH) ?
-                  PRUint16(nsIDOMMouseEvent::MOZ_SOURCE_TOUCH) : nsIDOMMouseEvent::MOZ_SOURCE_PEN;
-  }
-  return inputSource;
-}
-
 /* static */ void
 nsWindow::InitMouseWheelScrollData()
 {
   if (!sNeedsToInitMouseWheelSettings) {
     return;
   }
   sNeedsToInitMouseWheelSettings = false;
   ResetRemainingWheelDelta();
@@ -6659,17 +6595,18 @@ UINT nsWindow::MapFromNativeToDOM(UINT a
   return aNativeKeyCode;
 }
 
 /* static */
 bool nsWindow::IsRedirectedKeyDownMessage(const MSG &aMsg)
 {
   return (aMsg.message == WM_KEYDOWN || aMsg.message == WM_SYSKEYDOWN) &&
          (sRedirectedKeyDown.message == aMsg.message &&
-          GetScanCode(sRedirectedKeyDown.lParam) == GetScanCode(aMsg.lParam));
+          WinUtils::GetScanCode(sRedirectedKeyDown.lParam) ==
+            WinUtils::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
@@ -6750,19 +6687,19 @@ LRESULT nsWindow::OnKeyDown(const MSG &a
     nsIMEContext newIMEContext(mWnd);
     if (!noDefault && !aFakeCharMessage && focusedWnd && !PluginHasFocus() &&
         !IMEContext.get() && newIMEContext.get()) {
       RemoveNextCharMessage(focusedWnd);
 
       INPUT keyinput;
       keyinput.type = INPUT_KEYBOARD;
       keyinput.ki.wVk = aMsg.wParam;
-      keyinput.ki.wScan = GetScanCode(aMsg.lParam);
+      keyinput.ki.wScan = WinUtils::GetScanCode(aMsg.lParam);
       keyinput.ki.dwFlags = KEYEVENTF_SCANCODE;
-      if (IsExtendedScanCode(aMsg.lParam)) {
+      if (WinUtils::IsExtendedScanCode(aMsg.lParam)) {
         keyinput.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY;
       }
       keyinput.ki.time = 0;
       keyinput.ki.dwExtraInfo = NULL;
 
       sRedirectedKeyDownEventPreventedDefault = noDefault;
       sRedirectedKeyDown = aMsg;
 
@@ -7487,115 +7424,16 @@ bool nsWindow::OnResize(nsIntRect &aWind
   return false;
 }
 
 bool nsWindow::OnHotKey(WPARAM wParam, LPARAM lParam)
 {
   return true;
 }
 
-/* static */
-bool nsWindow::IsOurProcessWindow(HWND aHWND)
-{
-  if (!aHWND) {
-    return false;
-  }
-  DWORD processId = 0;
-  ::GetWindowThreadProcessId(aHWND, &processId);
-  return processId == ::GetCurrentProcessId();
-}
-
-/* static */
-HWND nsWindow::FindOurProcessWindow(HWND aHWND)
-{
-  for (HWND wnd = ::GetParent(aHWND); wnd; wnd = ::GetParent(wnd)) {
-    if (IsOurProcessWindow(wnd)) {
-      return wnd;
-    }
-  }
-  return nsnull;
-}
-
-static bool PointInWindow(HWND aHWND, const POINT& aPoint)
-{
-  RECT bounds;
-  if (!::GetWindowRect(aHWND, &bounds)) {
-    return false;
-  }
-
-  if (aPoint.x < bounds.left
-      || aPoint.x >= bounds.right
-      || aPoint.y < bounds.top
-      || aPoint.y >= bounds.bottom) {
-    return false;
-  }
-
-  return 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 (WINAPI *GetProcessImageFileNameProc)(HANDLE, LPWSTR, 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 bool IsElantechHelperWindow(HWND aHWND)
 {
@@ -7627,52 +7465,16 @@ static bool IsElantechHelperWindow(HWND 
       }
     }
     ::CloseHandle(hProcess);
   }
 
   return result;
 }
 
-// static
-UINT
-nsWindow::GetInternalMessage(UINT aNativeMessage)
-{
-  switch (aNativeMessage) {
-    case WM_MOUSEWHEEL:
-      return MOZ_WM_MOUSEVWHEEL;
-    case WM_MOUSEHWHEEL:
-      return MOZ_WM_MOUSEHWHEEL;
-    case WM_VSCROLL:
-      return MOZ_WM_VSCROLL;
-    case WM_HSCROLL:
-      return MOZ_WM_HSCROLL;
-    default:
-      return aNativeMessage;
-  }
-}
-
-// static
-UINT
-nsWindow::GetNativeMessage(UINT aInternalMessage)
-{
-  switch (aInternalMessage) {
-    case MOZ_WM_MOUSEVWHEEL:
-      return WM_MOUSEWHEEL;
-    case MOZ_WM_MOUSEHWHEEL:
-      return WM_MOUSEHWHEEL;
-    case MOZ_WM_VSCROLL:
-      return WM_VSCROLL;
-    case MOZ_WM_HSCROLL:
-      return WM_HSCROLL;
-    default:
-      return aInternalMessage;
-  }
-}
-
 /**
  * OnMouseWheel() is called when ProcessMessage() handles WM_MOUSEWHEEL,
  * WM_MOUSEHWHEEL and also OnScroll() tries to emulate mouse wheel action for
  * WM_VSCROLL or WM_HSCROLL.
  * So, aMsg may be WM_MOUSEWHEEL, WM_MOUSEHWHEEL, WM_VSCROLL or WM_HSCROLL.
  */
 void
 nsWindow::OnMouseWheel(UINT aMsg, WPARAM aWParam, LPARAM aLParam,
@@ -7716,32 +7518,32 @@ nsWindow::OnMouseWheel(UINT aMsg, WPARAM
     return;
   }
 
   if (sUseElantechPinchHack && IsElantechHelperWindow(underCursorWnd)) {
     // 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.
-    underCursorWnd = FindOurWindowAtPoint(point);
+    underCursorWnd = WinUtils::FindOurWindowAtPoint(point);
     if (!underCursorWnd) {
       return;
     }
   }
 
   // Handle most cases first.  If the window under mouse cursor is our window
   // except plugin window (MozillaWindowClass), we should handle the message
   // on the window.
-  if (IsOurProcessWindow(underCursorWnd)) {
-    nsWindow* destWindow = GetNSWindowPtr(underCursorWnd);
+  if (WinUtils::IsOurProcessWindow(underCursorWnd)) {
+    nsWindow* destWindow = WinUtils::GetNSWindowPtr(underCursorWnd);
     if (!destWindow) {
       NS_WARNING("We're not sure what cause this is.");
       HWND wnd = ::GetParent(underCursorWnd);
       for (; wnd; wnd = ::GetParent(wnd)) {
-        destWindow = GetNSWindowPtr(wnd);
+        destWindow = WinUtils::GetNSWindowPtr(wnd);
         if (destWindow) {
           break;
         }
       }
       if (!wnd) {
         return;
       }
     }
@@ -7751,41 +7553,41 @@ nsWindow::OnMouseWheel(UINT aMsg, WPARAM
     // has been handled by the plugin but not consumed.  We should handle the
     // message on its parent window.  However, note that the DOM event may
     // cause accessing the plugin.  Therefore, we should unlock the plugin
     // process by using PostMessage().
     if (destWindow->mWindowType == eWindowType_plugin) {
       destWindow = destWindow->GetParentWindow(false);
       NS_ENSURE_TRUE(destWindow, );
     }
-    UINT internalMessage = GetInternalMessage(aMsg);
+    UINT internalMessage = WinUtils::GetInternalMessage(aMsg);
     ::PostMessage(destWindow->mWnd, internalMessage, aWParam, aLParam);
     return;
   }
 
   // If the window under cursor is not in our process, it means:
   // 1. The window may be a plugin window (GeckoPluginWindow or its descendant).
   // 2. The window may be another application's window.
-  HWND pluginWnd = FindOurProcessWindow(underCursorWnd);
+  HWND pluginWnd = WinUtils::FindOurProcessWindow(underCursorWnd);
   if (!pluginWnd) {
     // If there is no plugin window in ancestors of the window under cursor,
     // the window is for another applications (case 2).
     // We don't need to handle this message.
     return;
   }
 
   // If we're a plugin window (MozillaWindowClass) and cursor in this window,
   // the message shouldn't go to plugin's wndproc again.  So, we should handle
   // it on parent window.  However, note that the DOM event may cause accessing
   // the plugin.  Therefore, we should unlock the plugin process by using
   // PostMessage().
   if (mWindowType == eWindowType_plugin && pluginWnd == mWnd) {
     nsWindow* destWindow = GetParentWindow(false);
     NS_ENSURE_TRUE(destWindow, );
-    UINT internalMessage = GetInternalMessage(aMsg);
+    UINT internalMessage = WinUtils::GetInternalMessage(aMsg);
     ::PostMessage(destWindow->mWnd, internalMessage, aWParam, aLParam);
     return;
   }
 
   // If the window is a part of plugin, we should post the message to it.
   ::PostMessage(underCursorWnd, aMsg, aWParam, aLParam);
 }
 
@@ -8180,17 +7982,17 @@ bool nsWindow::AssociateDefaultIMC(bool 
          ("\n  {\n     HWND: %d, parent HWND: %d, wndobj: %p,\n",              \
           mWnd, ::GetParent(mWnd), this));                                     \
   NS_LOG_WMGETOBJECT_WNDACC(this)                                              \
   PR_LOG(gWindowsLog, PR_LOG_ALWAYS, ("\n  }\n"));                             \
 }
 
 #define NS_LOG_WMGETOBJECT_WND(aMsg, aHwnd)                                    \
 {                                                                              \
-  nsWindow* wnd = GetNSWindowPtr(aHwnd);                                       \
+  nsWindow* wnd = WinUtils::GetNSWindowPtr(aHwnd);                             \
   PR_LOG(gWindowsLog, PR_LOG_ALWAYS,                                           \
          ("Get " aMsg ":\n  {\n     HWND: %d, parent HWND: %d, wndobj: %p,\n", \
           aHwnd, ::GetParent(aHwnd), wnd));                                    \
   NS_LOG_WMGETOBJECT_WNDACC(wnd);                                              \
   PR_LOG(gWindowsLog, PR_LOG_ALWAYS, ("\n }\n"));                              \
 }
 #else
 #define NS_LOG_WMGETOBJECT_THISWND
@@ -8288,18 +8090,18 @@ void nsWindow::ResizeTranslucentWindow(P
 }
 
 void nsWindow::SetWindowTranslucencyInner(nsTransparencyMode aMode)
 {
   if (aMode == mTransparencyMode)
     return;
 
   // stop on dialogs and popups!
-  HWND hWnd = GetTopLevelHWND(mWnd, true);
-  nsWindow* parent = GetNSWindowPtr(hWnd);
+  HWND hWnd = WinUtils::GetTopLevelHWND(mWnd, true);
+  nsWindow* parent = WinUtils::GetNSWindowPtr(hWnd);
 
   if (!parent)
   {
     NS_WARNING("Trying to use transparent chrome in an embedded context");
     return;
   }
 
   if (parent != this) {
@@ -8359,17 +8161,17 @@ nsresult nsWindow::UpdateTranslucentWind
   if (mBounds.IsEmpty())
     return NS_OK;
 
   ::GdiFlush();
 
   BLENDFUNCTION bf = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
   SIZE winSize = { mBounds.width, mBounds.height };
   POINT srcPos = { 0, 0 };
-  HWND hWnd = GetTopLevelHWND(mWnd, true);
+  HWND hWnd = WinUtils::GetTopLevelHWND(mWnd, true);
   RECT winRect;
   ::GetWindowRect(hWnd, &winRect);
 
 #ifdef CAIRO_HAS_D2D_SURFACE
   if (gfxWindowsPlatform::GetPlatform()->GetRenderMode() ==
       gfxWindowsPlatform::RENDER_DIRECT2D) {
     mMemoryDC = static_cast<gfxD2DSurface*>(mTransparentSurface.get())->
       GetDC(true);
@@ -8466,25 +8268,25 @@ LRESULT CALLBACK nsWindow::MozSpecialMsg
   return ::CallNextHookEx(sMsgFilterHook, code, wParam, lParam);
 }
 
 // Process all mouse messages. Roll up when a click is in a native window
 // that doesn't have an nsIWidget.
 LRESULT CALLBACK nsWindow::MozSpecialMouseProc(int code, WPARAM wParam, LPARAM lParam)
 {
   if (sProcessHook) {
-    switch (GetNativeMessage(wParam)) {
+    switch (WinUtils::GetNativeMessage(wParam)) {
       case WM_LBUTTONDOWN:
       case WM_RBUTTONDOWN:
       case WM_MBUTTONDOWN:
       case WM_MOUSEWHEEL:
       case WM_MOUSEHWHEEL:
       {
         MOUSEHOOKSTRUCT* ms = (MOUSEHOOKSTRUCT*)lParam;
-        nsIWidget* mozWin = (nsIWidget*)GetNSWindowPtr(ms->hwnd);
+        nsIWidget* mozWin = WinUtils::GetNSWindowPtr(ms->hwnd);
         if (mozWin) {
           // If this window is windowed plugin window, the mouse events are not
           // sent to us.
           if (static_cast<nsWindow*>(mozWin)->mWindowType == eWindowType_plugin)
             ScheduleHookTimer(ms->hwnd, (UINT)wParam);
         } else {
           ScheduleHookTimer(ms->hwnd, (UINT)wParam);
         }
@@ -8617,17 +8419,17 @@ VOID CALLBACK nsWindow::HookTimerForPopu
     DealWithPopups(sRollupMsgWnd, sRollupMsgId, 0, 0, &popupHandlingResult);
     sRollupMsgId = 0;
     sRollupMsgWnd = NULL;
   }
 }
 
 BOOL CALLBACK nsWindow::ClearResourcesCallback(HWND aWnd, LPARAM aMsg)
 {
-    nsWindow *window = nsWindow::GetNSWindowPtr(aWnd);
+    nsWindow *window = WinUtils::GetNSWindowPtr(aWnd);
     if (window) {
         window->ClearCachedResources();
     }  
     return TRUE;
 }
 
 void
 nsWindow::ClearCachedResources()
@@ -8668,17 +8470,17 @@ nsWindow::EventIsInsideWindow(UINT Msg, 
 }
 
 // Handle events that may cause a popup (combobox, XPMenu, etc) to need to rollup.
 BOOL
 nsWindow::DealWithPopups(HWND inWnd, UINT inMsg, WPARAM inWParam, LPARAM inLParam, LRESULT* outResult)
 {
   if (sRollupListener && sRollupWidget && ::IsWindowVisible(inWnd)) {
 
-    inMsg = GetNativeMessage(inMsg);
+    inMsg = WinUtils::GetNativeMessage(inMsg);
     if (inMsg == WM_LBUTTONDOWN || inMsg == WM_RBUTTONDOWN || inMsg == WM_MBUTTONDOWN ||
         inMsg == WM_MOUSEWHEEL || inMsg == WM_MOUSEHWHEEL || inMsg == WM_ACTIVATE ||
         (inMsg == WM_KILLFOCUS && IsDifferentThreadWindow((HWND)inWParam)) ||
         inMsg == WM_NCRBUTTONDOWN ||
         inMsg == WM_MOVING ||
         inMsg == WM_SIZING ||
         inMsg == WM_NCLBUTTONDOWN ||
         inMsg == WM_NCMBUTTONDOWN ||
@@ -8765,17 +8567,17 @@ nsWindow::DealWithPopups(HWND inWnd, UIN
         // false allows the event to be dispatched
         //
         // So if we are NOT supposed to be consuming events, let it go through
         if (consumeRollupEvent && inMsg != WM_RBUTTONDOWN) {
           *outResult = MA_ACTIVATE;
 
           // However, don't activate panels
           if (inMsg == WM_MOUSEACTIVATE) {
-            nsWindow* activateWindow = GetNSWindowPtr(inWnd);
+            nsWindow* activateWindow = WinUtils::GetNSWindowPtr(inWnd);
             if (activateWindow) {
               nsWindowType wintype;
               activateWindow->GetWindowType(wintype);
               if (wintype == eWindowType_popup && activateWindow->PopupType() == ePopupTypePanel) {
                 *outResult = MA_NOACTIVATE;
               }
             }
           }
@@ -8809,37 +8611,20 @@ nsWindow::DealWithPopups(HWND inWnd, UIN
 nsModifierKeyState::nsModifierKeyState()
 {
   mIsShiftDown   = IS_VK_DOWN(NS_VK_SHIFT);
   mIsControlDown = IS_VK_DOWN(NS_VK_CONTROL);
   mIsAltDown     = IS_VK_DOWN(NS_VK_ALT);
 }
 
 
-PRInt32 nsWindow::GetWindowsVersion()
-{
-  static PRInt32 version = 0;
-  static bool didCheck = false;
-
-  if (!didCheck)
-  {
-    didCheck = true;
-    OSVERSIONINFOEX osInfo;
-    osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
-    // This cast is safe and supposed to be here, don't worry
-    ::GetVersionEx((OSVERSIONINFO*)&osInfo);
-    version = (osInfo.dwMajorVersion & 0xff) << 8 | (osInfo.dwMinorVersion & 0xff);
-  }
-  return version;
-}
-
 // Note that the result of GetTopLevelWindow method can be different from the
-// result of GetTopLevelHWND method.  The result can be non-floating window.
-// Because our top level window may be contained in another window which is
-// not managed by us.
+// result of WinUtils::GetTopLevelHWND().  The result can be non-floating
+// window.  Because our top level window may be contained in another window
+// which is not managed by us.
 nsWindow* nsWindow::GetTopLevelWindow(bool aStopOnDialogOrPopup)
 {
   nsWindow* curWindow = this;
 
   while (true) {
     if (aStopOnDialogOrPopup) {
       switch (curWindow->mWindowType) {
         case eWindowType_dialog:
@@ -8855,53 +8640,16 @@ nsWindow* nsWindow::GetTopLevelWindow(bo
 
     if (!parentWindow)
       return curWindow;
 
     curWindow = parentWindow;
   }
 }
 
-// Note that the result of GetTopLevelHWND can be different from the result
-// of GetTopLevelWindow method.  Because this is checking whether the window
-// is top level only in Win32 window system.  Therefore, the result window
-// may not be managed by us.
-HWND nsWindow::GetTopLevelHWND(HWND aWnd, 
-                               bool aStopIfNotChild, 
-                               bool aStopIfNotPopup)
-{
-  HWND curWnd = aWnd;
-  HWND topWnd = NULL;
-  HWND upWnd = NULL;
-
-  while (curWnd) {
-    topWnd = curWnd;
-
-    if (aStopIfNotChild) {
-      DWORD_PTR style = ::GetWindowLongPtrW(curWnd, GWL_STYLE);
-
-      VERIFY_WINDOW_STYLE(style);
-
-      if (!(style & WS_CHILD)) // first top-level window
-        break;
-    }
-
-    upWnd = ::GetParent(curWnd); // Parent or owner (if has no parent)
-
-    // GetParent will only return the owner if the passed in window 
-    // has the WS_POPUP style.
-    if (!upWnd && !aStopIfNotPopup) {
-      upWnd = ::GetWindow(curWnd, GW_OWNER);
-    }
-    curWnd = upWnd;
-  }
-
-  return topWnd;
-}
-
 static BOOL CALLBACK gEnumWindowsProc(HWND hwnd, LPARAM lParam)
 {
   DWORD pid;
   ::GetWindowThreadProcessId(hwnd, &pid);
   if (pid == GetCurrentProcessId() && ::IsWindowVisible(hwnd))
   {
     gWindowsVisible = true;
     return FALSE;
@@ -8984,61 +8732,21 @@ HasRegistryKey(HKEY aRoot, PRUnichar* aN
     result = ::RegOpenKeyExW(aRoot, aName, 0, KEY_READ | KEY_WOW64_64KEY, &key);
     if (result != ERROR_SUCCESS)
       return false;
   }
   ::RegCloseKey(key);
   return 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.
- */
-bool
-nsWindow::GetRegistryKey(HKEY aRoot,
-                         const PRUnichar* aKeyName,
-                         const PRUnichar* aValueName,
-                         PRUnichar* aBuffer,
-                         DWORD aBufferLength)
-{
-  if (!aKeyName)
-    return false;
-
-  HKEY key;
-  LONG result = ::RegOpenKeyExW(aRoot, aKeyName, NULL, KEY_READ | KEY_WOW64_32KEY, &key);
-  if (result != ERROR_SUCCESS) {
-    result = ::RegOpenKeyExW(aRoot, aKeyName, NULL, KEY_READ | KEY_WOW64_64KEY, &key);
-    if (result != ERROR_SUCCESS)
-      return false;
-  }
-  DWORD type;
-  result = ::RegQueryValueExW(key, aValueName, NULL, &type, (BYTE*) aBuffer, &aBufferLength);
-  ::RegCloseKey(key);
-  if (result != ERROR_SUCCESS || type != REG_SZ)
-    return false;
-  if (aBuffer)
-    aBuffer[aBufferLength / sizeof(*aBuffer) - 1] = 0;
-  return true;
-}
-
 static bool
 IsObsoleteSynapticsDriver()
 {
   PRUnichar buf[40];
-  bool foundKey = nsWindow::GetRegistryKey(HKEY_LOCAL_MACHINE,
+  bool foundKey = WinUtils::GetRegistryKey(HKEY_LOCAL_MACHINE,
                                            L"Software\\Synaptics\\SynTP\\Install",
                                            L"DriverVersion",
                                            buf,
                                            sizeof buf);
   if (!foundKey)
     return false;
 
   int majorVersion = wcstol(buf, NULL, 10);
@@ -9050,23 +8758,23 @@ IsObsoleteSynapticsDriver()
   return majorVersion < 15 || majorVersion == 15 && minorVersion == 0;
 }
 
 static PRInt32
 GetElantechDriverMajorVersion()
 {
   PRUnichar buf[40];
   // The driver version is found in one of these two registry keys.
-  bool foundKey = nsWindow::GetRegistryKey(HKEY_CURRENT_USER,
+  bool foundKey = WinUtils::GetRegistryKey(HKEY_CURRENT_USER,
                                            L"Software\\Elantech\\MainOption",
                                            L"DriverVersion",
                                            buf,
                                            sizeof buf);
   if (!foundKey)
-    foundKey = nsWindow::GetRegistryKey(HKEY_CURRENT_USER,
+    foundKey = WinUtils::GetRegistryKey(HKEY_CURRENT_USER,
                                         L"Software\\Elantech",
                                         L"DriverVersion",
                                         buf,
                                         sizeof buf);
 
   if (!foundKey)
     return false;
 
--- a/widget/windows/nsWindow.h
+++ b/widget/windows/nsWindow.h
@@ -195,26 +195,16 @@ public:
   NS_IMETHOD              OnIMETextChange(PRUint32 aStart, PRUint32 aOldEnd, PRUint32 aNewEnd);
   NS_IMETHOD              OnIMESelectionChange(void);
 #endif // NS_ENABLE_TSF
   NS_IMETHOD              GetNonClientMargins(nsIntMargin &margins);
   NS_IMETHOD              SetNonClientMargins(nsIntMargin &margins);
   void                    SetDrawsInTitlebar(bool aState);
 
   /**
-   * Statics used in other classes
-   */
-  static PRInt32          GetWindowsVersion();
-  static bool             GetRegistryKey(HKEY aRoot,
-                                         const PRUnichar* aKeyName,
-                                         const PRUnichar* aValueName,
-                                         PRUnichar* aBuffer,
-                                         DWORD aBufferLength);
-
-  /**
    * Event helpers
    */
   void                    InitEvent(nsGUIEvent& event, nsIntPoint* aPoint = nsnull);
   virtual bool            DispatchMouseEvent(PRUint32 aEventType, WPARAM wParam,
                                              LPARAM lParam,
                                              bool aIsContextMenuKey = false,
                                              PRInt16 aButton = nsMouseEvent::eLeftButton,
                                              PRUint16 aInputSource = nsIDOMMouseEvent::MOZ_SOURCE_MOUSE);
@@ -237,22 +227,18 @@ public:
   nsAccessible* DispatchAccessibleEvent(PRUint32 aEventType);
   nsAccessible* GetRootAccessible();
 #endif // ACCESSIBILITY
 
   /**
    * Window utilities
    */
   nsWindow*               GetTopLevelWindow(bool aStopOnDialogOrPopup);
-  static HWND             GetTopLevelHWND(HWND aWnd, 
-                                          bool aStopIfNotChild = false, 
-                                          bool aStopIfNotPopup = true);
   HWND                    GetWindowHandle() { return mWnd; }
   WNDPROC                 GetPrevWindowProc() { return mPrevWndProc; }
-  static nsWindow*        GetNSWindowPtr(HWND aWnd);
   WindowHook&             GetWindowHook() { return mWindowHook; }
   nsWindow*               GetParentWindow(bool aIncludeOwner);
   // Get an array of all nsWindow*s on the main thread.
   typedef void            (WindowEnumCallback)(nsWindow*);
   static void             EnumAllWindows(WindowEnumCallback aCallback);
 
   /**
    * Misc.
@@ -332,23 +318,20 @@ protected:
   static LRESULT CALLBACK MozSpecialWndProc(int code, WPARAM wParam, LPARAM lParam);
   static LRESULT CALLBACK MozSpecialMouseProc(int code, WPARAM wParam, LPARAM lParam);
   static VOID    CALLBACK HookTimerForPopups( HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime );
   static BOOL    CALLBACK ClearResourcesCallback(HWND aChild, LPARAM aParam);
   static BOOL    CALLBACK EnumAllChildWindProc(HWND aWnd, LPARAM aParam);
   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
    */
-  static BOOL             SetNSWindowPtr(HWND aWnd, nsWindow * ptr);
-  static PRInt32          GetMonitorCount();
   LPARAM                  lParamToScreen(LPARAM lParam);
   LPARAM                  lParamToClient(LPARAM lParam);
   virtual void            SubclassWindow(BOOL bState);
   bool                    CanTakeFocus();
   bool                    UpdateNonClientMargins(PRInt32 aSizeMode = -1, bool aReflowWindow = true);
   void                    UpdateGetWindowInfoCaptionStatus(bool aActiveCaption);
   void                    ResetLayout();
   void                    InvalidateNonClientRegion();
@@ -357,57 +340,45 @@ protected:
   static bool             GetInputWorkaroundPref(const char* aPrefName, bool aValueIfAutomatic);
   static bool             UseTrackPointHack();
   static void             PerformElantechSwipeGestureHack(UINT& aVirtualKeyCode, nsModifierKeyState& aModKeyState);
   static void             GetMainWindowClass(nsAString& aClass);
   bool                    HasGlass() const {
     return mTransparencyMode == eTransparencyGlass ||
            mTransparencyMode == eTransparencyBorderlessGlass;
   }
-  static bool             IsOurProcessWindow(HWND aHWND);
-  static HWND             FindOurProcessWindow(HWND aHWND);
-  static HWND             FindOurWindowAtPoint(const POINT& aPoint);
 
   /**
    * Event processing helpers
    */
   bool                    DispatchPluginEvent(const MSG &aMsg);
   bool                    DispatchFocusToTopLevelWindow(PRUint32 aEventType);
   bool                    DispatchFocus(PRUint32 aEventType);
   bool                    DispatchStandardEvent(PRUint32 aMsg);
   bool                    DispatchCommandEvent(PRUint32 aEventCommand);
   void                    RelayMouseEvent(UINT aMsg, WPARAM wParam, LPARAM lParam);
   static void             RemoveNextCharMessage(HWND aWnd);
   void                    RemoveMessageAndDispatchPluginEvent(UINT aFirstMsg,
                             UINT aLastMsg,
                             nsFakeCharMessage* aFakeCharMessage = nsnull);
-  static MSG              InitMSG(UINT aMessage, WPARAM wParam, LPARAM lParam);
   virtual bool            ProcessMessage(UINT msg, WPARAM &wParam,
                                          LPARAM &lParam, LRESULT *aRetValue);
   bool                    ProcessMessageForPlugin(const MSG &aMsg,
                                                   LRESULT *aRetValue, bool &aCallDefWndProc);
   LRESULT                 ProcessCharMessage(const MSG &aMsg,
                                              bool *aEventDispatched);
   LRESULT                 ProcessKeyUpMessage(const MSG &aMsg,
                                               bool *aEventDispatched);
   LRESULT                 ProcessKeyDownMessage(const MSG &aMsg,
                                                 bool *aEventDispatched);
   static bool             EventIsInsideWindow(UINT Msg, nsWindow* aWindow);
   // Convert nsEventStatus value to a windows boolean
   static bool             ConvertStatus(nsEventStatus aStatus);
   static void             PostSleepWakeNotification(const bool aIsSleepMode);
   PRInt32                 ClientMarginHitTestPoint(PRInt32 mx, PRInt32 my);
-  static WORD             GetScanCode(LPARAM aLParam)
-  {
-    return (aLParam >> 16) & 0xFF;
-  }
-  static bool             IsExtendedScanCode(LPARAM aLParam)
-  {
-    return (aLParam & 0x1000000) != 0;
-  }
   static bool             IsRedirectedKeyDownMessage(const MSG &aMsg);
   static void             ForgetRedirectedKeyDownMessage()
   {
     sRedirectedKeyDown.message = WM_NULL;
   }
 
   /**
    * Event handlers
@@ -437,18 +408,16 @@ protected:
   bool                    OnGesture(WPARAM wParam, LPARAM lParam);
 #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_WIN7
   bool                    OnTouch(WPARAM wParam, LPARAM lParam);
 #endif
   bool                    OnHotKey(WPARAM wParam, LPARAM lParam);
   BOOL                    OnInputLangChange(HKL aHKL);
   bool                    OnPaint(HDC aDC, PRUint32 aNestingLevel);
   void                    OnWindowPosChanged(WINDOWPOS *wp, bool& aResult);
-  static UINT             GetInternalMessage(UINT aNativeMessage);
-  static UINT             GetNativeMessage(UINT aInternalMessage);
   void                    OnMouseWheel(UINT aMsg, WPARAM aWParam,
                                        LPARAM aLParam, LRESULT *aRetValue);
   void                    OnMouseWheelInternal(UINT aMessage, WPARAM aWParam,
                                                LPARAM aLParam,
                                                LRESULT *aRetValue);
   void                    OnWindowPosChanging(LPWINDOWPOS& info);
   void                    OnSysColorChanged();
 
@@ -506,17 +475,16 @@ protected:
   void                    StopFlashing();
   static bool             IsTopLevelMouseExit(HWND aWnd);
   static void             SetupKeyModifiersSequence(nsTArray<KeyPair>* aArray, PRUint32 aModifiers);
   nsresult                SetWindowClipRegion(const nsTArray<nsIntRect>& aRects,
                                               bool aIntersectWithExisting);
   nsIntRegion             GetRegionToPaint(bool aForceFullRepaint, 
                                            PAINTSTRUCT ps, HDC aDC);
   static void             ActivateOtherWindowHelper(HWND aWnd);
-  static PRUint16         GetMouseInputSource();
 #ifdef ACCESSIBILITY
   static STDMETHODIMP_(LRESULT) LresultFromObject(REFIID riid, WPARAM wParam, LPUNKNOWN pAcc);
 #endif // ACCESSIBILITY
   void                    ClearCachedResources();
 
   nsPopupType PopupType() { return mPopupType; }
 
 protected:
--- a/widget/windows/nsWindowDefs.h
+++ b/widget/windows/nsWindowDefs.h
@@ -63,23 +63,16 @@
 #define MOZ_WM_MOUSEVWHEEL                (WM_APP+0x0310)
 #define MOZ_WM_MOUSEHWHEEL                (WM_APP+0x0311)
 #define MOZ_WM_VSCROLL                    (WM_APP+0x0312)
 #define MOZ_WM_HSCROLL                    (WM_APP+0x0313)
 // Internal message for ensuring the file picker is visible on multi monitor
 // systems, and when the screen resolution changes.
 #define MOZ_WM_ENSUREVISIBLE              (WM_APP + 14159)
 
-// GetWindowsVersion constants
-#define WIN2K_VERSION                     0x500
-#define WINXP_VERSION                     0x501
-#define WIN2K3_VERSION                    0x502
-#define VISTA_VERSION                     0x600
-#define WIN7_VERSION                      0x601
-
 #ifndef WM_THEMECHANGED
 #define WM_THEMECHANGED                   0x031A
 #endif
 
 #ifndef WM_GETOBJECT
 #define WM_GETOBJECT                      0x03d
 #endif
 
@@ -181,17 +174,17 @@
    *#define GET_KEYSTATE_LPARAM(lParam)       GET_FLAGS_LPARAM(lParam)
    */
 #endif // #ifndef APPCOMMAND_BROWSER_BACKWARD
 
 //Tablet PC Mouse Input Source
 #define TABLET_INK_SIGNATURE 0xFFFFFF00
 #define TABLET_INK_CHECK     0xFF515700
 #define TABLET_INK_TOUCH     0x00000080
-#define MOUSE_INPUT_SOURCE() GetMouseInputSource()
+#define MOUSE_INPUT_SOURCE() WinUtils::GetMouseInputSource()
 
 /**************************************************************
  *
  * SECTION: enums
  * 
  **************************************************************/
 
 // nsWindow::sCanQuit
--- a/widget/windows/nsWindowGfx.cpp
+++ b/widget/windows/nsWindowGfx.cpp
@@ -60,16 +60,17 @@ using mozilla::plugins::PluginInstancePa
 #include <windows.h>
 #include "gfxImageSurface.h"
 #include "gfxWindowsSurface.h"
 #include "gfxWindowsPlatform.h"
 #include "nsGfxCIID.h"
 #include "gfxContext.h"
 #include "nsRenderingContext.h"
 #include "prmem.h"
+#include "WinUtils.h"
 
 #include "LayerManagerOGL.h"
 #include "BasicLayers.h"
 #ifdef MOZ_ENABLE_D3D9_LAYER
 #include "LayerManagerD3D9.h"
 #endif
 #ifdef MOZ_ENABLE_D3D10_LAYER
 #include "LayerManagerD3D10.h"
@@ -79,16 +80,17 @@ using mozilla::plugins::PluginInstancePa
 #include "nsUXThemeConstants.h"
 
 extern "C" {
 #define PIXMAN_DONT_DEFINE_STDINT
 #include "pixman.h"
 }
 
 using namespace mozilla::layers;
+using namespace mozilla::widget;
 
 /**************************************************************
  **************************************************************
  **
  ** BLOCK: Variables
  **
  ** nsWindow Class static initializations and global variables.
  **
@@ -756,17 +758,17 @@ PRUint8* nsWindowGfx::Data32BitTo1Bit(PR
 
 bool nsWindowGfx::IsCursorTranslucencySupported()
 {
   static bool didCheck = false;
   static bool isSupported = false;
   if (!didCheck) {
     didCheck = true;
     // Cursor translucency is supported on Windows XP and newer
-    isSupported = nsWindow::GetWindowsVersion() >= 0x501;
+    isSupported = WinUtils::GetWindowsVersion() >= WinUtils::WINXP_VERSION;
   }
 
   return isSupported;
 }
 
 /**
  * Convert the given image data to a HBITMAP. If the requested depth is
  * 32 bit and the OS supports translucency, a bitmap with an alpha channel