Added inital mouse and keyboard support for OSX

This commit is contained in:
Daniel Collin 2014-09-24 22:25:16 +02:00
parent 25d56825e8
commit 874790838c

View file

@ -126,8 +126,18 @@
} }
@end @end
// Scan codes on Mac taken from http://boredzo.org/blog/archives/2007-05-22/virtual-key-codes
#define KEY_RETURN 36
#define KEY_TAB 48
#define KEY_DELETE 51
#define KEY_ESCAPE 53
namespace entry namespace entry
{ {
static WindowHandle s_defaultWindow = { 0 }; // TODO: Add support for more windows
static uint8_t s_translateKey[256];
struct MainThreadEntry struct MainThreadEntry
{ {
int m_argc; int m_argc;
@ -145,6 +155,106 @@ namespace entry
Context() Context()
: m_exit(false) : m_exit(false)
{ {
s_translateKey[KEY_ESCAPE] = Key::Esc;
s_translateKey[KEY_RETURN] = Key::Return;
s_translateKey[KEY_TAB] = Key::Tab;
s_translateKey[KEY_DELETE] = Key::Backspace;
//s_translateKey[VK_SPACE] = Key::Space;
//s_translateKey[VK_UP] = Key::Up;
//s_translateKey[VK_DOWN] = Key::Down;
//s_translateKey[VK_LEFT] = Key::Left;
//s_translateKey[VK_RIGHT] = Key::Right;
//s_translateKey[VK_PRIOR] = Key::PageUp;
//s_translateKey[VK_NEXT] = Key::PageUp;
//s_translateKey[VK_HOME] = Key::Home;
//s_translateKey[VK_END] = Key::End;
//s_translateKey[VK_SNAPSHOT] = Key::Print;
//s_translateKey[VK_OEM_PLUS] = Key::Plus;
//s_translateKey[VK_OEM_MINUS] = Key::Minus;
//s_translateKey[VK_F1] = Key::F1;
//s_translateKey[VK_F2] = Key::F2;
//s_translateKey[VK_F3] = Key::F3;
//s_translateKey[VK_F4] = Key::F4;
//s_translateKey[VK_F5] = Key::F5;
//s_translateKey[VK_F6] = Key::F6;
//s_translateKey[VK_F7] = Key::F7;
//s_translateKey[VK_F8] = Key::F8;
//s_translateKey[VK_F9] = Key::F9;
//s_translateKey[VK_F10] = Key::F10;
//s_translateKey[VK_F11] = Key::F11;
//s_translateKey[VK_F12] = Key::F12;
//s_translateKey[VK_NUMPAD0] = Key::NumPad0;
//s_translateKey[VK_NUMPAD1] = Key::NumPad1;
//s_translateKey[VK_NUMPAD2] = Key::NumPad2;
//s_translateKey[VK_NUMPAD3] = Key::NumPad3;
//s_translateKey[VK_NUMPAD4] = Key::NumPad4;
//s_translateKey[VK_NUMPAD5] = Key::NumPad5;
//s_translateKey[VK_NUMPAD6] = Key::NumPad6;
//s_translateKey[VK_NUMPAD7] = Key::NumPad7;
//s_translateKey[VK_NUMPAD8] = Key::NumPad8;
//s_translateKey[VK_NUMPAD9] = Key::NumPad9;
s_translateKey['0'] = Key::Key0;
s_translateKey['1'] = Key::Key1;
s_translateKey['2'] = Key::Key2;
s_translateKey['3'] = Key::Key3;
s_translateKey['4'] = Key::Key4;
s_translateKey['5'] = Key::Key5;
s_translateKey['6'] = Key::Key6;
s_translateKey['7'] = Key::Key7;
s_translateKey['8'] = Key::Key8;
s_translateKey['9'] = Key::Key9;
s_translateKey['A'] = Key::KeyA;
s_translateKey['B'] = Key::KeyB;
s_translateKey['C'] = Key::KeyC;
s_translateKey['D'] = Key::KeyD;
s_translateKey['E'] = Key::KeyE;
s_translateKey['F'] = Key::KeyF;
s_translateKey['G'] = Key::KeyG;
s_translateKey['H'] = Key::KeyH;
s_translateKey['I'] = Key::KeyI;
s_translateKey['J'] = Key::KeyJ;
s_translateKey['K'] = Key::KeyK;
s_translateKey['L'] = Key::KeyL;
s_translateKey['M'] = Key::KeyM;
s_translateKey['N'] = Key::KeyN;
s_translateKey['O'] = Key::KeyO;
s_translateKey['P'] = Key::KeyP;
s_translateKey['Q'] = Key::KeyQ;
s_translateKey['R'] = Key::KeyR;
s_translateKey['S'] = Key::KeyS;
s_translateKey['T'] = Key::KeyT;
s_translateKey['U'] = Key::KeyU;
s_translateKey['V'] = Key::KeyV;
s_translateKey['W'] = Key::KeyW;
s_translateKey['X'] = Key::KeyX;
s_translateKey['Y'] = Key::KeyY;
s_translateKey['Z'] = Key::KeyZ;
s_translateKey['a'] = Key::KeyA;
s_translateKey['b'] = Key::KeyB;
s_translateKey['c'] = Key::KeyC;
s_translateKey['d'] = Key::KeyD;
s_translateKey['e'] = Key::KeyE;
s_translateKey['f'] = Key::KeyF;
s_translateKey['g'] = Key::KeyG;
s_translateKey['h'] = Key::KeyH;
s_translateKey['i'] = Key::KeyI;
s_translateKey['j'] = Key::KeyJ;
s_translateKey['k'] = Key::KeyK;
s_translateKey['l'] = Key::KeyL;
s_translateKey['m'] = Key::KeyM;
s_translateKey['n'] = Key::KeyN;
s_translateKey['o'] = Key::KeyO;
s_translateKey['p'] = Key::KeyP;
s_translateKey['q'] = Key::KeyQ;
s_translateKey['r'] = Key::KeyR;
s_translateKey['s'] = Key::KeyS;
s_translateKey['t'] = Key::KeyT;
s_translateKey['u'] = Key::KeyU;
s_translateKey['v'] = Key::KeyV;
s_translateKey['w'] = Key::KeyW;
s_translateKey['x'] = Key::KeyX;
s_translateKey['y'] = Key::KeyY;
s_translateKey['z'] = Key::KeyZ;
} }
NSEvent* waitEvent() NSEvent* waitEvent()
@ -167,12 +277,167 @@ namespace entry
]; ];
} }
void getMousePos(int* outX, int* outY)
{
NSRect originalFrame = [m_window frame];
NSPoint location = [m_window mouseLocationOutsideOfEventStream];
NSRect adjustFrame = [NSWindow contentRectForFrameRect: originalFrame styleMask: NSTitledWindowMask];
int x = location.x;
int y = (int)adjustFrame.size.height - (int)location.y;
// clamp within the range of the window
if (x < 0) x = 0;
if (y < 0) y = 0;
if (x > (int)adjustFrame.size.width) x = (int)adjustFrame.size.width;
if (y > (int)adjustFrame.size.height) y = (int)adjustFrame.size.height;
*outX = x;
*outY = y;
}
uint8_t translateModifiers(int flags)
{
uint8_t mask = 0;
if (flags & NSShiftKeyMask)
mask |= Modifier::LeftShift | Modifier::RightShift;
if (flags & NSAlternateKeyMask)
mask |= Modifier::LeftAlt | Modifier::RightAlt;
if (flags & NSControlKeyMask)
mask |= Modifier::LeftCtrl | Modifier::RightCtrl;
if (flags & NSCommandKeyMask)
mask |= Modifier::LeftMeta | Modifier::RightMeta;
return mask;
}
Key::Enum handleKeyEvent(NSEvent* event, uint8_t* specialKeys)
{
NSString* key = [event charactersIgnoringModifiers];
unichar keyChar = 0;
if ([key length] == 0)
return Key::None;
keyChar = [key characterAtIndex:0];
int keyCode = keyChar;
*specialKeys = translateModifiers([event modifierFlags]);
// if this is a unhandled key just return None
if (keyCode >= 256)
return Key::None;
return (Key::Enum)s_translateKey[keyCode];
}
bool dispatchEvent(NSEvent* event) bool dispatchEvent(NSEvent* event)
{ {
if (event) if (event)
{ {
NSEventType eventType = [event type];
switch (eventType)
{
case NSMouseMoved :
{
int x, y;
getMousePos(&x, &y);
m_eventQueue.postMouseEvent(s_defaultWindow, x, y, 0);
break;
}
case NSLeftMouseDown:
{
int x, y;
getMousePos(&x, &y);
m_eventQueue.postMouseEvent(s_defaultWindow, x, y, 0, MouseButton::Left, true);
break;
}
case NSLeftMouseUp:
{
int x, y;
getMousePos(&x, &y);
m_eventQueue.postMouseEvent(s_defaultWindow, x, y, 0, MouseButton::Left, false);
break;
}
case NSRightMouseDown:
{
int x, y;
getMousePos(&x, &y);
m_eventQueue.postMouseEvent(s_defaultWindow, x, y, 0, MouseButton::Right, true);
break;
}
case NSRightMouseUp:
{
int x, y;
getMousePos(&x, &y);
m_eventQueue.postMouseEvent(s_defaultWindow, x, y, 0, MouseButton::Right, false);
break;
}
case NSKeyDown:
{
uint8_t modifiers = 0;
Key::Enum key = handleKeyEvent(event, &modifiers);
// If KeyCode is none we don't don't handle the key and special case for cmd+q (quit)
// Note that return false here means that we take care of the key (instead of the default behavior)
if (key != Key::None)
{
if (key != Key::KeyQ && !((modifiers & Modifier::RightMeta)))
{
m_eventQueue.postKeyEvent(s_defaultWindow, key, modifiers, true);
return false;
}
}
break;
}
case NSKeyUp:
{
uint8_t modifiers = 0;
Key::Enum key = handleKeyEvent(event, &modifiers);
if (key != Key::None)
{
m_eventQueue.postKeyEvent(s_defaultWindow, key, modifiers, false);
return false;
}
break;
}
}
[NSApp sendEvent:event]; [NSApp sendEvent:event];
[NSApp updateWindows]; [NSApp updateWindows];
return true; return true;
} }
@ -229,9 +494,12 @@ namespace entry
[window cascadeTopLeftFromPoint:NSMakePoint(20,20)]; [window cascadeTopLeftFromPoint:NSMakePoint(20,20)];
[window makeKeyAndOrderFront:window]; [window makeKeyAndOrderFront:window];
// [window setContentView:nil]; // [window setContentView:nil];
[window setAcceptsMouseMovedEvents:YES];
[window setBackgroundColor:[NSColor blackColor]]; [window setBackgroundColor:[NSColor blackColor]];
[[Window sharedDelegate] windowCreated:window]; [[Window sharedDelegate] windowCreated:window];
m_window = window;
bgfx::osxSetNSWindow(window); bgfx::osxSetNSWindow(window);
MainThreadEntry mte; MainThreadEntry mte;
@ -265,6 +533,7 @@ namespace entry
EventQueue m_eventQueue; EventQueue m_eventQueue;
bool m_exit; bool m_exit;
NSWindow* m_window;
}; };
static Context s_ctx; static Context s_ctx;