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