xref: /haiku/src/add-ons/input_server/filters/switch_workspace/SwitchWorkspaceInputFilter.cpp (revision 558a3eede11d288ab7b639908198dce2830f73bc)
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 
instantiate_input_filter()26 extern "C" BInputServerFilter* instantiate_input_filter() {
27 	return new(std::nothrow) SwitchWorkspaceInputFilter();
28 }
29 
30 
SwitchWorkspaceInputFilter()31 SwitchWorkspaceInputFilter::SwitchWorkspaceInputFilter()
32 {
33 }
34 
35 
36 filter_result
Filter(BMessage * message,BList * _list)37 SwitchWorkspaceInputFilter::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 
119 status_t
InitCheck()120 SwitchWorkspaceInputFilter::InitCheck()
121 {
122 	return B_OK;
123 }
124