WIP: implement Linux IME support
diff --git a/mojo/services/native_viewport/interfaces/native_viewport.mojom b/mojo/services/native_viewport/interfaces/native_viewport.mojom index 3465414..99e2bad 100644 --- a/mojo/services/native_viewport/interfaces/native_viewport.mojom +++ b/mojo/services/native_viewport/interfaces/native_viewport.mojom
@@ -34,6 +34,7 @@ Close(); SetSize(Size size); SetEventDispatcher(NativeViewportEventDispatcher dispatcher); + SetKeyEventDispatcher(NativeViewportEventDispatcher dispatcher); // Requests a ContextProvider capable of producing contexts that draw to // this native viewport.
diff --git a/services/BUILD.gn b/services/BUILD.gn index 0321fe7..e7b815d 100644 --- a/services/BUILD.gn +++ b/services/BUILD.gn
@@ -41,6 +41,12 @@ } } + if (is_linux) { + deps += [ + "//services/keyboard", + ] + } + if (is_linux && !is_fnl) { deps += [ "//services/python" ] }
diff --git a/services/keyboard/BUILD.gn b/services/keyboard/BUILD.gn index a6b73fb..e3242cb 100644 --- a/services/keyboard/BUILD.gn +++ b/services/keyboard/BUILD.gn
@@ -2,19 +2,43 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//build/config/android/config.gni") -import("//build/config/android/rules.gni") +if (is_android) { + import("//build/config/android/config.gni") + import("//build/config/android/rules.gni") -android_library("keyboard") { - java_files = [ - "src/org/chromium/mojo/keyboard/InputConnectionAdaptor.java", - "src/org/chromium/mojo/keyboard/KeyboardServiceImpl.java", - "src/org/chromium/mojo/keyboard/KeyboardServiceState.java", - ] + android_library("keyboard") { + java_files = [ + "src/org/chromium/mojo/keyboard/InputConnectionAdaptor.java", + "src/org/chromium/mojo/keyboard/KeyboardServiceImpl.java", + "src/org/chromium/mojo/keyboard/KeyboardServiceState.java", + ] - deps = [ - "//mojo/public/java:bindings", - "//mojo/public/java:system", - "//mojo/services/keyboard/interfaces:interfaces_java", - ] + deps = [ + "//mojo/public/java:bindings", + "//mojo/public/java:system", + "//mojo/services/keyboard/interfaces:interfaces_java", + ] + } +} + +if (is_linux) { + import("//mojo/public/mojo_application.gni") + + mojo_native_application("keyboard") { + sources = [ + "linux/main.cc", + "linux/keyboard_service_impl.cc", + ] + + deps = [ + "//base", + "//mojo/application", + "//mojo/public/cpp/application", + "//mojo/public/cpp/bindings:callback", + "//mojo/public/cpp/system", + "//mojo/services/keyboard/interfaces", + "//mojo/services/native_viewport/interfaces", + "//mojo/services/native_viewport/cpp:args", + ] + } }
diff --git a/services/keyboard/linux/keyboard_service_impl.cc b/services/keyboard/linux/keyboard_service_impl.cc new file mode 100644 index 0000000..8b004c0 --- /dev/null +++ b/services/keyboard/linux/keyboard_service_impl.cc
@@ -0,0 +1,114 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "services/keyboard/linux/keyboard_service_impl.h" + +#include "base/logging.h" +#include "base/strings/string16.h" +#include "base/strings/utf_string_conversions.h" +#include "mojo/public/cpp/application/application_connection.h" +#include "mojo/public/cpp/application/connect.h" +#include "mojo/services/input_events/interfaces/input_key_codes.mojom.h" + +namespace keyboard { + +LinuxKeyboardServiceImpl::LinuxKeyboardServiceImpl( + mojo::InterfaceRequest<::keyboard::KeyboardService> request, + mojo::Shell* shell, + mojo::ApplicationConnection* connection) + : shell_(shell), connection_(connection), + binding_(this, request.Pass()), + event_dispatcher_binding_(this), + client_(nullptr) { + // Connect IME to provided client + mojo::NativeViewportPtr viewport_service_; + connection_->ConnectToService(&viewport_service_); + + if (!viewport_service_) { + mojo::ServiceProviderPtr viewport_service_provider; + shell_->ConnectToApplication("mojo:native_viewport_service", + mojo::GetProxy(&viewport_service_provider), + nullptr); + mojo::ConnectToService(viewport_service_provider.get(), &viewport_service_); + } + + if (viewport_service_) { + mojo::NativeViewportEventDispatcherPtr dispatcher; + event_dispatcher_binding_.Bind(GetProxy(&dispatcher)); + viewport_service_->SetKeyEventDispatcher(dispatcher.Pass()); + } + +} + +LinuxKeyboardServiceImpl::~LinuxKeyboardServiceImpl() { +} + +void LinuxKeyboardServiceImpl::Show(::keyboard::KeyboardClientPtr client, + ::keyboard::KeyboardType type) { + client_ = client.Pass(); +} + +void LinuxKeyboardServiceImpl::ShowByRequest() { +} + +void LinuxKeyboardServiceImpl::Hide() { + client_ = nullptr; +} + +void LinuxKeyboardServiceImpl::SetText(const mojo::String&) { + // Not applicable for physical keyboards +} + +void LinuxKeyboardServiceImpl::SetSelection(int32_t start, int32_t end) { + // Not applicable for physical keyboards +} + +/* + void commitCompletion(CompletionData completion); + void commitCorrection(CorrectionData correction); + void commitText(String text, int newCursorPosition); + void deleteSurroundingText(int beforeLength, int afterLength); + void setComposingRegion(int start, int end); + void setComposingText(String text, int newCursorPosition); + void setSelection(int start, int end); + void submit(SubmitAction action); +*/ + +// |mojo::NativeViewportEventDispatcher| implementation: +void LinuxKeyboardServiceImpl::OnEvent(mojo::EventPtr event, + const mojo::Callback<void()>& callback) { + if (event->action == mojo::EventType::KEY_PRESSED && event->key_data->is_char) { + if (client_ != nullptr) { + switch(event->key_data->windows_key_code) { + case mojo::KeyboardCode::BACK: // backspace + client_->DeleteSurroundingText(1, 0); + break; + case mojo::KeyboardCode::DELETE: + client_->DeleteSurroundingText(0, 1); + break; + case mojo::KeyboardCode::HOME: + client_->SetSelection(0, 0); + break; + case mojo::KeyboardCode::END: + client_->SetSelection(1, 1); + break; + case mojo::KeyboardCode::TAB: // tab + // TODO: Advance focus, in reverse if shifted + break; + case mojo::KeyboardCode::RETURN: + client_->Submit(::keyboard::SubmitAction::DONE); + break; + default: + base::string16 character; + character.push_back(event->key_data->character); + mojo::String text(base::UTF16ToUTF8(character)); + client_->CommitText(text, 1); + break; + } + } + } + callback.Run(); +} + +} // namespace keyboard
diff --git a/services/keyboard/linux/keyboard_service_impl.h b/services/keyboard/linux/keyboard_service_impl.h new file mode 100644 index 0000000..dc1b4bd --- /dev/null +++ b/services/keyboard/linux/keyboard_service_impl.h
@@ -0,0 +1,48 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SERVICES_KEYBOARD_LINUX_KEYBOARD_SERVICE_IMPL_H_ +#define SERVICES_KEYBOARD_LINUX_KEYBOARD_SERVICE_IMPL_H_ + +#include "base/macros.h" +#include "mojo/public/cpp/application/interface_factory.h" +#include "mojo/public/cpp/bindings/strong_binding.h" +#include "mojo/public/interfaces/application/shell.mojom.h" +#include "mojo/services/keyboard/interfaces/keyboard.mojom.h" +#include "mojo/services/native_viewport/interfaces/native_viewport.mojom.h" + +namespace keyboard { + +class LinuxKeyboardServiceImpl : public ::keyboard::KeyboardService, + public mojo::NativeViewportEventDispatcher { + public: + explicit LinuxKeyboardServiceImpl( + mojo::InterfaceRequest<::keyboard::KeyboardService> request, + mojo::Shell* shell, + mojo::ApplicationConnection* connection); + ~LinuxKeyboardServiceImpl() override; + void Show(::keyboard::KeyboardClientPtr client, + ::keyboard::KeyboardType type) override; + void ShowByRequest() override; + void Hide() override; + void SetText(const mojo::String& text) override; + void SetSelection(int32_t start, int32_t end) override; + + void OnEvent(mojo::EventPtr event, + const mojo::Callback<void()>& callback) override; + + private: + mojo::Shell* shell_; + mojo::ApplicationConnection* connection_; + mojo::StrongBinding<::keyboard::KeyboardService> binding_; + mojo::Binding<mojo::NativeViewportEventDispatcher> event_dispatcher_binding_; + + ::keyboard::KeyboardClientPtr client_; + + DISALLOW_COPY_AND_ASSIGN(LinuxKeyboardServiceImpl); +}; + +} // namespace keyboard + +#endif /* defined(SERVICES_KEYBOARD_LINUX_KEYBOARD_SERVICE_IMPL_H_) */
diff --git a/services/keyboard/linux/main.cc b/services/keyboard/linux/main.cc new file mode 100644 index 0000000..c7a0bbb --- /dev/null +++ b/services/keyboard/linux/main.cc
@@ -0,0 +1,70 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/macros.h" +#include "base/threading/sequenced_worker_pool.h" +#include "mojo/application/application_runner_chromium.h" +#include "mojo/public/c/system/main.h" +#include "mojo/public/cpp/application/application_connection.h" +#include "mojo/public/cpp/application/application_delegate.h" +#include "mojo/public/cpp/application/application_impl.h" +#include "mojo/public/cpp/application/connect.h" +#include "mojo/public/cpp/application/interface_factory.h" +#include "mojo/services/native_viewport/interfaces/native_viewport.mojom.h" +#include "services/keyboard/linux/keyboard_service_impl.h" + +namespace keyboard { + +class KeyboardServiceApp : public mojo::ApplicationDelegate, + public mojo::InterfaceFactory<KeyboardService> { + public: + KeyboardServiceApp() {} + ~KeyboardServiceApp() override {} + + private: + // |ApplicationDelegate| override: + void Initialize(mojo::ApplicationImpl* app) override { + shell_ = app->shell(); + + /* + // WRONG TROUSERS + mojo::ServiceProviderPtr viewport_service_provider; + shell_->ConnectToApplication("mojo:native_viewport_service", + mojo::GetProxy(&viewport_service_provider), + nullptr); + mojo::NativeViewportPtr viewport_service_; + mojo::ConnectToService(viewport_service_provider.get(), &viewport_service_); + + mojo::NativeViewportEventDispatcherPtr dispatcher; + mojo::Binding<mojo::NativeViewportEventDispatcher> event_dispatcher_binding_(this); + event_dispatcher_binding_.Bind(GetProxy(&dispatcher)); + viewport_service_->SetKeyEventDispatcher(dispatcher.Pass()); + */ + } + + // |ApplicationDelegate| override: + bool ConfigureIncomingConnection(mojo::ApplicationConnection* connection) override { + connection->AddService<KeyboardService>(this); + return true; + } + + // |InterfaceFactory<KeyboardService>| implementation: + void Create(mojo::ApplicationConnection* connection, + mojo::InterfaceRequest<KeyboardService> request) override { + new LinuxKeyboardServiceImpl(request.Pass(), shell_, connection); + } + + private: + + mojo::Shell* shell_; + DISALLOW_COPY_AND_ASSIGN(KeyboardServiceApp); +}; + +} // namespace keyboard + +MojoResult MojoMain(MojoHandle application_request) { + mojo::ApplicationRunnerChromium runner( + new keyboard::KeyboardServiceApp()); + return runner.Run(application_request); +}
diff --git a/services/native_viewport/native_viewport_impl.cc b/services/native_viewport/native_viewport_impl.cc index 6b86586..42c3980 100644 --- a/services/native_viewport/native_viewport_impl.cc +++ b/services/native_viewport/native_viewport_impl.cc
@@ -20,6 +20,8 @@ namespace native_viewport { +mojo::NativeViewportEventDispatcherPtr NativeViewportImpl::key_event_dispatcher_; + NativeViewportImpl::NativeViewportImpl( mojo::ApplicationImpl* application, bool is_headless, @@ -94,6 +96,11 @@ event_dispatcher_ = dispatcher.Pass(); } +void NativeViewportImpl::SetKeyEventDispatcher( + mojo::NativeViewportEventDispatcherPtr dispatcher) { + key_event_dispatcher_ = dispatcher.Pass(); +} + void NativeViewportImpl::OnMetricsChanged(mojo::ViewportMetricsPtr metrics) { if (metrics_->Equals(*metrics)) return; @@ -149,6 +156,13 @@ pointers_waiting_on_ack_.erase(event->pointer_data->pointer_id); break; + case mojo::EventType::KEY_PRESSED: + case mojo::EventType::KEY_RELEASED: + if (key_event_dispatcher_.get()) + key_event_dispatcher_->OnEvent(event.Pass(), callback); + return false; + break; + default: break; }
diff --git a/services/native_viewport/native_viewport_impl.h b/services/native_viewport/native_viewport_impl.h index 3391e88..0077fc2 100644 --- a/services/native_viewport/native_viewport_impl.h +++ b/services/native_viewport/native_viewport_impl.h
@@ -56,6 +56,8 @@ mojo::InterfaceRequest<mojo::ContextProvider> request) override; void SetEventDispatcher( mojo::NativeViewportEventDispatcherPtr dispatcher) override; + void SetKeyEventDispatcher( + mojo::NativeViewportEventDispatcherPtr dispatcher) override; // PlatformViewport::Delegate implementation. void OnMetricsChanged(mojo::ViewportMetricsPtr metrics) override; @@ -79,6 +81,7 @@ CreateCallback create_callback_; RequestMetricsCallback metrics_callback_; mojo::NativeViewportEventDispatcherPtr event_dispatcher_; + static mojo::NativeViewportEventDispatcherPtr key_event_dispatcher_; mojo::StrongBinding<mojo::NativeViewport> binding_; // Set of pointer_ids we've sent a move to and are waiting on an ack.