diff --git a/.gitignore b/.gitignore index 4f8ddbc9..07ff42be 100644 --- a/.gitignore +++ b/.gitignore @@ -53,6 +53,7 @@ tests/*.exe tests/accuracy tests/clipboard tests/defaults +tests/empty tests/events tests/fsaa tests/gamma diff --git a/README.md b/README.md index cc11851d..ef57db63 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ The following dependencies are needed by the examples and test programs: - Added native monitor handle access to native API - Added `glfwSetDropCallback` and `GLFWdropfun` for receiving dropped files + - Added `empty` test program for verifying posting of empty events - Bugfix: The debug context attribute was set from `GL_ARB_debug_output` even when a debug context had not been requested - Bugfix: The particles example was not linked against the threading library diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 56b000ac..456cf136 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -36,6 +36,9 @@ add_executable(reopen reopen.c) add_executable(accuracy WIN32 MACOSX_BUNDLE accuracy.c) set_target_properties(accuracy PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Accuracy") +add_executable(empty WIN32 MACOSX_BUNDLE empty.c ${TINYCTHREAD}) +set_target_properties(empty PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Empty Event") + add_executable(sharing WIN32 MACOSX_BUNDLE sharing.c) set_target_properties(sharing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Sharing") @@ -51,9 +54,10 @@ set_target_properties(title PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Title") add_executable(windows WIN32 MACOSX_BUNDLE windows.c) set_target_properties(windows PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Windows") +target_link_libraries(empty ${CMAKE_THREAD_LIBS_INIT} ${RT_LIBRARY}) target_link_libraries(threads ${CMAKE_THREAD_LIBS_INIT} ${RT_LIBRARY}) -set(WINDOWS_BINARIES accuracy sharing tearing threads title windows) +set(WINDOWS_BINARIES accuracy empty sharing tearing threads title windows) set(CONSOLE_BINARIES clipboard defaults events fsaa gamma glfwinfo iconify joysticks modes peter reopen) diff --git a/tests/empty.c b/tests/empty.c new file mode 100644 index 00000000..d096636f --- /dev/null +++ b/tests/empty.c @@ -0,0 +1,129 @@ +//======================================================================== +// Empty event test +// Copyright (c) Camilla Berglund +// +// 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. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +// +// This test is intended to verify that posting of empty events works +// +//======================================================================== + +#include "tinycthread.h" + +#include + +#include +#include +#include + +static volatile GLboolean running = GL_TRUE; + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static int thread_main(void* data) +{ + struct timespec time; + + while (running) + { + clock_gettime(CLOCK_REALTIME, &time); + time.tv_sec += 1; + thrd_sleep(&time, NULL); + + glfwPostEmptyEvent(); + } + + return 0; +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) + glfwSetWindowShouldClose(window, GL_TRUE); +} + +static float nrand(void) +{ + return (float) rand() / (float) RAND_MAX; +} + +int main(void) +{ + int result; + thrd_t thread; + GLFWwindow* window; + + srand(time(NULL)); + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + window = glfwCreateWindow(640, 480, "Empty Event Test", NULL, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwMakeContextCurrent(window); + glfwSetKeyCallback(window, key_callback); + + if (thrd_create(&thread, thread_main, NULL) != thrd_success) + { + fprintf(stderr, "Failed to create secondary thread\n"); + + glfwTerminate(); + exit(EXIT_FAILURE); + } + + while (running) + { + int width, height; + float r = nrand(), g = nrand(), b = nrand(); + float l = (float) sqrt(r * r + g * g + b * b); + + glfwGetFramebufferSize(window, &width, &height); + + glViewport(0, 0, width, height); + glClearColor(r / l, g / l, b / l, 1.f); + glClear(GL_COLOR_BUFFER_BIT); + glfwSwapBuffers(window); + + glfwWaitEvents(); + + if (glfwWindowShouldClose(window)) + running = GL_FALSE; + } + + glfwHideWindow(window); + thrd_join(thread, &result); + glfwDestroyWindow(window); + + glfwTerminate(); + exit(EXIT_SUCCESS); +} +