From 0fbf489bbb8abf94cfdb9a331c22421343e7bc45 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 20 Nov 2017 22:55:09 +0530 Subject: [PATCH] Implement glfwWindowBell Exposes the platform specific Bell/Beep API to make the default system beep sound. --- include/GLFW/glfw3.h | 24 +++++++++++++++++++++++- src/cocoa_window.m | 7 ++++++- src/internal.h | 2 +- src/null_window.c | 6 +++++- src/win32_window.c | 6 +++++- src/window.c | 11 ++++++++++- src/wl_window.c | 13 ++++++++++++- src/x11_window.c | 6 +++++- 8 files changed, 67 insertions(+), 8 deletions(-) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index b6d9f341f..9361ea92d 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -3185,6 +3185,29 @@ GLFWAPI void glfwFocusWindow(GLFWwindow* window); */ GLFWAPI void glfwRequestWindowAttention(GLFWwindow* window); +/*! @brief Sounds an audible bell associated with the window + * + * This function sounds an audible bell, on platforms where it is + * supported. Currently (macOS, Windows, X11 and Wayland). + * + * @param[in] window The window with which the bell is associated. + * @return GLFW_TRUE if the bell succeeded otherwise GLFW_FALSE + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark @macos Bell is associated to the application as a whole, not the + * specific window. + * + * @thread_safety This function must only be called from the main thread. + * + * @since Added in version 3.3. + * + * @ingroup window + */ +GLFWAPI int glfwWindowBell(GLFWwindow* window); + + /*! @brief Returns the monitor that the window uses for full screen mode. * * This function returns the handle of the monitor that the specified window is @@ -5519,4 +5542,3 @@ GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window #endif #endif /* _glfw3_h_ */ - diff --git a/src/cocoa_window.m b/src/cocoa_window.m index a54624cc5..b8f4b1503 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -1367,6 +1367,12 @@ void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) [NSApp requestUserAttention:NSInformationalRequest]; } +int _glfwPlatformWindowBell(_GLFWwindow* window) +{ + NSBeep(); + return GLFW_TRUE; +} + void _glfwPlatformFocusWindow(_GLFWwindow* window) { // Make us the active application @@ -1906,4 +1912,3 @@ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* handle) _GLFW_REQUIRE_INIT_OR_RETURN(nil); return window->ns.object; } - diff --git a/src/internal.h b/src/internal.h index 92bbfccec..020e58605 100644 --- a/src/internal.h +++ b/src/internal.h @@ -653,6 +653,7 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window); void _glfwPlatformShowWindow(_GLFWwindow* window); void _glfwPlatformHideWindow(_GLFWwindow* window); void _glfwPlatformRequestWindowAttention(_GLFWwindow* window); +int _glfwPlatformWindowBell(_GLFWwindow* window); void _glfwPlatformFocusWindow(_GLFWwindow* window); void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, @@ -768,4 +769,3 @@ void _glfwTerminateVulkan(void); const char* _glfwGetVulkanResultString(VkResult result); char* _glfw_strdup(const char* source); - diff --git a/src/null_window.c b/src/null_window.c index 6a54cfe56..0e380c58d 100644 --- a/src/null_window.c +++ b/src/null_window.c @@ -205,6 +205,11 @@ void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) { } +int _glfwPlatformWindowBell(_GLFWwindow* window) +{ + return GLFW_FALSE; +} + void _glfwPlatformUnhideWindow(_GLFWwindow* window) { } @@ -318,4 +323,3 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, // This seems like the most appropriate error to return here return VK_ERROR_INITIALIZATION_FAILED; } - diff --git a/src/win32_window.c b/src/win32_window.c index 4506c8a72..9dfe94ff6 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -1474,6 +1474,11 @@ void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) FlashWindow(window->win32.handle, TRUE); } +int _glfwPlatformWindowBell(_GLFWwindow* window) +{ + return MessageBeep(0xFFFFFFFF) ? GLFW_TRUE : GLFW_FALSE; +} + void _glfwPlatformFocusWindow(_GLFWwindow* window) { BringWindowToTop(window->win32.handle); @@ -2009,4 +2014,3 @@ GLFWAPI HWND glfwGetWin32Window(GLFWwindow* handle) _GLFW_REQUIRE_INIT_OR_RETURN(NULL); return window->win32.handle; } - diff --git a/src/window.c b/src/window.c index 38a8982bf..6be617433 100644 --- a/src/window.c +++ b/src/window.c @@ -768,6 +768,16 @@ GLFWAPI void glfwRequestWindowAttention(GLFWwindow* handle) _glfwPlatformRequestWindowAttention(window); } +GLFWAPI int glfwWindowBell(GLFWwindow* handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + + _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); + + return _glfwPlatformWindowBell(window); +} + GLFWAPI void glfwHideWindow(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; @@ -1096,4 +1106,3 @@ GLFWAPI void glfwPostEmptyEvent(void) _glfwPlatformPostEmptyEvent(); } - diff --git a/src/wl_window.c b/src/wl_window.c index c165ba73a..8201560c5 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1079,6 +1079,18 @@ void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) "Wayland: Window attention request not implemented yet"); } +int _glfwPlatformWindowBell(_GLFWwindow* window) +{ + // TODO: Use an actual Wayland API to implement this when one becomes available + int fd = open("/dev/tty", O_WRONLY | O_CLOEXEC); + if (fd > -1) { + int ret = write(fd, "\x07", 1) == 1 ? GLFW_TRUE : GLFW_FALSE; + close(fd); + return ret; + } + return GLFW_FALSE; +} + void _glfwPlatformFocusWindow(_GLFWwindow* window) { _glfwInputError(GLFW_PLATFORM_ERROR, @@ -1539,4 +1551,3 @@ GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* handle) _GLFW_REQUIRE_INIT_OR_RETURN(NULL); return window->wl.surface; } - diff --git a/src/x11_window.c b/src/x11_window.c index f3014ec9f..0186db8a7 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -2340,6 +2340,11 @@ void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) 0, 1, 0); } +int _glfwPlatformWindowBell(_GLFWwindow* window) +{ + return XkbBell(_glfw.x11.display, window->x11.handle, 100, (Atom)0) ? GLFW_TRUE : GLFW_FALSE; +} + void _glfwPlatformFocusWindow(_GLFWwindow* window) { if (_glfw.x11.NET_ACTIVE_WINDOW) @@ -3039,4 +3044,3 @@ GLFWAPI const char* glfwGetX11SelectionString(void) _GLFW_REQUIRE_INIT_OR_RETURN(NULL); return getSelectionString(_glfw.x11.PRIMARY); } -