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 15 matching lines...) Expand all Loading... |
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 */ | 30 */ |
31 | 31 |
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 Linux platform. | 34 // the Linux platform. |
35 | 35 |
| 36 #include "plugin/cross/main.h" |
| 37 |
36 #include <X11/keysym.h> | 38 #include <X11/keysym.h> |
37 #include <gdk/gdkx.h> | 39 #include <gdk/gdkx.h> |
38 #include <gdk/gdkkeysyms.h> | 40 #include <gdk/gdkkeysyms.h> |
39 #include "base/at_exit.h" | 41 |
40 #include "base/command_line.h" | |
41 #include "base/file_util.h" | |
42 #include "base/logging.h" | 42 #include "base/logging.h" |
43 #include "base/scoped_ptr.h" | |
44 #include "base/third_party/nspr/prtypes.h" | 43 #include "base/third_party/nspr/prtypes.h" |
45 #include "o3d/breakpad/linux/breakpad.h" | 44 #include "core/cross/event.h" |
46 #include "plugin/cross/main.h" | 45 #include "core/linux/display_window_linux.h" |
47 #include "plugin/cross/out_of_memory.h" | |
48 #include "plugin/cross/whitelist.h" | |
49 #include "plugin/linux/envvars.h" | 46 #include "plugin/linux/envvars.h" |
| 47 #if !defined(O3D_INTERNAL_PLUGIN) |
| 48 #include "breakpad/linux/breakpad.h" |
| 49 #endif |
50 | 50 |
51 using glue::_o3d::PluginObject; | 51 using glue::_o3d::PluginObject; |
52 using glue::StreamManager; | 52 using glue::StreamManager; |
53 using o3d::DisplayWindowLinux; | 53 using o3d::DisplayWindowLinux; |
54 using o3d::Event; | 54 using o3d::Event; |
55 | 55 |
56 namespace { | 56 namespace { |
57 // We would normally make this a stack variable in main(), but in a | |
58 // plugin, that's not possible, so we make it a global. When the DLL is loaded | |
59 // this it gets constructed and when it is unlooaded it is destructed. Note | |
60 // that this cannot be done in NP_Initialize and NP_Shutdown because those | |
61 // calls do not necessarily signify the DLL being loaded and unloaded. If the | |
62 // DLL is not unloaded then the values of global variables are preserved. | |
63 base::AtExitManager g_at_exit_manager; | |
64 | 57 |
65 bool g_xembed_support = false; | 58 bool g_xembed_support = false; |
66 | 59 |
| 60 #if !defined(O3D_INTERNAL_PLUGIN) |
67 o3d::Breakpad g_breakpad; | 61 o3d::Breakpad g_breakpad; |
| 62 #endif |
68 | 63 |
69 #ifdef O3D_PLUGIN_ENV_VARS_FILE | 64 #ifdef O3D_PLUGIN_ENV_VARS_FILE |
70 static const char *kEnvVarsFilePath = O3D_PLUGIN_ENV_VARS_FILE; | 65 static const char kEnvVarsFilePath[] = O3D_PLUGIN_ENV_VARS_FILE; |
71 #endif | 66 #endif |
72 | 67 |
73 static void DrawPlugin(PluginObject *obj) { | 68 static void DrawPlugin(PluginObject *obj) { |
74 // Limit drawing to no more than once every timer tick. | 69 // Limit drawing to no more than once every timer tick. |
75 if (!obj->draw_) return; | 70 if (!obj->draw_) return; |
76 // Don't allow re-entrant rendering (can happen in Chrome) | 71 // Don't allow re-entrant rendering (can happen in Chrome) |
77 if (obj->client()->IsRendering()) return; | 72 if (obj->client()->IsRendering()) return; |
78 obj->client()->RenderClient(true); | 73 obj->client()->RenderClient(true); |
79 obj->draw_ = false; | 74 obj->draw_ = false; |
80 } | 75 } |
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
618 widget = obj->gtk_fullscreen_container_; | 613 widget = obj->gtk_fullscreen_container_; |
619 } else { | 614 } else { |
620 widget = obj->gtk_container_; | 615 widget = obj->gtk_container_; |
621 } | 616 } |
622 gtk_widget_queue_draw(widget); | 617 gtk_widget_queue_draw(widget); |
623 } | 618 } |
624 } | 619 } |
625 return TRUE; | 620 return TRUE; |
626 } | 621 } |
627 | 622 |
628 NPError InitializePlugin() { | 623 } // end anonymous namespace |
629 if (!o3d::SetupOutOfMemoryHandler()) | |
630 return NPERR_MODULE_LOAD_FAILED_ERROR; | |
631 | 624 |
| 625 namespace o3d { |
| 626 |
| 627 NPError PlatformPreNPInitialize() { |
| 628 #if !defined(O3D_INTERNAL_PLUGIN) |
632 // Setup breakpad | 629 // Setup breakpad |
633 g_breakpad.Initialize(); | 630 g_breakpad.Initialize(); |
634 g_breakpad.set_version(O3D_PLUGIN_VERSION); | 631 g_breakpad.set_version(O3D_PLUGIN_VERSION); |
| 632 #endif |
| 633 return NPERR_NO_ERROR; |
| 634 } |
635 | 635 |
636 CommandLine::Init(0, NULL); | 636 NPError PlatformPostNPInitialize() { |
637 | |
638 FilePath log; | |
639 file_util::GetTempDir(&log); | |
640 log = log.Append("debug.log"); | |
641 | |
642 InitLogging(log.value().c_str(), | |
643 logging::LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG, | |
644 logging::DONT_LOCK_LOG_FILE, | |
645 logging::APPEND_TO_OLD_LOG_FILE); | |
646 | |
647 DLOG(INFO) << "NP_Initialize"; | |
648 | |
649 #ifdef O3D_PLUGIN_ENV_VARS_FILE | 637 #ifdef O3D_PLUGIN_ENV_VARS_FILE |
650 // Before doing anything more, we first load our environment variables file. | 638 // Before doing anything more, we first load our environment variables file. |
651 // This file is a newline-delimited list of any system-specific environment | 639 // This file is a newline-delimited list of any system-specific environment |
652 // variables that need to be set in the browser. Since we are a shared library | 640 // variables that need to be set in the browser. Since we are a shared library |
653 // and not an executable, we can't set them at browser start time, so we | 641 // and not an executable, we can't set them at browser start time, so we |
654 // instead set them in every process that loads our shared library. It is | 642 // instead set them in every process that loads our shared library. It is |
655 // important that we do this as early as possible so that any relevant | 643 // important that we do this as early as possible so that any relevant |
656 // variables are already set when we initialize our shared library | 644 // variables are already set when we initialize our shared library |
657 // dependencies. | 645 // dependencies. |
658 o3d::LoadEnvironmentVariablesFile(kEnvVarsFilePath); | 646 o3d::LoadEnvironmentVariablesFile(kEnvVarsFilePath); |
(...skipping 14 matching lines...) Expand all Loading... |
673 NPNToolkitType toolkit = static_cast<NPNToolkitType>(0); | 661 NPNToolkitType toolkit = static_cast<NPNToolkitType>(0); |
674 err = NPN_GetValue(NULL, NPNVToolkit, &toolkit); | 662 err = NPN_GetValue(NULL, NPNVToolkit, &toolkit); |
675 if (err != NPERR_NO_ERROR || toolkit != NPNVGtk2) | 663 if (err != NPERR_NO_ERROR || toolkit != NPNVGtk2) |
676 xembed_support = PR_FALSE; | 664 xembed_support = PR_FALSE; |
677 } | 665 } |
678 g_xembed_support = xembed_support != PR_FALSE; | 666 g_xembed_support = xembed_support != PR_FALSE; |
679 | 667 |
680 return NPERR_NO_ERROR; | 668 return NPERR_NO_ERROR; |
681 } | 669 } |
682 | 670 |
683 } // end anonymous namespace | 671 NPError PlatformPreNPShutdown() { |
684 | 672 return NPERR_NO_ERROR; |
685 #if defined(O3D_INTERNAL_PLUGIN) | |
686 namespace o3d { | |
687 #else | |
688 extern "C" { | |
689 #endif | |
690 | |
691 NPError EXPORT_SYMBOL OSCALL NP_Initialize(NPNetscapeFuncs *browserFuncs, | |
692 NPPluginFuncs *pluginFuncs) { | |
693 NPError retval = InitializeNPNApi(browserFuncs); | |
694 if (retval != NPERR_NO_ERROR) return retval; | |
695 NP_GetEntryPoints(pluginFuncs); | |
696 return InitializePlugin(); | |
697 } | 673 } |
698 | 674 |
699 NPError EXPORT_SYMBOL OSCALL NP_Shutdown(void) { | 675 NPError PlatformPostNPShutdown() { |
700 HANDLE_CRASHES; | 676 #if !defined(O3D_INTERNAL_PLUGIN) |
701 DLOG(INFO) << "NP_Shutdown"; | |
702 | |
703 CommandLine::Reset(); | |
704 | |
705 g_breakpad.Shutdown(); | 677 g_breakpad.Shutdown(); |
| 678 #endif |
706 | 679 |
707 return NPERR_NO_ERROR; | 680 return NPERR_NO_ERROR; |
708 } | 681 } |
709 | 682 |
710 } // namespace o3d / extern "C" | 683 NPError PlatformNPPGetValue(PluginObject *obj, |
711 | 684 NPPVariable variable, |
712 namespace o3d { | 685 void *value) { |
713 | |
714 NPError PlatformNPPGetValue(NPP instance, NPPVariable variable, void *value) { | |
715 switch (variable) { | 686 switch (variable) { |
716 case NPPVpluginNeedsXEmbed: | 687 case NPPVpluginNeedsXEmbed: |
717 *static_cast<NPBool *>(value) = g_xembed_support; | 688 *static_cast<NPBool *>(value) = g_xembed_support; |
718 return NPERR_NO_ERROR; | 689 return NPERR_NO_ERROR; |
719 default: | 690 default: |
720 return NPERR_INVALID_PARAM; | 691 return NPERR_INVALID_PARAM; |
721 } | 692 } |
722 return NPERR_NO_ERROR; | 693 return NPERR_NO_ERROR; |
723 } | 694 } |
724 | 695 |
725 NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, | 696 NPError PlatformNPPNew(NPP instance, PluginObject *obj) { |
726 char *argn[], char *argv[], NPSavedData *saved) { | |
727 HANDLE_CRASHES; | |
728 | |
729 if (!IsDomainAuthorized(instance)) { | |
730 return NPERR_INVALID_URL; | |
731 } | |
732 | |
733 PluginObject* pluginObject = glue::_o3d::PluginObject::Create( | |
734 instance); | |
735 instance->pdata = pluginObject; | |
736 glue::_o3d::InitializeGlue(instance); | |
737 pluginObject->Init(argc, argn, argv); | |
738 | |
739 // Get the metrics for the system setup | |
740 GetUserConfigMetrics(); | |
741 return NPERR_NO_ERROR; | 697 return NPERR_NO_ERROR; |
742 } | 698 } |
743 | 699 |
744 NPError NPP_Destroy(NPP instance, NPSavedData **save) { | 700 NPError PlatformNPPDestroy(NPP instance, PluginObject *obj) { |
745 HANDLE_CRASHES; | 701 // TODO(tschmelcher): Do we really have to do this before the other teardown |
746 PluginObject *obj = static_cast<PluginObject*>(instance->pdata); | 702 // below? If not then we can factor out the platform-specific TearDown() |
747 if (obj) { | 703 // calls into NPP_Destroy() in main.cc. |
748 obj->TearDown(); | 704 obj->TearDown(); |
749 | 705 |
750 if (obj->xt_widget_) { | 706 if (obj->xt_widget_) { |
751 // NOTE: This crashes. Not sure why, possibly the widget has | 707 // NOTE: This crashes. Not sure why, possibly the widget has |
752 // already been destroyed, but we haven't received a SetWindow(NULL). | 708 // already been destroyed, but we haven't received a SetWindow(NULL). |
753 // XtRemoveEventHandler(obj->xt_widget_, ExposureMask, False, | 709 // XtRemoveEventHandler(obj->xt_widget_, ExposureMask, False, |
754 // LinuxExposeHandler, obj); | 710 // LinuxExposeHandler, obj); |
755 obj->xt_widget_ = NULL; | 711 obj->xt_widget_ = NULL; |
756 } | |
757 if (obj->xt_interval_) { | |
758 XtRemoveTimeOut(obj->xt_interval_); | |
759 obj->xt_interval_ = 0; | |
760 } | |
761 if (obj->timeout_id_) { | |
762 g_source_remove(obj->timeout_id_); | |
763 obj->timeout_id_ = 0; | |
764 } | |
765 if (obj->gtk_container_) { | |
766 gtk_widget_destroy(obj->gtk_container_); | |
767 obj->gtk_container_ = NULL; | |
768 } | |
769 if (obj->gtk_fullscreen_container_) { | |
770 gtk_widget_destroy(obj->gtk_fullscreen_container_); | |
771 obj->gtk_fullscreen_container_ = NULL; | |
772 } | |
773 if (obj->gdk_display_) { | |
774 gdk_display_close(obj->gdk_display_); | |
775 obj->gdk_display_ = NULL; | |
776 } | |
777 obj->gtk_event_source_ = NULL; | |
778 obj->event_handler_id_ = 0; | |
779 obj->window_ = 0; | |
780 obj->drawable_ = 0; | |
781 | |
782 NPN_ReleaseObject(obj); | |
783 instance->pdata = NULL; | |
784 } | 712 } |
| 713 if (obj->xt_interval_) { |
| 714 XtRemoveTimeOut(obj->xt_interval_); |
| 715 obj->xt_interval_ = 0; |
| 716 } |
| 717 if (obj->timeout_id_) { |
| 718 g_source_remove(obj->timeout_id_); |
| 719 obj->timeout_id_ = 0; |
| 720 } |
| 721 if (obj->gtk_container_) { |
| 722 gtk_widget_destroy(obj->gtk_container_); |
| 723 obj->gtk_container_ = NULL; |
| 724 } |
| 725 if (obj->gtk_fullscreen_container_) { |
| 726 gtk_widget_destroy(obj->gtk_fullscreen_container_); |
| 727 obj->gtk_fullscreen_container_ = NULL; |
| 728 } |
| 729 if (obj->gdk_display_) { |
| 730 gdk_display_close(obj->gdk_display_); |
| 731 obj->gdk_display_ = NULL; |
| 732 } |
| 733 obj->gtk_event_source_ = NULL; |
| 734 obj->event_handler_id_ = 0; |
| 735 obj->window_ = 0; |
| 736 obj->drawable_ = 0; |
785 return NPERR_NO_ERROR; | 737 return NPERR_NO_ERROR; |
786 } | 738 } |
787 | 739 |
788 NPError NPP_SetWindow(NPP instance, NPWindow *window) { | 740 NPError PlatformNPPSetWindow(NPP instance, |
789 HANDLE_CRASHES; | 741 PluginObject *obj, |
790 PluginObject *obj = static_cast<PluginObject*>(instance->pdata); | 742 NPWindow *window) { |
791 | |
792 NPSetWindowCallbackStruct *cb_struct = | 743 NPSetWindowCallbackStruct *cb_struct = |
793 static_cast<NPSetWindowCallbackStruct *>(window->ws_info); | 744 static_cast<NPSetWindowCallbackStruct *>(window->ws_info); |
794 Window xwindow = reinterpret_cast<Window>(window->window); | 745 Window xwindow = reinterpret_cast<Window>(window->window); |
795 if (xwindow != obj->window_) { | 746 if (xwindow != obj->window_) { |
796 Display *display = cb_struct->display; | 747 Display *display = cb_struct->display; |
797 Window drawable = xwindow; | 748 Window drawable = xwindow; |
798 if (g_xembed_support) { | 749 if (g_xembed_support) { |
799 // We asked for a XEmbed plugin, the xwindow is a GtkSocket, we create | 750 // We asked for a XEmbed plugin, the xwindow is a GtkSocket, we create |
800 // a GtkPlug to go into it. | 751 // a GtkPlug to go into it. |
801 obj->gdk_display_ = gdk_display_open(XDisplayString(display)); | 752 obj->gdk_display_ = gdk_display_open(XDisplayString(display)); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
847 obj->client()->Init(); | 798 obj->client()->Init(); |
848 obj->SetDisplay(display); | 799 obj->SetDisplay(display); |
849 obj->window_ = xwindow; | 800 obj->window_ = xwindow; |
850 obj->drawable_ = drawable; | 801 obj->drawable_ = drawable; |
851 } | 802 } |
852 obj->Resize(window->width, window->height); | 803 obj->Resize(window->width, window->height); |
853 | 804 |
854 return NPERR_NO_ERROR; | 805 return NPERR_NO_ERROR; |
855 } | 806 } |
856 | 807 |
857 // Called when the browser has finished attempting to stream data to | 808 void PlatformNPPStreamAsFile(StreamManager *stream_manager, |
858 // a file as requested. If fname == NULL the attempt was not successful. | 809 NPStream *stream, |
859 void NPP_StreamAsFile(NPP instance, NPStream *stream, const char *fname) { | 810 const char *fname) { |
860 HANDLE_CRASHES; | |
861 PluginObject *obj = static_cast<PluginObject*>(instance->pdata); | |
862 StreamManager *stream_manager = obj->stream_manager(); | |
863 | |
864 stream_manager->SetStreamFile(stream, fname); | 811 stream_manager->SetStreamFile(stream, fname); |
865 } | 812 } |
866 | 813 |
867 int16 NPP_HandleEvent(NPP instance, void *event) { | 814 int16 PlatformNPPHandleEvent(NPP instance, PluginObject *obj, void *event) { |
868 HANDLE_CRASHES; | |
869 return 0; | 815 return 0; |
870 } | 816 } |
| 817 |
871 } // namespace o3d | 818 } // namespace o3d |
872 | 819 |
| 820 // TODO(tschmelcher): This stuff does not belong in this file. |
873 namespace glue { | 821 namespace glue { |
874 namespace _o3d { | 822 namespace _o3d { |
875 | 823 |
876 void PluginObject::SetGtkEventSource(GtkWidget *widget) { | 824 void PluginObject::SetGtkEventSource(GtkWidget *widget) { |
877 if (gtk_event_source_) { | 825 if (gtk_event_source_) { |
878 g_signal_handler_disconnect(G_OBJECT(gtk_event_source_), | 826 g_signal_handler_disconnect(G_OBJECT(gtk_event_source_), |
879 event_handler_id_); | 827 event_handler_id_); |
880 } | 828 } |
881 gtk_event_source_ = widget; | 829 gtk_event_source_ = widget; |
882 if (gtk_event_source_) { | 830 if (gtk_event_source_) { |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1008 client()->SendResizeEvent(renderer()->width(), renderer()->height(), | 956 client()->SendResizeEvent(renderer()->width(), renderer()->height(), |
1009 false); | 957 false); |
1010 SetGtkEventSource(gtk_container_); | 958 SetGtkEventSource(gtk_container_); |
1011 gtk_widget_destroy(gtk_fullscreen_container_); | 959 gtk_widget_destroy(gtk_fullscreen_container_); |
1012 gtk_fullscreen_container_ = NULL; | 960 gtk_fullscreen_container_ = NULL; |
1013 fullscreen_window_ = 0; | 961 fullscreen_window_ = 0; |
1014 fullscreen_ = false; | 962 fullscreen_ = false; |
1015 } | 963 } |
1016 } // namespace _o3d | 964 } // namespace _o3d |
1017 } // namespace glue | 965 } // namespace glue |
OLD | NEW |