Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix API/ABI breakage in Mir 0.13/0.14.
  • Loading branch information
bschaefer committed Feb 21, 2016
1 parent 481a21b commit 3607d3b
Show file tree
Hide file tree
Showing 12 changed files with 540 additions and 202 deletions.
6 changes: 3 additions & 3 deletions configure.in
Expand Up @@ -1284,12 +1284,12 @@ AC_HELP_STRING([--enable-video-mir], [use Mir video driver [[default=yes]]]),
MIR_LIBS=`$PKG_CONFIG --libs mirclient egl xkbcommon`
save_CFLAGS="$CFLAGS"
CFLAGS="$save_CFLAGS $MIR_CFLAGS"
dnl This will disable Mir on Ubuntu < 14.04

dnl This will disable Mir on Ubuntu < 15.04 (Mir should be 0.14 at this point)
AC_TRY_COMPILE([
#include <mir_toolkit/mir_client_library.h>
],[
MirMotionToolType tool = mir_motion_tool_type_mouse;
MirPointerButton button = mir_pointer_button_primary;
],[
video_mir=yes
])
Expand Down
4 changes: 4 additions & 0 deletions src/video/mir/SDL_mirdyn.c
Expand Up @@ -84,6 +84,7 @@ MIR_GetSym(const char *fnname, int *pHasModule)
/* 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;
#define SDL_MIR_SYM_CONST(type,name) SDL_DYMMIRCONST_##name MIR_##name = NULL;
#include "SDL_mirsym.h"

static int mir_load_refcount = 0;
Expand All @@ -101,6 +102,7 @@ SDL_MIR_UnloadSymbols(void)
/* 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;
#define SDL_MIR_SYM_CONST(type,name) MIR_##name = NULL;
#include "SDL_mirsym.h"


Expand Down Expand Up @@ -138,6 +140,7 @@ SDL_MIR_LoadSymbols(void)

#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);
#define SDL_MIR_SYM_CONST(type,name) MIR_##name = *(SDL_DYMMIRCONST_##name*) MIR_GetSym(#name,thismod);
#include "SDL_mirsym.h"

if ((SDL_MIR_HAVE_MIR_CLIENT) && (SDL_MIR_HAVE_XKBCOMMON)) {
Expand All @@ -153,6 +156,7 @@ SDL_MIR_LoadSymbols(void)

#define SDL_MIR_MODULE(modname) SDL_MIR_HAVE_##modname = 1; /* default yes */
#define SDL_MIR_SYM(rc,fn,params) MIR_##fn = fn;
#define SDL_MIR_SYM_CONST(type,name) MIR_##name = name;
#include "SDL_mirsym.h"

#endif
Expand Down
3 changes: 3 additions & 0 deletions src/video/mir/SDL_mirdyn.h
Expand Up @@ -39,6 +39,9 @@ void SDL_MIR_UnloadSymbols(void);
#define SDL_MIR_SYM(rc,fn,params) \
typedef rc (*SDL_DYNMIRFN_##fn) params; \
extern SDL_DYNMIRFN_##fn MIR_##fn;
#define SDL_MIR_SYM_CONST(type, name) \
typedef type SDL_DYMMIRCONST_##name; \
extern SDL_DYMMIRCONST_##name MIR_##name;
#include "SDL_mirsym.h"

#ifdef __cplusplus
Expand Down
214 changes: 127 additions & 87 deletions src/video/mir/SDL_mirevents.c
Expand Up @@ -58,7 +58,7 @@ CheckKeyboardFocus(SDL_Window* sdl_window)
{
SDL_Window* keyboard_window = SDL_GetKeyboardFocus();

if (keyboard_window != sdl_window)
if (sdl_window && keyboard_window != sdl_window)
SDL_SetKeyboardFocus(sdl_window);
}

Expand All @@ -68,51 +68,68 @@ CheckKeyboardFocus(SDL_Window* sdl_window)
a single key press produces a character.
*/
static void
HandleKeyEvent(MirKeyEvent const ev, SDL_Window* window)
HandleKeyEvent(MirKeyboardEvent const* key_event, SDL_Window* window)
{
uint32_t scancode = SDL_SCANCODE_UNKNOWN;
Uint8 key_state = ev.action == mir_key_action_up ? SDL_RELEASED : SDL_PRESSED;
xkb_keysym_t key_code;
Uint8 key_state;
int event_scancode;
uint32_t sdl_scancode = SDL_SCANCODE_UNKNOWN;

MirKeyboardAction action = MIR_mir_keyboard_event_action(key_event);

key_state = SDL_PRESSED;
key_code = MIR_mir_keyboard_event_key_code(key_event);
event_scancode = MIR_mir_keyboard_event_scan_code(key_event);

if (action == mir_keyboard_action_up)
key_state = SDL_RELEASED;

CheckKeyboardFocus(window);

if (ev.scan_code < SDL_arraysize(xfree86_scancode_table2))
scancode = xfree86_scancode_table2[ev.scan_code];
if (event_scancode < SDL_arraysize(xfree86_scancode_table2))
sdl_scancode = xfree86_scancode_table2[event_scancode];

if (scancode != SDL_SCANCODE_UNKNOWN)
SDL_SendKeyboardKey(key_state, scancode);
if (sdl_scancode != SDL_SCANCODE_UNKNOWN)
SDL_SendKeyboardKey(key_state, sdl_scancode);

if (key_state == SDL_PRESSED)
HandleKeyText(ev.key_code);
HandleKeyText(key_code);
}

static void
HandleMouseButton(SDL_Window* sdl_window, Uint8 state, MirMotionButton button_state)
HandleMouseButton(SDL_Window* sdl_window, Uint8 state, MirPointerEvent const* pointer)
{
static uint32_t last_sdl_button;
uint32_t sdl_button;
uint32_t sdl_button = SDL_BUTTON_LEFT;
MirPointerButton button_state = mir_pointer_button_primary;

static uint32_t old_button_states = 0;
uint32_t new_button_states = MIR_mir_pointer_event_buttons(pointer);

// XOR on our old button states vs our new states to get the newley pressed/released button
button_state = new_button_states ^ old_button_states;

switch (button_state) {
case mir_motion_button_primary:
case mir_pointer_button_primary:
sdl_button = SDL_BUTTON_LEFT;
break;
case mir_motion_button_secondary:
case mir_pointer_button_secondary:
sdl_button = SDL_BUTTON_RIGHT;
break;
case mir_motion_button_tertiary:
case mir_pointer_button_tertiary:
sdl_button = SDL_BUTTON_MIDDLE;
break;
case mir_motion_button_forward:
case mir_pointer_button_forward:
sdl_button = SDL_BUTTON_X1;
break;
case mir_motion_button_back:
case mir_pointer_button_back:
sdl_button = SDL_BUTTON_X2;
break;
default:
sdl_button = last_sdl_button;
break;
}

last_sdl_button = sdl_button;
old_button_states = new_button_states;

SDL_SendMouseButton(sdl_window, 0, state, sdl_button);
}

Expand Down Expand Up @@ -148,104 +165,127 @@ AddTouchDevice(int device_id)
}

static void
HandleTouchEvent(MirMotionEvent const motion, int cord_index, SDL_Window* sdl_window)
HandleTouchEvent(MirTouchEvent const* touch, int device_id, SDL_Window* sdl_window)
{
int device_id = motion.device_id;
int id = motion.pointer_coordinates[cord_index].id;
int i, point_count;
point_count = MIR_mir_touch_event_point_count(touch);

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;
AddTouchDevice(device_id);

float n_x = x / width;
float n_y = y / height;
float pressure = motion.pointer_coordinates[cord_index].pressure;
for (i = 0; i < point_count; i++) {
int id = MIR_mir_touch_event_id(touch, i);

AddTouchDevice(motion.device_id);
int width = sdl_window->w;
int height = sdl_window->h;

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;
float x = MIR_mir_touch_event_axis_value(touch, i, mir_touch_axis_x);
float y = MIR_mir_touch_event_axis_value(touch, i, mir_touch_axis_y);

float n_x = x / width;
float n_y = y / height;

float pressure = MIR_mir_touch_event_axis_value(touch, i, mir_touch_axis_pressure);

switch (MIR_mir_touch_event_action(touch, i)) {
case mir_touch_action_up:
HandleTouchPress(device_id, id, SDL_FALSE, n_x, n_y, pressure);
break;
case mir_touch_action_down:
HandleTouchPress(device_id, id, SDL_TRUE, n_x, n_y, pressure);
break;
case mir_touch_action_change:
HandleTouchMotion(device_id, id, n_x, n_y, pressure);
break;
}
}
}

static void
HandleMouseEvent(MirMotionEvent const motion, int cord_index, SDL_Window* sdl_window)
HandleMouseEvent(MirPointerEvent const* pointer, 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);
switch (MIR_mir_pointer_event_action(pointer)) {
case mir_pointer_action_button_down:
HandleMouseButton(sdl_window, SDL_PRESSED, pointer);
break;
case mir_motion_action_up:
case mir_motion_action_pointer_up:
HandleMouseButton(sdl_window, SDL_RELEASED, motion.button_state);
case mir_pointer_action_button_up:
HandleMouseButton(sdl_window, SDL_RELEASED, pointer);
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);
case mir_pointer_action_motion: {
int x, y;
int hscroll, vscroll;
SDL_Mouse* mouse = SDL_GetMouse();
x = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_x);
y = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_y);
hscroll = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_hscroll);
vscroll = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_vscroll);

if (mouse && (mouse->x != x || mouse->y != y))
HandleMouseMotion(sdl_window, x, y);
if (vscroll != 0 || hscroll != 0)
HandleMouseScroll(sdl_window, hscroll, vscroll);
}
break;
case mir_motion_action_outside:
case mir_pointer_action_leave:
SDL_SetMouseFocus(NULL);
break;
case mir_motion_action_scroll:
HandleMouseScroll(sdl_window,
motion.pointer_coordinates[cord_index].hscroll,
motion.pointer_coordinates[cord_index].vscroll);
case mir_pointer_action_enter:
default:
break;
}
}

static void
MIR_HandleInput(MirInputEvent const* input_event, SDL_Window* window)
{
switch (MIR_mir_input_event_get_type(input_event)) {
case (mir_input_event_type_key):
HandleKeyEvent(MIR_mir_input_event_get_keyboard_event(input_event), window);
break;
case (mir_input_event_type_pointer):
HandleMouseEvent(MIR_mir_input_event_get_pointer_event(input_event), window);
break;
case mir_motion_action_cancel:
case mir_motion_action_hover_enter:
case mir_motion_action_hover_exit:
case (mir_input_event_type_touch):
HandleTouchEvent(MIR_mir_input_event_get_touch_event(input_event),
MIR_mir_input_event_get_device_id(input_event),
window);
break;
default:
break;
}
}

static void
HandleMotionEvent(MirMotionEvent const motion, SDL_Window* sdl_window)
MIR_HandleResize(MirResizeEvent const* resize_event, SDL_Window* 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);
}
}
int new_w = MIR_mir_resize_event_get_width (resize_event);
int new_h = MIR_mir_resize_event_get_height(resize_event);

int old_w = window->w;
int old_h = window->h;

if (new_w != old_w || new_h != old_h)
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, new_w, new_h);
}

void
MIR_HandleInput(MirSurface* surface, MirEvent const* ev, void* context)
MIR_HandleEvent(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;
MirEventType event_type = MIR_mir_event_get_type(ev);
SDL_Window* window = (SDL_Window*)context;

if (window) {
switch (event_type) {
case (mir_event_type_input):
MIR_HandleInput(MIR_mir_event_get_input_event(ev), window);
break;
case (mir_event_type_resize):
MIR_HandleResize(MIR_mir_event_get_resize_event(ev), window);
break;
default:
break;
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/video/mir/SDL_mirevents.h
Expand Up @@ -29,7 +29,7 @@
#include <mir_toolkit/mir_client_library.h>

extern void
MIR_HandleInput(MirSurface* surface, MirEvent const* ev, void* context);
MIR_HandleEvent(MirSurface* surface, MirEvent const* ev, void* context);

#endif /* _SDL_mirevents_h */

Expand Down

0 comments on commit 3607d3b

Please sign in to comment.