1/*
2 * Copyright 2009-2015 Haiku, Inc. All rights reserved
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Axel D��rfler, axeld@pinc-software.de
7 *		John Scipione, jscipione@gmail.com
8 */
9
10
11#include "SwitchWorkspaceInputFilter.h"
12
13#include <string.h>
14
15#include <new>
16
17#include <AppServerLink.h>
18#include <InterfaceDefs.h>
19#include <Message.h>
20#include <ServerProtocol.h>
21
22
23#define _SWITCH_WORKSPACE_	'_SWS'
24
25
26extern "C" BInputServerFilter* instantiate_input_filter() {
27	return new(std::nothrow) SwitchWorkspaceInputFilter();
28}
29
30
31SwitchWorkspaceInputFilter::SwitchWorkspaceInputFilter()
32{
33}
34
35
36filter_result
37SwitchWorkspaceInputFilter::Filter(BMessage* message, BList* _list)
38{
39	switch (message->what) {
40		case B_KEY_DOWN:
41		{
42			const char* bytes;
43			if (message->FindString("bytes", &bytes) != B_OK)
44				break;
45
46			int32 modifiers;
47			if (message->FindInt32("modifiers", &modifiers) != B_OK)
48				break;
49
50			int32 modifiersHeld = modifiers & (B_COMMAND_KEY
51				| B_CONTROL_KEY | B_OPTION_KEY | B_MENU_KEY | B_SHIFT_KEY);
52
53			bool takeMeThere;
54			if (modifiersHeld == (B_COMMAND_KEY | B_CONTROL_KEY))
55				takeMeThere = false;
56			else if (modifiersHeld
57					== (B_COMMAND_KEY | B_CONTROL_KEY | B_SHIFT_KEY)) {
58				takeMeThere = true;
59			} else
60				break;
61
62			int32 deltaX = 0;
63			int32 deltaY = 0;
64
65			if (bytes[0] == B_LEFT_ARROW)
66				deltaX = -1;
67			else if (bytes[0] == B_UP_ARROW)
68				deltaY = -1;
69			else if (bytes[0] == B_RIGHT_ARROW)
70				deltaX = 1;
71			else if (bytes[0] == B_DOWN_ARROW)
72				deltaY = 1;
73			else
74				break;
75
76			BPrivate::AppServerLink link;
77			link.StartMessage(AS_GET_WORKSPACE_LAYOUT);
78
79			status_t status;
80			int32 columns;
81			int32 rows;
82			if (link.FlushWithReply(status) != B_OK || status != B_OK)
83				break;
84
85			link.Read<int32>(&columns);
86			link.Read<int32>(&rows);
87
88			int32 current = current_workspace();
89
90			int32 nextColumn = current % columns + deltaX;
91			if (nextColumn >= columns)
92				nextColumn = columns - 1;
93			else if (nextColumn < 0)
94				nextColumn = 0;
95
96			int32 nextRow = current / columns + deltaY;
97			if (nextRow >= rows)
98				nextRow = rows - 1;
99			else if (nextRow < 0)
100				nextRow = 0;
101
102			int32 next = nextColumn + nextRow * columns;
103			if (next != current) {
104				BPrivate::AppServerLink link;
105				link.StartMessage(AS_ACTIVATE_WORKSPACE);
106				link.Attach<int32>(next);
107				link.Attach<bool>(takeMeThere);
108				link.Flush();
109			}
110
111			return B_SKIP_MESSAGE;
112		}
113	}
114
115	return B_DISPATCH_MESSAGE;
116}
117
118
119status_t
120SwitchWorkspaceInputFilter::InitCheck()
121{
122	return B_OK;
123}
124