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

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: Incorporated comments from brettw, yzshen, and kochi. 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/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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 // Exported by pdf.dll 124 // Exported by pdf.dll
123 typedef bool (*RenderPDFPageToDCProc)( 125 typedef bool (*RenderPDFPageToDCProc)(
124 const unsigned char* pdf_buffer, int buffer_size, int page_number, HDC dc, 126 const unsigned char* pdf_buffer, int buffer_size, int page_number, HDC dc,
125 int dpi_x, int dpi_y, int bounds_origin_x, int bounds_origin_y, 127 int dpi_x, int dpi_y, int bounds_origin_x, int bounds_origin_y,
126 int bounds_width, int bounds_height, bool fit_to_bounds, 128 int bounds_width, int bounds_height, bool fit_to_bounds,
127 bool stretch_to_bounds, bool keep_aspect_ratio, bool center_in_bounds); 129 bool stretch_to_bounds, bool keep_aspect_ratio, bool center_in_bounds);
128 #endif // defined(OS_WIN) 130 #endif // defined(OS_WIN)
129 131
130 namespace { 132 namespace {
131 133
134 #if !defined(TOUCH_UI)
135 // The default text input type is to regard the plugin always accept text input.
136 // This is for allowing users to use input methods even on completely-IME-
137 // unaware plugins (e.g., PPAPI Flash or PDF plugin for M16).
138 // Plugins need to explicitly opt out the text input mode if they know
139 // that they don't accept texts.
140 const ui::TextInputType kPluginDefaultTextInputType = ui::TEXT_INPUT_TYPE_TEXT;
141 #else
142 // On the other hand, for touch ui, accepting text input implies to pop up
143 // virtual keyboard always. It makes IME-unaware plugins almost unusable,
144 // and hence is disabled by default (codereview.chromium.org/7800044).
145 const ui::TextInputType kPluginDefaultTextInputType = ui::TEXT_INPUT_TYPE_NONE;
146 #endif
147
132 #define COMPILE_ASSERT_MATCHING_ENUM(webkit_name, np_name) \ 148 #define COMPILE_ASSERT_MATCHING_ENUM(webkit_name, np_name) \
133 COMPILE_ASSERT(static_cast<int>(WebCursorInfo::webkit_name) \ 149 COMPILE_ASSERT(static_cast<int>(WebCursorInfo::webkit_name) \
134 == static_cast<int>(np_name), \ 150 == static_cast<int>(np_name), \
135 mismatching_enums) 151 mismatching_enums)
136 152
137 COMPILE_ASSERT_MATCHING_ENUM(TypePointer, PP_CURSORTYPE_POINTER); 153 COMPILE_ASSERT_MATCHING_ENUM(TypePointer, PP_CURSORTYPE_POINTER);
138 COMPILE_ASSERT_MATCHING_ENUM(TypeCross, PP_CURSORTYPE_CROSS); 154 COMPILE_ASSERT_MATCHING_ENUM(TypeCross, PP_CURSORTYPE_CROSS);
139 COMPILE_ASSERT_MATCHING_ENUM(TypeHand, PP_CURSORTYPE_HAND); 155 COMPILE_ASSERT_MATCHING_ENUM(TypeHand, PP_CURSORTYPE_HAND);
140 COMPILE_ASSERT_MATCHING_ENUM(TypeIBeam, PP_CURSORTYPE_IBEAM); 156 COMPILE_ASSERT_MATCHING_ENUM(TypeIBeam, PP_CURSORTYPE_IBEAM);
141 COMPILE_ASSERT_MATCHING_ENUM(TypeWait, PP_CURSORTYPE_WAIT); 157 COMPILE_ASSERT_MATCHING_ENUM(TypeWait, PP_CURSORTYPE_WAIT);
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 plugin_graphics_3d_interface_(NULL), 255 plugin_graphics_3d_interface_(NULL),
240 always_on_top_(false), 256 always_on_top_(false),
241 fullscreen_container_(NULL), 257 fullscreen_container_(NULL),
242 flash_fullscreen_(false), 258 flash_fullscreen_(false),
243 desired_fullscreen_state_(false), 259 desired_fullscreen_state_(false),
244 fullscreen_(false), 260 fullscreen_(false),
245 message_channel_(NULL), 261 message_channel_(NULL),
246 sad_plugin_(NULL), 262 sad_plugin_(NULL),
247 input_event_mask_(0), 263 input_event_mask_(0),
248 filtered_input_event_mask_(0), 264 filtered_input_event_mask_(0),
265 text_input_type_(kPluginDefaultTextInputType),
266 text_input_caret_(0, 0, 0, 0),
267 text_input_caret_bounds_(0, 0, 0, 0),
268 text_input_caret_set_(false),
249 lock_mouse_callback_(PP_BlockUntilComplete()) { 269 lock_mouse_callback_(PP_BlockUntilComplete()) {
250 pp_instance_ = ResourceTracker::Get()->AddInstance(this); 270 pp_instance_ = ResourceTracker::Get()->AddInstance(this);
251 271
252 memset(&current_print_settings_, 0, sizeof(current_print_settings_)); 272 memset(&current_print_settings_, 0, sizeof(current_print_settings_));
253 DCHECK(delegate); 273 DCHECK(delegate);
254 module_->InstanceCreated(this); 274 module_->InstanceCreated(this);
255 delegate_->InstanceCreated(this); 275 delegate_->InstanceCreated(this);
256 message_channel_.reset(new MessageChannel(this)); 276 message_channel_.reset(new MessageChannel(this));
257 } 277 }
258 278
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 argc, 463 argc,
444 argn.get(), 464 argn.get(),
445 argv.get())); 465 argv.get()));
446 } 466 }
447 467
448 bool PluginInstance::HandleDocumentLoad(PPB_URLLoader_Impl* loader) { 468 bool PluginInstance::HandleDocumentLoad(PPB_URLLoader_Impl* loader) {
449 return PP_ToBool(instance_interface_->HandleDocumentLoad( 469 return PP_ToBool(instance_interface_->HandleDocumentLoad(
450 pp_instance(), loader->pp_resource())); 470 pp_instance(), loader->pp_resource()));
451 } 471 }
452 472
473 bool PluginInstance::SendCompositionEventToPlugin(PP_InputEvent_Type type,
474 const string16& text) {
475 std::vector<WebKit::WebCompositionUnderline> empty;
476 return SendCompositionEventWithUnderlineInformationToPlugin(
477 type, text, empty, static_cast<int>(text.size()),
478 static_cast<int>(text.size()));
479 }
480
481 bool PluginInstance::SendCompositionEventWithUnderlineInformationToPlugin(
482 PP_InputEvent_Type type,
483 const string16& text,
484 const std::vector<WebKit::WebCompositionUnderline>& underlines,
485 int selection_start,
486 int selection_end) {
487 // Keep a reference on the stack. See NOTE above.
488 scoped_refptr<PluginInstance> ref(this);
489
490 if (!LoadInputEventInterface())
491 return false;
492
493 PP_InputEvent_Class event_class = PP_INPUTEVENT_CLASS_IME;
494 if (!(filtered_input_event_mask_ & event_class) &&
495 !(input_event_mask_ & event_class))
496 return false;
497
498 ::ppapi::InputEventData event;
499 event.event_type = type;
500 event.event_time_stamp = ::ppapi::TimeTicksToPPTimeTicks(
501 base::TimeTicks::Now());
502
503 // Convert UTF16 text to UTF8 with offset conversion.
504 std::vector<size_t> utf16_offsets;
505 utf16_offsets.push_back(selection_start);
506 utf16_offsets.push_back(selection_end);
507 for (size_t i = 0; i < underlines.size(); ++i) {
508 utf16_offsets.push_back(underlines[i].startOffset);
509 utf16_offsets.push_back(underlines[i].endOffset);
510 }
511 std::vector<size_t> utf8_offsets(utf16_offsets);
512 event.character_text = UTF16ToUTF8AndAdjustOffsets(text, &utf8_offsets);
513
514 // Set the converted selection range.
515 event.composition_selection_start = (utf8_offsets[0] == std::string::npos ?
516 event.character_text.size() : utf8_offsets[0]);
517 event.composition_selection_end = (utf8_offsets[1] == std::string::npos ?
518 event.character_text.size() : utf8_offsets[1]);
519
520 // Set the converted segmentation points.
521 // Be sure to add 0 and size(), and remove duplication or errors.
522 std::set<size_t> offset_set(utf8_offsets.begin()+2, utf8_offsets.end());
523 offset_set.insert(0);
524 offset_set.insert(event.character_text.size());
525 offset_set.erase(std::string::npos);
526 event.composition_segment_offsets.assign(offset_set.begin(),
527 offset_set.end());
528
529 // Set the composition target.
530 for (size_t i = 0; i < underlines.size(); ++i) {
531 if (underlines[i].thick) {
532 std::vector<uint32_t>::iterator it =
533 std::find(event.composition_segment_offsets.begin(),
534 event.composition_segment_offsets.end(),
535 utf8_offsets[2*i+2]);
536 if (it != event.composition_segment_offsets.end()) {
537 event.composition_target_segment =
538 it - event.composition_segment_offsets.begin();
539 break;
540 }
541 }
542 }
543
544 // Send the event.
545 bool handled = false;
546 if (filtered_input_event_mask_ & event_class)
547 event.is_filtered = true;
548 else
549 handled = true; // Unfiltered events are assumed to be handled.
550 scoped_refptr<InputEventImpl> event_resource(
551 new InputEventImpl(InputEventImpl::InitAsImpl(),
552 pp_instance(), event));
553 handled |= PP_ToBool(plugin_input_event_interface_->HandleInputEvent(
554 pp_instance(), event_resource->pp_resource()));
555 return handled;
556 }
557
558 bool PluginInstance::HandleCompositionStart(const string16& text) {
559 return SendCompositionEventToPlugin(PP_INPUTEVENT_TYPE_IME_COMPOSITION_START,
560 text);
561 }
562
563 bool PluginInstance::HandleCompositionUpdate(
564 const string16& text,
565 const std::vector<WebKit::WebCompositionUnderline>& underlines,
566 int selection_start,
567 int selection_end) {
568 return SendCompositionEventWithUnderlineInformationToPlugin(
569 PP_INPUTEVENT_TYPE_IME_COMPOSITION_UPDATE,
570 text, underlines, selection_start, selection_end);
571 }
572
573 bool PluginInstance::HandleCompositionEnd(const string16& text) {
574 return SendCompositionEventToPlugin(PP_INPUTEVENT_TYPE_IME_COMPOSITION_END,
575 text);
576 }
577
578 bool PluginInstance::HandleTextInput(const string16& text) {
579 return SendCompositionEventToPlugin(PP_INPUTEVENT_TYPE_IME_TEXT,
580 text);
581 }
582
583 void PluginInstance::UpdateCaretPosition(const gfx::Rect& caret,
584 const gfx::Rect& bounding_box) {
585 text_input_caret_ = caret;
586 text_input_caret_bounds_ = bounding_box;
587 text_input_caret_set_ = true;
588 }
589
590 void PluginInstance::SetTextInputType(ui::TextInputType type) {
591 text_input_type_ = type;
592 }
593
594 bool PluginInstance::IsPluginAcceptingCompositionEvents() const {
595 return (filtered_input_event_mask_ & PP_INPUTEVENT_CLASS_IME) ||
596 (input_event_mask_ & PP_INPUTEVENT_CLASS_IME);
597 }
598
599 gfx::Rect PluginInstance::GetCaretBounds() const {
600 if (!text_input_caret_set_) {
601 // If it is never set by the plugin, use the bottom left corner.
602 return gfx::Rect(position().x(), position().y()+position().height(), 0, 0);
603 }
604
605 // TODO(kinaba) Take CSS transformation into accont.
606 // TODO(kinaba) Take bounding_box into account. On some platforms, an
607 // "exclude rectangle" where candidate window must avoid the region can be
608 // passed to IME. Currently, we pass only the caret rectangle because
609 // it is the only information supported uniformly in Chromium.
610 gfx::Rect caret(text_input_caret_);
611 caret.Offset(position().origin());
612 return caret;
613 }
614
453 bool PluginInstance::HandleInputEvent(const WebKit::WebInputEvent& event, 615 bool PluginInstance::HandleInputEvent(const WebKit::WebInputEvent& event,
454 WebCursorInfo* cursor_info) { 616 WebCursorInfo* cursor_info) {
455 // Don't dispatch input events to crashed plugins. 617 // Don't dispatch input events to crashed plugins.
456 if (module()->is_crashed()) 618 if (module()->is_crashed())
457 return false; 619 return false;
458 620
459 // Keep a reference on the stack. See NOTE above. 621 // Keep a reference on the stack. See NOTE above.
460 scoped_refptr<PluginInstance> ref(this); 622 scoped_refptr<PluginInstance> ref(this);
461 623
462 bool rv = false; 624 bool rv = false;
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 instance_interface_->DidChangeView(pp_instance(), &pp_position, &pp_clip); 707 instance_interface_->DidChangeView(pp_instance(), &pp_position, &pp_clip);
546 } 708 }
547 709
548 void PluginInstance::SetWebKitFocus(bool has_focus) { 710 void PluginInstance::SetWebKitFocus(bool has_focus) {
549 if (has_webkit_focus_ == has_focus) 711 if (has_webkit_focus_ == has_focus)
550 return; 712 return;
551 713
552 bool old_plugin_focus = PluginHasFocus(); 714 bool old_plugin_focus = PluginHasFocus();
553 has_webkit_focus_ = has_focus; 715 has_webkit_focus_ = has_focus;
554 if (PluginHasFocus() != old_plugin_focus) { 716 if (PluginHasFocus() != old_plugin_focus) {
555 delegate()->PluginFocusChanged(PluginHasFocus()); 717 delegate()->PluginFocusChanged(this, PluginHasFocus());
556 instance_interface_->DidChangeFocus(pp_instance(), 718 instance_interface_->DidChangeFocus(pp_instance(),
557 PP_FromBool(PluginHasFocus())); 719 PP_FromBool(PluginHasFocus()));
558 } 720 }
559 } 721 }
560 722
561 void PluginInstance::SetContentAreaFocus(bool has_focus) { 723 void PluginInstance::SetContentAreaFocus(bool has_focus) {
562 if (has_content_area_focus_ == has_focus) 724 if (has_content_area_focus_ == has_focus)
563 return; 725 return;
564 726
565 bool old_plugin_focus = PluginHasFocus(); 727 bool old_plugin_focus = PluginHasFocus();
(...skipping 1102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1668 } 1830 }
1669 1831
1670 void PluginInstance::DoSetCursor(WebCursorInfo* cursor) { 1832 void PluginInstance::DoSetCursor(WebCursorInfo* cursor) {
1671 cursor_.reset(cursor); 1833 cursor_.reset(cursor);
1672 if (fullscreen_container_) 1834 if (fullscreen_container_)
1673 fullscreen_container_->DidChangeCursor(*cursor); 1835 fullscreen_container_->DidChangeCursor(*cursor);
1674 } 1836 }
1675 1837
1676 } // namespace ppapi 1838 } // namespace ppapi
1677 } // namespace webkit 1839 } // namespace webkit
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698