From 8e99996321766d674c6fdf7f9f2e71d4e42aac30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Mon, 17 Mar 2014 22:53:43 +0100 Subject: [PATCH] Introduce experimental Wayland backend This patch introduces a new backend that enables GLFW applications to run on Wayland. For now, only output is supported (windowed and fullscreen). Pointer cursor management, input devices, clipboard etc are not supported yet. There are some concepts that can not be supported, more specifically glfwSetWindowPos, glfwGetWindowPos and glfwSetCursorPos, as they are not supported by Wayland. This patch also changes the time and joystick implementations used by the X11 backend to be shared between the Wayland backend and the X11 backend. --- CMake/modules/FindWayland.cmake | 62 +++++ CMakeLists.txt | 36 ++- src/CMakeLists.txt | 15 +- src/glfw_config.h.in | 2 + src/internal.h | 2 + src/{x11_joystick.c => linux_joystick.c} | 65 +++--- src/linux_joystick.h | 46 ++++ src/unix_time.c | 96 ++++++++ src/unix_time.h | 42 ++++ src/wayland_clipboard.c | 47 ++++ src/wayland_gamma.c | 46 ++++ src/wayland_init.c | 159 +++++++++++++ src/wayland_monitor.c | 272 ++++++++++++++++++++++ src/wayland_platform.h | 99 ++++++++ src/wayland_window.c | 281 +++++++++++++++++++++++ src/x11_platform.h | 29 +-- 16 files changed, 1242 insertions(+), 57 deletions(-) create mode 100644 CMake/modules/FindWayland.cmake rename src/{x11_joystick.c => linux_joystick.c} (71%) create mode 100644 src/linux_joystick.h create mode 100644 src/unix_time.c create mode 100644 src/unix_time.h create mode 100644 src/wayland_clipboard.c create mode 100644 src/wayland_gamma.c create mode 100644 src/wayland_init.c create mode 100644 src/wayland_monitor.c create mode 100644 src/wayland_platform.h create mode 100644 src/wayland_window.c 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);