1be2b0592SFredrik Modeen/*
21ecf19b8SJohn Scipione * Copyright 1999-2009 Haiku, Inc. All rights reserved.
3be2b0592SFredrik Modeen * Distributed under the terms of the MIT License.
4be2b0592SFredrik Modeen *
5be2b0592SFredrik Modeen * Authors:
6be2b0592SFredrik Modeen *		Jeremy Friesner
7be2b0592SFredrik Modeen *		Fredrik Mod��en
8be2b0592SFredrik Modeen */
9be2b0592SFredrik Modeen
10be2b0592SFredrik Modeen
11be2b0592SFredrik Modeen#include "CommandActuators.h"
12be2b0592SFredrik Modeen
13be2b0592SFredrik Modeen
14be2b0592SFredrik Modeen#include <stdio.h>
15be2b0592SFredrik Modeen#include <stdlib.h>
163aeed660SJérôme Duval#include <strings.h>
17be2b0592SFredrik Modeen
18be2b0592SFredrik Modeen#include <String.h>
19be2b0592SFredrik Modeen#include <Roster.h>
20be2b0592SFredrik Modeen#include <Alert.h>
21be2b0592SFredrik Modeen#include <Screen.h>
22be2b0592SFredrik Modeen#include <Rect.h>
23be2b0592SFredrik Modeen#include <View.h>
24be2b0592SFredrik Modeen#include <Directory.h>
25be2b0592SFredrik Modeen#include <Entry.h>
26be2b0592SFredrik Modeen#include <List.h>
27be2b0592SFredrik Modeen#include <Beep.h>
28be2b0592SFredrik Modeen
29be2b0592SFredrik Modeen
30be2b0592SFredrik Modeen#include "ParseCommandLine.h"
31be2b0592SFredrik Modeen#include "KeyInfos.h"
32be2b0592SFredrik Modeen
33be2b0592SFredrik Modeen#define IS_KEY_DOWN(msg) ((msg->what == B_KEY_DOWN) \
34be2b0592SFredrik Modeen	|| (msg->what == B_UNMAPPED_KEY_DOWN))
35be2b0592SFredrik Modeen
361ecf19b8SJohn Scipione
371ecf19b8SJohn Scipione// factory function
38fcc3e627SStephan AßmusCommandActuator*
39be2b0592SFredrik ModeenCreateCommandActuator(const char* command)
40be2b0592SFredrik Modeen{
41fcc3e627SStephan Aßmus	CommandActuator* act = NULL;
42be2b0592SFredrik Modeen	int32 argc;
43be2b0592SFredrik Modeen	char** argv = ParseArgvFromString(command, argc);
44be2b0592SFredrik Modeen	if (command[0] == '*') {
45be2b0592SFredrik Modeen		if (argc > 0) {
46be2b0592SFredrik Modeen			char* c = argv[0] + 1;
47fcc3e627SStephan Aßmus			if (strcmp(c, "InsertString") == 0)
48be2b0592SFredrik Modeen				act = new KeyStrokeSequenceCommandActuator(argc, argv);
49be2b0592SFredrik Modeen			else if (strcmp(c, "MoveMouse") == 0)
50be2b0592SFredrik Modeen				act = new MoveMouseByCommandActuator(argc, argv);
51be2b0592SFredrik Modeen			else if (strcmp(c, "MoveMouseTo") == 0)
52be2b0592SFredrik Modeen				act = new MoveMouseToCommandActuator(argc, argv);
53fcc3e627SStephan Aßmus			else if (strcmp(c, "MouseButton") == 0)
54be2b0592SFredrik Modeen				act = new MouseButtonCommandActuator(argc, argv);
55be2b0592SFredrik Modeen			else if (strcmp(c, "LaunchHandler") == 0)
56be2b0592SFredrik Modeen				act = new MIMEHandlerCommandActuator(argc, argv);
57fcc3e627SStephan Aßmus			else if (strcmp(c, "Multi") == 0)
58be2b0592SFredrik Modeen				act = new MultiCommandActuator(argc, argv);
59fcc3e627SStephan Aßmus			else if (strcmp(c, "MouseDown") == 0)
60be2b0592SFredrik Modeen				act = new MouseDownCommandActuator(argc, argv);
61fcc3e627SStephan Aßmus			else if (strcmp(c, "MouseUp") == 0)
62be2b0592SFredrik Modeen				act = new MouseUpCommandActuator(argc, argv);
63fcc3e627SStephan Aßmus			else if (strcmp(c, "SendMessage") == 0)
64be2b0592SFredrik Modeen				act = new SendMessageCommandActuator(argc, argv);
65be2b0592SFredrik Modeen			else
66be2b0592SFredrik Modeen				act = new BeepCommandActuator(argc, argv);
67be2b0592SFredrik Modeen		}
68be2b0592SFredrik Modeen	} else
69be2b0592SFredrik Modeen		act = new LaunchCommandActuator(argc, argv);
70be2b0592SFredrik Modeen
71be2b0592SFredrik Modeen	FreeArgv(argv);
72be2b0592SFredrik Modeen	return act;
73be2b0592SFredrik Modeen}
74be2b0592SFredrik Modeen
75be2b0592SFredrik Modeen
761ecf19b8SJohn Scipione//	#pragma mark - CommandActuator
771ecf19b8SJohn Scipione
781ecf19b8SJohn Scipione
79be2b0592SFredrik ModeenCommandActuator::CommandActuator(int32 argc, char** argv)
80be2b0592SFredrik Modeen{
81be2b0592SFredrik Modeen}
82be2b0592SFredrik Modeen
83be2b0592SFredrik Modeen
84be2b0592SFredrik ModeenCommandActuator::CommandActuator(BMessage* from)
85be2b0592SFredrik Modeen	:
86be2b0592SFredrik Modeen	BArchivable(from)
87be2b0592SFredrik Modeen{
88be2b0592SFredrik Modeen}
89be2b0592SFredrik Modeen
90be2b0592SFredrik Modeen
91be2b0592SFredrik Modeenstatus_t
92be2b0592SFredrik ModeenCommandActuator::Archive(BMessage* into, bool deep) const
93be2b0592SFredrik Modeen{
94be2b0592SFredrik Modeen	status_t ret = BArchivable::Archive(into, deep);
95be2b0592SFredrik Modeen	return ret;
96be2b0592SFredrik Modeen}
97be2b0592SFredrik Modeen
98be2b0592SFredrik Modeen
991ecf19b8SJohn Scipione//	#pragma mark - LaunchCommandActuator
1001ecf19b8SJohn Scipione
1011ecf19b8SJohn Scipione
102be2b0592SFredrik ModeenLaunchCommandActuator::LaunchCommandActuator(int32 argc, char** argv)
103be2b0592SFredrik Modeen	:
104fcc3e627SStephan Aßmus	CommandActuator(argc, argv),
105fcc3e627SStephan Aßmus	fArgv(CloneArgv(argv)),
106be2b0592SFredrik Modeen	fArgc(argc)
107be2b0592SFredrik Modeen{
108be2b0592SFredrik Modeen}
109be2b0592SFredrik Modeen
110be2b0592SFredrik Modeen
111be2b0592SFredrik ModeenLaunchCommandActuator::LaunchCommandActuator(BMessage* from)
112be2b0592SFredrik Modeen	:
113be2b0592SFredrik Modeen	CommandActuator(from)
114be2b0592SFredrik Modeen{
115be2b0592SFredrik Modeen	BList argList;
116be2b0592SFredrik Modeen	const char* temp;
117be2b0592SFredrik Modeen	int idx = 0;
1181ecf19b8SJohn Scipione	while (from->FindString("largv", idx++, &temp) == B_OK) {
119be2b0592SFredrik Modeen		if (temp) {
120be2b0592SFredrik Modeen			char* copy = new char[strlen(temp) + 1];
121be2b0592SFredrik Modeen			strcpy(copy, temp);
122be2b0592SFredrik Modeen			argList.AddItem(copy);
123be2b0592SFredrik Modeen		}
124be2b0592SFredrik Modeen	}
125be2b0592SFredrik Modeen
126be2b0592SFredrik Modeen	fArgc = argList.CountItems();
127be2b0592SFredrik Modeen	fArgv = new char*[fArgc+ 1];
128fcc3e627SStephan Aßmus
129fcc3e627SStephan Aßmus	for (int i = 0; i < fArgc; i++)
130be2b0592SFredrik Modeen		fArgv[i] = (char*) argList.ItemAt(i);
131fcc3e627SStephan Aßmus
132be2b0592SFredrik Modeen	fArgv[fArgc] = NULL;// terminate the array
133be2b0592SFredrik Modeen}
134be2b0592SFredrik Modeen
135be2b0592SFredrik Modeen
136be2b0592SFredrik ModeenLaunchCommandActuator::~LaunchCommandActuator()
137be2b0592SFredrik Modeen{
138be2b0592SFredrik Modeen	FreeArgv(fArgv);
139be2b0592SFredrik Modeen}
140be2b0592SFredrik Modeen
141be2b0592SFredrik Modeen
142be2b0592SFredrik Modeenfilter_result
1431ecf19b8SJohn ScipioneLaunchCommandActuator::KeyEvent(const BMessage* keyMessage, BList* outList,
1441ecf19b8SJohn Scipione	void** setAsyncData, BMessage* mouseMessage)
145be2b0592SFredrik Modeen{
1461ecf19b8SJohn Scipione	if (IS_KEY_DOWN(keyMessage)) {
147be2b0592SFredrik Modeen		// cause KeyEventAsync() to be called asynchronously
148be2b0592SFredrik Modeen		*setAsyncData = (void*) true;
149be2b0592SFredrik Modeen	}
150be2b0592SFredrik Modeen	return B_SKIP_MESSAGE;
151be2b0592SFredrik Modeen}
152be2b0592SFredrik Modeen
153be2b0592SFredrik Modeen
154be2b0592SFredrik Modeenstatus_t
155be2b0592SFredrik ModeenLaunchCommandActuator::Archive(BMessage* into, bool deep) const
156be2b0592SFredrik Modeen{
157be2b0592SFredrik Modeen	status_t ret = CommandActuator::Archive(into, deep);
158fcc3e627SStephan Aßmus
159be2b0592SFredrik Modeen	for (int i = 0; i < fArgc; i++)
160be2b0592SFredrik Modeen		into->AddString("largv", fArgv[i]);
161be2b0592SFredrik Modeen
162be2b0592SFredrik Modeen	return ret;
163be2b0592SFredrik Modeen}
164be2b0592SFredrik Modeen
165be2b0592SFredrik Modeen
166be2b0592SFredrik ModeenBArchivable*
1671ecf19b8SJohn ScipioneLaunchCommandActuator::Instantiate(BMessage* from)
168be2b0592SFredrik Modeen{
169be2b0592SFredrik Modeen	if (validate_instantiation(from, "LaunchCommandActuator"))
170be2b0592SFredrik Modeen		return new LaunchCommandActuator(from);
171be2b0592SFredrik Modeen	else
172be2b0592SFredrik Modeen		return NULL;
173be2b0592SFredrik Modeen}
174be2b0592SFredrik Modeen
175be2b0592SFredrik Modeen
176be2b0592SFredrik Modeenvoid
1771ecf19b8SJohn ScipioneLaunchCommandActuator::KeyEventAsync(const BMessage* keyMessage,
178be2b0592SFredrik Modeen	void* asyncData)
179be2b0592SFredrik Modeen{
1801ecf19b8SJohn Scipione	if (be_roster == NULL)
1811ecf19b8SJohn Scipione		return;
1821ecf19b8SJohn Scipione
1831ecf19b8SJohn Scipione	status_t result = B_OK;
1841ecf19b8SJohn Scipione	BString string;
1851ecf19b8SJohn Scipione	if (fArgc < 1)
1861ecf19b8SJohn Scipione		string << "You didn't specify a command for this hotkey.";
1871ecf19b8SJohn Scipione	else if ((result = LaunchCommand(fArgv, fArgc)) != B_OK) {
1881ecf19b8SJohn Scipione		string << "Can't launch " << fArgv[0];
1891ecf19b8SJohn Scipione		string << ", no such file exists.";
1901ecf19b8SJohn Scipione		string << " Please check your Shortcuts settings.";
1911ecf19b8SJohn Scipione	}
192be2b0592SFredrik Modeen
1931ecf19b8SJohn Scipione	if (fArgc < 1 || result != B_OK) {
1941ecf19b8SJohn Scipione		BAlert* alert = new BAlert("Shortcuts launcher error",
1951ecf19b8SJohn Scipione			string.String(), "OK");
1961ecf19b8SJohn Scipione		alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
1971ecf19b8SJohn Scipione		alert->Go(NULL);
198be2b0592SFredrik Modeen	}
199be2b0592SFredrik Modeen}
200be2b0592SFredrik Modeen
201be2b0592SFredrik Modeen
2021ecf19b8SJohn Scipione//	#pragma mark - MouseCommandActuator
2031ecf19b8SJohn Scipione
2041ecf19b8SJohn Scipione
205be2b0592SFredrik ModeenMouseCommandActuator::MouseCommandActuator(int32 argc, char** argv)
206be2b0592SFredrik Modeen	:
207fcc3e627SStephan Aßmus	CommandActuator(argc, argv),
208be2b0592SFredrik Modeen	fWhichButtons(B_PRIMARY_MOUSE_BUTTON)
209be2b0592SFredrik Modeen{
210be2b0592SFredrik Modeen	if (argc > 1) {
211be2b0592SFredrik Modeen		fWhichButtons = 0;
212be2b0592SFredrik Modeen
213be2b0592SFredrik Modeen		for (int i = 1; i < argc; i++) {
214be2b0592SFredrik Modeen			int buttonNumber = atoi(argv[i]);
215fcc3e627SStephan Aßmus
216be2b0592SFredrik Modeen			switch(buttonNumber) {
217fcc3e627SStephan Aßmus				case 1:
218be2b0592SFredrik Modeen					fWhichButtons |= B_PRIMARY_MOUSE_BUTTON;
219be2b0592SFredrik Modeen				break;
220be2b0592SFredrik Modeen				case 2:
221be2b0592SFredrik Modeen					fWhichButtons |= B_SECONDARY_MOUSE_BUTTON;
222be2b0592SFredrik Modeen				break;
223be2b0592SFredrik Modeen				case 3:
224be2b0592SFredrik Modeen					fWhichButtons |= B_TERTIARY_MOUSE_BUTTON;
225be2b0592SFredrik Modeen				break;
226be2b0592SFredrik Modeen			}
227be2b0592SFredrik Modeen		}
228be2b0592SFredrik Modeen	}
229be2b0592SFredrik Modeen}
230be2b0592SFredrik Modeen
231be2b0592SFredrik Modeen
232be2b0592SFredrik ModeenMouseCommandActuator::MouseCommandActuator(BMessage* from)
233be2b0592SFredrik Modeen	:
234be2b0592SFredrik Modeen	CommandActuator(from),
235be2b0592SFredrik Modeen	fWhichButtons(B_PRIMARY_MOUSE_BUTTON)
236be2b0592SFredrik Modeen{
237be2b0592SFredrik Modeen	from->FindInt32("buttons", &fWhichButtons);
238be2b0592SFredrik Modeen}
239be2b0592SFredrik Modeen
240be2b0592SFredrik Modeen
241be2b0592SFredrik ModeenMouseCommandActuator::~MouseCommandActuator()
242be2b0592SFredrik Modeen{
243be2b0592SFredrik Modeen}
244be2b0592SFredrik Modeen
245be2b0592SFredrik Modeen
246be2b0592SFredrik Modeenstatus_t
247be2b0592SFredrik ModeenMouseCommandActuator::Archive(BMessage* into, bool deep) const
248be2b0592SFredrik Modeen{
249be2b0592SFredrik Modeen	status_t ret = CommandActuator::Archive(into, deep);
250fcc3e627SStephan Aßmus	into->AddInt32("buttons", fWhichButtons);
251be2b0592SFredrik Modeen	return ret;
252be2b0592SFredrik Modeen}
253be2b0592SFredrik Modeen
254be2b0592SFredrik Modeen
255be2b0592SFredrik Modeenint32
256be2b0592SFredrik ModeenMouseCommandActuator::_GetWhichButtons() const
257be2b0592SFredrik Modeen{
258be2b0592SFredrik Modeen	return fWhichButtons;
259be2b0592SFredrik Modeen}
260be2b0592SFredrik Modeen
261be2b0592SFredrik Modeen
262be2b0592SFredrik Modeenvoid
263fcc3e627SStephan AßmusMouseCommandActuator::_GenerateMouseButtonEvent(bool mouseDown,
2641ecf19b8SJohn Scipione	const BMessage* keyMessage, BList* outList, BMessage* mouseMessage)
265fcc3e627SStephan Aßmus{
2661ecf19b8SJohn Scipione	BMessage* fakeMouse = new BMessage(*mouseMessage);
267be2b0592SFredrik Modeen	fakeMouse->what = mouseDown ? B_MOUSE_DOWN : B_MOUSE_UP;
268fcc3e627SStephan Aßmus
269be2b0592SFredrik Modeen	// Update the buttons to reflect which mouse buttons we are faking
270be2b0592SFredrik Modeen	fakeMouse->RemoveName("buttons");
271be2b0592SFredrik Modeen
272fcc3e627SStephan Aßmus	if (mouseDown)
273fcc3e627SStephan Aßmus		fakeMouse->AddInt32("buttons", fWhichButtons);
274fcc3e627SStephan Aßmus
275fcc3e627SStephan Aßmus	// Trey sez you gotta keep then "when"'s increasing if you want
276be2b0592SFredrik Modeen	// click & drag to work!
277be2b0592SFredrik Modeen	int64 when;
278fcc3e627SStephan Aßmus
279be2b0592SFredrik Modeen	const BMessage* lastMessage;
2801ecf19b8SJohn Scipione	if (outList->CountItems() > 0) {
2811ecf19b8SJohn Scipione		int32 last = outList->CountItems() - 1;
2821ecf19b8SJohn Scipione		lastMessage = (const BMessage*)outList->ItemAt(last);
283be2b0592SFredrik Modeen	} else
2841ecf19b8SJohn Scipione		lastMessage = keyMessage;
285fcc3e627SStephan Aßmus
2861ecf19b8SJohn Scipione	if (lastMessage->FindInt64("when", &when) == B_OK) {
287be2b0592SFredrik Modeen		when++;
288be2b0592SFredrik Modeen		fakeMouse->RemoveName("when");
289be2b0592SFredrik Modeen		fakeMouse->AddInt64("when", when);
290be2b0592SFredrik Modeen	}
2911ecf19b8SJohn Scipione
2921ecf19b8SJohn Scipione	outList->AddItem(fakeMouse);
293be2b0592SFredrik Modeen}
294be2b0592SFredrik Modeen
295be2b0592SFredrik Modeen
2961ecf19b8SJohn Scipione//	#pragma mark - MouseDownCommandActuator
2971ecf19b8SJohn Scipione
2981ecf19b8SJohn Scipione
299be2b0592SFredrik ModeenMouseDownCommandActuator::MouseDownCommandActuator(int32 argc, char** argv)
300be2b0592SFredrik Modeen	:
301be2b0592SFredrik Modeen	MouseCommandActuator(argc, argv)
302be2b0592SFredrik Modeen{
303be2b0592SFredrik Modeen}
304be2b0592SFredrik Modeen
305be2b0592SFredrik Modeen
306be2b0592SFredrik ModeenMouseDownCommandActuator::MouseDownCommandActuator(BMessage* from)
307be2b0592SFredrik Modeen	:
308be2b0592SFredrik Modeen	MouseCommandActuator(from)
309be2b0592SFredrik Modeen{
310be2b0592SFredrik Modeen}
311be2b0592SFredrik Modeen
312be2b0592SFredrik Modeen
313be2b0592SFredrik ModeenMouseDownCommandActuator::~MouseDownCommandActuator()
314be2b0592SFredrik Modeen{
315be2b0592SFredrik Modeen}
316be2b0592SFredrik Modeen
317be2b0592SFredrik Modeen
318be2b0592SFredrik Modeenfilter_result
3191ecf19b8SJohn ScipioneMouseDownCommandActuator::KeyEvent(const BMessage* keyMessage, BList* outList,
3201ecf19b8SJohn Scipione	void** setAsyncData, BMessage* mouseMessage)
321be2b0592SFredrik Modeen{
3221ecf19b8SJohn Scipione	if (IS_KEY_DOWN(keyMessage))
3231ecf19b8SJohn Scipione		_GenerateMouseButtonEvent(true, keyMessage, outList, mouseMessage);
324fcc3e627SStephan Aßmus
325be2b0592SFredrik Modeen	return B_DISPATCH_MESSAGE;
326be2b0592SFredrik Modeen}
327be2b0592SFredrik Modeen
328be2b0592SFredrik Modeen
329be2b0592SFredrik Modeenstatus_t
330be2b0592SFredrik ModeenMouseDownCommandActuator::Archive(BMessage* into, bool deep) const
331be2b0592SFredrik Modeen{
332be2b0592SFredrik Modeen	return MouseCommandActuator::Archive(into, deep);
333be2b0592SFredrik Modeen}
334be2b0592SFredrik Modeen
335be2b0592SFredrik Modeen
336be2b0592SFredrik ModeenBArchivable*
3371ecf19b8SJohn ScipioneMouseDownCommandActuator::Instantiate(BMessage* from)
338be2b0592SFredrik Modeen{
339fcc3e627SStephan Aßmus	if (validate_instantiation(from, "MouseDownCommandActuator"))
340be2b0592SFredrik Modeen		return new MouseDownCommandActuator(from);
341be2b0592SFredrik Modeen	else
342be2b0592SFredrik Modeen		return NULL;
343be2b0592SFredrik Modeen}
344be2b0592SFredrik Modeen
345be2b0592SFredrik Modeen
3461ecf19b8SJohn Scipione//	#pragma mark - MouseUpCommandActuator
3471ecf19b8SJohn Scipione
3481ecf19b8SJohn Scipione
349be2b0592SFredrik ModeenMouseUpCommandActuator::MouseUpCommandActuator(int32 argc, char** argv)
350be2b0592SFredrik Modeen	:
351be2b0592SFredrik Modeen	MouseCommandActuator(argc, argv)
352be2b0592SFredrik Modeen{
353be2b0592SFredrik Modeen}
354be2b0592SFredrik Modeen
355be2b0592SFredrik Modeen
356be2b0592SFredrik ModeenMouseUpCommandActuator::MouseUpCommandActuator(BMessage* from)
357be2b0592SFredrik Modeen	:
358be2b0592SFredrik Modeen	MouseCommandActuator(from)
359be2b0592SFredrik Modeen{
360be2b0592SFredrik Modeen}
361be2b0592SFredrik Modeen
362be2b0592SFredrik Modeen
363be2b0592SFredrik ModeenMouseUpCommandActuator::~MouseUpCommandActuator()
364be2b0592SFredrik Modeen{
365be2b0592SFredrik Modeen}
366be2b0592SFredrik Modeen
367be2b0592SFredrik Modeen
368be2b0592SFredrik Modeenfilter_result
3691ecf19b8SJohn ScipioneMouseUpCommandActuator::KeyEvent(const BMessage* keyMessage, BList* outList,
3701ecf19b8SJohn Scipione	void** setAsyncData, BMessage* mouseMessage)
371be2b0592SFredrik Modeen{
3721ecf19b8SJohn Scipione	if (IS_KEY_DOWN(keyMessage))
3731ecf19b8SJohn Scipione		_GenerateMouseButtonEvent(false, keyMessage, outList, mouseMessage);
3741ecf19b8SJohn Scipione
375be2b0592SFredrik Modeen	return B_DISPATCH_MESSAGE;
376be2b0592SFredrik Modeen}
377be2b0592SFredrik Modeen
378be2b0592SFredrik Modeen
379be2b0592SFredrik Modeenstatus_t
380be2b0592SFredrik ModeenMouseUpCommandActuator::Archive(BMessage* into, bool deep) const
381be2b0592SFredrik Modeen{
382be2b0592SFredrik Modeen	return MouseCommandActuator::Archive(into, deep);
383be2b0592SFredrik Modeen}
384be2b0592SFredrik Modeen
385be2b0592SFredrik Modeen
386be2b0592SFredrik ModeenBArchivable*
3871ecf19b8SJohn ScipioneMouseUpCommandActuator::Instantiate(BMessage* from)
388be2b0592SFredrik Modeen{
389fcc3e627SStephan Aßmus	if (validate_instantiation(from, "MouseUpCommandActuator"))
390be2b0592SFredrik Modeen		return new MouseUpCommandActuator(from);
391be2b0592SFredrik Modeen	else
392be2b0592SFredrik Modeen		return NULL;
393be2b0592SFredrik Modeen}
394be2b0592SFredrik Modeen
395be2b0592SFredrik Modeen
3961ecf19b8SJohn Scipione//	#pragma mark - MouseButtonCommandActuator
3971ecf19b8SJohn Scipione
3981ecf19b8SJohn Scipione
399be2b0592SFredrik ModeenMouseButtonCommandActuator::MouseButtonCommandActuator(int32 argc, char** argv)
400be2b0592SFredrik Modeen	:
401be2b0592SFredrik Modeen	MouseCommandActuator(argc, argv),
402be2b0592SFredrik Modeen	fKeyDown(false)
403be2b0592SFredrik Modeen{
404be2b0592SFredrik Modeen}
405be2b0592SFredrik Modeen
406be2b0592SFredrik Modeen
407be2b0592SFredrik ModeenMouseButtonCommandActuator::MouseButtonCommandActuator(BMessage* from)
408be2b0592SFredrik Modeen	:
409be2b0592SFredrik Modeen	MouseCommandActuator(from),
410be2b0592SFredrik Modeen	fKeyDown(false)
411be2b0592SFredrik Modeen{
412be2b0592SFredrik Modeen}
413be2b0592SFredrik Modeen
414be2b0592SFredrik Modeen
415be2b0592SFredrik ModeenMouseButtonCommandActuator::~MouseButtonCommandActuator()
416be2b0592SFredrik Modeen{
417be2b0592SFredrik Modeen}
418be2b0592SFredrik Modeen
419be2b0592SFredrik Modeen
420be2b0592SFredrik Modeenfilter_result
4211ecf19b8SJohn ScipioneMouseButtonCommandActuator::KeyEvent(const BMessage* keyMessage, BList* outList,
4221ecf19b8SJohn Scipione	void** setAsyncData, BMessage* mouseMessage)
423be2b0592SFredrik Modeen{
4241ecf19b8SJohn Scipione	if (IS_KEY_DOWN(keyMessage) != fKeyDown) {
4251ecf19b8SJohn Scipione		_GenerateMouseButtonEvent(IS_KEY_DOWN(keyMessage), keyMessage, outList,
4261ecf19b8SJohn Scipione			mouseMessage);
4271ecf19b8SJohn Scipione		fKeyDown = IS_KEY_DOWN(keyMessage);
4281ecf19b8SJohn Scipione
429be2b0592SFredrik Modeen		return B_DISPATCH_MESSAGE;
4301ecf19b8SJohn Scipione	} else {
431fcc3e627SStephan Aßmus		// This will handle key-repeats, which we don't want turned into lots
432be2b0592SFredrik Modeen		// of B_MOUSE_DOWN messages.
433be2b0592SFredrik Modeen		return B_SKIP_MESSAGE;
4341ecf19b8SJohn Scipione	}
435be2b0592SFredrik Modeen}
436be2b0592SFredrik Modeen
437be2b0592SFredrik Modeen
438be2b0592SFredrik Modeenstatus_t
439be2b0592SFredrik ModeenMouseButtonCommandActuator::Archive(BMessage* into, bool deep) const
440be2b0592SFredrik Modeen{
441be2b0592SFredrik Modeen	return MouseCommandActuator::Archive(into, deep);
442be2b0592SFredrik Modeen}
443be2b0592SFredrik Modeen
444be2b0592SFredrik Modeen
445be2b0592SFredrik ModeenBArchivable*
4461ecf19b8SJohn ScipioneMouseButtonCommandActuator::Instantiate(BMessage* from)
447be2b0592SFredrik Modeen{
448fcc3e627SStephan Aßmus	if (validate_instantiation(from, "MouseButtonCommandActuator"))
449be2b0592SFredrik Modeen		return new MouseButtonCommandActuator(from);
450be2b0592SFredrik Modeen	else
451be2b0592SFredrik Modeen		return NULL;
452be2b0592SFredrik Modeen}
453be2b0592SFredrik Modeen
454be2b0592SFredrik Modeen
4551ecf19b8SJohn Scipione//	#pragma mark - KeyStrokeSequenceCommandActuator
4561ecf19b8SJohn Scipione
4571ecf19b8SJohn Scipione
458fcc3e627SStephan AßmusKeyStrokeSequenceCommandActuator::KeyStrokeSequenceCommandActuator(int32 argc,
459be2b0592SFredrik Modeen	char** argv)
460be2b0592SFredrik Modeen	:
461be2b0592SFredrik Modeen	CommandActuator(argc, argv)
462be2b0592SFredrik Modeen{
463be2b0592SFredrik Modeen	for (int s = 1; s < argc; s++) {
464be2b0592SFredrik Modeen		fSequence.Append(argv[s]);
465be2b0592SFredrik Modeen		if (s < argc - 1)
466be2b0592SFredrik Modeen			fSequence.Append(" ");
467be2b0592SFredrik Modeen	}
468be2b0592SFredrik Modeen
469be2b0592SFredrik Modeen	// Find any insert-unicode-here sequences and replace them with spaces...
470be2b0592SFredrik Modeen	int32 nextStart;
471be2b0592SFredrik Modeen	while ((nextStart = fSequence.FindFirst("$$")) >= 0) {
472be2b0592SFredrik Modeen		int32 nextEnd = fSequence.FindFirst("$$", nextStart + 2);
473be2b0592SFredrik Modeen		if (nextEnd >= 0) {
474be2b0592SFredrik Modeen			uint32 customKey= 0;
475be2b0592SFredrik Modeen			int32 unicodeVal= 0;
476be2b0592SFredrik Modeen			uint32 customMods = 0;
477fcc3e627SStephan Aßmus			BString sub;
478be2b0592SFredrik Modeen			fSequence.CopyInto(sub, nextStart + 2, nextEnd-(nextStart + 2));
479be2b0592SFredrik Modeen			sub.ToLower();
480fcc3e627SStephan Aßmus
481be2b0592SFredrik Modeen			if ((sub.FindFirst('-') >= 0) || ((sub.Length() > 0)
482be2b0592SFredrik Modeen				&& ((sub.String()[0] < '0') || (sub.String()[0] > '9')))) {
483fcc3e627SStephan Aßmus
484be2b0592SFredrik Modeen				const char* s = sub.String();
485be2b0592SFredrik Modeen				while (*s == '-') s++;// go past any initial dashes
486be2b0592SFredrik Modeen
487be2b0592SFredrik Modeen				bool lastWasDash = true;
488fcc3e627SStephan Aßmus				while (*s) {
489be2b0592SFredrik Modeen					if (lastWasDash) {
490be2b0592SFredrik Modeen						if (strncmp(s, "shift",5) == 0)
491be2b0592SFredrik Modeen							customMods |=B_LEFT_SHIFT_KEY| B_SHIFT_KEY;
492fcc3e627SStephan Aßmus						else if (strncmp(s, "leftsh", 6) == 0)
493be2b0592SFredrik Modeen							customMods |=B_LEFT_SHIFT_KEY| B_SHIFT_KEY;
494fcc3e627SStephan Aßmus						else if (strncmp(s, "rightsh",7) == 0)
495be2b0592SFredrik Modeen							customMods |=B_RIGHT_SHIFT_KEY | B_SHIFT_KEY;
496fcc3e627SStephan Aßmus						else if (strncmp(s, "alt",3) == 0)
497be2b0592SFredrik Modeen							customMods |=B_LEFT_COMMAND_KEY| B_COMMAND_KEY;
498fcc3e627SStephan Aßmus						else if (strncmp(s, "leftalt",7) == 0)
499be2b0592SFredrik Modeen							customMods |=B_LEFT_COMMAND_KEY| B_COMMAND_KEY;
500fcc3e627SStephan Aßmus						else if (strncmp(s, "rightalt", 8) == 0)
501be2b0592SFredrik Modeen							customMods |=B_RIGHT_COMMAND_KEY | B_COMMAND_KEY;
502fcc3e627SStephan Aßmus						else if (strncmp(s, "com",3) == 0)
503be2b0592SFredrik Modeen							customMods |=B_LEFT_COMMAND_KEY| B_COMMAND_KEY;
504fcc3e627SStephan Aßmus						else if (strncmp(s, "leftcom",7) == 0)
505be2b0592SFredrik Modeen							customMods |=B_LEFT_COMMAND_KEY| B_COMMAND_KEY;
506fcc3e627SStephan Aßmus						else if (strncmp(s, "rightcom", 8) == 0)
507be2b0592SFredrik Modeen							customMods |=B_RIGHT_COMMAND_KEY | B_COMMAND_KEY;
508fcc3e627SStephan Aßmus						else if (strncmp(s, "con",3) == 0)
509be2b0592SFredrik Modeen							customMods |=B_LEFT_CONTROL_KEY| B_CONTROL_KEY;
510fcc3e627SStephan Aßmus						else if (strncmp(s, "leftcon",7) == 0)
511be2b0592SFredrik Modeen							customMods |=B_LEFT_CONTROL_KEY| B_CONTROL_KEY;
512fcc3e627SStephan Aßmus						else if (strncmp(s, "rightcon", 8) == 0)
513be2b0592SFredrik Modeen							customMods |=B_RIGHT_CONTROL_KEY | B_CONTROL_KEY;
514fcc3e627SStephan Aßmus						else if (strncmp(s, "win",3) == 0)
515be2b0592SFredrik Modeen							customMods |=B_LEFT_OPTION_KEY | B_OPTION_KEY;
516fcc3e627SStephan Aßmus						else if (strncmp(s, "leftwin",7) == 0)
517be2b0592SFredrik Modeen							customMods |=B_LEFT_OPTION_KEY | B_OPTION_KEY;
518fcc3e627SStephan Aßmus						else if (strncmp(s, "rightwin", 8) == 0)
519be2b0592SFredrik Modeen							customMods |=B_RIGHT_OPTION_KEY| B_OPTION_KEY;
520fcc3e627SStephan Aßmus						else if (strncmp(s, "opt",3) == 0)
521be2b0592SFredrik Modeen							customMods |=B_LEFT_OPTION_KEY | B_OPTION_KEY;
522fcc3e627SStephan Aßmus						else if (strncmp(s, "leftopt",7) == 0)
523be2b0592SFredrik Modeen							customMods |=B_LEFT_OPTION_KEY | B_OPTION_KEY;
524fcc3e627SStephan Aßmus						else if (strncmp(s, "rightopt", 8) == 0)
525be2b0592SFredrik Modeen							customMods |=B_RIGHT_OPTION_KEY| B_OPTION_KEY;
526fcc3e627SStephan Aßmus						else if (strncmp(s, "menu", 4) == 0)
527be2b0592SFredrik Modeen							customMods |=B_MENU_KEY;
528fcc3e627SStephan Aßmus						else if (strncmp(s, "caps", 4) == 0)
529be2b0592SFredrik Modeen							customMods |=B_CAPS_LOCK;
530fcc3e627SStephan Aßmus						else if (strncmp(s, "scroll", 6) == 0)
531be2b0592SFredrik Modeen							customMods |=B_SCROLL_LOCK;
532fcc3e627SStephan Aßmus						else if (strncmp(s, "num",3) == 0)
533be2b0592SFredrik Modeen							customMods |=B_NUM_LOCK;
534be2b0592SFredrik Modeen						else if (customKey == 0) {
535be2b0592SFredrik Modeen							BString arg = s;
536be2b0592SFredrik Modeen							int32 dashIdx = arg.FindFirst('-');
537be2b0592SFredrik Modeen
538be2b0592SFredrik Modeen							if (dashIdx >= 0)
539be2b0592SFredrik Modeen								arg.Truncate(dashIdx);
540be2b0592SFredrik Modeen
541be2b0592SFredrik Modeen							uint32 key = (uint32)FindKeyCode(arg.String());
542be2b0592SFredrik Modeen
543be2b0592SFredrik Modeen							if (key > 0) {
544be2b0592SFredrik Modeen								customKey = key;
545fcc3e627SStephan Aßmus								const char* u = GetKeyUTF8(key);
546be2b0592SFredrik Modeen
547be2b0592SFredrik Modeen								//Parse the UTF8 back into an int32
548be2b0592SFredrik Modeen								switch(strlen(u)) {
549be2b0592SFredrik Modeen									case 1:
550be2b0592SFredrik Modeen										unicodeVal = ((uint32)(u[0]&0x7F));
551be2b0592SFredrik Modeen										break;
552be2b0592SFredrik Modeen									case 2:
553fcc3e627SStephan Aßmus										unicodeVal = ((uint32)(u[1]&0x3F)) |
554be2b0592SFredrik Modeen											(((uint32)(u[0]&0x1F)) << 6);
555be2b0592SFredrik Modeen										break;
556be2b0592SFredrik Modeen									case 3:
557fcc3e627SStephan Aßmus										unicodeVal = ((uint32)(u[2]&0x3F)) |
558fcc3e627SStephan Aßmus											(((uint32)(u[1]&0x3F)) << 6) |
559be2b0592SFredrik Modeen											(((uint32)(u[0]&0x0F)) << 12);
560be2b0592SFredrik Modeen										break;
561be2b0592SFredrik Modeen									default: unicodeVal = 0;
562be2b0592SFredrik Modeen										break;
563be2b0592SFredrik Modeen								}
564be2b0592SFredrik Modeen							}
565be2b0592SFredrik Modeen						}
566be2b0592SFredrik Modeen						lastWasDash = false;
567be2b0592SFredrik Modeen					} else
568be2b0592SFredrik Modeen						lastWasDash = (*s == '-');
5691ecf19b8SJohn Scipione
570be2b0592SFredrik Modeen					s++;
571be2b0592SFredrik Modeen				}
572be2b0592SFredrik Modeen
573be2b0592SFredrik Modeen				// If we have a letter, try to make it the correct case
574eddec292SOliver Tappe				if ((unicodeVal >= 'A') && (unicodeVal <= 'Z')) {
5751ecf19b8SJohn Scipione					if ((customMods & B_SHIFT_KEY) == 0)
576be2b0592SFredrik Modeen						unicodeVal += 'a'-'A';
5771ecf19b8SJohn Scipione				} else if ((unicodeVal >= 'a') && (unicodeVal <= 'z')) {
5781ecf19b8SJohn Scipione					if ((customMods & B_SHIFT_KEY) != 0)
579be2b0592SFredrik Modeen						unicodeVal -= 'a'-'A';
5801ecf19b8SJohn Scipione				}
581be2b0592SFredrik Modeen			} else {
5821ecf19b8SJohn Scipione				unicodeVal = strtol(&(fSequence.String())[nextStart + 2],
5831ecf19b8SJohn Scipione					NULL, 0);
584be2b0592SFredrik Modeen				customMods = (uint32) -1;
585be2b0592SFredrik Modeen			}
586be2b0592SFredrik Modeen
587be2b0592SFredrik Modeen			if (unicodeVal == 0)
588be2b0592SFredrik Modeen				unicodeVal = ' ';
589be2b0592SFredrik Modeen
5901ecf19b8SJohn Scipione			BString newString = fSequence;
5911ecf19b8SJohn Scipione			newString.Truncate(nextStart);
592e971f3b1SJérôme Duval			fOverrides.AddItem((void*)(addr_t)unicodeVal);
5931ecf19b8SJohn Scipione			fOverrideOffsets.AddItem((void*)(addr_t)newString.Length());
594e971f3b1SJérôme Duval			fOverrideModifiers.AddItem((void*)(addr_t)customMods);
595e971f3b1SJérôme Duval			fOverrideKeyCodes.AddItem((void*)(addr_t)customKey);
5961ecf19b8SJohn Scipione			newString.Append((unicodeVal > 0
5971ecf19b8SJohn Scipione				&& unicodeVal < 127) ? (char)unicodeVal : ' ', 1);
5981ecf19b8SJohn Scipione			newString.Append(&fSequence.String()[nextEnd + 2]);
5991ecf19b8SJohn Scipione			fSequence = newString;
600be2b0592SFredrik Modeen		} else
601be2b0592SFredrik Modeen			break;
602be2b0592SFredrik Modeen	}
6031ecf19b8SJohn Scipione
604be2b0592SFredrik Modeen	_GenerateKeyCodes();
605be2b0592SFredrik Modeen}
606be2b0592SFredrik Modeen
607be2b0592SFredrik Modeen
608be2b0592SFredrik ModeenKeyStrokeSequenceCommandActuator::KeyStrokeSequenceCommandActuator(
609be2b0592SFredrik Modeen	BMessage* from)
610be2b0592SFredrik Modeen	:
611be2b0592SFredrik Modeen	CommandActuator(from)
612be2b0592SFredrik Modeen{
6131ecf19b8SJohn Scipione	const char* sequence;
6141ecf19b8SJohn Scipione	if (from->FindString("sequence", 0, &sequence) == B_OK)
6151ecf19b8SJohn Scipione		fSequence = sequence;
616be2b0592SFredrik Modeen
617be2b0592SFredrik Modeen	int32 temp;
6181ecf19b8SJohn Scipione	for (int32 i = 0; from->FindInt32("ooffsets", i, &temp) == B_OK; i++) {
619e971f3b1SJérôme Duval		fOverrideOffsets.AddItem((void*)(addr_t)temp);
620be2b0592SFredrik Modeen
6211ecf19b8SJohn Scipione		if (from->FindInt32("overrides", i, &temp) != B_OK)
622be2b0592SFredrik Modeen			temp = ' ';
623fcc3e627SStephan Aßmus
624e971f3b1SJérôme Duval		fOverrides.AddItem((void*)(addr_t)temp);
625be2b0592SFredrik Modeen
6261ecf19b8SJohn Scipione		if (from->FindInt32("omods", i, &temp) != B_OK)
627be2b0592SFredrik Modeen			temp = -1;
628fcc3e627SStephan Aßmus
629e971f3b1SJérôme Duval		fOverrideModifiers.AddItem((void*)(addr_t)temp);
630be2b0592SFredrik Modeen
6311ecf19b8SJohn Scipione		if (from->FindInt32("okeys", i, &temp) != B_OK)
632be2b0592SFredrik Modeen			temp = 0;
633fcc3e627SStephan Aßmus
634e971f3b1SJérôme Duval		fOverrideKeyCodes.AddItem((void*)(addr_t)temp);
635be2b0592SFredrik Modeen	}
6361ecf19b8SJohn Scipione
637be2b0592SFredrik Modeen	_GenerateKeyCodes();
638be2b0592SFredrik Modeen}
639be2b0592SFredrik Modeen
640be2b0592SFredrik Modeen
641be2b0592SFredrik ModeenKeyStrokeSequenceCommandActuator::~KeyStrokeSequenceCommandActuator()
642be2b0592SFredrik Modeen{
6431ecf19b8SJohn Scipione	delete[] fKeyCodes;
6441ecf19b8SJohn Scipione	delete[] fModCodes;
6451ecf19b8SJohn Scipione	delete[] fStates;
646be2b0592SFredrik Modeen}
647be2b0592SFredrik Modeen
648be2b0592SFredrik Modeen
649be2b0592SFredrik Modeenvoid
650be2b0592SFredrik ModeenKeyStrokeSequenceCommandActuator::_GenerateKeyCodes()
651be2b0592SFredrik Modeen{
652be2b0592SFredrik Modeen	int slen = fSequence.Length();
653be2b0592SFredrik Modeen	fKeyCodes = new int32[slen];
654be2b0592SFredrik Modeen	fModCodes = new int32[slen];
655be2b0592SFredrik Modeen	fStates = new uint8[slen * 16];
656be2b0592SFredrik Modeen
657be2b0592SFredrik Modeen	memset(fStates, 0, slen * 16);
658be2b0592SFredrik Modeen
659be2b0592SFredrik Modeen	key_map* map;
660be2b0592SFredrik Modeen	char* keys;
661be2b0592SFredrik Modeen	get_key_map(&map, &keys);
662be2b0592SFredrik Modeen	for (int i = 0; i < slen; i++) {
6631ecf19b8SJohn Scipione		uint32 overrideKey = 0;
664be2b0592SFredrik Modeen		uint32 overrideMods = (uint32)-1;
665be2b0592SFredrik Modeen		for (int32 j = fOverrideOffsets.CountItems()-1; j >= 0; j--) {
666e971f3b1SJérôme Duval			if ((int32)(addr_t)fOverrideOffsets.ItemAt(j) == i) {
667e971f3b1SJérôme Duval				overrideKey= (uint32)(addr_t) fOverrideKeyCodes.ItemAt(j);
668e971f3b1SJérôme Duval				overrideMods = (uint32)(addr_t) fOverrideModifiers.ItemAt(j);
669be2b0592SFredrik Modeen				break;
670be2b0592SFredrik Modeen			}
671be2b0592SFredrik Modeen		}
672be2b0592SFredrik Modeen
673be2b0592SFredrik Modeen		uint8* states = &fStates[i * 16];
6741ecf19b8SJohn Scipione		int32& modCode = fModCodes[i];
675be2b0592SFredrik Modeen		if (overrideKey == 0) {
676fcc3e627SStephan Aßmus			// Gotta do reverse-lookups to find out the raw keycodes for a
677be2b0592SFredrik Modeen			// given character. Expensive--there oughtta be a better way to do
678be2b0592SFredrik Modeen			// this.
679be2b0592SFredrik Modeen			char next = fSequence.ByteAt(i);
6801ecf19b8SJohn Scipione			int32 key = _LookupKeyCode(map, keys, map->normal_map, next,
6811ecf19b8SJohn Scipione				states, modCode, 0);
6821ecf19b8SJohn Scipione			if (key < 0) {
683fcc3e627SStephan Aßmus				key = _LookupKeyCode(map, keys, map->shift_map, next, states,
6841ecf19b8SJohn Scipione					modCode, B_LEFT_SHIFT_KEY | B_SHIFT_KEY);
6851ecf19b8SJohn Scipione			}
686be2b0592SFredrik Modeen
6871ecf19b8SJohn Scipione			if (key < 0) {
688fcc3e627SStephan Aßmus				key = _LookupKeyCode(map, keys, map->caps_map, next, states,
6891ecf19b8SJohn Scipione					modCode, B_CAPS_LOCK);
6901ecf19b8SJohn Scipione			}
691be2b0592SFredrik Modeen
6921ecf19b8SJohn Scipione			if (key < 0) {
693fcc3e627SStephan Aßmus				key = _LookupKeyCode(map, keys, map->caps_shift_map, next,
6941ecf19b8SJohn Scipione					states, modCode,
6951ecf19b8SJohn Scipione					B_LEFT_SHIFT_KEY | B_SHIFT_KEY | B_CAPS_LOCK);
6961ecf19b8SJohn Scipione			}
697be2b0592SFredrik Modeen
6981ecf19b8SJohn Scipione			if (key < 0) {
699fcc3e627SStephan Aßmus				key = _LookupKeyCode(map, keys, map->option_map, next, states,
7001ecf19b8SJohn Scipione					modCode, B_LEFT_OPTION_KEY | B_OPTION_KEY);
7011ecf19b8SJohn Scipione			}
702be2b0592SFredrik Modeen
7031ecf19b8SJohn Scipione			if (key < 0) {
704fcc3e627SStephan Aßmus				key = _LookupKeyCode(map, keys, map->option_shift_map, next,
7051ecf19b8SJohn Scipione					states, modCode, B_LEFT_OPTION_KEY | B_OPTION_KEY
7061ecf19b8SJohn Scipione						| B_LEFT_SHIFT_KEY | B_SHIFT_KEY);
7071ecf19b8SJohn Scipione			}
708be2b0592SFredrik Modeen
7091ecf19b8SJohn Scipione			if (key < 0) {
710fcc3e627SStephan Aßmus				key = _LookupKeyCode(map, keys, map->option_caps_map, next,
7111ecf19b8SJohn Scipione					states, modCode,
7121ecf19b8SJohn Scipione					B_LEFT_OPTION_KEY | B_OPTION_KEY | B_CAPS_LOCK);
7131ecf19b8SJohn Scipione			}
714be2b0592SFredrik Modeen
7151ecf19b8SJohn Scipione			if (key < 0) {
716fcc3e627SStephan Aßmus				key = _LookupKeyCode(map, keys, map->option_caps_shift_map,
7171ecf19b8SJohn Scipione					next, states, modCode, B_LEFT_OPTION_KEY | B_OPTION_KEY
7181ecf19b8SJohn Scipione						| B_CAPS_LOCK | B_LEFT_SHIFT_KEY | B_SHIFT_KEY);
7191ecf19b8SJohn Scipione			}
720be2b0592SFredrik Modeen
7211ecf19b8SJohn Scipione			if (key < 0) {
722be2b0592SFredrik Modeen				key = _LookupKeyCode(map, keys, map->control_map, next, states,
7231ecf19b8SJohn Scipione					modCode, B_CONTROL_KEY);
7241ecf19b8SJohn Scipione			}
725fcc3e627SStephan Aßmus
7261ecf19b8SJohn Scipione			fKeyCodes[i] = key >= 0 ? key : 0;
727be2b0592SFredrik Modeen		}
728be2b0592SFredrik Modeen
729be2b0592SFredrik Modeen		if (overrideMods != (uint32)-1) {
7301ecf19b8SJohn Scipione			modCode = (int32)overrideMods;
731be2b0592SFredrik Modeen
732be2b0592SFredrik Modeen			// Clear any bits that might have been set by the lookups...
7331ecf19b8SJohn Scipione			_SetStateBit(states, map->caps_key, false);
7341ecf19b8SJohn Scipione			_SetStateBit(states, map->scroll_key, false);
735be2b0592SFredrik Modeen			_SetStateBit(states, map->num_key, false);
7361ecf19b8SJohn Scipione			_SetStateBit(states, map->menu_key, false);
7371ecf19b8SJohn Scipione			_SetStateBit(states, map->left_shift_key, false);
738be2b0592SFredrik Modeen			_SetStateBit(states, map->right_shift_key, false);
7391ecf19b8SJohn Scipione			_SetStateBit(states, map->left_command_key, false);
740be2b0592SFredrik Modeen			_SetStateBit(states, map->right_command_key, false);
7411ecf19b8SJohn Scipione			_SetStateBit(states, map->left_control_key, false);
742be2b0592SFredrik Modeen			_SetStateBit(states, map->right_control_key, false);
743be2b0592SFredrik Modeen			_SetStateBit(states, map->left_option_key, false);
7441ecf19b8SJohn Scipione			_SetStateBit(states, map->right_option_key, false);
745be2b0592SFredrik Modeen
746be2b0592SFredrik Modeen			// And then set any bits that were specified in our override.
7471ecf19b8SJohn Scipione			if (modCode & B_CAPS_LOCK)
748be2b0592SFredrik Modeen				_SetStateBit(states, map->caps_key);
749fcc3e627SStephan Aßmus
7501ecf19b8SJohn Scipione			if (modCode & B_SCROLL_LOCK)
751be2b0592SFredrik Modeen				_SetStateBit(states, map->scroll_key);
752fcc3e627SStephan Aßmus
7531ecf19b8SJohn Scipione			if (modCode & B_NUM_LOCK)
754be2b0592SFredrik Modeen				_SetStateBit(states, map->num_key);
755fcc3e627SStephan Aßmus
7561ecf19b8SJohn Scipione			if (modCode & B_MENU_KEY)
757be2b0592SFredrik Modeen				_SetStateBit(states, map->menu_key);
758fcc3e627SStephan Aßmus
7591ecf19b8SJohn Scipione			if (modCode & B_LEFT_SHIFT_KEY)
760be2b0592SFredrik Modeen				_SetStateBit(states, map->left_shift_key);
761fcc3e627SStephan Aßmus
7621ecf19b8SJohn Scipione			if (modCode & B_RIGHT_SHIFT_KEY)
763be2b0592SFredrik Modeen				_SetStateBit(states, map->right_shift_key);
764fcc3e627SStephan Aßmus
7651ecf19b8SJohn Scipione			if (modCode & B_LEFT_COMMAND_KEY)
766be2b0592SFredrik Modeen				_SetStateBit(states, map->left_command_key);
767fcc3e627SStephan Aßmus
7681ecf19b8SJohn Scipione			if (modCode & B_RIGHT_COMMAND_KEY)
769be2b0592SFredrik Modeen				_SetStateBit(states, map->right_command_key);
770fcc3e627SStephan Aßmus
7711ecf19b8SJohn Scipione			if (modCode & B_LEFT_CONTROL_KEY)
772be2b0592SFredrik Modeen				_SetStateBit(states, map->left_control_key);
773fcc3e627SStephan Aßmus
7741ecf19b8SJohn Scipione			if (modCode & B_RIGHT_CONTROL_KEY)
775be2b0592SFredrik Modeen				_SetStateBit(states, map->right_control_key);
776fcc3e627SStephan Aßmus
7771ecf19b8SJohn Scipione			if (modCode & B_LEFT_OPTION_KEY)
778be2b0592SFredrik Modeen				_SetStateBit(states, map->left_option_key);
779fcc3e627SStephan Aßmus
7801ecf19b8SJohn Scipione			if (modCode & B_RIGHT_OPTION_KEY)
781be2b0592SFredrik Modeen				_SetStateBit(states, map->right_option_key);
782be2b0592SFredrik Modeen		}
783be2b0592SFredrik Modeen
784be2b0592SFredrik Modeen		if (overrideKey > 0) {
7851ecf19b8SJohn Scipione			if (overrideKey > 127) {
7861ecf19b8SJohn Scipione				// invalid value?
7871ecf19b8SJohn Scipione				overrideKey = 0;
7881ecf19b8SJohn Scipione			}
789fcc3e627SStephan Aßmus
790be2b0592SFredrik Modeen			fKeyCodes[i] = overrideKey;
791be2b0592SFredrik Modeen			_SetStateBit(states, overrideKey);
792be2b0592SFredrik Modeen		}
793be2b0592SFredrik Modeen	}
7941ecf19b8SJohn Scipione
79574983a5fSPhilippe Saint-Pierre	free(keys);
79674983a5fSPhilippe Saint-Pierre	free(map);
797be2b0592SFredrik Modeen}
798be2b0592SFredrik Modeen
799be2b0592SFredrik Modeen
800be2b0592SFredrik Modeenint32
801fcc3e627SStephan AßmusKeyStrokeSequenceCommandActuator::_LookupKeyCode(key_map* map, char* keys,
8021ecf19b8SJohn Scipione	int32 offsets[128], char c, uint8* setStates, int32& setModifier,
8031ecf19b8SJohn Scipione	int32 setTo) const
804be2b0592SFredrik Modeen{
805be2b0592SFredrik Modeen	for (int i = 0; i < 128; i++) {
806be2b0592SFredrik Modeen		if (keys[offsets[i]+ 1] == c) {
807be2b0592SFredrik Modeen			_SetStateBit(setStates, i);
808fcc3e627SStephan Aßmus
809be2b0592SFredrik Modeen			if (setTo & B_SHIFT_KEY)
810be2b0592SFredrik Modeen				_SetStateBit(setStates, map->left_shift_key);
811fcc3e627SStephan Aßmus
812be2b0592SFredrik Modeen			if (setTo & B_OPTION_KEY)
813be2b0592SFredrik Modeen				_SetStateBit(setStates, map->left_option_key);
814fcc3e627SStephan Aßmus
815be2b0592SFredrik Modeen			if (setTo & B_CONTROL_KEY)
816be2b0592SFredrik Modeen				_SetStateBit(setStates, map->left_control_key);
817fcc3e627SStephan Aßmus
818be2b0592SFredrik Modeen			if (setTo & B_CAPS_LOCK)
819be2b0592SFredrik Modeen				_SetStateBit(setStates, map->caps_key);
820fcc3e627SStephan Aßmus
8211ecf19b8SJohn Scipione			setModifier = setTo;
8221ecf19b8SJohn Scipione
823be2b0592SFredrik Modeen			return i;
824be2b0592SFredrik Modeen		}
825be2b0592SFredrik Modeen	}
8261ecf19b8SJohn Scipione
827be2b0592SFredrik Modeen	return -1;
828be2b0592SFredrik Modeen}
829be2b0592SFredrik Modeen
830be2b0592SFredrik Modeen
831be2b0592SFredrik Modeenvoid
832fcc3e627SStephan AßmusKeyStrokeSequenceCommandActuator::_SetStateBit(uint8* setStates, uint32 key,
833be2b0592SFredrik Modeen	bool on) const
834be2b0592SFredrik Modeen{
835be2b0592SFredrik Modeen	if (on)
8361ecf19b8SJohn Scipione		setStates[key / 8] |= (0x80 >> (key % 8));
837fcc3e627SStephan Aßmus	else
8381ecf19b8SJohn Scipione		setStates[key / 8] &= ~(0x80 >> (key % 8));
839be2b0592SFredrik Modeen}
840be2b0592SFredrik Modeen
841be2b0592SFredrik Modeen
842be2b0592SFredrik Modeenstatus_t
843be2b0592SFredrik ModeenKeyStrokeSequenceCommandActuator::Archive(BMessage* into, bool deep) const
844be2b0592SFredrik Modeen{
8451ecf19b8SJohn Scipione	status_t result = CommandActuator::Archive(into, deep);
8461ecf19b8SJohn Scipione	if (result != B_OK)
8471ecf19b8SJohn Scipione		return result;
8481ecf19b8SJohn Scipione
849be2b0592SFredrik Modeen	into->AddString("sequence", fSequence.String());
850be2b0592SFredrik Modeen	int32 numOverrides = fOverrideOffsets.CountItems();
8511ecf19b8SJohn Scipione
8521ecf19b8SJohn Scipione	status_t overridesResult = B_OK;
853be2b0592SFredrik Modeen	for (int32 i = 0; i < numOverrides; i++) {
8541ecf19b8SJohn Scipione		result = into->AddInt32("ooffsets",
855e971f3b1SJérôme Duval			(int32)(addr_t)fOverrideOffsets.ItemAt(i));
8561ecf19b8SJohn Scipione		if (result != B_OK)
8571ecf19b8SJohn Scipione			overridesResult = B_ERROR;
858fcc3e627SStephan Aßmus
8591ecf19b8SJohn Scipione		result = into->AddInt32("overrides",
860e971f3b1SJérôme Duval			(int32)(addr_t)fOverrides.ItemAt(i));
8611ecf19b8SJohn Scipione		if (result != B_OK)
8621ecf19b8SJohn Scipione			overridesResult = B_ERROR;
863fcc3e627SStephan Aßmus
8641ecf19b8SJohn Scipione		result = into->AddInt32("omods",
865e971f3b1SJérôme Duval			(int32)(addr_t)fOverrideModifiers.ItemAt(i));
8661ecf19b8SJohn Scipione		if (result != B_OK)
8671ecf19b8SJohn Scipione			overridesResult = B_ERROR;
868fcc3e627SStephan Aßmus
8691ecf19b8SJohn Scipione		result = into->AddInt32("okeys",
870e971f3b1SJérôme Duval			(int32)(addr_t)fOverrideKeyCodes.ItemAt(i));
871be2b0592SFredrik Modeen	}
872fcc3e627SStephan Aßmus
8731ecf19b8SJohn Scipione	return overridesResult == B_ERROR ? B_ERROR : result;
874be2b0592SFredrik Modeen}
875be2b0592SFredrik Modeen
876be2b0592SFredrik Modeen
877be2b0592SFredrik Modeenfilter_result
8781ecf19b8SJohn ScipioneKeyStrokeSequenceCommandActuator::KeyEvent(const BMessage* keyMessage,
8791ecf19b8SJohn Scipione	BList* outList, void** setAsyncData, BMessage* mouseMessage)
880be2b0592SFredrik Modeen{
8811ecf19b8SJohn Scipione	if (IS_KEY_DOWN(keyMessage)) {
8821ecf19b8SJohn Scipione		BMessage temp(*keyMessage);
883be2b0592SFredrik Modeen		int numChars = fSequence.Length();
884be2b0592SFredrik Modeen		for (int i = 0; i < numChars; i++) {
885be2b0592SFredrik Modeen			char nextChar = fSequence.ByteAt(i);
886fcc3e627SStephan Aßmus
887be2b0592SFredrik Modeen			temp.RemoveName("modifiers");
888be2b0592SFredrik Modeen			temp.AddInt32("modifiers", fModCodes[i]);
889be2b0592SFredrik Modeen			temp.RemoveName("key");
890fcc3e627SStephan Aßmus			temp.AddInt32("key", fKeyCodes[i]);
891be2b0592SFredrik Modeen			temp.RemoveName("raw_char");
892be2b0592SFredrik Modeen			temp.AddInt32("raw_char", (int32) nextChar);
893be2b0592SFredrik Modeen			temp.RemoveName("byte");
894fcc3e627SStephan Aßmus
895be2b0592SFredrik Modeen			int32 override = -1;
896be2b0592SFredrik Modeen			for (int32 j = fOverrideOffsets.CountItems()-1; j >= 0; j--) {
897e971f3b1SJérôme Duval				int32 offset = (int32)(addr_t) fOverrideOffsets.ItemAt(j);
898be2b0592SFredrik Modeen				if (offset == i) {
899e971f3b1SJérôme Duval					override = (int32)(addr_t) fOverrides.ItemAt(j);
900be2b0592SFredrik Modeen					break;
901be2b0592SFredrik Modeen				}
902be2b0592SFredrik Modeen			}
903be2b0592SFredrik Modeen
904be2b0592SFredrik Modeen			char t[4];
905be2b0592SFredrik Modeen			if (override >= 0) {
906be2b0592SFredrik Modeen				if (override < 0x80) {
907be2b0592SFredrik Modeen					// one-byte encoding
908be2b0592SFredrik Modeen					t[0] = (char) override;
909be2b0592SFredrik Modeen					t[1] = 0x00;
910be2b0592SFredrik Modeen				} else if (override < 0x800) {
911be2b0592SFredrik Modeen					// two-byte encoding
912be2b0592SFredrik Modeen					t[0] = 0xC0 | ((char)((override & 0x7C0)>>6));
913be2b0592SFredrik Modeen					t[1] = 0x80 | ((char)((override & 0x03F)>>0));
914be2b0592SFredrik Modeen					t[2] = 0x00;
915be2b0592SFredrik Modeen				} else {
916be2b0592SFredrik Modeen					// three-byte encoding
917be2b0592SFredrik Modeen					t[0] = 0xE0 | ((char)((override & 0xF000)>>12));
918be2b0592SFredrik Modeen					t[1] = 0x80 | ((char)((override & 0x0FC0)>>6));
919be2b0592SFredrik Modeen					t[2] = 0x80 | ((char)((override & 0x003F)>>0));
920be2b0592SFredrik Modeen					t[3] = 0x00;
921be2b0592SFredrik Modeen				}
922be2b0592SFredrik Modeen			} else {
923be2b0592SFredrik Modeen				t[0] = nextChar;
924be2b0592SFredrik Modeen				t[1] = 0x00;
925be2b0592SFredrik Modeen			}
926be2b0592SFredrik Modeen
927be2b0592SFredrik Modeen			temp.RemoveName("byte");
928fcc3e627SStephan Aßmus
929be2b0592SFredrik Modeen			for (int m = 0; t[m] != 0x00; m++)
930be2b0592SFredrik Modeen				temp.AddInt8("byte", t[m]);
931be2b0592SFredrik Modeen
932be2b0592SFredrik Modeen			temp.RemoveName("states");
933be2b0592SFredrik Modeen			temp.AddData("states", B_UINT8_TYPE, &fStates[i * 16], 16, true, 16);
934be2b0592SFredrik Modeen			temp.RemoveName("bytes");
935be2b0592SFredrik Modeen			temp.AddString("bytes", t);
936be2b0592SFredrik Modeen			temp.what = B_KEY_DOWN;
9371ecf19b8SJohn Scipione			outList->AddItem(new BMessage(temp));
938be2b0592SFredrik Modeen			temp.what = B_KEY_UP;
9391ecf19b8SJohn Scipione			outList->AddItem(new BMessage(temp));
940be2b0592SFredrik Modeen		}
9411ecf19b8SJohn Scipione
942be2b0592SFredrik Modeen		return B_DISPATCH_MESSAGE;
9431ecf19b8SJohn Scipione	} else
944be2b0592SFredrik Modeen		return B_SKIP_MESSAGE;
945be2b0592SFredrik Modeen}
946be2b0592SFredrik Modeen
947be2b0592SFredrik Modeen
948be2b0592SFredrik ModeenBArchivable*
949be2b0592SFredrik ModeenKeyStrokeSequenceCommandActuator::Instantiate(BMessage* from)
950be2b0592SFredrik Modeen{
951fcc3e627SStephan Aßmus	if (validate_instantiation(from, "KeyStrokeSequenceCommandActuator"))
952be2b0592SFredrik Modeen		return new KeyStrokeSequenceCommandActuator(from);
953be2b0592SFredrik Modeen	else
954