14d8cdae7db48ae33295c35fc985675317361d33
[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, float deltaX, float deltaY)
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
85     int x = r->layer()->scrollXOffset() + deltaX;
86     int y = r->layer()->scrollYOffset() + deltaY;
87     r->layer()->scrollToOffset(x, y, true, true);
88 }
89
90 FrameGdk::FrameGdk(GdkDrawable* gdkdrawable)
91     : Frame(new Page, 0), m_drawable(gdkdrawable)
92 {
93     d->m_extension = new BrowserExtensionGdk(this);
94     Settings* settings = new Settings;
95     settings->setAutoLoadImages(true);
96     settings->setMinFontSize(5);
97     settings->setMinLogicalFontSize(5);
98     settings->setShouldPrintBackgrounds(true);
99
100     settings->setMediumFixedFontSize(14);
101     settings->setMediumFontSize(14);
102     settings->setSerifFontName("Times New Roman");
103     settings->setSansSerifFontName("Arial");
104     settings->setFixedFontName("Courier");
105     settings->setStdFontName("Arial");
106     setSettings(settings);
107     page()->setMainFrame(this);
108     FrameView* view = new FrameView(this);
109     setView(view);
110     IntRect geom = frameGeometry();
111     view->resize(geom.width(), geom.height());
112     view->ScrollView::setDrawable(gdkdrawable);
113 }
114
115 FrameGdk::FrameGdk(Page* page, Element* element)
116     : Frame(page,element)
117 {
118     d->m_extension = new BrowserExtensionGdk(this);
119     Settings* settings = new Settings;
120     settings->setAutoLoadImages(true);
121     setSettings(settings);
122 }
123
124 FrameGdk::~FrameGdk()
125 {
126     cancelAndClear();
127 }
128
129 bool FrameGdk::openURL(const KURL& url)
130 {
131     didOpenURL(url);
132     begin(url);
133     RefPtr<ResourceLoader> loader = ResourceLoader::create(this, "GET", url);
134     loader->start(document()->docLoader());
135     return true;
136 }
137
138 void FrameGdk::submitForm(const ResourceRequest&)
139 {
140 }
141
142 void FrameGdk::urlSelected(const ResourceRequest& request)
143 {
144     //need to potentially updateLocationBar(str.ascii()); or notify sys of new url mybe event or callback
145     const KURL url = request.url();
146     printf("------------------> LOADING NEW URL %s \n", url.url().ascii());
147     didOpenURL(url);
148     begin(url);
149     RefPtr<ResourceLoader> loader = ResourceLoader::create(this, "GET", url);
150     loader->start(document()->docLoader());
151 }
152
153 String FrameGdk::userAgent() const
154 {
155     return "Mozilla/5.0 (PC; U; Intel; Linux; en) AppleWebKit/420+ (KHTML, like Gecko)";
156 }
157
158 void FrameGdk::runJavaScriptAlert(String const& message)
159 {
160 }
161
162 bool FrameGdk::runJavaScriptConfirm(String const& message)
163 {
164     return true;
165 }
166
167 void FrameGdk::setTitle(const String &title)
168 {
169 }
170
171 void FrameGdk::handleGdkEvent(GdkEvent* event)
172 {
173     switch (event->type) {
174         case GDK_EXPOSE: {
175             GdkRectangle clip;
176             gdk_region_get_clipbox(event->expose.region, &clip);
177             gdk_window_begin_paint_region (event->any.window, event->expose.region);
178             cairo_t* cr = gdk_cairo_create (event->any.window);
179             GraphicsContext* ctx = new GraphicsContext(cr);
180             paint(ctx, IntRect(clip.x, clip.y, clip.width, clip.height));
181             delete ctx;
182             cairo_destroy(cr);
183             gdk_window_end_paint (event->any.window);
184             break;
185         }
186         case GDK_SCROLL: {
187             PlatformWheelEvent wheelEvent(event);
188             view()->handleWheelEvent(wheelEvent);
189             if (wheelEvent.isAccepted()) {
190                 return;
191             }
192             RenderObject::NodeInfo nodeInfo(true, true);
193             renderer()->layer()->hitTest(nodeInfo, wheelEvent.pos());
194             Node* node = nodeInfo.innerNode();
195             if (!node)
196                 return;
197             //Default to scrolling the page
198             //not sure why its null
199             //broke anyway when its not null
200             doScroll(renderer(), wheelEvent.deltaX(), wheelEvent.deltaY());
201             break;
202         }
203         case GDK_DRAG_ENTER:
204         case GDK_DRAG_LEAVE:
205         case GDK_DRAG_MOTION:
206         case GDK_DRAG_STATUS:
207         case GDK_DROP_START:
208         case GDK_DROP_FINISHED: {
209             //bool updateDragAndDrop(const PlatformMouseEvent&, Clipboard*);
210             //void cancelDragAndDrop(const PlatformMouseEvent&, Clipboard*);
211             //bool performDragAndDrop(const PlatformMouseEvent&, Clipboard*);
212             break;
213         }
214         case GDK_MOTION_NOTIFY:
215             view()->handleMouseMoveEvent(event);
216             break;
217         case GDK_BUTTON_PRESS:
218         case GDK_2BUTTON_PRESS:
219         case GDK_3BUTTON_PRESS:
220             view()->handleMousePressEvent(event);
221             break;
222         case GDK_BUTTON_RELEASE:
223             view()->handleMouseReleaseEvent(event);
224             break;
225         case GDK_KEY_PRESS:
226         case GDK_KEY_RELEASE: {
227             PlatformKeyboardEvent kevent(event);
228             bool handled = false;
229             if (!kevent.isKeyUp()) {
230                 Node* start = selectionController()->start().node();
231                 if (start && start->isContentEditable()) {
232                     switch(kevent.WindowsKeyCode()) {
233                         case VK_BACK:
234                             TypingCommand::deleteKeyPressed(document());
235                             break;
236                         case VK_DELETE:
237                             TypingCommand::forwardDeleteKeyPressed(document());
238                             break;
239                         case VK_LEFT:
240                             selectionController()->modify(SelectionController::MOVE, SelectionController::LEFT, CharacterGranularity);
241                             break;
242                         case VK_RIGHT:
243                             selectionController()->modify(SelectionController::MOVE, SelectionController::RIGHT, CharacterGranularity);
244                             break;
245                         case VK_UP:
246                             selectionController()->modify(SelectionController::MOVE, SelectionController::BACKWARD, ParagraphGranularity);
247                             break;
248                         case VK_DOWN:
249                             selectionController()->modify(SelectionController::MOVE, SelectionController::FORWARD, ParagraphGranularity);
250                             break;
251                         default:
252                             TypingCommand::insertText(document(), kevent.text(), false);
253
254                     }
255                     handled = true;
256                 }
257                 if (!handled) {
258                     switch (kevent.WindowsKeyCode()) {
259                         case VK_LEFT:
260                             doScroll(renderer(), true, -120);
261                             break;
262                         case VK_RIGHT:
263                             doScroll(renderer(), true, 120);
264                             break;
265                         case VK_UP:
266                             doScroll(renderer(), false, -120);
267                             break;
268                         case VK_PRIOR:
269                             //return SB_PAGEUP;
270                             break;
271                         case VK_NEXT:
272                             //return SB_PAGEDOWN;
273                             break;
274                         case VK_DOWN:
275                             doScroll(renderer(), false, 120);
276                             break;
277                         case VK_HOME:
278                             renderer()->layer()->scrollToOffset(0, 0, true, true);
279                             doScroll(renderer(), false, 120);
280                             break;
281                         case VK_END:
282                             renderer()->layer()->scrollToOffset(0,
283                                                                 renderer()->height(), true, true);
284                             break;
285                         case VK_SPACE:
286                             if (kevent.shiftKey())
287                                 doScroll(renderer(), false, -120);
288                             else
289                                 doScroll(renderer(), false, 120);
290                             break;
291                     }
292
293                 }
294             }
295         }
296         default:
297             break;
298     }
299 }
300
301 void FrameGdk::receivedData(ResourceLoader* job, const char* data, int length)
302 {
303     write(data, length);
304 }
305
306 void FrameGdk::receivedAllData(ResourceLoader* job, PlatformData data)
307 {
308     end();
309 }
310
311 void FrameGdk::setFrameGeometry(const IntRect &r)
312 {
313     if (!m_drawable || !GDK_IS_WINDOW(m_drawable))
314         return;
315     GdkWindow* window = GDK_WINDOW(m_drawable);
316     gdk_window_move_resize(window, r.x(), r.y(), r.width(), r.height());
317 }
318
319 IntRect FrameGdk::frameGeometry() const
320 {
321     gint x, y, width, height, depth;
322     if (!m_drawable)
323         return IntRect();
324
325     if (!GDK_IS_WINDOW(m_drawable)) {
326         gdk_drawable_get_size(m_drawable, &width, &height);
327         return IntRect(0, 0, width, height);
328     }
329
330     GdkWindow* window = GDK_WINDOW(m_drawable);
331     gdk_window_get_geometry(window, &x, &y, &width, &height, &depth);
332     return IntRect(x, y, width, height);
333 }
334
335 bool FrameGdk::passWheelEventToChildWidget(Node* node)
336 {
337     if (!node)
338         return false;
339     RenderObject* renderer = node->renderer();
340     if (!renderer || !renderer->isWidget())
341         return false;
342     Widget* widget = static_cast<RenderWidget*>(renderer)->widget();
343     if (!widget)
344         return false;
345     return true;
346 }
347
348 bool FrameGdk::passSubframeEventToSubframe(MouseEventWithHitTestResults& mev, Frame*)
349 {
350     if (mev.targetNode() == 0)
351         return true;
352     return false;
353 }
354
355 }