2011-01-25 Hans Wennborg <hans@chromium.org>
[WebKit.git] / Source / WebKit / chromium / src / PlatformBridge.cpp
1 /*
2  * Copyright (C) 2009 Google 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 are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "config.h"
32 #include "PlatformBridge.h"
33
34 #include <googleurl/src/url_util.h>
35
36 #include "Chrome.h"
37 #include "ChromeClientImpl.h"
38 #include "WebAudioBus.h"
39 #include "WebClipboard.h"
40 #include "WebCookie.h"
41 #include "WebCookieJar.h"
42 #include "WebData.h"
43 #include "WebDragData.h"
44 #include "WebFileUtilities.h"
45 #include "WebFrameClient.h"
46 #include "WebFrameImpl.h"
47 #include "WebIDBKey.h"
48 #include "WebImage.h"
49 #include "WebKit.h"
50 #include "WebKitClient.h"
51 #include "WebMimeRegistry.h"
52 #include "WebPluginContainerImpl.h"
53 #include "WebPluginListBuilderImpl.h"
54 #include "WebSandboxSupport.h"
55 #include "WebSerializedScriptValue.h"
56 #include "WebScreenInfo.h"
57 #include "WebString.h"
58 #include "WebURL.h"
59 #include "WebVector.h"
60 #include "WebViewClient.h"
61 #include "WebViewImpl.h"
62 #include "WebWorkerClientImpl.h"
63
64 #if PLATFORM(CG)
65 #include <CoreGraphics/CGContext.h>
66 #endif
67
68 #if OS(WINDOWS)
69 #include "WebRect.h"
70 #include "win/WebThemeEngine.h"
71 #endif
72
73 #if OS(LINUX) || OS(FREEBSD)
74 #include "linux/WebThemeEngine.h"
75 #include "WebFontInfo.h"
76 #include "WebFontRenderStyle.h"
77 #endif
78
79 #if OS(DARWIN)
80 #include "mac/WebThemeEngine.h"
81 #endif
82
83 #if WEBKIT_USING_SKIA
84 #include "NativeImageSkia.h"
85 #endif
86
87 #include "BitmapImage.h"
88 #include "Cookie.h"
89 #include "FrameView.h"
90 #include "GraphicsContext.h"
91 #include "IDBFactoryBackendProxy.h"
92 #include "KURL.h"
93 #include "NotImplemented.h"
94 #include "PlatformContextSkia.h"
95 #include "PluginData.h"
96 #include "SharedBuffer.h"
97
98 #include "Worker.h"
99 #include "WorkerContextProxy.h"
100 #include <wtf/Assertions.h>
101
102 // We are part of the WebKit implementation.
103 using namespace WebKit;
104
105 namespace WebCore {
106
107 static ChromeClientImpl* toChromeClientImpl(Widget* widget)
108 {
109     if (!widget)
110         return 0;
111
112     FrameView* view;
113     if (widget->isFrameView())
114         view = static_cast<FrameView*>(widget);
115     else if (widget->parent() && widget->parent()->isFrameView())
116         view = static_cast<FrameView*>(widget->parent());
117     else
118         return 0;
119
120     Page* page = view->frame() ? view->frame()->page() : 0;
121     if (!page)
122         return 0;
123
124     return static_cast<ChromeClientImpl*>(page->chrome()->client());
125 }
126
127 static WebWidgetClient* toWebWidgetClient(Widget* widget)
128 {
129     ChromeClientImpl* chromeClientImpl = toChromeClientImpl(widget);
130     if (!chromeClientImpl || !chromeClientImpl->webView())
131         return 0;
132     return chromeClientImpl->webView()->client();
133 }
134
135 static WebCookieJar* getCookieJar(const Document* document)
136 {
137     WebFrameImpl* frameImpl = WebFrameImpl::fromFrame(document->frame());
138     if (!frameImpl || !frameImpl->client())
139         return 0;
140     WebCookieJar* cookieJar = frameImpl->client()->cookieJar(frameImpl);
141     if (!cookieJar)
142         cookieJar = webKitClient()->cookieJar();
143     return cookieJar;
144 }
145
146 // Cache ----------------------------------------------------------------------
147
148 void PlatformBridge::cacheMetadata(const KURL& url, double responseTime, const Vector<char>& data)
149 {
150     webKitClient()->cacheMetadata(url, responseTime, data.data(), data.size());
151 }
152
153 // Clipboard ------------------------------------------------------------------
154
155 bool PlatformBridge::clipboardIsFormatAvailable(
156     PasteboardPrivate::ClipboardFormat format,
157     PasteboardPrivate::ClipboardBuffer buffer)
158 {
159     return webKitClient()->clipboard()->isFormatAvailable(
160         static_cast<WebClipboard::Format>(format),
161         static_cast<WebClipboard::Buffer>(buffer));
162 }
163
164 String PlatformBridge::clipboardReadPlainText(
165     PasteboardPrivate::ClipboardBuffer buffer)
166 {
167     return webKitClient()->clipboard()->readPlainText(
168         static_cast<WebClipboard::Buffer>(buffer));
169 }
170
171 void PlatformBridge::clipboardReadHTML(
172     PasteboardPrivate::ClipboardBuffer buffer,
173     String* htmlText, KURL* sourceURL)
174 {
175     WebURL url;
176     *htmlText = webKitClient()->clipboard()->readHTML(
177         static_cast<WebClipboard::Buffer>(buffer), &url);
178     *sourceURL = url;
179 }
180
181 void PlatformBridge::clipboardWriteSelection(const String& htmlText,
182                                              const KURL& sourceURL,
183                                              const String& plainText,
184                                              bool writeSmartPaste)
185 {
186     webKitClient()->clipboard()->writeHTML(
187         htmlText, sourceURL, plainText, writeSmartPaste);
188 }
189
190 void PlatformBridge::clipboardWritePlainText(const String& plainText)
191 {
192     webKitClient()->clipboard()->writePlainText(plainText);
193 }
194
195 void PlatformBridge::clipboardWriteURL(const KURL& url, const String& title)
196 {
197     webKitClient()->clipboard()->writeURL(url, title);
198 }
199
200 void PlatformBridge::clipboardWriteImage(NativeImagePtr image,
201                                          const KURL& sourceURL,
202                                          const String& title)
203 {
204 #if WEBKIT_USING_SKIA
205     WebImage webImage(*image);
206 #else
207     WebImage webImage(image);
208 #endif
209     webKitClient()->clipboard()->writeImage(webImage, sourceURL, title);
210 }
211
212 void PlatformBridge::clipboardWriteData(const String& type,
213                                         const String& data,
214                                         const String& metadata)
215 {
216     webKitClient()->clipboard()->writeData(type, data, metadata);
217 }
218
219 HashSet<String> PlatformBridge::clipboardReadAvailableTypes(
220     PasteboardPrivate::ClipboardBuffer buffer, bool* containsFilenames)
221 {
222     WebVector<WebString> result = webKitClient()->clipboard()->readAvailableTypes(
223         static_cast<WebClipboard::Buffer>(buffer), containsFilenames);
224     HashSet<String> types;
225     for (size_t i = 0; i < result.size(); ++i)
226         types.add(result[i]);
227     return types;
228 }
229
230 bool PlatformBridge::clipboardReadData(PasteboardPrivate::ClipboardBuffer buffer,
231                                        const String& type, String& data, String& metadata)
232 {
233     WebString resultData;
234     WebString resultMetadata;
235     bool succeeded = webKitClient()->clipboard()->readData(
236         static_cast<WebClipboard::Buffer>(buffer), type, &resultData, &resultMetadata);
237     if (succeeded) {
238         data = resultData;
239         metadata = resultMetadata;
240     }
241     return succeeded;
242 }
243
244 Vector<String> PlatformBridge::clipboardReadFilenames(PasteboardPrivate::ClipboardBuffer buffer)
245 {
246     WebVector<WebString> result = webKitClient()->clipboard()->readFilenames(
247         static_cast<WebClipboard::Buffer>(buffer));
248     Vector<String> convertedResult;
249     for (size_t i = 0; i < result.size(); ++i)
250         convertedResult.append(result[i]);
251     return convertedResult;
252 }
253
254 // Cookies --------------------------------------------------------------------
255
256 void PlatformBridge::setCookies(const Document* document, const KURL& url,
257                                 const String& value)
258 {
259     WebCookieJar* cookieJar = getCookieJar(document);
260     if (cookieJar)
261         cookieJar->setCookie(url, document->firstPartyForCookies(), value);
262 }
263
264 String PlatformBridge::cookies(const Document* document, const KURL& url)
265 {
266     String result;
267     WebCookieJar* cookieJar = getCookieJar(document);
268     if (cookieJar)
269         result = cookieJar->cookies(url, document->firstPartyForCookies());
270     return result;
271 }
272
273 String PlatformBridge::cookieRequestHeaderFieldValue(const Document* document,
274                                                      const KURL& url)
275 {
276     String result;
277     WebCookieJar* cookieJar = getCookieJar(document);
278     if (cookieJar)
279         result = cookieJar->cookieRequestHeaderFieldValue(url, document->firstPartyForCookies());
280     return result;
281 }
282
283 bool PlatformBridge::rawCookies(const Document* document, const KURL& url, Vector<Cookie>& rawCookies)
284 {
285     rawCookies.clear();
286     WebVector<WebCookie> webCookies;
287
288     WebCookieJar* cookieJar = getCookieJar(document);
289     if (cookieJar)
290         cookieJar->rawCookies(url, document->firstPartyForCookies(), webCookies);
291
292     for (unsigned i = 0; i < webCookies.size(); ++i) {
293         const WebCookie& webCookie = webCookies[i];
294         Cookie cookie(webCookie.name,
295                       webCookie.value,
296                       webCookie.domain,
297                       webCookie.path,
298                       webCookie.expires,
299                       webCookie.httpOnly,
300                       webCookie.secure,
301                       webCookie.session);
302         rawCookies.append(cookie);
303     }
304     return true;
305 }
306
307 void PlatformBridge::deleteCookie(const Document* document, const KURL& url, const String& cookieName)
308 {
309     WebCookieJar* cookieJar = getCookieJar(document);
310     if (cookieJar)
311         cookieJar->deleteCookie(url, cookieName);
312 }
313
314 bool PlatformBridge::cookiesEnabled(const Document* document)
315 {
316     bool result = false;
317     WebCookieJar* cookieJar = getCookieJar(document);
318     if (cookieJar)
319         result = cookieJar->cookiesEnabled(document->cookieURL(), document->firstPartyForCookies());
320     return result;
321 }
322
323 // DNS ------------------------------------------------------------------------
324
325 void PlatformBridge::prefetchDNS(const String& hostname)
326 {
327     webKitClient()->prefetchHostName(hostname);
328 }
329
330 // File ------------------------------------------------------------------------
331
332 bool PlatformBridge::fileExists(const String& path)
333 {
334     return webKitClient()->fileUtilities()->fileExists(path);
335 }
336
337 bool PlatformBridge::deleteFile(const String& path)
338 {
339     return webKitClient()->fileUtilities()->deleteFile(path);
340 }
341
342 bool PlatformBridge::deleteEmptyDirectory(const String& path)
343 {
344     return webKitClient()->fileUtilities()->deleteEmptyDirectory(path);
345 }
346
347 bool PlatformBridge::getFileSize(const String& path, long long& result)
348 {
349     return webKitClient()->fileUtilities()->getFileSize(path, result);
350 }
351
352 void PlatformBridge::revealFolderInOS(const String& path)
353 {
354     webKitClient()->fileUtilities()->revealFolderInOS(path);
355 }
356
357 bool PlatformBridge::getFileModificationTime(const String& path, time_t& result)
358 {
359     double modificationTime;
360     if (!webKitClient()->fileUtilities()->getFileModificationTime(path, modificationTime))
361         return false;
362     result = static_cast<time_t>(modificationTime);
363     return true;
364 }
365
366 String PlatformBridge::directoryName(const String& path)
367 {
368     return webKitClient()->fileUtilities()->directoryName(path);
369 }
370
371 String PlatformBridge::pathByAppendingComponent(const String& path, const String& component)
372 {
373     return webKitClient()->fileUtilities()->pathByAppendingComponent(path, component);
374 }
375
376 bool PlatformBridge::makeAllDirectories(const String& path)
377 {
378     return webKitClient()->fileUtilities()->makeAllDirectories(path);
379 }
380
381 String PlatformBridge::getAbsolutePath(const String& path)
382 {
383     return webKitClient()->fileUtilities()->getAbsolutePath(path);
384 }
385
386 bool PlatformBridge::isDirectory(const String& path)
387 {
388     return webKitClient()->fileUtilities()->isDirectory(path);
389 }
390
391 KURL PlatformBridge::filePathToURL(const String& path)
392 {
393     return webKitClient()->fileUtilities()->filePathToURL(path);
394 }
395
396 PlatformFileHandle PlatformBridge::openFile(const String& path, FileOpenMode mode)
397 {
398     return webKitClient()->fileUtilities()->openFile(path, mode);
399 }
400
401 void PlatformBridge::closeFile(PlatformFileHandle& handle)
402 {
403     webKitClient()->fileUtilities()->closeFile(handle);
404 }
405
406 long long PlatformBridge::seekFile(PlatformFileHandle handle, long long offset, FileSeekOrigin origin)
407 {
408     return webKitClient()->fileUtilities()->seekFile(handle, offset, origin);
409 }
410
411 bool PlatformBridge::truncateFile(PlatformFileHandle handle, long long offset)
412 {
413     return webKitClient()->fileUtilities()->truncateFile(handle, offset);
414 }
415
416 int PlatformBridge::readFromFile(PlatformFileHandle handle, char* data, int length)
417 {
418     return webKitClient()->fileUtilities()->readFromFile(handle, data, length);
419 }
420
421 int PlatformBridge::writeToFile(PlatformFileHandle handle, const char* data, int length)
422 {
423     return webKitClient()->fileUtilities()->writeToFile(handle, data, length);
424 }
425
426 // Font -----------------------------------------------------------------------
427
428 #if OS(WINDOWS)
429 bool PlatformBridge::ensureFontLoaded(HFONT font)
430 {
431     WebSandboxSupport* ss = webKitClient()->sandboxSupport();
432
433     // if there is no sandbox, then we can assume the font
434     // was able to be loaded successfully already
435     return ss ? ss->ensureFontLoaded(font) : true;
436 }
437 #endif
438
439 #if OS(LINUX) || OS(FREEBSD)
440 String PlatformBridge::getFontFamilyForCharacters(const UChar* characters, size_t numCharacters)
441 {
442     if (webKitClient()->sandboxSupport())
443         return webKitClient()->sandboxSupport()->getFontFamilyForCharacters(characters, numCharacters);
444
445     WebCString family = WebFontInfo::familyForChars(characters, numCharacters);
446     if (family.data())
447         return WebString::fromUTF8(family.data());
448
449     return WebString();
450 }
451
452 void PlatformBridge::getRenderStyleForStrike(const char* font, int sizeAndStyle, FontRenderStyle* result)
453 {
454     WebFontRenderStyle style;
455
456     if (webKitClient()->sandboxSupport())
457         webKitClient()->sandboxSupport()->getRenderStyleForStrike(font, sizeAndStyle, &style);
458     else
459         WebFontInfo::renderStyleForStrike(font, sizeAndStyle, &style);
460
461     style.toFontRenderStyle(result);
462 }
463 #endif
464
465 #if OS(DARWIN)
466 bool PlatformBridge::loadFont(NSFont* srcFont, ATSFontContainerRef* out)
467 {
468     WebSandboxSupport* ss = webKitClient()->sandboxSupport();
469     if (ss)
470         return ss->loadFont(srcFont, out);
471
472     // This function should only be called in response to an error loading a
473     // font due to being blocked by the sandbox.
474     // This by definition shouldn't happen if there is no sandbox support.
475     ASSERT_NOT_REACHED();
476     *out = 0;
477     return false;
478 }
479 #endif
480
481 // Databases ------------------------------------------------------------------
482
483 PlatformFileHandle PlatformBridge::databaseOpenFile(const String& vfsFileName, int desiredFlags)
484 {
485     return webKitClient()->databaseOpenFile(WebString(vfsFileName), desiredFlags);
486 }
487
488 int PlatformBridge::databaseDeleteFile(const String& vfsFileName, bool syncDir)
489 {
490     return webKitClient()->databaseDeleteFile(WebString(vfsFileName), syncDir);
491 }
492
493 long PlatformBridge::databaseGetFileAttributes(const String& vfsFileName)
494 {
495     return webKitClient()->databaseGetFileAttributes(WebString(vfsFileName));
496 }
497
498 long long PlatformBridge::databaseGetFileSize(const String& vfsFileName)
499 {
500     return webKitClient()->databaseGetFileSize(WebString(vfsFileName));
501 }
502
503 // Indexed Database -----------------------------------------------------------
504
505 PassRefPtr<IDBFactoryBackendInterface> PlatformBridge::idbFactory()
506 {
507     // There's no reason why we need to allocate a new proxy each time, but
508     // there's also no strong reason not to.
509     return IDBFactoryBackendProxy::create();
510 }
511
512 void PlatformBridge::createIDBKeysFromSerializedValuesAndKeyPath(const Vector<RefPtr<SerializedScriptValue> >& values, const String& keyPath, Vector<RefPtr<IDBKey> >& keys)
513 {
514     WebVector<WebSerializedScriptValue> webValues = values;
515     WebVector<WebIDBKey> webKeys;
516     webKitClient()->createIDBKeysFromSerializedValuesAndKeyPath(webValues, WebString(keyPath), webKeys);
517
518     size_t webKeysSize = webKeys.size();
519     keys.reserveCapacity(webKeysSize);
520     for (size_t i = 0; i < webKeysSize; ++i)
521         keys.append(PassRefPtr<IDBKey>(webKeys[i]));
522 }
523
524 // Keygen ---------------------------------------------------------------------
525
526 String PlatformBridge::signedPublicKeyAndChallengeString(
527     unsigned keySizeIndex, const String& challenge, const KURL& url)
528 {
529     return webKitClient()->signedPublicKeyAndChallengeString(keySizeIndex,
530                                                              WebString(challenge),
531                                                              WebURL(url));
532 }
533
534 // Language -------------------------------------------------------------------
535
536 String PlatformBridge::computedDefaultLanguage()
537 {
538     return webKitClient()->defaultLocale();
539 }
540
541 // LayoutTestMode -------------------------------------------------------------
542
543 bool PlatformBridge::layoutTestMode()
544 {
545     return WebKit::layoutTestMode();
546 }
547
548 // MimeType -------------------------------------------------------------------
549
550 bool PlatformBridge::isSupportedImageMIMEType(const String& mimeType)
551 {
552     return webKitClient()->mimeRegistry()->supportsImageMIMEType(mimeType)
553         != WebMimeRegistry::IsNotSupported;
554 }
555
556 bool PlatformBridge::isSupportedJavaScriptMIMEType(const String& mimeType)
557 {
558     return webKitClient()->mimeRegistry()->supportsJavaScriptMIMEType(mimeType)
559         != WebMimeRegistry::IsNotSupported;
560 }
561
562 bool PlatformBridge::isSupportedNonImageMIMEType(const String& mimeType)
563 {
564     return webKitClient()->mimeRegistry()->supportsNonImageMIMEType(mimeType)
565         != WebMimeRegistry::IsNotSupported;
566 }
567
568 String PlatformBridge::mimeTypeForExtension(const String& extension)
569 {
570     return webKitClient()->mimeRegistry()->mimeTypeForExtension(extension);
571 }
572
573 String PlatformBridge::mimeTypeFromFile(const String& path)
574 {
575     return webKitClient()->mimeRegistry()->mimeTypeFromFile(path);
576 }
577
578 String PlatformBridge::preferredExtensionForMIMEType(const String& mimeType)
579 {
580     return webKitClient()->mimeRegistry()->preferredExtensionForMIMEType(mimeType);
581 }
582
583 // Plugin ---------------------------------------------------------------------
584
585 bool PlatformBridge::plugins(bool refresh, Vector<PluginInfo>* results)
586 {
587     WebPluginListBuilderImpl builder(results);
588     webKitClient()->getPluginList(refresh, &builder);
589     return true;  // FIXME: There is no need for this function to return a value.
590 }
591
592 NPObject* PlatformBridge::pluginScriptableObject(Widget* widget)
593 {
594     if (!widget || !widget->isPluginContainer())
595         return 0;
596
597     return static_cast<WebPluginContainerImpl*>(widget)->scriptableObject();
598 }
599
600 // Resources ------------------------------------------------------------------
601
602 PassRefPtr<Image> PlatformBridge::loadPlatformImageResource(const char* name)
603 {
604     const WebData& resource = webKitClient()->loadResource(name);
605     if (resource.isEmpty())
606         return Image::nullImage();
607
608     RefPtr<Image> image = BitmapImage::create();
609     image->setData(resource, true);
610     return image;
611 }
612
613 #if ENABLE(WEB_AUDIO)
614
615 PassOwnPtr<AudioBus> PlatformBridge::loadPlatformAudioResource(const char* name, double sampleRate)
616 {
617     const WebData& resource = webKitClient()->loadResource(name);
618     if (resource.isEmpty())
619         return 0;
620     
621     return decodeAudioFileData(resource.data(), resource.size(), sampleRate);
622 }
623
624 PassOwnPtr<AudioBus> PlatformBridge::decodeAudioFileData(const char* data, size_t size, double sampleRate)
625 {
626     WebAudioBus webAudioBus;
627     if (webKitClient()->loadAudioResource(&webAudioBus, data, size, sampleRate))
628         return webAudioBus.release();
629     return 0;
630 }
631
632 #endif // ENABLE(WEB_AUDIO)
633
634 // Sandbox --------------------------------------------------------------------
635
636 bool PlatformBridge::sandboxEnabled()
637 {
638     return webKitClient()->sandboxEnabled();
639 }
640
641 // SharedTimers ---------------------------------------------------------------
642
643 void PlatformBridge::setSharedTimerFiredFunction(void (*func)())
644 {
645     webKitClient()->setSharedTimerFiredFunction(func);
646 }
647
648 void PlatformBridge::setSharedTimerFireTime(double fireTime)
649 {
650     webKitClient()->setSharedTimerFireTime(fireTime);
651 }
652
653 void PlatformBridge::stopSharedTimer()
654 {
655     webKitClient()->stopSharedTimer();
656 }
657
658 // StatsCounters --------------------------------------------------------------
659
660 void PlatformBridge::decrementStatsCounter(const char* name)
661 {
662     webKitClient()->decrementStatsCounter(name);
663 }
664
665 void PlatformBridge::incrementStatsCounter(const char* name)
666 {
667     webKitClient()->incrementStatsCounter(name);
668 }
669
670 void PlatformBridge::histogramCustomCounts(const char* name, int sample, int min, int max, int bucketCount)
671 {
672     webKitClient()->histogramCustomCounts(name, sample, min, max, bucketCount);
673 }
674
675 void PlatformBridge::histogramEnumeration(const char* name, int sample, int boundaryValue)
676 {
677     webKitClient()->histogramEnumeration(name, sample, boundaryValue);
678 }
679
680 // Sudden Termination ---------------------------------------------------------
681
682 void PlatformBridge::suddenTerminationChanged(bool enabled)
683 {
684     webKitClient()->suddenTerminationChanged(enabled);
685 }
686
687 // SystemTime -----------------------------------------------------------------
688
689 double PlatformBridge::currentTime()
690 {
691     return webKitClient()->currentTime();
692 }
693
694 // Theming --------------------------------------------------------------------
695
696 #if OS(WINDOWS)
697
698 void PlatformBridge::paintButton(
699     GraphicsContext* gc, int part, int state, int classicState,
700     const IntRect& rect)
701 {
702     webKitClient()->themeEngine()->paintButton(
703         gc->platformContext()->canvas(), part, state, classicState, rect);
704 }
705
706 void PlatformBridge::paintMenuList(
707     GraphicsContext* gc, int part, int state, int classicState,
708     const IntRect& rect)
709 {
710     webKitClient()->themeEngine()->paintMenuList(
711         gc->platformContext()->canvas(), part, state, classicState, rect);
712 }
713
714 void PlatformBridge::paintScrollbarArrow(
715     GraphicsContext* gc, int state, int classicState,
716     const IntRect& rect)
717 {
718     webKitClient()->themeEngine()->paintScrollbarArrow(
719         gc->platformContext()->canvas(), state, classicState, rect);
720 }
721
722 void PlatformBridge::paintScrollbarThumb(
723     GraphicsContext* gc, int part, int state, int classicState,
724     const IntRect& rect)
725 {
726     webKitClient()->themeEngine()->paintScrollbarThumb(
727         gc->platformContext()->canvas(), part, state, classicState, rect);
728 }
729
730 void PlatformBridge::paintScrollbarTrack(
731     GraphicsContext* gc, int part, int state, int classicState,
732     const IntRect& rect, const IntRect& alignRect)
733 {
734     webKitClient()->themeEngine()->paintScrollbarTrack(
735         gc->platformContext()->canvas(), part, state, classicState, rect,
736         alignRect);
737 }
738
739 void PlatformBridge::paintSpinButton(
740     GraphicsContext* gc, int part, int state, int classicState,
741     const IntRect& rect)
742 {
743     webKitClient()->themeEngine()->paintSpinButton(
744         gc->platformContext()->canvas(), part, state, classicState, rect);
745 }
746
747 void PlatformBridge::paintTextField(
748     GraphicsContext* gc, int part, int state, int classicState,
749     const IntRect& rect, const Color& color, bool fillContentArea,
750     bool drawEdges)
751 {
752     // Fallback to white when |color| is invalid.
753     RGBA32 backgroundColor = color.isValid() ? color.rgb() : Color::white;
754
755     webKitClient()->themeEngine()->paintTextField(
756         gc->platformContext()->canvas(), part, state, classicState, rect,
757         backgroundColor, fillContentArea, drawEdges);
758 }
759
760 void PlatformBridge::paintTrackbar(
761     GraphicsContext* gc, int part, int state, int classicState,
762     const IntRect& rect)
763 {
764     webKitClient()->themeEngine()->paintTrackbar(
765         gc->platformContext()->canvas(), part, state, classicState, rect);
766 }
767
768 void PlatformBridge::paintProgressBar(
769     GraphicsContext* gc, const IntRect& barRect, const IntRect& valueRect, bool determinate, double animatedSeconds)
770 {
771     webKitClient()->themeEngine()->paintProgressBar(
772         gc->platformContext()->canvas(), barRect, valueRect, determinate, animatedSeconds);
773 }
774
775 #elif OS(LINUX)
776
777 static WebThemeEngine::Part WebThemePart(PlatformBridge::ThemePart part)
778 {
779     switch (part) {
780     case PlatformBridge::PartScrollbarDownArrow: return WebThemeEngine::PartScrollbarDownArrow;
781     case PlatformBridge::PartScrollbarLeftArrow: return WebThemeEngine::PartScrollbarLeftArrow;
782     case PlatformBridge::PartScrollbarRightArrow: return WebThemeEngine::PartScrollbarRightArrow;
783     case PlatformBridge::PartScrollbarUpArrow: return WebThemeEngine::PartScrollbarUpArrow;
784     case PlatformBridge::PartScrollbarHorizontalThumb: return WebThemeEngine::PartScrollbarHorizontalThumb;
785     case PlatformBridge::PartScrollbarVerticalThumb: return WebThemeEngine::PartScrollbarVerticalThumb;
786     case PlatformBridge::PartScrollbarHorizontalTrack: return WebThemeEngine::PartScrollbarHorizontalTrack;
787     case PlatformBridge::PartScrollbarVerticalTrack: return WebThemeEngine::PartScrollbarVerticalTrack;
788     case PlatformBridge::PartCheckbox: return WebThemeEngine::PartCheckbox;
789     case PlatformBridge::PartRadio: return WebThemeEngine::PartRadio;
790     case PlatformBridge::PartButton: return WebThemeEngine::PartButton;
791     case PlatformBridge::PartTextField: return WebThemeEngine::PartTextField;
792     case PlatformBridge::PartMenuList: return WebThemeEngine::PartMenuList;
793     case PlatformBridge::PartSliderTrack: return WebThemeEngine::PartSliderTrack;
794     case PlatformBridge::PartSliderThumb: return WebThemeEngine::PartSliderThumb;
795     case PlatformBridge::PartInnerSpinButton: return WebThemeEngine::PartInnerSpinButton;
796     case PlatformBridge::PartProgressBar: return WebThemeEngine::PartProgressBar;
797     }
798     ASSERT_NOT_REACHED();
799     return WebThemeEngine::PartScrollbarDownArrow;
800 }
801
802 static WebThemeEngine::State WebThemeState(PlatformBridge::ThemePaintState state)
803 {
804     switch (state) {
805     case PlatformBridge::StateDisabled: return WebThemeEngine::StateDisabled;
806     case PlatformBridge::StateHover: return WebThemeEngine::StateHover;
807     case PlatformBridge::StateNormal: return WebThemeEngine::StateNormal;
808     case PlatformBridge::StatePressed: return WebThemeEngine::StatePressed;
809     }
810     ASSERT_NOT_REACHED();
811     return WebThemeEngine::StateDisabled;
812 }
813
814 static void GetWebThemeExtraParams(PlatformBridge::ThemePart part, PlatformBridge::ThemePaintState state, const PlatformBridge::ThemePaintExtraParams* extraParams, WebThemeEngine::ExtraParams* webThemeExtraParams)
815 {
816     switch (part) {
817     case PlatformBridge::PartScrollbarHorizontalTrack:
818     case PlatformBridge::PartScrollbarVerticalTrack:
819         webThemeExtraParams->scrollbarTrack.trackX = extraParams->scrollbarTrack.trackX;
820         webThemeExtraParams->scrollbarTrack.trackY = extraParams->scrollbarTrack.trackY;
821         webThemeExtraParams->scrollbarTrack.trackWidth = extraParams->scrollbarTrack.trackWidth;
822         webThemeExtraParams->scrollbarTrack.trackHeight = extraParams->scrollbarTrack.trackHeight;
823         break;
824     case PlatformBridge::PartCheckbox:
825         webThemeExtraParams->button.checked = extraParams->button.checked;
826         webThemeExtraParams->button.indeterminate = extraParams->button.indeterminate;
827         break;
828     case PlatformBridge::PartRadio:
829         webThemeExtraParams->button.checked = extraParams->button.checked;
830         break;
831     case PlatformBridge::PartButton:
832         webThemeExtraParams->button.isDefault = extraParams->button.isDefault;
833         webThemeExtraParams->button.backgroundColor = extraParams->button.backgroundColor;
834         break;
835     case PlatformBridge::PartTextField:
836         webThemeExtraParams->textField.isTextArea = extraParams->textField.isTextArea;
837         webThemeExtraParams->textField.isListbox = extraParams->textField.isListbox;
838         webThemeExtraParams->textField.backgroundColor = extraParams->textField.backgroundColor;
839         break;
840     case PlatformBridge::PartMenuList:
841         webThemeExtraParams->menuList.arrowX = extraParams->menuList.arrowX;
842         webThemeExtraParams->menuList.arrowY = extraParams->menuList.arrowY;
843         webThemeExtraParams->menuList.backgroundColor = extraParams->menuList.backgroundColor;
844         break;
845     case PlatformBridge::PartSliderTrack:
846     case PlatformBridge::PartSliderThumb:
847         webThemeExtraParams->slider.vertical = extraParams->slider.vertical;
848         webThemeExtraParams->slider.inDrag = extraParams->slider.inDrag;
849         break;
850     case PlatformBridge::PartInnerSpinButton:
851         webThemeExtraParams->innerSpin.spinUp = extraParams->innerSpin.spinUp;
852         webThemeExtraParams->innerSpin.readOnly = extraParams->innerSpin.readOnly;
853         break;
854     case PlatformBridge::PartProgressBar:
855         webThemeExtraParams->progressBar.determinate = extraParams->progressBar.determinate;
856         webThemeExtraParams->progressBar.valueRectX = extraParams->progressBar.valueRectX;
857         webThemeExtraParams->progressBar.valueRectY = extraParams->progressBar.valueRectY;
858         webThemeExtraParams->progressBar.valueRectWidth = extraParams->progressBar.valueRectWidth;
859         webThemeExtraParams->progressBar.valueRectHeight = extraParams->progressBar.valueRectHeight;
860         break;
861     default:
862         break; // Parts that have no extra params get here.
863     }
864 }
865
866 IntSize PlatformBridge::getThemePartSize(ThemePart part)
867 {
868      return webKitClient()->themeEngine()->getSize(WebThemePart(part));
869 }
870
871 void PlatformBridge::paintThemePart(
872     GraphicsContext* gc, ThemePart part, ThemePaintState state, const IntRect& rect, const ThemePaintExtraParams* extraParams)
873 {
874     WebThemeEngine::ExtraParams webThemeExtraParams;
875     GetWebThemeExtraParams(part, state, extraParams, &webThemeExtraParams);
876     webKitClient()->themeEngine()->paint(
877         gc->platformContext()->canvas(), WebThemePart(part), WebThemeState(state), rect, &webThemeExtraParams);
878 }
879
880 #elif OS(DARWIN)
881
882 void PlatformBridge::paintScrollbarThumb(
883     GraphicsContext* gc, ThemePaintState state, ThemePaintSize size, const IntRect& rect, const ThemePaintScrollbarInfo& scrollbarInfo)
884 {
885     WebThemeEngine::ScrollbarInfo webThemeScrollbarInfo;
886
887     webThemeScrollbarInfo.orientation = static_cast<WebThemeEngine::ScrollbarOrientation>(scrollbarInfo.orientation);
888     webThemeScrollbarInfo.parent = static_cast<WebThemeEngine::ScrollbarParent>(scrollbarInfo.parent);
889     webThemeScrollbarInfo.maxValue = scrollbarInfo.maxValue;
890     webThemeScrollbarInfo.currentValue = scrollbarInfo.currentValue;
891     webThemeScrollbarInfo.visibleSize = scrollbarInfo.visibleSize;
892     webThemeScrollbarInfo.totalSize = scrollbarInfo.totalSize;
893
894     webKitClient()->themeEngine()->paintScrollbarThumb(
895         gc->platformContext(),
896         static_cast<WebThemeEngine::State>(state),
897         static_cast<WebThemeEngine::Size>(size),
898         rect,
899         webThemeScrollbarInfo);
900 }
901
902 #endif
903
904 // Trace Event ----------------------------------------------------------------
905
906 void PlatformBridge::traceEventBegin(const char* name, void* id, const char* extra)
907 {
908     webKitClient()->traceEventBegin(name, id, extra);
909 }
910
911 void PlatformBridge::traceEventEnd(const char* name, void* id, const char* extra)
912 {
913     webKitClient()->traceEventEnd(name, id, extra);
914 }
915
916 // Visited Links --------------------------------------------------------------
917
918 LinkHash PlatformBridge::visitedLinkHash(const UChar* url, unsigned length)
919 {
920     url_canon::RawCanonOutput<2048> buffer;
921     url_parse::Parsed parsed;
922     if (!url_util::Canonicalize(url, length, 0, &buffer, &parsed))
923         return 0;  // Invalid URLs are unvisited.
924     return webKitClient()->visitedLinkHash(buffer.data(), buffer.length());
925 }
926
927 LinkHash PlatformBridge::visitedLinkHash(const KURL& base,
928                                          const AtomicString& attributeURL)
929 {
930     // Resolve the relative URL using googleurl and pass the absolute URL up to
931     // the embedder. We could create a GURL object from the base and resolve
932     // the relative URL that way, but calling the lower-level functions
933     // directly saves us the string allocation in most cases.
934     url_canon::RawCanonOutput<2048> buffer;
935     url_parse::Parsed parsed;
936
937 #if USE(GOOGLEURL)
938     const CString& cstr = base.utf8String();
939     const char* data = cstr.data();
940     int length = cstr.length();
941     const url_parse::Parsed& srcParsed = base.parsed();
942 #else
943     // When we're not using GoogleURL, first canonicalize it so we can resolve it
944     // below.
945     url_canon::RawCanonOutput<2048> srcCanon;
946     url_parse::Parsed srcParsed;
947     String str = base.string();
948     if (!url_util::Canonicalize(str.characters(), str.length(), 0, &srcCanon, &srcParsed))
949         return 0;
950     const char* data = srcCanon.data();
951     int length = srcCanon.length();
952 #endif
953
954     if (!url_util::ResolveRelative(data, length, srcParsed, attributeURL.characters(),
955                                    attributeURL.length(), 0, &buffer, &parsed))
956         return 0;  // Invalid resolved URL.
957
958     return webKitClient()->visitedLinkHash(buffer.data(), buffer.length());
959 }
960
961 bool PlatformBridge::isLinkVisited(LinkHash visitedLinkHash)
962 {
963     return webKitClient()->isLinkVisited(visitedLinkHash);
964 }
965
966 // These are temporary methods that the WebKit layer can use to call to the
967 // Glue layer. Once the Glue layer moves entirely into the WebKit layer, these
968 // methods will be deleted.
969
970 void PlatformBridge::notifyJSOutOfMemory(Frame* frame)
971 {
972     if (!frame)
973         return;
974
975     WebFrameImpl* webFrame = WebFrameImpl::fromFrame(frame);
976     if (!webFrame->client())
977         return;
978     webFrame->client()->didExhaustMemoryAvailableForScript(webFrame);
979 }
980
981 int PlatformBridge::memoryUsageMB()
982 {
983     return static_cast<int>(webKitClient()->memoryUsageMB());
984 }
985
986 int PlatformBridge::actualMemoryUsageMB()
987 {
988     return static_cast<int>(webKitClient()->actualMemoryUsageMB());
989 }
990
991 int PlatformBridge::screenDepth(Widget* widget)
992 {
993     WebWidgetClient* client = toWebWidgetClient(widget);
994     if (!client)
995         return 0;
996     return client->screenInfo().depth;
997 }
998
999 int PlatformBridge::screenDepthPerComponent(Widget* widget)
1000 {
1001     WebWidgetClient* client = toWebWidgetClient(widget);
1002     if (!client)
1003         return 0;
1004     return client->screenInfo().depthPerComponent;
1005 }
1006
1007 bool PlatformBridge::screenIsMonochrome(Widget* widget)
1008 {
1009     WebWidgetClient* client = toWebWidgetClient(widget);
1010     if (!client)
1011         return 0;
1012     return client->screenInfo().isMonochrome;
1013 }
1014
1015 IntRect PlatformBridge::screenRect(Widget* widget)
1016 {
1017     WebWidgetClient* client = toWebWidgetClient(widget);
1018     if (!client)
1019         return IntRect();
1020     return client->screenInfo().rect;
1021 }
1022
1023 IntRect PlatformBridge::screenAvailableRect(Widget* widget)
1024 {
1025     WebWidgetClient* client = toWebWidgetClient(widget);
1026     if (!client)
1027         return IntRect();
1028     return client->screenInfo().availableRect;
1029 }
1030
1031 bool PlatformBridge::popupsAllowed(NPP npp)
1032 {
1033     // FIXME: Give the embedder a way to control this.
1034     return false;
1035 }
1036
1037 WorkerContextProxy* WorkerContextProxy::create(Worker* worker)
1038 {
1039     return WebWorkerClientImpl::createWorkerContextProxy(worker);
1040 }
1041
1042 } // namespace WebCore