1/*
2 * Copyright 1999-2009 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Jeremy Friesner
7 */
8#ifndef _COMMAND_ACTUATORS_H
9#define _COMMAND_ACTUATORS_H
10
11
12#include <Message.h>
13#include <String.h>
14#include <Archivable.h>
15#include <List.h>
16#include <InputServerFilter.h>
17
18
19struct key_map;
20
21class CommandActuator;
22
23
24// Factory function: Given a text string, allocates and returns a
25// CommandActuator. Returns NULL on failure (usually a parse error)
26extern CommandActuator* CreateCommandActuator(const char* command);
27
28// This file contains various CommandActuator classes. Each CommandActuator
29// contains code to do something. They're functor objects, really. The input
30// server add-on will execute the CommandActuator associated with a key combo
31// when that key combo is detected.
32
33// The abstract base class. Defines the interface.
34class _EXPORT CommandActuator;
35class CommandActuator : public BArchivable {
36public:
37								CommandActuator(int32 argc, char** argv);
38								CommandActuator(BMessage* from);
39
40		// Called by the InputFilter whenever a key is pressed or depressed.
41		// It's important to ensure that this method returns quickly, as the
42		// input_server will block while it executes. (keyMessage) is the BMessage
43		// that triggered this call. (outList) is a BList that additional input
44		// events may be added to. If (*asyncData) is set to non-NULL,
45		// KeyEventAsync() will be called asynchronously with (asyncData) as
46		// the argument. Returns the filter_result to be given back to the
47		// input_server. (Defaults to B_SKIP_MESSAGE)
48		virtual filter_result	KeyEvent(const BMessage* keyMessage,
49									BList* outList, void** asyncData,
50									BMessage* mouseMessage)
51								{ return B_SKIP_MESSAGE; }
52
53		// Called in a separate thread if (*setAsyncData) was set to non-NULL
54		// in KeyEvent(). Defaults to a no-op.
55		virtual void 			KeyEventAsync(const BMessage* keyupMessage,
56									void* asyncData) {}
57
58		virtual status_t 		Archive(BMessage* into, bool deep = true)
59									const;
60};
61
62
63// This is the most common thing to do--launch a process.
64class _EXPORT LaunchCommandActuator;
65class LaunchCommandActuator : public CommandActuator {
66public:
67								LaunchCommandActuator(int32 argc, char** argv);
68								LaunchCommandActuator(BMessage* from);
69								~LaunchCommandActuator();
70
71		virtual	status_t 		Archive(BMessage* into, bool deep = true)
72									const;
73		static	BArchivable*	Instantiate(BMessage* from);
74		virtual filter_result 	KeyEvent(const BMessage* keyMessage,
75									BList* outList, void** setAsyncData,
76									BMessage* mouseMessage);
77		virtual void 			KeyEventAsync(const BMessage* keyMessage,
78									void* asyncData);
79
80private:
81				bool 			_GetNextWord(char** setBegin,
82									char** setEnd) const;
83
84				char**			fArgv;
85				int32			fArgc;
86};
87
88
89// Stupid actuator--just calls beep().
90class _EXPORT BeepCommandActuator;
91class BeepCommandActuator : public CommandActuator {
92public:
93								BeepCommandActuator(int32 argc, char** argv);
94								BeepCommandActuator(BMessage* from);
95								~BeepCommandActuator();
96
97		virtual	filter_result	KeyEvent(const BMessage* keyMessage,
98									BList* outList, void** setAsyncData,
99									BMessage* mouseMessage);
100		virtual	status_t 		Archive(BMessage* into, bool deep = true)
101									const;
102		static	BArchivable*	Instantiate(BMessage* from);
103};
104
105
106// This class will insert a string of keystrokes into the input stream.
107class _EXPORT KeyStrokeSequenceCommandActuator;
108class KeyStrokeSequenceCommandActuator : public CommandActuator {
109public:
110								KeyStrokeSequenceCommandActuator(int32 argc,
111									char** argv);
112								KeyStrokeSequenceCommandActuator(
113									BMessage* from);
114								~KeyStrokeSequenceCommandActuator();
115
116		virtual	filter_result	KeyEvent(const BMessage* keyMessage,
117									BList* outList, void** setAsyncData,
118									BMessage* mouseMessage);
119		virtual	status_t 		Archive(BMessage* into, bool deep = true)
120									const;
121		static	BArchivable*	Instantiate(BMessage * from);
122
123private:
124				void			_GenerateKeyCodes();
125				int32 			_LookupKeyCode(key_map* map, char* keys,
126									int32 offsets[128], char key,
127									uint8* setStates, int32& setModifier,
128									int32 setTo) const;
129				void 			_SetStateBit(uint8* setStates, uint32 key,
130									bool on = true) const;
131
132				uint8* 			fStates;
133				int32* 			fKeyCodes;
134				int32* 			fModCodes;
135				BString 		fSequence;
136				BList 			fOverrides;
137				BList 			fOverrideOffsets;
138				BList 			fOverrideModifiers;
139				BList 			fOverrideKeyCodes;
140};
141
142
143// This class will insert a string of keystrokes into the input stream.
144class _EXPORT MIMEHandlerCommandActuator;
145class MIMEHandlerCommandActuator : public CommandActuator {
146public:
147								MIMEHandlerCommandActuator(int32 argc,
148									char** argv);
149								MIMEHandlerCommandActuator(BMessage* from);
150								~MIMEHandlerCommandActuator();
151
152		virtual	filter_result 	KeyEvent(const BMessage* keyMessage,
153									BList* outList, void** setAsyncData,
154									BMessage* mouseMessage);
155		virtual	void 			KeyEventAsync(const BMessage* keyupMessage,
156									void* asyncData);
157		virtual	status_t 		Archive(BMessage * into,
158									bool deep = true) const;
159		static	BArchivable* 	Instantiate(BMessage* from);
160
161private:
162				BString 		fMimeType;
163};
164
165
166// Abstract base class for actuators that affect mouse buttons
167class _EXPORT MouseCommandActuator;
168class MouseCommandActuator : public CommandActuator {
169public:
170								MouseCommandActuator(int32 argc, char** argv);
171								MouseCommandActuator(BMessage* from);
172								~MouseCommandActuator();
173
174		virtual	status_t		Archive(BMessage* into, bool deep = true)
175									const;
176
177protected:
178				int32			_GetWhichButtons() const;
179				void 			_GenerateMouseButtonEvent(bool mouseDown,
180									const BMessage* keyMessage, BList* outList,
181									BMessage* mouseMessage);
182
183private:
184				int32			fWhichButtons;
185};
186
187
188// This class sends a single mouse down event when activated, causing the mouse
189// pointer to enter a "sticky down" state. Good for some things(like dragging).
190class _EXPORT MouseDownCommandActuator;
191class MouseDownCommandActuator : public MouseCommandActuator {
192public:
193								MouseDownCommandActuator(int32 argc,
194									char** argv);
195								MouseDownCommandActuator(BMessage* from);
196								~MouseDownCommandActuator();
197
198		virtual	filter_result	KeyEvent(const BMessage* keyMessage,
199									BList* outList, void** setAsyncData,
200									BMessage* mouseMessage);
201		virtual	status_t 		Archive(BMessage* into, bool deep = true)
202									const;
203		static	BArchivable*	Instantiate(BMessage* from);
204};
205
206
207// This class sends a single mouse down up when activated, releasing any
208// previously set "sticky down" state. Good for some things (like dragging).
209class _EXPORT MouseUpCommandActuator;
210class MouseUpCommandActuator : public MouseCommandActuator {
211public:
212								MouseUpCommandActuator(int32 argc,
213									char** argv);
214								MouseUpCommandActuator(BMessage* from);
215								~MouseUpCommandActuator();
216
217	virtual filter_result 		KeyEvent(const BMessage* keyMessage,
218									BList* outList, void** setAsyncData,
219									BMessage* mouseMessage);
220
221	virtual status_t 			Archive(BMessage* into,
222									bool deep = true) const;
223	static 	BArchivable* 		Instantiate(BMessage* from);
224};
225
226
227// This class will send B_MOUSE_UP and B_MOUSE_DOWN events whenever B_KEY_UP or
228// B_KEY_DOWN events are detected for its key This way a key can act sort of
229// like a mouse button.
230class _EXPORT MouseButtonCommandActuator;
231class MouseButtonCommandActuator : public MouseCommandActuator {
232public:
233								MouseButtonCommandActuator(int32 argc,
234									char** argv);
235								MouseButtonCommandActuator(BMessage* from);
236								~MouseButtonCommandActuator();
237
238	virtual filter_result 		KeyEvent(const BMessage* keyMessage,
239									BList* outList, void** setAsyncData,
240									BMessage* mouseMessage);
241
242	virtual status_t 			Archive(BMessage* into,
243									bool deep = true) const;
244	static 	BArchivable* 		Instantiate(BMessage* from);
245
246private:
247			bool 				fKeyDown ;
248};
249
250
251// Base class for some actuators that control the position of the mouse pointer
252class _EXPORT MoveMouseCommandActuator;
253class MoveMouseCommandActuator : public CommandActuator {
254public:
255								MoveMouseCommandActuator(int32 argc,
256									char** argv);
257								MoveMouseCommandActuator(BMessage* from);
258								~MoveMouseCommandActuator();
259
260	virtual	status_t			Archive(BMessage* into, bool deep) const;
261
262protected:
263			void 				CalculateCoords(float& setX, float& setY)
264									const;
265			BMessage* 			CreateMouseMessage(const BMessage* original,
266									BPoint where, BList* outList) const;
267
268private:
269			void 				_ParseArg(const char* arg, float& setPercent,
270									float& setPixels) const;
271
272			float 				fXPercent;
273			float 				fYPercent;
274			float 				fXPixels;
275			float 				fYPixels;
276};
277
278
279// Actuator that specifies multiple sub-actuators to be executed in series
280class _EXPORT MultiCommandActuator;
281class MultiCommandActuator : public CommandActuator {
282public:
283								MultiCommandActuator(int32 argc, char** argv);
284								MultiCommandActuator(BMessage* from);
285								~MultiCommandActuator();
286
287	virtual status_t			Archive(BMessage* into, bool deep) const;
288	virtual filter_result		KeyEvent(const BMessage* keyMessage,
289									BList* outList, void** asyncData,
290									BMessage* mouseMessage);
291	virtual void				KeyEventAsync(const BMessage* keyupMessage,
292									void * asyncData);
293	static	BArchivable*		Instantiate(BMessage* from);
294
295private:
296			BList				fSubActuators;
297};
298
299
300// Actuator for moving a mouse relative to its current position
301class _EXPORT MoveMouseToCommandActuator;
302class MoveMouseToCommandActuator : public MoveMouseCommandActuator {
303public:
304								MoveMouseToCommandActuator(int32 argc,
305									char** argv);
306								MoveMouseToCommandActuator(BMessage* from);
307								~MoveMouseToCommandActuator();
308
309	virtual	filter_result		KeyEvent(const BMessage* keyMessage, BList* outList
310									, void** setAsyncData,
311									BMessage* mouseMessage);
312
313	virtual status_t			Archive(BMessage* into, bool deep = true)
314									const;
315	static BArchivable*			Instantiate(BMessage* from);
316};
317
318
319// Actuator for moving a mouse relative to its current position
320class _EXPORT MoveMouseByCommandActuator;
321class MoveMouseByCommandActuator : public MoveMouseCommandActuator {
322public:
323									MoveMouseByCommandActuator(int32 argc,
324										char** argv);
325									MoveMouseByCommandActuator(BMessage* from);
326									~MoveMouseByCommandActuator();
327
328	virtual filter_result 			KeyEvent(const BMessage* keyMessage,
329										BList* outList, void** setAsyncData,
330										BMessage* mouseMessage);
331	virtual status_t 				Archive(BMessage * into, bool deep = true)
332										const;
333	static 	BArchivable*			Instantiate(BMessage * from);
334};
335
336
337// Actuator to send BMessage to an application - written by Daniel Wesslen
338class _EXPORT SendMessageCommandActuator;
339class SendMessageCommandActuator : public CommandActuator {
340public:
341									SendMessageCommandActuator(int32 argc,
342										char** argv);
343									SendMessageCommandActuator(BMessage* from);
344									~SendMessageCommandActuator();
345
346	virtual filter_result			KeyEvent(const BMessage* keyMessage,
347										BList* outList, void** setAsyncData,
348										BMessage* mouseMessage);
349	virtual void					KeyEventAsync(const BMessage* keyupMessage,
350										void* asyncData);
351	virtual status_t				Archive(BMessage* into, bool deep = true)
352										const;
353	static 	BArchivable*			Instantiate(BMessage * from);
354
355private:
356			void					_ParseFloatArgs(float* outArgs, int maxArgs
357										, const char* str) const;
358
359			BString					fSignature;
360			BMessage				fSendMessage;
361};
362
363
364#endif	// _COMMAND_ACTUATORS_H
365