Bug 1155505 - Part 1. Move WriteBitmap to WinUtils. r=jmathies
☠☠ backed out by 10b62fac5269 ☠ ☠
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Fri, 23 Mar 2018 16:41:58 -0400
changeset 495103 82e129f7545e704a77b3a8530124670e409b747f
parent 495102 8d9d8cde6d8bfa1c13a06b3d73f987bc7267ea0f
child 495104 5400ec20792c04d86c825e7debdcddd6f1e3b5f5
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjmathies
bugs1155505
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1155505 - Part 1. Move WriteBitmap to WinUtils. r=jmathies WriteBitmap will be used for Toast implementation, so it should be moved to WinUtils. Differential Revision: https://phabricator.services.mozilla.com/D3002
browser/components/shell/nsWindowsShellService.cpp
widget/windows/WinUtils.cpp
widget/windows/WinUtils.h
--- a/browser/components/shell/nsWindowsShellService.cpp
+++ b/browser/components/shell/nsWindowsShellService.cpp
@@ -4,21 +4,19 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsWindowsShellService.h"
 
 #include "BinaryPath.h"
 #include "city.h"
 #include "imgIContainer.h"
 #include "imgIRequest.h"
-#include "mozilla/gfx/2D.h"
 #include "mozilla/RefPtr.h"
 #include "nsIContent.h"
 #include "nsIImageLoadingContent.h"
-#include "nsIOutputStream.h"
 #include "nsIPrefService.h"
 #include "nsIPrefLocalizedString.h"
 #include "nsIServiceManager.h"
 #include "nsIStringBundle.h"
 #include "nsNetUtil.h"
 #include "nsServiceManagerUtils.h"
 #include "nsShellService.h"
 #include "nsIProcess.h"
@@ -41,16 +39,17 @@
 #undef _WIN32_WINNT
 #endif
 #define _WIN32_WINNT 0x0600
 #define INITGUID
 #undef NTDDI_VERSION
 #define NTDDI_VERSION NTDDI_WIN8
 // Needed for access to IApplicationActivationManager
 #include <shlobj.h>
+#include "WinUtils.h"
 
 #include <mbstring.h>
 #include <shlwapi.h>
 
 #include <lm.h>
 #undef ACCESS_READ
 
 #ifndef MAX_BUF
@@ -62,17 +61,17 @@
 
 #define REG_FAILED(val) \
   (val != ERROR_SUCCESS)
 
 #define APP_REG_NAME_BASE L"Firefox-"
 
 using mozilla::IsWin8OrLater;
 using namespace mozilla;
-using namespace mozilla::gfx;
+using namespace mozilla::widget;
 
 NS_IMPL_ISUPPORTS(nsWindowsShellService, nsIShellService)
 
 static nsresult
 OpenKeyForReading(HKEY aKeyRoot, const nsAString& aKeyName, HKEY* aKey)
 {
   const nsString &flatName = PromiseFlatString(aKeyName);
 
@@ -480,105 +479,16 @@ nsWindowsShellService::SetDefaultBrowser
     // Reset the number of times the dialog should be shown
     // before it is silenced.
     (void) prefs->SetIntPref(PREF_DEFAULTBROWSERCHECKCOUNT, 0);
   }
 
   return rv;
 }
 
-static nsresult
-WriteBitmap(nsIFile* aFile, imgIContainer* aImage)
-{
-  nsresult rv;
-
-  RefPtr<SourceSurface> surface =
-    aImage->GetFrame(imgIContainer::FRAME_FIRST,
-                     imgIContainer::FLAG_SYNC_DECODE);
-  NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE);
-
-  // For either of the following formats we want to set the biBitCount member
-  // of the BITMAPINFOHEADER struct to 32, below. For that value the bitmap
-  // format defines that the A8/X8 WORDs in the bitmap byte stream be ignored
-  // for the BI_RGB value we use for the biCompression member.
-  MOZ_ASSERT(surface->GetFormat() == SurfaceFormat::B8G8R8A8 ||
-             surface->GetFormat() == SurfaceFormat::B8G8R8X8);
-
-  RefPtr<DataSourceSurface> dataSurface = surface->GetDataSurface();
-  NS_ENSURE_TRUE(dataSurface, NS_ERROR_FAILURE);
-
-  int32_t width = dataSurface->GetSize().width;
-  int32_t height = dataSurface->GetSize().height;
-  int32_t bytesPerPixel = 4 * sizeof(uint8_t);
-  uint32_t bytesPerRow = bytesPerPixel * width;
-
-  // initialize these bitmap structs which we will later
-  // serialize directly to the head of the bitmap file
-  BITMAPINFOHEADER bmi;
-  bmi.biSize = sizeof(BITMAPINFOHEADER);
-  bmi.biWidth = width;
-  bmi.biHeight = height;
-  bmi.biPlanes = 1;
-  bmi.biBitCount = (WORD)bytesPerPixel*8;
-  bmi.biCompression = BI_RGB;
-  bmi.biSizeImage = bytesPerRow * height;
-  bmi.biXPelsPerMeter = 0;
-  bmi.biYPelsPerMeter = 0;
-  bmi.biClrUsed = 0;
-  bmi.biClrImportant = 0;
-
-  BITMAPFILEHEADER bf;
-  bf.bfType = 0x4D42; // 'BM'
-  bf.bfReserved1 = 0;
-  bf.bfReserved2 = 0;
-  bf.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
-  bf.bfSize = bf.bfOffBits + bmi.biSizeImage;
-
-  // get a file output stream
-  nsCOMPtr<nsIOutputStream> stream;
-  rv = NS_NewLocalFileOutputStream(getter_AddRefs(stream), aFile);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  DataSourceSurface::MappedSurface map;
-  if (!dataSurface->Map(DataSourceSurface::MapType::READ, &map)) {
-    return NS_ERROR_FAILURE;
-  }
-
-  // write the bitmap headers and rgb pixel data to the file
-  rv = NS_ERROR_FAILURE;
-  if (stream) {
-    uint32_t written;
-    stream->Write((const char*)&bf, sizeof(BITMAPFILEHEADER), &written);
-    if (written == sizeof(BITMAPFILEHEADER)) {
-      stream->Write((const char*)&bmi, sizeof(BITMAPINFOHEADER), &written);
-      if (written == sizeof(BITMAPINFOHEADER)) {
-        // write out the image data backwards because the desktop won't
-        // show bitmaps with negative heights for top-to-bottom
-        uint32_t i = map.mStride * height;
-        do {
-          i -= map.mStride;
-          stream->Write(((const char*)map.mData) + i, bytesPerRow, &written);
-          if (written == bytesPerRow) {
-            rv = NS_OK;
-          } else {
-            rv = NS_ERROR_FAILURE;
-            break;
-          }
-        } while (i != 0);
-      }
-    }
-
-    stream->Close();
-  }
-
-  dataSurface->Unmap();
-
-  return rv;
-}
-
 NS_IMETHODIMP
 nsWindowsShellService::SetDesktopBackground(dom::Element* aElement,
                                             int32_t aPosition,
                                             const nsACString& aImageName)
 {
   if (!aElement || !aElement->IsHTMLElement(nsGkAtoms::img)) {
     // XXX write background loading stuff!
     return NS_ERROR_NOT_AVAILABLE;
@@ -628,17 +538,17 @@ nsWindowsShellService::SetDesktopBackgro
   rv = file->Append(fileLeafName);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoString path;
   rv = file->GetPath(path);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // write the bitmap to a file in the profile directory
-  rv = WriteBitmap(file, container);
+  rv = WinUtils::WriteBitmap(file, container);
 
   // if the file was written successfully, set it as the system wallpaper
   if (NS_SUCCEEDED(rv)) {
     nsCOMPtr<nsIWindowsRegKey> regKey =
       do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv);
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = regKey->Create(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER,
--- a/widget/windows/WinUtils.cpp
+++ b/widget/windows/WinUtils.cpp
@@ -1785,16 +1785,113 @@ WinUtils::SetupKeyModifiersSequence(nsTA
       aArray->AppendElement(
                 KeyPair(VK_CONTROL, VK_LCONTROL, ScanCode::eControlLeft));
       aArray->AppendElement(
                 KeyPair(VK_MENU, VK_RMENU, ScanCode::eAltRight));
     }
   }
 }
 
+/* static */
+nsresult
+WinUtils::WriteBitmap(nsIFile* aFile, imgIContainer* aImage)
+{
+  RefPtr<SourceSurface> surface =
+    aImage->GetFrame(imgIContainer::FRAME_FIRST,
+                     imgIContainer::FLAG_SYNC_DECODE);
+  NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE);
+
+  return WriteBitmap(aFile, surface);
+}
+
+/* static */
+nsresult
+WinUtils::WriteBitmap(nsIFile* aFile, SourceSurface* surface)
+{
+  nsresult rv;
+
+  // For either of the following formats we want to set the biBitCount member
+  // of the BITMAPINFOHEADER struct to 32, below. For that value the bitmap
+  // format defines that the A8/X8 WORDs in the bitmap byte stream be ignored
+  // for the BI_RGB value we use for the biCompression member.
+  MOZ_ASSERT(surface->GetFormat() == SurfaceFormat::B8G8R8A8 ||
+             surface->GetFormat() == SurfaceFormat::B8G8R8X8);
+
+  RefPtr<DataSourceSurface> dataSurface = surface->GetDataSurface();
+  NS_ENSURE_TRUE(dataSurface, NS_ERROR_FAILURE);
+
+  int32_t width = dataSurface->GetSize().width;
+  int32_t height = dataSurface->GetSize().height;
+  int32_t bytesPerPixel = 4 * sizeof(uint8_t);
+  uint32_t bytesPerRow = bytesPerPixel * width;
+
+  // initialize these bitmap structs which we will later
+  // serialize directly to the head of the bitmap file
+  BITMAPINFOHEADER bmi;
+  bmi.biSize = sizeof(BITMAPINFOHEADER);
+  bmi.biWidth = width;
+  bmi.biHeight = height;
+  bmi.biPlanes = 1;
+  bmi.biBitCount = (WORD)bytesPerPixel*8;
+  bmi.biCompression = BI_RGB;
+  bmi.biSizeImage = bytesPerRow * height;
+  bmi.biXPelsPerMeter = 0;
+  bmi.biYPelsPerMeter = 0;
+  bmi.biClrUsed = 0;
+  bmi.biClrImportant = 0;
+
+  BITMAPFILEHEADER bf;
+  bf.bfType = 0x4D42; // 'BM'
+  bf.bfReserved1 = 0;
+  bf.bfReserved2 = 0;
+  bf.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
+  bf.bfSize = bf.bfOffBits + bmi.biSizeImage;
+
+  // get a file output stream
+  nsCOMPtr<nsIOutputStream> stream;
+  rv = NS_NewLocalFileOutputStream(getter_AddRefs(stream), aFile);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  DataSourceSurface::MappedSurface map;
+  if (!dataSurface->Map(DataSourceSurface::MapType::READ, &map)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  // write the bitmap headers and rgb pixel data to the file
+  rv = NS_ERROR_FAILURE;
+  if (stream) {
+    uint32_t written;
+    stream->Write((const char*)&bf, sizeof(BITMAPFILEHEADER), &written);
+    if (written == sizeof(BITMAPFILEHEADER)) {
+      stream->Write((const char*)&bmi, sizeof(BITMAPINFOHEADER), &written);
+      if (written == sizeof(BITMAPINFOHEADER)) {
+        // write out the image data backwards because the desktop won't
+        // show bitmaps with negative heights for top-to-bottom
+        uint32_t i = map.mStride * height;
+        do {
+          i -= map.mStride;
+          stream->Write(((const char*)map.mData) + i, bytesPerRow, &written);
+          if (written == bytesPerRow) {
+            rv = NS_OK;
+          } else {
+            rv = NS_ERROR_FAILURE;
+            break;
+          }
+        } while (i != 0);
+      }
+    }
+
+    stream->Close();
+  }
+
+  dataSurface->Unmap();
+
+  return rv;
+}
+
 // This is in use here and in dom/events/TouchEvent.cpp
 /* static */
 uint32_t
 WinUtils::IsTouchDeviceSupportPresent()
 {
   int32_t touchCapabilities = ::GetSystemMetrics(SM_DIGITIZER);
   return (touchCapabilities & NID_READY) &&
          (touchCapabilities & (NID_EXTERNAL_TOUCH | NID_INTEGRATED_TOUCH));
--- a/widget/windows/WinUtils.h
+++ b/widget/windows/WinUtils.h
@@ -501,16 +501,21 @@ public:
 
   /**
    * Returns true if executable's path is on a network drive.
    */
   static bool RunningFromANetworkDrive();
 
   static void Initialize();
 
+  static nsresult WriteBitmap(nsIFile* aFile, mozilla::gfx::SourceSurface* surface);
+  // This function is a helper, but it cannot be called from the main thread.
+  // Use the one above!
+  static nsresult WriteBitmap(nsIFile* aFile, imgIContainer* aImage);
+
   /**
    * This function normalizes the input path, converts short filenames to long
    * filenames, and substitutes environment variables for system paths.
    * The resulting output string length is guaranteed to be <= MAX_PATH.
    */
   static bool SanitizePath(const wchar_t* aInputPath, nsAString& aOutput);
 
   /**