1/* 2 * Copyright 2021, Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5#ifndef _VIRTIOINPUTDEVICE_H_ 6#define _VIRTIOINPUTDEVICE_H_ 7 8 9#include <add-ons/input_server/InputServerDevice.h> 10#include <AutoDeleter.h> 11#include <Handler.h> 12#include <InterfaceDefs.h> 13#include <MessageRunner.h> 14 15 16struct VirtioInputPacket; 17 18 19struct KeyboardState { 20 bigtime_t when; 21 uint8 keys[256 / 8]; 22 uint32 modifiers; 23}; 24 25struct TabletState { 26 bigtime_t when; 27 float x, y; 28 float pressure; 29 uint32 buttons; 30 int32 clicks; 31 int32 wheelX, wheelY; 32}; 33 34 35class VirtioInputDevice : public BInputServerDevice 36{ 37public: 38 VirtioInputDevice(); 39 virtual ~VirtioInputDevice(); 40 41 virtual status_t InitCheck(); 42 43 virtual status_t Start(const char* name, void* cookie); 44 virtual status_t Stop(const char* name, void* cookie); 45 46 virtual status_t Control(const char* name, void* cookie, 47 uint32 command, BMessage* message); 48}; 49 50 51class VirtioInputHandler 52{ 53public: 54 VirtioInputHandler(VirtioInputDevice* dev, 55 const char* name, input_device_type type); 56 virtual ~VirtioInputHandler(); 57 inline VirtioInputDevice* 58 Device() 59 {return fDev;} 60 inline input_device_ref* 61 Ref() 62 {return &fRef;} 63 void SetFd(int fd); 64 65 status_t Start(); 66 status_t Stop(); 67 68 static status_t Watcher(void* arg); 69 70 virtual void Reset() = 0; 71 virtual status_t Control(uint32 command, BMessage* message); 72 virtual void PacketReceived(const VirtioInputPacket &pkt) = 0; 73 74private: 75 VirtioInputDevice* 76 fDev; 77 input_device_ref 78 fRef; 79 FileDescriptorCloser 80 fDeviceFd; 81 thread_id fWatcherThread; 82 bool fRun; 83}; 84 85 86class KeyboardHandler : public VirtioInputHandler 87{ 88public: 89 KeyboardHandler(VirtioInputDevice* dev, 90 const char* name); 91 virtual ~KeyboardHandler(); 92 93 virtual void Reset(); 94 virtual status_t Control(uint32 command, BMessage* message); 95 virtual void PacketReceived(const VirtioInputPacket &pkt); 96 97private: 98 static bool _IsKeyPressed(const KeyboardState& state, 99 uint32 key); 100 void _KeyString(uint32 code, char* str, size_t len); 101 void _StartRepeating(BMessage* msg); 102 void _StopRepeating(); 103 static status_t _RepeatThread(void* arg); 104 void _StateChanged(); 105 106private: 107 KeyboardState fState; 108 KeyboardState fNewState; 109 BPrivate::AutoDeleter<key_map, BPrivate::MemoryDelete> 110 fKeyMap; 111 BPrivate::AutoDeleter<char, BPrivate::MemoryDelete> 112 fChars; 113 114 bigtime_t fRepeatDelay; 115 int32 fRepeatRate; 116 thread_id fRepeatThread; 117 sem_id fRepeatThreadSem; 118 BMessage fRepeatMsg; 119}; 120 121 122class TabletHandler : public VirtioInputHandler 123{ 124public: 125 TabletHandler(VirtioInputDevice* dev, 126 const char* name); 127 128 virtual void Reset(); 129 virtual status_t Control(uint32 command, BMessage* message); 130 virtual void PacketReceived(const VirtioInputPacket &pkt); 131 132private: 133 static bool _FillMessage(BMessage& msg, const TabletState& s); 134 135private: 136 TabletState fState; 137 TabletState fNewState; 138 bigtime_t fLastClick; 139 int fLastClickBtn; 140 141 bigtime_t fClickSpeed; 142}; 143 144 145extern "C" _EXPORT BInputServerDevice* instantiate_input_device(); 146 147 148#endif // _VIRTIOINPUTDEVICE_H_ 149