OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "webkit/glue/plugins/plugin_host.h" | 5 #include "webkit/glue/plugins/plugin_host.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/message_loop.h" | |
9 #include "base/string_util.h" | 8 #include "base/string_util.h" |
10 #include "webkit/default_plugin/default_plugin_shared.h" | 9 #include "webkit/default_plugin/default_plugin_shared.h" |
11 #include "webkit/glue/glue_util.h" | 10 #include "webkit/glue/glue_util.h" |
12 #include "webkit/glue/webplugin.h" | 11 #include "webkit/glue/webplugin.h" |
13 #include "webkit/glue/webkit_glue.h" | 12 #include "webkit/glue/webkit_glue.h" |
14 #include "webkit/glue/plugins/plugin_instance.h" | 13 #include "webkit/glue/plugins/plugin_instance.h" |
15 #include "webkit/glue/plugins/plugin_lib.h" | 14 #include "webkit/glue/plugins/plugin_lib.h" |
16 #include "webkit/glue/plugins/plugin_list.h" | 15 #include "webkit/glue/plugins/plugin_list.h" |
17 #include "webkit/glue/plugins/plugin_stream_url.h" | 16 #include "webkit/glue/plugins/plugin_stream_url.h" |
18 #include "third_party/npapi/bindings/npruntime.h" | 17 #include "third_party/npapi/bindings/npruntime.h" |
19 | 18 |
20 extern "C" { | |
21 | |
22 // FindInstance() | |
23 // Finds a PluginInstance from an NPP. | |
24 // The caller must take a reference if needed. | |
25 NPAPI::PluginInstance* FindInstance(NPP id) { | |
26 if (id == NULL) { | |
27 NOTREACHED(); | |
28 return NULL; | |
29 } | |
30 | |
31 return (NPAPI::PluginInstance *)id->ndata; | |
32 } | |
33 | 19 |
34 namespace NPAPI | 20 namespace NPAPI |
35 { | 21 { |
36 scoped_refptr<PluginHost> PluginHost::singleton_; | 22 scoped_refptr<PluginHost> PluginHost::singleton_; |
37 | 23 |
38 static const int kFlashMessageThrottleDelayMs = 10; | 24 PluginHost::PluginHost() { |
39 | |
40 PluginHost::PluginHost() | |
41 #pragma warning(suppress: 4355) // can use this | |
42 : throttle_factory_(this) { | |
43 InitializeHostFuncs(); | 25 InitializeHostFuncs(); |
44 } | 26 } |
45 | 27 |
46 PluginHost::~PluginHost() { | 28 PluginHost::~PluginHost() { |
47 } | 29 } |
48 | 30 |
49 PluginHost *PluginHost::Singleton() { | 31 PluginHost *PluginHost::Singleton() { |
50 if (singleton_.get() == NULL) { | 32 if (singleton_.get() == NULL) { |
51 singleton_ = new PluginHost(); | 33 singleton_ = new PluginHost(); |
52 } | 34 } |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 if (overrides->hasmethod) | 126 if (overrides->hasmethod) |
145 host_funcs_.hasmethod = overrides->hasmethod; | 127 host_funcs_.hasmethod = overrides->hasmethod; |
146 | 128 |
147 if (overrides->setexception) | 129 if (overrides->setexception) |
148 host_funcs_.setexception = overrides->setexception; | 130 host_funcs_.setexception = overrides->setexception; |
149 | 131 |
150 if (overrides->enumerate) | 132 if (overrides->enumerate) |
151 host_funcs_.enumerate = overrides->enumerate; | 133 host_funcs_.enumerate = overrides->enumerate; |
152 } | 134 } |
153 | 135 |
154 void PluginHost::InvalidateRect(NPP id, NPRect* invalidRect) { | |
155 if (!invalidRect) { | |
156 NOTREACHED(); | |
157 return; | |
158 } | |
159 | |
160 // Invalidates specified drawing area prior to repainting or refreshing a | |
161 // windowless plugin | |
162 | |
163 // Before a windowless plugin can refresh part of its drawing area, it must | |
164 // first invalidate it. This function causes the NPP_HandleEvent method to | |
165 // pass an update event or a paint message to the plug-in. After calling | |
166 // this method, the plug-in recieves a paint message asynchronously. | |
167 | |
168 // The browser redraws invalid areas of the document and any windowless | |
169 // plug-ins at regularly timed intervals. To force a paint message, the | |
170 // plug-in can call NPN_ForceRedraw after calling this method. | |
171 | |
172 scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); | |
173 DCHECK(plugin.get() != NULL); | |
174 | |
175 if (plugin.get() && plugin->webplugin()) { | |
176 if (!plugin->windowless()) { | |
177 RECT rect = {0}; | |
178 rect.left = invalidRect->left; | |
179 rect.right = invalidRect->right; | |
180 rect.top = invalidRect->top; | |
181 rect.bottom = invalidRect->bottom; | |
182 ::InvalidateRect(plugin->window_handle(), &rect, FALSE); | |
183 return; | |
184 } | |
185 | |
186 if (plugin->throttle_invalidate()) { | |
187 // We need to track plugin invalidates on a per instance basis. | |
188 ThrottledInvalidates plugin_instance_invalidates; | |
189 InstanceThrottledInvalidatesMap::iterator invalidate_index = | |
190 instance_throttled_invalidates_.find(id); | |
191 if (invalidate_index != instance_throttled_invalidates_.end()) { | |
192 plugin_instance_invalidates = (*invalidate_index).second; | |
193 } | |
194 | |
195 bool throttle_active = | |
196 (plugin_instance_invalidates.throttled_invalidates.size() > 0); | |
197 | |
198 gfx::Rect rect(invalidRect->left, | |
199 invalidRect->top, | |
200 invalidRect->right - invalidRect->left, | |
201 invalidRect->bottom - invalidRect->top); | |
202 | |
203 plugin_instance_invalidates.throttled_invalidates.push_back(rect); | |
204 | |
205 if (!throttle_active) { | |
206 // We hold a reference to the plugin instance to avoid race conditions | |
207 // due to the instance being released before the OnInvalidateRect | |
208 // function is invoked. | |
209 plugin->AddRef(); | |
210 MessageLoop::current()->PostDelayedTask(FROM_HERE, | |
211 throttle_factory_.NewRunnableMethod(&PluginHost::OnInvalidateRect, | |
212 id, plugin.get()), | |
213 kFlashMessageThrottleDelayMs); | |
214 } | |
215 instance_throttled_invalidates_[id] = plugin_instance_invalidates; | |
216 } else { | |
217 gfx::Rect rect(invalidRect->left, | |
218 invalidRect->top, | |
219 invalidRect->right - invalidRect->left, | |
220 invalidRect->bottom - invalidRect->top); | |
221 plugin->webplugin()->InvalidateRect(rect); | |
222 } | |
223 } | |
224 } | |
225 | |
226 bool PluginHost::SetPostData(const char *buf, | 136 bool PluginHost::SetPostData(const char *buf, |
227 uint32 length, | 137 uint32 length, |
228 std::vector<std::string>* names, | 138 std::vector<std::string>* names, |
229 std::vector<std::string>* values, | 139 std::vector<std::string>* values, |
230 std::vector<char>* body) { | 140 std::vector<char>* body) { |
231 // Use a state table to do the parsing. Whitespace must be | 141 // Use a state table to do the parsing. Whitespace must be |
232 // trimmed after the fact if desired. In our case, we actually | 142 // trimmed after the fact if desired. In our case, we actually |
233 // don't care about the whitespace, because we're just going to | 143 // don't care about the whitespace, because we're just going to |
234 // pass this back into another POST. This function strips out the | 144 // pass this back into another POST. This function strips out the |
235 // "Content-length" header and does not append it to the request. | 145 // "Content-length" header and does not append it to the request. |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 break; | 228 break; |
319 } | 229 } |
320 } | 230 } |
321 state = newstate; | 231 state = newstate; |
322 ptr++; | 232 ptr++; |
323 } while (!done); | 233 } while (!done); |
324 | 234 |
325 return !err; | 235 return !err; |
326 } | 236 } |
327 | 237 |
328 void PluginHost::OnInvalidateRect(NPP id, PluginInstance* instance) { | |
329 if (!instance) { | |
330 NOTREACHED(); | |
331 return; | |
332 } | |
333 | |
334 InstanceThrottledInvalidatesMap::iterator invalidate_index = | |
335 instance_throttled_invalidates_.find(id); | |
336 if (invalidate_index == instance_throttled_invalidates_.end()) { | |
337 NOTREACHED(); | |
338 instance->Release(); | |
339 return; | |
340 } | |
341 | |
342 ThrottledInvalidates plugin_instance_invalidates = | |
343 (*invalidate_index).second; | |
344 | |
345 if (instance->webplugin()) { | |
346 for (unsigned int throttle_index = 0; | |
347 throttle_index < | |
348 plugin_instance_invalidates.throttled_invalidates.size(); | |
349 throttle_index++) { | |
350 instance->webplugin()->InvalidateRect( | |
351 plugin_instance_invalidates.throttled_invalidates[throttle_index]); | |
352 } | |
353 } | |
354 | |
355 instance->Release(); | |
356 instance_throttled_invalidates_.erase(invalidate_index); | |
357 } | |
358 | |
359 } // namespace NPAPI | 238 } // namespace NPAPI |
360 | 239 |
| 240 extern "C" { |
| 241 |
| 242 // FindInstance() |
| 243 // Finds a PluginInstance from an NPP. |
| 244 // The caller must take a reference if needed. |
| 245 NPAPI::PluginInstance* FindInstance(NPP id) { |
| 246 if (id == NULL) { |
| 247 NOTREACHED(); |
| 248 return NULL; |
| 249 } |
| 250 |
| 251 return (NPAPI::PluginInstance *)id->ndata; |
| 252 } |
| 253 |
361 // Allocates memory from the host's memory space. | 254 // Allocates memory from the host's memory space. |
362 void* NPN_MemAlloc(uint32 size) { | 255 void* NPN_MemAlloc(uint32 size) { |
363 scoped_refptr<NPAPI::PluginHost> host = NPAPI::PluginHost::Singleton(); | 256 scoped_refptr<NPAPI::PluginHost> host = NPAPI::PluginHost::Singleton(); |
364 if (host != NULL) { | 257 if (host != NULL) { |
365 // Note: We must use the same allocator/deallocator | 258 // Note: We must use the same allocator/deallocator |
366 // that is used by the javascript library, as some of the | 259 // that is used by the javascript library, as some of the |
367 // JS APIs will pass memory to the plugin which the plugin | 260 // JS APIs will pass memory to the plugin which the plugin |
368 // will attempt to free. | 261 // will attempt to free. |
369 return malloc(size); | 262 return malloc(size); |
370 } | 263 } |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
639 } | 532 } |
640 | 533 |
641 void NPN_Status(NPP id, const char* message) { | 534 void NPN_Status(NPP id, const char* message) { |
642 // Displays a message on the status line of the browser window. | 535 // Displays a message on the status line of the browser window. |
643 | 536 |
644 // TODO: implement me | 537 // TODO: implement me |
645 DLOG(INFO) << "NPN_Status is not implemented yet."; | 538 DLOG(INFO) << "NPN_Status is not implemented yet."; |
646 } | 539 } |
647 | 540 |
648 void NPN_InvalidateRect(NPP id, NPRect *invalidRect) { | 541 void NPN_InvalidateRect(NPP id, NPRect *invalidRect) { |
649 scoped_refptr<NPAPI::PluginHost> host = NPAPI::PluginHost::Singleton(); | 542 // Invalidates specified drawing area prior to repainting or refreshing a |
650 if (host != NULL) { | 543 // windowless plugin |
651 host->InvalidateRect(id, invalidRect); | 544 |
| 545 // Before a windowless plugin can refresh part of its drawing area, it must |
| 546 // first invalidate it. This function causes the NPP_HandleEvent method to |
| 547 // pass an update event or a paint message to the plug-in. After calling |
| 548 // this method, the plug-in recieves a paint message asynchronously. |
| 549 |
| 550 // The browser redraws invalid areas of the document and any windowless |
| 551 // plug-ins at regularly timed intervals. To force a paint message, the |
| 552 // plug-in can call NPN_ForceRedraw after calling this method. |
| 553 |
| 554 scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); |
| 555 DCHECK(plugin.get() != NULL); |
| 556 if (plugin.get() && plugin->webplugin()) { |
| 557 if (invalidRect) { |
| 558 gfx::Rect rect(invalidRect->left, |
| 559 invalidRect->top, |
| 560 invalidRect->right - invalidRect->left, |
| 561 invalidRect->bottom - invalidRect->top); |
| 562 plugin->webplugin()->InvalidateRect(rect); |
| 563 } else { |
| 564 plugin->webplugin()->Invalidate(); |
| 565 } |
652 } | 566 } |
653 } | 567 } |
654 | 568 |
655 void NPN_InvalidateRegion(NPP id, NPRegion invalidRegion) { | 569 void NPN_InvalidateRegion(NPP id, NPRegion invalidRegion) { |
656 // Invalidates a specified drawing region prior to repainting | 570 // Invalidates a specified drawing region prior to repainting |
657 // or refreshing a window-less plugin. | 571 // or refreshing a window-less plugin. |
658 // | 572 // |
659 // Similar to NPN_InvalidateRect. | 573 // Similar to NPN_InvalidateRect. |
660 | 574 |
661 // TODO: implement me | 575 // TODO: implement me |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
875 NPObject* obj, | 789 NPObject* obj, |
876 const NPVariant *args, | 790 const NPVariant *args, |
877 uint32_t argCount, | 791 uint32_t argCount, |
878 NPVariant *result) { | 792 NPVariant *result) { |
879 NOTREACHED(); | 793 NOTREACHED(); |
880 return false; | 794 return false; |
881 } | 795 } |
882 | 796 |
883 } // extern "C" | 797 } // extern "C" |
884 | 798 |
OLD | NEW |