Unreviewed, rolling out r96108, r96111, r96113, and r96116.
[WebKit-https.git] / Source / WebKit / wx / WebView.cpp
1 /*
2  * Copyright (C) 2007 Kevin Ollivier  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "WebView.h"
28
29 #include "ContextMenu.h"
30 #include "ContextMenuController.h"
31 #include "ContextMenuItem.h"
32 #include "Document.h"
33 #include "Editor.h"
34 #include "Element.h"
35 #include "EmptyClients.h"
36 #include "EventHandler.h"
37 #include "FileChooser.h"
38 #include "FocusController.h"
39 #include "Frame.h"
40 #include "FrameLoader.h"
41 #include "FrameSelection.h"
42 #include "FrameView.h"
43 #include "GraphicsContext.h"
44 #include "HTMLFormElement.h"
45 #include "Logging.h"
46 #include "MemoryCache.h"
47 #include "Page.h"
48 #include "PlatformKeyboardEvent.h"
49 #include "PlatformMouseEvent.h"
50 #include "PlatformString.h"
51 #include "PlatformWheelEvent.h"
52 #include "RenderObject.h"
53 #include "RenderView.h"
54 #include "ResourceHandleManager.h"
55 #include "Scrollbar.h"
56 #include "Settings.h"
57 #include "SubstituteData.h"
58 #include "Threading.h"
59 #include "markup.h"
60 #if __WXMSW__
61 #include "WebCoreInstanceHandle.h"
62 #endif
63
64 #include "ChromeClientWx.h"
65 #include "ContextMenuClientWx.h"
66 #include "DragClientWx.h"
67 #include "EditorClientWx.h"
68 #include "FrameLoaderClientWx.h"
69 #include "InspectorClientWx.h"
70
71 #include "ScriptController.h"
72 #include "JSDOMBinding.h"
73 #include <runtime/InitializeThreading.h>
74 #include <runtime/JSValue.h>
75 #include <runtime/UString.h>
76 #include <wtf/MainThread.h>
77 #include <wtf/text/CString.h>
78
79 #if ENABLE(SQL_DATABASE)
80 #include "AbstractDatabase.h"
81 #include "DatabaseTracker.h"
82 #endif
83
84 #include "wx/wxprec.h"
85 #ifndef WX_PRECOMP
86     #include "wx/wx.h"
87 #endif
88
89 #include "WebDOMElement.h"
90 #include "WebDOMNode.h"
91
92 #include "WebFrame.h"
93 #include "WebViewPrivate.h"
94
95 #include <wx/defs.h>
96 #include <wx/dcbuffer.h>
97 #include <wx/dcgraph.h>
98
99 #if defined(_MSC_VER)
100 int rint(double val)
101 {
102     return (int)(val < 0 ? val - 0.5 : val + 0.5);
103 }
104 #endif
105
106 // ----------------------------------------------------------------------------
107 // wxWebView Events
108 // ----------------------------------------------------------------------------
109
110 IMPLEMENT_DYNAMIC_CLASS(wxWebViewLoadEvent, wxCommandEvent)
111
112 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_LOAD)
113
114 wxWebViewLoadEvent::wxWebViewLoadEvent(wxWindow* win)
115 {
116     SetEventType( wxEVT_WEBVIEW_LOAD);
117     SetEventObject( win );
118     if (win)
119         SetId(win->GetId());
120 }
121
122 IMPLEMENT_DYNAMIC_CLASS(wxWebViewBeforeLoadEvent, wxCommandEvent)
123
124 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_BEFORE_LOAD)
125
126 wxWebViewBeforeLoadEvent::wxWebViewBeforeLoadEvent(wxWindow* win)
127 {
128     m_cancelled = false;
129     SetEventType(wxEVT_WEBVIEW_BEFORE_LOAD);
130     SetEventObject(win);
131     if (win)
132         SetId(win->GetId());
133 }
134
135 IMPLEMENT_DYNAMIC_CLASS(wxWebViewNewWindowEvent, wxCommandEvent)
136
137 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_NEW_WINDOW)
138
139 wxWebViewNewWindowEvent::wxWebViewNewWindowEvent(wxWindow* win)
140 {
141     SetEventType(wxEVT_WEBVIEW_NEW_WINDOW);
142     SetEventObject(win);
143     if (win)
144         SetId(win->GetId());
145 }
146
147 IMPLEMENT_DYNAMIC_CLASS(wxWebViewRightClickEvent, wxCommandEvent)
148
149 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_RIGHT_CLICK)
150
151 wxWebViewRightClickEvent::wxWebViewRightClickEvent(wxWindow* win)
152 {
153     SetEventType(wxEVT_WEBVIEW_RIGHT_CLICK);
154     SetEventObject(win);
155     if (win)
156         SetId(win->GetId());
157 }
158
159 IMPLEMENT_DYNAMIC_CLASS(wxWebViewConsoleMessageEvent, wxCommandEvent)
160
161 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_CONSOLE_MESSAGE)
162
163 wxWebViewConsoleMessageEvent::wxWebViewConsoleMessageEvent(wxWindow* win)
164 {
165     SetEventType(wxEVT_WEBVIEW_CONSOLE_MESSAGE);
166     SetEventObject(win);
167     if (win)
168         SetId(win->GetId());
169 }
170
171 IMPLEMENT_DYNAMIC_CLASS(wxWebViewAlertEvent, wxCommandEvent)
172
173 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_JS_ALERT)
174
175 wxWebViewAlertEvent::wxWebViewAlertEvent(wxWindow* win)
176 {
177     SetEventType(wxEVT_WEBVIEW_JS_ALERT);
178     SetEventObject(win);
179     if (win)
180         SetId(win->GetId());
181 }
182
183 IMPLEMENT_DYNAMIC_CLASS(wxWebViewConfirmEvent, wxCommandEvent)
184
185 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_JS_CONFIRM)
186
187 wxWebViewConfirmEvent::wxWebViewConfirmEvent(wxWindow* win)
188 {
189     SetEventType(wxEVT_WEBVIEW_JS_CONFIRM);
190     SetEventObject(win);
191     if (win)
192         SetId(win->GetId());
193 }
194
195 IMPLEMENT_DYNAMIC_CLASS(wxWebViewPromptEvent, wxCommandEvent)
196
197 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_JS_PROMPT)
198
199 wxWebViewPromptEvent::wxWebViewPromptEvent(wxWindow* win)
200 {
201     SetEventType(wxEVT_WEBVIEW_JS_PROMPT);
202     SetEventObject(win);
203     if (win)
204         SetId(win->GetId());
205 }
206
207 IMPLEMENT_DYNAMIC_CLASS(wxWebViewReceivedTitleEvent, wxCommandEvent)
208
209 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_RECEIVED_TITLE)
210
211 wxWebViewReceivedTitleEvent::wxWebViewReceivedTitleEvent(wxWindow* win)
212 {
213     SetEventType(wxEVT_WEBVIEW_RECEIVED_TITLE);
214     SetEventObject(win);
215     if (win)
216         SetId(win->GetId());
217 }
218
219 IMPLEMENT_DYNAMIC_CLASS(wxWebViewWindowObjectClearedEvent, wxCommandEvent)
220
221 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_WINDOW_OBJECT_CLEARED)
222
223 wxWebViewWindowObjectClearedEvent::wxWebViewWindowObjectClearedEvent(wxWindow* win)
224 {
225     SetEventType(wxEVT_WEBVIEW_WINDOW_OBJECT_CLEARED);
226     SetEventObject(win);
227     if (win)
228         SetId(win->GetId());
229 }
230
231 IMPLEMENT_DYNAMIC_CLASS(wxWebViewContentsChangedEvent, wxCommandEvent)
232
233 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_CONTENTS_CHANGED)
234
235 wxWebViewContentsChangedEvent::wxWebViewContentsChangedEvent(wxWindow* win)
236 {
237     SetEventType(wxEVT_WEBVIEW_CONTENTS_CHANGED);
238     SetEventObject(win);
239     if (win)
240         SetId(win->GetId());
241 }
242
243 IMPLEMENT_DYNAMIC_CLASS(wxWebViewSelectionChangedEvent, wxCommandEvent)
244
245 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_SELECTION_CHANGED)
246
247 wxWebViewSelectionChangedEvent::wxWebViewSelectionChangedEvent(wxWindow* win)
248 {
249     SetEventType(wxEVT_WEBVIEW_SELECTION_CHANGED);
250     SetEventObject(win);
251     if (win)
252         SetId(win->GetId());
253 }
254
255 IMPLEMENT_DYNAMIC_CLASS(wxWebViewPrintFrameEvent, wxCommandEvent)
256
257 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_PRINT_FRAME)
258
259 wxWebViewPrintFrameEvent::wxWebViewPrintFrameEvent(wxWindow* win)
260 {
261     SetEventType(wxEVT_WEBVIEW_PRINT_FRAME);
262     SetEventObject(win);
263     if (win)
264         SetId(win->GetId());
265 }
266
267 //---------------------------------------------------------
268 // DOM Element info data type
269 //---------------------------------------------------------
270
271 wxWebViewDOMElementInfo::wxWebViewDOMElementInfo() :
272     m_isSelected(false),
273     m_text(wxEmptyString),
274     m_imageSrc(wxEmptyString),
275     m_link(wxEmptyString),
276     m_urlElement(NULL),
277     m_innerNode(NULL)
278 {
279 }
280
281 static wxWebViewCachePolicy gs_cachePolicy;
282
283 /* static */
284 void wxWebView::SetCachePolicy(const wxWebViewCachePolicy& cachePolicy)
285 {
286     WebCore::MemoryCache* globalCache = WebCore::memoryCache();
287     globalCache->setCapacities(cachePolicy.GetMinDeadCapacity(),
288                                cachePolicy.GetMaxDeadCapacity(),
289                                cachePolicy.GetCapacity());
290
291     // store a copy since there is no getter for MemoryCache values
292     gs_cachePolicy = cachePolicy;
293 }
294
295 /* static */
296 wxWebViewCachePolicy wxWebView::GetCachePolicy()
297 {
298     return gs_cachePolicy;
299 }
300
301 wxWebViewDOMElementInfo::wxWebViewDOMElementInfo(const wxWebViewDOMElementInfo& other)
302 {
303     m_isSelected = other.m_isSelected;
304     m_text = other.m_text;
305     m_imageSrc = other.m_imageSrc;
306     m_link = other.m_link;
307     m_innerNode = other.m_innerNode;
308     m_urlElement = other.m_urlElement;
309 }
310
311 wxWebViewDOMElementInfo::~wxWebViewDOMElementInfo() 
312 {
313     if (m_innerNode)
314         delete m_innerNode;
315         
316     if (m_urlElement)
317         delete m_urlElement;
318 }
319
320 #if OS(DARWIN)
321 // prototype - function is in WebSystemInterface.mm
322 void InitWebCoreSystemInterface(void);
323 #endif
324
325 BEGIN_EVENT_TABLE(wxWebView, wxWindow)
326     EVT_PAINT(wxWebView::OnPaint)
327     EVT_SIZE(wxWebView::OnSize)
328     EVT_MOUSE_EVENTS(wxWebView::OnMouseEvents)
329     EVT_CONTEXT_MENU(wxWebView::OnContextMenuEvents)
330     EVT_KEY_DOWN(wxWebView::OnKeyEvents)
331     EVT_KEY_UP(wxWebView::OnKeyEvents)
332     EVT_CHAR(wxWebView::OnKeyEvents)
333     EVT_SET_FOCUS(wxWebView::OnSetFocus)
334     EVT_KILL_FOCUS(wxWebView::OnKillFocus)
335     EVT_MOUSE_CAPTURE_LOST(wxWebView::OnMouseCaptureLost)
336 END_EVENT_TABLE()
337
338 IMPLEMENT_DYNAMIC_CLASS(wxWebView, wxWindow)
339
340 const wxChar* wxWebViewNameStr = wxT("webView");
341
342 wxWebView::wxWebView() :
343     m_textMagnifier(1.0),
344     m_isInitialized(false),
345     m_beingDestroyed(false),
346     m_mouseWheelZooms(false),
347     m_title(wxEmptyString)
348 {
349 }
350
351 wxWebView::wxWebView(wxWindow* parent, int id, const wxPoint& position, 
352                      const wxSize& size, long style, const wxString& name) :
353     m_textMagnifier(1.0),
354     m_isInitialized(false),
355     m_beingDestroyed(false),
356     m_mouseWheelZooms(false),
357     m_title(wxEmptyString)
358 {
359     Create(parent, id, position, size, style, name);
360 }
361
362 bool wxWebView::Create(wxWindow* parent, int id, const wxPoint& position, 
363                        const wxSize& size, long style, const wxString& name)
364 {
365 #if OS(DARWIN)
366     InitWebCoreSystemInterface();
367 #endif
368
369     if ( (style & wxBORDER_MASK) == 0)
370         style |= wxBORDER_NONE;
371     
372     if (!wxWindow::Create(parent, id, position, size, style, name))
373         return false;
374
375     JSC::initializeThreading();
376     WTF::initializeMainThread();
377
378 // This is necessary because we are using SharedTimerWin.cpp on Windows,
379 // due to a problem with exceptions getting eaten when using the callback
380 // approach to timers (which wx itself uses).
381 #if __WXMSW__
382     WebCore::setInstanceHandle(wxGetInstance());
383 #endif
384
385     // this helps reduce flicker on platforms like MSW
386     SetBackgroundStyle(wxBG_STYLE_CUSTOM);
387
388     m_impl = new WebViewPrivate();
389
390     WebCore::InitializeLoggingChannelsIfNecessary();    
391     WebCore::HTMLFrameOwnerElement* parentFrame = 0;
392
393     WebCore::EditorClientWx* editorClient = new WebCore::EditorClientWx();
394
395     WebCore::Page::PageClients pageClients;
396     pageClients.chromeClient = new WebCore::ChromeClientWx(this);
397     pageClients.contextMenuClient = new WebCore::ContextMenuClientWx();
398     pageClients.editorClient = editorClient;
399     pageClients.dragClient = new WebCore::DragClientWx();
400     pageClients.inspectorClient = new WebCore::InspectorClientWx();
401     m_impl->page = new WebCore::Page(pageClients);
402     editorClient->setPage(m_impl->page);
403     
404     m_mainFrame = new wxWebFrame(this);
405
406     // Default settings - we should have wxWebViewSettings class for this
407     // eventually
408     WebCore::Settings* settings = m_impl->page->settings();
409     settings->setLoadsImagesAutomatically(true);
410     settings->setDefaultFixedFontSize(13);
411     settings->setDefaultFontSize(16);
412     settings->setSerifFontFamily("Times New Roman");
413     settings->setFixedFontFamily("Courier New");
414     settings->setSansSerifFontFamily("Arial");
415     settings->setStandardFontFamily("Times New Roman");
416     settings->setJavaScriptEnabled(true);
417
418 #if ENABLE(SQL_DATABASE)
419     SetDatabasesEnabled(true);
420 #endif
421
422     // we need to do this so that objects like the focusController are properly
423     // initialized so that the activate handler is run properly.
424     LoadURL(wxT("about:blank"));
425     
426     m_isInitialized = true;
427
428     return true;
429 }
430
431 wxWebView::~wxWebView()
432 {
433     m_beingDestroyed = true;
434     
435     while (HasCapture())
436         ReleaseMouse();
437     
438     if (m_mainFrame && m_mainFrame->GetFrame())
439         m_mainFrame->GetFrame()->loader()->detachFromParent();
440     
441     delete m_impl->page;
442     m_impl->page = 0;   
443 }
444
445 // NOTE: binding to this event in the wxWebView constructor is too early in 
446 // some cases, but leave the event handler here so that users can bind to it
447 // at a later time if they have activation state problems.
448 void wxWebView::OnTLWActivated(wxActivateEvent& event)
449 {        
450     if (m_impl && m_impl->page && m_impl->page->focusController())
451         m_impl->page->focusController()->setActive(event.GetActive());
452     
453     event.Skip();
454     
455 }
456
457 void wxWebView::Stop()
458 {
459     if (m_mainFrame)
460         m_mainFrame->Stop();
461 }
462
463 void wxWebView::Reload()
464 {
465     if (m_mainFrame)
466         m_mainFrame->Reload();
467 }
468
469 wxString wxWebView::GetPageSource()
470 {
471     if (m_mainFrame)
472         return m_mainFrame->GetPageSource();
473
474     return wxEmptyString;
475 }
476
477 void wxWebView::SetPageSource(const wxString& source, const wxString& baseUrl, const wxString& mimetype)
478 {
479     if (m_mainFrame)
480         m_mainFrame->SetPageSource(source, baseUrl, mimetype);
481 }
482
483 wxString wxWebView::GetInnerText()
484 {
485     if (m_mainFrame)
486         return m_mainFrame->GetInnerText();
487         
488     return wxEmptyString;
489 }
490
491 wxString wxWebView::GetAsMarkup()
492 {
493     if (m_mainFrame)
494         return m_mainFrame->GetAsMarkup();
495         
496     return wxEmptyString;
497 }
498
499 wxString wxWebView::GetExternalRepresentation()
500 {
501     if (m_mainFrame)
502         return m_mainFrame->GetExternalRepresentation();
503         
504     return wxEmptyString;
505 }
506
507 wxWebKitSelection wxWebView::GetSelection()
508 {
509     if (m_mainFrame)
510         return m_mainFrame->GetSelection();
511         
512     return 0;
513 }
514
515 wxString wxWebView::GetSelectionAsHTML()
516 {
517     if (m_mainFrame)
518         return m_mainFrame->GetSelectionAsHTML();
519         
520     return wxEmptyString;
521 }
522
523 wxString wxWebView::GetSelectionAsText()
524 {
525     if (m_mainFrame)
526         return m_mainFrame->GetSelectionAsText();
527         
528     return wxEmptyString;
529 }
530
531 void wxWebView::SetTransparent(bool transparent)
532 {
533     WebCore::Frame* frame = 0;
534     if (m_mainFrame)
535         frame = m_mainFrame->GetFrame();
536     
537     if (!frame || !frame->view())
538         return;
539
540     frame->view()->setTransparent(transparent);
541 }
542
543 bool wxWebView::IsTransparent() const
544 {
545     WebCore::Frame* frame = 0;
546     if (m_mainFrame)
547         frame = m_mainFrame->GetFrame();
548
549    if (!frame || !frame->view())
550         return false;
551
552     return frame->view()->isTransparent();
553 }
554
555 wxString wxWebView::RunScript(const wxString& javascript)
556 {
557     if (m_mainFrame)
558         return m_mainFrame->RunScript(javascript);
559     
560     return wxEmptyString;
561 }
562
563 bool wxWebView::ExecuteEditCommand(const wxString& command, const wxString& parameter)
564 {
565     if (m_mainFrame)
566         return m_mainFrame->ExecuteEditCommand(command, parameter);
567 }
568
569 EditState wxWebView::GetEditCommandState(const wxString& command) const
570 {
571     if (m_mainFrame)
572         return m_mainFrame->GetEditCommandState(command);
573 }
574
575 wxString wxWebView::GetEditCommandValue(const wxString& command) const
576 {
577     if (m_mainFrame)
578         return m_mainFrame->GetEditCommandValue(command);
579  
580     return wxEmptyString;
581 }
582
583 void wxWebView::LoadURL(const wxString& url)
584 {
585     if (m_mainFrame)
586         m_mainFrame->LoadURL(url);
587 }
588
589 bool wxWebView::GoBack()
590 {
591     if (m_mainFrame)
592         return m_mainFrame->GoBack();
593
594     return false;
595 }
596
597 bool wxWebView::GoForward()
598 {
599     if (m_mainFrame)
600         return m_mainFrame->GoForward();
601
602     return false;
603 }
604
605 bool wxWebView::CanGoBack()
606 {
607     if (m_mainFrame)
608         return m_mainFrame->CanGoBack();
609
610     return false;
611 }
612
613 bool wxWebView::CanGoForward()
614 {
615     if (m_mainFrame)
616         return m_mainFrame->CanGoForward();
617
618     return false;
619 }
620
621 bool wxWebView::CanIncreaseTextSize() const
622 {
623     if (m_mainFrame)
624         return m_mainFrame->CanIncreaseTextSize();
625
626     return false;
627 }
628
629 void wxWebView::IncreaseTextSize()
630 {
631     if (m_mainFrame)
632         m_mainFrame->IncreaseTextSize();
633 }
634
635 bool wxWebView::CanDecreaseTextSize() const
636 {
637     if (m_mainFrame)
638         m_mainFrame->CanDecreaseTextSize();
639
640     return false;
641 }
642
643 void wxWebView::DecreaseTextSize()
644 {        
645     if (m_mainFrame)
646         m_mainFrame->DecreaseTextSize();
647 }
648
649 void wxWebView::ResetTextSize()
650 {
651     if (m_mainFrame)
652         m_mainFrame->ResetTextSize();    
653 }
654
655 void wxWebView::MakeEditable(bool enable)
656 {
657     if (m_mainFrame)
658         m_mainFrame->MakeEditable(enable);
659 }
660
661 bool wxWebView::IsEditable() const
662 {
663     if (m_mainFrame)
664         return m_mainFrame->IsEditable();
665     
666     return false;
667 }
668
669
670
671 /* 
672  * Event forwarding functions to send events down to WebCore.
673  */
674
675 void wxWebView::OnPaint(wxPaintEvent& event)
676 {
677     if (m_beingDestroyed || !m_mainFrame)
678         return;
679
680     WebCore::Frame* frame = m_mainFrame->GetFrame();
681     if (!frame || !frame->view())
682         return;
683     
684     wxAutoBufferedPaintDC dc(this);
685
686     if (IsShown() && frame->document()) {
687 #if USE(WXGC)
688 #if wxCHECK_VERSION(2, 9, 2) && defined(wxUSE_CAIRO) && wxUSE_CAIRO
689         wxGraphicsRenderer* renderer = wxGraphicsRenderer::GetCairoRenderer();
690         if (!renderer)
691             renderer = wxGraphicsRenderer::GetDefaultRenderer();
692         wxGraphicsContext* context = renderer->CreateContext(dc);
693         wxGCDC gcdc(context);
694 #else
695         wxGCDC gcdc(dc);
696 #endif
697 #endif
698
699         if (dc.IsOk()) {
700             wxRect paintRect = GetUpdateRegion().GetBox();
701
702 #if USE(WXGC)
703             WebCore::GraphicsContext gc(&gcdc);
704 #else
705             WebCore::GraphicsContext gc(&dc);
706 #endif
707             if (frame->contentRenderer()) {
708                 frame->view()->updateLayoutAndStyleIfNeededRecursive();
709                 frame->view()->paint(&gc, paintRect);
710             }
711         }
712     }
713 }
714
715 bool wxWebView::FindString(const wxString& string, bool forward, bool caseSensitive, bool wrapSelection, bool startInSelection)
716 {
717     if (m_mainFrame)
718         return m_mainFrame->FindString(string, forward, caseSensitive, wrapSelection, startInSelection);
719
720     return false;
721 }
722
723 void wxWebView::OnSize(wxSizeEvent& event)
724
725     if (m_isInitialized && m_mainFrame) {
726         WebCore::Frame* frame = m_mainFrame->GetFrame();
727         frame->view()->resize(event.GetSize());
728         frame->view()->adjustViewSize();
729     }
730       
731     event.Skip();
732 }
733
734 static int getDoubleClickTime()
735 {
736 #if __WXMSW__
737     return ::GetDoubleClickTime();
738 #else
739     return 500;
740 #endif
741 }
742
743 void wxWebView::OnMouseEvents(wxMouseEvent& event)
744 {
745     event.Skip();
746     
747     if (!m_impl->page)
748         return; 
749         
750     WebCore::Frame* frame = m_mainFrame->GetFrame();  
751     if (!frame || !frame->view())
752         return;
753     
754     wxPoint globalPoint = ClientToScreen(event.GetPosition());
755
756     wxEventType type = event.GetEventType();
757     
758     if (type == wxEVT_MOUSEWHEEL) {
759         if (m_mouseWheelZooms && event.ControlDown() && !event.AltDown() && !event.ShiftDown()) {
760             if (event.GetWheelRotation() < 0)
761                 DecreaseTextSize();
762             else if (event.GetWheelRotation() > 0)
763                 IncreaseTextSize();
764         } else {
765             WebCore::PlatformWheelEvent wkEvent(event, globalPoint);
766             frame->eventHandler()->handleWheelEvent(wkEvent);
767         }
768
769         return;
770     }
771     
772     // If an event, such as a right-click event, leads to a focus change (e.g. it 
773     // raises a dialog), WebKit never gets the mouse up event and never relinquishes 
774     // mouse capture. This leads to WebKit handling mouse events, such as modifying
775     // the selection, while other controls or top level windows have the focus.
776     // I'm not sure if this is the right place to handle this, but I can't seem to
777     // find a precedent on how to handle this in other ports.
778     if (wxWindow::FindFocus() != this) {
779         while (HasCapture())
780             ReleaseMouse();
781
782         frame->eventHandler()->setMousePressed(false);
783
784         return;
785     }
786         
787     int clickCount = event.ButtonDClick() ? 2 : 1;
788
789     if (clickCount == 1 && m_impl->tripleClickTimer.IsRunning()) {
790         wxPoint diff(event.GetPosition() - m_impl->tripleClickPos);
791         if (abs(diff.x) <= wxSystemSettings::GetMetric(wxSYS_DCLICK_X) &&
792             abs(diff.y) <= wxSystemSettings::GetMetric(wxSYS_DCLICK_Y)) {
793             clickCount = 3;
794         }
795     } else if (clickCount == 2) {
796         m_impl->tripleClickTimer.Start(getDoubleClickTime(), false);
797         m_impl->tripleClickPos = event.GetPosition();
798     }
799     
800     WebCore::PlatformMouseEvent wkEvent(event, globalPoint, clickCount);
801
802     if (type == wxEVT_LEFT_DOWN || type == wxEVT_MIDDLE_DOWN || type == wxEVT_RIGHT_DOWN || 
803                 type == wxEVT_LEFT_DCLICK || type == wxEVT_MIDDLE_DCLICK || type == wxEVT_RIGHT_DCLICK) {
804         frame->eventHandler()->handleMousePressEvent(wkEvent);
805         if (!HasCapture())
806             CaptureMouse();
807     } else if (type == wxEVT_LEFT_UP || type == wxEVT_MIDDLE_UP || type == wxEVT_RIGHT_UP) {
808         frame->eventHandler()->handleMouseReleaseEvent(wkEvent);
809         while (HasCapture())
810             ReleaseMouse();
811     } else if (type == wxEVT_MOTION || type == wxEVT_ENTER_WINDOW || type == wxEVT_LEAVE_WINDOW)
812         frame->eventHandler()->mouseMoved(wkEvent);
813 }
814
815 void wxWebView::OnContextMenuEvents(wxContextMenuEvent& event)
816 {
817     Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(wxWebView::OnMenuSelectEvents), NULL, this);
818     m_impl->page->contextMenuController()->clearContextMenu();
819     wxPoint localEventPoint = ScreenToClient(event.GetPosition());
820
821     if (!m_impl->page)
822         return;
823         
824     WebCore::Frame* focusedFrame = m_impl->page->focusController()->focusedOrMainFrame();
825     if (!focusedFrame->view())
826         return;
827
828     //Create WebCore mouse event from the wxContextMenuEvent
829     wxMouseEvent mouseEvent(wxEVT_RIGHT_DOWN);
830     mouseEvent.m_x = localEventPoint.x;
831     mouseEvent.m_y = localEventPoint.y;
832     WebCore::PlatformMouseEvent wkEvent(mouseEvent, event.GetPosition(), 1);
833
834     bool handledEvent = focusedFrame->eventHandler()->sendContextMenuEvent(wkEvent);
835     if (!handledEvent)
836         return;
837
838     WebCore::ContextMenu* coreMenu = m_impl->page->contextMenuController()->contextMenu();
839     if (!coreMenu)
840         return;
841
842     WebCore::PlatformMenuDescription menuWx = coreMenu->platformDescription();
843     if (!menuWx)
844         return;
845
846     PopupMenu(menuWx, localEventPoint);
847     
848     Disconnect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(wxWebView::OnMenuSelectEvents), NULL, this);
849 }
850
851 void wxWebView::OnMenuSelectEvents(wxCommandEvent& event)
852 {
853     // we shouldn't hit this unless there's a context menu showing
854     WebCore::ContextMenu* coreMenu = m_impl->page->contextMenuController()->contextMenu();
855     ASSERT(coreMenu);
856     if (!coreMenu)
857         return;
858
859     WebCore::ContextMenuItem* item = WebCore::ContextMenu::itemWithId (event.GetId());
860     if (!item)
861         return;
862
863     m_impl->page->contextMenuController()->contextMenuItemSelected(item);
864     delete item;
865 }
866
867 void wxWebView::OnMouseCaptureLost(wxMouseCaptureLostEvent& event)
868 {
869     // do nothing - unfortunately, we MUST handle this event due to wxWidgets rules,
870     // otherwise we will assert, even though there is nothing for us to do here.
871 }
872
873 bool wxWebView::CanCopy()
874 {
875     if (m_mainFrame)
876         return m_mainFrame->CanCopy();
877
878     return false;
879 }
880
881 void wxWebView::Copy()
882 {
883     if (m_mainFrame)
884         m_mainFrame->Copy();
885 }
886
887 bool wxWebView::CanCut()
888 {
889     if (m_mainFrame)
890         return m_mainFrame->CanCut();
891
892     return false;
893 }
894
895 void wxWebView::Cut()
896 {
897     if (m_mainFrame)
898         m_mainFrame->Cut();
899 }
900
901 bool wxWebView::CanPaste()
902 {
903     if (m_mainFrame)
904         return m_mainFrame->CanPaste();
905
906     return false;
907 }
908
909 void wxWebView::Paste()
910 {
911     if (m_mainFrame)
912         m_mainFrame->Paste();
913 }
914
915 void wxWebView::OnKeyEvents(wxKeyEvent& event)
916 {
917     WebCore::Frame* frame = 0;
918     if (m_impl->page)
919         frame = m_impl->page->focusController()->focusedOrMainFrame();
920
921     if (!(frame && frame->view()))
922         return;
923
924     WebCore::PlatformKeyboardEvent wkEvent(event);
925
926     if (frame->eventHandler()->keyEvent(wkEvent))
927         return;
928
929     //Some things WebKit won't do for us... Copy/Cut/Paste and KB scrolling
930     if (event.GetEventType() == wxEVT_KEY_DOWN) {
931         switch (event.GetKeyCode()) {
932         case 67: //"C"
933             if (CanCopy() && event.GetModifiers() == wxMOD_CMD) {
934                 Copy();
935                 return;
936             }
937             break;
938         case 86: //"V"
939             if (CanPaste() && event.GetModifiers() == wxMOD_CMD) {
940                 Paste();
941                 return;
942             }
943             break;
944         case 88: //"X"
945             if (CanCut() && event.GetModifiers() == wxMOD_CMD) {
946                 Cut();
947                 return;
948             }
949             break;
950         case WXK_INSERT:
951             if (CanCopy() && event.GetModifiers() == wxMOD_CMD) {
952                 Copy();
953                 return;
954             }
955             if (CanPaste() && event.GetModifiers() == wxMOD_SHIFT) {
956                 Paste();
957                 return;
958             }
959             return; //Insert shall not become a char
960         case WXK_DELETE:
961             if (CanCut() && event.GetModifiers() == wxMOD_SHIFT) {
962                 Cut();
963                 return;
964             }
965             break;
966         case WXK_LEFT:
967         case WXK_NUMPAD_LEFT:
968             frame->view()->scrollBy(WebCore::IntSize(-WebCore::Scrollbar::pixelsPerLineStep(), 0));
969             return;
970         case WXK_UP:
971         case WXK_NUMPAD_UP:
972             frame->view()->scrollBy(WebCore::IntSize(0, -WebCore::Scrollbar::pixelsPerLineStep()));
973             return;
974         case WXK_RIGHT:
975         case WXK_NUMPAD_RIGHT:
976             frame->view()->scrollBy(WebCore::IntSize(WebCore::Scrollbar::pixelsPerLineStep(), 0));
977             return;
978         case WXK_DOWN:
979         case WXK_NUMPAD_DOWN:
980             frame->view()->scrollBy(WebCore::IntSize(0, WebCore::Scrollbar::pixelsPerLineStep()));
981             return;
982         case WXK_END:
983         case WXK_NUMPAD_END:
984             frame->view()->setScrollPosition(WebCore::IntPoint(frame->view()->scrollX(), frame->view()->maximumScrollPosition().y()));
985             return;
986         case WXK_HOME:
987         case WXK_NUMPAD_HOME:
988             frame->view()->setScrollPosition(WebCore::IntPoint(frame->view()->scrollX(), 0));
989             return;
990         case WXK_PAGEUP:
991         case WXK_NUMPAD_PAGEUP:
992             frame->view()->scrollBy(WebCore::IntSize(0, -frame->view()->visibleHeight() * WebCore::Scrollbar::minFractionToStepWhenPaging()));
993             return;
994         case WXK_PAGEDOWN:
995         case WXK_NUMPAD_PAGEDOWN:
996             frame->view()->scrollBy(WebCore::IntSize(0, frame->view()->visibleHeight() * WebCore::Scrollbar::minFractionToStepWhenPaging()));
997             return;
998         //These we don't want turning into char events, stuff 'em
999         case WXK_ESCAPE:
1000         case WXK_LBUTTON:
1001         case WXK_RBUTTON:
1002         case WXK_CANCEL:
1003         case WXK_MENU:
1004         case WXK_MBUTTON:
1005         case WXK_CLEAR:
1006         case WXK_PAUSE:
1007         case WXK_SELECT:
1008         case WXK_PRINT:
1009         case WXK_EXECUTE:
1010         case WXK_SNAPSHOT:
1011         case WXK_HELP:
1012         case WXK_F1:
1013         case WXK_F2:
1014         case WXK_F3:
1015         case WXK_F4:
1016         case WXK_F5:
1017         case WXK_F6:
1018         case WXK_F7:
1019         case WXK_F8:
1020         case WXK_F9:
1021         case WXK_F10:
1022         case WXK_F11:
1023         case WXK_F12:
1024         case WXK_F13:
1025         case WXK_F14:
1026         case WXK_F15:
1027         case WXK_F16:
1028         case WXK_F17:
1029         case WXK_F18:
1030         case WXK_F19:
1031         case WXK_F20:
1032         case WXK_F21:
1033         case WXK_F22:
1034         case WXK_F23:
1035         case WXK_F24:
1036         case WXK_NUMPAD_F1:
1037         case WXK_NUMPAD_F2:
1038         case WXK_NUMPAD_F3:
1039         case WXK_NUMPAD_F4:
1040         //When numlock is off Numpad 5 becomes BEGIN, or HOME on Char
1041         case WXK_NUMPAD_BEGIN:
1042         case WXK_NUMPAD_INSERT:
1043             return;
1044         }
1045     }
1046
1047     event.Skip();
1048 }
1049
1050 void wxWebView::OnSetFocus(wxFocusEvent& event)
1051 {
1052     if (m_impl && m_impl->page && m_impl->page->focusController()) {
1053         m_impl->page->focusController()->setFocused(true);
1054         m_impl->page->focusController()->setActive(true);
1055
1056         if (!m_impl->page->focusController()->focusedFrame() && m_mainFrame)
1057             m_impl->page->focusController()->setFocusedFrame(m_mainFrame->GetFrame());
1058     }
1059     
1060     event.Skip();
1061 }
1062
1063 void wxWebView::OnKillFocus(wxFocusEvent& event)
1064 {
1065     if (m_impl && m_impl->page && m_impl->page->focusController()) {
1066         m_impl->page->focusController()->setFocused(false);
1067
1068         // We also handle active state in OnTLWActivated, but if a user does not
1069         // call event.Skip() in their own EVT_ACTIVATE handler, we won't get those
1070         // callbacks. So we handle active state here as well as a fallback.
1071         wxTopLevelWindow* tlw = dynamic_cast<wxTopLevelWindow*>(wxGetTopLevelParent(this));
1072         if (tlw && tlw->IsActive())
1073             m_impl->page->focusController()->setActive(true);
1074         else
1075             m_impl->page->focusController()->setActive(false);
1076     }
1077     
1078     while (HasCapture())
1079         ReleaseMouse();
1080     
1081     event.Skip();
1082 }
1083
1084 wxWebViewDOMElementInfo wxWebView::HitTest(const wxPoint& pos) const
1085 {
1086     if (m_mainFrame)
1087         return m_mainFrame->HitTest(pos);
1088
1089     return wxWebViewDOMElementInfo();
1090 }
1091
1092 bool wxWebView::ShouldClose() const
1093 {
1094     if (m_mainFrame)
1095         return m_mainFrame->ShouldClose();
1096
1097     return true;
1098 }
1099
1100 /* static */
1101 void wxWebView::SetDatabaseDirectory(const wxString& databaseDirectory)
1102 {
1103 #if ENABLE(SQL_DATABASE)
1104     WebCore::DatabaseTracker::tracker().setDatabaseDirectoryPath(databaseDirectory);
1105 #endif
1106 }
1107
1108 /* static */
1109 wxString wxWebView::GetDatabaseDirectory()
1110 {
1111 #if ENABLE(SQL_DATABASE)
1112     return WebCore::DatabaseTracker::tracker().databaseDirectoryPath();
1113 #else
1114     return wxEmptyString;
1115 #endif
1116 }
1117
1118 /* static */
1119 void wxWebView::SetDatabasesEnabled(bool enabled)
1120 {
1121 #if ENABLE(SQL_DATABASE)
1122     WebCore::AbstractDatabase::setIsAvailable(enabled);
1123 #endif
1124 }
1125
1126 /* static */
1127 bool wxWebView::AreDatabasesEnabled()
1128 {
1129 #if ENABLE(SQL_DATABASE)
1130     return WebCore::AbstractDatabase::isAvailable();
1131 #endif
1132     return false;
1133 }
1134
1135 static WebCore::ResourceHandleManager::ProxyType curlProxyType(wxProxyType type)
1136 {
1137     switch (type) {
1138         case HTTP: return WebCore::ResourceHandleManager::HTTP;
1139         case Socks4: return WebCore::ResourceHandleManager::Socks4;
1140         case Socks4A: return WebCore::ResourceHandleManager::Socks4A;
1141         case Socks5: return WebCore::ResourceHandleManager::Socks5;
1142         case Socks5Hostname: return WebCore::ResourceHandleManager::Socks5Hostname;
1143         default:
1144             ASSERT_NOT_REACHED();
1145             return WebCore::ResourceHandleManager::HTTP;
1146     }
1147 }
1148
1149 /* static */
1150 void wxWebView::SetProxyInfo(const wxString& host,
1151                              unsigned long port,
1152                              wxProxyType type,
1153                              const wxString& username,
1154                              const wxString& password)
1155 {
1156     using WebCore::ResourceHandleManager;
1157     if (ResourceHandleManager* mgr = ResourceHandleManager::sharedInstance())
1158         mgr->setProxyInfo(host, port, curlProxyType(type), username, password);
1159 }
1160
1161 wxWebSettings wxWebView::GetWebSettings()
1162 {
1163     ASSERT(m_impl->page);
1164     if (m_impl->page)
1165         return wxWebSettings(m_impl->page->settings());
1166     
1167     return wxWebSettings();
1168 }
1169
1170 wxWebKitCompatibilityMode wxWebView::GetCompatibilityMode() const
1171 {
1172     if (m_mainFrame)
1173         return m_mainFrame->GetCompatibilityMode();
1174
1175     return QuirksMode;
1176 }
1177
1178 void wxWebView::GrantUniversalAccess()
1179 {
1180     if (m_mainFrame)
1181         m_mainFrame->GrantUniversalAccess();
1182 }