зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1695381 - Refactor GTK icon processing in preparation for remoting. r=tnikkel
Differential Revision: https://phabricator.services.mozilla.com/D118595
This commit is contained in:
Родитель
552c921cc3
Коммит
7011e9f0bc
|
@ -13,6 +13,7 @@
|
|||
#include "mozilla/NullPrincipal.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/gfx/Swizzle.h"
|
||||
#include "mozilla/ipc/ByteBuf.h"
|
||||
#include <algorithm>
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
@ -33,11 +34,11 @@
|
|||
#include "gfxPlatform.h"
|
||||
|
||||
using mozilla::CheckedInt32;
|
||||
using mozilla::ipc::ByteBuf;
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsIconChannel, nsIRequest, nsIChannel)
|
||||
|
||||
static nsresult moz_gdk_pixbuf_to_channel(GdkPixbuf* aPixbuf, nsIURI* aURI,
|
||||
nsIChannel** aChannel) {
|
||||
static nsresult MozGdkPixbufToByteBuf(GdkPixbuf* aPixbuf, ByteBuf* aByteBuf) {
|
||||
int width = gdk_pixbuf_get_width(aPixbuf);
|
||||
int height = gdk_pixbuf_get_height(aPixbuf);
|
||||
NS_ENSURE_TRUE(height < 256 && width < 256 && height > 0 && width > 0 &&
|
||||
|
@ -73,31 +74,43 @@ static nsresult moz_gdk_pixbuf_to_channel(GdkPixbuf* aPixbuf, nsIURI* aURI,
|
|||
outstride, mozilla::gfx::SurfaceFormat::OS_RGBA,
|
||||
mozilla::gfx::IntSize(width, height));
|
||||
|
||||
*aByteBuf = ByteBuf(buf, buf_size.value(), buf_size.value());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult ByteBufToStream(ByteBuf&& aBuf, nsIInputStream** aStream) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIStringInputStream> stream =
|
||||
do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv);
|
||||
|
||||
// Prevent the leaking of buf
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
free(buf);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// stream takes ownership of buf and will free it on destruction.
|
||||
// This function cannot fail.
|
||||
rv = stream->AdoptData((char*)buf, buf_size.value());
|
||||
rv = stream->AdoptData(reinterpret_cast<char*>(aBuf.mData), aBuf.mLen);
|
||||
MOZ_ASSERT(CheckedInt32(aBuf.mLen).isValid(),
|
||||
"aBuf.mLen should fit in int32_t");
|
||||
aBuf.mData = nullptr;
|
||||
|
||||
// If this no longer holds then re-examine buf's lifetime.
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
stream.forget(aStream);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult StreamToChannel(already_AddRefed<nsIInputStream> aStream,
|
||||
nsIURI* aURI, nsIChannel** aChannel) {
|
||||
// nsIconProtocolHandler::NewChannel will provide the correct loadInfo for
|
||||
// this iconChannel. Use the most restrictive security settings for the
|
||||
// temporary loadInfo to make sure the channel can not be opened.
|
||||
nsCOMPtr<nsIPrincipal> nullPrincipal =
|
||||
mozilla::NullPrincipal::CreateWithoutOriginAttributes();
|
||||
return NS_NewInputStreamChannel(
|
||||
aChannel, aURI, stream.forget(), nullPrincipal,
|
||||
aChannel, aURI, std::move(aStream), nullPrincipal,
|
||||
nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED,
|
||||
nsIContentPolicy::TYPE_INTERNAL_IMAGE, nsLiteralCString(IMAGE_ICON_MS));
|
||||
}
|
||||
|
@ -182,7 +195,9 @@ static nsresult ScaleIconBuf(GdkPixbuf** aBuf, int32_t iconSize) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsIconChannel::InitWithGIO(nsIMozIconURI* aIconURI) {
|
||||
/* static */
|
||||
nsresult nsIconChannel::GetIconWithGIO(nsIMozIconURI* aIconURI,
|
||||
ByteBuf* aDataOut) {
|
||||
GIcon* icon = nullptr;
|
||||
nsCOMPtr<nsIURL> fileURI;
|
||||
|
||||
|
@ -265,12 +280,13 @@ nsresult nsIconChannel::InitWithGIO(nsIMozIconURI* aIconURI) {
|
|||
nsresult rv = ScaleIconBuf(&buf, iconSize);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = moz_gdk_pixbuf_to_channel(buf, aIconURI, getter_AddRefs(mRealChannel));
|
||||
rv = MozGdkPixbufToByteBuf(buf, aDataOut);
|
||||
g_object_unref(buf);
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsIconChannel::Init(nsIURI* aURI) {
|
||||
/* static */
|
||||
nsresult nsIconChannel::GetIcon(nsIURI* aURI, ByteBuf* aDataOut) {
|
||||
nsCOMPtr<nsIMozIconURI> iconURI = do_QueryInterface(aURI);
|
||||
NS_ASSERTION(iconURI, "URI is not an nsIMozIconURI");
|
||||
|
||||
|
@ -281,7 +297,7 @@ nsresult nsIconChannel::Init(nsIURI* aURI) {
|
|||
nsAutoCString stockIcon;
|
||||
iconURI->GetStockIcon(stockIcon);
|
||||
if (stockIcon.IsEmpty()) {
|
||||
return InitWithGIO(iconURI);
|
||||
return GetIconWithGIO(iconURI, aDataOut);
|
||||
}
|
||||
|
||||
// Search for stockIcon
|
||||
|
@ -373,14 +389,27 @@ nsresult nsIconChannel::Init(nsIURI* aURI) {
|
|||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsresult rv =
|
||||
moz_gdk_pixbuf_to_channel(icon, iconURI, getter_AddRefs(mRealChannel));
|
||||
nsresult rv = MozGdkPixbufToByteBuf(icon, aDataOut);
|
||||
|
||||
g_object_unref(icon);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsIconChannel::Init(nsIURI* aURI) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
|
||||
ByteBuf bytebuf;
|
||||
rv = GetIcon(aURI, &bytebuf);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = ByteBufToStream(std::move(bytebuf), getter_AddRefs(stream));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return StreamToChannel(stream.forget(), aURI, getter_AddRefs(mRealChannel));
|
||||
}
|
||||
|
||||
void nsIconChannel::Shutdown() {
|
||||
if (gProtoWindow) {
|
||||
gtk_widget_destroy(gProtoWindow);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
@ -12,9 +13,14 @@
|
|||
#include "nsIIconURI.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
/// This class is the gnome implementation of nsIconChannel. It basically asks
|
||||
/// gtk/gnome for an icon, saves it as a tmp icon, and creates a new channel for
|
||||
/// that file to which all calls will be proxied.
|
||||
namespace mozilla::ipc {
|
||||
class ByteBuf;
|
||||
}
|
||||
|
||||
/// This class is the GTK implementation of nsIconChannel. It asks
|
||||
/// GTK for the icon, translates the pixel data in-memory into
|
||||
/// nsIconDecoder format, and proxies the nsChannel interface to a new
|
||||
/// channel returning that image.
|
||||
class nsIconChannel final : public nsIChannel {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -30,13 +36,18 @@ class nsIconChannel final : public nsIChannel {
|
|||
/// If this method fails, no other function must be called on this object.
|
||||
nsresult Init(nsIURI* aURI);
|
||||
|
||||
/// Obtains an icon, in nsIconDecoder format, as a ByteBuf instead
|
||||
/// of a channel. For use with IPC.
|
||||
static nsresult GetIcon(nsIURI* aURI, mozilla::ipc::ByteBuf* aDataOut);
|
||||
|
||||
private:
|
||||
~nsIconChannel() {}
|
||||
/// The channel to the temp icon file (e.g. to /tmp/2qy9wjqw.html).
|
||||
/// The input stream channel which will yield the image.
|
||||
/// Will always be non-null after a successful Init.
|
||||
nsCOMPtr<nsIChannel> mRealChannel;
|
||||
|
||||
nsresult InitWithGIO(nsIMozIconURI* aIconURI);
|
||||
static nsresult GetIconWithGIO(nsIMozIconURI* aIconURI,
|
||||
mozilla::ipc::ByteBuf* aDataOut);
|
||||
};
|
||||
|
||||
#endif // mozilla_image_decoders_icon_gtk_nsIconChannel_h
|
||||
|
|
Загрузка…
Ссылка в новой задаче