OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "webkit/glue/plugins/webplugin_delegate_impl.h" | 5 #include "webkit/glue/plugins/webplugin_delegate_impl.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 std::wstring::npos) { | 291 std::wstring::npos) { |
292 // VLC hangs on NPP_Destroy if we call NPP_SetWindow with a null window | 292 // VLC hangs on NPP_Destroy if we call NPP_SetWindow with a null window |
293 // handle | 293 // handle |
294 quirks_ |= PLUGIN_QUIRK_DONT_SET_NULL_WINDOW_HANDLE_ON_DESTROY; | 294 quirks_ |= PLUGIN_QUIRK_DONT_SET_NULL_WINDOW_HANDLE_ON_DESTROY; |
295 // VLC 0.8.6d and 0.8.6e crash if multiple instances are created. | 295 // VLC 0.8.6d and 0.8.6e crash if multiple instances are created. |
296 quirks_ |= PLUGIN_QUIRK_DONT_ALLOW_MULTIPLE_INSTANCES; | 296 quirks_ |= PLUGIN_QUIRK_DONT_ALLOW_MULTIPLE_INSTANCES; |
297 } else if (filename == kSilverlightPlugin) { | 297 } else if (filename == kSilverlightPlugin) { |
298 // Explanation for this quirk can be found in | 298 // Explanation for this quirk can be found in |
299 // WebPluginDelegateImpl::Initialize. | 299 // WebPluginDelegateImpl::Initialize. |
300 quirks_ |= PLUGIN_QUIRK_PATCH_SETCURSOR; | 300 quirks_ |= PLUGIN_QUIRK_PATCH_SETCURSOR; |
| 301 } else if (instance_->mime_type() == "application/x-nacl-srpc") { |
| 302 // NaCl plugin runs in the sandbox - it cannot use the hwnd |
| 303 quirks_ |= PLUGIN_QUIRK_DONT_CREATE_DUMMY_WINDOW; |
301 } | 304 } |
302 } | 305 } |
303 | 306 |
304 WebPluginDelegateImpl::~WebPluginDelegateImpl() { | 307 WebPluginDelegateImpl::~WebPluginDelegateImpl() { |
305 if (::IsWindow(dummy_window_for_activation_)) { | 308 if (::IsWindow(dummy_window_for_activation_)) { |
306 ::DestroyWindow(dummy_window_for_activation_); | 309 ::DestroyWindow(dummy_window_for_activation_); |
307 } | 310 } |
308 | 311 |
309 DestroyInstance(); | 312 DestroyInstance(); |
310 | 313 |
311 if (!windowless_) | 314 if (!windowless_) |
312 WindowedDestroyWindow(); | 315 WindowedDestroyWindow(); |
313 | 316 |
314 if (handle_event_pump_messages_event_) { | 317 if (handle_event_pump_messages_event_) { |
315 CloseHandle(handle_event_pump_messages_event_); | 318 CloseHandle(handle_event_pump_messages_event_); |
316 } | 319 } |
317 } | 320 } |
318 | 321 |
319 void WebPluginDelegateImpl::PluginDestroyed() { | 322 void WebPluginDelegateImpl::PluginDestroyed() { |
320 if (handle_event_depth_) { | 323 if (handle_event_depth_) { |
321 MessageLoop::current()->DeleteSoon(FROM_HERE, this); | 324 MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
322 } else { | 325 } else { |
323 delete this; | 326 delete this; |
324 } | 327 } |
325 } | 328 } |
326 | 329 |
327 void WebPluginDelegateImpl::PlatformInitialize() { | 330 void WebPluginDelegateImpl::PlatformInitialize() { |
328 plugin_->SetWindow(windowed_handle_); | 331 plugin_->SetWindow(windowed_handle_); |
329 if (windowless_) { | 332 |
| 333 if (windowless_ && !(quirks_ & PLUGIN_QUIRK_DONT_CREATE_DUMMY_WINDOW)) { |
330 CreateDummyWindowForActivation(); | 334 CreateDummyWindowForActivation(); |
331 handle_event_pump_messages_event_ = CreateEvent(NULL, TRUE, FALSE, NULL); | 335 handle_event_pump_messages_event_ = CreateEvent(NULL, TRUE, FALSE, NULL); |
332 plugin_->SetWindowlessPumpEvent(handle_event_pump_messages_event_); | 336 plugin_->SetWindowlessPumpEvent(handle_event_pump_messages_event_); |
333 } | 337 } |
334 | 338 |
335 // Windowless plugins call the WindowFromPoint API and passes the result of | 339 // We cannot patch internal plugins as they are not shared libraries. |
336 // that to the TrackPopupMenu API call as the owner window. This causes the | 340 if (!instance_->plugin_lib()->internal()) { |
337 // API to fail as the API expects the window handle to live on the same thread | 341 // Windowless plugins call the WindowFromPoint API and passes the result of |
338 // as the caller. It works in the other browsers as the plugin lives on the | 342 // that to the TrackPopupMenu API call as the owner window. This causes the |
339 // browser thread. Our workaround is to intercept the TrackPopupMenu API and | 343 // API to fail as the API expects the window handle to live on the same |
340 // replace the window handle with the dummy activation window. | 344 // thread as the caller. It works in the other browsers as the plugin lives |
341 if (windowless_ && !g_iat_patch_track_popup_menu.Pointer()->is_patched()) { | 345 // on the browser thread. Our workaround is to intercept the TrackPopupMenu |
342 g_iat_patch_track_popup_menu.Pointer()->Patch( | 346 // API and replace the window handle with the dummy activation window. |
343 GetPluginPath().value().c_str(), "user32.dll", "TrackPopupMenu", | 347 if (windowless_ && !g_iat_patch_track_popup_menu.Pointer()->is_patched()) { |
344 WebPluginDelegateImpl::TrackPopupMenuPatch); | 348 g_iat_patch_track_popup_menu.Pointer()->Patch( |
345 } | 349 GetPluginPath().value().c_str(), "user32.dll", "TrackPopupMenu", |
| 350 WebPluginDelegateImpl::TrackPopupMenuPatch); |
| 351 } |
346 | 352 |
347 // Windowless plugins can set cursors by calling the SetCursor API. This | 353 // Windowless plugins can set cursors by calling the SetCursor API. This |
348 // works because the thread inputs of the browser UI thread and the plugin | 354 // works because the thread inputs of the browser UI thread and the plugin |
349 // thread are attached. We intercept the SetCursor API for windowless plugins | 355 // thread are attached. We intercept the SetCursor API for windowless |
350 // and remember the cursor being set. This is shipped over to the browser | 356 // plugins and remember the cursor being set. This is shipped over to the |
351 // in the HandleEvent call, which ensures that the cursor does not change | 357 // browser in the HandleEvent call, which ensures that the cursor does not |
352 // when a windowless plugin instance changes the cursor in a background tab. | 358 // change when a windowless plugin instance changes the cursor |
353 if (windowless_ && !g_iat_patch_set_cursor.Pointer()->is_patched() && | 359 // in a background tab. |
354 (quirks_ & PLUGIN_QUIRK_PATCH_SETCURSOR)) { | 360 if (windowless_ && !g_iat_patch_set_cursor.Pointer()->is_patched() && |
355 g_iat_patch_set_cursor.Pointer()->Patch( | 361 (quirks_ & PLUGIN_QUIRK_PATCH_SETCURSOR)) { |
356 GetPluginPath().value().c_str(), "user32.dll", "SetCursor", | 362 g_iat_patch_set_cursor.Pointer()->Patch( |
357 WebPluginDelegateImpl::SetCursorPatch); | 363 GetPluginPath().value().c_str(), "user32.dll", "SetCursor", |
| 364 WebPluginDelegateImpl::SetCursorPatch); |
| 365 } |
358 } | 366 } |
359 | 367 |
360 // On XP, WMP will use its old UI unless a registry key under HKLM has the | 368 // On XP, WMP will use its old UI unless a registry key under HKLM has the |
361 // name of the current process. We do it in the installer for admin users, | 369 // name of the current process. We do it in the installer for admin users, |
362 // for the rest patch this function. | 370 // for the rest patch this function. |
363 if ((quirks_ & PLUGIN_QUIRK_PATCH_REGENUMKEYEXW) && | 371 if ((quirks_ & PLUGIN_QUIRK_PATCH_REGENUMKEYEXW) && |
364 win_util::GetWinVersion() == win_util::WINVERSION_XP && | 372 win_util::GetWinVersion() == win_util::WINVERSION_XP && |
365 !RegKey().Open(HKEY_LOCAL_MACHINE, | 373 !RegKey().Open(HKEY_LOCAL_MACHINE, |
366 L"SOFTWARE\\Microsoft\\MediaPlayer\\ShimInclusionList\\chrome.exe") && | 374 L"SOFTWARE\\Microsoft\\MediaPlayer\\ShimInclusionList\\chrome.exe") && |
367 !g_iat_patch_reg_enum_key_ex_w.Pointer()->is_patched()) { | 375 !g_iat_patch_reg_enum_key_ex_w.Pointer()->is_patched()) { |
(...skipping 889 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1257 GetKeyPath(key).find(L"Microsoft\\MediaPlayer\\ShimInclusionList") != | 1265 GetKeyPath(key).find(L"Microsoft\\MediaPlayer\\ShimInclusionList") != |
1258 std::wstring::npos) { | 1266 std::wstring::npos) { |
1259 static const wchar_t kChromeExeName[] = L"chrome.exe"; | 1267 static const wchar_t kChromeExeName[] = L"chrome.exe"; |
1260 wcsncpy_s(name, orig_size, kChromeExeName, arraysize(kChromeExeName)); | 1268 wcsncpy_s(name, orig_size, kChromeExeName, arraysize(kChromeExeName)); |
1261 *name_size = | 1269 *name_size = |
1262 std::min(orig_size, static_cast<DWORD>(arraysize(kChromeExeName))); | 1270 std::min(orig_size, static_cast<DWORD>(arraysize(kChromeExeName))); |
1263 } | 1271 } |
1264 | 1272 |
1265 return rv; | 1273 return rv; |
1266 } | 1274 } |
OLD | NEW |