| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2009, Google Inc. | 2 * Copyright 2009, Google Inc. |
| 3 * All rights reserved. | 3 * All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
| 7 * met: | 7 * met: |
| 8 * | 8 * |
| 9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 | 32 |
| 33 // This file implements the platform specific parts of the plugin for | 33 // This file implements the platform specific parts of the plugin for |
| 34 // the Windows platform. | 34 // the Windows platform. |
| 35 | 35 |
| 36 #include "plugin/cross/main.h" | 36 #include "plugin/cross/main.h" |
| 37 | 37 |
| 38 #include <windows.h> | 38 #include <windows.h> |
| 39 #include <windowsx.h> | 39 #include <windowsx.h> |
| 40 #include <shellapi.h> | 40 #include <shellapi.h> |
| 41 | 41 |
| 42 #include "base/at_exit.h" | |
| 43 #include "base/command_line.h" | |
| 44 #include "base/file_util.h" | |
| 45 #include "base/logging.h" | 42 #include "base/logging.h" |
| 46 #include "base/ref_counted.h" | |
| 47 #include "core/cross/display_mode.h" | 43 #include "core/cross/display_mode.h" |
| 48 #include "core/cross/event.h" | 44 #include "core/cross/event.h" |
| 49 #include "plugin/cross/plugin_logging.h" | 45 #include "core/win/display_window_win.h" |
| 50 #include "plugin/cross/out_of_memory.h" | |
| 51 #include "plugin/cross/whitelist.h" | |
| 52 #include "statsreport/metrics.h" | |
| 53 #include "v8/include/v8.h" | 46 #include "v8/include/v8.h" |
| 54 #include "breakpad/win/bluescreen_detector.h" | 47 #if !defined(O3D_INTERNAL_PLUGIN) |
| 48 #include "breakpad/win/exception_handler_win32.h" |
| 49 #endif |
| 55 | 50 |
| 56 using glue::_o3d::PluginObject; | 51 using glue::_o3d::PluginObject; |
| 57 using glue::StreamManager; | 52 using glue::StreamManager; |
| 58 using o3d::DisplayWindowWindows; | 53 using o3d::DisplayWindowWindows; |
| 59 using o3d::Event; | 54 using o3d::Event; |
| 60 | 55 |
| 61 namespace { | 56 namespace { |
| 62 // The instance handle of the O3D DLL. | 57 // The instance handle of the O3D DLL. |
| 63 HINSTANCE g_module_instance; | 58 HINSTANCE g_module_instance; |
| 64 } // namespace anonymous | 59 } // namespace anonymous |
| 65 | 60 |
| 66 #if !defined(O3D_INTERNAL_PLUGIN) | 61 #if !defined(O3D_INTERNAL_PLUGIN) |
| 67 | 62 // Used for breakpad crash handling |
| 68 o3d::PluginLogging* g_logger = NULL; | 63 static ExceptionManager *g_exception_manager = NULL; |
| 69 bool g_logging_initialized = false; | |
| 70 o3d::BluescreenDetector *g_bluescreen_detector = NULL; | |
| 71 | 64 |
| 72 extern "C" BOOL WINAPI DllMain(HINSTANCE instance, | 65 extern "C" BOOL WINAPI DllMain(HINSTANCE instance, |
| 73 DWORD reason, | 66 DWORD reason, |
| 74 LPVOID reserved) { | 67 LPVOID reserved) { |
| 75 g_module_instance = instance; | 68 g_module_instance = instance; |
| 76 | 69 |
| 77 if (reason == DLL_PROCESS_DETACH) { | 70 if (reason == DLL_PROCESS_DETACH) { |
| 78 // Teardown V8 when the plugin dll is unloaded. | 71 // Teardown V8 when the plugin dll is unloaded. |
| 79 // NOTE: NP_Shutdown would have been a good place for this code but | 72 // NOTE: NP_Shutdown would have been a good place for this code but |
| 80 // unfortunately it looks like it gets called even when the dll | 73 // unfortunately it looks like it gets called even when the dll |
| 81 // isn't really unloaded. This is a problem since after calling | 74 // isn't really unloaded. This is a problem since after calling |
| 82 // V8::Dispose(), V8 cannot be initialized again. | 75 // V8::Dispose(), V8 cannot be initialized again. |
| 83 bool v8_disposed = v8::V8::Dispose(); | 76 bool v8_disposed = v8::V8::Dispose(); |
| 84 if (!v8_disposed) | 77 if (!v8_disposed) |
| 85 DLOG(ERROR) << "Failed to release V8 resources."; | 78 DLOG(ERROR) << "Failed to release V8 resources."; |
| 86 return true; | 79 return true; |
| 87 } | 80 } |
| 88 return true; | 81 return true; |
| 89 } | 82 } |
| 90 #endif // O3D_INTERNAL_PLUGIN | 83 #endif // O3D_INTERNAL_PLUGIN |
| 91 | 84 |
| 92 namespace { | 85 namespace { |
| 93 const wchar_t* const kO3DWindowClassName = L"O3DWindowClass"; | 86 const wchar_t* const kO3DWindowClassName = L"O3DWindowClass"; |
| 94 | 87 |
| 95 void CleanupAllWindows(PluginObject *obj); | 88 void CleanupAllWindows(PluginObject *obj); |
| 96 | 89 |
| 97 // We would normally make this a stack variable in main(), but in a | |
| 98 // plugin, that's not possible, so we make it a global. When the DLL is loaded | |
| 99 // this it gets constructed and when it is unlooaded it is destructed. Note | |
| 100 // that this cannot be done in NP_Initialize and NP_Shutdown because those | |
| 101 // calls do not necessarily signify the DLL being loaded and unloaded. If the | |
| 102 // DLL is not unloaded then the values of global variables are preserved. | |
| 103 base::AtExitManager g_at_exit_manager; | |
| 104 | |
| 105 static int HandleKeyboardEvent(PluginObject *obj, | 90 static int HandleKeyboardEvent(PluginObject *obj, |
| 106 HWND hWnd, | 91 HWND hWnd, |
| 107 UINT Msg, | 92 UINT Msg, |
| 108 WPARAM wParam, | 93 WPARAM wParam, |
| 109 LPARAM lParam) { | 94 LPARAM lParam) { |
| 110 DCHECK(obj); | 95 DCHECK(obj); |
| 111 DCHECK(obj->client()); | 96 DCHECK(obj->client()); |
| 112 Event::Type type; | 97 Event::Type type; |
| 113 // First figure out which kind of event to create, and do any event-specific | 98 // First figure out which kind of event to create, and do any event-specific |
| 114 // processing that can be done prior to creating it. | 99 // processing that can be done prior to creating it. |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 // Tell windows we don't need the background cleared. | 459 // Tell windows we don't need the background cleared. |
| 475 return 1; | 460 return 1; |
| 476 } | 461 } |
| 477 | 462 |
| 478 case WM_TIMER: { | 463 case WM_TIMER: { |
| 479 if (reentrance_count.get() > 1) { | 464 if (reentrance_count.get() > 1) { |
| 480 break; // Ignore this message; we're reentrant. | 465 break; // Ignore this message; we're reentrant. |
| 481 } | 466 } |
| 482 | 467 |
| 483 #if !defined(O3D_INTERNAL_PLUGIN) | 468 #if !defined(O3D_INTERNAL_PLUGIN) |
| 484 // TODO: Only logging for windows until we figure out the proper | |
| 485 // mac way | |
| 486 if (g_logger) g_logger->UpdateLogging(); | 469 if (g_logger) g_logger->UpdateLogging(); |
| 487 #endif | 470 #endif |
| 488 | 471 |
| 489 // If rendering continuously, invalidate the window and force a paint if | 472 // If rendering continuously, invalidate the window and force a paint if |
| 490 // it is visible. The paint invalidates the renderer and Tick will later | 473 // it is visible. The paint invalidates the renderer and Tick will later |
| 491 // repaint the window. | 474 // repaint the window. |
| 492 if (obj->client()->NeedsContinuousRender()) { | 475 if (obj->client()->NeedsContinuousRender()) { |
| 493 InvalidateRect(obj->GetHWnd(), NULL, FALSE); | 476 InvalidateRect(obj->GetHWnd(), NULL, FALSE); |
| 494 UpdateWindow(obj->GetHWnd()); | 477 UpdateWindow(obj->GetHWnd()); |
| 495 } | 478 } |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 646 window_class.lpszClassName = kO3DWindowClassName; | 629 window_class.lpszClassName = kO3DWindowClassName; |
| 647 // We use CS_OWNDC in case we are rendering OpenGL into this window. | 630 // We use CS_OWNDC in case we are rendering OpenGL into this window. |
| 648 window_class.style = CS_DBLCLKS | CS_OWNDC; | 631 window_class.style = CS_DBLCLKS | CS_OWNDC; |
| 649 return RegisterClassEx(&window_class) != 0; | 632 return RegisterClassEx(&window_class) != 0; |
| 650 } | 633 } |
| 651 | 634 |
| 652 void UnregisterO3DWindowClass() { | 635 void UnregisterO3DWindowClass() { |
| 653 UnregisterClass(kO3DWindowClassName, g_module_instance); | 636 UnregisterClass(kO3DWindowClassName, g_module_instance); |
| 654 } | 637 } |
| 655 | 638 |
| 656 NPError InitializePlugin() { | |
| 657 #if !defined(O3D_INTERNAL_PLUGIN) | |
| 658 if (!o3d::SetupOutOfMemoryHandler()) | |
| 659 return NPERR_MODULE_LOAD_FAILED_ERROR; | |
| 660 | |
| 661 // Setup crash handler | |
| 662 if (!g_exception_manager) { | |
| 663 g_exception_manager = new ExceptionManager(false); | |
| 664 g_exception_manager->StartMonitoring(); | |
| 665 } | |
| 666 | |
| 667 // Turn on the logging. | |
| 668 CommandLine::Init(0, NULL); | |
| 669 | |
| 670 FilePath log; | |
| 671 file_util::GetTempDir(&log); | |
| 672 log.Append(L"debug.log"); | |
| 673 | |
| 674 InitLogging(log.value().c_str(), | |
| 675 logging::LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG, | |
| 676 logging::DONT_LOCK_LOG_FILE, | |
| 677 logging::APPEND_TO_OLD_LOG_FILE); | |
| 678 #endif // O3D_INTERNAL_PLUGIN | |
| 679 | |
| 680 DLOG(INFO) << "NP_Initialize"; | |
| 681 | |
| 682 if (!RegisterO3DWindowClass()) | |
| 683 return NPERR_MODULE_LOAD_FAILED_ERROR; | |
| 684 | |
| 685 return NPERR_NO_ERROR; | |
| 686 } | |
| 687 | |
| 688 void CleanupAllWindows(PluginObject *obj) { | 639 void CleanupAllWindows(PluginObject *obj) { |
| 689 if (obj->GetContentHWnd()) { | 640 if (obj->GetContentHWnd()) { |
| 690 ::KillTimer(obj->GetContentHWnd(), 0); | 641 ::KillTimer(obj->GetContentHWnd(), 0); |
| 691 PluginObject::ClearPluginProperty(obj->GetContentHWnd()); | 642 PluginObject::ClearPluginProperty(obj->GetContentHWnd()); |
| 692 ::PostMessage(obj->GetContentHWnd(), kDestroyWindowMessageID, 0, 0); | 643 ::PostMessage(obj->GetContentHWnd(), kDestroyWindowMessageID, 0, 0); |
| 693 obj->SetContentHWnd(NULL); | 644 obj->SetContentHWnd(NULL); |
| 694 } | 645 } |
| 695 | 646 |
| 696 if (obj->GetPluginHWnd()) { | 647 if (obj->GetPluginHWnd()) { |
| 697 // Restore the original WNDPROC on the plugin window so that we | 648 // Restore the original WNDPROC on the plugin window so that we |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 if (GetMonitorInfo(monitor, &monitor_info)) { | 696 if (GetMonitorInfo(monitor, &monitor_info)) { |
| 746 *rect = monitor_info.rcMonitor; | 697 *rect = monitor_info.rcMonitor; |
| 747 return true; | 698 return true; |
| 748 } else { | 699 } else { |
| 749 return false; | 700 return false; |
| 750 } | 701 } |
| 751 } | 702 } |
| 752 | 703 |
| 753 } // namespace anonymous | 704 } // namespace anonymous |
| 754 | 705 |
| 755 #if defined(O3D_INTERNAL_PLUGIN) | |
| 756 namespace o3d { | 706 namespace o3d { |
| 757 #else | |
| 758 extern "C" { | |
| 759 #endif | |
| 760 | 707 |
| 761 NPError OSCALL NP_Initialize(NPNetscapeFuncs *browserFuncs) { | 708 NPError PlatformPreNPInitialize() { |
| 762 HANDLE_CRASHES; | 709 #if !defined(O3D_INTERNAL_PLUGIN) |
| 763 | 710 // Setup crash handler |
| 764 NPError retval = InitializeNPNApi(browserFuncs); | 711 if (!g_exception_manager) { |
| 765 if (retval != NPERR_NO_ERROR) return retval; | 712 g_exception_manager = new ExceptionManager(false); |
| 766 return InitializePlugin(); | 713 g_exception_manager->StartMonitoring(); |
| 714 } |
| 715 #endif // O3D_INTERNAL_PLUGIN |
| 716 return NPERR_NO_ERROR; |
| 767 } | 717 } |
| 768 | 718 |
| 769 NPError OSCALL NP_Shutdown(void) { | 719 NPError PlatformPostNPInitialize() { |
| 770 HANDLE_CRASHES; | 720 if (!RegisterO3DWindowClass()) |
| 771 DLOG(INFO) << "NP_Shutdown"; | 721 return NPERR_MODULE_LOAD_FAILED_ERROR; |
| 772 | 722 |
| 723 return NPERR_NO_ERROR; |
| 724 } |
| 725 |
| 726 NPError PlatformPreNPShutdown() { |
| 727 // TODO(tschmelcher): Is there a reason we need to do this before the main |
| 728 // shutdown tasks? If not, we can axe the PlatformPreNPShutdown() function. |
| 773 UnregisterO3DWindowClass(); | 729 UnregisterO3DWindowClass(); |
| 730 return NPERR_NO_ERROR; |
| 731 } |
| 774 | 732 |
| 733 NPError PlatformPostNPShutdown() { |
| 775 #if !defined(O3D_INTERNAL_PLUGIN) | 734 #if !defined(O3D_INTERNAL_PLUGIN) |
| 776 | |
| 777 if (g_logger) { | |
| 778 // Do a last sweep to aggregate metrics before we shut down | |
| 779 g_logger->ProcessMetrics(true, false, false); | |
| 780 delete g_logger; | |
| 781 g_logger = NULL; | |
| 782 g_logging_initialized = false; | |
| 783 stats_report::g_global_metrics.Uninitialize(); | |
| 784 } | |
| 785 | |
| 786 CommandLine::Reset(); | |
| 787 | |
| 788 // TODO : This is commented out until we can determine if | 735 // TODO : This is commented out until we can determine if |
| 789 // it's safe to shutdown breakpad at this stage (Gears, for | 736 // it's safe to shutdown breakpad at this stage (Gears, for |
| 790 // example, never deletes...) | 737 // example, never deletes...) |
| 791 // Shutdown breakpad | 738 // Shutdown breakpad |
| 792 // delete g_exception_manager; | 739 // delete g_exception_manager; |
| 793 | |
| 794 // Strictly speaking, on windows, it's not really necessary to call | |
| 795 // Stop(), but we do so for completeness | |
| 796 if (g_bluescreen_detector) { | |
| 797 g_bluescreen_detector->Stop(); | |
| 798 delete g_bluescreen_detector; | |
| 799 g_bluescreen_detector = NULL; | |
| 800 } | |
| 801 | |
| 802 #endif // O3D_INTERNAL_PLUGIN | |
| 803 | |
| 804 return NPERR_NO_ERROR; | |
| 805 } | |
| 806 } // extern "C" / namespace o3d | |
| 807 | |
| 808 namespace o3d { | |
| 809 | |
| 810 NPError NPP_New(NPMIMEType pluginType, | |
| 811 NPP instance, | |
| 812 uint16 mode, | |
| 813 int16 argc, | |
| 814 char *argn[], | |
| 815 char *argv[], | |
| 816 NPSavedData *saved) { | |
| 817 HANDLE_CRASHES; | |
| 818 | |
| 819 #if !defined(O3D_INTERNAL_PLUGIN) | |
| 820 if (!g_logging_initialized) { | |
| 821 // Get user config metrics. These won't be stored though unless the user | |
| 822 // opts-in for usagestats logging | |
| 823 GetUserAgentMetrics(instance); | |
| 824 GetUserConfigMetrics(); | |
| 825 // Create usage stats logs object | |
| 826 g_logger = o3d::PluginLogging::InitializeUsageStatsLogging(); | |
| 827 if (g_logger) { | |
| 828 // Setup blue-screen detection | |
| 829 g_bluescreen_detector = new o3d::BluescreenDetector(); | |
| 830 g_bluescreen_detector->Start(); | |
| 831 } | |
| 832 g_logging_initialized = true; | |
| 833 } | |
| 834 #endif | 740 #endif |
| 835 | 741 |
| 836 if (!IsDomainAuthorized(instance)) { | |
| 837 return NPERR_INVALID_URL; | |
| 838 } | |
| 839 | |
| 840 PluginObject* pluginObject = glue::_o3d::PluginObject::Create( | |
| 841 instance); | |
| 842 instance->pdata = pluginObject; | |
| 843 glue::_o3d::InitializeGlue(instance); | |
| 844 pluginObject->Init(argc, argn, argv); | |
| 845 return NPERR_NO_ERROR; | |
| 846 } | |
| 847 | |
| 848 NPError NPP_Destroy(NPP instance, NPSavedData **save) { | |
| 849 HANDLE_CRASHES; | |
| 850 PluginObject *obj = static_cast<PluginObject*>(instance->pdata); | |
| 851 if (obj) { | |
| 852 if (obj->GetHWnd()) { | |
| 853 CleanupAllWindows(obj); | |
| 854 } | |
| 855 | |
| 856 obj->TearDown(); | |
| 857 NPN_ReleaseObject(obj); | |
| 858 instance->pdata = NULL; | |
| 859 } | |
| 860 | |
| 861 return NPERR_NO_ERROR; | 742 return NPERR_NO_ERROR; |
| 862 } | 743 } |
| 863 | 744 |
| 864 NPError PlatformNPPGetValue(NPP instance, NPPVariable variable, void *value) { | 745 NPError PlatformNPPNew(NPP instance, PluginObject *obj) { |
| 746 return NPERR_NO_ERROR; |
| 747 } |
| 748 |
| 749 NPError PlatformNPPDestroy(NPP instance, PluginObject *obj) { |
| 750 if (obj->GetHWnd()) { |
| 751 CleanupAllWindows(obj); |
| 752 } |
| 753 |
| 754 obj->TearDown(); |
| 755 return NPERR_NO_ERROR; |
| 756 } |
| 757 |
| 758 NPError PlatformNPPGetValue(PluginObject *obj, |
| 759 NPPVariable variable, |
| 760 void *value) { |
| 865 return NPERR_INVALID_PARAM; | 761 return NPERR_INVALID_PARAM; |
| 866 } | 762 } |
| 867 | 763 |
| 868 NPError NPP_SetWindow(NPP instance, NPWindow *window) { | 764 NPError PlatformNPPSetWindow(NPP instance, |
| 869 HANDLE_CRASHES; | 765 PluginObject *obj, |
| 870 PluginObject *obj = static_cast<PluginObject*>(instance->pdata); | 766 NPWindow *window) { |
| 871 | |
| 872 HWND hWnd = static_cast<HWND>(window->window); | 767 HWND hWnd = static_cast<HWND>(window->window); |
| 873 if (!hWnd) { | 768 if (!hWnd) { |
| 874 // Chrome calls us this way before NPP_Destroy. | 769 // Chrome calls us this way before NPP_Destroy. |
| 875 if (obj->GetHWnd()) { | 770 if (obj->GetHWnd()) { |
| 876 CleanupAllWindows(obj); | 771 CleanupAllWindows(obj); |
| 877 } | 772 } |
| 878 return NPERR_NO_ERROR; | 773 return NPERR_NO_ERROR; |
| 879 } | 774 } |
| 880 | 775 |
| 881 if (obj->GetPluginHWnd() == hWnd) { | 776 if (obj->GetPluginHWnd() == hWnd) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 941 obj->client()->Init(); | 836 obj->client()->Init(); |
| 942 | 837 |
| 943 // we set the timer to 10ms or 100fps. At the time of this comment | 838 // we set the timer to 10ms or 100fps. At the time of this comment |
| 944 // the renderer does a vsync the max fps it will run will be the refresh | 839 // the renderer does a vsync the max fps it will run will be the refresh |
| 945 // rate of the monitor or 100fps, which ever is lower. | 840 // rate of the monitor or 100fps, which ever is lower. |
| 946 ::SetTimer(obj->GetHWnd(), 0, 10, NULL); | 841 ::SetTimer(obj->GetHWnd(), 0, 10, NULL); |
| 947 | 842 |
| 948 return NPERR_NO_ERROR; | 843 return NPERR_NO_ERROR; |
| 949 } | 844 } |
| 950 | 845 |
| 951 // Called when the browser has finished attempting to stream data to | 846 void PlatformNPPStreamAsFile(StreamManager *stream_manager, |
| 952 // a file as requested. If fname == NULL the attempt was not successful. | 847 NPStream *stream, |
| 953 void NPP_StreamAsFile(NPP instance, NPStream *stream, const char *fname) { | 848 const char *fname) { |
| 954 HANDLE_CRASHES; | |
| 955 PluginObject *obj = static_cast<PluginObject*>(instance->pdata); | |
| 956 StreamManager *stream_manager = obj->stream_manager(); | |
| 957 | |
| 958 stream_manager->SetStreamFile(stream, fname); | 849 stream_manager->SetStreamFile(stream, fname); |
| 959 } | 850 } |
| 960 | 851 |
| 961 int16 NPP_HandleEvent(NPP instance, void *event) { | 852 int16 PlatformNPPHandleEvent(NPP instance, PluginObject *obj, void *event) { |
| 962 HANDLE_CRASHES; | |
| 963 return 0; | 853 return 0; |
| 964 } | 854 } |
| 855 |
| 965 } // namespace o3d | 856 } // namespace o3d |
| 966 | 857 |
| 858 // TODO(tschmelcher): This stuff does not belong in this file. |
| 967 namespace glue { | 859 namespace glue { |
| 968 namespace _o3d { | 860 namespace _o3d { |
| 969 bool PluginObject::GetDisplayMode(int mode_id, o3d::DisplayMode *mode) { | 861 bool PluginObject::GetDisplayMode(int mode_id, o3d::DisplayMode *mode) { |
| 970 return renderer()->GetDisplayMode(mode_id, mode); | 862 return renderer()->GetDisplayMode(mode_id, mode); |
| 971 } | 863 } |
| 972 | 864 |
| 973 // TODO: Where should this really live? It's platform-specific, but in | 865 // TODO: Where should this really live? It's platform-specific, but in |
| 974 // PluginObject, which mainly lives in cross/o3d_glue.h+cc. | 866 // PluginObject, which mainly lives in cross/o3d_glue.h+cc. |
| 975 bool PluginObject::RequestFullscreenDisplay() { | 867 bool PluginObject::RequestFullscreenDisplay() { |
| 976 bool success = false; | 868 bool success = false; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1035 if (!renderer_->CancelFullscreen(display, prev_width_, prev_height_)) { | 927 if (!renderer_->CancelFullscreen(display, prev_width_, prev_height_)) { |
| 1036 LOG(FATAL) << "Failed to get the renderer out of fullscreen mode!"; | 928 LOG(FATAL) << "Failed to get the renderer out of fullscreen mode!"; |
| 1037 } | 929 } |
| 1038 ReplaceContentWindow(GetContentHWnd(), GetPluginHWnd(), | 930 ReplaceContentWindow(GetContentHWnd(), GetPluginHWnd(), |
| 1039 prev_width_, prev_height_); | 931 prev_width_, prev_height_); |
| 1040 client()->SendResizeEvent(prev_width_, prev_height_, false); | 932 client()->SendResizeEvent(prev_width_, prev_height_, false); |
| 1041 } | 933 } |
| 1042 } | 934 } |
| 1043 } // namespace _o3d | 935 } // namespace _o3d |
| 1044 } // namespace glue | 936 } // namespace glue |
| OLD | NEW |