2006-04-28 Steve Falkenburg <sfalken@apple.com>
[WebKit-https.git] / WebKitTools / Spinneret / Spinneret / WebFrame.cpp
1 /*
2  * Copyright (C) 2006 Apple Computer, Inc.  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 "stdafx.h"
27 #include "config.h"
28
29 #include "WebFrame.h"
30 #include "WebView.h"
31 #include "Spinneret.h"
32
33 #include "Document.h"
34 #include "FrameView.h"
35 #include "FrameWin.h"
36 #include "GraphicsContext.h"
37 #include "Page.h"
38 #include "render_frames.h"
39 #include "cairo.h"
40 #include "cairo-win32.h"
41 #include "TransferJob.h"
42
43 #include <io.h>
44 #include <fcntl.h>
45 #include <direct.h>
46
47 using namespace WebCore;
48
49 namespace WebKit {
50
51 class WebFrame::WebFramePrivate {
52 public:
53     WebFramePrivate() { }
54     ~WebFramePrivate() { }
55
56     RefPtr<Frame> frame;
57     RefPtr<FrameView> frameView;
58     WebView* webView;
59 };
60
61 WebFrame::WebFrame(char* name, WebView* view)
62 : d(new WebFrame::WebFramePrivate)
63 {
64     d->webView = view;
65     Page* page = new Page();
66     Frame* frame = new FrameWin(page, 0, this);
67     d->frame = frame;
68     frame->deref(); // Frames are created with a refcount of 1.  Release this ref, since we've assigned it to a RefPtr
69     page->setMainFrame(frame);
70     FrameView* frameView = new FrameView(frame);
71     d->frameView = frameView;
72     frameView->deref(); // FrameViews are created with a refcount of 1.  Release this ref, since we've assigned it to a RefPtr
73     d->frame->setView(frameView);
74     d->frameView->setWindowHandle(view->windowHandle());
75 }
76
77 WebFrame::~WebFrame()
78 {
79     delete d->frame->page();
80     delete d;
81 }
82
83 void WebFrame::loadFilePath(char* path)
84 {
85     char URL[2048];
86     strcpy(URL, "file://localhost/");
87     strncat(URL, path, 2020);
88
89     d->frame->didOpenURL(URL);
90     d->frame->begin(URL);
91     HANDLE fileHandle = CreateFileA(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
92      
93     bool result = false;
94     DWORD bytesRead = 0;
95     
96     do {
97       const int bufferSize = 8193;
98       char buffer[bufferSize];
99       result = ReadFile(fileHandle, &buffer, bufferSize - 1, &bytesRead, NULL); 
100       buffer[bytesRead] = '\0';
101       d->frame->write(buffer);
102       // Check for end of file. 
103     } while (result && bytesRead);
104
105     CloseHandle(fileHandle);
106     
107     d->frame->end();
108 }
109
110 void WebFrame::loadHTMLString(char *html, char *baseURL)
111 {
112     d->frame->begin();
113     d->frame->write(html);
114     d->frame->end();
115 }
116
117 void WebFrame::openURL(const DeprecatedString& str)
118 {
119    updateLocationBar(str.ascii());
120    loadURL(str.ascii());
121 }
122
123 void WebFrame::submitForm(const String& method, const KURL& url, const FormData* submitFormData)
124 {
125     // FIXME: This is a dumb implementation, doesn't handle subframes, etc.
126     d->frame->didOpenURL(url);
127     d->frame->begin(url);
128     TransferJob* job;
129     if (method == "GET" || !submitFormData)
130         job = new TransferJob(this, method, url);
131     else
132         job = new TransferJob(this, method, url, *submitFormData);
133     job->start(d->frame->document()->docLoader());
134 }
135
136 void WebFrame::loadURL(const char* URL)
137 {
138     d->frame->didOpenURL(URL);
139     d->frame->begin(URL);
140     WebCore::TransferJob* job = new TransferJob(this, "GET", URL);
141     job->start(d->frame->document()->docLoader());
142 }
143     
144 void WebFrame::receivedData(WebCore::TransferJob*, const char* data, int length)
145 {
146     d->frame->write(data, length);
147 }
148
149 void WebFrame::receivedAllData(WebCore::TransferJob* job, WebCore::PlatformData)
150 {
151     d->frame->end();
152 }
153
154 void WebFrame::paint()
155 {
156     d->frameView->layout();
157
158     PAINTSTRUCT ps;
159     HDC hdc = BeginPaint(d->webView->windowHandle(), &ps);
160     cairo_surface_t* finalSurface = cairo_win32_surface_create(hdc);
161     cairo_surface_t* surface = cairo_surface_create_similar(finalSurface,
162                                                             CAIRO_CONTENT_COLOR_ALPHA,
163                                                             ps.rcPaint.right, ps.rcPaint.bottom);
164
165     cairo_t* context = cairo_create(surface);
166     GraphicsContext gc(context);
167     
168     IntRect documentDirtyRect = ps.rcPaint;
169     documentDirtyRect.move(d->frameView->contentsX(), d->frameView->contentsY());
170
171     // FIXME: We have to set the transform using both cairo and GDI until we use cairo for text.
172     HDC surfaceDC = cairo_win32_surface_get_dc(surface);
173     SaveDC(surfaceDC);
174     OffsetViewportOrgEx(surfaceDC, -d->frameView->contentsX(), -d->frameView->contentsY(), 0);
175     cairo_translate(context, -d->frameView->contentsX(), -d->frameView->contentsY());
176     d->frame->paint(&gc, documentDirtyRect);
177     RestoreDC(surfaceDC, -1);
178
179     cairo_destroy(context);
180     context = cairo_create(finalSurface);
181     cairo_set_operator(context, CAIRO_OPERATOR_SOURCE);
182     cairo_set_source_surface(context, surface, 0, 0);
183     cairo_rectangle(context, 0, 0, ps.rcPaint.right, ps.rcPaint.bottom);
184     cairo_fill(context);
185     cairo_destroy(context);
186
187     cairo_surface_destroy(surface);
188     cairo_surface_destroy(finalSurface);
189
190     EndPaint(d->webView->windowHandle(), &ps);
191 }
192
193 WebCore::Frame* WebFrame::impl()
194 {
195     return d->frame.get();
196 }
197
198 }
199