/*
* This source file is part of RmlUi, the HTML/CSS Interface Middleware
*
* For the latest information, see http://github.com/mikke89/RmlUi
*
* Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
* Copyright (c) 2019 The RmlUi Team, and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
#include
#include
#include
#include
#include
// Defines for Carbon key modifiers.
#define KEY_ALT 256
#define KEY_SHIFT 512
#define KEY_CAPS 1024
#define KEY_OPTION 2048
#define KEY_CTRL 4096
static void InitialiseKeymap();
static int GetKeyModifierState(EventRef event);
static const int KEYMAP_SIZE = 256;
static Rml::Core::Input::KeyIdentifier key_identifier_map[KEYMAP_SIZE];
bool InputMacOSX::Initialise()
{
InitialiseKeymap();
return true;
}
void InputMacOSX::Shutdown()
{
}
OSStatus InputMacOSX::EventHandler(EventHandlerCallRef next_handler, EventRef event, void* p)
{
// Process all mouse and keyboard events
switch (GetEventClass(event))
{
case kEventClassMouse:
{
switch (GetEventKind(event))
{
case kEventMouseDown:
{
EventMouseButton mouse_button;
if (GetEventParameter(event, kEventParamMouseButton, typeMouseButton, nullptr, sizeof(EventMouseButton), nullptr, &mouse_button) == noErr)
context->ProcessMouseButtonDown(mouse_button - 1, GetKeyModifierState(event));
}
break;
case kEventMouseUp:
{
EventMouseButton mouse_button;
if (GetEventParameter(event, kEventParamMouseButton, typeMouseButton, nullptr, sizeof(EventMouseButton), nullptr, &mouse_button) == noErr)
context->ProcessMouseButtonUp(mouse_button - 1, GetKeyModifierState(event));
}
break;
case kEventMouseWheelMoved:
{
EventMouseWheelAxis axis;
SInt32 delta;
if (GetEventParameter(event, kEventParamMouseWheelAxis, typeMouseWheelAxis, nullptr, sizeof(EventMouseWheelAxis), nullptr, &axis) == noErr &&
GetEventParameter(event, kEventParamMouseWheelDelta, typeLongInteger, nullptr, sizeof(SInt32), nullptr, &delta) == noErr)
{
if (axis == kEventMouseWheelAxisY)
context->ProcessMouseWheel(-delta, GetKeyModifierState(event));
}
}
break;
case kEventMouseMoved:
case kEventMouseDragged:
{
HIPoint position;
if (GetEventParameter(event, kEventParamWindowMouseLocation, typeHIPoint, nullptr, sizeof(HIPoint), nullptr, &position) == noErr)
context->ProcessMouseMove(position.x, position.y - 22, GetKeyModifierState(event));
}
break;
}
}
break;
case kEventClassKeyboard:
{
switch (GetEventKind(event))
{
case kEventRawKeyDown:
{
UInt32 key_code;
if (GetEventParameter(event, kEventParamKeyCode, typeUInt32, nullptr, sizeof(UInt32), nullptr, &key_code) == noErr)
{
Rml::Core::Input::KeyIdentifier key_identifier = key_identifier_map[key_code & 0xFF];
int key_modifier_state = GetKeyModifierState(event);
// Check for a shift-~ to toggle the debugger.
if (key_identifier == Rml::Core::Input::KI_OEM_3 &&
key_modifier_state & Rml::Core::Input::KM_SHIFT)
{
Rml::Debugger::SetVisible(!Rml::Debugger::IsVisible());
break;
}
if (key_identifier != Rml::Core::Input::KI_UNKNOWN)
context->ProcessKeyDown(key_identifier, key_modifier_state);
Rml::Core::word character = GetCharacterCode(key_identifier, key_modifier_state);
if (character > 0)
context->ProcessTextInput(character);
}
}
break;
case kEventRawKeyUp:
{
UInt32 key_code;
if (GetEventParameter(event, kEventParamKeyCode, typeUInt32, nullptr, sizeof(UInt32), nullptr, &key_code) == noErr)
{
Rml::Core::Input::KeyIdentifier key_identifier = key_identifier_map[key_code & 0xFF];
int key_modifier_state = GetKeyModifierState(event);
if (key_identifier != Rml::Core::Input::KI_UNKNOWN)
context->ProcessKeyUp(key_identifier, key_modifier_state);
}
}
break;
}
}
break;
}
return CallNextEventHandler(next_handler, event);
}
static int GetKeyModifierState(EventRef event)
{
int key_modifier_state = 0;
UInt32 carbon_key_modifier_state;
if (GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, nullptr, sizeof(UInt32), nullptr, &carbon_key_modifier_state) == noErr)
{
if (carbon_key_modifier_state & KEY_ALT)
key_modifier_state |= Rml::Core::Input::KM_ALT;
if (carbon_key_modifier_state & KEY_SHIFT)
key_modifier_state |= Rml::Core::Input::KM_SHIFT;
if (carbon_key_modifier_state & KEY_CAPS)
key_modifier_state |= Rml::Core::Input::KM_CAPSLOCK;
if (carbon_key_modifier_state & KEY_OPTION)
key_modifier_state |= Rml::Core::Input::KM_META;
if (carbon_key_modifier_state & KEY_CTRL)
key_modifier_state |= Rml::Core::Input::KM_CTRL;
}
return key_modifier_state;
}
static void InitialiseKeymap()
{
// Initialise the key map with default values.
memset(key_identifier_map, sizeof(key_identifier_map), 0);
key_identifier_map[0x00] = Rml::Core::Input::KI_A;
key_identifier_map[0x01] = Rml::Core::Input::KI_S;
key_identifier_map[0x02] = Rml::Core::Input::KI_D;
key_identifier_map[0x03] = Rml::Core::Input::KI_F;
key_identifier_map[0x04] = Rml::Core::Input::KI_H;
key_identifier_map[0x05] = Rml::Core::Input::KI_G;
key_identifier_map[0x06] = Rml::Core::Input::KI_Z;
key_identifier_map[0x07] = Rml::Core::Input::KI_X;
key_identifier_map[0x08] = Rml::Core::Input::KI_C;
key_identifier_map[0x09] = Rml::Core::Input::KI_V;
key_identifier_map[0x0B] = Rml::Core::Input::KI_B;
key_identifier_map[0x0C] = Rml::Core::Input::KI_Q;
key_identifier_map[0x0D] = Rml::Core::Input::KI_W;
key_identifier_map[0x0E] = Rml::Core::Input::KI_E;
key_identifier_map[0x0F] = Rml::Core::Input::KI_R;
key_identifier_map[0x10] = Rml::Core::Input::KI_Y;
key_identifier_map[0x11] = Rml::Core::Input::KI_T;
key_identifier_map[0x12] = Rml::Core::Input::KI_1;
key_identifier_map[0x13] = Rml::Core::Input::KI_2;
key_identifier_map[0x14] = Rml::Core::Input::KI_3;
key_identifier_map[0x15] = Rml::Core::Input::KI_4;
key_identifier_map[0x16] = Rml::Core::Input::KI_6;
key_identifier_map[0x17] = Rml::Core::Input::KI_5;
key_identifier_map[0x18] = Rml::Core::Input::KI_OEM_PLUS;
key_identifier_map[0x19] = Rml::Core::Input::KI_9;
key_identifier_map[0x1A] = Rml::Core::Input::KI_7;
key_identifier_map[0x1B] = Rml::Core::Input::KI_OEM_MINUS;
key_identifier_map[0x1C] = Rml::Core::Input::KI_8;
key_identifier_map[0x1D] = Rml::Core::Input::KI_0;
key_identifier_map[0x1E] = Rml::Core::Input::KI_OEM_6;
key_identifier_map[0x1F] = Rml::Core::Input::KI_O;
key_identifier_map[0x20] = Rml::Core::Input::KI_U;
key_identifier_map[0x21] = Rml::Core::Input::KI_OEM_4;
key_identifier_map[0x22] = Rml::Core::Input::KI_I;
key_identifier_map[0x23] = Rml::Core::Input::KI_P;
key_identifier_map[0x24] = Rml::Core::Input::KI_RETURN;
key_identifier_map[0x25] = Rml::Core::Input::KI_L;
key_identifier_map[0x26] = Rml::Core::Input::KI_J;
key_identifier_map[0x27] = Rml::Core::Input::KI_OEM_7;
key_identifier_map[0x28] = Rml::Core::Input::KI_K;
key_identifier_map[0x29] = Rml::Core::Input::KI_OEM_1;
key_identifier_map[0x2A] = Rml::Core::Input::KI_OEM_5;
key_identifier_map[0x2B] = Rml::Core::Input::KI_OEM_COMMA;
key_identifier_map[0x2C] = Rml::Core::Input::KI_OEM_2;
key_identifier_map[0x2D] = Rml::Core::Input::KI_N;
key_identifier_map[0x2E] = Rml::Core::Input::KI_M;
key_identifier_map[0x2F] = Rml::Core::Input::KI_OEM_PERIOD;
key_identifier_map[0x30] = Rml::Core::Input::KI_TAB;
key_identifier_map[0x31] = Rml::Core::Input::KI_SPACE;
key_identifier_map[0x32] = Rml::Core::Input::KI_OEM_3;
key_identifier_map[0x33] = Rml::Core::Input::KI_BACK;
key_identifier_map[0x35] = Rml::Core::Input::KI_ESCAPE;
key_identifier_map[0x37] = Rml::Core::Input::KI_LMETA;
key_identifier_map[0x38] = Rml::Core::Input::KI_LSHIFT;
key_identifier_map[0x39] = Rml::Core::Input::KI_CAPITAL;
key_identifier_map[0x3A] = Rml::Core::Input::KI_LMENU;
key_identifier_map[0x3B] = Rml::Core::Input::KI_LCONTROL;
key_identifier_map[0x41] = Rml::Core::Input::KI_DECIMAL;
key_identifier_map[0x43] = Rml::Core::Input::KI_MULTIPLY;
key_identifier_map[0x45] = Rml::Core::Input::KI_ADD;
key_identifier_map[0x4B] = Rml::Core::Input::KI_DIVIDE;
key_identifier_map[0x4C] = Rml::Core::Input::KI_NUMPADENTER;
key_identifier_map[0x4E] = Rml::Core::Input::KI_SUBTRACT;
key_identifier_map[0x51] = Rml::Core::Input::KI_OEM_PLUS;
key_identifier_map[0x52] = Rml::Core::Input::KI_NUMPAD0;
key_identifier_map[0x53] = Rml::Core::Input::KI_NUMPAD1;
key_identifier_map[0x54] = Rml::Core::Input::KI_NUMPAD2;
key_identifier_map[0x55] = Rml::Core::Input::KI_NUMPAD3;
key_identifier_map[0x56] = Rml::Core::Input::KI_NUMPAD4;
key_identifier_map[0x57] = Rml::Core::Input::KI_NUMPAD5;
key_identifier_map[0x58] = Rml::Core::Input::KI_NUMPAD6;
key_identifier_map[0x59] = Rml::Core::Input::KI_NUMPAD7;
key_identifier_map[0x5B] = Rml::Core::Input::KI_NUMPAD8;
key_identifier_map[0x5C] = Rml::Core::Input::KI_NUMPAD9;
key_identifier_map[0x60] = Rml::Core::Input::KI_F5;
key_identifier_map[0x61] = Rml::Core::Input::KI_F6;
key_identifier_map[0x62] = Rml::Core::Input::KI_F7;
key_identifier_map[0x63] = Rml::Core::Input::KI_F3;
key_identifier_map[0x64] = Rml::Core::Input::KI_F8;
key_identifier_map[0x65] = Rml::Core::Input::KI_F9;
key_identifier_map[0x67] = Rml::Core::Input::KI_F11;
key_identifier_map[0x69] = Rml::Core::Input::KI_F13;
key_identifier_map[0x6B] = Rml::Core::Input::KI_F14;
key_identifier_map[0x6D] = Rml::Core::Input::KI_F10;
key_identifier_map[0x6F] = Rml::Core::Input::KI_F12;
key_identifier_map[0x71] = Rml::Core::Input::KI_F15;
key_identifier_map[0x73] = Rml::Core::Input::KI_HOME;
key_identifier_map[0x74] = Rml::Core::Input::KI_PRIOR;
key_identifier_map[0x75] = Rml::Core::Input::KI_DELETE;
key_identifier_map[0x76] = Rml::Core::Input::KI_F4;
key_identifier_map[0x77] = Rml::Core::Input::KI_END;
key_identifier_map[0x78] = Rml::Core::Input::KI_F2;
key_identifier_map[0x79] = Rml::Core::Input::KI_NEXT;
key_identifier_map[0x7A] = Rml::Core::Input::KI_F1;
key_identifier_map[0x7B] = Rml::Core::Input::KI_LEFT;
key_identifier_map[0x7C] = Rml::Core::Input::KI_RIGHT;
key_identifier_map[0x7D] = Rml::Core::Input::KI_DOWN;
key_identifier_map[0x7E] = Rml::Core::Input::KI_UP;
}