OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/plugins/ppapi/ppapi_plugin_instance.h" | 5 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
11 #include "base/utf_offset_string_conversions.h" | |
11 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
12 #include "ppapi/c/dev/ppb_console_dev.h" | 13 #include "ppapi/c/dev/ppb_console_dev.h" |
13 #include "ppapi/c/dev/ppb_find_dev.h" | 14 #include "ppapi/c/dev/ppb_find_dev.h" |
14 #include "ppapi/c/dev/ppb_memory_dev.h" | 15 #include "ppapi/c/dev/ppb_memory_dev.h" |
15 #include "ppapi/c/dev/ppb_zoom_dev.h" | 16 #include "ppapi/c/dev/ppb_zoom_dev.h" |
16 #include "ppapi/c/dev/ppp_find_dev.h" | 17 #include "ppapi/c/dev/ppp_find_dev.h" |
17 #include "ppapi/c/dev/ppp_mouse_lock_dev.h" | 18 #include "ppapi/c/dev/ppp_mouse_lock_dev.h" |
18 #include "ppapi/c/dev/ppp_policy_update_dev.h" | 19 #include "ppapi/c/dev/ppp_policy_update_dev.h" |
19 #include "ppapi/c/dev/ppp_selection_dev.h" | 20 #include "ppapi/c/dev/ppp_selection_dev.h" |
20 #include "ppapi/c/dev/ppp_zoom_dev.h" | 21 #include "ppapi/c/dev/ppp_zoom_dev.h" |
21 #include "ppapi/c/pp_input_event.h" | 22 #include "ppapi/c/pp_input_event.h" |
22 #include "ppapi/c/pp_instance.h" | 23 #include "ppapi/c/pp_instance.h" |
23 #include "ppapi/c/pp_rect.h" | 24 #include "ppapi/c/pp_rect.h" |
24 #include "ppapi/c/pp_resource.h" | 25 #include "ppapi/c/pp_resource.h" |
25 #include "ppapi/c/pp_var.h" | 26 #include "ppapi/c/pp_var.h" |
26 #include "ppapi/c/ppb_core.h" | 27 #include "ppapi/c/ppb_core.h" |
27 #include "ppapi/c/ppb_instance.h" | 28 #include "ppapi/c/ppb_instance.h" |
28 #include "ppapi/c/ppp_input_event.h" | 29 #include "ppapi/c/ppp_input_event.h" |
29 #include "ppapi/c/ppp_instance.h" | 30 #include "ppapi/c/ppp_instance.h" |
30 #include "ppapi/c/ppp_messaging.h" | 31 #include "ppapi/c/ppp_messaging.h" |
31 #include "ppapi/c/private/ppb_instance_private.h" | 32 #include "ppapi/c/private/ppb_instance_private.h" |
32 #include "ppapi/c/private/ppp_instance_private.h" | 33 #include "ppapi/c/private/ppp_instance_private.h" |
33 #include "ppapi/shared_impl/input_event_impl.h" | 34 #include "ppapi/shared_impl/input_event_impl.h" |
34 #include "ppapi/shared_impl/resource.h" | 35 #include "ppapi/shared_impl/resource.h" |
36 #include "ppapi/shared_impl/time_conversion.h" | |
35 #include "ppapi/shared_impl/var.h" | 37 #include "ppapi/shared_impl/var.h" |
36 #include "ppapi/thunk/enter.h" | 38 #include "ppapi/thunk/enter.h" |
37 #include "ppapi/thunk/ppb_buffer_api.h" | 39 #include "ppapi/thunk/ppb_buffer_api.h" |
38 #include "printing/units.h" | 40 #include "printing/units.h" |
39 #include "skia/ext/platform_canvas.h" | 41 #include "skia/ext/platform_canvas.h" |
40 #include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h" | 42 #include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h" |
41 #include "third_party/WebKit/Source/WebKit/chromium/public/WebConsoleMessage.h" | 43 #include "third_party/WebKit/Source/WebKit/chromium/public/WebConsoleMessage.h" |
42 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h" | 44 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h" |
43 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" | 45 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" |
44 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" | 46 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
239 plugin_graphics_3d_interface_(NULL), | 241 plugin_graphics_3d_interface_(NULL), |
240 always_on_top_(false), | 242 always_on_top_(false), |
241 fullscreen_container_(NULL), | 243 fullscreen_container_(NULL), |
242 flash_fullscreen_(false), | 244 flash_fullscreen_(false), |
243 desired_fullscreen_state_(false), | 245 desired_fullscreen_state_(false), |
244 fullscreen_(false), | 246 fullscreen_(false), |
245 message_channel_(NULL), | 247 message_channel_(NULL), |
246 sad_plugin_(NULL), | 248 sad_plugin_(NULL), |
247 input_event_mask_(0), | 249 input_event_mask_(0), |
248 filtered_input_event_mask_(0), | 250 filtered_input_event_mask_(0), |
251 #if !defined(TOUCH_UI) | |
brettw
2011/10/03 16:46:01
I think having these ifdefs and comments in the in
kinaba
2011/10/05 04:43:19
Done. It now looks much better, thanks!
| |
252 // The default mode is to regard the plugin always accept text input. | |
253 // This is for allowing users to use input methods even on completely-IME- | |
254 // unaware plugins (e.g., PPAPI Flash or PDF plugin for M16). | |
255 // Plugins need to explicitly opt out the text input mode if they know | |
256 // that they don't accept texts. | |
257 text_input_type_(ui::TEXT_INPUT_TYPE_TEXT), | |
258 #else | |
259 // On the other hand, for touch ui, accepting text input implies to pop up | |
260 // virtual keyboard always. It makes IME-unaware plugins almost unusable, | |
261 // and hence is disabled by default (codereview.chromium.org/7800044). | |
262 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), | |
263 #endif | |
264 text_input_caret_(0,0,0,0), | |
brettw
2011/10/03 16:46:01
Can you put spaces after the commas?
kinaba
2011/10/05 04:43:19
Done.
| |
265 text_input_caret_bounds_(0,0,0,0), | |
266 text_input_caret_set_(false), | |
249 lock_mouse_callback_(PP_BlockUntilComplete()) { | 267 lock_mouse_callback_(PP_BlockUntilComplete()) { |
250 pp_instance_ = ResourceTracker::Get()->AddInstance(this); | 268 pp_instance_ = ResourceTracker::Get()->AddInstance(this); |
251 | 269 |
252 memset(¤t_print_settings_, 0, sizeof(current_print_settings_)); | 270 memset(¤t_print_settings_, 0, sizeof(current_print_settings_)); |
253 DCHECK(delegate); | 271 DCHECK(delegate); |
254 module_->InstanceCreated(this); | 272 module_->InstanceCreated(this); |
255 delegate_->InstanceCreated(this); | 273 delegate_->InstanceCreated(this); |
256 message_channel_.reset(new MessageChannel(this)); | 274 message_channel_.reset(new MessageChannel(this)); |
257 } | 275 } |
258 | 276 |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
443 argc, | 461 argc, |
444 argn.get(), | 462 argn.get(), |
445 argv.get())); | 463 argv.get())); |
446 } | 464 } |
447 | 465 |
448 bool PluginInstance::HandleDocumentLoad(PPB_URLLoader_Impl* loader) { | 466 bool PluginInstance::HandleDocumentLoad(PPB_URLLoader_Impl* loader) { |
449 return PP_ToBool(instance_interface_->HandleDocumentLoad( | 467 return PP_ToBool(instance_interface_->HandleDocumentLoad( |
450 pp_instance(), loader->pp_resource())); | 468 pp_instance(), loader->pp_resource())); |
451 } | 469 } |
452 | 470 |
471 bool PluginInstance::SendCompositionEventToPlugin(PP_InputEvent_Type type, | |
472 const string16& text) { | |
473 std::vector<WebKit::WebCompositionUnderline> empty; | |
474 return SendCompositionEventWithUnderlineInformationToPlugin( | |
475 type, text, empty, static_cast<int>(text.size()), | |
476 static_cast<int>(text.size())); | |
477 } | |
478 | |
479 bool PluginInstance::SendCompositionEventWithUnderlineInformationToPlugin( | |
480 PP_InputEvent_Type type, | |
481 const string16& text, | |
482 const std::vector<WebKit::WebCompositionUnderline>& underlines, | |
483 int selection_start, | |
484 int selection_end) { | |
485 // Keep a reference on the stack. See NOTE above. | |
486 scoped_refptr<PluginInstance> ref(this); | |
487 | |
488 if (!LoadInputEventInterface()) | |
489 return false; | |
490 | |
491 PP_InputEvent_Class event_class = PP_INPUTEVENT_CLASS_IME; | |
492 if (!(filtered_input_event_mask_ & event_class) && | |
493 !(input_event_mask_ & event_class)) | |
494 return false; | |
495 | |
496 ::ppapi::InputEventData event; | |
497 event.event_type = type; | |
498 event.event_time_stamp = ::ppapi::TimeTicksToPPTimeTicks( | |
499 base::TimeTicks::Now()); | |
500 | |
501 // Convert UTF16 text to UTF8 with offset conversion. | |
502 std::vector<size_t> utf16_offsets; | |
503 utf16_offsets.push_back(selection_start); | |
504 utf16_offsets.push_back(selection_end); | |
505 for (size_t i=0; i<underlines.size(); ++i) { | |
brettw
2011/10/03 16:46:01
Can you put spaces around the = and < (same in the
kinaba
2011/10/05 04:43:19
Done.
| |
506 utf16_offsets.push_back(underlines[i].startOffset); | |
507 utf16_offsets.push_back(underlines[i].endOffset); | |
508 } | |
509 std::vector<size_t> utf8_offsets(utf16_offsets); | |
510 event.character_text = UTF16ToUTF8AndAdjustOffsets(text, &utf8_offsets); | |
511 | |
512 // Set the converted selection range. | |
513 event.composition_selection_start = (utf8_offsets[0]==std::string::npos ? | |
brettw
2011/10/03 16:46:01
Spaces around the == (same below)
kinaba
2011/10/05 04:43:19
Done.
| |
514 event.character_text.size() : utf8_offsets[0]); | |
515 event.composition_selection_end = (utf8_offsets[1]==std::string::npos ? | |
516 event.character_text.size() : utf8_offsets[1]); | |
517 | |
518 // Set the converted segmentation points. | |
519 // Be sure to add 0 and size(), and remove duplication or errors. | |
520 std::set<size_t> offset_set(utf8_offsets.begin()+2, utf8_offsets.end()); | |
521 offset_set.insert(0); | |
522 offset_set.insert(event.character_text.size()); | |
523 offset_set.erase(std::string::npos); | |
524 event.composition_segment_offsets.assign(offset_set.begin(), | |
525 offset_set.end()); | |
526 | |
527 // Set the composition target. | |
528 for (size_t i=0; i<underlines.size(); ++i) { | |
529 if (underlines[i].thick) { | |
530 std::vector<uint32_t>::iterator it = | |
531 std::find(event.composition_segment_offsets.begin(), | |
532 event.composition_segment_offsets.end(), | |
533 utf8_offsets[2*i+2]); | |
534 if (it != event.composition_segment_offsets.end()) { | |
535 event.composition_target_segment = | |
536 it - event.composition_segment_offsets.begin(); | |
537 break; | |
538 } | |
539 } | |
540 } | |
541 | |
542 // Send the event. | |
543 if (filtered_input_event_mask_ & event_class) | |
544 event.is_filtered = true; | |
545 scoped_refptr<InputEventImpl> event_resource( | |
546 new InputEventImpl(InputEventImpl::InitAsImpl(), | |
547 pp_instance(), event)); | |
548 return PP_ToBool(plugin_input_event_interface_->HandleInputEvent( | |
brettw
2011/10/03 16:46:01
Can you make it always return true if the event is
kinaba
2011/10/05 04:43:19
Done.
| |
549 pp_instance(), event_resource->pp_resource())); | |
550 } | |
551 | |
552 bool PluginInstance::HandleCompositionStart(const string16& text) { | |
553 return SendCompositionEventToPlugin(PP_INPUTEVENT_TYPE_IME_COMPOSITION_START, | |
554 text); | |
555 } | |
556 | |
557 bool PluginInstance::HandleCompositionUpdate( | |
558 const string16& text, | |
559 const std::vector<WebKit::WebCompositionUnderline>& underlines, | |
560 int selection_start, | |
561 int selection_end) { | |
562 return SendCompositionEventWithUnderlineInformationToPlugin( | |
563 PP_INPUTEVENT_TYPE_IME_COMPOSITION_UPDATE, | |
564 text, underlines, selection_start, selection_end); | |
565 } | |
566 | |
567 bool PluginInstance::HandleCompositionEnd(const string16& text) { | |
568 return SendCompositionEventToPlugin(PP_INPUTEVENT_TYPE_IME_COMPOSITION_END, | |
569 text); | |
570 } | |
571 | |
572 bool PluginInstance::HandleTextInput(const string16& text) { | |
573 return SendCompositionEventToPlugin(PP_INPUTEVENT_TYPE_IME_TEXT, | |
574 text); | |
575 } | |
576 | |
577 void PluginInstance::UpdateCaretPosition(const gfx::Rect& caret, | |
578 const gfx::Rect& bounding_box) { | |
579 text_input_caret_ = caret; | |
580 text_input_caret_bounds_ = bounding_box; | |
581 text_input_caret_set_ = true; | |
582 } | |
583 | |
584 void PluginInstance::SetTextInputType(ui::TextInputType type) { | |
585 text_input_type_ = type; | |
586 } | |
587 | |
588 bool PluginInstance::IsPluginAcceptingCompositionEvents() const { | |
589 return (filtered_input_event_mask_ & PP_INPUTEVENT_CLASS_IME) || | |
590 (input_event_mask_ & PP_INPUTEVENT_CLASS_IME); | |
591 } | |
592 | |
593 gfx::Rect PluginInstance::GetCaretBounds() const { | |
594 if (!text_input_caret_set_) { | |
595 // If it is never set by the plugin, use the bottom left corner. | |
596 return gfx::Rect(position().x(), position().y()+position().height(), 0, 0); | |
597 } | |
598 | |
599 // TODO(kinaba) Take CSS transformation into accont. | |
600 // TODO(kinaba) Take bounding_box into account. On some platforms, an | |
601 // "exclude rectangle" where candidate window must avoid the region can be | |
602 // passed to IME. Currently, we pass only the caret rectangle because | |
603 // it is the only information supported uniformly in Chromium. | |
604 gfx::Rect caret(text_input_caret_); | |
605 caret.Offset(position().origin()); | |
606 return caret; | |
607 } | |
608 | |
453 bool PluginInstance::HandleInputEvent(const WebKit::WebInputEvent& event, | 609 bool PluginInstance::HandleInputEvent(const WebKit::WebInputEvent& event, |
454 WebCursorInfo* cursor_info) { | 610 WebCursorInfo* cursor_info) { |
455 // Don't dispatch input events to crashed plugins. | 611 // Don't dispatch input events to crashed plugins. |
456 if (module()->is_crashed()) | 612 if (module()->is_crashed()) |
457 return false; | 613 return false; |
458 | 614 |
459 // Keep a reference on the stack. See NOTE above. | 615 // Keep a reference on the stack. See NOTE above. |
460 scoped_refptr<PluginInstance> ref(this); | 616 scoped_refptr<PluginInstance> ref(this); |
461 | 617 |
462 bool rv = false; | 618 bool rv = false; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
545 instance_interface_->DidChangeView(pp_instance(), &pp_position, &pp_clip); | 701 instance_interface_->DidChangeView(pp_instance(), &pp_position, &pp_clip); |
546 } | 702 } |
547 | 703 |
548 void PluginInstance::SetWebKitFocus(bool has_focus) { | 704 void PluginInstance::SetWebKitFocus(bool has_focus) { |
549 if (has_webkit_focus_ == has_focus) | 705 if (has_webkit_focus_ == has_focus) |
550 return; | 706 return; |
551 | 707 |
552 bool old_plugin_focus = PluginHasFocus(); | 708 bool old_plugin_focus = PluginHasFocus(); |
553 has_webkit_focus_ = has_focus; | 709 has_webkit_focus_ = has_focus; |
554 if (PluginHasFocus() != old_plugin_focus) { | 710 if (PluginHasFocus() != old_plugin_focus) { |
555 delegate()->PluginFocusChanged(PluginHasFocus()); | 711 delegate()->PluginFocusChanged(this, PluginHasFocus()); |
556 instance_interface_->DidChangeFocus(pp_instance(), | 712 instance_interface_->DidChangeFocus(pp_instance(), |
557 PP_FromBool(PluginHasFocus())); | 713 PP_FromBool(PluginHasFocus())); |
558 } | 714 } |
559 } | 715 } |
560 | 716 |
561 void PluginInstance::SetContentAreaFocus(bool has_focus) { | 717 void PluginInstance::SetContentAreaFocus(bool has_focus) { |
562 if (has_content_area_focus_ == has_focus) | 718 if (has_content_area_focus_ == has_focus) |
563 return; | 719 return; |
564 | 720 |
565 bool old_plugin_focus = PluginHasFocus(); | 721 bool old_plugin_focus = PluginHasFocus(); |
(...skipping 1102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1668 } | 1824 } |
1669 | 1825 |
1670 void PluginInstance::DoSetCursor(WebCursorInfo* cursor) { | 1826 void PluginInstance::DoSetCursor(WebCursorInfo* cursor) { |
1671 cursor_.reset(cursor); | 1827 cursor_.reset(cursor); |
1672 if (fullscreen_container_) | 1828 if (fullscreen_container_) |
1673 fullscreen_container_->DidChangeCursor(*cursor); | 1829 fullscreen_container_->DidChangeCursor(*cursor); |
1674 } | 1830 } |
1675 | 1831 |
1676 } // namespace ppapi | 1832 } // namespace ppapi |
1677 } // namespace webkit | 1833 } // namespace webkit |
OLD | NEW |