b60a5363e3f72e06f2c46cd6e2cfbc43f9d99882
[WebKit-https.git] / Source / WebKit2 / Shared / Plugins / Netscape / x11 / NetscapePluginModuleX11.cpp
1 /*
2  * Copyright (C) 2010 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #if PLUGIN_ARCHITECTURE(X11)
28
29 #include "NetscapePluginModule.h"
30
31 #include "NetscapeBrowserFuncs.h"
32 #include <WebCore/FileSystem.h>
33
34 #if PLATFORM(QT)
35 #include <QLibrary>
36 #endif
37
38 #include <fcntl.h>
39 #include <sys/stat.h>
40 #include <sys/types.h>
41 #include <unistd.h>
42
43 using namespace WebCore;
44
45 namespace WebKit {
46
47 class StdoutDevNullRedirector {
48 public:
49     StdoutDevNullRedirector();
50     ~StdoutDevNullRedirector();
51
52 private:
53     int m_savedStdout;
54 };
55
56 StdoutDevNullRedirector::StdoutDevNullRedirector()
57     : m_savedStdout(-1)
58 {
59     int newStdout = open("/dev/null", O_WRONLY);
60     if (newStdout == -1)
61         return;
62     m_savedStdout = dup(STDOUT_FILENO);
63     dup2(newStdout, STDOUT_FILENO);
64 }
65
66 StdoutDevNullRedirector::~StdoutDevNullRedirector()
67 {
68     if (m_savedStdout != -1)
69         dup2(m_savedStdout, STDOUT_FILENO);
70 }
71
72 #if PLATFORM(QT)
73 static void initializeGTK()
74 {
75     QLibrary library(QLatin1String("libgtk-x11-2.0.so.0"));
76     if (library.load()) {
77         typedef void *(*gtk_init_check_ptr)(int*, char***);
78         gtk_init_check_ptr gtkInitCheck = reinterpret_cast<gtk_init_check_ptr>(library.resolve("gtk_init_check"));
79         // NOTE: We're using gtk_init_check() since gtk_init() calls exit() on failure.
80         if (gtkInitCheck)
81             (void) gtkInitCheck(0, 0);
82     }
83 }
84 #endif
85
86 void NetscapePluginModule::applyX11QuirksBeforeLoad()
87 {
88 #if PLATFORM(QT)
89     if (m_pluginPath.contains("npwrapper") || m_pluginPath.contains("flashplayer")) {
90         initializeGTK();
91         m_pluginQuirks.add(PluginQuirks::RequiresGTKToolKit);
92     }
93 #endif
94 }
95
96 void NetscapePluginModule::setMIMEDescription(const String& mimeDescription, PluginModuleInfo& plugin)
97 {
98     Vector<String> types;
99     mimeDescription.lower().split(UChar(';'), false, types);
100     plugin.info.mimes.reserveCapacity(types.size());
101
102     size_t mimeInfoCount = 0;
103     for (size_t i = 0; i < types.size(); ++i) {
104         Vector<String> mimeTypeParts;
105         types[i].split(UChar(':'), true, mimeTypeParts);
106         if (mimeTypeParts.size() <= 0)
107             continue;
108
109         plugin.info.mimes.uncheckedAppend(MimeClassInfo());
110         MimeClassInfo& mimeInfo = plugin.info.mimes[mimeInfoCount++];
111         mimeInfo.type = mimeTypeParts[0];
112
113         if (mimeTypeParts.size() > 1)
114             mimeTypeParts[1].split(UChar(','), false, mimeInfo.extensions);
115
116         if (mimeTypeParts.size() > 2)
117             mimeInfo.desc = mimeTypeParts[2];
118     }
119 }
120
121 bool NetscapePluginModule::getPluginInfo(const String& pluginPath, PluginModuleInfo& plugin)
122 {
123     // Tempararily suppress stdout in this function as plugins will be loaded and shutdown and debug info
124     // is leaked to layout test output.
125     StdoutDevNullRedirector stdoutDevNullRedirector;
126
127     // We are loading the plugin here since it does not seem to be a standardized way to
128     // get the needed informations from a UNIX plugin without loading it.
129     RefPtr<NetscapePluginModule> pluginModule = NetscapePluginModule::getOrCreate(pluginPath);
130     if (!pluginModule)
131         return false;
132
133     pluginModule->incrementLoadCount();
134
135     plugin.path = pluginPath;
136     plugin.info.file = pathGetFileName(pluginPath);
137
138     Module* module = pluginModule->module();
139     NPP_GetValueProcPtr NPP_GetValue = module->functionPointer<NPP_GetValueProcPtr>("NP_GetValue");
140     if (!NPP_GetValue) {
141         pluginModule->decrementLoadCount();
142         return false;
143     }
144
145     NP_GetMIMEDescriptionFuncPtr NP_GetMIMEDescription = module->functionPointer<NP_GetMIMEDescriptionFuncPtr>("NP_GetMIMEDescription");
146     if (!NP_GetMIMEDescription) {
147         pluginModule->decrementLoadCount();
148         return false;
149     }
150
151     char* buffer;
152     NPError error = NPP_GetValue(0, NPPVpluginNameString, &buffer);
153     if (error == NPERR_NO_ERROR)
154         plugin.info.name = buffer;
155
156     error = NPP_GetValue(0, NPPVpluginDescriptionString, &buffer);
157     if (error == NPERR_NO_ERROR)
158         plugin.info.desc = buffer;
159
160     const char* mimeDescription = NP_GetMIMEDescription();
161     if (!mimeDescription) {
162         pluginModule->decrementLoadCount();
163         return false;
164     }
165
166     setMIMEDescription(mimeDescription, plugin);
167
168     pluginModule->decrementLoadCount();
169
170     return true;
171 }
172
173 void NetscapePluginModule::determineQuirks()
174 {
175 }
176
177 } // namespace WebKit
178
179 #endif // PLUGIN_ARCHITECTURE(X11)