1 /*
2  * This source file is part of libRocket, the HTML/CSS Interface Middleware
3  *
4  * For the latest information, see http://www.librocket.com
5  *
6  * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24  * THE SOFTWARE.
25  *
26  */
27 
28 #include <macosx/InputMacOSX.h>
29 #include <Rocket/Core/Context.h>
30 #include <Rocket/Core/Input.h>
31 #include <Rocket/Debugger.h>
32 #include <Shell.h>
33 
34 // Defines for Carbon key modifiers.
35 #define KEY_ALT 256
36 #define KEY_SHIFT 512
37 #define KEY_CAPS 1024
38 #define KEY_OPTION 2048
39 #define KEY_CTRL 4096
40 
41 static void InitialiseKeymap();
42 static int GetKeyModifierState(EventRef event);
43 
44 static const int KEYMAP_SIZE = 256;
45 static Rocket::Core::Input::KeyIdentifier key_identifier_map[KEYMAP_SIZE];
46 
Initialise()47 bool InputMacOSX::Initialise()
48 {
49 	InitialiseKeymap();
50 	return true;
51 }
52 
Shutdown()53 void InputMacOSX::Shutdown()
54 {
55 }
56 
EventHandler(EventHandlerCallRef next_handler,EventRef event,void * p)57 OSStatus InputMacOSX::EventHandler(EventHandlerCallRef next_handler, EventRef event, void* p)
58 {
59 	// Process all mouse and keyboard events
60 	switch (GetEventClass(event))
61 	{
62 		case kEventClassMouse:
63 		{
64 			switch (GetEventKind(event))
65 			{
66 				case kEventMouseDown:
67 				{
68 					EventMouseButton mouse_button;
69 					if (GetEventParameter(event, kEventParamMouseButton, typeMouseButton, NULL, sizeof(EventMouseButton), NULL, &mouse_button) == noErr)
70 						context->ProcessMouseButtonDown(mouse_button - 1, GetKeyModifierState(event));
71 				}
72 				break;
73 
74 				case kEventMouseUp:
75 				{
76 					EventMouseButton mouse_button;
77 					if (GetEventParameter(event, kEventParamMouseButton, typeMouseButton, NULL, sizeof(EventMouseButton), NULL, &mouse_button) == noErr)
78 						context->ProcessMouseButtonUp(mouse_button - 1, GetKeyModifierState(event));
79 				}
80 				break;
81 
82 				case kEventMouseWheelMoved:
83 				{
84 					EventMouseWheelAxis axis;
85 					SInt32 delta;
86 
87 					if (GetEventParameter(event, kEventParamMouseWheelAxis, typeMouseWheelAxis, NULL, sizeof(EventMouseWheelAxis), NULL, &axis) == noErr &&
88 						GetEventParameter(event, kEventParamMouseWheelDelta, typeLongInteger, NULL, sizeof(SInt32), NULL, &delta) == noErr)
89 					{
90 						if (axis == kEventMouseWheelAxisY)
91 							context->ProcessMouseWheel(-delta, GetKeyModifierState(event));
92 					}
93 				}
94 				break;
95 
96 				case kEventMouseMoved:
97 				case kEventMouseDragged:
98 				{
99 					HIPoint position;
100 					if (GetEventParameter(event, kEventParamWindowMouseLocation, typeHIPoint, NULL, sizeof(HIPoint), NULL, &position) == noErr)
101 						context->ProcessMouseMove(position.x, position.y - 22, GetKeyModifierState(event));
102 				}
103 				break;
104 			}
105 		}
106 		break;
107 
108 		case kEventClassKeyboard:
109 		{
110 			switch (GetEventKind(event))
111 			{
112 				case kEventRawKeyDown:
113 				{
114 					UInt32 key_code;
115 					if (GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &key_code) == noErr)
116 					{
117 						Rocket::Core::Input::KeyIdentifier key_identifier = key_identifier_map[key_code & 0xFF];
118 						int key_modifier_state = GetKeyModifierState(event);
119 
120 						// Check for a shift-~ to toggle the debugger.
121 						if (key_identifier == Rocket::Core::Input::KI_OEM_3 &&
122 							key_modifier_state & Rocket::Core::Input::KM_SHIFT)
123 						{
124 							Rocket::Debugger::SetVisible(!Rocket::Debugger::IsVisible());
125 							break;
126 						}
127 
128 						if (key_identifier != Rocket::Core::Input::KI_UNKNOWN)
129 							context->ProcessKeyDown(key_identifier, key_modifier_state);
130 
131 						Rocket::Core::word character = GetCharacterCode(key_identifier, key_modifier_state);
132 						if (character > 0)
133 							context->ProcessTextInput(character);
134 					}
135 				}
136 				break;
137 
138 				case kEventRawKeyUp:
139 				{
140 					UInt32 key_code;
141 					if (GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &key_code) == noErr)
142 					{
143 						Rocket::Core::Input::KeyIdentifier key_identifier = key_identifier_map[key_code & 0xFF];
144 						int key_modifier_state = GetKeyModifierState(event);
145 
146 						if (key_identifier != Rocket::Core::Input::KI_UNKNOWN)
147 							context->ProcessKeyUp(key_identifier, key_modifier_state);
148 					}
149 				}
150 				break;
151 			}
152 		}
153 		break;
154 	}
155 
156 	return CallNextEventHandler(next_handler, event);
157 }
158 
GetKeyModifierState(EventRef event)159 static int GetKeyModifierState(EventRef event)
160 {
161 	int key_modifier_state = 0;
162 
163 	UInt32 carbon_key_modifier_state;
164 	if (GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &carbon_key_modifier_state) == noErr)
165 	{
166 		if (carbon_key_modifier_state & KEY_ALT)
167 			key_modifier_state |= Rocket::Core::Input::KM_ALT;
168 		if (carbon_key_modifier_state & KEY_SHIFT)
169 			key_modifier_state |= Rocket::Core::Input::KM_SHIFT;
170 		if (carbon_key_modifier_state & KEY_CAPS)
171 			key_modifier_state |= Rocket::Core::Input::KM_CAPSLOCK;
172 		if (carbon_key_modifier_state & KEY_OPTION)
173 			key_modifier_state |= Rocket::Core::Input::KM_META;
174 		if (carbon_key_modifier_state & KEY_CTRL)
175 			key_modifier_state |= Rocket::Core::Input::KM_CTRL;
176 	}
177 
178 	return key_modifier_state;
179 }
180 
InitialiseKeymap()181 static void InitialiseKeymap()
182 {
183 	// Initialise the key map with default values.
184 	memset(key_identifier_map, sizeof(key_identifier_map), 0);
185 
186 	key_identifier_map[0x00] = Rocket::Core::Input::KI_A;
187 	key_identifier_map[0x01] = Rocket::Core::Input::KI_S;
188 	key_identifier_map[0x02] = Rocket::Core::Input::KI_D;
189 	key_identifier_map[0x03] = Rocket::Core::Input::KI_F;
190 	key_identifier_map[0x04] = Rocket::Core::Input::KI_H;
191 	key_identifier_map[0x05] = Rocket::Core::Input::KI_G;
192 	key_identifier_map[0x06] = Rocket::Core::Input::KI_Z;
193 	key_identifier_map[0x07] = Rocket::Core::Input::KI_X;
194 	key_identifier_map[0x08] = Rocket::Core::Input::KI_C;
195 	key_identifier_map[0x09] = Rocket::Core::Input::KI_V;
196 	key_identifier_map[0x0B] = Rocket::Core::Input::KI_B;
197 	key_identifier_map[0x0C] = Rocket::Core::Input::KI_Q;
198 	key_identifier_map[0x0D] = Rocket::Core::Input::KI_W;
199 	key_identifier_map[0x0E] = Rocket::Core::Input::KI_E;
200 	key_identifier_map[0x0F] = Rocket::Core::Input::KI_R;
201 	key_identifier_map[0x10] = Rocket::Core::Input::KI_Y;
202 	key_identifier_map[0x11] = Rocket::Core::Input::KI_T;
203 	key_identifier_map[0x12] = Rocket::Core::Input::KI_1;
204 	key_identifier_map[0x13] = Rocket::Core::Input::KI_2;
205 	key_identifier_map[0x14] = Rocket::Core::Input::KI_3;
206 	key_identifier_map[0x15] = Rocket::Core::Input::KI_4;
207 	key_identifier_map[0x16] = Rocket::Core::Input::KI_6;
208 	key_identifier_map[0x17] = Rocket::Core::Input::KI_5;
209 	key_identifier_map[0x18] = Rocket::Core::Input::KI_OEM_PLUS;
210 	key_identifier_map[0x19] = Rocket::Core::Input::KI_9;
211 	key_identifier_map[0x1A] = Rocket::Core::Input::KI_7;
212 	key_identifier_map[0x1B] = Rocket::Core::Input::KI_OEM_MINUS;
213 	key_identifier_map[0x1C] = Rocket::Core::Input::KI_8;
214 	key_identifier_map[0x1D] = Rocket::Core::Input::KI_0;
215 	key_identifier_map[0x1E] = Rocket::Core::Input::KI_OEM_6;
216 	key_identifier_map[0x1F] = Rocket::Core::Input::KI_O;
217 	key_identifier_map[0x20] = Rocket::Core::Input::KI_U;
218 	key_identifier_map[0x21] = Rocket::Core::Input::KI_OEM_4;
219 	key_identifier_map[0x22] = Rocket::Core::Input::KI_I;
220 	key_identifier_map[0x23] = Rocket::Core::Input::KI_P;
221 	key_identifier_map[0x24] = Rocket::Core::Input::KI_RETURN;
222 	key_identifier_map[0x25] = Rocket::Core::Input::KI_L;
223 	key_identifier_map[0x26] = Rocket::Core::Input::KI_J;
224 	key_identifier_map[0x27] = Rocket::Core::Input::KI_OEM_7;
225 	key_identifier_map[0x28] = Rocket::Core::Input::KI_K;
226 	key_identifier_map[0x29] = Rocket::Core::Input::KI_OEM_1;
227 	key_identifier_map[0x2A] = Rocket::Core::Input::KI_OEM_5;
228 	key_identifier_map[0x2B] = Rocket::Core::Input::KI_OEM_COMMA;
229 	key_identifier_map[0x2C] = Rocket::Core::Input::KI_OEM_2;
230 	key_identifier_map[0x2D] = Rocket::Core::Input::KI_N;
231 	key_identifier_map[0x2E] = Rocket::Core::Input::KI_M;
232 	key_identifier_map[0x2F] = Rocket::Core::Input::KI_OEM_PERIOD;
233 	key_identifier_map[0x30] = Rocket::Core::Input::KI_TAB;
234 	key_identifier_map[0x31] = Rocket::Core::Input::KI_SPACE;
235 	key_identifier_map[0x32] = Rocket::Core::Input::KI_OEM_3;
236 	key_identifier_map[0x33] = Rocket::Core::Input::KI_BACK;
237 	key_identifier_map[0x35] = Rocket::Core::Input::KI_ESCAPE;
238 	key_identifier_map[0x37] = Rocket::Core::Input::KI_LMETA;
239 	key_identifier_map[0x38] = Rocket::Core::Input::KI_LSHIFT;
240 	key_identifier_map[0x39] = Rocket::Core::Input::KI_CAPITAL;
241 	key_identifier_map[0x3A] = Rocket::Core::Input::KI_LMENU;
242 	key_identifier_map[0x3B] = Rocket::Core::Input::KI_LCONTROL;
243 	key_identifier_map[0x41] = Rocket::Core::Input::KI_DECIMAL;
244 	key_identifier_map[0x43] = Rocket::Core::Input::KI_MULTIPLY;
245 	key_identifier_map[0x45] = Rocket::Core::Input::KI_ADD;
246 	key_identifier_map[0x4B] = Rocket::Core::Input::KI_DIVIDE;
247 	key_identifier_map[0x4C] = Rocket::Core::Input::KI_NUMPADENTER;
248 	key_identifier_map[0x4E] = Rocket::Core::Input::KI_SUBTRACT;
249 	key_identifier_map[0x51] = Rocket::Core::Input::KI_OEM_PLUS;
250 	key_identifier_map[0x52] = Rocket::Core::Input::KI_NUMPAD0;
251 	key_identifier_map[0x53] = Rocket::Core::Input::KI_NUMPAD1;
252 	key_identifier_map[0x54] = Rocket::Core::Input::KI_NUMPAD2;
253 	key_identifier_map[0x55] = Rocket::Core::Input::KI_NUMPAD3;
254 	key_identifier_map[0x56] = Rocket::Core::Input::KI_NUMPAD4;
255 	key_identifier_map[0x57] = Rocket::Core::Input::KI_NUMPAD5;
256 	key_identifier_map[0x58] = Rocket::Core::Input::KI_NUMPAD6;
257 	key_identifier_map[0x59] = Rocket::Core::Input::KI_NUMPAD7;
258 	key_identifier_map[0x5B] = Rocket::Core::Input::KI_NUMPAD8;
259 	key_identifier_map[0x5C] = Rocket::Core::Input::KI_NUMPAD9;
260 	key_identifier_map[0x60] = Rocket::Core::Input::KI_F5;
261 	key_identifier_map[0x61] = Rocket::Core::Input::KI_F6;
262 	key_identifier_map[0x62] = Rocket::Core::Input::KI_F7;
263 	key_identifier_map[0x63] = Rocket::Core::Input::KI_F3;
264 	key_identifier_map[0x64] = Rocket::Core::Input::KI_F8;
265 	key_identifier_map[0x65] = Rocket::Core::Input::KI_F9;
266 	key_identifier_map[0x67] = Rocket::Core::Input::KI_F11;
267 	key_identifier_map[0x69] = Rocket::Core::Input::KI_F13;
268 	key_identifier_map[0x6B] = Rocket::Core::Input::KI_F14;
269 	key_identifier_map[0x6D] = Rocket::Core::Input::KI_F10;
270 	key_identifier_map[0x6F] = Rocket::Core::Input::KI_F12;
271 	key_identifier_map[0x71] = Rocket::Core::Input::KI_F15;
272 	key_identifier_map[0x73] = Rocket::Core::Input::KI_HOME;
273 	key_identifier_map[0x74] = Rocket::Core::Input::KI_PRIOR;
274 	key_identifier_map[0x75] = Rocket::Core::Input::KI_DELETE;
275 	key_identifier_map[0x76] = Rocket::Core::Input::KI_F4;
276 	key_identifier_map[0x77] = Rocket::Core::Input::KI_END;
277 	key_identifier_map[0x78] = Rocket::Core::Input::KI_F2;
278 	key_identifier_map[0x79] = Rocket::Core::Input::KI_NEXT;
279 	key_identifier_map[0x7A] = Rocket::Core::Input::KI_F1;
280 	key_identifier_map[0x7B] = Rocket::Core::Input::KI_LEFT;
281 	key_identifier_map[0x7C] = Rocket::Core::Input::KI_RIGHT;
282 	key_identifier_map[0x7D] = Rocket::Core::Input::KI_DOWN;
283 	key_identifier_map[0x7E] = Rocket::Core::Input::KI_UP;
284 }
285