add the ability to stream in data into the widget. r=valeski

git-svn-id: svn://10.0.0.236/trunk@70318 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
blizzard%redhat.com
2000-05-17 05:42:17 +00:00
parent 630825d9fa
commit 11b199eb3f
9 changed files with 466 additions and 0 deletions

View File

@@ -20,11 +20,19 @@
*/
#include "GtkMozEmbedChrome.h"
#include "GtkMozEmbedStream.h"
#include "nsCWebBrowser.h"
#include "nsIURI.h"
#include "nsNetUtil.h"
#include "nsIDocShellTreeItem.h"
#include "nsCRT.h"
#include "prlog.h"
#include "prprf.h"
#include "nsIDocumentLoaderFactory.h"
#include "nsIContentViewerContainer.h"
#include "nsIDocShell.h"
static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
// this is a define to make sure that we don't call certain function
// before the object has been properly initialized
@@ -73,6 +81,8 @@ GtkMozEmbedChrome::GtkMozEmbedChrome()
mLocation = NULL;
mTitle = NULL;
mChromeMask = 0;
mOffset = 0;
mDoingStream = PR_FALSE;
if (!mozEmbedLm)
mozEmbedLm = PR_NewLogModule("GtkMozEmbedChrome");
if (!sBrowsers)
@@ -223,6 +233,157 @@ NS_IMETHODIMP GtkMozEmbedChrome::GetTitleChar (char **retval)
return NS_OK;
}
NS_IMETHODIMP GtkMozEmbedChrome::OpenStream (const char *aBaseURI, const char *aContentType)
{
NS_ENSURE_ARG_POINTER(aBaseURI);
NS_ENSURE_ARG_POINTER(aContentType);
nsresult rv = NS_OK;
GtkMozEmbedStream *newStream = nsnull;
nsCOMPtr<nsIDocumentLoaderFactory> docLoaderFactory;
nsCOMPtr<nsIDocShell> docShell;
nsCOMPtr<nsIContentViewerContainer> viewerContainer;
nsCOMPtr<nsIContentViewer> contentViewer;
nsCOMPtr<nsIURI> uri;
nsCAutoString docLoaderProgID;
nsCAutoString spec(aBaseURI);
// check to see if we need to close the current stream
if (mDoingStream)
CloseStream();
mDoingStream = PR_TRUE;
// create our new stream object
newStream = new GtkMozEmbedStream();
if (!newStream)
return NS_ERROR_OUT_OF_MEMORY;
// we own this
NS_ADDREF(newStream);
// QI it to the right interface
mStream = do_QueryInterface(newStream);
if (!mStream)
return NS_ERROR_FAILURE;
// ok, now we're just using it for an nsIInputStream interface so
// release our second reference to it.
NS_RELEASE(newStream);
// get our hands on the docShell
mWebBrowser->GetDocShell(getter_AddRefs(docShell));
if (!docShell)
return NS_ERROR_FAILURE;
// QI that to a content viewer container
viewerContainer = do_QueryInterface(docShell);
if (!viewerContainer)
return NS_ERROR_FAILURE;
// create a new uri object
uri = do_CreateInstance(kSimpleURICID, &rv);
if (NS_FAILED(rv))
return rv;
rv = uri->SetSpec(spec.GetBuffer());
if (NS_FAILED(rv))
return rv;
// create a new load group
rv = NS_NewLoadGroup(getter_AddRefs(mLoadGroup), nsnull);
if (NS_FAILED(rv))
return rv;
// create a new input stream channel
rv = NS_NewInputStreamChannel(getter_AddRefs(mChannel), uri, mStream, aContentType,
1024 /* len */);
if (NS_FAILED(rv))
return rv;
// set the channel's load group
rv = mChannel->SetLoadGroup(mLoadGroup);
if (NS_FAILED(rv))
return rv;
// find a document loader for this command plus content type
// combination
docLoaderProgID = NS_DOCUMENT_LOADER_FACTORY_PROGID_PREFIX;
docLoaderProgID += "view";
docLoaderProgID += "/";
docLoaderProgID += aContentType;
docLoaderFactory = do_CreateInstance(docLoaderProgID, &rv);
if (NS_FAILED(rv))
return rv;
// ok, create an instance of the content viewer for that command and
// mime type
rv = docLoaderFactory->CreateInstance("view",
mChannel,
mLoadGroup,
aContentType,
viewerContainer,
nsnull,
getter_AddRefs(mStreamListener),
getter_AddRefs(contentViewer));
if (NS_FAILED(rv))
return rv;
// set the container viewer container for this content view
rv = contentViewer->SetContainer(viewerContainer);
if (NS_FAILED(rv))
return rv;
// embed this sucker.
rv = viewerContainer->Embed(contentViewer, "view", nsnull);
if (NS_FAILED(rv))
return rv;
// start our request
rv = mStreamListener->OnStartRequest(mChannel, NULL);
if (NS_FAILED(rv))
return rv;
return NS_OK;
}
NS_IMETHODIMP GtkMozEmbedChrome::AppendToStream (const char *aData, gint32 aLen)
{
GtkMozEmbedStream *embedStream = (GtkMozEmbedStream *)mStream.get();
nsresult rv;
NS_ENSURE_STATE(mDoingStream);
rv = embedStream->Append(aData, aLen);
if (NS_FAILED(rv))
return rv;
rv = mStreamListener->OnDataAvailable(mChannel,
NULL,
mStream,
mOffset, /* offset */
aLen); /* len */
mOffset += aLen;
if (NS_FAILED(rv))
return rv;
return NS_OK;
}
NS_IMETHODIMP GtkMozEmbedChrome::CloseStream (void)
{
nsresult rv;
NS_ENSURE_STATE(mDoingStream);
mDoingStream = PR_FALSE;
rv = mStreamListener->OnStopRequest(mChannel,
NULL,
NS_OK,
NULL);
if (NS_FAILED(rv))
return rv;
mStream = nsnull;
mLoadGroup = nsnull;
mChannel = nsnull;
mStreamListener = nsnull;
mContentViewer = nsnull;
mOffset = 0;
return NS_OK;
}
// nsIInterfaceRequestor interface
NS_IMETHODIMP GtkMozEmbedChrome::GetInterface(const nsIID &aIID, void** aInstancePtr)

View File

@@ -33,6 +33,11 @@
#include "nsIWebProgressListener.h"
#include "nsIWebProgress.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInputStream.h"
#include "nsILoadGroup.h"
#include "nsIChannel.h"
#include "nsIContentViewer.h"
#include "nsIStreamListener.h"
// utility classes
#include "nsXPIDLString.h"
@@ -70,6 +75,9 @@ public:
NS_IMETHOD GetJSStatus (char **retval);
NS_IMETHOD GetLocation (char **retval);
NS_IMETHOD GetTitleChar (char **retval);
NS_IMETHOD OpenStream (const char *aBaseURI, const char *aContentType);
NS_IMETHOD AppendToStream (const char *aData, gint32 aLen);
NS_IMETHOD CloseStream (void);
NS_DECL_ISUPPORTS
@@ -113,6 +121,13 @@ private:
nsString mTitleUnicode;
PRUint32 mChromeMask;
static nsVoidArray *sBrowsers;
nsCOMPtr<nsIInputStream> mStream;
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCOMPtr<nsIChannel> mChannel;
nsCOMPtr<nsIContentViewer> mContentViewer;
nsCOMPtr<nsIStreamListener> mStreamListener;
PRUint32 mOffset;
PRBool mDoingStream;
};
#endif /* __GtkMozEmbedChrome_h */

View File

@@ -0,0 +1,149 @@
/*
* 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 Christopher Blizzard.
* Portions created by Christopher Blizzard are Copyright (C)
* Christopher Blizzard. All Rights Reserved.
*
* Contributor(s):
* Christopher Blizzard <blizzard@mozilla.org>
*/
#include "GtkMozEmbedStream.h"
#include "nsIAllocator.h"
// nsIInputStream interface
NS_IMPL_ADDREF(GtkMozEmbedStream)
NS_IMPL_RELEASE(GtkMozEmbedStream)
NS_INTERFACE_MAP_BEGIN(GtkMozEmbedStream)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY(nsIInputStream)
NS_INTERFACE_MAP_END
GtkMozEmbedStream::GtkMozEmbedStream()
{
NS_INIT_REFCNT();
mLength = 0;
mBuffer = 0;
}
GtkMozEmbedStream::~GtkMozEmbedStream()
{
if (mBuffer)
nsAllocator::Free(mBuffer);
}
NS_IMETHODIMP GtkMozEmbedStream::Available(PRUint32 *_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
*_retval = mLength;
return NS_OK;
}
NS_IMETHODIMP GtkMozEmbedStream::Read(char * aBuf, PRUint32 aCount, PRUint32 *_retval)
{
PRUint32 bytesToRead;
NS_ENSURE_ARG_POINTER(aBuf);
NS_ENSURE_ARG_POINTER(_retval);
*_retval = 0;
// shortcut?
if (aCount == 0)
return NS_OK;
// check to see how many bytes we can read
if (aCount > mLength)
bytesToRead = mLength;
else
bytesToRead = aCount;
// copy our data
*_retval = bytesToRead;
memcpy(aBuf, mBuffer, bytesToRead);
// see if we can truncate the buffer entirely
if (bytesToRead == mBufLen)
{
mBuffer = nsnull;
mLength = 0;
mBufLen = 0;
return NS_OK;
}
// truncate it some, then
memmove(mBuffer, &mBuffer[bytesToRead], (mLength - bytesToRead));
mLength -= bytesToRead;
return NS_OK;
}
// nsIBaseStream interface
NS_IMETHODIMP GtkMozEmbedStream::Close(void)
{
if (mBuffer)
nsAllocator::Free(mBuffer);
mLength = 0;
mBufLen = 0;
return NS_OK;
}
NS_METHOD GtkMozEmbedStream::Append(const char *aData, PRUint32 aLen)
{
// shortcut?
if (aLen == 0 || aData == NULL)
return NS_OK;
mLength += aLen;
// first time
if (!mBuffer)
{
mBuffer = (char *)nsAllocator::Alloc(mLength);
mBufLen = mLength;
if (!mBuffer)
{
mLength = 0;
mBufLen = 0;
return NS_ERROR_OUT_OF_MEMORY;
}
memcpy(mBuffer, aData, aLen);
return NS_OK;
}
else
{
// see if we need to realloc
if (mLength > mBufLen)
{
char *newBuffer;
newBuffer = (char *)nsAllocator::Realloc(mBuffer, mLength);
if (!newBuffer)
{
mLength = 0;
mBufLen = 0;
nsAllocator::Free(mBuffer);
mBuffer = NULL;
return NS_ERROR_OUT_OF_MEMORY;
}
mBuffer = newBuffer;
mBufLen = mLength;
memcpy(&mBuffer[mLength - aLen], aData, aLen);
}
else
// no realloc required and don't have to update mBufLen, just
// update
memcpy(&mBuffer[mLength - aLen], aData, aLen);
}
return NS_OK;
}

View File

@@ -0,0 +1,46 @@
/*
* 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 Christopher Blizzard.
* Portions created by Christopher Blizzard are Copyright (C)
* Christopher Blizzard. All Rights Reserved.
*
* Contributor(s):
* Christopher Blizzard <blizzard@mozilla.org>
*/
#include "nsISupports.h"
#include "nsIInputStream.h"
class GtkMozEmbedStream : public nsIInputStream
{
public:
GtkMozEmbedStream();
virtual ~GtkMozEmbedStream();
// nsISupports
NS_DECL_ISUPPORTS
// nsIInputStream
NS_DECL_NSIINPUTSTREAM
// nsIBaseStream
NS_DECL_NSIBASESTREAM
NS_METHOD Append(const char *aData, PRUint32 aLen);
private:
char * mBuffer;
PRUint32 mLength;
PRUint32 mBufLen;
};

View File

@@ -31,6 +31,7 @@ REQUIRES = xpcom
CPPSRCS = \
GtkMozEmbedChrome.cpp \
GtkMozEmbedStream.cpp \
nsSetupRegistry.cpp \
gtkmozembed.cpp

View File

@@ -447,6 +447,63 @@ gtk_moz_embed_go_forward (GtkMozEmbed *embed)
embed_private->navigation->GoForward();
}
void
gtk_moz_embed_render_data (GtkMozEmbed *embed,
const char *data, guint32 len,
const char *base_uri, const char *mime_type)
{
GtkMozEmbedPrivate *embed_private;
g_return_if_fail (embed != NULL);
g_return_if_fail (GTK_IS_MOZ_EMBED(embed));
embed_private = (GtkMozEmbedPrivate *)embed->data;
embed_private->embed->OpenStream(base_uri, mime_type);
embed_private->embed->AppendToStream(data, len);
embed_private->embed->CloseStream();
}
void
gtk_moz_embed_open_stream (GtkMozEmbed *embed,
const char *base_uri, const char *mime_type)
{
GtkMozEmbedPrivate *embed_private;
g_return_if_fail (embed != NULL);
g_return_if_fail (GTK_IS_MOZ_EMBED(embed));
embed_private = (GtkMozEmbedPrivate *)embed->data;
embed_private->embed->OpenStream(base_uri, mime_type);
}
void
gtk_moz_embed_append_data (GtkMozEmbed *embed, const char *data, guint32 len)
{
GtkMozEmbedPrivate *embed_private;
g_return_if_fail (embed != NULL);
g_return_if_fail (GTK_IS_MOZ_EMBED(embed));
embed_private = (GtkMozEmbedPrivate *)embed->data;
embed_private->embed->AppendToStream(data, len);
}
void
gtk_moz_embed_close_stream (GtkMozEmbed *embed)
{
GtkMozEmbedPrivate *embed_private;
g_return_if_fail (embed != NULL);
g_return_if_fail (GTK_IS_MOZ_EMBED(embed));
embed_private = (GtkMozEmbedPrivate *)embed->data;
embed_private->embed->CloseStream();
}
void
gtk_moz_embed_reload (GtkMozEmbed *embed, gint32 flags)
{

View File

@@ -69,6 +69,14 @@ extern gboolean gtk_moz_embed_can_go_back (GtkMozEmbed *embed);
extern gboolean gtk_moz_embed_can_go_forward (GtkMozEmbed *embed);
extern void gtk_moz_embed_go_back (GtkMozEmbed *embed);
extern void gtk_moz_embed_go_forward (GtkMozEmbed *embed);
extern void gtk_moz_embed_render_data (GtkMozEmbed *embed,
const char *data, guint32 len,
const char *base_uri, const char *mime_type);
extern void gtk_moz_embed_open_stream (GtkMozEmbed *embed,
const char *base_uri, const char *mime_type);
extern void gtk_moz_embed_append_data (GtkMozEmbed *embed,
const char *data, guint32 len);
extern void gtk_moz_embed_close_stream (GtkMozEmbed *embed);
extern char *gtk_moz_embed_get_link_message (GtkMozEmbed *embed);
extern char *gtk_moz_embed_get_js_status (GtkMozEmbed *embed);
extern char *gtk_moz_embed_get_title (GtkMozEmbed *embed);

View File

@@ -62,6 +62,9 @@ public:
NS_IMETHOD GetJSStatus (char **retval) = 0;
NS_IMETHOD GetLocation (char **retval) = 0;
NS_IMETHOD GetTitleChar (char **retval) = 0;
NS_IMETHOD OpenStream (const char *aBaseURI, const char *aContentType) = 0;
NS_IMETHOD AppendToStream (const char *aData, gint32 aLen) = 0;
NS_IMETHOD CloseStream (void) = 0;
};
#endif /* __nsIGtkEmbed_h__ */

View File

@@ -32,6 +32,7 @@ typedef struct _TestGtkBrowser {
GtkWidget *stopButton;
GtkWidget *forwardButton;
GtkWidget *reloadButton;
GtkWidget *streamButton;
GtkWidget *urlEntry;
GtkWidget *mozEmbed;
GtkWidget *progressAreaHBox;
@@ -53,6 +54,7 @@ static void back_clicked_cb (GtkButton *button, TestGtkBrowser *browser
static void stop_clicked_cb (GtkButton *button, TestGtkBrowser *browser);
static void forward_clicked_cb (GtkButton *button, TestGtkBrowser *browser);
static void reload_clicked_cb (GtkButton *button, TestGtkBrowser *browser);
static void stream_clicked_cb (GtkButton *button, TestGtkBrowser *browser);
static void url_activate_cb (GtkEditable *widget, TestGtkBrowser *browser);
static gboolean delete_cb (GtkWidget *widget, GdkEventAny *event,
TestGtkBrowser *browser);
@@ -158,6 +160,14 @@ new_gtk_browser(guint32 chromeMask)
0, // XXX replace with icon
GTK_SIGNAL_FUNC(reload_clicked_cb),
browser);
// new stream button
browser->streamButton = gtk_toolbar_append_item(GTK_TOOLBAR(browser->toolbar),
"Stream",
"Stream",
"Stream",
0, // XXX replace with icon
GTK_SIGNAL_FUNC(stream_clicked_cb),
browser);
// create the url text entry
browser->urlEntry = gtk_entry_new();
// add it to the hbox
@@ -263,15 +273,31 @@ stop_clicked_cb (GtkButton *button, TestGtkBrowser *browser)
void
forward_clicked_cb (GtkButton *button, TestGtkBrowser *browser)
{
g_print("forward_clicked_cb\n");
gtk_moz_embed_go_forward(GTK_MOZ_EMBED(browser->mozEmbed));
}
void
reload_clicked_cb (GtkButton *button, TestGtkBrowser *browser)
{
g_print("reload_clicked_cb\n");
gtk_moz_embed_reload(GTK_MOZ_EMBED(browser->mozEmbed), gtk_moz_embed_flag_reloadNormal);
}
void
stream_clicked_cb (GtkButton *button, TestGtkBrowser *browser)
{
char *data;
char *data2;
data = "<html>Hi";
data2 = " there</html>\n";
g_print("stream_clicked_cb\n");
gtk_moz_embed_open_stream(GTK_MOZ_EMBED(browser->mozEmbed), "file://", "text/html");
gtk_moz_embed_append_data(GTK_MOZ_EMBED(browser->mozEmbed), data, strlen(data));
gtk_moz_embed_append_data(GTK_MOZ_EMBED(browser->mozEmbed), data2, strlen(data2));
gtk_moz_embed_close_stream(GTK_MOZ_EMBED(browser->mozEmbed));
}
void
url_activate_cb (GtkEditable *widget, TestGtkBrowser *browser)
{