diff --git a/include/inputdev/CDeviceBase.hpp b/include/inputdev/CDeviceBase.hpp index 392802f..6319dc1 100644 --- a/include/inputdev/CDeviceBase.hpp +++ b/include/inputdev/CDeviceBase.hpp @@ -35,7 +35,7 @@ public: /* High-Level API */ 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;} }; diff --git a/include/inputdev/CDeviceFinder.hpp b/include/inputdev/CDeviceFinder.hpp index ec68a78..00f09b3 100644 --- a/include/inputdev/CDeviceFinder.hpp +++ b/include/inputdev/CDeviceFinder.hpp @@ -1,7 +1,8 @@ #ifndef CDEVICEFINDER_HPP #define CDEVICEFINDER_HPP -#include +#include +#include #include #include #include "CDeviceToken.hpp" @@ -91,18 +92,18 @@ public: }; /* Application must specify its interested device-types */ - CDeviceFinder(std::vector types) + CDeviceFinder(std::unordered_set types) : m_listener(NULL) { if (skDevFinder) throw std::runtime_error("only one instance of CDeviceFinder may be constructed"); skDevFinder = this; - for (const char* typeName : types) + for (const std::type_index& typeIdx : types) { const SDeviceSignature* sigIter = BOO_DEVICE_SIGS; while (sigIter->m_name) { - if (!strcmp(sigIter->m_name, typeName)) + if (sigIter->m_typeIdx == typeIdx) m_types.push_back(sigIter); ++sigIter; } diff --git a/include/inputdev/CDolphinSmashAdapter.hpp b/include/inputdev/CDolphinSmashAdapter.hpp index ceb0795..ae21b15 100644 --- a/include/inputdev/CDolphinSmashAdapter.hpp +++ b/include/inputdev/CDolphinSmashAdapter.hpp @@ -40,10 +40,10 @@ struct SDolphinControllerState struct IDolphinSmashAdapterCallback { - virtual void controllerConnected(unsigned idx, EDolphinControllerType type) {} - virtual void controllerDisconnected(unsigned idx, EDolphinControllerType type) {} + virtual void controllerConnected(unsigned idx, EDolphinControllerType type) {(void)idx;(void)type;} + virtual void controllerDisconnected(unsigned idx, EDolphinControllerType type) {(void)idx;(void)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 diff --git a/include/inputdev/SDeviceSignature.hpp b/include/inputdev/SDeviceSignature.hpp index 80708b9..7c89d62 100644 --- a/include/inputdev/SDeviceSignature.hpp +++ b/include/inputdev/SDeviceSignature.hpp @@ -3,6 +3,7 @@ #include #include +#include namespace boo { @@ -15,17 +16,18 @@ struct SDeviceSignature typedef std::vector TDeviceSignatureSet; typedef std::function TFactoryLambda; const char* m_name; + std::type_index m_typeIdx; unsigned m_vid, m_pid; TFactoryLambda m_factory; - SDeviceSignature() : m_name(NULL) {} /* Sentinel constructor */ - SDeviceSignature(const char* name, unsigned vid, unsigned pid, TFactoryLambda&& factory) - : m_name(name), m_vid(vid), m_pid(pid), m_factory(factory) {} + SDeviceSignature() : m_name(NULL), m_typeIdx(typeid(SDeviceSignature)) {} /* Sentinel constructor */ + SDeviceSignature(const char* name, std::type_index&& typeIdx, unsigned vid, unsigned pid, TFactoryLambda&& 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 CDeviceBase* DeviceNew(CDeviceToken& token); }; #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() extern const SDeviceSignature BOO_DEVICE_SIGS[]; diff --git a/include/windowsys/IGraphicsContext.hpp b/include/windowsys/IGraphicsContext.hpp index ebcd5c6..e1ba30e 100644 --- a/include/windowsys/IGraphicsContext.hpp +++ b/include/windowsys/IGraphicsContext.hpp @@ -6,6 +6,10 @@ namespace boo class IGraphicsContext { + friend class CWindowCocoa; + virtual void _setPlatformWindowHandle(void* handle) {(void)handle;}; + virtual void _setCallback(class IWindowCallback* cb) {(void)cb;}; + public: enum EGraphicsAPI @@ -16,7 +20,9 @@ public: API_OPENGLES_3 = 3, API_VULKAN = 4, API_D3D11 = 5, - API_METAL = 6 + API_METAL = 6, + API_GX = 7, + API_GX2 = 8 }; enum EPixelFormat @@ -33,7 +39,6 @@ public: virtual EGraphicsAPI getAPI() const=0; virtual EPixelFormat getPixelFormat() const=0; virtual void setPixelFormat(EPixelFormat pf)=0; - virtual void setPlatformWindowHandle(void* handle)=0; virtual void initializeContext()=0; virtual IGraphicsContext* makeShareContext() const=0; virtual void makeCurrent()=0; diff --git a/include/windowsys/IWindow.hpp b/include/windowsys/IWindow.hpp index 212b44c..f5a7d46 100644 --- a/include/windowsys/IWindow.hpp +++ b/include/windowsys/IWindow.hpp @@ -5,6 +5,101 @@ 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 { @@ -12,6 +107,8 @@ public: virtual ~IWindow() {} + virtual void setCallback(IWindowCallback* cb)=0; + virtual void showWindow()=0; virtual void hideWindow()=0; @@ -21,10 +118,19 @@ public: virtual void setWindowFrameDefault()=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 float getVirtualPixelFactor() const=0; virtual bool isFullscreen() const=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(); diff --git a/src/windowsys/CGraphicsContextCocoa.mm b/src/windowsys/CGraphicsContextCocoa.mm index e217697..2a0ed3f 100644 --- a/src/windowsys/CGraphicsContextCocoa.mm +++ b/src/windowsys/CGraphicsContextCocoa.mm @@ -2,6 +2,7 @@ #include #include #include "windowsys/IGraphicsContext.hpp" +#include "windowsys/IWindow.hpp" static const NSOpenGLPixelFormatAttribute PF_RGBA8_ATTRS[] = { @@ -54,6 +55,10 @@ static const NSOpenGLPixelFormatAttribute* PF_TABLE[] = namespace boo {class CGraphicsContextCocoa;} @interface CGraphicsContextCocoaInternal : NSOpenGLView +{ + NSUInteger lastModifiers; + boo::CGraphicsContextCocoa* booContext; +} - (id)initWithBooContext:(boo::CGraphicsContextCocoa*)bctx; @end @@ -70,12 +75,15 @@ class CGraphicsContextCocoa final : public IGraphicsContext NSOpenGLContext* m_nsShareContext; public: + IWindowCallback* m_callback; + CGraphicsContextCocoa(EGraphicsAPI api) : m_api(api), m_pf(PF_RGBA8), m_parentWindow(NULL), m_nsContext(NULL), - m_nsShareContext(NULL) + m_nsShareContext(NULL), + m_callback(NULL) {} ~CGraphicsContextCocoa() @@ -84,6 +92,11 @@ public: [m_nsShareContext release]; } + void _setCallback(IWindowCallback* cb) + { + m_callback = cb; + } + EGraphicsAPI getAPI() const { return m_api; @@ -197,11 +210,428 @@ IGraphicsContext* IGraphicsContextNew(IGraphicsContext::EGraphicsAPI api) @implementation CGraphicsContextCocoaInternal - (id)initWithBooContext:(boo::CGraphicsContextCocoa*)bctx { + lastModifiers = 0; + booContext = bctx; boo::IGraphicsContext::EPixelFormat pf = bctx->getPixelFormat(); NSOpenGLPixelFormat* nspf = [[NSOpenGLPixelFormat alloc] initWithAttributes:PF_TABLE[pf]]; self = [self initWithFrame:NSMakeRect(0, 0, 100, 100) pixelFormat:nspf]; [nspf release]; 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(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 diff --git a/src/windowsys/CWindowCocoa.mm b/src/windowsys/CWindowCocoa.mm index 9d41c3a..0fde361 100644 --- a/src/windowsys/CWindowCocoa.mm +++ b/src/windowsys/CWindowCocoa.mm @@ -2,7 +2,12 @@ #include "windowsys/IWindow.hpp" #include "windowsys/IGraphicsContext.hpp" +namespace boo {class CWindowCocoa;} @interface CWindowCocoaInternal : NSWindow +{ + boo::CWindowCocoa* booWindow; +} +- (id)initWithBooWindow:(boo::CWindowCocoa*)bw; @end namespace boo @@ -13,13 +18,14 @@ class CWindowCocoa final : public IWindow CWindowCocoaInternal* m_nsWindow; IGraphicsContext* m_gfxCtx; - + public: + CWindowCocoa() { - m_nsWindow = [CWindowCocoaInternal new]; + m_nsWindow = [[CWindowCocoaInternal alloc] initWithBooWindow:this]; m_gfxCtx = IGraphicsContextNew(IGraphicsContext::API_OPENGL_3_3); - m_gfxCtx->setPlatformWindowHandle(m_nsWindow); + m_gfxCtx->_setPlatformWindowHandle(m_nsWindow); m_gfxCtx->initializeContext(); } @@ -30,6 +36,11 @@ public: delete m_gfxCtx; } + void setCallback(IWindowCallback* cb) + { + m_gfxCtx->_setCallback(cb); + } + void showWindow() { [m_nsWindow makeKeyAndOrderFront:nil]; @@ -74,6 +85,11 @@ public: [m_nsWindow setFrame:wFrame display:NO]; } + float getVirtualPixelFactor() const + { + return [m_nsWindow backingScaleFactor]; + } + bool isFullscreen() const { return ([m_nsWindow styleMask] & NSFullScreenWindowMask) == NSFullScreenWindowMask; @@ -85,6 +101,11 @@ public: [m_nsWindow toggleFullScreen:nil]; } + ETouchType getTouchType() const + { + return TOUCH_TRACKPAD; + } + }; IWindow* IWindowNew() @@ -95,8 +116,17 @@ IWindow* IWindowNew() } @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 diff --git a/test/main.cpp b/test/main.cpp index 79e4b27..d287d65 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -20,15 +20,15 @@ namespace boo class CDolphinSmashAdapterCallback : public IDolphinSmashAdapterCallback { - void controllerConnected(unsigned idx, EDolphinControllerType type) + void controllerConnected(unsigned idx, EDolphinControllerType) { printf("CONTROLLER %u CONNECTED\n", idx); } - void controllerDisconnected(unsigned idx, EDolphinControllerType type) + void controllerDisconnected(unsigned idx, EDolphinControllerType) { printf("CONTROLLER %u DISCONNECTED\n", idx); } - void controllerUpdate(unsigned idx, EDolphinControllerType type, + void controllerUpdate(unsigned idx, EDolphinControllerType, const SDolphinControllerState& state) { 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; public: CTestDeviceFinder() - : CDeviceFinder({"CDolphinSmashAdapter"}) + : CDeviceFinder({typeid(CDolphinSmashAdapter)}) {} void deviceConnected(CDeviceToken& tok) { @@ -141,19 +141,14 @@ int APIENTRY wWinMain( #else -int main(int argc, char** argv) +int main(int, char**) { boo::CTestDeviceFinder finder; finder.startScanning(); -#if 0 - boo::IGraphicsContext* ctx = new boo::CGraphicsContext; - - if (ctx->create()) - { - } -#endif + boo::IWindow* window = boo::IWindowNew(); + (void)window; #if __APPLE__ CFRunLoopRun();