1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 : * vim: sw=2 ts=8 et :
3 : */
4 : /* ***** BEGIN LICENSE BLOCK *****
5 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 : *
7 : * The contents of this file are subject to the Mozilla Public License Version
8 : * 1.1 (the "License"); you may not use this file except in compliance with
9 : * the License. You may obtain a copy of the License at:
10 : * http://www.mozilla.org/MPL/
11 : *
12 : * Software distributed under the License is distributed on an "AS IS" basis,
13 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 : * for the specific language governing rights and limitations under the
15 : * License.
16 : *
17 : * The Original Code is Mozilla Code.
18 : *
19 : * The Initial Developer of the Original Code is
20 : * The Mozilla Foundation
21 : * Portions created by the Initial Developer are Copyright (C) 2010
22 : * the Initial Developer. All Rights Reserved.
23 : *
24 : * Contributor(s):
25 : * Chris Jones <jones.chris.g@gmail.com>
26 : *
27 : * Alternatively, the contents of this file may be used under the terms of
28 : * either the GNU General Public License Version 2 or later (the "GPL"), or
29 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 : * in which case the provisions of the GPL or the LGPL are applicable instead
31 : * of those above. If you wish to allow use of your version of this file only
32 : * under the terms of either the GPL or the LGPL, and not to allow others to
33 : * use your version of this file under the terms of the MPL, indicate your
34 : * decision by deleting the provisions above and replace them with the notice
35 : * and other provisions required by the GPL or the LGPL. If you do not delete
36 : * the provisions above, a recipient may use your version of this file under
37 : * the terms of any one of the MPL, the GPL or the LGPL.
38 : *
39 : * ***** END LICENSE BLOCK ***** */
40 :
41 : #include "mozilla/dom/PBrowserChild.h"
42 : #include "BasicLayers.h"
43 : #if defined(MOZ_ENABLE_D3D10_LAYER)
44 : # include "LayerManagerD3D10.h"
45 : #endif
46 :
47 : #include "gfxPlatform.h"
48 : #include "PuppetWidget.h"
49 :
50 : using namespace mozilla::layers;
51 : using namespace mozilla::widget;
52 : using namespace mozilla::dom;
53 :
54 : static void
55 0 : InvalidateRegion(nsIWidget* aWidget, const nsIntRegion& aRegion)
56 : {
57 0 : nsIntRegionRectIterator it(aRegion);
58 0 : while(const nsIntRect* r = it.Next()) {
59 0 : aWidget->Invalidate(*r);
60 : }
61 0 : }
62 :
63 : /*static*/ already_AddRefed<nsIWidget>
64 0 : nsIWidget::CreatePuppetWidget(PBrowserChild *aTabChild)
65 : {
66 0 : NS_ABORT_IF_FALSE(nsIWidget::UsePuppetWidgets(),
67 : "PuppetWidgets not allowed in this configuration");
68 :
69 0 : nsCOMPtr<nsIWidget> widget = new PuppetWidget(aTabChild);
70 0 : return widget.forget();
71 : }
72 :
73 : namespace mozilla {
74 : namespace widget {
75 :
76 : static bool
77 0 : IsPopup(const nsWidgetInitData* aInitData)
78 : {
79 0 : return aInitData && aInitData->mWindowType == eWindowType_popup;
80 : }
81 :
82 : static bool
83 0 : MightNeedIMEFocus(const nsWidgetInitData* aInitData)
84 : {
85 : // In the puppet-widget world, popup widgets are just dummies and
86 : // shouldn't try to mess with IME state.
87 0 : return !IsPopup(aInitData);
88 : }
89 :
90 :
91 : // Arbitrary, fungible.
92 : const size_t PuppetWidget::kMaxDimension = 4000;
93 :
94 0 : NS_IMPL_ISUPPORTS_INHERITED1(PuppetWidget, nsBaseWidget,
95 : nsISupportsWeakReference)
96 :
97 0 : PuppetWidget::PuppetWidget(PBrowserChild *aTabChild)
98 : : mTabChild(aTabChild)
99 0 : , mDPI(-1)
100 : {
101 0 : MOZ_COUNT_CTOR(PuppetWidget);
102 0 : }
103 :
104 0 : PuppetWidget::~PuppetWidget()
105 : {
106 0 : MOZ_COUNT_DTOR(PuppetWidget);
107 0 : }
108 :
109 : NS_IMETHODIMP
110 0 : PuppetWidget::Create(nsIWidget *aParent,
111 : nsNativeWidget aNativeParent,
112 : const nsIntRect &aRect,
113 : EVENT_CALLBACK aHandleEventFunction,
114 : nsDeviceContext *aContext,
115 : nsWidgetInitData *aInitData)
116 : {
117 0 : NS_ABORT_IF_FALSE(!aNativeParent, "got a non-Puppet native parent");
118 :
119 0 : BaseCreate(nsnull, aRect, aHandleEventFunction, aContext, aInitData);
120 :
121 0 : mBounds = aRect;
122 0 : mEnabled = true;
123 0 : mVisible = true;
124 :
125 0 : mSurface = gfxPlatform::GetPlatform()
126 : ->CreateOffscreenSurface(gfxIntSize(1, 1),
127 0 : gfxASurface::ContentFromFormat(gfxASurface::ImageFormatARGB32));
128 :
129 0 : mIMEComposing = false;
130 0 : if (MightNeedIMEFocus(aInitData)) {
131 : PRUint32 chromeSeqno;
132 0 : mTabChild->SendNotifyIMEFocus(false, &mIMEPreference, &chromeSeqno);
133 0 : mIMELastBlurSeqno = mIMELastReceivedSeqno = chromeSeqno;
134 : }
135 :
136 0 : PuppetWidget* parent = static_cast<PuppetWidget*>(aParent);
137 0 : if (parent) {
138 0 : parent->SetChild(this);
139 0 : mLayerManager = parent->GetLayerManager();
140 : }
141 : else {
142 0 : Resize(mBounds.x, mBounds.y, mBounds.width, mBounds.height, false);
143 : }
144 :
145 0 : return NS_OK;
146 : }
147 :
148 : already_AddRefed<nsIWidget>
149 0 : PuppetWidget::CreateChild(const nsIntRect &aRect,
150 : EVENT_CALLBACK aHandleEventFunction,
151 : nsDeviceContext *aContext,
152 : nsWidgetInitData *aInitData,
153 : bool aForceUseIWidgetParent)
154 : {
155 0 : bool isPopup = IsPopup(aInitData);
156 0 : nsCOMPtr<nsIWidget> widget = nsIWidget::CreatePuppetWidget(mTabChild);
157 : return ((widget &&
158 0 : NS_SUCCEEDED(widget->Create(isPopup ? nsnull: this, nsnull, aRect,
159 : aHandleEventFunction,
160 : aContext, aInitData))) ?
161 0 : widget.forget() : nsnull);
162 : }
163 :
164 : NS_IMETHODIMP
165 0 : PuppetWidget::Destroy()
166 : {
167 0 : Base::OnDestroy();
168 0 : Base::Destroy();
169 0 : mPaintTask.Revoke();
170 0 : mChild = nsnull;
171 0 : if (mLayerManager) {
172 0 : mLayerManager->Destroy();
173 : }
174 0 : mLayerManager = nsnull;
175 0 : mTabChild = nsnull;
176 0 : return NS_OK;
177 : }
178 :
179 : NS_IMETHODIMP
180 0 : PuppetWidget::Show(bool aState)
181 : {
182 0 : NS_ASSERTION(mEnabled,
183 : "does it make sense to Show()/Hide() a disabled widget?");
184 :
185 0 : bool wasVisible = mVisible;
186 0 : mVisible = aState;
187 :
188 0 : if (!wasVisible && mVisible) {
189 0 : Resize(mBounds.width, mBounds.height, false);
190 : }
191 :
192 0 : return NS_OK;
193 : }
194 :
195 : NS_IMETHODIMP
196 0 : PuppetWidget::Resize(PRInt32 aWidth,
197 : PRInt32 aHeight,
198 : bool aRepaint)
199 : {
200 0 : nsIntRect oldBounds = mBounds;
201 0 : mBounds.SizeTo(nsIntSize(aWidth, aHeight));
202 :
203 0 : if (mChild) {
204 0 : return mChild->Resize(aWidth, aHeight, aRepaint);
205 : }
206 :
207 : // XXX: roc says that |aRepaint| dictates whether or not to
208 : // invalidate the expanded area
209 0 : if (oldBounds.Size() < mBounds.Size() && aRepaint) {
210 0 : nsIntRegion dirty(mBounds);
211 0 : dirty.Sub(dirty, oldBounds);
212 0 : InvalidateRegion(this, dirty);
213 : }
214 :
215 0 : if (!oldBounds.IsEqualEdges(mBounds)) {
216 0 : DispatchResizeEvent();
217 : }
218 :
219 0 : return NS_OK;
220 : }
221 :
222 : NS_IMETHODIMP
223 0 : PuppetWidget::SetFocus(bool aRaise)
224 : {
225 : // XXX/cjones: someone who knows about event handling needs to
226 : // decide how this should work.
227 0 : return NS_OK;
228 : }
229 :
230 : NS_IMETHODIMP
231 0 : PuppetWidget::Invalidate(const nsIntRect& aRect)
232 : {
233 : #ifdef DEBUG
234 : debug_DumpInvalidate(stderr, this, &aRect,
235 0 : nsCAutoString("PuppetWidget"), nsnull);
236 : #endif
237 :
238 0 : if (mChild) {
239 0 : return mChild->Invalidate(aRect);
240 : }
241 :
242 0 : mDirtyRegion.Or(mDirtyRegion, aRect);
243 :
244 0 : if (!mDirtyRegion.IsEmpty() && !mPaintTask.IsPending()) {
245 0 : mPaintTask = new PaintTask(this);
246 0 : return NS_DispatchToCurrentThread(mPaintTask.get());
247 : }
248 :
249 0 : return NS_OK;
250 : }
251 :
252 : void
253 0 : PuppetWidget::InitEvent(nsGUIEvent& event, nsIntPoint* aPoint)
254 : {
255 0 : if (nsnull == aPoint) {
256 0 : event.refPoint.x = 0;
257 0 : event.refPoint.y = 0;
258 : }
259 : else {
260 : // use the point override if provided
261 0 : event.refPoint.x = aPoint->x;
262 0 : event.refPoint.y = aPoint->y;
263 : }
264 0 : event.time = PR_Now() / 1000;
265 0 : }
266 :
267 : NS_IMETHODIMP
268 0 : PuppetWidget::DispatchEvent(nsGUIEvent* event, nsEventStatus& aStatus)
269 : {
270 : #ifdef DEBUG
271 : debug_DumpEvent(stdout, event->widget, event,
272 0 : nsCAutoString("PuppetWidget"), nsnull);
273 : #endif
274 :
275 0 : NS_ABORT_IF_FALSE(!mChild || mChild->mWindowType == eWindowType_popup,
276 : "Unexpected event dispatch!");
277 :
278 0 : aStatus = nsEventStatus_eIgnore;
279 :
280 0 : NS_ABORT_IF_FALSE(mViewCallback, "No view callback!");
281 :
282 0 : if (event->message == NS_COMPOSITION_START) {
283 0 : mIMEComposing = true;
284 : }
285 0 : switch (event->eventStructType) {
286 : case NS_COMPOSITION_EVENT:
287 0 : mIMELastReceivedSeqno = static_cast<nsCompositionEvent*>(event)->seqno;
288 0 : if (mIMELastReceivedSeqno < mIMELastBlurSeqno)
289 0 : return NS_OK;
290 0 : break;
291 : case NS_TEXT_EVENT:
292 0 : mIMELastReceivedSeqno = static_cast<nsTextEvent*>(event)->seqno;
293 0 : if (mIMELastReceivedSeqno < mIMELastBlurSeqno)
294 0 : return NS_OK;
295 0 : break;
296 : case NS_SELECTION_EVENT:
297 0 : mIMELastReceivedSeqno = static_cast<nsSelectionEvent*>(event)->seqno;
298 0 : if (mIMELastReceivedSeqno < mIMELastBlurSeqno)
299 0 : return NS_OK;
300 0 : break;
301 : }
302 0 : aStatus = (*mViewCallback)(event);
303 :
304 0 : if (event->message == NS_COMPOSITION_END) {
305 0 : mIMEComposing = false;
306 : }
307 :
308 0 : return NS_OK;
309 : }
310 :
311 : LayerManager*
312 0 : PuppetWidget::GetLayerManager(PLayersChild* aShadowManager,
313 : LayersBackend aBackendHint,
314 : LayerManagerPersistence aPersistence,
315 : bool* aAllowRetaining)
316 : {
317 0 : if (!mLayerManager) {
318 : // The backend hint is a temporary placeholder until Azure, when
319 : // all content-process layer managers will be BasicLayerManagers.
320 : #if defined(MOZ_ENABLE_D3D10_LAYER)
321 : if (LayerManager::LAYERS_D3D10 == aBackendHint) {
322 : nsRefPtr<LayerManagerD3D10> m = new LayerManagerD3D10(this);
323 : m->AsShadowForwarder()->SetShadowManager(aShadowManager);
324 : if (m->Initialize()) {
325 : mLayerManager = m;
326 : }
327 : }
328 : #endif
329 0 : if (!mLayerManager) {
330 0 : mLayerManager = new BasicShadowLayerManager(this);
331 0 : mLayerManager->AsShadowForwarder()->SetShadowManager(aShadowManager);
332 : }
333 : }
334 0 : if (aAllowRetaining) {
335 0 : *aAllowRetaining = true;
336 : }
337 0 : return mLayerManager;
338 : }
339 :
340 : gfxASurface*
341 0 : PuppetWidget::GetThebesSurface()
342 : {
343 0 : return mSurface;
344 : }
345 :
346 : nsresult
347 0 : PuppetWidget::IMEEndComposition(bool aCancel)
348 : {
349 : nsEventStatus status;
350 0 : nsTextEvent textEvent(true, NS_TEXT_TEXT, this);
351 0 : InitEvent(textEvent, nsnull);
352 0 : textEvent.seqno = mIMELastReceivedSeqno;
353 : // SendEndIMEComposition is always called since ResetInputState
354 : // should always be called even if we aren't composing something.
355 0 : if (!mTabChild ||
356 0 : !mTabChild->SendEndIMEComposition(aCancel, &textEvent.theText)) {
357 0 : return NS_ERROR_FAILURE;
358 : }
359 :
360 0 : if (!mIMEComposing)
361 0 : return NS_OK;
362 :
363 0 : DispatchEvent(&textEvent, status);
364 :
365 0 : nsCompositionEvent compEvent(true, NS_COMPOSITION_END, this);
366 0 : InitEvent(compEvent, nsnull);
367 0 : compEvent.seqno = mIMELastReceivedSeqno;
368 0 : DispatchEvent(&compEvent, status);
369 0 : return NS_OK;
370 : }
371 :
372 : NS_IMETHODIMP
373 0 : PuppetWidget::ResetInputState()
374 : {
375 0 : return IMEEndComposition(false);
376 : }
377 :
378 : NS_IMETHODIMP
379 0 : PuppetWidget::CancelComposition()
380 : {
381 0 : return IMEEndComposition(true);
382 : }
383 :
384 : NS_IMETHODIMP_(void)
385 0 : PuppetWidget::SetInputContext(const InputContext& aContext,
386 : const InputContextAction& aAction)
387 : {
388 0 : if (!mTabChild) {
389 0 : return;
390 : }
391 : mTabChild->SendSetInputContext(
392 : static_cast<PRInt32>(aContext.mIMEState.mEnabled),
393 : static_cast<PRInt32>(aContext.mIMEState.mOpen),
394 : aContext.mHTMLInputType,
395 : aContext.mActionHint,
396 : static_cast<PRInt32>(aAction.mCause),
397 0 : static_cast<PRInt32>(aAction.mFocusChange));
398 : }
399 :
400 : NS_IMETHODIMP_(InputContext)
401 0 : PuppetWidget::GetInputContext()
402 : {
403 0 : InputContext context;
404 0 : if (mTabChild) {
405 : PRInt32 enabled, open;
406 0 : mTabChild->SendGetInputContext(&enabled, &open);
407 0 : context.mIMEState.mEnabled = static_cast<IMEState::Enabled>(enabled);
408 0 : context.mIMEState.mOpen = static_cast<IMEState::Open>(open);
409 : }
410 : return context;
411 : }
412 :
413 : NS_IMETHODIMP
414 0 : PuppetWidget::OnIMEFocusChange(bool aFocus)
415 : {
416 0 : if (!mTabChild)
417 0 : return NS_ERROR_FAILURE;
418 :
419 0 : if (aFocus) {
420 : nsEventStatus status;
421 0 : nsQueryContentEvent queryEvent(true, NS_QUERY_TEXT_CONTENT, this);
422 0 : InitEvent(queryEvent, nsnull);
423 : // Query entire content
424 0 : queryEvent.InitForQueryTextContent(0, PR_UINT32_MAX);
425 0 : DispatchEvent(&queryEvent, status);
426 :
427 0 : if (queryEvent.mSucceeded) {
428 0 : mTabChild->SendNotifyIMETextHint(queryEvent.mReply.mString);
429 : }
430 : } else {
431 : // ResetInputState might not have been called yet
432 0 : ResetInputState();
433 : }
434 :
435 : PRUint32 chromeSeqno;
436 0 : mIMEPreference.mWantUpdates = false;
437 0 : mIMEPreference.mWantHints = false;
438 0 : if (!mTabChild->SendNotifyIMEFocus(aFocus, &mIMEPreference, &chromeSeqno))
439 0 : return NS_ERROR_FAILURE;
440 :
441 0 : if (aFocus) {
442 0 : if (!mIMEPreference.mWantUpdates && !mIMEPreference.mWantHints)
443 : // call OnIMEFocusChange on blur but no other updates
444 0 : return NS_SUCCESS_IME_NO_UPDATES;
445 0 : OnIMESelectionChange(); // Update selection
446 : } else {
447 0 : mIMELastBlurSeqno = chromeSeqno;
448 : }
449 0 : return NS_OK;
450 : }
451 :
452 : NS_IMETHODIMP
453 0 : PuppetWidget::OnIMETextChange(PRUint32 aStart, PRUint32 aEnd, PRUint32 aNewEnd)
454 : {
455 0 : if (!mTabChild)
456 0 : return NS_ERROR_FAILURE;
457 :
458 0 : if (mIMEPreference.mWantHints) {
459 : nsEventStatus status;
460 0 : nsQueryContentEvent queryEvent(true, NS_QUERY_TEXT_CONTENT, this);
461 0 : InitEvent(queryEvent, nsnull);
462 0 : queryEvent.InitForQueryTextContent(0, PR_UINT32_MAX);
463 0 : DispatchEvent(&queryEvent, status);
464 :
465 0 : if (queryEvent.mSucceeded) {
466 0 : mTabChild->SendNotifyIMETextHint(queryEvent.mReply.mString);
467 : }
468 : }
469 0 : if (mIMEPreference.mWantUpdates) {
470 0 : mTabChild->SendNotifyIMETextChange(aStart, aEnd, aNewEnd);
471 : }
472 0 : return NS_OK;
473 : }
474 :
475 : NS_IMETHODIMP
476 0 : PuppetWidget::OnIMESelectionChange(void)
477 : {
478 0 : if (!mTabChild)
479 0 : return NS_ERROR_FAILURE;
480 :
481 0 : if (mIMEPreference.mWantUpdates) {
482 : nsEventStatus status;
483 0 : nsQueryContentEvent queryEvent(true, NS_QUERY_SELECTED_TEXT, this);
484 0 : InitEvent(queryEvent, nsnull);
485 0 : DispatchEvent(&queryEvent, status);
486 :
487 0 : if (queryEvent.mSucceeded) {
488 : mTabChild->SendNotifyIMESelection(mIMELastReceivedSeqno,
489 0 : queryEvent.GetSelectionStart(),
490 0 : queryEvent.GetSelectionEnd());
491 : }
492 : }
493 0 : return NS_OK;
494 : }
495 :
496 : NS_IMETHODIMP
497 0 : PuppetWidget::SetCursor(nsCursor aCursor)
498 : {
499 0 : if (!mTabChild ||
500 0 : !mTabChild->SendSetCursor(aCursor)) {
501 0 : return NS_ERROR_FAILURE;
502 : }
503 0 : return NS_OK;
504 : }
505 :
506 : nsresult
507 0 : PuppetWidget::DispatchPaintEvent()
508 : {
509 0 : NS_ABORT_IF_FALSE(!mDirtyRegion.IsEmpty(), "paint event logic messed up");
510 :
511 0 : nsIntRect dirtyRect = mDirtyRegion.GetBounds();
512 0 : nsPaintEvent event(true, NS_PAINT, this);
513 0 : event.refPoint.x = dirtyRect.x;
514 0 : event.refPoint.y = dirtyRect.y;
515 0 : event.region = mDirtyRegion;
516 0 : event.willSendDidPaint = true;
517 :
518 : // reset repaint tracking
519 0 : mDirtyRegion.SetEmpty();
520 0 : mPaintTask.Revoke();
521 :
522 : nsEventStatus status;
523 : {
524 : #ifdef DEBUG
525 : debug_DumpPaintEvent(stderr, this, &event,
526 0 : nsCAutoString("PuppetWidget"), nsnull);
527 : #endif
528 :
529 0 : if (LayerManager::LAYERS_D3D10 == mLayerManager->GetBackendType()) {
530 0 : DispatchEvent(&event, status);
531 : } else {
532 0 : nsRefPtr<gfxContext> ctx = new gfxContext(mSurface);
533 0 : ctx->Rectangle(gfxRect(0,0,0,0));
534 0 : ctx->Clip();
535 : AutoLayerManagerSetup setupLayerManager(this, ctx,
536 0 : BasicLayerManager::BUFFER_NONE);
537 0 : DispatchEvent(&event, status);
538 : }
539 : }
540 :
541 0 : nsPaintEvent didPaintEvent(true, NS_DID_PAINT, this);
542 0 : DispatchEvent(&didPaintEvent, status);
543 :
544 0 : return NS_OK;
545 : }
546 :
547 : nsresult
548 0 : PuppetWidget::DispatchResizeEvent()
549 : {
550 0 : nsSizeEvent event(true, NS_SIZE, this);
551 :
552 0 : nsIntRect rect = mBounds; // copy in case something messes with it
553 0 : event.windowSize = ▭
554 0 : event.refPoint.x = rect.x;
555 0 : event.refPoint.y = rect.y;
556 0 : event.mWinWidth = rect.width;
557 0 : event.mWinHeight = rect.height;
558 :
559 : nsEventStatus status;
560 0 : return DispatchEvent(&event, status);
561 : }
562 :
563 : void
564 0 : PuppetWidget::SetChild(PuppetWidget* aChild)
565 : {
566 0 : NS_ABORT_IF_FALSE(this != aChild, "can't parent a widget to itself");
567 0 : NS_ABORT_IF_FALSE(!aChild->mChild,
568 : "fake widget 'hierarchy' only expected to have one level");
569 :
570 0 : mChild = aChild;
571 0 : }
572 :
573 : NS_IMETHODIMP
574 0 : PuppetWidget::PaintTask::Run()
575 : {
576 0 : if (mWidget) {
577 0 : mWidget->DispatchPaintEvent();
578 : }
579 0 : return NS_OK;
580 : }
581 :
582 : float
583 0 : PuppetWidget::GetDPI()
584 : {
585 0 : if (mDPI < 0) {
586 0 : NS_ABORT_IF_FALSE(mTabChild, "Need TabChild to get the DPI from!");
587 0 : mTabChild->SendGetDPI(&mDPI);
588 : }
589 :
590 0 : return mDPI;
591 : }
592 :
593 : void*
594 0 : PuppetWidget::GetNativeData(PRUint32 aDataType)
595 : {
596 0 : switch (aDataType) {
597 : case NS_NATIVE_SHAREABLE_WINDOW: {
598 0 : NS_ABORT_IF_FALSE(mTabChild, "Need TabChild to get the nativeWindow from!");
599 0 : mozilla::WindowsHandle nativeData = nsnull;
600 0 : mTabChild->SendGetWidgetNativeData(&nativeData);
601 0 : return (void*)nativeData;
602 : }
603 : case NS_NATIVE_WINDOW:
604 : case NS_NATIVE_DISPLAY:
605 : case NS_NATIVE_PLUGIN_PORT:
606 : case NS_NATIVE_GRAPHIC:
607 : case NS_NATIVE_SHELLWIDGET:
608 : case NS_NATIVE_WIDGET:
609 0 : NS_WARNING("nsWindow::GetNativeData not implemented for this type");
610 0 : break;
611 : default:
612 0 : NS_WARNING("nsWindow::GetNativeData called with bad value");
613 0 : break;
614 : }
615 0 : return nsnull;
616 : }
617 :
618 : } // namespace widget
619 : } // namespace mozilla
|