Reviewed by Darin.
[WebKit-https.git] / WebKitWin / WebFramePrivate.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 "WebFramePrivate.h"
31 #include "WebView.h"
32 #include "WebHost.h"
33
34 #include "Document.h"
35 #include "FrameView.h"
36 #include "FrameWin.h"
37 #include "GraphicsContext.h"
38 #include "Page.h"
39 #include "RenderFrame.h"
40 #include "cairo.h"
41 #include "cairo-win32.h"
42 #include "TransferJob.h"
43 #include "TransferJobWin.h"
44
45 #include <io.h>
46 #include <fcntl.h>
47 #include <direct.h>
48 #include <WinInet.h>
49
50 using namespace WebCore;
51
52 namespace WebKit {
53
54 class WebFramePrivate::WebFrameData {
55 public:
56     WebFrameData() { }
57     ~WebFrameData() { }
58
59     RefPtr<Frame> frame;
60     RefPtr<FrameView> frameView;
61     WebView* webView;
62     WebHost* m_host;
63 };
64
65 WebFramePrivate::WebFramePrivate(char* name, WebView* view, WebHost* host)
66 : d(new WebFramePrivate::WebFrameData)
67 {
68     d->m_host = host;
69     d->webView = view;
70     Page* page = new Page();
71     Frame* frame = new FrameWin(page, 0, this);
72     d->frame = frame;
73     frame->deref(); // Frames are created with a refcount of 1.  Release this ref, since we've assigned it to a RefPtr
74     page->setMainFrame(frame);
75     FrameView* frameView = new FrameView(frame);
76     d->frameView = frameView;
77     frameView->deref(); // FrameViews are created with a refcount of 1.  Release this ref, since we've assigned it to a RefPtr
78     d->frame->setView(frameView);
79     d->frameView->setWindowHandle(view->windowHandle());
80 }
81
82 WebFramePrivate::~WebFramePrivate()
83 {
84     delete d->frame->page();
85     delete d;
86 }
87
88 void WebFramePrivate::loadFilePath(char* path)
89 {
90     char URL[2048];
91     strcpy(URL, "file://localhost/");
92     strncat(URL, path, 2020);
93
94     d->frame->didOpenURL(URL);
95     d->frame->begin(URL);
96     HANDLE fileHandle = CreateFileA(path, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
97      
98     bool result = false;
99     DWORD bytesRead = 0;
100     
101     do {
102       const int bufferSize = 8193;
103       char buffer[bufferSize];
104       result = ReadFile(fileHandle, &buffer, bufferSize - 1, &bytesRead, 0); 
105       buffer[bytesRead] = '\0';
106       d->frame->write(buffer);
107       // Check for end of file. 
108     } while (result && bytesRead);
109
110     CloseHandle(fileHandle);
111     
112     d->frame->end();
113 }
114
115 void WebFramePrivate::loadHTMLString(char* html, char* baseURL)
116 {
117     d->frame->begin();
118     d->frame->write(html);
119     d->frame->end();
120 }
121
122 void WebFramePrivate::openURL(const DeprecatedString& str)
123 {
124     loadURL(str.ascii());
125 }
126
127 void WebFramePrivate::submitForm(const String& method, const KURL& url, const FormData* submitFormData)
128 {
129     // FIXME: This is a dumb implementation, doesn't handle subframes, etc.
130     d->frame->didOpenURL(url);
131     d->frame->begin(url);
132     TransferJob* job;
133     if (method == "GET" || !submitFormData)
134         job = new TransferJob(this, method, url);
135     else
136         job = new TransferJob(this, method, url, *submitFormData);
137     job->start(d->frame->document()->docLoader());
138     if (d->m_host) {
139         DeprecatedCString urlString = url.prettyURL().utf8();
140         d->m_host->updateLocationBar(urlString);
141     }
142 }
143
144 void WebFramePrivate::loadURL(const char* URL)
145 {
146     d->frame->didOpenURL(URL);
147     d->frame->begin(URL);
148     WebCore::TransferJob* job = new TransferJob(this, "GET", URL);
149     job->start(d->frame->document()->docLoader());
150     if (d->m_host)
151         d->m_host->updateLocationBar(URL);
152 }
153
154 void WebFramePrivate::getURL(char* url, int length)
155 {
156     if (length <= 0)
157         return;
158     *url = 0;
159
160     DeprecatedCString urlString = d->frame->url().prettyURL().utf8();
161     const char* srcURL = urlString;
162     if (srcURL) {
163         int srcURLLength = strlen(srcURL);
164         if (length > srcURLLength)
165             strcpy(url, srcURL);
166     }
167 }
168
169 void WebFramePrivate::reload()
170 {
171     if (!d->frame->url().url().startsWith("javascript:", false))
172         d->frame->scheduleLocationChange(d->frame->url().url(), d->frame->referrer(), true/*lock history*/, true/*userGesture*/);
173 }
174     
175 void WebFramePrivate::receivedData(WebCore::TransferJob*, const char* data, int length)
176 {
177     d->frame->write(data, length);
178 }
179
180 void WebFramePrivate::receivedAllData(WebCore::TransferJob* job, WebCore::PlatformData data)
181 {
182     if (d->m_host)
183         (d->m_host->loadEnd)(data->loaded, data->error, data->errorString);
184
185     d->frame->end();
186 }
187
188 void WebFramePrivate::paint()
189 {
190     d->frameView->layout();
191
192     PAINTSTRUCT ps;
193     HDC hdc = BeginPaint(d->webView->windowHandle(), &ps);
194     cairo_surface_t* finalSurface = cairo_win32_surface_create(hdc);
195     cairo_surface_t* surface = cairo_surface_create_similar(finalSurface,
196                                                             CAIRO_CONTENT_COLOR_ALPHA,
197                                                             ps.rcPaint.right, ps.rcPaint.bottom);
198
199     cairo_t* context = cairo_create(surface);
200     GraphicsContext gc(context);
201     
202     IntRect documentDirtyRect = ps.rcPaint;
203     documentDirtyRect.move(d->frameView->contentsX(), d->frameView->contentsY());
204
205     // FIXME: We have to set the transform using both cairo and GDI until we use cairo for text.
206     HDC surfaceDC = cairo_win32_surface_get_dc(surface);
207     SaveDC(surfaceDC);
208     OffsetViewportOrgEx(surfaceDC, -d->frameView->contentsX(), -d->frameView->contentsY(), 0);
209     cairo_translate(context, -d->frameView->contentsX(), -d->frameView->contentsY());
210     d->frame->paint(&gc, documentDirtyRect);
211     RestoreDC(surfaceDC, -1);
212
213     cairo_destroy(context);
214     context = cairo_create(finalSurface);
215     cairo_set_operator(context, CAIRO_OPERATOR_SOURCE);
216     cairo_set_source_surface(context, surface, 0, 0);
217     cairo_rectangle(context, 0, 0, ps.rcPaint.right, ps.rcPaint.bottom);
218     cairo_fill(context);
219     cairo_destroy(context);
220
221     cairo_surface_destroy(surface);
222     cairo_surface_destroy(finalSurface);
223
224     EndPaint(d->webView->windowHandle(), &ps);
225 }
226
227 WebCore::Frame* WebFramePrivate::impl()
228 {
229     return d->frame.get();
230 }
231
232 WebFramePrivate* WebFramePrivate::toPrivate()
233 {
234     return this;
235 }
236
237 }
238