Fixed crash if initialization of EGL failed but was tried again later.

The internal function SDL_EGL_LoadLibrary() did not delete and remove a mostly
uninitialized data structure if loading the library first failed. A later try to
use EGL then skipped initialization and assumed it was previously successful
because the data structure now already existed. This led to at least one crash
in the internal function SDL_EGL_ChooseConfig() because a NULL pointer was
dereferenced to make a call to eglBindAPI().
This commit is contained in:
Philipp Wiesemann
2015-06-21 17:33:46 +02:00
commit 0e45984fa0
1596 changed files with 468120 additions and 0 deletions

177
src/video/mir/SDL_mirdyn.c Normal file
View File

@@ -0,0 +1,177 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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_internal.h"
#if SDL_VIDEO_DRIVER_MIR
#define DEBUG_DYNAMIC_MIR 0
#include "SDL_mirdyn.h"
#if DEBUG_DYNAMIC_MIR
#include "SDL_log.h"
#endif
#ifdef SDL_VIDEO_DRIVER_MIR_DYNAMIC
#include "SDL_name.h"
#include "SDL_loadso.h"
typedef struct
{
void *lib;
const char *libname;
} mirdynlib;
#ifndef SDL_VIDEO_DRIVER_MIR_DYNAMIC
#define SDL_VIDEO_DRIVER_MIR_DYNAMIC NULL
#endif
#ifndef SDL_VIDEO_DRIVER_MIR_DYNAMIC_XKBCOMMON
#define SDL_VIDEO_DRIVER_MIR_DYNAMIC_XKBCOMMON NULL
#endif
static mirdynlib mirlibs[] = {
{NULL, SDL_VIDEO_DRIVER_MIR_DYNAMIC},
{NULL, SDL_VIDEO_DRIVER_MIR_DYNAMIC_XKBCOMMON}
};
static void *
MIR_GetSym(const char *fnname, int *pHasModule)
{
int i;
void *fn = NULL;
for (i = 0; i < SDL_TABLESIZE(mirlibs); i++) {
if (mirlibs[i].lib != NULL) {
fn = SDL_LoadFunction(mirlibs[i].lib, fnname);
if (fn != NULL)
break;
}
}
#if DEBUG_DYNAMIC_MIR
if (fn != NULL)
SDL_Log("MIR: Found '%s' in %s (%p)\n", fnname, mirlibs[i].libname, fn);
else
SDL_Log("MIR: Symbol '%s' NOT FOUND!\n", fnname);
#endif
if (fn == NULL)
*pHasModule = 0; /* kill this module. */
return fn;
}
#endif /* SDL_VIDEO_DRIVER_MIR_DYNAMIC */
/* Define all the function pointers and wrappers... */
#define SDL_MIR_MODULE(modname) int SDL_MIR_HAVE_##modname = 0;
#define SDL_MIR_SYM(rc,fn,params) SDL_DYNMIRFN_##fn MIR_##fn = NULL;
#include "SDL_mirsym.h"
#undef SDL_MIR_MODULE
#undef SDL_MIR_SYM
static int mir_load_refcount = 0;
void
SDL_MIR_UnloadSymbols(void)
{
/* Don't actually unload if more than one module is using the libs... */
if (mir_load_refcount > 0) {
if (--mir_load_refcount == 0) {
#ifdef SDL_VIDEO_DRIVER_MIR_DYNAMIC
int i;
#endif
/* set all the function pointers to NULL. */
#define SDL_MIR_MODULE(modname) SDL_MIR_HAVE_##modname = 0;
#define SDL_MIR_SYM(rc,fn,params) MIR_##fn = NULL;
#include "SDL_mirsym.h"
#undef SDL_MIR_MODULE
#undef SDL_MIR_SYM
#ifdef SDL_VIDEO_DRIVER_MIR_DYNAMIC
for (i = 0; i < SDL_TABLESIZE(mirlibs); i++) {
if (mirlibs[i].lib != NULL) {
SDL_UnloadObject(mirlibs[i].lib);
mirlibs[i].lib = NULL;
}
}
#endif
}
}
}
/* returns non-zero if all needed symbols were loaded. */
int
SDL_MIR_LoadSymbols(void)
{
int rc = 1; /* always succeed if not using Dynamic MIR stuff. */
/* deal with multiple modules (dga, wayland, mir, etc) needing these symbols... */
if (mir_load_refcount++ == 0) {
#ifdef SDL_VIDEO_DRIVER_MIR_DYNAMIC
int i;
int *thismod = NULL;
for (i = 0; i < SDL_TABLESIZE(mirlibs); i++) {
if (mirlibs[i].libname != NULL) {
mirlibs[i].lib = SDL_LoadObject(mirlibs[i].libname);
}
}
#define SDL_MIR_MODULE(modname) SDL_MIR_HAVE_##modname = 1; /* default yes */
#define SDL_MIR_SYM(rc,fn,params)
#include "SDL_mirsym.h"
#undef SDL_MIR_MODULE
#undef SDL_MIR_SYM
#define SDL_MIR_MODULE(modname) thismod = &SDL_MIR_HAVE_##modname;
#define SDL_MIR_SYM(rc,fn,params) MIR_##fn = (SDL_DYNMIRFN_##fn) MIR_GetSym(#fn,thismod);
#include "SDL_mirsym.h"
#undef SDL_MIR_MODULE
#undef SDL_MIR_SYM
if ((SDL_MIR_HAVE_MIR_CLIENT) && (SDL_MIR_HAVE_XKBCOMMON)) {
/* all required symbols loaded. */
SDL_ClearError();
} else {
/* in case something got loaded... */
SDL_MIR_UnloadSymbols();
rc = 0;
}
#else /* no dynamic MIR */
#define SDL_MIR_MODULE(modname) SDL_MIR_HAVE_##modname = 1; /* default yes */
#define SDL_MIR_SYM(rc,fn,params) MIR_##fn = fn;
#include "SDL_mirsym.h"
#undef SDL_MIR_MODULE
#undef SDL_MIR_SYM
#endif
}
return rc;
}
#endif /* SDL_VIDEO_DRIVER_MIR */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,53 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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 _SDL_mirdyn_h
#define _SDL_mirdyn_h
#include "../../SDL_internal.h"
#include <EGL/egl.h>
#include <mir_toolkit/mir_client_library.h>
#include <xkbcommon/xkbcommon.h>
#ifdef __cplusplus
extern "C" {
#endif
int SDL_MIR_LoadSymbols(void);
void SDL_MIR_UnloadSymbols(void);
/* Declare all the function pointers and wrappers... */
#define SDL_MIR_MODULE(modname)
#define SDL_MIR_SYM(rc,fn,params) \
typedef rc (*SDL_DYNMIRFN_##fn) params; \
extern SDL_DYNMIRFN_##fn MIR_##fn;
#include "SDL_mirsym.h"
#undef SDL_MIR_MODULE
#undef SDL_MIR_SYM
#ifdef __cplusplus
}
#endif
#endif /* !defined _SDL_mirdyn_h */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,254 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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_internal.h"
#if SDL_VIDEO_DRIVER_MIR
#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>
#include "SDL_mirdyn.h"
static void
HandleKeyText(int32_t key_code)
{
char text[8];
int size = 0;
size = MIR_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
HandleMouseMotion(SDL_Window* sdl_window, int x, int y)
{
SDL_SendMouseMotion(sdl_window, 0, 0, x, y);
}
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
HandleMouseScroll(SDL_Window* sdl_window, int hscroll, int vscroll)
{
SDL_SendMouseWheel(sdl_window, 0, hscroll, vscroll, SDL_MOUSEWHEEL_NORMAL);
}
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_finger) {
HandleTouchEvent(motion, cord_index, sdl_window);
}
else {
HandleMouseEvent(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;
}
}
#endif /* SDL_VIDEO_DRIVER_MIR */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,37 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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>
*/
#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 */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,159 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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_internal.h"
#if SDL_VIDEO_DRIVER_MIR
#include "SDL_mirevents.h"
#include "SDL_mirframebuffer.h"
#include "SDL_mirwindow.h"
#include "SDL_mirdyn.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;
mir_data->software = SDL_TRUE;
if (MIR_CreateWindow(_this, window) < 0)
return SDL_SetError("Failed to created a mir window.");
mir_window = window->driverdata;
MIR_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_mir_connection_create_surface_sync(mir_data->connection, &surfaceparm);
if (!MIR_mir_surface_is_valid(mir_window->surface)) {
const char* error = MIR_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;
char* s_dest;
char* pixels;
MIR_mir_surface_get_graphics_region(mir_window->surface, &region);
s_dest = region.vaddr;
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_mir_surface_swap_buffers_sync(mir_window->surface);
return 0;
}
void
MIR_DestroyWindowFramebuffer(_THIS, SDL_Window* window)
{
}
#endif /* SDL_VIDEO_DRIVER_MIR */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,47 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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>
*/
#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 */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,161 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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_internal.h"
#if SDL_VIDEO_DRIVER_MIR
#include "SDL_mirmouse.h"
#include "../../events/SDL_mouse_c.h"
#include "SDL_assert.h"
#include "SDL_mirdyn.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 void
MIR_WarpMouseGlobal(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->WarpMouseGlobal = MIR_WarpMouseGlobal;
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;
}
#endif /* SDL_VIDEO_DRIVER_MIR */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,37 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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>
*/
#ifndef _SDL_mirmouse_h
#define _SDL_mirmouse_h
extern void
MIR_InitMouse();
extern void
MIR_FiniMouse();
#endif /* _SDL_mirmouse_h */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,96 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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_internal.h"
#if SDL_VIDEO_DRIVER_MIR
#include "SDL_miropengl.h"
#include "SDL_mirdyn.h"
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_mir_connection_get_egl_native_display(mir_data->connection));
SDL_EGL_ChooseConfig(_this);
return 0;
}
void
MIR_GL_UnloadLibrary(_THIS)
{
SDL_EGL_UnloadLibrary(_this);
}
void*
MIR_GL_GetProcAddress(_THIS, const char* proc)
{
void* proc_addr = SDL_EGL_GetProcAddress(_this, proc);
if (!proc_addr) {
SDL_SetError("Failed to find proc address!");
}
return proc_addr;
}
#endif /* SDL_VIDEO_DRIVER_MIR */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,58 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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>
*/
#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 */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,49 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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.
*/
/* *INDENT-OFF* */
SDL_MIR_MODULE(MIR_CLIENT)
SDL_MIR_SYM(MirDisplayConfiguration*,mir_connection_create_display_config,(MirConnection *connection))
SDL_MIR_SYM(MirSurface *,mir_connection_create_surface_sync,(MirConnection *connection, MirSurfaceParameters const *params))
SDL_MIR_SYM(void,mir_connection_get_available_surface_formats,(MirConnection* connection, MirPixelFormat* formats, unsigned const int format_size, unsigned int *num_valid_formats))
SDL_MIR_SYM(MirEGLNativeDisplayType,mir_connection_get_egl_native_display,(MirConnection *connection))
SDL_MIR_SYM(MirBool,mir_connection_is_valid,(MirConnection *connection))
SDL_MIR_SYM(void,mir_connection_release,(MirConnection *connection))
SDL_MIR_SYM(MirConnection *,mir_connect_sync,(char const *server, char const *app_name))
SDL_MIR_SYM(void,mir_display_config_destroy,(MirDisplayConfiguration* display_configuration))
SDL_MIR_SYM(MirEGLNativeWindowType,mir_surface_get_egl_native_window,(MirSurface *surface))
SDL_MIR_SYM(char const *,mir_surface_get_error_message,(MirSurface *surface))
SDL_MIR_SYM(void,mir_surface_get_graphics_region,(MirSurface *surface, MirGraphicsRegion *graphics_region))
SDL_MIR_SYM(void,mir_surface_get_parameters,(MirSurface *surface, MirSurfaceParameters *parameters))
SDL_MIR_SYM(MirBool,mir_surface_is_valid,(MirSurface *surface))
SDL_MIR_SYM(void,mir_surface_release_sync,(MirSurface *surface))
SDL_MIR_SYM(void,mir_surface_set_event_handler,(MirSurface *surface, MirEventDelegate const *event_handler))
SDL_MIR_SYM(MirWaitHandle*,mir_surface_set_type,(MirSurface *surface, MirSurfaceType type))
SDL_MIR_SYM(MirWaitHandle*,mir_surface_set_state,(MirSurface *surface, MirSurfaceState state))
SDL_MIR_SYM(void,mir_surface_swap_buffers_sync,(MirSurface *surface))
SDL_MIR_MODULE(XKBCOMMON)
SDL_MIR_SYM(int,xkb_keysym_to_utf8,(xkb_keysym_t keysym, char *buffer, size_t size))
/* *INDENT-ON* */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,345 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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_internal.h"
#if SDL_VIDEO_DRIVER_MIR
#include "SDL_video.h"
#include "SDL_mirframebuffer.h"
#include "SDL_mirmouse.h"
#include "SDL_miropengl.h"
#include "SDL_mirvideo.h"
#include "SDL_mirwindow.h"
#include "SDL_mirdyn.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()
{
int available = 0;
if (SDL_MIR_LoadSymbols()) {
/* !!! FIXME: try to make a MirConnection here. */
available = 1;
SDL_MIR_UnloadSymbols();
}
return available;
}
static void
MIR_DeleteDevice(SDL_VideoDevice* device)
{
SDL_free(device);
SDL_MIR_UnloadSymbols();
}
void
MIR_PumpEvents(_THIS)
{
}
static SDL_VideoDevice*
MIR_CreateDevice(int device_index)
{
MIR_Data* mir_data;
SDL_VideoDevice* device = NULL;
if (!SDL_MIR_LoadSymbols()) {
return NULL;
}
device = SDL_calloc(1, sizeof(SDL_VideoDevice));
if (!device) {
SDL_MIR_UnloadSymbols();
SDL_OutOfMemory();
return NULL;
}
mir_data = SDL_calloc(1, sizeof(MIR_Data));
if (!mir_data) {
SDL_free(device);
SDL_MIR_UnloadSymbols();
SDL_OutOfMemory();
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_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_mir_display_config_destroy(display_config);
}
int
MIR_VideoInit(_THIS)
{
MIR_Data* mir_data = _this->driverdata;
mir_data->connection = MIR_mir_connect_sync(NULL, __PRETTY_FUNCTION__);
mir_data->software = SDL_FALSE;
if (!MIR_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_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_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_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;
}
#endif /* SDL_VIDEO_DRIVER_MIR */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,41 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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>
*/
#ifndef _SDL_mirvideo_h_
#define _SDL_mirvideo_h_
#include <EGL/egl.h>
#include <mir_toolkit/mir_client_library.h>
typedef struct
{
MirConnection* connection;
SDL_bool software;
} MIR_Data;
#endif /* _SDL_mirvideo_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,230 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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_internal.h"
#if SDL_VIDEO_DRIVER_MIR
#include "../SDL_egl_c.h"
#include "../SDL_sysvideo.h"
#include "SDL_mirevents.h"
#include "SDL_mirwindow.h"
#include "SDL_mirdyn.h"
int
IsSurfaceValid(MIR_Window* mir_window)
{
if (!MIR_mir_surface_is_valid(mir_window->surface)) {
const char* error = MIR_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_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,
.output_id = mir_display_output_id_invalid
};
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 (mir_data->software)
surfaceparm.buffer_usage = mir_buffer_usage_software;
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_mir_connection_create_surface_sync(mir_data->connection, &surfaceparm);
if (!MIR_mir_surface_is_valid(mir_window->surface)) {
const char* error = MIR_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_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_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;
if (mir_data) {
SDL_EGL_DestroySurface(_this, mir_window->egl_surface);
MIR_mir_surface_release_sync(mir_window->surface);
SDL_free(mir_window);
}
window->driverdata = NULL;
}
SDL_bool
MIR_GetWindowWMInfo(_THIS, SDL_Window* window, SDL_SysWMinfo* info)
{
if (info->version.major == SDL_MAJOR_VERSION &&
info->version.minor == SDL_MINOR_VERSION) {
MIR_Window* mir_window = window->driverdata;
info->subsystem = SDL_SYSWM_MIR;
info->info.mir.connection = mir_window->mir_data->connection;
info->info.mir.surface = mir_window->surface;
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_mir_surface_set_state(mir_window->surface, mir_surface_state_fullscreen);
} else {
MIR_mir_surface_set_state(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_mir_surface_set_state(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_mir_surface_set_state(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_mir_surface_set_state(mir_window->surface, mir_surface_state_restored);
}
#endif /* SDL_VIDEO_DRIVER_MIR */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,69 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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>
*/
#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_h */
/* vi: set ts=4 sw=4 expandtab: */