| 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 |