Added Mir video target (thanks, Brandon!).

This commit is contained in:
Ryan C. Gordon 2014-02-02 23:41:46 -05:00
parent dce9b7b129
commit 19f8c6224f
21 changed files with 1648 additions and 0 deletions

View File

@ -231,6 +231,7 @@ set_option(SNDIO "Support the sndio audio API" ${UNIX_SYS})
set_option(RPATH "Use an rpath when linking SDL" ${UNIX_SYS}) set_option(RPATH "Use an rpath when linking SDL" ${UNIX_SYS})
set_option(CLOCK_GETTIME "Use clock_gettime() instead of gettimeofday()" OFF) 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(INPUT_TSLIB "Use the Touchscreen library for input" ${UNIX_SYS})
set_option(VIDEO_MIR "Use Mir video driver" ${UNIX_SYS})
set_option(VIDEO_X11 "Use X11 video driver" ${UNIX_SYS}) set_option(VIDEO_X11 "Use X11 video driver" ${UNIX_SYS})
set_option(VIDEO_WAYLAND "Use Wayland 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) dep_option(X11_SHARED "Dynamically load X11 support" ON "VIDEO_X11" OFF)
@ -654,6 +655,7 @@ if(UNIX AND NOT APPLE)
if(SDL_VIDEO) if(SDL_VIDEO)
CheckX11() CheckX11()
CheckMir()
CheckDirectFB() CheckDirectFB()
CheckOpenGLX11() CheckOpenGLX11()
CheckOpenGLESX11() CheckOpenGLESX11()

View File

@ -505,6 +505,27 @@ macro(CheckX11)
endif(VIDEO_X11) endif(VIDEO_X11)
endmacro(CheckX11) endmacro(CheckX11)
macro(CheckMir)
if(VIDEO_MIR)
find_library(MIR_LIB mirclient mircommon egl)
pkg_check_modules(MIR_TOOLKIT mirclient mircommon)
pkg_check_modules(EGL egl)
pkg_check_modules(XKB xkbcommon)
if (MIR_LIB AND MIR_TOOLKIT_FOUND AND EGL_FOUND AND XKB_FOUND)
set(HAVE_VIDEO_MIR TRUE)
set(HAVE_SDL_VIDEO TRUE)
file(GLOB MIR_SOURCES ${SDL2_SOURCE_DIR}/src/video/mir/*.c)
set(SOURCE_FILES ${SOURCE_FILES} ${MIR_SOURCES})
set(SDL_VIDEO_DRIVER_MIR 1)
list(APPEND EXTRA_CFLAGS ${MIR_TOOLKIT_CFLAGS} ${EGL_CLFAGS} ${XKB_CLFLAGS})
list(APPEND EXTRA_LDFLAGS ${MIR_TOOLKIT_LDFLAGS} ${EGL_LDLAGS} ${XKB_LDLAGS})
endif (MIR_LIB AND MIR_TOOLKIT_FOUND AND EGL_FOUND AND XKB_FOUND)
endif(VIDEO_MIR)
endmacro(CheckMir)
# Requires: # Requires:
# - EGL # - EGL
macro(CheckWayland) macro(CheckWayland)

100
configure vendored
View File

@ -817,6 +817,7 @@ enable_sndio
enable_sndio_shared enable_sndio_shared
enable_diskaudio enable_diskaudio
enable_dummyaudio enable_dummyaudio
enable_video_mir
enable_video_wayland enable_video_wayland
enable_video_wayland_qt_touch enable_video_wayland_qt_touch
enable_wayland_shared enable_wayland_shared
@ -1534,6 +1535,7 @@ Optional Features:
--enable-sndio-shared dynamically load sndio audio support [[default=yes]] --enable-sndio-shared dynamically load sndio audio support [[default=yes]]
--enable-diskaudio support the disk writer audio driver [[default=yes]] --enable-diskaudio support the disk writer audio driver [[default=yes]]
--enable-dummyaudio support the dummy audio driver [[default=yes]] --enable-dummyaudio support the dummy audio driver [[default=yes]]
--enable-video-mir use Mir video driver [[default=yes]]
--enable-video-wayland use Wayland video driver [[default=yes]] --enable-video-wayland use Wayland video driver [[default=yes]]
--enable-video-wayland-qt-touch --enable-video-wayland-qt-touch
QtWayland server support for Wayland video driver QtWayland server support for Wayland video driver
@ -18627,6 +18629,103 @@ $as_echo "$have_gcc_preferred_stack_boundary" >&6; }
fi fi
} }
CheckMir()
{
# Check whether --enable-video-mir was given.
if test "${enable_video_mir+set}" = set; then :
enableval=$enable_video_mir;
else
enable_video_mir=yes
fi
if test x$enable_video = xyes -a x$enable_video_mir = 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
if test x$PKG_CONFIG != xno; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Mir support" >&5
$as_echo_n "checking for Mir support... " >&6; }
video_mir=no
tmp_CFLAGS="$CFLAGS"
CFLAGS="$EXTRA_CFLAGS `$PKG_CONFIG --cflags egl mirclient xkbcommon`"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <EGL/egl.h>
#include <xkbcommon/xkbcommon.h>
#include <mir_toolkit/mir_client_library.h>
int
main ()
{
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
video_mir=yes
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
CFLAGS="$tmp_CFLAGS"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $video_mir" >&5
$as_echo "$video_mir" >&6; }
if test x$video_mir = xyes; then
$as_echo "#define SDL_VIDEO_DRIVER_MIR 1" >>confdefs.h
SOURCES="$SOURCES $srcdir/src/video/mir/*.c"
EXTRA_CFLAGS="$EXTRA_CFLAGS `$PKG_CONFIG --cflags egl mirclient xkbcommon`"
EXTRA_LDFLAGS="$EXTRA_LDFLAGS `$PKG_CONFIG --libs egl mirclient xkbcommon`"
have_video=yes
fi
fi
fi
}
CheckWarnAll() CheckWarnAll()
{ {
@ -22451,6 +22550,7 @@ case "$host" in
CheckSNDIO CheckSNDIO
CheckX11 CheckX11
CheckWayland CheckWayland
CheckMir
CheckDirectFB CheckDirectFB
CheckFusionSound CheckFusionSound
CheckOpenGLX11 CheckOpenGLX11

View File

@ -1124,6 +1124,42 @@ CheckStackBoundary()
fi fi
} }
CheckMir()
{
AC_ARG_ENABLE(video-mir,
AC_HELP_STRING([--enable-video-mir], [use Mir video driver [[default=yes]]]),
, enable_video_mir=yes)
if test x$enable_video = xyes -a x$enable_video_mir = xyes; then
AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
if test x$PKG_CONFIG != xno; then
AC_MSG_CHECKING(for Mir support)
video_mir=no
tmp_CFLAGS="$CFLAGS"
CFLAGS="$EXTRA_CFLAGS `$PKG_CONFIG --cflags egl mirclient xkbcommon`"
AC_TRY_COMPILE([
#include <EGL/egl.h>
#include <xkbcommon/xkbcommon.h>
#include <mir_toolkit/mir_client_library.h>
],[
],[
video_mir=yes
])
CFLAGS="$tmp_CFLAGS"
AC_MSG_RESULT($video_mir)
if test x$video_mir = xyes; then
AC_DEFINE(SDL_VIDEO_DRIVER_MIR)
SOURCES="$SOURCES $srcdir/src/video/mir/*.c"
EXTRA_CFLAGS="$EXTRA_CFLAGS `$PKG_CONFIG --cflags egl mirclient xkbcommon`"
EXTRA_LDFLAGS="$EXTRA_LDFLAGS `$PKG_CONFIG --libs egl mirclient xkbcommon`"
have_video=yes
fi
fi
fi
}
dnl See if GCC's -Wall is supported. dnl See if GCC's -Wall is supported.
CheckWarnAll() CheckWarnAll()
@ -2612,6 +2648,7 @@ case "$host" in
CheckSNDIO CheckSNDIO
CheckX11 CheckX11
CheckWayland CheckWayland
CheckMir
CheckDirectFB CheckDirectFB
CheckFusionSound CheckFusionSound
CheckOpenGLX11 CheckOpenGLX11

View File

@ -259,6 +259,7 @@
#cmakedefine SDL_VIDEO_DRIVER_DUMMY @SDL_VIDEO_DRIVER_DUMMY@ #cmakedefine SDL_VIDEO_DRIVER_DUMMY @SDL_VIDEO_DRIVER_DUMMY@
#cmakedefine SDL_VIDEO_DRIVER_WINDOWS @SDL_VIDEO_DRIVER_WINDOWS@ #cmakedefine SDL_VIDEO_DRIVER_WINDOWS @SDL_VIDEO_DRIVER_WINDOWS@
#cmakedefine SDL_VIDEO_DRIVER_WAYLAND @SDL_VIDEO_DRIVER_WAYLAND@ #cmakedefine SDL_VIDEO_DRIVER_WAYLAND @SDL_VIDEO_DRIVER_WAYLAND@
#cmakedefine SDL_VIDEO_DRIVER_MIR @SDL_VIDEO_DRIVER_MIR@
#cmakedefine SDL_VIDEO_DRIVER_X11 @SDL_VIDEO_DRIVER_X11@ #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 @SDL_VIDEO_DRIVER_X11_DYNAMIC@
#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT @SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT@ #cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT @SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT@

View File

@ -267,6 +267,7 @@
#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL #undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL
#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR #undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR
#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON #undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON
#undef SDL_VIDEO_DRIVER_MIR
#undef SDL_VIDEO_DRIVER_X11 #undef SDL_VIDEO_DRIVER_X11
#undef SDL_VIDEO_DRIVER_RPI #undef SDL_VIDEO_DRIVER_RPI
#undef SDL_VIDEO_DRIVER_X11_DYNAMIC #undef SDL_VIDEO_DRIVER_X11_DYNAMIC

View File

@ -105,6 +105,7 @@ typedef enum
SDL_SYSWM_COCOA, SDL_SYSWM_COCOA,
SDL_SYSWM_UIKIT, SDL_SYSWM_UIKIT,
SDL_SYSWM_WAYLAND, SDL_SYSWM_WAYLAND,
SDL_SYSWM_MIR,
} SDL_SYSWM_TYPE; } SDL_SYSWM_TYPE;
/** /**

View File

@ -345,6 +345,9 @@ extern VideoBootStrap COCOA_bootstrap;
#if SDL_VIDEO_DRIVER_X11 #if SDL_VIDEO_DRIVER_X11
extern VideoBootStrap X11_bootstrap; extern VideoBootStrap X11_bootstrap;
#endif #endif
#if SDL_VIDEO_DRIVER_MIR
extern VideoBootStrap MIR_bootstrap;
#endif
#if SDL_VIDEO_DRIVER_DIRECTFB #if SDL_VIDEO_DRIVER_DIRECTFB
extern VideoBootStrap DirectFB_bootstrap; extern VideoBootStrap DirectFB_bootstrap;
#endif #endif

View File

@ -59,6 +59,9 @@ static VideoBootStrap *bootstrap[] = {
#if SDL_VIDEO_DRIVER_X11 #if SDL_VIDEO_DRIVER_X11
&X11_bootstrap, &X11_bootstrap,
#endif #endif
#if SDL_VIDEO_DRIVER_MIR
&MIR_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_DIRECTFB #if SDL_VIDEO_DRIVER_DIRECTFB
&DirectFB_bootstrap, &DirectFB_bootstrap,
#endif #endif

View File

@ -0,0 +1,246 @@
/*
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.
*/
/*
Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
*/
#include "SDL_config.h"
#include "../../events/SDL_events_c.h"
#include "../../events/SDL_keyboard_c.h"
#include "../../events/SDL_touch_c.h"
#include "../../events/scancodes_xfree86.h"
#include "SDL_mirevents.h"
#include "SDL_mirwindow.h"
#include <xkbcommon/xkbcommon.h>
static void
HandleKeyText(int32_t key_code)
{
char text[8];
int size = 0;
size = xkb_keysym_to_utf8(key_code, text, sizeof text);
if (size > 0) {
text[size] = '\0';
SDL_SendKeyboardText(text);
}
}
static void
CheckKeyboardFocus(SDL_Window* sdl_window)
{
SDL_Window* keyboard_window = SDL_GetKeyboardFocus();
if (keyboard_window != sdl_window)
SDL_SetKeyboardFocus(sdl_window);
}
/* FIXME
Mir still needs to implement its IM API, for now we assume
a single key press produces a character.
*/
static void
HandleKeyEvent(MirKeyEvent const ev, SDL_Window* window)
{
uint32_t scancode = SDL_SCANCODE_UNKNOWN;
Uint8 key_state = ev.action == mir_key_action_up ? SDL_RELEASED : SDL_PRESSED;
CheckKeyboardFocus(window);
if (ev.scan_code < SDL_arraysize(xfree86_scancode_table2))
scancode = xfree86_scancode_table2[ev.scan_code];
if (scancode != SDL_SCANCODE_UNKNOWN)
SDL_SendKeyboardKey(key_state, scancode);
if (key_state == SDL_PRESSED)
HandleKeyText(ev.key_code);
}
static void
HandleMouseButton(SDL_Window* sdl_window, Uint8 state, MirMotionButton button_state)
{
static uint32_t last_sdl_button;
uint32_t sdl_button;
switch (button_state) {
case mir_motion_button_primary:
sdl_button = SDL_BUTTON_LEFT;
break;
case mir_motion_button_secondary:
sdl_button = SDL_BUTTON_RIGHT;
break;
case mir_motion_button_tertiary:
sdl_button = SDL_BUTTON_MIDDLE;
break;
case mir_motion_button_forward:
sdl_button = SDL_BUTTON_X1;
break;
case mir_motion_button_back:
sdl_button = SDL_BUTTON_X2;
break;
default:
sdl_button = last_sdl_button;
break;
}
last_sdl_button = sdl_button;
SDL_SendMouseButton(sdl_window, 0, state, sdl_button);
}
static void
HandleTouchPress(int device_id, int source_id, SDL_bool down, float x, float y, float pressure)
{
SDL_SendTouch(device_id, source_id, down, x, y, pressure);
}
static void
HandleTouchMotion(int device_id, int source_id, float x, float y, float pressure)
{
SDL_SendTouchMotion(device_id, source_id, x, y, pressure);
}
static void
HandleMouseMotion(SDL_Window* sdl_window, int x, int y)
{
SDL_SendMouseMotion(sdl_window, 0, 0, x, y);
}
static void
HandleMouseScroll(SDL_Window* sdl_window, int hscroll, int vscroll)
{
SDL_SendMouseWheel(sdl_window, 0, hscroll, vscroll);
}
static void
AddTouchDevice(int device_id)
{
if (SDL_AddTouch(device_id, "") < 0)
SDL_SetError("Error: can't add touch %s, %d", __FILE__, __LINE__);
}
static void
HandleTouchEvent(MirMotionEvent const motion, int cord_index, SDL_Window* sdl_window)
{
int device_id = motion.device_id;
int id = motion.pointer_coordinates[cord_index].id;
int width = sdl_window->w;
int height = sdl_window->h;
float x = motion.pointer_coordinates[cord_index].x;
float y = motion.pointer_coordinates[cord_index].y;
float n_x = x / width;
float n_y = y / height;
float pressure = motion.pointer_coordinates[cord_index].pressure;
AddTouchDevice(motion.device_id);
switch (motion.action) {
case mir_motion_action_down:
case mir_motion_action_pointer_down:
HandleTouchPress(device_id, id, SDL_TRUE, n_x, n_y, pressure);
break;
case mir_motion_action_up:
case mir_motion_action_pointer_up:
HandleTouchPress(device_id, id, SDL_FALSE, n_x, n_y, pressure);
break;
case mir_motion_action_hover_move:
case mir_motion_action_move:
HandleTouchMotion(device_id, id, n_x, n_y, pressure);
break;
default:
break;
}
}
static void
HandleMouseEvent(MirMotionEvent const motion, int cord_index, SDL_Window* sdl_window)
{
SDL_SetMouseFocus(sdl_window);
switch (motion.action) {
case mir_motion_action_down:
case mir_motion_action_pointer_down:
HandleMouseButton(sdl_window, SDL_PRESSED, motion.button_state);
break;
case mir_motion_action_up:
case mir_motion_action_pointer_up:
HandleMouseButton(sdl_window, SDL_RELEASED, motion.button_state);
break;
case mir_motion_action_hover_move:
case mir_motion_action_move:
HandleMouseMotion(sdl_window,
motion.pointer_coordinates[cord_index].x,
motion.pointer_coordinates[cord_index].y);
break;
case mir_motion_action_outside:
SDL_SetMouseFocus(NULL);
break;
case mir_motion_action_scroll:
HandleMouseScroll(sdl_window,
motion.pointer_coordinates[cord_index].hscroll,
motion.pointer_coordinates[cord_index].vscroll);
break;
case mir_motion_action_cancel:
case mir_motion_action_hover_enter:
case mir_motion_action_hover_exit:
break;
default:
break;
}
}
static void
HandleMotionEvent(MirMotionEvent const motion, SDL_Window* sdl_window)
{
int cord_index;
for (cord_index = 0; cord_index < motion.pointer_count; cord_index++) {
if (motion.pointer_coordinates[cord_index].tool_type == mir_motion_tool_type_mouse) {
HandleMouseEvent(motion, cord_index, sdl_window);
}
else if (motion.pointer_coordinates[cord_index].tool_type == mir_motion_tool_type_finger) {
HandleTouchEvent(motion, cord_index, sdl_window);
}
}
}
void
MIR_HandleInput(MirSurface* surface, MirEvent const* ev, void* context)
{
SDL_Window* window = (SDL_Window*)context;
switch (ev->type) {
case (mir_event_type_key):
HandleKeyEvent(ev->key, window);
break;
case (mir_event_type_motion):
HandleMotionEvent(ev->motion, window);
break;
default:
break;
}
}

View File

@ -0,0 +1,36 @@
/*
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.
*/
/*
Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
*/
#include "SDL_config.h"
#ifndef _SDL_mirevents_h
#define _SDL_mirevents_h
#include <mir_toolkit/mir_client_library.h>
extern void
MIR_HandleInput(MirSurface* surface, MirEvent const* ev, void* context);
#endif /* _SDL_mirevents_h */

View File

@ -0,0 +1,146 @@
/*
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.
*/
/*
Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
*/
#include "SDL_config.h"
#include "SDL_mirevents.h"
#include "SDL_mirframebuffer.h"
#include "SDL_mirwindow.h"
static const Uint32 mir_pixel_format_to_sdl_format[] = {
SDL_PIXELFORMAT_UNKNOWN, /* mir_pixel_format_invalid */
SDL_PIXELFORMAT_ABGR8888, /* mir_pixel_format_abgr_8888 */
SDL_PIXELFORMAT_BGR888, /* mir_pixel_format_xbgr_8888 */
SDL_PIXELFORMAT_ARGB8888, /* mir_pixel_format_argb_8888 */
SDL_PIXELFORMAT_RGB888, /* mir_pixel_format_xrgb_8888 */
SDL_PIXELFORMAT_BGR24 /* mir_pixel_format_bgr_888 */
};
Uint32
MIR_GetSDLPixelFormat(MirPixelFormat format)
{
return mir_pixel_format_to_sdl_format[format];
}
int
MIR_CreateWindowFramebuffer(_THIS, SDL_Window* window, Uint32* format,
void** pixels, int* pitch)
{
MIR_Data* mir_data = _this->driverdata;
MIR_Window* mir_window;
MirSurfaceParameters surfaceparm;
if (MIR_CreateWindow(_this, window) < 0)
return SDL_SetError("Failed to created a mir window.");
mir_window = window->driverdata;
mir_surface_get_parameters(mir_window->surface, &surfaceparm);
*format = MIR_GetSDLPixelFormat(surfaceparm.pixel_format);
if (*format == SDL_PIXELFORMAT_UNKNOWN)
return SDL_SetError("Unknown pixel format");
*pitch = (((window->w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3);
*pixels = SDL_malloc(window->h*(*pitch));
if (*pixels == NULL)
return SDL_OutOfMemory();
mir_window->surface = mir_connection_create_surface_sync(mir_data->connection, &surfaceparm);
if (!mir_surface_is_valid(mir_window->surface)) {
const char* error = mir_surface_get_error_message(mir_window->surface);
return SDL_SetError("Failed to created a mir surface: %s", error);
}
return 0;
}
int
MIR_UpdateWindowFramebuffer(_THIS, SDL_Window* window,
const SDL_Rect* rects, int numrects)
{
MIR_Window* mir_window = window->driverdata;
MirGraphicsRegion region;
int i, j, x, y, w, h, start;
int bytes_per_pixel, bytes_per_row, s_stride, d_stride;
mir_surface_get_graphics_region(mir_window->surface, &region);
char* s_dest = region.vaddr;
char* pixels = (char*)window->surface->pixels;
s_stride = window->surface->pitch;
d_stride = region.stride;
bytes_per_pixel = window->surface->format->BytesPerPixel;
for (i = 0; i < numrects; i++) {
s_dest = region.vaddr;
pixels = (char*)window->surface->pixels;
x = rects[i].x;
y = rects[i].y;
w = rects[i].w;
h = rects[i].h;
if (w <= 0 || h <= 0 || (x + w) <= 0 || (y + h) <= 0)
continue;
if (x < 0) {
x += w;
w += rects[i].x;
}
if (y < 0) {
y += h;
h += rects[i].y;
}
if (x + w > window->w)
w = window->w - x;
if (y + h > window->h)
h = window->h - y;
start = y * s_stride + x;
pixels += start;
s_dest += start;
bytes_per_row = bytes_per_pixel * w;
for (j = 0; j < h; j++) {
memcpy(s_dest, pixels, bytes_per_row);
pixels += s_stride;
s_dest += d_stride;
}
}
mir_surface_swap_buffers_sync(mir_window->surface);
return 0;
}
void
MIR_DestroyWindowFramebuffer(_THIS, SDL_Window* window)
{
}

View File

@ -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.
*/
/*
Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
*/
#include "SDL_config.h"
#ifndef _SDL_mirframebuffer_h
#define _SDL_mirframebuffer_h
#include "../SDL_sysvideo.h"
#include "SDL_mirvideo.h"
extern int
MIR_CreateWindowFramebuffer(_THIS, SDL_Window* sdl_window, Uint32* format,
void** pixels, int* pitch);
extern int
MIR_UpdateWindowFramebuffer(_THIS, SDL_Window* sdl_window,
const SDL_Rect* rects, int numrects);
extern void
MIR_DestroyWindowFramebuffer(_THIS, SDL_Window* sdl_window);
#endif /* _SDL_mirframebuffer_h */

View File

@ -0,0 +1,145 @@
/*
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.
*/
/*
Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
*/
#include "SDL_config.h"
#include "SDL_mirmouse.h"
#include "../../events/SDL_mouse_c.h"
#include "SDL_assert.h"
static SDL_Cursor*
MIR_CreateDefaultCursor()
{
SDL_Cursor* cursor;
cursor = SDL_calloc(1, sizeof(SDL_Cursor));
if (cursor) {
}
else {
SDL_OutOfMemory();
}
return cursor;
}
static SDL_Cursor*
MIR_CreateCursor(SDL_Surface* sruface, int hot_x, int hot_y)
{
return MIR_CreateDefaultCursor();
}
static SDL_Cursor*
MIR_CreateSystemCursor(SDL_SystemCursor id)
{
switch(id) {
case SDL_SYSTEM_CURSOR_ARROW:
break;
case SDL_SYSTEM_CURSOR_IBEAM:
break;
case SDL_SYSTEM_CURSOR_WAIT:
break;
case SDL_SYSTEM_CURSOR_CROSSHAIR:
break;
case SDL_SYSTEM_CURSOR_WAITARROW:
break;
case SDL_SYSTEM_CURSOR_SIZENWSE:
break;
case SDL_SYSTEM_CURSOR_SIZENESW:
break;
case SDL_SYSTEM_CURSOR_SIZEWE:
break;
case SDL_SYSTEM_CURSOR_SIZENS:
break;
case SDL_SYSTEM_CURSOR_SIZEALL:
break;
case SDL_SYSTEM_CURSOR_NO:
break;
case SDL_SYSTEM_CURSOR_HAND:
break;
default:
SDL_assert(0);
return NULL;
}
return MIR_CreateDefaultCursor();
}
static void
MIR_FreeCursor(SDL_Cursor* cursor)
{
if (cursor)
SDL_free(cursor);
}
static int
MIR_ShowCursor(SDL_Cursor* cursor)
{
return 0;
}
static void
MIR_WarpMouse(SDL_Window* window, int x, int y)
{
SDL_Unsupported();
}
static int
MIR_SetRelativeMouseMode(SDL_bool enabled)
{
return SDL_Unsupported();
}
/* TODO Actually implement the cursor, need to wait for mir support */
void
MIR_InitMouse()
{
SDL_Mouse* mouse = SDL_GetMouse();
mouse->CreateCursor = MIR_CreateCursor;
mouse->ShowCursor = MIR_ShowCursor;
mouse->FreeCursor = MIR_FreeCursor;
mouse->WarpMouse = MIR_WarpMouse;
mouse->CreateSystemCursor = MIR_CreateSystemCursor;
mouse->SetRelativeMouseMode = MIR_SetRelativeMouseMode;
SDL_SetDefaultCursor(MIR_CreateDefaultCursor());
}
void
MIR_FiniMouse()
{
SDL_Mouse* mouse = SDL_GetMouse();
MIR_FreeCursor(mouse->def_cursor);
mouse->def_cursor = NULL;
mouse->CreateCursor = NULL;
mouse->ShowCursor = NULL;
mouse->FreeCursor = NULL;
mouse->WarpMouse = NULL;
mouse->CreateSystemCursor = NULL;
mouse->SetRelativeMouseMode = NULL;
}

View File

@ -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.
*/
/*
Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
*/
#include "SDL_config.h"
#ifndef _SDL_mirmouse_h
#define _SDL_mirmouse_h
extern void
MIR_InitMouse();
extern void
MIR_FiniMouse();
#endif /* _SDL_mirmouse_h */

View File

@ -0,0 +1,122 @@
/*
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.
*/
/*
Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
*/
#include "SDL_config.h"
#include "SDL_miropengl.h"
#include <dlfcn.h>
#define DEFAULT_OGL_ES2 "libGLESv2.so"
void* MIR_GLHandle = NULL;
void
MIR_GL_SwapWindow(_THIS, SDL_Window* window)
{
MIR_Window* mir_wind = window->driverdata;
SDL_EGL_SwapBuffers(_this, mir_wind->egl_surface);
}
int
MIR_GL_MakeCurrent(_THIS, SDL_Window* window, SDL_GLContext context)
{
if (window) {
EGLSurface egl_surface = ((MIR_Window*)window->driverdata)->egl_surface;
return SDL_EGL_MakeCurrent(_this, egl_surface, context);
}
return SDL_EGL_MakeCurrent(_this, NULL, NULL);
}
SDL_GLContext
MIR_GL_CreateContext(_THIS, SDL_Window* window)
{
MIR_Window* mir_window = window->driverdata;
SDL_GLContext context;
context = SDL_EGL_CreateContext(_this, mir_window->egl_surface);
return context;
}
int
MIR_GL_LoadLibrary(_THIS, const char* path)
{
MIR_Data* mir_data = _this->driverdata;
SDL_EGL_LoadLibrary(_this, path,
mir_connection_get_egl_native_display(mir_data->connection));
SDL_EGL_ChooseConfig(_this);
return 0;
}
void
MIR_GL_UnloadLibrary(_THIS)
{
SDL_EGL_UnloadLibrary(_this);
if (MIR_GLHandle) {
dlclose(MIR_GLHandle);
MIR_GLHandle = NULL;
}
}
void
Ensure_GL_HandleOpen()
{
if (!MIR_GLHandle) {
MIR_GLHandle = dlopen(DEFAULT_OGL_ES2, RTLD_GLOBAL);
if (!MIR_GLHandle) {
SDL_SetError("Failed to dlopen library.");
}
}
}
void*
MIR_GL_GetProcAddress(_THIS, const char* proc)
{
void* proc_addr = eglGetProcAddress(proc);
/* FIXME when on the phone/tablet eglGetProcAddress returns NULL through libhybris,
seems to be a problem in android. Also looks like a problem in the android video driver:
src/video/android/SDL_androidgl.c
Workaround, to just get the address ourself
*/
if (!proc_addr) {
Ensure_GL_HandleOpen();
proc_addr = dlsym(MIR_GLHandle, proc);
}
if (!proc_addr) {
SDL_SetError("Failed to find proc address!");
}
return proc_addr;
}

View File

@ -0,0 +1,57 @@
/*
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.
*/
/*
Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
*/
#include "SDL_config.h"
#ifndef _SDL_miropengl_h
#define _SDL_miropengl_h
#include "SDL_mirwindow.h"
#include "../SDL_egl_c.h"
#define MIR_GL_DeleteContext SDL_EGL_DeleteContext
#define MIR_GL_GetSwapInterval SDL_EGL_GetSwapInterval
#define MIR_GL_SetSwapInterval SDL_EGL_SetSwapInterval
extern void
MIR_GL_SwapWindow(_THIS, SDL_Window* window);
extern int
MIR_GL_MakeCurrent(_THIS, SDL_Window* window, SDL_GLContext context);
extern SDL_GLContext
MIR_GL_CreateContext(_THIS, SDL_Window* window);
extern int
MIR_GL_LoadLibrary(_THIS, const char* path);
extern void
MIR_GL_UnloadLibrary(_THIS);
extern void*
MIR_GL_GetProcAddress(_THIS, const char* proc);
#endif /* _SDL_miropengl_h */

View File

@ -0,0 +1,319 @@
/*
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.
*/
/*
Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
*/
#include "SDL_config.h"
#include "SDL_video.h"
#include "SDL_mirframebuffer.h"
#include "SDL_mirmouse.h"
#include "SDL_miropengl.h"
#include "SDL_mirvideo.h"
#include "SDL_mirwindow.h"
#define MIR_DRIVER_NAME "mir"
static int
MIR_VideoInit(_THIS);
static void
MIR_VideoQuit(_THIS);
static int
MIR_GetDisplayBounds(_THIS, SDL_VideoDisplay* display, SDL_Rect* rect);
static void
MIR_GetDisplayModes(_THIS, SDL_VideoDisplay* sdl_display);
static int
MIR_SetDisplayMode(_THIS, SDL_VideoDisplay* sdl_display, SDL_DisplayMode* mode);
static SDL_WindowShaper*
MIR_CreateShaper(SDL_Window* window)
{
/* FIXME Im not sure if mir support this atm, will have to come back to this */
return NULL;
}
static int
MIR_SetWindowShape(SDL_WindowShaper* shaper, SDL_Surface* shape, SDL_WindowShapeMode* shape_mode)
{
return SDL_Unsupported();
}
static int
MIR_ResizeWindowShape(SDL_Window* window)
{
return SDL_Unsupported();
}
static int
MIR_Available()
{
return 1;
}
static void
MIR_DeleteDevice(SDL_VideoDevice* device)
{
SDL_free(device);
}
void
MIR_PumpEvents(_THIS)
{
}
static SDL_VideoDevice*
MIR_CreateDevice(int device_index)
{
MIR_Data* mir_data;
SDL_VideoDevice* device = SDL_calloc(1, sizeof(SDL_VideoDevice));
if (!device) {
SDL_OutOfMemory();
return NULL;
}
mir_data = SDL_calloc(1, sizeof(MIR_Data));
if (!mir_data) {
SDL_OutOfMemory();
SDL_free(device);
return NULL;
}
device->driverdata = mir_data;
/* mirvideo */
device->VideoInit = MIR_VideoInit;
device->VideoQuit = MIR_VideoQuit;
device->GetDisplayBounds = MIR_GetDisplayBounds;
device->GetDisplayModes = MIR_GetDisplayModes;
device->SetDisplayMode = MIR_SetDisplayMode;
device->free = MIR_DeleteDevice;
/* miropengles */
device->GL_SwapWindow = MIR_GL_SwapWindow;
device->GL_MakeCurrent = MIR_GL_MakeCurrent;
device->GL_CreateContext = MIR_GL_CreateContext;
device->GL_DeleteContext = MIR_GL_DeleteContext;
device->GL_LoadLibrary = MIR_GL_LoadLibrary;
device->GL_UnloadLibrary = MIR_GL_UnloadLibrary;
device->GL_GetSwapInterval = MIR_GL_GetSwapInterval;
device->GL_SetSwapInterval = MIR_GL_SetSwapInterval;
device->GL_GetProcAddress = MIR_GL_GetProcAddress;
/* mirwindow */
device->CreateWindow = MIR_CreateWindow;
device->DestroyWindow = MIR_DestroyWindow;
device->GetWindowWMInfo = MIR_GetWindowWMInfo;
device->SetWindowFullscreen = MIR_SetWindowFullscreen;
device->MaximizeWindow = MIR_MaximizeWindow;
device->MinimizeWindow = MIR_MinimizeWindow;
device->RestoreWindow = MIR_RestoreWindow;
device->CreateWindowFrom = NULL;
device->SetWindowTitle = NULL;
device->SetWindowIcon = NULL;
device->SetWindowPosition = NULL;
device->SetWindowSize = NULL;
device->SetWindowMinimumSize = NULL;
device->SetWindowMaximumSize = NULL;
device->ShowWindow = NULL;
device->HideWindow = NULL;
device->RaiseWindow = NULL;
device->SetWindowBordered = NULL;
device->SetWindowGammaRamp = NULL;
device->GetWindowGammaRamp = NULL;
device->SetWindowGrab = NULL;
device->OnWindowEnter = NULL;
/* mirframebuffer */
device->CreateWindowFramebuffer = MIR_CreateWindowFramebuffer;
device->UpdateWindowFramebuffer = MIR_UpdateWindowFramebuffer;
device->DestroyWindowFramebuffer = MIR_DestroyWindowFramebuffer;
device->shape_driver.CreateShaper = MIR_CreateShaper;
device->shape_driver.SetWindowShape = MIR_SetWindowShape;
device->shape_driver.ResizeWindowShape = MIR_ResizeWindowShape;
device->PumpEvents = MIR_PumpEvents;
device->SuspendScreenSaver = NULL;
device->StartTextInput = NULL;
device->StopTextInput = NULL;
device->SetTextInputRect = NULL;
device->HasScreenKeyboardSupport = NULL;
device->ShowScreenKeyboard = NULL;
device->HideScreenKeyboard = NULL;
device->IsScreenKeyboardShown = NULL;
device->SetClipboardText = NULL;
device->GetClipboardText = NULL;
device->HasClipboardText = NULL;
device->ShowMessageBox = NULL;
return device;
}
VideoBootStrap MIR_bootstrap = {
MIR_DRIVER_NAME, "SDL Mir video driver",
MIR_Available, MIR_CreateDevice
};
static void
MIR_SetCurrentDisplayMode(MirDisplayOutput const* out, SDL_VideoDisplay* display)
{
SDL_DisplayMode mode = {
.format = SDL_PIXELFORMAT_RGB888,
.w = out->modes[out->current_mode].horizontal_resolution,
.h = out->modes[out->current_mode].vertical_resolution,
.refresh_rate = out->modes[out->current_mode].refresh_rate,
.driverdata = NULL
};
display->desktop_mode = mode;
display->current_mode = mode;
}
static void
MIR_AddAllModesFromDisplay(MirDisplayOutput const* out, SDL_VideoDisplay* display)
{
int n_mode;
for (n_mode = 0; n_mode < out->num_modes; ++n_mode) {
SDL_DisplayMode mode = {
.format = SDL_PIXELFORMAT_RGB888,
.w = out->modes[n_mode].horizontal_resolution,
.h = out->modes[n_mode].vertical_resolution,
.refresh_rate = out->modes[n_mode].refresh_rate,
.driverdata = NULL
};
SDL_AddDisplayMode(display, &mode);
}
}
static void
MIR_InitDisplays(_THIS)
{
MIR_Data* mir_data = _this->driverdata;
int d;
MirDisplayConfiguration* display_config =
mir_connection_create_display_config(mir_data->connection);
for (d = 0; d < display_config->num_outputs; d++) {
MirDisplayOutput const* out = display_config->outputs + d;
SDL_VideoDisplay display;
SDL_zero(display);
if (out->used &&
out->connected &&
out->num_modes &&
out->current_mode < out->num_modes) {
MIR_SetCurrentDisplayMode(out, &display);
MIR_AddAllModesFromDisplay(out, &display);
SDL_AddVideoDisplay(&display);
}
}
mir_display_config_destroy(display_config);
}
int
MIR_VideoInit(_THIS)
{
MIR_Data* mir_data = _this->driverdata;
mir_data->connection = mir_connect_sync(NULL, __PRETTY_FUNCTION__);
if (!mir_connection_is_valid(mir_data->connection))
return SDL_SetError("Failed to connect to the Mir Server");
MIR_InitDisplays(_this);
MIR_InitMouse();
return 0;
}
void
MIR_VideoQuit(_THIS)
{
MIR_Data* mir_data = _this->driverdata;
MIR_FiniMouse();
MIR_GL_DeleteContext(_this, NULL);
MIR_GL_UnloadLibrary(_this);
mir_connection_release(mir_data->connection);
SDL_free(mir_data);
_this->driverdata = NULL;
}
static int
MIR_GetDisplayBounds(_THIS, SDL_VideoDisplay* display, SDL_Rect* rect)
{
MIR_Data* mir_data = _this->driverdata;
int d;
MirDisplayConfiguration* display_config =
mir_connection_create_display_config(mir_data->connection);
for (d = 0; d < display_config->num_outputs; d++) {
MirDisplayOutput const* out = display_config->outputs + d;
if (out->used &&
out->connected &&
out->num_modes &&
out->current_mode < out->num_modes) {
rect->x = out->position_x;
rect->y = out->position_y;
rect->w = out->modes->horizontal_resolution;
rect->h = out->modes->vertical_resolution;
}
}
mir_display_config_destroy(display_config);
return 0;
}
static void
MIR_GetDisplayModes(_THIS, SDL_VideoDisplay* sdl_display)
{
}
static int
MIR_SetDisplayMode(_THIS, SDL_VideoDisplay* sdl_display, SDL_DisplayMode* mode)
{
return 0;
}

View File

@ -0,0 +1,40 @@
/*
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.
*/
/*
Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
*/
#include "SDL_config.h"
#ifndef _SDL_mirvideo_h_
#define _SDL_mirvideo_h_
#include <EGL/egl.h>
#include <mir_toolkit/mir_client_library.h>
typedef struct
{
MirConnection* connection;
} MIR_Data;
#endif /* _SDL_mirvideo_h_ */

View File

@ -0,0 +1,216 @@
/*
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.
*/
/*
Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
*/
#include "SDL_config.h"
#include "../SDL_egl_c.h"
#include "../SDL_sysvideo.h"
#include "SDL_mirevents.h"
#include "SDL_mirwindow.h"
int
IsSurfaceValid(MIR_Window* mir_window)
{
if (!mir_surface_is_valid(mir_window->surface)) {
const char* error = mir_surface_get_error_message(mir_window->surface);
return SDL_SetError("Failed to created a mir surface: %s", error);
}
return 0;
}
MirPixelFormat
FindValidPixelFormat(MIR_Data* mir_data)
{
unsigned int pf_size = 32;
unsigned int valid_formats;
unsigned int f;
MirPixelFormat formats[pf_size];
mir_connection_get_available_surface_formats(mir_data->connection, formats,
pf_size, &valid_formats);
for (f = 0; f < valid_formats; f++) {
MirPixelFormat cur_pf = formats[f];
if (cur_pf == mir_pixel_format_abgr_8888 ||
cur_pf == mir_pixel_format_xbgr_8888 ||
cur_pf == mir_pixel_format_argb_8888 ||
cur_pf == mir_pixel_format_xrgb_8888) {
return cur_pf;
}
}
return mir_pixel_format_invalid;
}
int
MIR_CreateWindow(_THIS, SDL_Window* window)
{
MIR_Window* mir_window;
MIR_Data* mir_data;
MirSurfaceParameters surfaceparm =
{
.name = "MirSurface",
.width = window->w,
.height = window->h,
.pixel_format = mir_pixel_format_invalid,
.buffer_usage = mir_buffer_usage_hardware
};
MirEventDelegate delegate = {
MIR_HandleInput,
window
};
mir_window = SDL_calloc(1, sizeof(MIR_Window));
if (!mir_window)
return SDL_OutOfMemory();
mir_data = _this->driverdata;
window->driverdata = mir_window;
if (window->x == SDL_WINDOWPOS_UNDEFINED)
window->x = 0;
if (window->y == SDL_WINDOWPOS_UNDEFINED)
window->y = 0;
mir_window->mir_data = mir_data;
mir_window->sdl_window = window;
surfaceparm.pixel_format = FindValidPixelFormat(mir_data);
if (surfaceparm.pixel_format == mir_pixel_format_invalid) {
return SDL_SetError("Failed to find a valid pixel format.");
}
mir_window->surface = mir_connection_create_surface_sync(mir_data->connection, &surfaceparm);
if (!mir_surface_is_valid(mir_window->surface)) {
const char* error = mir_surface_get_error_message(mir_window->surface);
return SDL_SetError("Failed to created a mir surface: %s", error);
}
if (window->flags & SDL_WINDOW_OPENGL) {
EGLNativeWindowType egl_native_window =
(EGLNativeWindowType)mir_surface_get_egl_native_window(mir_window->surface);
mir_window->egl_surface = SDL_EGL_CreateSurface(_this, egl_native_window);
if (mir_window->egl_surface == EGL_NO_SURFACE) {
return SDL_SetError("Failed to created a window surface %p",
_this->egl_data->egl_display);
}
}
else {
mir_window->egl_surface = EGL_NO_SURFACE;
}
mir_surface_set_event_handler(mir_window->surface, &delegate);
return 0;
}
void
MIR_DestroyWindow(_THIS, SDL_Window* window)
{
MIR_Data* mir_data = _this->driverdata;
MIR_Window* mir_window = window->driverdata;
window->driverdata = NULL;
if (mir_data) {
SDL_EGL_DestroySurface(_this, mir_window->egl_surface);
mir_surface_release_sync(mir_window->surface);
SDL_free(mir_window);
}
}
SDL_bool
MIR_GetWindowWMInfo(_THIS, SDL_Window* window, SDL_SysWMinfo* info)
{
if (info->version.major == SDL_MAJOR_VERSION &&
info->version.minor == SDL_MINOR_VERSION) {
info->subsystem = SDL_SYSWM_MIR;
return SDL_TRUE;
}
return SDL_FALSE;
}
void
MIR_SetWindowFullscreen(_THIS, SDL_Window* window,
SDL_VideoDisplay* display,
SDL_bool fullscreen)
{
MIR_Window* mir_window = window->driverdata;
if (IsSurfaceValid(mir_window) < 0)
return;
if (fullscreen) {
mir_surface_set_type(mir_window->surface, mir_surface_state_fullscreen);
}
else {
mir_surface_set_type(mir_window->surface, mir_surface_state_restored);
}
}
void
MIR_MaximizeWindow(_THIS, SDL_Window* window)
{
MIR_Window* mir_window = window->driverdata;
if (IsSurfaceValid(mir_window) < 0)
return;
mir_surface_set_type(mir_window->surface, mir_surface_state_maximized);
}
void
MIR_MinimizeWindow(_THIS, SDL_Window* window)
{
MIR_Window* mir_window = window->driverdata;
if (IsSurfaceValid(mir_window) < 0)
return;
mir_surface_set_type(mir_window->surface, mir_surface_state_minimized);
}
void
MIR_RestoreWindow(_THIS, SDL_Window * window)
{
MIR_Window* mir_window = window->driverdata;
if (IsSurfaceValid(mir_window) < 0)
return;
mir_surface_set_type(mir_window->surface, mir_surface_state_restored);
}

View File

@ -0,0 +1,69 @@
/*
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.
*/
/*
Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
*/
#include "SDL_config.h"
#ifndef _SDL_mirwindow_h
#define _SDL_mirwindow_h
#include "../SDL_sysvideo.h"
#include "SDL_syswm.h"
#include "SDL_mirvideo.h"
typedef struct {
SDL_Window* sdl_window;
MIR_Data* mir_data;
MirSurface* surface;
EGLSurface egl_surface;
} MIR_Window;
extern int
MIR_CreateWindow(_THIS, SDL_Window* window);
extern void
MIR_DestroyWindow(_THIS, SDL_Window* window);
extern void
MIR_SetWindowFullscreen(_THIS, SDL_Window* window,
SDL_VideoDisplay* display,
SDL_bool fullscreen);
extern void
MIR_MaximizeWindow(_THIS, SDL_Window* window);
extern void
MIR_MinimizeWindow(_THIS, SDL_Window* window);
extern void
MIR_RestoreWindow(_THIS, SDL_Window* window);
extern SDL_bool
MIR_GetWindowWMInfo(_THIS, SDL_Window* window, SDL_SysWMinfo* info);
#endif /* _SDL_mirwindow */