mirror of https://github.com/encounter/SDL.git
Wayland support
Based on the original port to Wayland by: Joel Teichroeb, Benjamin Franzke, Scott Moreau, et al. Additional changes in this commit, done by me: * Wayland uses the common EGL framework * EGL can now create a desktop OpenGL context * testgl2 loads GL functions dynamically, no need to link to libGL anymore * Assorted fixes to the Wayland backend Tested on the Weston Compositor (v1.0.5) that ships with Ubuntu 13.10, running Weston under X. Tests ran: testrendercopyex (all backends), testgl2, testgles2,testintersections
This commit is contained in:
parent
4a8c296712
commit
ec1cb49eab
|
@ -218,6 +218,7 @@ set_option(RPATH "Use an rpath when linking SDL" ${UNIX_SYS})
|
|||
set_option(CLOCK_GETTIME "Use clock_gettime() instead of gettimeofday()" OFF)
|
||||
set_option(INPUT_TSLIB "Use the Touchscreen library for input" ${UNIX_SYS})
|
||||
set_option(VIDEO_X11 "Use X11 video driver" ${UNIX_SYS})
|
||||
set_option(VIDEO_WAYLAND "Use Wayland video driver" ${UNIX_SYS})
|
||||
dep_option(X11_SHARED "Dynamically load X11 support" ON "VIDEO_X11" OFF)
|
||||
set(SDL_X11_OPTIONS Xcursor Xinerama XInput Xrandr Xscrnsaver XShape Xvm)
|
||||
foreach(_SUB ${SDL_X11_OPTIONS})
|
||||
|
@ -641,6 +642,7 @@ if(UNIX AND NOT APPLE)
|
|||
CheckDirectFB()
|
||||
CheckOpenGLX11()
|
||||
CheckOpenGLESX11()
|
||||
CheckWayland()
|
||||
endif(SDL_VIDEO)
|
||||
|
||||
if(LINUX)
|
||||
|
|
|
@ -7,6 +7,9 @@ This is a list of major changes in SDL's version history.
|
|||
General:
|
||||
* Added an API to load a database of Game Controller mappings from a file:
|
||||
SDL_GameControllerAddMappingsFromFile
|
||||
* EGL can now create/manage OpenGL and OpenGL ES 1.x/2.x contexts, and share
|
||||
them using SDL_GL_SHARE_WITH_CURRENT_CONTEXT
|
||||
* Added testgles2. testgl2 does not need to link with libGL anymore.
|
||||
|
||||
Windows:
|
||||
* Support for OpenGL ES 2.x contexts using either WGL or EGL (natively via
|
||||
|
@ -20,7 +23,7 @@ Android:
|
|||
|
||||
Linux:
|
||||
* Fixed fullscreen and focused behavior when receiving NotifyGrab events
|
||||
|
||||
* Wayland support
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
2.0.1:
|
||||
|
|
|
@ -505,6 +505,29 @@ macro(CheckX11)
|
|||
endif(VIDEO_X11)
|
||||
endmacro(CheckX11)
|
||||
|
||||
# Requires:
|
||||
# - EGL
|
||||
macro(CheckWayland)
|
||||
if(VIDEO_WAYLAND)
|
||||
pkg_check_modules(WAYLAND wayland-client wayland-cursor wayland-egl egl xkbcommon)
|
||||
if(WAYLAND_FOUND)
|
||||
link_directories(
|
||||
${WAYLAND_LIBRARY_DIRS}
|
||||
)
|
||||
include_directories(
|
||||
${WAYLAND_INCLUDE_DIRS}
|
||||
)
|
||||
set(EXTRA_LIBS ${WAYLAND_LIBRARIES} ${EXTRA_LIBS})
|
||||
set(HAVE_VIDEO_WAYLAND TRUE)
|
||||
set(HAVE_SDL_VIDEO TRUE)
|
||||
|
||||
file(GLOB WAYLAND_SOURCES ${SDL2_SOURCE_DIR}/src/video/wayland/*.c)
|
||||
set(SOURCE_FILES ${SOURCE_FILES} ${WAYLAND_SOURCES})
|
||||
set(SDL_VIDEO_DRIVER_WAYLAND 1)
|
||||
endif(WAYLAND_FOUND)
|
||||
endif(VIDEO_WAYLAND)
|
||||
endmacro(CheckWayland)
|
||||
|
||||
# Requires:
|
||||
# - n/a
|
||||
#
|
||||
|
|
|
@ -817,6 +817,7 @@ enable_sndio
|
|||
enable_sndio_shared
|
||||
enable_diskaudio
|
||||
enable_dummyaudio
|
||||
enable_video_wayland
|
||||
enable_video_x11
|
||||
with_x
|
||||
enable_x11_shared
|
||||
|
@ -1532,6 +1533,7 @@ Optional Features:
|
|||
--enable-sndio-shared dynamically load sndio audio support [[default=yes]]
|
||||
--enable-diskaudio support the disk writer audio driver [[default=yes]]
|
||||
--enable-dummyaudio support the dummy audio driver [[default=yes]]
|
||||
--enable-video-wayland use Wayland video driver [[default=yes]]
|
||||
--enable-video-x11 use X11 video driver [[default=yes]]
|
||||
--enable-x11-shared dynamically load X11 support [[default=maybe]]
|
||||
--enable-video-x11-xcursor
|
||||
|
@ -18633,6 +18635,82 @@ $as_echo "$need_gcc_Wno_multichar" >&6; }
|
|||
fi
|
||||
}
|
||||
|
||||
CheckWayland()
|
||||
{
|
||||
# Check whether --enable-video-wayland was given.
|
||||
if test "${enable_video_wayland+set}" = set; then :
|
||||
enableval=$enable_video_wayland;
|
||||
else
|
||||
enable_video_wayland=yes
|
||||
fi
|
||||
|
||||
|
||||
if test x$enable_video = xyes -a x$enable_video_wayland = xyes; then
|
||||
# Extract the first word of "pkg-config", so it can be a program name with args.
|
||||
set dummy pkg-config; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_path_PKG_CONFIG+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
case $PKG_CONFIG in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
PKG_CONFIG=$ac_cv_path_PKG_CONFIG
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
|
||||
$as_echo "$PKG_CONFIG" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Wayland support" >&5
|
||||
$as_echo_n "checking for Wayland support... " >&6; }
|
||||
video_wayland=no
|
||||
if test x$PKG_CONFIG != xno; then
|
||||
if $PKG_CONFIG --exists wayland-client wayland-egl wayland-cursor egl xkbcommon ; then
|
||||
WAYLAND_CFLAGS=`$PKG_CONFIG --cflags wayland-client wayland-egl wayland-cursor egl xkbcommon`
|
||||
WAYLAND_LIBS=`$PKG_CONFIG --libs wayland-client wayland-egl wayland-cursor egl xkbcommon`
|
||||
video_wayland=yes
|
||||
fi
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $video_wayland" >&5
|
||||
$as_echo "$video_wayland" >&6; }
|
||||
|
||||
if test x$video_wayland = xyes; then
|
||||
|
||||
$as_echo "#define SDL_VIDEO_DRIVER_WAYLAND 1" >>confdefs.h
|
||||
|
||||
SOURCES="$SOURCES $srcdir/src/video/wayland/*.c"
|
||||
EXTRA_CFLAGS="$EXTRA_CFLAGS $WAYLAND_CFLAGS"
|
||||
EXTRA_LDFLAGS="$EXTRA_LDFLAGS $WAYLAND_LIBS"
|
||||
have_video=yes
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
CheckX11()
|
||||
{
|
||||
|
@ -22220,6 +22298,7 @@ case "$host" in
|
|||
CheckNAS
|
||||
CheckSNDIO
|
||||
CheckX11
|
||||
CheckWayland
|
||||
CheckDirectFB
|
||||
CheckFusionSound
|
||||
CheckOpenGLX11
|
||||
|
|
31
configure.in
31
configure.in
|
@ -1115,6 +1115,36 @@ CheckWarnAll()
|
|||
fi
|
||||
}
|
||||
|
||||
dnl Check for Wayland
|
||||
CheckWayland()
|
||||
{
|
||||
AC_ARG_ENABLE(video-wayland,
|
||||
AC_HELP_STRING([--enable-video-wayland], [use Wayland video driver [[default=yes]]]),
|
||||
,enable_video_wayland=yes)
|
||||
|
||||
if test x$enable_video = xyes -a x$enable_video_wayland = xyes; then
|
||||
AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
|
||||
AC_MSG_CHECKING(for Wayland support)
|
||||
video_wayland=no
|
||||
if test x$PKG_CONFIG != xno; then
|
||||
if $PKG_CONFIG --exists wayland-client wayland-egl wayland-cursor egl xkbcommon ; then
|
||||
WAYLAND_CFLAGS=`$PKG_CONFIG --cflags wayland-client wayland-egl wayland-cursor egl xkbcommon`
|
||||
WAYLAND_LIBS=`$PKG_CONFIG --libs wayland-client wayland-egl wayland-cursor egl xkbcommon`
|
||||
video_wayland=yes
|
||||
fi
|
||||
fi
|
||||
AC_MSG_RESULT($video_wayland)
|
||||
|
||||
if test x$video_wayland = xyes; then
|
||||
AC_DEFINE(SDL_VIDEO_DRIVER_WAYLAND, 1, [ ])
|
||||
SOURCES="$SOURCES $srcdir/src/video/wayland/*.c"
|
||||
EXTRA_CFLAGS="$EXTRA_CFLAGS $WAYLAND_CFLAGS"
|
||||
dnl FIXME do dynamic loading code here.
|
||||
EXTRA_LDFLAGS="$EXTRA_LDFLAGS $WAYLAND_LIBS"
|
||||
have_video=yes
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
dnl Find the X11 include and library directories
|
||||
CheckX11()
|
||||
|
@ -2449,6 +2479,7 @@ case "$host" in
|
|||
CheckNAS
|
||||
CheckSNDIO
|
||||
CheckX11
|
||||
CheckWayland
|
||||
CheckDirectFB
|
||||
CheckFusionSound
|
||||
CheckOpenGLX11
|
||||
|
|
|
@ -259,6 +259,7 @@
|
|||
#cmakedefine SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC @SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC@
|
||||
#cmakedefine SDL_VIDEO_DRIVER_DUMMY @SDL_VIDEO_DRIVER_DUMMY@
|
||||
#cmakedefine SDL_VIDEO_DRIVER_WINDOWS @SDL_VIDEO_DRIVER_WINDOWS@
|
||||
#cmakedefine SDL_VIDEO_DRIVER_WAYLAND @SDL_VIDEO_DRIVER_WAYLAND@
|
||||
#cmakedefine SDL_VIDEO_DRIVER_X11 @SDL_VIDEO_DRIVER_X11@
|
||||
#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC @SDL_VIDEO_DRIVER_X11_DYNAMIC@
|
||||
#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT @SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT@
|
||||
|
|
|
@ -260,6 +260,7 @@
|
|||
#undef SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC
|
||||
#undef SDL_VIDEO_DRIVER_DUMMY
|
||||
#undef SDL_VIDEO_DRIVER_WINDOWS
|
||||
#undef SDL_VIDEO_DRIVER_WAYLAND
|
||||
#undef SDL_VIDEO_DRIVER_X11
|
||||
#undef SDL_VIDEO_DRIVER_RPI
|
||||
#undef SDL_VIDEO_DRIVER_X11_DYNAMIC
|
||||
|
|
|
@ -101,6 +101,7 @@ typedef enum
|
|||
SDL_SYSWM_UNKNOWN,
|
||||
SDL_SYSWM_WINDOWS,
|
||||
SDL_SYSWM_X11,
|
||||
SDL_SYSWM_WAYLAND,
|
||||
SDL_SYSWM_DIRECTFB,
|
||||
SDL_SYSWM_COCOA,
|
||||
SDL_SYSWM_UIKIT,
|
||||
|
@ -175,6 +176,14 @@ struct SDL_SysWMinfo
|
|||
Window window; /**< The X11 window */
|
||||
} x11;
|
||||
#endif
|
||||
#if defined(SDL_VIDEO_DRIVER_WAYLAND)
|
||||
struct
|
||||
{
|
||||
struct wl_display *display; /**< Wayland display */
|
||||
struct wl_surface *surface; /**< Wayland surface */
|
||||
struct wl_shell_surface *shell_surface; /**< Wayland shell_surface (window manager handle) */
|
||||
} wl;
|
||||
#endif
|
||||
#if defined(SDL_VIDEO_DRIVER_DIRECTFB)
|
||||
struct
|
||||
{
|
||||
|
|
|
@ -30,7 +30,7 @@ SDL_PROC_UNUSED(void, glColor3bv, (const GLbyte *))
|
|||
SDL_PROC_UNUSED(void, glColor3d, (GLdouble, GLdouble, GLdouble))
|
||||
SDL_PROC_UNUSED(void, glColor3dv, (const GLdouble *))
|
||||
SDL_PROC_UNUSED(void, glColor3f, (GLfloat, GLfloat, GLfloat))
|
||||
SDL_PROC_UNUSED(void, glColor3fv, (const GLfloat *))
|
||||
SDL_PROC(void, glColor3fv, (const GLfloat *))
|
||||
SDL_PROC_UNUSED(void, glColor3i, (GLint, GLint, GLint))
|
||||
SDL_PROC_UNUSED(void, glColor3iv, (const GLint *))
|
||||
SDL_PROC_UNUSED(void, glColor3s, (GLshort, GLshort, GLshort))
|
||||
|
@ -85,7 +85,7 @@ SDL_PROC_UNUSED(void, glCopyTexSubImage2D,
|
|||
SDL_PROC_UNUSED(void, glCullFace, (GLenum mode))
|
||||
SDL_PROC_UNUSED(void, glDeleteLists, (GLuint list, GLsizei range))
|
||||
SDL_PROC(void, glDeleteTextures, (GLsizei n, const GLuint * textures))
|
||||
SDL_PROC_UNUSED(void, glDepthFunc, (GLenum func))
|
||||
SDL_PROC(void, glDepthFunc, (GLenum func))
|
||||
SDL_PROC_UNUSED(void, glDepthMask, (GLboolean flag))
|
||||
SDL_PROC_UNUSED(void, glDepthRange, (GLclampd zNear, GLclampd zFar))
|
||||
SDL_PROC(void, glDisable, (GLenum cap))
|
||||
|
@ -334,13 +334,13 @@ SDL_PROC_UNUSED(void, glRectsv, (const GLshort * v1, const GLshort * v2))
|
|||
SDL_PROC_UNUSED(GLint, glRenderMode, (GLenum mode))
|
||||
SDL_PROC(void, glRotated,
|
||||
(GLdouble angle, GLdouble x, GLdouble y, GLdouble z))
|
||||
SDL_PROC_UNUSED(void, glRotatef,
|
||||
SDL_PROC(void, glRotatef,
|
||||
(GLfloat angle, GLfloat x, GLfloat y, GLfloat z))
|
||||
SDL_PROC_UNUSED(void, glScaled, (GLdouble x, GLdouble y, GLdouble z))
|
||||
SDL_PROC_UNUSED(void, glScalef, (GLfloat x, GLfloat y, GLfloat z))
|
||||
SDL_PROC(void, glScissor, (GLint x, GLint y, GLsizei width, GLsizei height))
|
||||
SDL_PROC_UNUSED(void, glSelectBuffer, (GLsizei size, GLuint * buffer))
|
||||
SDL_PROC_UNUSED(void, glShadeModel, (GLenum mode))
|
||||
SDL_PROC(void, glShadeModel, (GLenum mode))
|
||||
SDL_PROC_UNUSED(void, glStencilFunc, (GLenum func, GLint ref, GLuint mask))
|
||||
SDL_PROC_UNUSED(void, glStencilMask, (GLuint mask))
|
||||
SDL_PROC_UNUSED(void, glStencilOp, (GLenum fail, GLenum zfail, GLenum zpass))
|
||||
|
@ -432,7 +432,7 @@ SDL_PROC_UNUSED(void, glVertex2sv, (const GLshort * v))
|
|||
SDL_PROC_UNUSED(void, glVertex3d, (GLdouble x, GLdouble y, GLdouble z))
|
||||
SDL_PROC_UNUSED(void, glVertex3dv, (const GLdouble * v))
|
||||
SDL_PROC_UNUSED(void, glVertex3f, (GLfloat x, GLfloat y, GLfloat z))
|
||||
SDL_PROC_UNUSED(void, glVertex3fv, (const GLfloat * v))
|
||||
SDL_PROC(void, glVertex3fv, (const GLfloat * v))
|
||||
SDL_PROC_UNUSED(void, glVertex3i, (GLint x, GLint y, GLint z))
|
||||
SDL_PROC_UNUSED(void, glVertex3iv, (const GLint * v))
|
||||
SDL_PROC_UNUSED(void, glVertex3s, (GLshort x, GLshort y, GLshort z))
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
|
||||
#else
|
||||
/* Desktop Linux */
|
||||
#define DEFAULT_OGL "libGL.so.1"
|
||||
#define DEFAULT_EGL "libEGL.so.1"
|
||||
#define DEFAULT_OGL_ES2 "libGLESv2.so.2"
|
||||
#define DEFAULT_OGL_ES_PVR "libGLES_CM.so.1"
|
||||
|
@ -149,23 +150,31 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa
|
|||
}
|
||||
|
||||
if (egl_dll_handle == NULL) {
|
||||
if (_this->gl_config.major_version > 1) {
|
||||
path = DEFAULT_OGL_ES2;
|
||||
egl_dll_handle = SDL_LoadObject(path);
|
||||
}
|
||||
else {
|
||||
path = DEFAULT_OGL_ES;
|
||||
egl_dll_handle = SDL_LoadObject(path);
|
||||
if (egl_dll_handle == NULL) {
|
||||
path = DEFAULT_OGL_ES_PVR;
|
||||
if(_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
|
||||
if (_this->gl_config.major_version > 1) {
|
||||
path = DEFAULT_OGL_ES2;
|
||||
egl_dll_handle = SDL_LoadObject(path);
|
||||
}
|
||||
else {
|
||||
path = DEFAULT_OGL_ES;
|
||||
egl_dll_handle = SDL_LoadObject(path);
|
||||
if (egl_dll_handle == NULL) {
|
||||
path = DEFAULT_OGL_ES_PVR;
|
||||
egl_dll_handle = SDL_LoadObject(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef DEFAULT_OGL
|
||||
else {
|
||||
path = DEFAULT_OGL;
|
||||
egl_dll_handle = SDL_LoadObject(path);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
_this->egl_data->egl_dll_handle = egl_dll_handle;
|
||||
|
||||
if (egl_dll_handle == NULL) {
|
||||
return SDL_SetError("Could not initialize OpenGL ES library");
|
||||
return SDL_SetError("Could not initialize OpenGL / GLES library");
|
||||
}
|
||||
|
||||
/* Loading libGL* in the previous step took care of loading libEGL.so, but we future proof by double checking */
|
||||
|
@ -205,6 +214,7 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa
|
|||
LOAD_FUNC(eglSwapInterval);
|
||||
LOAD_FUNC(eglWaitNative);
|
||||
LOAD_FUNC(eglWaitGL);
|
||||
LOAD_FUNC(eglBindAPI);
|
||||
|
||||
_this->egl_data->egl_display = _this->egl_data->eglGetDisplay(native_display);
|
||||
if (!_this->egl_data->egl_display) {
|
||||
|
@ -281,10 +291,17 @@ SDL_EGL_ChooseConfig(_THIS)
|
|||
}
|
||||
|
||||
attribs[i++] = EGL_RENDERABLE_TYPE;
|
||||
if (_this->gl_config.major_version == 2) {
|
||||
attribs[i++] = EGL_OPENGL_ES2_BIT;
|
||||
} else {
|
||||
attribs[i++] = EGL_OPENGL_ES_BIT;
|
||||
if(_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
|
||||
if (_this->gl_config.major_version == 2) {
|
||||
attribs[i++] = EGL_OPENGL_ES2_BIT;
|
||||
} else {
|
||||
attribs[i++] = EGL_OPENGL_ES_BIT;
|
||||
}
|
||||
_this->egl_data->eglBindAPI(EGL_OPENGL_ES_API);
|
||||
}
|
||||
else {
|
||||
attribs[i++] = EGL_OPENGL_BIT;
|
||||
_this->egl_data->eglBindAPI(EGL_OPENGL_API);
|
||||
}
|
||||
|
||||
attribs[i++] = EGL_NONE;
|
||||
|
@ -347,18 +364,27 @@ SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (_this->gl_config.major_version) {
|
||||
context_attrib_list[1] = _this->gl_config.major_version;
|
||||
}
|
||||
|
||||
if (_this->gl_config.share_with_current_context) {
|
||||
share_context = (EGLContext)SDL_GL_GetCurrentContext();
|
||||
}
|
||||
|
||||
egl_context =
|
||||
_this->egl_data->eglCreateContext(_this->egl_data->egl_display,
|
||||
_this->egl_data->egl_config,
|
||||
share_context, context_attrib_list);
|
||||
/* Bind the API */
|
||||
if(_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
|
||||
_this->egl_data->eglBindAPI(EGL_OPENGL_ES_API);
|
||||
if (_this->gl_config.major_version) {
|
||||
context_attrib_list[1] = _this->gl_config.major_version;
|
||||
}
|
||||
|
||||
egl_context = _this->egl_data->eglCreateContext(_this->egl_data->egl_display,
|
||||
_this->egl_data->egl_config,
|
||||
share_context, context_attrib_list);
|
||||
}
|
||||
else {
|
||||
_this->egl_data->eglBindAPI(EGL_OPENGL_API);
|
||||
egl_context = _this->egl_data->eglCreateContext(_this->egl_data->egl_display,
|
||||
_this->egl_data->egl_config,
|
||||
share_context, NULL);
|
||||
}
|
||||
|
||||
if (egl_context == EGL_NO_CONTEXT) {
|
||||
SDL_SetError("Could not create EGL context");
|
||||
|
|
|
@ -76,6 +76,9 @@ typedef struct SDL_EGL_VideoData
|
|||
EGLBoolean(EGLAPIENTRY *eglWaitNative) (EGLint engine);
|
||||
|
||||
EGLBoolean(EGLAPIENTRY *eglWaitGL)(void);
|
||||
|
||||
EGLBoolean(EGLAPIENTRY *eglBindAPI)(EGLenum);
|
||||
|
||||
} SDL_EGL_VideoData;
|
||||
|
||||
/* OpenGLES functions */
|
||||
|
|
|
@ -369,6 +369,9 @@ extern VideoBootStrap RPI_bootstrap;
|
|||
#if SDL_VIDEO_DRIVER_DUMMY
|
||||
extern VideoBootStrap DUMMY_bootstrap;
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_WAYLAND
|
||||
extern VideoBootStrap Wayland_bootstrap;
|
||||
#endif
|
||||
|
||||
extern SDL_VideoDevice *SDL_GetVideoDevice(void);
|
||||
extern int SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode);
|
||||
|
|
|
@ -85,6 +85,9 @@ static VideoBootStrap *bootstrap[] = {
|
|||
#endif
|
||||
#if SDL_VIDEO_DRIVER_DUMMY
|
||||
&DUMMY_bootstrap,
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_WAYLAND
|
||||
&Wayland_bootstrap,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
|
|
@ -0,0 +1,381 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.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 "SDL_config.h"
|
||||
|
||||
#include "SDL_stdinc.h"
|
||||
#include "SDL_assert.h"
|
||||
|
||||
#include "../../events/SDL_sysevents.h"
|
||||
#include "../../events/SDL_events_c.h"
|
||||
#include "../../events/scancodes_xfree86.h"
|
||||
|
||||
#include "SDL_waylandvideo.h"
|
||||
#include "SDL_waylandevents_c.h"
|
||||
#include "SDL_waylandwindow.h"
|
||||
|
||||
#include <linux/input.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/mman.h>
|
||||
#include <poll.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
struct SDL_WaylandInput {
|
||||
SDL_VideoData *display;
|
||||
struct wl_seat *seat;
|
||||
struct wl_pointer *pointer;
|
||||
struct wl_keyboard *keyboard;
|
||||
SDL_WindowData *pointer_focus;
|
||||
SDL_WindowData *keyboard_focus;
|
||||
|
||||
struct {
|
||||
struct xkb_keymap *keymap;
|
||||
struct xkb_state *state;
|
||||
} xkb;
|
||||
};
|
||||
|
||||
void
|
||||
Wayland_PumpEvents(_THIS)
|
||||
{
|
||||
SDL_VideoData *d = _this->driverdata;
|
||||
struct pollfd pfd[1];
|
||||
|
||||
pfd[0].fd = wl_display_get_fd(d->display);
|
||||
pfd[0].events = POLLIN;
|
||||
poll(pfd, 1, 0);
|
||||
|
||||
if (pfd[0].revents & POLLIN)
|
||||
wl_display_dispatch(d->display);
|
||||
else
|
||||
wl_display_dispatch_pending(d->display);
|
||||
}
|
||||
|
||||
static void
|
||||
pointer_handle_enter(void *data, struct wl_pointer *pointer,
|
||||
uint32_t serial, struct wl_surface *surface,
|
||||
wl_fixed_t sx_w, wl_fixed_t sy_w)
|
||||
{
|
||||
struct SDL_WaylandInput *input = data;
|
||||
SDL_WindowData *window;
|
||||
|
||||
if (!surface) {
|
||||
/* enter event for a window we've just destroyed */
|
||||
return;
|
||||
}
|
||||
|
||||
input->pointer_focus = wl_surface_get_user_data(surface);
|
||||
window = input->pointer_focus;
|
||||
SDL_SetMouseFocus(window->sdlwindow);
|
||||
}
|
||||
|
||||
static void
|
||||
pointer_handle_leave(void *data, struct wl_pointer *pointer,
|
||||
uint32_t serial, struct wl_surface *surface)
|
||||
{
|
||||
struct SDL_WaylandInput *input = data;
|
||||
|
||||
SDL_SetMouseFocus(NULL);
|
||||
input->pointer_focus = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
pointer_handle_motion(void *data, struct wl_pointer *pointer,
|
||||
uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w)
|
||||
{
|
||||
struct SDL_WaylandInput *input = data;
|
||||
SDL_WindowData *window = input->pointer_focus;
|
||||
int sx = wl_fixed_to_int(sx_w);
|
||||
int sy = wl_fixed_to_int(sy_w);
|
||||
|
||||
SDL_SendMouseMotion(window->sdlwindow, 0, 0, sx, sy);
|
||||
}
|
||||
|
||||
static void
|
||||
pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
|
||||
uint32_t time, uint32_t button, uint32_t state_w)
|
||||
{
|
||||
struct SDL_WaylandInput *input = data;
|
||||
SDL_WindowData *window = input->pointer_focus;
|
||||
enum wl_pointer_button_state state = state_w;
|
||||
uint32_t sdl_button;
|
||||
|
||||
switch (button) {
|
||||
case BTN_LEFT:
|
||||
sdl_button = SDL_BUTTON_LEFT;
|
||||
break;
|
||||
case BTN_MIDDLE:
|
||||
sdl_button = SDL_BUTTON_MIDDLE;
|
||||
break;
|
||||
case BTN_RIGHT:
|
||||
sdl_button = SDL_BUTTON_RIGHT;
|
||||
break;
|
||||
case BTN_SIDE:
|
||||
sdl_button = SDL_BUTTON_X1;
|
||||
break;
|
||||
case BTN_EXTRA:
|
||||
sdl_button = SDL_BUTTON_X2;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_SendMouseButton(window->sdlwindow, 0,
|
||||
state ? SDL_PRESSED : SDL_RELEASED, sdl_button);
|
||||
}
|
||||
|
||||
static void
|
||||
pointer_handle_axis(void *data, struct wl_pointer *pointer,
|
||||
uint32_t time, uint32_t axis, wl_fixed_t value)
|
||||
{
|
||||
struct SDL_WaylandInput *input = data;
|
||||
SDL_WindowData *window = input->pointer_focus;
|
||||
enum wl_pointer_axis a = axis;
|
||||
int x, y;
|
||||
|
||||
switch (a) {
|
||||
case WL_POINTER_AXIS_VERTICAL_SCROLL:
|
||||
x = 0;
|
||||
y = wl_fixed_to_int(value);
|
||||
break;
|
||||
case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
|
||||
x = wl_fixed_to_int(value);
|
||||
y = 0;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_SendMouseWheel(window->sdlwindow, 0, x, y);
|
||||
}
|
||||
|
||||
static const struct wl_pointer_listener pointer_listener = {
|
||||
pointer_handle_enter,
|
||||
pointer_handle_leave,
|
||||
pointer_handle_motion,
|
||||
pointer_handle_button,
|
||||
pointer_handle_axis,
|
||||
};
|
||||
|
||||
static void
|
||||
keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
|
||||
uint32_t format, int fd, uint32_t size)
|
||||
{
|
||||
struct SDL_WaylandInput *input = data;
|
||||
char *map_str;
|
||||
|
||||
if (!data) {
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
map_str = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
if (map_str == MAP_FAILED) {
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
input->xkb.keymap = xkb_map_new_from_string(input->display->xkb_context,
|
||||
map_str,
|
||||
XKB_KEYMAP_FORMAT_TEXT_V1,
|
||||
0);
|
||||
munmap(map_str, size);
|
||||
close(fd);
|
||||
|
||||
if (!input->xkb.keymap) {
|
||||
fprintf(stderr, "failed to compile keymap\n");
|
||||
return;
|
||||
}
|
||||
|
||||
input->xkb.state = xkb_state_new(input->xkb.keymap);
|
||||
if (!input->xkb.state) {
|
||||
fprintf(stderr, "failed to create XKB state\n");
|
||||
xkb_map_unref(input->xkb.keymap);
|
||||
input->xkb.keymap = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
|
||||
uint32_t serial, struct wl_surface *surface,
|
||||
struct wl_array *keys)
|
||||
{
|
||||
struct SDL_WaylandInput *input = data;
|
||||
SDL_WindowData *window = wl_surface_get_user_data(surface);
|
||||
|
||||
input->keyboard_focus = window;
|
||||
window->keyboard_device = input;
|
||||
SDL_SetKeyboardFocus(window->sdlwindow);
|
||||
}
|
||||
|
||||
static void
|
||||
keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
|
||||
uint32_t serial, struct wl_surface *surface)
|
||||
{
|
||||
SDL_SetKeyboardFocus(NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
|
||||
uint32_t serial, uint32_t time, uint32_t key,
|
||||
uint32_t state_w)
|
||||
{
|
||||
struct SDL_WaylandInput *input = data;
|
||||
SDL_WindowData *window = input->keyboard_focus;
|
||||
enum wl_keyboard_key_state state = state_w;
|
||||
const xkb_keysym_t *syms;
|
||||
uint32_t scancode;
|
||||
char text[8];
|
||||
int size;
|
||||
|
||||
if (key < SDL_arraysize(xfree86_scancode_table2)) {
|
||||
scancode = xfree86_scancode_table2[key];
|
||||
|
||||
// TODO when do we get WL_KEYBOARD_KEY_STATE_REPEAT?
|
||||
if (scancode != SDL_SCANCODE_UNKNOWN)
|
||||
SDL_SendKeyboardKey(state == WL_KEYBOARD_KEY_STATE_PRESSED ?
|
||||
SDL_PRESSED : SDL_RELEASED, scancode);
|
||||
}
|
||||
|
||||
if (!window || window->keyboard_device != input || !input->xkb.state)
|
||||
return;
|
||||
|
||||
// TODO can this happen?
|
||||
if (xkb_key_get_syms(input->xkb.state, key + 8, &syms) != 1)
|
||||
return;
|
||||
|
||||
if (state) {
|
||||
size = xkb_keysym_to_utf8(syms[0], text, sizeof text);
|
||||
|
||||
if (size > 0) {
|
||||
text[size] = 0;
|
||||
SDL_SendKeyboardText(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
|
||||
uint32_t serial, uint32_t mods_depressed,
|
||||
uint32_t mods_latched, uint32_t mods_locked,
|
||||
uint32_t group)
|
||||
{
|
||||
struct SDL_WaylandInput *input = data;
|
||||
|
||||
xkb_state_update_mask(input->xkb.state, mods_depressed, mods_latched,
|
||||
mods_locked, 0, 0, group);
|
||||
}
|
||||
|
||||
static const struct wl_keyboard_listener keyboard_listener = {
|
||||
keyboard_handle_keymap,
|
||||
keyboard_handle_enter,
|
||||
keyboard_handle_leave,
|
||||
keyboard_handle_key,
|
||||
keyboard_handle_modifiers,
|
||||
};
|
||||
|
||||
static void
|
||||
seat_handle_capabilities(void *data, struct wl_seat *seat,
|
||||
enum wl_seat_capability caps)
|
||||
{
|
||||
struct SDL_WaylandInput *input = data;
|
||||
|
||||
if ((caps & WL_SEAT_CAPABILITY_POINTER) && !input->pointer) {
|
||||
input->pointer = wl_seat_get_pointer(seat);
|
||||
input->display->pointer = input->pointer;
|
||||
wl_pointer_set_user_data(input->pointer, input);
|
||||
wl_pointer_add_listener(input->pointer, &pointer_listener,
|
||||
input);
|
||||
} else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && input->pointer) {
|
||||
wl_pointer_destroy(input->pointer);
|
||||
input->pointer = NULL;
|
||||
}
|
||||
|
||||
if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !input->keyboard) {
|
||||
input->keyboard = wl_seat_get_keyboard(seat);
|
||||
wl_keyboard_set_user_data(input->keyboard, input);
|
||||
wl_keyboard_add_listener(input->keyboard, &keyboard_listener,
|
||||
input);
|
||||
} else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && input->keyboard) {
|
||||
wl_keyboard_destroy(input->keyboard);
|
||||
input->keyboard = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct wl_seat_listener seat_listener = {
|
||||
seat_handle_capabilities,
|
||||
};
|
||||
|
||||
void
|
||||
Wayland_display_add_input(SDL_VideoData *d, uint32_t id)
|
||||
{
|
||||
struct SDL_WaylandInput *input;
|
||||
|
||||
input = malloc(sizeof *input);
|
||||
if (input == NULL)
|
||||
return;
|
||||
|
||||
memset(input, 0, sizeof *input);
|
||||
input->display = d;
|
||||
input->seat = wl_registry_bind(d->registry, id, &wl_seat_interface, 1);
|
||||
|
||||
d->input = input;
|
||||
|
||||
wl_seat_add_listener(input->seat, &seat_listener, input);
|
||||
wl_seat_set_user_data(input->seat, input);
|
||||
|
||||
wayland_schedule_write(d);
|
||||
}
|
||||
|
||||
void Wayland_display_destroy_input(SDL_VideoData *d)
|
||||
{
|
||||
struct SDL_WaylandInput *input = d->input;
|
||||
|
||||
if (!input)
|
||||
return;
|
||||
|
||||
if (input->keyboard)
|
||||
wl_keyboard_destroy(input->keyboard);
|
||||
|
||||
if (input->pointer)
|
||||
wl_pointer_destroy(input->pointer);
|
||||
|
||||
if (input->seat)
|
||||
wl_seat_destroy(input->seat);
|
||||
|
||||
if (input->xkb.state)
|
||||
xkb_state_unref(input->xkb.state);
|
||||
|
||||
if (input->xkb.keymap)
|
||||
xkb_map_unref(input->xkb.keymap);
|
||||
|
||||
free(input);
|
||||
d->input = NULL;
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.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 "SDL_config.h"
|
||||
|
||||
#ifndef _SDL_waylandevents_h
|
||||
#define _SDL_waylandevents_h
|
||||
|
||||
#include "SDL_waylandvideo.h"
|
||||
#include "SDL_waylandwindow.h"
|
||||
|
||||
extern void Wayland_PumpEvents(_THIS);
|
||||
|
||||
extern void Wayland_display_add_input(SDL_VideoData *d, uint32_t id);
|
||||
extern void Wayland_display_destroy_input(SDL_VideoData *d);
|
||||
|
||||
#endif /* _SDL_waylandevents_h */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -0,0 +1,407 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.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 _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "../SDL_sysvideo.h"
|
||||
|
||||
#include "SDL_config.h"
|
||||
#include "SDL_mouse.h"
|
||||
#include "../../events/SDL_mouse_c.h"
|
||||
#include "SDL_waylandvideo.h"
|
||||
#include "SDL_waylandevents_c.h"
|
||||
|
||||
#include "SDL_assert.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_WAYLAND
|
||||
|
||||
typedef struct {
|
||||
struct wl_buffer *buffer;
|
||||
struct wl_surface *surface;
|
||||
|
||||
int hot_x, hot_y;
|
||||
|
||||
/* Either a preloaded cursor, or one we created ourselves */
|
||||
struct wl_cursor *cursor;
|
||||
void *shm_data;
|
||||
} Wayland_CursorData;
|
||||
|
||||
static int
|
||||
wayland_create_tmp_file(off_t size)
|
||||
{
|
||||
static const char template[] = "/sdl-shared-XXXXXX";
|
||||
char *xdg_path;
|
||||
char tmp_path[PATH_MAX];
|
||||
int fd;
|
||||
|
||||
xdg_path = SDL_getenv("XDG_RUNTIME_DIR");
|
||||
if (!xdg_path) {
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_strlcpy(tmp_path, xdg_path, PATH_MAX);
|
||||
SDL_strlcat(tmp_path, template, PATH_MAX);
|
||||
|
||||
fd = mkostemp(tmp_path, O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
|
||||
if (ftruncate(fd, size) < 0) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
static void
|
||||
mouse_buffer_release(void *data, struct wl_buffer *buffer)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct wl_buffer_listener mouse_buffer_listener = {
|
||||
mouse_buffer_release
|
||||
};
|
||||
|
||||
static int
|
||||
create_buffer_from_shm(Wayland_CursorData *d,
|
||||
int width,
|
||||
int height,
|
||||
uint32_t format)
|
||||
{
|
||||
SDL_VideoDevice *vd = SDL_GetVideoDevice();
|
||||
SDL_VideoData *data = (SDL_VideoData *) vd->driverdata;
|
||||
|
||||
int stride = width * 4;
|
||||
int size = stride * height;
|
||||
|
||||
int shm_fd;
|
||||
|
||||
shm_fd = wayland_create_tmp_file(size);
|
||||
if (shm_fd < 0)
|
||||
{
|
||||
fprintf(stderr, "creating mouse cursor buffer failed!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
d->shm_data = mmap(NULL,
|
||||
size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
shm_fd,
|
||||
0);
|
||||
if (data == MAP_FAILED) {
|
||||
d->shm_data = NULL;
|
||||
fprintf (stderr, "mmap () failed\n");
|
||||
close (shm_fd);
|
||||
}
|
||||
|
||||
struct wl_shm_pool *shm_pool = wl_shm_create_pool(data->shm,
|
||||
shm_fd,
|
||||
size);
|
||||
d->buffer = wl_shm_pool_create_buffer(shm_pool,
|
||||
0,
|
||||
width,
|
||||
height,
|
||||
stride,
|
||||
format);
|
||||
wl_buffer_add_listener(d->buffer,
|
||||
&mouse_buffer_listener,
|
||||
d);
|
||||
|
||||
wl_shm_pool_destroy (shm_pool);
|
||||
close (shm_fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SDL_Cursor *
|
||||
Wayland_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
|
||||
{
|
||||
SDL_Cursor *cursor;
|
||||
|
||||
cursor = calloc(1, sizeof (*cursor));
|
||||
if (cursor) {
|
||||
SDL_VideoDevice *vd = SDL_GetVideoDevice ();
|
||||
SDL_VideoData *wd = (SDL_VideoData *) vd->driverdata;
|
||||
Wayland_CursorData *data = calloc (1, sizeof (Wayland_CursorData));
|
||||
cursor->driverdata = (void *) data;
|
||||
|
||||
/* Assume ARGB8888 */
|
||||
SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);
|
||||
SDL_assert(surface->pitch == surface->w * 4);
|
||||
|
||||
/* Allocate shared memory buffer for this cursor */
|
||||
if (create_buffer_from_shm (data,
|
||||
surface->w,
|
||||
surface->h,
|
||||
WL_SHM_FORMAT_XRGB8888) < 0)
|
||||
{
|
||||
free (cursor->driverdata);
|
||||
free (cursor);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SDL_memcpy(data->shm_data,
|
||||
surface->pixels,
|
||||
surface->h * surface->pitch);
|
||||
|
||||
data->surface = wl_compositor_create_surface(wd->compositor);
|
||||
wl_surface_attach(data->surface,
|
||||
data->buffer,
|
||||
0,
|
||||
0);
|
||||
wl_surface_damage(data->surface,
|
||||
0,
|
||||
0,
|
||||
surface->w,
|
||||
surface->h);
|
||||
wl_surface_commit(data->surface);
|
||||
|
||||
data->hot_x = hot_x;
|
||||
data->hot_y = hot_y;
|
||||
}
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
static SDL_Cursor *
|
||||
CreateCursorFromWlCursor(SDL_VideoData *d, struct wl_cursor *wlcursor)
|
||||
{
|
||||
SDL_Cursor *cursor;
|
||||
|
||||
cursor = calloc(1, sizeof (*cursor));
|
||||
if (cursor) {
|
||||
Wayland_CursorData *data = calloc (1, sizeof (Wayland_CursorData));
|
||||
cursor->driverdata = (void *) data;
|
||||
|
||||
/* The wl_buffer here will be destroyed from wl_cursor_theme_destroy
|
||||
* if we are fetching this from a wl_cursor_theme, so don't store a
|
||||
* reference to it here */
|
||||
data->buffer = NULL;
|
||||
data->surface = wl_compositor_create_surface(d->compositor);
|
||||
wl_surface_attach(data->surface,
|
||||
wl_cursor_image_get_buffer(wlcursor->images[0]),
|
||||
0,
|
||||
0);
|
||||
wl_surface_damage(data->surface,
|
||||
0,
|
||||
0,
|
||||
wlcursor->images[0]->width,
|
||||
wlcursor->images[0]->height);
|
||||
wl_surface_commit(data->surface);
|
||||
data->hot_x = wlcursor->images[0]->hotspot_x;
|
||||
data->hot_y = wlcursor->images[0]->hotspot_y;
|
||||
data->cursor= wlcursor;
|
||||
} else {
|
||||
SDL_OutOfMemory ();
|
||||
}
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
static SDL_Cursor *
|
||||
Wayland_CreateDefaultCursor()
|
||||
{
|
||||
SDL_VideoDevice *device = SDL_GetVideoDevice();
|
||||
SDL_VideoData *data = device->driverdata;
|
||||
|
||||
return CreateCursorFromWlCursor (data,
|
||||
wl_cursor_theme_get_cursor(data->cursor_theme,
|
||||
"left_ptr"));
|
||||
}
|
||||
|
||||
static SDL_Cursor *
|
||||
Wayland_CreateSystemCursor(SDL_SystemCursor id)
|
||||
{
|
||||
SDL_VideoDevice *vd = SDL_GetVideoDevice();
|
||||
SDL_VideoData *d = vd->driverdata;
|
||||
|
||||
struct wl_cursor *cursor = NULL;
|
||||
|
||||
switch(id)
|
||||
{
|
||||
default:
|
||||
SDL_assert(0);
|
||||
return NULL;
|
||||
case SDL_SYSTEM_CURSOR_ARROW:
|
||||
cursor = wl_cursor_theme_get_cursor(d->cursor_theme, "left_ptr");
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_IBEAM:
|
||||
cursor = wl_cursor_theme_get_cursor(d->cursor_theme, "xterm");
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_WAIT:
|
||||
cursor = wl_cursor_theme_get_cursor(d->cursor_theme, "wait");
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_CROSSHAIR:
|
||||
cursor = wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_WAITARROW:
|
||||
cursor = wl_cursor_theme_get_cursor(d->cursor_theme, "wait");
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_SIZENWSE:
|
||||
cursor = wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_SIZENESW:
|
||||
cursor = wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_SIZEWE:
|
||||
cursor = wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_SIZENS:
|
||||
cursor = wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_SIZEALL:
|
||||
cursor = wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_NO:
|
||||
cursor = wl_cursor_theme_get_cursor(d->cursor_theme, "xterm");
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_HAND:
|
||||
cursor = wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
|
||||
break;
|
||||
}
|
||||
|
||||
SDL_Cursor *sdl_cursor = CreateCursorFromWlCursor (d, cursor);
|
||||
|
||||
return sdl_cursor;
|
||||
}
|
||||
|
||||
static void
|
||||
Wayland_FreeCursor(SDL_Cursor *cursor)
|
||||
{
|
||||
if (!cursor)
|
||||
return;
|
||||
|
||||
Wayland_CursorData *d = cursor->driverdata;
|
||||
|
||||
/* Probably not a cursor we own */
|
||||
if (!d)
|
||||
return;
|
||||
|
||||
if (d->buffer)
|
||||
wl_buffer_destroy(d->buffer);
|
||||
|
||||
if (d->surface)
|
||||
wl_surface_destroy(d->surface);
|
||||
|
||||
/* Not sure what's meant to happen to shm_data */
|
||||
free (cursor->driverdata);
|
||||
SDL_free(cursor);
|
||||
}
|
||||
|
||||
static int
|
||||
Wayland_ShowCursor(SDL_Cursor *cursor)
|
||||
{
|
||||
SDL_VideoDevice *vd = SDL_GetVideoDevice();
|
||||
SDL_VideoData *d = vd->driverdata;
|
||||
|
||||
struct wl_pointer *pointer = d->pointer;
|
||||
|
||||
if (!pointer)
|
||||
return -1;
|
||||
|
||||
if (cursor)
|
||||
{
|
||||
Wayland_CursorData *data = cursor->driverdata;
|
||||
|
||||
wl_pointer_set_cursor (pointer, 0,
|
||||
data->surface,
|
||||
data->hot_x,
|
||||
data->hot_y);
|
||||
}
|
||||
else
|
||||
{
|
||||
wl_pointer_set_cursor (pointer, 0,
|
||||
NULL,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
Wayland_WarpMouse(SDL_Window *window, int x, int y)
|
||||
{
|
||||
SDL_Unsupported();
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
Wayland_SetRelativeMouseMode(SDL_bool enabled)
|
||||
{
|
||||
SDL_Unsupported();
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
Wayland_InitMouse(void)
|
||||
{
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
|
||||
mouse->CreateCursor = Wayland_CreateCursor;
|
||||
mouse->CreateSystemCursor = Wayland_CreateSystemCursor;
|
||||
mouse->ShowCursor = Wayland_ShowCursor;
|
||||
mouse->FreeCursor = Wayland_FreeCursor;
|
||||
mouse->WarpMouse = Wayland_WarpMouse;
|
||||
mouse->SetRelativeMouseMode = Wayland_SetRelativeMouseMode;
|
||||
|
||||
SDL_SetDefaultCursor(Wayland_CreateDefaultCursor());
|
||||
}
|
||||
|
||||
void
|
||||
Wayland_FiniMouse(void)
|
||||
{
|
||||
/* This effectively assumes that nobody else
|
||||
* touches SDL_Mouse which is effectively
|
||||
* a singleton */
|
||||
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
|
||||
/* Free the current cursor if not the same pointer as
|
||||
* the default cursor */
|
||||
if (mouse->def_cursor != mouse->cur_cursor)
|
||||
Wayland_FreeCursor (mouse->cur_cursor);
|
||||
|
||||
Wayland_FreeCursor (mouse->def_cursor);
|
||||
mouse->def_cursor = NULL;
|
||||
mouse->cur_cursor = NULL;
|
||||
|
||||
mouse->CreateCursor = NULL;
|
||||
mouse->CreateSystemCursor = NULL;
|
||||
mouse->ShowCursor = NULL;
|
||||
mouse->FreeCursor = NULL;
|
||||
mouse->WarpMouse = NULL;
|
||||
mouse->SetRelativeMouseMode = NULL;
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.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 "SDL_config.h"
|
||||
#include "SDL_mouse.h"
|
||||
#include "SDL_waylandvideo.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_WAYLAND
|
||||
|
||||
extern void Wayland_InitMouse(void);
|
||||
extern void Wayland_FiniMouse(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.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 "SDL_config.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_WAYLAND && SDL_VIDEO_OPENGL_EGL
|
||||
|
||||
#include "SDL_waylandvideo.h"
|
||||
#include "SDL_waylandopengles.h"
|
||||
#include "SDL_waylandwindow.h"
|
||||
#include "SDL_waylandevents_c.h"
|
||||
|
||||
/* EGL implementation of SDL OpenGL ES support */
|
||||
|
||||
int
|
||||
Wayland_GLES_LoadLibrary(_THIS, const char *path) {
|
||||
int ret;
|
||||
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
|
||||
|
||||
ret = SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType) data->display);
|
||||
|
||||
Wayland_PumpEvents(_this);
|
||||
wayland_schedule_write(data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
SDL_GLContext
|
||||
Wayland_GLES_CreateContext(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_GLContext context;
|
||||
context = SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
|
||||
wayland_schedule_write(_this->driverdata);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
void
|
||||
Wayland_GLES_SwapWindow(_THIS, SDL_Window *window)
|
||||
{
|
||||
SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
|
||||
wayland_schedule_write(_this->driverdata);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
Wayland_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (window && context) {
|
||||
ret = SDL_EGL_MakeCurrent(_this, ((SDL_WindowData *) window->driverdata)->egl_surface, context);
|
||||
}
|
||||
else {
|
||||
ret = SDL_EGL_MakeCurrent(_this, NULL, NULL);
|
||||
}
|
||||
|
||||
wayland_schedule_write(_this->driverdata);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
Wayland_GLES_DeleteContext(_THIS, SDL_GLContext context)
|
||||
{
|
||||
SDL_EGL_DeleteContext(_this, context);
|
||||
wayland_schedule_write(_this->driverdata);
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_WAYLAND && SDL_VIDEO_OPENGL_EGL */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.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 "SDL_config.h"
|
||||
|
||||
#ifndef _SDL_waylandopengles_h
|
||||
#define _SDL_waylandopengles_h
|
||||
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include "../SDL_egl_c.h"
|
||||
|
||||
typedef struct SDL_PrivateGLESData
|
||||
{
|
||||
} SDL_PrivateGLESData;
|
||||
|
||||
/* OpenGLES functions */
|
||||
#define Wayland_GLES_GetAttribute SDL_EGL_GetAttribute
|
||||
#define Wayland_GLES_GetProcAddress SDL_EGL_GetProcAddress
|
||||
#define Wayland_GLES_UnloadLibrary SDL_EGL_UnloadLibrary
|
||||
#define Wayland_GLES_SetSwapInterval SDL_EGL_SetSwapInterval
|
||||
#define Wayland_GLES_GetSwapInterval SDL_EGL_GetSwapInterval
|
||||
|
||||
extern int Wayland_GLES_LoadLibrary(_THIS, const char *path);
|
||||
extern SDL_GLContext Wayland_GLES_CreateContext(_THIS, SDL_Window * window);
|
||||
extern void Wayland_GLES_SwapWindow(_THIS, SDL_Window * window);
|
||||
extern int Wayland_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
|
||||
extern void Wayland_GLES_DeleteContext(_THIS, SDL_GLContext context);
|
||||
|
||||
#endif /* _SDL_waylandopengles_h */
|
|
@ -0,0 +1,365 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.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 "SDL_config.h"
|
||||
|
||||
#include "SDL_video.h"
|
||||
#include "SDL_mouse.h"
|
||||
#include "../../events/SDL_events_c.h"
|
||||
|
||||
#include "SDL_waylandvideo.h"
|
||||
#include "SDL_waylandevents_c.h"
|
||||
#include "SDL_waylandwindow.h"
|
||||
#include "SDL_waylandopengles.h"
|
||||
#include "SDL_waylandmouse.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
#define WAYLANDVID_DRIVER_NAME "wayland"
|
||||
|
||||
struct wayland_mode {
|
||||
SDL_DisplayMode mode;
|
||||
struct wl_list link;
|
||||
};
|
||||
|
||||
/* Initialization/Query functions */
|
||||
static int
|
||||
Wayland_VideoInit(_THIS);
|
||||
|
||||
static void
|
||||
Wayland_GetDisplayModes(_THIS, SDL_VideoDisplay *sdl_display);
|
||||
static int
|
||||
Wayland_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode);
|
||||
|
||||
static void
|
||||
Wayland_VideoQuit(_THIS);
|
||||
|
||||
/* Wayland driver bootstrap functions */
|
||||
static int
|
||||
Wayland_Available(void)
|
||||
{
|
||||
struct wl_display *display = NULL;
|
||||
|
||||
display = wl_display_connect(NULL);
|
||||
if (display != NULL) {
|
||||
wl_display_disconnect(display);
|
||||
}
|
||||
|
||||
return (display != NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
Wayland_DeleteDevice(SDL_VideoDevice *device)
|
||||
{
|
||||
SDL_free(device);
|
||||
}
|
||||
|
||||
static SDL_VideoDevice *
|
||||
Wayland_CreateDevice(int devindex)
|
||||
{
|
||||
SDL_VideoDevice *device;
|
||||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
device = SDL_calloc(1, sizeof(SDL_VideoDevice));
|
||||
if (!device) {
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Set the function pointers */
|
||||
device->VideoInit = Wayland_VideoInit;
|
||||
device->VideoQuit = Wayland_VideoQuit;
|
||||
device->SetDisplayMode = Wayland_SetDisplayMode;
|
||||
device->GetDisplayModes = Wayland_GetDisplayModes;
|
||||
device->GetWindowWMInfo = Wayland_GetWindowWMInfo;
|
||||
|
||||
device->PumpEvents = Wayland_PumpEvents;
|
||||
|
||||
device->GL_SwapWindow = Wayland_GLES_SwapWindow;
|
||||
device->GL_GetSwapInterval = Wayland_GLES_GetSwapInterval;
|
||||
device->GL_SetSwapInterval = Wayland_GLES_SetSwapInterval;
|
||||
device->GL_MakeCurrent = Wayland_GLES_MakeCurrent;
|
||||
device->GL_CreateContext = Wayland_GLES_CreateContext;
|
||||
device->GL_LoadLibrary = Wayland_GLES_LoadLibrary;
|
||||
device->GL_UnloadLibrary = Wayland_GLES_UnloadLibrary;
|
||||
device->GL_GetProcAddress = Wayland_GLES_GetProcAddress;
|
||||
device->GL_DeleteContext = Wayland_GLES_DeleteContext;
|
||||
|
||||
device->CreateWindow = Wayland_CreateWindow;
|
||||
device->ShowWindow = Wayland_ShowWindow;
|
||||
device->SetWindowFullscreen = Wayland_SetWindowFullscreen;
|
||||
device->SetWindowSize = Wayland_SetWindowSize;
|
||||
device->DestroyWindow = Wayland_DestroyWindow;
|
||||
|
||||
device->free = Wayland_DeleteDevice;
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
VideoBootStrap Wayland_bootstrap = {
|
||||
WAYLANDVID_DRIVER_NAME, "SDL Wayland video driver",
|
||||
Wayland_Available, Wayland_CreateDevice
|
||||
};
|
||||
|
||||
static void
|
||||
wayland_add_mode(SDL_VideoData *d, SDL_DisplayMode m)
|
||||
{
|
||||
struct wayland_mode *mode;
|
||||
|
||||
/* Check for duplicate mode */
|
||||
wl_list_for_each(mode, &d->modes_list, link)
|
||||
if (mode->mode.w == m.w && mode->mode.h == m.h &&
|
||||
mode->mode.refresh_rate == m.refresh_rate)
|
||||
return;
|
||||
|
||||
/* Add new mode to the list */
|
||||
mode = SDL_calloc(1, sizeof *mode);
|
||||
|
||||
if (!mode)
|
||||
return;
|
||||
|
||||
mode->mode = m;
|
||||
wl_list_insert(&d->modes_list, &mode->link);
|
||||
}
|
||||
|
||||
static void
|
||||
display_handle_geometry(void *data,
|
||||
struct wl_output *output,
|
||||
int x, int y,
|
||||
int physical_width,
|
||||
int physical_height,
|
||||
int subpixel,
|
||||
const char *make,
|
||||
const char *model,
|
||||
int transform)
|
||||
|
||||
{
|
||||
SDL_VideoData *d = data;
|
||||
|
||||
d->screen_allocation.x = x;
|
||||
d->screen_allocation.y = y;
|
||||
}
|
||||
|
||||
static void
|
||||
display_handle_mode(void *data,
|
||||
struct wl_output *wl_output,
|
||||
uint32_t flags,
|
||||
int width,
|
||||
int height,
|
||||
int refresh)
|
||||
{
|
||||
SDL_VideoData *d = data;
|
||||
SDL_DisplayMode mode;
|
||||
|
||||
SDL_zero(mode);
|
||||
mode.w = width;
|
||||
mode.h = height;
|
||||
mode.refresh_rate = refresh / 1000;
|
||||
|
||||
wayland_add_mode(d, mode);
|
||||
|
||||
if (flags & WL_OUTPUT_MODE_CURRENT) {
|
||||
d->screen_allocation.width = width;
|
||||
d->screen_allocation.height = height;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct wl_output_listener output_listener = {
|
||||
display_handle_geometry,
|
||||
display_handle_mode
|
||||
};
|
||||
|
||||
static void
|
||||
shm_handle_format(void *data,
|
||||
struct wl_shm *shm,
|
||||
uint32_t format)
|
||||
{
|
||||
SDL_VideoData *d = data;
|
||||
|
||||
d->shm_formats |= (1 << format);
|
||||
}
|
||||
|
||||
static const struct wl_shm_listener shm_listener = {
|
||||
shm_handle_format
|
||||
};
|
||||
|
||||
static void
|
||||
display_handle_global(void *data, struct wl_registry *registry, uint32_t id,
|
||||
const char *interface, uint32_t version)
|
||||
{
|
||||
SDL_VideoData *d = data;
|
||||
|
||||
if (strcmp(interface, "wl_compositor") == 0) {
|
||||
d->compositor = wl_registry_bind(d->registry, id, &wl_compositor_interface, 1);
|
||||
} else if (strcmp(interface, "wl_output") == 0) {
|
||||
d->output = wl_registry_bind(d->registry, id, &wl_output_interface, 1);
|
||||
wl_output_add_listener(d->output, &output_listener, d);
|
||||
} else if (strcmp(interface, "wl_seat") == 0) {
|
||||
Wayland_display_add_input(d, id);
|
||||
} else if (strcmp(interface, "wl_shell") == 0) {
|
||||
d->shell = wl_registry_bind(d->registry, id, &wl_shell_interface, 1);
|
||||
} else if (strcmp(interface, "wl_shm") == 0) {
|
||||
d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
|
||||
d->cursor_theme = wl_cursor_theme_load(NULL, 32, d->shm);
|
||||
d->default_cursor = wl_cursor_theme_get_cursor(d->cursor_theme, "left_ptr");
|
||||
wl_shm_add_listener(d->shm, &shm_listener, d);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct wl_registry_listener registry_listener = {
|
||||
display_handle_global
|
||||
};
|
||||
|
||||
int
|
||||
Wayland_VideoInit(_THIS)
|
||||
{
|
||||
SDL_VideoData *data;
|
||||
|
||||
data = malloc(sizeof *data);
|
||||
if (data == NULL)
|
||||
return 0;
|
||||
memset(data, 0, sizeof *data);
|
||||
|
||||
_this->driverdata = data;
|
||||
|
||||
wl_list_init(&data->modes_list);
|
||||
|
||||
data->display = wl_display_connect(NULL);
|
||||
if (data->display == NULL) {
|
||||
SDL_SetError("Failed to connect to a Wayland display");
|
||||
return 0;
|
||||
}
|
||||
|
||||
data->registry = wl_display_get_registry(data->display);
|
||||
wl_registry_add_listener(data->registry, ®istry_listener, data);
|
||||
|
||||
while (data->screen_allocation.width == 0)
|
||||
wl_display_dispatch(data->display);
|
||||
|
||||
data->xkb_context = xkb_context_new(0);
|
||||
if (!data->xkb_context) {
|
||||
SDL_SetError("Failed to create XKB context");
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_VideoDisplay display;
|
||||
SDL_DisplayMode mode;
|
||||
|
||||
/* Use a fake 32-bpp desktop mode */
|
||||
mode.format = SDL_PIXELFORMAT_RGB888;
|
||||
mode.w = data->screen_allocation.width;
|
||||
mode.h = data->screen_allocation.height;
|
||||
mode.refresh_rate = 0;
|
||||
mode.driverdata = NULL;
|
||||
wayland_add_mode(data, mode);
|
||||
SDL_zero(display);
|
||||
display.desktop_mode = mode;
|
||||
display.current_mode = mode;
|
||||
display.driverdata = NULL;
|
||||
SDL_AddVideoDisplay(&display);
|
||||
|
||||
Wayland_InitMouse ();
|
||||
|
||||
wayland_schedule_write(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
Wayland_GetDisplayModes(_THIS, SDL_VideoDisplay *sdl_display)
|
||||
{
|
||||
SDL_VideoData *data = _this->driverdata;
|
||||
SDL_DisplayMode mode;
|
||||
struct wayland_mode *m;
|
||||
|
||||
Wayland_PumpEvents(_this);
|
||||
|
||||
wl_list_for_each(m, &data->modes_list, link) {
|
||||
m->mode.format = SDL_PIXELFORMAT_RGB888;
|
||||
SDL_AddDisplayMode(sdl_display, &m->mode);
|
||||
m->mode.format = SDL_PIXELFORMAT_RGBA8888;
|
||||
SDL_AddDisplayMode(sdl_display, &m->mode);
|
||||
}
|
||||
|
||||
mode.w = data->screen_allocation.width;
|
||||
mode.h = data->screen_allocation.height;
|
||||
mode.refresh_rate = 0;
|
||||
mode.driverdata = NULL;
|
||||
|
||||
mode.format = SDL_PIXELFORMAT_RGB888;
|
||||
SDL_AddDisplayMode(sdl_display, &mode);
|
||||
mode.format = SDL_PIXELFORMAT_RGBA8888;
|
||||
SDL_AddDisplayMode(sdl_display, &mode);
|
||||
}
|
||||
|
||||
static int
|
||||
Wayland_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Wayland_VideoQuit(_THIS)
|
||||
{
|
||||
SDL_VideoData *data = _this->driverdata;
|
||||
struct wayland_mode *t, *m;
|
||||
|
||||
Wayland_FiniMouse ();
|
||||
|
||||
if (data->output)
|
||||
wl_output_destroy(data->output);
|
||||
|
||||
Wayland_display_destroy_input(data);
|
||||
|
||||
if (data->xkb_context) {
|
||||
xkb_context_unref(data->xkb_context);
|
||||
data->xkb_context = NULL;
|
||||
}
|
||||
|
||||
if (data->shm)
|
||||
wl_shm_destroy(data->shm);
|
||||
|
||||
if (data->cursor_theme)
|
||||
wl_cursor_theme_destroy(data->cursor_theme);
|
||||
|
||||
if (data->shell)
|
||||
wl_shell_destroy(data->shell);
|
||||
|
||||
if (data->compositor)
|
||||
wl_compositor_destroy(data->compositor);
|
||||
|
||||
if (data->display) {
|
||||
wl_display_flush(data->display);
|
||||
wl_display_disconnect(data->display);
|
||||
}
|
||||
|
||||
wl_list_for_each_safe(m, t, &data->modes_list, link) {
|
||||
wl_list_remove(&m->link);
|
||||
free(m);
|
||||
}
|
||||
|
||||
|
||||
free(data);
|
||||
_this->driverdata = NULL;
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.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 "SDL_config.h"
|
||||
|
||||
#ifndef _SDL_waylandvideo_h
|
||||
#define _SDL_waylandvideo_h
|
||||
|
||||
#include <wayland-client.h>
|
||||
#include <wayland-cursor.h>
|
||||
#include <wayland-egl.h>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
|
||||
struct xkb_context;
|
||||
struct SDL_WaylandInput;
|
||||
|
||||
typedef struct {
|
||||
struct wl_display *display;
|
||||
struct wl_registry *registry;
|
||||
struct wl_compositor *compositor;
|
||||
struct wl_output *output;
|
||||
struct wl_shm *shm;
|
||||
struct wl_cursor_theme *cursor_theme;
|
||||
struct wl_cursor *default_cursor;
|
||||
struct wl_pointer *pointer;
|
||||
struct wl_shell *shell;
|
||||
|
||||
struct {
|
||||
int32_t x, y, width, height;
|
||||
} screen_allocation;
|
||||
|
||||
struct wl_list modes_list;
|
||||
|
||||
EGLDisplay edpy;
|
||||
EGLContext context;
|
||||
EGLConfig econf;
|
||||
|
||||
struct xkb_context *xkb_context;
|
||||
struct SDL_WaylandInput *input;
|
||||
|
||||
uint32_t shm_formats;
|
||||
} SDL_VideoData;
|
||||
|
||||
static inline void
|
||||
wayland_schedule_write(SDL_VideoData *data)
|
||||
{
|
||||
wl_display_flush(data->display);
|
||||
}
|
||||
|
||||
#endif /* _SDL_nullvideo_h */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.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 "SDL_config.h"
|
||||
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include "../../events/SDL_windowevents_c.h"
|
||||
#include "../SDL_egl_c.h"
|
||||
#include "SDL_waylandwindow.h"
|
||||
#include "SDL_waylandvideo.h"
|
||||
|
||||
static void
|
||||
handle_ping(void *data, struct wl_shell_surface *shell_surface,
|
||||
uint32_t serial)
|
||||
{
|
||||
wl_shell_surface_pong(shell_surface, serial);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_configure(void *data, struct wl_shell_surface *shell_surface,
|
||||
uint32_t edges, int32_t width, int32_t height)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
handle_popup_done(void *data, struct wl_shell_surface *shell_surface)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct wl_shell_surface_listener shell_surface_listener = {
|
||||
handle_ping,
|
||||
handle_configure,
|
||||
handle_popup_done
|
||||
};
|
||||
|
||||
SDL_bool
|
||||
Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
|
||||
{
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
|
||||
info->info.wl.display = data->waylandData->display;
|
||||
info->info.wl.surface = data->surface;
|
||||
info->info.wl.shell_surface = data->shell_surface;
|
||||
info->subsystem = SDL_SYSWM_WAYLAND;
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
void Wayland_ShowWindow(_THIS, SDL_Window *window)
|
||||
{
|
||||
SDL_WindowData *wind = window->driverdata;
|
||||
|
||||
if (window->flags & SDL_WINDOW_FULLSCREEN)
|
||||
wl_shell_surface_set_fullscreen(wind->shell_surface,
|
||||
WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
|
||||
0, NULL);
|
||||
else
|
||||
wl_shell_surface_set_toplevel(wind->shell_surface);
|
||||
|
||||
wayland_schedule_write(_this->driverdata);
|
||||
}
|
||||
|
||||
void
|
||||
Wayland_SetWindowFullscreen(_THIS, SDL_Window * window,
|
||||
SDL_VideoDisplay * _display, SDL_bool fullscreen)
|
||||
{
|
||||
SDL_WindowData *wind = window->driverdata;
|
||||
|
||||
if (fullscreen)
|
||||
wl_shell_surface_set_fullscreen(wind->shell_surface,
|
||||
WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE,
|
||||
0, NULL);
|
||||
else
|
||||
wl_shell_surface_set_toplevel(wind->shell_surface);
|
||||
|
||||
wayland_schedule_write(_this->driverdata);
|
||||
}
|
||||
|
||||
int Wayland_CreateWindow(_THIS, SDL_Window *window)
|
||||
{
|
||||
SDL_WindowData *data;
|
||||
SDL_VideoData *c;
|
||||
struct wl_region *region;
|
||||
|
||||
data = calloc(1, sizeof *data);
|
||||
if (data == NULL)
|
||||
return 0;
|
||||
|
||||
c = _this->driverdata;
|
||||
window->driverdata = data;
|
||||
|
||||
if (!(window->flags & SDL_WINDOW_OPENGL)) {
|
||||
SDL_GL_LoadLibrary(NULL);
|
||||
window->flags |= SDL_WINDOW_OPENGL;
|
||||
}
|
||||
|
||||
if (window->x == SDL_WINDOWPOS_UNDEFINED) {
|
||||
window->x = 0;
|
||||
}
|
||||
if (window->y == SDL_WINDOWPOS_UNDEFINED) {
|
||||
window->y = 0;
|
||||
}
|
||||
|
||||
data->waylandData = c;
|
||||
data->sdlwindow = window;
|
||||
|
||||
data->surface =
|
||||
wl_compositor_create_surface(c->compositor);
|
||||
wl_surface_set_user_data(data->surface, data);
|
||||
data->shell_surface = wl_shell_get_shell_surface(c->shell,
|
||||
data->surface);
|
||||
data->egl_window = wl_egl_window_create(data->surface,
|
||||
window->w, window->h);
|
||||
|
||||
/* Create the GLES window surface */
|
||||
data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->egl_window);
|
||||
|
||||
if (data->egl_surface == EGL_NO_SURFACE) {
|
||||
SDL_SetError("failed to create a window surface");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (data->shell_surface) {
|
||||
wl_shell_surface_set_user_data(data->shell_surface, data);
|
||||
wl_shell_surface_add_listener(data->shell_surface,
|
||||
&shell_surface_listener, data);
|
||||
}
|
||||
|
||||
region = wl_compositor_create_region(c->compositor);
|
||||
wl_region_add(region, 0, 0, window->w, window->h);
|
||||
wl_surface_set_opaque_region(data->surface, region);
|
||||
wl_region_destroy(region);
|
||||
|
||||
wayland_schedule_write(c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Wayland_SetWindowSize(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_VideoData *data = _this->driverdata;
|
||||
SDL_WindowData *wind = window->driverdata;
|
||||
struct wl_region *region;
|
||||
|
||||
wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0);
|
||||
|
||||
region = wl_compositor_create_region(data->compositor);
|
||||
wl_region_add(region, 0, 0, window->w, window->h);
|
||||
wl_surface_set_opaque_region(wind->surface, region);
|
||||
wl_region_destroy(region);
|
||||
}
|
||||
|
||||
void Wayland_DestroyWindow(_THIS, SDL_Window *window)
|
||||
{
|
||||
SDL_VideoData *data = _this->driverdata;
|
||||
SDL_WindowData *wind = window->driverdata;
|
||||
|
||||
window->driverdata = NULL;
|
||||
|
||||
if (data) {
|
||||
SDL_EGL_DestroySurface(_this, wind->egl_surface);
|
||||
wl_egl_window_destroy(wind->egl_window);
|
||||
|
||||
if (wind->shell_surface)
|
||||
wl_shell_surface_destroy(wind->shell_surface);
|
||||
|
||||
wl_surface_destroy(wind->surface);
|
||||
|
||||
SDL_free(wind);
|
||||
wayland_schedule_write(data);
|
||||
}
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.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 "SDL_config.h"
|
||||
|
||||
#ifndef _SDL_waylandwindow_h
|
||||
#define _SDL_waylandwindow_h
|
||||
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include "SDL_syswm.h"
|
||||
|
||||
#include "SDL_waylandvideo.h"
|
||||
|
||||
struct SDL_WaylandInput;
|
||||
|
||||
typedef struct {
|
||||
SDL_Window *sdlwindow;
|
||||
SDL_VideoData *waylandData;
|
||||
struct wl_surface *surface;
|
||||
struct wl_shell_surface *shell_surface;
|
||||
struct wl_egl_window *egl_window;
|
||||
struct SDL_WaylandInput *keyboard_device;
|
||||
|
||||
EGLSurface egl_surface;
|
||||
} SDL_WindowData;
|
||||
|
||||
extern void Wayland_ShowWindow(_THIS, SDL_Window *window);
|
||||
extern void Wayland_SetWindowFullscreen(_THIS, SDL_Window * window,
|
||||
SDL_VideoDisplay * _display,
|
||||
SDL_bool fullscreen);
|
||||
extern int Wayland_CreateWindow(_THIS, SDL_Window *window);
|
||||
extern void Wayland_SetWindowSize(_THIS, SDL_Window * window);
|
||||
extern void Wayland_DestroyWindow(_THIS, SDL_Window *window);
|
||||
|
||||
extern SDL_bool
|
||||
Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info);
|
||||
|
||||
#endif /* _SDL_waylandwindow_h */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -128,13 +128,13 @@ testgesture$(EXE): $(srcdir)/testgesture.c
|
|||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS) @MATHLIB@
|
||||
|
||||
testgl2$(EXE): $(srcdir)/testgl2.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS) @GLLIB@ @MATHLIB@
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS) @MATHLIB@
|
||||
|
||||
testgles$(EXE): $(srcdir)/testgles.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS) @GLESLIB@ @MATHLIB@
|
||||
|
||||
testgles2$(EXE): $(srcdir)/testgles2.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS) @GLES2LIB@ @MATHLIB@
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS) @MATHLIB@
|
||||
|
||||
testhaptic$(EXE): $(srcdir)/testhaptic.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
|
238
test/testgl2.c
238
test/testgl2.c
|
@ -24,11 +24,48 @@
|
|||
|
||||
#include "SDL_opengl.h"
|
||||
|
||||
typedef struct GL_Context
|
||||
{
|
||||
#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
|
||||
#include "../src/render/opengl/SDL_glfuncs.h"
|
||||
#undef SDL_PROC
|
||||
} GL_Context;
|
||||
|
||||
|
||||
/* Undefine this if you want a flat cube instead of a rainbow cube */
|
||||
#define SHADED_CUBE
|
||||
|
||||
static SDLTest_CommonState *state;
|
||||
static SDL_GLContext context;
|
||||
static GL_Context ctx;
|
||||
|
||||
static int LoadContext(GL_Context * data)
|
||||
{
|
||||
#if SDL_VIDEO_DRIVER_UIKIT
|
||||
#define __SDL_NOGETPROCADDR__
|
||||
#elif SDL_VIDEO_DRIVER_ANDROID
|
||||
#define __SDL_NOGETPROCADDR__
|
||||
#elif SDL_VIDEO_DRIVER_PANDORA
|
||||
#define __SDL_NOGETPROCADDR__
|
||||
#endif
|
||||
|
||||
#if defined __SDL_NOGETPROCADDR__
|
||||
#define SDL_PROC(ret,func,params) data->func=func;
|
||||
#else
|
||||
#define SDL_PROC(ret,func,params) \
|
||||
do { \
|
||||
data->func = SDL_GL_GetProcAddress(#func); \
|
||||
if ( ! data->func ) { \
|
||||
return SDL_SetError("Couldn't load GL function %s: %s\n", #func, SDL_GetError()); \
|
||||
} \
|
||||
} while ( 0 );
|
||||
#endif /* _SDL_NOGETPROCADDR_ */
|
||||
|
||||
#include "../src/render/opengl/SDL_glfuncs.h"
|
||||
#undef SDL_PROC
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
|
||||
static void
|
||||
|
@ -67,107 +104,107 @@ Render()
|
|||
};
|
||||
|
||||
/* Do our drawing, too. */
|
||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
ctx.glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||
ctx.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
ctx.glBegin(GL_QUADS);
|
||||
|
||||
#ifdef SHADED_CUBE
|
||||
glColor3fv(color[0]);
|
||||
glVertex3fv(cube[0]);
|
||||
glColor3fv(color[1]);
|
||||
glVertex3fv(cube[1]);
|
||||
glColor3fv(color[2]);
|
||||
glVertex3fv(cube[2]);
|
||||
glColor3fv(color[3]);
|
||||
glVertex3fv(cube[3]);
|
||||
ctx.glColor3fv(color[0]);
|
||||
ctx.glVertex3fv(cube[0]);
|
||||
ctx.glColor3fv(color[1]);
|
||||
ctx.glVertex3fv(cube[1]);
|
||||
ctx.glColor3fv(color[2]);
|
||||
ctx.glVertex3fv(cube[2]);
|
||||
ctx.glColor3fv(color[3]);
|
||||
ctx.glVertex3fv(cube[3]);
|
||||
|
||||
glColor3fv(color[3]);
|
||||
glVertex3fv(cube[3]);
|
||||
glColor3fv(color[4]);
|
||||
glVertex3fv(cube[4]);
|
||||
glColor3fv(color[7]);
|
||||
glVertex3fv(cube[7]);
|
||||
glColor3fv(color[2]);
|
||||
glVertex3fv(cube[2]);
|
||||
ctx.glColor3fv(color[3]);
|
||||
ctx.glVertex3fv(cube[3]);
|
||||
ctx.glColor3fv(color[4]);
|
||||
ctx.glVertex3fv(cube[4]);
|
||||
ctx.glColor3fv(color[7]);
|
||||
ctx.glVertex3fv(cube[7]);
|
||||
ctx.glColor3fv(color[2]);
|
||||
ctx.glVertex3fv(cube[2]);
|
||||
|
||||
glColor3fv(color[0]);
|
||||
glVertex3fv(cube[0]);
|
||||
glColor3fv(color[5]);
|
||||
glVertex3fv(cube[5]);
|
||||
glColor3fv(color[6]);
|
||||
glVertex3fv(cube[6]);
|
||||
glColor3fv(color[1]);
|
||||
glVertex3fv(cube[1]);
|
||||
ctx.glColor3fv(color[0]);
|
||||
ctx.glVertex3fv(cube[0]);
|
||||
ctx.glColor3fv(color[5]);
|
||||
ctx.glVertex3fv(cube[5]);
|
||||
ctx.glColor3fv(color[6]);
|
||||
ctx.glVertex3fv(cube[6]);
|
||||
ctx.glColor3fv(color[1]);
|
||||
ctx.glVertex3fv(cube[1]);
|
||||
|
||||
glColor3fv(color[5]);
|
||||
glVertex3fv(cube[5]);
|
||||
glColor3fv(color[4]);
|
||||
glVertex3fv(cube[4]);
|
||||
glColor3fv(color[7]);
|
||||
glVertex3fv(cube[7]);
|
||||
glColor3fv(color[6]);
|
||||
glVertex3fv(cube[6]);
|
||||
ctx.glColor3fv(color[5]);
|
||||
ctx.glVertex3fv(cube[5]);
|
||||
ctx.glColor3fv(color[4]);
|
||||
ctx.glVertex3fv(cube[4]);
|
||||
ctx.glColor3fv(color[7]);
|
||||
ctx.glVertex3fv(cube[7]);
|
||||
ctx.glColor3fv(color[6]);
|
||||
ctx.glVertex3fv(cube[6]);
|
||||
|
||||
glColor3fv(color[5]);
|
||||
glVertex3fv(cube[5]);
|
||||
glColor3fv(color[0]);
|
||||
glVertex3fv(cube[0]);
|
||||
glColor3fv(color[3]);
|
||||
glVertex3fv(cube[3]);
|
||||
glColor3fv(color[4]);
|
||||
glVertex3fv(cube[4]);
|
||||
ctx.glColor3fv(color[5]);
|
||||
ctx.glVertex3fv(cube[5]);
|
||||
ctx.glColor3fv(color[0]);
|
||||
ctx.glVertex3fv(cube[0]);
|
||||
ctx.glColor3fv(color[3]);
|
||||
ctx.glVertex3fv(cube[3]);
|
||||
ctx.glColor3fv(color[4]);
|
||||
ctx.glVertex3fv(cube[4]);
|
||||
|
||||
glColor3fv(color[6]);
|
||||
glVertex3fv(cube[6]);
|
||||
glColor3fv(color[1]);
|
||||
glVertex3fv(cube[1]);
|
||||
glColor3fv(color[2]);
|
||||
glVertex3fv(cube[2]);
|
||||
glColor3fv(color[7]);
|
||||
glVertex3fv(cube[7]);
|
||||
ctx.glColor3fv(color[6]);
|
||||
ctx.glVertex3fv(cube[6]);
|
||||
ctx.glColor3fv(color[1]);
|
||||
ctx.glVertex3fv(cube[1]);
|
||||
ctx.glColor3fv(color[2]);
|
||||
ctx.glVertex3fv(cube[2]);
|
||||
ctx.glColor3fv(color[7]);
|
||||
ctx.glVertex3fv(cube[7]);
|
||||
#else /* flat cube */
|
||||
glColor3f(1.0, 0.0, 0.0);
|
||||
glVertex3fv(cube[0]);
|
||||
glVertex3fv(cube[1]);
|
||||
glVertex3fv(cube[2]);
|
||||
glVertex3fv(cube[3]);
|
||||
ctx.glColor3f(1.0, 0.0, 0.0);
|
||||
ctx.glVertex3fv(cube[0]);
|
||||
ctx.glVertex3fv(cube[1]);
|
||||
ctx.glVertex3fv(cube[2]);
|
||||
ctx.glVertex3fv(cube[3]);
|
||||
|
||||
glColor3f(0.0, 1.0, 0.0);
|
||||
glVertex3fv(cube[3]);
|
||||
glVertex3fv(cube[4]);
|
||||
glVertex3fv(cube[7]);
|
||||
glVertex3fv(cube[2]);
|
||||
ctx.glColor3f(0.0, 1.0, 0.0);
|
||||
ctx.glVertex3fv(cube[3]);
|
||||
ctx.glVertex3fv(cube[4]);
|
||||
ctx.glVertex3fv(cube[7]);
|
||||
ctx.glVertex3fv(cube[2]);
|
||||
|
||||
glColor3f(0.0, 0.0, 1.0);
|
||||
glVertex3fv(cube[0]);
|
||||
glVertex3fv(cube[5]);
|
||||
glVertex3fv(cube[6]);
|
||||
glVertex3fv(cube[1]);
|
||||
ctx.glColor3f(0.0, 0.0, 1.0);
|
||||
ctx.glVertex3fv(cube[0]);
|
||||
ctx.glVertex3fv(cube[5]);
|
||||
ctx.glVertex3fv(cube[6]);
|
||||
ctx.glVertex3fv(cube[1]);
|
||||
|
||||
glColor3f(0.0, 1.0, 1.0);
|
||||
glVertex3fv(cube[5]);
|
||||
glVertex3fv(cube[4]);
|
||||
glVertex3fv(cube[7]);
|
||||
glVertex3fv(cube[6]);
|
||||
ctx.glColor3f(0.0, 1.0, 1.0);
|
||||
ctx.glVertex3fv(cube[5]);
|
||||
ctx.glVertex3fv(cube[4]);
|
||||
ctx.glVertex3fv(cube[7]);
|
||||
ctx.glVertex3fv(cube[6]);
|
||||
|
||||
glColor3f(1.0, 1.0, 0.0);
|
||||
glVertex3fv(cube[5]);
|
||||
glVertex3fv(cube[0]);
|
||||
glVertex3fv(cube[3]);
|
||||
glVertex3fv(cube[4]);
|
||||
ctx.glColor3f(1.0, 1.0, 0.0);
|
||||
ctx.glVertex3fv(cube[5]);
|
||||
ctx.glVertex3fv(cube[0]);
|
||||
ctx.glVertex3fv(cube[3]);
|
||||
ctx.glVertex3fv(cube[4]);
|
||||
|
||||
glColor3f(1.0, 0.0, 1.0);
|
||||
glVertex3fv(cube[6]);
|
||||
glVertex3fv(cube[1]);
|
||||
glVertex3fv(cube[2]);
|
||||
glVertex3fv(cube[7]);
|
||||
ctx.glColor3f(1.0, 0.0, 1.0);
|
||||
ctx.glVertex3fv(cube[6]);
|
||||
ctx.glVertex3fv(cube[1]);
|
||||
ctx.glVertex3fv(cube[2]);
|
||||
ctx.glVertex3fv(cube[7]);
|
||||
#endif /* SHADED_CUBE */
|
||||
|
||||
glEnd();
|
||||
ctx.glEnd();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glRotatef(5.0, 1.0, 1.0, 1.0);
|
||||
ctx.glMatrixMode(GL_MODELVIEW);
|
||||
ctx.glRotatef(5.0, 1.0, 1.0, 1.0);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -243,6 +280,13 @@ main(int argc, char *argv[])
|
|||
quit(2);
|
||||
}
|
||||
|
||||
/* Important: call this *after* creating the context */
|
||||
if (LoadContext(&ctx) < 0) {
|
||||
SDL_Log("Could not load GL functions\n");
|
||||
quit(2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (state->render_flags & SDL_RENDERER_PRESENTVSYNC) {
|
||||
/* try late-swap-tearing first. If not supported, try normal vsync. */
|
||||
if (SDL_GL_SetSwapInterval(-1) == -1) {
|
||||
|
@ -260,10 +304,10 @@ main(int argc, char *argv[])
|
|||
SDL_GL_GetDrawableSize(state->windows[0], &dw, &dh);
|
||||
SDL_Log("Draw Size : %d,%d\n", dw, dh);
|
||||
SDL_Log("\n");
|
||||
SDL_Log("Vendor : %s\n", glGetString(GL_VENDOR));
|
||||
SDL_Log("Renderer : %s\n", glGetString(GL_RENDERER));
|
||||
SDL_Log("Version : %s\n", glGetString(GL_VERSION));
|
||||
SDL_Log("Extensions : %s\n", glGetString(GL_EXTENSIONS));
|
||||
SDL_Log("Vendor : %s\n", ctx.glGetString(GL_VENDOR));
|
||||
SDL_Log("Renderer : %s\n", ctx.glGetString(GL_RENDERER));
|
||||
SDL_Log("Version : %s\n", ctx.glGetString(GL_VERSION));
|
||||
SDL_Log("Extensions : %s\n", ctx.glGetString(GL_EXTENSIONS));
|
||||
SDL_Log("\n");
|
||||
|
||||
status = SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value);
|
||||
|
@ -319,14 +363,14 @@ main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
/* Set rendering settings */
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(-2.0, 2.0, -2.0, 2.0, -20.0, 20.0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LESS);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
ctx.glMatrixMode(GL_PROJECTION);
|
||||
ctx.glLoadIdentity();
|
||||
ctx.glOrtho(-2.0, 2.0, -2.0, 2.0, -20.0, 20.0);
|
||||
ctx.glMatrixMode(GL_MODELVIEW);
|
||||
ctx.glLoadIdentity();
|
||||
ctx.glEnable(GL_DEPTH_TEST);
|
||||
ctx.glDepthFunc(GL_LESS);
|
||||
ctx.glShadeModel(GL_SMOOTH);
|
||||
|
||||
/* Main render loop */
|
||||
frames = 0;
|
||||
|
@ -344,7 +388,7 @@ main(int argc, char *argv[])
|
|||
continue;
|
||||
SDL_GL_MakeCurrent(state->windows[i], context);
|
||||
SDL_GL_GetDrawableSize(state->windows[i], &w, &h);
|
||||
glViewport(0, 0, w, h);
|
||||
ctx.glViewport(0, 0, w, h);
|
||||
Render();
|
||||
SDL_GL_SwapWindow(state->windows[i]);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue