Merge pull request #30 from Tarnyko/git_master
Implement initial Wayland support
This commit is contained in:
commit
7fbdb4ea1e
@ -52,8 +52,10 @@ ENDIF()
|
||||
# OpenGL ES support
|
||||
OPTION(FREEGLUT_GLES "Use OpenGL ES (requires EGL)" OFF)
|
||||
|
||||
# option to build either as "glut" (ON) or "freeglut" (OFF)
|
||||
IF(NOT WIN32)
|
||||
# Wayland support
|
||||
OPTION(FREEGLUT_WAYLAND "Use Wayland (no X11)" OFF)
|
||||
# option to build either as "glut" (ON) or "freeglut" (OFF)
|
||||
OPTION(FREEGLUT_REPLACE_GLUT "Be a replacement for GLUT" ON)
|
||||
ENDIF()
|
||||
|
||||
@ -167,36 +169,60 @@ ELSEIF(ANDROID OR BLACKBERRY)
|
||||
src/blackberry/fg_window_blackberry.c
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
ELSE()
|
||||
LIST(APPEND FREEGLUT_SRCS
|
||||
src/x11/fg_cursor_x11.c
|
||||
src/x11/fg_ext_x11.c
|
||||
src/x11/fg_gamemode_x11.c
|
||||
src/x11/fg_glutfont_definitions_x11.c
|
||||
src/x11/fg_init_x11.c
|
||||
src/x11/fg_internal_x11.h
|
||||
src/x11/fg_input_devices_x11.c
|
||||
src/x11/fg_joystick_x11.c
|
||||
src/x11/fg_main_x11.c
|
||||
src/x11/fg_menu_x11.c
|
||||
src/x11/fg_spaceball_x11.c
|
||||
src/x11/fg_state_x11.c
|
||||
src/x11/fg_structure_x11.c
|
||||
src/x11/fg_window_x11.c
|
||||
src/x11/fg_xinput_x11.c
|
||||
)
|
||||
IF(NOT(FREEGLUT_GLES))
|
||||
# UNIX (Wayland)
|
||||
IF(FREEGLUT_WAYLAND)
|
||||
LIST(APPEND FREEGLUT_SRCS
|
||||
src/x11/fg_internal_x11_glx.h
|
||||
src/x11/fg_display_x11_glx.c
|
||||
src/x11/fg_state_x11_glx.c
|
||||
src/x11/fg_state_x11_glx.h
|
||||
src/x11/fg_window_x11_glx.c
|
||||
src/x11/fg_window_x11_glx.h
|
||||
src/wayland/fg_cursor_wl.c
|
||||
src/wayland/fg_ext_wl.c
|
||||
src/wayland/fg_gamemode_wl.c
|
||||
src/wayland/fg_init_wl.c
|
||||
src/wayland/fg_internal_wl.h
|
||||
src/wayland/fg_input_devices_wl.c
|
||||
src/wayland/fg_main_wl.c
|
||||
src/wayland/fg_state_wl.c
|
||||
src/wayland/fg_structure_wl.c
|
||||
src/wayland/fg_window_wl.c
|
||||
# font, serial port & joystick code are agnostic
|
||||
src/x11/fg_glutfont_definitions_x11.c
|
||||
src/x11/fg_input_devices_x11.c
|
||||
src/x11/fg_joystick_x11.c
|
||||
)
|
||||
# UNIX (X11)
|
||||
ELSE()
|
||||
LIST(APPEND FREEGLUT_SRCS
|
||||
src/x11/fg_cursor_x11.c
|
||||
src/x11/fg_ext_x11.c
|
||||
src/x11/fg_gamemode_x11.c
|
||||
src/x11/fg_glutfont_definitions_x11.c
|
||||
src/x11/fg_init_x11.c
|
||||
src/x11/fg_internal_x11.h
|
||||
src/x11/fg_input_devices_x11.c
|
||||
src/x11/fg_joystick_x11.c
|
||||
src/x11/fg_main_x11.c
|
||||
src/x11/fg_menu_x11.c
|
||||
src/x11/fg_spaceball_x11.c
|
||||
src/x11/fg_state_x11.c
|
||||
src/x11/fg_structure_x11.c
|
||||
src/x11/fg_window_x11.c
|
||||
src/x11/fg_xinput_x11.c
|
||||
)
|
||||
IF(NOT(FREEGLUT_GLES))
|
||||
LIST(APPEND FREEGLUT_SRCS
|
||||
src/x11/fg_internal_x11_glx.h
|
||||
src/x11/fg_display_x11_glx.c
|
||||
src/x11/fg_state_x11_glx.c
|
||||
src/x11/fg_state_x11_glx.h
|
||||
src/x11/fg_window_x11_glx.c
|
||||
src/x11/fg_window_x11_glx.h
|
||||
)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(FREEGLUT_GLES)
|
||||
|
||||
# OpenGL ES requires EGL, and so does Wayland
|
||||
IF(FREEGLUT_GLES OR FREEGLUT_WAYLAND)
|
||||
LIST(APPEND FREEGLUT_SRCS
|
||||
src/egl/fg_internal_egl.h
|
||||
src/egl/fg_display_egl.c
|
||||
@ -226,6 +252,12 @@ ELSE()
|
||||
INCLUDE_DIRECTORIES(${OPENGL_INCLUDE_DIR})
|
||||
ENDIF()
|
||||
|
||||
# For Wayland: compile with -DFREEGLUT_WAYLAND and pull EGL
|
||||
IF(FREEGLUT_WAYLAND)
|
||||
ADD_DEFINITIONS(-DFREEGLUT_WAYLAND)
|
||||
LIST(APPEND LIBS wayland-client wayland-cursor wayland-egl EGL xkbcommon)
|
||||
ENDIF()
|
||||
|
||||
# lib m for math, not needed on windows
|
||||
IF (NOT WIN32)
|
||||
# For compilation:
|
||||
@ -248,14 +280,14 @@ ENDIF()
|
||||
|
||||
IF(CMAKE_COMPILER_IS_GNUCC)
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
||||
IF(NOT(ANDROID OR BLACKBERRY))
|
||||
IF(NOT(ANDROID OR BLACKBERRY OR FREEGLUT_WAYLAND))
|
||||
# not setting -ansi as EGL/KHR headers doesn't support it
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic")
|
||||
ENDIF()
|
||||
ENDIF(CMAKE_COMPILER_IS_GNUCC)
|
||||
|
||||
INCLUDE(CheckIncludeFiles)
|
||||
IF(UNIX AND NOT(ANDROID OR BLACKBERRY))
|
||||
IF(UNIX AND NOT(ANDROID OR BLACKBERRY OR FREEGLUT_WAYLAND))
|
||||
FIND_PACKAGE(X11 REQUIRED)
|
||||
INCLUDE_DIRECTORIES(${X11_INCLUDE_DIR})
|
||||
LIST(APPEND LIBS ${X11_LIBRARIES})
|
||||
@ -506,11 +538,17 @@ ELSEIF(FREEGLUT_GLES)
|
||||
ELSE()
|
||||
SET(PC_LIBS_PRIVATE "-lbps -lslog2 -lscreen -lGLESv2 -lGLESv1_CM -lEGL -lm")
|
||||
ENDIF()
|
||||
ELSEIF(FREEGLUT_WAYLAND)
|
||||
SET(PC_LIBS_PRIVATE "-lwayland-client -lwayland-cursor -lwayland-egl -lGLESv2 -lGLESv1_CM -lEGL -lxkbcommon -lm")
|
||||
ELSE()
|
||||
SET(PC_LIBS_PRIVATE "-lX11 -lXxf86vm -lXrandr -lGLESv2 -lGLESv1_CM -lEGL -lm")
|
||||
ENDIF()
|
||||
ELSE()
|
||||
SET(PC_LIBS_PRIVATE "-lX11 -lXxf86vm -lXrandr -lGL -lm")
|
||||
IF(FREEGLUT_WAYLAND)
|
||||
SET(PC_LIBS_PRIVATE "-lwayland-client -lwayland-cursor -lwayland-egl -lGL -lxkbcommon -lm")
|
||||
ELSE()
|
||||
SET(PC_LIBS_PRIVATE "-lX11 -lXxf86vm -lXrandr -lGL -lm")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
# Client applications need to define FreeGLUT GLES version to
|
||||
# bootstrap headers inclusion in freeglut_std.h:
|
||||
|
@ -34,8 +34,13 @@ void fghPlatformInitializeEGL()
|
||||
{
|
||||
/* CreateDisplay */
|
||||
/* Using EGL_DEFAULT_DISPLAY, or a specific native display */
|
||||
#ifdef FREEGLUT_WAYLAND
|
||||
fgDisplay.pDisplay.egl.Display = eglGetDisplay(
|
||||
(EGLNativeDisplayType)fgDisplay.pDisplay.display);
|
||||
#else
|
||||
EGLNativeDisplayType nativeDisplay = EGL_DEFAULT_DISPLAY;
|
||||
fgDisplay.pDisplay.egl.Display = eglGetDisplay(nativeDisplay);
|
||||
#endif
|
||||
|
||||
FREEGLUT_INTERNAL_ERROR_EXIT(fgDisplay.pDisplay.egl.Display != EGL_NO_DISPLAY,
|
||||
"No display available", "fgPlatformInitialize");
|
||||
|
@ -51,7 +51,11 @@
|
||||
# define TARGET_HOST_BLACKBERRY 1
|
||||
|
||||
#elif defined(__posix__) || defined(__unix__) || defined(__linux__) || defined(__sun)
|
||||
# define TARGET_HOST_POSIX_X11 1
|
||||
# if defined(FREEGLUT_WAYLAND)
|
||||
# define TARGET_HOST_POSIX_WAYLAND 1
|
||||
# else
|
||||
# define TARGET_HOST_POSIX_X11 1
|
||||
# endif
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
/* This is a placeholder until we get native OSX support ironed out -- JFF 11/18/09 */
|
||||
@ -70,32 +74,36 @@
|
||||
#endif
|
||||
|
||||
#ifndef TARGET_HOST_MS_WINDOWS
|
||||
# define TARGET_HOST_MS_WINDOWS 0
|
||||
# define TARGET_HOST_MS_WINDOWS 0
|
||||
#endif
|
||||
|
||||
#ifndef TARGET_HOST_ANDROID
|
||||
# define TARGET_HOST_ANDROID 0
|
||||
# define TARGET_HOST_ANDROID 0
|
||||
#endif
|
||||
|
||||
#ifndef TARGET_HOST_BLACKBERRY
|
||||
# define TARGET_HOST_BLACKBERRY 0
|
||||
# define TARGET_HOST_BLACKBERRY 0
|
||||
#endif
|
||||
|
||||
#ifndef TARGET_HOST_POSIX_WAYLAND
|
||||
# define TARGET_HOST_POSIX_WAYLAND 0
|
||||
#endif
|
||||
|
||||
#ifndef TARGET_HOST_POSIX_X11
|
||||
# define TARGET_HOST_POSIX_X11 0
|
||||
# define TARGET_HOST_POSIX_X11 0
|
||||
#endif
|
||||
|
||||
#ifndef TARGET_HOST_MAC_OSX
|
||||
# define TARGET_HOST_MAC_OSX 0
|
||||
# define TARGET_HOST_MAC_OSX 0
|
||||
#endif
|
||||
|
||||
#ifndef TARGET_HOST_SOLARIS
|
||||
# define TARGET_HOST_SOLARIS 0
|
||||
# define TARGET_HOST_SOLARIS 0
|
||||
#endif
|
||||
|
||||
/* -- FIXED CONFIGURATION LIMITS ------------------------------------------- */
|
||||
|
||||
#define FREEGLUT_MAX_MENUS 3
|
||||
#define FREEGLUT_MAX_MENUS 3
|
||||
|
||||
/* These files should be available on every platform. */
|
||||
#include <stdio.h>
|
||||
@ -188,6 +196,9 @@
|
||||
#endif
|
||||
|
||||
/* Platform-specific includes */
|
||||
#if TARGET_HOST_POSIX_WAYLAND
|
||||
#include "wayland/fg_internal_wl.h"
|
||||
#endif
|
||||
#if TARGET_HOST_POSIX_X11
|
||||
#include "x11/fg_internal_x11.h"
|
||||
#endif
|
||||
|
137
freeglut/freeglut/src/wayland/fg_cursor_wl.c
Normal file
137
freeglut/freeglut/src/wayland/fg_cursor_wl.c
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* fg_cursor_wl.c
|
||||
*
|
||||
* The Wayland-specific mouse cursor related stuff.
|
||||
*
|
||||
* Copyright (c) 2015 Manuel Bachmann. All Rights Reserved.
|
||||
* Written by Manuel Bachmann, <tarnyko@tarnyko.net>
|
||||
* Creation date: Thur Mar 19, 2015
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* MANUEL BACHMANN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <GL/freeglut.h>
|
||||
#include "../fg_internal.h"
|
||||
|
||||
/*
|
||||
* Note: The arrangement of the table below depends on the fact that
|
||||
* the "normal" GLUT_CURSOR_* values start a 0 and are consecutive.
|
||||
*/
|
||||
static char* cursorList[] = {
|
||||
"UNSUPPORTED", /* GLUT_CURSOR_RIGHT_ARROW */
|
||||
"left_ptr", /* GLUT_CURSOR_LEFT_ARROW */
|
||||
"hand1", /* GLUT_CURSOR_INFO */
|
||||
"UNSUPPORTED", /* GLUT_CURSOR_DESTROY */
|
||||
"UNSUPPORTED", /* GLUT_CURSOR_HELP */
|
||||
"UNSUPPORTED", /* GLUT_CURSOR_CYCLE */
|
||||
"UNSUPPORTED", /* GLUT_CURSOR_SPRAY */
|
||||
"watch", /* GLUT_CURSOR_WAIT */
|
||||
"xterm", /* GLUT_CURSOR_TEXT */
|
||||
"grabbing", /* GLUT_CURSOR_CROSSHAIR */
|
||||
"UNSUPPORTED", /* GLUT_CURSOR_UP_DOWN */
|
||||
"UNSUPPORTED", /* GLUT_CURSOR_LEFT_RIGHT */
|
||||
"top_side", /* GLUT_CURSOR_TOP_SIDE */
|
||||
"bottom_side", /* GLUT_CURSOR_BOTTOM_SIDE */
|
||||
"left_side", /* GLUT_CURSOR_LEFT_SIDE */
|
||||
"right_side", /* GLUT_CURSOR_RIGHT_SIDE */
|
||||
"top_left_corner", /* GLUT_CURSOR_TOP_LEFT_CORNER */
|
||||
"top_right_corner", /* GLUT_CURSOR_TOP_RIGHT_CORNER */
|
||||
"bottom_right_corner", /* GLUT_CURSOR_BOTTOM_RIGHT_CORNER */
|
||||
"bottom_left_corner" /* GLUT_CURSOR_BOTTOM_LEFT_CORNER */
|
||||
};
|
||||
|
||||
void fgPlatformSetCursor ( SFG_Window *window, int cursorID )
|
||||
{
|
||||
/*
|
||||
* XXX FULL_CROSSHAIR demotes to plain CROSSHAIR. Old GLUT allows
|
||||
* for this, but if there is a system that easily supports a full-
|
||||
* window (or full-screen) crosshair, we might consider it.
|
||||
*/
|
||||
int cursorIDToUse =
|
||||
( cursorID == GLUT_CURSOR_FULL_CROSSHAIR ) ? GLUT_CURSOR_CROSSHAIR : cursorID;
|
||||
|
||||
char* cursor;
|
||||
|
||||
if( ( cursorIDToUse >= 0 ) &&
|
||||
( cursorIDToUse < sizeof( cursorList ) / sizeof( cursorList[0] ) ) ) {
|
||||
|
||||
cursor = cursorList[cursorIDToUse];
|
||||
|
||||
/* if the type is UNSUPPORTED, fall back to GLUT_CURSOR_LEFT_ARROW */
|
||||
if ( ! strcmp( cursor, "UNSUPPORTED" ) )
|
||||
{
|
||||
fgWarning( "glutSetCursor(): cursor type unsupported under Wayland : %d",
|
||||
cursorIDToUse );
|
||||
cursor = "left_ptr";
|
||||
}
|
||||
} else {
|
||||
switch( cursorIDToUse )
|
||||
{
|
||||
case GLUT_CURSOR_NONE:
|
||||
case GLUT_CURSOR_INHERIT:
|
||||
cursor = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
fgError( "Unknown cursor type: %d", cursorIDToUse );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( cursorIDToUse == GLUT_CURSOR_INHERIT ) {
|
||||
if( window->Parent )
|
||||
window->Window.pContext.cursor =
|
||||
window->Parent->Window.pContext.cursor;
|
||||
} else {
|
||||
window->Window.pContext.cursor = wl_cursor_theme_get_cursor(
|
||||
fgDisplay.pDisplay.cursor_theme,
|
||||
cursor );
|
||||
if ( ! window->Window.pContext.cursor )
|
||||
fgError( "Failed to create cursor" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void fgPlatformWarpPointer ( int x, int y )
|
||||
{
|
||||
/* unsupported under Wayland */
|
||||
fgWarning( "glutWarpPointer(): function unsupported under Wayland" );
|
||||
}
|
||||
|
||||
void fghPlatformGetCursorPos(const SFG_Window *window, GLboolean client, SFG_XYUse *mouse_pos)
|
||||
{
|
||||
/* Get current pointer location relative to top-left of client area of window (if client is true and window is not NULL)
|
||||
* We cannot get current pointer location in screen coordinates under Wayland, so inform the user and return -1 is this case
|
||||
*/
|
||||
|
||||
if (client && window)
|
||||
{
|
||||
mouse_pos->X = window->State.MouseX;
|
||||
mouse_pos->Y = window->State.MouseY;
|
||||
}
|
||||
else
|
||||
{
|
||||
fgWarning( "glutGetCursorPos(): cannot get screen position under Wayland" );
|
||||
mouse_pos->X = -1;
|
||||
mouse_pos->Y = -1;
|
||||
}
|
||||
|
||||
mouse_pos->Use = GL_TRUE;
|
||||
}
|
||||
|
49
freeglut/freeglut/src/wayland/fg_ext_wl.c
Normal file
49
freeglut/freeglut/src/wayland/fg_ext_wl.c
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* fg_ext_wl.c
|
||||
*
|
||||
* Wayland-specific functions related to OpenGL extensions.
|
||||
*
|
||||
* Copyright (c) 2015 Manuel Bachmann. All Rights Reserved.
|
||||
* Written by Manuel Bachmann, <tarnyko@tarnyko.net>
|
||||
* Creation date: Wed Mar 25 2015
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* MANUEL BACHMANN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <GL/freeglut.h>
|
||||
#include "../fg_internal.h"
|
||||
|
||||
GLUTproc fgPlatformGetGLUTProcAddress( const char* procName )
|
||||
{
|
||||
/* optimization: quick initial check */
|
||||
if( strncmp( procName, "glut", 4 ) != 0 )
|
||||
return NULL;
|
||||
|
||||
#define CHECK_NAME(x) if( strcmp( procName, #x ) == 0) return (GLUTproc)x;
|
||||
CHECK_NAME(glutJoystickFunc);
|
||||
CHECK_NAME(glutForceJoystickFunc);
|
||||
CHECK_NAME(glutGameModeString);
|
||||
CHECK_NAME(glutEnterGameMode);
|
||||
CHECK_NAME(glutLeaveGameMode);
|
||||
CHECK_NAME(glutGameModeGet);
|
||||
#undef CHECK_NAME
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
161
freeglut/freeglut/src/wayland/fg_gamemode_wl.c
Normal file
161
freeglut/freeglut/src/wayland/fg_gamemode_wl.c
Normal file
@ -0,0 +1,161 @@
|
||||
/*
|
||||
* fg_gamemode_wl.c
|
||||
*
|
||||
* The game mode handling code.
|
||||
*
|
||||
* Copyright (c) 2015 Manuel Bachmann. All Rights Reserved.
|
||||
* Written by Manuel Bachmann, <tarnyko@tarnyko.net>
|
||||
* Creation date: Sun Mar 23 2015
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* MANUEL BACHMANN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <GL/freeglut.h>
|
||||
#include "../fg_internal.h"
|
||||
|
||||
/* Pointer locking is a Weston-specific WIP protocol (for now)
|
||||
*
|
||||
* #include "pointer-lock-client-protocol.h"
|
||||
* #include "relative-pointer-client-protocol.h"
|
||||
*
|
||||
* static struct _wl_relative_pointer_manager* relative_pointer_manager;
|
||||
* static struct _wl_pointer_lock* pointer_lock;
|
||||
*
|
||||
* static struct _wl_relative_pointer* relative_pointer;
|
||||
* static struct _wl_locked_pointer* locked_pointer;
|
||||
*
|
||||
*
|
||||
* static void fghRelativeMotion( void* data, struct _wl_relative_pointer
|
||||
* pointer, uint32_t time,
|
||||
* wl_fixed_t x_w, wl_fixed_t y_w,
|
||||
* wl_fixed_t x_noacc, wl_fixed_t y_noacc )
|
||||
* {
|
||||
* SFG_Window* win = fgStructure.CurrentWindow;
|
||||
* win->State.MouseX = wl_fixed_to_int( x_w );
|
||||
* win->State.MouseY = wl_fixed_to_int( y_w );
|
||||
* INVOKE_WCB( *win, Passive, ( win->State.MouseX,
|
||||
* win->State.MouseY ) );
|
||||
* }
|
||||
* static const struct _wl_relative_pointer_listener
|
||||
* fghRelativeListener =
|
||||
* {
|
||||
* fghRelativeMotion
|
||||
* };
|
||||
*
|
||||
* static void fghLockedLocked( void* data, struct _wl_locked_pointer
|
||||
* pointer, uint32_t serial )
|
||||
* {
|
||||
* fgPlatformRememberState();
|
||||
* fgPlatformSetCursor( win, GLUT_CURSOR_NONE ):
|
||||
* }
|
||||
* static void fghLockedUnlocked( void* data, struct _wl_locked_pointer
|
||||
* pointer )
|
||||
* {
|
||||
* fgPlatformRestoreState();
|
||||
* }
|
||||
* static const struct _wl_locked_pointer_listener
|
||||
* fghLockedListener =
|
||||
* {
|
||||
* fghLockedLocked,
|
||||
* fghLockedUnlocked
|
||||
* };
|
||||
*/
|
||||
|
||||
|
||||
static struct wl_cursor* saved_cursor;
|
||||
|
||||
/*
|
||||
* Remembers the current visual settings, so that
|
||||
* we can change them and restore later...
|
||||
*/
|
||||
void fgPlatformRememberState( void )
|
||||
{
|
||||
SFG_Window* win = fgStructure.CurrentWindow;
|
||||
saved_cursor = win->Window.pContext.cursor;
|
||||
}
|
||||
|
||||
/*
|
||||
* Restores the previously remembered visual settings
|
||||
*/
|
||||
void fgPlatformRestoreState( void )
|
||||
{
|
||||
SFG_Window* win = fgStructure.CurrentWindow;
|
||||
win->Window.pContext.cursor = saved_cursor;
|
||||
}
|
||||
|
||||
/*
|
||||
* * Private function to get the virtual maximum screen extent
|
||||
* */
|
||||
GLvoid fgPlatformGetGameModeVMaxExtent( SFG_Window* window, int* x, int* y )
|
||||
{
|
||||
/*
|
||||
* under Wayland, just return the size of the window,
|
||||
* at least until we start messing with the outputs...
|
||||
*/
|
||||
*x = window->State.Width;
|
||||
*y = window->State.Height;
|
||||
}
|
||||
|
||||
/*
|
||||
* Changes the current display mode to match user's settings
|
||||
*/
|
||||
GLboolean fgPlatformChangeDisplayMode( GLboolean haveToTest )
|
||||
{
|
||||
/* Such a protocol is being studied in Wayland */
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
void fgPlatformEnterGameMode( void )
|
||||
{
|
||||
SFG_Window* win = fgStructure.CurrentWindow;
|
||||
struct wl_region* region;
|
||||
|
||||
region = wl_compositor_create_region (
|
||||
fgDisplay.pDisplay.compositor );
|
||||
wl_region_add( region, 0, 0,
|
||||
win->State.Width,
|
||||
win->State.Height );
|
||||
/*
|
||||
* relative_pointer =
|
||||
* _wl_relative_pointer_manager_get_relative_pointer (
|
||||
* relative_pointer_manager,
|
||||
* fgDisplay.pDisplay.seat );
|
||||
* _wl_relative_pointer_add_listener( relative_pointer,
|
||||
* &fghRelativeListener,
|
||||
* NULL );
|
||||
* locked_pointer = _wl_pointer_lock_lock_pointer (
|
||||
* pointer_lock,
|
||||
* win->Window.pContext.surface,
|
||||
* fgDisplay.pDisplay.seat,
|
||||
* NULL);
|
||||
* _wl_locked_pointer_add_listener( locked_pointer,
|
||||
* &fghLockedListener,
|
||||
* NULL );
|
||||
*/
|
||||
wl_region_destroy( region );
|
||||
}
|
||||
|
||||
void fgPlatformLeaveGameMode( void )
|
||||
{
|
||||
/*
|
||||
* _wl_locked_pointer_destroy( locked_pointer );
|
||||
* _wl_relative_pointer_release( relative_pointer );
|
||||
*/
|
||||
}
|
||||
|
134
freeglut/freeglut/src/wayland/fg_init_wl.c
Normal file
134
freeglut/freeglut/src/wayland/fg_init_wl.c
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* fg_init_wl.c
|
||||
*
|
||||
* Various freeglut Wayland initialization functions.
|
||||
*
|
||||
* Copyright (c) 2015 Manuel Bachmann. All Rights Reserved.
|
||||
* Written by Manuel Bachmann, <tarnyko@tarnyko.net>
|
||||
* Creation date: Tue Mar 17, 2015
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* MANUEL BACHMANN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define FREEGLUT_BUILDING_LIB
|
||||
#include <string.h>
|
||||
#include <GL/freeglut.h>
|
||||
#include "fg_internal.h"
|
||||
#include "egl/fg_init_egl.h"
|
||||
|
||||
void fgPlatformInitialiseInputDevices( void );
|
||||
void fgPlatformCloseInputDevices( void );
|
||||
|
||||
|
||||
static void fghRegistryGlobal( void* data,
|
||||
struct wl_registry* registry,
|
||||
uint32_t id,
|
||||
const char* interface,
|
||||
uint32_t version )
|
||||
{
|
||||
SFG_PlatformDisplay* pDisplay = data;
|
||||
|
||||
if ( ! strcmp( interface, "wl_compositor" ) )
|
||||
pDisplay->compositor = wl_registry_bind ( registry, id,
|
||||
&wl_compositor_interface, 1 );
|
||||
else if ( ! strcmp( interface, "wl_shell" ) )
|
||||
pDisplay->shell = wl_registry_bind ( registry, id,
|
||||
&wl_shell_interface, 1 );
|
||||
else if ( ! strcmp( interface, "wl_seat" ) )
|
||||
pDisplay->seat = wl_registry_bind ( registry, id,
|
||||
&wl_seat_interface, 1 );
|
||||
else if ( ! strcmp( interface, "wl_shm" ) )
|
||||
pDisplay->shm = wl_registry_bind ( registry, id,
|
||||
&wl_shm_interface, 1 );
|
||||
}
|
||||
static void fghRegistryGlobalRemove( void* data,
|
||||
struct wl_registry* registry,
|
||||
uint32_t id )
|
||||
{
|
||||
}
|
||||
static const struct wl_registry_listener fghRegistryListener =
|
||||
{
|
||||
fghRegistryGlobal,
|
||||
fghRegistryGlobalRemove
|
||||
};
|
||||
|
||||
|
||||
static void fghInitialiseCursorTheme(void)
|
||||
{
|
||||
fgDisplay.pDisplay.cursor_theme = wl_cursor_theme_load (
|
||||
"default", 32,
|
||||
fgDisplay.pDisplay.shm );
|
||||
};
|
||||
|
||||
void fgPlatformInitialize( const char* displayName )
|
||||
{
|
||||
fgDisplay.pDisplay.display = wl_display_connect( NULL );
|
||||
|
||||
if( fgDisplay.pDisplay.display == NULL )
|
||||
fgError( "failed to connect to a Wayland compositor" );
|
||||
|
||||
fgDisplay.pDisplay.registry = wl_display_get_registry(
|
||||
fgDisplay.pDisplay.display );
|
||||
wl_registry_add_listener( fgDisplay.pDisplay.registry,
|
||||
&fghRegistryListener,
|
||||
&fgDisplay.pDisplay );
|
||||
wl_display_roundtrip( fgDisplay.pDisplay.display );
|
||||
|
||||
if( fgDisplay.pDisplay.compositor == NULL ||
|
||||
fgDisplay.pDisplay.shell == NULL ||
|
||||
fgDisplay.pDisplay.seat == NULL ||
|
||||
fgDisplay.pDisplay.shm == NULL )
|
||||
fgError( "failed to discover all needed compositor interfaces" );
|
||||
|
||||
fghInitialiseCursorTheme();
|
||||
|
||||
fghPlatformInitializeEGL();
|
||||
|
||||
/* Get start time */
|
||||
fgState.Time = fgSystemTime();
|
||||
|
||||
fgState.Initialised = GL_TRUE;
|
||||
|
||||
atexit(fgDeinitialize);
|
||||
|
||||
/* InputDevice uses GlutTimerFunc(), so fgState.Initialised must be TRUE */
|
||||
fgPlatformInitialiseInputDevices();
|
||||
}
|
||||
|
||||
|
||||
void fgPlatformDeinitialiseInputDevices ( void )
|
||||
{
|
||||
fgPlatformCloseInputDevices();
|
||||
|
||||
fgState.InputDevsInitialised = GL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
void fgPlatformCloseDisplay ( void )
|
||||
{
|
||||
wl_cursor_theme_destroy( fgDisplay.pDisplay.cursor_theme );
|
||||
|
||||
wl_shm_destroy( fgDisplay.pDisplay.shm );
|
||||
wl_seat_destroy( fgDisplay.pDisplay.seat );
|
||||
wl_shell_destroy( fgDisplay.pDisplay.shell );
|
||||
wl_compositor_destroy( fgDisplay.pDisplay.compositor );
|
||||
wl_registry_destroy( fgDisplay.pDisplay.registry );
|
||||
|
||||
wl_display_disconnect( fgDisplay.pDisplay.display );
|
||||
}
|
||||
|
433
freeglut/freeglut/src/wayland/fg_input_devices_wl.c
Normal file
433
freeglut/freeglut/src/wayland/fg_input_devices_wl.c
Normal file
@ -0,0 +1,433 @@
|
||||
/*
|
||||
* fg_input_devices_wl.c
|
||||
*
|
||||
* Handles Wayland input devices : keyboard, pointer, touchscreen.
|
||||
*
|
||||
* Written by Manuel Bachmann <tarnyko@tarnyko.net> 2015
|
||||
*
|
||||
* Copyright (c) 2015 Manuel Bachmann. All Rights Reserved.
|
||||
* Creation date: Thur Mar 19 2015
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* MANUEL BACHMANN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/input.h>
|
||||
#else
|
||||
#define BTN_LEFT 0x110
|
||||
#define BTN_RIGHT 0x111
|
||||
#define BTN_MIDDLE 0x112
|
||||
#endif
|
||||
#include <sys/mman.h>
|
||||
#include <GL/freeglut.h>
|
||||
#include "../fg_internal.h"
|
||||
|
||||
/*
|
||||
* This function will effectively set the pointer (mouse) cursor
|
||||
* depending on the GLUT_CURSOR_* choice.
|
||||
*/
|
||||
void fghPointerSetCursor( SFG_Window* window,
|
||||
struct wl_pointer* pointer,
|
||||
uint32_t serial )
|
||||
{
|
||||
struct wl_cursor_image* image;
|
||||
struct wl_buffer* buffer;
|
||||
|
||||
image = window->Window.pContext.cursor->images[0];
|
||||
buffer = wl_cursor_image_get_buffer( image );
|
||||
|
||||
wl_surface_attach( window->Window.pContext.cursor_surface, buffer,
|
||||
0, 0 );
|
||||
wl_surface_damage( window->Window.pContext.cursor_surface, 0, 0,
|
||||
image->width, image->height );
|
||||
wl_surface_commit( window->Window.pContext.cursor_surface );
|
||||
|
||||
wl_pointer_set_cursor( pointer, serial,
|
||||
window->Window.pContext.cursor_surface,
|
||||
image->hotspot_x, image->hotspot_y );
|
||||
}
|
||||
|
||||
/*
|
||||
* This function will interpret a keyboard keysym, and call the
|
||||
* possible callbacks accordingly.
|
||||
*/
|
||||
void fghKeyboardInterpretKeysym( SFG_Window* window,
|
||||
uint32_t key,
|
||||
xkb_keysym_t sym,
|
||||
uint32_t state )
|
||||
{
|
||||
FGCBKeyboard keyboard_cb;
|
||||
FGCBSpecial special_cb;
|
||||
char string[16];
|
||||
int special = -1;
|
||||
|
||||
/* GLUT API tells us to have two separate callbacks, one for
|
||||
* the ASCII translateable keypresses, and one for all the
|
||||
* others, which need to be translated to GLUT_KEY_Xs... */
|
||||
if( state )
|
||||
{
|
||||
keyboard_cb = (FGCBKeyboard)( FETCH_WCB( *window, Keyboard ));
|
||||
special_cb = (FGCBSpecial) ( FETCH_WCB( *window, Special ));
|
||||
}
|
||||
else
|
||||
{
|
||||
keyboard_cb = (FGCBKeyboard)( FETCH_WCB( *window, KeyboardUp ));
|
||||
special_cb = (FGCBSpecial) ( FETCH_WCB( *window, SpecialUp ));
|
||||
}
|
||||
|
||||
switch( sym )
|
||||
{
|
||||
case XKB_KEY_F1: special = GLUT_KEY_F1; break;
|
||||
case XKB_KEY_F2: special = GLUT_KEY_F2; break;
|
||||
case XKB_KEY_F3: special = GLUT_KEY_F3; break;
|
||||
case XKB_KEY_F4: special = GLUT_KEY_F4; break;
|
||||
case XKB_KEY_F5: special = GLUT_KEY_F5; break;
|
||||
case XKB_KEY_F6: special = GLUT_KEY_F6; break;
|
||||
case XKB_KEY_F7: special = GLUT_KEY_F7; break;
|
||||
case XKB_KEY_F8: special = GLUT_KEY_F8; break;
|
||||
case XKB_KEY_F9: special = GLUT_KEY_F9; break;
|
||||
case XKB_KEY_F10: special = GLUT_KEY_F10; break;
|
||||
case XKB_KEY_F11: special = GLUT_KEY_F11; break;
|
||||
case XKB_KEY_F12: special = GLUT_KEY_F12; break;
|
||||
case XKB_KEY_Left: special = GLUT_KEY_LEFT; break;
|
||||
case XKB_KEY_Right: special = GLUT_KEY_RIGHT; break;
|
||||
case XKB_KEY_Up: special = GLUT_KEY_UP; break;
|
||||
case XKB_KEY_Down: special = GLUT_KEY_DOWN; break;
|
||||
case XKB_KEY_Page_Up: special = GLUT_KEY_PAGE_UP; break;
|
||||
case XKB_KEY_Page_Down: special = GLUT_KEY_PAGE_DOWN; break;
|
||||
case XKB_KEY_Home: special = GLUT_KEY_HOME; break;
|
||||
case XKB_KEY_End: special = GLUT_KEY_END; break;
|
||||
case XKB_KEY_Insert: special = GLUT_KEY_INSERT; break;
|
||||
case XKB_KEY_Num_Lock: special = GLUT_KEY_NUM_LOCK; break;
|
||||
case XKB_KEY_Begin: special = GLUT_KEY_BEGIN; break;
|
||||
case XKB_KEY_Delete: special = GLUT_KEY_DELETE; break;
|
||||
case XKB_KEY_Shift_L: special = GLUT_KEY_SHIFT_L; break;
|
||||
case XKB_KEY_Shift_R: special = GLUT_KEY_SHIFT_R; break;
|
||||
case XKB_KEY_Control_L: special = GLUT_KEY_CTRL_L; break;
|
||||
case XKB_KEY_Control_R: special = GLUT_KEY_CTRL_R; break;
|
||||
case XKB_KEY_Alt_L: special = GLUT_KEY_ALT_L; break;
|
||||
case XKB_KEY_Alt_R: special = GLUT_KEY_ALT_R; break;
|
||||
}
|
||||
|
||||
if( special_cb && (special != -1) )
|
||||
{
|
||||
fgSetWindow( window );
|
||||
special_cb( special, window->State.MouseX, window->State.MouseY );
|
||||
}
|
||||
else if( keyboard_cb && (special == -1) )
|
||||
{
|
||||
fgSetWindow( window );
|
||||
xkb_keysym_to_utf8( sym, string, sizeof( string ) );
|
||||
keyboard_cb( string[0], window->State.MouseX, window->State.MouseY );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Touchscreen section
|
||||
* For now, let us pretend it is a mouse with only one button
|
||||
*/
|
||||
static void fghTouchDown( void* data, struct wl_touch* touch,
|
||||
uint32_t serial, uint32_t time,
|
||||
struct wl_surface* surface,
|
||||
int32_t id,
|
||||
wl_fixed_t x_w, wl_fixed_t y_w )
|
||||
{
|
||||
SFG_Window* win = fgStructure.CurrentWindow;
|
||||
win->State.MouseX = wl_fixed_to_int( x_w );
|
||||
win->State.MouseY = wl_fixed_to_int( y_w );
|
||||
INVOKE_WCB( *win, Mouse, ( GLUT_LEFT_BUTTON,
|
||||
GLUT_DOWN,
|
||||
win->State.MouseX,
|
||||
win->State.MouseY ) );
|
||||
}
|
||||
static void fghTouchUp( void* data, struct wl_touch* touch,
|
||||
uint32_t serial, uint32_t time,
|
||||
int32_t id )
|
||||
{
|
||||
SFG_Window* win = fgStructure.CurrentWindow;
|
||||
INVOKE_WCB( *win, Mouse, ( GLUT_LEFT_BUTTON,
|
||||
GLUT_UP,
|
||||
win->State.MouseX,
|
||||
win->State.MouseY ) );
|
||||
}
|
||||
static void fghTouchMotion( void* data, struct wl_touch* touch,
|
||||
uint32_t time, int32_t id,
|
||||
wl_fixed_t x_w, wl_fixed_t y_w )
|
||||
{
|
||||
SFG_Window* win = fgStructure.CurrentWindow;
|
||||
win->State.MouseX = wl_fixed_to_int( x_w );
|
||||
win->State.MouseY = wl_fixed_to_int( y_w );
|
||||
INVOKE_WCB( *win, Motion, ( win->State.MouseX,
|
||||
win->State.MouseY ) );
|
||||
}
|
||||
static void fghTouchFrame( void* data, struct wl_touch* touch )
|
||||
{
|
||||
}
|
||||
static void fghTouchCancel( void* data, struct wl_touch* touch )
|
||||
{
|
||||
}
|
||||
static const struct wl_touch_listener fghTouchListener =
|
||||
{
|
||||
fghTouchDown,
|
||||
fghTouchUp,
|
||||
fghTouchMotion,
|
||||
fghTouchFrame,
|
||||
fghTouchCancel
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Pointer (mouse) section
|
||||
*/
|
||||
static void fghPointerEnter( void* data, struct wl_pointer* pointer,
|
||||
uint32_t serial,
|
||||
struct wl_surface* surface,
|
||||
wl_fixed_t x_w, wl_fixed_t y_w )
|
||||
{
|
||||
SFG_Window* win = fgStructure.CurrentWindow;
|
||||
fghPointerSetCursor( win, pointer, serial );
|
||||
win->State.MouseX = wl_fixed_to_int( x_w );
|
||||
win->State.MouseY = wl_fixed_to_int( y_w );
|
||||
INVOKE_WCB( *win, Entry, ( GLUT_ENTERED ) );
|
||||
}
|
||||
static void fghPointerLeave( void* data, struct wl_pointer* pointer,
|
||||
uint32_t serial,
|
||||
struct wl_surface* surface )
|
||||
{
|
||||
SFG_Window* win = fgStructure.CurrentWindow;
|
||||
INVOKE_WCB( *win, Entry, ( GLUT_LEFT ) );
|
||||
}
|
||||
static void fghPointerMotion( void* data, struct wl_pointer* pointer,
|
||||
uint32_t time,
|
||||
wl_fixed_t x_w, wl_fixed_t y_w )
|
||||
{
|
||||
SFG_Window* win = fgStructure.CurrentWindow;
|
||||
win->State.MouseX = wl_fixed_to_int( x_w );
|
||||
win->State.MouseY = wl_fixed_to_int( y_w );
|
||||
|
||||
if ( win->Window.pContext.pointer_button_pressed )
|
||||
INVOKE_WCB( *win, Motion, ( win->State.MouseX,
|
||||
win->State.MouseY ) );
|
||||
else
|
||||
INVOKE_WCB( *win, Passive, ( win->State.MouseX,
|
||||
win->State.MouseY ) );
|
||||
}
|
||||
static void fghPointerButton( void* data, struct wl_pointer* pointer,
|
||||
uint32_t serial, uint32_t time,
|
||||
uint32_t button, uint32_t state )
|
||||
{
|
||||
SFG_Window* win = fgStructure.CurrentWindow;
|
||||
int button_f;
|
||||
|
||||
switch( button )
|
||||
{
|
||||
case BTN_LEFT:
|
||||
button_f = GLUT_LEFT_BUTTON;
|
||||
break;
|
||||
case BTN_RIGHT:
|
||||
button_f = GLUT_RIGHT_BUTTON;
|
||||
break;
|
||||
case BTN_MIDDLE:
|
||||
button_f = GLUT_MIDDLE_BUTTON;
|
||||
break;
|
||||
}
|
||||
|
||||
win->Window.pContext.pointer_button_pressed =
|
||||
state ? GL_TRUE : GL_FALSE;
|
||||
|
||||
INVOKE_WCB( *win, Mouse, ( button_f,
|
||||
state ? GLUT_DOWN : GLUT_UP ,
|
||||
win->State.MouseX,
|
||||
win->State.MouseY ) );
|
||||
}
|
||||
static void fghPointerAxis( void* data, struct wl_pointer* pointer,
|
||||
uint32_t time, uint32_t axis,
|
||||
wl_fixed_t value )
|
||||
{
|
||||
SFG_Window* win = fgStructure.CurrentWindow;
|
||||
int direction = wl_fixed_to_int( value );
|
||||
|
||||
INVOKE_WCB( *win, MouseWheel, ( 0,
|
||||
direction ,
|
||||
win->State.MouseX,
|
||||
win->State.MouseY ) );
|
||||
}
|
||||
static const struct wl_pointer_listener fghPointerListener =
|
||||
{
|
||||
fghPointerEnter,
|
||||
fghPointerLeave,
|
||||
fghPointerMotion,
|
||||
fghPointerButton,
|
||||
fghPointerAxis
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Keyboard section
|
||||
*/
|
||||
static void fghKeyboardKeymap( void* data, struct wl_keyboard* keyboard,
|
||||
uint32_t format, int fd, uint32_t size )
|
||||
{
|
||||
SFG_PlatformDisplay* pDisplay = data;
|
||||
char* keymap_str;
|
||||
struct xkb_keymap* keymap;
|
||||
|
||||
keymap_str = mmap( NULL, size, PROT_READ, MAP_SHARED, fd, 0 );
|
||||
keymap = xkb_keymap_new_from_string( pDisplay->xkb_context,
|
||||
keymap_str,
|
||||
XKB_KEYMAP_FORMAT_TEXT_V1,
|
||||
0 );
|
||||
munmap( keymap_str, size );
|
||||
|
||||
if( pDisplay->xkb_state )
|
||||
xkb_state_unref( pDisplay->xkb_state );
|
||||
pDisplay->xkb_state = xkb_state_new( keymap );
|
||||
}
|
||||
static void fghKeyboardEnter( void* data, struct wl_keyboard* keyboard,
|
||||
uint32_t serial, struct wl_surface* surface,
|
||||
struct wl_array* keys )
|
||||
{
|
||||
SFG_Window* win = fgStructure.CurrentWindow;
|
||||
INVOKE_WCB( *win, Entry, ( GLUT_ENTERED ) );
|
||||
}
|
||||
static void fghKeyboardLeave( void* data, struct wl_keyboard* keyboard,
|
||||
uint32_t serial, struct wl_surface* surface )
|
||||
{
|
||||
SFG_Window* win = fgStructure.CurrentWindow;
|
||||
INVOKE_WCB( *win, Entry, ( GLUT_LEFT ) );
|
||||
}
|
||||
static void fghKeyboardKey( void* data, struct wl_keyboard* keyboard,
|
||||
uint32_t serial, uint32_t time,
|
||||
uint32_t key, uint32_t state )
|
||||
{
|
||||
SFG_PlatformDisplay* pDisplay = data;
|
||||
SFG_Window* win = fgStructure.CurrentWindow;
|
||||
const xkb_keysym_t* syms;
|
||||
|
||||
xkb_state_key_get_syms( pDisplay->xkb_state,
|
||||
key + 8, &syms );
|
||||
fghKeyboardInterpretKeysym( win, key, syms[0], state );
|
||||
}
|
||||
static void fghKeyboardModifiers( void* data, struct wl_keyboard* keyboard,
|
||||
uint32_t serial, uint32_t mods_depr,
|
||||
uint32_t mods_latch, uint32_t mods_lock,
|
||||
uint32_t group )
|
||||
{
|
||||
}
|
||||
static const struct wl_keyboard_listener fghKeyboardListener =
|
||||
{
|
||||
fghKeyboardKeymap,
|
||||
fghKeyboardEnter,
|
||||
fghKeyboardLeave,
|
||||
fghKeyboardKey,
|
||||
fghKeyboardModifiers
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Discover potential input device(s) (keyboard, pointer, touch)
|
||||
*/
|
||||
static void fghSeatCapabilities( void* data,
|
||||
struct wl_seat* seat,
|
||||
enum wl_seat_capability capabilities )
|
||||
{
|
||||
SFG_PlatformDisplay* pDisplay = data;
|
||||
|
||||
if( capabilities & WL_SEAT_CAPABILITY_KEYBOARD )
|
||||
{
|
||||
pDisplay->xkb_context = xkb_context_new ( 0 );
|
||||
pDisplay->keyboard = wl_seat_get_keyboard( seat );
|
||||
wl_keyboard_add_listener( pDisplay->keyboard,
|
||||
&fghKeyboardListener,
|
||||
pDisplay );
|
||||
}
|
||||
|
||||
if( capabilities & WL_SEAT_CAPABILITY_POINTER )
|
||||
{
|
||||
pDisplay->pointer = wl_seat_get_pointer( seat );
|
||||
wl_pointer_add_listener( pDisplay->pointer,
|
||||
&fghPointerListener,
|
||||
pDisplay );
|
||||
}
|
||||
|
||||
if( capabilities & WL_SEAT_CAPABILITY_TOUCH )
|
||||
{
|
||||
pDisplay->touch = wl_seat_get_touch( seat );
|
||||
wl_touch_add_listener( pDisplay->touch,
|
||||
&fghTouchListener,
|
||||
pDisplay );
|
||||
}
|
||||
}
|
||||
static const struct wl_seat_listener fghSeatListener =
|
||||
{
|
||||
fghSeatCapabilities
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Try initializing the input device(s)
|
||||
*/
|
||||
void fgPlatformInitialiseInputDevices( void )
|
||||
{
|
||||
wl_seat_add_listener( fgDisplay.pDisplay.seat,
|
||||
&fghSeatListener,
|
||||
&fgDisplay.pDisplay );
|
||||
|
||||
wl_display_roundtrip( fgDisplay.pDisplay.display );
|
||||
}
|
||||
|
||||
/*
|
||||
* Try closing the input device(s)
|
||||
*/
|
||||
void fgPlatformCloseInputDevices( void )
|
||||
{
|
||||
if( fgDisplay.pDisplay.touch )
|
||||
wl_touch_destroy( fgDisplay.pDisplay.touch );
|
||||
if( fgDisplay.pDisplay.pointer )
|
||||
wl_pointer_destroy( fgDisplay.pDisplay.pointer );
|
||||
if( fgDisplay.pDisplay.keyboard )
|
||||
wl_keyboard_destroy( fgDisplay.pDisplay.keyboard );
|
||||
if( fgDisplay.pDisplay.xkb_state )
|
||||
xkb_state_unref( fgDisplay.pDisplay.xkb_state );
|
||||
if( fgDisplay.pDisplay.xkb_context )
|
||||
xkb_context_unref( fgDisplay.pDisplay.xkb_context );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Wayland backend will not be implementing spaceball at all
|
||||
*/
|
||||
void fgPlatformInitializeSpaceball( void )
|
||||
{
|
||||
}
|
||||
void fgPlatformSpaceballClose( void )
|
||||
{
|
||||
}
|
||||
void fgPlatformSpaceballSetWindow( SFG_Window *window )
|
||||
{
|
||||
}
|
||||
int fgPlatformHasSpaceball( void )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int fgPlatformSpaceballNumButtons( void )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
186
freeglut/freeglut/src/wayland/fg_internal_wl.h
Normal file
186
freeglut/freeglut/src/wayland/fg_internal_wl.h
Normal file
@ -0,0 +1,186 @@
|
||||
/*
|
||||
* fg_internal_wl.h
|
||||
*
|
||||
* The freeglut library private include file.
|
||||
*
|
||||
* Copyright (c) 2015 Manuel Bachmann. All Rights Reserved.
|
||||
* Written by Manuel Bachmann, <tarnyko@tarnyko.net>
|
||||
* Creation date: Tue Mar 17, 2015
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* MANUEL BACHMANN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef FREEGLUT_INTERNAL_WL_H
|
||||
#define FREEGLUT_INTERNAL_WL_H
|
||||
|
||||
|
||||
/* -- PLATFORM-SPECIFIC INCLUDES ------------------------------------------- */
|
||||
#include "egl/fg_internal_egl.h"
|
||||
#include <wayland-egl.h>
|
||||
#include <wayland-client.h>
|
||||
#include <wayland-cursor.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
|
||||
/* -- GLOBAL TYPE DEFINITIONS ---------------------------------------------- */
|
||||
/* The structure used by display initialization in fg_init.c */
|
||||
typedef struct tagSFG_PlatformDisplay SFG_PlatformDisplay;
|
||||
struct tagSFG_PlatformDisplay
|
||||
{
|
||||
struct tagSFG_PlatformDisplayEGL egl;
|
||||
|
||||
struct wl_display* display; /* The display we are being run in */
|
||||
struct wl_registry* registry; /* The global interface registry */
|
||||
struct wl_compositor* compositor; /* The compositor */
|
||||
struct wl_shell* shell; /* The shell, AKA window manager */
|
||||
struct wl_seat* seat; /* The seat, references input devices */
|
||||
|
||||
struct xkb_context* xkb_context; /* The global XKB keyboard context */
|
||||
struct xkb_state* xkb_state; /* The current XKB keyboard state */
|
||||
struct wl_keyboard* keyboard; /* The keyboard input device */
|
||||
struct wl_pointer* pointer; /* The pointer input device (mouse) */
|
||||
struct wl_touch* touch; /* The touchscreen input device */
|
||||
|
||||
struct wl_shm* shm; /* The software rendering engine */
|
||||
struct wl_cursor_theme* cursor_theme; /* The pointer cursor theme */
|
||||
};
|
||||
|
||||
|
||||
/* The structure used by window creation in fg_window.c */
|
||||
typedef struct tagSFG_PlatformContext SFG_PlatformContext;
|
||||
struct tagSFG_PlatformContext
|
||||
{
|
||||
struct tagSFG_PlatformContextEGL egl;
|
||||
GLboolean pointer_button_pressed;
|
||||
|
||||
struct wl_surface* surface; /* The drawing surface */
|
||||
struct wl_shell_surface* shsurface; /* The shell surface, has states */
|
||||
struct wl_egl_window* egl_window; /* Binding between WL/EGL surfaces */
|
||||
|
||||
struct wl_cursor* cursor; /* The active cursor */
|
||||
struct wl_surface* cursor_surface; /* The active cursor surface */
|
||||
};
|
||||
|
||||
|
||||
/* The window state description. This structure should be kept portable. */
|
||||
typedef struct tagSFG_PlatformWindowState SFG_PlatformWindowState;
|
||||
struct tagSFG_PlatformWindowState
|
||||
{
|
||||
int OldWidth; /* Window width from before a resize */
|
||||
int OldHeight; /* " height " " " " */
|
||||
};
|
||||
|
||||
|
||||
/* -- JOYSTICK-SPECIFIC STRUCTURES AND TYPES ------------------------------- */
|
||||
/*
|
||||
* Initial defines from "js.h" starting around line 33 with the existing "fg_joystick.c"
|
||||
* interspersed
|
||||
*/
|
||||
# ifdef HAVE_SYS_IOCTL_H
|
||||
# include <sys/ioctl.h>
|
||||
# endif
|
||||
# ifdef HAVE_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
# endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)
|
||||
/* XXX The below hack is done until freeglut's autoconf is updated. */
|
||||
# define HAVE_USB_JS 1
|
||||
|
||||
# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
# include <sys/joystick.h>
|
||||
# else
|
||||
/*
|
||||
* XXX NetBSD/amd64 systems may find that they have to steal the
|
||||
* XXX /usr/include/machine/joystick.h from a NetBSD/i386 system.
|
||||
* XXX I cannot comment whether that works for the interface, but
|
||||
* XXX it lets you compile...(^& I do not think that we can do away
|
||||
* XXX with this header.
|
||||
*/
|
||||
# include <machine/joystick.h> /* For analog joysticks */
|
||||
# endif
|
||||
# define JS_DATA_TYPE joystick
|
||||
# define JS_RETURN (sizeof(struct JS_DATA_TYPE))
|
||||
# endif
|
||||
|
||||
# if defined(__linux__)
|
||||
# include <linux/joystick.h>
|
||||
|
||||
/* check the joystick driver version */
|
||||
# if defined(JS_VERSION) && JS_VERSION >= 0x010000
|
||||
# define JS_NEW
|
||||
# endif
|
||||
# else /* Not BSD or Linux */
|
||||
# ifndef JS_RETURN
|
||||
|
||||
/*
|
||||
* We'll put these values in and that should
|
||||
* allow the code to at least compile when there is
|
||||
* no support. The JS open routine should error out
|
||||
* and shut off all the code downstream anyway and if
|
||||
* the application doesn't use a joystick we'll be fine.
|
||||
*/
|
||||
|
||||
struct JS_DATA_TYPE
|
||||
{
|
||||
int buttons;
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
# define JS_RETURN (sizeof(struct JS_DATA_TYPE))
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* XXX It might be better to poll the operating system for the numbers of buttons and
|
||||
* XXX axes and then dynamically allocate the arrays.
|
||||
*/
|
||||
# define _JS_MAX_AXES 16
|
||||
typedef struct tagSFG_PlatformJoystick SFG_PlatformJoystick;
|
||||
struct tagSFG_PlatformJoystick
|
||||
{
|
||||
# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)
|
||||
struct os_specific_s *os;
|
||||
# endif
|
||||
|
||||
# ifdef JS_NEW
|
||||
struct js_event js;
|
||||
int tmp_buttons;
|
||||
float tmp_axes [ _JS_MAX_AXES ];
|
||||
# else
|
||||
struct JS_DATA_TYPE js;
|
||||
# endif
|
||||
|
||||
char fname [ 128 ];
|
||||
int fd;
|
||||
};
|
||||
|
||||
|
||||
/* Menu font and color definitions */
|
||||
#define FREEGLUT_MENU_FONT GLUT_BITMAP_HELVETICA_18
|
||||
|
||||
#define FREEGLUT_MENU_PEN_FORE_COLORS {0.0f, 0.0f, 0.0f, 1.0f}
|
||||
#define FREEGLUT_MENU_PEN_BACK_COLORS {0.70f, 0.70f, 0.70f, 1.0f}
|
||||
#define FREEGLUT_MENU_PEN_HFORE_COLORS {0.0f, 0.0f, 0.0f, 1.0f}
|
||||
#define FREEGLUT_MENU_PEN_HBACK_COLORS {1.0f, 1.0f, 1.0f, 1.0f}
|
||||
|
||||
|
||||
#endif /* FREEGLUT_INTERNAL_WL_H */
|
134
freeglut/freeglut/src/wayland/fg_main_wl.c
Normal file
134
freeglut/freeglut/src/wayland/fg_main_wl.c
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* fg_main_wl.c
|
||||
*
|
||||
* The Wayland-specific windows message processing methods.
|
||||
*
|
||||
* Copyright (c) 2015 Manuel Bachmann. All Rights Reserved.
|
||||
* Written by Manuel Bachmann, <tarnyko@tarnyko.net>
|
||||
* Creation date: Sun Mar 22 2015
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* MANUEL BACHMANN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <GL/freeglut.h>
|
||||
#include "../fg_internal.h"
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
|
||||
void fgPlatformFullScreenToggle( SFG_Window *win );
|
||||
void fgPlatformPositionWindow( SFG_Window *window, int x, int y );
|
||||
void fgPlatformReshapeWindow( SFG_Window *window, int width, int height );
|
||||
void fgPlatformPushWindow( SFG_Window *window );
|
||||
void fgPlatformPopWindow( SFG_Window *window );
|
||||
void fgPlatformHideWindow( SFG_Window *window );
|
||||
void fgPlatformIconifyWindow( SFG_Window *window );
|
||||
void fgPlatformShowWindow( SFG_Window *window );
|
||||
|
||||
|
||||
fg_time_t fgPlatformSystemTime( void )
|
||||
{
|
||||
#ifdef CLOCK_MONOTONIC
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
return now.tv_nsec/1000000 + now.tv_sec*1000;
|
||||
#elif defined(HAVE_GETTIMEOFDAY)
|
||||
struct timeval now;
|
||||
gettimeofday( &now, NULL );
|
||||
return now.tv_usec/1000 + now.tv_sec*1000;
|
||||
#endif
|
||||
}
|
||||
|
||||
void fgPlatformSleepForEvents( fg_time_t msec )
|
||||
{
|
||||
struct pollfd pfd;
|
||||
int err;
|
||||
|
||||
pfd.fd = wl_display_get_fd( fgDisplay.pDisplay.display );
|
||||
pfd.events = POLLIN | POLLERR | POLLHUP;
|
||||
|
||||
wl_display_dispatch_pending( fgDisplay.pDisplay.display );
|
||||
if ( ! wl_display_flush( fgDisplay.pDisplay.display ) )
|
||||
{
|
||||
err = poll( &pfd, 1, msec );
|
||||
|
||||
if( ( -1 == err ) && ( errno != EINTR ) )
|
||||
fgWarning ( "freeglut poll() error: %d", errno );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void fgPlatformProcessSingleEvent( void )
|
||||
{
|
||||
SFG_Window *win = fgStructure.CurrentWindow;
|
||||
|
||||
wl_display_dispatch_pending( fgDisplay.pDisplay.display );
|
||||
INVOKE_WCB( *win, Display, ( ) );
|
||||
}
|
||||
|
||||
void fgPlatformMainLoopPreliminaryWork( void )
|
||||
{
|
||||
/* Under Wayland, this is a no-op */
|
||||
}
|
||||
|
||||
void fgPlatformInitWork( SFG_Window* window )
|
||||
{
|
||||
/* Under Wayland, all events happen relative to input handlers
|
||||
* -> this is a no-op
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
void fgPlatformPosResZordWork( SFG_Window* window, unsigned int workMask )
|
||||
{
|
||||
if( workMask & GLUT_FULL_SCREEN_WORK )
|
||||
fgPlatformFullScreenToggle( window );
|
||||
if( workMask & GLUT_POSITION_WORK )
|
||||
fgPlatformPositionWindow( window, window->State.DesiredXpos, window->State.DesiredYpos );
|
||||
if( workMask & GLUT_SIZE_WORK )
|
||||
fgPlatformReshapeWindow ( window, window->State.DesiredWidth, window->State.DesiredHeight );
|
||||
if( workMask & GLUT_ZORDER_WORK )
|
||||
{
|
||||
if( window->State.DesiredZOrder < 0 )
|
||||
fgPlatformPushWindow( window );
|
||||
else
|
||||
fgPlatformPopWindow( window );
|
||||
}
|
||||
}
|
||||
|
||||
void fgPlatformVisibilityWork( SFG_Window* window )
|
||||
{
|
||||
/* Visibility status of window gets updated in the window message handlers above
|
||||
*/
|
||||
SFG_Window *win = window;
|
||||
switch (window->State.DesiredVisibility)
|
||||
{
|
||||
case DesireHiddenState:
|
||||
fgPlatformHideWindow( window );
|
||||
break;
|
||||
case DesireIconicState:
|
||||
/* Call on top-level window */
|
||||
while (win->Parent)
|
||||
win = win->Parent;
|
||||
fgPlatformIconifyWindow( win );
|
||||
break;
|
||||
case DesireNormalState:
|
||||
fgPlatformShowWindow( window );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
150
freeglut/freeglut/src/wayland/fg_state_wl.c
Normal file
150
freeglut/freeglut/src/wayland/fg_state_wl.c
Normal file
@ -0,0 +1,150 @@
|
||||
/*
|
||||
* fg_state_wl.c
|
||||
*
|
||||
* Wayland-specific freeglut state query methods.
|
||||
*
|
||||
* Copyright (c) 2015 Manuel Bachmann. All Rights Reserved.
|
||||
* Written by Manuel Bachmann, <tarnyko@tarnyko.net>
|
||||
* Creation date: Sun Mar 23 2015
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* MANUEL BACHMANN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <GL/freeglut.h>
|
||||
#include "fg_internal.h"
|
||||
#include "egl/fg_state_egl.h"
|
||||
|
||||
int fgPlatformGlutDeviceGet ( GLenum eWhat )
|
||||
{
|
||||
switch( eWhat )
|
||||
{
|
||||
case GLUT_HAS_KEYBOARD:
|
||||
if( fgDisplay.pDisplay.keyboard )
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
|
||||
case GLUT_HAS_MOUSE:
|
||||
/* we want the touchscreen to behave like a mouse,
|
||||
* so let us pretend it is one.
|
||||
*/
|
||||
if( fgDisplay.pDisplay.pointer ||
|
||||
fgDisplay.pDisplay.touch )
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
|
||||
case GLUT_NUM_MOUSE_BUTTONS:
|
||||
/* Wayland has no way of telling us how much buttons
|
||||
* a mouse has, unless the actual event gets sent to
|
||||
* the client. As we are only handling 3 buttons
|
||||
* currently, return this fixed number for now.
|
||||
*/
|
||||
if( fgDisplay.pDisplay.pointer )
|
||||
return 3;
|
||||
/* touchscreen is considered as having one button */
|
||||
else if( fgDisplay.pDisplay.touch )
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
|
||||
default:
|
||||
fgWarning( "glutDeviceGet(): missing enum handle %d", eWhat );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int fgPlatformGlutGet ( GLenum eWhat )
|
||||
{
|
||||
switch( eWhat )
|
||||
{
|
||||
|
||||
/*
|
||||
* Those calls are pointless under Wayland, so inform the user
|
||||
*/
|
||||
case GLUT_WINDOW_X:
|
||||
case GLUT_WINDOW_Y:
|
||||
{
|
||||
if( fgStructure.CurrentWindow == NULL )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
fgWarning( "glutGet(): GLUT_WINDOW_X/Y properties "
|
||||
"unsupported under Wayland" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO : support this correctly once we will start drawing
|
||||
* client-side decorations
|
||||
*/
|
||||
case GLUT_WINDOW_BORDER_WIDTH:
|
||||
case GLUT_WINDOW_HEADER_HEIGHT:
|
||||
{
|
||||
if( fgStructure.CurrentWindow == NULL ||
|
||||
fgStructure.CurrentWindow->Parent )
|
||||
/* can't get widths/heights if no current window
|
||||
* and child windows don't have borders */
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
case GLUT_WINDOW_WIDTH:
|
||||
case GLUT_WINDOW_HEIGHT:
|
||||
{
|
||||
if( fgStructure.CurrentWindow == NULL )
|
||||
return 0;
|
||||
|
||||
switch ( eWhat )
|
||||
{
|
||||
case GLUT_WINDOW_WIDTH:
|
||||
return fgStructure.CurrentWindow->State.Width;
|
||||
case GLUT_WINDOW_HEIGHT:
|
||||
return fgStructure.CurrentWindow->State.Height;
|
||||
}
|
||||
}
|
||||
|
||||
/* Colormap size is handled in a bit different way than all the rest */
|
||||
case GLUT_WINDOW_COLORMAP_SIZE:
|
||||
{
|
||||
if( fgStructure.CurrentWindow == NULL )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int result = 0;
|
||||
if ( ! eglGetConfigAttrib( fgDisplay.pDisplay.egl.Display,
|
||||
fgStructure.CurrentWindow->Window.pContext.egl.Config,
|
||||
EGL_BUFFER_SIZE, &result ) )
|
||||
fgError( "eglGetConfigAttrib(EGL_BUFFER_SIZE) failed" );
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
return fghPlatformGlutGetEGL( eWhat );
|
||||
}
|
||||
}
|
||||
|
40
freeglut/freeglut/src/wayland/fg_structure_wl.c
Normal file
40
freeglut/freeglut/src/wayland/fg_structure_wl.c
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* fg_structure_wl.c
|
||||
*
|
||||
* Windows and menus need tree structure for Wayland
|
||||
*
|
||||
* Copyright (c) 2015 Manuel Bachmann. All Rights Reserved.
|
||||
* Written by Manuel Bachmann, <tarnyko@tarnyko.net>
|
||||
* Creation date: Tue Mar 17, 2015
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* MANUEL BACHMANN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <GL/freeglut.h>
|
||||
#include "fg_internal.h"
|
||||
#include "egl/fg_structure_egl.h"
|
||||
|
||||
extern SFG_Structure fgStructure;
|
||||
|
||||
void fgPlatformCreateWindow( SFG_Window *window )
|
||||
{
|
||||
fghPlatformCreateWindowEGL( window );
|
||||
|
||||
window->State.pWState.OldHeight = window->State.pWState.OldWidth = -1;
|
||||
}
|
||||
|
310
freeglut/freeglut/src/wayland/fg_window_wl.c
Normal file
310
freeglut/freeglut/src/wayland/fg_window_wl.c
Normal file
@ -0,0 +1,310 @@
|
||||
/*
|
||||
* fg_window_wl.c
|
||||
*
|
||||
* Window management methods for Wayland
|
||||
*
|
||||
* Copyright (c) 2015 Manuel Bachmann. All Rights Reserved.
|
||||
* Written by Manuel Bachmann, <tarnyko@tarnyko.net>
|
||||
* Creation date: Tue Mar 17, 2015
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* MANUEL BACHMANN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define FREEGLUT_BUILDING_LIB
|
||||
#include <GL/freeglut.h>
|
||||
#include "../fg_internal.h"
|
||||
#include "egl/fg_window_egl.h"
|
||||
#define fghCreateNewContext fghCreateNewContextEGL
|
||||
|
||||
extern void fghOnReshapeNotify( SFG_Window *window, int width, int height, GLboolean forceNotify );
|
||||
void fgPlatformReshapeWindow( SFG_Window *window, int width, int height );
|
||||
void fgPlatformIconifyWindow( SFG_Window *window );
|
||||
|
||||
|
||||
static void fghShSurfacePing( void* data,
|
||||
struct wl_shell_surface* shsurface,
|
||||
uint32_t serial )
|
||||
{
|
||||
wl_shell_surface_pong( shsurface, serial );
|
||||
}
|
||||
static void fghShSurfaceConfigure( void* data,
|
||||
struct wl_shell_surface* shsurface,
|
||||
uint32_t edges,
|
||||
int32_t width, int32_t height )
|
||||
{
|
||||
SFG_Window* window = data;
|
||||
fgPlatformReshapeWindow( window, width, height );
|
||||
}
|
||||
static const struct wl_shell_surface_listener fghShSurfaceListener =
|
||||
{
|
||||
fghShSurfacePing,
|
||||
fghShSurfaceConfigure,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
static int fghToggleFullscreen(void)
|
||||
{
|
||||
SFG_Window* win = fgStructure.CurrentWindow;
|
||||
|
||||
if ( ! win->State.IsFullscreen )
|
||||
{
|
||||
win->State.pWState.OldWidth = win->State.Width;
|
||||
win->State.pWState.OldHeight = win->State.Height;
|
||||
wl_shell_surface_set_fullscreen( win->Window.pContext.shsurface,
|
||||
WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
|
||||
0, NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
fgPlatformReshapeWindow( win, win->State.pWState.OldWidth,
|
||||
win->State.pWState.OldHeight );
|
||||
wl_shell_surface_set_toplevel( win->Window.pContext.shsurface );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fgPlatformOpenWindow( SFG_Window* window, const char* title,
|
||||
GLboolean positionUse, int x, int y,
|
||||
GLboolean sizeUse, int w, int h,
|
||||
GLboolean gameMode, GLboolean isSubWindow )
|
||||
{
|
||||
/* Save the display mode if we are creating a menu window */
|
||||
if( window->IsMenu && ( ! fgStructure.MenuContext ) )
|
||||
fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB ;
|
||||
|
||||
fghChooseConfig( &window->Window.pContext.egl.Config );
|
||||
|
||||
if( ! window->Window.pContext.egl.Config )
|
||||
{
|
||||
/*
|
||||
* The "fghChooseConfig" returned a null meaning that the visual
|
||||
* context is not available.
|
||||
* Try a couple of variations to see if they will work.
|
||||
*/
|
||||
if( fgState.DisplayMode & GLUT_MULTISAMPLE )
|
||||
{
|
||||
fgState.DisplayMode &= ~GLUT_MULTISAMPLE ;
|
||||
fghChooseConfig( &window->Window.pContext.egl.Config );
|
||||
fgState.DisplayMode |= GLUT_MULTISAMPLE;
|
||||
}
|
||||
}
|
||||
|
||||
FREEGLUT_INTERNAL_ERROR_EXIT( window->Window.pContext.egl.Config != NULL,
|
||||
"EGL configuration with necessary capabilities "
|
||||
"not found", "fgOpenWindow" );
|
||||
|
||||
if( ! positionUse )
|
||||
x = y = -1; /* default window position */
|
||||
if( ! sizeUse )
|
||||
w = h = 300; /* default window size */
|
||||
|
||||
/* Create the cursor */
|
||||
window->Window.pContext.cursor = wl_cursor_theme_get_cursor(
|
||||
fgDisplay.pDisplay.cursor_theme,
|
||||
"left_ptr" );
|
||||
window->Window.pContext.cursor_surface = wl_compositor_create_surface(
|
||||
fgDisplay.pDisplay.compositor );
|
||||
|
||||
/* Create the main surface */
|
||||
window->Window.pContext.surface = wl_compositor_create_surface(
|
||||
fgDisplay.pDisplay.compositor );
|
||||
|
||||
/* Create the shell surface with respects to the parent/child tree */
|
||||
window->Window.pContext.shsurface = wl_shell_get_shell_surface(
|
||||
fgDisplay.pDisplay.shell,
|
||||
window->Window.pContext.surface );
|
||||
wl_shell_surface_add_listener( window->Window.pContext.shsurface,
|
||||
&fghShSurfaceListener, window );
|
||||
|
||||
if( title)
|
||||
wl_shell_surface_set_title( window->Window.pContext.shsurface, title );
|
||||
|
||||
if( gameMode )
|
||||
{
|
||||
window->State.IsFullscreen = GL_TRUE;
|
||||
wl_shell_surface_set_fullscreen( window->Window.pContext.shsurface,
|
||||
WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
|
||||
0, NULL );
|
||||
}
|
||||
else if( !isSubWindow && !window->IsMenu )
|
||||
{
|
||||
wl_shell_surface_set_toplevel( window->Window.pContext.shsurface );
|
||||
}
|
||||
else
|
||||
{
|
||||
wl_shell_surface_set_transient( window->Window.pContext.shsurface,
|
||||
window->Parent->Window.pContext.surface,
|
||||
x, y, 0 );
|
||||
}
|
||||
|
||||
/* Create the Wl_EGL_Window */
|
||||
window->Window.Context = fghCreateNewContext( window );
|
||||
window->Window.pContext.egl_window = wl_egl_window_create(
|
||||
window->Window.pContext.surface,
|
||||
w, h);
|
||||
window->Window.pContext.egl.Surface = eglCreateWindowSurface(
|
||||
fgDisplay.pDisplay.egl.Display,
|
||||
window->Window.pContext.egl.Config,
|
||||
(EGLNativeWindowType)window->Window.pContext.egl_window,
|
||||
NULL );
|
||||
eglMakeCurrent( fgDisplay.pDisplay.egl.Display, window->Window.pContext.egl.Surface,
|
||||
window->Window.pContext.egl.Surface, window->Window.Context );
|
||||
|
||||
window->Window.pContext.pointer_button_pressed = GL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Request a window resize
|
||||
*/
|
||||
void fgPlatformReshapeWindow( SFG_Window *window, int width, int height )
|
||||
{
|
||||
fghOnReshapeNotify(window, width, height, GL_FALSE);
|
||||
|
||||
if( window->Window.pContext.egl_window )
|
||||
wl_egl_window_resize( window->Window.pContext.egl_window,
|
||||
width, height, 0, 0 );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Closes a window, destroying the frame and OpenGL context
|
||||
*/
|
||||
void fgPlatformCloseWindow( SFG_Window* window )
|
||||
{
|
||||
fghPlatformCloseWindowEGL(window);
|
||||
|
||||
if ( window->Window.pContext.egl_window )
|
||||
wl_egl_window_destroy( window->Window.pContext.egl_window );
|
||||
if ( window->Window.pContext.shsurface )
|
||||
wl_shell_surface_destroy( window->Window.pContext.shsurface );
|
||||
if ( window->Window.pContext.surface )
|
||||
wl_surface_destroy( window->Window.pContext.surface );
|
||||
if ( window->Window.pContext.cursor_surface )
|
||||
wl_surface_destroy( window->Window.pContext.cursor_surface );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function re-creates the window assets if they
|
||||
* have been destroyed
|
||||
*/
|
||||
void fgPlatformShowWindow( SFG_Window *window )
|
||||
{
|
||||
if ( ! window->Window.pContext.egl_window ||
|
||||
! window->Window.pContext.shsurface ||
|
||||
! window->Window.pContext.surface)
|
||||
{
|
||||
fgPlatformCloseWindow( window );
|
||||
fgPlatformOpenWindow( window, "", /* TODO : save the title for further use */
|
||||
GL_TRUE, window->State.Xpos, window->State.Ypos,
|
||||
GL_TRUE, window->State.Width, window->State.Height,
|
||||
(GLboolean)(window->State.IsFullscreen ? GL_TRUE : GL_FALSE),
|
||||
(GLboolean)(window->Parent ? GL_TRUE : GL_FALSE) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* TODO : support this once we start using xdg-shell
|
||||
*
|
||||
* xdg_surface_present( window->Window.pContext.shsurface, 0 );
|
||||
* INVOKE_WCB( *window, WindowStatus, ( GLUT_FULLY_RETAINED ) );
|
||||
* window->State.Visible = GL_TRUE;
|
||||
*/
|
||||
fgWarning( "glutShownWindow(): function unsupported for an already existing"
|
||||
" window under Wayland" );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function hides the specified window
|
||||
*/
|
||||
void fgPlatformHideWindow( SFG_Window *window )
|
||||
{
|
||||
fgPlatformIconifyWindow( window );
|
||||
}
|
||||
|
||||
/*
|
||||
* Iconify the specified window (top-level windows only)
|
||||
*/
|
||||
void fgPlatformIconifyWindow( SFG_Window *window )
|
||||
{
|
||||
/* TODO : support this once we start using xdg-shell
|
||||
*
|
||||
* xdg_surface_set_minimized( window->Window.pContext.shsurface );
|
||||
* INVOKE_WCB( *window, WindowStatus, ( GLUT_HIDDEN ) );
|
||||
* window->State.Visible = GL_FALSE;
|
||||
*/
|
||||
fgWarning( "glutIconifyWindow(): function unsupported under Wayland" );
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the current window's title
|
||||
*/
|
||||
void fgPlatformGlutSetWindowTitle( const char* title )
|
||||
{
|
||||
SFG_Window* win = fgStructure.CurrentWindow;
|
||||
wl_shell_surface_set_title( win->Window.pContext.shsurface, title );
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the current window's iconified title
|
||||
*/
|
||||
void fgPlatformGlutSetIconTitle( const char* title )
|
||||
{
|
||||
fgPlatformGlutSetWindowTitle( title );
|
||||
}
|
||||
|
||||
/*
|
||||
* Change the specified window's position
|
||||
*/
|
||||
void fgPlatformPositionWindow( SFG_Window *window, int x, int y )
|
||||
{
|
||||
/* pointless under Wayland */
|
||||
fgWarning( "glutPositionWindow(): function unsupported under Wayland" );
|
||||
}
|
||||
|
||||
/*
|
||||
* Lowers the specified window (by Z order change)
|
||||
*/
|
||||
void fgPlatformPushWindow( SFG_Window *window )
|
||||
{
|
||||
/* pointless under Wayland */
|
||||
fgWarning( "glutPushWindow(): function unsupported under Wayland" );
|
||||
}
|
||||
|
||||
/*
|
||||
* Raises the specified window (by Z order change)
|
||||
*/
|
||||
void fgPlatformPopWindow( SFG_Window *window )
|
||||
{
|
||||
/* pointless under Wayland */
|
||||
fgWarning( "glutPopWindow(): function unsupported under Wayland" );
|
||||
}
|
||||
|
||||
/*
|
||||
* Toggle the window's full screen state.
|
||||
*/
|
||||
void fgPlatformFullScreenToggle( SFG_Window *win )
|
||||
{
|
||||
if(fghToggleFullscreen() != -1) {
|
||||
win->State.IsFullscreen = !win->State.IsFullscreen;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user