diff -urN firefox-58.0-orig/browser/components/shell/nsKDEShellService.cpp firefox-58.0-patched/browser/components/shell/nsKDEShellService.cpp --- firefox-58.0-orig/browser/components/shell/nsKDEShellService.cpp 2018-01-24 21:57:22.555032884 +1000 +++ firefox-58.0-patched/browser/components/shell/nsKDEShellService.cpp 2018-01-24 22:12:00.541009839 +1000 @@ -17,6 +17,22 @@ #include "nsIMutableArray.h" #include "nsISupportsPrimitives.h" #include "nsArrayUtils.h" +#include "nsIImageLoadingContent.h" +#include "imgIContainer.h" +#include "imgIRequest.h" +#include "nsIStringBundle.h" +#include "mozilla/dom/Element.h" +#include "prenv.h" + +#include +#include +#include +#include +#if defined(MOZ_WIDGET_GTK) +#include "nsIImageToPixbuf.h" +#endif +#include +#include using namespace mozilla; @@ -28,6 +44,28 @@ return NS_OK; } +static nsresult +WriteImage(const nsCString& aPath, imgIContainer* aImage) +{ +#if !defined(MOZ_WIDGET_GTK) + return NS_ERROR_NOT_AVAILABLE; +#else + nsCOMPtr imgToPixbuf = + do_GetService("@mozilla.org/widget/image-to-gdk-pixbuf;1"); + if (!imgToPixbuf) + return NS_ERROR_NOT_AVAILABLE; + + GdkPixbuf* pixbuf = imgToPixbuf->ConvertImageToPixbuf(aImage); + if (!pixbuf) + return NS_ERROR_NOT_AVAILABLE; + + gboolean res = gdk_pixbuf_save(pixbuf, aPath.get(), "png", nullptr, nullptr); + + g_object_unref(pixbuf); + return res ? NS_OK : NS_ERROR_FAILURE; +#endif +} + NS_IMPL_ISUPPORTS(nsKDEShellService, nsIGNOMEShellService, nsIShellService) NS_IMETHODIMP @@ -89,19 +127,82 @@ int32_t aPosition, const nsACString& aImageName) { - return NS_ERROR_NOT_IMPLEMENTED; + nsresult rv; + nsCOMPtr imageContent = do_QueryInterface(aElement, &rv); + if (!imageContent) return rv; + + // get the image container + nsCOMPtr request; + rv = imageContent->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST, + getter_AddRefs(request)); + if (!request) return rv; + nsCOMPtr container; + rv = request->GetImage(getter_AddRefs(container)); + if (!container) return rv; + + // Set desktop wallpaper filling style + nsAutoCString options; + if (aPosition == BACKGROUND_TILE) + options.Assign("TiledResize"); + else if (aPosition == BACKGROUND_STRETCH) + options.Assign("ScaledResize"); + else if (aPosition == BACKGROUND_FILL) + options.Assign("ScaledAndCroppedResize"); + else if (aPosition == BACKGROUND_FIT) + options.Assign("MaxpectResize"); + else + options.Assign("CenteredResize"); + + // Write the background file to the home directory. + nsAutoCString filePath(PR_GetEnv("HOME")); + + // get the product brand name from localized strings + nsString brandName; + nsCID bundleCID = NS_STRINGBUNDLESERVICE_CID; + nsCOMPtr bundleService(do_GetService(bundleCID)); + if (bundleService) { + nsCOMPtr brandBundle; + rv = bundleService->CreateBundle(BRAND_PROPERTIES, + getter_AddRefs(brandBundle)); + if (NS_SUCCEEDED(rv) && brandBundle) { + rv = brandBundle->GetStringFromName("brandShortName", brandName); + NS_ENSURE_SUCCESS(rv, rv); + } + } + + // build the file name + filePath.Append('/'); + filePath.Append(NS_ConvertUTF16toUTF8(brandName)); + filePath.Append("_wallpaper.png"); + + // write the image to a file in the home dir + rv = WriteImage(filePath, container); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr command = do_CreateInstance( NS_ARRAY_CONTRACTID ); + nsCOMPtr cmdstr = do_CreateInstance( NS_SUPPORTS_CSTRING_CONTRACTID ); + nsCOMPtr imgstr = do_CreateInstance( NS_SUPPORTS_CSTRING_CONTRACTID ); + nsCOMPtr modestr = do_CreateInstance( NS_SUPPORTS_CSTRING_CONTRACTID ); + cmdstr->SetData( NS_LITERAL_CSTRING( "SETWALLPAPER" )); + command->AppendElement( cmdstr ); + imgstr->SetData( filePath ); + command->AppendElement( imgstr ); + modestr->SetData( options ); + command->AppendElement( modestr ); + return nsKDEUtils::command( command ) ? rv : NS_ERROR_FAILURE; } NS_IMETHODIMP nsKDEShellService::GetDesktopBackgroundColor(PRUint32 *aColor) { - return NS_ERROR_NOT_IMPLEMENTED; + aColor = 0; + return NS_OK; } NS_IMETHODIMP nsKDEShellService::SetDesktopBackgroundColor(PRUint32 aColor) { - return NS_ERROR_NOT_IMPLEMENTED; + return NS_OK; } NS_IMETHODIMP