diff --git a/include/CInputDeferredRelay.hpp b/include/CInputDeferredRelay.hpp deleted file mode 100644 index 524261c..0000000 --- a/include/CInputDeferredRelay.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef CINPUTDEFERREDRELAY_HPP -#define CINPUTDEFERREDRELAY_HPP - -#include "IInputWaiter.hpp" - -namespace boo -{ - -} - -#endif // CINPUTDEFERREDRELAY_HPP diff --git a/include/CInputRelay.hpp b/include/CInputRelay.hpp deleted file mode 100644 index 03eacbe..0000000 --- a/include/CInputRelay.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef CINPUTRELAY_HPP -#define CINPUTRELAY_HPP - -#include "IInputWaiter.hpp" - -namespace boo -{ - -class CInputRelay : IInputWaiter -{ - -}; - -} - -#endif // CINPUTRELAY_HPP diff --git a/include/CQtOpenGLWindow.hpp b/include/CQtOpenGLWindow.hpp deleted file mode 100644 index 650513c..0000000 --- a/include/CQtOpenGLWindow.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef CQTOPENGLWINDOW_HPP -#define CQTOPENGLWINDOW_HPP - -#include -#include -#include - -class CQtOpenGLWindow : public QWindow, ISurface -{ - Q_OBJECT -public: - explicit CQtOpenGLWindow(QWindow *parent = 0); - CQtOpenGLWindow(); - - virtual void render(); - - virtual void initialize(); - - - public slots: - void renderLater(); - void renderNow(); - -protected: - bool event(QEvent *event) Q_DECL_OVERRIDE; - - void exposeEvent(QExposeEvent *event) Q_DECL_OVERRIDE; - -private: - bool m_update_pending; - bool m_animating; - - QOpenGLContext *m_context; -}; - -#endif // CQTOPENGLWINDOW_HPP diff --git a/include/CSurface.hpp b/include/CSurface.hpp deleted file mode 100644 index a1916a8..0000000 --- a/include/CSurface.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef CSURFACE_HPP -#define CSURFACE_HPP - -#include "ISurface.hpp" - -namespace boo -{ - -ISurface* CSurfaceNewWindow(); -ISurface* CSurfaceNewQWidget(); - -} - -#endif // CSURFACE_HPP diff --git a/include/IApplication.hpp b/include/IApplication.hpp new file mode 100644 index 0000000..5c1690b --- /dev/null +++ b/include/IApplication.hpp @@ -0,0 +1,79 @@ +#ifndef IRUNLOOP_HPP +#define IRUNLOOP_HPP + +#include +#include + +#include "windowsys/IWindow.hpp" +#include "inputdev/CDeviceFinder.hpp" + +namespace boo +{ +class IApplication; + +struct IApplicationCallback +{ + virtual void appLaunched(IApplication* app) {(void)app;} + virtual void appQuitting(IApplication* app) {(void)app;} + virtual bool appFileOpen(IApplication* app, const std::string& path) {(void)app;(void)path;return true;} +}; + +class IApplication +{ + friend class CWindowCocoa; + friend class CWindowWayland; + friend class CWindowXCB; + friend class CWindowWin32; + virtual void _deletedWindow(IWindow* window)=0; +public: + virtual ~IApplication() {} + + enum EPlatformType + { + PLAT_AUTO = 0, + PLAT_WAYLAND = 1, + PLAT_XCB = 2, + PLAT_ANDROID = 3, + PLAT_COCOA = 4, + PLAT_COCOA_TOUCH = 5, + PLAT_WIN32 = 6, + PLAT_WINRT = 7, + PLAT_REVOLUTION = 8, + PLAT_CAFE = 9 + }; + virtual EPlatformType getPlatformType() const=0; + + virtual void run()=0; + virtual void quit()=0; + virtual const std::string& getProcessName() const=0; + virtual const std::vector& getArgs() const=0; + + /* Constructors/initializers for sub-objects */ + virtual IWindow* newWindow(const std::string& title)=0; + +}; + +IApplication* IApplicationBootstrap(IApplication::EPlatformType platform, + IApplicationCallback& cb, + const std::string& friendlyName, + const std::string& pname, + const std::vector& args); +extern IApplication* APP; +#define IApplicationInstance() APP + +static inline IApplication* IApplicationBootstrap(IApplication::EPlatformType platform, + IApplicationCallback& cb, + const std::string& friendlyName, + int argc, char** argv) +{ + if (APP) + return APP; + std::vector args; + for (int i=1 ; i - -namespace boo -{ - -class IGraphicsContext -{ -public: - virtual ~IGraphicsContext() {} - - virtual void setMinVersion (const int& min)=0; - virtual void setMajorVersion(const int& maj)=0; - virtual bool create()=0; - virtual const std::string version() const=0; - virtual const std::string name() const=0; - virtual int depthSize() const=0; - virtual int redDepth() const=0; - virtual int greenDepth() const=0; - virtual int blueDepth() const=0; -}; - -} - -#endif // IGRAPHICSCONTEXT_HPP diff --git a/include/IInputWaiter.hpp b/include/IInputWaiter.hpp deleted file mode 100644 index 552a2d8..0000000 --- a/include/IInputWaiter.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef IINPUTWAITER_HPP -#define IINPUTWAITER_HPP - -namespace boo -{ - -class IInputWaiter -{ - -}; - -} - -#endif // IINPUTWAITER_HPP diff --git a/include/IRetraceWaiter.hpp b/include/IRetraceWaiter.hpp deleted file mode 100644 index aacd34f..0000000 --- a/include/IRetraceWaiter.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef IRETRACEWAITER_HPP -#define IRETRACEWAITER_HPP - -namespace boo -{ - -class IRetraceWaiter -{ - -}; - -} - -#endif // IRETRACEWAITER_HPP diff --git a/include/ISurface.hpp b/include/ISurface.hpp deleted file mode 100644 index 6f2f13d..0000000 --- a/include/ISurface.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef ISURFACE_HPP -#define ISURFACE_HPP - -namespace boo -{ - -class ISurface -{ -public: - -}; - -} - -#endif // CSURFACE_HPP diff --git a/include/boo.hpp b/include/boo.hpp index f4f01c9..c2a5e6f 100644 --- a/include/boo.hpp +++ b/include/boo.hpp @@ -1,6 +1,7 @@ #ifndef BOO_HPP #define BOO_HPP +#include "IApplication.hpp" #include "windowsys/IWindow.hpp" #include "inputdev/CDeviceFinder.hpp" #include "inputdev/CDolphinSmashAdapter.hpp" diff --git a/include/win/CWGLContext.hpp b/include/win/CWGLContext.hpp deleted file mode 100644 index ea40ff7..0000000 --- a/include/win/CWGLContext.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef CWGLCONTEXT_HPP -#define CWGLCONTEXT_HPP - -#ifdef _WIN32 - -#include "IGraphicsContext.hpp" - -namespace boo -{ - -class CWGLContext : public IGraphicsContext -{ - -}; - -} - -#endif // _WIN32 -#endif // CWGLCONTEXT_HPP diff --git a/include/windowsys/IGraphicsContext.hpp b/include/windowsys/IGraphicsContext.hpp index e1ba30e..3411570 100644 --- a/include/windowsys/IGraphicsContext.hpp +++ b/include/windowsys/IGraphicsContext.hpp @@ -50,8 +50,6 @@ public: }; -IGraphicsContext* IGraphicsContextNew(IGraphicsContext::EGraphicsAPI api); - } #endif // IGRAPHICSCONTEXT_HPP diff --git a/include/windowsys/IWindow.hpp b/include/windowsys/IWindow.hpp index f5a7d46..4cd70d8 100644 --- a/include/windowsys/IWindow.hpp +++ b/include/windowsys/IWindow.hpp @@ -123,6 +123,8 @@ public: virtual bool isFullscreen() const=0; virtual void setFullscreen(bool fs)=0; + virtual void* getPlatformHandle() const=0; + enum ETouchType { TOUCH_NONE = 0, @@ -133,8 +135,6 @@ public: }; -IWindow* IWindowNew(); - } #endif // IWINDOW_HPP diff --git a/include/x11/CGLXContext.hpp b/include/x11/CGLXContext.hpp deleted file mode 100644 index 809101a..0000000 --- a/include/x11/CGLXContext.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef CGLXCONTEXT_HPP -#define CGLXCONTEXT_HPP - -#if !defined(__APPLE__) && (defined(__linux__) || defined(BSD)) -#include -#include "IGraphicsContext.hpp" - -namespace boo -{ - -class CGLXContext final : public IGraphicsContext -{ -public: - CGLXContext(); - virtual ~CGLXContext() {} - - bool create(); - void setMajorVersion(const int& maj) override; - void setMinVersion(const int& min) override; - const std::string version() const override; - const std::string name() const override; - int depthSize() const override; - int redDepth() const override; - int greenDepth() const override; - int blueDepth() const override; -private: - int m_majVersion; - int m_minVersion; - - Display* m_display; -}; - -} - -#endif // !defined(__APPLE__) && (defined(__linux__) || defined(BSD)) -#endif // CGLXCONTEXT_HPP diff --git a/libBoo.pri b/libBoo.pri index f15161c..36a9714 100644 --- a/libBoo.pri +++ b/libBoo.pri @@ -1,5 +1,6 @@ HEADERS += \ $$PWD/include/boo.hpp \ + $$PWD/include/IApplication.hpp \ $$PWD/include/windowsys/IWindow.hpp \ $$PWD/include/windowsys/IGraphicsContext.hpp \ $$PWD/include/inputdev/CDolphinSmashAdapter.hpp \ @@ -16,10 +17,6 @@ HEADERS += \ SOURCES += \ $$PWD/InputDeviceClasses.cpp \ - $$PWD/src/CSurface.cpp \ - $$PWD/src/CRetraceWaiter.cpp \ - $$PWD/src/CInputRelay.cpp \ - $$PWD/src/CInputDeferredRelay.cpp \ $$PWD/src/inputdev/CDolphinSmashAdapter.cpp \ $$PWD/src/inputdev/CRevolutionPad.cpp \ $$PWD/src/inputdev/CCafeProPad.cpp \ @@ -29,10 +26,13 @@ SOURCES += \ $$PWD/src/inputdev/SDeviceSignature.cpp unix:!macx { - HEADERS += \ - $$PWD/include/x11/CGLXContext.hpp SOURCES += \ - $$PWD/src/x11/CGLXContext.cpp + $$PWD/src/CApplicationXCB.cpp \ + $$PWD/src/CApplicationWayland.cpp \ + $$PWD/src/windowsys/CWindowXCB.cpp \ + $$PWD/src/windowsys/CWindowWayland.cpp \ + $$PWD/src/windowsys/CGraphicsContextXCB.cpp \ + $$PWD/src/windowsys/CGraphicsContextWayland.cpp } linux { @@ -47,18 +47,19 @@ macx { $$PWD/src/inputdev/CHIDDeviceIOKit.cpp \ $$PWD/src/inputdev/CHIDListenerIOKit.cpp OBJECTIVE_SOURCES += \ + $$PWD/src/CApplicationCocoa.mm \ $$PWD/src/windowsys/CWindowCocoa.mm \ $$PWD/src/windowsys/CGraphicsContextCocoa.mm LIBS += -framework AppKit } win32 { - HEADERS += \ - $$PWD/include/win/CWGLContext.hpp SOURCES += \ - $$PWD/src/win/CWGLContext.cpp \ + $$PWD/src/CApplicationWin32.cpp \ $$PWD/src/inputdev/CHIDListenerWinUSB.cpp \ - $$PWD/src/inputdev/CHIDDeviceWinUSB.cpp + $$PWD/src/inputdev/CHIDDeviceWinUSB.cpp \ + $$PWD/src/windowsys/CWindowWin32.cpp \ + $$PWD/src/windowsys/CGraphicsContextWin32.cpp } INCLUDEPATH += $$PWD/include diff --git a/src/CApplicationCocoa.mm b/src/CApplicationCocoa.mm new file mode 100644 index 0000000..f972666 --- /dev/null +++ b/src/CApplicationCocoa.mm @@ -0,0 +1,180 @@ +#include + +#include "IApplication.hpp" + +@interface AppDelegate : NSObject +{ + boo::IApplicationCallback* callback; + NSPanel* aboutPanel; +} +- (id)initWithCallback:(boo::IApplicationCallback*)cb; +@end + +@implementation AppDelegate +- (id)initWithCallback:(boo::IApplicationCallback*)cb +{ + self = [super init]; + callback = cb; + return self; +} +- (void)applicationDidFinishLaunching:(NSNotification*)notification +{ + (void)notification; + callback->appLaunched(boo::IApplicationInstance()); +} +- (void)applicationWillTerminate:(NSNotification*)notification +{ + (void)notification; + callback->appQuitting(boo::IApplicationInstance()); +} +- (BOOL)application:(NSApplication*)sender openFile:(NSString*)filename +{ + (void)sender; + return callback->appFileOpen(boo::IApplicationInstance(), [filename UTF8String]); +} +- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)sender { + (void)sender; + return YES; +} +- (IBAction)aboutApp:(id)sender +{ + (void)sender; + NSRect screenFrame = [[aboutPanel screen] frame]; + CGFloat xPos = NSWidth(screenFrame)/2 - 300/2; + CGFloat yPos = NSHeight(screenFrame)/2 - 220/2; + NSRect aboutCr = NSMakeRect(xPos, yPos, 300, 220); + [aboutPanel setFrame:aboutCr display:NO]; + [aboutPanel makeKeyAndOrderFront:self]; +} +- (IBAction)toggleFs:(id)sender +{ + (void)sender; + [[NSApp keyWindow] toggleFullScreen:nil]; +} +- (IBAction)quitApp:(id)sender +{ + (void)sender; + [NSApp terminate:nil]; +} +@end + +namespace boo +{ + +IWindow* _CWindowCocoaNew(const std::string& title); + +class CApplicationCocoa final : public IApplication +{ + IApplicationCallback& m_callback; + const std::string m_friendlyName; + const std::string m_pname; + const std::vector m_args; + + NSPanel* aboutPanel; + + void _deletedWindow(IWindow* window) + { + (void)window; + } + +public: + CApplicationCocoa(IApplicationCallback& callback, + const std::string& friendlyName, + const std::string& pname, + const std::vector& args) + : m_callback(callback), + m_friendlyName(friendlyName), + m_pname(pname), + m_args(args) + {} + + EPlatformType getPlatformType() const + { + return PLAT_COCOA; + } + + void run() + { + @autoreleasepool + { + NSApplication* app = [NSApplication sharedApplication]; + [app setActivationPolicy:NSApplicationActivationPolicyRegular]; + + /* Delegate (OS X callbacks) */ + AppDelegate* appDelegate = [[AppDelegate alloc] initWithCallback:&m_callback]; + [app setDelegate:appDelegate]; + + /* App menu */ + NSMenu* appMenu = [[NSMenu alloc] initWithTitle:@"main"]; + NSMenu* rwkMenu = [[NSMenu alloc] initWithTitle:[[NSString stringWithUTF8String:m_friendlyName.c_str()] autorelease]]; + [rwkMenu addItemWithTitle:[[NSString stringWithFormat:@"About %s", m_friendlyName.c_str()] autorelease] + action:@selector(aboutApp:) + keyEquivalent:@""]; + NSMenuItem* fsItem = [rwkMenu addItemWithTitle:@"Toggle Full Screen" + action:@selector(toggleFs:) + keyEquivalent:@"f"]; + [fsItem setKeyEquivalentModifierMask:NSCommandKeyMask]; + [rwkMenu addItem:[NSMenuItem separatorItem]]; + NSMenuItem* quit_item = [rwkMenu addItemWithTitle:[[NSString stringWithFormat:@"Quit %s", m_friendlyName.c_str()] autorelease] + action:@selector(quitApp:) + keyEquivalent:@"q"]; + [quit_item setKeyEquivalentModifierMask:NSCommandKeyMask]; + [[appMenu addItemWithTitle:[[NSString stringWithUTF8String:m_friendlyName.c_str()] autorelease] + action:nil keyEquivalent:@""] setSubmenu:rwkMenu]; + [[NSApplication sharedApplication] setMainMenu:appMenu]; + + /* About panel */ + NSRect aboutCr = NSMakeRect(0, 0, 300, 220); + aboutPanel = [[NSPanel alloc] initWithContentRect:aboutCr + styleMask:NSUtilityWindowMask|NSTitledWindowMask|NSClosableWindowMask + backing:NSBackingStoreBuffered defer:YES]; + [aboutPanel setTitle:[[NSString stringWithFormat:@"About %s", m_friendlyName.c_str()] autorelease]]; + NSText* aboutText = [[NSText alloc] initWithFrame:aboutCr]; + [aboutText setEditable:NO]; + [aboutText setAlignment:NSCenterTextAlignment]; + [aboutText setString:@"\nRWK Authors\n\nJackoalan\nAntidote\n"]; + [aboutPanel setContentView:aboutText]; + + [app run]; + } + } + + void quit() + { + [NSApp terminate:nil]; + } + + const std::string& getProcessName() const + { + return m_pname; + } + + const std::vector& getArgs() const + { + return m_args; + } + + IWindow* newWindow(const std::string& title) + { + return _CWindowCocoaNew(title); + } +}; + +IApplication* APP = NULL; +IApplication* IApplicationBootstrap(IApplication::EPlatformType platform, + IApplicationCallback& cb, + const std::string& friendlyName, + const std::string& pname, + const std::vector& args) +{ + if (!APP) + { + if (platform != IApplication::PLAT_COCOA && + platform != IApplication::PLAT_AUTO) + return NULL; + APP = new CApplicationCocoa(cb, friendlyName, pname, args); + } + return APP; +} + +} diff --git a/src/CApplicationUnix.cpp b/src/CApplicationUnix.cpp new file mode 100644 index 0000000..61c8318 --- /dev/null +++ b/src/CApplicationUnix.cpp @@ -0,0 +1,32 @@ +/* Meta-implementation for dynamically-constructing user's preferred + * platform interface + */ + +#define CAPPLICATION_UNIX_CPP +#include "CApplicationXCB.hpp" +#include "CApplicationWayland.hpp" + +namespace boo +{ + +IApplication* APP = NULL; +IApplication* IApplicationBootstrap(IApplication::EPlatformType platform, + IApplicationCallback& cb, + const std::string& friendlyName, + const std::string& pname, + const std::vector& args) +{ + if (!APP) + { + if (platform == IApplication::PLAT_WAYLAND) + APP = new CApplicationWayland(cb, friendlyName, pname, args); + else if (platform == IApplication::PLAT_XCB || + platform == IApplication::PLAT_AUTO) + APP = new CApplicationXCB(cb, friendlyName, pname, args); + else + return NULL; + } + return APP; +} + +} diff --git a/src/CApplicationWayland.hpp b/src/CApplicationWayland.hpp new file mode 100644 index 0000000..06556c6 --- /dev/null +++ b/src/CApplicationWayland.hpp @@ -0,0 +1,61 @@ +#ifndef CAPPLICATION_UNIX_CPP +#error This file may only be included from CApplicationUnix.cpp +#endif + +#include "IApplication.hpp" + +namespace boo +{ + +IWindow* _CWindowWaylandNew(const std::string& title); + +class CApplicationWayland final : public IApplication +{ + const IApplicationCallback& m_callback; + const std::string m_friendlyName; + const std::string m_pname; + const std::vector m_args; + + void _deletedWindow(IWindow* window) + { + (void)window; + } + +public: + CApplicationWayland(const IApplicationCallback& callback, + const std::string& friendlyName, + const std::string& pname, + const std::vector& args) + : m_callback(callback), + m_friendlyName(friendlyName), + m_pname(pname), + m_args(args) + {} + + EPlatformType getPlatformType() const + { + return PLAT_WAYLAND; + } + + void run() + { + + } + + const std::string& getProcessName() const + { + return m_pname; + } + + const std::vector& getArgs() const + { + return m_args; + } + + IWindow* newWindow(const std::string& title) + { + return _CWindowWaylandNew(title); + } +}; + +} diff --git a/src/CApplicationWin32.cpp b/src/CApplicationWin32.cpp new file mode 100644 index 0000000..67f1842 --- /dev/null +++ b/src/CApplicationWin32.cpp @@ -0,0 +1,162 @@ +#define _CRT_SECURE_NO_WARNINGS 1 /* STFU MSVC */ +#define _WIN32_LEAN_AND_MEAN 1 +#include +#include +#include + +#include + +#include "IRunLoop.hpp" +#include "inputdev/CDeviceFinder.hpp" + +namespace boo +{ + +IWindow* _CWindowWin32New(const std::string& title); + +class CApplicationWin32 final : public IApplication +{ + const IApplicationCallback& m_callback; + const std::string m_friendlyName; + const std::string m_pname; + const std::vector m_args; + std::unordered_map m_allWindows; + + void _deletedWindow(IWindow* window) + { + m_allWindows.erase(window); + } + +public: + + CApplicationWin32(const IApplicationCallback& callback, + const std::string& friendlyName, + const std::string& pname, + const std::vector& args) + : m_callback(callback), + m_friendlyName(friendlyName), + m_pname(pname), + m_args(args) + {} + + EPlatformType getPlatformType() const + { + return PLAT_WIN32; + } + + LRESULT winHwndHandler(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) + { + /* Lookup boo window instance */ + IWindow* window = m_allWindows[hwnd]; + switch (uMsg) + { + case WM_CREATE: + return 0; + + case WM_DEVICECHANGE: + return CDeviceFinder::winDevChangedHandler(wParam, lParam); + + default: + return DefWindowProc(hwnd, uMsg, wParam, lParam); + } + } + + void run() + { + /* Pump messages */ + MSG msg = {0}; + while (GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + const std::string& getProcessName() const + { + return m_pname; + } + + const std::vector& getArgs() const + { + return m_args; + } + + IWindow* newWindow(const std::string& title) + { + IWindow* window = _CWindowWin32New(title); + HWND hwnd = window->getPlatformHandle(); + m_allWindows[hwnd] = window; + } +}; + +IApplication* APP = NULL; +IApplication* IApplicationBootstrap(IApplication::EPlatformType platform, + IApplicationCallback& cb, + const std::string& friendlyName, + const std::string& pname, + const std::vector& args) +{ + if (!APP) + { + if (platform != IApplication::PLAT_WIN32 && + platform != IApplication::PLAT_AUTO) + return NULL; + APP = new CApplicationWin32(cb, friendlyName, pname, args); + } + return APP; +} + +} + +static const DEV_BROADCAST_DEVICEINTERFACE_A HOTPLUG_CONF = +{ + sizeof(DEV_BROADCAST_DEVICEINTERFACE_A), + DBT_DEVTYP_DEVICEINTERFACE, + 0, + GUID_DEVINTERFACE_USB_DEVICE +}; +static bool HOTPLUG_REGISTERED = false; +static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (!HOTPLUG_REGISTERED && hwnd == WM_CREATE) + { + /* Register hotplug notification with windows */ + RegisterDeviceNotificationA(hwnd, (LPVOID)&HOTPLUG_CONF, DEVICE_NOTIFY_WINDOW_HANDLE); + HOTPLUG_REGISTERED = true; + } + return IRunLoopInstance()->winHwndHandler(hwnd, uMsg, wParam, lParam); +} + +int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPCWSTR lpCmdLine, int) +{ +#if DEBUG + /* Debug console */ + AllocConsole(); + freopen("CONOUT$", "w", stdout); +#endif + + /* One class for *all* boo windows */ + WNDCLASS wndClass = + { + 0, + WindowProc, + 0, + 0, + hInstance, + 0, + 0, + 0, + 0, + L"BooWindow" + }; + + RegisterClassW(&wndClass); + + int argc = 0; + LPWSTR* argv = CommandLineToArgvW(lpCmdLine, &argc); + + /* Call into the 'proper' entry point */ + return main(argc, argv); + +} diff --git a/src/CApplicationXCB.hpp b/src/CApplicationXCB.hpp new file mode 100644 index 0000000..1b0a7f5 --- /dev/null +++ b/src/CApplicationXCB.hpp @@ -0,0 +1,61 @@ +#ifndef CAPPLICATION_UNIX_CPP +#error This file may only be included from CApplicationUnix.cpp +#endif + +#include "IApplication.hpp" + +namespace boo +{ + +IWindow* _CWindowXCBNew(const std::string& title); + +class CApplicationXCB final : public IApplication +{ + const IApplicationCallback& m_callback; + const std::string m_friendlyName; + const std::string m_pname; + const std::vector m_args; + + void _deletedWindow(IWindow* window) + { + (void)window; + } + +public: + CApplicationXCB(const IApplicationCallback& callback, + const std::string& friendlyName, + const std::string& pname, + const std::vector& args) + : m_callback(callback), + m_friendlyName(friendlyName), + m_pname(pname), + m_args(args) + {} + + EPlatformType getPlatformType() const + { + return PLAT_XCB; + } + + void run() + { + + } + + const std::string& getProcessName() const + { + return m_pname; + } + + const std::vector& getArgs() const + { + return m_args; + } + + IWindow* newWindow(const std::string& title) + { + return _CWindowXCBNew(title); + } +}; + +} diff --git a/src/CInputDeferredRelay.cpp b/src/CInputDeferredRelay.cpp deleted file mode 100644 index 7fed569..0000000 --- a/src/CInputDeferredRelay.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "CInputDeferredRelay.hpp" \ No newline at end of file diff --git a/src/CInputRelay.cpp b/src/CInputRelay.cpp deleted file mode 100644 index 2d38700..0000000 --- a/src/CInputRelay.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "CInputRelay.hpp" \ No newline at end of file diff --git a/src/CQtOpenGLWindow.cpp b/src/CQtOpenGLWindow.cpp deleted file mode 100644 index 07d3ba2..0000000 --- a/src/CQtOpenGLWindow.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "CQtOpenGLWindow.hpp" - - diff --git a/src/CRetraceWaiter.cpp b/src/CRetraceWaiter.cpp deleted file mode 100644 index 6734c86..0000000 --- a/src/CRetraceWaiter.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "IRetraceWaiter.hpp" diff --git a/src/CSurface.cpp b/src/CSurface.cpp deleted file mode 100644 index e23af70..0000000 --- a/src/CSurface.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "CSurface.hpp" - -namespace boo -{ - -ISurface* CSurfaceNewWindow() -{ - return nullptr; -} - -ISurface* CSurfaceNewQWidget() -{ - return nullptr; -} - -} diff --git a/src/win/CWGLContext.cpp b/src/win/CWGLContext.cpp deleted file mode 100644 index dfdd625..0000000 --- a/src/win/CWGLContext.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef _WIN32 -#include "win/CWGLContext.hpp" - -#endif diff --git a/src/windowsys/CGraphicsContextCocoa.mm b/src/windowsys/CGraphicsContextCocoa.mm index 2a0ed3f..ef61ad1 100644 --- a/src/windowsys/CGraphicsContextCocoa.mm +++ b/src/windowsys/CGraphicsContextCocoa.mm @@ -4,6 +4,12 @@ #include "windowsys/IGraphicsContext.hpp" #include "windowsys/IWindow.hpp" +/* AppKit applies OpenGL much differently than other platforms + * the NSOpenGLView class composes together all necessary + * OGL context members and provides the necessary event hooks + * for KB/Mouse/Touch events + */ + static const NSOpenGLPixelFormatAttribute PF_RGBA8_ATTRS[] = { NSOpenGLPFAAccelerated, @@ -70,17 +76,17 @@ class CGraphicsContextCocoa final : public IGraphicsContext EGraphicsAPI m_api; EPixelFormat m_pf; - NSWindow* m_parentWindow; + IWindow* m_parentWindow; CGraphicsContextCocoaInternal* m_nsContext; NSOpenGLContext* m_nsShareContext; public: IWindowCallback* m_callback; - CGraphicsContextCocoa(EGraphicsAPI api) + CGraphicsContextCocoa(EGraphicsAPI api, IWindow* parentWindow) : m_api(api), m_pf(PF_RGBA8), - m_parentWindow(NULL), + m_parentWindow(parentWindow), m_nsContext(NULL), m_nsShareContext(NULL), m_callback(NULL) @@ -114,17 +120,12 @@ public: m_pf = pf; } - void setPlatformWindowHandle(void* handle) - { - m_parentWindow = (NSWindow*)handle; - } - void initializeContext() { if (m_nsShareContext) return; m_nsContext = [[CGraphicsContextCocoaInternal alloc] initWithBooContext:this]; - [m_parentWindow setContentView:m_nsContext]; + [(NSWindow*)m_parentWindow->getPlatformHandle() setContentView:m_nsContext]; } IGraphicsContext* makeShareContext() const @@ -144,7 +145,7 @@ public: return NULL; if (!nsctx) return NULL; - CGraphicsContextCocoa* newCtx = new CGraphicsContextCocoa(m_api); + CGraphicsContextCocoa* newCtx = new CGraphicsContextCocoa(m_api, NULL); newCtx->m_nsShareContext = nsctx; return newCtx; } @@ -169,7 +170,8 @@ public: }; -IGraphicsContext* IGraphicsContextNew(IGraphicsContext::EGraphicsAPI api) +IGraphicsContext* _CGraphicsContextCocoaNew(IGraphicsContext::EGraphicsAPI api, + IWindow* parentWindow) { if (api != IGraphicsContext::API_OPENGL_3_3 && api != IGraphicsContext::API_OPENGL_4_2) return NULL; @@ -202,7 +204,7 @@ IGraphicsContext* IGraphicsContextNew(IGraphicsContext::EGraphicsAPI api) if (api == IGraphicsContext::API_OPENGL_4_2) return NULL; - return new CGraphicsContextCocoa(api); + return new CGraphicsContextCocoa(api, parentWindow); } } diff --git a/src/windowsys/CGraphicsContextWayland.cpp b/src/windowsys/CGraphicsContextWayland.cpp new file mode 100644 index 0000000..a669d77 --- /dev/null +++ b/src/windowsys/CGraphicsContextWayland.cpp @@ -0,0 +1,87 @@ +#include "windowsys/IGraphicsContext.hpp" +#include "windowsys/IWindow.hpp" + +namespace boo +{ + +class CGraphicsContextWayland final : public IGraphicsContext +{ + + EGraphicsAPI m_api; + EPixelFormat m_pf; + IWindow* m_parentWindow; + +public: + IWindowCallback* m_callback; + + CGraphicsContextWayland(EGraphicsAPI api, IWindow* parentWindow) + : m_api(api), + m_pf(PF_RGBA8), + m_parentWindow(parentWindow) + {} + + ~CGraphicsContextWayland() + { + + } + + void _setCallback(IWindowCallback* cb) + { + m_callback = cb; + } + + EGraphicsAPI getAPI() const + { + return m_api; + } + + EPixelFormat getPixelFormat() const + { + return m_pf; + } + + void setPixelFormat(EPixelFormat pf) + { + if (pf > PF_RGBAF32_Z24) + return; + m_pf = pf; + } + + void setPlatformWindowHandle(void* handle) + { + } + + void initializeContext() + { + + } + + IGraphicsContext* makeShareContext() const + { + + } + + void makeCurrent() + { + + } + + void clearCurrent() + { + + } + + void swapBuffer() + { + + } + +}; + +IGraphicsContext* _CGraphicsContextWaylandNew(IGraphicsContext::EGraphicsAPI api, + IWindow* parentWindow) +{ + +} + +} diff --git a/src/windowsys/CGraphicsContextWin32.cpp b/src/windowsys/CGraphicsContextWin32.cpp new file mode 100644 index 0000000..f8036c5 --- /dev/null +++ b/src/windowsys/CGraphicsContextWin32.cpp @@ -0,0 +1,87 @@ +#include "windowsys/IGraphicsContext.hpp" +#include "windowsys/IWindow.hpp" + +namespace boo +{ + +class CGraphicsContextWin32 final : public IGraphicsContext +{ + + EGraphicsAPI m_api; + EPixelFormat m_pf; + IWindow* m_parentWindow; + +public: + IWindowCallback* m_callback; + + CGraphicsContextWin32(EGraphicsAPI api, IWindow* parentWindow) + : m_api(api), + m_pf(PF_RGBA8), + m_parentWindow(parentWindow) + {} + + ~CGraphicsContextWin32() + { + + } + + void _setCallback(IWindowCallback* cb) + { + m_callback = cb; + } + + EGraphicsAPI getAPI() const + { + return m_api; + } + + EPixelFormat getPixelFormat() const + { + return m_pf; + } + + void setPixelFormat(EPixelFormat pf) + { + if (pf > PF_RGBAF32_Z24) + return; + m_pf = pf; + } + + void setPlatformWindowHandle(void* handle) + { + } + + void initializeContext() + { + + } + + IGraphicsContext* makeShareContext() const + { + + } + + void makeCurrent() + { + + } + + void clearCurrent() + { + + } + + void swapBuffer() + { + + } + +}; + +IGraphicsContext* _CGraphicsContextWin32New(IGraphicsContext::EGraphicsAPI api, + IWindow* parentWindow) +{ + +} + +} diff --git a/src/windowsys/CGraphicsContextXCB.cpp b/src/windowsys/CGraphicsContextXCB.cpp new file mode 100644 index 0000000..60799d5 --- /dev/null +++ b/src/windowsys/CGraphicsContextXCB.cpp @@ -0,0 +1,87 @@ +#include "windowsys/IGraphicsContext.hpp" +#include "windowsys/IWindow.hpp" + +namespace boo +{ + +class CGraphicsContextXCB final : public IGraphicsContext +{ + + EGraphicsAPI m_api; + EPixelFormat m_pf; + IWindow* m_parentWindow; + +public: + IWindowCallback* m_callback; + + CGraphicsContextXCB(EGraphicsAPI api, IWindow* parentWindow) + : m_api(api), + m_pf(PF_RGBA8), + m_parentWindow(parentWindow) + {} + + ~CGraphicsContextXCB() + { + + } + + void _setCallback(IWindowCallback* cb) + { + m_callback = cb; + } + + EGraphicsAPI getAPI() const + { + return m_api; + } + + EPixelFormat getPixelFormat() const + { + return m_pf; + } + + void setPixelFormat(EPixelFormat pf) + { + if (pf > PF_RGBAF32_Z24) + return; + m_pf = pf; + } + + void setPlatformWindowHandle(void* handle) + { + } + + void initializeContext() + { + + } + + IGraphicsContext* makeShareContext() const + { + + } + + void makeCurrent() + { + + } + + void clearCurrent() + { + + } + + void swapBuffer() + { + + } + +}; + +IGraphicsContext* _CGraphicsContextXCBNew(IGraphicsContext::EGraphicsAPI api, + IWindow* parentWindow) +{ + +} + +} diff --git a/src/windowsys/CWindowCocoa.mm b/src/windowsys/CWindowCocoa.mm index 0fde361..42b1819 100644 --- a/src/windowsys/CWindowCocoa.mm +++ b/src/windowsys/CWindowCocoa.mm @@ -1,4 +1,5 @@ #import +#include "IApplication.hpp" #include "windowsys/IWindow.hpp" #include "windowsys/IGraphicsContext.hpp" @@ -7,11 +8,16 @@ namespace boo {class CWindowCocoa;} { boo::CWindowCocoa* booWindow; } -- (id)initWithBooWindow:(boo::CWindowCocoa*)bw; +- (id)initWithBooWindow:(boo::CWindowCocoa*)bw title:(const std::string&)title; +- (void)setFrameDefault; +- (NSRect)genFrameDefault; @end namespace boo { + +IGraphicsContext* _CGraphicsContextCocoaNew(IGraphicsContext::EGraphicsAPI api, + IWindow* parentWindow); class CWindowCocoa final : public IWindow { @@ -21,19 +27,25 @@ class CWindowCocoa final : public IWindow public: - CWindowCocoa() + CWindowCocoa(const std::string& title) { - m_nsWindow = [[CWindowCocoaInternal alloc] initWithBooWindow:this]; - m_gfxCtx = IGraphicsContextNew(IGraphicsContext::API_OPENGL_3_3); + m_nsWindow = [[CWindowCocoaInternal alloc] initWithBooWindow:this title:title]; + m_gfxCtx = _CGraphicsContextCocoaNew(IGraphicsContext::API_OPENGL_3_3, this); m_gfxCtx->_setPlatformWindowHandle(m_nsWindow); m_gfxCtx->initializeContext(); } + void _clearWindow() + { + m_nsWindow = NULL; + } + ~CWindowCocoa() { [m_nsWindow orderOut:nil]; [m_nsWindow release]; delete m_gfxCtx; + IApplicationInstance()->_deletedWindow(this); } void setCallback(IWindowCallback* cb) @@ -58,7 +70,7 @@ public: void setTitle(const std::string& title) { - [m_nsWindow setTitle:[NSString stringWithUTF8String:title.c_str()]]; + [m_nsWindow setTitle:[[NSString stringWithUTF8String:title.c_str()] autorelease]]; } void setWindowFrameDefault() @@ -106,27 +118,64 @@ public: return TOUCH_TRACKPAD; } + void* getPlatformHandle() const + { + return m_nsWindow; + } + }; -IWindow* IWindowNew() +IWindow* _CWindowCocoaNew(const std::string& title) { - return new CWindowCocoa; + return new CWindowCocoa(title); } } @implementation CWindowCocoaInternal -- (id)initWithBooWindow:(boo::CWindowCocoa *)bw +- (id)initWithBooWindow:(boo::CWindowCocoa *)bw title:(const std::string&)title { - self = [self initWithContentRect:NSMakeRect(0, 0, 100, 100) + self = [self initWithContentRect:[self genFrameDefault] styleMask:NSTitledWindowMask| NSClosableWindowMask| NSMiniaturizableWindowMask| NSResizableWindowMask backing:NSBackingStoreBuffered defer:YES]; + self.title = [[NSString stringWithUTF8String:title.c_str()] autorelease]; booWindow = bw; return self; } +- (void)setFrameDefault +{ + [self setFrame:[self genFrameDefault] display:NO]; +} +- (NSRect)genFrameDefault +{ + NSScreen* mainScreen = [NSScreen mainScreen]; + NSRect scrFrame = mainScreen.frame; + float width = scrFrame.size.width * 2.0 / 3.0; + float height = scrFrame.size.height * 2.0 / 3.0; + return NSMakeRect((scrFrame.size.width - width) / 2.0, + (scrFrame.size.height - height) / 2.0, + width, height); +} +- (void)close +{ + booWindow->_clearWindow(); + [super close]; +} +- (BOOL)acceptsFirstResponder +{ + return YES; +} +- (BOOL)acceptsMouseMovedEvents +{ + return YES; +} +- (NSWindowCollectionBehavior)collectionBehavior +{ + return NSWindowCollectionBehaviorFullScreenPrimary; +} @end diff --git a/src/windowsys/CWindowWayland.cpp b/src/windowsys/CWindowWayland.cpp new file mode 100644 index 0000000..ffbd2d4 --- /dev/null +++ b/src/windowsys/CWindowWayland.cpp @@ -0,0 +1,93 @@ +#include "windowsys/IWindow.hpp" +#include "windowsys/IGraphicsContext.hpp" + +namespace boo +{ + +IGraphicsContext* _CGraphicsContextWaylandNew(IGraphicsContext::EGraphicsAPI api, + IWindow* parentWindow); + +class CWindowWayland final : public IWindow +{ + + +public: + + CWindowWayland(const std::string& title) + { + + } + + ~CWindowWayland() + { + + } + + void setCallback(IWindowCallback* cb) + { + + } + + void showWindow() + { + + } + + void hideWindow() + { + + } + + std::string getTitle() + { + + } + + void setTitle(const std::string& title) + { + + } + + void setWindowFrameDefault() + { + + } + + void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const + { + + } + + void setWindowFrame(float x, float y, float w, float h) + { + + } + + float getVirtualPixelFactor() const + { + + } + + bool isFullscreen() const + { + + } + + void setFullscreen(bool fs) + { + + } + + ETouchType getTouchType() const + { + + } + +}; + +IWindow* _CWindowWaylandNew(const std::string& title) +{ + return new CWindowWayland(title); +} + +} diff --git a/src/windowsys/CWindowWin32.cpp b/src/windowsys/CWindowWin32.cpp new file mode 100644 index 0000000..5617358 --- /dev/null +++ b/src/windowsys/CWindowWin32.cpp @@ -0,0 +1,96 @@ +#include "windowsys/IWindow.hpp" +#include "windowsys/IGraphicsContext.hpp" + +namespace boo +{ + +IGraphicsContext* _CGraphicsContextWin32New(IGraphicsContext::EGraphicsAPI api, + IWindow* parentWindow); + +class CWindowWin32 final : public IWindow +{ + + HWND m_hwnd; + +public: + + CWindowWin32(const std::string& title) + { + m_hwnd = CreateWindowW(L"BooWindow", L"BooTest", WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + NULL, NULL, hInstance, NULL); + } + + ~CWindowWin32() + { + + } + + void setCallback(IWindowCallback* cb) + { + + } + + void showWindow() + { + + } + + void hideWindow() + { + + } + + std::string getTitle() + { + + } + + void setTitle(const std::string& title) + { + + } + + void setWindowFrameDefault() + { + + } + + void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const + { + + } + + void setWindowFrame(float x, float y, float w, float h) + { + + } + + float getVirtualPixelFactor() const + { + + } + + bool isFullscreen() const + { + + } + + void setFullscreen(bool fs) + { + + } + + ETouchType getTouchType() const + { + + } + +}; + +IWindow* _CWindowWin32New(const std::string& title) +{ + return new CWindowWin32(title); +} + +} diff --git a/src/windowsys/CWindowXCB.cpp b/src/windowsys/CWindowXCB.cpp new file mode 100644 index 0000000..f30fc69 --- /dev/null +++ b/src/windowsys/CWindowXCB.cpp @@ -0,0 +1,93 @@ +#include "windowsys/IWindow.hpp" +#include "windowsys/IGraphicsContext.hpp" + +namespace boo +{ + +IGraphicsContext* _CGraphicsContextXCBNew(IGraphicsContext::EGraphicsAPI api, + IWindow* parentWindow); + +class CWindowXCB final : public IWindow +{ + + +public: + + CWindowXCB(const std::string& title) + { + + } + + ~CWindowXCB() + { + + } + + void setCallback(IWindowCallback* cb) + { + + } + + void showWindow() + { + + } + + void hideWindow() + { + + } + + std::string getTitle() + { + + } + + void setTitle(const std::string& title) + { + + } + + void setWindowFrameDefault() + { + + } + + void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const + { + + } + + void setWindowFrame(float x, float y, float w, float h) + { + + } + + float getVirtualPixelFactor() const + { + + } + + bool isFullscreen() const + { + + } + + void setFullscreen(bool fs) + { + + } + + ETouchType getTouchType() const + { + + } + +}; + +IWindow* _CWindowXCBNew(const std::string& title) +{ + return new CWindowXCB(title); +} + +} diff --git a/src/x11/CGLXContext.cpp b/src/x11/CGLXContext.cpp deleted file mode 100644 index f1e42e2..0000000 --- a/src/x11/CGLXContext.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#if !defined(__APPLE__) && (defined(__linux__) || defined(BSD)) -#include "x11/CGLXContext.hpp" -#include - -namespace boo -{ - -CGLXContext::CGLXContext() - : m_majVersion(3), - m_minVersion(3), - m_display(nullptr) -{ - std::cout << "Hello from GLX" << std::endl; -} - -bool CGLXContext::create() -{ - return true; -} - -void CGLXContext::setMinVersion(const int& min) -{ - m_minVersion = min; -} - -void CGLXContext::setMajorVersion(const int& maj) -{ - m_majVersion = maj; -} - -const std::string CGLXContext::version() const -{ - return "Invalid version"; -} - -const std::string CGLXContext::name() const -{ - return "GLX Context"; -} - -int CGLXContext::depthSize() const -{ - return -1; -} - -int CGLXContext::redDepth() const -{ - return -1; -} - -int CGLXContext::greenDepth() const -{ - return -1; -} - -int CGLXContext::blueDepth() const -{ - return -1; -} - -} - -#endif // !defined(__APPLE__) && (defined(__linux__) || defined(BSD)) diff --git a/test/main.cpp b/test/main.cpp index d287d65..b4a0a86 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -1,4 +1,3 @@ -#define _CRT_SECURE_NO_WARNINGS 1 #if __APPLE__ #include @@ -7,10 +6,7 @@ #include #include #if _WIN32 -#define _WIN32_LEAN_AND_MEAN 1 -#include -#include -#include + #else #include #endif @@ -58,104 +54,37 @@ public: } } }; - -} - -#if _WIN32 - -/* This simple 'test' console app needs a full windows - * message loop for receiving device connection events - */ -static const DEV_BROADCAST_DEVICEINTERFACE_A HOTPLUG_CONF = + + +struct CTestApplicationCallback : public IApplicationCallback { - sizeof(DEV_BROADCAST_DEVICEINTERFACE_A), - DBT_DEVTYP_DEVICEINTERFACE, - 0, - GUID_DEVINTERFACE_USB_DEVICE + IWindow* mainWindow = NULL; + boo::CTestDeviceFinder devFinder; + void appLaunched(IApplication* app) + { + mainWindow = app->newWindow("YAY!"); + mainWindow->showWindow(); + devFinder.startScanning(); + } + void appQuitting(IApplication*) + { + delete mainWindow; + } + bool appFileOpen(IApplication*, const std::string& path) + { + printf("OPENING: %s\n", path.c_str()); + return true; + } }; -LRESULT CALLBACK WindowProc( - _In_ HWND hwnd, - _In_ UINT uMsg, - _In_ WPARAM wParam, - _In_ LPARAM lParam -) -{ - switch (uMsg) - { - case WM_CREATE: - /* Register hotplug notification with windows */ - RegisterDeviceNotificationA(hwnd, (LPVOID)&HOTPLUG_CONF, DEVICE_NOTIFY_WINDOW_HANDLE); - return 0; - - case WM_DEVICECHANGE: - return boo::CDeviceFinder::winDevChangedHandler(wParam, lParam); - - default: - return DefWindowProc(hwnd, uMsg, wParam, lParam); - } } -int APIENTRY wWinMain( - _In_ HINSTANCE hInstance, - _In_ HINSTANCE, - _In_ LPTSTR, - _In_ int -) +int main(int argc, char** argv) { - AllocConsole(); - freopen("CONOUT$", "w", stdout); - - WNDCLASS wndClass = - { - 0, - WindowProc, - 0, - 0, - hInstance, - 0, - 0, - 0, - 0, - L"BooTestWindow" - }; - - RegisterClassW(&wndClass); - - boo::CTestDeviceFinder finder; - finder.startScanning(); - - HWND hwnd = CreateWindowW(L"BooTestWindow", L"BooTest", WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - NULL, NULL, hInstance, NULL); - - /* Pump messages */ - MSG msg = {0}; - while (GetMessage(&msg, hwnd, 0, 0)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - -} - -#else - -int main(int, char**) -{ - - boo::CTestDeviceFinder finder; - finder.startScanning(); - - boo::IWindow* window = boo::IWindowNew(); - (void)window; - -#if __APPLE__ - CFRunLoopRun(); -#endif - - //delete ctx; + boo::CTestApplicationCallback appCb; + boo::IApplication* app = IApplicationBootstrap(boo::IApplication::PLAT_AUTO, appCb, "RWK", argc, argv); + app->run(); + delete app; return 0; } -#endif