From 9e44f7b1346771a49034eff8b27c80930b7a07c3 Mon Sep 17 00:00:00 2001 From: Giorgio Marcias Date: Wed, 8 Jun 2016 07:15:42 +0200 Subject: [PATCH 01/17] Added glfwSetWindowMonitor --- include/glfwm/window.hpp | 21 +++++++++++++++++++++ src/window.cpp | 29 +++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/include/glfwm/window.hpp b/include/glfwm/window.hpp index d43974a..3ac6393 100644 --- a/include/glfwm/window.hpp +++ b/include/glfwm/window.hpp @@ -286,6 +286,27 @@ namespace glfwm { */ GLFWmonitor * getMonitor() const; + /** + * @brief The setMonitor method sets this window at full-screen (if monitor != nullptr) or windowed (otherwise). + * + * When setting a monitor, this function updates the width, height and refresh rate of the desired video mode + * and switches to the video mode closest to it. + * The window position is ignored when setting a monitor. + * When the monitor is nullptr, the position, width and height are used to place the window client area. + * The refresh rate is ignored when no monitor is specified. + * If you only wish to update the resolution of a full screen window or the size of a windowed mode window, see setSize. + * When a window transitions from full screen to windowed mode, this function restores any previous window settings + * such as whether it is decorated, floating, resizable, has size or aspect ratio limits, etc.. + * + * @param monitor The desired monitor, or nullptr to set windowed mode. + * @param xpos The desired x-coordinate of the upper-left corner of the client area. + * @param ypos The desired y-coordinate of the upper-left corner of the client area. + * @param width The desired with, in screen coordinates, of the client area or video mode. + * @param height The desired height, in screen coordinates, of the client area or video mode. + * @param refreshRate The desired refresh rate, in Hz, of the video mode, or GLFW_DONT_CARE. + */ + void setMonitor(GLFWmonitor *monitor, int xpos, int ypos, int width, int height, int refreshRate); + /** * @brief The getAttribute method returns this window attributes. See GLFW. * @param attribute The attribute to read. diff --git a/src/window.cpp b/src/window.cpp index bb7bc20..ecf8321 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -567,6 +567,35 @@ namespace glfwm { return nullptr; } + /** + * @brief The setMonitor method sets this window at full-screen (if monitor != nullptr) or windowed (otherwise). + * + * When setting a monitor, this function updates the width, height and refresh rate of the desired video mode + * and switches to the video mode closest to it. + * The window position is ignored when setting a monitor. + * When the monitor is nullptr, the position, width and height are used to place the window client area. + * The refresh rate is ignored when no monitor is specified. + * If you only wish to update the resolution of a full screen window or the size of a windowed mode window, see setSize. + * When a window transitions from full screen to windowed mode, this function restores any previous window settings + * such as whether it is decorated, floating, resizable, has size or aspect ratio limits, etc.. + * + * @param monitor The desired monitor, or nullptr to set windowed mode. + * @param xpos The desired x-coordinate of the upper-left corner of the client area. + * @param ypos The desired y-coordinate of the upper-left corner of the client area. + * @param width The desired with, in screen coordinates, of the client area or video mode. + * @param height The desired height, in screen coordinates, of the client area or video mode. + * @param refreshRate The desired refresh rate, in Hz, of the video mode, or GLFW_DONT_CARE. + */ + void Window::setMonitor(GLFWmonitor *monitor, int xpos, int ypos, int width, int height, int refreshRate) + { +#ifndef NO_MULTITHREADING + // acquire ownership + std::lock_guard lock(mutexes[sharedMutexID].mutex); +#endif + if (glfwWindow) + glfwSetWindowMonitor(glfwWindow, monitor, xpos, ypos, width, height, refreshRate); + } + /** * @brief The getAttribute method returns this window attributes. See GLFW. * @param attribute The attribute to read. From 57afe03ad2584285d71b93756a9d73432c128051 Mon Sep 17 00:00:00 2001 From: Giorgio Marcias Date: Wed, 8 Jun 2016 07:19:13 +0200 Subject: [PATCH 02/17] Added glfwMaximizeWindow --- include/glfwm/window.hpp | 6 ++++++ src/window.cpp | 14 ++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/include/glfwm/window.hpp b/include/glfwm/window.hpp index 3ac6393..d4a150e 100644 --- a/include/glfwm/window.hpp +++ b/include/glfwm/window.hpp @@ -255,6 +255,12 @@ namespace glfwm { */ void setCursorPosition(double x, double y); + /** + * @brief The maximize method maximizes the specified window if it was previously not maximized. + * If the window is already maximized, this function does nothing. + */ + void maximize(); + /** * @brief The iconify method minimizes this window. * @note This may only be called from the main thread. diff --git a/src/window.cpp b/src/window.cpp index ecf8321..05f5166 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -496,6 +496,20 @@ namespace glfwm { glfwSetCursorPos(glfwWindow, x, y); } + /** + * @brief The maximize method maximizes the specified window if it was previously not maximized. + * If the window is already maximized, this function does nothing. + */ + void Window::maximize() + { +#ifndef NO_MULTITHREADING + // acquire ownership + std::lock_guard lock(mutexes[sharedMutexID].mutex); +#endif + if (glfwWindow) + glfwMaximizeWindow(glfwWindow); + } + /** * @brief The iconify method minimizes this window. * @note This may only be called from the main thread. From 299d8581da854f48364f30dfff290e803824fb86 Mon Sep 17 00:00:00 2001 From: Giorgio Marcias Date: Wed, 8 Jun 2016 07:27:42 +0200 Subject: [PATCH 03/17] Added glfwFocusWindow --- include/glfwm/window.hpp | 46 +++++++++++++++++++++------------- src/window.cpp | 54 +++++++++++++++++++++++++++------------- 2 files changed, 66 insertions(+), 34 deletions(-) diff --git a/include/glfwm/window.hpp b/include/glfwm/window.hpp index d4a150e..77a8a6e 100644 --- a/include/glfwm/window.hpp +++ b/include/glfwm/window.hpp @@ -256,8 +256,9 @@ namespace glfwm { void setCursorPosition(double x, double y); /** - * @brief The maximize method maximizes the specified window if it was previously not maximized. - * If the window is already maximized, this function does nothing. + * @brief The maximize method maximizes the specified window if it was previously not maximized. + * If the window is already maximized, this function does nothing. + * @note This may only be called from the main thread. */ void maximize(); @@ -285,6 +286,16 @@ namespace glfwm { */ void show(); + /** + * @brief The focus method brings the specified window to front and sets input focus. By default, + * both windowed and full screen mode windows are focused when initially created. Set the GLFW_FOCUSED to disable this behavior. + * @note The window should already be visible and not iconified. Do not use this function to steal focus + * from other applications unless you are certain that is what the user wants. + * Focus stealing can be extremely disruptive. + * This may only be called from the main thread. + */ + void focus(); + /** * @brief The getMonitor method returns the GLFWMonitor this window uses in fullscreen. * @return This window monitor. @@ -293,23 +304,24 @@ namespace glfwm { GLFWmonitor * getMonitor() const; /** - * @brief The setMonitor method sets this window at full-screen (if monitor != nullptr) or windowed (otherwise). + * @brief The setMonitor method sets this window at full-screen (if monitor != nullptr) or windowed (otherwise). * - * When setting a monitor, this function updates the width, height and refresh rate of the desired video mode - * and switches to the video mode closest to it. - * The window position is ignored when setting a monitor. - * When the monitor is nullptr, the position, width and height are used to place the window client area. - * The refresh rate is ignored when no monitor is specified. - * If you only wish to update the resolution of a full screen window or the size of a windowed mode window, see setSize. - * When a window transitions from full screen to windowed mode, this function restores any previous window settings - * such as whether it is decorated, floating, resizable, has size or aspect ratio limits, etc.. + * When setting a monitor, this function updates the width, height and refresh rate of the desired video mode + * and switches to the video mode closest to it. + * The window position is ignored when setting a monitor. + * When the monitor is nullptr, the position, width and height are used to place the window client area. + * The refresh rate is ignored when no monitor is specified. + * If you only wish to update the resolution of a full screen window or the size of a windowed mode window, see setSize. + * When a window transitions from full screen to windowed mode, this function restores any previous window settings + * such as whether it is decorated, floating, resizable, has size or aspect ratio limits, etc.. * - * @param monitor The desired monitor, or nullptr to set windowed mode. - * @param xpos The desired x-coordinate of the upper-left corner of the client area. - * @param ypos The desired y-coordinate of the upper-left corner of the client area. - * @param width The desired with, in screen coordinates, of the client area or video mode. - * @param height The desired height, in screen coordinates, of the client area or video mode. - * @param refreshRate The desired refresh rate, in Hz, of the video mode, or GLFW_DONT_CARE. + * @param monitor The desired monitor, or nullptr to set windowed mode. + * @param xpos The desired x-coordinate of the upper-left corner of the client area. + * @param ypos The desired y-coordinate of the upper-left corner of the client area. + * @param width The desired with, in screen coordinates, of the client area or video mode. + * @param height The desired height, in screen coordinates, of the client area or video mode. + * @param refreshRate The desired refresh rate, in Hz, of the video mode, or GLFW_DONT_CARE. + * @note This may only be called from the main thread. */ void setMonitor(GLFWmonitor *monitor, int xpos, int ypos, int width, int height, int refreshRate); diff --git a/src/window.cpp b/src/window.cpp index 05f5166..2fdcfb6 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -497,8 +497,9 @@ namespace glfwm { } /** - * @brief The maximize method maximizes the specified window if it was previously not maximized. - * If the window is already maximized, this function does nothing. + * @brief The maximize method maximizes the specified window if it was previously not maximized. + * If the window is already maximized, this function does nothing. + * @note This may only be called from the main thread. */ void Window::maximize() { @@ -566,6 +567,24 @@ namespace glfwm { glfwShowWindow(glfwWindow); } + /** + * @brief The focus method brings the specified window to front and sets input focus. By default, + * both windowed and full screen mode windows are focused when initially created. Set the GLFW_FOCUSED to disable this behavior. + * @note The window should already be visible and not iconified. Do not use this function to steal focus + * from other applications unless you are certain that is what the user wants. + * Focus stealing can be extremely disruptive. + * This may only be called from the main thread. + */ + void Window::focus() + { +#ifndef NO_MULTITHREADING + // acquire ownership + std::lock_guard lock(mutexes[sharedMutexID].mutex); +#endif + if (glfwWindow) + glfwFocusWindow(glfwWindow); + } + /** * @brief The getMonitor method returns the GLFWMonitor this window uses in fullscreen. * @return This window monitor. @@ -582,23 +601,24 @@ namespace glfwm { } /** - * @brief The setMonitor method sets this window at full-screen (if monitor != nullptr) or windowed (otherwise). + * @brief The setMonitor method sets this window at full-screen (if monitor != nullptr) or windowed (otherwise). * - * When setting a monitor, this function updates the width, height and refresh rate of the desired video mode - * and switches to the video mode closest to it. - * The window position is ignored when setting a monitor. - * When the monitor is nullptr, the position, width and height are used to place the window client area. - * The refresh rate is ignored when no monitor is specified. - * If you only wish to update the resolution of a full screen window or the size of a windowed mode window, see setSize. - * When a window transitions from full screen to windowed mode, this function restores any previous window settings - * such as whether it is decorated, floating, resizable, has size or aspect ratio limits, etc.. + * When setting a monitor, this function updates the width, height and refresh rate of the desired video mode + * and switches to the video mode closest to it. + * The window position is ignored when setting a monitor. + * When the monitor is nullptr, the position, width and height are used to place the window client area. + * The refresh rate is ignored when no monitor is specified. + * If you only wish to update the resolution of a full screen window or the size of a windowed mode window, see setSize. + * When a window transitions from full screen to windowed mode, this function restores any previous window settings + * such as whether it is decorated, floating, resizable, has size or aspect ratio limits, etc.. * - * @param monitor The desired monitor, or nullptr to set windowed mode. - * @param xpos The desired x-coordinate of the upper-left corner of the client area. - * @param ypos The desired y-coordinate of the upper-left corner of the client area. - * @param width The desired with, in screen coordinates, of the client area or video mode. - * @param height The desired height, in screen coordinates, of the client area or video mode. - * @param refreshRate The desired refresh rate, in Hz, of the video mode, or GLFW_DONT_CARE. + * @param monitor The desired monitor, or nullptr to set windowed mode. + * @param xpos The desired x-coordinate of the upper-left corner of the client area. + * @param ypos The desired y-coordinate of the upper-left corner of the client area. + * @param width The desired with, in screen coordinates, of the client area or video mode. + * @param height The desired height, in screen coordinates, of the client area or video mode. + * @param refreshRate The desired refresh rate, in Hz, of the video mode, or GLFW_DONT_CARE. + * @note This may only be called from the main thread. */ void Window::setMonitor(GLFWmonitor *monitor, int xpos, int ypos, int width, int height, int refreshRate) { From dfdaa2c2b8c55edb4a28bae49f8fd4e983a2d5dd Mon Sep 17 00:00:00 2001 From: Giorgio Marcias Date: Wed, 8 Jun 2016 07:38:35 +0200 Subject: [PATCH 04/17] Added glfwSetWindowSizeLimits --- include/glfwm/window.hpp | 21 ++++++++++++++++++++- src/window.cpp | 28 +++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/include/glfwm/window.hpp b/include/glfwm/window.hpp index 77a8a6e..48f7e02 100644 --- a/include/glfwm/window.hpp +++ b/include/glfwm/window.hpp @@ -182,6 +182,25 @@ namespace glfwm { */ void setSize(const int width, const int height); + /** + * @brief The setSizeLimits method sets the size limits of the client area of the specified window. + * + * If the window is full screen, the size limits only take effect once it is made windowed. + * If the window is not resizable, this function does nothing. + * The size limits are applied immediately to a windowed mode window and may cause it to be resized. + * The maximum dimensions must be greater than or equal to the minimum dimensions and all must be + * greater than or equal to zero. + * + * @param minWidth The minimum width, in screen coordinates, of the client area, or GLFW_DONT_CARE. + * @param minHeight The minimum height, in screen coordinates, of the client area, or GLFW_DONT_CARE. + * @param maxWidth The maximum width, in screen coordinates, of the client area, or GLFW_DONT_CARE. + * @param maxHeight The maximum height, in screen coordinates, of the client area, or GLFW_DONT_CARE. + * @note If you set size limits and an aspect ratio that conflict, the results are undefined. + * This may only be called from the main thread. + */ + void setSizeLimits(const int minWidth, const int minHeight, const int maxWidth, const int maxHeight); + + /** * @brief The getFramebufferSize method returns the width and height of this window framebuffer. * @param width The width of this window framebuffer. @@ -323,7 +342,7 @@ namespace glfwm { * @param refreshRate The desired refresh rate, in Hz, of the video mode, or GLFW_DONT_CARE. * @note This may only be called from the main thread. */ - void setMonitor(GLFWmonitor *monitor, int xpos, int ypos, int width, int height, int refreshRate); + void setMonitor(GLFWmonitor *monitor, const int xpos, const int ypos, const int width, const int height, const int refreshRate); /** * @brief The getAttribute method returns this window attributes. See GLFW. diff --git a/src/window.cpp b/src/window.cpp index 2fdcfb6..b929e91 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -343,6 +343,32 @@ namespace glfwm { glfwSetWindowSize(glfwWindow, width, height); } + /** + * @brief The setSizeLimits method sets the size limits of the client area of the specified window. + * + * If the window is full screen, the size limits only take effect once it is made windowed. + * If the window is not resizable, this function does nothing. + * The size limits are applied immediately to a windowed mode window and may cause it to be resized. + * The maximum dimensions must be greater than or equal to the minimum dimensions and all must be + * greater than or equal to zero. + * + * @param minWidth The minimum width, in screen coordinates, of the client area, or GLFW_DONT_CARE. + * @param minHeight The minimum height, in screen coordinates, of the client area, or GLFW_DONT_CARE. + * @param maxWidth The maximum width, in screen coordinates, of the client area, or GLFW_DONT_CARE. + * @param maxHeight The maximum height, in screen coordinates, of the client area, or GLFW_DONT_CARE. + * @note If you set size limits and an aspect ratio that conflict, the results are undefined. + * This may only be called from the main thread. + */ + void Window::setSizeLimits(const int minWidth, const int minHeight, const int maxWidth, const int maxHeight) + { +#ifndef NO_MULTITHREADING + // acquire ownership + std::lock_guard lock(mutexes[sharedMutexID].mutex); +#endif + if (glfwWindow) + glfwSetWindowSizeLimits(glfwWindow, minWidth, minHeight, maxWidth, maxHeight); + } + /** * @brief The getFramebufferSize method returns the width and height of this window framebuffer. * @param width The width of this window framebuffer. @@ -620,7 +646,7 @@ namespace glfwm { * @param refreshRate The desired refresh rate, in Hz, of the video mode, or GLFW_DONT_CARE. * @note This may only be called from the main thread. */ - void Window::setMonitor(GLFWmonitor *monitor, int xpos, int ypos, int width, int height, int refreshRate) + void Window::setMonitor(GLFWmonitor *monitor, const int xpos, const int ypos, const int width, const int height, const int refreshRate) { #ifndef NO_MULTITHREADING // acquire ownership From 74d428f8a55fdf7805c23e106f5eafe1b55f72b8 Mon Sep 17 00:00:00 2001 From: Giorgio Marcias Date: Wed, 8 Jun 2016 07:43:41 +0200 Subject: [PATCH 05/17] Added glfwSetWindowAspectRatio --- include/glfwm/window.hpp | 16 ++++++++++++++++ src/window.cpp | 25 +++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/include/glfwm/window.hpp b/include/glfwm/window.hpp index 48f7e02..99e1933 100644 --- a/include/glfwm/window.hpp +++ b/include/glfwm/window.hpp @@ -200,6 +200,22 @@ namespace glfwm { */ void setSizeLimits(const int minWidth, const int minHeight, const int maxWidth, const int maxHeight); + /** + * @brief The setAspectRatio method sets the required aspect ratio of the client area of the specified window. + * + * If the window is full screen, the aspect ratio only takes effect once it is made windowed. + * If the window is not resizable, this function does nothing. + * The aspect ratio is specified as a numerator and a denominator and both values must be greater than zero. + * For example, the common 16:9 aspect ratio is specified as 16 and 9, respectively. + * If the numerator and denominator is set to GLFW_DONT_CARE then the aspect ratio limit is disabled. + * The aspect ratio is applied immediately to a windowed mode window and may cause it to be resized. + * + * @param numerator The numerator of the desired aspect ratio, or GLFW_DONT_CARE. + * @param denominator The denominator of the desired aspect ratio, or GLFW_DONT_CARE. + * @note If you set size limits and an aspect ratio that conflict, the results are undefined. + * This may only be called from the main thread. + */ + void setAspectRatio(const int numerator, const int denominator); /** * @brief The getFramebufferSize method returns the width and height of this window framebuffer. diff --git a/src/window.cpp b/src/window.cpp index b929e91..3e7d171 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -369,6 +369,31 @@ namespace glfwm { glfwSetWindowSizeLimits(glfwWindow, minWidth, minHeight, maxWidth, maxHeight); } + /** + * @brief The setAspectRatio method sets the required aspect ratio of the client area of the specified window. + * + * If the window is full screen, the aspect ratio only takes effect once it is made windowed. + * If the window is not resizable, this function does nothing. + * The aspect ratio is specified as a numerator and a denominator and both values must be greater than zero. + * For example, the common 16:9 aspect ratio is specified as 16 and 9, respectively. + * If the numerator and denominator is set to GLFW_DONT_CARE then the aspect ratio limit is disabled. + * The aspect ratio is applied immediately to a windowed mode window and may cause it to be resized. + * + * @param numerator The numerator of the desired aspect ratio, or GLFW_DONT_CARE. + * @param denominator The denominator of the desired aspect ratio, or GLFW_DONT_CARE. + * @note If you set size limits and an aspect ratio that conflict, the results are undefined. + * This may only be called from the main thread. + */ + void Window::setAspectRatio(const int numerator, const int denominator) + { +#ifndef NO_MULTITHREADING + // acquire ownership + std::lock_guard lock(mutexes[sharedMutexID].mutex); +#endif + if (glfwWindow) + glfwSetWindowAspectRatio(glfwWindow, numerator, denominator); + } + /** * @brief The getFramebufferSize method returns the width and height of this window framebuffer. * @param width The width of this window framebuffer. From 76e2bbea3e6147e0af5bcc383fb432f33621791e Mon Sep 17 00:00:00 2001 From: Giorgio Marcias Date: Wed, 8 Jun 2016 07:56:35 +0200 Subject: [PATCH 06/17] Added glfwGetKeyName --- include/glfwm/enums.hpp | 15 +++++++++++++++ src/enums.cpp | 17 +++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/include/glfwm/enums.hpp b/include/glfwm/enums.hpp index aeda586..e2f5478 100644 --- a/include/glfwm/enums.hpp +++ b/include/glfwm/enums.hpp @@ -277,6 +277,21 @@ namespace glfwm { KEY_LAST = GLFW_KEY_LAST }; + /** + * @brief The getKeyName function returns the localized name of the specified printable key. + * This is intended for displaying key bindings to the user. + * + * If the key is KEY_UNKNOWN, the scancode is used instead, otherwise the scancode is ignored. + * If a non-printable key or (if the key is KEY_UNKNOWN) a scancode that maps to a non-printable + * key is specified, this function returns an empty string. + * + * @param k The key to query. + * @param s The scancode of the key to query. + * @return The localized name of the key. + * @note This may only be called from the main thread. + */ + std::string getKeyName(const KeyType k, const char32_t s); + /** diff --git a/src/enums.cpp b/src/enums.cpp index 99fccf4..9900e0d 100644 --- a/src/enums.cpp +++ b/src/enums.cpp @@ -49,4 +49,21 @@ namespace glfwm { return ebt; } + /** + * @brief The getKeyName function returns the localized name of the specified printable key. + * This is intended for displaying key bindings to the user. + * + * If the key is KEY_UNKNOWN, the scancode is used instead, otherwise the scancode is ignored. + * If a non-printable key or (if the key is KEY_UNKNOWN) a scancode that maps to a non-printable + * key is specified, this function returns an empty string. + * + * @param k The key to query. + * @param s The scancode of the key to query. + * @return The localized name of the key. + * @note This may only be called from the main thread. + */ + std::string getKeyName(const KeyType k, const char32_t s) + { + return glfwGetKeyName(static_cast(k), static_cast(s)); + } } From b3350b7e91b6410ff6347b5fbdf0d9d2fa16ec5e Mon Sep 17 00:00:00 2001 From: Giorgio Marcias Date: Wed, 8 Jun 2016 08:15:45 +0200 Subject: [PATCH 07/17] Added glfwSetWindowIcon --- include/glfwm/window.hpp | 32 ++++++++++++++++++++++++-------- src/window.cpp | 40 ++++++++++++++++++++++++++++++++-------- 2 files changed, 56 insertions(+), 16 deletions(-) diff --git a/include/glfwm/window.hpp b/include/glfwm/window.hpp index 99e1933..61bd5bb 100644 --- a/include/glfwm/window.hpp +++ b/include/glfwm/window.hpp @@ -275,21 +275,37 @@ namespace glfwm { void setCursor(GLFWcursor *cursor); /** - * @brief The getCursorPosition method returns the cursor position, in screen coordinates, relative to - * the upper left corner of this window. - * @param x The x-coordinate of the cursor. - * @param y The y-coordinate of the cursor. + * @brief The getCursorPosition method returns the cursor position, in screen coordinates, relative to + * the upper left corner of this window. + * @param x The x-coordinate of the cursor. + * @param y The y-coordinate of the cursor. */ void getCursorPosition(double &x, double &y) const; /** - * @brief The setCursorPosition method changes the cursor position, in screen coordinates, relative to - * the upper left corner of this window. - * @param x The new x-coordinate of the cursor. - * @param y The new y-coordinate of the cursor. + * @brief The setCursorPosition method changes the cursor position, in screen coordinates, relative to + * the upper left corner of this window. + * @param x The new x-coordinate of the cursor. + * @param y The new y-coordinate of the cursor. */ void setCursorPosition(double x, double y); + /** + * @brief The setIcon method sets the icon of this window. + * + * If passed an array of candidate images, those of or closest to the sizes desired by the system are selected. + * If no images are specified, the window reverts to its default icon. + * The desired image sizes varies depending on platform and system settings. The selected images will be rescaled + * as needed. Good sizes include 16x16, 32x32 and 48x48. + * + * @param count The number of images in the specified array, or zero to revert to the default window icon. + * @param images The images to create the icon from. This is ignored if count is zero. + * @note On Mac OS X, the window has no icon, as it is not a document window, so this function does nothing. + * The dock icon will be the same as the application bundle's icon. + * This may only be called from the main thread. + */ + void setIcon(const int count, const GLFWimage *images); + /** * @brief The maximize method maximizes the specified window if it was previously not maximized. * If the window is already maximized, this function does nothing. diff --git a/src/window.cpp b/src/window.cpp index 3e7d171..6696573 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -516,10 +516,10 @@ namespace glfwm { } /** - * @brief The getCursorPosition method returns the cursor position, in screen coordinates, relative to - * the upper left corner of this window. - * @param x The x-coordinate of the cursor. - * @param y The y-coordinate of the cursor. + * @brief The getCursorPosition method returns the cursor position, in screen coordinates, relative to + * the upper left corner of this window. + * @param x The x-coordinate of the cursor. + * @param y The y-coordinate of the cursor. */ void Window::getCursorPosition(double &x, double &y) const { @@ -532,10 +532,10 @@ namespace glfwm { } /** - * @brief The setCursorPosition method changes the cursor position, in screen coordinates, relative to - * the upper left corner of this window. - * @param x The new x-coordinate of the cursor. - * @param y The new y-coordinate of the cursor. + * @brief The setCursorPosition method changes the cursor position, in screen coordinates, relative to + * the upper left corner of this window. + * @param x The new x-coordinate of the cursor. + * @param y The new y-coordinate of the cursor. */ void Window::setCursorPosition(double x, double y) { @@ -547,6 +547,30 @@ namespace glfwm { glfwSetCursorPos(glfwWindow, x, y); } + /** + * @brief The setIcon method sets the icon of this window. + * + * If passed an array of candidate images, those of or closest to the sizes desired by the system are selected. + * If no images are specified, the window reverts to its default icon. + * The desired image sizes varies depending on platform and system settings. The selected images will be rescaled + * as needed. Good sizes include 16x16, 32x32 and 48x48. + * + * @param count The number of images in the specified array, or zero to revert to the default window icon. + * @param images The images to create the icon from. This is ignored if count is zero. + * @note On Mac OS X, the window has no icon, as it is not a document window, so this function does nothing. + * The dock icon will be the same as the application bundle's icon. + * This may only be called from the main thread. + */ + void Window::setIcon(const int count, const GLFWimage *images) + { +#ifndef NO_MULTITHREADING + // acquire ownership + std::lock_guard lock(mutexes[sharedMutexID].mutex); +#endif + if (glfwWindow) + glfwSetWindowIcon(glfwWindow, count, images); + } + /** * @brief The maximize method maximizes the specified window if it was previously not maximized. * If the window is already maximized, this function does nothing. From 7a6d6aca7caffb8ceda31ea66f3763ce1624f17e Mon Sep 17 00:00:00 2001 From: Giorgio Marcias Date: Wed, 8 Jun 2016 09:01:56 +0200 Subject: [PATCH 08/17] Added glfwCreateWindowSurface --- include/glfwm/window.hpp | 20 ++++++++++++++++++++ src/window.cpp | 29 +++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/include/glfwm/window.hpp b/include/glfwm/window.hpp index 61bd5bb..5e8fcac 100644 --- a/include/glfwm/window.hpp +++ b/include/glfwm/window.hpp @@ -427,6 +427,26 @@ namespace glfwm { */ void doneCurrentContext(); +#ifdef VK_VERSION_1_0 + /** + * @brief The createVulkanWindowSurface method creates a Vulkan surface for this window. + * + * If the Vulkan loader was not found at initialization, this function returns VK_ERROR_INITIALIZATION_FAILED + * and generates a GLFW_API_UNAVAILABLE error. Call glfwVulkanSupported to check whether the Vulkan loader was found. + * If the required window surface creation instance extensions are not available or if the specified instance was not + * created with these extensions enabled, this function returns VK_ERROR_EXTENSION_NOT_PRESENT and generates a + * GLFW_API_UNAVAILABLE error. Call glfwGetRequiredInstanceExtensions to check what instance extensions are required. + * The window surface must be destroyed before the specified Vulkan instance. It is the responsibility of the caller + * to destroy the window surface. GLFW(M) does not destroy it for you. Call vkDestroySurfaceKHR to destroy the surface. + * + * @param instance The Vulkan instance to create the surface in. + * @param allocator The allocator to use, or null_ptr to use the default allocator. + * @param surface Where to store the handle of the surface. This is set to VK_NULL_HANDLE if an error occurred. + * @return VK_SUCCESS if successful, or a Vulkan error code if an error occurred. + */ + VkResult createVulkanWindowSurface(VkInstance instance, const VkAllocationCallbacks * allocator, VkSurfaceKHR *surface); +#endif + private: diff --git a/src/window.cpp b/src/window.cpp index 6696573..eaef4d0 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -823,6 +823,35 @@ namespace glfwm { #endif } +#ifdef VK_VERSION_1_0 + /** + * @brief The createVulkanWindowSurface method creates a Vulkan surface for this window. + * + * If the Vulkan loader was not found at initialization, this function returns VK_ERROR_INITIALIZATION_FAILED + * and generates a GLFW_API_UNAVAILABLE error. Call glfwVulkanSupported to check whether the Vulkan loader was found. + * If the required window surface creation instance extensions are not available or if the specified instance was not + * created with these extensions enabled, this function returns VK_ERROR_EXTENSION_NOT_PRESENT and generates a + * GLFW_API_UNAVAILABLE error. Call glfwGetRequiredInstanceExtensions to check what instance extensions are required. + * The window surface must be destroyed before the specified Vulkan instance. It is the responsibility of the caller + * to destroy the window surface. GLFW(M) does not destroy it for you. Call vkDestroySurfaceKHR to destroy the surface. + * + * @param instance The Vulkan instance to create the surface in. + * @param allocator The allocator to use, or null_ptr to use the default allocator. + * @param surface Where to store the handle of the surface. This is set to VK_NULL_HANDLE if an error occurred. + * @return VK_SUCCESS if successful, or a Vulkan error code if an error occurred. + */ + VkResult Window::createVulkanWindowSurface(VkInstance instance, const VkAllocationCallbacks * allocator, VkSurfaceKHR *surface) + { +#ifndef NO_MULTITHREADING + // acquire ownership + std::lock_guard lock(mutexes[sharedMutexID].mutex); +#endif + if (!glfwWindow) + throw std::runtime_error(std::string("Error. GLFW window does not exist. Impossible to create Vulkan surface.")); + return glfwCreateWindowSurface(instance, glfwWindow, allocator, surface); + } +#endif + #ifndef NO_MULTITHREADING From 7cf0fafe2a0e25ff8b010810016082c7daf77da6 Mon Sep 17 00:00:00 2001 From: Giorgio Marcias Date: Wed, 8 Jun 2016 10:05:17 +0200 Subject: [PATCH 09/17] Added glfwWaitEventsTimeout --- include/glfwm/glfwm.hpp | 23 +++++++++++++++++++---- src/glfwm.cpp | 40 +++++++++++++++++++++++++++++++++------- 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/include/glfwm/glfwm.hpp b/include/glfwm/glfwm.hpp index ff9391b..1b47b8e 100644 --- a/include/glfwm/glfwm.hpp +++ b/include/glfwm/glfwm.hpp @@ -47,11 +47,26 @@ namespace glfwm { static void setHint(const int target, const int value); /** - * @brief The setPoll static method changes the current way of managing the event queue: process any event in the queue, or wait and then process them. - * @param doPoll true for processing without waiting, false for waiting and then processing. + * @brief The setPoll static method changes the current way of managing the event queue: process any event in the queue soon, + * or wait untill any events have occurred and process them. + * @param doPoll true for processing without waiting, false for waiting and then processing. */ static void setPoll(const bool doPoll); + /** + * @brief The setWaitTimeout method changes the current way of managing the event queue: process any event in the queue soon, + * or wait untill timeout has expired or any events have occurred and process them. + * @param timeout The maximum time to wait before processing the event queue. + * @note 0 corresponds to poll, infinity corresponds to wait undefinitely, k corresponds to wait k seconds. + */ + static void setWaitTimeout(const double timeout = std::numeric_limits::infinity()); + + /** + * @brief The getWaitTimeout method returns the current time to wait in the current polling events management. + * @return The current timeout. + */ + static double getWaitTimeout(); + /** * @brief The createWindow static method is a convenient way of constructing a new Window and directly registering the callbacks for the events of type eventTypes. * @param width The window width. @@ -129,9 +144,9 @@ namespace glfwm { static void inputDropCallback(GLFWwindow *glfwWindow, int count, const char **paths); #ifndef NO_MULTITHREADING - static std::atomic poll; ///< Boolean indicating the current way of managing the event queue: true - poll, false - wait. Atomic version. + static std::atomic waitTimeout; ///< Timeout for the polling event management: 0 -> poll, inf -> wait indefinitely, k -> wait k seconds. #else - static bool poll; ///< Boolean indicating the current way of managing the event queue: true - poll, false - wait. + static double waitTimeout; ///< Timeout for the polling event management: 0 -> poll, inf -> wait indefinitely, k -> wait k seconds. #endif }; diff --git a/src/glfwm.cpp b/src/glfwm.cpp index f7cc5b4..4ff0159 100644 --- a/src/glfwm.cpp +++ b/src/glfwm.cpp @@ -16,9 +16,9 @@ namespace glfwm { #ifndef NO_MULTITHREADING - std::atomic WindowManager::poll(false); + std::atomic WindowManager::waitTimeout(std::numeric_limits::infinity()); #else - bool WindowManager::poll = false; + bool WindowManager::waitTimeout = std::numeric_limits::infinity(); #endif /** @@ -58,16 +58,40 @@ namespace glfwm { } /** - * @brief The setPoll static method changes the current way of managing the event queue: process any event in the queue, or wait and then process them. - * @param doPoll true for processing without waiting, false for waiting and then processing. + * @brief The setPoll static method changes the current way of managing the event queue: process any event in the queue soon, + * or wait untill any events have occurred and process them. + * @param doPoll true for processing without waiting, false for waiting and then processing. */ void WindowManager::setPoll(const bool doPoll) { - poll = doPoll; if (doPoll) + setWaitTimeout(0.0); + else + setWaitTimeout(std::numeric_limits::infinity()); + } + + /** + * @brief The setWaitTimeout method changes the current way of managing the event queue: process any event in the queue soon, + * or wait untill timeout has expired or any events have occurred and process them. + * @param timeout The maximum time to wait before processing the event queue. + * @note 0 corresponds to poll, infinity corresponds to wait undefinitely, k corresponds to wait k seconds. + */ + void WindowManager::setWaitTimeout(const double timeout) + { + waitTimeout = timeout; + if (waitTimeout == 0.0) UpdateMap::notify(); } + /** + * @brief The getWaitTimeout method returns the current time to wait in the current polling events management. + * @return The current timeout. + */ + double WindowManager::getWaitTimeout() + { + return waitTimeout; + } + /** * @brief The createWindow static method is a convenient way of constructing a new Window and directly registering the callbacks for the events of type eventTypes. * @param width The window width. @@ -231,11 +255,13 @@ namespace glfwm { } // manage events - if (poll) { + if (waitTimeout == 0.0) { glfwPollEvents(); UpdateMap::setToUpdate(AllWindowGroupIDs, AllWindowIDs); - } else { + } else if(waitTimeout == std::numeric_limits::infinity()) { glfwWaitEvents(); + } else { + glfwWaitEventsTimeout(waitTimeout); } // check for windows to close (and detach from groups) From 0ce6f4f0ece89dfd88c9869318153de0b6a16f9d Mon Sep 17 00:00:00 2001 From: Giorgio Marcias Date: Mon, 20 Jun 2016 17:43:26 +0200 Subject: [PATCH 10/17] require glfw 3.2 --- CMakeLists.txt | 11 +++------ cmake/Modules/FindGLFW.cmake | 45 ------------------------------------ example/main.cpp | 3 +++ 3 files changed, 6 insertions(+), 53 deletions(-) delete mode 100644 cmake/Modules/FindGLFW.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 5690f39..ebc8675 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,11 +14,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.1) # GLFW -SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules ${CMAKE_MODULE_PATH}) -FIND_PACKAGE(GLFW REQUIRED) -IF(NOT GLFW_FOUND) - MESSAGE(FATAL_ERROR "GLFW not found!") -ENDIF(NOT GLFW_FOUND) +FIND_PACKAGE(glfw3 3.2 REQUIRED) OPTION(WITH_MULTITHREADING "Build GLFWM with multithreading facilities (i.e. thread-safe) or not." ON) @@ -50,13 +46,12 @@ SET_TARGET_PROPERTIES(GLFWM PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED ON) -TARGET_INCLUDE_DIRECTORIES(GLFWM PUBLIC ${GLFW_INCLUDE_DIRS}) TARGET_INCLUDE_DIRECTORIES(GLFWM PUBLIC ${HDR_DIR}/glfwm) -TARGET_LINK_LIBRARIES(GLFWM ${GLFW_LIBRARY_DIRS}/${GLFW_LIBRARIES}) +TARGET_LINK_LIBRARIES(GLFWM glfw) IF(NOT WITH_MULTITHREADING) TARGET_COMPILE_DEFINITIONS(GLFWM PRIVATE NO_MULTITHREADING) ENDIF(NOT WITH_MULTITHREADING) # expose the directories -SET(GLFWM_INCLUDE_DIRS ${GLFW_INCLUDE_DIRS} ${HDR_DIR} PARENT_SCOPE) +SET(GLFWM_INCLUDE_DIRS ${HDR_DIR} PARENT_SCOPE) SET(GLFWM_LIBRARIES GLFWM PARENT_SCOPE) diff --git a/cmake/Modules/FindGLFW.cmake b/cmake/Modules/FindGLFW.cmake deleted file mode 100644 index ee46dd6..0000000 --- a/cmake/Modules/FindGLFW.cmake +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright (c) 2015-2016 Giorgio Marcias -# -# This file is part of GLFWM, a C++11 wrapper of GLFW with -# multi-threading management (GLFW Manager). -# -# This source code is subject to zlib/libpng License. -# This software is provided 'as-is', without any express -# or implied warranty. In no event will the authors be held -# liable for any damages arising from the use of this software. -# -# Author: Giorgio Marcias -# email: marcias.giorgio@gmail.com - - - -# FindGLFW -# -------- -# -# Find the GLFW library - -FIND_PATH(GLFW_INCLUDE_DIRS - GLFW/glfw3.h - PATHS - /usr/include - /usr/local/include - /usr/X11/include - /opt/local/include - ) - -FIND_LIBRARY(GLFW_LIBRARIES - glfw glfw3 - PATHS - /usr - /usr/local - /usr/X11 - /opt/local - PATH_SUFFIXES - a - lib - lib64 - ) - -IF(GLFW_INCLUDE_DIRS AND GLFW_LIBRARIES) - SET(GLFW_FOUND TRUE) -ENDIF(GLFW_INCLUDE_DIRS AND GLFW_LIBRARIES) diff --git a/example/main.cpp b/example/main.cpp index 16693e9..b34bd22 100644 --- a/example/main.cpp +++ b/example/main.cpp @@ -37,6 +37,9 @@ #include +// Before the main header, if not in the CMakefile.txt, define any GLFW macro you need, e.g.: +//#define GLFW_INCLUDE_GLCOREARB + // Include the main header. // Depending on what you have to do (e.g. inherit some glfwm base class) you can include just any other header file. #include From a2706b9c65be02fba9018869d900a21c9e298b70 Mon Sep 17 00:00:00 2001 From: Giorgio Marcias Date: Thu, 14 Jul 2016 10:57:57 +0200 Subject: [PATCH 11/17] adding project name and version --- CMakeLists.txt | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ebc8675..63d06c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,8 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.1) +PROJECT(GLFWM 3.2) + # GLFW FIND_PACKAGE(glfw3 3.2 REQUIRED) @@ -40,18 +42,20 @@ SET(SRCS ${SRC_DIR}/window_group.cpp ${SRC_DIR}/glfwm.cpp) -ADD_LIBRARY(GLFWM ${HDRS} ${SRCS}) +ADD_LIBRARY(${PROJECT_NAME} ${HDRS} ${SRCS}) -SET_TARGET_PROPERTIES(GLFWM PROPERTIES +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED ON) -TARGET_INCLUDE_DIRECTORIES(GLFWM PUBLIC ${HDR_DIR}/glfwm) -TARGET_LINK_LIBRARIES(GLFWM glfw) +TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME} PUBLIC ${HDR_DIR}/glfwm) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} glfw) IF(NOT WITH_MULTITHREADING) - TARGET_COMPILE_DEFINITIONS(GLFWM PRIVATE NO_MULTITHREADING) + TARGET_COMPILE_DEFINITIONS(${PROJECT_NAME} PRIVATE NO_MULTITHREADING) ENDIF(NOT WITH_MULTITHREADING) # expose the directories -SET(GLFWM_INCLUDE_DIRS ${HDR_DIR} PARENT_SCOPE) -SET(GLFWM_LIBRARIES GLFWM PARENT_SCOPE) +IF(PARENT_DIRECTORY) + SET(GLFWM_INCLUDE_DIRS ${HDR_DIR} PARENT_SCOPE) + SET(GLFWM_LIBRARIES ${PROJECT_NAME} PARENT_SCOPE) +ENDIF(PARENT_DIRECTORY) From 395a9a0e5c1f9a8873d186c1ab87c7d634d0dcb0 Mon Sep 17 00:00:00 2001 From: Giorgio Marcias Date: Thu, 14 Jul 2016 19:25:40 +0200 Subject: [PATCH 12/17] made installable --- CMakeLists.txt | 96 ++++++++++++++++++++++----------- example/CMakeLists.txt | 16 +++--- example/main.cpp | 2 +- include/glfwm/drawable.hpp | 2 +- include/glfwm/enums.hpp | 2 +- include/glfwm/event.hpp | 2 +- include/glfwm/event_handler.hpp | 2 +- include/glfwm/glfwm.hpp | 2 +- include/glfwm/update_map.hpp | 2 +- include/glfwm/utility.hpp | 2 +- include/glfwm/window.hpp | 4 +- include/glfwm/window_group.hpp | 4 +- src/enums.cpp | 2 +- src/event.cpp | 2 +- src/glfwm.cpp | 2 +- src/update_map.cpp | 2 +- src/window.cpp | 2 +- src/window_group.cpp | 2 +- 18 files changed, 90 insertions(+), 58 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 63d06c2..a47ed21 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,30 +11,56 @@ # Author: Giorgio Marcias # email: marcias.giorgio@gmail.com -CMAKE_MINIMUM_REQUIRED(VERSION 3.1) +cmake_minimum_required(VERSION 3.1) -PROJECT(GLFWM 3.2) +project(glfwm VERSION 3.2 LANGUAGES CXX) # GLFW -FIND_PACKAGE(glfw3 3.2 REQUIRED) - -OPTION(WITH_MULTITHREADING "Build GLFWM with multithreading facilities (i.e. thread-safe) or not." ON) - -SET(HDR_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) -SET(HDRS - ${HDR_DIR}/glfwm/common.hpp - ${HDR_DIR}/glfwm/drawable.hpp - ${HDR_DIR}/glfwm/enums.hpp - ${HDR_DIR}/glfwm/event.hpp - ${HDR_DIR}/glfwm/event_handler.hpp - ${HDR_DIR}/glfwm/update_map.hpp - ${HDR_DIR}/glfwm/utility.hpp - ${HDR_DIR}/glfwm/window.hpp - ${HDR_DIR}/glfwm/window_group.hpp - ${HDR_DIR}/glfwm/glfwm.hpp) - -SET(SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src) -SET(SRCS +find_package(glfw3 3.2 REQUIRED) + + + +get_directory_property(GLFWM_PARENT_DIRECTORY PARENT_DIRECTORY) + + + +option(WITH_MULTITHREADING "Build GLFWM with multithreading facilities (i.e. thread-safe) or not." ON) + +if(GLFWM_PARENT_DIRECTORY) + set(MAKE_SHARED OFF) +else(GLFWM_PARENT_DIRECTORY) + set(MAKE_SHARED ON) +endif(GLFWM_PARENT_DIRECTORY) +option(BUILD_SHARED_LIBS "Build GLFWM as a shared library or a static library." ${MAKE_SHARED}) + +if(GLFWM_PARENT_DIRECTORY) + set(MAKE_INSTALL OFF) +else(GLFWM_PARENT_DIRECTORY) + set(MAKE_INSTALL ON) +endif(GLFWM_PARENT_DIRECTORY) +option(INSTALL_GLFWM "Specify whether installing GLFWM on the system or not" ${MAKE_INSTALL}) + +if(NOT GLFWM_PARENT_DIRECTORY AND NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug|Release|RelWithDebInfo|MinSizeRel." FORCE) +endif(NOT GLFWM_PARENT_DIRECTORY AND NOT CMAKE_BUILD_TYPE) + + +set(HDR_DIR_NAME "GLFWM") +set(HDR_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) +set(HDRS + ${HDR_DIR}/${HDR_DIR_NAME}/common.hpp + ${HDR_DIR}/${HDR_DIR_NAME}/drawable.hpp + ${HDR_DIR}/${HDR_DIR_NAME}/enums.hpp + ${HDR_DIR}/${HDR_DIR_NAME}/event.hpp + ${HDR_DIR}/${HDR_DIR_NAME}/event_handler.hpp + ${HDR_DIR}/${HDR_DIR_NAME}/update_map.hpp + ${HDR_DIR}/${HDR_DIR_NAME}/utility.hpp + ${HDR_DIR}/${HDR_DIR_NAME}/window.hpp + ${HDR_DIR}/${HDR_DIR_NAME}/window_group.hpp + ${HDR_DIR}/${HDR_DIR_NAME}/glfwm.hpp) + +set(SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src) +set(SRCS ${SRC_DIR}/enums.cpp ${SRC_DIR}/event.cpp ${SRC_DIR}/update_map.cpp @@ -42,20 +68,26 @@ SET(SRCS ${SRC_DIR}/window_group.cpp ${SRC_DIR}/glfwm.cpp) -ADD_LIBRARY(${PROJECT_NAME} ${HDRS} ${SRCS}) +add_library(${PROJECT_NAME} ${HDRS} ${SRCS}) -SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES +set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED ON) -TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME} PUBLIC ${HDR_DIR}/glfwm) -TARGET_LINK_LIBRARIES(${PROJECT_NAME} glfw) -IF(NOT WITH_MULTITHREADING) - TARGET_COMPILE_DEFINITIONS(${PROJECT_NAME} PRIVATE NO_MULTITHREADING) -ENDIF(NOT WITH_MULTITHREADING) +target_include_directories(${PROJECT_NAME} PUBLIC ${HDR_DIR}) +target_link_libraries(${PROJECT_NAME} glfw) +if(NOT WITH_MULTITHREADING) + target_compile_definitions(${PROJECT_NAME} PRIVATE NO_MULTITHREADING) +endif(NOT WITH_MULTITHREADING) # expose the directories -IF(PARENT_DIRECTORY) - SET(GLFWM_INCLUDE_DIRS ${HDR_DIR} PARENT_SCOPE) - SET(GLFWM_LIBRARIES ${PROJECT_NAME} PARENT_SCOPE) -ENDIF(PARENT_DIRECTORY) +if(GLFWM_PARENT_DIRECTORY) + set(GLFWM_TARGET ${PROJECT_NAME} PARENT_SCOPE) + set(GLFWM_INCLUDE_DIRS ${HDR_DIR} PARENT_SCOPE) + set(GLFWM_LIBRARIES ${PROJECT_NAME} PARENT_SCOPE) +endif(GLFWM_PARENT_DIRECTORY) + +if(INSTALL_GLFWM) + install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib) + install(DIRECTORY ${HDR_DIR}/${HDR_DIR_NAME} DESTINATION include) +endif(INSTALL_GLFWM) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 33ae06d..1d8f310 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -11,21 +11,21 @@ # Author: Giorgio Marcias # email: marcias.giorgio@gmail.com -PROJECT(glfwmExample) -CMAKE_MINIMUM_REQUIRED(VERSION 3.1) +cmake_minimum_required(VERSION 3.1) +project(glfwmExample LANGUAGES CXX) # GLFWM # if you want to use glfwm without multi-threading, uncomment the following line -#SET(WITH_MULTITHREADING OFF CACHE BOOL "Build GLFWM with multithreading facilities (i.e. thread-safe) or not.") -ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_CURRENT_BINARY_DIR}/glfwm) +#option(WITH_MULTITHREADING "Build GLFWM with multithreading facilities (i.e. thread-safe) or not." OFF) +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_CURRENT_BINARY_DIR}/glfwm) # create the executable -ADD_EXECUTABLE(${PROJECT_NAME} main.cpp) +add_executable(${PROJECT_NAME} main.cpp) -SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES +set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED ON) # link libraries -TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME} PUBLIC ${GLFWM_INCLUDE_DIRS}) -TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${GLFWM_LIBRARIES}) +target_include_directories(${PROJECT_NAME} PUBLIC ${GLFWM_INCLUDE_DIRS}) +target_link_libraries(${PROJECT_NAME} ${GLFWM_LIBRARIES}) diff --git a/example/main.cpp b/example/main.cpp index b34bd22..68488f2 100644 --- a/example/main.cpp +++ b/example/main.cpp @@ -42,7 +42,7 @@ // Include the main header. // Depending on what you have to do (e.g. inherit some glfwm base class) you can include just any other header file. -#include +#include // This class responsible of drawing the content of a window must inherit glfwm::Drawable and // implement its draw abstract method. Note that the parameter id can be used to retrieve diff --git a/include/glfwm/drawable.hpp b/include/glfwm/drawable.hpp index afdec3e..794545e 100644 --- a/include/glfwm/drawable.hpp +++ b/include/glfwm/drawable.hpp @@ -14,7 +14,7 @@ #ifndef GLFWM_DRAWABLE_HPP #define GLFWM_DRAWABLE_HPP -#include "enums.hpp" +#include namespace glfwm { diff --git a/include/glfwm/enums.hpp b/include/glfwm/enums.hpp index e2f5478..b1e5dc0 100644 --- a/include/glfwm/enums.hpp +++ b/include/glfwm/enums.hpp @@ -14,7 +14,7 @@ #ifndef GLFWM_ENUMS_HPP #define GLFWM_ENUMS_HPP -#include "utility.hpp" +#include namespace glfwm { diff --git a/include/glfwm/event.hpp b/include/glfwm/event.hpp index a526e71..0ecdc6a 100644 --- a/include/glfwm/event.hpp +++ b/include/glfwm/event.hpp @@ -14,7 +14,7 @@ #ifndef GLFWM_EVENT_HPP #define GLFWM_EVENT_HPP -#include "enums.hpp" +#include namespace glfwm { diff --git a/include/glfwm/event_handler.hpp b/include/glfwm/event_handler.hpp index 1000f2e..22c5d82 100644 --- a/include/glfwm/event_handler.hpp +++ b/include/glfwm/event_handler.hpp @@ -14,7 +14,7 @@ #ifndef GLFWM_EVENT_HANDLER_HPP #define GLFWM_EVENT_HANDLER_HPP -#include "event.hpp" +#include namespace glfwm { diff --git a/include/glfwm/glfwm.hpp b/include/glfwm/glfwm.hpp index 1b47b8e..101a6d3 100644 --- a/include/glfwm/glfwm.hpp +++ b/include/glfwm/glfwm.hpp @@ -14,7 +14,7 @@ #ifndef GLFWM_HPP #define GLFWM_HPP -#include "window_group.hpp" +#include namespace glfwm { diff --git a/include/glfwm/update_map.hpp b/include/glfwm/update_map.hpp index 395e551..7feec35 100644 --- a/include/glfwm/update_map.hpp +++ b/include/glfwm/update_map.hpp @@ -14,7 +14,7 @@ #ifndef GLFWM_UPDATE_MAP_HPP #define GLFWM_UPDATE_MAP_HPP -#include "enums.hpp" +#include namespace glfwm { diff --git a/include/glfwm/utility.hpp b/include/glfwm/utility.hpp index 1ae12c4..46b0c21 100644 --- a/include/glfwm/utility.hpp +++ b/include/glfwm/utility.hpp @@ -14,7 +14,7 @@ #ifndef GLFWM_UTILITY_HPP #define GLFWM_UTILITY_HPP -#include "common.hpp" +#include namespace glfwm { diff --git a/include/glfwm/window.hpp b/include/glfwm/window.hpp index 5e8fcac..ab7d118 100644 --- a/include/glfwm/window.hpp +++ b/include/glfwm/window.hpp @@ -14,8 +14,8 @@ #ifndef GLFWM_WINDOW_HPP #define GLFWM_WINDOW_HPP -#include "event_handler.hpp" -#include "drawable.hpp" +#include +#include namespace glfwm { diff --git a/include/glfwm/window_group.hpp b/include/glfwm/window_group.hpp index 86e4126..7dfe42e 100644 --- a/include/glfwm/window_group.hpp +++ b/include/glfwm/window_group.hpp @@ -14,8 +14,8 @@ #ifndef GLFWM_WINDOW_GROUP_HPP #define GLFWM_WINDOW_GROUP_HPP -#include "window.hpp" -#include "update_map.hpp" +#include +#include namespace glfwm { diff --git a/src/enums.cpp b/src/enums.cpp index 9900e0d..8fb5893 100644 --- a/src/enums.cpp +++ b/src/enums.cpp @@ -11,7 +11,7 @@ // Author: Giorgio Marcias // email: marcias.giorgio@gmail.com -#include "enums.hpp" +#include namespace glfwm { diff --git a/src/event.cpp b/src/event.cpp index b8c8366..7ac8a86 100644 --- a/src/event.cpp +++ b/src/event.cpp @@ -11,7 +11,7 @@ // Author: Giorgio Marcias // email: marcias.giorgio@gmail.com -#include "event.hpp" +#include namespace glfwm { diff --git a/src/glfwm.cpp b/src/glfwm.cpp index 4ff0159..bfe520b 100644 --- a/src/glfwm.cpp +++ b/src/glfwm.cpp @@ -11,7 +11,7 @@ // Author: Giorgio Marcias // email: marcias.giorgio@gmail.com -#include "glfwm.hpp" +#include namespace glfwm { diff --git a/src/update_map.cpp b/src/update_map.cpp index c7cebed..f009155 100644 --- a/src/update_map.cpp +++ b/src/update_map.cpp @@ -11,7 +11,7 @@ // Author: Giorgio Marcias // email: marcias.giorgio@gmail.com -#include "update_map.hpp" +#include namespace glfwm { diff --git a/src/window.cpp b/src/window.cpp index eaef4d0..8fc4a7d 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -11,7 +11,7 @@ // Author: Giorgio Marcias // email: marcias.giorgio@gmail.com -#include "window.hpp" +#include namespace glfwm { diff --git a/src/window_group.cpp b/src/window_group.cpp index e153b8b..3553568 100644 --- a/src/window_group.cpp +++ b/src/window_group.cpp @@ -11,7 +11,7 @@ // Author: Giorgio Marcias // email: marcias.giorgio@gmail.com -#include "window_group.hpp" +#include namespace glfwm { From ef1cf2c6c14fa9cfedac9b4661f95ca3d2d3326f Mon Sep 17 00:00:00 2001 From: Giorgio Marcias Date: Sun, 17 Jul 2016 23:24:50 +0200 Subject: [PATCH 13/17] added installation directives --- CMakeLists.txt | 55 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a47ed21..fb54baf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,14 @@ cmake_minimum_required(VERSION 3.1) -project(glfwm VERSION 3.2 LANGUAGES CXX) +project(glfwm LANGUAGES CXX) + +set(${PROJECT_NAME}_VERSION_MAJOR "3") +set(${PROJECT_NAME}_VERSION_MINOR "2") +set(${PROJECT_NAME}_VERSION_PATCH "0") +set(${PROJECT_NAME}_VERSION_TWEAK "") +set(${PROJECT_NAME}_VERSION "${${PROJECT_NAME}_VERSION_MAJOR}.${${PROJECT_NAME}_VERSION_MINOR}") +set(${PROJECT_NAME}_VERSION_FULL "${${PROJECT_NAME}_VERSION}.${${PROJECT_NAME}_VERSION_PATCH}${${PROJECT_NAME}_VERSION_TWEAK}") # GLFW find_package(glfw3 3.2 REQUIRED) @@ -46,7 +53,7 @@ endif(NOT GLFWM_PARENT_DIRECTORY AND NOT CMAKE_BUILD_TYPE) set(HDR_DIR_NAME "GLFWM") -set(HDR_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) +set(HDR_DIR "${${PROJECT_NAME}_SOURCE_DIR}/include") set(HDRS ${HDR_DIR}/${HDR_DIR_NAME}/common.hpp ${HDR_DIR}/${HDR_DIR_NAME}/drawable.hpp @@ -59,7 +66,7 @@ set(HDRS ${HDR_DIR}/${HDR_DIR_NAME}/window_group.hpp ${HDR_DIR}/${HDR_DIR_NAME}/glfwm.hpp) -set(SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src) +set(SRC_DIR "${${PROJECT_NAME}_SOURCE_DIR}/src") set(SRCS ${SRC_DIR}/enums.cpp ${SRC_DIR}/event.cpp @@ -72,10 +79,20 @@ add_library(${PROJECT_NAME} ${HDRS} ${SRCS}) set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 11 - CXX_STANDARD_REQUIRED ON) - -target_include_directories(${PROJECT_NAME} PUBLIC ${HDR_DIR}) -target_link_libraries(${PROJECT_NAME} glfw) + CXX_STANDARD_REQUIRED ON + VERSION ${${PROJECT_NAME}_VERSION} + SOVERSION ${${PROJECT_NAME}_VERSION_MAJOR} +) +if(NOT GLFWM_PARENT_DIRECTORY) + set_target_properties(${PROJECT_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON) +endif(NOT GLFWM_PARENT_DIRECTORY) + +target_include_directories(${PROJECT_NAME} PRIVATE ${HDR_DIR}) +target_include_directories(${PROJECT_NAME} INTERFACE + $ + $/include> +) +target_link_libraries(${PROJECT_NAME} PUBLIC glfw) if(NOT WITH_MULTITHREADING) target_compile_definitions(${PROJECT_NAME} PRIVATE NO_MULTITHREADING) endif(NOT WITH_MULTITHREADING) @@ -88,6 +105,28 @@ if(GLFWM_PARENT_DIRECTORY) endif(GLFWM_PARENT_DIRECTORY) if(INSTALL_GLFWM) - install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib) + install(TARGETS ${PROJECT_NAME} + EXPORT ${PROJECT_NAME} + LIBRARY DESTINATION lib + INCLUDES DESTINATION include + ) install(DIRECTORY ${HDR_DIR}/${HDR_DIR_NAME} DESTINATION include) + + include(CMakePackageConfigHelpers) + set(${PROJECT_NAME}_CONFIG_PATH "lib/cmake/${PROJECT_NAME}") + + write_basic_package_version_file(${PROJECT_NAME}ConfigVersion.cmake + VERSION ${${PROJECT_NAME}_VERSION_FULL} + COMPATIBILITY SameMajorVersion + ) + install(FILES + ${${PROJECT_NAME}_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake + DESTINATION "${${PROJECT_NAME}_CONFIG_PATH}" + ) + + install(EXPORT ${PROJECT_NAME} + DESTINATION ${${PROJECT_NAME}_CONFIG_PATH} + CONFIGURATIONS Release + EXPORT_LINK_INTERFACE_LIBRARIES + ) endif(INSTALL_GLFWM) From ed97339673fab35a3618d2122b18421642b806c1 Mon Sep 17 00:00:00 2001 From: Giorgio Marcias Date: Mon, 18 Jul 2016 09:59:23 +0200 Subject: [PATCH 14/17] fixed cmake list file with right package glfw3 dependency inclusion for consumers --- CMakeLists.txt | 72 ++++++++++++++++++++++++-------------- cmake/glfwmConfig.cmake.in | 4 +++ 2 files changed, 50 insertions(+), 26 deletions(-) create mode 100644 cmake/glfwmConfig.cmake.in diff --git a/CMakeLists.txt b/CMakeLists.txt index fb54baf..f439fac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,21 +15,27 @@ cmake_minimum_required(VERSION 3.1) project(glfwm LANGUAGES CXX) -set(${PROJECT_NAME}_VERSION_MAJOR "3") -set(${PROJECT_NAME}_VERSION_MINOR "2") -set(${PROJECT_NAME}_VERSION_PATCH "0") -set(${PROJECT_NAME}_VERSION_TWEAK "") -set(${PROJECT_NAME}_VERSION "${${PROJECT_NAME}_VERSION_MAJOR}.${${PROJECT_NAME}_VERSION_MINOR}") -set(${PROJECT_NAME}_VERSION_FULL "${${PROJECT_NAME}_VERSION}.${${PROJECT_NAME}_VERSION_PATCH}${${PROJECT_NAME}_VERSION_TWEAK}") +# set current glfwm version +set(GLFWM_VERSION_MAJOR "3") +set(GLFWM_VERSION_MINOR "2") +set(GLFWM_VERSION_PATCH "0") +set(GLFWM_VERSION_TWEAK "") +set(GLFWM_VERSION "${GLFWM_VERSION_MAJOR}.${GLFWM_VERSION_MINOR}") +set(GLFWM_VERSION_FULL "${GLFWM_VERSION}.${GLFWM_VERSION_PATCH}${GLFWM_VERSION_TWEAK}") + +# depending on whether this list file is included with add_subdirectory or not, behaviour changes +get_directory_property(GLFWM_PARENT_DIRECTORY PARENT_DIRECTORY) -# GLFW -find_package(glfw3 3.2 REQUIRED) +# dependencies: + +# GLFW +find_package(glfw3 3.2 REQUIRED) -get_directory_property(GLFWM_PARENT_DIRECTORY PARENT_DIRECTORY) +# options: option(WITH_MULTITHREADING "Build GLFWM with multithreading facilities (i.e. thread-safe) or not." ON) @@ -52,6 +58,7 @@ if(NOT GLFWM_PARENT_DIRECTORY AND NOT CMAKE_BUILD_TYPE) endif(NOT GLFWM_PARENT_DIRECTORY AND NOT CMAKE_BUILD_TYPE) +# collect source files set(HDR_DIR_NAME "GLFWM") set(HDR_DIR "${${PROJECT_NAME}_SOURCE_DIR}/include") set(HDRS @@ -75,13 +82,20 @@ set(SRCS ${SRC_DIR}/window_group.cpp ${SRC_DIR}/glfwm.cpp) + + +# create the target library add_library(${PROJECT_NAME} ${HDRS} ${SRCS}) + + +# set target properties: + set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED ON - VERSION ${${PROJECT_NAME}_VERSION} - SOVERSION ${${PROJECT_NAME}_VERSION_MAJOR} + VERSION ${GLFWM_VERSION} + SOVERSION ${GLFWM_VERSION_MAJOR} ) if(NOT GLFWM_PARENT_DIRECTORY) set_target_properties(${PROJECT_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON) @@ -92,41 +106,47 @@ target_include_directories(${PROJECT_NAME} INTERFACE $ $/include> ) + target_link_libraries(${PROJECT_NAME} PUBLIC glfw) if(NOT WITH_MULTITHREADING) target_compile_definitions(${PROJECT_NAME} PRIVATE NO_MULTITHREADING) endif(NOT WITH_MULTITHREADING) -# expose the directories -if(GLFWM_PARENT_DIRECTORY) - set(GLFWM_TARGET ${PROJECT_NAME} PARENT_SCOPE) - set(GLFWM_INCLUDE_DIRS ${HDR_DIR} PARENT_SCOPE) - set(GLFWM_LIBRARIES ${PROJECT_NAME} PARENT_SCOPE) -endif(GLFWM_PARENT_DIRECTORY) + +# installation directives: if(INSTALL_GLFWM) + # first, install the target library install(TARGETS ${PROJECT_NAME} - EXPORT ${PROJECT_NAME} + EXPORT ${PROJECT_NAME}Targets LIBRARY DESTINATION lib - INCLUDES DESTINATION include + INCLUDES DESTINATION include # this appears in INTERFACE properties when exporting ) + # install the header files install(DIRECTORY ${HDR_DIR}/${HDR_DIR_NAME} DESTINATION include) - include(CMakePackageConfigHelpers) - set(${PROJECT_NAME}_CONFIG_PATH "lib/cmake/${PROJECT_NAME}") + # set and intall the cmake config files, s.t. consumers can easily find this library locations and properties + set(GLFWM_CONFIG_PATH "lib/cmake/${PROJECT_NAME}") + include(CMakePackageConfigHelpers) + configure_package_config_file(cmake/glfwmConfig.cmake.in + ${PROJECT_NAME}Config.cmake + INSTALL_DESTINATION "${GLFWM_CONFIG_PATH}" + NO_CHECK_REQUIRED_COMPONENTS_MACRO + ) write_basic_package_version_file(${PROJECT_NAME}ConfigVersion.cmake - VERSION ${${PROJECT_NAME}_VERSION_FULL} + VERSION ${GLFWM_VERSION_FULL} COMPATIBILITY SameMajorVersion ) install(FILES + ${${PROJECT_NAME}_BINARY_DIR}/${PROJECT_NAME}Config.cmake ${${PROJECT_NAME}_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake - DESTINATION "${${PROJECT_NAME}_CONFIG_PATH}" + DESTINATION "${GLFWM_CONFIG_PATH}" ) - install(EXPORT ${PROJECT_NAME} - DESTINATION ${${PROJECT_NAME}_CONFIG_PATH} - CONFIGURATIONS Release + install(EXPORT ${PROJECT_NAME}Targets + DESTINATION ${GLFWM_CONFIG_PATH} + FILE ${PROJECT_NAME}Targets.cmake EXPORT_LINK_INTERFACE_LIBRARIES ) endif(INSTALL_GLFWM) diff --git a/cmake/glfwmConfig.cmake.in b/cmake/glfwmConfig.cmake.in new file mode 100644 index 0000000..f803a00 --- /dev/null +++ b/cmake/glfwmConfig.cmake.in @@ -0,0 +1,4 @@ +include(CMakeFindDependencyMacro) +find_dependency(glfw3 3.2) + +include("${CMAKE_CURRENT_LIST_DIR}/glfwmTargets.cmake") From 29989e0b3ffb85241f753cf32b91d6011182da84 Mon Sep 17 00:00:00 2001 From: Giorgio Marcias Date: Mon, 18 Jul 2016 10:03:29 +0200 Subject: [PATCH 15/17] separate examples: from installed with find_package and included with add_subdirectory --- .../simple_no_install}/CMakeLists.txt | 5 +- .../simple_no_install}/main.cpp | 0 examples/simple_with_install/CMakeLists.txt | 28 +++ examples/simple_with_install/main.cpp | 187 ++++++++++++++++++ 4 files changed, 217 insertions(+), 3 deletions(-) rename {example => examples/simple_no_install}/CMakeLists.txt (80%) rename {example => examples/simple_no_install}/main.cpp (100%) create mode 100644 examples/simple_with_install/CMakeLists.txt create mode 100644 examples/simple_with_install/main.cpp diff --git a/example/CMakeLists.txt b/examples/simple_no_install/CMakeLists.txt similarity index 80% rename from example/CMakeLists.txt rename to examples/simple_no_install/CMakeLists.txt index 1d8f310..1c8848e 100644 --- a/example/CMakeLists.txt +++ b/examples/simple_no_install/CMakeLists.txt @@ -17,7 +17,7 @@ project(glfwmExample LANGUAGES CXX) # GLFWM # if you want to use glfwm without multi-threading, uncomment the following line #option(WITH_MULTITHREADING "Build GLFWM with multithreading facilities (i.e. thread-safe) or not." OFF) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_CURRENT_BINARY_DIR}/glfwm) +add_subdirectory(${${PROJECT_NAME}_SOURCE_DIR}/../.. ${${PROJECT_NAME}_BINARY_DIR}/glfwm) # create the executable add_executable(${PROJECT_NAME} main.cpp) @@ -27,5 +27,4 @@ set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD_REQUIRED ON) # link libraries -target_include_directories(${PROJECT_NAME} PUBLIC ${GLFWM_INCLUDE_DIRS}) -target_link_libraries(${PROJECT_NAME} ${GLFWM_LIBRARIES}) +target_link_libraries(${PROJECT_NAME} glfwm) diff --git a/example/main.cpp b/examples/simple_no_install/main.cpp similarity index 100% rename from example/main.cpp rename to examples/simple_no_install/main.cpp diff --git a/examples/simple_with_install/CMakeLists.txt b/examples/simple_with_install/CMakeLists.txt new file mode 100644 index 0000000..bdfc2af --- /dev/null +++ b/examples/simple_with_install/CMakeLists.txt @@ -0,0 +1,28 @@ +# Copyright (c) 2015-2016 Giorgio Marcias +# +# This file is part of GLFWM, a C++11 wrapper of GLFW with +# multi-threading management (GLFW Manager). +# +# This source code is subject to zlib/libpng License. +# This software is provided 'as-is', without any express +# or implied warranty. In no event will the authors be held +# liable for any damages arising from the use of this software. +# +# Author: Giorgio Marcias +# email: marcias.giorgio@gmail.com + +cmake_minimum_required(VERSION 3.1) +project(glfwmExample LANGUAGES CXX) + +# find GLFWM +find_package(glfwm 3.2 REQUIRED CONFIG) + +# create the executable +add_executable(${PROJECT_NAME} main.cpp) + +set_target_properties(${PROJECT_NAME} PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED ON) + +# link libraries +target_link_libraries(${PROJECT_NAME} glfwm) diff --git a/examples/simple_with_install/main.cpp b/examples/simple_with_install/main.cpp new file mode 100644 index 0000000..68488f2 --- /dev/null +++ b/examples/simple_with_install/main.cpp @@ -0,0 +1,187 @@ +// Copyright (c) 2015-2016 Giorgio Marcias +// +// This file is part of GLFWM, a C++11 wrapper of GLFW with +// multi-threading management (GLFW Manager). +// +// This source code is subject to zlib/libpng License. +// This software is provided 'as-is', without any express +// or implied warranty. In no event will the authors be held +// liable for any damages arising from the use of this software. +// +// Author: Giorgio Marcias +// email: marcias.giorgio@gmail.com + + + +// glfwmExample +// +// This example basically shows how to use GLFWM. +// First of all, you must have GLFW installed (see http://www.glfw.org ). +// This software works as follows. +// A first window is created. Whenever a left-click on it occurs, a new +// window is created from that taking the 90% of its space, starting from +// the bottom-right corner. +// Any left-click from any window causes the creation of a new window as +// before, from the window where the click occurred. +// A right-click on a window closes that window, without affecting the ones +// that have previously been created from that. +// When all windows are closed, the program ends. +// Any click on a window causes also a drawing, which consists of writing +// "Drawing window #" on the standard outputs, where '#' correponds to the +// ID of the window to be drawn. +// +// A more advanced usage of GLFWM implies a good knowledge of GLFW and can +// be achieved by reading the documentation in the header files. + + + +#include + +// Before the main header, if not in the CMakefile.txt, define any GLFW macro you need, e.g.: +//#define GLFW_INCLUDE_GLCOREARB + +// Include the main header. +// Depending on what you have to do (e.g. inherit some glfwm base class) you can include just any other header file. +#include + +// This class responsible of drawing the content of a window must inherit glfwm::Drawable and +// implement its draw abstract method. Note that the parameter id can be used to retrieve +// that window specific resources (e.g. OpenGL buffers or VAOs). +class MyDrawable : public glfwm::Drawable { +public: + void draw(const glfwm::WindowID id) + { + // Here you can do anything you want for drawing, like glViewport(x, y, w, h). + // Note: you don't have to call any swapping render buffer function, as it is + // called when all the bound Drawables' draw method have been called (see + // glfwm::WindowManager::mainLoop()). + std::cout << "Drawing window " << id << std::endl; + } +}; +std::shared_ptr myDrawable; + + + +class MyHandler; +std::shared_ptr myHandler; + +// This class is responsible of handling the events sent to the window(s) it is bound to. +// It must inherit glfwm::EventHandler and implement the getHandledEventTypes() and +// handle() methods. +class MyHandler : public glfwm::EventHandler { +public: + // It is essential that this method returns a mask corresponding to + // the event types that can be handled, otherwise the handle() method won't never be called + // for the events not indicated, even if they can actually be handled. + glfwm::EventBaseType getHandledEventTypes() const + { + return static_cast(glfwm::EventType::MOUSE_BUTTON); + } + + // Then this method takes an action when the events that can be handled occur. + // Specifically, when you left-click on a window, a new window is created, whilst + // when you right-click on a window, it is closed without affecting those created + // from that one. + // PS: When several handlers that can handle the same event are bound to a window + // and that event occurs, the handlers that come after the first one to handle it + // are not executed. This is because this method returns true when it actually handles + // the event. The order of handlers is determined by what you specify at binding time + // (see glfwm::Window::bindEventHandler()). If you want to execute more than one handler + // for the same event, you are free to return false even having actually handled it; in + // this way, the following handlers are called. + bool handle(const glfwm::EventPointer &e) + { + if (e->getEventType() == glfwm::EventType::MOUSE_BUTTON) { + + std::shared_ptr mb = std::dynamic_pointer_cast(e); + + if (mb->getAction() != glfwm::ActionType::RELEASE) + return false; + + glfwm::WindowPointer win = glfwm::Window::getWindow(e->getWindowID()); + int w, h, x, y; + win->getSize(w, h); + win->getPosition(x, y); + + if (mb->getMouseButton() == glfwm::MouseButtonType::MOUSE_BUTTON_LEFT) { + glfwm::WindowPointer newWin = glfwm::WindowManager::createWindow(w * 0.9, h * 0.9, std::string(), getHandledEventTypes()); + newWin->setTitle(std::string("Window ") + std::to_string(newWin->getID()) + std::string(". Built from ") + std::to_string(e->getWindowID())); + newWin->setPosition(x + w * 0.1, y + h * 0.1); + newWin->bindEventHandler(myHandler, 0); + newWin->bindDrawable(myDrawable, 0); + glfwm::WindowGroupPointer grp = glfwm::WindowGroup::getGroup(glfwm::WindowGroup::getWindowGroup(e->getWindowID())); + if (grp) + grp->attachWindow(newWin->getID()); + return true; + } else if (mb->getMouseButton() == glfwm::MouseButtonType::MOUSE_BUTTON_RIGHT) { + win->setShouldClose(true); + return true; + } + return false; + } + + return false; + } +}; + + + +int main(int argc, char *argv[]) +{ + // First thing to do: initialization! + glfwm::WindowManager::init(); + + // You can set any GLFW hint with this method: + glfwm::WindowManager::setHint(GLFW_CONTEXT_VERSION_MAJOR, 1); + glfwm::WindowManager::setHint(GLFW_CONTEXT_VERSION_MINOR, 1); + + // Remember to instantiate the handlers and the drawables to bind to the windows. + // A handler can be bound to any number of different windows, and a window can have + // any number of handlers bound to it. + // The same holds for Drawables. + myHandler = std::make_shared(); + myDrawable = std::make_shared(); + + // Create windows with the glfwm::WindowManager::createWindow() method. + // Alternatively, call glfwm::Window::newWindow() and then glfwm::WindowManager::registerCallbacks(). + // At this time, remember to register the callbacks for the event you want to handle. + glfwm::WindowPointer mainWin = glfwm::WindowManager::createWindow(800, 600, std::string(), myHandler->getHandledEventTypes()); + + // You can set the title of the window, and other stuff: see glfwm::Window. + mainWin->setTitle(std::string("Main Window ") + std::to_string(mainWin->getID())); + + // Remember to bind the handlers and the drawables. The second parameter is the rank that determines + // the position in the list bound to the Window. The list is sorted accordingly: + // a handler with rank 3 comes before one with 4 and after one with -100; two handlers with the same + // rank appear one after the other depending on which is bound after. + mainWin->bindEventHandler(myHandler, 0); + mainWin->bindDrawable(myDrawable, 0); + + // Now, if you want to draw the windows' content in parallel, the best way to do it is + // to create a group, attach windows to it, and make it run in a separate thread by + // calling glfwm::WindowGroup::runLoopConcurrently(). Of course you don't have to. + // If you want to keep everything in the main thread, groups may still be usefull, + // for example to send update notifications to all the windows in the same group + // (see glfwm::UpdateMap::notify()). You could also turn off the multi-threading + // support at compile time through the option WITH_MULTITHREADING (see CMakeLists.txt). + glfwm::WindowGroupPointer grp = glfwm::WindowGroup::newGroup(); + grp->attachWindow(mainWin->getID()); + grp->runLoopConcurrently(); + + // When at least one Window has been created, you can start the main loop. + // It consists of alternating event handling and content drawing. + // There are two possibilities: + // 1) wait (blocking) for any event to occur and then drawing after handling + // 2) handling and then drawing, without waiting if no event is in the queue. + // These two ways can be exchanged at any time (and from any thread) by calling + // glfwm::WindowManager::setPoll(). + // The main loop will run until at least one window is open. When all windows + // are closed, the mainLoop() method ends. + // Note that a window is closed and others remain open, that window is destroyed. + glfwm::WindowManager::mainLoop(); + + // Finally, deletes all the resources: any group is destroyed and GLFW is terminated. + glfwm::WindowManager::terminate(); + + return 0; +} From 910a2703681a7207329b3e4b4a3c53d3bc4d179a Mon Sep 17 00:00:00 2001 From: Giorgio Marcias Date: Mon, 18 Jul 2016 15:40:47 +0200 Subject: [PATCH 16/17] completed README with more information --- CMakeLists.txt | 2 +- README.md | 147 +++++++++++++++++++++++--- examples/simple_no_install/main.cpp | 9 +- examples/simple_with_install/main.cpp | 9 +- 4 files changed, 144 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f439fac..6a05930 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,7 +37,7 @@ find_package(glfw3 3.2 REQUIRED) # options: -option(WITH_MULTITHREADING "Build GLFWM with multithreading facilities (i.e. thread-safe) or not." ON) +option(WITH_MULTITHREADING "Build GLFWM with multithreading (i.e. thread-safe) or not." ON) if(GLFWM_PARENT_DIRECTORY) set(MAKE_SHARED OFF) diff --git a/README.md b/README.md index 03321be..35e4915 100644 --- a/README.md +++ b/README.md @@ -17,25 +17,148 @@ A [GLFW](http://www.glfw.org) C++ wrapper with additional OOP features. * update notifications to whole groups * automatic control of the loop + + ### Compilation -To compile this software, import it in another software through cmake. -Supposing to have your software root cmake file at +#### Dependencies +There are two mandatory dependencies. + +* [GLFW](http://www.glfw.org), which must have already been installed on the system. +See [http://www.glfw.org](http://www.glfw.org) for details. +Alternatively, it is possible to get GLFW through package managers, such as apt-get (Linux) or MacPort/Homebrew (Mac OS). + +* [cmake](https://cmake.org), which is used to compile and install this library, greatly simplifying this tasks. +See [https://cmake.org](https://cmake.org) for details. +Alternatively, as before, it is possible to get cmake through package managers. + + + +#### Building +Through *cmake* it is possible to compile and eventually import this library into another software. +There are two ways to do that. + +* *install* the shared library binaries somewhere on the system and then import it: + + mkdir glfwm_build + cd glfwm_build + cmake + make + make install + + Now `glfwm` is installed as a shared library depending on the value of `CMAKE_INSTALL_PREFIX` and can be linked to. + Then in the cmake list file `CMakeList.txt` of another project just add: - /CMakeLists.txt + ... + find_package(glfwm 3.2 REQUIRED) + ... + add_executable(myexe myexe.cpp) + target_link_libraries(myexe glfwm) -add GLFWM as subdirectory to it: + And that's all. - # uncomment the following line if you do NOT want multi-threading support - #SET(WITH_MULTITHREADING OFF CACHE BOOL "Build GLFWM with multithreading facilities (i.e. thread-safe) or not.") - ADD_SUBDIRECTORY( ${CMAKE_CURRENT_BINARY_DIR}/glfwm) +* *include* the library sources in a cmake list file `CMakeList.txt` of another project: + + ... + add_subdirectory( ${${PROJECT_NAME}_BINARY_DIR}/glfwm) + ... + add_executable(myexe myexe.cpp) + target_link_libraries(myexe glfwm) + + In this way, `glfwm` is compiled as a static library in the build tree of the `myexe` target. + +##### Build options +There are some options that affect the compilation and/or installation: + +* `WITH_MULTITHREADING` enables/disables multi-threading support. This allows windows to operate and be managed in separate threads. + +* `BUILD_SHARED_LIBS` makes `glfwm` be built as a shared (if `ON`) or a static (if `OFF`) library. + +* `INSTALL_GLFWM` makes `glfwm` be installed (if `ON`) or not (if `OFF`). + +Default values mainly depends on the way it is built as described in the **Building** section above. +`BUILD_SHARED_LIBS` and `INSTALL_GLFWM` are `OFF` when glfwm is included as a sub-directory, `ON` otherwise. +`WITH_MULTITHREADING` is always `ON`. + +It is possible to change these options either as argument to the `cmake` command, e.g. `-DWITH_MULTITHREADING=OFF`, or directly in the cmake list file of another project which includes glfwm: + + ... + option(WITH_MULTITHREADING "Build GLFWM with multithreading (i.e. thread-safe) or not." OFF) + add_subdirectory( ${${PROJECT_NAME}_BINARY_DIR}/glfwm) ... - TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME} PUBLIC ${GLFWM_INCLUDE_DIRS}) - TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${GLFWM_LIBRARIES}) -Then it can be compiled with the commands: +### Usage +The main purpose is to manage windows. +So the main objects are `Window`s and a `WindowManager` which takes care of. + +First of all, include the main header: + + #include + +Then initialize the library resources by calling + + glfwm::WindowManager::init(); + +at the beginning of the program execution, e.g. in the `main` function before everything. + +A `Window` can receive events and draw some content. +For this purpose, special objects can bind to it. + +Derive `EventHandler` and override the `getHandledEventTypes()` and `handle()` methods in order to react to events like cursor position changes and mouse button clicks. +Then bind such objects to a `Window` s.t. events directed to it may handled: + + class MyHandler : public glfwm::EventHandler { + public: + glfwm::EventBaseType getHandledEventTypes() const override + { + return static_cast(glfwm::EventType::MOUSE_BUTTON); + } + + bool handle(const glfwm::EventPointer &e) override + { + if (e->getEventType() == glfwm::EventType::MOUSE_BUTTON) { + // make some action based on this event + ... + return true; + } + return false; + } + }; + +Derive `Drawable` and override the `draw()` method. +There put the code responsible of drawing the content, e.g. OpenGL calls: + + class MyDrawable : public glfwm::Drawable { + public: + void draw(const glfwm::WindowID id) override + { + // draw the content on the screen + } + }; + +Then create some `Window` and bind the handler and the drawable to it: + + ... + std::shared_ptr myHandler = std::make_shared(); + std::shared_ptr myDrawable = std::make_shared(); + glfwm::WindowPointer mainWin = glfwm::WindowManager::createWindow(800, 600, std::string(), myHandler->getHandledEventTypes()); + mainWin->bindEventHandler(myHandler, 0); // 0 is the rank among all event handlers bound + mainWin->bindDrawable(myDrawable, 0); // 0 is the rank among all drawables bound + +Possibly create other windows and group them. +Groups are usefull for concurrent management (i.e. multi-threaded windows) or even just for sending notifications to all the windows in the same group. +Notifications can be used to make several windows react to a single event. +To create a group and attach windows: + + glfwm::WindowGroupPointer grp = glfwm::WindowGroup::newGroup(); + grp->attachWindow(mainWin->getID()); + grp->runLoopConcurrently(); // this is available if compiled with WITH_MULTITHREADING=ON + +Finally, start the main loop, which ends when all the windows are closed, and release the library resources: + + glfwm::WindowManager::mainLoop(); + glfwm::WindowManager::terminate(); + - > cmake - > make It has been tested on Mac OS X 10.9 - 10.10 - 10.11 diff --git a/examples/simple_no_install/main.cpp b/examples/simple_no_install/main.cpp index 68488f2..d00a14c 100644 --- a/examples/simple_no_install/main.cpp +++ b/examples/simple_no_install/main.cpp @@ -49,7 +49,7 @@ // that window specific resources (e.g. OpenGL buffers or VAOs). class MyDrawable : public glfwm::Drawable { public: - void draw(const glfwm::WindowID id) + void draw(const glfwm::WindowID id) override { // Here you can do anything you want for drawing, like glViewport(x, y, w, h). // Note: you don't have to call any swapping render buffer function, as it is @@ -73,7 +73,7 @@ class MyHandler : public glfwm::EventHandler { // It is essential that this method returns a mask corresponding to // the event types that can be handled, otherwise the handle() method won't never be called // for the events not indicated, even if they can actually be handled. - glfwm::EventBaseType getHandledEventTypes() const + glfwm::EventBaseType getHandledEventTypes() const override { return static_cast(glfwm::EventType::MOUSE_BUTTON); } @@ -89,7 +89,7 @@ class MyHandler : public glfwm::EventHandler { // (see glfwm::Window::bindEventHandler()). If you want to execute more than one handler // for the same event, you are free to return false even having actually handled it; in // this way, the following handlers are called. - bool handle(const glfwm::EventPointer &e) + bool handle(const glfwm::EventPointer &e) override { if (e->getEventType() == glfwm::EventType::MOUSE_BUTTON) { @@ -132,8 +132,7 @@ int main(int argc, char *argv[]) glfwm::WindowManager::init(); // You can set any GLFW hint with this method: - glfwm::WindowManager::setHint(GLFW_CONTEXT_VERSION_MAJOR, 1); - glfwm::WindowManager::setHint(GLFW_CONTEXT_VERSION_MINOR, 1); + glfwm::WindowManager::setHint(GLFW_CLIENT_API, GLFW_NO_API); // Remember to instantiate the handlers and the drawables to bind to the windows. // A handler can be bound to any number of different windows, and a window can have diff --git a/examples/simple_with_install/main.cpp b/examples/simple_with_install/main.cpp index 68488f2..d00a14c 100644 --- a/examples/simple_with_install/main.cpp +++ b/examples/simple_with_install/main.cpp @@ -49,7 +49,7 @@ // that window specific resources (e.g. OpenGL buffers or VAOs). class MyDrawable : public glfwm::Drawable { public: - void draw(const glfwm::WindowID id) + void draw(const glfwm::WindowID id) override { // Here you can do anything you want for drawing, like glViewport(x, y, w, h). // Note: you don't have to call any swapping render buffer function, as it is @@ -73,7 +73,7 @@ class MyHandler : public glfwm::EventHandler { // It is essential that this method returns a mask corresponding to // the event types that can be handled, otherwise the handle() method won't never be called // for the events not indicated, even if they can actually be handled. - glfwm::EventBaseType getHandledEventTypes() const + glfwm::EventBaseType getHandledEventTypes() const override { return static_cast(glfwm::EventType::MOUSE_BUTTON); } @@ -89,7 +89,7 @@ class MyHandler : public glfwm::EventHandler { // (see glfwm::Window::bindEventHandler()). If you want to execute more than one handler // for the same event, you are free to return false even having actually handled it; in // this way, the following handlers are called. - bool handle(const glfwm::EventPointer &e) + bool handle(const glfwm::EventPointer &e) override { if (e->getEventType() == glfwm::EventType::MOUSE_BUTTON) { @@ -132,8 +132,7 @@ int main(int argc, char *argv[]) glfwm::WindowManager::init(); // You can set any GLFW hint with this method: - glfwm::WindowManager::setHint(GLFW_CONTEXT_VERSION_MAJOR, 1); - glfwm::WindowManager::setHint(GLFW_CONTEXT_VERSION_MINOR, 1); + glfwm::WindowManager::setHint(GLFW_CLIENT_API, GLFW_NO_API); // Remember to instantiate the handlers and the drawables to bind to the windows. // A handler can be bound to any number of different windows, and a window can have From 75632125dd1fe2b8be0fb48bea03d485c9150819 Mon Sep 17 00:00:00 2001 From: Giorgio Marcias Date: Mon, 18 Jul 2016 15:51:56 +0200 Subject: [PATCH 17/17] fixed small issues --- README.md | 5 ++--- src/glfwm.cpp | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 35e4915..d046a67 100644 --- a/README.md +++ b/README.md @@ -137,7 +137,6 @@ There put the code responsible of drawing the content, e.g. OpenGL calls: Then create some `Window` and bind the handler and the drawable to it: - ... std::shared_ptr myHandler = std::make_shared(); std::shared_ptr myDrawable = std::make_shared(); glfwm::WindowPointer mainWin = glfwm::WindowManager::createWindow(800, 600, std::string(), myHandler->getHandledEventTypes()); @@ -151,14 +150,14 @@ To create a group and attach windows: glfwm::WindowGroupPointer grp = glfwm::WindowGroup::newGroup(); grp->attachWindow(mainWin->getID()); - grp->runLoopConcurrently(); // this is available if compiled with WITH_MULTITHREADING=ON + grp->runLoopConcurrently(); // this is available only if compiled with WITH_MULTITHREADING=ON Finally, start the main loop, which ends when all the windows are closed, and release the library resources: glfwm::WindowManager::mainLoop(); glfwm::WindowManager::terminate(); - +See the examples for more details. It has been tested on Mac OS X 10.9 - 10.10 - 10.11 diff --git a/src/glfwm.cpp b/src/glfwm.cpp index bfe520b..82a6fd4 100644 --- a/src/glfwm.cpp +++ b/src/glfwm.cpp @@ -18,7 +18,7 @@ namespace glfwm { #ifndef NO_MULTITHREADING std::atomic WindowManager::waitTimeout(std::numeric_limits::infinity()); #else - bool WindowManager::waitTimeout = std::numeric_limits::infinity(); + double WindowManager::waitTimeout = std::numeric_limits::infinity(); #endif /**