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