b648b164dcf2596bea398a786f75e0189bbf9559
[WebKit-https.git] / WebCore / platform / gdk / FrameGdk.cpp
1 /*
2  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
3  * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com 
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
16  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
26  */
27
28 #include "config.h"
29 #include "FrameGdk.h"
30 #include "Element.h"
31 #include "RenderObject.h"
32 #include "RenderWidget.h"
33 #include "RenderLayer.h"
34 #include "Page.h"
35 #include "Document.h"
36 #include "DOMWindow.h"
37 #include "DOMImplementation.h"
38 #include "BrowserExtensionGdk.h"
39 #include "Document.h"
40 #include "Settings.h"
41 #include "Plugin.h"
42 #include "FramePrivate.h"
43 #include "GraphicsContext.h"
44 #include "HTMLDocument.h"
45 #include "ResourceLoader.h"
46 #include "PlatformMouseEvent.h"
47 #include "PlatformKeyboardEvent.h"
48 #include "PlatformWheelEvent.h"
49 #include "MouseEventWithHitTestResults.h"
50 #include "SelectionController.h"
51 #include "TypingCommand.h"
52 #include "SSLKeyGenerator.h"
53 #include "KeyboardCodes.h"
54 #include <gdk/gdk.h>
55
56
57 // This function loads resources from WebKit
58 // This does not belong here and I'm not sure where
59 // it should go
60 // I don't know what the plans or design is
61 // for none code resources
62 Vector<char> loadResourceIntoArray(const char* resourceName)
63 {
64     Vector<char> resource;
65     //if (strcmp(resourceName,"missingImage") == 0) {
66     //}
67     return resource;
68 }
69
70 namespace WebCore {
71
72 static void doScroll(const RenderObject* r, bool isHorizontal, int multiplier)
73 {
74     // FIXME: The scrolling done here should be done in the default handlers
75     // of the elements rather than here in the part.
76     if (!r)
77         return;
78
79     //broken since it calls scroll on scrollbars
80     //and we have none now
81     //r->scroll(direction, ScrollByWheel, multiplier);
82     if (!r->layer())
83         return;
84     int x = r->layer()->scrollXOffset();
85     int y = r->layer()->scrollYOffset();
86     if (isHorizontal)
87         x += multiplier;
88     else
89         y += multiplier;
90     r->layer()->scrollToOffset(x, y, true, true);
91 }
92
93 bool FrameView::isFrameView() const
94 {
95     return true;
96 }
97
98 FrameGdk::FrameGdk(GdkDrawable* gdkdrawable)
99     : Frame(new Page, 0), m_drawable(gdkdrawable)
100 {
101     d->m_extension = new BrowserExtensionGdk(this);
102     Settings* settings = new Settings;
103     settings->setAutoLoadImages(true);
104     settings->setMinFontSize(5);
105     settings->setMinLogicalFontSize(5);
106     settings->setShouldPrintBackgrounds(true);
107
108     settings->setMediumFixedFontSize(14);
109     settings->setMediumFontSize(14);
110     settings->setSerifFontName("Times New Roman");
111     settings->setSansSerifFontName("Arial");
112     settings->setFixedFontName("Courier");
113     settings->setStdFontName("Arial");
114     setSettings(settings);
115     page()->setMainFrame(this);
116     FrameView* view = new FrameView(this);
117     setView(view);
118     IntRect geom = frameGeometry();
119     view->resize(geom.width(), geom.height());
120     view->ScrollView::setDrawable(gdkdrawable);
121 }
122
123 FrameGdk::FrameGdk(Page* page, Element* element)
124     : Frame(page,element)
125 {
126     d->m_extension = new BrowserExtensionGdk(this);
127     Settings* settings = new Settings;
128     settings->setAutoLoadImages(true);
129     setSettings(settings);
130 }
131
132 FrameGdk::~FrameGdk()
133 {
134 }
135
136 bool FrameGdk::openURL(const KURL& url)
137 {
138     didOpenURL(url);
139     begin(url);
140     ResourceLoader* job = new ResourceLoader(this, "GET", url);
141     job->start(document()->docLoader());
142     return true;
143 }
144
145 void FrameGdk::submitForm(const ResourceRequest&)
146 {
147 }
148
149 void FrameGdk::urlSelected(const ResourceRequest& request)
150 {
151     //need to potentially updateLocationBar(str.ascii()); or notify sys of new url mybe event or callback
152     const KURL url = request.url();
153     printf("------------------> LOADING NEW URL %s \n", url.url().ascii());
154     didOpenURL(url);
155     begin(url);
156     ResourceLoader* job = new ResourceLoader(this, "GET", url);
157     job->start(document()->docLoader());
158 }
159
160 String FrameGdk::userAgent() const
161 {
162     return "Mozilla/5.0 (PC; U; Intel; Linux; en) AppleWebKit/420+ (KHTML, like Gecko)";
163 }
164
165 void FrameGdk::runJavaScriptAlert(String const& message)
166 {
167 }
168
169 bool FrameGdk::runJavaScriptConfirm(String const& message)
170 {
171     return true;
172 }
173
174 void FrameGdk::setTitle(const String &title)
175 {
176 }
177
178 void FrameGdk::handleGdkEvent(GdkEvent* event)
179 {
180     switch (event->type) {
181         case GDK_EXPOSE: {
182             GdkRectangle clip;
183             gdk_region_get_clipbox(event->expose.region, &clip);
184             gdk_window_begin_paint_region (event->any.window, event->expose.region);
185             cairo_t* cr = gdk_cairo_create (event->any.window);
186             GraphicsContext* ctx = new GraphicsContext(cr);
187             paint(ctx, IntRect(clip.x, clip.y, clip.width, clip.height));
188             delete ctx;
189             gdk_window_end_paint (event->any.window);
190             break;
191         }
192         case GDK_SCROLL: {
193             PlatformWheelEvent wheelEvent(event);
194             view()->handleWheelEvent(wheelEvent);
195             if (wheelEvent.isAccepted()) {
196                 return;
197             }
198             RenderObject::NodeInfo nodeInfo(true, true);
199             renderer()->layer()->hitTest(nodeInfo, wheelEvent.pos());
200             Node* node = nodeInfo.innerNode();
201             if (!node)
202                 return;
203             //Default to scrolling the page
204             //not sure why its null
205             //broke anyway when its not null
206             doScroll(renderer(), wheelEvent.isHorizontal(), wheelEvent.delta());
207             break;
208         }
209         case GDK_DRAG_ENTER:
210         case GDK_DRAG_LEAVE:
211         case GDK_DRAG_MOTION:
212         case GDK_DRAG_STATUS:
213         case GDK_DROP_START:
214         case GDK_DROP_FINISHED: {
215             //bool updateDragAndDrop(const PlatformMouseEvent&, Clipboard*);
216             //void cancelDragAndDrop(const PlatformMouseEvent&, Clipboard*);
217             //bool performDragAndDrop(const PlatformMouseEvent&, Clipboard*);
218             break;
219         }
220         case GDK_MOTION_NOTIFY:
221             view()->handleMouseMoveEvent(event);
222             break;
223         case GDK_BUTTON_PRESS:
224         case GDK_2BUTTON_PRESS:
225         case GDK_3BUTTON_PRESS:
226             view()->handleMousePressEvent(event);
227             break;
228         case GDK_BUTTON_RELEASE:
229             view()->handleMouseReleaseEvent(event);
230             break;
231         case GDK_KEY_PRESS:
232         case GDK_KEY_RELEASE: {
233             PlatformKeyboardEvent kevent(event);
234             bool handled = false;
235             if (!kevent.isKeyUp()) {
236                 Node* start = selectionController()->start().node();
237                 if (start && start->isContentEditable()) {
238                     switch(kevent.WindowsKeyCode()) {
239                         case VK_BACK:
240                             TypingCommand::deleteKeyPressed(document());
241                             break;
242                         case VK_DELETE:
243                             TypingCommand::forwardDeleteKeyPressed(document());
244                             break;
245                         case VK_LEFT:
246                             selectionController()->modify(SelectionController::MOVE, SelectionController::LEFT, CharacterGranularity);
247                             break;
248                         case VK_RIGHT:
249                             selectionController()->modify(SelectionController::MOVE, SelectionController::RIGHT, CharacterGranularity);
250                             break;
251                         case VK_UP:
252                             selectionController()->modify(SelectionController::MOVE, SelectionController::BACKWARD, ParagraphGranularity);
253                             break;
254                         case VK_DOWN:
255                             selectionController()->modify(SelectionController::MOVE, SelectionController::FORWARD, ParagraphGranularity);
256                             break;
257                         default:
258                             TypingCommand::insertText(document(), kevent.text(), false);
259
260                     }
261                     handled = true;
262                 }
263                 if (!handled) {
264                     switch (kevent.WindowsKeyCode()) {
265                         case VK_LEFT:
266                             doScroll(renderer(), true, -120);
267                             break;
268                         case VK_RIGHT:
269                             doScroll(renderer(), true, 120);
270                             break;
271                         case VK_UP:
272                             doScroll(renderer(), false, -120);
273                             break;
274                         case VK_PRIOR:
275                             //return SB_PAGEUP;
276                             break;
277                         case VK_NEXT:
278                             //return SB_PAGEDOWN;
279                             break;
280                         case VK_DOWN:
281                             doScroll(renderer(), false, 120);
282                             break;
283                         case VK_HOME:
284                             renderer()->layer()->scrollToOffset(0, 0, true, true);
285                             doScroll(renderer(), false, 120);
286                             break;
287                         case VK_END:
288                             renderer()->layer()->scrollToOffset(0,
289                                                                 renderer()->height(), true, true);
290                             break;
291                         case VK_SPACE:
292                             if (kevent.shiftKey())
293                                 doScroll(renderer(), false, -120);
294                             else
295                                 doScroll(renderer(), false, 120);
296                             break;
297                     }
298
299                 }
300             }
301         }
302         default:
303             break;
304     }
305 }
306
307 void FrameGdk::receivedData(ResourceLoader* job, const char* data, int length)
308 {
309     write(data, length);
310 }
311
312 void FrameGdk::receivedAllData(ResourceLoader* job, PlatformData data)
313 {
314     end();
315 }
316
317 void FrameGdk::setFrameGeometry(const IntRect &r)
318 {
319     if (!m_drawable || !GDK_IS_WINDOW(m_drawable))
320         return;
321     GdkWindow* window = GDK_WINDOW(m_drawable);
322     gdk_window_move_resize(window, r.x(), r.y(), r.width(), r.height());
323 }
324
325 IntRect FrameGdk::frameGeometry() const
326 {
327     gint x, y, width, height, depth;
328     if (!m_drawable)
329         return IntRect();
330
331     if (!GDK_IS_WINDOW(m_drawable)) {
332         gdk_drawable_get_size(m_drawable, &width, &height);
333         return IntRect(0, 0, width, height);
334     }
335
336     GdkWindow* window = GDK_WINDOW(m_drawable);
337     gdk_window_get_geometry(window, &x, &y, &width, &height, &depth);
338     return IntRect(x, y, width, height);
339 }
340
341 bool FrameGdk::passWheelEventToChildWidget(Node* node)
342 {
343     if (!node)
344         return false;
345     RenderObject* renderer = node->renderer();
346     if (!renderer || !renderer->isWidget())
347         return false;
348     Widget* widget = static_cast<RenderWidget*>(renderer)->widget();
349     if (!widget)
350         return false;
351     return true;
352 }
353
354 bool FrameGdk::passSubframeEventToSubframe(MouseEventWithHitTestResults& mev, Frame*)
355 {
356     if (mev.targetNode() == 0)
357         return true;
358     return false;
359 }
360
361 }