eea0051168e3793f4dba914cedb28dc4d1f902f2
[WebKit-https.git] / WebCore / plugins / gtk / PluginPackageGtk.cpp
1 /*
2  * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
3  * Copyright (C) 2008 Collabora Ltd. All rights reserved.
4  * Copyright (C) 2008 Nuanti Ltd.
5  * Copyright (C) 2008 Novell Inc. All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
20  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
24  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
27  */
28
29 #include "config.h"
30 #include "PluginPackage.h"
31
32 #include <stdio.h>
33
34 #include "CString.h"
35 #include "MIMETypeRegistry.h"
36 #include "NotImplemented.h"
37 #include "npruntime_impl.h"
38 #include "PluginDebug.h"
39
40 namespace WebCore {
41
42 static PlatformModuleVersion getModuleVersion(const char *description)
43 {
44     // It's a bit lame to detect the plugin version by parsing it
45     // from the plugin description string, but it doesn't seem that
46     // version information is available in any standardized way at
47     // the module level, like in Windows
48
49     PlatformModuleVersion version = 0;
50
51     if (!description)
52         return 0;
53
54     if (g_str_has_prefix(description, "Shockwave Flash ") && strlen(description) >= 19) {
55         // The flash version as a PlatformModuleVersion differs in GTK from Windows
56         // since the revision can be larger than a 8 bits, so we allow it 16 here and
57         // push the major/minor up 8 bits. Thus in GTK, Flash's version may be
58         // 0x0a000000 instead of 0x000a0000. This avoids having to modify 
59         // PlatformModuleVersion in the GTK port 
60
61         char **version_parts = g_strsplit(description + 16, " ", -1);
62         if (!version_parts)
63             return 0;
64
65         int parts_length = g_strv_length(version_parts);
66
67         if (parts_length >= 1) {
68             guint16 major = 0, minor = 0;
69             if (sscanf(version_parts[0], "%" G_GUINT16_FORMAT ".%" G_GUINT16_FORMAT, &major, &minor) == 2)
70                 version = ((guint8)major << 24) | ((guint8)minor << 16);
71         }
72
73         if (parts_length >= 2) {
74             char *rev_str = version_parts[1];
75             if (strlen(rev_str) > 1 && (rev_str[0] == 'r' || rev_str[0] == 'b'))
76                 version |= (guint16)atoi(rev_str + 1);
77         }
78         
79         g_strfreev(version_parts);
80     }
81
82     return version;
83 }
84
85 bool PluginPackage::fetchInfo()
86 {
87 #if defined(XP_UNIX)
88     if (!load())
89         return false;
90
91     NP_GetMIMEDescriptionFuncPtr NP_GetMIMEDescription = 0;
92     NPP_GetValueProcPtr NPP_GetValue = 0;
93
94     g_module_symbol(m_module, "NP_GetMIMEDescription", (void**)&NP_GetMIMEDescription);
95     g_module_symbol(m_module, "NP_GetValue", (void**)&NPP_GetValue);
96
97     if (!NP_GetMIMEDescription || !NPP_GetValue)
98         return false;
99
100     char* buffer = 0;
101     NPError err = NPP_GetValue(0, NPPVpluginNameString, &buffer);
102     if (err == NPERR_NO_ERROR)
103         m_name = buffer;
104
105     buffer = 0;
106     err = NPP_GetValue(0, NPPVpluginDescriptionString, &buffer);
107     if (err == NPERR_NO_ERROR) {
108         m_description = buffer;
109         determineModuleVersionFromDescription();
110     }
111
112     const gchar* types = NP_GetMIMEDescription();
113     gchar** mimeDescs = g_strsplit(types, ";", -1);
114     for (int i = 0; mimeDescs[i] && mimeDescs[i][0]; i++) {
115         gchar** mimeData = g_strsplit(mimeDescs[i], ":", 3);
116         if (g_strv_length(mimeData) < 3) {
117             g_strfreev(mimeData);
118             continue;
119         }
120
121         String description = String::fromUTF8(mimeData[2]);
122         gchar** extensions = g_strsplit(mimeData[1], ",", -1);
123
124         Vector<String> extVector;
125         for (int j = 0; extensions[j]; j++)
126             extVector.append(String::fromUTF8(extensions[j]));
127
128         determineQuirks(mimeData[0]);
129         m_mimeToExtensions.add(mimeData[0], extVector);
130         m_mimeToDescriptions.add(mimeData[0], description);
131
132         g_strfreev(extensions);
133         g_strfreev(mimeData);
134     }
135     g_strfreev(mimeDescs);
136
137     return true;
138 #else
139     notImplemented();
140     return false;
141 #endif
142 }
143
144 bool PluginPackage::load()
145 {
146     if (m_isLoaded) {
147         m_loadCount++;
148         return true;
149     }
150
151     m_module = g_module_open((m_path.utf8()).data(), G_MODULE_BIND_LOCAL);
152
153     if (!m_module) {
154         LOG(Plugins,"Module Load Failed :%s, Error:%s\n", (m_path.utf8()).data(), g_module_error());
155         return false;
156     }
157
158     m_isLoaded = true;
159
160     NP_InitializeFuncPtr NP_Initialize = 0;
161     m_NPP_Shutdown = 0;
162
163     NPError npErr;
164
165     g_module_symbol(m_module, "NP_Initialize", (void**)&NP_Initialize);
166     g_module_symbol(m_module, "NP_Shutdown", (void**)&m_NPP_Shutdown);
167
168     if (!NP_Initialize || !m_NPP_Shutdown)
169         goto abort;
170
171     memset(&m_pluginFuncs, 0, sizeof(m_pluginFuncs));
172     m_pluginFuncs.size = sizeof(m_pluginFuncs);
173
174     initializeBrowserFuncs();
175
176 #if defined(XP_UNIX)
177     npErr = NP_Initialize(&m_browserFuncs, &m_pluginFuncs);
178 #else
179     npErr = NP_Initialize(&m_browserFuncs);
180 #endif
181     if (npErr != NPERR_NO_ERROR)
182         goto abort;
183
184     m_loadCount++;
185     return true;
186
187 abort:
188     unloadWithoutShutdown();
189     return false;
190 }
191
192 }