blob: 2af7fe2c5cbc5e0264750798a19347e69c16f22a [file] [log] [blame]
// Copyright 2018 The Fuchsia 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 GARNET_LIB_UI_INPUT_INPUT_SYSTEM_H_
#define GARNET_LIB_UI_INPUT_INPUT_SYSTEM_H_
#include <fuchsia/ui/input/cpp/fidl.h>
#include <memory>
#include <unordered_map>
#include <unordered_set>
#include "garnet/lib/ui/gfx/gfx_system.h"
#include "garnet/lib/ui/gfx/id.h"
#include "garnet/lib/ui/gfx/resources/view.h"
#include "garnet/lib/ui/input/view_id.h"
#include "garnet/lib/ui/scenic/system.h"
namespace scenic_impl {
namespace input {
// Routes input events from a root presenter to Scenic clients.
// Manages input-related state, such as focus.
//
// The general flow of events is:
// DispatchCommand --[decide what/where]--> EnqueueEvent
class InputSystem : public System {
public:
static constexpr TypeId kTypeId = kInput;
explicit InputSystem(SystemContext context, gfx::GfxSystem* scenic);
virtual ~InputSystem() = default;
virtual std::unique_ptr<CommandDispatcher> CreateCommandDispatcher(
CommandDispatcherContext context) override;
fuchsia::ui::input::ImeServicePtr& text_sync_service() {
return text_sync_service_;
}
std::unordered_set<SessionId>& hard_keyboard_requested() {
return hard_keyboard_requested_;
}
private:
gfx::GfxSystem* const gfx_system_;
// Send hard keyboard events to Text Sync for dispatch via IME; this is the
// intended flow for clients to receive *mediated* keyboard events.
// The connection to Text Sync is shared between all dispatchers.
fuchsia::ui::input::ImeServicePtr text_sync_service_;
// By default, clients don't get hard keyboard events directly from Scenic.
// Clients may request these events via the SetHardKeyboardDeliveryCmd;
// this set remembers which sessions have opted in. We need this map because
// each InputCommandDispatcher works independently.
std::unordered_set<SessionId> hard_keyboard_requested_;
};
// Per-session treatment of input commands.
class InputCommandDispatcher : public CommandDispatcher {
public:
InputCommandDispatcher(CommandDispatcherContext context,
gfx::GfxSystem* gfx_system, InputSystem* input_system);
~InputCommandDispatcher() override = default;
// |CommandDispatcher|
void DispatchCommand(const fuchsia::ui::scenic::Command command) override;
private:
// Per-command dispatch logic.
void DispatchCommand(const fuchsia::ui::input::SendPointerInputCmd command);
void DispatchCommand(const fuchsia::ui::input::SendKeyboardInputCmd command);
void DispatchCommand(
const fuchsia::ui::input::SetHardKeyboardDeliveryCmd command);
void DispatchCommand(
const fuchsia::ui::input::SetParallelDispatchCmd command);
// Per-pointer-type dispatch logic.
void DispatchTouchCommand(
const fuchsia::ui::input::SendPointerInputCmd command);
void DispatchMouseCommand(
const fuchsia::ui::input::SendPointerInputCmd command);
// Enqueue the focus event into the view's SessionListener.
void EnqueueEventToView(GlobalId view_id,
fuchsia::ui::input::FocusEvent focus);
// Enqueue the pointer event into the view's SessionListener.
void EnqueueEventToView(GlobalId view_id,
fuchsia::ui::input::PointerEvent pointer);
// Enqueue the keyboard event into the view's SessionListener.
void EnqueueEventToView(GlobalId view_id,
fuchsia::ui::input::KeyboardEvent keyboard);
// Enqueue the keyboard event to the Text Sync service.
void EnqueueEventToTextSync(GlobalId view_id,
fuchsia::ui::input::KeyboardEvent keyboard);
// FIELDS
gfx::GfxSystem* const gfx_system_ = nullptr;
InputSystem* const input_system_ = nullptr;
// Tracks which View has focus.
GlobalId focus_;
// Tracks the set of Views each touch event is delivered to; a map from
// pointer ID to a stack of GlobalIds. This is used to ensure consistent
// delivery of pointer events for a given finger to its original destination
// targets on their respective DOWN event. In particular, a focus change
// triggered by a new finger should *not* affect delivery of events to
// existing fingers.
//
// NOTE: We assume there is one touch screen, and hence unique pointer IDs.
std::unordered_map<uint32_t, ViewStack> touch_targets_;
// Tracks the View each mouse pointer is delivered to; a map from device ID to
// a GlobalId. This is used to ensure consistent delivery of mouse events for
// a given device. A focus change triggered by other pointer events should
// *not* affect delivery of events to existing mice.
//
// NOTE: We reuse the ViewStack here just for convenience.
std::unordered_map<uint32_t, ViewStack> mouse_targets_;
// TODO(SCN-1047): Remove when gesture disambiguation is the default.
bool parallel_dispatch_ = true;
};
} // namespace input
} // namespace scenic_impl
#endif // GARNET_LIB_UI_INPUT_INPUT_SYSTEM_H_