added keyboard/mouse events to AppKit implementation

This commit is contained in:
Jack Andersen
2015-05-04 21:16:06 -10:00
parent afe93bee38
commit df4c484489
9 changed files with 600 additions and 31 deletions

View File

@@ -35,7 +35,7 @@ public:
/* High-Level API */ /* High-Level API */
bool sendHIDReport(const uint8_t* data, size_t length); bool sendHIDReport(const uint8_t* data, size_t length);
virtual size_t receiveReport(uint8_t* data, size_t length) {return 0;} virtual size_t receiveReport(uint8_t* data, size_t length) {(void)data;(void)length;return 0;}
}; };

View File

@@ -1,7 +1,8 @@
#ifndef CDEVICEFINDER_HPP #ifndef CDEVICEFINDER_HPP
#define CDEVICEFINDER_HPP #define CDEVICEFINDER_HPP
#include <set> #include <unordered_set>
#include <typeindex>
#include <mutex> #include <mutex>
#include <stdexcept> #include <stdexcept>
#include "CDeviceToken.hpp" #include "CDeviceToken.hpp"
@@ -91,18 +92,18 @@ public:
}; };
/* Application must specify its interested device-types */ /* Application must specify its interested device-types */
CDeviceFinder(std::vector<const char*> types) CDeviceFinder(std::unordered_set<std::type_index> types)
: m_listener(NULL) : m_listener(NULL)
{ {
if (skDevFinder) if (skDevFinder)
throw std::runtime_error("only one instance of CDeviceFinder may be constructed"); throw std::runtime_error("only one instance of CDeviceFinder may be constructed");
skDevFinder = this; skDevFinder = this;
for (const char* typeName : types) for (const std::type_index& typeIdx : types)
{ {
const SDeviceSignature* sigIter = BOO_DEVICE_SIGS; const SDeviceSignature* sigIter = BOO_DEVICE_SIGS;
while (sigIter->m_name) while (sigIter->m_name)
{ {
if (!strcmp(sigIter->m_name, typeName)) if (sigIter->m_typeIdx == typeIdx)
m_types.push_back(sigIter); m_types.push_back(sigIter);
++sigIter; ++sigIter;
} }

View File

@@ -40,10 +40,10 @@ struct SDolphinControllerState
struct IDolphinSmashAdapterCallback struct IDolphinSmashAdapterCallback
{ {
virtual void controllerConnected(unsigned idx, EDolphinControllerType type) {} virtual void controllerConnected(unsigned idx, EDolphinControllerType type) {(void)idx;(void)type;}
virtual void controllerDisconnected(unsigned idx, EDolphinControllerType type) {} virtual void controllerDisconnected(unsigned idx, EDolphinControllerType type) {(void)idx;(void)type;}
virtual void controllerUpdate(unsigned idx, EDolphinControllerType type, virtual void controllerUpdate(unsigned idx, EDolphinControllerType type,
const SDolphinControllerState& state) {} const SDolphinControllerState& state) {(void)idx;(void)type;(void)state;}
}; };
class CDolphinSmashAdapter final : public CDeviceBase class CDolphinSmashAdapter final : public CDeviceBase

View File

@@ -3,6 +3,7 @@
#include <vector> #include <vector>
#include <functional> #include <functional>
#include <typeindex>
namespace boo namespace boo
{ {
@@ -15,17 +16,18 @@ struct SDeviceSignature
typedef std::vector<const SDeviceSignature*> TDeviceSignatureSet; typedef std::vector<const SDeviceSignature*> TDeviceSignatureSet;
typedef std::function<CDeviceBase*(CDeviceToken*)> TFactoryLambda; typedef std::function<CDeviceBase*(CDeviceToken*)> TFactoryLambda;
const char* m_name; const char* m_name;
std::type_index m_typeIdx;
unsigned m_vid, m_pid; unsigned m_vid, m_pid;
TFactoryLambda m_factory; TFactoryLambda m_factory;
SDeviceSignature() : m_name(NULL) {} /* Sentinel constructor */ SDeviceSignature() : m_name(NULL), m_typeIdx(typeid(SDeviceSignature)) {} /* Sentinel constructor */
SDeviceSignature(const char* name, unsigned vid, unsigned pid, TFactoryLambda&& factory) SDeviceSignature(const char* name, std::type_index&& typeIdx, unsigned vid, unsigned pid, TFactoryLambda&& factory)
: m_name(name), m_vid(vid), m_pid(pid), m_factory(factory) {} : m_name(name), m_typeIdx(typeIdx), m_vid(vid), m_pid(pid), m_factory(factory) {}
static bool DeviceMatchToken(const CDeviceToken& token, const TDeviceSignatureSet& sigSet); static bool DeviceMatchToken(const CDeviceToken& token, const TDeviceSignatureSet& sigSet);
static CDeviceBase* DeviceNew(CDeviceToken& token); static CDeviceBase* DeviceNew(CDeviceToken& token);
}; };
#define DEVICE_SIG(name, vid, pid) \ #define DEVICE_SIG(name, vid, pid) \
SDeviceSignature(#name, vid, pid, [](CDeviceToken* tok) -> CDeviceBase* {return new name(tok);}) SDeviceSignature(#name, typeid(name), vid, pid, [](CDeviceToken* tok) -> CDeviceBase* {return new name(tok);})
#define DEVICE_SIG_SENTINEL() SDeviceSignature() #define DEVICE_SIG_SENTINEL() SDeviceSignature()
extern const SDeviceSignature BOO_DEVICE_SIGS[]; extern const SDeviceSignature BOO_DEVICE_SIGS[];

View File

@@ -6,6 +6,10 @@ namespace boo
class IGraphicsContext class IGraphicsContext
{ {
friend class CWindowCocoa;
virtual void _setPlatformWindowHandle(void* handle) {(void)handle;};
virtual void _setCallback(class IWindowCallback* cb) {(void)cb;};
public: public:
enum EGraphicsAPI enum EGraphicsAPI
@@ -16,7 +20,9 @@ public:
API_OPENGLES_3 = 3, API_OPENGLES_3 = 3,
API_VULKAN = 4, API_VULKAN = 4,
API_D3D11 = 5, API_D3D11 = 5,
API_METAL = 6 API_METAL = 6,
API_GX = 7,
API_GX2 = 8
}; };
enum EPixelFormat enum EPixelFormat
@@ -33,7 +39,6 @@ public:
virtual EGraphicsAPI getAPI() const=0; virtual EGraphicsAPI getAPI() const=0;
virtual EPixelFormat getPixelFormat() const=0; virtual EPixelFormat getPixelFormat() const=0;
virtual void setPixelFormat(EPixelFormat pf)=0; virtual void setPixelFormat(EPixelFormat pf)=0;
virtual void setPlatformWindowHandle(void* handle)=0;
virtual void initializeContext()=0; virtual void initializeContext()=0;
virtual IGraphicsContext* makeShareContext() const=0; virtual IGraphicsContext* makeShareContext() const=0;
virtual void makeCurrent()=0; virtual void makeCurrent()=0;

View File

@@ -5,6 +5,101 @@
namespace boo namespace boo
{ {
class IWindowCallback
{
public:
enum EMouseButton
{
BUTTON_NONE = 0,
BUTTON_PRIMARY = 1,
BUTTON_SECONDARY = 2,
BUTTON_MIDDLE = 3,
BUTTON_AUX1 = 4,
BUTTON_AUX2 = 5
};
struct SWindowCoord
{
unsigned pixel[2];
unsigned virtualPixel[2];
float norm[2];
};
struct SScrollDelta
{
float delta[2];
bool isFine; /* Use system-scale fine-scroll (for scrollable-trackpads) */
};
enum ESpecialKey
{
KEY_NONE = 0,
KEY_F1 = 1,
KEY_F2 = 2,
KEY_F3 = 3,
KEY_F4 = 4,
KEY_F5 = 5,
KEY_F6 = 6,
KEY_F7 = 7,
KEY_F8 = 8,
KEY_F9 = 9,
KEY_F10 = 10,
KEY_F11 = 11,
KEY_F12 = 12,
KEY_ESC = 13,
KEY_ENTER = 14,
KEY_BACKSPACE = 15,
KEY_INSERT = 16,
KEY_DELETE = 17,
KEY_HOME = 18,
KEY_END = 19,
KEY_PGUP = 20,
KEY_PGDOWN = 21,
KEY_LEFT = 22,
KEY_RIGHT = 23,
KEY_UP = 24,
KEY_DOWN = 25
};
enum EModifierKey
{
MKEY_NONE = 0,
MKEY_CTRL = 1<<0,
MKEY_ALT = 1<<2,
MKEY_SHIFT = 1<<3,
MKEY_COMMAND = 1<<4
};
virtual void mouseDown(const SWindowCoord& coord, EMouseButton button, EModifierKey mods)
{(void)coord;(void)button;(void)mods;}
virtual void mouseUp(const SWindowCoord& coord, EMouseButton button, EModifierKey mods)
{(void)coord;(void)button;(void)mods;}
virtual void mouseMove(const SWindowCoord& coord)
{(void)coord;}
virtual void scroll(const SScrollDelta& scroll)
{(void)scroll;};
virtual void touchDown(const SWindowCoord& coord, uintptr_t tid)
{(void)coord;(void)tid;}
virtual void touchUp(const SWindowCoord& coord, uintptr_t tid)
{(void)coord;(void)tid;}
virtual void touchMove(const SWindowCoord& coord, uintptr_t tid)
{(void)coord;(void)tid;}
virtual void charKeyDown(unsigned long charCode, EModifierKey mods, bool isRepeat)
{(void)charCode;(void)mods;(void)isRepeat;}
virtual void charKeyUp(unsigned long charCode, EModifierKey mods)
{(void)charCode;(void)mods;}
virtual void specialKeyDown(ESpecialKey key, EModifierKey mods, bool isRepeat)
{(void)key;(void)mods;(void)isRepeat;}
virtual void specialKeyUp(ESpecialKey key, EModifierKey mods)
{(void)key;(void)mods;}
virtual void modKeyDown(EModifierKey mod, bool isRepeat)
{(void)mod;(void)isRepeat;}
virtual void modKeyUp(EModifierKey mod) {(void)mod;}
};
class IWindow class IWindow
{ {
@@ -12,6 +107,8 @@ public:
virtual ~IWindow() {} virtual ~IWindow() {}
virtual void setCallback(IWindowCallback* cb)=0;
virtual void showWindow()=0; virtual void showWindow()=0;
virtual void hideWindow()=0; virtual void hideWindow()=0;
@@ -21,10 +118,19 @@ public:
virtual void setWindowFrameDefault()=0; virtual void setWindowFrameDefault()=0;
virtual void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const=0; virtual void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const=0;
virtual void setWindowFrame(float x, float y, float w, float h)=0; virtual void setWindowFrame(float x, float y, float w, float h)=0;
virtual float getVirtualPixelFactor() const=0;
virtual bool isFullscreen() const=0; virtual bool isFullscreen() const=0;
virtual void setFullscreen(bool fs)=0; virtual void setFullscreen(bool fs)=0;
enum ETouchType
{
TOUCH_NONE = 0,
TOUCH_DISPLAY = 1,
TOUCH_TRACKPAD = 2
};
virtual ETouchType getTouchType() const=0;
}; };
IWindow* IWindowNew(); IWindow* IWindowNew();

View File

@@ -2,6 +2,7 @@
#include <OpenGL/OpenGL.h> #include <OpenGL/OpenGL.h>
#include <OpenGL/gl3.h> #include <OpenGL/gl3.h>
#include "windowsys/IGraphicsContext.hpp" #include "windowsys/IGraphicsContext.hpp"
#include "windowsys/IWindow.hpp"
static const NSOpenGLPixelFormatAttribute PF_RGBA8_ATTRS[] = static const NSOpenGLPixelFormatAttribute PF_RGBA8_ATTRS[] =
{ {
@@ -54,6 +55,10 @@ static const NSOpenGLPixelFormatAttribute* PF_TABLE[] =
namespace boo {class CGraphicsContextCocoa;} namespace boo {class CGraphicsContextCocoa;}
@interface CGraphicsContextCocoaInternal : NSOpenGLView @interface CGraphicsContextCocoaInternal : NSOpenGLView
{
NSUInteger lastModifiers;
boo::CGraphicsContextCocoa* booContext;
}
- (id)initWithBooContext:(boo::CGraphicsContextCocoa*)bctx; - (id)initWithBooContext:(boo::CGraphicsContextCocoa*)bctx;
@end @end
@@ -70,12 +75,15 @@ class CGraphicsContextCocoa final : public IGraphicsContext
NSOpenGLContext* m_nsShareContext; NSOpenGLContext* m_nsShareContext;
public: public:
IWindowCallback* m_callback;
CGraphicsContextCocoa(EGraphicsAPI api) CGraphicsContextCocoa(EGraphicsAPI api)
: m_api(api), : m_api(api),
m_pf(PF_RGBA8), m_pf(PF_RGBA8),
m_parentWindow(NULL), m_parentWindow(NULL),
m_nsContext(NULL), m_nsContext(NULL),
m_nsShareContext(NULL) m_nsShareContext(NULL),
m_callback(NULL)
{} {}
~CGraphicsContextCocoa() ~CGraphicsContextCocoa()
@@ -84,6 +92,11 @@ public:
[m_nsShareContext release]; [m_nsShareContext release];
} }
void _setCallback(IWindowCallback* cb)
{
m_callback = cb;
}
EGraphicsAPI getAPI() const EGraphicsAPI getAPI() const
{ {
return m_api; return m_api;
@@ -197,11 +210,428 @@ IGraphicsContext* IGraphicsContextNew(IGraphicsContext::EGraphicsAPI api)
@implementation CGraphicsContextCocoaInternal @implementation CGraphicsContextCocoaInternal
- (id)initWithBooContext:(boo::CGraphicsContextCocoa*)bctx - (id)initWithBooContext:(boo::CGraphicsContextCocoa*)bctx
{ {
lastModifiers = 0;
booContext = bctx;
boo::IGraphicsContext::EPixelFormat pf = bctx->getPixelFormat(); boo::IGraphicsContext::EPixelFormat pf = bctx->getPixelFormat();
NSOpenGLPixelFormat* nspf = [[NSOpenGLPixelFormat alloc] initWithAttributes:PF_TABLE[pf]]; NSOpenGLPixelFormat* nspf = [[NSOpenGLPixelFormat alloc] initWithAttributes:PF_TABLE[pf]];
self = [self initWithFrame:NSMakeRect(0, 0, 100, 100) pixelFormat:nspf]; self = [self initWithFrame:NSMakeRect(0, 0, 100, 100) pixelFormat:nspf];
[nspf release]; [nspf release];
return self; return self;
} }
- (BOOL)acceptsTouchEvents
{
return YES;
}
static inline boo::IWindowCallback::EModifierKey getMod(NSEventModifierFlags flags)
{
int ret = boo::IWindowCallback::MKEY_NONE;
if (flags & NSControlKeyMask)
ret |= boo::IWindowCallback::MKEY_CTRL;
if (flags & NSAlternateKeyMask)
ret |= boo::IWindowCallback::MKEY_ALT;
if (flags & NSShiftKeyMask)
ret |= boo::IWindowCallback::MKEY_SHIFT;
if (flags & NSCommandKeyMask)
ret |= boo::IWindowCallback::MKEY_COMMAND;
return static_cast<boo::IWindowCallback::EModifierKey>(ret);
}
static inline boo::IWindowCallback::EMouseButton getButton(NSEvent* event)
{
NSInteger buttonNumber = event.buttonNumber;
if (buttonNumber == 3)
return boo::IWindowCallback::BUTTON_MIDDLE;
else if (buttonNumber == 4)
return boo::IWindowCallback::BUTTON_AUX1;
else if (buttonNumber == 5)
return boo::IWindowCallback::BUTTON_AUX2;
return boo::IWindowCallback::BUTTON_NONE;
}
- (void)mouseDown:(NSEvent*)theEvent
{
if (!booContext->m_callback)
return;
NSPoint liw = [self convertPoint:[theEvent locationInWindow] fromView:nil];
float pixelFactor = [[self window] backingScaleFactor];
NSRect frame = [self frame];
boo::IWindowCallback::SWindowCoord coord =
{
{(unsigned)(liw.x * pixelFactor), (unsigned)(liw.y * pixelFactor)},
{(unsigned)liw.x, (unsigned)liw.y},
{(float)(liw.x / frame.size.width), (float)(liw.y / frame.size.height)}
};
booContext->m_callback->mouseDown(coord, boo::IWindowCallback::BUTTON_PRIMARY,
getMod([theEvent modifierFlags]));
}
- (void)mouseUp:(NSEvent*)theEvent
{
if (!booContext->m_callback)
return;
NSPoint liw = [self convertPoint:[theEvent locationInWindow] fromView:nil];
float pixelFactor = [[self window] backingScaleFactor];
NSRect frame = [self frame];
boo::IWindowCallback::SWindowCoord coord =
{
{(unsigned)(liw.x * pixelFactor), (unsigned)(liw.y * pixelFactor)},
{(unsigned)liw.x, (unsigned)liw.y},
{(float)(liw.x / frame.size.width), (float)(liw.y / frame.size.height)}
};
booContext->m_callback->mouseUp(coord, boo::IWindowCallback::BUTTON_PRIMARY,
getMod([theEvent modifierFlags]));
}
- (void)rightMouseDown:(NSEvent*)theEvent
{
if (!booContext->m_callback)
return;
NSPoint liw = [self convertPoint:[theEvent locationInWindow] fromView:nil];
float pixelFactor = [[self window] backingScaleFactor];
NSRect frame = [self frame];
boo::IWindowCallback::SWindowCoord coord =
{
{(unsigned)(liw.x * pixelFactor), (unsigned)(liw.y * pixelFactor)},
{(unsigned)liw.x, (unsigned)liw.y},
{(float)(liw.x / frame.size.width), (float)(liw.y / frame.size.height)}
};
booContext->m_callback->mouseDown(coord, boo::IWindowCallback::BUTTON_SECONDARY,
getMod([theEvent modifierFlags]));
}
- (void)rightMouseUp:(NSEvent*)theEvent
{
if (!booContext->m_callback)
return;
NSPoint liw = [self convertPoint:[theEvent locationInWindow] fromView:nil];
float pixelFactor = [[self window] backingScaleFactor];
NSRect frame = [self frame];
boo::IWindowCallback::SWindowCoord coord =
{
{(unsigned)(liw.x * pixelFactor), (unsigned)(liw.y * pixelFactor)},
{(unsigned)liw.x, (unsigned)liw.y},
{(float)(liw.x / frame.size.width), (float)(liw.y / frame.size.height)}
};
booContext->m_callback->mouseUp(coord, boo::IWindowCallback::BUTTON_SECONDARY,
getMod([theEvent modifierFlags]));
}
- (void)otherMouseDown:(NSEvent*)theEvent
{
if (!booContext->m_callback)
return;
boo::IWindowCallback::EMouseButton button = getButton(theEvent);
if (!button)
return;
NSPoint liw = [self convertPoint:[theEvent locationInWindow] fromView:nil];
float pixelFactor = [[self window] backingScaleFactor];
NSRect frame = [self frame];
boo::IWindowCallback::SWindowCoord coord =
{
{(unsigned)(liw.x * pixelFactor), (unsigned)(liw.y * pixelFactor)},
{(unsigned)liw.x, (unsigned)liw.y},
{(float)(liw.x / frame.size.width), (float)(liw.y / frame.size.height)}
};
booContext->m_callback->mouseDown(coord, button, getMod([theEvent modifierFlags]));
}
- (void)otherMouseUp:(NSEvent*)theEvent
{
if (!booContext->m_callback)
return;
boo::IWindowCallback::EMouseButton button = getButton(theEvent);
if (!button)
return;
NSPoint liw = [self convertPoint:[theEvent locationInWindow] fromView:nil];
float pixelFactor = [[self window] backingScaleFactor];
NSRect frame = [self frame];
boo::IWindowCallback::SWindowCoord coord =
{
{(unsigned)(liw.x * pixelFactor), (unsigned)(liw.y * pixelFactor)},
{(unsigned)liw.x, (unsigned)liw.y},
{(float)(liw.x / frame.size.width), (float)(liw.y / frame.size.height)}
};
booContext->m_callback->mouseUp(coord, button, getMod([theEvent modifierFlags]));
}
- (void)mouseMoved:(NSEvent*)theEvent
{
if (!booContext->m_callback)
return;
NSPoint liw = [self convertPoint:[theEvent locationInWindow] fromView:nil];
float pixelFactor = [[self window] backingScaleFactor];
NSRect frame = [self frame];
boo::IWindowCallback::SWindowCoord coord =
{
{(unsigned)(liw.x * pixelFactor), (unsigned)(liw.y * pixelFactor)},
{(unsigned)liw.x, (unsigned)liw.y},
{(float)(liw.x / frame.size.width), (float)(liw.y / frame.size.height)}
};
booContext->m_callback->mouseMove(coord);
}
- (void)mouseDragged:(NSEvent*)theEvent
{
[self mouseMoved:theEvent];
}
- (void)rightMouseDragged:(NSEvent*)theEvent
{
[self mouseMoved:theEvent];
}
- (void)otherMouseDragged:(NSEvent*)theEvent
{
[self mouseMoved:theEvent];
}
- (void)scrollWheel:(NSEvent*)theEvent
{
if (!booContext->m_callback)
return;
boo::IWindowCallback::SScrollDelta scroll =
{
{(float)[theEvent scrollingDeltaX], (float)[theEvent scrollingDeltaY]},
(bool)[theEvent hasPreciseScrollingDeltas]
};
booContext->m_callback->scroll(scroll);
}
- (void)touchesBeganWithEvent:(NSEvent*)event
{
if (!booContext->m_callback)
return;
for (NSTouch* touch in [event touchesMatchingPhase:NSTouchPhaseBegan inView:nil])
{
NSPoint pos = touch.normalizedPosition;
boo::IWindowCallback::SWindowCoord coord =
{
{0, 0},
{0, 0},
{(float)pos.x, (float)pos.y}
};
booContext->m_callback->touchDown(coord, (uintptr_t)touch.identity);
}
}
- (void)touchesEndedWithEvent:(NSEvent*)event
{
if (!booContext->m_callback)
return;
for (NSTouch* touch in [event touchesMatchingPhase:NSTouchPhaseEnded inView:nil])
{
NSPoint pos = touch.normalizedPosition;
boo::IWindowCallback::SWindowCoord coord =
{
{0, 0},
{0, 0},
{(float)pos.x, (float)pos.y}
};
booContext->m_callback->touchUp(coord, (uintptr_t)touch.identity);
}
}
- (void)touchesMovedWithEvent:(NSEvent*)event
{
if (!booContext->m_callback)
return;
for (NSTouch* touch in [event touchesMatchingPhase:NSTouchPhaseMoved inView:nil])
{
NSPoint pos = touch.normalizedPosition;
boo::IWindowCallback::SWindowCoord coord =
{
{0, 0},
{0, 0},
{(float)pos.x, (float)pos.y}
};
booContext->m_callback->touchMove(coord, (uintptr_t)touch.identity);
}
}
- (void)touchesCancelledWithEvent:(NSEvent*)event
{
if (!booContext->m_callback)
return;
for (NSTouch* touch in [event touchesMatchingPhase:NSTouchPhaseCancelled inView:nil])
{
NSPoint pos = touch.normalizedPosition;
boo::IWindowCallback::SWindowCoord coord =
{
{0, 0},
{0, 0},
{(float)pos.x, (float)pos.y}
};
booContext->m_callback->touchUp(coord, (uintptr_t)touch.identity);
}
}
/* keycodes for keys that are independent of keyboard layout*/
enum
{
kVK_Return = 0x24,
kVK_Tab = 0x30,
kVK_Space = 0x31,
kVK_Delete = 0x33,
kVK_Escape = 0x35,
kVK_Command = 0x37,
kVK_Shift = 0x38,
kVK_CapsLock = 0x39,
kVK_Option = 0x3A,
kVK_Control = 0x3B,
kVK_RightShift = 0x3C,
kVK_RightOption = 0x3D,
kVK_RightControl = 0x3E,
kVK_Function = 0x3F,
kVK_F17 = 0x40,
kVK_VolumeUp = 0x48,
kVK_VolumeDown = 0x49,
kVK_Mute = 0x4A,
kVK_F18 = 0x4F,
kVK_F19 = 0x50,
kVK_F20 = 0x5A,
kVK_F5 = 0x60,
kVK_F6 = 0x61,
kVK_F7 = 0x62,
kVK_F3 = 0x63,
kVK_F8 = 0x64,
kVK_F9 = 0x65,
kVK_F11 = 0x67,
kVK_F13 = 0x69,
kVK_F16 = 0x6A,
kVK_F14 = 0x6B,
kVK_F10 = 0x6D,
kVK_F12 = 0x6F,
kVK_F15 = 0x71,
kVK_Help = 0x72,
kVK_Home = 0x73,
kVK_PageUp = 0x74,
kVK_ForwardDelete = 0x75,
kVK_F4 = 0x76,
kVK_End = 0x77,
kVK_F2 = 0x78,
kVK_PageDown = 0x79,
kVK_F1 = 0x7A,
kVK_LeftArrow = 0x7B,
kVK_RightArrow = 0x7C,
kVK_DownArrow = 0x7D,
kVK_UpArrow = 0x7E
};
static boo::IWindowCallback::ESpecialKey translateKeycode(short code)
{
switch (code) {
case kVK_F1:
return boo::IWindowCallback::KEY_F1;
case kVK_F2:
return boo::IWindowCallback::KEY_F2;
case kVK_F3:
return boo::IWindowCallback::KEY_F3;
case kVK_F4:
return boo::IWindowCallback::KEY_F4;
case kVK_F5:
return boo::IWindowCallback::KEY_F5;
case kVK_F6:
return boo::IWindowCallback::KEY_F6;
case kVK_F7:
return boo::IWindowCallback::KEY_F7;
case kVK_F8:
return boo::IWindowCallback::KEY_F8;
case kVK_F9:
return boo::IWindowCallback::KEY_F9;
case kVK_F10:
return boo::IWindowCallback::KEY_F10;
case kVK_F11:
return boo::IWindowCallback::KEY_F11;
case kVK_F12:
return boo::IWindowCallback::KEY_F12;
case kVK_Escape:
return boo::IWindowCallback::KEY_ESC;
case kVK_Return:
return boo::IWindowCallback::KEY_ENTER;
case kVK_Delete:
return boo::IWindowCallback::KEY_BACKSPACE;
case kVK_ForwardDelete:
return boo::IWindowCallback::KEY_DELETE;
case kVK_Home:
return boo::IWindowCallback::KEY_HOME;
case kVK_End:
return boo::IWindowCallback::KEY_END;
case kVK_PageUp:
return boo::IWindowCallback::KEY_PGUP;
case kVK_PageDown:
return boo::IWindowCallback::KEY_PGDOWN;
case kVK_LeftArrow:
return boo::IWindowCallback::KEY_LEFT;
case kVK_RightArrow:
return boo::IWindowCallback::KEY_RIGHT;
case kVK_UpArrow:
return boo::IWindowCallback::KEY_UP;
case kVK_DownArrow:
return boo::IWindowCallback::KEY_DOWN;
default:
return boo::IWindowCallback::KEY_NONE;
}
}
- (void)keyDown:(NSEvent*)theEvent
{
if (!booContext->m_callback)
return;
NSString* chars = theEvent.characters;
if ([chars length] == 0)
booContext->m_callback->specialKeyDown(translateKeycode(theEvent.keyCode),
getMod(theEvent.modifierFlags),
theEvent.isARepeat);
else
booContext->m_callback->charKeyDown([chars characterAtIndex:0],
getMod(theEvent.modifierFlags),
theEvent.isARepeat);
}
- (void)keyUp:(NSEvent*)theEvent
{
if (!booContext->m_callback)
return;
NSString* chars = theEvent.characters;
if ([chars length] == 0)
booContext->m_callback->specialKeyUp(translateKeycode(theEvent.keyCode),
getMod(theEvent.modifierFlags));
else
booContext->m_callback->charKeyUp([chars characterAtIndex:0],
getMod(theEvent.modifierFlags));
}
- (void)flagsChanged:(NSEvent*)theEvent
{
if (!booContext->m_callback)
return;
NSUInteger modFlags = theEvent.modifierFlags;
bool isRepeat = theEvent.isARepeat;
if (modFlags != lastModifiers)
{
NSUInteger changedFlags = modFlags ^ lastModifiers;
NSUInteger downFlags = changedFlags & modFlags;
if (downFlags & NSControlKeyMask)
booContext->m_callback->modKeyDown(boo::IWindowCallback::MKEY_CTRL, isRepeat);
if (downFlags & NSAlternateKeyMask)
booContext->m_callback->modKeyDown(boo::IWindowCallback::MKEY_ALT, isRepeat);
if (downFlags & NSShiftKeyMask)
booContext->m_callback->modKeyDown(boo::IWindowCallback::MKEY_SHIFT, isRepeat);
if (downFlags & NSCommandKeyMask)
booContext->m_callback->modKeyDown(boo::IWindowCallback::MKEY_COMMAND, isRepeat);
NSUInteger upFlags = changedFlags & ~modFlags;
if (upFlags & NSControlKeyMask)
booContext->m_callback->modKeyUp(boo::IWindowCallback::MKEY_CTRL);
if (upFlags & NSAlternateKeyMask)
booContext->m_callback->modKeyUp(boo::IWindowCallback::MKEY_ALT);
if (upFlags & NSShiftKeyMask)
booContext->m_callback->modKeyUp(boo::IWindowCallback::MKEY_SHIFT);
if (upFlags & NSCommandKeyMask)
booContext->m_callback->modKeyUp(boo::IWindowCallback::MKEY_COMMAND);
lastModifiers = modFlags;
}
}
@end @end

View File

@@ -2,7 +2,12 @@
#include "windowsys/IWindow.hpp" #include "windowsys/IWindow.hpp"
#include "windowsys/IGraphicsContext.hpp" #include "windowsys/IGraphicsContext.hpp"
namespace boo {class CWindowCocoa;}
@interface CWindowCocoaInternal : NSWindow @interface CWindowCocoaInternal : NSWindow
{
boo::CWindowCocoa* booWindow;
}
- (id)initWithBooWindow:(boo::CWindowCocoa*)bw;
@end @end
namespace boo namespace boo
@@ -13,13 +18,14 @@ class CWindowCocoa final : public IWindow
CWindowCocoaInternal* m_nsWindow; CWindowCocoaInternal* m_nsWindow;
IGraphicsContext* m_gfxCtx; IGraphicsContext* m_gfxCtx;
public: public:
CWindowCocoa() CWindowCocoa()
{ {
m_nsWindow = [CWindowCocoaInternal new]; m_nsWindow = [[CWindowCocoaInternal alloc] initWithBooWindow:this];
m_gfxCtx = IGraphicsContextNew(IGraphicsContext::API_OPENGL_3_3); m_gfxCtx = IGraphicsContextNew(IGraphicsContext::API_OPENGL_3_3);
m_gfxCtx->setPlatformWindowHandle(m_nsWindow); m_gfxCtx->_setPlatformWindowHandle(m_nsWindow);
m_gfxCtx->initializeContext(); m_gfxCtx->initializeContext();
} }
@@ -30,6 +36,11 @@ public:
delete m_gfxCtx; delete m_gfxCtx;
} }
void setCallback(IWindowCallback* cb)
{
m_gfxCtx->_setCallback(cb);
}
void showWindow() void showWindow()
{ {
[m_nsWindow makeKeyAndOrderFront:nil]; [m_nsWindow makeKeyAndOrderFront:nil];
@@ -74,6 +85,11 @@ public:
[m_nsWindow setFrame:wFrame display:NO]; [m_nsWindow setFrame:wFrame display:NO];
} }
float getVirtualPixelFactor() const
{
return [m_nsWindow backingScaleFactor];
}
bool isFullscreen() const bool isFullscreen() const
{ {
return ([m_nsWindow styleMask] & NSFullScreenWindowMask) == NSFullScreenWindowMask; return ([m_nsWindow styleMask] & NSFullScreenWindowMask) == NSFullScreenWindowMask;
@@ -85,6 +101,11 @@ public:
[m_nsWindow toggleFullScreen:nil]; [m_nsWindow toggleFullScreen:nil];
} }
ETouchType getTouchType() const
{
return TOUCH_TRACKPAD;
}
}; };
IWindow* IWindowNew() IWindow* IWindowNew()
@@ -95,8 +116,17 @@ IWindow* IWindowNew()
} }
@implementation CWindowCocoaInternal @implementation CWindowCocoaInternal
- (id)initWithBooWindow:(boo::CWindowCocoa *)bw
{ {
self = [self initWithContentRect:NSMakeRect(0, 0, 100, 100)
styleMask:NSTitledWindowMask|
NSClosableWindowMask|
NSMiniaturizableWindowMask|
NSResizableWindowMask
backing:NSBackingStoreBuffered
defer:YES];
booWindow = bw;
return self;
} }
@end @end

View File

@@ -20,15 +20,15 @@ namespace boo
class CDolphinSmashAdapterCallback : public IDolphinSmashAdapterCallback class CDolphinSmashAdapterCallback : public IDolphinSmashAdapterCallback
{ {
void controllerConnected(unsigned idx, EDolphinControllerType type) void controllerConnected(unsigned idx, EDolphinControllerType)
{ {
printf("CONTROLLER %u CONNECTED\n", idx); printf("CONTROLLER %u CONNECTED\n", idx);
} }
void controllerDisconnected(unsigned idx, EDolphinControllerType type) void controllerDisconnected(unsigned idx, EDolphinControllerType)
{ {
printf("CONTROLLER %u DISCONNECTED\n", idx); printf("CONTROLLER %u DISCONNECTED\n", idx);
} }
void controllerUpdate(unsigned idx, EDolphinControllerType type, void controllerUpdate(unsigned idx, EDolphinControllerType,
const SDolphinControllerState& state) const SDolphinControllerState& state)
{ {
printf("CONTROLLER %u UPDATE %d %d\n", idx, state.m_leftStick[0], state.m_leftStick[1]); printf("CONTROLLER %u UPDATE %d %d\n", idx, state.m_leftStick[0], state.m_leftStick[1]);
@@ -41,7 +41,7 @@ class CTestDeviceFinder : public CDeviceFinder
CDolphinSmashAdapterCallback m_cb; CDolphinSmashAdapterCallback m_cb;
public: public:
CTestDeviceFinder() CTestDeviceFinder()
: CDeviceFinder({"CDolphinSmashAdapter"}) : CDeviceFinder({typeid(CDolphinSmashAdapter)})
{} {}
void deviceConnected(CDeviceToken& tok) void deviceConnected(CDeviceToken& tok)
{ {
@@ -141,19 +141,14 @@ int APIENTRY wWinMain(
#else #else
int main(int argc, char** argv) int main(int, char**)
{ {
boo::CTestDeviceFinder finder; boo::CTestDeviceFinder finder;
finder.startScanning(); finder.startScanning();
#if 0 boo::IWindow* window = boo::IWindowNew();
boo::IGraphicsContext* ctx = new boo::CGraphicsContext; (void)window;
if (ctx->create())
{
}
#endif
#if __APPLE__ #if __APPLE__
CFRunLoopRun(); CFRunLoopRun();