diff --git a/CMake/modules/FindWayland.cmake b/CMake/modules/FindWayland.cmake new file mode 100644 index 00000000..00c17a3c --- /dev/null +++ b/CMake/modules/FindWayland.cmake @@ -0,0 +1,62 @@ +# Try to find Wayland on a Unix system +# +# This will define: +# +# WAYLAND_FOUND - True if Wayland is found +# WAYLAND_LIBRARIES - Link these to use Wayland +# WAYLAND_INCLUDE_DIR - Include directory for Wayland +# WAYLAND_DEFINITIONS - Compiler flags for using Wayland +# +# In addition the following more fine grained variables will be defined: +# +# WAYLAND_CLIENT_FOUND WAYLAND_CLIENT_INCLUDE_DIR WAYLAND_CLIENT_LIBRARIES +# WAYLAND_SERVER_FOUND WAYLAND_SERVER_INCLUDE_DIR WAYLAND_SERVER_LIBRARIES +# WAYLAND_EGL_FOUND WAYLAND_EGL_INCLUDE_DIR WAYLAND_EGL_LIBRARIES +# +# Copyright (c) 2013 Martin Gräßlin +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +IF (NOT WIN32) + IF (WAYLAND_INCLUDE_DIR AND WAYLAND_LIBRARIES) + # In the cache already + SET(WAYLAND_FIND_QUIETLY TRUE) + ENDIF () + + # Use pkg-config to get the directories and then use these values + # in the FIND_PATH() and FIND_LIBRARY() calls + FIND_PACKAGE(PkgConfig) + PKG_CHECK_MODULES(PKG_WAYLAND QUIET wayland-client wayland-server wayland-egl) + + SET(WAYLAND_DEFINITIONS ${PKG_WAYLAND_CFLAGS}) + + FIND_PATH(WAYLAND_CLIENT_INCLUDE_DIR NAMES wayland-client.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS}) + FIND_PATH(WAYLAND_SERVER_INCLUDE_DIR NAMES wayland-server.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS}) + FIND_PATH(WAYLAND_EGL_INCLUDE_DIR NAMES wayland-egl.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS}) + + FIND_LIBRARY(WAYLAND_CLIENT_LIBRARIES NAMES wayland-client HINTS ${PKG_WAYLAND_LIBRARY_DIRS}) + FIND_LIBRARY(WAYLAND_SERVER_LIBRARIES NAMES wayland-server HINTS ${PKG_WAYLAND_LIBRARY_DIRS}) + FIND_LIBRARY(WAYLAND_EGL_LIBRARIES NAMES wayland-egl HINTS ${PKG_WAYLAND_LIBRARY_DIRS}) + + set(WAYLAND_INCLUDE_DIR ${WAYLAND_CLIENT_INCLUDE_DIR} ${WAYLAND_SERVER_INCLUDE_DIR} ${WAYLAND_EGL_INCLUDE_DIR}) + + set(WAYLAND_LIBRARIES ${WAYLAND_CLIENT_LIBRARIES} ${WAYLAND_SERVER_LIBRARIES} ${WAYLAND_EGL_LIBRARIES}) + + list(REMOVE_DUPLICATES WAYLAND_INCLUDE_DIR) + + include(FindPackageHandleStandardArgs) + + FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_CLIENT DEFAULT_MSG WAYLAND_CLIENT_LIBRARIES WAYLAND_CLIENT_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_SERVER DEFAULT_MSG WAYLAND_SERVER_LIBRARIES WAYLAND_SERVER_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_EGL DEFAULT_MSG WAYLAND_EGL_LIBRARIES WAYLAND_EGL_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND DEFAULT_MSG WAYLAND_LIBRARIES WAYLAND_INCLUDE_DIR) + + MARK_AS_ADVANCED( + WAYLAND_INCLUDE_DIR WAYLAND_LIBRARIES + WAYLAND_CLIENT_INCLUDE_DIR WAYLAND_CLIENT_LIBRARIES + WAYLAND_SERVER_INCLUDE_DIR WAYLAND_SERVER_LIBRARIES + WAYLAND_EGL_INCLUDE_DIR WAYLAND_EGL_LIBRARIES + ) + +ENDIF () diff --git a/CMakeLists.txt b/CMakeLists.txt index af9929c6..61f6c83e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,10 @@ else() option(GLFW_USE_EGL "Use EGL for context creation" OFF) endif() +if (UNIX) + option(GLFW_USE_WAYLAND "Use Wayland for context creation (implies EGL as well)" OFF) +endif() + if (MSVC) option(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC runtime library DLL" ON) endif() @@ -39,6 +43,10 @@ if (BUILD_SHARED_LIBS) set(_GLFW_BUILD_DLL 1) endif() +if (GLFW_USE_WAYLAND) + set(GLFW_USE_EGL 1) +endif() + if (GLFW_USE_EGL) set(GLFW_CLIENT_LIBRARY "opengl" CACHE STRING "The client library to use; one of opengl, glesv1 or glesv2") @@ -136,8 +144,13 @@ elseif (APPLE) set(_GLFW_NSGL 1) message(STATUS "Using NSGL for context creation") elseif (UNIX) - set(_GLFW_X11 1) - message(STATUS "Using X11 for window creation") + if (GLFW_USE_WAYLAND) + set(_GLFW_WAYLAND 1) + message(STATUS "Using Wayland for window creation") + else() + set(_GLFW_X11 1) + message(STATUS "Using X11 for window creation") + endif() if (GLFW_USE_EGL) set(_GLFW_EGL 1) @@ -189,7 +202,6 @@ if (_GLFW_WGL) list(APPEND glfw_INCLUDE_DIRS ${OPENGL_INCLUDE_DIR}) list(APPEND glfw_LIBRARIES ${OPENGL_gl_LIBRARY}) - endif() #-------------------------------------------------------------------- @@ -279,6 +291,24 @@ if (_GLFW_X11) endif() +#-------------------------------------------------------------------- +# Use Wayland for window creation +#-------------------------------------------------------------------- +if (_GLFW_WAYLAND) + find_package(Wayland REQUIRED) + set(GLFW_PKG_DEPS "${GLFW_PKG_DEPS} wayland") + + list(APPEND glfw_INCLUDE_DIRS ${WAYLAND_INCLUDE_DIR}) + list(APPEND glfw_LIBRARIES ${WAYLAND_LIBRARIES}) + + find_library(MATH_LIBRARY m) + mark_as_advanced(MATH_LIBRARY) + if (MATH_LIBRARY) + list(APPEND glfw_LIBRARIES ${MATH_LIBRARY}) + set(GLFW_PKG_LIBS "${GLFW_PKG_LIBS} -lm") + endif() +endif() + #-------------------------------------------------------------------- # Use GLX for context creation #-------------------------------------------------------------------- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index de00a8c1..0f194b12 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -22,10 +22,19 @@ elseif (_GLFW_WIN32) win32_init.c win32_joystick.c win32_monitor.c win32_time.c win32_tls.c win32_window.c) elseif (_GLFW_X11) - set(glfw_HEADERS ${common_HEADERS} x11_platform.h posix_tls.h) + set(glfw_HEADERS ${common_HEADERS} x11_platform.h posix_tls.h unix_time.h) set(glfw_SOURCES ${common_SOURCES} x11_clipboard.c x11_gamma.c x11_init.c - x11_joystick.c x11_monitor.c x11_time.c x11_window.c - x11_unicode.c posix_tls.c) + x11_monitor.c x11_window.c x11_unicode.c posix_tls.c) +elseif (_GLFW_WAYLAND) + set(glfw_HEADERS ${common_HEADERS} wayland_platform.h posix_tls.h) + set(glfw_SOURCES ${common_SOURCES} wayland_clipboard.c wayland_gamma.c + wayland_init.c wayland_monitor.c wayland_window.c + posix_tls.c) +endif() + +if (_GLFW_X11 OR _GLFW_WAYLAND) + list(APPEND glfw_HEADERS linux_joystick.h unix_time.h) + list(APPEND glfw_SOURCES linux_joystick.c unix_time.c) endif() if (_GLFW_EGL) diff --git a/src/glfw_config.h.in b/src/glfw_config.h.in index 7234eb95..676bf380 100644 --- a/src/glfw_config.h.in +++ b/src/glfw_config.h.in @@ -40,6 +40,8 @@ #cmakedefine _GLFW_WIN32 // Define this to 1 if building GLFW for Cocoa #cmakedefine _GLFW_COCOA +// Define this to 1 if building GLFW for Wayland +#cmakedefine _GLFW_WAYLAND // Define this to 1 if building GLFW for EGL #cmakedefine _GLFW_EGL diff --git a/src/internal.h b/src/internal.h index e1e1a613..95e8fc3b 100644 --- a/src/internal.h +++ b/src/internal.h @@ -72,6 +72,8 @@ typedef struct _GLFWcursor _GLFWcursor; #include "win32_platform.h" #elif defined(_GLFW_X11) #include "x11_platform.h" +#elif defined(_GLFW_WAYLAND) + #include "wayland_platform.h" #else #error "No supported window creation API selected" #endif diff --git a/src/x11_joystick.c b/src/linux_joystick.c similarity index 71% rename from src/x11_joystick.c rename to src/linux_joystick.c index 0c49e618..bb5efcda 100644 --- a/src/x11_joystick.c +++ b/src/linux_joystick.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.1 X11 - www.glfw.org +// GLFW 3.1 Linux - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2010 Camilla Berglund @@ -39,6 +39,7 @@ #include #include #include +#include #endif // __linux__ @@ -55,7 +56,7 @@ static int openJoystickDevice(int joy, const char* path) if (fd == -1) return GL_FALSE; - _glfw.x11.joystick[joy].fd = fd; + _GLFW_LINUX_JOYSTICK_CONTEXT.joystick[joy].fd = fd; // Verify that the joystick driver version is at least 1.0 ioctl(fd, JSIOCGVERSION, &version); @@ -69,18 +70,20 @@ static int openJoystickDevice(int joy, const char* path) if (ioctl(fd, JSIOCGNAME(sizeof(name)), name) < 0) strncpy(name, "Unknown", sizeof(name)); - _glfw.x11.joystick[joy].name = strdup(name); + _GLFW_LINUX_JOYSTICK_CONTEXT.joystick[joy].name = strdup(name); ioctl(fd, JSIOCGAXES, &axisCount); - _glfw.x11.joystick[joy].axisCount = (int) axisCount; + _GLFW_LINUX_JOYSTICK_CONTEXT.joystick[joy].axisCount = (int) axisCount; ioctl(fd, JSIOCGBUTTONS, &buttonCount); - _glfw.x11.joystick[joy].buttonCount = (int) buttonCount; + _GLFW_LINUX_JOYSTICK_CONTEXT.joystick[joy].buttonCount = (int) buttonCount; - _glfw.x11.joystick[joy].axes = calloc(axisCount, sizeof(float)); - _glfw.x11.joystick[joy].buttons = calloc(buttonCount, 1); + _GLFW_LINUX_JOYSTICK_CONTEXT.joystick[joy].axes = + calloc(axisCount, sizeof(float)); + _GLFW_LINUX_JOYSTICK_CONTEXT.joystick[joy].buttons = + calloc(buttonCount, 1); - _glfw.x11.joystick[joy].present = GL_TRUE; + _GLFW_LINUX_JOYSTICK_CONTEXT.joystick[joy].present = GL_TRUE; #endif // __linux__ return GL_TRUE; @@ -97,21 +100,23 @@ static void pollJoystickEvents(void) for (i = 0; i <= GLFW_JOYSTICK_LAST; i++) { - if (!_glfw.x11.joystick[i].present) + if (!_GLFW_LINUX_JOYSTICK_CONTEXT.joystick[i].present) continue; // Read all queued events (non-blocking) for (;;) { errno = 0; - result = read(_glfw.x11.joystick[i].fd, &e, sizeof(e)); + result = read(_GLFW_LINUX_JOYSTICK_CONTEXT.joystick[i].fd, + &e, + sizeof(e)); if (errno == ENODEV) { - free(_glfw.x11.joystick[i].axes); - free(_glfw.x11.joystick[i].buttons); - free(_glfw.x11.joystick[i].name); - _glfw.x11.joystick[i].present = GL_FALSE; + free(_GLFW_LINUX_JOYSTICK_CONTEXT.joystick[i].axes); + free(_GLFW_LINUX_JOYSTICK_CONTEXT.joystick[i].buttons); + free(_GLFW_LINUX_JOYSTICK_CONTEXT.joystick[i].name); + _GLFW_LINUX_JOYSTICK_CONTEXT.joystick[i].present = GL_FALSE; } if (result == -1) @@ -123,12 +128,12 @@ static void pollJoystickEvents(void) switch (e.type) { case JS_EVENT_AXIS: - _glfw.x11.joystick[i].axes[e.number] = + _GLFW_LINUX_JOYSTICK_CONTEXT.joystick[i].axes[e.number] = (float) e.value / 32767.0f; break; case JS_EVENT_BUTTON: - _glfw.x11.joystick[i].buttons[e.number] = + _GLFW_LINUX_JOYSTICK_CONTEXT.joystick[i].buttons[e.number] = e.value ? GLFW_PRESS : GLFW_RELEASE; break; @@ -203,14 +208,14 @@ void _glfwTerminateJoysticks(void) for (i = 0; i <= GLFW_JOYSTICK_LAST; i++) { - if (_glfw.x11.joystick[i].present) + if (_GLFW_LINUX_JOYSTICK_CONTEXT.joystick[i].present) { - close(_glfw.x11.joystick[i].fd); - free(_glfw.x11.joystick[i].axes); - free(_glfw.x11.joystick[i].buttons); - free(_glfw.x11.joystick[i].name); + close(_GLFW_LINUX_JOYSTICK_CONTEXT.joystick[i].fd); + free(_GLFW_LINUX_JOYSTICK_CONTEXT.joystick[i].axes); + free(_GLFW_LINUX_JOYSTICK_CONTEXT.joystick[i].buttons); + free(_GLFW_LINUX_JOYSTICK_CONTEXT.joystick[i].name); - _glfw.x11.joystick[i].present = GL_FALSE; + _GLFW_LINUX_JOYSTICK_CONTEXT.joystick[i].present = GL_FALSE; } } #endif // __linux__ @@ -225,35 +230,35 @@ int _glfwPlatformJoystickPresent(int joy) { pollJoystickEvents(); - return _glfw.x11.joystick[joy].present; + return _GLFW_LINUX_JOYSTICK_CONTEXT.joystick[joy].present; } const float* _glfwPlatformGetJoystickAxes(int joy, int* count) { pollJoystickEvents(); - if (!_glfw.x11.joystick[joy].present) + if (!_GLFW_LINUX_JOYSTICK_CONTEXT.joystick[joy].present) return NULL; - *count = _glfw.x11.joystick[joy].axisCount; - return _glfw.x11.joystick[joy].axes; + *count = _GLFW_LINUX_JOYSTICK_CONTEXT.joystick[joy].axisCount; + return _GLFW_LINUX_JOYSTICK_CONTEXT.joystick[joy].axes; } const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count) { pollJoystickEvents(); - if (!_glfw.x11.joystick[joy].present) + if (!_GLFW_LINUX_JOYSTICK_CONTEXT.joystick[joy].present) return NULL; - *count = _glfw.x11.joystick[joy].buttonCount; - return _glfw.x11.joystick[joy].buttons; + *count = _GLFW_LINUX_JOYSTICK_CONTEXT.joystick[joy].buttonCount; + return _GLFW_LINUX_JOYSTICK_CONTEXT.joystick[joy].buttons; } const char* _glfwPlatformGetJoystickName(int joy) { pollJoystickEvents(); - return _glfw.x11.joystick[joy].name; + return _GLFW_LINUX_JOYSTICK_CONTEXT.joystick[joy].name; } diff --git a/src/linux_joystick.h b/src/linux_joystick.h new file mode 100644 index 00000000..8f49b784 --- /dev/null +++ b/src/linux_joystick.h @@ -0,0 +1,46 @@ +//======================================================================== +// GLFW 3.1 Linux - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014 Jonas Ådahl +// +// 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. +// +//======================================================================== + +#ifndef _linux_joystick_h_ +#define _linux_joystick_h_ + +typedef struct _GLFWjoystickLinux { + struct { + int present; + int fd; + float* axes; + int axisCount; + unsigned char* buttons; + int buttonCount; + char* name; + } joystick[GLFW_JOYSTICK_LAST + 1]; +} _GLFWjoystickLinux; + +// Joystick input +void _glfwInitJoysticks(void); +void _glfwTerminateJoysticks(void); + +#endif // _linux_joystick_h_ diff --git a/src/unix_time.c b/src/unix_time.c new file mode 100644 index 00000000..3a558080 --- /dev/null +++ b/src/unix_time.c @@ -0,0 +1,96 @@ +//======================================================================== +// GLFW 3.1 UNIX - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 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. +// +//======================================================================== + +#include "internal.h" + +#include +#include + +// Return raw time +// +static uint64_t getRawTime(void) +{ +#if defined(CLOCK_MONOTONIC) + if (_GLFW_UNIX_TIME_CONTEXT.monotonic) + { + struct timespec ts; + + clock_gettime(CLOCK_MONOTONIC, &ts); + return (uint64_t) ts.tv_sec * (uint64_t) 1000000000 + (uint64_t) ts.tv_nsec; + } + else +#endif + { + struct timeval tv; + + gettimeofday(&tv, NULL); + return (uint64_t) tv.tv_sec * (uint64_t) 1000000 + (uint64_t) tv.tv_usec; + } +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +// Initialise timer +// +void _glfwInitTimer(void) +{ +#if defined(CLOCK_MONOTONIC) + struct timespec ts; + + if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) + { + _GLFW_UNIX_TIME_CONTEXT.monotonic = GL_TRUE; + _GLFW_UNIX_TIME_CONTEXT.resolution = 1e-9; + } + else +#endif + { + _GLFW_UNIX_TIME_CONTEXT.resolution = 1e-6; + } + + _GLFW_UNIX_TIME_CONTEXT.base = getRawTime(); +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +double _glfwPlatformGetTime(void) +{ + return (double) (getRawTime() - _GLFW_UNIX_TIME_CONTEXT.base) * + _GLFW_UNIX_TIME_CONTEXT.resolution; +} + +void _glfwPlatformSetTime(double time) +{ + _GLFW_UNIX_TIME_CONTEXT.base = getRawTime() - + (uint64_t) (time / _GLFW_UNIX_TIME_CONTEXT.resolution); +} diff --git a/src/unix_time.h b/src/unix_time.h new file mode 100644 index 00000000..34294732 --- /dev/null +++ b/src/unix_time.h @@ -0,0 +1,42 @@ +//======================================================================== +// GLFW 3.1 UNIX - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 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. +// +//======================================================================== + +#ifndef _unix_time_h_ +#define _unix_time_h_ + +#include +#include + +typedef struct _GLFWtimeUNIX{ + GLboolean monotonic; + double resolution; + uint64_t base; +} _GLFWtimeUNIX; + +void _glfwInitTimer(void); + +#endif // _unix_time_h_ diff --git a/src/wayland_clipboard.c b/src/wayland_clipboard.c new file mode 100644 index 00000000..247e8ef1 --- /dev/null +++ b/src/wayland_clipboard.c @@ -0,0 +1,47 @@ +//======================================================================== +// GLFW 3.1 Wayland - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014 Jonas Ådahl +// +// 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. +// +//======================================================================== + +#include "internal.h" + +#include + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string) +{ + // TODO + fprintf(stderr, "_glfwPlatformSetClipboardString not implemented yet\n"); +} + +const char* _glfwPlatformGetClipboardString(_GLFWwindow* window) +{ + // TODO + fprintf(stderr, "_glfwPlatformGetClipboardString not implemented yet\n"); + return NULL; +} diff --git a/src/wayland_gamma.c b/src/wayland_gamma.c new file mode 100644 index 00000000..5197a236 --- /dev/null +++ b/src/wayland_gamma.c @@ -0,0 +1,46 @@ +//======================================================================== +// GLFW 3.1 Wayland - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014 Jonas Ådahl +// +// 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. +// +//======================================================================== + +#include "internal.h" + +#include + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) +{ + // TODO + fprintf(stderr, "_glfwPlatformGetGammaRamp not implemented yet\n"); +} + +void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) +{ + // TODO + fprintf(stderr, "_glfwPlatformSetGammaRamp not implemented yet\n"); +} diff --git a/src/wayland_init.c b/src/wayland_init.c new file mode 100644 index 00000000..0e825bdc --- /dev/null +++ b/src/wayland_init.c @@ -0,0 +1,159 @@ +//======================================================================== +// GLFW 3.1 Wayland - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014 Jonas Ådahl +// +// 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. +// +//======================================================================== + +#include "internal.h" + +#include +#include +#include +#include +#include +#include + + +static void +handlePing(void* data, + struct wl_shell_surface* shellSurface, + uint32_t serial) +{ + wl_shell_surface_pong(shellSurface, serial); +} + +static void +handleConfigure(void* data, + struct wl_shell_surface* shellSurface, + uint32_t edges, + int32_t width, + int32_t height) +{ +} + +static void +handlePopupDone(void *data, struct wl_shell_surface *shell_surface) +{ +} + +static const struct wl_shell_surface_listener shellSurfaceListener = { + handlePing, + handleConfigure, + handlePopupDone +}; + +static void registryHandleGlobal(void* data, + struct wl_registry* registry, + uint32_t name, + const char* interface, + uint32_t version) +{ + _GLFWlibraryWayland* wayland = &_glfw.wayland; + + if (strcmp(interface, "wl_compositor") == 0) + { + wayland->compositor = + wl_registry_bind(registry, name, &wl_compositor_interface, 1); + } + else if (strcmp(interface, "wl_shell") == 0) + { + wayland->shell = + wl_registry_bind(registry, name, &wl_shell_interface, 1); + } + else if (strcmp(interface, "wl_output") == 0) + { + _glfwAddOutput(name, version); + } +} + +static void registryHandleGlobalRemove(void *data, + struct wl_registry *registry, + uint32_t name) +{ +} + + +static const struct wl_registry_listener registryListener = { + registryHandleGlobal, + registryHandleGlobalRemove +}; + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +int _glfwPlatformInit(void) +{ + _glfw.wayland.display = wl_display_connect(NULL); + if (!_glfw.wayland.display) + return GL_FALSE; + + _glfw.wayland.registry = wl_display_get_registry(_glfw.wayland.display); + wl_registry_add_listener(_glfw.wayland.registry, ®istryListener, NULL); + + _glfw.wayland.monitors = calloc(4, sizeof(_GLFWmonitor*)); + if (!_glfw.wayland.monitors) + return GL_FALSE; + _glfw.wayland.monitorsSize = 4; + + // Sync so we got all registry objects. + wl_display_roundtrip(_glfw.wayland.display); + + // Sync so we got all initial output events. + wl_display_roundtrip(_glfw.wayland.display); + + if (!_glfwInitContextAPI()) + return GL_FALSE; + + _glfwInitTimer(); + _glfwInitJoysticks(); + + return GL_TRUE; +} + +void _glfwPlatformTerminate(void) +{ + _glfwTerminateContextAPI(); + + if (_glfw.wayland.registry) + wl_registry_destroy(_glfw.wayland.registry); + if (_glfw.wayland.display) + wl_display_flush(_glfw.wayland.display); + if (_glfw.wayland.display) + wl_display_disconnect(_glfw.wayland.display); +} + +const char* _glfwPlatformGetVersionString(void) +{ + const char* version = _GLFW_VERSION_NUMBER " Wayland EGL " +#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK) + " clock_gettime" +#endif +#if defined(_GLFW_BUILD_DLL) + " shared" +#endif + ; + + return version; +} diff --git a/src/wayland_monitor.c b/src/wayland_monitor.c new file mode 100644 index 00000000..ae77e7f9 --- /dev/null +++ b/src/wayland_monitor.c @@ -0,0 +1,272 @@ +//======================================================================== +// GLFW 3.1 Wayland - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014 Jonas Ådahl +// +// 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. +// +//======================================================================== + +#include "internal.h" + +#include +#include +#include +#include + + +struct _GLFWvidmodeWayland { + GLFWvidmode base; + uint32_t flags; +}; + +static void geometry(void* data, + struct wl_output* output, + int32_t x, + int32_t y, + int32_t physicalWidth, + int32_t physicalHeight, + int32_t subpixel, + const char* make, + const char* model, + int32_t transform) +{ + struct _GLFWmonitor *monitor = data; + + monitor->wayland.x = x; + monitor->wayland.y = y; + monitor->widthMM = physicalWidth; + monitor->heightMM = physicalHeight; +} + +static void mode(void* data, + struct wl_output* output, + uint32_t flags, + int32_t width, + int32_t height, + int32_t refresh) +{ + struct _GLFWmonitor *monitor = data; + _GLFWvidmodeWayland mode = { { 0 }, }; + + mode.base.width = width; + mode.base.height = height; + mode.base.refreshRate = refresh; + mode.flags = flags; + + if (monitor->wayland.modesCount + 1 >= monitor->wayland.modesSize) + { + int size = monitor->wayland.modesSize * 2; + _GLFWvidmodeWayland* modes = + realloc(monitor->wayland.modes, + monitor->wayland.modesSize * sizeof(_GLFWvidmodeWayland)); + if (!modes) + { + return; + } + monitor->wayland.modes = modes; + monitor->wayland.modesSize = size; + } + + monitor->wayland.modes[monitor->wayland.modesCount++] = mode; +} + +static void done(void* data, + struct wl_output* output) +{ + struct _GLFWmonitor *monitor = data; + + monitor->wayland.done = GL_TRUE; +} + +static void scale(void* data, + struct wl_output* output, + int32_t factor) +{ +} + +static const struct wl_output_listener output_listener = { + geometry, + mode, + done, + scale, +}; + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +void _glfwAddOutput(uint32_t name, uint32_t version) +{ + _GLFWmonitor *monitor; + struct wl_output *output; + char name_str[80]; + + memset(name_str, 0, 80 * sizeof(char)); + snprintf(name_str, 79, "wl_output@%u", name); + + if (version < 2) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Unsupported wl_output interface version"); + return; + } + + monitor = _glfwAllocMonitor(name_str, 0, 0); + + output = wl_registry_bind(_glfw.wayland.registry, + name, + &wl_output_interface, + 2); + if (!output) + { + _glfwFreeMonitor(monitor); + return; + } + + monitor->wayland.modes = calloc(4, sizeof(_GLFWvidmodeWayland)); + monitor->wayland.modesSize = 4; + + monitor->wayland.output = output; + wl_output_add_listener(output, &output_listener, monitor); + + if (_glfw.wayland.monitorsCount + 1 >= _glfw.wayland.monitorsSize) + { + _GLFWmonitor** monitors = _glfw.wayland.monitors; + int size = _glfw.wayland.monitorsSize * 2; + + monitors = realloc(monitors, size * sizeof(_GLFWmonitor*)); + if (!monitors) + { + wl_output_destroy(output); + _glfwFreeMonitor(monitor); + _glfwInputError(GLFW_PLATFORM_ERROR, + "Failed to retrieve monitor information"); + return; + } + + _glfw.wayland.monitors = monitors; + _glfw.wayland.monitorsSize = size; + } + + _glfw.wayland.monitors[_glfw.wayland.monitorsCount++] = monitor; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +_GLFWmonitor** _glfwPlatformGetMonitors(int* count) +{ + _GLFWmonitor** monitors; + _GLFWmonitor* monitor; + int monitorsCount = _glfw.wayland.monitorsCount; + int i; + + if (_glfw.wayland.monitorsCount == 0) + goto err; + + monitors = calloc(monitorsCount, sizeof(_GLFWmonitor*)); + if (!monitors) + goto err; + + for (i = 0; i < monitorsCount; i++) + { + _GLFWmonitor* origMonitor = _glfw.wayland.monitors[i]; + monitor = malloc(sizeof(_GLFWmonitor)); + if (!monitor) + { + if (i > 0) + { + *count = i; + return monitors; + } + else + { + goto err_free; + } + } + + monitor->modes = + _glfwPlatformGetVideoModes(origMonitor, + &origMonitor->wayland.modesCount); + *monitor = *_glfw.wayland.monitors[i]; + monitors[i] = monitor; + } + + *count = monitorsCount; + return monitors; + +err_free: + free(monitors); + +err: + *count = 0; + return NULL; +} + +GLboolean _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second) +{ + return first->wayland.output == second->wayland.output; +} + +void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) +{ + if (xpos) + *xpos = monitor->wayland.x; + if (ypos) + *ypos = monitor->wayland.y; +} + +GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) +{ + GLFWvidmode *modes; + int modesCount = monitor->wayland.modesCount; + int i; + + modes = calloc(modesCount, sizeof(GLFWvidmode)); + if (!modes) + { + *found = 0;; + return NULL; + } + + for (i = 0; i < modesCount; i++) + modes[i] = monitor->wayland.modes[i].base; + + *found = modesCount; + return modes; +} + +void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) +{ + int i; + + for (i = 0; i < monitor->wayland.modesCount; i++) + { + if (monitor->wayland.modes[i].flags & WL_OUTPUT_MODE_CURRENT) + { + *mode = monitor->wayland.modes[i].base; + return; + } + } +} diff --git a/src/wayland_platform.h b/src/wayland_platform.h new file mode 100644 index 00000000..a683fb00 --- /dev/null +++ b/src/wayland_platform.h @@ -0,0 +1,99 @@ +//======================================================================== +// GLFW 3.1 Wayland - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014 Jonas Ådahl +// +// 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. +// +//======================================================================== + +#ifndef _wayland_platform_h_ +#define _wayland_platform_h_ + + +#if !defined(_GLFW_EGL) + #error "The Wayland backend depends on EGL platform support" +#endif + +#include +#include "egl_platform.h" +#include "linux_joystick.h" +#include "unix_time.h" + +#define _GLFW_X11_CONTEXT_VISUAL window->egl.visual +#define _GLFW_EGL_NATIVE_WINDOW window->wayland.native +#define _GLFW_EGL_NATIVE_DISPLAY _glfw.wayland.display +#define _GLFW_UNIX_TIME_CONTEXT _glfw.wayland.timer +#define _GLFW_LINUX_JOYSTICK_CONTEXT _glfw.wayland.joystick + +#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWayland wayland +#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWayland wayland +#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWayland wayland + + +typedef struct _GLFWvidmodeWayland _GLFWvidmodeWayland; + +typedef struct _GLFWwindowWayland +{ + int width, height; + GLboolean visible; + struct wl_surface* surface; + struct wl_egl_window* native; + struct wl_shell_surface* shell_surface; + EGLSurface egl_surface; + struct wl_callback* callback; +} _GLFWwindowWayland; + +typedef struct _GLFWlibraryWayland +{ + struct wl_display* display; + struct wl_registry* registry; + struct wl_compositor* compositor; + struct wl_shell* shell; + + _GLFWmonitor** monitors; + int monitorsCount; + int monitorsSize; + + _GLFWtimeUNIX timer; + _GLFWjoystickLinux joystick; +} _GLFWlibraryWayland; + +typedef struct _GLFWmonitorWayland +{ + struct wl_output* output; + + _GLFWvidmodeWayland* modes; + int modesCount; + int modesSize; + GLboolean done; + + int x; + int y; +} _GLFWmonitorWayland; + + +//======================================================================== +// Prototypes for platform specific internal functions +//======================================================================== + +void _glfwAddOutput(uint32_t name, uint32_t version); + +#endif // _wayland_platform_h_ diff --git a/src/wayland_window.c b/src/wayland_window.c new file mode 100644 index 00000000..862426ba --- /dev/null +++ b/src/wayland_window.c @@ -0,0 +1,281 @@ +//======================================================================== +// GLFW 3.1 Wayland - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014 Jonas Ådahl +// +// 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. +// +//======================================================================== + +#include "internal.h" + +#include +#include +#include +#include + + +static void +handlePing(void* data, + struct wl_shell_surface* shellSurface, + uint32_t serial) +{ + wl_shell_surface_pong(shellSurface, serial); +} + +static void +handleConfigure(void* data, + struct wl_shell_surface* shellSurface, + uint32_t edges, + int32_t width, + int32_t height) +{ +} + +static void +handlePopupDone(void* data, + struct wl_shell_surface* shellSurface) +{ +} + +static const struct wl_shell_surface_listener shellSurfaceListener = { + handlePing, + handleConfigure, + handlePopupDone +}; + +static GLboolean createSurface(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig) +{ + window->wayland.surface = + wl_compositor_create_surface(_glfw.wayland.compositor); + if (!window->wayland.surface) + return GL_FALSE; + + window->wayland.native = + wl_egl_window_create(window->wayland.surface, + wndconfig->width, + wndconfig->height); + if (!window->wayland.native) + return GL_FALSE; + + window->wayland.shell_surface = + wl_shell_get_shell_surface(_glfw.wayland.shell, + window->wayland.surface); + if (!window->wayland.shell_surface) + return GL_FALSE; + + wl_shell_surface_add_listener(window->wayland.shell_surface, + &shellSurfaceListener, + window); + + window->wayland.width = wndconfig->width; + window->wayland.height = wndconfig->height; + + return GL_TRUE; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +int _glfwPlatformCreateWindow(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig) +{ + if (!_glfwCreateContext(window, ctxconfig, fbconfig)) + return GL_FALSE; + + if (!createSurface(window, wndconfig)) + return GL_FALSE; + + if (wndconfig->monitor) + { + wl_shell_surface_set_fullscreen( + window->wayland.shell_surface, + WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, + 0, + wndconfig->monitor->wayland.output); + } + else + { + wl_shell_surface_set_toplevel(window->wayland.shell_surface); + } + + return GL_TRUE; +} + +void _glfwPlatformDestroyWindow(_GLFWwindow* window) +{ + if (window->wayland.native) + wl_egl_window_destroy(window->wayland.native); + + _glfwDestroyContext(window); + + if (window->wayland.shell_surface) + wl_shell_surface_destroy(window->wayland.shell_surface); + + if (window->wayland.surface) + wl_surface_destroy(window->wayland.surface); +} + +void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) +{ + wl_shell_surface_set_title(window->wayland.shell_surface, title); +} + +void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) +{ + // A Wayland client is not aware of its position, so just warn and set it + // to (0, 0) + + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland does not allow manual window positioning"); + + if (xpos) + *xpos = 0; + if (ypos) + *ypos = 0; +} + +void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos) +{ + // A Wayland client can not set its position, so just warn and set it + // to (0, 0) + + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland does not allow manual window positioning"); +} + +void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) +{ + if (width) + *width = window->wayland.width; + if (height) + *height = window->wayland.height; +} + +void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) +{ + wl_egl_window_resize(window->wayland.native, width, height, 0, 0); + window->wayland.width = width; + window->wayland.height = height; +} + +void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) +{ + _glfwPlatformGetWindowSize(window, width, height); +} + +void _glfwPlatformIconifyWindow(_GLFWwindow* window) +{ + // TODO + fprintf(stderr, "_glfwPlatformIconifyWindow not implemented yet\n"); +} + +void _glfwPlatformRestoreWindow(_GLFWwindow* window) +{ + // TODO + fprintf(stderr, "_glfwPlatformRestoreWindow not implemented yet\n"); +} + +void _glfwPlatformShowWindow(_GLFWwindow* window) +{ + wl_shell_surface_set_toplevel(window->wayland.shell_surface); +} + +void _glfwPlatformHideWindow(_GLFWwindow* window) +{ + wl_surface_attach(window->wayland.surface, NULL, 0, 0); + wl_surface_commit(window->wayland.surface); +} + +void _glfwPlatformPollEvents(void) +{ + struct wl_display* display = _glfw.wayland.display; + struct pollfd fds[] = { + { wl_display_get_fd(display), POLLIN }, + }; + + while (wl_display_prepare_read(display) != 0) + wl_display_dispatch_pending(display); + wl_display_flush(display); + if (poll(fds, 1, 0) > 0) + { + wl_display_read_events(display); + wl_display_dispatch_pending(display); + } + else + { + wl_display_cancel_read(display); + } +} + +void _glfwPlatformWaitEvents(void) +{ + struct wl_display* display = _glfw.wayland.display; + struct pollfd fds[] = { + { wl_display_get_fd(display), POLLIN }, + }; + + while (wl_display_prepare_read(display) != 0) + wl_display_dispatch_pending(display); + wl_display_flush(display); + if (poll(fds, 1, -1) > 0) + { + wl_display_read_events(display); + wl_display_dispatch_pending(display); + } + else + { + wl_display_cancel_read(display); + } +} + +void _glfwPlatformPostEmptyEvent(void) +{ + wl_display_sync(_glfw.wayland.display); +} + +void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) +{ + // A Wayland client can not set the cursor position. + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland does not allow cursor positioning"); +} + +void _glfwPlatformApplyCursorMode(_GLFWwindow* window) +{ + fprintf(stderr, "_glfwPlatformApplyCursorMode not implemented yet\n"); + switch (window->cursorMode) + { + case GLFW_CURSOR_NORMAL: + // TODO: enable showing cursor + break; + case GLFW_CURSOR_HIDDEN: + // TODO: enable not showing cursor + break; + case GLFW_CURSOR_DISABLED: + // TODO: enable pointer lock and hide cursor + break; + } +} diff --git a/src/x11_platform.h b/src/x11_platform.h index fca8d3e1..802aaec4 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -62,6 +62,12 @@ #error "No supported context creation API selected" #endif +#define _GLFW_UNIX_TIME_CONTEXT _glfw.x11.timer +#include "unix_time.h" + +#define _GLFW_LINUX_JOYSTICK_CONTEXT _glfw.x11.joystick +#include "linux_joystick.h" + #define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 x11 #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11 #define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorX11 x11 @@ -199,11 +205,7 @@ typedef struct _GLFWlibraryX11 int exposure; } saver; - struct { - GLboolean monotonic; - double resolution; - uint64_t base; - } timer; + _GLFWtimeUNIX timer; struct { char* string; @@ -213,15 +215,7 @@ typedef struct _GLFWlibraryX11 Window source; } xdnd; - struct { - int present; - int fd; - float* axes; - int axisCount; - unsigned char* buttons; - int buttonCount; - char* name; - } joystick[GLFW_JOYSTICK_LAST + 1]; + _GLFWjoystickLinux joystick; } _GLFWlibraryX11; @@ -251,9 +245,6 @@ typedef struct _GLFWcursorX11 // Prototypes for platform specific internal functions //======================================================================== -// Time -void _glfwInitTimer(void); - // Gamma void _glfwInitGammaRamp(void); @@ -261,10 +252,6 @@ void _glfwInitGammaRamp(void); GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired); void _glfwRestoreVideoMode(_GLFWmonitor* monitor); -// Joystick input -void _glfwInitJoysticks(void); -void _glfwTerminateJoysticks(void); - // Unicode support long _glfwKeySym2Unicode(KeySym keysym);