blob: 7427e397f8ef50f0ad0b54503ad8c7d232e86f65 [file] [log] [blame]
[email protected]52993562008-10-31 22:28:401// Copyright (c) 2008 The Chromium Authors. All rights reserved. Use of this
2// source code is governed by a BSD-style license that can be found in the
3// LICENSE file.
4
5#include "config.h"
6#include "ChromiumBridge.h"
7
[email protected]d055d8e2008-11-18 21:08:028#include "BitmapImage.h"
[email protected]3ccbdb92008-11-11 22:25:599#include "ClipboardUtilitiesChromium.h"
[email protected]4c870b42008-11-06 00:36:5210#include "Cursor.h"
11#include "Frame.h"
12#include "FrameView.h"
[email protected]52993562008-10-31 22:28:4013#include "HostWindow.h"
[email protected]3ccbdb92008-11-11 22:25:5914#include "KURL.h"
15#include "NativeImageSkia.h"
[email protected]4c870b42008-11-06 00:36:5216#include "Page.h"
[email protected]3ccbdb92008-11-11 22:25:5917#include "PasteboardPrivate.h"
18#include "PlatformString.h"
[email protected]52993562008-10-31 22:28:4019#include "PlatformWidget.h"
[email protected]aad0ab52008-11-18 17:09:2020#include "PluginData.h"
21#include "PluginInfoStore.h"
[email protected]3c821eb2008-11-18 16:20:5122#include "ScrollbarTheme.h"
[email protected]52993562008-10-31 22:28:4023#include "ScrollView.h"
[email protected]f0f97172008-11-18 22:00:5924#include "SystemTime.h"
[email protected]52993562008-10-31 22:28:4025#include "Widget.h"
26
[email protected]4c870b42008-11-06 00:36:5227#undef LOG
[email protected]3ccbdb92008-11-11 22:25:5928#include "base/clipboard.h"
[email protected]aad0ab52008-11-18 17:09:2029#include "base/file_util.h"
[email protected]f0f97172008-11-18 22:00:5930#include "base/message_loop.h"
[email protected]5190d28c2008-11-14 19:22:4731#include "base/stats_counters.h"
[email protected]3ccbdb92008-11-11 22:25:5932#include "base/string_util.h"
[email protected]f0f97172008-11-18 22:00:5933#include "base/time.h"
[email protected]5190d28c2008-11-14 19:22:4734#include "base/trace_event.h"
[email protected]d055d8e2008-11-18 21:08:0235#include "build/build_config.h"
[email protected]aad0ab52008-11-18 17:09:2036#include "net/base/mime_util.h"
[email protected]a4bcf7d2008-11-14 21:24:5637#if USE(V8)
[email protected]5190d28c2008-11-14 19:22:4738#include <v8.h>
[email protected]a4bcf7d2008-11-14 21:24:5639#endif
[email protected]4c870b42008-11-06 00:36:5240#include "webkit/glue/chrome_client_impl.h"
[email protected]52993562008-10-31 22:28:4041#include "webkit/glue/glue_util.h"
[email protected]3ccbdb92008-11-11 22:25:5942#include "webkit/glue/scoped_clipboard_writer_glue.h"
[email protected]4c870b42008-11-06 00:36:5243#include "webkit/glue/webcursor.h"
[email protected]52993562008-10-31 22:28:4044#include "webkit/glue/webkit_glue.h"
[email protected]aad0ab52008-11-18 17:09:2045#include "webkit/glue/webplugin.h"
[email protected]3c821eb2008-11-18 16:20:5146#include "webkit/glue/webkit_resources.h"
[email protected]4c870b42008-11-06 00:36:5247#include "webkit/glue/webview_impl.h"
48#include "webkit/glue/webview_delegate.h"
[email protected]52993562008-10-31 22:28:4049
[email protected]d055d8e2008-11-18 21:08:0250#if defined(OS_WIN)
51#include <windows.h>
52#include <vssym32.h>
53
54#include "base/gfx/native_theme.h"
55
56// This is only needed on Windows right now.
57#include "BitmapImageSingleFrameSkia.h"
58#endif
59
[email protected]3ccbdb92008-11-11 22:25:5960namespace {
[email protected]52993562008-10-31 22:28:4061
[email protected]3ccbdb92008-11-11 22:25:5962PlatformWidget ToPlatform(WebCore::Widget* widget) {
[email protected]52993562008-10-31 22:28:4063 return widget ? widget->root()->hostWindow()->platformWindow() : 0;
64}
65
[email protected]3ccbdb92008-11-11 22:25:5966ChromeClientImpl* ToChromeClient(WebCore::Widget* widget) {
67 WebCore::FrameView* view;
[email protected]4c870b42008-11-06 00:36:5268 if (widget->isFrameView()) {
[email protected]3ccbdb92008-11-11 22:25:5969 view = static_cast<WebCore::FrameView*>(widget);
[email protected]4c870b42008-11-06 00:36:5270 } else if (widget->parent() && widget->parent()->isFrameView()) {
[email protected]3ccbdb92008-11-11 22:25:5971 view = static_cast<WebCore::FrameView*>(widget->parent());
[email protected]4c870b42008-11-06 00:36:5272 } else {
73 return NULL;
74 }
75
[email protected]3ccbdb92008-11-11 22:25:5976 WebCore::Page* page = view->frame() ? view->frame()->page() : NULL;
[email protected]4c870b42008-11-06 00:36:5277 if (!page)
78 return NULL;
79
80 return static_cast<ChromeClientImpl*>(page->chrome()->client());
81}
82
[email protected]3ccbdb92008-11-11 22:25:5983std::wstring UrlToImageMarkup(const WebCore::KURL& url,
84 const WebCore::String& alt_str) {
85 std::wstring markup(L"<img src=\"");
86 markup.append(webkit_glue::StringToStdWString(url.string()));
87 markup.append(L"\"");
88 if (!alt_str.isEmpty()) {
89 markup.append(L" alt=\"");
90 std::wstring alt_stdstr = webkit_glue::StringToStdWString(alt_str);
91 ReplaceSubstringsAfterOffset(&alt_stdstr, 0, L"\"", L"&quot;");
92 markup.append(alt_stdstr);
93 markup.append(L"\"");
94 }
95 markup.append(L"/>");
96 return markup;
97}
98
99} // namespace
100
101namespace WebCore {
102
103bool ChromiumBridge::clipboardIsFormatAvailable(
104 PasteboardPrivate::ClipboardFormat format) {
105 switch (format) {
106 case PasteboardPrivate::HTMLFormat:
107 return webkit_glue::ClipboardIsFormatAvailable(
108 ::Clipboard::GetHtmlFormatType());
109
[email protected]c3fac8b2008-11-17 14:45:48110 case PasteboardPrivate::WebSmartPasteFormat:
111 return webkit_glue::ClipboardIsFormatAvailable(
112 ::Clipboard::GetWebKitSmartPasteFormatType());
113
[email protected]3ccbdb92008-11-11 22:25:59114 case PasteboardPrivate::BookmarkFormat:
115#if defined(OS_WIN) || defined(OS_MACOSX)
116 return webkit_glue::ClipboardIsFormatAvailable(
117 ::Clipboard::GetUrlWFormatType());
118#endif
119
[email protected]3ccbdb92008-11-11 22:25:59120 default:
121 NOTREACHED();
122 return false;
123 }
124}
125
126String ChromiumBridge::clipboardReadPlainText() {
127 if (webkit_glue::ClipboardIsFormatAvailable(
128 ::Clipboard::GetPlainTextWFormatType())) {
129 std::wstring text;
130 webkit_glue::ClipboardReadText(&text);
131 if (!text.empty())
132 return webkit_glue::StdWStringToString(text);
133 }
134
135 if (webkit_glue::ClipboardIsFormatAvailable(
136 ::Clipboard::GetPlainTextFormatType())) {
137 std::string text;
138 webkit_glue::ClipboardReadAsciiText(&text);
139 if (!text.empty())
140 return webkit_glue::StdStringToString(text);
141 }
142
143 return String();
144}
145
146void ChromiumBridge::clipboardReadHTML(String* html, KURL* url) {
147 std::wstring html_stdstr;
148 GURL gurl;
149 webkit_glue::ClipboardReadHTML(&html_stdstr, &gurl);
150 *html = webkit_glue::StdWStringToString(html_stdstr);
151 *url = webkit_glue::GURLToKURL(gurl);
152}
153
154void ChromiumBridge::clipboardWriteSelection(const String& html,
155 const KURL& url,
156 const String& plain_text,
157 bool can_smart_copy_or_delete) {
158 ScopedClipboardWriterGlue scw(webkit_glue::ClipboardGetClipboard());
159 scw.WriteHTML(webkit_glue::StringToStdWString(html),
160 webkit_glue::CStringToStdString(url.utf8String()));
161 scw.WriteText(webkit_glue::StringToStdWString(plain_text));
162
[email protected]3ccbdb92008-11-11 22:25:59163 if (can_smart_copy_or_delete)
164 scw.WriteWebSmartPaste();
[email protected]3ccbdb92008-11-11 22:25:59165}
166
167void ChromiumBridge::clipboardWriteURL(const KURL& url, const String& title) {
168 ScopedClipboardWriterGlue scw(webkit_glue::ClipboardGetClipboard());
169
170 GURL gurl = webkit_glue::KURLToGURL(url);
171 scw.WriteBookmark(webkit_glue::StringToStdWString(title), gurl.spec());
172
173 std::wstring link(webkit_glue::StringToStdWString(urlToMarkup(url, title)));
174 scw.WriteHTML(link, "");
175
176 scw.WriteText(ASCIIToWide(gurl.spec()));
177}
178
179void ChromiumBridge::clipboardWriteImage(const NativeImageSkia* bitmap,
180 const KURL& url, const String& title) {
181 ScopedClipboardWriterGlue scw(webkit_glue::ClipboardGetClipboard());
182
183#if defined(OS_WIN)
184 if (bitmap)
185 scw.WriteBitmap(*bitmap);
186#endif
187 if (!url.isEmpty()) {
188 GURL gurl = webkit_glue::KURLToGURL(url);
189 scw.WriteBookmark(webkit_glue::StringToStdWString(title), gurl.spec());
190
191 scw.WriteHTML(UrlToImageMarkup(url, title), "");
192
193 scw.WriteText(ASCIIToWide(gurl.spec()));
194 }
195}
196
[email protected]c277dd92008-11-10 22:56:58197// Cookies --------------------------------------------------------------------
198
199void ChromiumBridge::setCookies(
200 const KURL& url, const KURL& policy_url, const String& cookie) {
201 webkit_glue::SetCookie(
202 webkit_glue::KURLToGURL(url),
203 webkit_glue::KURLToGURL(policy_url),
204 webkit_glue::StringToStdString(cookie));
205}
206
207String ChromiumBridge::cookies(const KURL& url, const KURL& policy_url) {
208 return webkit_glue::StdStringToString(webkit_glue::GetCookies(
209 webkit_glue::KURLToGURL(url),
210 webkit_glue::KURLToGURL(policy_url)));
211}
212
213// DNS ------------------------------------------------------------------------
214
215void ChromiumBridge::prefetchDNS(const String& hostname) {
216 webkit_glue::PrefetchDns(webkit_glue::StringToStdString(hostname));
217}
218
[email protected]da8765902008-11-13 20:27:07219// Font -----------------------------------------------------------------------
220
221#if defined(OS_WIN)
222bool ChromiumBridge::ensureFontLoaded(HFONT font) {
223 return webkit_glue::EnsureFontLoaded(font);
224}
225#endif
226
[email protected]caae5412008-11-14 18:22:47227// Forms ----------------------------------------------------------------------
228
229void ChromiumBridge::notifyFormStateChanged(const Document* doc) {
230 webkit_glue::NotifyFormStateChanged(doc);
231}
232
233// JavaScript -----------------------------------------------------------------
234
235void ChromiumBridge::notifyJSOutOfMemory(Frame* frame) {
236 webkit_glue::NotifyJSOutOfMemory(frame);
237}
[email protected]da8765902008-11-13 20:27:07238
[email protected]f00e34452008-11-11 05:42:05239// Language -------------------------------------------------------------------
240
241String ChromiumBridge::computedDefaultLanguage() {
242 return webkit_glue::StdWStringToString(webkit_glue::GetWebKitLocale());
243}
244
[email protected]799edbd2008-11-12 00:51:10245// LayoutTestMode -------------------------------------------------------------
246
247bool ChromiumBridge::layoutTestMode() {
248 return webkit_glue::IsLayoutTestMode();
249}
250
[email protected]1c444692008-11-12 21:38:57251// MimeType -------------------------------------------------------------------
252
[email protected]aad0ab52008-11-18 17:09:20253bool ChromiumBridge::matchesMIMEType(const String& pattern,
254 const String& type) {
255 return net::MatchesMimeType(webkit_glue::StringToStdString(pattern),
256 webkit_glue::StringToStdString(type));
257}
258
259String ChromiumBridge::mimeTypeForExtension(const String& ext) {
[email protected]1c444692008-11-12 21:38:57260 if (ext.isEmpty())
261 return String();
262
263 std::string type;
264 webkit_glue::GetMimeTypeFromExtension(webkit_glue::StringToStdWString(ext),
265 &type);
266 return webkit_glue::StdStringToString(type);
267}
268
269String ChromiumBridge::mimeTypeFromFile(const String& file_path) {
270 if (file_path.isEmpty())
271 return String();
272
273 std::string type;
274 webkit_glue::GetMimeTypeFromFile(webkit_glue::StringToStdWString(file_path),
275 &type);
276 return webkit_glue::StdStringToString(type);
277}
278
[email protected]aad0ab52008-11-18 17:09:20279String ChromiumBridge::preferredExtensionForMIMEType(const String& mime_type) {
[email protected]1c444692008-11-12 21:38:57280 if (mime_type.isEmpty())
281 return String();
282
283 std::wstring stdext;
284 webkit_glue::GetPreferredExtensionForMimeType(
285 webkit_glue::StringToStdString(mime_type), &stdext);
286 return webkit_glue::StdWStringToString(stdext);
287}
288
[email protected]aad0ab52008-11-18 17:09:20289// Plugin ---------------------------------------------------------------------
290
291bool ChromiumBridge::getPlugins(bool refresh, Vector<PluginInfo*>* plugins) {
292 std::vector< ::WebPluginInfo> glue_plugins;
293 if (!webkit_glue::GetPlugins(refresh, &glue_plugins))
294 return false;
295 for (size_t i = 0; i < glue_plugins.size(); ++i) {
296 WebCore::PluginInfo* rv = new WebCore::PluginInfo;
297 const ::WebPluginInfo& plugin = glue_plugins[i];
298 rv->name = webkit_glue::StdWStringToString(plugin.name);
299 rv->desc = webkit_glue::StdWStringToString(plugin.desc);
300 rv->file = webkit_glue::StdWStringToString(
301 file_util::GetFilenameFromPath(plugin.file));
302 for (size_t j = 0; j < plugin.mime_types.size(); ++ j) {
303 WebCore::MimeClassInfo* new_mime = new WebCore::MimeClassInfo();
304 const WebPluginMimeType& mime_type = plugin.mime_types[j];
305 new_mime->desc = webkit_glue::StdWStringToString(mime_type.description);
306
307 for (size_t k = 0; k < mime_type.file_extensions.size(); ++k) {
308 if (new_mime->suffixes.length())
309 new_mime->suffixes.append(",");
310
311 new_mime->suffixes.append(webkit_glue::StdStringToString(
312 mime_type.file_extensions[k]));
313 }
314
315 new_mime->type = webkit_glue::StdStringToString(mime_type.mime_type);
316 new_mime->plugin = rv;
317 rv->mimes.append(new_mime);
318 }
319 plugins->append(rv);
320 }
321 return true;
322}
323
[email protected]1c444692008-11-12 21:38:57324// Protocol -------------------------------------------------------------------
325
326String ChromiumBridge::uiResourceProtocol() {
327 return webkit_glue::StdStringToString(webkit_glue::GetUIResourceProtocol());
328}
329
[email protected]d055d8e2008-11-18 21:08:02330
331// Resources ------------------------------------------------------------------
332
333#if defined(OS_WIN)
334// Creates an Image for the text area resize corner. We do this by drawing the
335// theme native control into a memory buffer then converting the memory buffer
336// into an image. We don't bother caching this image because the caller holds
337// onto a static copy (see WebCore/rendering/RenderLayer.cpp).
338static PassRefPtr<Image> GetTextAreaResizeCorner() {
339 // Get the size of the resizer.
340 const int thickness = ScrollbarTheme::nativeTheme()->scrollbarThickness();
341
342 // Setup a memory buffer.
343 gfx::PlatformCanvasWin canvas(thickness, thickness, false);
344 gfx::PlatformDeviceWin& device = canvas.getTopPlatformDevice();
345 device.prepareForGDI(0, 0, thickness, thickness);
346 HDC hdc = device.getBitmapDC();
347 RECT widgetRect = { 0, 0, thickness, thickness };
348
349 // Do the drawing.
350 gfx::NativeTheme::instance()->PaintStatusGripper(hdc, SP_GRIPPER, 0, 0,
351 &widgetRect);
352 device.postProcessGDI(0, 0, thickness, thickness);
353 return BitmapImageSingleFrameSkia::create(device.accessBitmap(false));
354}
355#endif
356
357PassRefPtr<Image> ChromiumBridge::loadPlatformImageResource(const char* name) {
358 // Some need special handling.
359 if (!strcmp(name, "textAreaResizeCorner")) {
360#if defined(OS_WIN)
361 return GetTextAreaResizeCorner();
362#else
363 DLOG(WARNING) << "This needs implementing on other platforms.";
364 return Image::nullImage();
365#endif
366 }
367
368 // The rest get converted to a resource ID that we can pass to the glue.
369 int resource_id = 0;
370 if (!strcmp(name, "missingImage")) {
371 resource_id = IDR_BROKENIMAGE;
372 } else if (!strcmp(name, "tickmarkDash")) {
373 resource_id = IDR_TICKMARK_DASH;
374 } else if (!strcmp(name, "deleteButton") ||
375 !strcmp(name, "deleteButtonPressed")) {
376 NOTREACHED() << "Image resource " << name << " does not exist yet.";
377 return Image::nullImage();
378 } else {
379 NOTREACHED() << "Unknown image resource " << name;
380 return Image::nullImage();
381 }
382
383 std::string data = webkit_glue::GetDataResource(resource_id);
384 RefPtr<SharedBuffer> buffer(
385 SharedBuffer::create(data.empty() ? "" : data.data(),
386 data.length()));
387 RefPtr<Image> image = BitmapImage::create();
388 image->setData(buffer, true);
389 return image;
390}
391
[email protected]52993562008-10-31 22:28:40392// Screen ---------------------------------------------------------------------
393
394int ChromiumBridge::screenDepth(Widget* widget) {
395 return webkit_glue::GetScreenInfo(ToPlatform(widget)).depth;
396}
397
398int ChromiumBridge::screenDepthPerComponent(Widget* widget) {
399 return webkit_glue::GetScreenInfo(ToPlatform(widget)).depth_per_component;
400}
401
402bool ChromiumBridge::screenIsMonochrome(Widget* widget) {
403 return webkit_glue::GetScreenInfo(ToPlatform(widget)).is_monochrome;
404}
405
406IntRect ChromiumBridge::screenRect(Widget* widget) {
407 return webkit_glue::ToIntRect(
408 webkit_glue::GetScreenInfo(ToPlatform(widget)).rect);
409}
410
411IntRect ChromiumBridge::screenAvailableRect(Widget* widget) {
412 return webkit_glue::ToIntRect(
413 webkit_glue::GetScreenInfo(ToPlatform(widget)).available_rect);
414}
415
[email protected]f0f97172008-11-18 22:00:59416// SharedTimers ----------------------------------------------------------------
417// Called by SharedTimerChromium.cpp
418
419class SharedTimerTask;
420
421// We maintain a single active timer and a single active task for
422// setting timers directly on the platform.
423static SharedTimerTask* shared_timer_task;
424static void (*shared_timer_function)();
425
426// Timer task to run in the chrome message loop.
427class SharedTimerTask : public Task {
428 public:
429 SharedTimerTask(void (*callback)()) : callback_(callback) {}
430
431 virtual void Run() {
432 if (!callback_)
433 return;
434 // Since we only have one task running at a time, verify 'this' is it
435 DCHECK(shared_timer_task == this);
436 shared_timer_task = NULL;
437 callback_();
438 }
439
440 void Cancel() {
441 callback_ = NULL;
442 }
443
444 private:
445 void (*callback_)();
446 DISALLOW_COPY_AND_ASSIGN(SharedTimerTask);
447};
448
449void ChromiumBridge::setSharedTimerFiredFunction(void (*func)()) {
450 shared_timer_function = func;
451}
452
453void ChromiumBridge::setSharedTimerFireTime(double fire_time) {
454 DCHECK(shared_timer_function);
455 int interval = static_cast<int>((fire_time - currentTime()) * 1000);
456 if (interval < 0)
457 interval = 0;
458
459 stopSharedTimer();
460
461 // Verify that we didn't leak the task or timer objects.
462 DCHECK(shared_timer_task == NULL);
463 shared_timer_task = new SharedTimerTask(shared_timer_function);
464 MessageLoop::current()->PostDelayedTask(FROM_HERE, shared_timer_task,
465 interval);
466}
467
468void ChromiumBridge::stopSharedTimer() {
469 if (!shared_timer_task)
470 return;
471 shared_timer_task->Cancel();
472 shared_timer_task = NULL;
473}
474
[email protected]5190d28c2008-11-14 19:22:47475// StatsCounters --------------------------------------------------------------
[email protected]b47a27fe2008-11-18 18:22:07476
[email protected]5190d28c2008-11-14 19:22:47477void ChromiumBridge::decrementStatsCounter(const wchar_t* name) {
478 StatsCounter(name).Decrement();
479}
480
481void ChromiumBridge::incrementStatsCounter(const wchar_t* name) {
482 StatsCounter(name).Increment();
483}
484
[email protected]a4bcf7d2008-11-14 21:24:56485#if USE(V8)
[email protected]5190d28c2008-11-14 19:22:47486void ChromiumBridge::initV8CounterFunction() {
487 v8::V8::SetCounterFunction(StatsTable::FindLocation);
488}
[email protected]a4bcf7d2008-11-14 21:24:56489#endif
[email protected]5190d28c2008-11-14 19:22:47490
[email protected]f0f97172008-11-18 22:00:59491// SystemTime ------------------------------------------------------------------
492// Called by SystemTimeChromium.cpp
493
494double ChromiumBridge::currentTime() {
495 // Get the current time in seconds since epoch.
496 return base::Time::Now().ToDoubleT();
497}
498
[email protected]5190d28c2008-11-14 19:22:47499// Trace Event ----------------------------------------------------------------
[email protected]b47a27fe2008-11-18 18:22:07500
[email protected]5190d28c2008-11-14 19:22:47501void ChromiumBridge::traceEventBegin(const char* name,
502 void* id,
503 const char* extra) {
504 TRACE_EVENT_BEGIN(name, id, extra);
505}
506
507void ChromiumBridge::traceEventEnd(const char* name,
508 void* id,
509 const char* extra) {
510 TRACE_EVENT_END(name, id, extra);
511}
512
[email protected]5190d28c2008-11-14 19:22:47513// URL ------------------------------------------------------------------------
[email protected]b47a27fe2008-11-18 18:22:07514
[email protected]caae5412008-11-14 18:22:47515KURL ChromiumBridge::inspectorURL() {
516 return webkit_glue::GURLToKURL(webkit_glue::GetInspectorURL());
517}
518
[email protected]4c870b42008-11-06 00:36:52519// Widget ---------------------------------------------------------------------
520
521void ChromiumBridge::widgetSetCursor(Widget* widget, const Cursor& cursor) {
522 ChromeClientImpl* chrome_client = ToChromeClient(widget);
523 if (chrome_client)
524 chrome_client->SetCursor(WebCursor(cursor.impl()));
525}
526
527void ChromiumBridge::widgetSetFocus(Widget* widget) {
528 ChromeClientImpl* chrome_client = ToChromeClient(widget);
529 if (chrome_client)
530 chrome_client->focus();
531}
532
[email protected]52993562008-10-31 22:28:40533} // namespace WebCore