blob: 2b895cacd1675ac0d71ab6602f4d4e86bd4ab6b1 [file] [log] [blame]
// Copyright 2017 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 SRC_BRINGUP_VIRTCON_KEYBOARD_H_
#define SRC_BRINGUP_VIRTCON_KEYBOARD_H_
#include <fuchsia/input/report/llcpp/fidl.h>
#include <fuchsia/io/c/fidl.h>
#include <lib/fdio/cpp/caller.h>
#include <lib/zx/timer.h>
#include <stdint.h>
#include <zircon/types.h>
#include <array>
#include <optional>
#include "vc.h"
#define MOD_LSHIFT (1 << 0)
#define MOD_RSHIFT (1 << 1)
#define MOD_LALT (1 << 2)
#define MOD_RALT (1 << 3)
#define MOD_LCTRL (1 << 4)
#define MOD_RCTRL (1 << 5)
#define MOD_CAPSLOCK (1 << 6)
#define MOD_SHIFT (MOD_LSHIFT | MOD_RSHIFT)
#define MOD_ALT (MOD_LALT | MOD_RALT)
#define MOD_CTRL (MOD_LCTRL | MOD_RCTRL)
// Global function which sets up the global keyboard watcher.
zx_status_t setup_keyboard_watcher(keypress_handler_t handler, bool repeat_keys);
// A |Keyboard| is created with a callback to handle keypresses.
// The Keyboard is responsible for watching the keyboard device, parsing
// events, handling key-repeats/modifiers, and sending keypresses to
// the |keypress_handler_t|.
class Keyboard {
public:
Keyboard(keypress_handler_t handler, bool repeat_keys)
: handler_(handler), repeat_enabled_(repeat_keys) {}
~Keyboard();
// Have the keyboard start watching a given device.
// |caller| represents the keyboard device.
zx_status_t Setup(llcpp::fuchsia::input::report::InputDevice::SyncClient keyboard_client);
// Process a given set of keys and send them to the handler.
void ProcessInput(const ::llcpp::fuchsia::input::report::InputReport& report);
private:
// The callback for when key-repeat is triggered.
zx_status_t TimerCallback(zx_signals_t signals, uint32_t evt);
// The callback for when the device has a new input event.
zx_status_t InputCallback(unsigned pollevt, uint32_t evt);
// Send a report to the device that enables/disables the capslock LED.
void SetCapsLockLed(bool caps_lock);
port_handler_t input_notifier_ = {};
port_handler_t timer_notifier_ = {};
zx::timer timer_;
keypress_handler_t handler_ = {};
zx::duration repeat_interval_ = zx::duration::infinite();
zx::event keyboard_event_;
std::optional<llcpp::fuchsia::input::report::InputDevice::SyncClient> keyboard_client_;
int modifiers_ = 0;
bool repeat_enabled_ = true;
bool is_repeating_ = false;
uint32_t repeating_key_;
std::array<llcpp::fuchsia::ui::input2::Key,
llcpp::fuchsia::input::report::KEYBOARD_MAX_PRESSED_KEYS>
last_pressed_keys_;
size_t last_pressed_keys_size_ = 0;
};
// A |KeyboardWatcher| opens a directory and will watch for new input devices.
// It will create a |Keyboard| for each input device that is a keyboard.
class KeyboardWatcher {
public:
zx_status_t Setup(keypress_handler_t handler, bool repeat_keys);
// Callback when a new file is created in the directory.
zx_status_t DirCallback(port_handler_t* ph, zx_signals_t signals, uint32_t evt);
private:
// Attempts to open the file and create a new Keyboard.
zx_status_t OpenFile(uint8_t evt, char* name);
// The Fd() representing the directory this is watching.
int Fd() { return dir_caller_.fd().get(); }
bool repeat_keys_ = true;
keypress_handler_t handler_ = {};
fdio_cpp::FdioCaller dir_caller_;
port_handler_t dir_handler_ = {};
};
#endif // SRC_BRINGUP_VIRTCON_KEYBOARD_H_