~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/embedding/browser/gtk/src/EmbedPrivate.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * The contents of this file are subject to the Mozilla Public
 
3
 * License Version 1.1 (the "License"); you may not use this file
 
4
 * except in compliance with the License. You may obtain a copy of
 
5
 * the License at http://www.mozilla.org/MPL/
 
6
 * 
 
7
 * Software distributed under the License is distributed on an "AS
 
8
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 
9
 * implied. See the License for the specific language governing
 
10
 * rights and limitations under the License.
 
11
 * 
 
12
 * The Original Code is mozilla.org code.
 
13
 * 
 
14
 * The Initial Developer of the Original Code is Christopher Blizzard.
 
15
 * Portions created by Christopher Blizzard are Copyright (C)
 
16
 * Christopher Blizzard.  All Rights Reserved.
 
17
 * 
 
18
 * Contributor(s):
 
19
 *   Christopher Blizzard <blizzard@mozilla.org>
 
20
 */
 
21
 
 
22
#include <nsIDocShell.h>
 
23
#include <nsIWebProgress.h>
 
24
#include "nsIWidget.h"
 
25
#include "nsCRT.h"
 
26
 
 
27
// for NS_APPSHELL_CID
 
28
#include <nsWidgetsCID.h>
 
29
 
 
30
// for do_GetInterface
 
31
#include <nsIInterfaceRequestor.h>
 
32
// for do_CreateInstance
 
33
#include <nsIComponentManager.h>
 
34
 
 
35
// for initializing our window watcher service
 
36
#include <nsIWindowWatcher.h>
 
37
 
 
38
#include <nsILocalFile.h>
 
39
#include <nsEmbedAPI.h>
 
40
 
 
41
// all of the crap that we need for event listeners
 
42
// and when chrome windows finish loading
 
43
#include <nsIDOMWindow.h>
 
44
#include <nsPIDOMWindow.h>
 
45
#include <nsIDOMWindowInternal.h>
 
46
#include <nsIChromeEventHandler.h>
 
47
 
 
48
// for the focus hacking we need to do
 
49
#include <nsIFocusController.h>
 
50
 
 
51
// for profiles
 
52
#include <nsProfileDirServiceProvider.h>
 
53
 
 
54
// app component registration
 
55
#include <nsIGenericFactory.h>
 
56
#include <nsIComponentRegistrar.h>
 
57
 
 
58
// all of our local includes
 
59
#include "EmbedPrivate.h"
 
60
#include "EmbedWindow.h"
 
61
#include "EmbedProgress.h"
 
62
#include "EmbedContentListener.h"
 
63
#include "EmbedEventListener.h"
 
64
#include "EmbedWindowCreator.h"
 
65
#include "EmbedStream.h"
 
66
#ifdef MOZ_WIDGET_GTK2
 
67
#include "GtkPromptService.h"
 
68
#endif
 
69
 
 
70
#ifdef MOZ_ACCESSIBILITY_ATK
 
71
#include "nsIAccessibilityService.h"
 
72
#include "nsIAccessible.h"
 
73
#include "nsIDOMDocument.h"
 
74
#endif
 
75
 
 
76
#ifdef _BUILD_STATIC_BIN
 
77
#include "nsStaticComponent.h"
 
78
nsresult PR_CALLBACK
 
79
gtk_getModuleInfo(nsStaticModuleInfo **info, PRUint32 *count);
 
80
#endif
 
81
 
 
82
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
 
83
 
 
84
PRUint32     EmbedPrivate::sWidgetCount = 0;
 
85
char        *EmbedPrivate::sCompPath    = nsnull;
 
86
nsIAppShell *EmbedPrivate::sAppShell    = nsnull;
 
87
nsVoidArray *EmbedPrivate::sWindowList  = nsnull;
 
88
char        *EmbedPrivate::sProfileDir  = nsnull;
 
89
char        *EmbedPrivate::sProfileName = nsnull;
 
90
nsIPref     *EmbedPrivate::sPrefs       = nsnull;
 
91
GtkWidget   *EmbedPrivate::sOffscreenWindow = 0;
 
92
GtkWidget   *EmbedPrivate::sOffscreenFixed  = 0;
 
93
nsIDirectoryServiceProvider *EmbedPrivate::sAppFileLocProvider = nsnull;
 
94
nsProfileDirServiceProvider *EmbedPrivate::sProfileDirServiceProvider = nsnull;
 
95
 
 
96
#define NS_PROMPTSERVICE_CID \
 
97
 {0x95611356, 0xf583, 0x46f5, {0x81, 0xff, 0x4b, 0x3e, 0x01, 0x62, 0xc6, 0x19}}
 
98
 
 
99
#ifdef MOZ_WIDGET_GTK2
 
100
NS_GENERIC_FACTORY_CONSTRUCTOR(GtkPromptService)
 
101
#endif
 
102
 
 
103
#ifdef MOZ_WIDGET_GTK2
 
104
 
 
105
static const nsModuleComponentInfo defaultAppComps[] = {
 
106
  {
 
107
    "Prompt Service",
 
108
    NS_PROMPTSERVICE_CID,
 
109
    "@mozilla.org/embedcomp/prompt-service;1",
 
110
    GtkPromptServiceConstructor
 
111
  }
 
112
};
 
113
 
 
114
const nsModuleComponentInfo *EmbedPrivate::sAppComps = defaultAppComps;
 
115
int   EmbedPrivate::sNumAppComps = sizeof(defaultAppComps) / sizeof(nsModuleComponentInfo);
 
116
 
 
117
#else
 
118
 
 
119
const nsModuleComponentInfo *EmbedPrivate::sAppComps = nsnull;
 
120
int   EmbedPrivate::sNumAppComps = 0;
 
121
 
 
122
#endif
 
123
 
 
124
EmbedPrivate::EmbedPrivate(void)
 
125
{
 
126
  mOwningWidget     = nsnull;
 
127
  mWindow           = nsnull;
 
128
  mProgress         = nsnull;
 
129
  mContentListener  = nsnull;
 
130
  mEventListener    = nsnull;
 
131
  mStream           = nsnull;
 
132
  mChromeMask       = 0;
 
133
  mIsChrome         = PR_FALSE;
 
134
  mChromeLoaded     = PR_FALSE;
 
135
  mListenersAttached = PR_FALSE;
 
136
  mMozWindowWidget  = 0;
 
137
  mIsDestroyed      = PR_FALSE;
 
138
 
 
139
  PushStartup();
 
140
  if (!sWindowList) {
 
141
    sWindowList = new nsVoidArray();
 
142
  }
 
143
  sWindowList->AppendElement(this);
 
144
}
 
145
 
 
146
EmbedPrivate::~EmbedPrivate()
 
147
{
 
148
  sWindowList->RemoveElement(this);
 
149
  PopStartup();
 
150
}
 
151
 
 
152
nsresult
 
153
EmbedPrivate::Init(GtkMozEmbed *aOwningWidget)
 
154
{
 
155
  // are we being re-initialized?
 
156
  if (mOwningWidget)
 
157
    return NS_OK;
 
158
 
 
159
  // hang on with a reference to the owning widget
 
160
  mOwningWidget = aOwningWidget;
 
161
 
 
162
  // Create our embed window, and create an owning reference to it and
 
163
  // initialize it.  It is assumed that this window will be destroyed
 
164
  // when we go out of scope.
 
165
  mWindow = new EmbedWindow();
 
166
  mWindowGuard = NS_STATIC_CAST(nsIWebBrowserChrome *, mWindow);
 
167
  mWindow->Init(this);
 
168
 
 
169
  // Create our progress listener object, make an owning reference,
 
170
  // and initialize it.  It is assumed that this progress listener
 
171
  // will be destroyed when we go out of scope.
 
172
  mProgress = new EmbedProgress();
 
173
  mProgressGuard = NS_STATIC_CAST(nsIWebProgressListener *,
 
174
                                       mProgress);
 
175
  mProgress->Init(this);
 
176
 
 
177
  // Create our content listener object, initialize it and attach it.
 
178
  // It is assumed that this will be destroyed when we go out of
 
179
  // scope.
 
180
  mContentListener = new EmbedContentListener();
 
181
  mContentListenerGuard = NS_STATIC_CAST(nsISupports*, NS_STATIC_CAST(nsIURIContentListener*, mContentListener));
 
182
  mContentListener->Init(this);
 
183
 
 
184
  // Create our key listener object and initialize it.  It is assumed
 
185
  // that this will be destroyed before we go out of scope.
 
186
  mEventListener = new EmbedEventListener();
 
187
  mEventListenerGuard =
 
188
    NS_STATIC_CAST(nsISupports *, NS_STATIC_CAST(nsIDOMKeyListener *,
 
189
                                                 mEventListener));
 
190
  mEventListener->Init(this);
 
191
 
 
192
  // has the window creator service been set up?
 
193
  static int initialized = PR_FALSE;
 
194
  // Set up our window creator ( only once )
 
195
  if (!initialized) {
 
196
    // We set this flag here instead of on success.  If it failed we
 
197
    // don't want to keep trying and leaking window creator objects.
 
198
    initialized = PR_TRUE;
 
199
 
 
200
    // create our local object
 
201
    EmbedWindowCreator *creator = new EmbedWindowCreator();
 
202
    nsCOMPtr<nsIWindowCreator> windowCreator;
 
203
    windowCreator = NS_STATIC_CAST(nsIWindowCreator *, creator);
 
204
 
 
205
    // Attach it via the watcher service
 
206
    nsCOMPtr<nsIWindowWatcher> watcher = do_GetService(NS_WINDOWWATCHER_CONTRACTID);
 
207
    if (watcher)
 
208
      watcher->SetWindowCreator(windowCreator);
 
209
  }
 
210
  return NS_OK;
 
211
}
 
212
 
 
213
nsresult
 
214
EmbedPrivate::Realize(PRBool *aAlreadyRealized)
 
215
{
 
216
 
 
217
  *aAlreadyRealized = PR_FALSE;
 
218
 
 
219
  // create the offscreen window if we have to
 
220
  EnsureOffscreenWindow();
 
221
 
 
222
  // Have we ever been initialized before?  If so then just reparetn
 
223
  // from the offscreen window.
 
224
  if (mMozWindowWidget) {
 
225
    gtk_widget_reparent(mMozWindowWidget, GTK_WIDGET(mOwningWidget));
 
226
    *aAlreadyRealized = PR_TRUE;
 
227
    return NS_OK;
 
228
  }
 
229
 
 
230
  // Get the nsIWebBrowser object for our embedded window.
 
231
  nsCOMPtr<nsIWebBrowser> webBrowser;
 
232
  mWindow->GetWebBrowser(getter_AddRefs(webBrowser));
 
233
 
 
234
  // get a handle on the navigation object
 
235
  mNavigation = do_QueryInterface(webBrowser);
 
236
 
 
237
  // Create our session history object and tell the navigation object
 
238
  // to use it.  We need to do this before we create the web browser
 
239
  // window.
 
240
  mSessionHistory = do_CreateInstance(NS_SHISTORY_CONTRACTID);
 
241
  mNavigation->SetSessionHistory(mSessionHistory);
 
242
 
 
243
  // create the window
 
244
  mWindow->CreateWindow();
 
245
 
 
246
  // bind the progress listener to the browser object
 
247
  nsCOMPtr<nsISupportsWeakReference> supportsWeak;
 
248
  supportsWeak = do_QueryInterface(mProgressGuard);
 
249
  nsCOMPtr<nsIWeakReference> weakRef;
 
250
  supportsWeak->GetWeakReference(getter_AddRefs(weakRef));
 
251
  webBrowser->AddWebBrowserListener(weakRef,
 
252
                                    nsIWebProgressListener::GetIID());
 
253
 
 
254
  // set ourselves as the parent uri content listener
 
255
  nsCOMPtr<nsIURIContentListener> uriListener;
 
256
  uriListener = do_QueryInterface(mContentListenerGuard);
 
257
  webBrowser->SetParentURIContentListener(uriListener);
 
258
 
 
259
  // save the window id of the newly created window
 
260
  nsCOMPtr<nsIWidget> mozWidget;
 
261
  mWindow->mBaseWindow->GetMainWidget(getter_AddRefs(mozWidget));
 
262
  // get the native drawing area
 
263
  GdkWindow *tmp_window =
 
264
    NS_STATIC_CAST(GdkWindow *,
 
265
                   mozWidget->GetNativeData(NS_NATIVE_WINDOW));
 
266
  // and, thanks to superwin we actually need the parent of that.
 
267
  tmp_window = gdk_window_get_parent(tmp_window);
 
268
  // save the widget ID - it should be the mozarea of the window.
 
269
  gpointer data = nsnull;
 
270
  gdk_window_get_user_data(tmp_window, &data);
 
271
  mMozWindowWidget = NS_STATIC_CAST(GtkWidget *, data);
 
272
 
 
273
  return NS_OK;
 
274
}
 
275
 
 
276
void
 
277
EmbedPrivate::Unrealize(void)
 
278
{
 
279
  // reparent to our offscreen window
 
280
  gtk_widget_reparent(mMozWindowWidget, sOffscreenFixed);
 
281
}
 
282
 
 
283
void
 
284
EmbedPrivate::Show(void)
 
285
{
 
286
  // Get the nsIWebBrowser object for our embedded window.
 
287
  nsCOMPtr<nsIWebBrowser> webBrowser;
 
288
  mWindow->GetWebBrowser(getter_AddRefs(webBrowser));
 
289
 
 
290
  // and set the visibility on the thing
 
291
  nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(webBrowser);
 
292
  baseWindow->SetVisibility(PR_TRUE);
 
293
}
 
294
 
 
295
void
 
296
EmbedPrivate::Hide(void)
 
297
{
 
298
  // Get the nsIWebBrowser object for our embedded window.
 
299
  nsCOMPtr<nsIWebBrowser> webBrowser;
 
300
  mWindow->GetWebBrowser(getter_AddRefs(webBrowser));
 
301
 
 
302
  // and set the visibility on the thing
 
303
  nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(webBrowser);
 
304
  baseWindow->SetVisibility(PR_FALSE);
 
305
}
 
306
 
 
307
void
 
308
EmbedPrivate::Resize(PRUint32 aWidth, PRUint32 aHeight)
 
309
{
 
310
  mWindow->SetDimensions(nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION |
 
311
                         nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_INNER,
 
312
                         0, 0, aWidth, aHeight);
 
313
}
 
314
 
 
315
void
 
316
EmbedPrivate::Destroy(void)
 
317
{
 
318
  // This flag might have been set from
 
319
  // EmbedWindow::DestroyBrowserWindow() as well if someone used a
 
320
  // window.close() or something or some other script action to close
 
321
  // the window.  No harm setting it again.
 
322
  mIsDestroyed = PR_TRUE;
 
323
 
 
324
  // Get the nsIWebBrowser object for our embedded window.
 
325
  nsCOMPtr<nsIWebBrowser> webBrowser;
 
326
  mWindow->GetWebBrowser(getter_AddRefs(webBrowser));
 
327
 
 
328
  // Release our progress listener
 
329
  nsCOMPtr<nsISupportsWeakReference> supportsWeak;
 
330
  supportsWeak = do_QueryInterface(mProgressGuard);
 
331
  nsCOMPtr<nsIWeakReference> weakRef;
 
332
  supportsWeak->GetWeakReference(getter_AddRefs(weakRef));
 
333
  webBrowser->RemoveWebBrowserListener(weakRef,
 
334
                                       nsIWebProgressListener::GetIID());
 
335
  weakRef = nsnull;
 
336
  supportsWeak = nsnull;
 
337
 
 
338
  // Release our content listener
 
339
  webBrowser->SetParentURIContentListener(nsnull);
 
340
  mContentListenerGuard = nsnull;
 
341
  mContentListener = nsnull;
 
342
 
 
343
  // Now that we have removed the listener, release our progress
 
344
  // object
 
345
  mProgressGuard = nsnull;
 
346
  mProgress = nsnull;
 
347
 
 
348
  // detach our event listeners and release the event receiver
 
349
  DetachListeners();
 
350
  if (mEventReceiver)
 
351
    mEventReceiver = nsnull;
 
352
  
 
353
  // destroy our child window
 
354
  mWindow->ReleaseChildren();
 
355
 
 
356
  // release navigation
 
357
  mNavigation = nsnull;
 
358
 
 
359
  // release session history
 
360
  mSessionHistory = nsnull;
 
361
 
 
362
  mOwningWidget = nsnull;
 
363
 
 
364
  mMozWindowWidget = 0;
 
365
}
 
366
 
 
367
void
 
368
EmbedPrivate::SetURI(const char *aURI)
 
369
{
 
370
#ifdef MOZ_WIDGET_GTK
 
371
  mURI.AssignWithConversion(aURI);
 
372
#endif
 
373
 
 
374
#ifdef MOZ_WIDGET_GTK2
 
375
  mURI.Assign(NS_ConvertUTF8toUCS2(aURI));
 
376
#endif
 
377
}
 
378
 
 
379
void
 
380
EmbedPrivate::LoadCurrentURI(void)
 
381
{
 
382
  if (mURI.Length())
 
383
    mNavigation->LoadURI(mURI.get(),                        // URI string
 
384
                         nsIWebNavigation::LOAD_FLAGS_NONE, // Load flags
 
385
                         nsnull,                            // Referring URI
 
386
                         nsnull,                            // Post data
 
387
                         nsnull);                           // extra headers
 
388
}
 
389
 
 
390
void
 
391
EmbedPrivate::Reload(PRUint32 reloadFlags)
 
392
{
 
393
  /* Use the session history if it is available, this
 
394
   * allows framesets to reload correctly */
 
395
  nsCOMPtr<nsIWebNavigation> wn;
 
396
 
 
397
  if (mSessionHistory) {
 
398
    wn = do_QueryInterface(mSessionHistory);
 
399
  }
 
400
  if (!wn)
 
401
    wn = mNavigation;
 
402
 
 
403
  if (wn)
 
404
    wn->Reload(reloadFlags);
 
405
}
 
406
 
 
407
 
 
408
/* static */
 
409
void
 
410
EmbedPrivate::PushStartup(void)
 
411
{
 
412
  // increment the number of widgets
 
413
  sWidgetCount++;
 
414
  
 
415
  // if this is the first widget, fire up xpcom
 
416
  if (sWidgetCount == 1) {
 
417
    nsresult rv;
 
418
    nsCOMPtr<nsILocalFile> binDir;
 
419
    
 
420
    if (sCompPath) {
 
421
      rv = NS_NewNativeLocalFile(nsDependentCString(sCompPath), 1, getter_AddRefs(binDir));
 
422
      if (NS_FAILED(rv))
 
423
        return;
 
424
    }
 
425
 
 
426
#ifdef _BUILD_STATIC_BIN
 
427
    // Initialize XPCOM's module info table
 
428
    NSGetStaticModuleInfo = gtk_getModuleInfo;
 
429
#endif
 
430
 
 
431
    rv = NS_InitEmbedding(binDir, sAppFileLocProvider);
 
432
    if (NS_FAILED(rv))
 
433
      return;
 
434
 
 
435
    // we no longer need a reference to the DirectoryServiceProvider
 
436
    if (sAppFileLocProvider) {
 
437
      NS_RELEASE(sAppFileLocProvider);
 
438
      sAppFileLocProvider = nsnull;
 
439
    }
 
440
 
 
441
    rv = StartupProfile();
 
442
    NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Warning: Failed to start up profiles.\n");
 
443
 
 
444
    rv = RegisterAppComponents();
 
445
    NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Warning: Failed to register app components.\n");
 
446
 
 
447
    // XXX startup appshell service?
 
448
    // XXX create offscreen window for appshell service?
 
449
    // XXX remove X prop from offscreen window?
 
450
    
 
451
    nsCOMPtr<nsIAppShell> appShell;
 
452
    appShell = do_CreateInstance(kAppShellCID);
 
453
    if (!appShell) {
 
454
      NS_WARNING("Failed to create appshell in EmbedPrivate::PushStartup!\n");
 
455
      return;
 
456
    }
 
457
    sAppShell = appShell.get();
 
458
    NS_ADDREF(sAppShell);
 
459
    sAppShell->Create(0, nsnull);
 
460
    sAppShell->Spinup();
 
461
  }
 
462
}
 
463
 
 
464
/* static */
 
465
void
 
466
EmbedPrivate::PopStartup(void)
 
467
{
 
468
  sWidgetCount--;
 
469
  if (sWidgetCount == 0) {
 
470
 
 
471
    // destroy the offscreen window
 
472
    DestroyOffscreenWindow();
 
473
    
 
474
    // shut down the profiles
 
475
    ShutdownProfile();
 
476
 
 
477
    if (sAppShell) {
 
478
      // Shutdown the appshell service.
 
479
      sAppShell->Spindown();
 
480
      NS_RELEASE(sAppShell);
 
481
      sAppShell = 0;
 
482
    }
 
483
 
 
484
    // shut down XPCOM/Embedding
 
485
    NS_TermEmbedding();
 
486
  }
 
487
}
 
488
 
 
489
/* static */
 
490
void
 
491
EmbedPrivate::SetCompPath(char *aPath)
 
492
{
 
493
  if (sCompPath)
 
494
    free(sCompPath);
 
495
  if (aPath)
 
496
    sCompPath = strdup(aPath);
 
497
  else
 
498
    sCompPath = nsnull;
 
499
}
 
500
 
 
501
/* static */
 
502
void
 
503
EmbedPrivate::SetAppComponents(const nsModuleComponentInfo* aComps,
 
504
                               int aNumComponents)
 
505
{
 
506
  sAppComps = aComps;
 
507
  sNumAppComps = aNumComponents;
 
508
}
 
509
 
 
510
/* static */
 
511
void
 
512
EmbedPrivate::SetProfilePath(char *aDir, char *aName)
 
513
{
 
514
  if (sProfileDir) {
 
515
    nsMemory::Free(sProfileDir);
 
516
    sProfileDir = nsnull;
 
517
  }
 
518
 
 
519
  if (sProfileName) {
 
520
    nsMemory::Free(sProfileName);
 
521
    sProfileName = nsnull;
 
522
  }
 
523
 
 
524
  if (aDir)
 
525
    sProfileDir = (char *)nsMemory::Clone(aDir, strlen(aDir) + 1);
 
526
  
 
527
  if (aName)
 
528
    sProfileName = (char *)nsMemory::Clone(aName, strlen(aDir) + 1);
 
529
}
 
530
 
 
531
void 
 
532
EmbedPrivate::SetDirectoryServiceProvider(nsIDirectoryServiceProvider * appFileLocProvider) 
 
533
{
 
534
  if (sAppFileLocProvider)
 
535
    NS_RELEASE(sAppFileLocProvider);
 
536
  
 
537
  if (appFileLocProvider) {
 
538
    sAppFileLocProvider = appFileLocProvider;
 
539
    NS_ADDREF(sAppFileLocProvider);
 
540
  }
 
541
}
 
542
 
 
543
nsresult
 
544
EmbedPrivate::OpenStream(const char *aBaseURI, const char *aContentType)
 
545
{
 
546
  nsresult rv;
 
547
 
 
548
  if (!mStream) {
 
549
    mStream = new EmbedStream();
 
550
    mStreamGuard = do_QueryInterface(mStream);
 
551
    mStream->InitOwner(this);
 
552
    rv = mStream->Init();
 
553
    if (NS_FAILED(rv))
 
554
      return rv;
 
555
  }
 
556
 
 
557
  rv = mStream->OpenStream(aBaseURI, aContentType);
 
558
  return rv;
 
559
}
 
560
 
 
561
nsresult
 
562
EmbedPrivate::AppendToStream(const char *aData, PRInt32 aLen)
 
563
{
 
564
  if (!mStream)
 
565
    return NS_ERROR_FAILURE;
 
566
 
 
567
  // Attach listeners to this document since in some cases we don't
 
568
  // get updates for content added this way.
 
569
  ContentStateChange();
 
570
 
 
571
  return mStream->AppendToStream(aData, aLen);
 
572
}
 
573
 
 
574
nsresult
 
575
EmbedPrivate::CloseStream(void)
 
576
{
 
577
  nsresult rv;
 
578
 
 
579
  if (!mStream)
 
580
    return NS_ERROR_FAILURE;
 
581
  rv = mStream->CloseStream();
 
582
 
 
583
  // release
 
584
  mStream = 0;
 
585
  mStreamGuard = 0;
 
586
 
 
587
  return rv;
 
588
}
 
589
 
 
590
/* static */
 
591
EmbedPrivate *
 
592
EmbedPrivate::FindPrivateForBrowser(nsIWebBrowserChrome *aBrowser)
 
593
{
 
594
  if (!sWindowList)
 
595
    return nsnull;
 
596
 
 
597
  // Get the number of browser windows.
 
598
  PRInt32 count = sWindowList->Count();
 
599
  // This function doesn't get called very often at all ( only when
 
600
  // creating a new window ) so it's OK to walk the list of open
 
601
  // windows.
 
602
  for (int i = 0; i < count; i++) {
 
603
    EmbedPrivate *tmpPrivate = NS_STATIC_CAST(EmbedPrivate *,
 
604
                                              sWindowList->ElementAt(i));
 
605
    // get the browser object for that window
 
606
    nsIWebBrowserChrome *chrome = NS_STATIC_CAST(nsIWebBrowserChrome *,
 
607
                                                 tmpPrivate->mWindow);
 
608
    if (chrome == aBrowser)
 
609
      return tmpPrivate;
 
610
  }
 
611
 
 
612
  return nsnull;
 
613
}
 
614
 
 
615
void
 
616
EmbedPrivate::ContentStateChange(void)
 
617
{
 
618
 
 
619
  // we don't attach listeners to chrome
 
620
  if (mListenersAttached && !mIsChrome)
 
621
    return;
 
622
 
 
623
  GetListener();
 
624
 
 
625
  if (!mEventReceiver)
 
626
    return;
 
627
  
 
628
  AttachListeners();
 
629
 
 
630
}
 
631
 
 
632
void
 
633
EmbedPrivate::ContentFinishedLoading(void)
 
634
{
 
635
  if (mIsChrome) {
 
636
    // We're done loading.
 
637
    mChromeLoaded = PR_TRUE;
 
638
 
 
639
    // get the web browser
 
640
    nsCOMPtr<nsIWebBrowser> webBrowser;
 
641
    mWindow->GetWebBrowser(getter_AddRefs(webBrowser));
 
642
    
 
643
    // get the content DOM window for that web browser
 
644
    nsCOMPtr<nsIDOMWindow> domWindow;
 
645
    webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
 
646
    if (!domWindow) {
 
647
      NS_WARNING("no dom window in content finished loading\n");
 
648
      return;
 
649
    }
 
650
    
 
651
    // resize the content
 
652
    domWindow->SizeToContent();
 
653
 
 
654
    // and since we're done loading show the window, assuming that the
 
655
    // visibility flag has been set.
 
656
    PRBool visibility;
 
657
    mWindow->GetVisibility(&visibility);
 
658
    if (visibility)
 
659
      mWindow->SetVisibility(PR_TRUE);
 
660
  }
 
661
}
 
662
 
 
663
// handle focus in and focus out events
 
664
void
 
665
EmbedPrivate::TopLevelFocusIn(void)
 
666
{
 
667
  if (mIsDestroyed)
 
668
    return;
 
669
 
 
670
  nsCOMPtr<nsPIDOMWindow> piWin;
 
671
  GetPIDOMWindow(getter_AddRefs(piWin));
 
672
 
 
673
  if (!piWin)
 
674
    return;
 
675
 
 
676
  nsCOMPtr<nsIFocusController> focusController;
 
677
  piWin->GetRootFocusController(getter_AddRefs(focusController));
 
678
  if (focusController)
 
679
    focusController->SetActive(PR_TRUE);
 
680
}
 
681
 
 
682
void
 
683
EmbedPrivate::TopLevelFocusOut(void)
 
684
{
 
685
  if (mIsDestroyed)
 
686
    return;
 
687
 
 
688
  nsCOMPtr<nsPIDOMWindow> piWin;
 
689
  GetPIDOMWindow(getter_AddRefs(piWin));
 
690
 
 
691
  if (!piWin)
 
692
    return;
 
693
 
 
694
  nsCOMPtr<nsIFocusController> focusController;
 
695
  piWin->GetRootFocusController(getter_AddRefs(focusController));
 
696
  if (focusController)
 
697
    focusController->SetActive(PR_FALSE);
 
698
}
 
699
 
 
700
void
 
701
EmbedPrivate::ChildFocusIn(void)
 
702
{
 
703
  if (mIsDestroyed)
 
704
    return;
 
705
 
 
706
  nsCOMPtr<nsPIDOMWindow> piWin;
 
707
  GetPIDOMWindow(getter_AddRefs(piWin));
 
708
 
 
709
  if (!piWin)
 
710
    return;
 
711
 
 
712
  piWin->Activate();
 
713
}
 
714
 
 
715
void
 
716
EmbedPrivate::ChildFocusOut(void)
 
717
{
 
718
  if (mIsDestroyed)
 
719
    return;
 
720
 
 
721
  nsCOMPtr<nsPIDOMWindow> piWin;
 
722
  GetPIDOMWindow(getter_AddRefs(piWin));
 
723
 
 
724
  if (!piWin)
 
725
    return;
 
726
 
 
727
  piWin->Deactivate();
 
728
 
 
729
  // but the window is still active until the toplevel gets a focus
 
730
  // out
 
731
  nsCOMPtr<nsIFocusController> focusController;
 
732
  piWin->GetRootFocusController(getter_AddRefs(focusController));
 
733
  if (focusController)
 
734
    focusController->SetActive(PR_TRUE);
 
735
 
 
736
}
 
737
 
 
738
// Get the event listener for the chrome event handler.
 
739
 
 
740
void
 
741
EmbedPrivate::GetListener(void)
 
742
{
 
743
  if (mEventReceiver)
 
744
    return;
 
745
 
 
746
  nsCOMPtr<nsPIDOMWindow> piWin;
 
747
  GetPIDOMWindow(getter_AddRefs(piWin));
 
748
 
 
749
  if (!piWin)
 
750
    return;
 
751
 
 
752
  nsCOMPtr<nsIChromeEventHandler> chromeHandler;
 
753
  piWin->GetChromeEventHandler(getter_AddRefs(chromeHandler));
 
754
 
 
755
  mEventReceiver = do_QueryInterface(chromeHandler);
 
756
}
 
757
 
 
758
// attach key and mouse event listeners
 
759
 
 
760
void
 
761
EmbedPrivate::AttachListeners(void)
 
762
{
 
763
  if (!mEventReceiver || mListenersAttached)
 
764
    return;
 
765
 
 
766
  nsIDOMEventListener *eventListener =
 
767
    NS_STATIC_CAST(nsIDOMEventListener *,
 
768
                   NS_STATIC_CAST(nsIDOMKeyListener *, mEventListener));
 
769
 
 
770
  // add the key listener
 
771
  nsresult rv;
 
772
  rv = mEventReceiver->AddEventListenerByIID(eventListener,
 
773
                                             NS_GET_IID(nsIDOMKeyListener));
 
774
  if (NS_FAILED(rv)) {
 
775
    NS_WARNING("Failed to add key listener\n");
 
776
    return;
 
777
  }
 
778
 
 
779
  rv = mEventReceiver->AddEventListenerByIID(eventListener,
 
780
                                             NS_GET_IID(nsIDOMMouseListener));
 
781
  if (NS_FAILED(rv)) {
 
782
    NS_WARNING("Failed to add mouse listener\n");
 
783
    return;
 
784
  }
 
785
 
 
786
  // ok, all set.
 
787
  mListenersAttached = PR_TRUE;
 
788
}
 
789
 
 
790
void
 
791
EmbedPrivate::DetachListeners(void)
 
792
{
 
793
  if (!mListenersAttached || !mEventReceiver)
 
794
    return;
 
795
 
 
796
  nsIDOMEventListener *eventListener =
 
797
    NS_STATIC_CAST(nsIDOMEventListener *,
 
798
                   NS_STATIC_CAST(nsIDOMKeyListener *, mEventListener));
 
799
 
 
800
  nsresult rv;
 
801
  rv = mEventReceiver->RemoveEventListenerByIID(eventListener,
 
802
                                                NS_GET_IID(nsIDOMKeyListener));
 
803
  if (NS_FAILED(rv)) {
 
804
    NS_WARNING("Failed to remove key listener\n");
 
805
    return;
 
806
  }
 
807
 
 
808
  rv =
 
809
    mEventReceiver->RemoveEventListenerByIID(eventListener,
 
810
                                             NS_GET_IID(nsIDOMMouseListener));
 
811
  if (NS_FAILED(rv)) {
 
812
    NS_WARNING("Failed to remove mouse listener\n");
 
813
    return;
 
814
  }
 
815
 
 
816
 
 
817
  mListenersAttached = PR_FALSE;
 
818
}
 
819
 
 
820
nsresult
 
821
EmbedPrivate::GetPIDOMWindow(nsPIDOMWindow **aPIWin)
 
822
{
 
823
  *aPIWin = nsnull;
 
824
 
 
825
  // get the web browser
 
826
  nsCOMPtr<nsIWebBrowser> webBrowser;
 
827
  mWindow->GetWebBrowser(getter_AddRefs(webBrowser));
 
828
 
 
829
  // get the content DOM window for that web browser
 
830
  nsCOMPtr<nsIDOMWindow> domWindow;
 
831
  webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
 
832
  if (!domWindow)
 
833
    return NS_ERROR_FAILURE;
 
834
 
 
835
  // get the private DOM window
 
836
  nsCOMPtr<nsPIDOMWindow> domWindowPrivate = do_QueryInterface(domWindow);
 
837
  // and the root window for that DOM window
 
838
  nsCOMPtr<nsIDOMWindowInternal> rootWindow;
 
839
  domWindowPrivate->GetPrivateRoot(getter_AddRefs(rootWindow));
 
840
  
 
841
  nsCOMPtr<nsIChromeEventHandler> chromeHandler;
 
842
  nsCOMPtr<nsPIDOMWindow> piWin(do_QueryInterface(rootWindow));
 
843
 
 
844
  *aPIWin = piWin.get();
 
845
 
 
846
  if (*aPIWin) {
 
847
    NS_ADDREF(*aPIWin);
 
848
    return NS_OK;
 
849
  }
 
850
 
 
851
  return NS_ERROR_FAILURE;
 
852
 
 
853
}
 
854
 
 
855
#ifdef MOZ_ACCESSIBILITY_ATK
 
856
void *
 
857
EmbedPrivate::GetAtkObjectForCurrentDocument()
 
858
{
 
859
  if (!mNavigation)
 
860
    return nsnull;
 
861
 
 
862
  nsCOMPtr<nsIAccessibilityService> accService =
 
863
    do_GetService("@mozilla.org/accessibilityService;1");
 
864
  if (accService) {
 
865
    //get current document
 
866
    nsCOMPtr<nsIDOMDocument> domDoc;
 
867
    mNavigation->GetDocument(getter_AddRefs(domDoc));
 
868
    NS_ENSURE_TRUE(domDoc, nsnull);
 
869
 
 
870
    nsCOMPtr<nsIDOMNode> domNode(do_QueryInterface(domDoc));
 
871
    NS_ENSURE_TRUE(domNode, nsnull);
 
872
 
 
873
    nsCOMPtr<nsIAccessible> acc;
 
874
    accService->GetAccessibleFor(domNode, getter_AddRefs(acc));
 
875
    NS_ENSURE_TRUE(acc, nsnull);
 
876
 
 
877
    void *atkObj = nsnull;
 
878
    if (NS_SUCCEEDED(acc->GetNativeInterface(&atkObj)))
 
879
      return atkObj;
 
880
  }
 
881
  return nsnull;
 
882
}
 
883
#endif /* MOZ_ACCESSIBILITY_ATK */
 
884
 
 
885
/* static */
 
886
nsresult
 
887
EmbedPrivate::StartupProfile(void)
 
888
{
 
889
  // initialize profiles
 
890
  if (sProfileDir && sProfileName) {
 
891
    nsresult rv;
 
892
    nsCOMPtr<nsILocalFile> profileDir;
 
893
    NS_NewNativeLocalFile(nsDependentCString(sProfileDir), PR_TRUE,
 
894
                          getter_AddRefs(profileDir));
 
895
    if (!profileDir)
 
896
      return NS_ERROR_FAILURE;
 
897
    rv = profileDir->AppendNative(nsDependentCString(sProfileName));
 
898
    if (NS_FAILED(rv))
 
899
      return NS_ERROR_FAILURE;
 
900
 
 
901
    nsCOMPtr<nsProfileDirServiceProvider> locProvider;
 
902
    NS_NewProfileDirServiceProvider(PR_TRUE, getter_AddRefs(locProvider));
 
903
    if (!locProvider)
 
904
      return NS_ERROR_FAILURE;
 
905
    rv = locProvider->Register();
 
906
    if (NS_FAILED(rv))
 
907
      return rv;
 
908
    rv = locProvider->SetProfileDir(profileDir);
 
909
    if (NS_FAILED(rv))
 
910
      return rv;
 
911
    // Keep a ref so we can shut it down.
 
912
    NS_ADDREF(sProfileDirServiceProvider = locProvider);
 
913
 
 
914
    // get prefs
 
915
    nsCOMPtr<nsIPref> pref;
 
916
    pref = do_GetService(NS_PREF_CONTRACTID);
 
917
    if (!pref)
 
918
      return NS_ERROR_FAILURE;
 
919
    sPrefs = pref.get();
 
920
    NS_ADDREF(sPrefs);
 
921
  }
 
922
  return NS_OK;
 
923
}
 
924
 
 
925
/* static */
 
926
void
 
927
EmbedPrivate::ShutdownProfile(void)
 
928
{
 
929
  if (sProfileDirServiceProvider) {
 
930
    sProfileDirServiceProvider->Shutdown();
 
931
    NS_RELEASE(sProfileDirServiceProvider);
 
932
    sProfileDirServiceProvider = 0;
 
933
  }
 
934
  if (sPrefs) {
 
935
    NS_RELEASE(sPrefs);
 
936
    sPrefs = 0;
 
937
  }
 
938
}
 
939
 
 
940
/* static */
 
941
nsresult
 
942
EmbedPrivate::RegisterAppComponents(void)
 
943
{
 
944
  nsCOMPtr<nsIComponentRegistrar> cr;
 
945
  nsresult rv = NS_GetComponentRegistrar(getter_AddRefs(cr));
 
946
  NS_ENSURE_SUCCESS(rv, rv);
 
947
 
 
948
  for (int i = 0; i < sNumAppComps; ++i) {
 
949
    nsCOMPtr<nsIGenericFactory> componentFactory;
 
950
    rv = NS_NewGenericFactory(getter_AddRefs(componentFactory),
 
951
                              &(sAppComps[i]));
 
952
    if (NS_FAILED(rv)) {
 
953
      NS_WARNING("Unable to create factory for component");
 
954
      continue;  // don't abort registering other components
 
955
    }
 
956
 
 
957
    rv = cr->RegisterFactory(sAppComps[i].mCID, sAppComps[i].mDescription,
 
958
                             sAppComps[i].mContractID, componentFactory);
 
959
    NS_ASSERTION(NS_SUCCEEDED(rv), "Unable to register factory for component");
 
960
  }
 
961
 
 
962
  return rv;
 
963
}
 
964
                             
 
965
/* static */
 
966
void
 
967
EmbedPrivate::EnsureOffscreenWindow(void)
 
968
{
 
969
  if (sOffscreenWindow)
 
970
    return;
 
971
  sOffscreenWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 
972
  gtk_widget_realize(sOffscreenWindow);
 
973
  sOffscreenFixed = gtk_fixed_new();
 
974
  gtk_container_add(GTK_CONTAINER(sOffscreenWindow), sOffscreenFixed);
 
975
  gtk_widget_realize(sOffscreenFixed);
 
976
}
 
977
 
 
978
/* static */
 
979
void
 
980
EmbedPrivate::DestroyOffscreenWindow(void)
 
981
{
 
982
  if (!sOffscreenWindow)
 
983
    return;
 
984
  gtk_widget_destroy(sOffscreenWindow);
 
985
  sOffscreenWindow = 0;
 
986
}