Commit 8e999963 authored by Jonas Ådahl's avatar Jonas Ådahl Committed by Camilla Berglund
Browse files

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.
parent 99c98407
# 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 <mgraesslin@kde.org>
#
# 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 ()
......@@ -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
#--------------------------------------------------------------------
......
......@@ -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)
......
......@@ -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
......
......@@ -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
......
//========================================================================
// 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 <elmindreda@elmindreda.org>
......@@ -39,6 +39,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#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;
}
//========================================================================
// GLFW 3.1 Linux - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
//
// 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_
//========================================================================
// GLFW 3.1 UNIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
//
// 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 <sys/time.h>
#include <time.h>
// 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);
}
//========================================================================
// GLFW 3.1 UNIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
//
// 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 <stdint.h>
#include <GL/gl.h>
typedef struct _GLFWtimeUNIX{
GLboolean monotonic;
double resolution;
uint64_t base;
} _GLFWtimeUNIX;
void _glfwInitTimer(void);
#endif // _unix_time_h_
//========================================================================
// GLFW 3.1 Wayland - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
//
// 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 <stdio.h>
//////////////////////////////////////////////////////////////////////////
////// 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;
}
//========================================================================
// GLFW 3.1 Wayland - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
//
// 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 <stdio.h>
//////////////////////////////////////////////////////////////////////////
////// 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");
}
//========================================================================
// GLFW 3.1 Wayland - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
//
// 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:
//