Back to index

lightning-sunbird  0.9+nobinonly
DotNETEmbed.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 2003
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Roy Yokoyama <yokoyama@netscape.com> (original author)
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include <vcclr.h>
00040 #include "nsCOMPtr.h"
00041 #include "nsIWebBrowser.h"
00042 #include "nsIWebBrowserChrome.h"
00043 #include "nsIEmbeddingSiteWindow.h"
00044 #include "nsIBaseWindow.h"
00045 #include "nsIWebNavigation.h"
00046 #include "nsIWindowWatcher.h"
00047 #include "nsIInputStream.h"
00048 #include "nsEmbedAPI.h"
00049 
00050 #include "DotNETEmbed.h"
00051 #include "umWebChrome.h"
00052 
00053 using namespace Mozilla::Embedding;
00054 
00055 // Silly class for holding on to a static UTF8Encoding so that we
00056 // don't need to create a new one in every call to CopyString()...
00057 public __gc class UTF8EncodingHolder
00058 {
00059 public:
00060   static Text::UTF8Encoding *sUTF8Encoding = new Text::UTF8Encoding();
00061 };
00062 
00063 String *
00064 Mozilla::Embedding::CopyString(const nsAFlatCString& aStr)
00065 {
00066   return new String(aStr.get(), 0, aStr.Length(),
00067                     UTF8EncodingHolder::sUTF8Encoding);
00068 }
00069 
00070 // In stead of copying String's to nsAString's we could write a class
00071 // that wraps a String object and exposes it's underlying
00072 // buffer. Doable, if we pin the String object, and so on, but this'll
00073 // do for now.
00074 nsAFlatString&
00075 Mozilla::Embedding::CopyString(String *aSrc, nsAFlatString& aDest)
00076 {
00077   const wchar_t __pin * strbuf = PtrToStringChars(aSrc);
00078 
00079   aDest.Assign(strbuf, aSrc->Length);
00080 
00081   return aDest;
00082 }
00083 
00084 nsAFlatCString&
00085 Mozilla::Embedding::CopyString(String *aSrc, nsAFlatCString& aDest)
00086 {
00087   const wchar_t __pin * strbuf = PtrToStringChars(aSrc);
00088 
00089   CopyUTF16toUTF8(nsDependentString(strbuf, aSrc->Length), aDest);
00090 
00091   return aDest;
00092 }
00093 
00094 void
00095 Mozilla::Embedding::ThrowIfFailed(nsresult rv)
00096 {
00097   if (NS_FAILED(rv)) {
00098     // XXX: Throw some useful exception here!
00099 
00100     throw "rv is an error code!";
00101   }
00102 }
00103 
00104 #pragma unmanaged
00105 
00106 #define NS_WEBBROWSER_CONTRACTID "@mozilla.org/embedding/browser/nsWebBrowser;1"
00107 //*****************************************************************************
00108 // WebBrowserChrome::nsISupports
00109 //*****************************************************************************
00110 
00111 NS_IMPL_ADDREF(WebBrowserChrome)
00112 NS_IMPL_RELEASE(WebBrowserChrome)
00113 
00114 NS_INTERFACE_MAP_BEGIN(WebBrowserChrome)
00115  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebBrowserChrome)
00116  NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome)
00117  NS_INTERFACE_MAP_ENTRY(nsIEmbeddingSiteWindow)
00118 NS_INTERFACE_MAP_END
00119 
00120 
00121 WebBrowserChrome::WebBrowserChrome()
00122 {
00123   mNativeWindow = nsnull;
00124 }
00125 
00126 WebBrowserChrome::~WebBrowserChrome()
00127 {
00128 }
00129 
00130 /* attribute nativeSiteWindow siteWindow */
00131 NS_IMETHODIMP
00132 WebBrowserChrome::GetSiteWindow(void * *aSiteWindow)
00133 {
00134   *aSiteWindow = mNativeWindow;
00135   return NS_OK;
00136 }
00137 
00138 NS_IMETHODIMP
00139 WebBrowserChrome::GetTitle(PRUnichar * *aTitle)
00140 {
00141   NS_ENSURE_ARG_POINTER(aTitle);
00142   *aTitle = nsnull;
00143   return NS_ERROR_NOT_IMPLEMENTED;
00144 }
00145 NS_IMETHODIMP
00146 WebBrowserChrome::SetTitle(const PRUnichar * aTitle)
00147 {
00148   return NS_ERROR_NOT_IMPLEMENTED;
00149 }
00150 
00151 /* attribute boolean visibility; */
00152 NS_IMETHODIMP
00153 WebBrowserChrome::GetVisibility(PRBool * aVisibility)
00154 {
00155   NS_ENSURE_ARG_POINTER(aVisibility);
00156   *aVisibility = PR_TRUE;
00157   return NS_OK;
00158 }
00159 
00160 
00161 NS_IMETHODIMP
00162 WebBrowserChrome::SetVisibility(PRBool aVisibility)
00163 {
00164   return NS_OK;
00165 }
00166 
00167 /* void setFocus (); */
00168 NS_IMETHODIMP
00169 WebBrowserChrome::SetFocus()
00170 {
00171   return NS_OK;
00172 }
00173 
00174 NS_IMETHODIMP
00175 WebBrowserChrome::SetDimensions(PRUint32 aFlags, PRInt32 x, PRInt32 y,
00176                                 PRInt32 cx, PRInt32 cy)
00177 {
00178   return NS_OK;
00179 }
00180 
00181 NS_IMETHODIMP
00182 WebBrowserChrome::GetDimensions(PRUint32 aFlags, PRInt32 *x, PRInt32 *y,
00183                                 PRInt32 *cx, PRInt32 *cy)
00184 {
00185   if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION)
00186   {
00187     *x = 0;
00188     *y = 0;
00189   }
00190 
00191   if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_INNER ||
00192       aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER)
00193   {
00194     *cx = 0;
00195     *cy = 0;
00196   }
00197 
00198   return NS_OK;
00199 }
00200 
00201 NS_IMETHODIMP
00202 WebBrowserChrome::ExitModalEventLoop(nsresult aStatus)
00203 {
00204   return NS_OK;
00205 }
00206 
00207 NS_IMETHODIMP
00208 WebBrowserChrome::ShowAsModal(void)
00209 {
00210   return NS_OK;
00211 }
00212 
00213 NS_IMETHODIMP
00214 WebBrowserChrome::IsWindowModal(PRBool *_retval)
00215 {
00216   *_retval = PR_FALSE;
00217   return NS_ERROR_NOT_IMPLEMENTED;
00218 }
00219 
00220 
00221 NS_IMETHODIMP
00222 WebBrowserChrome::SetStatus(PRUint32 aType, const PRUnichar* aStatus)
00223 {
00224   return NS_OK;
00225 }
00226 
00227 NS_IMETHODIMP
00228 WebBrowserChrome::GetWebBrowser(nsIWebBrowser** aWebBrowser)
00229 {
00230   NS_ENSURE_ARG_POINTER(aWebBrowser);
00231   *aWebBrowser = mWebBrowser;
00232   NS_IF_ADDREF(*aWebBrowser);
00233   return NS_OK;
00234 }
00235 
00236 NS_IMETHODIMP
00237 WebBrowserChrome::SetWebBrowser(nsIWebBrowser* aWebBrowser)
00238 {
00239   mWebBrowser = aWebBrowser;
00240   return NS_OK;
00241 }
00242 
00243 NS_IMETHODIMP
00244 WebBrowserChrome::GetChromeFlags(PRUint32* aChromeMask)
00245 {
00246   *aChromeMask = mChromeFlags;
00247   return NS_OK;
00248 }
00249 
00250 NS_IMETHODIMP
00251 WebBrowserChrome::SetChromeFlags(PRUint32 aChromeMask)
00252 {
00253   mChromeFlags = aChromeMask;
00254   return NS_OK;
00255 }
00256 
00257 NS_IMETHODIMP
00258 WebBrowserChrome::DestroyBrowserWindow(void)
00259 {
00260   return NS_OK;
00261 }
00262 
00263 
00264 NS_IMETHODIMP
00265 WebBrowserChrome::SizeBrowserTo(PRInt32 aWidth, PRInt32 aHeight)
00266 {
00267   ::MoveWindow((HWND)mNativeWindow, 0, 0, aWidth, aHeight, TRUE);
00268   return NS_OK;
00269 }
00270 
00271 nsresult
00272 WebBrowserChrome::CreateBrowser(HWND hWnd, PRInt32 aX, PRInt32 aY, PRInt32 aCX,
00273                                 PRInt32 aCY, nsIWebBrowser **aBrowser)
00274 {
00275   NS_ENSURE_ARG_POINTER(aBrowser);
00276   *aBrowser = nsnull;
00277 
00278   mWebBrowser = do_CreateInstance(NS_WEBBROWSER_CONTRACTID);
00279 
00280   if (!mWebBrowser)
00281     return NS_ERROR_FAILURE;
00282 
00283   mWebBrowser->SetContainerWindow(NS_STATIC_CAST(nsIWebBrowserChrome*, this));
00284 
00285   nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(mWebBrowser);
00286   dsti->SetItemType(nsIDocShellTreeItem::typeContentWrapper);
00287 
00288   nsCOMPtr<nsIBaseWindow> browserBaseWindow = do_QueryInterface(mWebBrowser);
00289 
00290   mNativeWindow = hWnd;
00291 
00292   if (!mNativeWindow)
00293     return NS_ERROR_FAILURE;
00294 
00295   browserBaseWindow->InitWindow(mNativeWindow, nsnull, aX, aY, aCX, aCY);
00296   browserBaseWindow->Create();
00297 
00298   if (mWebBrowser)
00299   {
00300     *aBrowser = mWebBrowser;
00301     NS_ADDREF(*aBrowser);
00302     return NS_OK;
00303   }
00304 
00305   return NS_ERROR_FAILURE;
00306 }
00307 
00308 #pragma managed
00309 
00310 
00311 Gecko::Gecko()
00312   : mChrome(nsnull)
00313 {
00314 }
00315 
00316 void
00317 Gecko::TermEmbedding()
00318 {
00319   if (!sIsInitialized) {
00320     return;
00321   }
00322 
00323   sIsInitialized = false;
00324 
00325   nsresult rv = NS_TermEmbedding();
00326   ThrowIfFailed(rv);
00327 }
00328 
00329 void
00330 Gecko::OpenURL(String *aUrl)
00331 {
00332   if (!sIsInitialized) {
00333     nsresult rv = NS_InitEmbedding(nsnull, nsnull);
00334     ThrowIfFailed(rv);
00335 
00336     sIsInitialized = true;
00337   }
00338 
00339   const wchar_t __pin * url = PtrToStringChars(aUrl);
00340   nsresult rv;
00341 
00342   HWND hWnd = (HWND)Handle.ToPointer();
00343 
00344   if (!mChrome) {
00345     CreateBrowserWindow(nsIWebBrowserChrome::CHROME_ALL, nsnull);
00346   }
00347 
00348   // Start loading a page
00349   nsCOMPtr<nsIWebBrowser> newBrowser;
00350   mChrome->GetWebBrowser(getter_AddRefs(newBrowser));
00351   nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(newBrowser));
00352 
00353   rv = webNav->LoadURI(url, nsIWebNavigation::LOAD_FLAGS_NONE, nsnull, nsnull,
00354                        nsnull);
00355 
00356   ThrowIfFailed(rv);
00357 }
00358 
00359 void
00360 Gecko::OnResize(EventArgs *e)
00361 {
00362   if (mChrome) {
00363     nsCOMPtr<nsIEmbeddingSiteWindow> embeddingSite =
00364       do_QueryInterface(mChrome);
00365 
00366     RECT rect;
00367     GetClientRect((HWND)Handle.ToPointer(), &rect);
00368 
00369     // Make sure the browser is visible and sized
00370     nsCOMPtr<nsIWebBrowser> webBrowser;
00371     mChrome->GetWebBrowser(getter_AddRefs(webBrowser));
00372     nsCOMPtr<nsIBaseWindow> webBrowserAsWin = do_QueryInterface(webBrowser);
00373     if (webBrowserAsWin) {
00374       webBrowserAsWin->SetPositionAndSize(rect.left,
00375                                           rect.top,
00376                                           rect.right - rect.left,
00377                                           rect.bottom - rect.top,
00378                                           PR_TRUE);
00379       webBrowserAsWin->SetVisibility(PR_TRUE);
00380     }
00381   }
00382 
00383   UserControl::OnResize(e);
00384 }
00385 
00386 void
00387 Gecko::CreateBrowserWindow(PRUint32 aChromeFlags, nsIWebBrowserChrome *aParent)
00388 {
00389   WebBrowserChrome * chrome = new WebBrowserChrome();
00390   if (!chrome) {
00391     throw new OutOfMemoryException();
00392   }
00393 
00394   mChrome = chrome;
00395   NS_ADDREF(mChrome);
00396 
00397   // XXX: Is this really needed?
00398   // now an extra addref; the window owns itself (to be released by
00399   // WebBrowserChromeUI::Destroy)
00400   NS_ADDREF(mChrome);
00401 
00402   chrome->SetChromeFlags(aChromeFlags);
00403 
00404   HWND hWnd = (HWND)Handle.ToPointer();
00405 
00406   // Insert the browser
00407   nsCOMPtr<nsIWebBrowser> newBrowser;
00408   chrome->CreateBrowser(hWnd, -1, -1, -1, -1, getter_AddRefs(newBrowser));
00409   if (!newBrowser) {
00410     ThrowIfFailed(NS_ERROR_FAILURE);
00411   }
00412 
00413   // Place it where we want it.
00414   OnResize(0);
00415 
00416   // if opened as chrome, it'll be made visible after the chrome has loaded.
00417   // otherwise, go ahead and show it now.
00418   if (!(aChromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME))
00419     ::ShowWindow(hWnd, SW_RESTORE);
00420 }
00421