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