Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: webkit/plugins/ppapi/ppapi_plugin_instance.cc

Issue 8073021: Implement Pepper IME API. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merge trunk. Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/debug/trace_event.h" 7 #include "base/debug/trace_event.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
11 #include "base/metrics/histogram.h" 11 #include "base/metrics/histogram.h"
12 #include "base/utf_offset_string_conversions.h"
12 #include "base/utf_string_conversions.h" 13 #include "base/utf_string_conversions.h"
13 #include "ppapi/c/dev/ppb_console_dev.h" 14 #include "ppapi/c/dev/ppb_console_dev.h"
14 #include "ppapi/c/dev/ppb_find_dev.h" 15 #include "ppapi/c/dev/ppb_find_dev.h"
15 #include "ppapi/c/dev/ppb_memory_dev.h" 16 #include "ppapi/c/dev/ppb_memory_dev.h"
16 #include "ppapi/c/dev/ppb_zoom_dev.h" 17 #include "ppapi/c/dev/ppb_zoom_dev.h"
17 #include "ppapi/c/dev/ppp_find_dev.h" 18 #include "ppapi/c/dev/ppp_find_dev.h"
18 #include "ppapi/c/dev/ppp_mouse_lock_dev.h" 19 #include "ppapi/c/dev/ppp_mouse_lock_dev.h"
19 #include "ppapi/c/dev/ppp_policy_update_dev.h" 20 #include "ppapi/c/dev/ppp_policy_update_dev.h"
20 #include "ppapi/c/dev/ppp_selection_dev.h" 21 #include "ppapi/c/dev/ppp_selection_dev.h"
21 #include "ppapi/c/dev/ppp_zoom_dev.h" 22 #include "ppapi/c/dev/ppp_zoom_dev.h"
22 #include "ppapi/c/pp_input_event.h" 23 #include "ppapi/c/pp_input_event.h"
23 #include "ppapi/c/pp_instance.h" 24 #include "ppapi/c/pp_instance.h"
24 #include "ppapi/c/pp_rect.h" 25 #include "ppapi/c/pp_rect.h"
25 #include "ppapi/c/pp_resource.h" 26 #include "ppapi/c/pp_resource.h"
26 #include "ppapi/c/pp_var.h" 27 #include "ppapi/c/pp_var.h"
27 #include "ppapi/c/ppb_core.h" 28 #include "ppapi/c/ppb_core.h"
28 #include "ppapi/c/ppb_instance.h" 29 #include "ppapi/c/ppb_instance.h"
29 #include "ppapi/c/ppp_input_event.h" 30 #include "ppapi/c/ppp_input_event.h"
30 #include "ppapi/c/ppp_instance.h" 31 #include "ppapi/c/ppp_instance.h"
31 #include "ppapi/c/ppp_messaging.h" 32 #include "ppapi/c/ppp_messaging.h"
32 #include "ppapi/c/private/ppb_instance_private.h" 33 #include "ppapi/c/private/ppb_instance_private.h"
33 #include "ppapi/c/private/ppp_instance_private.h" 34 #include "ppapi/c/private/ppp_instance_private.h"
34 #include "ppapi/shared_impl/input_event_impl.h" 35 #include "ppapi/shared_impl/input_event_impl.h"
35 #include "ppapi/shared_impl/resource.h" 36 #include "ppapi/shared_impl/resource.h"
37 #include "ppapi/shared_impl/time_conversion.h"
36 #include "ppapi/shared_impl/var.h" 38 #include "ppapi/shared_impl/var.h"
37 #include "ppapi/thunk/enter.h" 39 #include "ppapi/thunk/enter.h"
38 #include "ppapi/thunk/ppb_buffer_api.h" 40 #include "ppapi/thunk/ppb_buffer_api.h"
39 #include "printing/units.h" 41 #include "printing/units.h"
40 #include "skia/ext/platform_canvas.h" 42 #include "skia/ext/platform_canvas.h"
41 #include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h" 43 #include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h"
42 #include "third_party/WebKit/Source/WebKit/chromium/public/WebConsoleMessage.h" 44 #include "third_party/WebKit/Source/WebKit/chromium/public/WebConsoleMessage.h"
43 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h" 45 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h"
44 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" 46 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
45 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" 47 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 // Exported by pdf.dll 126 // Exported by pdf.dll
125 typedef bool (*RenderPDFPageToDCProc)( 127 typedef bool (*RenderPDFPageToDCProc)(
126 const unsigned char* pdf_buffer, int buffer_size, int page_number, HDC dc, 128 const unsigned char* pdf_buffer, int buffer_size, int page_number, HDC dc,
127 int dpi_x, int dpi_y, int bounds_origin_x, int bounds_origin_y, 129 int dpi_x, int dpi_y, int bounds_origin_x, int bounds_origin_y,
128 int bounds_width, int bounds_height, bool fit_to_bounds, 130 int bounds_width, int bounds_height, bool fit_to_bounds,
129 bool stretch_to_bounds, bool keep_aspect_ratio, bool center_in_bounds); 131 bool stretch_to_bounds, bool keep_aspect_ratio, bool center_in_bounds);
130 #endif // defined(OS_WIN) 132 #endif // defined(OS_WIN)
131 133
132 namespace { 134 namespace {
133 135
136 #if !defined(TOUCH_UI)
137 // The default text input type is to regard the plugin always accept text input.
138 // This is for allowing users to use input methods even on completely-IME-
139 // unaware plugins (e.g., PPAPI Flash or PDF plugin for M16).
140 // Plugins need to explicitly opt out the text input mode if they know
141 // that they don't accept texts.
142 const ui::TextInputType kPluginDefaultTextInputType = ui::TEXT_INPUT_TYPE_TEXT;
143 #else
144 // On the other hand, for touch ui, accepting text input implies to pop up
145 // virtual keyboard always. It makes IME-unaware plugins almost unusable,
146 // and hence is disabled by default (codereview.chromium.org/7800044).
147 const ui::TextInputType kPluginDefaultTextInputType = ui::TEXT_INPUT_TYPE_NONE;
148 #endif
149
134 #define COMPILE_ASSERT_MATCHING_ENUM(webkit_name, np_name) \ 150 #define COMPILE_ASSERT_MATCHING_ENUM(webkit_name, np_name) \
135 COMPILE_ASSERT(static_cast<int>(WebCursorInfo::webkit_name) \ 151 COMPILE_ASSERT(static_cast<int>(WebCursorInfo::webkit_name) \
136 == static_cast<int>(np_name), \ 152 == static_cast<int>(np_name), \
137 mismatching_enums) 153 mismatching_enums)
138 154
139 COMPILE_ASSERT_MATCHING_ENUM(TypePointer, PP_CURSORTYPE_POINTER); 155 COMPILE_ASSERT_MATCHING_ENUM(TypePointer, PP_CURSORTYPE_POINTER);
140 COMPILE_ASSERT_MATCHING_ENUM(TypeCross, PP_CURSORTYPE_CROSS); 156 COMPILE_ASSERT_MATCHING_ENUM(TypeCross, PP_CURSORTYPE_CROSS);
141 COMPILE_ASSERT_MATCHING_ENUM(TypeHand, PP_CURSORTYPE_HAND); 157 COMPILE_ASSERT_MATCHING_ENUM(TypeHand, PP_CURSORTYPE_HAND);
142 COMPILE_ASSERT_MATCHING_ENUM(TypeIBeam, PP_CURSORTYPE_IBEAM); 158 COMPILE_ASSERT_MATCHING_ENUM(TypeIBeam, PP_CURSORTYPE_IBEAM);
143 COMPILE_ASSERT_MATCHING_ENUM(TypeWait, PP_CURSORTYPE_WAIT); 159 COMPILE_ASSERT_MATCHING_ENUM(TypeWait, PP_CURSORTYPE_WAIT);
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 plugin_graphics_3d_interface_(NULL), 257 plugin_graphics_3d_interface_(NULL),
242 always_on_top_(false), 258 always_on_top_(false),
243 fullscreen_container_(NULL), 259 fullscreen_container_(NULL),
244 flash_fullscreen_(false), 260 flash_fullscreen_(false),
245 desired_fullscreen_state_(false), 261 desired_fullscreen_state_(false),
246 fullscreen_(false), 262 fullscreen_(false),
247 message_channel_(NULL), 263 message_channel_(NULL),
248 sad_plugin_(NULL), 264 sad_plugin_(NULL),
249 input_event_mask_(0), 265 input_event_mask_(0),
250 filtered_input_event_mask_(0), 266 filtered_input_event_mask_(0),
267 text_input_type_(kPluginDefaultTextInputType),
268 text_input_caret_(0, 0, 0, 0),
269 text_input_caret_bounds_(0, 0, 0, 0),
270 text_input_caret_set_(false),
251 lock_mouse_callback_(PP_BlockUntilComplete()) { 271 lock_mouse_callback_(PP_BlockUntilComplete()) {
252 pp_instance_ = ResourceTracker::Get()->AddInstance(this); 272 pp_instance_ = ResourceTracker::Get()->AddInstance(this);
253 273
254 memset(&current_print_settings_, 0, sizeof(current_print_settings_)); 274 memset(&current_print_settings_, 0, sizeof(current_print_settings_));
255 DCHECK(delegate); 275 DCHECK(delegate);
256 module_->InstanceCreated(this); 276 module_->InstanceCreated(this);
257 delegate_->InstanceCreated(this); 277 delegate_->InstanceCreated(this);
258 message_channel_.reset(new MessageChannel(this)); 278 message_channel_.reset(new MessageChannel(this));
259 } 279 }
260 280
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 argc, 468 argc,
449 argn.get(), 469 argn.get(),
450 argv.get())); 470 argv.get()));
451 } 471 }
452 472
453 bool PluginInstance::HandleDocumentLoad(PPB_URLLoader_Impl* loader) { 473 bool PluginInstance::HandleDocumentLoad(PPB_URLLoader_Impl* loader) {
454 return PP_ToBool(instance_interface_->HandleDocumentLoad( 474 return PP_ToBool(instance_interface_->HandleDocumentLoad(
455 pp_instance(), loader->pp_resource())); 475 pp_instance(), loader->pp_resource()));
456 } 476 }
457 477
478 bool PluginInstance::SendCompositionEventToPlugin(PP_InputEvent_Type type,
479 const string16& text) {
480 std::vector<WebKit::WebCompositionUnderline> empty;
481 return SendCompositionEventWithUnderlineInformationToPlugin(
482 type, text, empty, static_cast<int>(text.size()),
483 static_cast<int>(text.size()));
484 }
485
486 bool PluginInstance::SendCompositionEventWithUnderlineInformationToPlugin(
487 PP_InputEvent_Type type,
488 const string16& text,
489 const std::vector<WebKit::WebCompositionUnderline>& underlines,
490 int selection_start,
491 int selection_end) {
492 // Keep a reference on the stack. See NOTE above.
493 scoped_refptr<PluginInstance> ref(this);
494
495 if (!LoadInputEventInterface())
496 return false;
497
498 PP_InputEvent_Class event_class = PP_INPUTEVENT_CLASS_IME;
499 if (!(filtered_input_event_mask_ & event_class) &&
500 !(input_event_mask_ & event_class))
501 return false;
502
503 ::ppapi::InputEventData event;
504 event.event_type = type;
505 event.event_time_stamp = ::ppapi::TimeTicksToPPTimeTicks(
506 base::TimeTicks::Now());
507
508 // Convert UTF16 text to UTF8 with offset conversion.
509 std::vector<size_t> utf16_offsets;
510 utf16_offsets.push_back(selection_start);
511 utf16_offsets.push_back(selection_end);
512 for (size_t i = 0; i < underlines.size(); ++i) {
513 utf16_offsets.push_back(underlines[i].startOffset);
514 utf16_offsets.push_back(underlines[i].endOffset);
515 }
516 std::vector<size_t> utf8_offsets(utf16_offsets);
517 event.character_text = UTF16ToUTF8AndAdjustOffsets(text, &utf8_offsets);
518
519 // Set the converted selection range.
520 event.composition_selection_start = (utf8_offsets[0] == std::string::npos ?
521 event.character_text.size() : utf8_offsets[0]);
522 event.composition_selection_end = (utf8_offsets[1] == std::string::npos ?
523 event.character_text.size() : utf8_offsets[1]);
524
525 // Set the converted segmentation points.
526 // Be sure to add 0 and size(), and remove duplication or errors.
527 std::set<size_t> offset_set(utf8_offsets.begin()+2, utf8_offsets.end());
528 offset_set.insert(0);
529 offset_set.insert(event.character_text.size());
530 offset_set.erase(std::string::npos);
531 event.composition_segment_offsets.assign(offset_set.begin(),
532 offset_set.end());
533
534 // Set the composition target.
535 for (size_t i = 0; i < underlines.size(); ++i) {
536 if (underlines[i].thick) {
537 std::vector<uint32_t>::iterator it =
538 std::find(event.composition_segment_offsets.begin(),
539 event.composition_segment_offsets.end(),
540 utf8_offsets[2*i+2]);
541 if (it != event.composition_segment_offsets.end()) {
542 event.composition_target_segment =
543 it - event.composition_segment_offsets.begin();
544 break;
545 }
546 }
547 }
548
549 // Send the event.
550 bool handled = false;
551 if (filtered_input_event_mask_ & event_class)
552 event.is_filtered = true;
553 else
554 handled = true; // Unfiltered events are assumed to be handled.
555 scoped_refptr<InputEventImpl> event_resource(
556 new InputEventImpl(InputEventImpl::InitAsImpl(),
557 pp_instance(), event));
558 handled |= PP_ToBool(plugin_input_event_interface_->HandleInputEvent(
559 pp_instance(), event_resource->pp_resource()));
560 return handled;
561 }
562
563 bool PluginInstance::HandleCompositionStart(const string16& text) {
564 return SendCompositionEventToPlugin(PP_INPUTEVENT_TYPE_IME_COMPOSITION_START,
565 text);
566 }
567
568 bool PluginInstance::HandleCompositionUpdate(
569 const string16& text,
570 const std::vector<WebKit::WebCompositionUnderline>& underlines,
571 int selection_start,
572 int selection_end) {
573 return SendCompositionEventWithUnderlineInformationToPlugin(
574 PP_INPUTEVENT_TYPE_IME_COMPOSITION_UPDATE,
575 text, underlines, selection_start, selection_end);
576 }
577
578 bool PluginInstance::HandleCompositionEnd(const string16& text) {
579 return SendCompositionEventToPlugin(PP_INPUTEVENT_TYPE_IME_COMPOSITION_END,
580 text);
581 }
582
583 bool PluginInstance::HandleTextInput(const string16& text) {
584 return SendCompositionEventToPlugin(PP_INPUTEVENT_TYPE_IME_TEXT,
585 text);
586 }
587
588 void PluginInstance::UpdateCaretPosition(const gfx::Rect& caret,
589 const gfx::Rect& bounding_box) {
590 text_input_caret_ = caret;
591 text_input_caret_bounds_ = bounding_box;
592 text_input_caret_set_ = true;
593 }
594
595 void PluginInstance::SetTextInputType(ui::TextInputType type) {
596 text_input_type_ = type;
597 }
598
599 bool PluginInstance::IsPluginAcceptingCompositionEvents() const {
600 return (filtered_input_event_mask_ & PP_INPUTEVENT_CLASS_IME) ||
601 (input_event_mask_ & PP_INPUTEVENT_CLASS_IME);
602 }
603
604 gfx::Rect PluginInstance::GetCaretBounds() const {
605 if (!text_input_caret_set_) {
606 // If it is never set by the plugin, use the bottom left corner.
607 return gfx::Rect(position().x(), position().y()+position().height(), 0, 0);
608 }
609
610 // TODO(kinaba) Take CSS transformation into accont.
611 // TODO(kinaba) Take bounding_box into account. On some platforms, an
612 // "exclude rectangle" where candidate window must avoid the region can be
613 // passed to IME. Currently, we pass only the caret rectangle because
614 // it is the only information supported uniformly in Chromium.
615 gfx::Rect caret(text_input_caret_);
616 caret.Offset(position().origin());
617 return caret;
618 }
619
458 bool PluginInstance::HandleInputEvent(const WebKit::WebInputEvent& event, 620 bool PluginInstance::HandleInputEvent(const WebKit::WebInputEvent& event,
459 WebCursorInfo* cursor_info) { 621 WebCursorInfo* cursor_info) {
460 TRACE_EVENT0("ppapi", "PluginInstance::HandleInputEvent"); 622 TRACE_EVENT0("ppapi", "PluginInstance::HandleInputEvent");
461 // Don't dispatch input events to crashed plugins. 623 // Don't dispatch input events to crashed plugins.
462 if (module()->is_crashed()) 624 if (module()->is_crashed())
463 return false; 625 return false;
464 626
465 // Keep a reference on the stack. See NOTE above. 627 // Keep a reference on the stack. See NOTE above.
466 scoped_refptr<PluginInstance> ref(this); 628 scoped_refptr<PluginInstance> ref(this);
467 629
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 instance_interface_->DidChangeView(pp_instance(), &pp_position, &pp_clip); 714 instance_interface_->DidChangeView(pp_instance(), &pp_position, &pp_clip);
553 } 715 }
554 716
555 void PluginInstance::SetWebKitFocus(bool has_focus) { 717 void PluginInstance::SetWebKitFocus(bool has_focus) {
556 if (has_webkit_focus_ == has_focus) 718 if (has_webkit_focus_ == has_focus)
557 return; 719 return;
558 720
559 bool old_plugin_focus = PluginHasFocus(); 721 bool old_plugin_focus = PluginHasFocus();
560 has_webkit_focus_ = has_focus; 722 has_webkit_focus_ = has_focus;
561 if (PluginHasFocus() != old_plugin_focus) { 723 if (PluginHasFocus() != old_plugin_focus) {
562 delegate()->PluginFocusChanged(PluginHasFocus()); 724 delegate()->PluginFocusChanged(this, PluginHasFocus());
563 instance_interface_->DidChangeFocus(pp_instance(), 725 instance_interface_->DidChangeFocus(pp_instance(),
564 PP_FromBool(PluginHasFocus())); 726 PP_FromBool(PluginHasFocus()));
565 } 727 }
566 } 728 }
567 729
568 void PluginInstance::SetContentAreaFocus(bool has_focus) { 730 void PluginInstance::SetContentAreaFocus(bool has_focus) {
569 if (has_content_area_focus_ == has_focus) 731 if (has_content_area_focus_ == has_focus)
570 return; 732 return;
571 733
572 bool old_plugin_focus = PluginHasFocus(); 734 bool old_plugin_focus = PluginHasFocus();
(...skipping 1142 matching lines...) Expand 10 before | Expand all | Expand 10 after
1715 } 1877 }
1716 WebKit::WebDocument main_document = 1878 WebKit::WebDocument main_document =
1717 containing_document.frame()->view()->mainFrame()->document(); 1879 containing_document.frame()->view()->mainFrame()->document();
1718 1880
1719 return containing_document.securityOrigin().canAccess( 1881 return containing_document.securityOrigin().canAccess(
1720 main_document.securityOrigin()); 1882 main_document.securityOrigin());
1721 } 1883 }
1722 1884
1723 } // namespace ppapi 1885 } // namespace ppapi
1724 } // namespace webkit 1886 } // namespace webkit
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698