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

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/bind.h" 7 #include "base/bind.h"
8 #include "base/debug/trace_event.h" 8 #include "base/debug/trace_event.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop.h" 11 #include "base/message_loop.h"
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/utf_offset_string_conversions.h"
13 #include "base/utf_string_conversions.h" 14 #include "base/utf_string_conversions.h"
14 #include "ppapi/c/dev/ppb_console_dev.h" 15 #include "ppapi/c/dev/ppb_console_dev.h"
15 #include "ppapi/c/dev/ppb_find_dev.h" 16 #include "ppapi/c/dev/ppb_find_dev.h"
16 #include "ppapi/c/dev/ppb_memory_dev.h" 17 #include "ppapi/c/dev/ppb_memory_dev.h"
17 #include "ppapi/c/dev/ppb_zoom_dev.h" 18 #include "ppapi/c/dev/ppb_zoom_dev.h"
18 #include "ppapi/c/dev/ppp_find_dev.h" 19 #include "ppapi/c/dev/ppp_find_dev.h"
19 #include "ppapi/c/dev/ppp_mouse_lock_dev.h" 20 #include "ppapi/c/dev/ppp_mouse_lock_dev.h"
20 #include "ppapi/c/dev/ppp_policy_update_dev.h" 21 #include "ppapi/c/dev/ppp_policy_update_dev.h"
21 #include "ppapi/c/dev/ppp_selection_dev.h" 22 #include "ppapi/c/dev/ppp_selection_dev.h"
22 #include "ppapi/c/dev/ppp_zoom_dev.h" 23 #include "ppapi/c/dev/ppp_zoom_dev.h"
23 #include "ppapi/c/pp_input_event.h" 24 #include "ppapi/c/pp_input_event.h"
24 #include "ppapi/c/pp_instance.h" 25 #include "ppapi/c/pp_instance.h"
25 #include "ppapi/c/pp_rect.h" 26 #include "ppapi/c/pp_rect.h"
26 #include "ppapi/c/pp_resource.h" 27 #include "ppapi/c/pp_resource.h"
27 #include "ppapi/c/pp_var.h" 28 #include "ppapi/c/pp_var.h"
28 #include "ppapi/c/ppb_core.h" 29 #include "ppapi/c/ppb_core.h"
29 #include "ppapi/c/ppb_instance.h" 30 #include "ppapi/c/ppb_instance.h"
30 #include "ppapi/c/ppp_input_event.h" 31 #include "ppapi/c/ppp_input_event.h"
31 #include "ppapi/c/ppp_instance.h" 32 #include "ppapi/c/ppp_instance.h"
32 #include "ppapi/c/ppp_messaging.h" 33 #include "ppapi/c/ppp_messaging.h"
33 #include "ppapi/c/private/ppb_instance_private.h" 34 #include "ppapi/c/private/ppb_instance_private.h"
34 #include "ppapi/c/private/ppp_instance_private.h" 35 #include "ppapi/c/private/ppp_instance_private.h"
35 #include "ppapi/shared_impl/input_event_impl.h" 36 #include "ppapi/shared_impl/input_event_impl.h"
36 #include "ppapi/shared_impl/resource.h" 37 #include "ppapi/shared_impl/resource.h"
38 #include "ppapi/shared_impl/time_conversion.h"
37 #include "ppapi/shared_impl/url_util_impl.h" 39 #include "ppapi/shared_impl/url_util_impl.h"
38 #include "ppapi/shared_impl/var.h" 40 #include "ppapi/shared_impl/var.h"
39 #include "ppapi/thunk/enter.h" 41 #include "ppapi/thunk/enter.h"
40 #include "ppapi/thunk/ppb_buffer_api.h" 42 #include "ppapi/thunk/ppb_buffer_api.h"
41 #include "printing/units.h" 43 #include "printing/units.h"
42 #include "skia/ext/platform_canvas.h" 44 #include "skia/ext/platform_canvas.h"
43 #include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h" 45 #include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h"
44 #include "third_party/WebKit/Source/WebKit/chromium/public/WebConsoleMessage.h" 46 #include "third_party/WebKit/Source/WebKit/chromium/public/WebConsoleMessage.h"
45 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h" 47 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h"
46 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" 48 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 typedef bool (*RenderPDFPageToDCProc)( 129 typedef bool (*RenderPDFPageToDCProc)(
128 const unsigned char* pdf_buffer, int buffer_size, int page_number, HDC dc, 130 const unsigned char* pdf_buffer, int buffer_size, int page_number, HDC dc,
129 int dpi_x, int dpi_y, int bounds_origin_x, int bounds_origin_y, 131 int dpi_x, int dpi_y, int bounds_origin_x, int bounds_origin_y,
130 int bounds_width, int bounds_height, bool fit_to_bounds, 132 int bounds_width, int bounds_height, bool fit_to_bounds,
131 bool stretch_to_bounds, bool keep_aspect_ratio, bool center_in_bounds, 133 bool stretch_to_bounds, bool keep_aspect_ratio, bool center_in_bounds,
132 bool autorotate); 134 bool autorotate);
133 #endif // defined(OS_WIN) 135 #endif // defined(OS_WIN)
134 136
135 namespace { 137 namespace {
136 138
139 #if !defined(TOUCH_UI)
140 // The default text input type is to regard the plugin always accept text input.
141 // This is for allowing users to use input methods even on completely-IME-
142 // unaware plugins (e.g., PPAPI Flash or PDF plugin for M16).
143 // Plugins need to explicitly opt out the text input mode if they know
144 // that they don't accept texts.
145 const ui::TextInputType kPluginDefaultTextInputType = ui::TEXT_INPUT_TYPE_TEXT;
146 #else
147 // On the other hand, for touch ui, accepting text input implies to pop up
148 // virtual keyboard always. It makes IME-unaware plugins almost unusable,
149 // and hence is disabled by default (codereview.chromium.org/7800044).
150 const ui::TextInputType kPluginDefaultTextInputType = ui::TEXT_INPUT_TYPE_NONE;
151 #endif
152
137 #define COMPILE_ASSERT_MATCHING_ENUM(webkit_name, np_name) \ 153 #define COMPILE_ASSERT_MATCHING_ENUM(webkit_name, np_name) \
138 COMPILE_ASSERT(static_cast<int>(WebCursorInfo::webkit_name) \ 154 COMPILE_ASSERT(static_cast<int>(WebCursorInfo::webkit_name) \
139 == static_cast<int>(np_name), \ 155 == static_cast<int>(np_name), \
140 mismatching_enums) 156 mismatching_enums)
141 157
142 COMPILE_ASSERT_MATCHING_ENUM(TypePointer, PP_CURSORTYPE_POINTER); 158 COMPILE_ASSERT_MATCHING_ENUM(TypePointer, PP_CURSORTYPE_POINTER);
143 COMPILE_ASSERT_MATCHING_ENUM(TypeCross, PP_CURSORTYPE_CROSS); 159 COMPILE_ASSERT_MATCHING_ENUM(TypeCross, PP_CURSORTYPE_CROSS);
144 COMPILE_ASSERT_MATCHING_ENUM(TypeHand, PP_CURSORTYPE_HAND); 160 COMPILE_ASSERT_MATCHING_ENUM(TypeHand, PP_CURSORTYPE_HAND);
145 COMPILE_ASSERT_MATCHING_ENUM(TypeIBeam, PP_CURSORTYPE_IBEAM); 161 COMPILE_ASSERT_MATCHING_ENUM(TypeIBeam, PP_CURSORTYPE_IBEAM);
146 COMPILE_ASSERT_MATCHING_ENUM(TypeWait, PP_CURSORTYPE_WAIT); 162 COMPILE_ASSERT_MATCHING_ENUM(TypeWait, PP_CURSORTYPE_WAIT);
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 plugin_graphics_3d_interface_(NULL), 275 plugin_graphics_3d_interface_(NULL),
260 always_on_top_(false), 276 always_on_top_(false),
261 fullscreen_container_(NULL), 277 fullscreen_container_(NULL),
262 flash_fullscreen_(false), 278 flash_fullscreen_(false),
263 desired_fullscreen_state_(false), 279 desired_fullscreen_state_(false),
264 fullscreen_(false), 280 fullscreen_(false),
265 message_channel_(NULL), 281 message_channel_(NULL),
266 sad_plugin_(NULL), 282 sad_plugin_(NULL),
267 input_event_mask_(0), 283 input_event_mask_(0),
268 filtered_input_event_mask_(0), 284 filtered_input_event_mask_(0),
285 text_input_type_(kPluginDefaultTextInputType),
286 text_input_caret_(0, 0, 0, 0),
287 text_input_caret_bounds_(0, 0, 0, 0),
288 text_input_caret_set_(false),
269 lock_mouse_callback_(PP_BlockUntilComplete()) { 289 lock_mouse_callback_(PP_BlockUntilComplete()) {
270 pp_instance_ = ResourceTracker::Get()->AddInstance(this); 290 pp_instance_ = ResourceTracker::Get()->AddInstance(this);
271 291
272 memset(&current_print_settings_, 0, sizeof(current_print_settings_)); 292 memset(&current_print_settings_, 0, sizeof(current_print_settings_));
273 DCHECK(delegate); 293 DCHECK(delegate);
274 module_->InstanceCreated(this); 294 module_->InstanceCreated(this);
275 delegate_->InstanceCreated(this); 295 delegate_->InstanceCreated(this);
276 message_channel_.reset(new MessageChannel(this)); 296 message_channel_.reset(new MessageChannel(this));
277 } 297 }
278 298
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 argc, 488 argc,
469 argn.get(), 489 argn.get(),
470 argv.get())); 490 argv.get()));
471 } 491 }
472 492
473 bool PluginInstance::HandleDocumentLoad(PPB_URLLoader_Impl* loader) { 493 bool PluginInstance::HandleDocumentLoad(PPB_URLLoader_Impl* loader) {
474 return PP_ToBool(instance_interface_->HandleDocumentLoad( 494 return PP_ToBool(instance_interface_->HandleDocumentLoad(
475 pp_instance(), loader->pp_resource())); 495 pp_instance(), loader->pp_resource()));
476 } 496 }
477 497
498 bool PluginInstance::SendCompositionEventToPlugin(PP_InputEvent_Type type,
499 const string16& text) {
500 std::vector<WebKit::WebCompositionUnderline> empty;
501 return SendCompositionEventWithUnderlineInformationToPlugin(
502 type, text, empty, static_cast<int>(text.size()),
503 static_cast<int>(text.size()));
504 }
505
506 bool PluginInstance::SendCompositionEventWithUnderlineInformationToPlugin(
507 PP_InputEvent_Type type,
508 const string16& text,
509 const std::vector<WebKit::WebCompositionUnderline>& underlines,
510 int selection_start,
511 int selection_end) {
512 // Keep a reference on the stack. See NOTE above.
513 scoped_refptr<PluginInstance> ref(this);
514
515 if (!LoadInputEventInterface())
516 return false;
517
518 PP_InputEvent_Class event_class = PP_INPUTEVENT_CLASS_IME;
519 if (!(filtered_input_event_mask_ & event_class) &&
520 !(input_event_mask_ & event_class))
521 return false;
522
523 ::ppapi::InputEventData event;
524 event.event_type = type;
525 event.event_time_stamp = ::ppapi::TimeTicksToPPTimeTicks(
526 base::TimeTicks::Now());
527
528 // Convert UTF16 text to UTF8 with offset conversion.
529 std::vector<size_t> utf16_offsets;
530 utf16_offsets.push_back(selection_start);
531 utf16_offsets.push_back(selection_end);
532 for (size_t i = 0; i < underlines.size(); ++i) {
533 utf16_offsets.push_back(underlines[i].startOffset);
534 utf16_offsets.push_back(underlines[i].endOffset);
535 }
536 std::vector<size_t> utf8_offsets(utf16_offsets);
537 event.character_text = UTF16ToUTF8AndAdjustOffsets(text, &utf8_offsets);
538
539 // Set the converted selection range.
540 event.composition_selection_start = (utf8_offsets[0] == std::string::npos ?
541 event.character_text.size() : utf8_offsets[0]);
542 event.composition_selection_end = (utf8_offsets[1] == std::string::npos ?
543 event.character_text.size() : utf8_offsets[1]);
544
545 // Set the converted segmentation points.
546 // Be sure to add 0 and size(), and remove duplication or errors.
547 std::set<size_t> offset_set(utf8_offsets.begin()+2, utf8_offsets.end());
548 offset_set.insert(0);
549 offset_set.insert(event.character_text.size());
550 offset_set.erase(std::string::npos);
551 event.composition_segment_offsets.assign(offset_set.begin(),
552 offset_set.end());
553
554 // Set the composition target.
555 for (size_t i = 0; i < underlines.size(); ++i) {
556 if (underlines[i].thick) {
557 std::vector<uint32_t>::iterator it =
558 std::find(event.composition_segment_offsets.begin(),
559 event.composition_segment_offsets.end(),
560 utf8_offsets[2*i+2]);
561 if (it != event.composition_segment_offsets.end()) {
562 event.composition_target_segment =
563 it - event.composition_segment_offsets.begin();
564 break;
565 }
566 }
567 }
568
569 // Send the event.
570 bool handled = false;
571 if (filtered_input_event_mask_ & event_class)
572 event.is_filtered = true;
573 else
574 handled = true; // Unfiltered events are assumed to be handled.
575 scoped_refptr<InputEventImpl> event_resource(
576 new InputEventImpl(InputEventImpl::InitAsImpl(),
577 pp_instance(), event));
578 handled |= PP_ToBool(plugin_input_event_interface_->HandleInputEvent(
579 pp_instance(), event_resource->pp_resource()));
580 return handled;
581 }
582
583 bool PluginInstance::HandleCompositionStart(const string16& text) {
584 return SendCompositionEventToPlugin(PP_INPUTEVENT_TYPE_IME_COMPOSITION_START,
585 text);
586 }
587
588 bool PluginInstance::HandleCompositionUpdate(
589 const string16& text,
590 const std::vector<WebKit::WebCompositionUnderline>& underlines,
591 int selection_start,
592 int selection_end) {
593 return SendCompositionEventWithUnderlineInformationToPlugin(
594 PP_INPUTEVENT_TYPE_IME_COMPOSITION_UPDATE,
595 text, underlines, selection_start, selection_end);
596 }
597
598 bool PluginInstance::HandleCompositionEnd(const string16& text) {
599 return SendCompositionEventToPlugin(PP_INPUTEVENT_TYPE_IME_COMPOSITION_END,
600 text);
601 }
602
603 bool PluginInstance::HandleTextInput(const string16& text) {
604 return SendCompositionEventToPlugin(PP_INPUTEVENT_TYPE_IME_TEXT,
605 text);
606 }
607
608 void PluginInstance::UpdateCaretPosition(const gfx::Rect& caret,
609 const gfx::Rect& bounding_box) {
610 text_input_caret_ = caret;
611 text_input_caret_bounds_ = bounding_box;
612 text_input_caret_set_ = true;
613 }
614
615 void PluginInstance::SetTextInputType(ui::TextInputType type) {
616 text_input_type_ = type;
617 }
618
619 bool PluginInstance::IsPluginAcceptingCompositionEvents() const {
620 return (filtered_input_event_mask_ & PP_INPUTEVENT_CLASS_IME) ||
621 (input_event_mask_ & PP_INPUTEVENT_CLASS_IME);
622 }
623
624 gfx::Rect PluginInstance::GetCaretBounds() const {
625 if (!text_input_caret_set_) {
626 // If it is never set by the plugin, use the bottom left corner.
627 return gfx::Rect(position().x(), position().y()+position().height(), 0, 0);
628 }
629
630 // TODO(kinaba) Take CSS transformation into accont.
631 // TODO(kinaba) Take bounding_box into account. On some platforms, an
632 // "exclude rectangle" where candidate window must avoid the region can be
633 // passed to IME. Currently, we pass only the caret rectangle because
634 // it is the only information supported uniformly in Chromium.
635 gfx::Rect caret(text_input_caret_);
636 caret.Offset(position().origin());
637 return caret;
638 }
639
478 bool PluginInstance::HandleInputEvent(const WebKit::WebInputEvent& event, 640 bool PluginInstance::HandleInputEvent(const WebKit::WebInputEvent& event,
479 WebCursorInfo* cursor_info) { 641 WebCursorInfo* cursor_info) {
480 TRACE_EVENT0("ppapi", "PluginInstance::HandleInputEvent"); 642 TRACE_EVENT0("ppapi", "PluginInstance::HandleInputEvent");
481 643
482 if (WebInputEvent::isMouseEventType(event.type)) 644 if (WebInputEvent::isMouseEventType(event.type))
483 delegate()->DidReceiveMouseEvent(this); 645 delegate()->DidReceiveMouseEvent(this);
484 646
485 // Don't dispatch input events to crashed plugins. 647 // Don't dispatch input events to crashed plugins.
486 if (module()->is_crashed()) 648 if (module()->is_crashed())
487 return false; 649 return false;
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 instance_interface_->DidChangeView(pp_instance(), &pp_position, &pp_clip); 738 instance_interface_->DidChangeView(pp_instance(), &pp_position, &pp_clip);
577 } 739 }
578 740
579 void PluginInstance::SetWebKitFocus(bool has_focus) { 741 void PluginInstance::SetWebKitFocus(bool has_focus) {
580 if (has_webkit_focus_ == has_focus) 742 if (has_webkit_focus_ == has_focus)
581 return; 743 return;
582 744
583 bool old_plugin_focus = PluginHasFocus(); 745 bool old_plugin_focus = PluginHasFocus();
584 has_webkit_focus_ = has_focus; 746 has_webkit_focus_ = has_focus;
585 if (PluginHasFocus() != old_plugin_focus) { 747 if (PluginHasFocus() != old_plugin_focus) {
586 delegate()->PluginFocusChanged(PluginHasFocus()); 748 delegate()->PluginFocusChanged(this, PluginHasFocus());
587 instance_interface_->DidChangeFocus(pp_instance(), 749 instance_interface_->DidChangeFocus(pp_instance(),
588 PP_FromBool(PluginHasFocus())); 750 PP_FromBool(PluginHasFocus()));
589 } 751 }
590 } 752 }
591 753
592 void PluginInstance::SetContentAreaFocus(bool has_focus) { 754 void PluginInstance::SetContentAreaFocus(bool has_focus) {
593 if (has_content_area_focus_ == has_focus) 755 if (has_content_area_focus_ == has_focus)
594 return; 756 return;
595 757
596 bool old_plugin_focus = PluginHasFocus(); 758 bool old_plugin_focus = PluginHasFocus();
(...skipping 1209 matching lines...) Expand 10 before | Expand all | Expand 10 after
1806 } 1968 }
1807 WebKit::WebDocument main_document = 1969 WebKit::WebDocument main_document =
1808 containing_document.frame()->view()->mainFrame()->document(); 1970 containing_document.frame()->view()->mainFrame()->document();
1809 1971
1810 return containing_document.securityOrigin().canAccess( 1972 return containing_document.securityOrigin().canAccess(
1811 main_document.securityOrigin()); 1973 main_document.securityOrigin());
1812 } 1974 }
1813 1975
1814 } // namespace ppapi 1976 } // namespace ppapi
1815 } // namespace webkit 1977 } // namespace webkit
OLDNEW
« no previous file with comments | « webkit/plugins/ppapi/ppapi_plugin_instance.h ('k') | webkit/plugins/ppapi/ppb_text_input_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698