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