blob: 700314828c493a4ecfab0216bb5a984835ff3c1f [file] [log] [blame]
/*
* Copyright 2016 The Fuchsia Authors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <wtf/Noncopyable.h>
#include <hid/hid.h>
#include <future>
#include <map>
#include <string>
#include <vector>
#include <zircon/types.h>
namespace Fuchsia {
#pragma mark - Event
class Event {
public:
enum Type {
kMouse,
kKey
};
Type type() const { return fType; }
int eventSource() const { return fEventSource; }
protected:
Event(Type type, int eventSource)
: fType(type)
, fEventSource(eventSource)
{
}
virtual ~Event() {}
private:
Type fType;
int fEventSource;
};
typedef std::shared_ptr<Event> EventPtr;
typedef std::vector<EventPtr> EventList;
#pragma mark - MouseEvent
class MouseEvent : public Event {
public:
MouseEvent(int fd, int x, int y, int buttons)
: Event(kMouse, fd)
, fDeltaX(x)
, fDeltaY(y)
, fButtons(buttons)
{
}
int fDeltaX;
int fDeltaY;
int fButtons;
};
#pragma mark - KeyEvent
class KeyEvent : public Event {
public:
KeyEvent(int fd, uint8_t keyCode, bool pressed)
: Event(kKey, fd)
, fKeyCode(keyCode)
, fPressed(pressed)
{
}
uint8_t keycode() const { return fKeyCode; }
bool pressed() const { return fPressed; }
private:
uint8_t fKeyCode;
bool fPressed;
};
#pragma mark - InputReportHandler
class InputReportHandler {
public:
ssize_t openHandle();
void checkForEvents(EventList&);
int descriptor() const { return fDescriptor; }
zx_handle_t handle() const { return fHandle; }
protected:
InputReportHandler(int descriptor, const std::string& deviceName);
virtual ~InputReportHandler();
virtual void handleReport(size_t byteLength, const char* reportData, EventList& events) = 0;
int fDescriptor;
std::string fName;
zx_handle_t fHandle = { ZX_HANDLE_INVALID };
};
typedef std::shared_ptr<InputReportHandler> InputReportHandlerPtr;
class MouseReportHandler : public InputReportHandler {
public:
MouseReportHandler(int descriptor, const std::string& deviceName);
void handleReport(size_t byteLength, const char* reportData, EventList& events) override;
};
class KeyboardReportHandler : public InputReportHandler {
public:
KeyboardReportHandler(int descriptor, const std::string& deviceName);
void handleReport(size_t byteLength, const char* reportData, EventList& events) override;
private:
hid_keys_t fKeyState = {};
};
class InputHandler {
WTF_MAKE_NONCOPYABLE(InputHandler);
public:
InputHandler();
void openDevices();
bool hasEvents();
EventList getPendingEvents();
void addEvents(const EventList& newEvents);
private:
void startReaderThread();
void readEvents();
std::vector<InputReportHandlerPtr> fReportHandlers;
EventList fEvents;
std::mutex fEventsMutex;
std::thread fEventReaderThread;
};
}