2007-05-18 Holger Hans Peter Freyther <zecke@selfish.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
31 #include "CString.h"
32 #include "Document.h"
33 #include "DocumentLoader.h"
34 #include "EventHandler.h"
35 #include "FrameLoader.h"
36 #include "FrameLoaderClientGdk.h"
37 #include "FramePrivate.h"
38 #include "FrameView.h"
39 #include "GraphicsContext.h"
40 #include "HitTestRequest.h"
41 #include "HitTestResult.h"
42 #include "KeyboardCodes.h"
43 #include "NotImplementedGdk.h"
44 #include "Page.h"
45 #include "PlatformKeyboardEvent.h"
46 #include "PlatformMouseEvent.h"
47 #include "PlatformString.h"
48 #include "PlatformWheelEvent.h"
49 #include "RenderObject.h"
50 #include "RenderTreeAsText.h"
51 #include "ResourceHandle.h"
52 #include "ResourceResponse.h"
53 #include "SelectionController.h"
54 #include "Settings.h"
55 #include "TypingCommand.h"
56
57 #include <gdk/gdk.h>
58 #include <gtk/gtk.h>
59
60 // This function loads resources from WebKit
61 // This does not belong here and I'm not sure where
62 // it should go
63 // I don't know what the plans or design is
64 // for none code resources
65 Vector<char> loadResourceIntoArray(const char* resourceName)
66 {
67     Vector<char> resource;
68     //if (strcmp(resourceName,"missingImage") == 0) {
69     //}
70     return resource;
71 }
72
73 namespace WebCore {
74
75 static void doScroll(const RenderObject* r, float deltaX, float deltaY)
76 {
77     // FIXME: The scrolling done here should be done in the default handlers
78     // of the elements rather than here in the part.
79     if (!r)
80         return;
81
82     //broken since it calls scroll on scrollbars
83     //and we have none now
84     //r->scroll(direction, ScrollByWheel, multiplier);
85     if (!r->layer())
86         return;
87
88     int x = r->layer()->scrollXOffset() + (int)deltaX;
89     int y = r->layer()->scrollYOffset() + (int)deltaY;
90     r->layer()->scrollToOffset(x, y, true, true);
91 }
92
93 FrameGdk::FrameGdk(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClientGdk* frameLoader)
94     : Frame(page, ownerElement, frameLoader)
95 {
96     m_exitAfterLoading = false;
97     m_dumpRenderTreeAfterLoading = false;
98
99     Settings* settings = new Settings;
100     settings->setLoadsImagesAutomatically(true);
101     settings->setMinimumFontSize(5);
102     settings->setMinimumLogicalFontSize(5);
103     settings->setShouldPrintBackgrounds(true);
104     settings->setJavaScriptEnabled(true);
105
106     settings->setDefaultFixedFontSize(14);
107     settings->setDefaultFontSize(14);
108     settings->setSerifFontFamily("Times New Roman");
109     settings->setSansSerifFontFamily("Arial");
110     settings->setFixedFontFamily("Courier");
111     settings->setStandardFontFamily("Arial");
112
113     setSettings(settings);
114     frameLoader->setFrame(this);
115 }
116
117 FrameGdk::~FrameGdk()
118 {
119     loader()->cancelAndClear();
120 }
121
122 void FrameGdk::onDidFinishLoad()
123 {
124     if (dumpRenderTreeAfterLoading())
125         dumpRenderTree();
126     if (exitAfterLoading())
127         gtk_main_quit();  // FIXME: a bit drastic?
128 }
129
130 void FrameGdk::dumpRenderTree() const
131 {
132     if (view()->needsLayout())
133         view()->layout();
134     
135     String txt = externalRepresentation(renderer());
136     CString utf8Str = txt.utf8();
137     const char *utf8 = utf8Str.data();
138     if (utf8)
139         printf("%s\n", utf8);
140     else
141         printf("FrameGdk::dumpRenderTree() no data\n");
142 }
143
144 bool FrameGdk::keyPress(const PlatformKeyboardEvent& keyEvent)
145 {
146     if (!eventHandler())
147         return false;
148
149     bool handled = eventHandler()->keyEvent(keyEvent);
150     if (handled)
151         return handled;
152
153     switch (keyEvent.WindowsKeyCode()) {
154         case VK_LEFT:
155             if (!keyEvent.isKeyUp())
156                 doScroll(renderer(), true, -120);
157             break;
158         case VK_RIGHT:
159             if (!keyEvent.isKeyUp())
160                 doScroll(renderer(), true, 120);
161             break;
162         case VK_UP:
163             if (!keyEvent.isKeyUp())
164                 doScroll(renderer(), false, -120);
165             break;
166         case VK_PRIOR:
167             // FIXME: implement me
168             break;
169         case VK_NEXT:
170             // FIXME: implement me
171             break;
172         case VK_DOWN:
173             if (!keyEvent.isKeyUp())
174                 doScroll(renderer(), false, 120);
175             break;
176         case VK_HOME:
177             if (!keyEvent.isKeyUp()) {
178                 renderer()->layer()->scrollToOffset(0, 0, true, true);
179                 doScroll(renderer(), false, 120);
180             }
181             break;
182         case VK_END:
183             if (!keyEvent.isKeyUp())
184                 renderer()->layer()->scrollToOffset(0, renderer()->height(), true, true);
185             break;
186         case VK_SPACE:
187             if (!keyEvent.isKeyUp()) {
188                 if (keyEvent.shiftKey())
189                     doScroll(renderer(), false, -120);
190                 else
191                     doScroll(renderer(), false, 120);
192             }
193             break;
194     }
195     return true;
196 }
197
198 void FrameGdk::handleGdkEvent(GdkEvent* event)
199 {
200     switch (event->type) {
201
202         case GDK_EXPOSE: {
203             GdkRectangle clip;
204             gdk_region_get_clipbox(event->expose.region, &clip);
205             gdk_window_begin_paint_region(event->any.window, event->expose.region);
206             cairo_t* cr = gdk_cairo_create(event->any.window);
207             GraphicsContext ctx(cr);
208             if (renderer()) {
209                 if (view()->needsLayout())
210                     view()->layout();
211                 IntRect rect(clip.x, clip.y, clip.width, clip.height);
212                 paint(&ctx, rect);
213             } else {
214                 IntRect rect(clip.x, clip.y, clip.width, clip.height);
215                 ctx.fillRect(rect, Color(0xff, 0xff, 0xff));
216 #if 0 // FIXME: crashes because font subsystem isn't ready yet
217                 StringImpl txt("Welcome to Gdk Web Browser");
218                 TextRun textRun(txt);
219                 ctx.drawText(textRun, IntPoint(10,10));
220 #endif
221             }
222             cairo_destroy(cr);
223             gdk_window_end_paint(event->any.window);
224             break;
225         }
226
227         case GDK_CONFIGURE: {
228             view()->updateGeometry();
229             forceLayout();
230             break;
231         }
232
233         case GDK_SCROLL: {
234             PlatformWheelEvent wheelEvent(event);
235             view()->wheelEvent(wheelEvent);
236             if (wheelEvent.isAccepted())
237                 return;
238
239             HitTestRequest hitTestRequest(true, true);
240             HitTestResult hitTestResult(wheelEvent.pos());
241             renderer()->layer()->hitTest(hitTestRequest, hitTestResult);
242             Node* node = hitTestResult.innerNode();
243             if (!node)
244                 return;
245             //Default to scrolling the page
246             //not sure why its null
247             //broke anyway when its not null
248             doScroll(renderer(), wheelEvent.deltaX(), wheelEvent.deltaY());
249             break;
250         }
251         case GDK_DRAG_ENTER:
252         case GDK_DRAG_LEAVE:
253         case GDK_DRAG_MOTION:
254         case GDK_DRAG_STATUS:
255         case GDK_DROP_START:
256         case GDK_DROP_FINISHED: {
257             //bool updateDragAndDrop(const PlatformMouseEvent&, Clipboard*);
258             //void cancelDragAndDrop(const PlatformMouseEvent&, Clipboard*);
259             //bool performDragAndDrop(const PlatformMouseEvent&, Clipboard*);
260             break;
261         }
262         case GDK_MOTION_NOTIFY:
263             eventHandler()->handleMouseMoveEvent(PlatformMouseEvent(event));
264             break;
265         case GDK_BUTTON_PRESS:
266         case GDK_2BUTTON_PRESS:
267         case GDK_3BUTTON_PRESS:
268             eventHandler()->handleMousePressEvent(PlatformMouseEvent(event));
269             break;
270         case GDK_BUTTON_RELEASE:
271             eventHandler()->handleMouseReleaseEvent(PlatformMouseEvent(event));
272             break;
273         case GDK_KEY_PRESS:
274         case GDK_KEY_RELEASE: {
275             PlatformKeyboardEvent keyEvent(event);
276             keyPress(keyEvent);
277         }
278         default:
279             break;
280     }
281 }
282
283 void Frame::print() 
284 {
285     notImplementedGdk();
286 }
287
288 void Frame::issueTransposeCommand()
289 {
290     notImplementedGdk();
291 }
292
293 void Frame::cleanupPlatformScriptObjects()
294 {
295     notImplementedGdk();
296 }
297
298 bool Frame::isCharacterSmartReplaceExempt(UChar, bool)
299 {
300     // no smart replace
301     return true;
302 }
303
304 DragImageRef Frame::dragImageForSelection() 
305 {
306     notImplementedGdk();
307     return 0;
308 }
309
310 void Frame::dashboardRegionsChanged()
311 {
312     notImplementedGdk();
313 }
314
315 }