Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(723)

Side by Side Diff: plugin/win/main_win.cc

Issue 149130: In preparation for becoming an internal plugin in chrome I did these things:... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/o3d/
Patch Set: '' Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 52
53 using glue::_o3d::PluginObject; 53 using glue::_o3d::PluginObject;
54 using glue::StreamManager; 54 using glue::StreamManager;
55 using o3d::DisplayWindowWindows; 55 using o3d::DisplayWindowWindows;
56 using o3d::Event; 56 using o3d::Event;
57 57
58 o3d::PluginLogging* g_logger = NULL; 58 o3d::PluginLogging* g_logger = NULL;
59 bool g_logging_initialized = false; 59 bool g_logging_initialized = false;
60 o3d::BluescreenDetector *g_bluescreen_detector = NULL; 60 o3d::BluescreenDetector *g_bluescreen_detector = NULL;
61 61
62 #if !defined(O3D_INTERNAL_PLUGIN)
63 extern "C" BOOL WINAPI DllMain(HINSTANCE instance,
64 DWORD reason,
65 LPVOID reserved) {
66 if (reason == DLL_PROCESS_DETACH) {
67 // Teardown V8 when the plugin dll is unloaded.
68 // NOTE: NP_Shutdown would have been a good place for this code but
69 // unfortunately it looks like it gets called even when the dll
70 // isn't really unloaded. This is a problem since after calling
71 // V8::Dispose(), V8 cannot be initialized again.
72 bool v8_disposed = v8::V8::Dispose();
73 if (!v8_disposed)
74 DLOG(ERROR) << "Failed to release V8 resources.";
75 return true;
76 }
77 return true;
78 }
79 #endif // O3D_INTERNAL_PLUGIN
80
62 namespace { 81 namespace {
63 // We would normally make this a stack variable in main(), but in a 82 // We would normally make this a stack variable in main(), but in a
64 // plugin, that's not possible, so we allocate it dynamically and 83 // plugin, that's not possible, so we allocate it dynamically and
65 // destroy it explicitly. 84 // destroy it explicitly.
66 scoped_ptr<base::AtExitManager> g_at_exit_manager; 85 scoped_ptr<base::AtExitManager> g_at_exit_manager;
67 } // end anonymous namespace
68
69 void RenderOnDemandCallbackHandler::Run() {
70 ::InvalidateRect(obj_->GetHWnd(), NULL, TRUE);
71 }
72 86
73 static int HandleKeyboardEvent(PluginObject *obj, 87 static int HandleKeyboardEvent(PluginObject *obj,
74 HWND hWnd, 88 HWND hWnd,
75 UINT Msg, 89 UINT Msg,
76 WPARAM wParam, 90 WPARAM wParam,
77 LPARAM lParam) { 91 LPARAM lParam) {
78 DCHECK(obj); 92 DCHECK(obj);
79 DCHECK(obj->client()); 93 DCHECK(obj->client());
80 Event::Type type; 94 Event::Type type;
81 // First figure out which kind of event to create, and do any event-specific 95 // First figure out which kind of event to create, and do any event-specific
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 if (event.type() == Event::TYPE_KEYDOWN && 155 if (event.type() == Event::TYPE_KEYDOWN &&
142 (wParam == VK_ESCAPE || 156 (wParam == VK_ESCAPE ||
143 (wParam == VK_F4 && (modifier_state & Event::MODIFIER_ALT)))) { 157 (wParam == VK_F4 && (modifier_state & Event::MODIFIER_ALT)))) {
144 obj->CancelFullscreenDisplay(); 158 obj->CancelFullscreenDisplay();
145 } 159 }
146 160
147 obj->client()->AddEventToQueue(event); 161 obj->client()->AddEventToQueue(event);
148 return 0; 162 return 0;
149 } 163 }
150 164
151 static void HandleMouseEvent(PluginObject *obj, 165 void HandleMouseEvent(PluginObject *obj,
152 HWND hWnd, 166 HWND hWnd,
153 UINT Msg, 167 UINT Msg,
154 WPARAM wParam, 168 WPARAM wParam,
155 LPARAM lParam) { 169 LPARAM lParam) {
156 DCHECK(obj); 170 DCHECK(obj);
157 DCHECK(obj->client()); 171 DCHECK(obj->client());
158 bool fake_dblclick = false; 172 bool fake_dblclick = false;
159 Event::Type type; 173 Event::Type type;
160 int x = GET_X_LPARAM(lParam); 174 int x = GET_X_LPARAM(lParam);
161 int y = GET_Y_LPARAM(lParam); 175 int y = GET_Y_LPARAM(lParam);
162 int screen_x, screen_y; 176 int screen_x, screen_y;
163 bool in_plugin = false; 177 bool in_plugin = false;
164 { 178 {
165 RECT rect; 179 RECT rect;
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 event.set_type(Event::TYPE_DBLCLICK); 333 event.set_type(Event::TYPE_DBLCLICK);
320 obj->client()->AddEventToQueue(event); 334 obj->client()->AddEventToQueue(event);
321 } 335 }
322 if (in_plugin && type == Event::TYPE_MOUSEDOWN && 336 if (in_plugin && type == Event::TYPE_MOUSEDOWN &&
323 obj->HitFullscreenClickRegion(x, y)) { 337 obj->HitFullscreenClickRegion(x, y)) {
324 obj->RequestFullscreenDisplay(); 338 obj->RequestFullscreenDisplay();
325 } 339 }
326 } 340 }
327 341
328 // This returns 0 on success, 1 on failure, to match WindowProc. 342 // This returns 0 on success, 1 on failure, to match WindowProc.
329 static LRESULT ForwardEvent(PluginObject *obj, 343 LRESULT ForwardEvent(PluginObject *obj,
330 HWND hWnd, 344 HWND hWnd,
331 UINT Msg, 345 UINT Msg,
332 WPARAM wParam, 346 WPARAM wParam,
333 LPARAM lParam, 347 LPARAM lParam,
334 bool translateCoords) { 348 bool translateCoords) {
335 DCHECK(obj); 349 DCHECK(obj);
336 DCHECK(obj->GetPluginHWnd()); 350 DCHECK(obj->GetPluginHWnd());
337 HWND dest_hwnd = obj->GetParentHWnd(); 351 HWND dest_hwnd = obj->GetParentHWnd();
338 DCHECK(hWnd); 352 DCHECK(hWnd);
339 DCHECK(dest_hwnd); 353 DCHECK(dest_hwnd);
340 bool fullscreen = hWnd == obj->GetFullscreenHWnd(); 354 bool fullscreen = hWnd == obj->GetFullscreenHWnd();
341 if (fullscreen) { 355 if (fullscreen) {
342 dest_hwnd = obj->GetPluginHWnd(); 356 dest_hwnd = obj->GetPluginHWnd();
343 } else if (obj->IsChrome()) { 357 } else if (obj->IsChrome()) {
344 // When trying to find the parent window of the Chrome plugin, new Chrome is 358 // When trying to find the parent window of the Chrome plugin, new Chrome is
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 // The plugin and the fullscreen window each fill their respective entire 405 // The plugin and the fullscreen window each fill their respective entire
392 // window, so there aren't any offsets to add or subtract. 406 // window, so there aren't any offsets to add or subtract.
393 y_1 = y * height_1 / height; 407 y_1 = y * height_1 / height;
394 } 408 }
395 409
396 lParam = MAKELPARAM(x_1, y_1); 410 lParam = MAKELPARAM(x_1, y_1);
397 } 411 }
398 return !::PostMessage(dest_hwnd, Msg, wParam, lParam); 412 return !::PostMessage(dest_hwnd, Msg, wParam, lParam);
399 } 413 }
400 414
401 static LRESULT HandleDragAndDrop(PluginObject *obj, WPARAM wParam) { 415 LRESULT HandleDragAndDrop(PluginObject *obj, WPARAM wParam) {
402 HDROP hDrop = reinterpret_cast<HDROP>(wParam); 416 HDROP hDrop = reinterpret_cast<HDROP>(wParam);
403 UINT num_files = ::DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0); 417 UINT num_files = ::DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0);
404 if (!num_files) { 418 if (!num_files) {
405 ::DragFinish(hDrop); 419 ::DragFinish(hDrop);
406 return 0; 420 return 0;
407 } 421 }
408 UINT path_len = ::DragQueryFile(hDrop, 0, NULL, 0); 422 UINT path_len = ::DragQueryFile(hDrop, 0, NULL, 0);
409 // Let's limit that length, just in case. 423 // Let's limit that length, just in case.
410 if (!path_len || path_len > 4096) { 424 if (!path_len || path_len > 4096) {
411 ::DragFinish(hDrop); 425 ::DragFinish(hDrop);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 for (UINT i = 0; i < num_chars; ++i) { 464 for (UINT i = 0; i < num_chars; ++i) {
451 if (path_to_use[i] == '\\') { 465 if (path_to_use[i] == '\\') {
452 path_to_use[i] = '/'; 466 path_to_use[i] = '/';
453 } 467 }
454 } 468 }
455 obj->RedirectToFile(path_to_use); 469 obj->RedirectToFile(path_to_use);
456 470
457 return 1; 471 return 1;
458 } 472 }
459 473
460 static LRESULT CALLBACK 474 LRESULT CALLBACK WindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
461 WindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
462 PluginObject *obj = PluginObject::GetPluginProperty(hWnd); 475 PluginObject *obj = PluginObject::GetPluginProperty(hWnd);
463 if (obj == NULL) { // It's not my window 476 if (obj == NULL) { // It's not my window
464 return 1; // 0 often means we handled it. 477 return 1; // 0 often means we handled it.
465 } 478 }
466 479
467 // Limit the ways in which we can be reentrant. Note that this WindowProc 480 // Limit the ways in which we can be reentrant. Note that this WindowProc
468 // may be called by different threads. For example, IE will register plugin 481 // may be called by different threads. For example, IE will register plugin
469 // instances on separate threads. 482 // instances on separate threads.
470 o3d::Client::ScopedIncrement reentrance_count(obj->client()); 483 o3d::Client::ScopedIncrement reentrance_count(obj->client());
471 484
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 return ::CallWindowProc(obj->GetDefaultPluginWindowProc(), 650 return ::CallWindowProc(obj->GetDefaultPluginWindowProc(),
638 hWnd, 651 hWnd,
639 Msg, 652 Msg,
640 wParam, 653 wParam,
641 lParam); 654 lParam);
642 } 655 }
643 } 656 }
644 return 0; 657 return 0;
645 } 658 }
646 659
660 NPError InitializePlugin() {
661 #if !defined(O3D_INTERNAL_PLUGIN)
662 if (!o3d::SetupOutOfMemoryHandler())
663 return NPERR_MODULE_LOAD_FAILED_ERROR;
664
665 // Setup crash handler
666 if (!g_exception_manager) {
667 g_exception_manager = new ExceptionManager(false);
668 g_exception_manager->StartMonitoring();
669 }
670
671 // Initialize the AtExitManager so that base singletons can be
672 // destroyed properly.
673 g_at_exit_manager.reset(new base::AtExitManager());
674
675 // Turn on the logging.
676 CommandLine::Init(0, NULL);
677 InitLogging(L"debug.log",
678 logging::LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG,
679 logging::DONT_LOCK_LOG_FILE,
680 logging::APPEND_TO_OLD_LOG_FILE);
681 #endif // O3D_INTERNAL_PLUGIN
682
683 DLOG(INFO) << "NP_Initialize";
684
685 return NPERR_NO_ERROR;
686 }
687
688 void CleanupFullscreenWindow(PluginObject *obj) {
689 DCHECK(obj->GetFullscreenHWnd());
690 obj->StorePluginProperty(obj->GetPluginHWnd(), obj);
691 ::DestroyWindow(obj->GetFullscreenHWnd());
692 obj->SetFullscreenHWnd(NULL);
693 }
694
695 void CleanupAllWindows(PluginObject *obj) {
696 DCHECK(obj->GetHWnd());
697 DCHECK(obj->GetPluginHWnd());
698 ::KillTimer(obj->GetHWnd(), 0);
699 if (obj->GetFullscreenHWnd()) {
700 CleanupFullscreenWindow(obj);
701 }
702 PluginObject::ClearPluginProperty(obj->GetHWnd());
703 ::SetWindowLongPtr(obj->GetPluginHWnd(),
704 GWL_WNDPROC,
705 reinterpret_cast<LONG_PTR>(
706 obj->GetDefaultPluginWindowProc()));
707 obj->SetPluginHWnd(NULL);
708 obj->SetHWnd(NULL);
709 }
710
711 HWND CreateFullscreenWindow(PluginObject *obj,
712 int mode_id) {
713 o3d::DisplayMode mode;
714 if (!obj->renderer()->GetDisplayMode(mode_id, &mode)) {
715 return NULL;
716 }
717 CHECK(mode.width() > 0 && mode.height() > 0);
718
719 HINSTANCE instance =
720 reinterpret_cast<HINSTANCE>(
721 ::GetWindowLongPtr(obj->GetPluginHWnd(), GWLP_HINSTANCE));
722 WNDCLASSEX *wcx = obj->GetFullscreenWindowClass(instance, WindowProc);
723 HWND hWnd = CreateWindowEx(NULL,
724 wcx->lpszClassName,
725 L"O3D Test Fullscreen Window",
726 WS_POPUP,
727 0, 0,
728 mode.width(),
729 mode.height(),
730 NULL,
731 NULL,
732 instance,
733 NULL);
734
735 ShowWindow(hWnd, SW_SHOW);
736 return hWnd;
737 }
738 } // namespace anonymous
739
740 #if defined(O3D_INTERNAL_PLUGIN)
741 namespace o3d {
742 #else
743 extern "C" {
744 #endif
745
746 NPError OSCALL NP_Initialize(NPNetscapeFuncs *browserFuncs) {
747 HANDLE_CRASHES;
748 NPError retval = InitializeNPNApi(browserFuncs);
749 if (retval != NPERR_NO_ERROR) return retval;
750 return InitializePlugin();
751 }
752
753 NPError OSCALL NP_Shutdown(void) {
754 HANDLE_CRASHES;
755 DLOG(INFO) << "NP_Shutdown";
756
757 #if !defined(O3D_INTERNAL_PLUGIN)
758
759 if (g_logger) {
760 // Do a last sweep to aggregate metrics before we shut down
761 g_logger->ProcessMetrics(true, false);
762 delete g_logger;
763 g_logger = NULL;
764 g_logging_initialized = false;
765 stats_report::g_global_metrics.Uninitialize();
766 }
767
768 CommandLine::Terminate();
769
770 // Force all base singletons to be destroyed.
771 g_at_exit_manager.reset(NULL);
772
773 // TODO : This is commented out until we can determine if
774 // it's safe to shutdown breakpad at this stage (Gears, for
775 // example, never deletes...)
776 // Shutdown breakpad
777 // delete g_exception_manager;
778
779 // Strictly speaking, on windows, it's not really necessary to call
780 // Stop(), but we do so for completeness
781 if (g_bluescreen_detector) {
782 g_bluescreen_detector->Stop();
783 delete g_bluescreen_detector;
784 g_bluescreen_detector = NULL;
785 }
786
787 #endif // O3D_INTERNAL_PLUGIN
788
789 return NPERR_NO_ERROR;
790 }
791 } // extern "C" / namespace o3d
792
793 namespace o3d {
794 void RenderOnDemandCallbackHandler::Run() {
795 ::InvalidateRect(obj_->GetHWnd(), NULL, TRUE);
796 }
797
798 NPError NPP_New(NPMIMEType pluginType,
799 NPP instance,
800 uint16 mode,
801 int16 argc,
802 char *argn[],
803 char *argv[],
804 NPSavedData *saved) {
805 HANDLE_CRASHES;
806
807 if (!g_logging_initialized) {
808 // Get user config metrics. These won't be stored though unless the user
809 // opts-in for usagestats logging
810 GetUserAgentMetrics(instance);
811 GetUserConfigMetrics();
812 // Create usage stats logs object
813 g_logger = o3d::PluginLogging::InitializeUsageStatsLogging();
814 if (g_logger) {
815 // Setup blue-screen detection
816 g_bluescreen_detector = new o3d::BluescreenDetector();
817 g_bluescreen_detector->Start();
818 }
819 g_logging_initialized = true;
820 }
821 PluginObject* pluginObject = glue::_o3d::PluginObject::Create(
822 instance);
823 instance->pdata = pluginObject;
824 glue::_o3d::InitializeGlue(instance);
825 pluginObject->Init(argc, argn, argv);
826 return NPERR_NO_ERROR;
827 }
828
829 NPError NPP_Destroy(NPP instance, NPSavedData **save) {
830 HANDLE_CRASHES;
831 PluginObject *obj = static_cast<PluginObject*>(instance->pdata);
832 if (obj) {
833 if (obj->GetHWnd()) {
834 CleanupAllWindows(obj);
835 }
836
837 obj->TearDown();
838 NPN_ReleaseObject(obj);
839 instance->pdata = NULL;
840 }
841
842 return NPERR_NO_ERROR;
843 }
844
647 NPError PlatformNPPGetValue(NPP instance, NPPVariable variable, void *value) { 845 NPError PlatformNPPGetValue(NPP instance, NPPVariable variable, void *value) {
648 return NPERR_INVALID_PARAM; 846 return NPERR_INVALID_PARAM;
649 } 847 }
650 848
651 extern "C" { 849 NPError NPP_SetWindow(NPP instance, NPWindow *window) {
652 BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) { 850 HANDLE_CRASHES;
653 if (reason == DLL_PROCESS_DETACH) { 851 PluginObject *obj = static_cast<PluginObject*>(instance->pdata);
654 // Teardown V8 when the plugin dll is unloaded. 852
655 // NOTE: NP_Shutdown would have been a good place for this code but 853 HWND hWnd = static_cast<HWND>(window->window);
656 // unfortunately it looks like it gets called even when the dll 854 if (!hWnd) {
657 // isn't really unloaded. This is a problem since after calling 855 // Chrome calls us this way before NPP_Destroy.
658 // V8::Dispose(), V8 cannot be initialized again. 856 if (obj->GetHWnd()) {
659 bool v8_disposed = v8::V8::Dispose(); 857 CleanupAllWindows(obj);
660 if (!v8_disposed) 858 }
661 DLOG(ERROR) << "Failed to release V8 resources."; 859 return NPERR_NO_ERROR;
662 return true; 860 }
663 } 861 if (obj->GetHWnd() == hWnd) {
664 return true; 862 return NPERR_NO_ERROR;
665 } 863 }
666 864 if (obj->fullscreen()) {
667 NPError InitializePlugin() { 865 // We can get here if the user alt+tabs away from the fullscreen plugin
668 if (!o3d::SetupOutOfMemoryHandler()) 866 // window or JavaScript resizes the plugin window.
669 return NPERR_MODULE_LOAD_FAILED_ERROR; 867 DCHECK(obj->GetPluginHWnd());
670 868 DCHECK(obj->GetFullscreenHWnd());
671 // Setup crash handler 869 DCHECK(obj->GetPluginHWnd() == hWnd);
672 if (!g_exception_manager) { 870 return NPERR_NO_ERROR;
673 g_exception_manager = new ExceptionManager(false); 871 }
674 g_exception_manager->StartMonitoring(); 872 DCHECK(!obj->GetPluginHWnd());
675 } 873 obj->SetPluginHWnd(hWnd);
676 874 obj->SetParentHWnd(::GetParent(hWnd));
677 // Initialize the AtExitManager so that base singletons can be 875 PluginObject::StorePluginProperty(hWnd, obj);
678 // destroyed properly. 876 obj->SetDefaultPluginWindowProc(
679 g_at_exit_manager.reset(new base::AtExitManager()); 877 reinterpret_cast<WNDPROC>(
680 878 ::SetWindowLongPtr(hWnd,
681 // Turn on the logging. 879 GWL_WNDPROC,
682 CommandLine::Init(0, NULL); 880 reinterpret_cast<LONG_PTR>(WindowProc))));
683 InitLogging(L"debug.log", 881
684 logging::LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG, 882 // create and assign the graphics context
685 logging::DONT_LOCK_LOG_FILE, 883 DisplayWindowWindows default_display;
686 logging::APPEND_TO_OLD_LOG_FILE); 884 default_display.set_hwnd(obj->GetHWnd());
687 885
688 DLOG(INFO) << "NP_Initialize"; 886 obj->CreateRenderer(default_display);
689 887 obj->client()->Init();
690 // Limit the current thread to one processor (the current one). This ensures 888 obj->client()->SetRenderOnDemandCallback(
691 // that timing code runs on only one processor, and will not suffer any ill 889 new RenderOnDemandCallbackHandler(obj));
692 // effects from power management. See "Game Timing and Multicore Processors" 890
693 // in the DirectX docs for more details 891 // we set the timer to 10ms or 100fps. At the time of this comment
694 { 892 // the renderer does a vsync the max fps it will run will be the refresh
695 HANDLE current_process_handle = GetCurrentProcess(); 893 // rate of the monitor or 100fps, which ever is lower.
696 894 ::SetTimer(obj->GetHWnd(), 0, 10, NULL);
697 // Get the processor affinity mask for this process 895
698 DWORD_PTR process_affinity_mask = 0; 896 return NPERR_NO_ERROR;
699 DWORD_PTR system_affinity_mask = 0; 897 }
700 898
701 if (GetProcessAffinityMask(current_process_handle, 899 // Called when the browser has finished attempting to stream data to
702 &process_affinity_mask, 900 // a file as requested. If fname == NULL the attempt was not successful.
703 &system_affinity_mask) != 0 && 901 void NPP_StreamAsFile(NPP instance, NPStream *stream, const char *fname) {
704 process_affinity_mask) { 902 HANDLE_CRASHES;
705 // Find the lowest processor that our process is allows to run against 903 PluginObject *obj = static_cast<PluginObject*>(instance->pdata);
706 DWORD_PTR affinity_mask = (process_affinity_mask & 904 StreamManager *stream_manager = obj->stream_manager();
707 ((~process_affinity_mask) + 1)); 905
708 906 stream_manager->SetStreamFile(stream, fname);
709 // Set this as the processor that our thread must always run against 907 }
710 // This must be a subset of the process affinity mask 908
711 HANDLE hCurrentThread = GetCurrentThread(); 909 int16 NPP_HandleEvent(NPP instance, void *event) {
712 if (INVALID_HANDLE_VALUE != hCurrentThread) { 910 HANDLE_CRASHES;
713 SetThreadAffinityMask(hCurrentThread, affinity_mask); 911 return 0;
714 CloseHandle(hCurrentThread); 912 }
715 } 913 } // namespace o3d
914
915 namespace glue {
916 namespace _o3d {
917 bool PluginObject::GetDisplayMode(int mode_id, o3d::DisplayMode *mode) {
918 return renderer()->GetDisplayMode(mode_id, mode);
919 }
920
921 // TODO: Where should this really live? It's platform-specific, but in
922 // PluginObject, which mainly lives in cross/o3d_glue.h+cc.
923 bool PluginObject::RequestFullscreenDisplay() {
924 bool success = false;
925 DCHECK(GetPluginHWnd());
926 if (!fullscreen_ && renderer_ && fullscreen_region_valid_) {
927 DCHECK(renderer_->fullscreen() == fullscreen_);
928 DCHECK(!GetFullscreenHWnd());
929 HWND drawing_hwnd =
930 CreateFullscreenWindow(this, fullscreen_region_mode_id_);
931 if (drawing_hwnd) {
932 ::KillTimer(GetHWnd(), 0);
933 SetFullscreenHWnd(drawing_hwnd);
934 StorePluginPropertyUnsafe(drawing_hwnd, this);
935
936 DisplayWindowWindows display;
937 display.set_hwnd(GetHWnd());
938 if (renderer_->SetFullscreen(true, display,
939 fullscreen_region_mode_id_)) {
940 fullscreen_ = true;
941 client()->SendResizeEvent(renderer_->width(), renderer_->height(),
942 true);
943 success = true;
944 } else {
945 CleanupFullscreenWindow(this);
716 } 946 }
717
718 CloseHandle(current_process_handle);
719 }
720
721 return NPERR_NO_ERROR;
722 }
723
724 NPError OSCALL NP_Initialize(NPNetscapeFuncs *browserFuncs) {
725 HANDLE_CRASHES;
726 NPError retval = InitializeNPNApi(browserFuncs);
727 if (retval != NPERR_NO_ERROR) return retval;
728 return InitializePlugin();
729 }
730
731 NPError OSCALL NP_Shutdown(void) {
732 HANDLE_CRASHES;
733 DLOG(INFO) << "NP_Shutdown";
734 if (g_logger) {
735 // Do a last sweep to aggregate metrics before we shut down
736 g_logger->ProcessMetrics(true, false);
737 delete g_logger;
738 g_logger = NULL;
739 g_logging_initialized = false;
740 stats_report::g_global_metrics.Uninitialize();
741 }
742
743 CommandLine::Terminate();
744
745 // Force all base singletons to be destroyed.
746 g_at_exit_manager.reset(NULL);
747
748 // TODO : This is commented out until we can determine if
749 // it's safe to shutdown breakpad at this stage (Gears, for
750 // example, never deletes...)
751 // Shutdown breakpad
752 // delete g_exception_manager;
753
754 // Strictly speaking, on windows, it's not really necessary to call
755 // Stop(), but we do so for completeness
756 if (g_bluescreen_detector) {
757 g_bluescreen_detector->Stop();
758 delete g_bluescreen_detector;
759 g_bluescreen_detector = NULL;
760 }
761
762 return NPERR_NO_ERROR;
763 }
764
765 NPError NPP_New(NPMIMEType pluginType,
766 NPP instance,
767 uint16 mode,
768 int16 argc,
769 char *argn[],
770 char *argv[],
771 NPSavedData *saved) {
772 HANDLE_CRASHES;
773
774 if (!g_logging_initialized) {
775 // Get user config metrics. These won't be stored though unless the user
776 // opts-in for usagestats logging
777 GetUserAgentMetrics(instance);
778 GetUserConfigMetrics();
779 // Create usage stats logs object
780 g_logger = o3d::PluginLogging::InitializeUsageStatsLogging();
781 if (g_logger) {
782 // Setup blue-screen detection
783 g_bluescreen_detector = new o3d::BluescreenDetector();
784 g_bluescreen_detector->Start();
785 }
786 g_logging_initialized = true;
787 }
788 PluginObject* pluginObject = glue::_o3d::PluginObject::Create(
789 instance);
790 instance->pdata = pluginObject;
791 glue::_o3d::InitializeGlue(instance);
792 pluginObject->Init(argc, argn, argv);
793 return NPERR_NO_ERROR;
794 }
795
796 void CleanupFullscreenWindow(PluginObject *obj) {
797 DCHECK(obj->GetFullscreenHWnd());
798 obj->StorePluginProperty(obj->GetPluginHWnd(), obj);
799 ::DestroyWindow(obj->GetFullscreenHWnd());
800 obj->SetFullscreenHWnd(NULL);
801 }
802
803 void CleanupAllWindows(PluginObject *obj) {
804 DCHECK(obj->GetHWnd());
805 DCHECK(obj->GetPluginHWnd());
806 ::KillTimer(obj->GetHWnd(), 0);
807 if (obj->GetFullscreenHWnd()) {
808 CleanupFullscreenWindow(obj);
809 }
810 PluginObject::ClearPluginProperty(obj->GetHWnd());
811 ::SetWindowLongPtr(obj->GetPluginHWnd(),
812 GWL_WNDPROC,
813 reinterpret_cast<LONG_PTR>(
814 obj->GetDefaultPluginWindowProc()));
815 obj->SetPluginHWnd(NULL);
816 obj->SetHWnd(NULL);
817 }
818
819 NPError NPP_Destroy(NPP instance, NPSavedData **save) {
820 HANDLE_CRASHES;
821 PluginObject *obj = static_cast<PluginObject*>(instance->pdata);
822 if (obj) {
823 if (obj->GetHWnd()) {
824 CleanupAllWindows(obj);
825 }
826
827 obj->TearDown();
828 NPN_ReleaseObject(obj);
829 instance->pdata = NULL;
830 }
831
832 return NPERR_NO_ERROR;
833 }
834
835 bool PluginObject::GetDisplayMode(int mode_id, o3d::DisplayMode *mode) {
836 return renderer()->GetDisplayMode(mode_id, mode);
837 }
838
839
840 HWND CreateFullscreenWindow(PluginObject *obj,
841 int mode_id) {
842 o3d::DisplayMode mode;
843 if (!obj->renderer()->GetDisplayMode(mode_id, &mode)) {
844 return NULL;
845 }
846 CHECK(mode.width() > 0 && mode.height() > 0);
847
848 HINSTANCE instance =
849 reinterpret_cast<HINSTANCE>(
850 ::GetWindowLongPtr(obj->GetPluginHWnd(), GWLP_HINSTANCE));
851 WNDCLASSEX *wcx = obj->GetFullscreenWindowClass(instance, WindowProc);
852 HWND hWnd = CreateWindowEx(NULL,
853 wcx->lpszClassName,
854 L"O3D Test Fullscreen Window",
855 WS_POPUP,
856 0, 0,
857 mode.width(),
858 mode.height(),
859 NULL,
860 NULL,
861 instance,
862 NULL);
863
864 ShowWindow(hWnd, SW_SHOW);
865 return hWnd;
866 }
867
868 // TODO: Where should this really live? It's platform-specific, but in
869 // PluginObject, which mainly lives in cross/o3d_glue.h+cc.
870 bool PluginObject::RequestFullscreenDisplay() {
871 bool success = false;
872 DCHECK(GetPluginHWnd());
873 if (!fullscreen_ && renderer_ && fullscreen_region_valid_) {
874 DCHECK(renderer_->fullscreen() == fullscreen_);
875 DCHECK(!GetFullscreenHWnd());
876 HWND drawing_hwnd =
877 CreateFullscreenWindow(this, fullscreen_region_mode_id_);
878 if (drawing_hwnd) {
879 ::KillTimer(GetHWnd(), 0);
880 SetFullscreenHWnd(drawing_hwnd);
881 StorePluginPropertyUnsafe(drawing_hwnd, this);
882
883 DisplayWindowWindows display;
884 display.set_hwnd(GetHWnd());
885 if (renderer_->SetFullscreen(true, display,
886 fullscreen_region_mode_id_)) {
887 fullscreen_ = true;
888 client()->SendResizeEvent(renderer_->width(), renderer_->height(),
889 true);
890 success = true;
891 } else {
892 CleanupFullscreenWindow(this);
893 }
894 prev_width_ = renderer_->width();
895 prev_height_ = renderer_->height();
896 ::SetTimer(GetHWnd(), 0, 10, NULL);
897 } else {
898 LOG(ERROR) << "Failed to create fullscreen window.";
899 }
900 }
901 return success;
902 }
903
904 void PluginObject::CancelFullscreenDisplay() {
905 DCHECK(GetPluginHWnd());
906 if (fullscreen_) {
907 DCHECK(renderer());
908 DCHECK(renderer()->fullscreen());
909 ::KillTimer(GetHWnd(), 0);
910 DisplayWindowWindows display;
911 display.set_hwnd(GetPluginHWnd());
912 if (!renderer_->SetFullscreen(false, display, 0)) {
913 LOG(FATAL) << "Failed to get the renderer out of fullscreen mode!";
914 }
915 CleanupFullscreenWindow(this);
916 prev_width_ = renderer_->width(); 947 prev_width_ = renderer_->width();
917 prev_height_ = renderer_->height(); 948 prev_height_ = renderer_->height();
918 client()->SendResizeEvent(prev_width_, prev_height_, false);
919 ::SetTimer(GetHWnd(), 0, 10, NULL); 949 ::SetTimer(GetHWnd(), 0, 10, NULL);
920 fullscreen_ = false; 950 } else {
921 } 951 LOG(ERROR) << "Failed to create fullscreen window.";
922 } 952 }
923 953 }
924 NPError NPP_SetWindow(NPP instance, NPWindow *window) { 954 return success;
925 HANDLE_CRASHES; 955 }
926 PluginObject *obj = static_cast<PluginObject*>(instance->pdata); 956
927 957 void PluginObject::CancelFullscreenDisplay() {
928 HWND hWnd = static_cast<HWND>(window->window); 958 DCHECK(GetPluginHWnd());
929 if (!hWnd) { 959 if (fullscreen_) {
930 // Chrome calls us this way before NPP_Destroy. 960 DCHECK(renderer());
931 if (obj->GetHWnd()) { 961 DCHECK(renderer()->fullscreen());
932 CleanupAllWindows(obj); 962 ::KillTimer(GetHWnd(), 0);
933 } 963 DisplayWindowWindows display;
934 return NPERR_NO_ERROR; 964 display.set_hwnd(GetPluginHWnd());
935 } 965 if (!renderer_->SetFullscreen(false, display, 0)) {
936 if (obj->GetHWnd() == hWnd) { 966 LOG(FATAL) << "Failed to get the renderer out of fullscreen mode!";
937 return NPERR_NO_ERROR; 967 }
938 } 968 CleanupFullscreenWindow(this);
939 if (obj->fullscreen()) { 969 prev_width_ = renderer_->width();
940 // We can get here if the user alt+tabs away from the fullscreen plugin 970 prev_height_ = renderer_->height();
941 // window or JavaScript resizes the plugin window. 971 client()->SendResizeEvent(prev_width_, prev_height_, false);
942 DCHECK(obj->GetPluginHWnd()); 972 ::SetTimer(GetHWnd(), 0, 10, NULL);
943 DCHECK(obj->GetFullscreenHWnd()); 973 fullscreen_ = false;
944 DCHECK(obj->GetPluginHWnd() == hWnd); 974 }
945 return NPERR_NO_ERROR; 975 }
946 } 976 } // namespace _o3d
947 DCHECK(!obj->GetPluginHWnd()); 977 } // namespace glue
948 obj->SetPluginHWnd(hWnd);
949 obj->SetParentHWnd(::GetParent(hWnd));
950 PluginObject::StorePluginProperty(hWnd, obj);
951 obj->SetDefaultPluginWindowProc(
952 reinterpret_cast<WNDPROC>(
953 ::SetWindowLongPtr(hWnd,
954 GWL_WNDPROC,
955 reinterpret_cast<LONG_PTR>(WindowProc))));
956
957 // create and assign the graphics context
958 DisplayWindowWindows default_display;
959 default_display.set_hwnd(obj->GetHWnd());
960
961 obj->CreateRenderer(default_display);
962 obj->client()->Init();
963 obj->client()->SetRenderOnDemandCallback(
964 new RenderOnDemandCallbackHandler(obj));
965
966 // we set the timer to 10ms or 100fps. At the time of this comment
967 // the renderer does a vsync the max fps it will run will be the refresh
968 // rate of the monitor or 100fps, which ever is lower.
969 ::SetTimer(obj->GetHWnd(), 0, 10, NULL);
970
971 return NPERR_NO_ERROR;
972 }
973
974 // Called when the browser has finished attempting to stream data to
975 // a file as requested. If fname == NULL the attempt was not successful.
976 void NPP_StreamAsFile(NPP instance, NPStream *stream, const char *fname) {
977 HANDLE_CRASHES;
978 PluginObject *obj = static_cast<PluginObject*>(instance->pdata);
979 StreamManager *stream_manager = obj->stream_manager();
980
981 stream_manager->SetStreamFile(stream, fname);
982 }
983
984 int16 NPP_HandleEvent(NPP instance, void *event) {
985 HANDLE_CRASHES;
986 return 0;
987 }
988 } // end extern "C"
OLDNEW
« plugin/mac/main_mac.mm ('K') | « plugin/win/config.cc ('k') | plugin/win/update_lock.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698