Merge mozilla-central and mozilla-inbound
authorMarco Bonardo <mbonardo@mozilla.com>
Tue, 02 Aug 2011 11:52:56 +0200
changeset 73664 10927265c5558da7d729fa86fba3237f2eb2125c
parent 73663 1c2f8133da3c8036beb8cd628eab1cf5b7d660f8 (current diff)
parent 73621 cb495bdd4aeafd936358758ed41ac6f8ae0eab6b (diff)
child 73672 a8bbb17fd043d21756fd3272f48040e5c85ee06d
child 73695 0cdcf876dd05b21bf64b16f2c5323d4af591fabc
child 75529 b764f55dd37d724dd80d002de3f09ecc9f271cc3
push id20900
push usermak77@bonardo.net
push dateTue, 02 Aug 2011 09:54:14 +0000
treeherdermozilla-central@10927265c555 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone8.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central and mozilla-inbound
configure.in
js/src/configure.in
widget/src/windows/nsWindow.cpp
--- a/build/autoconf/mozconfig-find
+++ b/build/autoconf/mozconfig-find
@@ -41,33 +41,27 @@
 #    command-line. The .mozconfig file is searched for in the 
 #    order:
 #       if $MOZCONFIG is set, use that.
 #       Otherwise, use $TOPSRCDIR/.mozconfig
 #       Otherwise, use $HOME/.mozconfig
 #
 topsrcdir=$1
 
-absolute_path() {
-  if [ -n "${1%%/*}" ]; then
-    echo $topsrcdir/$1
-  else
-    echo $1
-  fi
-}
-
-if [ -n "$MOZCONFIG" ]; then
-  MOZCONFIG=`absolute_path "$MOZCONFIG"`
-  if ! [ -f "$MOZCONFIG" ]; then
-    echo "Specified MOZCONFIG \"$MOZCONFIG\" does not exist!"
+for _config in "$MOZCONFIG" \
+               "$MOZ_MYCONFIG"
+do
+  if [ -n "$_config" ] && ! [ -f "$_config" ]; then
+    echo "Specified MOZCONFIG \"$_config\" does not exist!"
     exit 1
   fi
-fi
+done
 
 for _config in "$MOZCONFIG" \
+               "$MOZ_MYCONFIG" \
                "$topsrcdir/.mozconfig" \
                "$topsrcdir/mozconfig" \
                "$topsrcdir/mozconfig.sh" \
                "$topsrcdir/myconfig.sh" \
                "$HOME/.mozconfig" \
                "$HOME/.mozconfig.sh" \
                "$HOME/.mozmyconfig.sh"
 do
--- a/build/manifestparser.py
+++ b/build/manifestparser.py
@@ -50,20 +50,20 @@ Mozilla universal manifest parser
 
 import os
 import re
 import shutil
 import sys
 from fnmatch import fnmatch
 from optparse import OptionParser
 
-version = '0.5.2' # package version
+version = '0.5.3' # package version
 try:
     from setuptools import setup
-except ImportError:
+except:
     setup = None
 
 # we need relpath, but it is introduced in python 2.6
 # http://docs.python.org/library/os.path.html
 try:
     relpath = os.path.relpath
 except AttributeError:
     def relpath(path, start):
--- a/configure.in
+++ b/configure.in
@@ -4283,18 +4283,21 @@ AC_CACHE_CHECK(for trouble comparing to 
                                [Foo<int> f; return (0 != f);],
                                ac_cv_trouble_comparing_to_zero=no,
                                ac_cv_trouble_comparing_to_zero=yes)])
 if test "$ac_cv_trouble_comparing_to_zero" = yes ; then
   AC_DEFINE(HAVE_CPP_TROUBLE_COMPARING_TO_ZERO)
 fi
 
 # try harder, when checking for __thread support, see bug 521750 comment #33 and below
+# We pass MOZ_OPTIMIZE_LDFLAGS to the linker because if dead_strip is
+# enabled, the linker in xcode 4.1 will crash. Without this it would crash when
+# linking XUL.
 _SAVE_LDFLAGS=$LDFLAGS
-LDFLAGS="$LDFLAGS $DSO_PIC_CFLAGS $DSO_LDOPTS"
+LDFLAGS="$LDFLAGS $DSO_PIC_CFLAGS $DSO_LDOPTS $MOZ_OPTIMIZE_LDFLAGS"
 AC_CACHE_CHECK(for __thread keyword for TLS variables,
                ac_cv_thread_keyword,
                [AC_TRY_LINK([__thread bool tlsIsMainThread = false;],
                             [return tlsIsMainThread;],
                             ac_cv_thread_keyword=yes,
                             ac_cv_thread_keyword=no)])
 LDFLAGS=$_SAVE_LDFLAGS
 if test "$ac_cv_thread_keyword" = yes; then
--- a/dom/plugins/ipc/PluginInstanceChild.cpp
+++ b/dom/plugins/ipc/PluginInstanceChild.cpp
@@ -1284,20 +1284,16 @@ PluginInstanceChild::PluginWindowProcInt
       self->CallPluginFocusChange(true);
 
     // Prevent lockups due to plugins making rpc calls when the parent
     // is making a synchronous SendMessage call to the child window. Add
     // more messages as needed.
     if ((InSendMessageEx(NULL)&(ISMEX_REPLIED|ISMEX_SEND)) == ISMEX_SEND) {
         switch(message) {
             case WM_KILLFOCUS:
-            case WM_MOUSEHWHEEL:
-            case WM_MOUSEWHEEL:
-            case WM_HSCROLL:
-            case WM_VSCROLL:
             ReplyMessage(0);
             break;
         }
     }
 
     if (message == WM_KILLFOCUS)
       self->CallPluginFocusChange(false);
 
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -4197,18 +4197,21 @@ AC_CACHE_CHECK(for trouble comparing to 
                                [Foo<int> f; return (0 != f);],
                                ac_cv_trouble_comparing_to_zero=no,
                                ac_cv_trouble_comparing_to_zero=yes)])
 if test "$ac_cv_trouble_comparing_to_zero" = yes ; then
   AC_DEFINE(HAVE_CPP_TROUBLE_COMPARING_TO_ZERO)
 fi
 
 # try harder, when checking for __thread support, see bug 521750 comment #33 and below
+# We pass MOZ_OPTIMIZE_LDFLAGS to the linker because if dead_strip is
+# enabled, the linker in xcode 4.1 will crash. Without this it would crash when
+# linking XUL.
 _SAVE_LDFLAGS=$LDFLAGS
-LDFLAGS="$LDFLAGS $DSO_PIC_CFLAGS $DSO_LDOPTS"
+LDFLAGS="$LDFLAGS $DSO_PIC_CFLAGS $DSO_LDOPTS $MOZ_OPTIMIZE_LDFLAGS"
 AC_CACHE_CHECK(for __thread keyword for TLS variables,
                ac_cv_thread_keyword,
                [AC_TRY_LINK([__thread bool tlsIsMainThread = false;],
                             [return tlsIsMainThread;],
                             ac_cv_thread_keyword=yes,
                             ac_cv_thread_keyword=no)])
 LDFLAGS=$_SAVE_LDFLAGS
 if test "$ac_cv_thread_keyword" = yes; then
--- a/mobile/chrome/content/common-ui.js
+++ b/mobile/chrome/content/common-ui.js
@@ -1269,82 +1269,84 @@ var SelectionHelper = {
 
     this._end.customDragger = {
       isDraggable: function isDraggable(target, content) { return { x: true, y: false }; },
       dragStart: function dragStart(cx, cy, target, scroller) {},
       dragStop: function dragStop(dx, dy, scroller) { return false; },
       dragMove: function dragMove(dx, dy, scroller) { return false; }
     };
 
-    this._start.addEventListener("TapDown", this, true);
     this._start.addEventListener("TapUp", this, true);
-
-    this._end.addEventListener("TapDown", this, true);
     this._end.addEventListener("TapUp", this, true);
 
     messageManager.addMessageListener("Browser:SelectionRange", this);
     messageManager.addMessageListener("Browser:SelectionCopied", this);
 
     this.popupState.target.messageManager.sendAsyncMessage("Browser:SelectionStart", { x: this.popupState.x, y: this.popupState.y });
 
-    BrowserUI.pushPopup(this, [this._start, this._end]);
-
     // Hide the selection handles
+    window.addEventListener("TapDown", this, true);
     window.addEventListener("resize", this, true);
     window.addEventListener("keypress", this, true);
     Elements.browsers.addEventListener("URLChanged", this, true);
     Elements.browsers.addEventListener("SizeChanged", this, true);
     Elements.browsers.addEventListener("ZoomChanged", this, true);
 
     let event = document.createEvent("Events");
     event.initEvent("CancelTouchSequence", true, false);
     this.popupState.target.dispatchEvent(event);
 
     return true;
   },
 
-  hide: function sh_hide() {
+  hide: function sh_hide(aEvent) {
     if (this._start.hidden)
       return;
 
+    let pos = this.popupState.target.transformClientToBrowser(aEvent.clientX || 0, aEvent.clientY || 0);
+    let json = {
+      x: pos.x,
+      y: pos.y
+    };
+
     try {
-      this.popupState.target.messageManager.sendAsyncMessage("Browser:SelectionEnd", {});
+      this.popupState.target.messageManager.sendAsyncMessage("Browser:SelectionEnd", json);
     } catch (e) {
       Cu.reportError(e);
     }
 
     this.popupState = null;
 
     this._start.hidden = true;
     this._end.hidden = true;
 
-    this._start.removeEventListener("TapDown", this, true);
     this._start.removeEventListener("TapUp", this, true);
-
-    this._end.removeEventListener("TapDown", this, true);
     this._end.removeEventListener("TapUp", this, true);
 
     messageManager.removeMessageListener("Browser:SelectionRange", this);
 
+    window.removeEventListener("TapDown", this, true);
     window.removeEventListener("resize", this, true);
     window.removeEventListener("keypress", this, true);
     Elements.browsers.removeEventListener("URLChanged", this, true);
     Elements.browsers.removeEventListener("SizeChanged", this, true);
     Elements.browsers.removeEventListener("ZoomChanged", this, true);
-
-    BrowserUI.popPopup(this);
   },
 
   handleEvent: function handleEvent(aEvent) {
     switch (aEvent.type) {
       case "TapDown":
-        this.target = aEvent.target;
-        this.deltaX = (aEvent.clientX - this.target.left);
-        this.deltaY = (aEvent.clientY - this.target.top);
-        window.addEventListener("TapMove", this, true);
+        if (aEvent.target == this._start || aEvent.target == this._end) {
+          this.target = aEvent.target;
+          this.deltaX = (aEvent.clientX - this.target.left);
+          this.deltaY = (aEvent.clientY - this.target.top);
+          window.addEventListener("TapMove", this, true);
+        } else {
+          this.hide(aEvent);
+        }
         break;
       case "TapUp":
         window.removeEventListener("TapMove", this, true);
         this.target = null;
         this.deltaX = -1;
         this.deltaY = -1;
         break;
       case "TapMove":
@@ -1362,17 +1364,17 @@ var SelectionHelper = {
           this.popupState.target.messageManager.sendAsyncMessage("Browser:SelectionMove", json);
         }
         break;
       case "resize":
       case "keypress":
       case "URLChanged":
       case "SizeChanged":
       case "ZoomChanged":
-        this.hide();
+        this.hide(aEvent);
         break;
     }
   },
 
   receiveMessage: function sh_receiveMessage(aMessage) {
     let json = aMessage.json;
     switch (aMessage.name) {
       case "Browser:SelectionRange": {
--- a/mobile/chrome/content/content.js
+++ b/mobile/chrome/content/content.js
@@ -1329,45 +1329,44 @@ var TouchEventHandler = {
 
 TouchEventHandler.init();
 
 var SelectionHandler = {
   cache: {},
   selectedText: "",
   contentWindow: null,
   
-  init: function() {
+  init: function sh_init() {
     addMessageListener("Browser:SelectionStart", this);
     addMessageListener("Browser:SelectionEnd", this);
     addMessageListener("Browser:SelectionMove", this);
   },
 
-  receiveMessage: function(aMessage) {
+  receiveMessage: function sh_receiveMessage(aMessage) {
     let scrollOffset = ContentScroll.getScrollOffset(content);
     let utils = Util.getWindowUtils(content);
     let json = aMessage.json;
 
     switch (aMessage.name) {
       case "Browser:SelectionStart": {
         this.selectedText = "";
 
         // if this is an iframe, dig down to find the document that was clicked
         let x = json.x;
         let y = json.y;
-        let offsetX = 0;
-        let offsetY = 0;
+        let offset = scrollOffset;
         let elem = utils.elementFromPoint(x, y, true, false);
         while (elem && (elem instanceof HTMLIFrameElement || elem instanceof HTMLFrameElement)) {
           // adjust client coordinates' origin to be top left of iframe viewport
           let rect = elem.getBoundingClientRect();
           scrollOffset = ContentScroll.getScrollOffset(elem.ownerDocument.defaultView);
-          offsetX += rect.left;
+          offset.x += rect.left;
           x -= rect.left;
 
-          offsetY += rect.top + scrollOffset.y;
+          offset.y += rect.top + scrollOffset.y;
           y -= rect.top + scrollOffset.y;
           utils = elem.contentDocument.defaultView.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
           elem = utils.elementFromPoint(x, y, true, false);
         }
         let contentWindow = elem.ownerDocument.defaultView;
         let currentDocShell = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation).QueryInterface(Ci.nsIDocShell);
 
         // Position the caret using a fake mouse click
@@ -1397,73 +1396,106 @@ var SelectionHandler = {
         this.selectedText = selection.toString().trim();
 
         // If the range didn't have any text, let's bail
         if (!this.selectedText.length) {
           selection.collapseToStart();
           return;
         }
 
-        this.cache = { start: {}, end: {} };
-        let rects = range.getClientRects();
-        for (let i=0; i<rects.length; i++) {
-          if (i == 0) {
-            this.cache.start.x = rects[i].left + offsetX;
-            this.cache.start.y = rects[i].bottom + offsetY;
-          }
-          this.cache.end.x = rects[i].right + offsetX;
-          this.cache.end.y = rects[i].bottom + offsetY;
+        this.cache = this._extractFromRange(range, offset);
+
+        let tap = { x: json.x - this.cache.offset.x, y: json.y - this.cache.offset.y };
+        pointInSelection = (tap.x > this.cache.rect.left && tap.x < this.cache.rect.right) && (tap.y > this.cache.rect.top && tap.y < this.cache.rect.bottom);
+        if (!pointInSelection) {
+          selection.collapseToStart();
+          return;
         }
 
         this.contentWindow = contentWindow;
+
         sendAsyncMessage("Browser:SelectionRange", this.cache);
         break;
       }
 
       case "Browser:SelectionEnd": {
+        let tap = { x: json.x - this.cache.offset.x, y: json.y - this.cache.offset.y };
+        pointInSelection = (tap.x > this.cache.rect.left && tap.x < this.cache.rect.right) && (tap.y > this.cache.rect.top && tap.y < this.cache.rect.bottom);
+
         try {
           // The selection might already be gone
           if (this.contentWindow)
             this.contentWindow.getSelection().collapseToStart();
           this.contentWindow = null;
         } catch(e) {}
 
-        if (this.selectedText.length) {
+        if (pointInSelection && this.selectedText.length) {
           let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
           clipboard.copyString(this.selectedText);
           sendAsyncMessage("Browser:SelectionCopied", { succeeded: true });
         } else {
           sendAsyncMessage("Browser:SelectionCopied", { succeeded: false });
         }
         break;
       }
 
       case "Browser:SelectionMove":
         if (!this.contentWindow)
           return;
+
         // Hack to avoid setting focus in a textbox [Bugs 654352 & 667243]
         let elemUnder = elementFromPoint(json.x - scrollOffset.x, json.y - scrollOffset.y);
         if (elemUnder && elemUnder instanceof Ci.nsIDOMHTMLInputElement || elemUnder instanceof Ci.nsIDOMHTMLTextAreaElement)
           return;
 
+        // Limit the selection to the initial content window (don't leave or enter iframes)
+        if (elemUnder && elemUnder.ownerDocument.defaultView != this.contentWindow)
+          return;
+
         if (json.type == "end") {
           this.cache.end.x = json.x - scrollOffset.x;
           this.cache.end.y = json.y - scrollOffset.y;
           utils.sendMouseEventToWindow("mousedown", this.cache.end.x, this.cache.end.y, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true);
           utils.sendMouseEventToWindow("mouseup", this.cache.end.x, this.cache.end.y, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true);
         } else {
           this.cache.start.x = json.x - scrollOffset.x;
           this.cache.start.y = json.y - scrollOffset.y;
           utils.sendMouseEventToWindow("mousedown", this.cache.start.x, this.cache.start.y, 0, 1, 0, true);
           // Don't cause a click. A mousedown is enough to move the caret
           //utils.sendMouseEventToWindow("mouseup", this.cache.start.x, this.cache.start.y, 0, 1, 0, true);
           utils.sendMouseEventToWindow("mousedown", this.cache.end.x, this.cache.end.y, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true);
           utils.sendMouseEventToWindow("mouseup", this.cache.end.x, this.cache.end.y, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true);
         }
 
         // Cache the selected text since the selection might be gone by the time we get the "end" message
-        this.selectedText = this.contentWindow.getSelection().toString().trim();
+        let selection = this.contentWindow.getSelection()
+        this.selectedText = selection.toString().trim();
+
+        // Update the rect we use to test when finishing the clipboard operation
+        let range = selection.getRangeAt(0).QueryInterface(Ci.nsIDOMNSRange);
+        this.cache.rect = this._extractFromRange(range, this.cache.offset).rect;
         break;
     }
+  },
+
+  _extractFromRange: function sh_extractFromRange(aRange, aOffset) {
+    let cache = { start: {}, end: {}, rect: { left: Number.MAX_VALUE, top: Number.MAX_VALUE, right: 0, bottom: 0 } };
+    let rects = aRange.getClientRects();
+    for (let i=0; i<rects.length; i++) {
+      if (i == 0) {
+        cache.start.x = rects[i].left + aOffset.x;
+        cache.start.y = rects[i].bottom + aOffset.y;
+      }
+      cache.end.x = rects[i].right + aOffset.x;
+      cache.end.y = rects[i].bottom + aOffset.y;
+    }
+    cache.rect = aRange.getBoundingClientRect();
+    cache.rect.left += aOffset.x;
+    cache.rect.top += aOffset.y;
+    cache.rect.right += aOffset.x;
+    cache.rect.bottom += aOffset.y;
+    cache.offset = aOffset;
+
+    return cache;
   }
 };
 
 SelectionHandler.init();
--- a/mobile/themes/core/gingerbread/platform.css
+++ b/mobile/themes/core/gingerbread/platform.css
@@ -732,17 +732,17 @@ dialog {
   }
   
   /* This will affect the prefs screen, but not the awesome screen */
   #panel-controls {
     -moz-box-orient: vertical !important;
     -moz-box-align: start;
   }
   
-  .panel-row-button {
+  #panel-controls > .panel-row-button {
     -moz-box-orient: horizontal;
     -moz-box-flex: 0;
     min-width: @tablet_panel_controls@ !important;
   }
 
   #panel-controls .toolbarbutton-text {
     display: -moz-box !important;
     -moz-box-flex: 1;
--- a/mobile/themes/core/platform.css
+++ b/mobile/themes/core/platform.css
@@ -745,17 +745,17 @@ dialog {
   }
   
   /* This will affect the prefs screen, but not the awesome screen */
   #panel-controls {
     -moz-box-orient: vertical !important;
     -moz-box-align: start;
   }
   
-  .panel-row-button {
+  #panel-controls > .panel-row-button {
     -moz-box-orient: horizontal;
     -moz-box-flex: 0;
     min-width: @tablet_panel_controls@ !important;
   }
 
   #panel-controls .toolbarbutton-text {
     display: -moz-box !important;
     -moz-box-flex: 1;
--- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/minidump_generator.cc
+++ b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/minidump_generator.cc
@@ -28,26 +28,30 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <algorithm>
 #include <cstdio>
 
 #include <mach/host_info.h>
 #include <mach/i386/thread_status.h>
 #include <mach/mach_vm.h>
-#include <mach/ppc/thread_status.h>
 #include <mach/vm_statistics.h>
 #include <mach-o/dyld.h>
 #include <mach-o/loader.h>
 #include <sys/sysctl.h>
 #include <sys/resource.h>
 
 #include <CoreFoundation/CoreFoundation.h>
 
 #include "client/mac/handler/minidump_generator.h"
+
+#ifdef HAS_PPC_SUPPORT
+#include <mach/ppc/thread_status.h>
+#endif
+
 #include "client/minidump_file_writer-inl.h"
 #include "common/mac/file_id.h"
 #include "common/mac/string_utilities.h"
 
 using MacStringUtils::ConvertToString;
 using MacStringUtils::IntegerValueAtIndex;
 
 namespace google_breakpad {
@@ -331,62 +335,69 @@ bool MinidumpGenerator::WriteStackFromSt
   stack_location->memory = memory.location();
 
   return result;
 }
 
 bool MinidumpGenerator::WriteStack(breakpad_thread_state_data_t state,
                                    MDMemoryDescriptor *stack_location) {
   switch (cpu_type_) {
+#ifdef HAS_PPC_SUUPORT
     case CPU_TYPE_POWERPC:
       return WriteStackPPC(state, stack_location);
     case CPU_TYPE_POWERPC64:
       return WriteStackPPC64(state, stack_location);
+#endif
     case CPU_TYPE_I386:
       return WriteStackX86(state, stack_location);
     case CPU_TYPE_X86_64:
       return WriteStackX86_64(state, stack_location);
     default:
       return false;
   }
 }
 
 bool MinidumpGenerator::WriteContext(breakpad_thread_state_data_t state,
                                      MDLocationDescriptor *register_location) {
   switch (cpu_type_) {
+#ifdef HAS_PPC_SUPPORT
     case CPU_TYPE_POWERPC:
       return WriteContextPPC(state, register_location);
     case CPU_TYPE_POWERPC64:
       return WriteContextPPC64(state, register_location);
+#endif
     case CPU_TYPE_I386:
       return WriteContextX86(state, register_location);
     case CPU_TYPE_X86_64:
       return WriteContextX86_64(state, register_location);
     default:
       return false;
   }
 }
 
 u_int64_t MinidumpGenerator::CurrentPCForStack(
     breakpad_thread_state_data_t state) {
   switch (cpu_type_) {
+#ifdef HAS_PPC_SUPPORT
     case CPU_TYPE_POWERPC:
       return CurrentPCForStackPPC(state);
     case CPU_TYPE_POWERPC64:
       return CurrentPCForStackPPC64(state);
+#endif
     case CPU_TYPE_I386:
       return CurrentPCForStackX86(state);
     case CPU_TYPE_X86_64:
       return CurrentPCForStackX86_64(state);
     default:
       assert("Unknown CPU type!");
       return 0;
   }
 }
 
+#ifdef HAS_PCC_SUPPORT
 bool MinidumpGenerator::WriteStackPPC(breakpad_thread_state_data_t state,
                                       MDMemoryDescriptor *stack_location) {
   ppc_thread_state_t *machine_state =
       reinterpret_cast<ppc_thread_state_t *>(state);
   mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, r1);
   return WriteStackFromStartAddress(start_addr, stack_location);
 }
 
@@ -534,16 +545,18 @@ bool MinidumpGenerator::WriteContextPPC6
   AddGPR(30);
   AddGPR(31);
 #undef AddReg
 #undef AddGPR
 
   return true;
 }
 
+#endif
+
 bool MinidumpGenerator::WriteStackX86(breakpad_thread_state_data_t state,
                                    MDMemoryDescriptor *stack_location) {
   i386_thread_state_t *machine_state =
       reinterpret_cast<i386_thread_state_t *>(state);
 
   mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, esp);
   return WriteStackFromStartAddress(start_addr, stack_location);
 }
@@ -658,22 +671,24 @@ bool MinidumpGenerator::WriteContextX86_
   return true;
 }
 
 bool MinidumpGenerator::GetThreadState(thread_act_t target_thread,
                                        thread_state_t state,
                                        mach_msg_type_number_t *count) {
   thread_state_flavor_t flavor;
   switch (cpu_type_) {
+#ifdef HAS_PPC_SUPPORT
     case CPU_TYPE_POWERPC:
       flavor = PPC_THREAD_STATE;
       break;
     case CPU_TYPE_POWERPC64:
       flavor = PPC_THREAD_STATE64;
       break;
+#endif
     case CPU_TYPE_I386:
       flavor = i386_THREAD_STATE;
       break;
     case CPU_TYPE_X86_64:
       flavor = x86_THREAD_STATE64;
       break;
     default:
       return false;
--- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/minidump_generator.h
+++ b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/minidump_generator.h
@@ -38,16 +38,20 @@
 
 #include "client/minidump_file_writer.h"
 #include "common/memory.h"
 #include "common/mac/macho_utilities.h"
 #include "google_breakpad/common/minidump_format.h"
 
 #include "dynamic_images.h"
 
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7
+  #define HAS_PPC_SUPPORT
+#endif
+
 namespace google_breakpad {
 
 using std::string;
 
 const u_int64_t TOP_OF_THREAD0_STACK_64BIT = 0x00007fff5fbff000LL;
 const u_int32_t TOP_OF_THREAD0_STACK_32BIT = 0xbffff000;
 
 // Use the REGISTER_FROM_THREADSTATE to access a register name from the
@@ -123,26 +127,28 @@ class MinidumpGenerator {
   bool WriteThreadStream(mach_port_t thread_id, MDRawThread *thread);
   bool WriteCVRecord(MDRawModule *module, int cpu_type, 
                      const char *module_path);
   bool WriteModuleStream(unsigned int index, MDRawModule *module);
   size_t CalculateStackSize(mach_vm_address_t start_addr);
   int  FindExecutableModule();
 
   // Per-CPU implementations of these methods
+#ifdef HAS_PPC_SUPPORT
   bool WriteStackPPC(breakpad_thread_state_data_t state,
                      MDMemoryDescriptor *stack_location);
   bool WriteContextPPC(breakpad_thread_state_data_t state,
                        MDLocationDescriptor *register_location);
   u_int64_t CurrentPCForStackPPC(breakpad_thread_state_data_t state);
   bool WriteStackPPC64(breakpad_thread_state_data_t state,
                        MDMemoryDescriptor *stack_location);
   bool WriteContextPPC64(breakpad_thread_state_data_t state,
                        MDLocationDescriptor *register_location);
   u_int64_t CurrentPCForStackPPC64(breakpad_thread_state_data_t state);
+#endif
   bool WriteStackX86(breakpad_thread_state_data_t state,
                        MDMemoryDescriptor *stack_location);
   bool WriteContextX86(breakpad_thread_state_data_t state,
                        MDLocationDescriptor *register_location);
   u_int64_t CurrentPCForStackX86(breakpad_thread_state_data_t state);
   bool WriteStackX86_64(breakpad_thread_state_data_t state,
                         MDMemoryDescriptor *stack_location);
   bool WriteContextX86_64(breakpad_thread_state_data_t state,
--- a/widget/src/windows/nsWindow.cpp
+++ b/widget/src/windows/nsWindow.cpp
@@ -4246,21 +4246,16 @@ nsWindow::IPCWindowProcHandler(UINT& msg
               !wcscmp(szClass, L"Edit") &&
               !IsOurProcessWindow(focusWnd)) {
             break;
           }
         }
         handled = PR_TRUE;
       }
     break;
-    // Wheel events forwarded from the child.
-    case WM_MOUSEWHEEL:
-    case WM_MOUSEHWHEEL:
-    case WM_HSCROLL:
-    case WM_VSCROLL:
     // Plugins taking or losing focus triggering focus app messages.
     case WM_SETFOCUS:
     case WM_KILLFOCUS:
     // Windowed plugins that pass sys key events to defwndproc generate
     // WM_SYSCOMMAND events to the main window.
     case WM_SYSCOMMAND:
     // Windowed plugins that fire context menu selection events to parent
     // windows.
@@ -5118,16 +5113,23 @@ PRBool nsWindow::ProcessMessage(UINT msg
     break;
 
     case WM_HSCROLL:
     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);
+      // Doesn't need to call next wndproc for internal message.
+      return PR_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
     // events once the focus events arrive.
     case WM_ACTIVATE:
       if (mEventCallback) {
@@ -5280,28 +5282,36 @@ PRBool nsWindow::ProcessMessage(UINT msg
                           MOZ_SYSCONTEXT_Y_POS);
         result = PR_TRUE;
       }
     }
     break;
 
   case WM_MOUSEWHEEL:
   case WM_MOUSEHWHEEL:
+    OnMouseWheel(msg, wParam, lParam, aRetValue);
+    // 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 PR_TRUE;
+
+  case MOZ_WM_MOUSEVWHEEL:
+  case MOZ_WM_MOUSEHWHEEL:
     {
+      UINT nativeMessage = 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.
-      if (OnMouseWheel(msg, wParam, lParam, result, aRetValue)) {
-        return result;
-      }
-    }
-    break;
+      OnMouseWheelInternal(nativeMessage, wParam, lParam, aRetValue);
+      // Doesn't need to call next wndproc for internal message.
+      return PR_TRUE;
+    }
 
 #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
   case WM_DWMCOMPOSITIONCHANGED:
     // First, update the compositor state to latest one. All other methods
     // should use same state as here for consistency painting.
     nsUXThemeData::CheckForCompositor(PR_TRUE);
 
     UpdateNonClientMargins();
@@ -6361,59 +6371,44 @@ nsWindow::ResetRemainingWheelDelta()
   sLastMouseWheelWnd = NULL;
 }
 
 static PRInt32 RoundDelta(double aDelta)
 {
   return aDelta >= 0 ? (PRInt32)NS_floor(aDelta) : (PRInt32)NS_ceil(aDelta);
 }
 
-/*
- * OnMouseWheel - mouse wheel event processing. This was originally embedded
- * within the message case block. If returning true result should be returned
- * immediately (no more processing).
+/**
+ * OnMouseWheelInternal - mouse wheel event processing.
+ * aMessage may be WM_MOUSEWHEEL or WM_MOUSEHWHEEL but this is called when
+ * ProcessMessage() handles MOZ_WM_MOUSEVWHEEL or MOZ_WM_MOUSEHWHEEL.
  */
-PRBool
-nsWindow::OnMouseWheel(UINT aMessage, WPARAM aWParam, LPARAM aLParam,
-                       PRBool& aHandled, LRESULT *aRetValue)
+void
+nsWindow::OnMouseWheelInternal(UINT aMessage, WPARAM aWParam, LPARAM aLParam,
+                               LRESULT *aRetValue)
 {
   InitMouseWheelScrollData();
 
   PRBool isVertical = (aMessage == WM_MOUSEWHEEL);
   if ((isVertical && sMouseWheelScrollLines == 0) ||
       (!isVertical && sMouseWheelScrollChars == 0)) {
     // XXX I think that we should dispatch mouse wheel events even if the
     // operation will not scroll because the wheel operation really happened
     // and web application may want to handle the event for non-scroll action.
     ResetRemainingWheelDelta();
     *aRetValue = isVertical ? TRUE : FALSE; // means we don't process it
-    aHandled = PR_FALSE;
-    return PR_FALSE;
-  }
-
-  // The mousewheel event will be dispatched to the toplevel
-  // window.  We need to give it to the child window.
-  PRBool quit;
-  if (!HandleScrollingPlugins(aMessage, aWParam, aLParam,
-                              aHandled, aRetValue, quit)) {
-    ResetRemainingWheelDelta();
-    return quit; // return immediately if it's not our window
- }
+    return;
+  }
 
   PRInt32 nativeDelta = (short)HIWORD(aWParam);
   if (!nativeDelta) {
     *aRetValue = isVertical ? TRUE : FALSE; // means we don't process it
-    aHandled = PR_FALSE;
     ResetRemainingWheelDelta();
-    return PR_FALSE; // We cannot process this message
-  }
-
-  // The event may go to a plug-in which already dispatched this message.
-  // Then, the event can cause deadlock.  We should unlock the sender here.
-  ::ReplyMessage(isVertical ? 0 : TRUE);
+    return; // We cannot process this message
+  }
 
   PRBool isPageScroll =
     ((isVertical && sMouseWheelScrollLines == WHEEL_PAGESCROLL) ||
      (!isVertical && sMouseWheelScrollChars == WHEEL_PAGESCROLL));
 
   // Discard the remaining delta if current wheel message and last one are
   // received by different window or to scroll different direction or
   // different unit scroll.  Furthermore, if the last event was too old.
@@ -6551,27 +6546,27 @@ nsWindow::OnMouseWheel(UINT aMessage, WP
     scrollEvent.delta =
       RoundDelta((double)nativeDeltaForScroll * orienter / deltaPerUnit);
     PRInt32 recomputedNativeDelta =
       (PRInt32)(scrollEvent.delta * orienter * deltaPerUnit);
     sRemainingDeltaForScroll = nativeDeltaForScroll - recomputedNativeDelta;
   }
 
   if (scrollEvent.delta) {
-    aHandled = DispatchWindowEvent(&scrollEvent);
+    DispatchWindowEvent(&scrollEvent);
     if (mOnDestroyCalled) {
       ResetRemainingWheelDelta();
-      return PR_FALSE;
+      return;
     }
   }
 
   // If the query event failed, we cannot send pixel events.
   if (!dispatchPixelScrollEvent) {
     sRemainingDeltaForPixel = 0;
-    return PR_FALSE;
+    return;
   }
 
   nsMouseScrollEvent pixelEvent(PR_TRUE, NS_MOUSE_PIXEL_SCROLL, this);
   InitEvent(pixelEvent);
   pixelEvent.scrollFlags = nsMouseScrollEvent::kAllowSmoothScroll;
   pixelEvent.scrollFlags |= isVertical ?
     nsMouseScrollEvent::kIsVertical : nsMouseScrollEvent::kIsHorizontal;
   if (actualScrollAction == nsQueryContentEvent::SCROLL_ACTION_PAGE) {
@@ -6591,19 +6586,19 @@ nsWindow::OnMouseWheel(UINT aMessage, WP
   double deltaPerPixel =
     (double)WHEEL_DELTA / computedScrollAmount / pixelsPerUnit;
   pixelEvent.delta =
     RoundDelta((double)nativeDeltaForPixel * orienterForPixel / deltaPerPixel);
   PRInt32 recomputedNativeDelta =
     (PRInt32)(pixelEvent.delta * orienterForPixel * deltaPerPixel);
   sRemainingDeltaForPixel = nativeDeltaForPixel - recomputedNativeDelta;
   if (pixelEvent.delta != 0) {
-    aHandled = DispatchWindowEvent(&pixelEvent);
-  }
-  return PR_FALSE;
+    DispatchWindowEvent(&pixelEvent);
+  }
+  return;
 }
 
 static PRBool
 StringCaseInsensitiveEquals(const PRUnichar* aChars1, const PRUint32 aNumChars1,
                             const PRUnichar* aChars2, const PRUint32 aNumChars2)
 {
   if (aNumChars1 != aNumChars2)
     return PR_FALSE;
@@ -7577,38 +7572,69 @@ static PRBool IsElantechHelperWindow(HWN
       }
     }
     ::CloseHandle(hProcess);
   }
 
   return result;
 }
 
-// Scrolling helper function for handling plugins.  
-// Return value indicates whether the calling function should handle this
-// aHandled indicates whether this was handled at all
-// aQuitProcessing tells whether or not to continue processing the message
-PRBool nsWindow::HandleScrollingPlugins(UINT aMsg, WPARAM aWParam,
-                                        LPARAM aLParam, PRBool& aHandled,
-                                        LRESULT* aRetValue,
-                                        PRBool& aQuitProcessing)
-{
-  // The scroll event will be dispatched to the toplevel
-  // window.  We need to give it to the child window
-  aQuitProcessing = PR_FALSE; // default is to not stop processing
+// 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,
+                       LRESULT *aRetValue)
+{
+  *aRetValue = (aMsg != WM_MOUSEHWHEEL) ? TRUE : FALSE;
+
   POINT point;
   DWORD dwPoints = ::GetMessagePos();
   point.x = GET_X_LPARAM(dwPoints);
   point.y = GET_Y_LPARAM(dwPoints);
 
-  static PRBool sIsProcessing = PR_FALSE;
-  if (sIsProcessing) {
-    return PR_TRUE;  // the caller should handle this.
-  }
-
   static PRBool sMayBeUsingLogitechMouse = PR_FALSE;
   if (aMsg == WM_MOUSEHWHEEL) {
     // Logitech (Logicool) mouse driver (confirmed with 4.82.11 and MX-1100)
     // always sets 0 to the lParam of WM_MOUSEHWHEEL.  The driver SENDs one
     // message at first time, this time, ::GetMessagePos works fine.
     // Then, we will return 0 (0 means we process it) to the message. Then, the
     // driver will POST the same messages continuously during the wheel tilted.
     // But ::GetMessagePos API always returns (0, 0), even if the actual mouse
@@ -7625,167 +7651,111 @@ PRBool nsWindow::HandleScrollingPlugins(
     // If the WM_MOUSEHWHEEL comes from Logitech's mouse driver, and the
     // ::GetMessagePos isn't correct, probably, we should use ::GetCursorPos
     // instead.
     if (sMayBeUsingLogitechMouse && aLParam == 0 && dwPoints == 0) {
       ::GetCursorPos(&point);
     }
   }
 
-  HWND destWnd = ::WindowFromPoint(point);
-  // Since we receive scroll events for as long as
-  // we are focused, it's entirely possible that there
-  // is another app's window or no window under the
-  // pointer.
-
-  if (sUseElantechPinchHack && IsElantechHelperWindow(destWnd)) {
+  HWND underCursorWnd = ::WindowFromPoint(point);
+  if (!underCursorWnd) {
+    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.
-    destWnd = FindOurWindowAtPoint(point);
-  }
-
-  if (!destWnd) {
-    // No window is under the pointer
-    return PR_FALSE; // break, but continue processing
-  }
-
-  nsWindow* destWindow;
-
-  // We don't handle the message if the found window belongs to another
-  // process's top window.  If it belongs window, that is a plug-in's window.
-  // Then, we need to send the message to the plug-in window.
-  if (!IsOurProcessWindow(destWnd)) {
-    HWND ourPluginWnd = FindOurProcessWindow(destWnd);
-    if (!ourPluginWnd) {
-      // Somebody elses window
-      return PR_FALSE; // break, but continue processing
-    }
-    destWindow = GetNSWindowPtr(ourPluginWnd);
-  } else {
-    destWindow = GetNSWindowPtr(destWnd);
-  }
-
-  if (destWindow == this && mWindowType == eWindowType_plugin) {
-    // If this is plug-in window, the message came from the plug-in window.
-    // Then, the message should be processed on the parent window.
-    destWindow = static_cast<nsWindow*>(GetParent());
-    NS_ENSURE_TRUE(destWindow, PR_FALSE); // break, but continue processing
-    destWnd = destWindow->mWnd;
-    NS_ENSURE_TRUE(destWnd, PR_FALSE); // break, but continue processing
-  }
-
-  if (!destWindow || destWindow->mWindowType == eWindowType_plugin) {
-    // Some other app, or a plugin window.
-    // Windows directs scrolling messages to the focused window.
-    // However, Mozilla does not like plugins having focus, so a
-    // Mozilla window (ie, the plugin's parent (us!) has focus.)
-    // Therefore, plugins etc _should_ get first grab at the
-    // message, but this focus vaguary means the plugin misses
-    // out. If the window is a child of ours, forward it on.
-    // Determine if a child by walking the parent list until
-    // we find a parent matching our wndproc.
-    HWND parentWnd = ::GetParent(destWnd);
-    while (parentWnd) {
-      nsWindow* parentWindow = GetNSWindowPtr(parentWnd);
-      if (parentWindow) {
-        // We have a child window - quite possibly a plugin window.
-        // However, not all plugins are created equal - some will handle this 
-        // message themselves, some will forward directly back to us, while 
-        // others will call DefWndProc, which itself still forwards back to us.
-        // So if we have sent it once, we need to handle it ourself.
-
-        // XXX The message shouldn't come from the plugin window at here.
-        // But the message might come from it due to some bugs.  If it happens,
-        // SendMessage causes deadlock.  For safety, we should unlock the
-        // sender here.
-        ::ReplyMessage(aMsg == WM_MOUSEHWHEEL ? TRUE : 0);
-
-        // First time we have seen this message.
-        // Call the child - either it will consume it, or
-        // it will wind it's way back to us,triggering the destWnd case above
-        // either way,when the call returns,we are all done with the message,
-        sIsProcessing = PR_TRUE;
-        ::SendMessageW(destWnd, aMsg, aWParam, aLParam);
-        sIsProcessing = PR_FALSE;
-        aHandled = PR_TRUE;
-        aQuitProcessing = PR_TRUE;
-        return PR_FALSE; // break, and stop processing
+    underCursorWnd = 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 (!destWindow) {
+      NS_WARNING("We're not sure what cause this is.");
+      HWND wnd = ::GetParent(underCursorWnd);
+      for (; wnd; wnd = ::GetParent(wnd)) {
+        destWindow = GetNSWindowPtr(wnd);
+        if (destWindow) {
+          break;
+        }
+      }
+      if (!wnd) {
+        return;
       }
-      parentWnd = ::GetParent(parentWnd);
-    } // while parentWnd
-  }
-  if (destWnd == nsnull)
-    return PR_FALSE;
-  if (destWnd != mWnd) {
-    if (destWindow) {
-      sIsProcessing = PR_TRUE;
-      aHandled = destWindow->ProcessMessage(aMsg, aWParam, aLParam, aRetValue);
-      sIsProcessing = PR_FALSE;
-      aQuitProcessing = PR_TRUE;
-      return PR_FALSE; // break, and stop processing
-    }
-  #ifdef DEBUG
-    else
-      printf("WARNING: couldn't get child window for SCROLL event\n");
-  #endif
-  }
-  return PR_TRUE;  // caller should handle this
-}
-
-PRBool nsWindow::OnScroll(UINT aMsg, WPARAM aWParam, LPARAM aLParam)
+    }
+
+    NS_ASSERTION(destWindow, "destWindow must not be NULL");
+    // If the found window is our plugin window, it means that the message
+    // has been handled by the plugin but not consumed.  We should handle the
+    // message on its parent window.
+    if (destWindow->mWindowType == eWindowType_plugin) {
+      destWindow = destWindow->GetParentWindow(PR_FALSE);
+      NS_ENSURE_TRUE(destWindow, );
+    }
+    UINT internalMessage = GetInternalMessage(aMsg);
+    destWindow->ProcessMessage(internalMessage, aWParam, aLParam, aRetValue);
+    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);
+  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.
+  if (mWindowType == eWindowType_plugin && pluginWnd == mWnd) {
+    nsWindow* destWindow = GetParentWindow(PR_FALSE);
+    NS_ENSURE_TRUE(destWindow, );
+    UINT internalMessage = GetInternalMessage(aMsg);
+    destWindow->ProcessMessage(internalMessage, aWParam, aLParam, aRetValue);
+    return;
+  }
+
+  // If the window is a part of plugin, we should post the message to it.
+  ::PostMessage(underCursorWnd, aMsg, aWParam, aLParam);
+}
+
+/**
+ * OnScroll() is called when ProcessMessage() handles WM_VSCROLL or WM_HSCROLL.
+ * aMsg may be WM_VSCROLL or WM_HSCROLL.
+ */
+PRBool
+nsWindow::OnScroll(UINT aMsg, WPARAM aWParam, LPARAM aLParam)
 {
   static PRInt8 sMouseWheelEmulation = -1;
   if (sMouseWheelEmulation < 0) {
     PRBool emulate =
       Preferences::GetBool("mousewheel.emulate_at_wm_scroll", PR_FALSE);
     sMouseWheelEmulation = PRInt8(emulate);
   }
 
   if (aLParam || sMouseWheelEmulation) {
     // Scroll message generated by Thinkpad Trackpoint Driver or similar
     // Treat as a mousewheel message and scroll appropriately
-    PRBool quit, result;
     LRESULT retVal;
-
-    if (!HandleScrollingPlugins(aMsg, aWParam, aLParam, result, &retVal, quit))
-      return quit;  // Return if it's not our message or has been dispatched
-
-    nsMouseScrollEvent scrollevent(PR_TRUE, NS_MOUSE_SCROLL, this);
-    scrollevent.scrollFlags = (aMsg == WM_VSCROLL) 
-                              ? nsMouseScrollEvent::kIsVertical
-                              : nsMouseScrollEvent::kIsHorizontal;
-    switch (LOWORD(aWParam))
-    {
-      case SB_PAGEDOWN:
-        scrollevent.scrollFlags |= nsMouseScrollEvent::kIsFullPage;
-      case SB_LINEDOWN:
-        scrollevent.delta = 1;
-        break;
-      case SB_PAGEUP:
-        scrollevent.scrollFlags |= nsMouseScrollEvent::kIsFullPage;
-      case SB_LINEUP:
-        scrollevent.delta = -1;
-        break;
-      default:
-        return PR_FALSE;
-    }
-    // The event may go to a plug-in which already dispatched this message.
-    // Then, the event can cause deadlock.  We should unlock the sender here.
-    ::ReplyMessage(0);
-    scrollevent.isShift   = IS_VK_DOWN(NS_VK_SHIFT);
-    scrollevent.isControl = IS_VK_DOWN(NS_VK_CONTROL);
-    scrollevent.isMeta    = PR_FALSE;
-    scrollevent.isAlt     = IS_VK_DOWN(NS_VK_ALT);
-    InitEvent(scrollevent);
-    if (nsnull != mEventCallback)
-    {
-      DispatchWindowEvent(&scrollevent);
-    }
+    OnMouseWheel(aMsg, aWParam, aLParam, &retVal);
+    // Always consume the scroll message if we try to emulate mouse wheel
+    // action.
     return PR_TRUE;
   }
 
   // Scroll message generated by external application
   nsContentCommandEvent command(PR_TRUE, NS_CONTENT_COMMAND_SCROLL, this);
 
   command.mScroll.mIsHorizontal = (aMsg == WM_HSCROLL);
 
@@ -7813,20 +7783,59 @@ PRBool nsWindow::OnScroll(UINT aMsg, WPA
       break;
     case SB_BOTTOM:   // SB_RIGHT
       command.mScroll.mUnit = nsContentCommandEvent::eCmdScrollUnit_Whole;
       command.mScroll.mAmount = 1;
       break;
     default:
       return PR_FALSE;
   }
+  // XXX If this is a plugin window, we should dispatch the event from
+  //     parent window.
   DispatchWindowEvent(&command);
   return PR_TRUE;
 }
 
+/**
+ * OnScrollInternal() is called when ProcessMessage() handles MOZ_WM_VSCROLL or
+ * MOZ_WM_HSCROLL but aMsg may be WM_VSCROLL or WM_HSCROLL.
+ * These internal messages used only when OnScroll() tries to emulate mouse
+ * wheel action for the WM_VSCROLL or WM_HSCROLL message.
+ */
+void
+nsWindow::OnScrollInternal(UINT aMsg, WPARAM aWParam, LPARAM aLParam)
+{
+  nsMouseScrollEvent scrollevent(PR_TRUE, NS_MOUSE_SCROLL, this);
+  scrollevent.scrollFlags = (aMsg == WM_VSCROLL) 
+                            ? nsMouseScrollEvent::kIsVertical
+                            : nsMouseScrollEvent::kIsHorizontal;
+  switch (LOWORD(aWParam)) {
+    case SB_PAGEDOWN:
+      scrollevent.scrollFlags |= nsMouseScrollEvent::kIsFullPage;
+    case SB_LINEDOWN:
+      scrollevent.delta = 1;
+      break;
+    case SB_PAGEUP:
+      scrollevent.scrollFlags |= nsMouseScrollEvent::kIsFullPage;
+    case SB_LINEUP:
+      scrollevent.delta = -1;
+      break;
+    default:
+      return;
+  }
+  scrollevent.isShift   = IS_VK_DOWN(NS_VK_SHIFT);
+  scrollevent.isControl = IS_VK_DOWN(NS_VK_CONTROL);
+  scrollevent.isMeta    = PR_FALSE;
+  scrollevent.isAlt     = IS_VK_DOWN(NS_VK_ALT);
+  InitEvent(scrollevent);
+  if (mEventCallback) {
+    DispatchWindowEvent(&scrollevent);
+  }
+}
+
 // Can be overriden. Controls auto-erase of background.
 PRBool nsWindow::AutoErase(HDC dc)
 {
   return PR_FALSE;
 }
 
 void
 nsWindow::AllowD3D9Callback(nsWindow *aWindow)
@@ -8384,17 +8393,17 @@ 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 (wParam) {
+    switch (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);
@@ -8585,16 +8594,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);
     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 ||
--- a/widget/src/windows/nsWindow.h
+++ b/widget/src/windows/nsWindow.h
@@ -370,21 +370,16 @@ protected:
   LRESULT                 ProcessKeyUpMessage(const MSG &aMsg,
                                               PRBool *aEventDispatched);
   LRESULT                 ProcessKeyDownMessage(const MSG &aMsg,
                                                 PRBool *aEventDispatched);
   static PRBool           EventIsInsideWindow(UINT Msg, nsWindow* aWindow);
   // Convert nsEventStatus value to a windows boolean
   static PRBool           ConvertStatus(nsEventStatus aStatus);
   static void             PostSleepWakeNotification(const char* aNotification);
-  PRBool                  HandleScrollingPlugins(UINT aMsg, WPARAM aWParam, 
-                                                 LPARAM aLParam,
-                                                 PRBool& aResult,
-                                                 LRESULT* aRetValue,
-                                                 PRBool& aQuitProcessing);
   PRInt32                 ClientMarginHitTestPoint(PRInt32 mx, PRInt32 my);
   static WORD             GetScanCode(LPARAM aLParam)
   {
     return (aLParam >> 16) & 0xFF;
   }
   static PRBool           IsExtendedScanCode(LPARAM aLParam)
   {
     return (aLParam & 0x1000000) != 0;
@@ -412,28 +407,34 @@ protected:
   LRESULT                 OnKeyUp(const MSG &aMsg,
                                   nsModifierKeyState &aModKeyState,
                                   PRBool *aEventDispatched);
   LRESULT                 OnCharRaw(UINT charCode, UINT aScanCode,
                                     nsModifierKeyState &aModKeyState,
                                     PRUint32 aFlags = 0,
                                     const MSG *aMsg = nsnull,
                                     PRBool *aEventDispatched = nsnull);
-  virtual PRBool          OnScroll(UINT aMsg, WPARAM aWParam, LPARAM aLParam);
+  PRBool                  OnScroll(UINT aMsg, WPARAM aWParam, LPARAM aLParam);
+  void                    OnScrollInternal(UINT aMsg, WPARAM aWParam,
+                                           LPARAM aLParam);
   PRBool                  OnGesture(WPARAM wParam, LPARAM lParam);
 #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_WIN7
   PRBool                  OnTouch(WPARAM wParam, LPARAM lParam);
 #endif
   PRBool                  OnHotKey(WPARAM wParam, LPARAM lParam);
   BOOL                    OnInputLangChange(HKL aHKL);
   PRBool                  OnPaint(HDC aDC, PRUint32 aNestingLevel);
   void                    OnWindowPosChanged(WINDOWPOS *wp, PRBool& aResult);
-  PRBool                  OnMouseWheel(UINT aMessage, WPARAM aWParam,
-                                       LPARAM aLParam, PRBool& aHandled,
-                                       LRESULT *aRetValue);
+  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);
 
   /**
    * Function that registers when the user has been active (used for detecting
    * when the user is idle).
    */
   void                    UserActivity();
 
--- a/widget/src/windows/nsWindowDefs.h
+++ b/widget/src/windows/nsWindowDefs.h
@@ -53,16 +53,22 @@
  * 
  **************************************************************/
 
 // A magic APP message that can be sent to quit, sort of like a QUERYENDSESSION/ENDSESSION,
 // but without the query.
 #define MOZ_WM_APP_QUIT                   (WM_APP+0x0300)
 // Used as a "tracer" event to probe event loop latency.
 #define MOZ_WM_TRACE                      (WM_APP+0x0301)
+// Our internal message for WM_MOUSEWHEEL, WM_MOUSEHWHEEL, WM_VSCROLL and
+// WM_HSCROLL
+#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)
 
 // GetWindowsVersion constants
 #define WIN2K_VERSION                     0x500
 #define WINXP_VERSION                     0x501
 #define WIN2K3_VERSION                    0x502
 #define VISTA_VERSION                     0x600
 #define WIN7_VERSION                      0x601
 
--- a/xpcom/typelib/xpt/tools/xpt.py
+++ b/xpcom/typelib/xpt/tools/xpt.py
@@ -1113,57 +1113,60 @@ class Typelib(object):
             for m in i.methods:
                 for n, p in enumerate(m.params):
                     if isinstance(p, InterfaceType) and \
                         p.iface not in self.interfaces:
                         raise DataError, "Interface method %s::%s, parameter %d references interface %s not present in typelib!" % (i.name, m.name, n, p.iface.name)
                 if isinstance(m.result, InterfaceType) and m.result.iface not in self.interfaces:
                     raise DataError, "Interface method %s::%s, result references interface %s not present in typelib!" % (i.name, m.name, m.result.iface.name)
 
+    def writefd(self, fd):
+        # write out space for a header + one empty annotation,
+        # padded to 4-byte alignment.
+        headersize = (Typelib._header.size + 1)
+        if headersize % 4:
+            headersize += 4 - headersize % 4
+        fd.write("\x00" * headersize)
+        # save this offset, it's the interface directory offset.
+        interface_directory_offset = fd.tell()
+        # write out space for an interface directory
+        fd.write("\x00" * Interface._direntry.size * len(self.interfaces))
+        # save this offset, it's the data pool offset.
+        data_pool_offset = fd.tell()
+        # write out all the interface descriptors to the data pool
+        for i in self.interfaces:
+            i.write_names(fd, data_pool_offset)
+            i.write(self, fd, data_pool_offset)
+        # now, seek back and write the header
+        file_len = fd.tell()
+        fd.seek(0)
+        fd.write(Typelib._header.pack(XPT_MAGIC,
+                                      TYPELIB_VERSION[0],
+                                      TYPELIB_VERSION[1],
+                                      len(self.interfaces),
+                                      file_len,
+                                      interface_directory_offset,
+                                      data_pool_offset))
+        # write an empty annotation
+        fd.write(struct.pack(">B", 0x80))
+        # now write the interface directory
+        #XXX: bug-compatible with existing xpt lib, put it one byte
+        # ahead of where it's supposed to be.
+        fd.seek(interface_directory_offset - 1)
+        for i in self.interfaces:
+            i.write_directory_entry(fd)
+
     def write(self, filename):
         """
         Write the contents of this typelib to the file named |filename|.
 
         """
         self._sanityCheck()
         with open(filename, "wb") as f:
-            # write out space for a header + one empty annotation,
-            # padded to 4-byte alignment.
-            headersize = (Typelib._header.size + 1)
-            if headersize % 4:
-                headersize += 4 - headersize % 4
-            f.write("\x00" * headersize)
-            # save this offset, it's the interface directory offset.
-            interface_directory_offset = f.tell()
-            # write out space for an interface directory
-            f.write("\x00" * Interface._direntry.size * len(self.interfaces))
-            # save this offset, it's the data pool offset.
-            data_pool_offset = f.tell()
-            # write out all the interface descriptors to the data pool
-            for i in self.interfaces:
-                i.write_names(f, data_pool_offset)
-                i.write(self, f, data_pool_offset)
-            # now, seek back and write the header
-            file_len = f.tell()
-            f.seek(0)
-            f.write(Typelib._header.pack(XPT_MAGIC,
-                                         TYPELIB_VERSION[0],
-                                         TYPELIB_VERSION[1],
-                                         len(self.interfaces),
-                                         file_len,
-                                         interface_directory_offset,
-                                         data_pool_offset))
-            # write an empty annotation
-            f.write(struct.pack(">B", 0x80))
-            # now write the interface directory
-            #XXX: bug-compatible with existing xpt lib, put it one byte
-            # ahead of where it's supposed to be.
-            f.seek(interface_directory_offset - 1)
-            for i in self.interfaces:
-                i.write_directory_entry(f)
+            self.writefd(f)
 
     def merge(self, other, sanitycheck=True):
         """
         Merge the contents of Typelib |other| into this typelib.
         If |sanitycheck| is False, don't sort the interface table
         after merging.
 
         """