Bug 712483 Implement mozilla::widget::WinUtils r=jimm
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 04 Jan 2012 19:21:44 +0900
changeset 84975 43f76a0051889e5c07dac4dab2e090e03ce2be16
parent 84974 ad98a08690cb7329ee47bda90ab8f9ea28c3e186
child 84976 ae7a421e7fdbd6d70e6de9314c72f56f4a5c993b
push idunknown
push userunknown
push dateunknown
reviewersjimm
bugs712483
milestone12.0a1
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