1/*
2 * Copyright 2001-2013 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef INPUT_SERVER_APP_H
6#define INPUT_SERVER_APP_H
7
8
9#include <stdlib.h>
10#include <string.h>
11#include <unistd.h>
12
13//#define DEBUG 1
14
15#include <Application.h>
16#include <Debug.h>
17#include <FindDirectory.h>
18#include <InputServerDevice.h>
19#include <InputServerFilter.h>
20#include <InputServerMethod.h>
21#include <InterfaceDefs.h>
22#include <Locker.h>
23#include <Message.h>
24#include <ObjectList.h>
25#include <OS.h>
26#include <Screen.h>
27#include <SupportDefs.h>
28
29#include <shared_cursor_area.h>
30
31#include "AddOnManager.h"
32#include "KeyboardSettings.h"
33#include "MouseSettings.h"
34#include "PathList.h"
35
36
37#define INPUTSERVER_SIGNATURE "application/x-vnd.Be-input_server"
38	// use this when target should replace R5 input_server
39
40typedef BObjectList<BMessage> EventList;
41
42class BottomlineWindow;
43
44class InputDeviceListItem {
45	public:
46		InputDeviceListItem(BInputServerDevice& serverDevice,
47			const input_device_ref& device);
48		~InputDeviceListItem();
49
50		void Start();
51		void Stop();
52		void Control(uint32 code, BMessage* message);
53
54		const char* Name() const { return fDevice.name; }
55		input_device_type Type() const { return fDevice.type; }
56		bool Running() const { return fRunning; }
57
58		bool HasName(const char* name) const;
59		bool HasType(input_device_type type) const;
60		bool Matches(const char* name, input_device_type type) const;
61
62		BInputServerDevice* ServerDevice() { return fServerDevice; }
63
64	private:
65		BInputServerDevice* fServerDevice;
66		input_device_ref   	fDevice;
67		bool 				fRunning;
68};
69
70namespace BPrivate {
71
72class DeviceAddOn {
73public:
74								DeviceAddOn(BInputServerDevice* device);
75								~DeviceAddOn();
76
77			bool				HasPath(const char* path) const;
78			status_t			AddPath(const char* path);
79			status_t			RemovePath(const char* path);
80			int32				CountPaths() const;
81
82			BInputServerDevice*	Device() { return fDevice; }
83
84private:
85			BInputServerDevice*	fDevice;
86			PathList			fMonitoredPaths;
87};
88
89}	// namespace BPrivate
90
91class _BMethodAddOn_ {
92	public:
93		_BMethodAddOn_(BInputServerMethod *method, const char* name,
94			const uchar* icon);
95		~_BMethodAddOn_();
96
97		status_t SetName(const char* name);
98		status_t SetIcon(const uchar* icon);
99		status_t SetMenu(const BMenu* menu, const BMessenger& messenger);
100		status_t MethodActivated(bool activate);
101		status_t AddMethod();
102		int32 Cookie() { return fCookie; }
103
104	private:
105		BInputServerMethod* fMethod;
106		char* fName;
107		uchar fIcon[16*16*1];
108		const BMenu* fMenu;
109		BMessenger fMessenger;
110		int32 fCookie;
111};
112
113class KeymapMethod : public BInputServerMethod {
114	public:
115		KeymapMethod();
116		~KeymapMethod();
117};
118
119class InputServer : public BApplication {
120	public:
121		InputServer();
122		virtual ~InputServer();
123
124		virtual void ArgvReceived(int32 argc, char** argv);
125
126		virtual bool QuitRequested();
127		virtual void ReadyToRun();
128		virtual void MessageReceived(BMessage* message);
129
130		void HandleSetMethod(BMessage* message);
131		status_t HandleGetSetMouseType(BMessage* message, BMessage* reply);
132		status_t HandleGetSetMouseAcceleration(BMessage* message, BMessage* reply);
133		status_t HandleGetSetKeyRepeatDelay(BMessage* message, BMessage* reply);
134		status_t HandleGetKeyInfo(BMessage* message, BMessage* reply);
135		status_t HandleGetModifiers(BMessage* message, BMessage* reply);
136		status_t HandleGetModifierKey(BMessage* message, BMessage* reply);
137		status_t HandleSetModifierKey(BMessage* message, BMessage* reply);
138		status_t HandleSetKeyboardLocks(BMessage* message, BMessage* reply);
139		status_t HandleGetSetMouseSpeed(BMessage* message, BMessage* reply);
140		status_t HandleSetMousePosition(BMessage* message, BMessage* reply);
141		status_t HandleGetSetMouseMap(BMessage* message, BMessage* reply);
142		status_t HandleGetSetKeyboardID(BMessage* message, BMessage* reply);
143		status_t HandleGetSetClickSpeed(BMessage* message, BMessage* reply);
144		status_t HandleGetSetKeyRepeatRate(BMessage* message, BMessage* reply);
145		status_t HandleGetSetKeyMap(BMessage* message, BMessage* reply);
146		status_t HandleFocusUnfocusIMAwareView(BMessage* message, BMessage* reply);
147
148		status_t EnqueueDeviceMessage(BMessage* message);
149		status_t EnqueueMethodMessage(BMessage* message);
150		status_t SetNextMethod(bool direction);
151		void SetActiveMethod(BInputServerMethod* method);
152		const BMessenger* MethodReplicant();
153		void SetMethodReplicant(const BMessenger *replicant);
154		bool EventLoopRunning();
155
156		status_t GetDeviceInfo(const char* name, input_device_type *_type,
157					bool *_isRunning = NULL);
158		status_t GetDeviceInfos(BMessage *msg);
159		status_t UnregisterDevices(BInputServerDevice& serverDevice,
160					input_device_ref** devices = NULL);
161		status_t RegisterDevices(BInputServerDevice& serverDevice,
162					input_device_ref** devices);
163		status_t StartStopDevices(const char* name, input_device_type type,
164					bool doStart);
165		status_t StartStopDevices(BInputServerDevice& serverDevice, bool start);
166		status_t ControlDevices(const char *name, input_device_type type,
167					uint32 code, BMessage* message);
168
169		bool SafeMode();
170
171		::AddOnManager* AddOnManager() { return fAddOnManager; }
172
173		static BList gInputFilterList;
174		static BLocker gInputFilterListLocker;
175
176		static BList gInputMethodList;
177		static BLocker gInputMethodListLocker;
178
179		static KeymapMethod gKeymapMethod;
180
181		BRect& ScreenFrame() { return fFrame; }
182
183	private:
184		typedef BApplication _inherited;
185
186		status_t _LoadKeymap();
187		status_t _LoadSystemKeymap();
188		status_t _SaveKeymap(bool isDefault = false);
189		void _InitKeyboardMouseStates();
190		MouseSettings* _GetSettingsForMouse(BString mouseName);
191
192		status_t _StartEventLoop();
193		void _EventLoop();
194		static status_t _EventLooper(void *arg);
195
196		void _UpdateMouseAndKeys(EventList& events);
197		bool _SanitizeEvents(EventList& events);
198		bool _MethodizeEvents(EventList& events);
199		bool _FilterEvents(EventList& events);
200		void _DispatchEvents(EventList& events);
201
202		void _FilterEvent(BInputServerFilter* filter, EventList& events,
203					int32& index, int32& count);
204		status_t _DispatchEvent(BMessage* event);
205
206		status_t _AcquireInput(BMessage& message, BMessage& reply);
207		void _ReleaseInput(BMessage* message);
208
209	private:
210		uint16			fKeyboardID;
211
212		BList			fInputDeviceList;
213		BLocker 		fInputDeviceListLocker;
214
215		KeyboardSettings fKeyboardSettings;
216		MultipleMouseSettings	fMouseSettings;
217
218		BPoint			fMousePos;		// current mouse position
219		key_info		fKeyInfo;		// current key info
220		key_map			fKeys;			// current key_map
221		char*			fChars;			// current keymap chars
222		uint32			fCharsSize;		// current keymap char count
223
224		port_id      	fEventLooperPort;
225
226		::AddOnManager*	fAddOnManager;
227
228		BScreen			fScreen;
229		BRect			fFrame;
230
231		BLocker			fEventQueueLock;
232		EventList 		fEventQueue;
233
234		BInputServerMethod*	fActiveMethod;
235		EventList			fMethodQueue;
236		const BMessenger*	fReplicantMessenger;
237		BottomlineWindow*	fInputMethodWindow;
238		bool				fInputMethodAware;
239
240		sem_id 			fCursorSem;
241		port_id			fAppServerPort;
242		team_id			fAppServerTeam;
243		area_id			fCursorArea;
244		shared_cursor*	fCursorBuffer;
245
246		typedef std::map<BString, MouseSettings*> mouse_settings_object;
247		mouse_settings_object  fMouseSettingsObject;
248};
249
250extern InputServer* gInputServer;
251
252#if DEBUG >= 1
253#	if DEBUG == 2
254#		undef PRINT
255		inline void _iprint(const char *fmt, ...) {
256			FILE* log = fopen("/var/log/input_server.log", "a");
257			char buf[1024];
258			va_list ap;
259			va_start(ap, fmt);
260			vsprintf(buf, fmt, ap);
261			va_end(ap);
262			fputs(buf, log);
263			fflush(log);
264			fclose(log);
265        }
266#		define PRINT(x)	_iprint x
267#	else
268#		undef PRINT
269#		define PRINT(x)	SERIAL_PRINT(x)
270#	endif
271#	define PRINTERR(x)		PRINT(x)
272#	define EXIT()          PRINT(("EXIT %s\n", __PRETTY_FUNCTION__))
273#	define CALLED()        PRINT(("CALLED %s\n", __PRETTY_FUNCTION__))
274#else
275#	define EXIT()          ((void)0)
276#	define CALLED()        ((void)0)
277#	define PRINTERR(x)		SERIAL_PRINT(x)
278#endif
279
280#endif	/* INPUT_SERVER_APP_H */
281