From 646483815910c3f5b12a4f18886b15ff52f4c5a0 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sat, 1 Jun 2019 01:13:44 +0200 Subject: [PATCH 01/58] source/Platform/Unix: stub implementation --- source/Display/GLContext.cpp | 3 ++ source/Game.cpp | 14 +++++- source/Platform/PlatformDisplay.cpp | 3 ++ source/Platform/Unix/GLXContext.cpp | 61 ++++++++++++++++++++++++ source/Platform/Unix/GLXContext.h | 39 +++++++++++++++ source/Platform/Unix/UnixApplication.cpp | 26 ++++++++++ source/Platform/Unix/UnixApplication.h | 30 ++++++++++++ source/Platform/Unix/UnixMisc.cpp | 15 ++++++ source/Platform/Unix/UnixSystem.cpp | 31 ++++++++++++ source/Platform/Unix/X11Display.cpp | 56 ++++++++++++++++++++++ source/Platform/Unix/X11Display.h | 40 ++++++++++++++++ source/Platform/Unix/X11EventQueue.cpp | 11 +++++ source/Platform/Unix/X11EventQueue.h | 18 +++++++ source/Platform/Unix/X11Input.cpp | 22 +++++++++ source/Platform/Unix/X11Input.h | 21 ++++++++ source/Platform/Unix/X11Keyboard.cpp | 20 ++++++++ source/Platform/Unix/X11Keyboard.h | 25 ++++++++++ source/Platform/Unix/X11Mouse.cpp | 31 ++++++++++++ source/Platform/Unix/X11Mouse.h | 31 ++++++++++++ source/System/MessageQueue.cpp | 3 ++ 20 files changed, 498 insertions(+), 2 deletions(-) create mode 100644 source/Platform/Unix/GLXContext.cpp create mode 100644 source/Platform/Unix/GLXContext.h create mode 100644 source/Platform/Unix/UnixApplication.cpp create mode 100644 source/Platform/Unix/UnixApplication.h create mode 100644 source/Platform/Unix/UnixMisc.cpp create mode 100644 source/Platform/Unix/UnixSystem.cpp create mode 100644 source/Platform/Unix/X11Display.cpp create mode 100644 source/Platform/Unix/X11Display.h create mode 100644 source/Platform/Unix/X11EventQueue.cpp create mode 100644 source/Platform/Unix/X11EventQueue.h create mode 100644 source/Platform/Unix/X11Input.cpp create mode 100644 source/Platform/Unix/X11Input.h create mode 100644 source/Platform/Unix/X11Keyboard.cpp create mode 100644 source/Platform/Unix/X11Keyboard.h create mode 100644 source/Platform/Unix/X11Mouse.cpp create mode 100644 source/Platform/Unix/X11Mouse.h diff --git a/source/Display/GLContext.cpp b/source/Display/GLContext.cpp index cd26ca8..912c9ff 100644 --- a/source/Display/GLContext.cpp +++ b/source/Display/GLContext.cpp @@ -4,6 +4,9 @@ #ifdef _WIN32 #include typedef sp::Win32GLContext ContextType; +#elif defined(__linux__) || defined(unix) || defined(__unix) || defined(__unix__) +#include +typedef sp::GLXContext ContextType; #else #error "No GLContext implementation exists" #endif diff --git a/source/Game.cpp b/source/Game.cpp index 5213c50..01cccc1 100644 --- a/source/Game.cpp +++ b/source/Game.cpp @@ -4,17 +4,27 @@ #include #include #include +#include #include + +// TODO: move this to Application::create() +#ifdef _WIN32 #include -#include +typedef sp::Win32Application ApplicationType; +#elif defined(__linux__) || defined(unix) || defined(__unix) || defined(__unix__) +#include +typedef sp::UnixApplication ApplicationType; +#else +#error "No Application implementation exists" +#endif namespace sp { Game::Game() : m_running(false) { - m_platform = new Win32Application(); + m_platform = new ApplicationType(); m_graphics = new Graphics(m_platform); m_input = new InputModule(&m_platform->getInput()); m_messageHandler = new MessageHandler(); diff --git a/source/Platform/PlatformDisplay.cpp b/source/Platform/PlatformDisplay.cpp index 154930e..3298b98 100644 --- a/source/Platform/PlatformDisplay.cpp +++ b/source/Platform/PlatformDisplay.cpp @@ -5,6 +5,9 @@ #ifdef _WIN32 #include typedef sp::Win32Display DisplayType; +#elif defined(__linux__) || defined(unix) || defined(__unix) || defined(__unix__) +#include +typedef sp::X11Display DisplayType; #else #error "No Display implementation exists" #endif diff --git a/source/Platform/Unix/GLXContext.cpp b/source/Platform/Unix/GLXContext.cpp new file mode 100644 index 0000000..a488bdd --- /dev/null +++ b/source/Platform/Unix/GLXContext.cpp @@ -0,0 +1,61 @@ + +#include "GLXContext.h" + +namespace sp { + +GLXContext::GLXContext() +{ + +} + +GLXContext::~GLXContext() +{ + +} + +bool GLXContext::create(const PlatformDisplay* display) +{ + return true; +} + +void GLXContext::destroy() +{ + +} + +bool GLXContext::activate() +{ + return true; +} + +bool GLXContext::deactivate() +{ + return true; +} + +bool GLXContext::isActive() const +{ + return true; +} + +bool GLXContext::setSwapInterval(int interval) +{ + return true; +} + +void GLXContext::setSize(unsigned int width, unsigned int height) +{ + +} + +void GLXContext::setSize(const Vector2u size) +{ + setSize(size.x, size.y); +} + +void GLXContext::swapBuffers() +{ + +} + +} // namespace sp diff --git a/source/Platform/Unix/GLXContext.h b/source/Platform/Unix/GLXContext.h new file mode 100644 index 0000000..3a5dcbe --- /dev/null +++ b/source/Platform/Unix/GLXContext.h @@ -0,0 +1,39 @@ + +#ifndef PLATFORM_UNIX_GLXCONTEXT_H +#define PLATFORM_UNIX_GLXCONTEXT_H + +// X11 OpenGL Context (glx) + +#include + +namespace sp { + +class GLXContext : public GLContext +{ +public : + GLXContext(); + ~GLXContext(); + + // Create a context associated with a display. + bool create(const PlatformDisplay* display); + + void destroy(); + + bool activate(); + + bool deactivate(); + + bool isActive() const; + + bool setSwapInterval(int interval); + + void setSize(unsigned int width, unsigned int height); + + void setSize(const Vector2u size); + + void swapBuffers(); +}; + +} // namespace sp + +#endif /* PLATFORM_UNIX_GLXCONTEXT_H */ diff --git a/source/Platform/Unix/UnixApplication.cpp b/source/Platform/Unix/UnixApplication.cpp new file mode 100644 index 0000000..a8925d4 --- /dev/null +++ b/source/Platform/Unix/UnixApplication.cpp @@ -0,0 +1,26 @@ + +#include "UnixApplication.h" + +namespace sp { + +void UnixApplication::init() +{ + // TODO +} + +void UnixApplication::shutdown() +{ + // TODO +} + +PlatformInput& UnixApplication::getInput() +{ + return m_input; +} + +MessageQueue& UnixApplication::getMessageQueue() +{ + return m_messageQueue; +} + +} // namespace sp diff --git a/source/Platform/Unix/UnixApplication.h b/source/Platform/Unix/UnixApplication.h new file mode 100644 index 0000000..1f5c2dc --- /dev/null +++ b/source/Platform/Unix/UnixApplication.h @@ -0,0 +1,30 @@ + +#ifndef PLATFORM_UNIX_APPLICATION_H +#define PLATFORM_UNIX_APPLICATION_H + +#include +#include +#include "X11Input.h" + +namespace sp { + +class UnixApplication : public PlatformApplication +{ +public : + virtual void init(); + + virtual void shutdown(); + + virtual PlatformInput& getInput(); + + virtual MessageQueue& getMessageQueue(); + +protected : + + X11Input m_input; + MessageQueue m_messageQueue; +}; + +} // namespace sp + +#endif /* PLATFORM_UNIX_APPLICATION_H */ diff --git a/source/Platform/Unix/UnixMisc.cpp b/source/Platform/Unix/UnixMisc.cpp new file mode 100644 index 0000000..c168588 --- /dev/null +++ b/source/Platform/Unix/UnixMisc.cpp @@ -0,0 +1,15 @@ + +#include + +namespace sp { + +void PlatformMisc::GetDisplayModes(std::vector& modes) +{ +} + +DisplayMode PlatformMisc::GetDesktopMode() +{ + return DisplayMode(); +} + +} // namespace sp diff --git a/source/Platform/Unix/UnixSystem.cpp b/source/Platform/Unix/UnixSystem.cpp new file mode 100644 index 0000000..68d5384 --- /dev/null +++ b/source/Platform/Unix/UnixSystem.cpp @@ -0,0 +1,31 @@ + +#include +#include +#include + +namespace sp { + +unsigned long system::getMilliseconds() +{ + struct timespec tv; + clock_gettime(CLOCK_REALTIME, &tv); + return (tv.tv_sec * 1000ul) + (tv.tv_nsec / 1000000ul); + +} + +void system::sleep(int milliseconds) +{ + struct timespec req, rem; + req.tv_sec = milliseconds / 1000ul; + req.tv_nsec = (milliseconds - (req.tv_sec * 1000ul)) * 1000000ul; + +_start: + // Try again if we get interrupted. + if (clock_nanosleep(CLOCK_REALTIME, 0, &req, &rem) == EINTR) { + // Update req with remaining time. + req = rem; + goto _start; + } +} + +} // namespace sp diff --git a/source/Platform/Unix/X11Display.cpp b/source/Platform/Unix/X11Display.cpp new file mode 100644 index 0000000..eb32495 --- /dev/null +++ b/source/Platform/Unix/X11Display.cpp @@ -0,0 +1,56 @@ + +#include "X11Display.h" + +namespace sp { + +bool X11Display::create(DisplayDescription description) +{ + return true; +} + +void X11Display::destroy() +{ + +} + +bool X11Display::isValid() +{ + return true; +} + +void* X11Display::getHandle() const +{ + return NULL; +} + +void X11Display::setSize(unsigned int width, unsigned int height) +{ + m_size = Vector2u(width, height); +} + +Vector2u X11Display::getSize() const +{ + return m_size; +} + +void X11Display::setPosition(unsigned int x, unsigned int y) +{ + +} + +void X11Display::setCaption(const std::string& caption) +{ + +} + +void X11Display::setIcon(const std::string& icon) +{ + +} + +void X11Display::showCursor(bool value) +{ + +} + +} // namespace sp diff --git a/source/Platform/Unix/X11Display.h b/source/Platform/Unix/X11Display.h new file mode 100644 index 0000000..5e1724d --- /dev/null +++ b/source/Platform/Unix/X11Display.h @@ -0,0 +1,40 @@ + +#ifndef PLATFORM_UNIX_X11DISPLAY_H +#define PLATFORM_UNIX_X11DISPLAY_H + +#include + +namespace sp { + +class X11Display : public PlatformDisplay +{ +public : + + virtual bool create(DisplayDescription description); + + virtual void destroy(); + + virtual bool isValid(); + + virtual void* getHandle() const; + + virtual void setSize(unsigned int width, unsigned int height); + + virtual Vector2u getSize() const; + + virtual void setPosition(unsigned int x, unsigned int y); + + virtual void setCaption(const std::string& caption); + + virtual void setIcon(const std::string& icon); + + virtual void showCursor(bool value); + +protected : + + Vector2u m_size; +}; + +} // namespace sp + +#endif /* PLATFORM_UNIX_X11DISPLAY_H */ diff --git a/source/Platform/Unix/X11EventQueue.cpp b/source/Platform/Unix/X11EventQueue.cpp new file mode 100644 index 0000000..d71faaa --- /dev/null +++ b/source/Platform/Unix/X11EventQueue.cpp @@ -0,0 +1,11 @@ + +#include "X11EventQueue.h" + +namespace sp { + +bool X11EventQueue::poll(Event& event) +{ + return false; +} + +} //namespace sp diff --git a/source/Platform/Unix/X11EventQueue.h b/source/Platform/Unix/X11EventQueue.h new file mode 100644 index 0000000..9239694 --- /dev/null +++ b/source/Platform/Unix/X11EventQueue.h @@ -0,0 +1,18 @@ + +#ifndef PLATFORM_UNIX_X11_EVENT_QUEUE_H +#define PLATFORM_UNIX_X11_EVENT_QUEUE_H + +#include +#include + +namespace sp { + +class X11EventQueue : public PlatformEventQueue +{ +public : + virtual bool poll(Event& event); +}; + +} // namespace sp + +#endif /* PLATFORM_UNIX_X11_EVENT_QUEUE_H */ diff --git a/source/Platform/Unix/X11Input.cpp b/source/Platform/Unix/X11Input.cpp new file mode 100644 index 0000000..2af3f10 --- /dev/null +++ b/source/Platform/Unix/X11Input.cpp @@ -0,0 +1,22 @@ + +#include "X11Keyboard.h" +#include "X11Mouse.h" +#include "X11Input.h" + +namespace sp { + +Keyboard* X11Input::createKeyboard() +{ + return new X11Keyboard(); +} + +Mouse* X11Input::createMouse() +{ + return new X11Mouse(); +} + +void X11Input::update() +{ +} + +} // namespace sp diff --git a/source/Platform/Unix/X11Input.h b/source/Platform/Unix/X11Input.h new file mode 100644 index 0000000..6bb7439 --- /dev/null +++ b/source/Platform/Unix/X11Input.h @@ -0,0 +1,21 @@ + +#ifndef PLATFORM_UNIX_X11INPUT_H +#define PLATFORM_UNIX_X11INPUT_H + +#include + +namespace sp { + +class X11Input : public PlatformInput +{ +public : + virtual Keyboard* createKeyboard(); + + virtual Mouse* createMouse(); + + virtual void update(); +}; + +} // namespace sp + +#endif /* PLATFORM_UNIX_X11INPUT_H */ diff --git a/source/Platform/Unix/X11Keyboard.cpp b/source/Platform/Unix/X11Keyboard.cpp new file mode 100644 index 0000000..adc7e08 --- /dev/null +++ b/source/Platform/Unix/X11Keyboard.cpp @@ -0,0 +1,20 @@ +#include "X11Keyboard.h" + +namespace sp { + +void X11Keyboard::init() +{ + +} + +bool X11Keyboard::isKeyDown(Keyboard::Key key) +{ + return false; +} + +void X11Keyboard::update(InputModule *input) +{ + +} + +} // namespace sp diff --git a/source/Platform/Unix/X11Keyboard.h b/source/Platform/Unix/X11Keyboard.h new file mode 100644 index 0000000..7f7485c --- /dev/null +++ b/source/Platform/Unix/X11Keyboard.h @@ -0,0 +1,25 @@ + +#ifndef PLATFORM_UNIX_X11KEYBOARD_H +#define PLATFORM_UNIX_X11KEYBOARD_H + +#include + +namespace sp { + +class X11Keyboard : public Keyboard +{ +public : + virtual ~X11Keyboard() {} + + void init(); + + bool isKeyDown(Keyboard::Key key); + +protected : + + virtual void update(InputModule *input); +}; + +} // namespace sp + +#endif /* PLATFORM_UNIX_X11KEYBOARD_H */ diff --git a/source/Platform/Unix/X11Mouse.cpp b/source/Platform/Unix/X11Mouse.cpp new file mode 100644 index 0000000..48ef3bc --- /dev/null +++ b/source/Platform/Unix/X11Mouse.cpp @@ -0,0 +1,31 @@ + +#include "X11Mouse.h" + +namespace sp { + +void X11Mouse::init() +{ + +} + +Vector2f X11Mouse::getPosition() const +{ + return m_position; +} + +Vector2f X11Mouse::getAbsPosition() const +{ + return m_position; +} + +bool X11Mouse::isButtonDown(Mouse::Button button) const +{ + return false; +} + +void X11Mouse::update(InputModule *input) +{ + +} + +} // namespace sp diff --git a/source/Platform/Unix/X11Mouse.h b/source/Platform/Unix/X11Mouse.h new file mode 100644 index 0000000..55c044e --- /dev/null +++ b/source/Platform/Unix/X11Mouse.h @@ -0,0 +1,31 @@ + +#ifndef PLATFORM_UNIX_X11MOUSE_H +#define PLATFORM_UNIX_X11MOUSE_H + +#include + +namespace sp { + +class X11Mouse : public Mouse +{ +public : + virtual void init(); + + // Get mouse position + virtual Vector2f getPosition() const; + + virtual Vector2f getAbsPosition() const; + + virtual bool isButtonDown(Mouse::Button button) const; + +protected : + + virtual void update(InputModule *input); + +protected : + Vector2f m_position; +}; + +} // namespace sp + +#endif /* PLATFORM_UNIX_X11MOUSE_H */ diff --git a/source/System/MessageQueue.cpp b/source/System/MessageQueue.cpp index 8ff7a3b..3550e36 100644 --- a/source/System/MessageQueue.cpp +++ b/source/System/MessageQueue.cpp @@ -4,6 +4,9 @@ #ifdef _WIN32 #include typedef sp::Win32EventQueue ImplType; +#elif defined(__linux__) || defined(unix) || defined(__unix) || defined(__unix__) +#include +typedef sp::X11EventQueue ImplType; #else #error "No MessageQueue implementation exists" #endif From 1cfd4adca463e487ca74a32ac8c153f992ad33d4 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Tue, 24 Dec 2019 21:07:21 +0100 Subject: [PATCH 02/58] bam: adding unix support. --- .bam/functions.lua | 17 +++++++++----- .gitignore | 1 + engine.build.lua | 56 +++++++++++++++++++++++++++++++--------------- examples/build.lua | 4 ++++ 4 files changed, 55 insertions(+), 23 deletions(-) diff --git a/.bam/functions.lua b/.bam/functions.lua index 1312770..5a796da 100644 --- a/.bam/functions.lua +++ b/.bam/functions.lua @@ -1,7 +1,7 @@ local _systems = { "Win32", - -- "Linux" + "Unix" } @@ -14,12 +14,19 @@ end -- Detect what system we currently are on. function system() - local win = os.getenv('OS') - - if win:lower():match('windows') then - return _systems[1] + if family ~= nil then + if family == "windows" then + return _systems[1] + end + if family == "unix" then + return _systems[2] + end end + local win = os.getenv('OS') + if win ~= nil and win:lower():match('windows') then + return _systems[1] + end return nil end diff --git a/.gitignore b/.gitignore index bcd7a8c..6977329 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ +# Build system related files build/ .bam/* !.bam/*.lua diff --git a/engine.build.lua b/engine.build.lua index 9d3f97b..817560b 100644 --- a/engine.build.lua +++ b/engine.build.lua @@ -18,7 +18,14 @@ if global_settings.debug then end -- FreeType2 -settings.cc.includes:Add("vendor/FreeType2/include") +if TARGET_OS == "Win32" then + settings.cc.includes:Add("vendor/FreeType2/include") + + -- Staticly link freetype on windows. + settings.link.libpath:Add("vendor/FreeType2/lib/x86") +else + settings.cc.includes:Add("/usr/include/freetype2") +end -- STB settings.cc.includes:Add("vendor/stb/include") @@ -41,22 +48,33 @@ local platform_common_module = Module("source/Platform", { "PlatformDisplay.cpp" }) - --- if TARGET_OS == "Win32" then -- Needed later for unix. -local platform_spec_module = Module("source/Platform/Win32", { - "Win32Application.cpp", - "Win32Display.cpp", - "Win32GLContext.cpp", - "Win32Input.cpp", - "Win32Internal.cpp", - "Win32Keyboard.cpp", - "Win32Misc.cpp", - "Win32Mouse.cpp", - "Win32EventQueue.cpp", - "Win32System.cpp", - "glad_wgl.c" -}) ---end +if TARGET_OS == "Win32" then + local platform_spec_module = Module("source/Platform/Win32", { + "Win32Application.cpp", + "Win32Display.cpp", + "Win32GLContext.cpp", + "Win32Input.cpp", + "Win32Internal.cpp", + "Win32Keyboard.cpp", + "Win32Misc.cpp", + "Win32Mouse.cpp", + "Win32EventQueue.cpp", + "Win32System.cpp", + "glad_wgl.c" + }) +elseif TARGET_OS == "Unix" then + platform_spec_module = Module("source/Platform/Unix", { + "UnixApplication.cpp", + "X11Display.cpp", + "GLXContext.cpp", + "X11Input.cpp", + "X11Keyboard.cpp", + "X11Mouse.cpp", + "X11EventQueue.cpp", + "UnixMisc.cpp", + "UnixSystem.cpp" + }) +end local input_module = Module("source/Input", { "InputDevice.cpp", @@ -132,7 +150,9 @@ local scene_module = Module("source/Scene", { ----------------------------------------------------------- -- Dependancies -Import("vendor/FreeType2/build.lua") +if TARGET_OS == "Win32" then + Import("vendor/FreeType2/build.lua") +end -- engine local obj = Compile(settings, { diff --git a/examples/build.lua b/examples/build.lua index 552dea1..2445a86 100644 --- a/examples/build.lua +++ b/examples/build.lua @@ -16,6 +16,10 @@ if TARGET_OS == "Win32" then -- Windows needs to link against these. example_settings.link.libs:Add("opengl32", "gdi32", "user32") +elseif TARGET_OS == "Unix" then + + -- Unix nees dl and X11 libs. + example_settings.link.libs:Add("dl", 'X11', 'freetype') end -- For now, to get examples working From 7fd1ee54453802aaa47ad38f5eed1a153149b7ef Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Tue, 24 Dec 2019 21:22:37 +0100 Subject: [PATCH 03/58] assets: bam does not like whitespace in file names. --- .../fonts/{Anonymous Pro.ttf => Anonymous-Pro.ttf} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename assets/fonts/{Anonymous Pro.ttf => Anonymous-Pro.ttf} (100%) diff --git a/assets/fonts/Anonymous Pro.ttf b/assets/fonts/Anonymous-Pro.ttf similarity index 100% rename from assets/fonts/Anonymous Pro.ttf rename to assets/fonts/Anonymous-Pro.ttf From c41fb6c013262dcac2b8018015b9c7668dbf2b3e Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Tue, 24 Dec 2019 21:30:13 +0100 Subject: [PATCH 04/58] Adding glad GLX --- engine.build.lua | 3 +- source/Platform/Unix/glad_glx.c | 382 ++++++++++++++++++++ source/Platform/Unix/glad_glx.h | 602 ++++++++++++++++++++++++++++++++ 3 files changed, 986 insertions(+), 1 deletion(-) create mode 100644 source/Platform/Unix/glad_glx.c create mode 100644 source/Platform/Unix/glad_glx.h diff --git a/engine.build.lua b/engine.build.lua index 817560b..24c1821 100644 --- a/engine.build.lua +++ b/engine.build.lua @@ -72,7 +72,8 @@ elseif TARGET_OS == "Unix" then "X11Mouse.cpp", "X11EventQueue.cpp", "UnixMisc.cpp", - "UnixSystem.cpp" + "UnixSystem.cpp", + "glad_glx.c" }) end diff --git a/source/Platform/Unix/glad_glx.c b/source/Platform/Unix/glad_glx.c new file mode 100644 index 0000000..c9af335 --- /dev/null +++ b/source/Platform/Unix/glad_glx.c @@ -0,0 +1,382 @@ +#include +#include +#include +#include "glad_glx.h" + +#ifndef GLAD_IMPL_UTIL_C_ +#define GLAD_IMPL_UTIL_C_ + +#ifdef _MSC_VER +#define GLAD_IMPL_UTIL_SSCANF sscanf_s +#else +#define GLAD_IMPL_UTIL_SSCANF sscanf +#endif + +#endif /* GLAD_IMPL_UTIL_C_ */ + + +int GLAD_GLX_VERSION_1_0 = 0; +int GLAD_GLX_VERSION_1_1 = 0; +int GLAD_GLX_VERSION_1_2 = 0; +int GLAD_GLX_VERSION_1_3 = 0; +int GLAD_GLX_VERSION_1_4 = 0; +int GLAD_GLX_ARB_create_context = 0; +int GLAD_GLX_ARB_create_context_profile = 0; +int GLAD_GLX_ARB_get_proc_address = 0; +int GLAD_GLX_EXT_swap_control = 0; +int GLAD_GLX_MESA_swap_control = 0; +int GLAD_GLX_SGI_swap_control = 0; + + + +PFNGLXCHOOSEFBCONFIGPROC glad_glXChooseFBConfig = NULL; +PFNGLXCHOOSEVISUALPROC glad_glXChooseVisual = NULL; +PFNGLXCOPYCONTEXTPROC glad_glXCopyContext = NULL; +PFNGLXCREATECONTEXTPROC glad_glXCreateContext = NULL; +PFNGLXCREATECONTEXTATTRIBSARBPROC glad_glXCreateContextAttribsARB = NULL; +PFNGLXCREATEGLXPIXMAPPROC glad_glXCreateGLXPixmap = NULL; +PFNGLXCREATENEWCONTEXTPROC glad_glXCreateNewContext = NULL; +PFNGLXCREATEPBUFFERPROC glad_glXCreatePbuffer = NULL; +PFNGLXCREATEPIXMAPPROC glad_glXCreatePixmap = NULL; +PFNGLXCREATEWINDOWPROC glad_glXCreateWindow = NULL; +PFNGLXDESTROYCONTEXTPROC glad_glXDestroyContext = NULL; +PFNGLXDESTROYGLXPIXMAPPROC glad_glXDestroyGLXPixmap = NULL; +PFNGLXDESTROYPBUFFERPROC glad_glXDestroyPbuffer = NULL; +PFNGLXDESTROYPIXMAPPROC glad_glXDestroyPixmap = NULL; +PFNGLXDESTROYWINDOWPROC glad_glXDestroyWindow = NULL; +PFNGLXGETCLIENTSTRINGPROC glad_glXGetClientString = NULL; +PFNGLXGETCONFIGPROC glad_glXGetConfig = NULL; +PFNGLXGETCURRENTCONTEXTPROC glad_glXGetCurrentContext = NULL; +PFNGLXGETCURRENTDISPLAYPROC glad_glXGetCurrentDisplay = NULL; +PFNGLXGETCURRENTDRAWABLEPROC glad_glXGetCurrentDrawable = NULL; +PFNGLXGETCURRENTREADDRAWABLEPROC glad_glXGetCurrentReadDrawable = NULL; +PFNGLXGETFBCONFIGATTRIBPROC glad_glXGetFBConfigAttrib = NULL; +PFNGLXGETFBCONFIGSPROC glad_glXGetFBConfigs = NULL; +PFNGLXGETPROCADDRESSPROC glad_glXGetProcAddress = NULL; +PFNGLXGETPROCADDRESSARBPROC glad_glXGetProcAddressARB = NULL; +PFNGLXGETSELECTEDEVENTPROC glad_glXGetSelectedEvent = NULL; +PFNGLXGETSWAPINTERVALMESAPROC glad_glXGetSwapIntervalMESA = NULL; +PFNGLXGETVISUALFROMFBCONFIGPROC glad_glXGetVisualFromFBConfig = NULL; +PFNGLXISDIRECTPROC glad_glXIsDirect = NULL; +PFNGLXMAKECONTEXTCURRENTPROC glad_glXMakeContextCurrent = NULL; +PFNGLXMAKECURRENTPROC glad_glXMakeCurrent = NULL; +PFNGLXQUERYCONTEXTPROC glad_glXQueryContext = NULL; +PFNGLXQUERYDRAWABLEPROC glad_glXQueryDrawable = NULL; +PFNGLXQUERYEXTENSIONPROC glad_glXQueryExtension = NULL; +PFNGLXQUERYEXTENSIONSSTRINGPROC glad_glXQueryExtensionsString = NULL; +PFNGLXQUERYSERVERSTRINGPROC glad_glXQueryServerString = NULL; +PFNGLXQUERYVERSIONPROC glad_glXQueryVersion = NULL; +PFNGLXSELECTEVENTPROC glad_glXSelectEvent = NULL; +PFNGLXSWAPBUFFERSPROC glad_glXSwapBuffers = NULL; +PFNGLXSWAPINTERVALEXTPROC glad_glXSwapIntervalEXT = NULL; +PFNGLXSWAPINTERVALMESAPROC glad_glXSwapIntervalMESA = NULL; +PFNGLXSWAPINTERVALSGIPROC glad_glXSwapIntervalSGI = NULL; +PFNGLXUSEXFONTPROC glad_glXUseXFont = NULL; +PFNGLXWAITGLPROC glad_glXWaitGL = NULL; +PFNGLXWAITXPROC glad_glXWaitX = NULL; + + +static void glad_glx_load_GLX_VERSION_1_0( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GLX_VERSION_1_0) return; + glad_glXChooseVisual = (PFNGLXCHOOSEVISUALPROC) load(userptr, "glXChooseVisual"); + glad_glXCopyContext = (PFNGLXCOPYCONTEXTPROC) load(userptr, "glXCopyContext"); + glad_glXCreateContext = (PFNGLXCREATECONTEXTPROC) load(userptr, "glXCreateContext"); + glad_glXCreateGLXPixmap = (PFNGLXCREATEGLXPIXMAPPROC) load(userptr, "glXCreateGLXPixmap"); + glad_glXDestroyContext = (PFNGLXDESTROYCONTEXTPROC) load(userptr, "glXDestroyContext"); + glad_glXDestroyGLXPixmap = (PFNGLXDESTROYGLXPIXMAPPROC) load(userptr, "glXDestroyGLXPixmap"); + glad_glXGetConfig = (PFNGLXGETCONFIGPROC) load(userptr, "glXGetConfig"); + glad_glXGetCurrentContext = (PFNGLXGETCURRENTCONTEXTPROC) load(userptr, "glXGetCurrentContext"); + glad_glXGetCurrentDrawable = (PFNGLXGETCURRENTDRAWABLEPROC) load(userptr, "glXGetCurrentDrawable"); + glad_glXIsDirect = (PFNGLXISDIRECTPROC) load(userptr, "glXIsDirect"); + glad_glXMakeCurrent = (PFNGLXMAKECURRENTPROC) load(userptr, "glXMakeCurrent"); + glad_glXQueryExtension = (PFNGLXQUERYEXTENSIONPROC) load(userptr, "glXQueryExtension"); + glad_glXQueryVersion = (PFNGLXQUERYVERSIONPROC) load(userptr, "glXQueryVersion"); + glad_glXSwapBuffers = (PFNGLXSWAPBUFFERSPROC) load(userptr, "glXSwapBuffers"); + glad_glXUseXFont = (PFNGLXUSEXFONTPROC) load(userptr, "glXUseXFont"); + glad_glXWaitGL = (PFNGLXWAITGLPROC) load(userptr, "glXWaitGL"); + glad_glXWaitX = (PFNGLXWAITXPROC) load(userptr, "glXWaitX"); +} +static void glad_glx_load_GLX_VERSION_1_1( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GLX_VERSION_1_1) return; + glad_glXGetClientString = (PFNGLXGETCLIENTSTRINGPROC) load(userptr, "glXGetClientString"); + glad_glXQueryExtensionsString = (PFNGLXQUERYEXTENSIONSSTRINGPROC) load(userptr, "glXQueryExtensionsString"); + glad_glXQueryServerString = (PFNGLXQUERYSERVERSTRINGPROC) load(userptr, "glXQueryServerString"); +} +static void glad_glx_load_GLX_VERSION_1_2( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GLX_VERSION_1_2) return; + glad_glXGetCurrentDisplay = (PFNGLXGETCURRENTDISPLAYPROC) load(userptr, "glXGetCurrentDisplay"); +} +static void glad_glx_load_GLX_VERSION_1_3( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GLX_VERSION_1_3) return; + glad_glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC) load(userptr, "glXChooseFBConfig"); + glad_glXCreateNewContext = (PFNGLXCREATENEWCONTEXTPROC) load(userptr, "glXCreateNewContext"); + glad_glXCreatePbuffer = (PFNGLXCREATEPBUFFERPROC) load(userptr, "glXCreatePbuffer"); + glad_glXCreatePixmap = (PFNGLXCREATEPIXMAPPROC) load(userptr, "glXCreatePixmap"); + glad_glXCreateWindow = (PFNGLXCREATEWINDOWPROC) load(userptr, "glXCreateWindow"); + glad_glXDestroyPbuffer = (PFNGLXDESTROYPBUFFERPROC) load(userptr, "glXDestroyPbuffer"); + glad_glXDestroyPixmap = (PFNGLXDESTROYPIXMAPPROC) load(userptr, "glXDestroyPixmap"); + glad_glXDestroyWindow = (PFNGLXDESTROYWINDOWPROC) load(userptr, "glXDestroyWindow"); + glad_glXGetCurrentReadDrawable = (PFNGLXGETCURRENTREADDRAWABLEPROC) load(userptr, "glXGetCurrentReadDrawable"); + glad_glXGetFBConfigAttrib = (PFNGLXGETFBCONFIGATTRIBPROC) load(userptr, "glXGetFBConfigAttrib"); + glad_glXGetFBConfigs = (PFNGLXGETFBCONFIGSPROC) load(userptr, "glXGetFBConfigs"); + glad_glXGetSelectedEvent = (PFNGLXGETSELECTEDEVENTPROC) load(userptr, "glXGetSelectedEvent"); + glad_glXGetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC) load(userptr, "glXGetVisualFromFBConfig"); + glad_glXMakeContextCurrent = (PFNGLXMAKECONTEXTCURRENTPROC) load(userptr, "glXMakeContextCurrent"); + glad_glXQueryContext = (PFNGLXQUERYCONTEXTPROC) load(userptr, "glXQueryContext"); + glad_glXQueryDrawable = (PFNGLXQUERYDRAWABLEPROC) load(userptr, "glXQueryDrawable"); + glad_glXSelectEvent = (PFNGLXSELECTEVENTPROC) load(userptr, "glXSelectEvent"); +} +static void glad_glx_load_GLX_VERSION_1_4( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GLX_VERSION_1_4) return; + glad_glXGetProcAddress = (PFNGLXGETPROCADDRESSPROC) load(userptr, "glXGetProcAddress"); +} +static void glad_glx_load_GLX_ARB_create_context( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GLX_ARB_create_context) return; + glad_glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) load(userptr, "glXCreateContextAttribsARB"); +} +static void glad_glx_load_GLX_ARB_get_proc_address( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GLX_ARB_get_proc_address) return; + glad_glXGetProcAddressARB = (PFNGLXGETPROCADDRESSARBPROC) load(userptr, "glXGetProcAddressARB"); +} +static void glad_glx_load_GLX_EXT_swap_control( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GLX_EXT_swap_control) return; + glad_glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) load(userptr, "glXSwapIntervalEXT"); +} +static void glad_glx_load_GLX_MESA_swap_control( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GLX_MESA_swap_control) return; + glad_glXGetSwapIntervalMESA = (PFNGLXGETSWAPINTERVALMESAPROC) load(userptr, "glXGetSwapIntervalMESA"); + glad_glXSwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC) load(userptr, "glXSwapIntervalMESA"); +} +static void glad_glx_load_GLX_SGI_swap_control( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GLX_SGI_swap_control) return; + glad_glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) load(userptr, "glXSwapIntervalSGI"); +} + + + +static int glad_glx_has_extension(Display *display, int screen, const char *ext) { +#ifndef GLX_VERSION_1_1 + (void) display; + (void) screen; + (void) ext; +#else + const char *terminator; + const char *loc; + const char *extensions; + + if (glXQueryExtensionsString == NULL) { + return 0; + } + + extensions = glXQueryExtensionsString(display, screen); + + if(extensions == NULL || ext == NULL) { + return 0; + } + + while(1) { + loc = strstr(extensions, ext); + if(loc == NULL) + break; + + terminator = loc + strlen(ext); + if((loc == extensions || *(loc - 1) == ' ') && + (*terminator == ' ' || *terminator == '\0')) { + return 1; + } + extensions = terminator; + } +#endif + + return 0; +} + +static GLADapiproc glad_glx_get_proc_from_userptr(void *userptr, const char* name) { + return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name); +} + +static int glad_glx_find_extensions(Display *display, int screen) { + GLAD_GLX_ARB_create_context = glad_glx_has_extension(display, screen, "GLX_ARB_create_context"); + GLAD_GLX_ARB_create_context_profile = glad_glx_has_extension(display, screen, "GLX_ARB_create_context_profile"); + GLAD_GLX_ARB_get_proc_address = glad_glx_has_extension(display, screen, "GLX_ARB_get_proc_address"); + GLAD_GLX_EXT_swap_control = glad_glx_has_extension(display, screen, "GLX_EXT_swap_control"); + GLAD_GLX_MESA_swap_control = glad_glx_has_extension(display, screen, "GLX_MESA_swap_control"); + GLAD_GLX_SGI_swap_control = glad_glx_has_extension(display, screen, "GLX_SGI_swap_control"); + return 1; +} + +static int glad_glx_find_core_glx(Display **display, int *screen) { + int major = 0, minor = 0; + if(*display == NULL) { +#ifdef GLAD_GLX_NO_X11 + (void) screen; + return 0; +#else + *display = XOpenDisplay(0); + if (*display == NULL) { + return 0; + } + *screen = XScreenNumberOfScreen(XDefaultScreenOfDisplay(*display)); +#endif + } + glXQueryVersion(*display, &major, &minor); + GLAD_GLX_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; + GLAD_GLX_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; + GLAD_GLX_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; + GLAD_GLX_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; + GLAD_GLX_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1; + return GLAD_MAKE_VERSION(major, minor); +} + +int gladLoadGLXUserPtr(Display *display, int screen, GLADuserptrloadfunc load, void *userptr) { + int version; + glXQueryVersion = (PFNGLXQUERYVERSIONPROC) load(userptr, "glXQueryVersion"); + if(glXQueryVersion == NULL) return 0; + version = glad_glx_find_core_glx(&display, &screen); + + glad_glx_load_GLX_VERSION_1_0(load, userptr); + glad_glx_load_GLX_VERSION_1_1(load, userptr); + glad_glx_load_GLX_VERSION_1_2(load, userptr); + glad_glx_load_GLX_VERSION_1_3(load, userptr); + glad_glx_load_GLX_VERSION_1_4(load, userptr); + + if (!glad_glx_find_extensions(display, screen)) return 0; + glad_glx_load_GLX_ARB_create_context(load, userptr); + glad_glx_load_GLX_ARB_get_proc_address(load, userptr); + glad_glx_load_GLX_EXT_swap_control(load, userptr); + glad_glx_load_GLX_MESA_swap_control(load, userptr); + glad_glx_load_GLX_SGI_swap_control(load, userptr); + + return version; +} + +int gladLoadGLX(Display *display, int screen, GLADloadfunc load) { + return gladLoadGLXUserPtr(display, screen, glad_glx_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load); +} + + + +#ifdef GLAD_GLX + +#ifndef GLAD_LOADER_LIBRARY_C_ +#define GLAD_LOADER_LIBRARY_C_ + +#include +#include + +#if GLAD_PLATFORM_WIN32 +#include +#else +#include +#endif + + +static void* glad_get_dlopen_handle(const char *lib_names[], int length) { + void *handle = NULL; + int i; + + for (i = 0; i < length; ++i) { +#if GLAD_PLATFORM_WIN32 + #if GLAD_PLATFORM_UWP + size_t buffer_size = (strlen(lib_names[i]) + 1) * sizeof(WCHAR); + LPWSTR buffer = (LPWSTR) malloc(buffer_size); + if (buffer != NULL) { + int ret = MultiByteToWideChar(CP_ACP, 0, lib_names[i], -1, buffer, buffer_size); + if (ret != 0) { + handle = (void*) LoadPackagedLibrary(buffer, 0); + } + free((void*) buffer); + } + #else + handle = (void*) LoadLibraryA(lib_names[i]); + #endif +#else + handle = dlopen(lib_names[i], RTLD_LAZY | RTLD_LOCAL); +#endif + if (handle != NULL) { + return handle; + } + } + + return NULL; +} + +static void glad_close_dlopen_handle(void* handle) { + if (handle != NULL) { +#if GLAD_PLATFORM_WIN32 + FreeLibrary((HMODULE) handle); +#else + dlclose(handle); +#endif + } +} + +static GLADapiproc glad_dlsym_handle(void* handle, const char *name) { + if (handle == NULL) { + return NULL; + } + +#if GLAD_PLATFORM_WIN32 + return (GLADapiproc) GetProcAddress((HMODULE) handle, name); +#else + return GLAD_GNUC_EXTENSION (GLADapiproc) dlsym(handle, name); +#endif +} + +#endif /* GLAD_LOADER_LIBRARY_C_ */ + +typedef void* (GLAD_API_PTR *GLADglxprocaddrfunc)(const char*); + +static GLADapiproc glad_glx_get_proc(void *userptr, const char *name) { + return GLAD_GNUC_EXTENSION ((GLADapiproc (*)(const char *name)) userptr)(name); +} + +static void* _glx_handle; + +static void* glad_glx_dlopen_handle(void) { + static const char *NAMES[] = { +#if defined __CYGWIN__ + "libGL-1.so", +#endif + "libGL.so.1", + "libGL.so" + }; + + if (_glx_handle == NULL) { + _glx_handle = glad_get_dlopen_handle(NAMES, sizeof(NAMES) / sizeof(NAMES[0])); + } + + return _glx_handle; +} + +int gladLoaderLoadGLX(Display *display, int screen) { + int version = 0; + void *handle = NULL; + int did_load = 0; + GLADglxprocaddrfunc loader; + + did_load = _glx_handle == NULL; + handle = glad_glx_dlopen_handle(); + if (handle != NULL) { + loader = (GLADglxprocaddrfunc) glad_dlsym_handle(handle, "glXGetProcAddressARB"); + if (loader != NULL) { + version = gladLoadGLXUserPtr(display, screen, glad_glx_get_proc, GLAD_GNUC_EXTENSION (void*) loader); + } + + if (!version && did_load) { + gladLoaderUnloadGLX(); + } + } + + return version; +} + + +void gladLoaderUnloadGLX() { + if (_glx_handle != NULL) { + glad_close_dlopen_handle(_glx_handle); + _glx_handle = NULL; + } +} + +#endif /* GLAD_GLX */ diff --git a/source/Platform/Unix/glad_glx.h b/source/Platform/Unix/glad_glx.h new file mode 100644 index 0000000..d6ffe96 --- /dev/null +++ b/source/Platform/Unix/glad_glx.h @@ -0,0 +1,602 @@ +/** + * Loader generated by glad 2.0.0-beta on Sat Dec 21 20:36:57 2019 + * + * Generator: C/C++ + * Specification: glx + * Extensions: 6 + * + * APIs: + * - glx=1.4 + * + * Options: + * - MX_GLOBAL = False + * - ON_DEMAND = False + * - LOADER = True + * - ALIAS = False + * - HEADER_ONLY = False + * - DEBUG = False + * - MX = False + * + * Commandline: + * --api='glx=1.4' --extensions='GLX_ARB_create_context,GLX_ARB_create_context_profile,GLX_ARB_get_proc_address,GLX_EXT_swap_control,GLX_MESA_swap_control,GLX_SGI_swap_control' c --loader + * + * Online: + * http://glad.sh/#api=glx%3D1.4&extensions=GLX_ARB_create_context%2CGLX_ARB_create_context_profile%2CGLX_ARB_get_proc_address%2CGLX_EXT_swap_control%2CGLX_MESA_swap_control%2CGLX_SGI_swap_control&generator=c&options=LOADER + * + */ + +#ifndef GLAD_GLX_H_ +#define GLAD_GLX_H_ + +#ifdef GLX_H + #error GLX header already included (API: glx), remove previous include! +#endif +#define GLX_H 1 + + +#include +#include +#include + +#include + +#define GLAD_GLX +#define GLAD_OPTION_GLX_LOADER + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef GLAD_PLATFORM_H_ +#define GLAD_PLATFORM_H_ + +#ifndef GLAD_PLATFORM_WIN32 + #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__) + #define GLAD_PLATFORM_WIN32 1 + #else + #define GLAD_PLATFORM_WIN32 0 + #endif +#endif + +#ifndef GLAD_PLATFORM_APPLE + #ifdef __APPLE__ + #define GLAD_PLATFORM_APPLE 1 + #else + #define GLAD_PLATFORM_APPLE 0 + #endif +#endif + +#ifndef GLAD_PLATFORM_EMSCRIPTEN + #ifdef __EMSCRIPTEN__ + #define GLAD_PLATFORM_EMSCRIPTEN 1 + #else + #define GLAD_PLATFORM_EMSCRIPTEN 0 + #endif +#endif + +#ifndef GLAD_PLATFORM_UWP + #if defined(_MSC_VER) && !defined(GLAD_INTERNAL_HAVE_WINAPIFAMILY) + #ifdef __has_include + #if __has_include() + #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 + #endif + #elif _MSC_VER >= 1700 && !_USING_V110_SDK71_ + #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 + #endif + #endif + + #ifdef GLAD_INTERNAL_HAVE_WINAPIFAMILY + #include + #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) + #define GLAD_PLATFORM_UWP 1 + #endif + #endif + + #ifndef GLAD_PLATFORM_UWP + #define GLAD_PLATFORM_UWP 0 + #endif +#endif + +#ifdef __GNUC__ + #define GLAD_GNUC_EXTENSION __extension__ +#else + #define GLAD_GNUC_EXTENSION +#endif + +#ifndef GLAD_API_CALL + #if defined(GLAD_API_CALL_EXPORT) + #if GLAD_PLATFORM_WIN32 || defined(__CYGWIN__) + #if defined(GLAD_API_CALL_EXPORT_BUILD) + #if defined(__GNUC__) + #define GLAD_API_CALL __attribute__ ((dllexport)) extern + #else + #define GLAD_API_CALL __declspec(dllexport) extern + #endif + #else + #if defined(__GNUC__) + #define GLAD_API_CALL __attribute__ ((dllimport)) extern + #else + #define GLAD_API_CALL __declspec(dllimport) extern + #endif + #endif + #elif defined(__GNUC__) && defined(GLAD_API_CALL_EXPORT_BUILD) + #define GLAD_API_CALL __attribute__ ((visibility ("default"))) extern + #else + #define GLAD_API_CALL extern + #endif + #else + #define GLAD_API_CALL extern + #endif +#endif + +#ifdef APIENTRY + #define GLAD_API_PTR APIENTRY +#elif GLAD_PLATFORM_WIN32 + #define GLAD_API_PTR __stdcall +#else + #define GLAD_API_PTR +#endif + +#ifndef GLAPI +#define GLAPI GLAD_API_CALL +#endif + +#ifndef GLAPIENTRY +#define GLAPIENTRY GLAD_API_PTR +#endif + +#define GLAD_MAKE_VERSION(major, minor) (major * 10000 + minor) +#define GLAD_VERSION_MAJOR(version) (version / 10000) +#define GLAD_VERSION_MINOR(version) (version % 10000) + +#define GLAD_GENERATOR_VERSION "2.0.0-beta" + +typedef void (*GLADapiproc)(void); + +typedef GLADapiproc (*GLADloadfunc)(const char *name); +typedef GLADapiproc (*GLADuserptrloadfunc)(void *userptr, const char *name); + +typedef void (*GLADprecallback)(const char *name, GLADapiproc apiproc, int len_args, ...); +typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apiproc, int len_args, ...); + +#endif /* GLAD_PLATFORM_H_ */ + +#define GLX_ACCUM_ALPHA_SIZE 17 +#define GLX_ACCUM_BLUE_SIZE 16 +#define GLX_ACCUM_BUFFER_BIT 0x00000080 +#define GLX_ACCUM_GREEN_SIZE 15 +#define GLX_ACCUM_RED_SIZE 14 +#define GLX_ALPHA_SIZE 11 +#define GLX_AUX_BUFFERS 7 +#define GLX_AUX_BUFFERS_BIT 0x00000010 +#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 +#define GLX_BAD_ATTRIBUTE 2 +#define GLX_BAD_CONTEXT 5 +#define GLX_BAD_ENUM 7 +#define GLX_BAD_SCREEN 1 +#define GLX_BAD_VALUE 6 +#define GLX_BAD_VISUAL 4 +#define GLX_BLUE_SIZE 10 +#define GLX_BUFFER_SIZE 2 +#define GLX_BufferSwapComplete 1 +#define GLX_COLOR_INDEX_BIT 0x00000002 +#define GLX_COLOR_INDEX_TYPE 0x8015 +#define GLX_CONFIG_CAVEAT 0x20 +#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 +#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001 +#define GLX_CONTEXT_FLAGS_ARB 0x2094 +#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 +#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 +#define GLX_DAMAGED 0x8020 +#define GLX_DEPTH_BUFFER_BIT 0x00000020 +#define GLX_DEPTH_SIZE 12 +#define GLX_DIRECT_COLOR 0x8003 +#define GLX_DONT_CARE 0xFFFFFFFF +#define GLX_DOUBLEBUFFER 5 +#define GLX_DRAWABLE_TYPE 0x8010 +#define GLX_EVENT_MASK 0x801F +#define GLX_EXTENSIONS 0x3 +#define GLX_EXTENSION_NAME "GLX" +#define GLX_FBCONFIG_ID 0x8013 +#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 +#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 +#define GLX_GRAY_SCALE 0x8006 +#define GLX_GREEN_SIZE 9 +#define GLX_HEIGHT 0x801E +#define GLX_LARGEST_PBUFFER 0x801C +#define GLX_LEVEL 3 +#define GLX_MAX_PBUFFER_HEIGHT 0x8017 +#define GLX_MAX_PBUFFER_PIXELS 0x8018 +#define GLX_MAX_PBUFFER_WIDTH 0x8016 +#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2 +#define GLX_NONE 0x8000 +#define GLX_NON_CONFORMANT_CONFIG 0x800D +#define GLX_NO_EXTENSION 3 +#define GLX_PBUFFER 0x8023 +#define GLX_PBUFFER_BIT 0x00000004 +#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 +#define GLX_PBUFFER_HEIGHT 0x8040 +#define GLX_PBUFFER_WIDTH 0x8041 +#define GLX_PIXMAP_BIT 0x00000002 +#define GLX_PRESERVED_CONTENTS 0x801B +#define GLX_PSEUDO_COLOR 0x8004 +#define GLX_PbufferClobber 0 +#define GLX_RED_SIZE 8 +#define GLX_RENDER_TYPE 0x8011 +#define GLX_RGBA 4 +#define GLX_RGBA_BIT 0x00000001 +#define GLX_RGBA_TYPE 0x8014 +#define GLX_SAMPLES 100001 +#define GLX_SAMPLE_BUFFERS 100000 +#define GLX_SAVED 0x8021 +#define GLX_SCREEN 0x800C +#define GLX_SLOW_CONFIG 0x8001 +#define GLX_STATIC_COLOR 0x8005 +#define GLX_STATIC_GRAY 0x8007 +#define GLX_STENCIL_BUFFER_BIT 0x00000040 +#define GLX_STENCIL_SIZE 13 +#define GLX_STEREO 6 +#define GLX_SWAP_INTERVAL_EXT 0x20F1 +#define GLX_TRANSPARENT_ALPHA_VALUE 0x28 +#define GLX_TRANSPARENT_BLUE_VALUE 0x27 +#define GLX_TRANSPARENT_GREEN_VALUE 0x26 +#define GLX_TRANSPARENT_INDEX 0x8009 +#define GLX_TRANSPARENT_INDEX_VALUE 0x24 +#define GLX_TRANSPARENT_RED_VALUE 0x25 +#define GLX_TRANSPARENT_RGB 0x8008 +#define GLX_TRANSPARENT_TYPE 0x23 +#define GLX_TRUE_COLOR 0x8002 +#define GLX_USE_GL 1 +#define GLX_VENDOR 0x1 +#define GLX_VERSION 0x2 +#define GLX_VISUAL_ID 0x800B +#define GLX_WIDTH 0x801D +#define GLX_WINDOW 0x8022 +#define GLX_WINDOW_BIT 0x00000001 +#define GLX_X_RENDERABLE 0x8012 +#define GLX_X_VISUAL_TYPE 0x22 +#define __GLX_NUMBER_EVENTS 17 + + +#ifndef GLEXT_64_TYPES_DEFINED +/* This code block is duplicated in glext.h, so must be protected */ +#define GLEXT_64_TYPES_DEFINED +/* Define int32_t, int64_t, and uint64_t types for UST/MSC */ +/* (as used in the GLX_OML_sync_control extension). */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#include +#elif defined(__sun__) || defined(__digital__) +#include +#if defined(__STDC__) +#if defined(__arch64__) || defined(_LP64) +typedef long int int64_t; +typedef unsigned long int uint64_t; +#else +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#endif /* __arch64__ */ +#endif /* __STDC__ */ +#elif defined( __VMS ) || defined(__sgi) +#include +#elif defined(__SCO__) || defined(__USLC__) +#include +#elif defined(__UNIXOS2__) || defined(__SOL64__) +typedef long int int32_t; +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#elif defined(_WIN32) && defined(__GNUC__) +#include +#elif defined(_WIN32) +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else +/* Fallback if nothing above works */ +#include +#endif +#endif + + + + + + + + + + + + + + + + +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) + +#else + +#endif + +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) + +#else + +#endif + + + + + + + +typedef XID GLXFBConfigID; +typedef struct __GLXFBConfigRec *GLXFBConfig; +typedef XID GLXContextID; +typedef struct __GLXcontextRec *GLXContext; +typedef XID GLXPixmap; +typedef XID GLXDrawable; +typedef XID GLXWindow; +typedef XID GLXPbuffer; +typedef void (GLAD_API_PTR *__GLXextFuncPtr)(void); +typedef XID GLXVideoCaptureDeviceNV; +typedef unsigned int GLXVideoDeviceNV; +typedef XID GLXVideoSourceSGIX; +typedef XID GLXFBConfigIDSGIX; +typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; +typedef XID GLXPbufferSGIX; +typedef struct { + int event_type; /* GLX_DAMAGED or GLX_SAVED */ + int draw_type; /* GLX_WINDOW or GLX_PBUFFER */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came for SendEvent request */ + Display *display; /* display the event was read from */ + GLXDrawable drawable; /* XID of Drawable */ + unsigned int buffer_mask; /* mask indicating which buffers are affected */ + unsigned int aux_buffer; /* which aux buffer was affected */ + int x, y; + int width, height; + int count; /* if nonzero, at least this many more */ +} GLXPbufferClobberEvent; +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + GLXDrawable drawable; /* drawable on which event was requested in event mask */ + int event_type; + int64_t ust; + int64_t msc; + int64_t sbc; +} GLXBufferSwapComplete; +typedef union __GLXEvent { + GLXPbufferClobberEvent glxpbufferclobber; + GLXBufferSwapComplete glxbufferswapcomplete; + long pad[24]; +} GLXEvent; +typedef struct { + int type; + unsigned long serial; + Bool send_event; + Display *display; + int extension; + int evtype; + GLXDrawable window; + Bool stereo_tree; +} GLXStereoNotifyEventEXT; +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came for SendEvent request */ + Display *display; /* display the event was read from */ + GLXDrawable drawable; /* i.d. of Drawable */ + int event_type; /* GLX_DAMAGED_SGIX or GLX_SAVED_SGIX */ + int draw_type; /* GLX_WINDOW_SGIX or GLX_PBUFFER_SGIX */ + unsigned int mask; /* mask indicating which buffers are affected*/ + int x, y; + int width, height; + int count; /* if nonzero, at least this many more */ +} GLXBufferClobberEventSGIX; +typedef struct { + char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */ + int networkId; +} GLXHyperpipeNetworkSGIX; +typedef struct { + char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */ + int channel; + unsigned int participationType; + int timeSlice; +} GLXHyperpipeConfigSGIX; +typedef struct { + char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */ + int srcXOrigin, srcYOrigin, srcWidth, srcHeight; + int destXOrigin, destYOrigin, destWidth, destHeight; +} GLXPipeRect; +typedef struct { + char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */ + int XOrigin, YOrigin, maxHeight, maxWidth; +} GLXPipeRectLimits; + + +#define GLX_VERSION_1_0 1 +GLAD_API_CALL int GLAD_GLX_VERSION_1_0; +#define GLX_VERSION_1_1 1 +GLAD_API_CALL int GLAD_GLX_VERSION_1_1; +#define GLX_VERSION_1_2 1 +GLAD_API_CALL int GLAD_GLX_VERSION_1_2; +#define GLX_VERSION_1_3 1 +GLAD_API_CALL int GLAD_GLX_VERSION_1_3; +#define GLX_VERSION_1_4 1 +GLAD_API_CALL int GLAD_GLX_VERSION_1_4; +#define GLX_ARB_create_context 1 +GLAD_API_CALL int GLAD_GLX_ARB_create_context; +#define GLX_ARB_create_context_profile 1 +GLAD_API_CALL int GLAD_GLX_ARB_create_context_profile; +#define GLX_ARB_get_proc_address 1 +GLAD_API_CALL int GLAD_GLX_ARB_get_proc_address; +#define GLX_EXT_swap_control 1 +GLAD_API_CALL int GLAD_GLX_EXT_swap_control; +#define GLX_MESA_swap_control 1 +GLAD_API_CALL int GLAD_GLX_MESA_swap_control; +#define GLX_SGI_swap_control 1 +GLAD_API_CALL int GLAD_GLX_SGI_swap_control; + + +typedef GLXFBConfig * (GLAD_API_PTR *PFNGLXCHOOSEFBCONFIGPROC)(Display * dpy, int screen, const int * attrib_list, int * nelements); +typedef XVisualInfo * (GLAD_API_PTR *PFNGLXCHOOSEVISUALPROC)(Display * dpy, int screen, int * attribList); +typedef void (GLAD_API_PTR *PFNGLXCOPYCONTEXTPROC)(Display * dpy, GLXContext src, GLXContext dst, unsigned long mask); +typedef GLXContext (GLAD_API_PTR *PFNGLXCREATECONTEXTPROC)(Display * dpy, XVisualInfo * vis, GLXContext shareList, Bool direct); +typedef GLXContext (GLAD_API_PTR *PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display * dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int * attrib_list); +typedef GLXPixmap (GLAD_API_PTR *PFNGLXCREATEGLXPIXMAPPROC)(Display * dpy, XVisualInfo * visual, Pixmap pixmap); +typedef GLXContext (GLAD_API_PTR *PFNGLXCREATENEWCONTEXTPROC)(Display * dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); +typedef GLXPbuffer (GLAD_API_PTR *PFNGLXCREATEPBUFFERPROC)(Display * dpy, GLXFBConfig config, const int * attrib_list); +typedef GLXPixmap (GLAD_API_PTR *PFNGLXCREATEPIXMAPPROC)(Display * dpy, GLXFBConfig config, Pixmap pixmap, const int * attrib_list); +typedef GLXWindow (GLAD_API_PTR *PFNGLXCREATEWINDOWPROC)(Display * dpy, GLXFBConfig config, Window win, const int * attrib_list); +typedef void (GLAD_API_PTR *PFNGLXDESTROYCONTEXTPROC)(Display * dpy, GLXContext ctx); +typedef void (GLAD_API_PTR *PFNGLXDESTROYGLXPIXMAPPROC)(Display * dpy, GLXPixmap pixmap); +typedef void (GLAD_API_PTR *PFNGLXDESTROYPBUFFERPROC)(Display * dpy, GLXPbuffer pbuf); +typedef void (GLAD_API_PTR *PFNGLXDESTROYPIXMAPPROC)(Display * dpy, GLXPixmap pixmap); +typedef void (GLAD_API_PTR *PFNGLXDESTROYWINDOWPROC)(Display * dpy, GLXWindow win); +typedef const char * (GLAD_API_PTR *PFNGLXGETCLIENTSTRINGPROC)(Display * dpy, int name); +typedef int (GLAD_API_PTR *PFNGLXGETCONFIGPROC)(Display * dpy, XVisualInfo * visual, int attrib, int * value); +typedef GLXContext (GLAD_API_PTR *PFNGLXGETCURRENTCONTEXTPROC)(void); +typedef Display * (GLAD_API_PTR *PFNGLXGETCURRENTDISPLAYPROC)(void); +typedef GLXDrawable (GLAD_API_PTR *PFNGLXGETCURRENTDRAWABLEPROC)(void); +typedef GLXDrawable (GLAD_API_PTR *PFNGLXGETCURRENTREADDRAWABLEPROC)(void); +typedef int (GLAD_API_PTR *PFNGLXGETFBCONFIGATTRIBPROC)(Display * dpy, GLXFBConfig config, int attribute, int * value); +typedef GLXFBConfig * (GLAD_API_PTR *PFNGLXGETFBCONFIGSPROC)(Display * dpy, int screen, int * nelements); +typedef __GLXextFuncPtr (GLAD_API_PTR *PFNGLXGETPROCADDRESSPROC)(const GLubyte * procName); +typedef __GLXextFuncPtr (GLAD_API_PTR *PFNGLXGETPROCADDRESSARBPROC)(const GLubyte * procName); +typedef void (GLAD_API_PTR *PFNGLXGETSELECTEDEVENTPROC)(Display * dpy, GLXDrawable draw, unsigned long * event_mask); +typedef int (GLAD_API_PTR *PFNGLXGETSWAPINTERVALMESAPROC)(void); +typedef XVisualInfo * (GLAD_API_PTR *PFNGLXGETVISUALFROMFBCONFIGPROC)(Display * dpy, GLXFBConfig config); +typedef Bool (GLAD_API_PTR *PFNGLXISDIRECTPROC)(Display * dpy, GLXContext ctx); +typedef Bool (GLAD_API_PTR *PFNGLXMAKECONTEXTCURRENTPROC)(Display * dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); +typedef Bool (GLAD_API_PTR *PFNGLXMAKECURRENTPROC)(Display * dpy, GLXDrawable drawable, GLXContext ctx); +typedef int (GLAD_API_PTR *PFNGLXQUERYCONTEXTPROC)(Display * dpy, GLXContext ctx, int attribute, int * value); +typedef void (GLAD_API_PTR *PFNGLXQUERYDRAWABLEPROC)(Display * dpy, GLXDrawable draw, int attribute, unsigned int * value); +typedef Bool (GLAD_API_PTR *PFNGLXQUERYEXTENSIONPROC)(Display * dpy, int * errorb, int * event); +typedef const char * (GLAD_API_PTR *PFNGLXQUERYEXTENSIONSSTRINGPROC)(Display * dpy, int screen); +typedef const char * (GLAD_API_PTR *PFNGLXQUERYSERVERSTRINGPROC)(Display * dpy, int screen, int name); +typedef Bool (GLAD_API_PTR *PFNGLXQUERYVERSIONPROC)(Display * dpy, int * maj, int * min); +typedef void (GLAD_API_PTR *PFNGLXSELECTEVENTPROC)(Display * dpy, GLXDrawable draw, unsigned long event_mask); +typedef void (GLAD_API_PTR *PFNGLXSWAPBUFFERSPROC)(Display * dpy, GLXDrawable drawable); +typedef void (GLAD_API_PTR *PFNGLXSWAPINTERVALEXTPROC)(Display * dpy, GLXDrawable drawable, int interval); +typedef int (GLAD_API_PTR *PFNGLXSWAPINTERVALMESAPROC)(unsigned int interval); +typedef int (GLAD_API_PTR *PFNGLXSWAPINTERVALSGIPROC)(int interval); +typedef void (GLAD_API_PTR *PFNGLXUSEXFONTPROC)(Font font, int first, int count, int list); +typedef void (GLAD_API_PTR *PFNGLXWAITGLPROC)(void); +typedef void (GLAD_API_PTR *PFNGLXWAITXPROC)(void); + +GLAD_API_CALL PFNGLXCHOOSEFBCONFIGPROC glad_glXChooseFBConfig; +#define glXChooseFBConfig glad_glXChooseFBConfig +GLAD_API_CALL PFNGLXCHOOSEVISUALPROC glad_glXChooseVisual; +#define glXChooseVisual glad_glXChooseVisual +GLAD_API_CALL PFNGLXCOPYCONTEXTPROC glad_glXCopyContext; +#define glXCopyContext glad_glXCopyContext +GLAD_API_CALL PFNGLXCREATECONTEXTPROC glad_glXCreateContext; +#define glXCreateContext glad_glXCreateContext +GLAD_API_CALL PFNGLXCREATECONTEXTATTRIBSARBPROC glad_glXCreateContextAttribsARB; +#define glXCreateContextAttribsARB glad_glXCreateContextAttribsARB +GLAD_API_CALL PFNGLXCREATEGLXPIXMAPPROC glad_glXCreateGLXPixmap; +#define glXCreateGLXPixmap glad_glXCreateGLXPixmap +GLAD_API_CALL PFNGLXCREATENEWCONTEXTPROC glad_glXCreateNewContext; +#define glXCreateNewContext glad_glXCreateNewContext +GLAD_API_CALL PFNGLXCREATEPBUFFERPROC glad_glXCreatePbuffer; +#define glXCreatePbuffer glad_glXCreatePbuffer +GLAD_API_CALL PFNGLXCREATEPIXMAPPROC glad_glXCreatePixmap; +#define glXCreatePixmap glad_glXCreatePixmap +GLAD_API_CALL PFNGLXCREATEWINDOWPROC glad_glXCreateWindow; +#define glXCreateWindow glad_glXCreateWindow +GLAD_API_CALL PFNGLXDESTROYCONTEXTPROC glad_glXDestroyContext; +#define glXDestroyContext glad_glXDestroyContext +GLAD_API_CALL PFNGLXDESTROYGLXPIXMAPPROC glad_glXDestroyGLXPixmap; +#define glXDestroyGLXPixmap glad_glXDestroyGLXPixmap +GLAD_API_CALL PFNGLXDESTROYPBUFFERPROC glad_glXDestroyPbuffer; +#define glXDestroyPbuffer glad_glXDestroyPbuffer +GLAD_API_CALL PFNGLXDESTROYPIXMAPPROC glad_glXDestroyPixmap; +#define glXDestroyPixmap glad_glXDestroyPixmap +GLAD_API_CALL PFNGLXDESTROYWINDOWPROC glad_glXDestroyWindow; +#define glXDestroyWindow glad_glXDestroyWindow +GLAD_API_CALL PFNGLXGETCLIENTSTRINGPROC glad_glXGetClientString; +#define glXGetClientString glad_glXGetClientString +GLAD_API_CALL PFNGLXGETCONFIGPROC glad_glXGetConfig; +#define glXGetConfig glad_glXGetConfig +GLAD_API_CALL PFNGLXGETCURRENTCONTEXTPROC glad_glXGetCurrentContext; +#define glXGetCurrentContext glad_glXGetCurrentContext +GLAD_API_CALL PFNGLXGETCURRENTDISPLAYPROC glad_glXGetCurrentDisplay; +#define glXGetCurrentDisplay glad_glXGetCurrentDisplay +GLAD_API_CALL PFNGLXGETCURRENTDRAWABLEPROC glad_glXGetCurrentDrawable; +#define glXGetCurrentDrawable glad_glXGetCurrentDrawable +GLAD_API_CALL PFNGLXGETCURRENTREADDRAWABLEPROC glad_glXGetCurrentReadDrawable; +#define glXGetCurrentReadDrawable glad_glXGetCurrentReadDrawable +GLAD_API_CALL PFNGLXGETFBCONFIGATTRIBPROC glad_glXGetFBConfigAttrib; +#define glXGetFBConfigAttrib glad_glXGetFBConfigAttrib +GLAD_API_CALL PFNGLXGETFBCONFIGSPROC glad_glXGetFBConfigs; +#define glXGetFBConfigs glad_glXGetFBConfigs +GLAD_API_CALL PFNGLXGETPROCADDRESSPROC glad_glXGetProcAddress; +#define glXGetProcAddress glad_glXGetProcAddress +GLAD_API_CALL PFNGLXGETPROCADDRESSARBPROC glad_glXGetProcAddressARB; +#define glXGetProcAddressARB glad_glXGetProcAddressARB +GLAD_API_CALL PFNGLXGETSELECTEDEVENTPROC glad_glXGetSelectedEvent; +#define glXGetSelectedEvent glad_glXGetSelectedEvent +GLAD_API_CALL PFNGLXGETSWAPINTERVALMESAPROC glad_glXGetSwapIntervalMESA; +#define glXGetSwapIntervalMESA glad_glXGetSwapIntervalMESA +GLAD_API_CALL PFNGLXGETVISUALFROMFBCONFIGPROC glad_glXGetVisualFromFBConfig; +#define glXGetVisualFromFBConfig glad_glXGetVisualFromFBConfig +GLAD_API_CALL PFNGLXISDIRECTPROC glad_glXIsDirect; +#define glXIsDirect glad_glXIsDirect +GLAD_API_CALL PFNGLXMAKECONTEXTCURRENTPROC glad_glXMakeContextCurrent; +#define glXMakeContextCurrent glad_glXMakeContextCurrent +GLAD_API_CALL PFNGLXMAKECURRENTPROC glad_glXMakeCurrent; +#define glXMakeCurrent glad_glXMakeCurrent +GLAD_API_CALL PFNGLXQUERYCONTEXTPROC glad_glXQueryContext; +#define glXQueryContext glad_glXQueryContext +GLAD_API_CALL PFNGLXQUERYDRAWABLEPROC glad_glXQueryDrawable; +#define glXQueryDrawable glad_glXQueryDrawable +GLAD_API_CALL PFNGLXQUERYEXTENSIONPROC glad_glXQueryExtension; +#define glXQueryExtension glad_glXQueryExtension +GLAD_API_CALL PFNGLXQUERYEXTENSIONSSTRINGPROC glad_glXQueryExtensionsString; +#define glXQueryExtensionsString glad_glXQueryExtensionsString +GLAD_API_CALL PFNGLXQUERYSERVERSTRINGPROC glad_glXQueryServerString; +#define glXQueryServerString glad_glXQueryServerString +GLAD_API_CALL PFNGLXQUERYVERSIONPROC glad_glXQueryVersion; +#define glXQueryVersion glad_glXQueryVersion +GLAD_API_CALL PFNGLXSELECTEVENTPROC glad_glXSelectEvent; +#define glXSelectEvent glad_glXSelectEvent +GLAD_API_CALL PFNGLXSWAPBUFFERSPROC glad_glXSwapBuffers; +#define glXSwapBuffers glad_glXSwapBuffers +GLAD_API_CALL PFNGLXSWAPINTERVALEXTPROC glad_glXSwapIntervalEXT; +#define glXSwapIntervalEXT glad_glXSwapIntervalEXT +GLAD_API_CALL PFNGLXSWAPINTERVALMESAPROC glad_glXSwapIntervalMESA; +#define glXSwapIntervalMESA glad_glXSwapIntervalMESA +GLAD_API_CALL PFNGLXSWAPINTERVALSGIPROC glad_glXSwapIntervalSGI; +#define glXSwapIntervalSGI glad_glXSwapIntervalSGI +GLAD_API_CALL PFNGLXUSEXFONTPROC glad_glXUseXFont; +#define glXUseXFont glad_glXUseXFont +GLAD_API_CALL PFNGLXWAITGLPROC glad_glXWaitGL; +#define glXWaitGL glad_glXWaitGL +GLAD_API_CALL PFNGLXWAITXPROC glad_glXWaitX; +#define glXWaitX glad_glXWaitX + + + + + +GLAD_API_CALL int gladLoadGLXUserPtr(Display *display, int screen, GLADuserptrloadfunc load, void *userptr); +GLAD_API_CALL int gladLoadGLX(Display *display, int screen, GLADloadfunc load); + +#ifdef GLAD_GLX + +GLAD_API_CALL int gladLoaderLoadGLX(Display *display, int screen); + +GLAD_API_CALL void gladLoaderUnloadGLX(void); + +#endif +#ifdef __cplusplus +} +#endif +#endif From bd38e9e98f97f8389aba2aad58da1bbe7f5c90ff Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Tue, 24 Dec 2019 21:31:08 +0100 Subject: [PATCH 05/58] Adding source/Platform/Unix/X11SharedDisplay.cpp --- engine.build.lua | 1 + source/Platform/Unix/X11SharedDisplay.cpp | 32 +++++++++++++++++++++++ source/Platform/Unix/X11SharedDisplay.h | 15 +++++++++++ 3 files changed, 48 insertions(+) create mode 100644 source/Platform/Unix/X11SharedDisplay.cpp create mode 100644 source/Platform/Unix/X11SharedDisplay.h diff --git a/engine.build.lua b/engine.build.lua index 24c1821..55ff80f 100644 --- a/engine.build.lua +++ b/engine.build.lua @@ -65,6 +65,7 @@ if TARGET_OS == "Win32" then elseif TARGET_OS == "Unix" then platform_spec_module = Module("source/Platform/Unix", { "UnixApplication.cpp", + "X11SharedDisplay.cpp", "X11Display.cpp", "GLXContext.cpp", "X11Input.cpp", diff --git a/source/Platform/Unix/X11SharedDisplay.cpp b/source/Platform/Unix/X11SharedDisplay.cpp new file mode 100644 index 0000000..bb76064 --- /dev/null +++ b/source/Platform/Unix/X11SharedDisplay.cpp @@ -0,0 +1,32 @@ + +#include "X11SharedDisplay.h" + +namespace sp { + +// Define a global display (for simplicity, we always connect to local one.) +::Display* sharedDisplay = NULL; +unsigned int refcount = 0; + +::Display* XGetDisplay() { + + // Create if we dont have any references. + if (refcount == 0) { + sharedDisplay = XOpenDisplay(NULL); + } + + refcount++; + return sharedDisplay; +} + +void XReleaseDisplay() { + + if (refcount < 1) { + return; + } + + if (--refcount == 0) { + XCloseDisplay(sharedDisplay); + } +} + +} // namespace sp diff --git a/source/Platform/Unix/X11SharedDisplay.h b/source/Platform/Unix/X11SharedDisplay.h new file mode 100644 index 0000000..91de116 --- /dev/null +++ b/source/Platform/Unix/X11SharedDisplay.h @@ -0,0 +1,15 @@ + +#ifndef SPECTRE_PLATFORM_UNIX_X11SHAREDDISPLAY_H +#define SPECTRE_PLATFORM_UNIX_X11SHAREDDISPLAY_H + +#include + +namespace sp { + +::Display* XGetDisplay(); + +void XReleaseDisplay(); + +} // namespace sp + +#endif /* SPECTRE_PLATFORM_UNIX_X11SHAREDDISPLAY_H */ From b65cb9c2d27a7d5edae45c6dcd25aa15a5b1dbd3 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Tue, 24 Dec 2019 21:32:05 +0100 Subject: [PATCH 06/58] source/Platform/Unix/X11Display.cpp: Initial implementation --- source/Platform/Unix/X11Display.cpp | 64 +++++++++++++++++++++++++---- source/Platform/Unix/X11Display.h | 13 ++++++ 2 files changed, 70 insertions(+), 7 deletions(-) diff --git a/source/Platform/Unix/X11Display.cpp b/source/Platform/Unix/X11Display.cpp index eb32495..92f2bfb 100644 --- a/source/Platform/Unix/X11Display.cpp +++ b/source/Platform/Unix/X11Display.cpp @@ -1,31 +1,81 @@ +#include // Prevents conflict with X.h defining "None" +#include +#include "X11SharedDisplay.h" +#include "GLXContext.h" #include "X11Display.h" namespace sp { +X11Display:: +X11Display() : +m_screen (0), +m_disp (NULL), +m_size (200,200) +{ +} + bool X11Display::create(DisplayDescription description) { + XSetWindowAttributes attr; + XVisualInfo* vi; + + m_disp = XGetDisplay(); + if (m_disp == NULL) { + Log::warn("X11: Could not open display"); + return false; + } + + m_screen = DefaultScreen(m_disp); + + attr.border_pixel = BlackPixel(m_disp, m_screen); + attr.background_pixel = WhitePixel(m_disp, m_screen); + //attr.override_redirect = True; + attr.colormap = ::XCreateColormap(m_disp, RootWindow(m_disp, m_screen), DefaultVisual(m_disp, m_screen), AllocNone); + attr.event_mask = ExposureMask; + + m_win = XCreateWindow(m_disp, + RootWindow(m_disp, m_screen), + 0, 0, + m_size.x, m_size.y, 0, DefaultDepth(m_disp, m_screen), + InputOutput, DefaultVisual(m_disp, m_screen), + CWBackPixel | CWColormap | CWBorderPixel | CWEventMask, &attr); + + + XMapWindow(m_disp, m_win); + + // Clear and take focus + XClearWindow(m_disp, m_win); + XMapRaised(m_disp, m_win); + + Log::info("X11: Created display"); + return true; } void X11Display::destroy() { - + if (m_disp) { + XReleaseDisplay(); + m_disp = NULL; + } } bool X11Display::isValid() { - return true; + return m_disp && m_win; } void* X11Display::getHandle() const { - return NULL; + return (void*) m_win; } void X11Display::setSize(unsigned int width, unsigned int height) { m_size = Vector2u(width, height); + + ::XResizeWindow(m_disp, m_win, m_size.x, m_size.y); } Vector2u X11Display::getSize() const @@ -35,22 +85,22 @@ Vector2u X11Display::getSize() const void X11Display::setPosition(unsigned int x, unsigned int y) { - + ::XMoveWindow(m_disp, m_win, x, y); } void X11Display::setCaption(const std::string& caption) { - + ::XStoreName(m_disp, m_win, caption.c_str()); } void X11Display::setIcon(const std::string& icon) { - + // TODO: Implement } void X11Display::showCursor(bool value) { - + // TODO: Implement } } // namespace sp diff --git a/source/Platform/Unix/X11Display.h b/source/Platform/Unix/X11Display.h index 5e1724d..28818b8 100644 --- a/source/Platform/Unix/X11Display.h +++ b/source/Platform/Unix/X11Display.h @@ -2,6 +2,10 @@ #ifndef PLATFORM_UNIX_X11DISPLAY_H #define PLATFORM_UNIX_X11DISPLAY_H +#include // Prevents conflict with X.h defining "None" +#include +#include +#include #include namespace sp { @@ -9,6 +13,7 @@ namespace sp { class X11Display : public PlatformDisplay { public : + X11Display(); virtual bool create(DisplayDescription description); @@ -32,6 +37,14 @@ public : protected : + ::Display* m_disp; + + ::Window m_win; + + int m_screen; + + //GC m_GC; + Vector2u m_size; }; From 7dedabba572614ffdd31a8d68c513d5f1e82e7cf Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Tue, 24 Dec 2019 21:32:38 +0100 Subject: [PATCH 07/58] source/Platform/Unix/GLXContext: Initial implementation --- source/Platform/Unix/GLXContext.cpp | 178 ++++++++++++++++++++++++++-- source/Platform/Unix/GLXContext.h | 12 ++ 2 files changed, 181 insertions(+), 9 deletions(-) diff --git a/source/Platform/Unix/GLXContext.cpp b/source/Platform/Unix/GLXContext.cpp index a488bdd..b00db35 100644 --- a/source/Platform/Unix/GLXContext.cpp +++ b/source/Platform/Unix/GLXContext.cpp @@ -1,51 +1,211 @@ +#include +#include +#include + +#include "glad_glx.h" +#include "X11SharedDisplay.h" #include "GLXContext.h" namespace sp { -GLXContext::GLXContext() -{ +static bool loadGL() { + static bool init = false; + if (!init) { + int ver; + init = true; + + ver = gladLoaderLoadGL(); + if (!ver) { + return false; + } + + Log::info("GLX: Opengl Version %d.%d loaded.", + GLAD_VERSION_MAJOR(ver), GLAD_VERSION_MINOR(ver)); + } + + return true; +} + +// Ensure that OpenGL extensions are loaded. +static bool ensureExtensionsLoaded(::Display* disp, int screen) +{ + char msg[1024]; + static bool init = false; + + if (!init) { + int ver; + init = true; + + ver = gladLoaderLoadGLX(disp, screen); + if (!ver) { + Log::warn("GLX: Could not load GLX extensions"); + return false; + } + + snprintf(msg, 1024, "GLX: GLX Version %d.%d loaded", + GLAD_VERSION_MAJOR(ver), GLAD_VERSION_MINOR(ver)); + + // Check for atleast version 1.4 + if (ver < 10004) { + Log::error("%s but atleast version 1.4 is needed.", msg); + return false; + } + + Log::info("%s.", msg); + } + + return true; +} + +GLXContext::GLXContext() : +m_disp (NULL), +m_win (0), +m_ctx (NULL) +{ } GLXContext::~GLXContext() { - + destroy(); } bool GLXContext::create(const PlatformDisplay* display) { + // Destroy any previous context first. + destroy(); + + m_disp = XGetDisplay(); + if (m_disp == NULL) { + destroy(); + Log::warn("X11: Could not open display"); + return false; + } + + m_win = (::Window) display->getHandle(); + + if (!createGLContext()) { + destroy(); + return false; + } + + return true; +} + +bool GLXContext::createGLContext() +{ + ::GLXFBConfig *fbc; + ::XVisualInfo *info; + int fbcount; + + GLint vi_attr[] = { + GLX_RGBA, + GLX_DEPTH_SIZE, 24, + GLX_DOUBLEBUFFER, 1, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + None + }; + + GLint ctx_attr[] = { + GLX_CONTEXT_MAJOR_VERSION_ARB, 3, + GLX_CONTEXT_MINOR_VERSION_ARB, 2, + GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, + None + }; + + // Ensure glx extensions are loaded. + if (!ensureExtensionsLoaded(m_disp, DefaultScreen(m_disp))) { + return false; + } + + info = ::glXChooseVisual(m_disp, DefaultScreen(m_disp), vi_attr); + if (info == NULL) { + Log::warn("GLX: Could not find a valid VisualInfo."); + return false; + } + + // Setup GL settings. + fbc = glXChooseFBConfig(m_disp, DefaultScreen(m_disp), (const int*) info->visual, &fbcount); + if (fbc == NULL) { + Log::warn("GLX: Could not find FB Config."); + return false; + } + + // Create context. + m_ctx = glXCreateContextAttribsARB(m_disp, fbc[0], NULL, GL_TRUE, ctx_attr); + if (m_ctx == NULL) { + Log::warn("GLX: Failed to create context."); + return false; + } + + glXMakeCurrent(m_disp, m_win, m_ctx); + + // Load OpenGL + if (!loadGL()) { + Log::warn("GLX: Could not load OpenGL"); + return false; + } + return true; } void GLXContext::destroy() { + if (m_ctx) { + ::glXDestroyContext(m_disp, m_ctx); + m_ctx = NULL; + } + if (m_disp) { + XReleaseDisplay(); + m_disp = NULL; + } + + m_win = None; } bool GLXContext::activate() { - return true; + if (m_win && m_ctx) { + return ::glXMakeCurrent(m_disp, m_win, m_ctx); + } + return false; } bool GLXContext::deactivate() { - return true; + return ::glXMakeCurrent(m_disp, None, NULL); } bool GLXContext::isActive() const { - return true; + return ::glXGetCurrentContext() == m_ctx; } bool GLXContext::setSwapInterval(int interval) { - return true; + ensureExtensionsLoaded(m_disp, DefaultScreen(m_disp)); + + if (GLAD_GLX_MESA_swap_control) { + return glXSwapIntervalMESA(interval); + } + + if (GLAD_GLX_SGI_swap_control) { + return glXSwapIntervalSGI(interval); + } + + return false; } void GLXContext::setSize(unsigned int width, unsigned int height) { - + // TODO: Not GLX specific! move to generic GLContext class. + if (activate()) { + glViewport(0, 0, width, height); + } } void GLXContext::setSize(const Vector2u size) @@ -55,7 +215,7 @@ void GLXContext::setSize(const Vector2u size) void GLXContext::swapBuffers() { - + glXSwapBuffers(m_disp, m_win); } } // namespace sp diff --git a/source/Platform/Unix/GLXContext.h b/source/Platform/Unix/GLXContext.h index 3a5dcbe..305d789 100644 --- a/source/Platform/Unix/GLXContext.h +++ b/source/Platform/Unix/GLXContext.h @@ -4,6 +4,7 @@ // X11 OpenGL Context (glx) +#include "glad_glx.h" #include namespace sp { @@ -32,6 +33,17 @@ public : void setSize(const Vector2u size); void swapBuffers(); + +private : + bool createGLContext(); + +private : + + ::Display* m_disp; + + ::Window m_win; + + ::GLXContext m_ctx; }; } // namespace sp From 5e27f820de7ddcb44dc2d6a417677ae8fbce3e3a Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Wed, 25 Dec 2019 22:39:10 +0100 Subject: [PATCH 08/58] source/Platform/Unix/X11Display.cpp: in create() set the attr.event_mask to include some interesting events. --- source/Platform/Unix/X11Display.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/Platform/Unix/X11Display.cpp b/source/Platform/Unix/X11Display.cpp index 92f2bfb..fc6f700 100644 --- a/source/Platform/Unix/X11Display.cpp +++ b/source/Platform/Unix/X11Display.cpp @@ -32,7 +32,10 @@ bool X11Display::create(DisplayDescription description) attr.background_pixel = WhitePixel(m_disp, m_screen); //attr.override_redirect = True; attr.colormap = ::XCreateColormap(m_disp, RootWindow(m_disp, m_screen), DefaultVisual(m_disp, m_screen), AllocNone); - attr.event_mask = ExposureMask; + // We want Keyboard,Mouse,Resize,Exposure (repaint) events. + attr.event_mask = KeyPressMask | KeyReleaseMask + | ButtonPressMask | ButtonReleaseMask | PointerMotionMask + | ResizeRedirectMask | ExposureMask; m_win = XCreateWindow(m_disp, RootWindow(m_disp, m_screen), From f8188c4358a0ceecc385e2bc3798b9300e7b9ff9 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Wed, 25 Dec 2019 22:40:00 +0100 Subject: [PATCH 09/58] source/Platform/Unix/UnixEventQueue.cpp: implement a poll method (only log events for now) --- source/Platform/Unix/X11EventQueue.cpp | 40 ++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/source/Platform/Unix/X11EventQueue.cpp b/source/Platform/Unix/X11EventQueue.cpp index d71faaa..0e81cbe 100644 --- a/source/Platform/Unix/X11EventQueue.cpp +++ b/source/Platform/Unix/X11EventQueue.cpp @@ -1,10 +1,50 @@ +#include #include "X11EventQueue.h" +#include "X11SharedDisplay.h" namespace sp { bool X11EventQueue::poll(Event& event) { + XEvent xevent; + int num_events; + ::Display* disp; + + disp = XGetDisplay(); + if (disp == NULL) { + return false; + } + + num_events = XEventsQueued(disp, QueuedAlready); + + for(int i = 0; i < num_events; i++) { + + XNextEvent(disp, &xevent); + + switch(xevent.type) { + case ResizeRequest: + Log::info("X11: Resize event"); + break; + case KeyPress: + case KeyRelease: + Log::info("X11: KeyEvent"); + break; + case ButtonPress: + case ButtonRelease: + Log::info("X11: MouseButtonEvent"); + break; + case MotionNotify: + // This generates alot of events :) + //Log::info("X11: MouseMotionEvent"); + break; + default: + Log::info("Unknown event"); + } + } + + XReleaseDisplay(); + return false; } From d94c7fcf9a5eb59e2116666fe2d3742c8e148ea6 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Thu, 26 Dec 2019 07:48:53 +0100 Subject: [PATCH 10/58] Platform/Unix/X11SharedDisplay: adding getAtom() --- source/Platform/Unix/X11SharedDisplay.cpp | 5 +++++ source/Platform/Unix/X11SharedDisplay.h | 3 +++ 2 files changed, 8 insertions(+) diff --git a/source/Platform/Unix/X11SharedDisplay.cpp b/source/Platform/Unix/X11SharedDisplay.cpp index bb76064..a7c691d 100644 --- a/source/Platform/Unix/X11SharedDisplay.cpp +++ b/source/Platform/Unix/X11SharedDisplay.cpp @@ -29,4 +29,9 @@ void XReleaseDisplay() { } } +Atom getAtom(const std::string& name, bool onlyIfExists) { + + return XInternAtom(sharedDisplay, name.c_str(), onlyIfExists); +} + } // namespace sp diff --git a/source/Platform/Unix/X11SharedDisplay.h b/source/Platform/Unix/X11SharedDisplay.h index 91de116..fed3a05 100644 --- a/source/Platform/Unix/X11SharedDisplay.h +++ b/source/Platform/Unix/X11SharedDisplay.h @@ -2,6 +2,7 @@ #ifndef SPECTRE_PLATFORM_UNIX_X11SHAREDDISPLAY_H #define SPECTRE_PLATFORM_UNIX_X11SHAREDDISPLAY_H +#include #include namespace sp { @@ -10,6 +11,8 @@ namespace sp { void XReleaseDisplay(); +Atom getAtom(const std::string& name, bool onlyIfExists = false); + } // namespace sp #endif /* SPECTRE_PLATFORM_UNIX_X11SHAREDDISPLAY_H */ From 46bf27f4a4b17c77a4c50906812db098fa4db1e0 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Fri, 27 Dec 2019 22:21:46 +0100 Subject: [PATCH 11/58] source/Platform/Unix/X11Display.cpp: call XSetWMProtocols with "WM_DELETE_WINDOW" flag. --- source/Platform/Unix/X11Display.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/Platform/Unix/X11Display.cpp b/source/Platform/Unix/X11Display.cpp index fc6f700..1c825f6 100644 --- a/source/Platform/Unix/X11Display.cpp +++ b/source/Platform/Unix/X11Display.cpp @@ -19,6 +19,7 @@ bool X11Display::create(DisplayDescription description) { XSetWindowAttributes attr; XVisualInfo* vi; + Atom protocols; m_disp = XGetDisplay(); if (m_disp == NULL) { @@ -44,6 +45,11 @@ bool X11Display::create(DisplayDescription description) InputOutput, DefaultVisual(m_disp, m_screen), CWBackPixel | CWColormap | CWBorderPixel | CWEventMask, &attr); + // X11 does not handle pressing the X button on a window. + // that is the job of the window manager. + // Here we can request the WM to send us a delete event so we can handle it ourself. + protocols = getAtom("WM_DELETE_WINDOW"); + XSetWMProtocols(m_disp, m_win, &protocols, 1); XMapWindow(m_disp, m_win); From 035dd333dad4e35d896c0c16a9854cf1a713e788 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Fri, 27 Dec 2019 22:23:00 +0100 Subject: [PATCH 12/58] source/Platform/Unix/X11EventQueue.cpp: log "WM_DESTROY_WINDOW" message. --- source/Platform/Unix/X11EventQueue.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/source/Platform/Unix/X11EventQueue.cpp b/source/Platform/Unix/X11EventQueue.cpp index 0e81cbe..ded3920 100644 --- a/source/Platform/Unix/X11EventQueue.cpp +++ b/source/Platform/Unix/X11EventQueue.cpp @@ -10,6 +10,8 @@ bool X11EventQueue::poll(Event& event) XEvent xevent; int num_events; ::Display* disp; + Atom del_win = getAtom("WM_DELETE_WINDOW"); + Atom wm_proto = getAtom("WM_PROTOCOLS"); disp = XGetDisplay(); if (disp == NULL) { @@ -23,6 +25,15 @@ bool X11EventQueue::poll(Event& event) XNextEvent(disp, &xevent); switch(xevent.type) { + case ClientMessage: + Log::info("X11: ClientMessage"); + + if (xevent.xclient.message_type == wm_proto + && xevent.xclient.data.l[0] == del_win) { + + Log::info("X11: Delete window"); + } + break; case ResizeRequest: Log::info("X11: Resize event"); break; From 9b5bd9dcd07279d545068d93c226054bce37b370 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sat, 28 Dec 2019 21:19:30 +0100 Subject: [PATCH 13/58] source/Platform/Unix/X11EventQueue.cpp: post quit event on "WM_DELETE_WINDOW". --- source/Platform/Unix/X11EventQueue.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/Platform/Unix/X11EventQueue.cpp b/source/Platform/Unix/X11EventQueue.cpp index ded3920..63b2aae 100644 --- a/source/Platform/Unix/X11EventQueue.cpp +++ b/source/Platform/Unix/X11EventQueue.cpp @@ -31,7 +31,8 @@ bool X11EventQueue::poll(Event& event) if (xevent.xclient.message_type == wm_proto && xevent.xclient.data.l[0] == del_win) { - Log::info("X11: Delete window"); + event.type = Event::Quit; + return true; } break; case ResizeRequest: From 96b61f0ee39eecbb91670ab5b7504b80fd80b8ec Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Mon, 30 Dec 2019 05:06:32 +0100 Subject: [PATCH 14/58] source/Platform/Unix/X11Display.cpp: in create() call setSize() --- source/Platform/Unix/X11Display.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/Platform/Unix/X11Display.cpp b/source/Platform/Unix/X11Display.cpp index 1c825f6..7e57b76 100644 --- a/source/Platform/Unix/X11Display.cpp +++ b/source/Platform/Unix/X11Display.cpp @@ -53,6 +53,8 @@ bool X11Display::create(DisplayDescription description) XMapWindow(m_disp, m_win); + setSize(description.mode.width, description.mode.height); + // Clear and take focus XClearWindow(m_disp, m_win); XMapRaised(m_disp, m_win); From f07be50bd358dc972308527a902c4136e6e8155f Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Mon, 30 Dec 2019 05:30:31 +0100 Subject: [PATCH 15/58] source/Platform/Unix/X11Display.cpp: Replace ResizeRedirectMask with StructureNotifyMask ResizeRedirectMask is broken (will not update the window size). We use StrucutreNotifyMask instead and capture the window size from CaptureNotify event instead. --- source/Platform/Unix/X11Display.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Platform/Unix/X11Display.cpp b/source/Platform/Unix/X11Display.cpp index 7e57b76..a98ccd3 100644 --- a/source/Platform/Unix/X11Display.cpp +++ b/source/Platform/Unix/X11Display.cpp @@ -36,7 +36,7 @@ bool X11Display::create(DisplayDescription description) // We want Keyboard,Mouse,Resize,Exposure (repaint) events. attr.event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask - | ResizeRedirectMask | ExposureMask; + | StructureNotifyMask | ExposureMask; m_win = XCreateWindow(m_disp, RootWindow(m_disp, m_screen), From 7a694e8fd0b8b3fc0b5171d5502b543b3e1e56da Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Mon, 30 Dec 2019 05:32:31 +0100 Subject: [PATCH 16/58] Platform/Unix/X11Display: Adding processEvent() to handle resize. --- source/Platform/Unix/X11Display.cpp | 18 ++++++++++++++++++ source/Platform/Unix/X11Display.h | 2 ++ 2 files changed, 20 insertions(+) diff --git a/source/Platform/Unix/X11Display.cpp b/source/Platform/Unix/X11Display.cpp index a98ccd3..217c21c 100644 --- a/source/Platform/Unix/X11Display.cpp +++ b/source/Platform/Unix/X11Display.cpp @@ -114,4 +114,22 @@ void X11Display::showCursor(bool value) // TODO: Implement } +void X11Display::processEvent(const ::XEvent& event) +{ + Vector2u size; + + switch(event.xany.type) { + case ConfigureNotify: + size.x = event.xconfigure.width; + size.y = event.xconfigure.height; + + if (m_size != size) { + m_size = size; + Log::info("X11: Resize event"); + onReshape(size.x, size.y); + } + break; + } +} + } // namespace sp diff --git a/source/Platform/Unix/X11Display.h b/source/Platform/Unix/X11Display.h index 28818b8..330ffba 100644 --- a/source/Platform/Unix/X11Display.h +++ b/source/Platform/Unix/X11Display.h @@ -35,6 +35,8 @@ public : virtual void showCursor(bool value); + void processEvent(const ::XEvent& event); + protected : ::Display* m_disp; From 7402896ce69e03d0218d7803f3f5c851b66207bb Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Mon, 30 Dec 2019 05:33:14 +0100 Subject: [PATCH 17/58] Adding Platform/Unix/X11WindowEventHandler --- engine.build.lua | 1 + .../Platform/Unix/X11WindowEventHandler.cpp | 52 +++++++++++++++++++ source/Platform/Unix/X11WindowEventHandler.h | 29 +++++++++++ 3 files changed, 82 insertions(+) create mode 100644 source/Platform/Unix/X11WindowEventHandler.cpp create mode 100644 source/Platform/Unix/X11WindowEventHandler.h diff --git a/engine.build.lua b/engine.build.lua index 55ff80f..831d539 100644 --- a/engine.build.lua +++ b/engine.build.lua @@ -72,6 +72,7 @@ elseif TARGET_OS == "Unix" then "X11Keyboard.cpp", "X11Mouse.cpp", "X11EventQueue.cpp", + "X11WindowEventHandler.cpp", "UnixMisc.cpp", "UnixSystem.cpp", "glad_glx.c" diff --git a/source/Platform/Unix/X11WindowEventHandler.cpp b/source/Platform/Unix/X11WindowEventHandler.cpp new file mode 100644 index 0000000..a4ec542 --- /dev/null +++ b/source/Platform/Unix/X11WindowEventHandler.cpp @@ -0,0 +1,52 @@ + +#include +#include "X11Display.h" +#include "X11SharedDisplay.h" +#include "X11WindowEventHandler.h" +#include + +namespace sp { + +// Context used to store X11Display pointer. +::XContext X11WindowEventHandler::win_context = None; + +void X11WindowEventHandler::registerHandler(::Display* disp, ::Window window, X11Display *ptr) +{ + // Initialize context before use. + if (win_context == None) { + win_context = XUniqueContext(); + } + + // Save pointer to window. + XSaveContext(disp, window, win_context, (XPointer) ptr); +} + +void X11WindowEventHandler::unregisterHandler(::Display* disp, ::Window window) +{ + // No context. nothing to do. + if (win_context == None) { + return; + } + + XDeleteContext(disp, window, win_context); +} + +void X11WindowEventHandler::process(::Display* disp, const ::XEvent& event) +{ + XPointer ptr; + + // No context. nothing to do. + if (win_context == None) { + return; + } + + // Get the pointer for window ID. + if (XFindContext(disp, event.xany.window, win_context, &ptr) == 0) { + X11Display* disp_ptr = (X11Display*) ptr; + + // Delegate + disp_ptr->processEvent(event); + } +} + +} // namespace sp diff --git a/source/Platform/Unix/X11WindowEventHandler.h b/source/Platform/Unix/X11WindowEventHandler.h new file mode 100644 index 0000000..79f6ed2 --- /dev/null +++ b/source/Platform/Unix/X11WindowEventHandler.h @@ -0,0 +1,29 @@ + +#ifndef PLATFORM_UNIX_X11_WINDOW_EVENT_HANDLER_H +#define PLATFORM_UNIX_X11_WINDOW_EVENT_HANDLER_H + +#include +#include + +namespace sp { + +class X11Display; + +class X11WindowEventHandler +{ +public: + + static void registerHandler(::Display* disp, ::Window window, X11Display *ptr); + + static void unregisterHandler(::Display* disp, ::Window window); + + static void process(::Display* disp, const ::XEvent& event); + +protected : + + static ::XContext win_context; +}; + +} // namespace sp + +#endif /* PLATFORM_UNIX_WINDOW_EVENT_HANDLER_H */ From 2b14977eeda7f835aaf1c75ea8ccee9e97defb81 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Mon, 30 Dec 2019 05:34:01 +0100 Subject: [PATCH 18/58] source/Platform/Unix/X11Display.cpp: register with X11WindowEventHandler --- source/Platform/Unix/X11Display.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source/Platform/Unix/X11Display.cpp b/source/Platform/Unix/X11Display.cpp index 217c21c..21308a1 100644 --- a/source/Platform/Unix/X11Display.cpp +++ b/source/Platform/Unix/X11Display.cpp @@ -1,6 +1,7 @@ #include // Prevents conflict with X.h defining "None" #include +#include "X11WindowEventHandler.h" #include "X11SharedDisplay.h" #include "GLXContext.h" #include "X11Display.h" @@ -45,6 +46,9 @@ bool X11Display::create(DisplayDescription description) InputOutput, DefaultVisual(m_disp, m_screen), CWBackPixel | CWColormap | CWBorderPixel | CWEventMask, &attr); + // Register event handler + X11WindowEventHandler::registerHandler(m_disp, m_win, this); + // X11 does not handle pressing the X button on a window. // that is the job of the window manager. // Here we can request the WM to send us a delete event so we can handle it ourself. @@ -66,6 +70,10 @@ bool X11Display::create(DisplayDescription description) void X11Display::destroy() { + if (m_win) { + X11WindowEventHandler::unregisterHandler(m_disp, m_win); + } + if (m_disp) { XReleaseDisplay(); m_disp = NULL; From c5648a51054ac4d81d243df739b0e53fd76bce21 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Mon, 30 Dec 2019 05:34:50 +0100 Subject: [PATCH 19/58] Platform/Unix/X11EventQueue: redirect unkown events to X11WindowEventHandler. --- source/Platform/Unix/X11EventQueue.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/Platform/Unix/X11EventQueue.cpp b/source/Platform/Unix/X11EventQueue.cpp index 63b2aae..be51bac 100644 --- a/source/Platform/Unix/X11EventQueue.cpp +++ b/source/Platform/Unix/X11EventQueue.cpp @@ -2,6 +2,7 @@ #include #include "X11EventQueue.h" #include "X11SharedDisplay.h" +#include "X11WindowEventHandler.h" namespace sp { @@ -51,7 +52,8 @@ bool X11EventQueue::poll(Event& event) //Log::info("X11: MouseMotionEvent"); break; default: - Log::info("Unknown event"); + // Pass to window. + X11WindowEventHandler::process(disp, xevent); } } From 7648c23e438b290bab90c7ce39ad731789a8b450 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Fri, 25 Sep 2020 18:17:36 +0200 Subject: [PATCH 20/58] Platform/Unix/X11EventQueue: get and release display handle in constructor/destructor instead of every call to poll() Should be fine as the display should never change during runtime. --- source/Platform/Unix/X11EventQueue.cpp | 24 ++++++++++++++++-------- source/Platform/Unix/X11EventQueue.h | 7 +++++++ 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/source/Platform/Unix/X11EventQueue.cpp b/source/Platform/Unix/X11EventQueue.cpp index be51bac..6a4e73f 100644 --- a/source/Platform/Unix/X11EventQueue.cpp +++ b/source/Platform/Unix/X11EventQueue.cpp @@ -6,24 +6,34 @@ namespace sp { +X11EventQueue::X11EventQueue() +{ + m_disp = XGetDisplay(); +} + +X11EventQueue::~X11EventQueue() +{ + if (m_disp) { + XReleaseDisplay(); + } +} + bool X11EventQueue::poll(Event& event) { XEvent xevent; int num_events; - ::Display* disp; Atom del_win = getAtom("WM_DELETE_WINDOW"); Atom wm_proto = getAtom("WM_PROTOCOLS"); - disp = XGetDisplay(); - if (disp == NULL) { + if (m_disp == NULL) { return false; } - num_events = XEventsQueued(disp, QueuedAlready); + num_events = XEventsQueued(m_disp, QueuedAlready); for(int i = 0; i < num_events; i++) { - XNextEvent(disp, &xevent); + XNextEvent(m_disp, &xevent); switch(xevent.type) { case ClientMessage: @@ -53,12 +63,10 @@ bool X11EventQueue::poll(Event& event) break; default: // Pass to window. - X11WindowEventHandler::process(disp, xevent); + X11WindowEventHandler::process(m_disp, xevent); } } - XReleaseDisplay(); - return false; } diff --git a/source/Platform/Unix/X11EventQueue.h b/source/Platform/Unix/X11EventQueue.h index 9239694..73b363f 100644 --- a/source/Platform/Unix/X11EventQueue.h +++ b/source/Platform/Unix/X11EventQueue.h @@ -4,13 +4,20 @@ #include #include +#include namespace sp { class X11EventQueue : public PlatformEventQueue { public : + X11EventQueue(); + virtual ~X11EventQueue(); + virtual bool poll(Event& event); + +private : + ::Display* m_disp; }; } // namespace sp From 23cf17f9af177f34bdacfc855251b12b10c7c3ac Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Fri, 25 Sep 2020 18:24:12 +0200 Subject: [PATCH 21/58] Platform/Unix/X11EventQueue.cpp: Only process one event per call to poll(). Confirming to Platform API. --- source/Platform/Unix/X11EventQueue.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/source/Platform/Unix/X11EventQueue.cpp b/source/Platform/Unix/X11EventQueue.cpp index 6a4e73f..a552643 100644 --- a/source/Platform/Unix/X11EventQueue.cpp +++ b/source/Platform/Unix/X11EventQueue.cpp @@ -20,8 +20,6 @@ X11EventQueue::~X11EventQueue() bool X11EventQueue::poll(Event& event) { - XEvent xevent; - int num_events; Atom del_win = getAtom("WM_DELETE_WINDOW"); Atom wm_proto = getAtom("WM_PROTOCOLS"); @@ -29,9 +27,8 @@ bool X11EventQueue::poll(Event& event) return false; } - num_events = XEventsQueued(m_disp, QueuedAlready); - - for(int i = 0; i < num_events; i++) { + if (XEventsQueued(m_disp, QueuedAlready)) { + XEvent xevent; XNextEvent(m_disp, &xevent); From 30dc11f0d5e0277451393edb3e1a8cf4c2518bf0 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Fri, 25 Sep 2020 18:24:49 +0200 Subject: [PATCH 22/58] Platform/Unix/X11Display.h: Some documentation. --- source/Platform/Unix/X11Display.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/Platform/Unix/X11Display.h b/source/Platform/Unix/X11Display.h index 330ffba..9343705 100644 --- a/source/Platform/Unix/X11Display.h +++ b/source/Platform/Unix/X11Display.h @@ -10,6 +10,8 @@ namespace sp { +// NOTE: This class wraps a X11 Window and Screen handle +// and is NOT a Class wrapper around X11's `Display` type. class X11Display : public PlatformDisplay { public : From 9954c45fe98ab9fc7a2b33ce87b0060e9f56ee2e Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Tue, 13 Oct 2020 18:12:59 +0200 Subject: [PATCH 23/58] Platform/Unix/X11Keyboard: Implement handleMessage() --- source/Platform/Unix/X11Keyboard.cpp | 212 ++++++++++++++++++++++++++- source/Platform/Unix/X11Keyboard.h | 6 +- 2 files changed, 216 insertions(+), 2 deletions(-) diff --git a/source/Platform/Unix/X11Keyboard.cpp b/source/Platform/Unix/X11Keyboard.cpp index adc7e08..e2184ad 100644 --- a/source/Platform/Unix/X11Keyboard.cpp +++ b/source/Platform/Unix/X11Keyboard.cpp @@ -1,7 +1,204 @@ + #include "X11Keyboard.h" +#include +#include +#include namespace sp { +static Keyboard::Key KeySymToKeyboardKey(KeySym key) { + + switch(key) { + // Letters + case XK_A: case XK_a: + return Keyboard::Key::A; + case XK_B: case XK_b: + return Keyboard::Key::B; + case XK_C: case XK_c: + return Keyboard::Key::C; + case XK_D: case XK_d: + return Keyboard::Key::D; + case XK_E: case XK_e: + return Keyboard::Key::E; + case XK_F: case XK_f: + return Keyboard::Key::F; + case XK_G: case XK_g: + return Keyboard::Key::G; + case XK_H: case XK_h: + return Keyboard::Key::H; + case XK_I: case XK_i: + return Keyboard::Key::I; + case XK_J: case XK_j: + return Keyboard::Key::J; + case XK_K: case XK_k: + return Keyboard::Key::K; + case XK_L: case XK_l: + return Keyboard::Key::L; + case XK_M: case XK_m: + return Keyboard::Key::M; + case XK_N: case XK_n: + return Keyboard::Key::N; + case XK_O: case XK_o: + return Keyboard::Key::O; + case XK_P: case XK_p: + return Keyboard::Key::P; + case XK_Q: case XK_q: + return Keyboard::Key::Q; + case XK_R: case XK_r: + return Keyboard::Key::R; + case XK_S: case XK_s: + return Keyboard::Key::S; + case XK_T: case XK_t: + return Keyboard::Key::T; + case XK_U: case XK_u: + return Keyboard::Key::U; + case XK_V: case XK_v: + return Keyboard::Key::V; + case XK_W: case XK_w: + return Keyboard::Key::W; + case XK_X: case XK_x: + return Keyboard::Key::X; + case XK_Y: case XK_y: + return Keyboard::Key::Y; + case XK_Z: case XK_z: + return Keyboard::Key::Z; + + // Numbers + case XK_1: + return Keyboard::Key::One; + case XK_2: + return Keyboard::Key::Two; + case XK_3: + return Keyboard::Key::Three; + case XK_4: + return Keyboard::Key::Four; + case XK_5: + return Keyboard::Key::Five; + case XK_6: + return Keyboard::Key::Six; + case XK_7: + return Keyboard::Key::Seven; + case XK_8: + return Keyboard::Key::Eight; + case XK_9: + return Keyboard::Key::Nine; + case XK_0: + return Keyboard::Key::Zero; + + case XK_period : + return Keyboard::Key::Period; + case XK_comma : + return Keyboard::Key::Comma; + case XK_Return : + return Keyboard::Key::Enter; + case XK_BackSpace : + return Keyboard::Key::Backspace; + case XK_Escape : + return Keyboard::Key::Escape; + case XK_space : + return Keyboard::Key::Space; + case XK_Caps_Lock : + return Keyboard::Key::Capslock; + + // Arrows + case XK_Up : + return Keyboard::Key::Up; + case XK_Down : + return Keyboard::Key::Down; + case XK_Left : + return Keyboard::Key::Left; + case XK_Right : + return Keyboard::Key::Right; + + // Numpad + + case XK_KP_1 : case XK_KP_End : + return Keyboard::Key::Numpad1; + case XK_KP_2 : case XK_KP_Down : + return Keyboard::Key::Numpad2; + case XK_KP_3 : case XK_KP_Page_Down : + return Keyboard::Key::Numpad3; + case XK_KP_4 : case XK_KP_Left : + return Keyboard::Key::Numpad4; + case XK_KP_5 : case XK_KP_Begin : + return Keyboard::Key::Numpad5; + case XK_KP_6 : case XK_KP_Right : + return Keyboard::Key::Numpad6; + case XK_KP_7 : case XK_KP_Home : + return Keyboard::Key::Numpad7; + case XK_KP_8 : case XK_KP_Up : + return Keyboard::Key::Numpad8; + case XK_KP_9 : case XK_KP_Page_Up : + return Keyboard::Key::Numpad9; + case XK_KP_0 : case XK_KP_Insert : + return Keyboard::Key::Numpad0; + + case XK_Home : + return Keyboard::Key::Home; + case XK_End : + return Keyboard::Key::End; + case XK_Insert : + return Keyboard::Key::Insert; + case XK_Delete : + return Keyboard::Key::Delete; + case XK_Page_Up : + return Keyboard::Key::PageUp; + case XK_Page_Down : + return Keyboard::Key::PageDown; + case XK_Pause : + return Keyboard::Key::Pause; + + + // Function keys + case XK_F1 : + return Keyboard::Key::F1; + case XK_F2 : + return Keyboard::Key::F2; + case XK_F3 : + return Keyboard::Key::F3; + case XK_F4 : + return Keyboard::Key::F4; + case XK_F5 : + return Keyboard::Key::F5; + case XK_F6 : + return Keyboard::Key::F6; + case XK_F7 : + return Keyboard::Key::F7; + case XK_F8 : + return Keyboard::Key::F8; + case XK_F9 : + return Keyboard::Key::F9; + case XK_F10 : + return Keyboard::Key::F10; + case XK_F11 : + return Keyboard::Key::F11; + case XK_F12 : + return Keyboard::Key::F12; + + case XK_Tab : + return Keyboard::Key::Tab; + case XK_Shift_L : + return Keyboard::Key::LShift; + case XK_Shift_R : + return Keyboard::Key::RShift; + case XK_Control_L : + return Keyboard::Key::LCtrl; + case XK_Control_R : + return Keyboard::Key::RCtrl; + case XK_Alt_L : + return Keyboard::Key::LAlt; + case XK_Alt_R : +#ifdef XK_XKB_KEYS + case XK_ISO_Level3_Shift : +#endif /* XK_XKB_KEYS */ + return Keyboard::Key::RAlt; + + default: + sp::Log::debug("X11Keyboard - Unknown keycode: 0x%X", key); + return Keyboard::Key::Unknown; + }; +} + void X11Keyboard::init() { @@ -12,9 +209,22 @@ bool X11Keyboard::isKeyDown(Keyboard::Key key) return false; } +bool X11Keyboard::handleMessage(XKeyEvent* xkeyevent, Event& event) +{ + KeySym sym = ::XLookupKeysym(xkeyevent, 0); + Keyboard::Key code = KeySymToKeyboardKey(sym); + + if (code != Keyboard::Key::Unknown) { + event.type = Event::Key; + event.key.code = code; + event.key.pressed = xkeyevent->type == KeyPress; + return true; + } + return false; +} + void X11Keyboard::update(InputModule *input) { - } } // namespace sp diff --git a/source/Platform/Unix/X11Keyboard.h b/source/Platform/Unix/X11Keyboard.h index 7f7485c..c0cda41 100644 --- a/source/Platform/Unix/X11Keyboard.h +++ b/source/Platform/Unix/X11Keyboard.h @@ -2,8 +2,9 @@ #ifndef PLATFORM_UNIX_X11KEYBOARD_H #define PLATFORM_UNIX_X11KEYBOARD_H +#include #include - +#include namespace sp { class X11Keyboard : public Keyboard @@ -15,6 +16,9 @@ public : bool isKeyDown(Keyboard::Key key); + // Translate a XKeyEvent to sp::Event, Called from X11EventQueue + static bool handleMessage(XKeyEvent* xkeyevent, Event& event); + protected : virtual void update(InputModule *input); From 4193b3b7196007c55c696e00dca65120bacc96e1 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Tue, 13 Oct 2020 18:14:10 +0200 Subject: [PATCH 24/58] Platform/Unix/X11EventQueue: send KeyPress and KeyRelease events to X11Keyboard::handleMessage() --- source/Platform/Unix/X11EventQueue.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/Platform/Unix/X11EventQueue.cpp b/source/Platform/Unix/X11EventQueue.cpp index a552643..06438e4 100644 --- a/source/Platform/Unix/X11EventQueue.cpp +++ b/source/Platform/Unix/X11EventQueue.cpp @@ -2,6 +2,7 @@ #include #include "X11EventQueue.h" #include "X11SharedDisplay.h" +#include "X11Keyboard.h" #include "X11WindowEventHandler.h" namespace sp { @@ -48,7 +49,9 @@ bool X11EventQueue::poll(Event& event) break; case KeyPress: case KeyRelease: - Log::info("X11: KeyEvent"); + if (X11Keyboard::handleMessage(&xevent.xkey, event)) { + return true; + } break; case ButtonPress: case ButtonRelease: From 7356bdebdda2894758f1171d4775a6cccd0cca16 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Wed, 14 Oct 2020 13:18:18 +0200 Subject: [PATCH 25/58] Platform/Unix/X11EventQueue: Fix bug where messeges where not flushed to the event queue. XEventsQueued(disp, QueuedAlready) only returns the number of events currently in the queue and does not flush new events. So this must happen elsewhere and if it does not we will never see any events. i noticed this bug when removing the call to glXSwapBuffers(). Fix this by using XPending() instead as this flushes new events if the queue is empty before returning the length. see https://tronche.com/gui/x/xlib/event-handling/XEventsQueued.html and https://tronche.com/gui/x/xlib/event-handling/XPending.html --- source/Platform/Unix/X11EventQueue.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/Platform/Unix/X11EventQueue.cpp b/source/Platform/Unix/X11EventQueue.cpp index 06438e4..19f4177 100644 --- a/source/Platform/Unix/X11EventQueue.cpp +++ b/source/Platform/Unix/X11EventQueue.cpp @@ -28,7 +28,7 @@ bool X11EventQueue::poll(Event& event) return false; } - if (XEventsQueued(m_disp, QueuedAlready)) { + if (XPending(m_disp)) { XEvent xevent; XNextEvent(m_disp, &xevent); @@ -63,6 +63,7 @@ bool X11EventQueue::poll(Event& event) break; default: // Pass to window. + Log::info("X11: Window Event"); X11WindowEventHandler::process(m_disp, xevent); } } From cfe064f02cb7a78e01278d1134d6967b42268da8 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Fri, 16 Oct 2020 14:41:41 +0200 Subject: [PATCH 26/58] Platform/Unix/X11Keyboard: implement isKeyDown() --- source/Platform/Unix/X11Keyboard.cpp | 129 ++++++++++++++++++++++++++- source/Platform/Unix/X11Keyboard.h | 10 ++- 2 files changed, 137 insertions(+), 2 deletions(-) diff --git a/source/Platform/Unix/X11Keyboard.cpp b/source/Platform/Unix/X11Keyboard.cpp index e2184ad..9121ebe 100644 --- a/source/Platform/Unix/X11Keyboard.cpp +++ b/source/Platform/Unix/X11Keyboard.cpp @@ -1,5 +1,7 @@ +#include #include "X11Keyboard.h" +#include "X11SharedDisplay.h" #include #include #include @@ -199,13 +201,136 @@ static Keyboard::Key KeySymToKeyboardKey(KeySym key) { }; } +X11Keyboard::X11Keyboard() : +m_disp(NULL) +{ + memset(m_key_state, 0, sizeof(m_key_state) / sizeof(m_key_state[0])); +} + +X11Keyboard::~X11Keyboard() +{ + if (m_disp) { + XReleaseDisplay(); + } +} + void X11Keyboard::init() { - + m_disp = XGetDisplay(); } bool X11Keyboard::isKeyDown(Keyboard::Key key) { + KeySym sym; + + switch(key) { + // Letters + case Keyboard::Key::A : sym = XK_a; break; + case Keyboard::Key::B : sym = XK_b; break; + case Keyboard::Key::C : sym = XK_c; break; + case Keyboard::Key::D : sym = XK_d; break; + case Keyboard::Key::E : sym = XK_e; break; + case Keyboard::Key::F : sym = XK_f; break; + case Keyboard::Key::G : sym = XK_g; break; + case Keyboard::Key::H : sym = XK_h; break; + case Keyboard::Key::I : sym = XK_i; break; + case Keyboard::Key::J : sym = XK_j; break; + case Keyboard::Key::K : sym = XK_k; break; + case Keyboard::Key::L : sym = XK_l; break; + case Keyboard::Key::M : sym = XK_m; break; + case Keyboard::Key::N : sym = XK_n; break; + case Keyboard::Key::O : sym = XK_o; break; + case Keyboard::Key::P : sym = XK_p; break; + case Keyboard::Key::Q : sym = XK_q; break; + case Keyboard::Key::R : sym = XK_r; break; + case Keyboard::Key::S : sym = XK_s; break; + case Keyboard::Key::T : sym = XK_t; break; + case Keyboard::Key::U : sym = XK_u; break; + case Keyboard::Key::V : sym = XK_v; break; + case Keyboard::Key::W : sym = XK_w; break; + case Keyboard::Key::X : sym = XK_x; break; + case Keyboard::Key::Y : sym = XK_y; break; + case Keyboard::Key::Z : sym = XK_z; break; + + // Numbers + case Keyboard::Key::One : sym = XK_1; break; + case Keyboard::Key::Two : sym = XK_2; break; + case Keyboard::Key::Three : sym = XK_3; break; + case Keyboard::Key::Four : sym = XK_4; break; + case Keyboard::Key::Five : sym = XK_5; break; + case Keyboard::Key::Six : sym = XK_6; break; + case Keyboard::Key::Seven : sym = XK_7; break; + case Keyboard::Key::Eight : sym = XK_8; break; + case Keyboard::Key::Nine : sym = XK_9; break; + case Keyboard::Key::Zero : sym = XK_0; break; + + case Keyboard::Key::Period : sym = XK_period; break; + case Keyboard::Key::Comma : sym = XK_comma; break; + case Keyboard::Key::Enter : sym = XK_Return; break; + case Keyboard::Key::Backspace : sym = XK_BackSpace; break; + case Keyboard::Key::Escape : sym = XK_Escape; break; + case Keyboard::Key::Space : sym = XK_space; break; + case Keyboard::Key::Capslock : sym = XK_Caps_Lock; break; + + // Arrows + case Keyboard::Key::Up : sym = XK_Up; break; + case Keyboard::Key::Down : sym = XK_Down; break; + case Keyboard::Key::Left : sym = XK_Left; break; + case Keyboard::Key::Right : sym = XK_Right; break; + + // Numpad + case Keyboard::Key::Numpad1 : sym = XK_KP_1; break; + case Keyboard::Key::Numpad2 : sym = XK_KP_2; break; + case Keyboard::Key::Numpad3 : sym = XK_KP_3; break; + case Keyboard::Key::Numpad4 : sym = XK_KP_4; break; + case Keyboard::Key::Numpad5 : sym = XK_KP_5; break; + case Keyboard::Key::Numpad6 : sym = XK_KP_6; break; + case Keyboard::Key::Numpad7 : sym = XK_KP_7; break; + case Keyboard::Key::Numpad8 : sym = XK_KP_8; break; + case Keyboard::Key::Numpad9 : sym = XK_KP_9; break; + case Keyboard::Key::Numpad0 : sym = XK_KP_0; break; + + case Keyboard::Key::Home : sym = XK_Home; break; + case Keyboard::Key::End : sym = XK_End; break; + case Keyboard::Key::Insert : sym = XK_Insert; break; + case Keyboard::Key::Delete : sym = XK_Delete; break; + case Keyboard::Key::PageUp : sym = XK_Page_Up; break; + case Keyboard::Key::PageDown : sym = XK_Page_Down; break; + case Keyboard::Key::Pause : sym = XK_Pause; break; + + // Function keys + case Keyboard::Key::F1 : sym = XK_F1; break; + case Keyboard::Key::F2 : sym = XK_F2; break; + case Keyboard::Key::F3 : sym = XK_F3; break; + case Keyboard::Key::F4 : sym = XK_F4; break; + case Keyboard::Key::F5 : sym = XK_F5; break; + case Keyboard::Key::F6 : sym = XK_F6; break; + case Keyboard::Key::F7 : sym = XK_F7; break; + case Keyboard::Key::F8 : sym = XK_F8; break; + case Keyboard::Key::F9 : sym = XK_F9; break; + case Keyboard::Key::F10 : sym = XK_F10; break; + case Keyboard::Key::F11 : sym = XK_F11; break; + case Keyboard::Key::F12 : sym = XK_F12; break; + + case Keyboard::Key::Tab : sym = XK_Tab; break; + case Keyboard::Key::LShift : sym = XK_Shift_L; break; + case Keyboard::Key::RShift : sym = XK_Shift_R; break; + case Keyboard::Key::LCtrl : sym = XK_Control_L; break; + case Keyboard::Key::RCtrl : sym = XK_Control_R; break; + case Keyboard::Key::LAlt : sym = XK_Alt_L; break; +#ifdef XK_XKB_KEYS + case Keyboard::Key::RAlt : sym = XK_ISO_Level3_Shift; break; +#else + case Keyboard::Key::RAlt : sym = XK_Alt_R; break; +#endif /* XK_XKB_KEYS */ + default : sym = 0; break; + } + + KeyCode keycode = ::XKeysymToKeycode(m_disp, sym); + + if (keycode) { + return m_key_state[keycode / 8] & (1 << (keycode % 8)); + } return false; } @@ -225,6 +350,8 @@ bool X11Keyboard::handleMessage(XKeyEvent* xkeyevent, Event& event) void X11Keyboard::update(InputModule *input) { + // Query keyboard state. + ::XQueryKeymap(m_disp, m_key_state); } } // namespace sp diff --git a/source/Platform/Unix/X11Keyboard.h b/source/Platform/Unix/X11Keyboard.h index c0cda41..4684bba 100644 --- a/source/Platform/Unix/X11Keyboard.h +++ b/source/Platform/Unix/X11Keyboard.h @@ -5,12 +5,14 @@ #include #include #include + namespace sp { class X11Keyboard : public Keyboard { public : - virtual ~X11Keyboard() {} + X11Keyboard(); + ~X11Keyboard(); void init(); @@ -22,6 +24,12 @@ public : protected : virtual void update(InputModule *input); + +private : + ::Display* m_disp; + + // Cached keyboard state. + char m_key_state[32]; }; } // namespace sp From 816cf3a072a26e3b3f396a9d8047ae551f5f9f5c Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Fri, 16 Oct 2020 19:35:32 +0200 Subject: [PATCH 27/58] Platform/Unix/X11Mouse: adding a basic implementation to get things going. --- source/Platform/Unix/X11Mouse.cpp | 76 ++++++++++++++++++++++++++++++- source/Platform/Unix/X11Mouse.h | 12 +++++ 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/source/Platform/Unix/X11Mouse.cpp b/source/Platform/Unix/X11Mouse.cpp index 48ef3bc..35bf945 100644 --- a/source/Platform/Unix/X11Mouse.cpp +++ b/source/Platform/Unix/X11Mouse.cpp @@ -1,15 +1,33 @@ +#include +#include #include "X11Mouse.h" +#include "X11SharedDisplay.h" + namespace sp { +X11Mouse::X11Mouse() : +m_disp(NULL), +m_btn_state(0) +{ +} + +X11Mouse::~X11Mouse() +{ + if (m_disp) { + XReleaseDisplay(); + } +} + void X11Mouse::init() { - + m_disp = XGetDisplay(); } Vector2f X11Mouse::getPosition() const { + // TODO: Translate to window. return m_position; } @@ -20,12 +38,68 @@ Vector2f X11Mouse::getAbsPosition() const bool X11Mouse::isButtonDown(Mouse::Button button) const { + // TODO: Button1 and 2 is defined in x11 and + // therefore clashes with Mouse::Button::Button1 and 2. + switch(button) { + case Mouse::Button::Left : + return m_btn_state & Button1Mask; + case Mouse::Button::Right : + return m_btn_state & Button3Mask; + case Mouse::Button::Middle : + return m_btn_state & Button2Mask; + default : + return false; + } return false; } void X11Mouse::update(InputModule *input) { + ::Window root, child; + int rx, ry, x = 0, y = 0; + // Query position and button state. + XQueryPointer(m_disp, ::XDefaultRootWindow(m_disp), + &root, &child, + &rx, &ry, + &x, &y, &m_btn_state); + + // Update position + m_position.x = x; + m_position.y = y; +} + +bool X11Mouse::handleMessage(XEvent* xevent, Event& event) +{ + if (xevent->type == MotionNotify) { + event.type = Event::MouseMove; + event.mouseMove.x = xevent->xmotion.x; + event.mouseMove.y = xevent->xmotion.y; + return true; + } + + if (xevent->type == ButtonPress || xevent->type == ButtonRelease) { + + Mouse::Button trans = Mouse::Button::Unknown; + + switch(xevent->xbutton.button) { + case Button1 : trans = Mouse::Button::Left; break; + case Button2 : trans = Mouse::Button::Middle; break; + case Button3 : trans = Mouse::Button::Right; break; + // TODO: name clash, need to rename Mouse::Button enums. + // case Button4 : trans = Mouse::Button::Button1; break; // clashes with X11's "Button1" define. + // case Button5 : trans = Mouse::Button::Button2; break; // clashes with X11's "Button2" define. + } + + if (trans != Mouse::Button::Unknown) { + event.type = Event::MouseButton; + event.mouseButton.pressed = xevent->type == ButtonPress; + event.mouseButton.button = trans; + return true; + } + } + + return false; } } // namespace sp diff --git a/source/Platform/Unix/X11Mouse.h b/source/Platform/Unix/X11Mouse.h index 55c044e..84c326c 100644 --- a/source/Platform/Unix/X11Mouse.h +++ b/source/Platform/Unix/X11Mouse.h @@ -3,12 +3,16 @@ #define PLATFORM_UNIX_X11MOUSE_H #include +#include namespace sp { class X11Mouse : public Mouse { public : + X11Mouse(); + ~X11Mouse(); + virtual void init(); // Get mouse position @@ -18,12 +22,20 @@ public : virtual bool isButtonDown(Mouse::Button button) const; + // Translate a XEvent to sp::Event, Called from X11EventQueue + static bool handleMessage(XEvent* xevent, Event& event); + protected : virtual void update(InputModule *input); protected : + ::Display* m_disp; + ::Window m_win; + Vector2f m_position; + + unsigned int m_btn_state; }; } // namespace sp From 03186ebea021cd9cb2720ae9ebd4a08240e3ba09 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Fri, 16 Oct 2020 19:36:22 +0200 Subject: [PATCH 28/58] Platform/Unix/X11EventQueue.cpp: pass ButtonPress/ButtonRelease/MotionNotify events to X11Mouse --- source/Platform/Unix/X11EventQueue.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/Platform/Unix/X11EventQueue.cpp b/source/Platform/Unix/X11EventQueue.cpp index 19f4177..adcce7f 100644 --- a/source/Platform/Unix/X11EventQueue.cpp +++ b/source/Platform/Unix/X11EventQueue.cpp @@ -3,6 +3,7 @@ #include "X11EventQueue.h" #include "X11SharedDisplay.h" #include "X11Keyboard.h" +#include "X11Mouse.h" #include "X11WindowEventHandler.h" namespace sp { @@ -55,11 +56,10 @@ bool X11EventQueue::poll(Event& event) break; case ButtonPress: case ButtonRelease: - Log::info("X11: MouseButtonEvent"); - break; case MotionNotify: - // This generates alot of events :) - //Log::info("X11: MouseMotionEvent"); + if (X11Mouse::handleMessage(&xevent, event)) { + return true; + } break; default: // Pass to window. From dfe29acc1e50aadf9da1d0312fcf2044a347303e Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sat, 17 Oct 2020 14:06:46 +0200 Subject: [PATCH 29/58] Platform/Unix/UnixMisc.cpp: implement display mode lookups using xrandr extension. --- source/Platform/Unix/UnixMisc.cpp | 102 +++++++++++++++++++++++++++++- 1 file changed, 101 insertions(+), 1 deletion(-) diff --git a/source/Platform/Unix/UnixMisc.cpp b/source/Platform/Unix/UnixMisc.cpp index c168588..9f88478 100644 --- a/source/Platform/Unix/UnixMisc.cpp +++ b/source/Platform/Unix/UnixMisc.cpp @@ -1,15 +1,115 @@ +#include #include +#include "X11SharedDisplay.h" +#include +#include +#include namespace sp { +// Code "borrowed" from SFML :) +// see: https://github.com/SFML/SFML/blob/master/src/SFML/Window/Unix/VideoModeImpl.cpp + void PlatformMisc::GetDisplayModes(std::vector& modes) { + ::Display *disp = XGetDisplay(); + + if (disp) { + int scr = DefaultScreen(disp); + + // Check for XRandR. + int ver; + if (XQueryExtension(disp, "RANDR", &ver, &ver, &ver)) { + + XRRScreenConfiguration* config = ::XRRGetScreenInfo(disp, RootWindow(disp, scr)); + if (config) { + int nbSizes; + XRRScreenSize* sizes = ::XRRConfigSizes(config, &nbSizes); + if (sizes && nbSizes > 0) { + int nbDepths = 0; + int* depths = XListDepths(disp, scr, &nbDepths); + if (depths && nbDepths > 0) { + + for(int i = 0; i < nbDepths; i++) { + for(int j = 0; j < nbSizes; j++) { + DisplayMode mode(sizes[j].width, sizes[j].height, depths[i]); + + ::Rotation rot; + XRRConfigRotations(config, &rot); + + if (rot == RR_Rotate_90 || rot == RR_Rotate_270) { + std::swap(mode.width, mode.height); + } + + if (std::find(modes.begin(), modes.end(), mode) == modes.end()) { + modes.push_back(mode); + } + } + } + + XFree(depths); + } + } + } else { + Log::error("Failed to get screen configuration while trying to get display modes."); + } + + XRRFreeScreenConfigInfo(config); + } else { + Log::error("Failed to use XRandR extension while trying to get display modes."); + } + + XReleaseDisplay(); + } else { + Log::error("Failed to connect to the X server while trying to get display modes."); + } } DisplayMode PlatformMisc::GetDesktopMode() { - return DisplayMode(); + DisplayMode mode; + + ::Display *disp = XGetDisplay(); + + if (disp) { + int scr = DefaultScreen(disp); + + // Check for XRandR. + int ver; + if (XQueryExtension(disp, "RANDR", &ver, &ver, &ver)) { + + XRRScreenConfiguration* config = ::XRRGetScreenInfo(disp, RootWindow(disp, scr)); + if (config) { + int nbSizes; + ::Rotation rot; + int current = XRRConfigCurrentConfiguration(config, &rot); + + XRRScreenSize* sizes = ::XRRConfigSizes(config, &nbSizes); + if (sizes && nbSizes > 0) { + + mode = DisplayMode(sizes[current].width, sizes[current].height, DefaultDepth(disp, scr)); + + XRRConfigRotations(config, &rot); + if (rot == RR_Rotate_90 || rot == RR_Rotate_270) { + std::swap(mode.width, mode.height); + } + } + } else { + Log::error("Failed to get screen configuration while trying to get desktop display mode."); + } + + XRRFreeScreenConfigInfo(config); + } else { + Log::error("Failed to use XRandR extension while trying to get desktop display mode."); + } + + XReleaseDisplay(); + } else { + Log::error("Failed to connect to the X server while trying to get desktop display mode."); + } + + return mode; } } // namespace sp From 421bf819d5571842d0b3ba25dc3cf9745b744a6a Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sat, 17 Oct 2020 14:10:33 +0200 Subject: [PATCH 30/58] examples/build.lua: Unix systems needs to link with xrandr. --- examples/build.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/build.lua b/examples/build.lua index 2445a86..381f5e3 100644 --- a/examples/build.lua +++ b/examples/build.lua @@ -19,7 +19,7 @@ if TARGET_OS == "Win32" then elseif TARGET_OS == "Unix" then -- Unix nees dl and X11 libs. - example_settings.link.libs:Add("dl", 'X11', 'freetype') + example_settings.link.libs:Add("dl", 'X11', 'Xrandr', 'freetype') end -- For now, to get examples working From d73c787f40bda183075208b48793aa82331a3dea Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sat, 17 Oct 2020 14:18:41 +0200 Subject: [PATCH 31/58] Platform/Unix/X11SharedDisplay: pass a pointer to the display to XReleaseDisplay() just to be sure client code has a valid pointer --- source/Platform/Unix/GLXContext.cpp | 2 +- source/Platform/Unix/UnixMisc.cpp | 4 ++-- source/Platform/Unix/X11Display.cpp | 2 +- source/Platform/Unix/X11EventQueue.cpp | 2 +- source/Platform/Unix/X11Keyboard.cpp | 2 +- source/Platform/Unix/X11Mouse.cpp | 2 +- source/Platform/Unix/X11SharedDisplay.cpp | 5 ++++- source/Platform/Unix/X11SharedDisplay.h | 2 +- 8 files changed, 12 insertions(+), 9 deletions(-) diff --git a/source/Platform/Unix/GLXContext.cpp b/source/Platform/Unix/GLXContext.cpp index b00db35..53465a5 100644 --- a/source/Platform/Unix/GLXContext.cpp +++ b/source/Platform/Unix/GLXContext.cpp @@ -160,7 +160,7 @@ void GLXContext::destroy() } if (m_disp) { - XReleaseDisplay(); + XReleaseDisplay(m_disp); m_disp = NULL; } diff --git a/source/Platform/Unix/UnixMisc.cpp b/source/Platform/Unix/UnixMisc.cpp index 9f88478..afe2deb 100644 --- a/source/Platform/Unix/UnixMisc.cpp +++ b/source/Platform/Unix/UnixMisc.cpp @@ -60,7 +60,7 @@ void PlatformMisc::GetDisplayModes(std::vector& modes) Log::error("Failed to use XRandR extension while trying to get display modes."); } - XReleaseDisplay(); + XReleaseDisplay(disp); } else { Log::error("Failed to connect to the X server while trying to get display modes."); } @@ -104,7 +104,7 @@ DisplayMode PlatformMisc::GetDesktopMode() Log::error("Failed to use XRandR extension while trying to get desktop display mode."); } - XReleaseDisplay(); + XReleaseDisplay(disp); } else { Log::error("Failed to connect to the X server while trying to get desktop display mode."); } diff --git a/source/Platform/Unix/X11Display.cpp b/source/Platform/Unix/X11Display.cpp index 21308a1..ed93a7a 100644 --- a/source/Platform/Unix/X11Display.cpp +++ b/source/Platform/Unix/X11Display.cpp @@ -75,7 +75,7 @@ void X11Display::destroy() } if (m_disp) { - XReleaseDisplay(); + XReleaseDisplay(m_disp); m_disp = NULL; } } diff --git a/source/Platform/Unix/X11EventQueue.cpp b/source/Platform/Unix/X11EventQueue.cpp index adcce7f..d251eab 100644 --- a/source/Platform/Unix/X11EventQueue.cpp +++ b/source/Platform/Unix/X11EventQueue.cpp @@ -16,7 +16,7 @@ X11EventQueue::X11EventQueue() X11EventQueue::~X11EventQueue() { if (m_disp) { - XReleaseDisplay(); + XReleaseDisplay(m_disp); } } diff --git a/source/Platform/Unix/X11Keyboard.cpp b/source/Platform/Unix/X11Keyboard.cpp index 9121ebe..5a7b059 100644 --- a/source/Platform/Unix/X11Keyboard.cpp +++ b/source/Platform/Unix/X11Keyboard.cpp @@ -210,7 +210,7 @@ m_disp(NULL) X11Keyboard::~X11Keyboard() { if (m_disp) { - XReleaseDisplay(); + XReleaseDisplay(m_disp); } } diff --git a/source/Platform/Unix/X11Mouse.cpp b/source/Platform/Unix/X11Mouse.cpp index 35bf945..c6c846d 100644 --- a/source/Platform/Unix/X11Mouse.cpp +++ b/source/Platform/Unix/X11Mouse.cpp @@ -16,7 +16,7 @@ m_btn_state(0) X11Mouse::~X11Mouse() { if (m_disp) { - XReleaseDisplay(); + XReleaseDisplay(m_disp); } } diff --git a/source/Platform/Unix/X11SharedDisplay.cpp b/source/Platform/Unix/X11SharedDisplay.cpp index a7c691d..51f0d10 100644 --- a/source/Platform/Unix/X11SharedDisplay.cpp +++ b/source/Platform/Unix/X11SharedDisplay.cpp @@ -1,4 +1,5 @@ +#include #include "X11SharedDisplay.h" namespace sp { @@ -18,7 +19,9 @@ unsigned int refcount = 0; return sharedDisplay; } -void XReleaseDisplay() { +void XReleaseDisplay(::Display* disp) { + + assert(disp == sharedDisplay); if (refcount < 1) { return; diff --git a/source/Platform/Unix/X11SharedDisplay.h b/source/Platform/Unix/X11SharedDisplay.h index fed3a05..b662afc 100644 --- a/source/Platform/Unix/X11SharedDisplay.h +++ b/source/Platform/Unix/X11SharedDisplay.h @@ -9,7 +9,7 @@ namespace sp { ::Display* XGetDisplay(); -void XReleaseDisplay(); +void XReleaseDisplay(::Display* disp); Atom getAtom(const std::string& name, bool onlyIfExists = false); From 3d9dda64cacab090881bcc4fb461125ae9025faa Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sat, 17 Oct 2020 15:07:20 +0200 Subject: [PATCH 32/58] Platform/Unix/X11Display: Implement showCursor() --- source/Platform/Unix/X11Display.cpp | 30 +++++++++++++++++++++++++---- source/Platform/Unix/X11Display.h | 7 ++++++- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/source/Platform/Unix/X11Display.cpp b/source/Platform/Unix/X11Display.cpp index ed93a7a..968a9c3 100644 --- a/source/Platform/Unix/X11Display.cpp +++ b/source/Platform/Unix/X11Display.cpp @@ -10,9 +10,11 @@ namespace sp { X11Display:: X11Display() : -m_screen (0), -m_disp (NULL), -m_size (200,200) +m_screen (0), +m_disp (NULL), +m_size (200,200), +m_cur_last (0), +m_cur_hidden (0) { } @@ -65,6 +67,8 @@ bool X11Display::create(DisplayDescription description) Log::info("X11: Created display"); + createHiddenCursor(); + return true; } @@ -117,9 +121,27 @@ void X11Display::setIcon(const std::string& icon) // TODO: Implement } +void X11Display::createHiddenCursor() +{ + XColor c; + Pixmap pix = ::XCreatePixmap(m_disp, m_win, 1, 1, 1); + GC gc = ::XCreateGC(m_disp, pix, 0, NULL); + + // Draw transparent pixel. + ::XDrawPoint(m_disp, pix, gc, 0, 0); + + c.red = c.green = c.blue = 0; + c.flags = DoRed | DoGreen | DoBlue; + m_cur_hidden = XCreatePixmapCursor(m_disp, pix, pix, &c, &c, 0, 0); + + // Free GC and pixmap. + ::XFreePixmap(m_disp, pix); + ::XFreeGC(m_disp, gc); +} + void X11Display::showCursor(bool value) { - // TODO: Implement + XDefineCursor(m_disp, m_win, value ? m_cur_last : m_cur_hidden); } void X11Display::processEvent(const ::XEvent& event) diff --git a/source/Platform/Unix/X11Display.h b/source/Platform/Unix/X11Display.h index 9343705..ec4c094 100644 --- a/source/Platform/Unix/X11Display.h +++ b/source/Platform/Unix/X11Display.h @@ -39,6 +39,10 @@ public : void processEvent(const ::XEvent& event); +protected : + + void createHiddenCursor(); + protected : ::Display* m_disp; @@ -47,7 +51,8 @@ protected : int m_screen; - //GC m_GC; + ::Cursor m_cur_hidden; + ::Cursor m_cur_last; Vector2u m_size; }; From f5d80aa46f100a5fd76955998341fad7c3f42a47 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Tue, 27 Oct 2020 17:04:10 +0100 Subject: [PATCH 33/58] Platform/Unix/X11Display: Implement setIcon() --- source/Platform/Unix/X11Display.cpp | 35 ++++++++++++++++++++++++++++- source/Platform/Unix/X11Display.h | 3 +++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/source/Platform/Unix/X11Display.cpp b/source/Platform/Unix/X11Display.cpp index 968a9c3..94cea38 100644 --- a/source/Platform/Unix/X11Display.cpp +++ b/source/Platform/Unix/X11Display.cpp @@ -1,6 +1,7 @@ #include // Prevents conflict with X.h defining "None" #include +#include #include "X11WindowEventHandler.h" #include "X11SharedDisplay.h" #include "GLXContext.h" @@ -116,9 +117,41 @@ void X11Display::setCaption(const std::string& caption) ::XStoreName(m_disp, m_win, caption.c_str()); } +// TODO: Move this up to the non-platform layer. void X11Display::setIcon(const std::string& icon) { - // TODO: Implement + Image img; + + if (img.loadFromFile(icon)) { + setIcon(img.getWidth(), img.getHeight(), img.getPixels()); + } +} + +void X11Display::setIcon(unsigned int width, unsigned int height, const uint8_t *pixels) +{ + ::Atom net_wm_icon = getAtom("_NET_WM_ICON", False); + ::Atom cardinal = getAtom("CARDINAL", False); + std::vector buffer(2 + width * height); + uint64_t *ptr = &buffer[0]; + + *ptr++ = width; + *ptr++ = height; + + // TODO: Conversion between differnet formats should be defined as functions in Graphics/PixelFormat.h + for (std::size_t i = 0; i < width * height; i++) { + *ptr++ = (pixels[i * 4 + 2] << 0) + | (pixels[i * 4 + 1] << 8) + | (pixels[i * 4 + 0] << 16) + | (pixels[i * 4 + 3] << 24); + } + + ::XChangeProperty(m_disp, m_win, + net_wm_icon, cardinal, 32, + PropModeReplace, + reinterpret_cast(&buffer[0]), + 2 + width * height); + + XFlush(m_disp); } void X11Display::createHiddenCursor() diff --git a/source/Platform/Unix/X11Display.h b/source/Platform/Unix/X11Display.h index ec4c094..538e5c0 100644 --- a/source/Platform/Unix/X11Display.h +++ b/source/Platform/Unix/X11Display.h @@ -6,6 +6,7 @@ #include #include #include +#include #include namespace sp { @@ -35,6 +36,8 @@ public : virtual void setIcon(const std::string& icon); + virtual void setIcon(unsigned int width, unsigned int height, const uint8_t *pixels); + virtual void showCursor(bool value); void processEvent(const ::XEvent& event); From 61b233f708810d45e8d7243793dc83c0953bf3e2 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Tue, 27 Oct 2020 18:47:26 +0100 Subject: [PATCH 34/58] Platform/Unix/X11Display.cpp: Minor cleanup. --- source/Platform/Unix/X11Display.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/source/Platform/Unix/X11Display.cpp b/source/Platform/Unix/X11Display.cpp index 94cea38..ef67380 100644 --- a/source/Platform/Unix/X11Display.cpp +++ b/source/Platform/Unix/X11Display.cpp @@ -24,6 +24,8 @@ bool X11Display::create(DisplayDescription description) XSetWindowAttributes attr; XVisualInfo* vi; Atom protocols; + Visual* visual; + Window root_win; m_disp = XGetDisplay(); if (m_disp == NULL) { @@ -32,21 +34,22 @@ bool X11Display::create(DisplayDescription description) } m_screen = DefaultScreen(m_disp); + root_win = XRootWindow(m_disp, m_screen); + visual = DefaultVisual(m_disp, m_screen); attr.border_pixel = BlackPixel(m_disp, m_screen); attr.background_pixel = WhitePixel(m_disp, m_screen); //attr.override_redirect = True; - attr.colormap = ::XCreateColormap(m_disp, RootWindow(m_disp, m_screen), DefaultVisual(m_disp, m_screen), AllocNone); + attr.colormap = ::XCreateColormap(m_disp, root_win, visual, AllocNone); // We want Keyboard,Mouse,Resize,Exposure (repaint) events. attr.event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | ExposureMask; - m_win = XCreateWindow(m_disp, - RootWindow(m_disp, m_screen), + m_win = XCreateWindow(m_disp, root_win, 0, 0, m_size.x, m_size.y, 0, DefaultDepth(m_disp, m_screen), - InputOutput, DefaultVisual(m_disp, m_screen), + InputOutput, visual, CWBackPixel | CWColormap | CWBorderPixel | CWEventMask, &attr); // Register event handler From 0d029817fec4634c7f965af6cd4f4265fe1d8e54 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Tue, 27 Oct 2020 18:49:17 +0100 Subject: [PATCH 35/58] source/Platform/Unix/X11Display.cpp: in destroy() call XDestroyWindow() --- source/Platform/Unix/X11Display.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/source/Platform/Unix/X11Display.cpp b/source/Platform/Unix/X11Display.cpp index ef67380..083546e 100644 --- a/source/Platform/Unix/X11Display.cpp +++ b/source/Platform/Unix/X11Display.cpp @@ -80,6 +80,7 @@ void X11Display::destroy() { if (m_win) { X11WindowEventHandler::unregisterHandler(m_disp, m_win); + ::XDestroyWindow(m_disp, m_win); } if (m_disp) { From 50439a58bd85302379365bfbb89178db5f6180a3 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Tue, 27 Oct 2020 18:50:33 +0100 Subject: [PATCH 36/58] source/Platform/Unix/X11Display.cpp: in destroy() make sure m_disp is valid before calling functions that needs it. --- source/Platform/Unix/X11Display.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/source/Platform/Unix/X11Display.cpp b/source/Platform/Unix/X11Display.cpp index 083546e..f2f5289 100644 --- a/source/Platform/Unix/X11Display.cpp +++ b/source/Platform/Unix/X11Display.cpp @@ -78,12 +78,13 @@ bool X11Display::create(DisplayDescription description) void X11Display::destroy() { - if (m_win) { - X11WindowEventHandler::unregisterHandler(m_disp, m_win); - ::XDestroyWindow(m_disp, m_win); - } - if (m_disp) { + + if (m_win) { + X11WindowEventHandler::unregisterHandler(m_disp, m_win); + ::XDestroyWindow(m_disp, m_win); + } + XReleaseDisplay(m_disp); m_disp = NULL; } From 0c76864b40b0d11b14e07d12a92bad477b00c334 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Tue, 27 Oct 2020 19:39:25 +0100 Subject: [PATCH 37/58] Platform/Unix/X11Display: in setSize() check if width or height is zero before calling XResizeWindow() --- source/Platform/Unix/X11Display.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/source/Platform/Unix/X11Display.cpp b/source/Platform/Unix/X11Display.cpp index f2f5289..9b54150 100644 --- a/source/Platform/Unix/X11Display.cpp +++ b/source/Platform/Unix/X11Display.cpp @@ -102,8 +102,16 @@ void* X11Display::getHandle() const void X11Display::setSize(unsigned int width, unsigned int height) { - m_size = Vector2u(width, height); + // X11 does not like if width or height is zero. + if (width == 0) { + width = 1; + } + if (height == 0) { + height = 1; + } + + m_size = Vector2u(width, height); ::XResizeWindow(m_disp, m_win, m_size.x, m_size.y); } From 40e4f954529dae76260b57a925355e94b4420c0f Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Wed, 28 Oct 2020 11:00:45 +0100 Subject: [PATCH 38/58] Platform/Unix/X11Display.cpp: minor stuff. --- source/Platform/Unix/X11Display.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/Platform/Unix/X11Display.cpp b/source/Platform/Unix/X11Display.cpp index 9b54150..b9e73ac 100644 --- a/source/Platform/Unix/X11Display.cpp +++ b/source/Platform/Unix/X11Display.cpp @@ -46,9 +46,9 @@ bool X11Display::create(DisplayDescription description) | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | ExposureMask; - m_win = XCreateWindow(m_disp, root_win, - 0, 0, - m_size.x, m_size.y, 0, DefaultDepth(m_disp, m_screen), + m_win = ::XCreateWindow(m_disp, root_win, + 0, 0, /* Position */ + m_size.x, m_size.y, 0 /* Border width */, DefaultDepth(m_disp, m_screen), InputOutput, visual, CWBackPixel | CWColormap | CWBorderPixel | CWEventMask, &attr); From 56c24f7118750fd2fe41a98c0abcf1bd2673e626 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 20 Dec 2020 13:42:30 +0100 Subject: [PATCH 39/58] Platform/Unix/X11Display: Implement missing interface functions. * getPosition * setVisible * minimize * maximize * grabCursor (only stub. to get the code to compile) --- source/Platform/Unix/X11Display.cpp | 55 ++++++++++++++++++++++++++++- source/Platform/Unix/X11Display.h | 10 ++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/source/Platform/Unix/X11Display.cpp b/source/Platform/Unix/X11Display.cpp index b9e73ac..2cbb3d0 100644 --- a/source/Platform/Unix/X11Display.cpp +++ b/source/Platform/Unix/X11Display.cpp @@ -7,6 +7,11 @@ #include "GLXContext.h" #include "X11Display.h" +// Sometimes not defined in headers. +#ifndef _NET_WM_STATE_TOGGLE +#define _NET_WM_STATE_TOGGLE 2 +#endif + namespace sp { X11Display:: @@ -61,7 +66,7 @@ bool X11Display::create(DisplayDescription description) protocols = getAtom("WM_DELETE_WINDOW"); XSetWMProtocols(m_disp, m_win, &protocols, 1); - XMapWindow(m_disp, m_win); + setVisible(true); setSize(description.mode.width, description.mode.height); @@ -125,6 +130,49 @@ void X11Display::setPosition(unsigned int x, unsigned int y) ::XMoveWindow(m_disp, m_win, x, y); } +Vector2u X11Display::getPosition() const +{ + Vector2u pos(0, 0); + XWindowAttributes attr; + + if (XGetWindowAttributes(m_disp, m_win, &attr)) { + pos.x = attr.x; + pos.y = attr.y; + } + return pos; +} + +void X11Display::setVisible(bool visible) +{ + if (visible) { + ::XMapWindow(m_disp, m_win); + } else { + ::XUnmapWindow(m_disp, m_win); + } +} + +void X11Display::minimize() +{ + ::XIconifyWindow(m_disp, m_win, m_screen); +} + +void X11Display::maximize() +{ + ::XClientMessageEvent ev = {}; + + ev.type = ClientMessage; + ev.window = m_win; + ev.message_type = getAtom("_NET_WM_STATE"); + ev.format = 32; + ev.data.l[0] = _NET_WM_STATE_TOGGLE; + ev.data.l[1] = getAtom("_NET_WM_STATE_MAXIMIZED_HORZ"); + ev.data.l[2] = getAtom("_NET_WM_STATE_MAXIMIZED_VERT"); + ev.data.l[3] = 1; + + ::XSendEvent(m_disp, DefaultRootWindow(m_disp), False, + SubstructureNotifyMask, (XEvent*) &ev); +} + void X11Display::setCaption(const std::string& caption) { ::XStoreName(m_disp, m_win, caption.c_str()); @@ -190,6 +238,11 @@ void X11Display::showCursor(bool value) XDefineCursor(m_disp, m_win, value ? m_cur_last : m_cur_hidden); } +void X11Display::grabCursor(bool value) +{ + // TODO (this is abit harder on X11 than windows.) +} + void X11Display::processEvent(const ::XEvent& event) { Vector2u size; diff --git a/source/Platform/Unix/X11Display.h b/source/Platform/Unix/X11Display.h index 538e5c0..b62a372 100644 --- a/source/Platform/Unix/X11Display.h +++ b/source/Platform/Unix/X11Display.h @@ -32,6 +32,14 @@ public : virtual void setPosition(unsigned int x, unsigned int y); + virtual Vector2u getPosition() const; + + virtual void setVisible(bool visible); + + virtual void minimize(); + + virtual void maximize(); + virtual void setCaption(const std::string& caption); virtual void setIcon(const std::string& icon); @@ -40,6 +48,8 @@ public : virtual void showCursor(bool value); + virtual void grabCursor(bool value); + void processEvent(const ::XEvent& event); protected : From d971cd6cb2640ac5d810a9037b5562d4c32e803e Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 20 Dec 2020 13:55:56 +0100 Subject: [PATCH 40/58] Platform/Unix/X11Display.cpp: Capture input focus events (just log for now). --- source/Platform/Unix/X11Display.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/source/Platform/Unix/X11Display.cpp b/source/Platform/Unix/X11Display.cpp index 2cbb3d0..435ab82 100644 --- a/source/Platform/Unix/X11Display.cpp +++ b/source/Platform/Unix/X11Display.cpp @@ -46,8 +46,9 @@ bool X11Display::create(DisplayDescription description) attr.background_pixel = WhitePixel(m_disp, m_screen); //attr.override_redirect = True; attr.colormap = ::XCreateColormap(m_disp, root_win, visual, AllocNone); - // We want Keyboard,Mouse,Resize,Exposure (repaint) events. - attr.event_mask = KeyPressMask | KeyReleaseMask + // We want InputFocus,Keyboard,Mouse,Resize,Exposure (repaint) events. + attr.event_mask = FocusChangeMask + | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | ExposureMask; @@ -258,6 +259,15 @@ void X11Display::processEvent(const ::XEvent& event) onReshape(size.x, size.y); } break; + case MotionNotify : + // Generates to much events to log :) + break; + case FocusIn: + Log::debug("X11: FocusIn"); + break; + case FocusOut: + Log::debug("X11: FocusOut"); + break; } } From d9f54b08ca5c4a8155e5649ad593cf00de7a07a2 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 20 Dec 2020 16:01:37 +0100 Subject: [PATCH 41/58] Platform/Unix/X11Display: Adding getFocused() --- source/Platform/Unix/X11Display.cpp | 11 +++++++++++ source/Platform/Unix/X11Display.h | 3 +++ 2 files changed, 14 insertions(+) diff --git a/source/Platform/Unix/X11Display.cpp b/source/Platform/Unix/X11Display.cpp index 435ab82..556e601 100644 --- a/source/Platform/Unix/X11Display.cpp +++ b/source/Platform/Unix/X11Display.cpp @@ -14,6 +14,17 @@ namespace sp { +namespace _priv { + + // Pointer to the display that has focus (or NULL if none have). + X11Display* focused_display = NULL; +} + +X11Display* X11Display::getFocused() +{ + return _priv::focused_display; +} + X11Display:: X11Display() : m_screen (0), diff --git a/source/Platform/Unix/X11Display.h b/source/Platform/Unix/X11Display.h index b62a372..1816c37 100644 --- a/source/Platform/Unix/X11Display.h +++ b/source/Platform/Unix/X11Display.h @@ -16,6 +16,9 @@ namespace sp { class X11Display : public PlatformDisplay { public : + + static X11Display* getFocused(); + X11Display(); virtual bool create(DisplayDescription description); From 227d58725d36800bff642dfa507c262bd3cc6729 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 20 Dec 2020 16:03:05 +0100 Subject: [PATCH 42/58] Platform/Unix/X11Display.cpp: Set and unset focused_display variable when the display receives FocusIn/Out events. --- source/Platform/Unix/X11Display.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/Platform/Unix/X11Display.cpp b/source/Platform/Unix/X11Display.cpp index 556e601..c3eecf4 100644 --- a/source/Platform/Unix/X11Display.cpp +++ b/source/Platform/Unix/X11Display.cpp @@ -275,9 +275,11 @@ void X11Display::processEvent(const ::XEvent& event) break; case FocusIn: Log::debug("X11: FocusIn"); + _priv::focused_display = this; break; case FocusOut: Log::debug("X11: FocusOut"); + _priv::focused_display = NULL; break; } } From f71cfa86f2696344be75bcddfcfbbc1d4f076dc0 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 20 Dec 2020 16:09:16 +0100 Subject: [PATCH 43/58] Platform/Unix/X11Mouse: use X11Display::getFocused() to get the coordinates relative to the focused window. --- source/Platform/Unix/X11Mouse.cpp | 28 ++++++++++++++++++++++------ source/Platform/Unix/X11Mouse.h | 6 +++++- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/source/Platform/Unix/X11Mouse.cpp b/source/Platform/Unix/X11Mouse.cpp index c6c846d..850eec0 100644 --- a/source/Platform/Unix/X11Mouse.cpp +++ b/source/Platform/Unix/X11Mouse.cpp @@ -1,6 +1,7 @@ #include #include +#include "X11Display.h" #include "X11Mouse.h" #include "X11SharedDisplay.h" @@ -23,17 +24,17 @@ X11Mouse::~X11Mouse() void X11Mouse::init() { m_disp = XGetDisplay(); + updateFocusedWindow(); } Vector2f X11Mouse::getPosition() const { - // TODO: Translate to window. return m_position; } Vector2f X11Mouse::getAbsPosition() const { - return m_position; + return m_abs_position; } bool X11Mouse::isButtonDown(Mouse::Button button) const @@ -58,15 +59,30 @@ void X11Mouse::update(InputModule *input) ::Window root, child; int rx, ry, x = 0, y = 0; + updateFocusedWindow(); + // Query position and button state. - XQueryPointer(m_disp, ::XDefaultRootWindow(m_disp), + XQueryPointer(m_disp, + m_win ? m_win : ::XDefaultRootWindow(m_disp), &root, &child, &rx, &ry, &x, &y, &m_btn_state); - // Update position - m_position.x = x; - m_position.y = y; + // Update abs position (relative to root). + m_abs_position.x = rx; + m_abs_position.y = ry; + + // Update window position. + if (m_win) { + m_position.x = x; + m_position.y = y; + } +} + +void X11Mouse::updateFocusedWindow() +{ + X11Display *focus = X11Display::getFocused(); + m_win = focus ? (::Window) focus->getHandle() : 0; } bool X11Mouse::handleMessage(XEvent* xevent, Event& event) diff --git a/source/Platform/Unix/X11Mouse.h b/source/Platform/Unix/X11Mouse.h index 84c326c..26717c2 100644 --- a/source/Platform/Unix/X11Mouse.h +++ b/source/Platform/Unix/X11Mouse.h @@ -29,12 +29,16 @@ protected : virtual void update(InputModule *input); + void updateFocusedWindow(); + protected : ::Display* m_disp; - ::Window m_win; + ::Window m_win; // Focused window. Vector2f m_position; + Vector2f m_abs_position; + unsigned int m_btn_state; }; From 6c96a3d9a13d5c1390b4cc2ae66055ebab173eba Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 20 Dec 2020 16:28:25 +0100 Subject: [PATCH 44/58] Platform/Unix/X11Mouse.cpp: in isButtonDown() check if we have a focused window. --- source/Platform/Unix/X11Mouse.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/Platform/Unix/X11Mouse.cpp b/source/Platform/Unix/X11Mouse.cpp index 850eec0..9ef045a 100644 --- a/source/Platform/Unix/X11Mouse.cpp +++ b/source/Platform/Unix/X11Mouse.cpp @@ -39,6 +39,12 @@ Vector2f X11Mouse::getAbsPosition() const bool X11Mouse::isButtonDown(Mouse::Button button) const { + // Only signal that a button is down + // if we have focus on a window. + if (!m_win) { + return false; + } + // TODO: Button1 and 2 is defined in x11 and // therefore clashes with Mouse::Button::Button1 and 2. switch(button) { From 080c4f77c3a15883a5e6ef705e55a7c1588eb7bd Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 20 Dec 2020 16:29:12 +0100 Subject: [PATCH 45/58] Platform/Unix/X11Keyboard: only update state and signal key down if we have a focused window. --- source/Platform/Unix/X11Keyboard.cpp | 23 ++++++++++++++++++++--- source/Platform/Unix/X11Keyboard.h | 1 + 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/source/Platform/Unix/X11Keyboard.cpp b/source/Platform/Unix/X11Keyboard.cpp index 5a7b059..5843f94 100644 --- a/source/Platform/Unix/X11Keyboard.cpp +++ b/source/Platform/Unix/X11Keyboard.cpp @@ -1,6 +1,9 @@ +#include // FIXME: Weird name clashes with Xlib.h + #include #include "X11Keyboard.h" +#include "X11Display.h" #include "X11SharedDisplay.h" #include #include @@ -202,7 +205,8 @@ static Keyboard::Key KeySymToKeyboardKey(KeySym key) { } X11Keyboard::X11Keyboard() : -m_disp(NULL) +m_disp(NULL), +m_win(0) { memset(m_key_state, 0, sizeof(m_key_state) / sizeof(m_key_state[0])); } @@ -223,6 +227,12 @@ bool X11Keyboard::isKeyDown(Keyboard::Key key) { KeySym sym; + // Only signal that a button is down + // if we have focus on a window. + if (!m_win) { + return false; + } + switch(key) { // Letters case Keyboard::Key::A : sym = XK_a; break; @@ -350,8 +360,15 @@ bool X11Keyboard::handleMessage(XKeyEvent* xkeyevent, Event& event) void X11Keyboard::update(InputModule *input) { - // Query keyboard state. - ::XQueryKeymap(m_disp, m_key_state); + X11Display *focus = X11Display::getFocused(); + m_win = focus ? (::Window) focus->getHandle() : 0; + + // If we have focus. + if (m_win) { + + // Query keyboard state. + ::XQueryKeymap(m_disp, m_key_state); + } } } // namespace sp diff --git a/source/Platform/Unix/X11Keyboard.h b/source/Platform/Unix/X11Keyboard.h index 4684bba..3140160 100644 --- a/source/Platform/Unix/X11Keyboard.h +++ b/source/Platform/Unix/X11Keyboard.h @@ -27,6 +27,7 @@ protected : private : ::Display* m_disp; + ::Window m_win; // Focused window // Cached keyboard state. char m_key_state[32]; From 12b2413e232dea129109c94d4b40abffa90280a9 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Wed, 23 Dec 2020 14:34:12 +0100 Subject: [PATCH 46/58] include/Spectre/Display/DisplayDescription.h: Rename DisplayDecorate::None to Empty (None clashes with X11) --- include/Spectre/Display/DisplayDescription.h | 2 +- source/Display/Display.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/Spectre/Display/DisplayDescription.h b/include/Spectre/Display/DisplayDescription.h index 0d6539b..06067e0 100644 --- a/include/Spectre/Display/DisplayDescription.h +++ b/include/Spectre/Display/DisplayDescription.h @@ -9,7 +9,7 @@ namespace sp { namespace DisplayDecorate { enum Type { - None = 0, + Empty = 0, Menu = 1 << 0, Resize = 1 << 1, Close = 1 << 2, diff --git a/source/Display/Display.cpp b/source/Display/Display.cpp index 24ced50..bd13bd6 100644 --- a/source/Display/Display.cpp +++ b/source/Display/Display.cpp @@ -114,7 +114,7 @@ void Display::setVideoMode(Mode mode) m_cacheDesc = m_description; } - desc.decoration = DisplayDecorate::None; + desc.decoration = DisplayDecorate::Empty; } else { desc = m_cacheDesc; } From 197b4df87ffe3d697c1172c26ab3c8339da1188d Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Wed, 23 Dec 2020 14:36:38 +0100 Subject: [PATCH 47/58] Unix: Remove unnecessary includes of Spectre/Display/DisplayDescription.h --- source/Platform/Unix/X11Display.cpp | 1 - source/Platform/Unix/X11Display.h | 1 - source/Platform/Unix/X11Keyboard.cpp | 2 -- 3 files changed, 4 deletions(-) diff --git a/source/Platform/Unix/X11Display.cpp b/source/Platform/Unix/X11Display.cpp index c3eecf4..577ee10 100644 --- a/source/Platform/Unix/X11Display.cpp +++ b/source/Platform/Unix/X11Display.cpp @@ -1,5 +1,4 @@ -#include // Prevents conflict with X.h defining "None" #include #include #include "X11WindowEventHandler.h" diff --git a/source/Platform/Unix/X11Display.h b/source/Platform/Unix/X11Display.h index 1816c37..708e4ca 100644 --- a/source/Platform/Unix/X11Display.h +++ b/source/Platform/Unix/X11Display.h @@ -2,7 +2,6 @@ #ifndef PLATFORM_UNIX_X11DISPLAY_H #define PLATFORM_UNIX_X11DISPLAY_H -#include // Prevents conflict with X.h defining "None" #include #include #include diff --git a/source/Platform/Unix/X11Keyboard.cpp b/source/Platform/Unix/X11Keyboard.cpp index 5843f94..a7e30df 100644 --- a/source/Platform/Unix/X11Keyboard.cpp +++ b/source/Platform/Unix/X11Keyboard.cpp @@ -1,6 +1,4 @@ -#include // FIXME: Weird name clashes with Xlib.h - #include #include "X11Keyboard.h" #include "X11Display.h" From 60dd9bacb02de61ae5513cdb510471bc1e770235 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Fri, 25 Dec 2020 17:13:47 +0100 Subject: [PATCH 48/58] source/Game.cpp: make sure we call init() and shutdown() for platform --- source/Game.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/Game.cpp b/source/Game.cpp index 01cccc1..e8ff9c2 100644 --- a/source/Game.cpp +++ b/source/Game.cpp @@ -34,12 +34,17 @@ Game::~Game() { delete m_input; delete m_graphics; - delete m_platform; delete m_messageHandler; + + // TODO: This is abit ugly tbh. + m_platform->shutdown(); + delete m_platform; } void Game::run() { + m_platform->init(); + if (!m_graphics->init()) { return; } From 090646b61aee413cff7e20a75f553702c01dbeba Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Fri, 25 Dec 2020 17:17:51 +0100 Subject: [PATCH 49/58] Platform/Unix: Rename X11SharedDisplay to Xlib, and remove Display member variable from all classes. We now initialize/destroy the display in Xlib::init/shutdown that is called in UnixApplication::init/shutdown and therefore is valid through the whole lifetime. So no need for classes to keep references. --- engine.build.lua | 2 +- source/Platform/Unix/GLXContext.cpp | 37 +++---- source/Platform/Unix/GLXContext.h | 2 - source/Platform/Unix/UnixApplication.cpp | 5 +- source/Platform/Unix/UnixMisc.cpp | 13 +-- source/Platform/Unix/X11Display.cpp | 98 +++++++++---------- source/Platform/Unix/X11Display.h | 2 - source/Platform/Unix/X11EventQueue.cpp | 30 ++---- source/Platform/Unix/X11EventQueue.h | 5 - source/Platform/Unix/X11Keyboard.cpp | 10 +- source/Platform/Unix/X11Mouse.cpp | 17 +--- source/Platform/Unix/X11Mouse.h | 2 - source/Platform/Unix/X11SharedDisplay.cpp | 40 -------- source/Platform/Unix/X11SharedDisplay.h | 18 ---- .../Platform/Unix/X11WindowEventHandler.cpp | 1 - source/Platform/Unix/Xlib.cpp | 34 +++++++ source/Platform/Unix/Xlib.h | 22 +++++ 17 files changed, 137 insertions(+), 201 deletions(-) delete mode 100644 source/Platform/Unix/X11SharedDisplay.cpp delete mode 100644 source/Platform/Unix/X11SharedDisplay.h create mode 100644 source/Platform/Unix/Xlib.cpp create mode 100644 source/Platform/Unix/Xlib.h diff --git a/engine.build.lua b/engine.build.lua index 831d539..c050a73 100644 --- a/engine.build.lua +++ b/engine.build.lua @@ -64,8 +64,8 @@ if TARGET_OS == "Win32" then }) elseif TARGET_OS == "Unix" then platform_spec_module = Module("source/Platform/Unix", { + "Xlib.cpp", "UnixApplication.cpp", - "X11SharedDisplay.cpp", "X11Display.cpp", "GLXContext.cpp", "X11Input.cpp", diff --git a/source/Platform/Unix/GLXContext.cpp b/source/Platform/Unix/GLXContext.cpp index 53465a5..ea93438 100644 --- a/source/Platform/Unix/GLXContext.cpp +++ b/source/Platform/Unix/GLXContext.cpp @@ -4,7 +4,7 @@ #include #include "glad_glx.h" -#include "X11SharedDisplay.h" +#include "Xlib.h" #include "GLXContext.h" namespace sp { @@ -60,7 +60,6 @@ static bool ensureExtensionsLoaded(::Display* disp, int screen) } GLXContext::GLXContext() : -m_disp (NULL), m_win (0), m_ctx (NULL) { @@ -76,13 +75,6 @@ bool GLXContext::create(const PlatformDisplay* display) // Destroy any previous context first. destroy(); - m_disp = XGetDisplay(); - if (m_disp == NULL) { - destroy(); - Log::warn("X11: Could not open display"); - return false; - } - m_win = (::Window) display->getHandle(); if (!createGLContext()) { @@ -95,6 +87,7 @@ bool GLXContext::create(const PlatformDisplay* display) bool GLXContext::createGLContext() { + ::Display* disp = Xlib::getDisplay(); ::GLXFBConfig *fbc; ::XVisualInfo *info; int fbcount; @@ -117,31 +110,31 @@ bool GLXContext::createGLContext() }; // Ensure glx extensions are loaded. - if (!ensureExtensionsLoaded(m_disp, DefaultScreen(m_disp))) { + if (!ensureExtensionsLoaded(disp, DefaultScreen(disp))) { return false; } - info = ::glXChooseVisual(m_disp, DefaultScreen(m_disp), vi_attr); + info = ::glXChooseVisual(disp, DefaultScreen(disp), vi_attr); if (info == NULL) { Log::warn("GLX: Could not find a valid VisualInfo."); return false; } // Setup GL settings. - fbc = glXChooseFBConfig(m_disp, DefaultScreen(m_disp), (const int*) info->visual, &fbcount); + fbc = glXChooseFBConfig(disp, DefaultScreen(disp), (const int*) info->visual, &fbcount); if (fbc == NULL) { Log::warn("GLX: Could not find FB Config."); return false; } // Create context. - m_ctx = glXCreateContextAttribsARB(m_disp, fbc[0], NULL, GL_TRUE, ctx_attr); + m_ctx = glXCreateContextAttribsARB(disp, fbc[0], NULL, GL_TRUE, ctx_attr); if (m_ctx == NULL) { Log::warn("GLX: Failed to create context."); return false; } - glXMakeCurrent(m_disp, m_win, m_ctx); + glXMakeCurrent(disp, m_win, m_ctx); // Load OpenGL if (!loadGL()) { @@ -155,29 +148,24 @@ bool GLXContext::createGLContext() void GLXContext::destroy() { if (m_ctx) { - ::glXDestroyContext(m_disp, m_ctx); + ::glXDestroyContext(Xlib::getDisplay(), m_ctx); m_ctx = NULL; } - if (m_disp) { - XReleaseDisplay(m_disp); - m_disp = NULL; - } - m_win = None; } bool GLXContext::activate() { if (m_win && m_ctx) { - return ::glXMakeCurrent(m_disp, m_win, m_ctx); + return ::glXMakeCurrent(Xlib::getDisplay(), m_win, m_ctx); } return false; } bool GLXContext::deactivate() { - return ::glXMakeCurrent(m_disp, None, NULL); + return ::glXMakeCurrent(Xlib::getDisplay(), None, NULL); } bool GLXContext::isActive() const @@ -187,7 +175,8 @@ bool GLXContext::isActive() const bool GLXContext::setSwapInterval(int interval) { - ensureExtensionsLoaded(m_disp, DefaultScreen(m_disp)); + ::Display *disp = Xlib::getDisplay(); + ensureExtensionsLoaded(disp, DefaultScreen(disp)); if (GLAD_GLX_MESA_swap_control) { return glXSwapIntervalMESA(interval); @@ -215,7 +204,7 @@ void GLXContext::setSize(const Vector2u size) void GLXContext::swapBuffers() { - glXSwapBuffers(m_disp, m_win); + glXSwapBuffers(Xlib::getDisplay(), m_win); } } // namespace sp diff --git a/source/Platform/Unix/GLXContext.h b/source/Platform/Unix/GLXContext.h index 305d789..878a6f7 100644 --- a/source/Platform/Unix/GLXContext.h +++ b/source/Platform/Unix/GLXContext.h @@ -39,8 +39,6 @@ private : private : - ::Display* m_disp; - ::Window m_win; ::GLXContext m_ctx; diff --git a/source/Platform/Unix/UnixApplication.cpp b/source/Platform/Unix/UnixApplication.cpp index a8925d4..f2c175f 100644 --- a/source/Platform/Unix/UnixApplication.cpp +++ b/source/Platform/Unix/UnixApplication.cpp @@ -1,16 +1,17 @@ #include "UnixApplication.h" +#include "Xlib.h" namespace sp { void UnixApplication::init() { - // TODO + Xlib::init(); } void UnixApplication::shutdown() { - // TODO + Xlib::shutdown(); } PlatformInput& UnixApplication::getInput() diff --git a/source/Platform/Unix/UnixMisc.cpp b/source/Platform/Unix/UnixMisc.cpp index afe2deb..fd557f2 100644 --- a/source/Platform/Unix/UnixMisc.cpp +++ b/source/Platform/Unix/UnixMisc.cpp @@ -1,8 +1,7 @@ #include #include -#include "X11SharedDisplay.h" -#include +#include "Xlib.h" #include #include @@ -13,7 +12,7 @@ namespace sp { void PlatformMisc::GetDisplayModes(std::vector& modes) { - ::Display *disp = XGetDisplay(); + ::Display *disp = Xlib::getDisplay(); if (disp) { int scr = DefaultScreen(disp); @@ -28,7 +27,7 @@ void PlatformMisc::GetDisplayModes(std::vector& modes) XRRScreenSize* sizes = ::XRRConfigSizes(config, &nbSizes); if (sizes && nbSizes > 0) { int nbDepths = 0; - int* depths = XListDepths(disp, scr, &nbDepths); + int* depths = ::XListDepths(disp, scr, &nbDepths); if (depths && nbDepths > 0) { for(int i = 0; i < nbDepths; i++) { @@ -59,8 +58,6 @@ void PlatformMisc::GetDisplayModes(std::vector& modes) } else { Log::error("Failed to use XRandR extension while trying to get display modes."); } - - XReleaseDisplay(disp); } else { Log::error("Failed to connect to the X server while trying to get display modes."); } @@ -70,7 +67,7 @@ DisplayMode PlatformMisc::GetDesktopMode() { DisplayMode mode; - ::Display *disp = XGetDisplay(); + ::Display *disp = Xlib::getDisplay(); if (disp) { int scr = DefaultScreen(disp); @@ -103,8 +100,6 @@ DisplayMode PlatformMisc::GetDesktopMode() } else { Log::error("Failed to use XRandR extension while trying to get desktop display mode."); } - - XReleaseDisplay(disp); } else { Log::error("Failed to connect to the X server while trying to get desktop display mode."); } diff --git a/source/Platform/Unix/X11Display.cpp b/source/Platform/Unix/X11Display.cpp index 577ee10..d960670 100644 --- a/source/Platform/Unix/X11Display.cpp +++ b/source/Platform/Unix/X11Display.cpp @@ -2,7 +2,7 @@ #include #include #include "X11WindowEventHandler.h" -#include "X11SharedDisplay.h" +#include "Xlib.h" #include "GLXContext.h" #include "X11Display.h" @@ -27,7 +27,6 @@ X11Display* X11Display::getFocused() X11Display:: X11Display() : m_screen (0), -m_disp (NULL), m_size (200,200), m_cur_last (0), m_cur_hidden (0) @@ -41,49 +40,44 @@ bool X11Display::create(DisplayDescription description) Atom protocols; Visual* visual; Window root_win; + ::Display* disp = Xlib::getDisplay(); - m_disp = XGetDisplay(); - if (m_disp == NULL) { - Log::warn("X11: Could not open display"); - return false; - } + m_screen = DefaultScreen(disp); + root_win = XRootWindow(disp, m_screen); + visual = DefaultVisual(disp, m_screen); - m_screen = DefaultScreen(m_disp); - root_win = XRootWindow(m_disp, m_screen); - visual = DefaultVisual(m_disp, m_screen); - - attr.border_pixel = BlackPixel(m_disp, m_screen); - attr.background_pixel = WhitePixel(m_disp, m_screen); + attr.border_pixel = BlackPixel(disp, m_screen); + attr.background_pixel = WhitePixel(disp, m_screen); //attr.override_redirect = True; - attr.colormap = ::XCreateColormap(m_disp, root_win, visual, AllocNone); + attr.colormap = ::XCreateColormap(disp, root_win, visual, AllocNone); // We want InputFocus,Keyboard,Mouse,Resize,Exposure (repaint) events. attr.event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | ExposureMask; - m_win = ::XCreateWindow(m_disp, root_win, + m_win = ::XCreateWindow(disp, root_win, 0, 0, /* Position */ - m_size.x, m_size.y, 0 /* Border width */, DefaultDepth(m_disp, m_screen), + m_size.x, m_size.y, 0 /* Border width */, DefaultDepth(disp, m_screen), InputOutput, visual, CWBackPixel | CWColormap | CWBorderPixel | CWEventMask, &attr); // Register event handler - X11WindowEventHandler::registerHandler(m_disp, m_win, this); + X11WindowEventHandler::registerHandler(disp, m_win, this); // X11 does not handle pressing the X button on a window. // that is the job of the window manager. // Here we can request the WM to send us a delete event so we can handle it ourself. - protocols = getAtom("WM_DELETE_WINDOW"); - XSetWMProtocols(m_disp, m_win, &protocols, 1); + protocols = Xlib::getAtom("WM_DELETE_WINDOW"); + XSetWMProtocols(disp, m_win, &protocols, 1); setVisible(true); setSize(description.mode.width, description.mode.height); // Clear and take focus - XClearWindow(m_disp, m_win); - XMapRaised(m_disp, m_win); + XClearWindow(disp, m_win); + XMapRaised(disp, m_win); Log::info("X11: Created display"); @@ -94,21 +88,16 @@ bool X11Display::create(DisplayDescription description) void X11Display::destroy() { - if (m_disp) { - - if (m_win) { - X11WindowEventHandler::unregisterHandler(m_disp, m_win); - ::XDestroyWindow(m_disp, m_win); - } - - XReleaseDisplay(m_disp); - m_disp = NULL; + if (m_win) { + ::Display* disp = Xlib::getDisplay(); + X11WindowEventHandler::unregisterHandler(disp, m_win); + ::XDestroyWindow(disp, m_win); } } bool X11Display::isValid() { - return m_disp && m_win; + return m_win; } void* X11Display::getHandle() const @@ -128,7 +117,7 @@ void X11Display::setSize(unsigned int width, unsigned int height) } m_size = Vector2u(width, height); - ::XResizeWindow(m_disp, m_win, m_size.x, m_size.y); + ::XResizeWindow(Xlib::getDisplay(), m_win, m_size.x, m_size.y); } Vector2u X11Display::getSize() const @@ -138,7 +127,7 @@ Vector2u X11Display::getSize() const void X11Display::setPosition(unsigned int x, unsigned int y) { - ::XMoveWindow(m_disp, m_win, x, y); + ::XMoveWindow(Xlib::getDisplay(), m_win, x, y); } Vector2u X11Display::getPosition() const @@ -146,7 +135,7 @@ Vector2u X11Display::getPosition() const Vector2u pos(0, 0); XWindowAttributes attr; - if (XGetWindowAttributes(m_disp, m_win, &attr)) { + if (XGetWindowAttributes(Xlib::getDisplay(), m_win, &attr)) { pos.x = attr.x; pos.y = attr.y; } @@ -156,37 +145,38 @@ Vector2u X11Display::getPosition() const void X11Display::setVisible(bool visible) { if (visible) { - ::XMapWindow(m_disp, m_win); + ::XMapWindow(Xlib::getDisplay(), m_win); } else { - ::XUnmapWindow(m_disp, m_win); + ::XUnmapWindow(Xlib::getDisplay(), m_win); } } void X11Display::minimize() { - ::XIconifyWindow(m_disp, m_win, m_screen); + ::XIconifyWindow(Xlib::getDisplay(), m_win, m_screen); } void X11Display::maximize() { ::XClientMessageEvent ev = {}; + ::Display* disp = Xlib::getDisplay(); ev.type = ClientMessage; ev.window = m_win; - ev.message_type = getAtom("_NET_WM_STATE"); + ev.message_type = Xlib::getAtom("_NET_WM_STATE"); ev.format = 32; ev.data.l[0] = _NET_WM_STATE_TOGGLE; - ev.data.l[1] = getAtom("_NET_WM_STATE_MAXIMIZED_HORZ"); - ev.data.l[2] = getAtom("_NET_WM_STATE_MAXIMIZED_VERT"); + ev.data.l[1] = Xlib::getAtom("_NET_WM_STATE_MAXIMIZED_HORZ"); + ev.data.l[2] = Xlib::getAtom("_NET_WM_STATE_MAXIMIZED_VERT"); ev.data.l[3] = 1; - ::XSendEvent(m_disp, DefaultRootWindow(m_disp), False, + ::XSendEvent(disp, DefaultRootWindow(disp), False, SubstructureNotifyMask, (XEvent*) &ev); } void X11Display::setCaption(const std::string& caption) { - ::XStoreName(m_disp, m_win, caption.c_str()); + ::XStoreName(Xlib::getDisplay(), m_win, caption.c_str()); } // TODO: Move this up to the non-platform layer. @@ -201,8 +191,9 @@ void X11Display::setIcon(const std::string& icon) void X11Display::setIcon(unsigned int width, unsigned int height, const uint8_t *pixels) { - ::Atom net_wm_icon = getAtom("_NET_WM_ICON", False); - ::Atom cardinal = getAtom("CARDINAL", False); + ::Display* disp = Xlib::getDisplay(); + ::Atom net_wm_icon = Xlib::getAtom("_NET_WM_ICON", False); + ::Atom cardinal = Xlib::getAtom("CARDINAL", False); std::vector buffer(2 + width * height); uint64_t *ptr = &buffer[0]; @@ -217,36 +208,37 @@ void X11Display::setIcon(unsigned int width, unsigned int height, const uint8_t | (pixels[i * 4 + 3] << 24); } - ::XChangeProperty(m_disp, m_win, + ::XChangeProperty(disp, m_win, net_wm_icon, cardinal, 32, PropModeReplace, reinterpret_cast(&buffer[0]), 2 + width * height); - XFlush(m_disp); + XFlush(disp); } void X11Display::createHiddenCursor() { + ::Display* disp = Xlib::getDisplay(); XColor c; - Pixmap pix = ::XCreatePixmap(m_disp, m_win, 1, 1, 1); - GC gc = ::XCreateGC(m_disp, pix, 0, NULL); + Pixmap pix = ::XCreatePixmap(disp, m_win, 1, 1, 1); + GC gc = ::XCreateGC(disp, pix, 0, NULL); // Draw transparent pixel. - ::XDrawPoint(m_disp, pix, gc, 0, 0); + ::XDrawPoint(disp, pix, gc, 0, 0); c.red = c.green = c.blue = 0; c.flags = DoRed | DoGreen | DoBlue; - m_cur_hidden = XCreatePixmapCursor(m_disp, pix, pix, &c, &c, 0, 0); + m_cur_hidden = XCreatePixmapCursor(disp, pix, pix, &c, &c, 0, 0); // Free GC and pixmap. - ::XFreePixmap(m_disp, pix); - ::XFreeGC(m_disp, gc); + ::XFreePixmap(disp, pix); + ::XFreeGC(disp, gc); } void X11Display::showCursor(bool value) { - XDefineCursor(m_disp, m_win, value ? m_cur_last : m_cur_hidden); + XDefineCursor(Xlib::getDisplay(), m_win, value ? m_cur_last : m_cur_hidden); } void X11Display::grabCursor(bool value) diff --git a/source/Platform/Unix/X11Display.h b/source/Platform/Unix/X11Display.h index 708e4ca..403aaaf 100644 --- a/source/Platform/Unix/X11Display.h +++ b/source/Platform/Unix/X11Display.h @@ -60,8 +60,6 @@ protected : protected : - ::Display* m_disp; - ::Window m_win; int m_screen; diff --git a/source/Platform/Unix/X11EventQueue.cpp b/source/Platform/Unix/X11EventQueue.cpp index d251eab..86931f8 100644 --- a/source/Platform/Unix/X11EventQueue.cpp +++ b/source/Platform/Unix/X11EventQueue.cpp @@ -1,38 +1,24 @@ #include + #include "X11EventQueue.h" -#include "X11SharedDisplay.h" +#include "Xlib.h" #include "X11Keyboard.h" #include "X11Mouse.h" #include "X11WindowEventHandler.h" namespace sp { -X11EventQueue::X11EventQueue() -{ - m_disp = XGetDisplay(); -} - -X11EventQueue::~X11EventQueue() -{ - if (m_disp) { - XReleaseDisplay(m_disp); - } -} - bool X11EventQueue::poll(Event& event) { - Atom del_win = getAtom("WM_DELETE_WINDOW"); - Atom wm_proto = getAtom("WM_PROTOCOLS"); + ::Display* disp = Xlib::getDisplay(); + Atom del_win = Xlib::getAtom("WM_DELETE_WINDOW"); + Atom wm_proto = Xlib::getAtom("WM_PROTOCOLS"); - if (m_disp == NULL) { - return false; - } - - if (XPending(m_disp)) { + if (XPending(disp)) { XEvent xevent; - XNextEvent(m_disp, &xevent); + XNextEvent(disp, &xevent); switch(xevent.type) { case ClientMessage: @@ -64,7 +50,7 @@ bool X11EventQueue::poll(Event& event) default: // Pass to window. Log::info("X11: Window Event"); - X11WindowEventHandler::process(m_disp, xevent); + X11WindowEventHandler::process(disp, xevent); } } diff --git a/source/Platform/Unix/X11EventQueue.h b/source/Platform/Unix/X11EventQueue.h index 73b363f..b34c3dc 100644 --- a/source/Platform/Unix/X11EventQueue.h +++ b/source/Platform/Unix/X11EventQueue.h @@ -11,13 +11,8 @@ namespace sp { class X11EventQueue : public PlatformEventQueue { public : - X11EventQueue(); - virtual ~X11EventQueue(); virtual bool poll(Event& event); - -private : - ::Display* m_disp; }; } // namespace sp diff --git a/source/Platform/Unix/X11Keyboard.cpp b/source/Platform/Unix/X11Keyboard.cpp index a7e30df..b345ecb 100644 --- a/source/Platform/Unix/X11Keyboard.cpp +++ b/source/Platform/Unix/X11Keyboard.cpp @@ -2,7 +2,7 @@ #include #include "X11Keyboard.h" #include "X11Display.h" -#include "X11SharedDisplay.h" +#include "Xlib.h" #include #include #include @@ -211,14 +211,10 @@ m_win(0) X11Keyboard::~X11Keyboard() { - if (m_disp) { - XReleaseDisplay(m_disp); - } } void X11Keyboard::init() { - m_disp = XGetDisplay(); } bool X11Keyboard::isKeyDown(Keyboard::Key key) @@ -334,7 +330,7 @@ bool X11Keyboard::isKeyDown(Keyboard::Key key) default : sym = 0; break; } - KeyCode keycode = ::XKeysymToKeycode(m_disp, sym); + KeyCode keycode = ::XKeysymToKeycode(Xlib::getDisplay(), sym); if (keycode) { return m_key_state[keycode / 8] & (1 << (keycode % 8)); @@ -365,7 +361,7 @@ void X11Keyboard::update(InputModule *input) if (m_win) { // Query keyboard state. - ::XQueryKeymap(m_disp, m_key_state); + ::XQueryKeymap(Xlib::getDisplay(), m_key_state); } } diff --git a/source/Platform/Unix/X11Mouse.cpp b/source/Platform/Unix/X11Mouse.cpp index 9ef045a..cabbedc 100644 --- a/source/Platform/Unix/X11Mouse.cpp +++ b/source/Platform/Unix/X11Mouse.cpp @@ -1,29 +1,19 @@ #include #include +#include "Xlib.h" #include "X11Display.h" #include "X11Mouse.h" -#include "X11SharedDisplay.h" - namespace sp { X11Mouse::X11Mouse() : -m_disp(NULL), m_btn_state(0) { } -X11Mouse::~X11Mouse() -{ - if (m_disp) { - XReleaseDisplay(m_disp); - } -} - void X11Mouse::init() { - m_disp = XGetDisplay(); updateFocusedWindow(); } @@ -62,14 +52,15 @@ bool X11Mouse::isButtonDown(Mouse::Button button) const void X11Mouse::update(InputModule *input) { + ::Display* disp = Xlib::getDisplay(); ::Window root, child; int rx, ry, x = 0, y = 0; updateFocusedWindow(); // Query position and button state. - XQueryPointer(m_disp, - m_win ? m_win : ::XDefaultRootWindow(m_disp), + XQueryPointer(disp, + m_win ? m_win : ::XDefaultRootWindow(disp), &root, &child, &rx, &ry, &x, &y, &m_btn_state); diff --git a/source/Platform/Unix/X11Mouse.h b/source/Platform/Unix/X11Mouse.h index 26717c2..9cb0872 100644 --- a/source/Platform/Unix/X11Mouse.h +++ b/source/Platform/Unix/X11Mouse.h @@ -11,7 +11,6 @@ class X11Mouse : public Mouse { public : X11Mouse(); - ~X11Mouse(); virtual void init(); @@ -32,7 +31,6 @@ protected : void updateFocusedWindow(); protected : - ::Display* m_disp; ::Window m_win; // Focused window. Vector2f m_position; diff --git a/source/Platform/Unix/X11SharedDisplay.cpp b/source/Platform/Unix/X11SharedDisplay.cpp deleted file mode 100644 index 51f0d10..0000000 --- a/source/Platform/Unix/X11SharedDisplay.cpp +++ /dev/null @@ -1,40 +0,0 @@ - -#include -#include "X11SharedDisplay.h" - -namespace sp { - -// Define a global display (for simplicity, we always connect to local one.) -::Display* sharedDisplay = NULL; -unsigned int refcount = 0; - -::Display* XGetDisplay() { - - // Create if we dont have any references. - if (refcount == 0) { - sharedDisplay = XOpenDisplay(NULL); - } - - refcount++; - return sharedDisplay; -} - -void XReleaseDisplay(::Display* disp) { - - assert(disp == sharedDisplay); - - if (refcount < 1) { - return; - } - - if (--refcount == 0) { - XCloseDisplay(sharedDisplay); - } -} - -Atom getAtom(const std::string& name, bool onlyIfExists) { - - return XInternAtom(sharedDisplay, name.c_str(), onlyIfExists); -} - -} // namespace sp diff --git a/source/Platform/Unix/X11SharedDisplay.h b/source/Platform/Unix/X11SharedDisplay.h deleted file mode 100644 index b662afc..0000000 --- a/source/Platform/Unix/X11SharedDisplay.h +++ /dev/null @@ -1,18 +0,0 @@ - -#ifndef SPECTRE_PLATFORM_UNIX_X11SHAREDDISPLAY_H -#define SPECTRE_PLATFORM_UNIX_X11SHAREDDISPLAY_H - -#include -#include - -namespace sp { - -::Display* XGetDisplay(); - -void XReleaseDisplay(::Display* disp); - -Atom getAtom(const std::string& name, bool onlyIfExists = false); - -} // namespace sp - -#endif /* SPECTRE_PLATFORM_UNIX_X11SHAREDDISPLAY_H */ diff --git a/source/Platform/Unix/X11WindowEventHandler.cpp b/source/Platform/Unix/X11WindowEventHandler.cpp index a4ec542..fa6eb45 100644 --- a/source/Platform/Unix/X11WindowEventHandler.cpp +++ b/source/Platform/Unix/X11WindowEventHandler.cpp @@ -1,7 +1,6 @@ #include #include "X11Display.h" -#include "X11SharedDisplay.h" #include "X11WindowEventHandler.h" #include diff --git a/source/Platform/Unix/Xlib.cpp b/source/Platform/Unix/Xlib.cpp new file mode 100644 index 0000000..32e36fb --- /dev/null +++ b/source/Platform/Unix/Xlib.cpp @@ -0,0 +1,34 @@ + +#include +#include "Xlib.h" + +namespace sp { namespace Xlib { + +namespace _priv { + // Define a global display (for simplicity, we always connect to local one.) + ::Display* display = NULL; +}; + +void init() +{ + _priv::display = XOpenDisplay(NULL); +} + +void shutdown() +{ + XCloseDisplay(_priv::display); + _priv::display = NULL; +} + +::Display* getDisplay() +{ + assert(_priv::display != NULL); + return _priv::display; +} + +::Atom getAtom(const std::string& name, bool onlyIfExists) +{ + return XInternAtom(getDisplay(), name.c_str(), onlyIfExists); +} + +} } // namespace sp::Xlib diff --git a/source/Platform/Unix/Xlib.h b/source/Platform/Unix/Xlib.h new file mode 100644 index 0000000..cc5cb2d --- /dev/null +++ b/source/Platform/Unix/Xlib.h @@ -0,0 +1,22 @@ + +#ifndef SPECTRE_PLATFORM_UNIX_XLIB_H +#define SPECTRE_PLATFORM_UNIX_XLIB_H + +#include +#include + +// Wrapper for some Xlib functions. + +namespace sp { namespace Xlib { + +void init(); + +void shutdown(); + +::Display* getDisplay(); + +::Atom getAtom(const std::string& name, bool onlyIfExists = false); + +} } // namespace sp::xlib + +#endif /* SPECTRE_PLATFORM_UNIX_XLIB_H */ From 0540f5d2018a5db7c35efb8590436a1adee9ca0d Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sat, 26 Dec 2020 15:53:52 +0100 Subject: [PATCH 50/58] engine.build.lua: add platform defines. --- engine.build.lua | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/engine.build.lua b/engine.build.lua index c050a73..ffce57e 100644 --- a/engine.build.lua +++ b/engine.build.lua @@ -17,6 +17,13 @@ if global_settings.debug then settings.cc.flags:Add("-DSPECTRE_DEBUG") end +-- Platform +if TARGET_OS == "Win32" then + settings.cc.defines:Add("SPECTRE_PLATFORM_WIN=1") +elseif TARGET_OS == "Unix" then + settings.cc.defines:Add("SPECTRE_PLATFORM_UNIX=1") +end + -- FreeType2 if TARGET_OS == "Win32" then settings.cc.includes:Add("vendor/FreeType2/include") From b91b9f37684954ecb5e22347f994c4650ccc3e27 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sat, 26 Dec 2020 17:20:05 +0100 Subject: [PATCH 51/58] Platform/PlatformApplication: adding create() method. --- engine.build.lua | 1 + source/Platform/PlatformApplication.cpp | 21 +++++++++++++++++++++ source/Platform/PlatformApplication.h | 2 ++ 3 files changed, 24 insertions(+) create mode 100644 source/Platform/PlatformApplication.cpp diff --git a/engine.build.lua b/engine.build.lua index ffce57e..82f6200 100644 --- a/engine.build.lua +++ b/engine.build.lua @@ -52,6 +52,7 @@ local system_module = Module("source/System", { }) local platform_common_module = Module("source/Platform", { + "PlatformApplication.cpp", "PlatformDisplay.cpp" }) diff --git a/source/Platform/PlatformApplication.cpp b/source/Platform/PlatformApplication.cpp new file mode 100644 index 0000000..02076a0 --- /dev/null +++ b/source/Platform/PlatformApplication.cpp @@ -0,0 +1,21 @@ + +#include "PlatformApplication.h" + +#ifdef _WIN32 +#include +typedef sp::Win32Application ApplicationType; +#elif defined(__linux__) || defined(unix) || defined(__unix) || defined(__unix__) +#include +typedef sp::UnixApplication ApplicationType; +#else +#error "No Application implementation exists" +#endif + +namespace sp { + +PlatformApplication* PlatformApplication::create() +{ + return new ApplicationType; +} + +} // namespace sp diff --git a/source/Platform/PlatformApplication.h b/source/Platform/PlatformApplication.h index 800bf31..d094ca3 100644 --- a/source/Platform/PlatformApplication.h +++ b/source/Platform/PlatformApplication.h @@ -11,6 +11,8 @@ class MessageQueue; class PlatformApplication { public : + static PlatformApplication* create(); + virtual void init() = 0; virtual void shutdown() = 0; From 2eec1c9f755cac2ca180383632e76c663b01d801 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sat, 26 Dec 2020 17:20:30 +0100 Subject: [PATCH 52/58] source/Game.cpp: use PlatformApplication::create() --- source/Game.cpp | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/source/Game.cpp b/source/Game.cpp index e8ff9c2..573b5af 100644 --- a/source/Game.cpp +++ b/source/Game.cpp @@ -4,27 +4,18 @@ #include #include #include +#include #include +#include #include -// TODO: move this to Application::create() -#ifdef _WIN32 -#include -typedef sp::Win32Application ApplicationType; -#elif defined(__linux__) || defined(unix) || defined(__unix) || defined(__unix__) -#include -typedef sp::UnixApplication ApplicationType; -#else -#error "No Application implementation exists" -#endif - namespace sp { Game::Game() : m_running(false) { - m_platform = new ApplicationType(); + m_platform = PlatformApplication::create(); m_graphics = new Graphics(m_platform); m_input = new InputModule(&m_platform->getInput()); m_messageHandler = new MessageHandler(); From 81c7e34c581749558164bfad370d35d0442592b9 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sat, 26 Dec 2020 17:25:25 +0100 Subject: [PATCH 53/58] Use SPECTRE_PLATFORM_* defines instead of raw compiler ones. --- source/Display/GLContext.cpp | 4 ++-- source/Platform/PlatformApplication.cpp | 4 ++-- source/Platform/PlatformDisplay.cpp | 4 ++-- source/System/MessageQueue.cpp | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/source/Display/GLContext.cpp b/source/Display/GLContext.cpp index 912c9ff..2c812dc 100644 --- a/source/Display/GLContext.cpp +++ b/source/Display/GLContext.cpp @@ -1,10 +1,10 @@ #include -#ifdef _WIN32 +#ifdef SPECTRE_PLATFORM_WIN #include typedef sp::Win32GLContext ContextType; -#elif defined(__linux__) || defined(unix) || defined(__unix) || defined(__unix__) +#elif SPECTRE_PLATFORM_UNIX #include typedef sp::GLXContext ContextType; #else diff --git a/source/Platform/PlatformApplication.cpp b/source/Platform/PlatformApplication.cpp index 02076a0..9bd32b3 100644 --- a/source/Platform/PlatformApplication.cpp +++ b/source/Platform/PlatformApplication.cpp @@ -1,10 +1,10 @@ #include "PlatformApplication.h" -#ifdef _WIN32 +#ifdef SPECTRE_PLATFORM_WIN #include typedef sp::Win32Application ApplicationType; -#elif defined(__linux__) || defined(unix) || defined(__unix) || defined(__unix__) +#elif SPECTRE_PLATFORM_UNIX #include typedef sp::UnixApplication ApplicationType; #else diff --git a/source/Platform/PlatformDisplay.cpp b/source/Platform/PlatformDisplay.cpp index 3298b98..4cfb3c7 100644 --- a/source/Platform/PlatformDisplay.cpp +++ b/source/Platform/PlatformDisplay.cpp @@ -2,10 +2,10 @@ #include #include "PlatformDisplay.h" -#ifdef _WIN32 +#ifdef SPECTRE_PLATFORM_WIN #include typedef sp::Win32Display DisplayType; -#elif defined(__linux__) || defined(unix) || defined(__unix) || defined(__unix__) +#elif SPECTRE_PLATFORM_UNIX #include typedef sp::X11Display DisplayType; #else diff --git a/source/System/MessageQueue.cpp b/source/System/MessageQueue.cpp index 3550e36..57f4fa4 100644 --- a/source/System/MessageQueue.cpp +++ b/source/System/MessageQueue.cpp @@ -1,10 +1,10 @@ #include -#ifdef _WIN32 +#ifdef SPECTRE_PLATFORM_WIN #include typedef sp::Win32EventQueue ImplType; -#elif defined(__linux__) || defined(unix) || defined(__unix) || defined(__unix__) +#elif SPECTRE_PLATFORM_UNIX #include typedef sp::X11EventQueue ImplType; #else From c0827008915805915d7a4d2cd13017eca818906e Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sat, 26 Dec 2020 17:30:32 +0100 Subject: [PATCH 54/58] include/Spectre/Input/Mouse.h rename Button1,Button2 to XButton1 and XButton2 Button1 and Button2 are defined by Xlib. So lets change our ones to avoid headache. --- include/Spectre/Input/Mouse.h | 4 ++-- source/Input/Mouse.cpp | 4 ++-- source/Platform/Win32/Win32Mouse.cpp | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/Spectre/Input/Mouse.h b/include/Spectre/Input/Mouse.h index 9140b7a..949638e 100644 --- a/include/Spectre/Input/Mouse.h +++ b/include/Spectre/Input/Mouse.h @@ -16,8 +16,8 @@ public : Left, Right, Middle, - Button1, - Button2, + XButton1, + XButton2, NUM_MBUTTONS }; diff --git a/source/Input/Mouse.cpp b/source/Input/Mouse.cpp index 3b58f0e..e939583 100644 --- a/source/Input/Mouse.cpp +++ b/source/Input/Mouse.cpp @@ -10,8 +10,8 @@ Mouse::~Mouse() std::string Mouse::getButtonName(Button button) { switch(button) { - case Button::Button1 : return "Button1"; - case Button::Button2 : return "Button2"; + case Button::XButton1 : return "XButton1"; + case Button::XButton2 : return "XButton2"; case Button::Left : return "Left"; case Button::Right : return "Right"; case Button::Middle : return "Middle"; diff --git a/source/Platform/Win32/Win32Mouse.cpp b/source/Platform/Win32/Win32Mouse.cpp index 3ad6a41..61a49da 100644 --- a/source/Platform/Win32/Win32Mouse.cpp +++ b/source/Platform/Win32/Win32Mouse.cpp @@ -46,8 +46,8 @@ bool Win32Mouse::isButtonDown(Mouse::Button button) const case Mouse::Left : btn = GetSystemMetrics(SM_SWAPBUTTON) ? VK_RBUTTON : VK_LBUTTON; break; case Mouse::Right : btn = GetSystemMetrics(SM_SWAPBUTTON) ? VK_LBUTTON : VK_RBUTTON; break; case Mouse::Middle : btn = VK_MBUTTON; break; - case Mouse::Button1 : btn = VK_XBUTTON1; break; - case Mouse::Button2 : btn = VK_XBUTTON2; break; + case Mouse::XButton1 : btn = VK_XBUTTON1; break; + case Mouse::XButton2 : btn = VK_XBUTTON2; break; default: btn = 0; } @@ -109,7 +109,7 @@ bool Win32Mouse::handleMessage(MSG msg, Event& event) case WM_XBUTTONUP : case WM_XBUTTONDOWN : event.mouseButton.button = GET_XBUTTON_WPARAM(msg.wParam) == XBUTTON1 - ? Mouse::Button::Button1 : Mouse::Button::Button2; + ? Mouse::Button::XButton1 : Mouse::Button::XButton2; event.mouseButton.pressed = msg.message == WM_XBUTTONDOWN; return true; From f6aa0246d30c69db4f20f4ed3212a8af942330fc Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 27 Dec 2020 18:12:09 +0100 Subject: [PATCH 55/58] source/Platform/Unix/X11Mouse.cpp: implement hack for XButton1 and 2. --- source/Platform/Unix/X11Mouse.cpp | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/source/Platform/Unix/X11Mouse.cpp b/source/Platform/Unix/X11Mouse.cpp index cabbedc..f4bd651 100644 --- a/source/Platform/Unix/X11Mouse.cpp +++ b/source/Platform/Unix/X11Mouse.cpp @@ -5,8 +5,17 @@ #include "X11Display.h" #include "X11Mouse.h" +#define XBUTTON1BIT (1<<0) +#define XBUTTON2BIT (1<<1) + namespace sp { +namespace _priv { + + // Variable to handle extra button state (not queryable in xlib) + unsigned int xstate = 0; +} + X11Mouse::X11Mouse() : m_btn_state(0) { @@ -35,8 +44,6 @@ bool X11Mouse::isButtonDown(Mouse::Button button) const return false; } - // TODO: Button1 and 2 is defined in x11 and - // therefore clashes with Mouse::Button::Button1 and 2. switch(button) { case Mouse::Button::Left : return m_btn_state & Button1Mask; @@ -44,6 +51,10 @@ bool X11Mouse::isButtonDown(Mouse::Button button) const return m_btn_state & Button3Mask; case Mouse::Button::Middle : return m_btn_state & Button2Mask; + case Mouse::Button::XButton1 : + return _priv::xstate & XBUTTON1BIT; + case Mouse::Button::XButton2 : + return _priv::xstate & XBUTTON2BIT; default : return false; } @@ -82,6 +93,11 @@ void X11Mouse::updateFocusedWindow() m_win = focus ? (::Window) focus->getHandle() : 0; } +#define SETXSTATE(bit) \ + _priv::xstate = (xevent->type == ButtonPress) \ + ? _priv::xstate | (bit) \ + : _priv::xstate & ~(bit) + bool X11Mouse::handleMessage(XEvent* xevent, Event& event) { if (xevent->type == MotionNotify) { @@ -99,9 +115,10 @@ bool X11Mouse::handleMessage(XEvent* xevent, Event& event) case Button1 : trans = Mouse::Button::Left; break; case Button2 : trans = Mouse::Button::Middle; break; case Button3 : trans = Mouse::Button::Right; break; - // TODO: name clash, need to rename Mouse::Button enums. - // case Button4 : trans = Mouse::Button::Button1; break; // clashes with X11's "Button1" define. - // case Button5 : trans = Mouse::Button::Button2; break; // clashes with X11's "Button2" define. + // Xlib do not support querying of button 8 and 9. + // so we have to fake it. + case 8 : trans = Mouse::Button::XButton1; SETXSTATE(XBUTTON1BIT); break; + case 9 : trans = Mouse::Button::XButton2; SETXSTATE(XBUTTON2BIT); break; } if (trans != Mouse::Button::Unknown) { From 845b93fb4844e7d69ebde312de6013c7dc138cc9 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Mon, 28 Dec 2020 18:38:27 +0100 Subject: [PATCH 56/58] source/Platform/Win32/Win32Display.cpp: DisplayDecorate::None has changed to DisplayDecorate::Empty --- source/Platform/Win32/Win32Display.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Platform/Win32/Win32Display.cpp b/source/Platform/Win32/Win32Display.cpp index de68f77..89bedd0 100644 --- a/source/Platform/Win32/Win32Display.cpp +++ b/source/Platform/Win32/Win32Display.cpp @@ -246,7 +246,7 @@ DWORD Win32Display::getWin32Flags(unsigned int flags) { DWORD win32_flags = WS_VISIBLE; - if (flags == DisplayDecorate::None) { + if (flags == DisplayDecorate::Empty) { win32_flags |= WS_POPUP; } else { if (flags & DisplayDecorate::Menu) { From d48cc650a8afbf2842c3390a466afcd7dd4be3d2 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Mon, 28 Dec 2020 18:39:16 +0100 Subject: [PATCH 57/58] source/Platform/PlatformApplication.cpp: ApplicationType is defined by some Win32 headers. --- source/Platform/PlatformApplication.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/Platform/PlatformApplication.cpp b/source/Platform/PlatformApplication.cpp index 9bd32b3..f50e54b 100644 --- a/source/Platform/PlatformApplication.cpp +++ b/source/Platform/PlatformApplication.cpp @@ -3,10 +3,10 @@ #ifdef SPECTRE_PLATFORM_WIN #include -typedef sp::Win32Application ApplicationType; +typedef sp::Win32Application ApplicationImpl; #elif SPECTRE_PLATFORM_UNIX #include -typedef sp::UnixApplication ApplicationType; +typedef sp::UnixApplication ApplicationImpl; #else #error "No Application implementation exists" #endif @@ -15,7 +15,7 @@ namespace sp { PlatformApplication* PlatformApplication::create() { - return new ApplicationType; + return new ApplicationImpl; } } // namespace sp From a172fbb323e8af2e1636da5bb2d4c541e297d597 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Mon, 28 Dec 2020 18:41:16 +0100 Subject: [PATCH 58/58] engine.build.lua: Fix local variable inside if statement. --- engine.build.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine.build.lua b/engine.build.lua index 82f6200..ef73c5d 100644 --- a/engine.build.lua +++ b/engine.build.lua @@ -57,7 +57,7 @@ local platform_common_module = Module("source/Platform", { }) if TARGET_OS == "Win32" then - local platform_spec_module = Module("source/Platform/Win32", { + platform_spec_module = Module("source/Platform/Win32", { "Win32Application.cpp", "Win32Display.cpp", "Win32GLContext.cpp",